2 * This file is part of wl18xx
4 * Copyright (C) 2011 Texas Instruments
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 #include <linux/module.h>
23 #include <linux/platform_device.h>
25 #include <linux/firmware.h>
27 #include "../wlcore/wlcore.h"
28 #include "../wlcore/debug.h"
29 #include "../wlcore/io.h"
30 #include "../wlcore/acx.h"
31 #include "../wlcore/tx.h"
32 #include "../wlcore/rx.h"
33 #include "../wlcore/boot.h"
46 #define WL18XX_RX_CHECKSUM_MASK 0x40
48 static char *ht_mode_param = NULL;
49 static char *board_type_param = NULL;
50 static bool checksum_param = false;
51 static int num_rx_desc_param = -1;
54 static int dc2dc_param = -1;
55 static int n_antennas_2_param = -1;
56 static int n_antennas_5_param = -1;
57 static int low_band_component_param = -1;
58 static int low_band_component_type_param = -1;
59 static int high_band_component_param = -1;
60 static int high_band_component_type_param = -1;
61 static int pwr_limit_reference_11_abg_param = -1;
63 static const u8 wl18xx_rate_to_idx_2ghz[] = {
64 /* MCS rates are used only with 11n */
65 15, /* WL18XX_CONF_HW_RXTX_RATE_MCS15 */
66 14, /* WL18XX_CONF_HW_RXTX_RATE_MCS14 */
67 13, /* WL18XX_CONF_HW_RXTX_RATE_MCS13 */
68 12, /* WL18XX_CONF_HW_RXTX_RATE_MCS12 */
69 11, /* WL18XX_CONF_HW_RXTX_RATE_MCS11 */
70 10, /* WL18XX_CONF_HW_RXTX_RATE_MCS10 */
71 9, /* WL18XX_CONF_HW_RXTX_RATE_MCS9 */
72 8, /* WL18XX_CONF_HW_RXTX_RATE_MCS8 */
73 7, /* WL18XX_CONF_HW_RXTX_RATE_MCS7 */
74 6, /* WL18XX_CONF_HW_RXTX_RATE_MCS6 */
75 5, /* WL18XX_CONF_HW_RXTX_RATE_MCS5 */
76 4, /* WL18XX_CONF_HW_RXTX_RATE_MCS4 */
77 3, /* WL18XX_CONF_HW_RXTX_RATE_MCS3 */
78 2, /* WL18XX_CONF_HW_RXTX_RATE_MCS2 */
79 1, /* WL18XX_CONF_HW_RXTX_RATE_MCS1 */
80 0, /* WL18XX_CONF_HW_RXTX_RATE_MCS0 */
82 11, /* WL18XX_CONF_HW_RXTX_RATE_54 */
83 10, /* WL18XX_CONF_HW_RXTX_RATE_48 */
84 9, /* WL18XX_CONF_HW_RXTX_RATE_36 */
85 8, /* WL18XX_CONF_HW_RXTX_RATE_24 */
87 /* TI-specific rate */
88 CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_22 */
90 7, /* WL18XX_CONF_HW_RXTX_RATE_18 */
91 6, /* WL18XX_CONF_HW_RXTX_RATE_12 */
92 3, /* WL18XX_CONF_HW_RXTX_RATE_11 */
93 5, /* WL18XX_CONF_HW_RXTX_RATE_9 */
94 4, /* WL18XX_CONF_HW_RXTX_RATE_6 */
95 2, /* WL18XX_CONF_HW_RXTX_RATE_5_5 */
96 1, /* WL18XX_CONF_HW_RXTX_RATE_2 */
97 0 /* WL18XX_CONF_HW_RXTX_RATE_1 */
100 static const u8 wl18xx_rate_to_idx_5ghz[] = {
101 /* MCS rates are used only with 11n */
102 15, /* WL18XX_CONF_HW_RXTX_RATE_MCS15 */
103 14, /* WL18XX_CONF_HW_RXTX_RATE_MCS14 */
104 13, /* WL18XX_CONF_HW_RXTX_RATE_MCS13 */
105 12, /* WL18XX_CONF_HW_RXTX_RATE_MCS12 */
106 11, /* WL18XX_CONF_HW_RXTX_RATE_MCS11 */
107 10, /* WL18XX_CONF_HW_RXTX_RATE_MCS10 */
108 9, /* WL18XX_CONF_HW_RXTX_RATE_MCS9 */
109 8, /* WL18XX_CONF_HW_RXTX_RATE_MCS8 */
110 7, /* WL18XX_CONF_HW_RXTX_RATE_MCS7 */
111 6, /* WL18XX_CONF_HW_RXTX_RATE_MCS6 */
112 5, /* WL18XX_CONF_HW_RXTX_RATE_MCS5 */
113 4, /* WL18XX_CONF_HW_RXTX_RATE_MCS4 */
114 3, /* WL18XX_CONF_HW_RXTX_RATE_MCS3 */
115 2, /* WL18XX_CONF_HW_RXTX_RATE_MCS2 */
116 1, /* WL18XX_CONF_HW_RXTX_RATE_MCS1 */
117 0, /* WL18XX_CONF_HW_RXTX_RATE_MCS0 */
119 7, /* WL18XX_CONF_HW_RXTX_RATE_54 */
120 6, /* WL18XX_CONF_HW_RXTX_RATE_48 */
121 5, /* WL18XX_CONF_HW_RXTX_RATE_36 */
122 4, /* WL18XX_CONF_HW_RXTX_RATE_24 */
124 /* TI-specific rate */
125 CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_22 */
127 3, /* WL18XX_CONF_HW_RXTX_RATE_18 */
128 2, /* WL18XX_CONF_HW_RXTX_RATE_12 */
129 CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_11 */
130 1, /* WL18XX_CONF_HW_RXTX_RATE_9 */
131 0, /* WL18XX_CONF_HW_RXTX_RATE_6 */
132 CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_5_5 */
133 CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_2 */
134 CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_1 */
137 static const u8 *wl18xx_band_rate_to_idx[] = {
138 [IEEE80211_BAND_2GHZ] = wl18xx_rate_to_idx_2ghz,
139 [IEEE80211_BAND_5GHZ] = wl18xx_rate_to_idx_5ghz
142 enum wl18xx_hw_rates {
143 WL18XX_CONF_HW_RXTX_RATE_MCS15 = 0,
144 WL18XX_CONF_HW_RXTX_RATE_MCS14,
145 WL18XX_CONF_HW_RXTX_RATE_MCS13,
146 WL18XX_CONF_HW_RXTX_RATE_MCS12,
147 WL18XX_CONF_HW_RXTX_RATE_MCS11,
148 WL18XX_CONF_HW_RXTX_RATE_MCS10,
149 WL18XX_CONF_HW_RXTX_RATE_MCS9,
150 WL18XX_CONF_HW_RXTX_RATE_MCS8,
151 WL18XX_CONF_HW_RXTX_RATE_MCS7,
152 WL18XX_CONF_HW_RXTX_RATE_MCS6,
153 WL18XX_CONF_HW_RXTX_RATE_MCS5,
154 WL18XX_CONF_HW_RXTX_RATE_MCS4,
155 WL18XX_CONF_HW_RXTX_RATE_MCS3,
156 WL18XX_CONF_HW_RXTX_RATE_MCS2,
157 WL18XX_CONF_HW_RXTX_RATE_MCS1,
158 WL18XX_CONF_HW_RXTX_RATE_MCS0,
159 WL18XX_CONF_HW_RXTX_RATE_54,
160 WL18XX_CONF_HW_RXTX_RATE_48,
161 WL18XX_CONF_HW_RXTX_RATE_36,
162 WL18XX_CONF_HW_RXTX_RATE_24,
163 WL18XX_CONF_HW_RXTX_RATE_22,
164 WL18XX_CONF_HW_RXTX_RATE_18,
165 WL18XX_CONF_HW_RXTX_RATE_12,
166 WL18XX_CONF_HW_RXTX_RATE_11,
167 WL18XX_CONF_HW_RXTX_RATE_9,
168 WL18XX_CONF_HW_RXTX_RATE_6,
169 WL18XX_CONF_HW_RXTX_RATE_5_5,
170 WL18XX_CONF_HW_RXTX_RATE_2,
171 WL18XX_CONF_HW_RXTX_RATE_1,
172 WL18XX_CONF_HW_RXTX_RATE_MAX,
175 static struct wlcore_conf wl18xx_conf = {
178 [CONF_SG_ACL_BT_MASTER_MIN_BR] = 10,
179 [CONF_SG_ACL_BT_MASTER_MAX_BR] = 180,
180 [CONF_SG_ACL_BT_SLAVE_MIN_BR] = 10,
181 [CONF_SG_ACL_BT_SLAVE_MAX_BR] = 180,
182 [CONF_SG_ACL_BT_MASTER_MIN_EDR] = 10,
183 [CONF_SG_ACL_BT_MASTER_MAX_EDR] = 80,
184 [CONF_SG_ACL_BT_SLAVE_MIN_EDR] = 10,
185 [CONF_SG_ACL_BT_SLAVE_MAX_EDR] = 80,
186 [CONF_SG_ACL_WLAN_PS_MASTER_BR] = 8,
187 [CONF_SG_ACL_WLAN_PS_SLAVE_BR] = 8,
188 [CONF_SG_ACL_WLAN_PS_MASTER_EDR] = 20,
189 [CONF_SG_ACL_WLAN_PS_SLAVE_EDR] = 20,
190 [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_BR] = 20,
191 [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_BR] = 35,
192 [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_BR] = 16,
193 [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_BR] = 35,
194 [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_EDR] = 32,
195 [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_EDR] = 50,
196 [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_EDR] = 28,
197 [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_EDR] = 50,
198 [CONF_SG_ACL_ACTIVE_SCAN_WLAN_BR] = 10,
199 [CONF_SG_ACL_ACTIVE_SCAN_WLAN_EDR] = 20,
200 [CONF_SG_ACL_PASSIVE_SCAN_BT_BR] = 75,
201 [CONF_SG_ACL_PASSIVE_SCAN_WLAN_BR] = 15,
202 [CONF_SG_ACL_PASSIVE_SCAN_BT_EDR] = 27,
203 [CONF_SG_ACL_PASSIVE_SCAN_WLAN_EDR] = 17,
204 /* active scan params */
205 [CONF_SG_AUTO_SCAN_PROBE_REQ] = 170,
206 [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3] = 50,
207 [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP] = 100,
208 /* passive scan params */
209 [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP_BR] = 800,
210 [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP_EDR] = 200,
211 [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3] = 200,
212 /* passive scan in dual antenna params */
213 [CONF_SG_CONSECUTIVE_HV3_IN_PASSIVE_SCAN] = 0,
214 [CONF_SG_BCN_HV3_COLLISION_THRESH_IN_PASSIVE_SCAN] = 0,
215 [CONF_SG_TX_RX_PROTECTION_BWIDTH_IN_PASSIVE_SCAN] = 0,
217 [CONF_SG_STA_FORCE_PS_IN_BT_SCO] = 1,
218 [CONF_SG_ANTENNA_CONFIGURATION] = 0,
219 [CONF_SG_BEACON_MISS_PERCENT] = 60,
220 [CONF_SG_DHCP_TIME] = 5000,
221 [CONF_SG_RXT] = 1200,
222 [CONF_SG_TXT] = 1000,
223 [CONF_SG_ADAPTIVE_RXT_TXT] = 1,
224 [CONF_SG_GENERAL_USAGE_BIT_MAP] = 3,
225 [CONF_SG_HV3_MAX_SERVED] = 6,
226 [CONF_SG_PS_POLL_TIMEOUT] = 10,
227 [CONF_SG_UPSD_TIMEOUT] = 10,
228 [CONF_SG_CONSECUTIVE_CTS_THRESHOLD] = 2,
229 [CONF_SG_STA_RX_WINDOW_AFTER_DTIM] = 5,
230 [CONF_SG_STA_CONNECTION_PROTECTION_TIME] = 30,
232 [CONF_AP_BEACON_MISS_TX] = 3,
233 [CONF_AP_RX_WINDOW_AFTER_BEACON] = 10,
234 [CONF_AP_BEACON_WINDOW_INTERVAL] = 2,
235 [CONF_AP_CONNECTION_PROTECTION_TIME] = 0,
236 [CONF_AP_BT_ACL_VAL_BT_SERVE_TIME] = 25,
237 [CONF_AP_BT_ACL_VAL_WL_SERVE_TIME] = 25,
238 /* CTS Diluting params */
239 [CONF_SG_CTS_DILUTED_BAD_RX_PACKETS_TH] = 0,
240 [CONF_SG_CTS_CHOP_IN_DUAL_ANT_SCO_MASTER] = 0,
242 .state = CONF_SG_PROTECTIVE,
245 .rx_msdu_life_time = 512000,
246 .packet_detection_threshold = 0,
247 .ps_poll_timeout = 15,
249 .rts_threshold = IEEE80211_MAX_RTS_THRESHOLD,
250 .rx_cca_threshold = 0,
251 .irq_blk_threshold = 0xFFFF,
252 .irq_pkt_threshold = 0,
254 .queue_type = CONF_RX_QUEUE_TYPE_LOW_PRIORITY,
257 .tx_energy_detection = 0,
260 .short_retry_limit = 10,
261 .long_retry_limit = 10,
284 .aifsn = CONF_TX_AIFS_PIFS,
291 .aifsn = CONF_TX_AIFS_PIFS,
295 .max_tx_retries = 100,
296 .ap_aging_period = 300,
300 .queue_id = CONF_TX_AC_BE,
301 .channel_type = CONF_CHANNEL_TYPE_EDCF,
302 .tsid = CONF_TX_AC_BE,
303 .ps_scheme = CONF_PS_SCHEME_LEGACY,
304 .ack_policy = CONF_ACK_POLICY_LEGACY,
308 .queue_id = CONF_TX_AC_BK,
309 .channel_type = CONF_CHANNEL_TYPE_EDCF,
310 .tsid = CONF_TX_AC_BK,
311 .ps_scheme = CONF_PS_SCHEME_LEGACY,
312 .ack_policy = CONF_ACK_POLICY_LEGACY,
316 .queue_id = CONF_TX_AC_VI,
317 .channel_type = CONF_CHANNEL_TYPE_EDCF,
318 .tsid = CONF_TX_AC_VI,
319 .ps_scheme = CONF_PS_SCHEME_LEGACY,
320 .ack_policy = CONF_ACK_POLICY_LEGACY,
324 .queue_id = CONF_TX_AC_VO,
325 .channel_type = CONF_CHANNEL_TYPE_EDCF,
326 .tsid = CONF_TX_AC_VO,
327 .ps_scheme = CONF_PS_SCHEME_LEGACY,
328 .ack_policy = CONF_ACK_POLICY_LEGACY,
332 .frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD,
333 .tx_compl_timeout = 350,
334 .tx_compl_threshold = 10,
335 .basic_rate = CONF_HW_BIT_RATE_1MBPS,
336 .basic_rate_5 = CONF_HW_BIT_RATE_6MBPS,
337 .tmpl_short_retry_limit = 10,
338 .tmpl_long_retry_limit = 10,
339 .tx_watchdog_timeout = 5000,
340 .slow_link_thold = 3,
341 .fast_link_thold = 30,
344 .wake_up_event = CONF_WAKE_UP_EVENT_DTIM,
345 .listen_interval = 1,
346 .suspend_wake_up_event = CONF_WAKE_UP_EVENT_N_DTIM,
347 .suspend_listen_interval = 3,
348 .bcn_filt_mode = CONF_BCN_FILT_MODE_ENABLED,
349 .bcn_filt_ie_count = 3,
352 .ie = WLAN_EID_CHANNEL_SWITCH,
353 .rule = CONF_BCN_RULE_PASS_ON_APPEARANCE,
356 .ie = WLAN_EID_HT_OPERATION,
357 .rule = CONF_BCN_RULE_PASS_ON_CHANGE,
360 .ie = WLAN_EID_ERP_INFO,
361 .rule = CONF_BCN_RULE_PASS_ON_CHANGE,
364 .synch_fail_thold = 12,
365 .bss_lose_timeout = 400,
366 .beacon_rx_timeout = 10000,
367 .broadcast_timeout = 20000,
368 .rx_broadcast_in_ps = 1,
369 .ps_poll_threshold = 10,
370 .bet_enable = CONF_BET_MODE_ENABLE,
371 .bet_max_consecutive = 50,
372 .psm_entry_retries = 8,
373 .psm_exit_retries = 16,
374 .psm_entry_nullfunc_retries = 3,
375 .dynamic_ps_timeout = 1500,
377 .keep_alive_interval = 55000,
378 .max_listen_interval = 20,
379 .sta_sleep_auth = WL1271_PSM_ILLEGAL,
386 .host_clk_settling_time = 5000,
387 .host_fast_wakeup_support = CONF_FAST_WAKEUP_DISABLE,
391 .avg_weight_rssi_beacon = 20,
392 .avg_weight_rssi_data = 10,
393 .avg_weight_snr_beacon = 20,
394 .avg_weight_snr_data = 10,
397 .min_dwell_time_active = 7500,
398 .max_dwell_time_active = 30000,
399 .min_dwell_time_active_long = 25000,
400 .max_dwell_time_active_long = 50000,
401 .dwell_time_passive = 100000,
402 .dwell_time_dfs = 150000,
404 .split_scan_timeout = 50000,
408 * Values are in TU/1000 but since sched scan FW command
409 * params are in TUs rounding up may occur.
411 .base_dwell_time = 7500,
412 .max_dwell_time_delta = 22500,
413 /* based on 250bits per probe @1Mbps */
414 .dwell_time_delta_per_probe = 2000,
415 /* based on 250bits per probe @6Mbps (plus a bit more) */
416 .dwell_time_delta_per_probe_5 = 350,
417 .dwell_time_passive = 100000,
418 .dwell_time_dfs = 150000,
420 .rssi_threshold = -90,
424 .rx_ba_win_size = 32,
425 .tx_ba_win_size = 64,
426 .inactivity_timeout = 10000,
427 .tx_ba_tid_bitmap = CONF_TX_BA_ENABLED_TID_BITMAP,
433 .tx_min_block_num = 40,
435 .min_req_tx_blocks = 45,
436 .min_req_rx_blocks = 22,
442 .n_divider_fref_set_1 = 0xff, /* default */
443 .n_divider_fref_set_2 = 12,
444 .m_divider_fref_set_1 = 0xffff,
445 .m_divider_fref_set_2 = 148, /* default */
446 .coex_pll_stabilization_time = 0xffffffff, /* default */
447 .ldo_stabilization_time = 0xffff, /* default */
448 .fm_disturbed_band_margin = 0xff, /* default */
449 .swallow_clk_diff = 0xff, /* default */
458 .mode = WL12XX_FWLOG_ON_DEMAND,
461 .timestamp = WL12XX_FWLOG_TIMESTAMP_DISABLED,
462 .output = WL12XX_FWLOG_OUTPUT_HOST,
466 .rate_retry_score = 32000,
471 .inverse_curiosity_factor = 5,
473 .tx_fail_high_th = 10,
474 .per_alpha_shift = 4,
476 .per_beta1_shift = 10,
477 .per_beta2_shift = 8,
479 .rate_check_down = 12,
480 .rate_retry_policy = {
481 0x00, 0x00, 0x00, 0x00, 0x00,
482 0x00, 0x00, 0x00, 0x00, 0x00,
488 .hangover_period = 20,
490 .early_termination_mode = 1,
500 .bug_on_recovery = 0,
505 static struct wl18xx_priv_conf wl18xx_default_priv_conf = {
507 .mode = HT_MODE_DEFAULT,
510 .phy_standalone = 0x00,
511 .primary_clock_setting_time = 0x05,
512 .clock_valid_on_wake_up = 0x00,
513 .secondary_clock_setting_time = 0x05,
514 .board_type = BOARD_TYPE_HDK_18XX,
516 .dedicated_fem = FEM_NONE,
517 .low_band_component = COMPONENT_3_WAY_SWITCH,
518 .low_band_component_type = 0x04,
519 .high_band_component = COMPONENT_2_WAY_SWITCH,
520 .high_band_component_type = 0x09,
521 .tcxo_ldo_voltage = 0x00,
522 .xtal_itrim_val = 0x04,
524 .io_configuration = 0x01,
525 .sdio_configuration = 0x00,
528 .enable_tx_low_pwr_on_siso_rdl = 0x00,
530 .pwr_limit_reference_11_abg = 0x64,
531 .per_chan_pwr_limit_arr_11abg = {
532 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
533 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
534 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
535 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
536 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
537 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
538 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
539 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
540 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
541 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
542 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
543 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
544 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
545 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
546 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
547 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
548 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
549 .pwr_limit_reference_11p = 0x64,
550 .per_chan_bo_mode_11_abg = { 0x00, 0x00, 0x00, 0x00,
551 0x00, 0x00, 0x00, 0x00,
552 0x00, 0x00, 0x00, 0x00,
554 .per_chan_bo_mode_11_p = { 0x00, 0x00, 0x00, 0x00 },
555 .per_chan_pwr_limit_arr_11p = { 0xff, 0xff, 0xff, 0xff,
558 .low_power_val = 0x08,
559 .med_power_val = 0x12,
560 .high_power_val = 0x18,
561 .low_power_val_2nd = 0x05,
562 .med_power_val_2nd = 0x0a,
563 .high_power_val_2nd = 0x14,
564 .external_pa_dc2dc = 0,
565 .number_of_assembled_ant2_4 = 2,
566 .number_of_assembled_ant5 = 1,
571 static const struct wlcore_partition_set wl18xx_ptable[PART_TABLE_LEN] = {
572 [PART_TOP_PRCM_ELP_SOC] = {
573 .mem = { .start = 0x00A02000, .size = 0x00010000 },
574 .reg = { .start = 0x00807000, .size = 0x00005000 },
575 .mem2 = { .start = 0x00800000, .size = 0x0000B000 },
576 .mem3 = { .start = 0x00000000, .size = 0x00000000 },
579 .mem = { .start = 0x00000000, .size = 0x00014000 },
580 .reg = { .start = 0x00810000, .size = 0x0000BFFF },
581 .mem2 = { .start = 0x00000000, .size = 0x00000000 },
582 .mem3 = { .start = 0x00000000, .size = 0x00000000 },
585 .mem = { .start = 0x00700000, .size = 0x0000030c },
586 .reg = { .start = 0x00802000, .size = 0x00014578 },
587 .mem2 = { .start = 0x00B00404, .size = 0x00001000 },
588 .mem3 = { .start = 0x00C00000, .size = 0x00000400 },
591 .mem = { .start = 0x00800000, .size = 0x000050FC },
592 .reg = { .start = 0x00B00404, .size = 0x00001000 },
593 .mem2 = { .start = 0x00C00000, .size = 0x00000400 },
594 .mem3 = { .start = 0x00000000, .size = 0x00000000 },
597 .mem = { .start = 0x80926000,
598 .size = sizeof(struct wl18xx_mac_and_phy_params) },
599 .reg = { .start = 0x00000000, .size = 0x00000000 },
600 .mem2 = { .start = 0x00000000, .size = 0x00000000 },
601 .mem3 = { .start = 0x00000000, .size = 0x00000000 },
605 static const int wl18xx_rtable[REG_TABLE_LEN] = {
606 [REG_ECPU_CONTROL] = WL18XX_REG_ECPU_CONTROL,
607 [REG_INTERRUPT_NO_CLEAR] = WL18XX_REG_INTERRUPT_NO_CLEAR,
608 [REG_INTERRUPT_ACK] = WL18XX_REG_INTERRUPT_ACK,
609 [REG_COMMAND_MAILBOX_PTR] = WL18XX_REG_COMMAND_MAILBOX_PTR,
610 [REG_EVENT_MAILBOX_PTR] = WL18XX_REG_EVENT_MAILBOX_PTR,
611 [REG_INTERRUPT_TRIG] = WL18XX_REG_INTERRUPT_TRIG_H,
612 [REG_INTERRUPT_MASK] = WL18XX_REG_INTERRUPT_MASK,
613 [REG_PC_ON_RECOVERY] = WL18XX_SCR_PAD4,
614 [REG_CHIP_ID_B] = WL18XX_REG_CHIP_ID_B,
615 [REG_CMD_MBOX_ADDRESS] = WL18XX_CMD_MBOX_ADDRESS,
617 /* data access memory addresses, used with partition translation */
618 [REG_SLV_MEM_DATA] = WL18XX_SLV_MEM_DATA,
619 [REG_SLV_REG_DATA] = WL18XX_SLV_REG_DATA,
621 /* raw data access memory addresses */
622 [REG_RAW_FW_STATUS_ADDR] = WL18XX_FW_STATUS_ADDR,
625 static const struct wl18xx_clk_cfg wl18xx_clk_table[NUM_CLOCK_CONFIGS] = {
626 [CLOCK_CONFIG_16_2_M] = { 7, 104, 801, 4, true },
627 [CLOCK_CONFIG_16_368_M] = { 9, 132, 3751, 4, true },
628 [CLOCK_CONFIG_16_8_M] = { 7, 100, 0, 0, false },
629 [CLOCK_CONFIG_19_2_M] = { 8, 100, 0, 0, false },
630 [CLOCK_CONFIG_26_M] = { 13, 120, 0, 0, false },
631 [CLOCK_CONFIG_32_736_M] = { 9, 132, 3751, 4, true },
632 [CLOCK_CONFIG_33_6_M] = { 7, 100, 0, 0, false },
633 [CLOCK_CONFIG_38_468_M] = { 8, 100, 0, 0, false },
634 [CLOCK_CONFIG_52_M] = { 13, 120, 0, 0, false },
637 /* TODO: maybe move to a new header file? */
638 #define WL18XX_FW_NAME "ti-connectivity/wl18xx-fw-2.bin"
640 static int wl18xx_identify_chip(struct wl1271 *wl)
644 switch (wl->chip.id) {
645 case CHIP_ID_185x_PG20:
646 wl1271_debug(DEBUG_BOOT, "chip id 0x%x (185x PG20)",
648 wl->sr_fw_name = WL18XX_FW_NAME;
649 /* wl18xx uses the same firmware for PLT */
650 wl->plt_fw_name = WL18XX_FW_NAME;
651 wl->quirks |= WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN |
652 WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN |
653 WLCORE_QUIRK_NO_SCHED_SCAN_WHILE_CONN |
654 WLCORE_QUIRK_TX_PAD_LAST_FRAME |
655 WLCORE_QUIRK_REGDOMAIN_CONF |
656 WLCORE_QUIRK_DUAL_PROBE_TMPL;
658 wlcore_set_min_fw_ver(wl, WL18XX_CHIP_VER,
659 WL18XX_IFTYPE_VER, WL18XX_MAJOR_VER,
660 WL18XX_SUBTYPE_VER, WL18XX_MINOR_VER,
661 /* there's no separate multi-role FW */
664 case CHIP_ID_185x_PG10:
665 wl1271_warning("chip id 0x%x (185x PG10) is deprecated",
671 wl1271_warning("unsupported chip id: 0x%x", wl->chip.id);
676 wl->scan_templ_id_2_4 = CMD_TEMPL_CFG_PROBE_REQ_2_4;
677 wl->scan_templ_id_5 = CMD_TEMPL_CFG_PROBE_REQ_5;
678 wl->sched_scan_templ_id_2_4 = CMD_TEMPL_PROBE_REQ_2_4_PERIODIC;
679 wl->sched_scan_templ_id_5 = CMD_TEMPL_PROBE_REQ_5_PERIODIC;
680 wl->max_channels_5 = WL18XX_MAX_CHANNELS_5GHZ;
681 wl->ba_rx_session_count_max = WL18XX_RX_BA_MAX_SESSIONS;
686 static int wl18xx_set_clk(struct wl1271 *wl)
691 ret = wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]);
695 /* TODO: PG2: apparently we need to read the clk type */
697 ret = wl18xx_top_reg_read(wl, PRIMARY_CLK_DETECT, &clk_freq);
701 wl1271_debug(DEBUG_BOOT, "clock freq %d (%d, %d, %d, %d, %s)", clk_freq,
702 wl18xx_clk_table[clk_freq].n, wl18xx_clk_table[clk_freq].m,
703 wl18xx_clk_table[clk_freq].p, wl18xx_clk_table[clk_freq].q,
704 wl18xx_clk_table[clk_freq].swallow ? "swallow" : "spit");
706 ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_N,
707 wl18xx_clk_table[clk_freq].n);
711 ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_M,
712 wl18xx_clk_table[clk_freq].m);
716 if (wl18xx_clk_table[clk_freq].swallow) {
717 /* first the 16 lower bits */
718 ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_Q_FACTOR_CFG_1,
719 wl18xx_clk_table[clk_freq].q &
720 PLLSH_WCS_PLL_Q_FACTOR_CFG_1_MASK);
724 /* then the 16 higher bits, masked out */
725 ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_Q_FACTOR_CFG_2,
726 (wl18xx_clk_table[clk_freq].q >> 16) &
727 PLLSH_WCS_PLL_Q_FACTOR_CFG_2_MASK);
731 /* first the 16 lower bits */
732 ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_P_FACTOR_CFG_1,
733 wl18xx_clk_table[clk_freq].p &
734 PLLSH_WCS_PLL_P_FACTOR_CFG_1_MASK);
738 /* then the 16 higher bits, masked out */
739 ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_P_FACTOR_CFG_2,
740 (wl18xx_clk_table[clk_freq].p >> 16) &
741 PLLSH_WCS_PLL_P_FACTOR_CFG_2_MASK);
743 ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_SWALLOW_EN,
744 PLLSH_WCS_PLL_SWALLOW_EN_VAL2);
751 static int wl18xx_boot_soft_reset(struct wl1271 *wl)
756 ret = wlcore_write32(wl, WL18XX_ENABLE, 0x0);
760 /* disable auto calibration on start*/
761 ret = wlcore_write32(wl, WL18XX_SPARE_A2, 0xffff);
767 static int wl18xx_pre_boot(struct wl1271 *wl)
771 ret = wl18xx_set_clk(wl);
775 /* Continue the ELP wake up sequence */
776 ret = wlcore_write32(wl, WL18XX_WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL);
782 ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
786 /* Disable interrupts */
787 ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
791 ret = wl18xx_boot_soft_reset(wl);
797 static int wl18xx_pre_upload(struct wl1271 *wl)
802 ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
806 /* TODO: check if this is all needed */
807 ret = wlcore_write32(wl, WL18XX_EEPROMLESS_IND, WL18XX_EEPROMLESS_IND);
811 ret = wlcore_read_reg(wl, REG_CHIP_ID_B, &tmp);
815 wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp);
817 ret = wlcore_read32(wl, WL18XX_SCR_PAD2, &tmp);
823 static int wl18xx_set_mac_and_phy(struct wl1271 *wl)
825 struct wl18xx_priv *priv = wl->priv;
826 struct wl18xx_mac_and_phy_params *params;
829 params = kmemdup(&priv->conf.phy, sizeof(*params), GFP_KERNEL);
835 ret = wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]);
839 ret = wlcore_write(wl, WL18XX_PHY_INIT_MEM_ADDR, params,
840 sizeof(*params), false);
847 static int wl18xx_enable_interrupts(struct wl1271 *wl)
849 u32 event_mask, intr_mask;
852 event_mask = WL18XX_ACX_EVENTS_VECTOR;
853 intr_mask = WL18XX_INTR_MASK;
855 ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK, event_mask);
859 wlcore_enable_interrupts(wl);
861 ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK,
862 WL1271_ACX_INTR_ALL & ~intr_mask);
864 goto disable_interrupts;
869 wlcore_disable_interrupts(wl);
875 static int wl18xx_boot(struct wl1271 *wl)
879 ret = wl18xx_pre_boot(wl);
883 ret = wl18xx_pre_upload(wl);
887 ret = wlcore_boot_upload_firmware(wl);
891 ret = wl18xx_set_mac_and_phy(wl);
895 wl->event_mask = BSS_LOSS_EVENT_ID |
896 SCAN_COMPLETE_EVENT_ID |
897 RSSI_SNR_TRIGGER_0_EVENT_ID |
898 PERIODIC_SCAN_COMPLETE_EVENT_ID |
899 PERIODIC_SCAN_REPORT_EVENT_ID |
900 DUMMY_PACKET_EVENT_ID |
901 PEER_REMOVE_COMPLETE_EVENT_ID |
902 BA_SESSION_RX_CONSTRAINT_EVENT_ID |
903 REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID |
904 INACTIVE_STA_EVENT_ID |
905 MAX_TX_FAILURE_EVENT_ID |
906 CHANNEL_SWITCH_COMPLETE_EVENT_ID |
907 DFS_CHANNELS_CONFIG_COMPLETE_EVENT;
909 ret = wlcore_boot_run_firmware(wl);
913 ret = wl18xx_enable_interrupts(wl);
919 static int wl18xx_trigger_cmd(struct wl1271 *wl, int cmd_box_addr,
920 void *buf, size_t len)
922 struct wl18xx_priv *priv = wl->priv;
924 memcpy(priv->cmd_buf, buf, len);
925 memset(priv->cmd_buf + len, 0, WL18XX_CMD_MAX_SIZE - len);
927 return wlcore_write(wl, cmd_box_addr, priv->cmd_buf,
928 WL18XX_CMD_MAX_SIZE, false);
931 static int wl18xx_ack_event(struct wl1271 *wl)
933 return wlcore_write_reg(wl, REG_INTERRUPT_TRIG,
934 WL18XX_INTR_TRIG_EVENT_ACK);
937 static u32 wl18xx_calc_tx_blocks(struct wl1271 *wl, u32 len, u32 spare_blks)
939 u32 blk_size = WL18XX_TX_HW_BLOCK_SIZE;
940 return (len + blk_size - 1) / blk_size + spare_blks;
944 wl18xx_set_tx_desc_blocks(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc,
945 u32 blks, u32 spare_blks)
947 desc->wl18xx_mem.total_mem_blocks = blks;
951 wl18xx_set_tx_desc_data_len(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc,
954 desc->length = cpu_to_le16(skb->len);
956 /* if only the last frame is to be padded, we unset this bit on Tx */
957 if (wl->quirks & WLCORE_QUIRK_TX_PAD_LAST_FRAME)
958 desc->wl18xx_mem.ctrl = WL18XX_TX_CTRL_NOT_PADDED;
960 desc->wl18xx_mem.ctrl = 0;
962 wl1271_debug(DEBUG_TX, "tx_fill_hdr: hlid: %d "
963 "len: %d life: %d mem: %d", desc->hlid,
964 le16_to_cpu(desc->length),
965 le16_to_cpu(desc->life_time),
966 desc->wl18xx_mem.total_mem_blocks);
969 static enum wl_rx_buf_align
970 wl18xx_get_rx_buf_align(struct wl1271 *wl, u32 rx_desc)
972 if (rx_desc & RX_BUF_PADDED_PAYLOAD)
973 return WLCORE_RX_BUF_PADDED;
975 return WLCORE_RX_BUF_ALIGNED;
978 static u32 wl18xx_get_rx_packet_len(struct wl1271 *wl, void *rx_data,
981 struct wl1271_rx_descriptor *desc = rx_data;
984 if (data_len < sizeof(*desc))
987 return data_len - sizeof(*desc);
990 static void wl18xx_tx_immediate_completion(struct wl1271 *wl)
992 wl18xx_tx_immediate_complete(wl);
995 static int wl18xx_set_host_cfg_bitmap(struct wl1271 *wl, u32 extra_mem_blk)
998 u32 sdio_align_size = 0;
999 u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE |
1000 HOST_IF_CFG_ADD_RX_ALIGNMENT;
1002 /* Enable Tx SDIO padding */
1003 if (wl->quirks & WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN) {
1004 host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK;
1005 sdio_align_size = WL12XX_BUS_BLOCK_SIZE;
1008 /* Enable Rx SDIO padding */
1009 if (wl->quirks & WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN) {
1010 host_cfg_bitmap |= HOST_IF_CFG_RX_PAD_TO_SDIO_BLK;
1011 sdio_align_size = WL12XX_BUS_BLOCK_SIZE;
1014 ret = wl18xx_acx_host_if_cfg_bitmap(wl, host_cfg_bitmap,
1015 sdio_align_size, extra_mem_blk,
1016 WL18XX_HOST_IF_LEN_SIZE_FIELD);
1023 static int wl18xx_hw_init(struct wl1271 *wl)
1026 struct wl18xx_priv *priv = wl->priv;
1028 /* (re)init private structures. Relevant on recovery as well. */
1029 priv->last_fw_rls_idx = 0;
1030 priv->extra_spare_key_count = 0;
1032 /* set the default amount of spare blocks in the bitmap */
1033 ret = wl18xx_set_host_cfg_bitmap(wl, WL18XX_TX_HW_BLOCK_SPARE);
1037 if (checksum_param) {
1038 ret = wl18xx_acx_set_checksum_state(wl);
1046 static void wl18xx_set_tx_desc_csum(struct wl1271 *wl,
1047 struct wl1271_tx_hw_descr *desc,
1048 struct sk_buff *skb)
1051 struct iphdr *ip_hdr;
1053 if (!checksum_param) {
1054 desc->wl18xx_checksum_data = 0;
1058 if (skb->ip_summed != CHECKSUM_PARTIAL) {
1059 desc->wl18xx_checksum_data = 0;
1063 ip_hdr_offset = skb_network_header(skb) - skb_mac_header(skb);
1064 if (WARN_ON(ip_hdr_offset >= (1<<7))) {
1065 desc->wl18xx_checksum_data = 0;
1069 desc->wl18xx_checksum_data = ip_hdr_offset << 1;
1071 /* FW is interested only in the LSB of the protocol TCP=0 UDP=1 */
1072 ip_hdr = (void *)skb_network_header(skb);
1073 desc->wl18xx_checksum_data |= (ip_hdr->protocol & 0x01);
1076 static void wl18xx_set_rx_csum(struct wl1271 *wl,
1077 struct wl1271_rx_descriptor *desc,
1078 struct sk_buff *skb)
1080 if (desc->status & WL18XX_RX_CHECKSUM_MASK)
1081 skb->ip_summed = CHECKSUM_UNNECESSARY;
1084 static bool wl18xx_is_mimo_supported(struct wl1271 *wl)
1086 struct wl18xx_priv *priv = wl->priv;
1088 /* only support MIMO with multiple antennas, and when SISO
1089 * is not forced through config
1091 return (priv->conf.phy.number_of_assembled_ant2_4 >= 2) &&
1092 (priv->conf.ht.mode != HT_MODE_WIDE) &&
1093 (priv->conf.ht.mode != HT_MODE_SISO20);
1097 * TODO: instead of having these two functions to get the rate mask,
1098 * we should modify the wlvif->rate_set instead
1100 static u32 wl18xx_sta_get_ap_rate_mask(struct wl1271 *wl,
1101 struct wl12xx_vif *wlvif)
1103 u32 hw_rate_set = wlvif->rate_set;
1105 if (wlvif->channel_type == NL80211_CHAN_HT40MINUS ||
1106 wlvif->channel_type == NL80211_CHAN_HT40PLUS) {
1107 wl1271_debug(DEBUG_ACX, "using wide channel rate mask");
1108 hw_rate_set |= CONF_TX_RATE_USE_WIDE_CHAN;
1110 /* we don't support MIMO in wide-channel mode */
1111 hw_rate_set &= ~CONF_TX_MIMO_RATES;
1112 } else if (wl18xx_is_mimo_supported(wl)) {
1113 wl1271_debug(DEBUG_ACX, "using MIMO channel rate mask");
1114 hw_rate_set |= CONF_TX_MIMO_RATES;
1120 static u32 wl18xx_ap_get_mimo_wide_rate_mask(struct wl1271 *wl,
1121 struct wl12xx_vif *wlvif)
1123 if (wlvif->channel_type == NL80211_CHAN_HT40MINUS ||
1124 wlvif->channel_type == NL80211_CHAN_HT40PLUS) {
1125 wl1271_debug(DEBUG_ACX, "using wide channel rate mask");
1127 /* sanity check - we don't support this */
1128 if (WARN_ON(wlvif->band != IEEE80211_BAND_5GHZ))
1131 return CONF_TX_RATE_USE_WIDE_CHAN;
1132 } else if (wl18xx_is_mimo_supported(wl) &&
1133 wlvif->band == IEEE80211_BAND_2GHZ) {
1134 wl1271_debug(DEBUG_ACX, "using MIMO rate mask");
1136 * we don't care about HT channel here - if a peer doesn't
1137 * support MIMO, we won't enable it in its rates
1139 return CONF_TX_MIMO_RATES;
1145 static int wl18xx_get_pg_ver(struct wl1271 *wl, s8 *ver)
1150 ret = wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]);
1154 ret = wlcore_read32(wl, WL18XX_REG_FUSE_DATA_1_3, &fuse);
1159 *ver = (fuse & WL18XX_PG_VER_MASK) >> WL18XX_PG_VER_OFFSET;
1161 ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
1167 #define WL18XX_CONF_FILE_NAME "ti-connectivity/wl18xx-conf.bin"
1168 static int wl18xx_conf_init(struct wl1271 *wl, struct device *dev)
1170 struct wl18xx_priv *priv = wl->priv;
1171 struct wlcore_conf_file *conf_file;
1172 const struct firmware *fw;
1175 ret = request_firmware(&fw, WL18XX_CONF_FILE_NAME, dev);
1177 wl1271_error("could not get configuration binary %s: %d",
1178 WL18XX_CONF_FILE_NAME, ret);
1182 if (fw->size != WL18XX_CONF_SIZE) {
1183 wl1271_error("configuration binary file size is wrong, expected %zu got %zu",
1184 WL18XX_CONF_SIZE, fw->size);
1189 conf_file = (struct wlcore_conf_file *) fw->data;
1191 if (conf_file->header.magic != cpu_to_le32(WL18XX_CONF_MAGIC)) {
1192 wl1271_error("configuration binary file magic number mismatch, "
1193 "expected 0x%0x got 0x%0x", WL18XX_CONF_MAGIC,
1194 conf_file->header.magic);
1199 if (conf_file->header.version != cpu_to_le32(WL18XX_CONF_VERSION)) {
1200 wl1271_error("configuration binary file version not supported, "
1201 "expected 0x%08x got 0x%08x",
1202 WL18XX_CONF_VERSION, conf_file->header.version);
1207 memcpy(&wl->conf, &conf_file->core, sizeof(wl18xx_conf));
1208 memcpy(&priv->conf, &conf_file->priv, sizeof(priv->conf));
1213 wl1271_warning("falling back to default config");
1215 /* apply driver default configuration */
1216 memcpy(&wl->conf, &wl18xx_conf, sizeof(wl18xx_conf));
1217 /* apply default private configuration */
1218 memcpy(&priv->conf, &wl18xx_default_priv_conf, sizeof(priv->conf));
1220 /* For now we just fallback */
1224 release_firmware(fw);
1228 static int wl18xx_plt_init(struct wl1271 *wl)
1232 /* calibrator based auto/fem detect not supported for 18xx */
1233 if (wl->plt_mode == PLT_FEM_DETECT) {
1234 wl1271_error("wl18xx_plt_init: PLT FEM_DETECT not supported");
1238 ret = wlcore_write32(wl, WL18XX_SCR_PAD8, WL18XX_SCR_PAD8_PLT);
1242 return wl->ops->boot(wl);
1245 static int wl18xx_get_mac(struct wl1271 *wl)
1250 ret = wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]);
1254 ret = wlcore_read32(wl, WL18XX_REG_FUSE_BD_ADDR_1, &mac1);
1258 ret = wlcore_read32(wl, WL18XX_REG_FUSE_BD_ADDR_2, &mac2);
1262 /* these are the two parts of the BD_ADDR */
1263 wl->fuse_oui_addr = ((mac2 & 0xffff) << 8) +
1264 ((mac1 & 0xff000000) >> 24);
1265 wl->fuse_nic_addr = (mac1 & 0xffffff);
1267 ret = wlcore_set_partition(wl, &wl->ptable[PART_DOWN]);
1273 static int wl18xx_handle_static_data(struct wl1271 *wl,
1274 struct wl1271_static_data *static_data)
1276 struct wl18xx_static_data_priv *static_data_priv =
1277 (struct wl18xx_static_data_priv *) static_data->priv;
1279 strncpy(wl->chip.phy_fw_ver_str, static_data_priv->phy_version,
1280 sizeof(wl->chip.phy_fw_ver_str));
1282 /* make sure the string is NULL-terminated */
1283 wl->chip.phy_fw_ver_str[sizeof(wl->chip.phy_fw_ver_str) - 1] = '\0';
1285 wl1271_info("PHY firmware version: %s", static_data_priv->phy_version);
1290 static int wl18xx_get_spare_blocks(struct wl1271 *wl, bool is_gem)
1292 struct wl18xx_priv *priv = wl->priv;
1294 /* If we have keys requiring extra spare, indulge them */
1295 if (priv->extra_spare_key_count)
1296 return WL18XX_TX_HW_EXTRA_BLOCK_SPARE;
1298 return WL18XX_TX_HW_BLOCK_SPARE;
1301 static int wl18xx_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
1302 struct ieee80211_vif *vif,
1303 struct ieee80211_sta *sta,
1304 struct ieee80211_key_conf *key_conf)
1306 struct wl18xx_priv *priv = wl->priv;
1307 bool change_spare = false, special_enc;
1310 wl1271_debug(DEBUG_CRYPT, "extra spare keys before: %d",
1311 priv->extra_spare_key_count);
1313 special_enc = key_conf->cipher == WL1271_CIPHER_SUITE_GEM ||
1314 key_conf->cipher == WLAN_CIPHER_SUITE_TKIP;
1316 ret = wlcore_set_key(wl, cmd, vif, sta, key_conf);
1321 * when adding the first or removing the last GEM/TKIP key,
1322 * we have to adjust the number of spare blocks.
1325 if (cmd == SET_KEY) {
1327 change_spare = (priv->extra_spare_key_count == 0);
1328 priv->extra_spare_key_count++;
1329 } else if (cmd == DISABLE_KEY) {
1331 change_spare = (priv->extra_spare_key_count == 1);
1332 priv->extra_spare_key_count--;
1336 wl1271_debug(DEBUG_CRYPT, "extra spare keys after: %d",
1337 priv->extra_spare_key_count);
1342 /* key is now set, change the spare blocks */
1343 if (priv->extra_spare_key_count)
1344 ret = wl18xx_set_host_cfg_bitmap(wl,
1345 WL18XX_TX_HW_EXTRA_BLOCK_SPARE);
1347 ret = wl18xx_set_host_cfg_bitmap(wl,
1348 WL18XX_TX_HW_BLOCK_SPARE);
1354 static u32 wl18xx_pre_pkt_send(struct wl1271 *wl,
1355 u32 buf_offset, u32 last_len)
1357 if (wl->quirks & WLCORE_QUIRK_TX_PAD_LAST_FRAME) {
1358 struct wl1271_tx_hw_descr *last_desc;
1360 /* get the last TX HW descriptor written to the aggr buf */
1361 last_desc = (struct wl1271_tx_hw_descr *)(wl->aggr_buf +
1362 buf_offset - last_len);
1364 /* the last frame is padded up to an SDIO block */
1365 last_desc->wl18xx_mem.ctrl &= ~WL18XX_TX_CTRL_NOT_PADDED;
1366 return ALIGN(buf_offset, WL12XX_BUS_BLOCK_SIZE);
1369 /* no modifications */
1373 static void wl18xx_sta_rc_update(struct wl1271 *wl,
1374 struct wl12xx_vif *wlvif,
1375 struct ieee80211_sta *sta,
1378 bool wide = sta->bandwidth >= IEEE80211_STA_RX_BW_40;
1380 wl1271_debug(DEBUG_MAC80211, "mac80211 sta_rc_update wide %d", wide);
1382 if (!(changed & IEEE80211_RC_BW_CHANGED))
1385 mutex_lock(&wl->mutex);
1388 if (WARN_ON(wlvif->bss_type != BSS_TYPE_STA_BSS))
1391 /* ignore the change before association */
1392 if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
1396 * If we started out as wide, we can change the operation mode. If we
1397 * thought this was a 20mhz AP, we have to reconnect
1399 if (wlvif->sta.role_chan_type == NL80211_CHAN_HT40MINUS ||
1400 wlvif->sta.role_chan_type == NL80211_CHAN_HT40PLUS)
1401 wl18xx_acx_peer_ht_operation_mode(wl, wlvif->sta.hlid, wide);
1403 ieee80211_connection_loss(wl12xx_wlvif_to_vif(wlvif));
1406 mutex_unlock(&wl->mutex);
1409 static int wl18xx_set_peer_cap(struct wl1271 *wl,
1410 struct ieee80211_sta_ht_cap *ht_cap,
1411 bool allow_ht_operation,
1412 u32 rate_set, u8 hlid)
1414 return wl18xx_acx_set_peer_cap(wl, ht_cap, allow_ht_operation,
1418 static bool wl18xx_lnk_high_prio(struct wl1271 *wl, u8 hlid,
1419 struct wl1271_link *lnk)
1422 struct wl18xx_fw_status_priv *status_priv =
1423 (struct wl18xx_fw_status_priv *)wl->fw_status_2->priv;
1424 u32 suspend_bitmap = le32_to_cpu(status_priv->link_suspend_bitmap);
1426 /* suspended links are never high priority */
1427 if (test_bit(hlid, (unsigned long *)&suspend_bitmap))
1430 /* the priority thresholds are taken from FW */
1431 if (test_bit(hlid, (unsigned long *)&wl->fw_fast_lnk_map) &&
1432 !test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map))
1433 thold = status_priv->tx_fast_link_prio_threshold;
1435 thold = status_priv->tx_slow_link_prio_threshold;
1437 return lnk->allocated_pkts < thold;
1440 static bool wl18xx_lnk_low_prio(struct wl1271 *wl, u8 hlid,
1441 struct wl1271_link *lnk)
1444 struct wl18xx_fw_status_priv *status_priv =
1445 (struct wl18xx_fw_status_priv *)wl->fw_status_2->priv;
1446 u32 suspend_bitmap = le32_to_cpu(status_priv->link_suspend_bitmap);
1448 if (test_bit(hlid, (unsigned long *)&suspend_bitmap))
1449 thold = status_priv->tx_suspend_threshold;
1450 else if (test_bit(hlid, (unsigned long *)&wl->fw_fast_lnk_map) &&
1451 !test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map))
1452 thold = status_priv->tx_fast_stop_threshold;
1454 thold = status_priv->tx_slow_stop_threshold;
1456 return lnk->allocated_pkts < thold;
1459 static int wl18xx_setup(struct wl1271 *wl);
1461 static struct wlcore_ops wl18xx_ops = {
1462 .setup = wl18xx_setup,
1463 .identify_chip = wl18xx_identify_chip,
1464 .boot = wl18xx_boot,
1465 .plt_init = wl18xx_plt_init,
1466 .trigger_cmd = wl18xx_trigger_cmd,
1467 .ack_event = wl18xx_ack_event,
1468 .wait_for_event = wl18xx_wait_for_event,
1469 .process_mailbox_events = wl18xx_process_mailbox_events,
1470 .calc_tx_blocks = wl18xx_calc_tx_blocks,
1471 .set_tx_desc_blocks = wl18xx_set_tx_desc_blocks,
1472 .set_tx_desc_data_len = wl18xx_set_tx_desc_data_len,
1473 .get_rx_buf_align = wl18xx_get_rx_buf_align,
1474 .get_rx_packet_len = wl18xx_get_rx_packet_len,
1475 .tx_immediate_compl = wl18xx_tx_immediate_completion,
1476 .tx_delayed_compl = NULL,
1477 .hw_init = wl18xx_hw_init,
1478 .set_tx_desc_csum = wl18xx_set_tx_desc_csum,
1479 .get_pg_ver = wl18xx_get_pg_ver,
1480 .set_rx_csum = wl18xx_set_rx_csum,
1481 .sta_get_ap_rate_mask = wl18xx_sta_get_ap_rate_mask,
1482 .ap_get_mimo_wide_rate_mask = wl18xx_ap_get_mimo_wide_rate_mask,
1483 .get_mac = wl18xx_get_mac,
1484 .debugfs_init = wl18xx_debugfs_add_files,
1485 .scan_start = wl18xx_scan_start,
1486 .scan_stop = wl18xx_scan_stop,
1487 .sched_scan_start = wl18xx_sched_scan_start,
1488 .sched_scan_stop = wl18xx_scan_sched_scan_stop,
1489 .handle_static_data = wl18xx_handle_static_data,
1490 .get_spare_blocks = wl18xx_get_spare_blocks,
1491 .set_key = wl18xx_set_key,
1492 .channel_switch = wl18xx_cmd_channel_switch,
1493 .pre_pkt_send = wl18xx_pre_pkt_send,
1494 .sta_rc_update = wl18xx_sta_rc_update,
1495 .set_peer_cap = wl18xx_set_peer_cap,
1496 .lnk_high_prio = wl18xx_lnk_high_prio,
1497 .lnk_low_prio = wl18xx_lnk_low_prio,
1500 /* HT cap appropriate for wide channels in 2Ghz */
1501 static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_2ghz = {
1502 .cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 |
1503 IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_DSSSCCK40 |
1504 IEEE80211_HT_CAP_GRN_FLD,
1505 .ht_supported = true,
1506 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
1507 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
1509 .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
1510 .rx_highest = cpu_to_le16(150),
1511 .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
1515 /* HT cap appropriate for wide channels in 5Ghz */
1516 static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_5ghz = {
1517 .cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 |
1518 IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
1519 IEEE80211_HT_CAP_GRN_FLD,
1520 .ht_supported = true,
1521 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
1522 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
1524 .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
1525 .rx_highest = cpu_to_le16(150),
1526 .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
1530 /* HT cap appropriate for SISO 20 */
1531 static struct ieee80211_sta_ht_cap wl18xx_siso20_ht_cap = {
1532 .cap = IEEE80211_HT_CAP_SGI_20 |
1533 IEEE80211_HT_CAP_GRN_FLD,
1534 .ht_supported = true,
1535 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
1536 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
1538 .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
1539 .rx_highest = cpu_to_le16(72),
1540 .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
1544 /* HT cap appropriate for MIMO rates in 20mhz channel */
1545 static struct ieee80211_sta_ht_cap wl18xx_mimo_ht_cap_2ghz = {
1546 .cap = IEEE80211_HT_CAP_SGI_20 |
1547 IEEE80211_HT_CAP_GRN_FLD,
1548 .ht_supported = true,
1549 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
1550 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
1552 .rx_mask = { 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, },
1553 .rx_highest = cpu_to_le16(144),
1554 .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
1558 static int wl18xx_setup(struct wl1271 *wl)
1560 struct wl18xx_priv *priv = wl->priv;
1563 wl->rtable = wl18xx_rtable;
1564 wl->num_tx_desc = WL18XX_NUM_TX_DESCRIPTORS;
1565 wl->num_rx_desc = WL18XX_NUM_RX_DESCRIPTORS;
1566 wl->num_channels = 2;
1567 wl->num_mac_addr = WL18XX_NUM_MAC_ADDRESSES;
1568 wl->band_rate_to_idx = wl18xx_band_rate_to_idx;
1569 wl->hw_tx_rate_tbl_size = WL18XX_CONF_HW_RXTX_RATE_MAX;
1570 wl->hw_min_ht_rate = WL18XX_CONF_HW_RXTX_RATE_MCS0;
1571 wl->fw_status_priv_len = sizeof(struct wl18xx_fw_status_priv);
1572 wl->stats.fw_stats_len = sizeof(struct wl18xx_acx_statistics);
1573 wl->static_data_priv_len = sizeof(struct wl18xx_static_data_priv);
1575 if (num_rx_desc_param != -1)
1576 wl->num_rx_desc = num_rx_desc_param;
1578 ret = wl18xx_conf_init(wl, wl->dev);
1582 /* If the module param is set, update it in conf */
1583 if (board_type_param) {
1584 if (!strcmp(board_type_param, "fpga")) {
1585 priv->conf.phy.board_type = BOARD_TYPE_FPGA_18XX;
1586 } else if (!strcmp(board_type_param, "hdk")) {
1587 priv->conf.phy.board_type = BOARD_TYPE_HDK_18XX;
1588 } else if (!strcmp(board_type_param, "dvp")) {
1589 priv->conf.phy.board_type = BOARD_TYPE_DVP_18XX;
1590 } else if (!strcmp(board_type_param, "evb")) {
1591 priv->conf.phy.board_type = BOARD_TYPE_EVB_18XX;
1592 } else if (!strcmp(board_type_param, "com8")) {
1593 priv->conf.phy.board_type = BOARD_TYPE_COM8_18XX;
1595 wl1271_error("invalid board type '%s'",
1601 if (priv->conf.phy.board_type >= NUM_BOARD_TYPES) {
1602 wl1271_error("invalid board type '%d'",
1603 priv->conf.phy.board_type);
1607 if (low_band_component_param != -1)
1608 priv->conf.phy.low_band_component = low_band_component_param;
1609 if (low_band_component_type_param != -1)
1610 priv->conf.phy.low_band_component_type =
1611 low_band_component_type_param;
1612 if (high_band_component_param != -1)
1613 priv->conf.phy.high_band_component = high_band_component_param;
1614 if (high_band_component_type_param != -1)
1615 priv->conf.phy.high_band_component_type =
1616 high_band_component_type_param;
1617 if (pwr_limit_reference_11_abg_param != -1)
1618 priv->conf.phy.pwr_limit_reference_11_abg =
1619 pwr_limit_reference_11_abg_param;
1620 if (n_antennas_2_param != -1)
1621 priv->conf.phy.number_of_assembled_ant2_4 = n_antennas_2_param;
1622 if (n_antennas_5_param != -1)
1623 priv->conf.phy.number_of_assembled_ant5 = n_antennas_5_param;
1624 if (dc2dc_param != -1)
1625 priv->conf.phy.external_pa_dc2dc = dc2dc_param;
1627 if (ht_mode_param) {
1628 if (!strcmp(ht_mode_param, "default"))
1629 priv->conf.ht.mode = HT_MODE_DEFAULT;
1630 else if (!strcmp(ht_mode_param, "wide"))
1631 priv->conf.ht.mode = HT_MODE_WIDE;
1632 else if (!strcmp(ht_mode_param, "siso20"))
1633 priv->conf.ht.mode = HT_MODE_SISO20;
1635 wl1271_error("invalid ht_mode '%s'", ht_mode_param);
1640 if (priv->conf.ht.mode == HT_MODE_DEFAULT) {
1642 * Only support mimo with multiple antennas. Fall back to
1645 if (wl18xx_is_mimo_supported(wl))
1646 wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ,
1647 &wl18xx_mimo_ht_cap_2ghz);
1649 wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ,
1650 &wl18xx_siso40_ht_cap_2ghz);
1652 /* 5Ghz is always wide */
1653 wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ,
1654 &wl18xx_siso40_ht_cap_5ghz);
1655 } else if (priv->conf.ht.mode == HT_MODE_WIDE) {
1656 wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ,
1657 &wl18xx_siso40_ht_cap_2ghz);
1658 wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ,
1659 &wl18xx_siso40_ht_cap_5ghz);
1660 } else if (priv->conf.ht.mode == HT_MODE_SISO20) {
1661 wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ,
1662 &wl18xx_siso20_ht_cap);
1663 wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ,
1664 &wl18xx_siso20_ht_cap);
1667 if (!checksum_param) {
1668 wl18xx_ops.set_rx_csum = NULL;
1669 wl18xx_ops.init_vif = NULL;
1672 /* Enable 11a Band only if we have 5G antennas */
1673 wl->enable_11a = (priv->conf.phy.number_of_assembled_ant5 != 0);
1678 static int wl18xx_probe(struct platform_device *pdev)
1681 struct ieee80211_hw *hw;
1684 hw = wlcore_alloc_hw(sizeof(struct wl18xx_priv),
1685 WL18XX_AGGR_BUFFER_SIZE,
1686 sizeof(struct wl18xx_event_mailbox));
1688 wl1271_error("can't allocate hw");
1694 wl->ops = &wl18xx_ops;
1695 wl->ptable = wl18xx_ptable;
1696 ret = wlcore_probe(wl, pdev);
1708 static const struct platform_device_id wl18xx_id_table[] = {
1710 { } /* Terminating Entry */
1712 MODULE_DEVICE_TABLE(platform, wl18xx_id_table);
1714 static struct platform_driver wl18xx_driver = {
1715 .probe = wl18xx_probe,
1716 .remove = wlcore_remove,
1717 .id_table = wl18xx_id_table,
1719 .name = "wl18xx_driver",
1720 .owner = THIS_MODULE,
1724 module_platform_driver(wl18xx_driver);
1725 module_param_named(ht_mode, ht_mode_param, charp, S_IRUSR);
1726 MODULE_PARM_DESC(ht_mode, "Force HT mode: wide or siso20");
1728 module_param_named(board_type, board_type_param, charp, S_IRUSR);
1729 MODULE_PARM_DESC(board_type, "Board type: fpga, hdk (default), evb, com8 or "
1732 module_param_named(checksum, checksum_param, bool, S_IRUSR);
1733 MODULE_PARM_DESC(checksum, "Enable TCP checksum: boolean (defaults to false)");
1735 module_param_named(dc2dc, dc2dc_param, int, S_IRUSR);
1736 MODULE_PARM_DESC(dc2dc, "External DC2DC: u8 (defaults to 0)");
1738 module_param_named(n_antennas_2, n_antennas_2_param, int, S_IRUSR);
1739 MODULE_PARM_DESC(n_antennas_2,
1740 "Number of installed 2.4GHz antennas: 1 (default) or 2");
1742 module_param_named(n_antennas_5, n_antennas_5_param, int, S_IRUSR);
1743 MODULE_PARM_DESC(n_antennas_5,
1744 "Number of installed 5GHz antennas: 1 (default) or 2");
1746 module_param_named(low_band_component, low_band_component_param, int,
1748 MODULE_PARM_DESC(low_band_component, "Low band component: u8 "
1749 "(default is 0x01)");
1751 module_param_named(low_band_component_type, low_band_component_type_param,
1753 MODULE_PARM_DESC(low_band_component_type, "Low band component type: u8 "
1754 "(default is 0x05 or 0x06 depending on the board_type)");
1756 module_param_named(high_band_component, high_band_component_param, int,
1758 MODULE_PARM_DESC(high_band_component, "High band component: u8, "
1759 "(default is 0x01)");
1761 module_param_named(high_band_component_type, high_band_component_type_param,
1763 MODULE_PARM_DESC(high_band_component_type, "High band component type: u8 "
1764 "(default is 0x09)");
1766 module_param_named(pwr_limit_reference_11_abg,
1767 pwr_limit_reference_11_abg_param, int, S_IRUSR);
1768 MODULE_PARM_DESC(pwr_limit_reference_11_abg, "Power limit reference: u8 "
1769 "(default is 0xc8)");
1771 module_param_named(num_rx_desc,
1772 num_rx_desc_param, int, S_IRUSR);
1773 MODULE_PARM_DESC(num_rx_desc_param,
1774 "Number of Rx descriptors: u8 (default is 32)");
1776 MODULE_LICENSE("GPL v2");
1777 MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
1778 MODULE_FIRMWARE(WL18XX_FW_NAME);