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/mod_devicetable.h>
24 #include <linux/platform_device.h>
26 #include <linux/firmware.h>
27 #include <linux/etherdevice.h>
28 #include <linux/irq.h>
30 #include "../wlcore/wlcore.h"
31 #include "../wlcore/debug.h"
32 #include "../wlcore/io.h"
33 #include "../wlcore/acx.h"
34 #include "../wlcore/tx.h"
35 #include "../wlcore/rx.h"
36 #include "../wlcore/boot.h"
49 #define WL18XX_RX_CHECKSUM_MASK 0x40
51 static char *ht_mode_param = NULL;
52 static char *board_type_param = NULL;
53 static bool checksum_param = false;
54 static int num_rx_desc_param = -1;
57 static int dc2dc_param = -1;
58 static int n_antennas_2_param = -1;
59 static int n_antennas_5_param = -1;
60 static int low_band_component_param = -1;
61 static int low_band_component_type_param = -1;
62 static int high_band_component_param = -1;
63 static int high_band_component_type_param = -1;
64 static int pwr_limit_reference_11_abg_param = -1;
66 static const u8 wl18xx_rate_to_idx_2ghz[] = {
67 /* MCS rates are used only with 11n */
68 15, /* WL18XX_CONF_HW_RXTX_RATE_MCS15 */
69 14, /* WL18XX_CONF_HW_RXTX_RATE_MCS14 */
70 13, /* WL18XX_CONF_HW_RXTX_RATE_MCS13 */
71 12, /* WL18XX_CONF_HW_RXTX_RATE_MCS12 */
72 11, /* WL18XX_CONF_HW_RXTX_RATE_MCS11 */
73 10, /* WL18XX_CONF_HW_RXTX_RATE_MCS10 */
74 9, /* WL18XX_CONF_HW_RXTX_RATE_MCS9 */
75 8, /* WL18XX_CONF_HW_RXTX_RATE_MCS8 */
76 7, /* WL18XX_CONF_HW_RXTX_RATE_MCS7 */
77 6, /* WL18XX_CONF_HW_RXTX_RATE_MCS6 */
78 5, /* WL18XX_CONF_HW_RXTX_RATE_MCS5 */
79 4, /* WL18XX_CONF_HW_RXTX_RATE_MCS4 */
80 3, /* WL18XX_CONF_HW_RXTX_RATE_MCS3 */
81 2, /* WL18XX_CONF_HW_RXTX_RATE_MCS2 */
82 1, /* WL18XX_CONF_HW_RXTX_RATE_MCS1 */
83 0, /* WL18XX_CONF_HW_RXTX_RATE_MCS0 */
85 11, /* WL18XX_CONF_HW_RXTX_RATE_54 */
86 10, /* WL18XX_CONF_HW_RXTX_RATE_48 */
87 9, /* WL18XX_CONF_HW_RXTX_RATE_36 */
88 8, /* WL18XX_CONF_HW_RXTX_RATE_24 */
90 /* TI-specific rate */
91 CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_22 */
93 7, /* WL18XX_CONF_HW_RXTX_RATE_18 */
94 6, /* WL18XX_CONF_HW_RXTX_RATE_12 */
95 3, /* WL18XX_CONF_HW_RXTX_RATE_11 */
96 5, /* WL18XX_CONF_HW_RXTX_RATE_9 */
97 4, /* WL18XX_CONF_HW_RXTX_RATE_6 */
98 2, /* WL18XX_CONF_HW_RXTX_RATE_5_5 */
99 1, /* WL18XX_CONF_HW_RXTX_RATE_2 */
100 0 /* WL18XX_CONF_HW_RXTX_RATE_1 */
103 static const u8 wl18xx_rate_to_idx_5ghz[] = {
104 /* MCS rates are used only with 11n */
105 15, /* WL18XX_CONF_HW_RXTX_RATE_MCS15 */
106 14, /* WL18XX_CONF_HW_RXTX_RATE_MCS14 */
107 13, /* WL18XX_CONF_HW_RXTX_RATE_MCS13 */
108 12, /* WL18XX_CONF_HW_RXTX_RATE_MCS12 */
109 11, /* WL18XX_CONF_HW_RXTX_RATE_MCS11 */
110 10, /* WL18XX_CONF_HW_RXTX_RATE_MCS10 */
111 9, /* WL18XX_CONF_HW_RXTX_RATE_MCS9 */
112 8, /* WL18XX_CONF_HW_RXTX_RATE_MCS8 */
113 7, /* WL18XX_CONF_HW_RXTX_RATE_MCS7 */
114 6, /* WL18XX_CONF_HW_RXTX_RATE_MCS6 */
115 5, /* WL18XX_CONF_HW_RXTX_RATE_MCS5 */
116 4, /* WL18XX_CONF_HW_RXTX_RATE_MCS4 */
117 3, /* WL18XX_CONF_HW_RXTX_RATE_MCS3 */
118 2, /* WL18XX_CONF_HW_RXTX_RATE_MCS2 */
119 1, /* WL18XX_CONF_HW_RXTX_RATE_MCS1 */
120 0, /* WL18XX_CONF_HW_RXTX_RATE_MCS0 */
122 7, /* WL18XX_CONF_HW_RXTX_RATE_54 */
123 6, /* WL18XX_CONF_HW_RXTX_RATE_48 */
124 5, /* WL18XX_CONF_HW_RXTX_RATE_36 */
125 4, /* WL18XX_CONF_HW_RXTX_RATE_24 */
127 /* TI-specific rate */
128 CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_22 */
130 3, /* WL18XX_CONF_HW_RXTX_RATE_18 */
131 2, /* WL18XX_CONF_HW_RXTX_RATE_12 */
132 CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_11 */
133 1, /* WL18XX_CONF_HW_RXTX_RATE_9 */
134 0, /* WL18XX_CONF_HW_RXTX_RATE_6 */
135 CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_5_5 */
136 CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_2 */
137 CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_1 */
140 static const u8 *wl18xx_band_rate_to_idx[] = {
141 [NL80211_BAND_2GHZ] = wl18xx_rate_to_idx_2ghz,
142 [NL80211_BAND_5GHZ] = wl18xx_rate_to_idx_5ghz
145 enum wl18xx_hw_rates {
146 WL18XX_CONF_HW_RXTX_RATE_MCS15 = 0,
147 WL18XX_CONF_HW_RXTX_RATE_MCS14,
148 WL18XX_CONF_HW_RXTX_RATE_MCS13,
149 WL18XX_CONF_HW_RXTX_RATE_MCS12,
150 WL18XX_CONF_HW_RXTX_RATE_MCS11,
151 WL18XX_CONF_HW_RXTX_RATE_MCS10,
152 WL18XX_CONF_HW_RXTX_RATE_MCS9,
153 WL18XX_CONF_HW_RXTX_RATE_MCS8,
154 WL18XX_CONF_HW_RXTX_RATE_MCS7,
155 WL18XX_CONF_HW_RXTX_RATE_MCS6,
156 WL18XX_CONF_HW_RXTX_RATE_MCS5,
157 WL18XX_CONF_HW_RXTX_RATE_MCS4,
158 WL18XX_CONF_HW_RXTX_RATE_MCS3,
159 WL18XX_CONF_HW_RXTX_RATE_MCS2,
160 WL18XX_CONF_HW_RXTX_RATE_MCS1,
161 WL18XX_CONF_HW_RXTX_RATE_MCS0,
162 WL18XX_CONF_HW_RXTX_RATE_54,
163 WL18XX_CONF_HW_RXTX_RATE_48,
164 WL18XX_CONF_HW_RXTX_RATE_36,
165 WL18XX_CONF_HW_RXTX_RATE_24,
166 WL18XX_CONF_HW_RXTX_RATE_22,
167 WL18XX_CONF_HW_RXTX_RATE_18,
168 WL18XX_CONF_HW_RXTX_RATE_12,
169 WL18XX_CONF_HW_RXTX_RATE_11,
170 WL18XX_CONF_HW_RXTX_RATE_9,
171 WL18XX_CONF_HW_RXTX_RATE_6,
172 WL18XX_CONF_HW_RXTX_RATE_5_5,
173 WL18XX_CONF_HW_RXTX_RATE_2,
174 WL18XX_CONF_HW_RXTX_RATE_1,
175 WL18XX_CONF_HW_RXTX_RATE_MAX,
178 static struct wlcore_conf wl18xx_conf = {
181 [WL18XX_CONF_SG_PARAM_0] = 0,
182 /* Configuration Parameters */
183 [WL18XX_CONF_SG_ANTENNA_CONFIGURATION] = 0,
184 [WL18XX_CONF_SG_ZIGBEE_COEX] = 0,
185 [WL18XX_CONF_SG_TIME_SYNC] = 0,
186 [WL18XX_CONF_SG_PARAM_4] = 0,
187 [WL18XX_CONF_SG_PARAM_5] = 0,
188 [WL18XX_CONF_SG_PARAM_6] = 0,
189 [WL18XX_CONF_SG_PARAM_7] = 0,
190 [WL18XX_CONF_SG_PARAM_8] = 0,
191 [WL18XX_CONF_SG_PARAM_9] = 0,
192 [WL18XX_CONF_SG_PARAM_10] = 0,
193 [WL18XX_CONF_SG_PARAM_11] = 0,
194 [WL18XX_CONF_SG_PARAM_12] = 0,
195 [WL18XX_CONF_SG_PARAM_13] = 0,
196 [WL18XX_CONF_SG_PARAM_14] = 0,
197 [WL18XX_CONF_SG_PARAM_15] = 0,
198 [WL18XX_CONF_SG_PARAM_16] = 0,
199 [WL18XX_CONF_SG_PARAM_17] = 0,
200 [WL18XX_CONF_SG_PARAM_18] = 0,
201 [WL18XX_CONF_SG_PARAM_19] = 0,
202 [WL18XX_CONF_SG_PARAM_20] = 0,
203 [WL18XX_CONF_SG_PARAM_21] = 0,
204 [WL18XX_CONF_SG_PARAM_22] = 0,
205 [WL18XX_CONF_SG_PARAM_23] = 0,
206 [WL18XX_CONF_SG_PARAM_24] = 0,
207 [WL18XX_CONF_SG_PARAM_25] = 0,
208 /* Active Scan Parameters */
209 [WL18XX_CONF_SG_AUTO_SCAN_PROBE_REQ] = 170,
210 [WL18XX_CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3] = 50,
211 [WL18XX_CONF_SG_PARAM_28] = 0,
212 /* Passive Scan Parameters */
213 [WL18XX_CONF_SG_PARAM_29] = 0,
214 [WL18XX_CONF_SG_PARAM_30] = 0,
215 [WL18XX_CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3] = 200,
216 /* Passive Scan in Dual Antenna Parameters */
217 [WL18XX_CONF_SG_CONSECUTIVE_HV3_IN_PASSIVE_SCAN] = 0,
218 [WL18XX_CONF_SG_BEACON_HV3_COLL_TH_IN_PASSIVE_SCAN] = 0,
219 [WL18XX_CONF_SG_TX_RX_PROTECT_BW_IN_PASSIVE_SCAN] = 0,
220 /* General Parameters */
221 [WL18XX_CONF_SG_STA_FORCE_PS_IN_BT_SCO] = 1,
222 [WL18XX_CONF_SG_PARAM_36] = 0,
223 [WL18XX_CONF_SG_BEACON_MISS_PERCENT] = 60,
224 [WL18XX_CONF_SG_PARAM_38] = 0,
225 [WL18XX_CONF_SG_RXT] = 1200,
226 [WL18XX_CONF_SG_UNUSED] = 0,
227 [WL18XX_CONF_SG_ADAPTIVE_RXT_TXT] = 1,
228 [WL18XX_CONF_SG_GENERAL_USAGE_BIT_MAP] = 3,
229 [WL18XX_CONF_SG_HV3_MAX_SERVED] = 6,
230 [WL18XX_CONF_SG_PARAM_44] = 0,
231 [WL18XX_CONF_SG_PARAM_45] = 0,
232 [WL18XX_CONF_SG_CONSECUTIVE_CTS_THRESHOLD] = 2,
233 [WL18XX_CONF_SG_GEMINI_PARAM_47] = 0,
234 [WL18XX_CONF_SG_STA_CONNECTION_PROTECTION_TIME] = 0,
236 [WL18XX_CONF_SG_AP_BEACON_MISS_TX] = 3,
237 [WL18XX_CONF_SG_PARAM_50] = 0,
238 [WL18XX_CONF_SG_AP_BEACON_WINDOW_INTERVAL] = 2,
239 [WL18XX_CONF_SG_AP_CONNECTION_PROTECTION_TIME] = 30,
240 [WL18XX_CONF_SG_PARAM_53] = 0,
241 [WL18XX_CONF_SG_PARAM_54] = 0,
242 /* CTS Diluting Parameters */
243 [WL18XX_CONF_SG_CTS_DILUTED_BAD_RX_PACKETS_TH] = 0,
244 [WL18XX_CONF_SG_CTS_CHOP_IN_DUAL_ANT_SCO_MASTER] = 0,
245 [WL18XX_CONF_SG_TEMP_PARAM_1] = 0,
246 [WL18XX_CONF_SG_TEMP_PARAM_2] = 0,
247 [WL18XX_CONF_SG_TEMP_PARAM_3] = 0,
248 [WL18XX_CONF_SG_TEMP_PARAM_4] = 0,
249 [WL18XX_CONF_SG_TEMP_PARAM_5] = 0,
250 [WL18XX_CONF_SG_TEMP_PARAM_6] = 0,
251 [WL18XX_CONF_SG_TEMP_PARAM_7] = 0,
252 [WL18XX_CONF_SG_TEMP_PARAM_8] = 0,
253 [WL18XX_CONF_SG_TEMP_PARAM_9] = 0,
254 [WL18XX_CONF_SG_TEMP_PARAM_10] = 0,
256 .state = CONF_SG_PROTECTIVE,
259 .rx_msdu_life_time = 512000,
260 .packet_detection_threshold = 0,
261 .ps_poll_timeout = 15,
263 .rts_threshold = IEEE80211_MAX_RTS_THRESHOLD,
264 .rx_cca_threshold = 0,
265 .irq_blk_threshold = 0xFFFF,
266 .irq_pkt_threshold = 0,
268 .queue_type = CONF_RX_QUEUE_TYPE_LOW_PRIORITY,
271 .tx_energy_detection = 0,
274 .short_retry_limit = 10,
275 .long_retry_limit = 10,
298 .aifsn = CONF_TX_AIFS_PIFS,
305 .aifsn = CONF_TX_AIFS_PIFS,
309 .max_tx_retries = 100,
310 .ap_aging_period = 300,
314 .queue_id = CONF_TX_AC_BE,
315 .channel_type = CONF_CHANNEL_TYPE_EDCF,
316 .tsid = CONF_TX_AC_BE,
317 .ps_scheme = CONF_PS_SCHEME_LEGACY,
318 .ack_policy = CONF_ACK_POLICY_LEGACY,
322 .queue_id = CONF_TX_AC_BK,
323 .channel_type = CONF_CHANNEL_TYPE_EDCF,
324 .tsid = CONF_TX_AC_BK,
325 .ps_scheme = CONF_PS_SCHEME_LEGACY,
326 .ack_policy = CONF_ACK_POLICY_LEGACY,
330 .queue_id = CONF_TX_AC_VI,
331 .channel_type = CONF_CHANNEL_TYPE_EDCF,
332 .tsid = CONF_TX_AC_VI,
333 .ps_scheme = CONF_PS_SCHEME_LEGACY,
334 .ack_policy = CONF_ACK_POLICY_LEGACY,
338 .queue_id = CONF_TX_AC_VO,
339 .channel_type = CONF_CHANNEL_TYPE_EDCF,
340 .tsid = CONF_TX_AC_VO,
341 .ps_scheme = CONF_PS_SCHEME_LEGACY,
342 .ack_policy = CONF_ACK_POLICY_LEGACY,
346 .frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD,
347 .tx_compl_timeout = 350,
348 .tx_compl_threshold = 10,
349 .basic_rate = CONF_HW_BIT_RATE_1MBPS,
350 .basic_rate_5 = CONF_HW_BIT_RATE_6MBPS,
351 .tmpl_short_retry_limit = 10,
352 .tmpl_long_retry_limit = 10,
353 .tx_watchdog_timeout = 5000,
354 .slow_link_thold = 3,
355 .fast_link_thold = 30,
358 .wake_up_event = CONF_WAKE_UP_EVENT_DTIM,
359 .listen_interval = 1,
360 .suspend_wake_up_event = CONF_WAKE_UP_EVENT_N_DTIM,
361 .suspend_listen_interval = 3,
362 .bcn_filt_mode = CONF_BCN_FILT_MODE_ENABLED,
363 .bcn_filt_ie_count = 3,
366 .ie = WLAN_EID_CHANNEL_SWITCH,
367 .rule = CONF_BCN_RULE_PASS_ON_APPEARANCE,
370 .ie = WLAN_EID_HT_OPERATION,
371 .rule = CONF_BCN_RULE_PASS_ON_CHANGE,
374 .ie = WLAN_EID_ERP_INFO,
375 .rule = CONF_BCN_RULE_PASS_ON_CHANGE,
378 .synch_fail_thold = 12,
379 .bss_lose_timeout = 400,
380 .beacon_rx_timeout = 10000,
381 .broadcast_timeout = 20000,
382 .rx_broadcast_in_ps = 1,
383 .ps_poll_threshold = 10,
384 .bet_enable = CONF_BET_MODE_ENABLE,
385 .bet_max_consecutive = 50,
386 .psm_entry_retries = 8,
387 .psm_exit_retries = 16,
388 .psm_entry_nullfunc_retries = 3,
389 .dynamic_ps_timeout = 1500,
391 .keep_alive_interval = 55000,
392 .max_listen_interval = 20,
393 .sta_sleep_auth = WL1271_PSM_ILLEGAL,
394 .suspend_rx_ba_activity = 0,
401 .host_clk_settling_time = 5000,
402 .host_fast_wakeup_support = CONF_FAST_WAKEUP_DISABLE,
406 .avg_weight_rssi_beacon = 20,
407 .avg_weight_rssi_data = 10,
408 .avg_weight_snr_beacon = 20,
409 .avg_weight_snr_data = 10,
412 .min_dwell_time_active = 7500,
413 .max_dwell_time_active = 30000,
414 .min_dwell_time_active_long = 25000,
415 .max_dwell_time_active_long = 50000,
416 .dwell_time_passive = 100000,
417 .dwell_time_dfs = 150000,
419 .split_scan_timeout = 50000,
423 * Values are in TU/1000 but since sched scan FW command
424 * params are in TUs rounding up may occur.
426 .base_dwell_time = 7500,
427 .max_dwell_time_delta = 22500,
428 /* based on 250bits per probe @1Mbps */
429 .dwell_time_delta_per_probe = 2000,
430 /* based on 250bits per probe @6Mbps (plus a bit more) */
431 .dwell_time_delta_per_probe_5 = 350,
432 .dwell_time_passive = 100000,
433 .dwell_time_dfs = 150000,
435 .rssi_threshold = -90,
437 .num_short_intervals = SCAN_MAX_SHORT_INTERVALS,
438 .long_interval = 30000,
441 .rx_ba_win_size = 32,
442 .tx_ba_win_size = 64,
443 .inactivity_timeout = 10000,
444 .tx_ba_tid_bitmap = CONF_TX_BA_ENABLED_TID_BITMAP,
450 .tx_min_block_num = 40,
452 .min_req_tx_blocks = 45,
453 .min_req_rx_blocks = 22,
459 .n_divider_fref_set_1 = 0xff, /* default */
460 .n_divider_fref_set_2 = 12,
461 .m_divider_fref_set_1 = 0xffff,
462 .m_divider_fref_set_2 = 148, /* default */
463 .coex_pll_stabilization_time = 0xffffffff, /* default */
464 .ldo_stabilization_time = 0xffff, /* default */
465 .fm_disturbed_band_margin = 0xff, /* default */
466 .swallow_clk_diff = 0xff, /* default */
475 .mode = WL12XX_FWLOG_CONTINUOUS,
478 .timestamp = WL12XX_FWLOG_TIMESTAMP_DISABLED,
479 .output = WL12XX_FWLOG_OUTPUT_DBG_PINS,
483 .rate_retry_score = 32000,
488 .inverse_curiosity_factor = 5,
490 .tx_fail_high_th = 10,
491 .per_alpha_shift = 4,
493 .per_beta1_shift = 10,
494 .per_beta2_shift = 8,
496 .rate_check_down = 12,
497 .rate_retry_policy = {
498 0x00, 0x00, 0x00, 0x00, 0x00,
499 0x00, 0x00, 0x00, 0x00, 0x00,
505 .hangover_period = 20,
507 .early_termination_mode = 1,
517 .bug_on_recovery = 0,
522 static struct wl18xx_priv_conf wl18xx_default_priv_conf = {
524 .mode = HT_MODE_WIDE,
527 .phy_standalone = 0x00,
528 .primary_clock_setting_time = 0x05,
529 .clock_valid_on_wake_up = 0x00,
530 .secondary_clock_setting_time = 0x05,
531 .board_type = BOARD_TYPE_HDK_18XX,
533 .dedicated_fem = FEM_NONE,
534 .low_band_component = COMPONENT_3_WAY_SWITCH,
535 .low_band_component_type = 0x05,
536 .high_band_component = COMPONENT_2_WAY_SWITCH,
537 .high_band_component_type = 0x09,
538 .tcxo_ldo_voltage = 0x00,
539 .xtal_itrim_val = 0x04,
541 .io_configuration = 0x01,
542 .sdio_configuration = 0x00,
545 .enable_tx_low_pwr_on_siso_rdl = 0x00,
547 .pwr_limit_reference_11_abg = 0x64,
548 .per_chan_pwr_limit_arr_11abg = {
549 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
550 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
551 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
552 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
553 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
554 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
555 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
556 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
557 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
558 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
559 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
560 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
561 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
562 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
563 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
564 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
565 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
566 .pwr_limit_reference_11p = 0x64,
567 .per_chan_bo_mode_11_abg = { 0x00, 0x00, 0x00, 0x00,
568 0x00, 0x00, 0x00, 0x00,
569 0x00, 0x00, 0x00, 0x00,
571 .per_chan_bo_mode_11_p = { 0x00, 0x00, 0x00, 0x00 },
572 .per_chan_pwr_limit_arr_11p = { 0xff, 0xff, 0xff, 0xff,
575 .external_pa_dc2dc = 0,
576 .number_of_assembled_ant2_4 = 2,
577 .number_of_assembled_ant5 = 1,
578 .low_power_val = 0xff,
579 .med_power_val = 0xff,
580 .high_power_val = 0xff,
581 .low_power_val_2nd = 0xff,
582 .med_power_val_2nd = 0xff,
583 .high_power_val_2nd = 0xff,
586 .ap_sleep = { /* disabled by default */
587 .idle_duty_cycle = 0,
588 .connected_duty_cycle = 0,
589 .max_stations_thresh = 0,
590 .idle_conn_thresh = 0,
594 static const struct wlcore_partition_set wl18xx_ptable[PART_TABLE_LEN] = {
595 [PART_TOP_PRCM_ELP_SOC] = {
596 .mem = { .start = 0x00A00000, .size = 0x00012000 },
597 .reg = { .start = 0x00807000, .size = 0x00005000 },
598 .mem2 = { .start = 0x00800000, .size = 0x0000B000 },
599 .mem3 = { .start = 0x00401594, .size = 0x00001020 },
602 .mem = { .start = 0x00000000, .size = 0x00014000 },
603 .reg = { .start = 0x00810000, .size = 0x0000BFFF },
604 .mem2 = { .start = 0x00000000, .size = 0x00000000 },
605 .mem3 = { .start = 0x00000000, .size = 0x00000000 },
608 .mem = { .start = 0x00700000, .size = 0x0000030c },
609 .reg = { .start = 0x00802000, .size = 0x00014578 },
610 .mem2 = { .start = 0x00B00404, .size = 0x00001000 },
611 .mem3 = { .start = 0x00C00000, .size = 0x00000400 },
614 .mem = { .start = 0x00800000, .size = 0x000050FC },
615 .reg = { .start = 0x00B00404, .size = 0x00001000 },
616 .mem2 = { .start = 0x00C00000, .size = 0x00000400 },
617 .mem3 = { .start = 0x00401594, .size = 0x00001020 },
620 .mem = { .start = WL18XX_PHY_INIT_MEM_ADDR,
621 .size = WL18XX_PHY_INIT_MEM_SIZE },
622 .reg = { .start = 0x00000000, .size = 0x00000000 },
623 .mem2 = { .start = 0x00000000, .size = 0x00000000 },
624 .mem3 = { .start = 0x00000000, .size = 0x00000000 },
628 static const int wl18xx_rtable[REG_TABLE_LEN] = {
629 [REG_ECPU_CONTROL] = WL18XX_REG_ECPU_CONTROL,
630 [REG_INTERRUPT_NO_CLEAR] = WL18XX_REG_INTERRUPT_NO_CLEAR,
631 [REG_INTERRUPT_ACK] = WL18XX_REG_INTERRUPT_ACK,
632 [REG_COMMAND_MAILBOX_PTR] = WL18XX_REG_COMMAND_MAILBOX_PTR,
633 [REG_EVENT_MAILBOX_PTR] = WL18XX_REG_EVENT_MAILBOX_PTR,
634 [REG_INTERRUPT_TRIG] = WL18XX_REG_INTERRUPT_TRIG_H,
635 [REG_INTERRUPT_MASK] = WL18XX_REG_INTERRUPT_MASK,
636 [REG_PC_ON_RECOVERY] = WL18XX_SCR_PAD4,
637 [REG_CHIP_ID_B] = WL18XX_REG_CHIP_ID_B,
638 [REG_CMD_MBOX_ADDRESS] = WL18XX_CMD_MBOX_ADDRESS,
640 /* data access memory addresses, used with partition translation */
641 [REG_SLV_MEM_DATA] = WL18XX_SLV_MEM_DATA,
642 [REG_SLV_REG_DATA] = WL18XX_SLV_REG_DATA,
644 /* raw data access memory addresses */
645 [REG_RAW_FW_STATUS_ADDR] = WL18XX_FW_STATUS_ADDR,
648 static const struct wl18xx_clk_cfg wl18xx_clk_table_coex[NUM_CLOCK_CONFIGS] = {
649 [CLOCK_CONFIG_16_2_M] = { 8, 121, 0, 0, false },
650 [CLOCK_CONFIG_16_368_M] = { 8, 120, 0, 0, false },
651 [CLOCK_CONFIG_16_8_M] = { 8, 117, 0, 0, false },
652 [CLOCK_CONFIG_19_2_M] = { 10, 128, 0, 0, false },
653 [CLOCK_CONFIG_26_M] = { 11, 104, 0, 0, false },
654 [CLOCK_CONFIG_32_736_M] = { 8, 120, 0, 0, false },
655 [CLOCK_CONFIG_33_6_M] = { 8, 117, 0, 0, false },
656 [CLOCK_CONFIG_38_468_M] = { 10, 128, 0, 0, false },
657 [CLOCK_CONFIG_52_M] = { 11, 104, 0, 0, false },
660 static const struct wl18xx_clk_cfg wl18xx_clk_table[NUM_CLOCK_CONFIGS] = {
661 [CLOCK_CONFIG_16_2_M] = { 7, 104, 801, 4, true },
662 [CLOCK_CONFIG_16_368_M] = { 9, 132, 3751, 4, true },
663 [CLOCK_CONFIG_16_8_M] = { 7, 100, 0, 0, false },
664 [CLOCK_CONFIG_19_2_M] = { 8, 100, 0, 0, false },
665 [CLOCK_CONFIG_26_M] = { 13, 120, 0, 0, false },
666 [CLOCK_CONFIG_32_736_M] = { 9, 132, 3751, 4, true },
667 [CLOCK_CONFIG_33_6_M] = { 7, 100, 0, 0, false },
668 [CLOCK_CONFIG_38_468_M] = { 8, 100, 0, 0, false },
669 [CLOCK_CONFIG_52_M] = { 13, 120, 0, 0, false },
672 /* TODO: maybe move to a new header file? */
673 #define WL18XX_FW_NAME "/*(DEBLOBBED)*/"
675 static int wl18xx_identify_chip(struct wl1271 *wl)
679 switch (wl->chip.id) {
680 case CHIP_ID_185x_PG20:
681 wl1271_debug(DEBUG_BOOT, "chip id 0x%x (185x PG20)",
683 wl->sr_fw_name = WL18XX_FW_NAME;
684 /* wl18xx uses the same firmware for PLT */
685 wl->plt_fw_name = WL18XX_FW_NAME;
686 wl->quirks |= WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN |
687 WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN |
688 WLCORE_QUIRK_NO_SCHED_SCAN_WHILE_CONN |
689 WLCORE_QUIRK_TX_PAD_LAST_FRAME |
690 WLCORE_QUIRK_REGDOMAIN_CONF |
691 WLCORE_QUIRK_DUAL_PROBE_TMPL;
693 wlcore_set_min_fw_ver(wl, WL18XX_CHIP_VER,
694 WL18XX_IFTYPE_VER, WL18XX_MAJOR_VER,
695 WL18XX_SUBTYPE_VER, WL18XX_MINOR_VER,
696 /* there's no separate multi-role FW */
699 case CHIP_ID_185x_PG10:
700 wl1271_warning("chip id 0x%x (185x PG10) is deprecated",
706 wl1271_warning("unsupported chip id: 0x%x", wl->chip.id);
711 wl->fw_mem_block_size = 272;
712 wl->fwlog_end = 0x40000000;
714 wl->scan_templ_id_2_4 = CMD_TEMPL_CFG_PROBE_REQ_2_4;
715 wl->scan_templ_id_5 = CMD_TEMPL_CFG_PROBE_REQ_5;
716 wl->sched_scan_templ_id_2_4 = CMD_TEMPL_PROBE_REQ_2_4_PERIODIC;
717 wl->sched_scan_templ_id_5 = CMD_TEMPL_PROBE_REQ_5_PERIODIC;
718 wl->max_channels_5 = WL18XX_MAX_CHANNELS_5GHZ;
719 wl->ba_rx_session_count_max = WL18XX_RX_BA_MAX_SESSIONS;
724 static int wl18xx_set_clk(struct wl1271 *wl)
729 ret = wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]);
733 /* TODO: PG2: apparently we need to read the clk type */
735 ret = wl18xx_top_reg_read(wl, PRIMARY_CLK_DETECT, &clk_freq);
739 wl1271_debug(DEBUG_BOOT, "clock freq %d (%d, %d, %d, %d, %s)", clk_freq,
740 wl18xx_clk_table[clk_freq].n, wl18xx_clk_table[clk_freq].m,
741 wl18xx_clk_table[clk_freq].p, wl18xx_clk_table[clk_freq].q,
742 wl18xx_clk_table[clk_freq].swallow ? "swallow" : "spit");
744 /* coex PLL configuration */
745 ret = wl18xx_top_reg_write(wl, PLLSH_COEX_PLL_N,
746 wl18xx_clk_table_coex[clk_freq].n);
750 ret = wl18xx_top_reg_write(wl, PLLSH_COEX_PLL_M,
751 wl18xx_clk_table_coex[clk_freq].m);
755 /* bypass the swallowing logic */
756 ret = wl18xx_top_reg_write(wl, PLLSH_COEX_PLL_SWALLOW_EN,
757 PLLSH_COEX_PLL_SWALLOW_EN_VAL1);
761 ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_N,
762 wl18xx_clk_table[clk_freq].n);
766 ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_M,
767 wl18xx_clk_table[clk_freq].m);
771 if (wl18xx_clk_table[clk_freq].swallow) {
772 /* first the 16 lower bits */
773 ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_Q_FACTOR_CFG_1,
774 wl18xx_clk_table[clk_freq].q &
775 PLLSH_WCS_PLL_Q_FACTOR_CFG_1_MASK);
779 /* then the 16 higher bits, masked out */
780 ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_Q_FACTOR_CFG_2,
781 (wl18xx_clk_table[clk_freq].q >> 16) &
782 PLLSH_WCS_PLL_Q_FACTOR_CFG_2_MASK);
786 /* first the 16 lower bits */
787 ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_P_FACTOR_CFG_1,
788 wl18xx_clk_table[clk_freq].p &
789 PLLSH_WCS_PLL_P_FACTOR_CFG_1_MASK);
793 /* then the 16 higher bits, masked out */
794 ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_P_FACTOR_CFG_2,
795 (wl18xx_clk_table[clk_freq].p >> 16) &
796 PLLSH_WCS_PLL_P_FACTOR_CFG_2_MASK);
800 ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_SWALLOW_EN,
801 PLLSH_WCS_PLL_SWALLOW_EN_VAL2);
807 ret = wl18xx_top_reg_write(wl, PLLSH_WL_PLL_SEL,
808 PLLSH_WL_PLL_SEL_WCS_PLL);
812 /* enable both PLLs */
813 ret = wl18xx_top_reg_write(wl, PLLSH_WL_PLL_EN, PLLSH_WL_PLL_EN_VAL1);
819 /* disable coex PLL */
820 ret = wl18xx_top_reg_write(wl, PLLSH_WL_PLL_EN, PLLSH_WL_PLL_EN_VAL2);
824 /* reset the swallowing logic */
825 ret = wl18xx_top_reg_write(wl, PLLSH_COEX_PLL_SWALLOW_EN,
826 PLLSH_COEX_PLL_SWALLOW_EN_VAL2);
832 static int wl18xx_boot_soft_reset(struct wl1271 *wl)
837 ret = wlcore_write32(wl, WL18XX_ENABLE, 0x0);
841 /* disable auto calibration on start*/
842 ret = wlcore_write32(wl, WL18XX_SPARE_A2, 0xffff);
848 static int wl18xx_pre_boot(struct wl1271 *wl)
852 ret = wl18xx_set_clk(wl);
856 /* Continue the ELP wake up sequence */
857 ret = wlcore_write32(wl, WL18XX_WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL);
863 ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
867 /* Disable interrupts */
868 ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
872 ret = wl18xx_boot_soft_reset(wl);
878 static int wl18xx_pre_upload(struct wl1271 *wl)
884 BUILD_BUG_ON(sizeof(struct wl18xx_mac_and_phy_params) >
885 WL18XX_PHY_INIT_MEM_SIZE);
887 ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
891 /* TODO: check if this is all needed */
892 ret = wlcore_write32(wl, WL18XX_EEPROMLESS_IND, WL18XX_EEPROMLESS_IND);
896 ret = wlcore_read_reg(wl, REG_CHIP_ID_B, &tmp);
900 wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp);
902 ret = wlcore_read32(wl, WL18XX_SCR_PAD2, &tmp);
907 * Workaround for FDSP code RAM corruption (needed for PG2.1
908 * and newer; for older chips it's a NOP). Change FDSP clock
909 * settings so that it's muxed to the ATGP clock instead of
913 ret = wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]);
917 /* disable FDSP clock */
918 ret = wlcore_write32(wl, WL18XX_PHY_FPGA_SPARE_1,
919 MEM_FDSP_CLK_120_DISABLE);
923 /* set ATPG clock toward FDSP Code RAM rather than its own clock */
924 ret = wlcore_write32(wl, WL18XX_PHY_FPGA_SPARE_1,
925 MEM_FDSP_CODERAM_FUNC_CLK_SEL);
929 /* re-enable FDSP clock */
930 ret = wlcore_write32(wl, WL18XX_PHY_FPGA_SPARE_1,
931 MEM_FDSP_CLK_120_ENABLE);
935 ret = irq_get_trigger_type(wl->irq);
936 if ((ret == IRQ_TYPE_LEVEL_LOW) || (ret == IRQ_TYPE_EDGE_FALLING)) {
937 wl1271_info("using inverted interrupt logic: %d", ret);
938 ret = wlcore_set_partition(wl,
939 &wl->ptable[PART_TOP_PRCM_ELP_SOC]);
943 ret = wl18xx_top_reg_read(wl, TOP_FN0_CCCR_REG_32, &irq_invert);
947 irq_invert |= BIT(1);
948 ret = wl18xx_top_reg_write(wl, TOP_FN0_CCCR_REG_32, irq_invert);
952 ret = wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]);
959 static int wl18xx_set_mac_and_phy(struct wl1271 *wl)
961 struct wl18xx_priv *priv = wl->priv;
962 struct wl18xx_mac_and_phy_params *params;
965 params = kmemdup(&priv->conf.phy, sizeof(*params), GFP_KERNEL);
971 ret = wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]);
975 ret = wlcore_write(wl, WL18XX_PHY_INIT_MEM_ADDR, params,
976 sizeof(*params), false);
983 static int wl18xx_enable_interrupts(struct wl1271 *wl)
985 u32 event_mask, intr_mask;
988 event_mask = WL18XX_ACX_EVENTS_VECTOR;
989 intr_mask = WL18XX_INTR_MASK;
991 ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK, event_mask);
995 wlcore_enable_interrupts(wl);
997 ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK,
998 WL1271_ACX_INTR_ALL & ~intr_mask);
1000 goto disable_interrupts;
1005 wlcore_disable_interrupts(wl);
1011 static int wl18xx_boot(struct wl1271 *wl)
1015 ret = wl18xx_pre_boot(wl);
1019 ret = wl18xx_pre_upload(wl);
1023 ret = wlcore_boot_upload_firmware(wl);
1027 ret = wl18xx_set_mac_and_phy(wl);
1031 wl->event_mask = BSS_LOSS_EVENT_ID |
1032 SCAN_COMPLETE_EVENT_ID |
1033 RADAR_DETECTED_EVENT_ID |
1034 RSSI_SNR_TRIGGER_0_EVENT_ID |
1035 PERIODIC_SCAN_COMPLETE_EVENT_ID |
1036 PERIODIC_SCAN_REPORT_EVENT_ID |
1037 DUMMY_PACKET_EVENT_ID |
1038 PEER_REMOVE_COMPLETE_EVENT_ID |
1039 BA_SESSION_RX_CONSTRAINT_EVENT_ID |
1040 REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID |
1041 INACTIVE_STA_EVENT_ID |
1042 CHANNEL_SWITCH_COMPLETE_EVENT_ID |
1043 DFS_CHANNELS_CONFIG_COMPLETE_EVENT |
1044 SMART_CONFIG_SYNC_EVENT_ID |
1045 SMART_CONFIG_DECODE_EVENT_ID |
1046 TIME_SYNC_EVENT_ID |
1047 FW_LOGGER_INDICATION |
1048 RX_BA_WIN_SIZE_CHANGE_EVENT_ID;
1050 wl->ap_event_mask = MAX_TX_FAILURE_EVENT_ID;
1052 ret = wlcore_boot_run_firmware(wl);
1056 ret = wl18xx_enable_interrupts(wl);
1062 static int wl18xx_trigger_cmd(struct wl1271 *wl, int cmd_box_addr,
1063 void *buf, size_t len)
1065 struct wl18xx_priv *priv = wl->priv;
1067 memcpy(priv->cmd_buf, buf, len);
1068 memset(priv->cmd_buf + len, 0, WL18XX_CMD_MAX_SIZE - len);
1070 return wlcore_write(wl, cmd_box_addr, priv->cmd_buf,
1071 WL18XX_CMD_MAX_SIZE, false);
1074 static int wl18xx_ack_event(struct wl1271 *wl)
1076 return wlcore_write_reg(wl, REG_INTERRUPT_TRIG,
1077 WL18XX_INTR_TRIG_EVENT_ACK);
1080 static u32 wl18xx_calc_tx_blocks(struct wl1271 *wl, u32 len, u32 spare_blks)
1082 u32 blk_size = WL18XX_TX_HW_BLOCK_SIZE;
1083 return (len + blk_size - 1) / blk_size + spare_blks;
1087 wl18xx_set_tx_desc_blocks(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc,
1088 u32 blks, u32 spare_blks)
1090 desc->wl18xx_mem.total_mem_blocks = blks;
1094 wl18xx_set_tx_desc_data_len(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc,
1095 struct sk_buff *skb)
1097 desc->length = cpu_to_le16(skb->len);
1099 /* if only the last frame is to be padded, we unset this bit on Tx */
1100 if (wl->quirks & WLCORE_QUIRK_TX_PAD_LAST_FRAME)
1101 desc->wl18xx_mem.ctrl = WL18XX_TX_CTRL_NOT_PADDED;
1103 desc->wl18xx_mem.ctrl = 0;
1105 wl1271_debug(DEBUG_TX, "tx_fill_hdr: hlid: %d "
1106 "len: %d life: %d mem: %d", desc->hlid,
1107 le16_to_cpu(desc->length),
1108 le16_to_cpu(desc->life_time),
1109 desc->wl18xx_mem.total_mem_blocks);
1112 static enum wl_rx_buf_align
1113 wl18xx_get_rx_buf_align(struct wl1271 *wl, u32 rx_desc)
1115 if (rx_desc & RX_BUF_PADDED_PAYLOAD)
1116 return WLCORE_RX_BUF_PADDED;
1118 return WLCORE_RX_BUF_ALIGNED;
1121 static u32 wl18xx_get_rx_packet_len(struct wl1271 *wl, void *rx_data,
1124 struct wl1271_rx_descriptor *desc = rx_data;
1126 /* invalid packet */
1127 if (data_len < sizeof(*desc))
1130 return data_len - sizeof(*desc);
1133 static void wl18xx_tx_immediate_completion(struct wl1271 *wl)
1135 wl18xx_tx_immediate_complete(wl);
1138 static int wl18xx_set_host_cfg_bitmap(struct wl1271 *wl, u32 extra_mem_blk)
1141 u32 sdio_align_size = 0;
1142 u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE |
1143 HOST_IF_CFG_ADD_RX_ALIGNMENT;
1145 /* Enable Tx SDIO padding */
1146 if (wl->quirks & WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN) {
1147 host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK;
1148 sdio_align_size = WL12XX_BUS_BLOCK_SIZE;
1151 /* Enable Rx SDIO padding */
1152 if (wl->quirks & WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN) {
1153 host_cfg_bitmap |= HOST_IF_CFG_RX_PAD_TO_SDIO_BLK;
1154 sdio_align_size = WL12XX_BUS_BLOCK_SIZE;
1157 ret = wl18xx_acx_host_if_cfg_bitmap(wl, host_cfg_bitmap,
1158 sdio_align_size, extra_mem_blk,
1159 WL18XX_HOST_IF_LEN_SIZE_FIELD);
1166 static int wl18xx_hw_init(struct wl1271 *wl)
1169 struct wl18xx_priv *priv = wl->priv;
1171 /* (re)init private structures. Relevant on recovery as well. */
1172 priv->last_fw_rls_idx = 0;
1173 priv->extra_spare_key_count = 0;
1175 /* set the default amount of spare blocks in the bitmap */
1176 ret = wl18xx_set_host_cfg_bitmap(wl, WL18XX_TX_HW_BLOCK_SPARE);
1180 /* set the dynamic fw traces bitmap */
1181 ret = wl18xx_acx_dynamic_fw_traces(wl);
1185 if (checksum_param) {
1186 ret = wl18xx_acx_set_checksum_state(wl);
1194 static void wl18xx_convert_fw_status(struct wl1271 *wl, void *raw_fw_status,
1195 struct wl_fw_status *fw_status)
1197 struct wl18xx_fw_status *int_fw_status = raw_fw_status;
1199 fw_status->intr = le32_to_cpu(int_fw_status->intr);
1200 fw_status->fw_rx_counter = int_fw_status->fw_rx_counter;
1201 fw_status->drv_rx_counter = int_fw_status->drv_rx_counter;
1202 fw_status->tx_results_counter = int_fw_status->tx_results_counter;
1203 fw_status->rx_pkt_descs = int_fw_status->rx_pkt_descs;
1205 fw_status->fw_localtime = le32_to_cpu(int_fw_status->fw_localtime);
1206 fw_status->link_ps_bitmap = le32_to_cpu(int_fw_status->link_ps_bitmap);
1207 fw_status->link_fast_bitmap =
1208 le32_to_cpu(int_fw_status->link_fast_bitmap);
1209 fw_status->total_released_blks =
1210 le32_to_cpu(int_fw_status->total_released_blks);
1211 fw_status->tx_total = le32_to_cpu(int_fw_status->tx_total);
1213 fw_status->counters.tx_released_pkts =
1214 int_fw_status->counters.tx_released_pkts;
1215 fw_status->counters.tx_lnk_free_pkts =
1216 int_fw_status->counters.tx_lnk_free_pkts;
1217 fw_status->counters.tx_voice_released_blks =
1218 int_fw_status->counters.tx_voice_released_blks;
1219 fw_status->counters.tx_last_rate =
1220 int_fw_status->counters.tx_last_rate;
1221 fw_status->counters.tx_last_rate_mbps =
1222 int_fw_status->counters.tx_last_rate_mbps;
1223 fw_status->counters.hlid =
1224 int_fw_status->counters.hlid;
1226 fw_status->log_start_addr = le32_to_cpu(int_fw_status->log_start_addr);
1228 fw_status->priv = &int_fw_status->priv;
1231 static void wl18xx_set_tx_desc_csum(struct wl1271 *wl,
1232 struct wl1271_tx_hw_descr *desc,
1233 struct sk_buff *skb)
1236 struct iphdr *ip_hdr;
1238 if (!checksum_param) {
1239 desc->wl18xx_checksum_data = 0;
1243 if (skb->ip_summed != CHECKSUM_PARTIAL) {
1244 desc->wl18xx_checksum_data = 0;
1248 ip_hdr_offset = skb_network_header(skb) - skb_mac_header(skb);
1249 if (WARN_ON(ip_hdr_offset >= (1<<7))) {
1250 desc->wl18xx_checksum_data = 0;
1254 desc->wl18xx_checksum_data = ip_hdr_offset << 1;
1256 /* FW is interested only in the LSB of the protocol TCP=0 UDP=1 */
1257 ip_hdr = (void *)skb_network_header(skb);
1258 desc->wl18xx_checksum_data |= (ip_hdr->protocol & 0x01);
1261 static void wl18xx_set_rx_csum(struct wl1271 *wl,
1262 struct wl1271_rx_descriptor *desc,
1263 struct sk_buff *skb)
1265 if (desc->status & WL18XX_RX_CHECKSUM_MASK)
1266 skb->ip_summed = CHECKSUM_UNNECESSARY;
1269 static bool wl18xx_is_mimo_supported(struct wl1271 *wl)
1271 struct wl18xx_priv *priv = wl->priv;
1273 /* only support MIMO with multiple antennas, and when SISO
1274 * is not forced through config
1276 return (priv->conf.phy.number_of_assembled_ant2_4 >= 2) &&
1277 (priv->conf.ht.mode != HT_MODE_WIDE) &&
1278 (priv->conf.ht.mode != HT_MODE_SISO20);
1282 * TODO: instead of having these two functions to get the rate mask,
1283 * we should modify the wlvif->rate_set instead
1285 static u32 wl18xx_sta_get_ap_rate_mask(struct wl1271 *wl,
1286 struct wl12xx_vif *wlvif)
1288 u32 hw_rate_set = wlvif->rate_set;
1290 if (wlvif->channel_type == NL80211_CHAN_HT40MINUS ||
1291 wlvif->channel_type == NL80211_CHAN_HT40PLUS) {
1292 wl1271_debug(DEBUG_ACX, "using wide channel rate mask");
1293 hw_rate_set |= CONF_TX_RATE_USE_WIDE_CHAN;
1295 /* we don't support MIMO in wide-channel mode */
1296 hw_rate_set &= ~CONF_TX_MIMO_RATES;
1297 } else if (wl18xx_is_mimo_supported(wl)) {
1298 wl1271_debug(DEBUG_ACX, "using MIMO channel rate mask");
1299 hw_rate_set |= CONF_TX_MIMO_RATES;
1305 static u32 wl18xx_ap_get_mimo_wide_rate_mask(struct wl1271 *wl,
1306 struct wl12xx_vif *wlvif)
1308 if (wlvif->channel_type == NL80211_CHAN_HT40MINUS ||
1309 wlvif->channel_type == NL80211_CHAN_HT40PLUS) {
1310 wl1271_debug(DEBUG_ACX, "using wide channel rate mask");
1312 /* sanity check - we don't support this */
1313 if (WARN_ON(wlvif->band != NL80211_BAND_5GHZ))
1316 return CONF_TX_RATE_USE_WIDE_CHAN;
1317 } else if (wl18xx_is_mimo_supported(wl) &&
1318 wlvif->band == NL80211_BAND_2GHZ) {
1319 wl1271_debug(DEBUG_ACX, "using MIMO rate mask");
1321 * we don't care about HT channel here - if a peer doesn't
1322 * support MIMO, we won't enable it in its rates
1324 return CONF_TX_MIMO_RATES;
1330 static const char *wl18xx_rdl_name(enum wl18xx_rdl_num rdl_num)
1336 return "183x or 180x";
1342 return "RDL11 - Not Supported";
1346 return "RDL13 - Not Supported (1893Q)";
1356 static int wl18xx_get_pg_ver(struct wl1271 *wl, s8 *ver)
1359 s8 rom = 0, metal = 0, pg_ver = 0, rdl_ver = 0, package_type = 0;
1362 ret = wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]);
1366 ret = wlcore_read32(wl, WL18XX_REG_FUSE_DATA_2_3, &fuse);
1370 package_type = (fuse >> WL18XX_PACKAGE_TYPE_OFFSET) & 1;
1372 ret = wlcore_read32(wl, WL18XX_REG_FUSE_DATA_1_3, &fuse);
1376 pg_ver = (fuse & WL18XX_PG_VER_MASK) >> WL18XX_PG_VER_OFFSET;
1377 rom = (fuse & WL18XX_ROM_VER_MASK) >> WL18XX_ROM_VER_OFFSET;
1379 if ((rom <= 0xE) && (package_type == WL18XX_PACKAGE_TYPE_WSP))
1380 metal = (fuse & WL18XX_METAL_VER_MASK) >>
1381 WL18XX_METAL_VER_OFFSET;
1383 metal = (fuse & WL18XX_NEW_METAL_VER_MASK) >>
1384 WL18XX_NEW_METAL_VER_OFFSET;
1386 ret = wlcore_read32(wl, WL18XX_REG_FUSE_DATA_2_3, &fuse);
1390 rdl_ver = (fuse & WL18XX_RDL_VER_MASK) >> WL18XX_RDL_VER_OFFSET;
1392 wl1271_info("wl18xx HW: %s, PG %d.%d (ROM 0x%x)",
1393 wl18xx_rdl_name(rdl_ver), pg_ver, metal, rom);
1398 ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
1404 static int wl18xx_load_conf_file(struct device *dev, struct wlcore_conf *conf,
1405 struct wl18xx_priv_conf *priv_conf,
1408 struct wlcore_conf_file *conf_file;
1409 const struct firmware *fw;
1412 ret = reject_firmware(&fw, file, dev);
1414 wl1271_error("could not get configuration binary %s: %d",
1419 if (fw->size != WL18XX_CONF_SIZE) {
1420 wl1271_error("%s configuration binary size is wrong, expected %zu got %zu",
1421 file, WL18XX_CONF_SIZE, fw->size);
1426 conf_file = (struct wlcore_conf_file *) fw->data;
1428 if (conf_file->header.magic != cpu_to_le32(WL18XX_CONF_MAGIC)) {
1429 wl1271_error("configuration binary file magic number mismatch, "
1430 "expected 0x%0x got 0x%0x", WL18XX_CONF_MAGIC,
1431 conf_file->header.magic);
1436 if (conf_file->header.version != cpu_to_le32(WL18XX_CONF_VERSION)) {
1437 wl1271_error("configuration binary file version not supported, "
1438 "expected 0x%08x got 0x%08x",
1439 WL18XX_CONF_VERSION, conf_file->header.version);
1444 memcpy(conf, &conf_file->core, sizeof(*conf));
1445 memcpy(priv_conf, &conf_file->priv, sizeof(*priv_conf));
1448 release_firmware(fw);
1452 static int wl18xx_conf_init(struct wl1271 *wl, struct device *dev)
1454 struct platform_device *pdev = wl->pdev;
1455 struct wlcore_platdev_data *pdata = dev_get_platdata(&pdev->dev);
1456 struct wl18xx_priv *priv = wl->priv;
1458 if (wl18xx_load_conf_file(dev, &wl->conf, &priv->conf,
1459 pdata->family->cfg_name) < 0) {
1460 wl1271_warning("falling back to default config");
1462 /* apply driver default configuration */
1463 memcpy(&wl->conf, &wl18xx_conf, sizeof(wl->conf));
1464 /* apply default private configuration */
1465 memcpy(&priv->conf, &wl18xx_default_priv_conf,
1466 sizeof(priv->conf));
1472 static int wl18xx_plt_init(struct wl1271 *wl)
1476 /* calibrator based auto/fem detect not supported for 18xx */
1477 if (wl->plt_mode == PLT_FEM_DETECT) {
1478 wl1271_error("wl18xx_plt_init: PLT FEM_DETECT not supported");
1482 ret = wlcore_write32(wl, WL18XX_SCR_PAD8, WL18XX_SCR_PAD8_PLT);
1486 return wl->ops->boot(wl);
1489 static int wl18xx_get_mac(struct wl1271 *wl)
1494 ret = wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]);
1498 ret = wlcore_read32(wl, WL18XX_REG_FUSE_BD_ADDR_1, &mac1);
1502 ret = wlcore_read32(wl, WL18XX_REG_FUSE_BD_ADDR_2, &mac2);
1506 /* these are the two parts of the BD_ADDR */
1507 wl->fuse_oui_addr = ((mac2 & 0xffff) << 8) +
1508 ((mac1 & 0xff000000) >> 24);
1509 wl->fuse_nic_addr = (mac1 & 0xffffff);
1511 if (!wl->fuse_oui_addr && !wl->fuse_nic_addr) {
1514 eth_random_addr(mac);
1516 wl->fuse_oui_addr = (mac[0] << 16) + (mac[1] << 8) + mac[2];
1517 wl->fuse_nic_addr = (mac[3] << 16) + (mac[4] << 8) + mac[5];
1518 wl1271_warning("MAC address from fuse not available, using random locally administered addresses.");
1521 ret = wlcore_set_partition(wl, &wl->ptable[PART_DOWN]);
1527 static int wl18xx_handle_static_data(struct wl1271 *wl,
1528 struct wl1271_static_data *static_data)
1530 struct wl18xx_static_data_priv *static_data_priv =
1531 (struct wl18xx_static_data_priv *) static_data->priv;
1533 strncpy(wl->chip.phy_fw_ver_str, static_data_priv->phy_version,
1534 sizeof(wl->chip.phy_fw_ver_str));
1536 /* make sure the string is NULL-terminated */
1537 wl->chip.phy_fw_ver_str[sizeof(wl->chip.phy_fw_ver_str) - 1] = '\0';
1539 wl1271_info("PHY firmware version: %s", static_data_priv->phy_version);
1544 static int wl18xx_get_spare_blocks(struct wl1271 *wl, bool is_gem)
1546 struct wl18xx_priv *priv = wl->priv;
1548 /* If we have keys requiring extra spare, indulge them */
1549 if (priv->extra_spare_key_count)
1550 return WL18XX_TX_HW_EXTRA_BLOCK_SPARE;
1552 return WL18XX_TX_HW_BLOCK_SPARE;
1555 static int wl18xx_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
1556 struct ieee80211_vif *vif,
1557 struct ieee80211_sta *sta,
1558 struct ieee80211_key_conf *key_conf)
1560 struct wl18xx_priv *priv = wl->priv;
1561 bool change_spare = false, special_enc;
1564 wl1271_debug(DEBUG_CRYPT, "extra spare keys before: %d",
1565 priv->extra_spare_key_count);
1567 special_enc = key_conf->cipher == WL1271_CIPHER_SUITE_GEM ||
1568 key_conf->cipher == WLAN_CIPHER_SUITE_TKIP;
1570 ret = wlcore_set_key(wl, cmd, vif, sta, key_conf);
1575 * when adding the first or removing the last GEM/TKIP key,
1576 * we have to adjust the number of spare blocks.
1579 if (cmd == SET_KEY) {
1581 change_spare = (priv->extra_spare_key_count == 0);
1582 priv->extra_spare_key_count++;
1583 } else if (cmd == DISABLE_KEY) {
1585 change_spare = (priv->extra_spare_key_count == 1);
1586 priv->extra_spare_key_count--;
1590 wl1271_debug(DEBUG_CRYPT, "extra spare keys after: %d",
1591 priv->extra_spare_key_count);
1596 /* key is now set, change the spare blocks */
1597 if (priv->extra_spare_key_count)
1598 ret = wl18xx_set_host_cfg_bitmap(wl,
1599 WL18XX_TX_HW_EXTRA_BLOCK_SPARE);
1601 ret = wl18xx_set_host_cfg_bitmap(wl,
1602 WL18XX_TX_HW_BLOCK_SPARE);
1608 static u32 wl18xx_pre_pkt_send(struct wl1271 *wl,
1609 u32 buf_offset, u32 last_len)
1611 if (wl->quirks & WLCORE_QUIRK_TX_PAD_LAST_FRAME) {
1612 struct wl1271_tx_hw_descr *last_desc;
1614 /* get the last TX HW descriptor written to the aggr buf */
1615 last_desc = (struct wl1271_tx_hw_descr *)(wl->aggr_buf +
1616 buf_offset - last_len);
1618 /* the last frame is padded up to an SDIO block */
1619 last_desc->wl18xx_mem.ctrl &= ~WL18XX_TX_CTRL_NOT_PADDED;
1620 return ALIGN(buf_offset, WL12XX_BUS_BLOCK_SIZE);
1623 /* no modifications */
1627 static void wl18xx_sta_rc_update(struct wl1271 *wl,
1628 struct wl12xx_vif *wlvif)
1630 bool wide = wlvif->rc_update_bw >= IEEE80211_STA_RX_BW_40;
1632 wl1271_debug(DEBUG_MAC80211, "mac80211 sta_rc_update wide %d", wide);
1635 if (WARN_ON(wlvif->bss_type != BSS_TYPE_STA_BSS))
1638 /* ignore the change before association */
1639 if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
1643 * If we started out as wide, we can change the operation mode. If we
1644 * thought this was a 20mhz AP, we have to reconnect
1646 if (wlvif->sta.role_chan_type == NL80211_CHAN_HT40MINUS ||
1647 wlvif->sta.role_chan_type == NL80211_CHAN_HT40PLUS)
1648 wl18xx_acx_peer_ht_operation_mode(wl, wlvif->sta.hlid, wide);
1650 ieee80211_connection_loss(wl12xx_wlvif_to_vif(wlvif));
1653 static int wl18xx_set_peer_cap(struct wl1271 *wl,
1654 struct ieee80211_sta_ht_cap *ht_cap,
1655 bool allow_ht_operation,
1656 u32 rate_set, u8 hlid)
1658 return wl18xx_acx_set_peer_cap(wl, ht_cap, allow_ht_operation,
1662 static bool wl18xx_lnk_high_prio(struct wl1271 *wl, u8 hlid,
1663 struct wl1271_link *lnk)
1666 struct wl18xx_fw_status_priv *status_priv =
1667 (struct wl18xx_fw_status_priv *)wl->fw_status->priv;
1668 unsigned long suspend_bitmap;
1670 /* if we don't have the link map yet, assume they all low prio */
1674 /* suspended links are never high priority */
1675 suspend_bitmap = le32_to_cpu(status_priv->link_suspend_bitmap);
1676 if (test_bit(hlid, &suspend_bitmap))
1679 /* the priority thresholds are taken from FW */
1680 if (test_bit(hlid, &wl->fw_fast_lnk_map) &&
1681 !test_bit(hlid, &wl->ap_fw_ps_map))
1682 thold = status_priv->tx_fast_link_prio_threshold;
1684 thold = status_priv->tx_slow_link_prio_threshold;
1686 return lnk->allocated_pkts < thold;
1689 static bool wl18xx_lnk_low_prio(struct wl1271 *wl, u8 hlid,
1690 struct wl1271_link *lnk)
1693 struct wl18xx_fw_status_priv *status_priv =
1694 (struct wl18xx_fw_status_priv *)wl->fw_status->priv;
1695 unsigned long suspend_bitmap;
1697 /* if we don't have the link map yet, assume they all low prio */
1701 suspend_bitmap = le32_to_cpu(status_priv->link_suspend_bitmap);
1702 if (test_bit(hlid, &suspend_bitmap))
1703 thold = status_priv->tx_suspend_threshold;
1704 else if (test_bit(hlid, &wl->fw_fast_lnk_map) &&
1705 !test_bit(hlid, &wl->ap_fw_ps_map))
1706 thold = status_priv->tx_fast_stop_threshold;
1708 thold = status_priv->tx_slow_stop_threshold;
1710 return lnk->allocated_pkts < thold;
1713 static u32 wl18xx_convert_hwaddr(struct wl1271 *wl, u32 hwaddr)
1715 return hwaddr & ~0x80000000;
1718 static int wl18xx_setup(struct wl1271 *wl);
1720 static struct wlcore_ops wl18xx_ops = {
1721 .setup = wl18xx_setup,
1722 .identify_chip = wl18xx_identify_chip,
1723 .boot = wl18xx_boot,
1724 .plt_init = wl18xx_plt_init,
1725 .trigger_cmd = wl18xx_trigger_cmd,
1726 .ack_event = wl18xx_ack_event,
1727 .wait_for_event = wl18xx_wait_for_event,
1728 .process_mailbox_events = wl18xx_process_mailbox_events,
1729 .calc_tx_blocks = wl18xx_calc_tx_blocks,
1730 .set_tx_desc_blocks = wl18xx_set_tx_desc_blocks,
1731 .set_tx_desc_data_len = wl18xx_set_tx_desc_data_len,
1732 .get_rx_buf_align = wl18xx_get_rx_buf_align,
1733 .get_rx_packet_len = wl18xx_get_rx_packet_len,
1734 .tx_immediate_compl = wl18xx_tx_immediate_completion,
1735 .tx_delayed_compl = NULL,
1736 .hw_init = wl18xx_hw_init,
1737 .convert_fw_status = wl18xx_convert_fw_status,
1738 .set_tx_desc_csum = wl18xx_set_tx_desc_csum,
1739 .get_pg_ver = wl18xx_get_pg_ver,
1740 .set_rx_csum = wl18xx_set_rx_csum,
1741 .sta_get_ap_rate_mask = wl18xx_sta_get_ap_rate_mask,
1742 .ap_get_mimo_wide_rate_mask = wl18xx_ap_get_mimo_wide_rate_mask,
1743 .get_mac = wl18xx_get_mac,
1744 .debugfs_init = wl18xx_debugfs_add_files,
1745 .scan_start = wl18xx_scan_start,
1746 .scan_stop = wl18xx_scan_stop,
1747 .sched_scan_start = wl18xx_sched_scan_start,
1748 .sched_scan_stop = wl18xx_scan_sched_scan_stop,
1749 .handle_static_data = wl18xx_handle_static_data,
1750 .get_spare_blocks = wl18xx_get_spare_blocks,
1751 .set_key = wl18xx_set_key,
1752 .channel_switch = wl18xx_cmd_channel_switch,
1753 .pre_pkt_send = wl18xx_pre_pkt_send,
1754 .sta_rc_update = wl18xx_sta_rc_update,
1755 .set_peer_cap = wl18xx_set_peer_cap,
1756 .convert_hwaddr = wl18xx_convert_hwaddr,
1757 .lnk_high_prio = wl18xx_lnk_high_prio,
1758 .lnk_low_prio = wl18xx_lnk_low_prio,
1759 .smart_config_start = wl18xx_cmd_smart_config_start,
1760 .smart_config_stop = wl18xx_cmd_smart_config_stop,
1761 .smart_config_set_group_key = wl18xx_cmd_smart_config_set_group_key,
1762 .interrupt_notify = wl18xx_acx_interrupt_notify_config,
1763 .rx_ba_filter = wl18xx_acx_rx_ba_filter,
1764 .ap_sleep = wl18xx_acx_ap_sleep,
1765 .set_cac = wl18xx_cmd_set_cac,
1766 .dfs_master_restart = wl18xx_cmd_dfs_master_restart,
1769 /* HT cap appropriate for wide channels in 2Ghz */
1770 static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_2ghz = {
1771 .cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 |
1772 IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_DSSSCCK40 |
1773 IEEE80211_HT_CAP_GRN_FLD,
1774 .ht_supported = true,
1775 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
1776 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
1778 .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
1779 .rx_highest = cpu_to_le16(150),
1780 .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
1784 /* HT cap appropriate for wide channels in 5Ghz */
1785 static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_5ghz = {
1786 .cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 |
1787 IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
1788 IEEE80211_HT_CAP_GRN_FLD,
1789 .ht_supported = true,
1790 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
1791 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
1793 .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
1794 .rx_highest = cpu_to_le16(150),
1795 .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
1799 /* HT cap appropriate for SISO 20 */
1800 static struct ieee80211_sta_ht_cap wl18xx_siso20_ht_cap = {
1801 .cap = IEEE80211_HT_CAP_SGI_20 |
1802 IEEE80211_HT_CAP_GRN_FLD,
1803 .ht_supported = true,
1804 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
1805 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
1807 .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
1808 .rx_highest = cpu_to_le16(72),
1809 .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
1813 /* HT cap appropriate for MIMO rates in 20mhz channel */
1814 static struct ieee80211_sta_ht_cap wl18xx_mimo_ht_cap_2ghz = {
1815 .cap = IEEE80211_HT_CAP_SGI_20 |
1816 IEEE80211_HT_CAP_GRN_FLD,
1817 .ht_supported = true,
1818 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
1819 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
1821 .rx_mask = { 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, },
1822 .rx_highest = cpu_to_le16(144),
1823 .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
1827 static const struct ieee80211_iface_limit wl18xx_iface_limits[] = {
1830 .types = BIT(NL80211_IFTYPE_STATION),
1834 .types = BIT(NL80211_IFTYPE_AP)
1835 | BIT(NL80211_IFTYPE_P2P_GO)
1836 | BIT(NL80211_IFTYPE_P2P_CLIENT)
1837 #ifdef CONFIG_MAC80211_MESH
1838 | BIT(NL80211_IFTYPE_MESH_POINT)
1843 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
1847 static const struct ieee80211_iface_limit wl18xx_iface_ap_limits[] = {
1850 .types = BIT(NL80211_IFTYPE_AP),
1852 #ifdef CONFIG_MAC80211_MESH
1855 .types = BIT(NL80211_IFTYPE_MESH_POINT),
1860 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
1864 static const struct ieee80211_iface_limit wl18xx_iface_ap_cl_limits[] = {
1867 .types = BIT(NL80211_IFTYPE_STATION),
1871 .types = BIT(NL80211_IFTYPE_AP),
1875 .types = BIT(NL80211_IFTYPE_P2P_CLIENT),
1879 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
1883 static const struct ieee80211_iface_limit wl18xx_iface_ap_go_limits[] = {
1886 .types = BIT(NL80211_IFTYPE_STATION),
1890 .types = BIT(NL80211_IFTYPE_AP),
1894 .types = BIT(NL80211_IFTYPE_P2P_GO),
1898 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
1902 static const struct ieee80211_iface_combination
1903 wl18xx_iface_combinations[] = {
1905 .max_interfaces = 3,
1906 .limits = wl18xx_iface_limits,
1907 .n_limits = ARRAY_SIZE(wl18xx_iface_limits),
1908 .num_different_channels = 2,
1911 .max_interfaces = 2,
1912 .limits = wl18xx_iface_ap_limits,
1913 .n_limits = ARRAY_SIZE(wl18xx_iface_ap_limits),
1914 .num_different_channels = 1,
1915 .radar_detect_widths = BIT(NL80211_CHAN_NO_HT) |
1916 BIT(NL80211_CHAN_HT20) |
1917 BIT(NL80211_CHAN_HT40MINUS) |
1918 BIT(NL80211_CHAN_HT40PLUS),
1922 static int wl18xx_setup(struct wl1271 *wl)
1924 struct wl18xx_priv *priv = wl->priv;
1927 BUILD_BUG_ON(WL18XX_MAX_LINKS > WLCORE_MAX_LINKS);
1928 BUILD_BUG_ON(WL18XX_MAX_AP_STATIONS > WL18XX_MAX_LINKS);
1929 BUILD_BUG_ON(WL18XX_CONF_SG_PARAMS_MAX > WLCORE_CONF_SG_PARAMS_MAX);
1931 wl->rtable = wl18xx_rtable;
1932 wl->num_tx_desc = WL18XX_NUM_TX_DESCRIPTORS;
1933 wl->num_rx_desc = WL18XX_NUM_RX_DESCRIPTORS;
1934 wl->num_links = WL18XX_MAX_LINKS;
1935 wl->max_ap_stations = WL18XX_MAX_AP_STATIONS;
1936 wl->iface_combinations = wl18xx_iface_combinations;
1937 wl->n_iface_combinations = ARRAY_SIZE(wl18xx_iface_combinations);
1938 wl->num_mac_addr = WL18XX_NUM_MAC_ADDRESSES;
1939 wl->band_rate_to_idx = wl18xx_band_rate_to_idx;
1940 wl->hw_tx_rate_tbl_size = WL18XX_CONF_HW_RXTX_RATE_MAX;
1941 wl->hw_min_ht_rate = WL18XX_CONF_HW_RXTX_RATE_MCS0;
1942 wl->fw_status_len = sizeof(struct wl18xx_fw_status);
1943 wl->fw_status_priv_len = sizeof(struct wl18xx_fw_status_priv);
1944 wl->stats.fw_stats_len = sizeof(struct wl18xx_acx_statistics);
1945 wl->static_data_priv_len = sizeof(struct wl18xx_static_data_priv);
1947 if (num_rx_desc_param != -1)
1948 wl->num_rx_desc = num_rx_desc_param;
1950 ret = wl18xx_conf_init(wl, wl->dev);
1954 /* If the module param is set, update it in conf */
1955 if (board_type_param) {
1956 if (!strcmp(board_type_param, "fpga")) {
1957 priv->conf.phy.board_type = BOARD_TYPE_FPGA_18XX;
1958 } else if (!strcmp(board_type_param, "hdk")) {
1959 priv->conf.phy.board_type = BOARD_TYPE_HDK_18XX;
1960 } else if (!strcmp(board_type_param, "dvp")) {
1961 priv->conf.phy.board_type = BOARD_TYPE_DVP_18XX;
1962 } else if (!strcmp(board_type_param, "evb")) {
1963 priv->conf.phy.board_type = BOARD_TYPE_EVB_18XX;
1964 } else if (!strcmp(board_type_param, "com8")) {
1965 priv->conf.phy.board_type = BOARD_TYPE_COM8_18XX;
1967 wl1271_error("invalid board type '%s'",
1973 if (priv->conf.phy.board_type >= NUM_BOARD_TYPES) {
1974 wl1271_error("invalid board type '%d'",
1975 priv->conf.phy.board_type);
1979 if (low_band_component_param != -1)
1980 priv->conf.phy.low_band_component = low_band_component_param;
1981 if (low_band_component_type_param != -1)
1982 priv->conf.phy.low_band_component_type =
1983 low_band_component_type_param;
1984 if (high_band_component_param != -1)
1985 priv->conf.phy.high_band_component = high_band_component_param;
1986 if (high_band_component_type_param != -1)
1987 priv->conf.phy.high_band_component_type =
1988 high_band_component_type_param;
1989 if (pwr_limit_reference_11_abg_param != -1)
1990 priv->conf.phy.pwr_limit_reference_11_abg =
1991 pwr_limit_reference_11_abg_param;
1992 if (n_antennas_2_param != -1)
1993 priv->conf.phy.number_of_assembled_ant2_4 = n_antennas_2_param;
1994 if (n_antennas_5_param != -1)
1995 priv->conf.phy.number_of_assembled_ant5 = n_antennas_5_param;
1996 if (dc2dc_param != -1)
1997 priv->conf.phy.external_pa_dc2dc = dc2dc_param;
1999 if (ht_mode_param) {
2000 if (!strcmp(ht_mode_param, "default"))
2001 priv->conf.ht.mode = HT_MODE_DEFAULT;
2002 else if (!strcmp(ht_mode_param, "wide"))
2003 priv->conf.ht.mode = HT_MODE_WIDE;
2004 else if (!strcmp(ht_mode_param, "siso20"))
2005 priv->conf.ht.mode = HT_MODE_SISO20;
2007 wl1271_error("invalid ht_mode '%s'", ht_mode_param);
2012 if (priv->conf.ht.mode == HT_MODE_DEFAULT) {
2014 * Only support mimo with multiple antennas. Fall back to
2017 if (wl18xx_is_mimo_supported(wl))
2018 wlcore_set_ht_cap(wl, NL80211_BAND_2GHZ,
2019 &wl18xx_mimo_ht_cap_2ghz);
2021 wlcore_set_ht_cap(wl, NL80211_BAND_2GHZ,
2022 &wl18xx_siso40_ht_cap_2ghz);
2024 /* 5Ghz is always wide */
2025 wlcore_set_ht_cap(wl, NL80211_BAND_5GHZ,
2026 &wl18xx_siso40_ht_cap_5ghz);
2027 } else if (priv->conf.ht.mode == HT_MODE_WIDE) {
2028 wlcore_set_ht_cap(wl, NL80211_BAND_2GHZ,
2029 &wl18xx_siso40_ht_cap_2ghz);
2030 wlcore_set_ht_cap(wl, NL80211_BAND_5GHZ,
2031 &wl18xx_siso40_ht_cap_5ghz);
2032 } else if (priv->conf.ht.mode == HT_MODE_SISO20) {
2033 wlcore_set_ht_cap(wl, NL80211_BAND_2GHZ,
2034 &wl18xx_siso20_ht_cap);
2035 wlcore_set_ht_cap(wl, NL80211_BAND_5GHZ,
2036 &wl18xx_siso20_ht_cap);
2039 if (!checksum_param) {
2040 wl18xx_ops.set_rx_csum = NULL;
2041 wl18xx_ops.init_vif = NULL;
2044 /* Enable 11a Band only if we have 5G antennas */
2045 wl->enable_11a = (priv->conf.phy.number_of_assembled_ant5 != 0);
2050 static int wl18xx_probe(struct platform_device *pdev)
2053 struct ieee80211_hw *hw;
2056 hw = wlcore_alloc_hw(sizeof(struct wl18xx_priv),
2057 WL18XX_AGGR_BUFFER_SIZE,
2058 sizeof(struct wl18xx_event_mailbox));
2060 wl1271_error("can't allocate hw");
2066 wl->ops = &wl18xx_ops;
2067 wl->ptable = wl18xx_ptable;
2068 ret = wlcore_probe(wl, pdev);
2080 static const struct platform_device_id wl18xx_id_table[] = {
2082 { } /* Terminating Entry */
2084 MODULE_DEVICE_TABLE(platform, wl18xx_id_table);
2086 static struct platform_driver wl18xx_driver = {
2087 .probe = wl18xx_probe,
2088 .remove = wlcore_remove,
2089 .id_table = wl18xx_id_table,
2091 .name = "wl18xx_driver",
2095 module_platform_driver(wl18xx_driver);
2096 module_param_named(ht_mode, ht_mode_param, charp, 0400);
2097 MODULE_PARM_DESC(ht_mode, "Force HT mode: wide or siso20");
2099 module_param_named(board_type, board_type_param, charp, 0400);
2100 MODULE_PARM_DESC(board_type, "Board type: fpga, hdk (default), evb, com8 or "
2103 module_param_named(checksum, checksum_param, bool, 0400);
2104 MODULE_PARM_DESC(checksum, "Enable TCP checksum: boolean (defaults to false)");
2106 module_param_named(dc2dc, dc2dc_param, int, 0400);
2107 MODULE_PARM_DESC(dc2dc, "External DC2DC: u8 (defaults to 0)");
2109 module_param_named(n_antennas_2, n_antennas_2_param, int, 0400);
2110 MODULE_PARM_DESC(n_antennas_2,
2111 "Number of installed 2.4GHz antennas: 1 (default) or 2");
2113 module_param_named(n_antennas_5, n_antennas_5_param, int, 0400);
2114 MODULE_PARM_DESC(n_antennas_5,
2115 "Number of installed 5GHz antennas: 1 (default) or 2");
2117 module_param_named(low_band_component, low_band_component_param, int, 0400);
2118 MODULE_PARM_DESC(low_band_component, "Low band component: u8 "
2119 "(default is 0x01)");
2121 module_param_named(low_band_component_type, low_band_component_type_param,
2123 MODULE_PARM_DESC(low_band_component_type, "Low band component type: u8 "
2124 "(default is 0x05 or 0x06 depending on the board_type)");
2126 module_param_named(high_band_component, high_band_component_param, int, 0400);
2127 MODULE_PARM_DESC(high_band_component, "High band component: u8, "
2128 "(default is 0x01)");
2130 module_param_named(high_band_component_type, high_band_component_type_param,
2132 MODULE_PARM_DESC(high_band_component_type, "High band component type: u8 "
2133 "(default is 0x09)");
2135 module_param_named(pwr_limit_reference_11_abg,
2136 pwr_limit_reference_11_abg_param, int, 0400);
2137 MODULE_PARM_DESC(pwr_limit_reference_11_abg, "Power limit reference: u8 "
2138 "(default is 0xc8)");
2140 module_param_named(num_rx_desc, num_rx_desc_param, int, 0400);
2141 MODULE_PARM_DESC(num_rx_desc_param,
2142 "Number of Rx descriptors: u8 (default is 32)");
2144 MODULE_LICENSE("GPL v2");
2145 MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");