xref: /openbmc/linux/drivers/net/wireless/ti/wl18xx/main.c (revision 4f3db074)
1 /*
2  * This file is part of wl18xx
3  *
4  * Copyright (C) 2011 Texas Instruments
5  *
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.
9  *
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.
14  *
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
18  * 02110-1301 USA
19  *
20  */
21 
22 #include <linux/module.h>
23 #include <linux/platform_device.h>
24 #include <linux/ip.h>
25 #include <linux/firmware.h>
26 #include <linux/etherdevice.h>
27 
28 #include "../wlcore/wlcore.h"
29 #include "../wlcore/debug.h"
30 #include "../wlcore/io.h"
31 #include "../wlcore/acx.h"
32 #include "../wlcore/tx.h"
33 #include "../wlcore/rx.h"
34 #include "../wlcore/boot.h"
35 
36 #include "reg.h"
37 #include "conf.h"
38 #include "cmd.h"
39 #include "acx.h"
40 #include "tx.h"
41 #include "wl18xx.h"
42 #include "io.h"
43 #include "scan.h"
44 #include "event.h"
45 #include "debugfs.h"
46 
47 #define WL18XX_RX_CHECKSUM_MASK      0x40
48 
49 static char *ht_mode_param = NULL;
50 static char *board_type_param = NULL;
51 static bool checksum_param = false;
52 static int num_rx_desc_param = -1;
53 
54 /* phy paramters */
55 static int dc2dc_param = -1;
56 static int n_antennas_2_param = -1;
57 static int n_antennas_5_param = -1;
58 static int low_band_component_param = -1;
59 static int low_band_component_type_param = -1;
60 static int high_band_component_param = -1;
61 static int high_band_component_type_param = -1;
62 static int pwr_limit_reference_11_abg_param = -1;
63 
64 static const u8 wl18xx_rate_to_idx_2ghz[] = {
65 	/* MCS rates are used only with 11n */
66 	15,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS15 */
67 	14,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS14 */
68 	13,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS13 */
69 	12,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS12 */
70 	11,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS11 */
71 	10,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS10 */
72 	9,                             /* WL18XX_CONF_HW_RXTX_RATE_MCS9 */
73 	8,                             /* WL18XX_CONF_HW_RXTX_RATE_MCS8 */
74 	7,                             /* WL18XX_CONF_HW_RXTX_RATE_MCS7 */
75 	6,                             /* WL18XX_CONF_HW_RXTX_RATE_MCS6 */
76 	5,                             /* WL18XX_CONF_HW_RXTX_RATE_MCS5 */
77 	4,                             /* WL18XX_CONF_HW_RXTX_RATE_MCS4 */
78 	3,                             /* WL18XX_CONF_HW_RXTX_RATE_MCS3 */
79 	2,                             /* WL18XX_CONF_HW_RXTX_RATE_MCS2 */
80 	1,                             /* WL18XX_CONF_HW_RXTX_RATE_MCS1 */
81 	0,                             /* WL18XX_CONF_HW_RXTX_RATE_MCS0 */
82 
83 	11,                            /* WL18XX_CONF_HW_RXTX_RATE_54   */
84 	10,                            /* WL18XX_CONF_HW_RXTX_RATE_48   */
85 	9,                             /* WL18XX_CONF_HW_RXTX_RATE_36   */
86 	8,                             /* WL18XX_CONF_HW_RXTX_RATE_24   */
87 
88 	/* TI-specific rate */
89 	CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_22   */
90 
91 	7,                             /* WL18XX_CONF_HW_RXTX_RATE_18   */
92 	6,                             /* WL18XX_CONF_HW_RXTX_RATE_12   */
93 	3,                             /* WL18XX_CONF_HW_RXTX_RATE_11   */
94 	5,                             /* WL18XX_CONF_HW_RXTX_RATE_9    */
95 	4,                             /* WL18XX_CONF_HW_RXTX_RATE_6    */
96 	2,                             /* WL18XX_CONF_HW_RXTX_RATE_5_5  */
97 	1,                             /* WL18XX_CONF_HW_RXTX_RATE_2    */
98 	0                              /* WL18XX_CONF_HW_RXTX_RATE_1    */
99 };
100 
101 static const u8 wl18xx_rate_to_idx_5ghz[] = {
102 	/* MCS rates are used only with 11n */
103 	15,                           /* WL18XX_CONF_HW_RXTX_RATE_MCS15 */
104 	14,                           /* WL18XX_CONF_HW_RXTX_RATE_MCS14 */
105 	13,                           /* WL18XX_CONF_HW_RXTX_RATE_MCS13 */
106 	12,                           /* WL18XX_CONF_HW_RXTX_RATE_MCS12 */
107 	11,                           /* WL18XX_CONF_HW_RXTX_RATE_MCS11 */
108 	10,                           /* WL18XX_CONF_HW_RXTX_RATE_MCS10 */
109 	9,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS9 */
110 	8,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS8 */
111 	7,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS7 */
112 	6,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS6 */
113 	5,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS5 */
114 	4,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS4 */
115 	3,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS3 */
116 	2,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS2 */
117 	1,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS1 */
118 	0,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS0 */
119 
120 	7,                             /* WL18XX_CONF_HW_RXTX_RATE_54   */
121 	6,                             /* WL18XX_CONF_HW_RXTX_RATE_48   */
122 	5,                             /* WL18XX_CONF_HW_RXTX_RATE_36   */
123 	4,                             /* WL18XX_CONF_HW_RXTX_RATE_24   */
124 
125 	/* TI-specific rate */
126 	CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_22   */
127 
128 	3,                             /* WL18XX_CONF_HW_RXTX_RATE_18   */
129 	2,                             /* WL18XX_CONF_HW_RXTX_RATE_12   */
130 	CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_11   */
131 	1,                             /* WL18XX_CONF_HW_RXTX_RATE_9    */
132 	0,                             /* WL18XX_CONF_HW_RXTX_RATE_6    */
133 	CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_5_5  */
134 	CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_2    */
135 	CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_1    */
136 };
137 
138 static const u8 *wl18xx_band_rate_to_idx[] = {
139 	[IEEE80211_BAND_2GHZ] = wl18xx_rate_to_idx_2ghz,
140 	[IEEE80211_BAND_5GHZ] = wl18xx_rate_to_idx_5ghz
141 };
142 
143 enum wl18xx_hw_rates {
144 	WL18XX_CONF_HW_RXTX_RATE_MCS15 = 0,
145 	WL18XX_CONF_HW_RXTX_RATE_MCS14,
146 	WL18XX_CONF_HW_RXTX_RATE_MCS13,
147 	WL18XX_CONF_HW_RXTX_RATE_MCS12,
148 	WL18XX_CONF_HW_RXTX_RATE_MCS11,
149 	WL18XX_CONF_HW_RXTX_RATE_MCS10,
150 	WL18XX_CONF_HW_RXTX_RATE_MCS9,
151 	WL18XX_CONF_HW_RXTX_RATE_MCS8,
152 	WL18XX_CONF_HW_RXTX_RATE_MCS7,
153 	WL18XX_CONF_HW_RXTX_RATE_MCS6,
154 	WL18XX_CONF_HW_RXTX_RATE_MCS5,
155 	WL18XX_CONF_HW_RXTX_RATE_MCS4,
156 	WL18XX_CONF_HW_RXTX_RATE_MCS3,
157 	WL18XX_CONF_HW_RXTX_RATE_MCS2,
158 	WL18XX_CONF_HW_RXTX_RATE_MCS1,
159 	WL18XX_CONF_HW_RXTX_RATE_MCS0,
160 	WL18XX_CONF_HW_RXTX_RATE_54,
161 	WL18XX_CONF_HW_RXTX_RATE_48,
162 	WL18XX_CONF_HW_RXTX_RATE_36,
163 	WL18XX_CONF_HW_RXTX_RATE_24,
164 	WL18XX_CONF_HW_RXTX_RATE_22,
165 	WL18XX_CONF_HW_RXTX_RATE_18,
166 	WL18XX_CONF_HW_RXTX_RATE_12,
167 	WL18XX_CONF_HW_RXTX_RATE_11,
168 	WL18XX_CONF_HW_RXTX_RATE_9,
169 	WL18XX_CONF_HW_RXTX_RATE_6,
170 	WL18XX_CONF_HW_RXTX_RATE_5_5,
171 	WL18XX_CONF_HW_RXTX_RATE_2,
172 	WL18XX_CONF_HW_RXTX_RATE_1,
173 	WL18XX_CONF_HW_RXTX_RATE_MAX,
174 };
175 
176 static struct wlcore_conf wl18xx_conf = {
177 	.sg = {
178 		.params = {
179 			[CONF_SG_ACL_BT_MASTER_MIN_BR] = 10,
180 			[CONF_SG_ACL_BT_MASTER_MAX_BR] = 180,
181 			[CONF_SG_ACL_BT_SLAVE_MIN_BR] = 10,
182 			[CONF_SG_ACL_BT_SLAVE_MAX_BR] = 180,
183 			[CONF_SG_ACL_BT_MASTER_MIN_EDR] = 10,
184 			[CONF_SG_ACL_BT_MASTER_MAX_EDR] = 80,
185 			[CONF_SG_ACL_BT_SLAVE_MIN_EDR] = 10,
186 			[CONF_SG_ACL_BT_SLAVE_MAX_EDR] = 80,
187 			[CONF_SG_ACL_WLAN_PS_MASTER_BR] = 8,
188 			[CONF_SG_ACL_WLAN_PS_SLAVE_BR] = 8,
189 			[CONF_SG_ACL_WLAN_PS_MASTER_EDR] = 20,
190 			[CONF_SG_ACL_WLAN_PS_SLAVE_EDR] = 20,
191 			[CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_BR] = 20,
192 			[CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_BR] = 35,
193 			[CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_BR] = 16,
194 			[CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_BR] = 35,
195 			[CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_EDR] = 32,
196 			[CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_EDR] = 50,
197 			[CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_EDR] = 28,
198 			[CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_EDR] = 50,
199 			[CONF_SG_ACL_ACTIVE_SCAN_WLAN_BR] = 10,
200 			[CONF_SG_ACL_ACTIVE_SCAN_WLAN_EDR] = 20,
201 			[CONF_SG_ACL_PASSIVE_SCAN_BT_BR] = 75,
202 			[CONF_SG_ACL_PASSIVE_SCAN_WLAN_BR] = 15,
203 			[CONF_SG_ACL_PASSIVE_SCAN_BT_EDR] = 27,
204 			[CONF_SG_ACL_PASSIVE_SCAN_WLAN_EDR] = 17,
205 			/* active scan params */
206 			[CONF_SG_AUTO_SCAN_PROBE_REQ] = 170,
207 			[CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3] = 50,
208 			[CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP] = 100,
209 			/* passive scan params */
210 			[CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP_BR] = 800,
211 			[CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP_EDR] = 200,
212 			[CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3] = 200,
213 			/* passive scan in dual antenna params */
214 			[CONF_SG_CONSECUTIVE_HV3_IN_PASSIVE_SCAN] = 0,
215 			[CONF_SG_BCN_HV3_COLLISION_THRESH_IN_PASSIVE_SCAN] = 0,
216 			[CONF_SG_TX_RX_PROTECTION_BWIDTH_IN_PASSIVE_SCAN] = 0,
217 			/* general params */
218 			[CONF_SG_STA_FORCE_PS_IN_BT_SCO] = 1,
219 			[CONF_SG_ANTENNA_CONFIGURATION] = 0,
220 			[CONF_SG_BEACON_MISS_PERCENT] = 60,
221 			[CONF_SG_DHCP_TIME] = 5000,
222 			[CONF_SG_RXT] = 1200,
223 			[CONF_SG_TXT] = 1000,
224 			[CONF_SG_ADAPTIVE_RXT_TXT] = 1,
225 			[CONF_SG_GENERAL_USAGE_BIT_MAP] = 3,
226 			[CONF_SG_HV3_MAX_SERVED] = 6,
227 			[CONF_SG_PS_POLL_TIMEOUT] = 10,
228 			[CONF_SG_UPSD_TIMEOUT] = 10,
229 			[CONF_SG_CONSECUTIVE_CTS_THRESHOLD] = 2,
230 			[CONF_SG_STA_RX_WINDOW_AFTER_DTIM] = 5,
231 			[CONF_SG_STA_CONNECTION_PROTECTION_TIME] = 30,
232 			/* AP params */
233 			[CONF_AP_BEACON_MISS_TX] = 3,
234 			[CONF_AP_RX_WINDOW_AFTER_BEACON] = 10,
235 			[CONF_AP_BEACON_WINDOW_INTERVAL] = 2,
236 			[CONF_AP_CONNECTION_PROTECTION_TIME] = 0,
237 			[CONF_AP_BT_ACL_VAL_BT_SERVE_TIME] = 25,
238 			[CONF_AP_BT_ACL_VAL_WL_SERVE_TIME] = 25,
239 			/* CTS Diluting params */
240 			[CONF_SG_CTS_DILUTED_BAD_RX_PACKETS_TH] = 0,
241 			[CONF_SG_CTS_CHOP_IN_DUAL_ANT_SCO_MASTER] = 0,
242 		},
243 		.state = CONF_SG_PROTECTIVE,
244 	},
245 	.rx = {
246 		.rx_msdu_life_time           = 512000,
247 		.packet_detection_threshold  = 0,
248 		.ps_poll_timeout             = 15,
249 		.upsd_timeout                = 15,
250 		.rts_threshold               = IEEE80211_MAX_RTS_THRESHOLD,
251 		.rx_cca_threshold            = 0,
252 		.irq_blk_threshold           = 0xFFFF,
253 		.irq_pkt_threshold           = 0,
254 		.irq_timeout                 = 600,
255 		.queue_type                  = CONF_RX_QUEUE_TYPE_LOW_PRIORITY,
256 	},
257 	.tx = {
258 		.tx_energy_detection         = 0,
259 		.sta_rc_conf                 = {
260 			.enabled_rates       = 0,
261 			.short_retry_limit   = 10,
262 			.long_retry_limit    = 10,
263 			.aflags              = 0,
264 		},
265 		.ac_conf_count               = 4,
266 		.ac_conf                     = {
267 			[CONF_TX_AC_BE] = {
268 				.ac          = CONF_TX_AC_BE,
269 				.cw_min      = 15,
270 				.cw_max      = 63,
271 				.aifsn       = 3,
272 				.tx_op_limit = 0,
273 			},
274 			[CONF_TX_AC_BK] = {
275 				.ac          = CONF_TX_AC_BK,
276 				.cw_min      = 15,
277 				.cw_max      = 63,
278 				.aifsn       = 7,
279 				.tx_op_limit = 0,
280 			},
281 			[CONF_TX_AC_VI] = {
282 				.ac          = CONF_TX_AC_VI,
283 				.cw_min      = 15,
284 				.cw_max      = 63,
285 				.aifsn       = CONF_TX_AIFS_PIFS,
286 				.tx_op_limit = 3008,
287 			},
288 			[CONF_TX_AC_VO] = {
289 				.ac          = CONF_TX_AC_VO,
290 				.cw_min      = 15,
291 				.cw_max      = 63,
292 				.aifsn       = CONF_TX_AIFS_PIFS,
293 				.tx_op_limit = 1504,
294 			},
295 		},
296 		.max_tx_retries = 100,
297 		.ap_aging_period = 300,
298 		.tid_conf_count = 4,
299 		.tid_conf = {
300 			[CONF_TX_AC_BE] = {
301 				.queue_id    = CONF_TX_AC_BE,
302 				.channel_type = CONF_CHANNEL_TYPE_EDCF,
303 				.tsid        = CONF_TX_AC_BE,
304 				.ps_scheme   = CONF_PS_SCHEME_LEGACY,
305 				.ack_policy  = CONF_ACK_POLICY_LEGACY,
306 				.apsd_conf   = {0, 0},
307 			},
308 			[CONF_TX_AC_BK] = {
309 				.queue_id    = CONF_TX_AC_BK,
310 				.channel_type = CONF_CHANNEL_TYPE_EDCF,
311 				.tsid        = CONF_TX_AC_BK,
312 				.ps_scheme   = CONF_PS_SCHEME_LEGACY,
313 				.ack_policy  = CONF_ACK_POLICY_LEGACY,
314 				.apsd_conf   = {0, 0},
315 			},
316 			[CONF_TX_AC_VI] = {
317 				.queue_id    = CONF_TX_AC_VI,
318 				.channel_type = CONF_CHANNEL_TYPE_EDCF,
319 				.tsid        = CONF_TX_AC_VI,
320 				.ps_scheme   = CONF_PS_SCHEME_LEGACY,
321 				.ack_policy  = CONF_ACK_POLICY_LEGACY,
322 				.apsd_conf   = {0, 0},
323 			},
324 			[CONF_TX_AC_VO] = {
325 				.queue_id    = CONF_TX_AC_VO,
326 				.channel_type = CONF_CHANNEL_TYPE_EDCF,
327 				.tsid        = CONF_TX_AC_VO,
328 				.ps_scheme   = CONF_PS_SCHEME_LEGACY,
329 				.ack_policy  = CONF_ACK_POLICY_LEGACY,
330 				.apsd_conf   = {0, 0},
331 			},
332 		},
333 		.frag_threshold              = IEEE80211_MAX_FRAG_THRESHOLD,
334 		.tx_compl_timeout            = 350,
335 		.tx_compl_threshold          = 10,
336 		.basic_rate                  = CONF_HW_BIT_RATE_1MBPS,
337 		.basic_rate_5                = CONF_HW_BIT_RATE_6MBPS,
338 		.tmpl_short_retry_limit      = 10,
339 		.tmpl_long_retry_limit       = 10,
340 		.tx_watchdog_timeout         = 5000,
341 		.slow_link_thold             = 3,
342 		.fast_link_thold             = 30,
343 	},
344 	.conn = {
345 		.wake_up_event               = CONF_WAKE_UP_EVENT_DTIM,
346 		.listen_interval             = 1,
347 		.suspend_wake_up_event       = CONF_WAKE_UP_EVENT_N_DTIM,
348 		.suspend_listen_interval     = 3,
349 		.bcn_filt_mode               = CONF_BCN_FILT_MODE_ENABLED,
350 		.bcn_filt_ie_count           = 3,
351 		.bcn_filt_ie = {
352 			[0] = {
353 				.ie          = WLAN_EID_CHANNEL_SWITCH,
354 				.rule        = CONF_BCN_RULE_PASS_ON_APPEARANCE,
355 			},
356 			[1] = {
357 				.ie          = WLAN_EID_HT_OPERATION,
358 				.rule        = CONF_BCN_RULE_PASS_ON_CHANGE,
359 			},
360 			[2] = {
361 				.ie	     = WLAN_EID_ERP_INFO,
362 				.rule	     = CONF_BCN_RULE_PASS_ON_CHANGE,
363 			},
364 		},
365 		.synch_fail_thold            = 12,
366 		.bss_lose_timeout            = 400,
367 		.beacon_rx_timeout           = 10000,
368 		.broadcast_timeout           = 20000,
369 		.rx_broadcast_in_ps          = 1,
370 		.ps_poll_threshold           = 10,
371 		.bet_enable                  = CONF_BET_MODE_ENABLE,
372 		.bet_max_consecutive         = 50,
373 		.psm_entry_retries           = 8,
374 		.psm_exit_retries            = 16,
375 		.psm_entry_nullfunc_retries  = 3,
376 		.dynamic_ps_timeout          = 1500,
377 		.forced_ps                   = false,
378 		.keep_alive_interval         = 55000,
379 		.max_listen_interval         = 20,
380 		.sta_sleep_auth              = WL1271_PSM_ILLEGAL,
381 		.suspend_rx_ba_activity      = 0,
382 	},
383 	.itrim = {
384 		.enable = false,
385 		.timeout = 50000,
386 	},
387 	.pm_config = {
388 		.host_clk_settling_time = 5000,
389 		.host_fast_wakeup_support = CONF_FAST_WAKEUP_DISABLE,
390 	},
391 	.roam_trigger = {
392 		.trigger_pacing               = 1,
393 		.avg_weight_rssi_beacon       = 20,
394 		.avg_weight_rssi_data         = 10,
395 		.avg_weight_snr_beacon        = 20,
396 		.avg_weight_snr_data          = 10,
397 	},
398 	.scan = {
399 		.min_dwell_time_active        = 7500,
400 		.max_dwell_time_active        = 30000,
401 		.min_dwell_time_active_long   = 25000,
402 		.max_dwell_time_active_long   = 50000,
403 		.dwell_time_passive           = 100000,
404 		.dwell_time_dfs               = 150000,
405 		.num_probe_reqs               = 2,
406 		.split_scan_timeout           = 50000,
407 	},
408 	.sched_scan = {
409 		/*
410 		 * Values are in TU/1000 but since sched scan FW command
411 		 * params are in TUs rounding up may occur.
412 		 */
413 		.base_dwell_time		= 7500,
414 		.max_dwell_time_delta		= 22500,
415 		/* based on 250bits per probe @1Mbps */
416 		.dwell_time_delta_per_probe	= 2000,
417 		/* based on 250bits per probe @6Mbps (plus a bit more) */
418 		.dwell_time_delta_per_probe_5	= 350,
419 		.dwell_time_passive		= 100000,
420 		.dwell_time_dfs			= 150000,
421 		.num_probe_reqs			= 2,
422 		.rssi_threshold			= -90,
423 		.snr_threshold			= 0,
424 	},
425 	.ht = {
426 		.rx_ba_win_size = 32,
427 		.tx_ba_win_size = 64,
428 		.inactivity_timeout = 10000,
429 		.tx_ba_tid_bitmap = CONF_TX_BA_ENABLED_TID_BITMAP,
430 	},
431 	.mem = {
432 		.num_stations                 = 1,
433 		.ssid_profiles                = 1,
434 		.rx_block_num                 = 40,
435 		.tx_min_block_num             = 40,
436 		.dynamic_memory               = 1,
437 		.min_req_tx_blocks            = 45,
438 		.min_req_rx_blocks            = 22,
439 		.tx_min                       = 27,
440 	},
441 	.fm_coex = {
442 		.enable                       = true,
443 		.swallow_period               = 5,
444 		.n_divider_fref_set_1         = 0xff,       /* default */
445 		.n_divider_fref_set_2         = 12,
446 		.m_divider_fref_set_1         = 0xffff,
447 		.m_divider_fref_set_2         = 148,        /* default */
448 		.coex_pll_stabilization_time  = 0xffffffff, /* default */
449 		.ldo_stabilization_time       = 0xffff,     /* default */
450 		.fm_disturbed_band_margin     = 0xff,       /* default */
451 		.swallow_clk_diff             = 0xff,       /* default */
452 	},
453 	.rx_streaming = {
454 		.duration                      = 150,
455 		.queues                        = 0x1,
456 		.interval                      = 20,
457 		.always                        = 0,
458 	},
459 	.fwlog = {
460 		.mode                         = WL12XX_FWLOG_CONTINUOUS,
461 		.mem_blocks                   = 2,
462 		.severity                     = 0,
463 		.timestamp                    = WL12XX_FWLOG_TIMESTAMP_DISABLED,
464 		.output                       = WL12XX_FWLOG_OUTPUT_DBG_PINS,
465 		.threshold                    = 0,
466 	},
467 	.rate = {
468 		.rate_retry_score = 32000,
469 		.per_add = 8192,
470 		.per_th1 = 2048,
471 		.per_th2 = 4096,
472 		.max_per = 8100,
473 		.inverse_curiosity_factor = 5,
474 		.tx_fail_low_th = 4,
475 		.tx_fail_high_th = 10,
476 		.per_alpha_shift = 4,
477 		.per_add_shift = 13,
478 		.per_beta1_shift = 10,
479 		.per_beta2_shift = 8,
480 		.rate_check_up = 2,
481 		.rate_check_down = 12,
482 		.rate_retry_policy = {
483 			0x00, 0x00, 0x00, 0x00, 0x00,
484 			0x00, 0x00, 0x00, 0x00, 0x00,
485 			0x00, 0x00, 0x00,
486 		},
487 	},
488 	.hangover = {
489 		.recover_time               = 0,
490 		.hangover_period            = 20,
491 		.dynamic_mode               = 1,
492 		.early_termination_mode     = 1,
493 		.max_period                 = 20,
494 		.min_period                 = 1,
495 		.increase_delta             = 1,
496 		.decrease_delta             = 2,
497 		.quiet_time                 = 4,
498 		.increase_time              = 1,
499 		.window_size                = 16,
500 	},
501 	.recovery = {
502 		.bug_on_recovery	    = 0,
503 		.no_recovery		    = 0,
504 	},
505 };
506 
507 static struct wl18xx_priv_conf wl18xx_default_priv_conf = {
508 	.ht = {
509 		.mode				= HT_MODE_WIDE,
510 	},
511 	.phy = {
512 		.phy_standalone			= 0x00,
513 		.primary_clock_setting_time	= 0x05,
514 		.clock_valid_on_wake_up		= 0x00,
515 		.secondary_clock_setting_time	= 0x05,
516 		.board_type 			= BOARD_TYPE_HDK_18XX,
517 		.auto_detect			= 0x00,
518 		.dedicated_fem			= FEM_NONE,
519 		.low_band_component		= COMPONENT_3_WAY_SWITCH,
520 		.low_band_component_type	= 0x05,
521 		.high_band_component		= COMPONENT_2_WAY_SWITCH,
522 		.high_band_component_type	= 0x09,
523 		.tcxo_ldo_voltage		= 0x00,
524 		.xtal_itrim_val			= 0x04,
525 		.srf_state			= 0x00,
526 		.io_configuration		= 0x01,
527 		.sdio_configuration		= 0x00,
528 		.settings			= 0x00,
529 		.enable_clpc			= 0x00,
530 		.enable_tx_low_pwr_on_siso_rdl	= 0x00,
531 		.rx_profile			= 0x00,
532 		.pwr_limit_reference_11_abg	= 0x64,
533 		.per_chan_pwr_limit_arr_11abg	= {
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, 0xff, 0xff, 0xff,
549 			0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
550 			0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
551 		.pwr_limit_reference_11p	= 0x64,
552 		.per_chan_bo_mode_11_abg	= { 0x00, 0x00, 0x00, 0x00,
553 						    0x00, 0x00, 0x00, 0x00,
554 						    0x00, 0x00, 0x00, 0x00,
555 						    0x00 },
556 		.per_chan_bo_mode_11_p		= { 0x00, 0x00, 0x00, 0x00 },
557 		.per_chan_pwr_limit_arr_11p	= { 0xff, 0xff, 0xff, 0xff,
558 						    0xff, 0xff, 0xff },
559 		.psat				= 0,
560 		.external_pa_dc2dc		= 0,
561 		.number_of_assembled_ant2_4	= 2,
562 		.number_of_assembled_ant5	= 1,
563 		.low_power_val			= 0xff,
564 		.med_power_val			= 0xff,
565 		.high_power_val			= 0xff,
566 		.low_power_val_2nd		= 0xff,
567 		.med_power_val_2nd		= 0xff,
568 		.high_power_val_2nd		= 0xff,
569 		.tx_rf_margin			= 1,
570 	},
571 	.ap_sleep = {               /* disabled by default */
572 		.idle_duty_cycle        = 0,
573 		.connected_duty_cycle   = 0,
574 		.max_stations_thresh    = 0,
575 		.idle_conn_thresh       = 0,
576 	},
577 };
578 
579 static const struct wlcore_partition_set wl18xx_ptable[PART_TABLE_LEN] = {
580 	[PART_TOP_PRCM_ELP_SOC] = {
581 		.mem  = { .start = 0x00A02000, .size  = 0x00010000 },
582 		.reg  = { .start = 0x00807000, .size  = 0x00005000 },
583 		.mem2 = { .start = 0x00800000, .size  = 0x0000B000 },
584 		.mem3 = { .start = 0x00000000, .size  = 0x00000000 },
585 	},
586 	[PART_DOWN] = {
587 		.mem  = { .start = 0x00000000, .size  = 0x00014000 },
588 		.reg  = { .start = 0x00810000, .size  = 0x0000BFFF },
589 		.mem2 = { .start = 0x00000000, .size  = 0x00000000 },
590 		.mem3 = { .start = 0x00000000, .size  = 0x00000000 },
591 	},
592 	[PART_BOOT] = {
593 		.mem  = { .start = 0x00700000, .size = 0x0000030c },
594 		.reg  = { .start = 0x00802000, .size = 0x00014578 },
595 		.mem2 = { .start = 0x00B00404, .size = 0x00001000 },
596 		.mem3 = { .start = 0x00C00000, .size = 0x00000400 },
597 	},
598 	[PART_WORK] = {
599 		.mem  = { .start = 0x00800000, .size  = 0x000050FC },
600 		.reg  = { .start = 0x00B00404, .size  = 0x00001000 },
601 		.mem2 = { .start = 0x00C00000, .size  = 0x00000400 },
602 		.mem3 = { .start = 0x00000000, .size  = 0x00000000 },
603 	},
604 	[PART_PHY_INIT] = {
605 		.mem  = { .start = WL18XX_PHY_INIT_MEM_ADDR,
606 			  .size  = WL18XX_PHY_INIT_MEM_SIZE },
607 		.reg  = { .start = 0x00000000, .size = 0x00000000 },
608 		.mem2 = { .start = 0x00000000, .size = 0x00000000 },
609 		.mem3 = { .start = 0x00000000, .size = 0x00000000 },
610 	},
611 };
612 
613 static const int wl18xx_rtable[REG_TABLE_LEN] = {
614 	[REG_ECPU_CONTROL]		= WL18XX_REG_ECPU_CONTROL,
615 	[REG_INTERRUPT_NO_CLEAR]	= WL18XX_REG_INTERRUPT_NO_CLEAR,
616 	[REG_INTERRUPT_ACK]		= WL18XX_REG_INTERRUPT_ACK,
617 	[REG_COMMAND_MAILBOX_PTR]	= WL18XX_REG_COMMAND_MAILBOX_PTR,
618 	[REG_EVENT_MAILBOX_PTR]		= WL18XX_REG_EVENT_MAILBOX_PTR,
619 	[REG_INTERRUPT_TRIG]		= WL18XX_REG_INTERRUPT_TRIG_H,
620 	[REG_INTERRUPT_MASK]		= WL18XX_REG_INTERRUPT_MASK,
621 	[REG_PC_ON_RECOVERY]		= WL18XX_SCR_PAD4,
622 	[REG_CHIP_ID_B]			= WL18XX_REG_CHIP_ID_B,
623 	[REG_CMD_MBOX_ADDRESS]		= WL18XX_CMD_MBOX_ADDRESS,
624 
625 	/* data access memory addresses, used with partition translation */
626 	[REG_SLV_MEM_DATA]		= WL18XX_SLV_MEM_DATA,
627 	[REG_SLV_REG_DATA]		= WL18XX_SLV_REG_DATA,
628 
629 	/* raw data access memory addresses */
630 	[REG_RAW_FW_STATUS_ADDR]	= WL18XX_FW_STATUS_ADDR,
631 };
632 
633 static const struct wl18xx_clk_cfg wl18xx_clk_table_coex[NUM_CLOCK_CONFIGS] = {
634 	[CLOCK_CONFIG_16_2_M]	= { 8,  121, 0, 0, false },
635 	[CLOCK_CONFIG_16_368_M]	= { 8,  120, 0, 0, false },
636 	[CLOCK_CONFIG_16_8_M]	= { 8,  117, 0, 0, false },
637 	[CLOCK_CONFIG_19_2_M]	= { 10, 128, 0, 0, false },
638 	[CLOCK_CONFIG_26_M]	= { 11, 104, 0, 0, false },
639 	[CLOCK_CONFIG_32_736_M]	= { 8,  120, 0, 0, false },
640 	[CLOCK_CONFIG_33_6_M]	= { 8,  117, 0, 0, false },
641 	[CLOCK_CONFIG_38_468_M]	= { 10, 128, 0, 0, false },
642 	[CLOCK_CONFIG_52_M]	= { 11, 104, 0, 0, false },
643 };
644 
645 static const struct wl18xx_clk_cfg wl18xx_clk_table[NUM_CLOCK_CONFIGS] = {
646 	[CLOCK_CONFIG_16_2_M]	= { 7,  104,  801, 4,  true },
647 	[CLOCK_CONFIG_16_368_M]	= { 9,  132, 3751, 4,  true },
648 	[CLOCK_CONFIG_16_8_M]	= { 7,  100,    0, 0, false },
649 	[CLOCK_CONFIG_19_2_M]	= { 8,  100,    0, 0, false },
650 	[CLOCK_CONFIG_26_M]	= { 13, 120,    0, 0, false },
651 	[CLOCK_CONFIG_32_736_M]	= { 9,  132, 3751, 4,  true },
652 	[CLOCK_CONFIG_33_6_M]	= { 7,  100,    0, 0, false },
653 	[CLOCK_CONFIG_38_468_M]	= { 8,  100,    0, 0, false },
654 	[CLOCK_CONFIG_52_M]	= { 13, 120,    0, 0, false },
655 };
656 
657 /* TODO: maybe move to a new header file? */
658 #define WL18XX_FW_NAME "ti-connectivity/wl18xx-fw-4.bin"
659 
660 static int wl18xx_identify_chip(struct wl1271 *wl)
661 {
662 	int ret = 0;
663 
664 	switch (wl->chip.id) {
665 	case CHIP_ID_185x_PG20:
666 		wl1271_debug(DEBUG_BOOT, "chip id 0x%x (185x PG20)",
667 				 wl->chip.id);
668 		wl->sr_fw_name = WL18XX_FW_NAME;
669 		/* wl18xx uses the same firmware for PLT */
670 		wl->plt_fw_name = WL18XX_FW_NAME;
671 		wl->quirks |= WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN |
672 			      WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN |
673 			      WLCORE_QUIRK_NO_SCHED_SCAN_WHILE_CONN |
674 			      WLCORE_QUIRK_TX_PAD_LAST_FRAME |
675 			      WLCORE_QUIRK_REGDOMAIN_CONF |
676 			      WLCORE_QUIRK_DUAL_PROBE_TMPL;
677 
678 		wlcore_set_min_fw_ver(wl, WL18XX_CHIP_VER,
679 				      WL18XX_IFTYPE_VER,  WL18XX_MAJOR_VER,
680 				      WL18XX_SUBTYPE_VER, WL18XX_MINOR_VER,
681 				      /* there's no separate multi-role FW */
682 				      0, 0, 0, 0);
683 		break;
684 	case CHIP_ID_185x_PG10:
685 		wl1271_warning("chip id 0x%x (185x PG10) is deprecated",
686 			       wl->chip.id);
687 		ret = -ENODEV;
688 		goto out;
689 
690 	default:
691 		wl1271_warning("unsupported chip id: 0x%x", wl->chip.id);
692 		ret = -ENODEV;
693 		goto out;
694 	}
695 
696 	wl->fw_mem_block_size = 272;
697 	wl->fwlog_end = 0x40000000;
698 
699 	wl->scan_templ_id_2_4 = CMD_TEMPL_CFG_PROBE_REQ_2_4;
700 	wl->scan_templ_id_5 = CMD_TEMPL_CFG_PROBE_REQ_5;
701 	wl->sched_scan_templ_id_2_4 = CMD_TEMPL_PROBE_REQ_2_4_PERIODIC;
702 	wl->sched_scan_templ_id_5 = CMD_TEMPL_PROBE_REQ_5_PERIODIC;
703 	wl->max_channels_5 = WL18XX_MAX_CHANNELS_5GHZ;
704 	wl->ba_rx_session_count_max = WL18XX_RX_BA_MAX_SESSIONS;
705 out:
706 	return ret;
707 }
708 
709 static int wl18xx_set_clk(struct wl1271 *wl)
710 {
711 	u16 clk_freq;
712 	int ret;
713 
714 	ret = wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]);
715 	if (ret < 0)
716 		goto out;
717 
718 	/* TODO: PG2: apparently we need to read the clk type */
719 
720 	ret = wl18xx_top_reg_read(wl, PRIMARY_CLK_DETECT, &clk_freq);
721 	if (ret < 0)
722 		goto out;
723 
724 	wl1271_debug(DEBUG_BOOT, "clock freq %d (%d, %d, %d, %d, %s)", clk_freq,
725 		     wl18xx_clk_table[clk_freq].n, wl18xx_clk_table[clk_freq].m,
726 		     wl18xx_clk_table[clk_freq].p, wl18xx_clk_table[clk_freq].q,
727 		     wl18xx_clk_table[clk_freq].swallow ? "swallow" : "spit");
728 
729 	/* coex PLL configuration */
730 	ret = wl18xx_top_reg_write(wl, PLLSH_COEX_PLL_N,
731 				   wl18xx_clk_table_coex[clk_freq].n);
732 	if (ret < 0)
733 		goto out;
734 
735 	ret = wl18xx_top_reg_write(wl, PLLSH_COEX_PLL_M,
736 				   wl18xx_clk_table_coex[clk_freq].m);
737 	if (ret < 0)
738 		goto out;
739 
740 	/* bypass the swallowing logic */
741 	ret = wl18xx_top_reg_write(wl, PLLSH_COEX_PLL_SWALLOW_EN,
742 				   PLLSH_COEX_PLL_SWALLOW_EN_VAL1);
743 	if (ret < 0)
744 		goto out;
745 
746 	ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_N,
747 				   wl18xx_clk_table[clk_freq].n);
748 	if (ret < 0)
749 		goto out;
750 
751 	ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_M,
752 				   wl18xx_clk_table[clk_freq].m);
753 	if (ret < 0)
754 		goto out;
755 
756 	if (wl18xx_clk_table[clk_freq].swallow) {
757 		/* first the 16 lower bits */
758 		ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_Q_FACTOR_CFG_1,
759 					   wl18xx_clk_table[clk_freq].q &
760 					   PLLSH_WCS_PLL_Q_FACTOR_CFG_1_MASK);
761 		if (ret < 0)
762 			goto out;
763 
764 		/* then the 16 higher bits, masked out */
765 		ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_Q_FACTOR_CFG_2,
766 					(wl18xx_clk_table[clk_freq].q >> 16) &
767 					PLLSH_WCS_PLL_Q_FACTOR_CFG_2_MASK);
768 		if (ret < 0)
769 			goto out;
770 
771 		/* first the 16 lower bits */
772 		ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_P_FACTOR_CFG_1,
773 					   wl18xx_clk_table[clk_freq].p &
774 					   PLLSH_WCS_PLL_P_FACTOR_CFG_1_MASK);
775 		if (ret < 0)
776 			goto out;
777 
778 		/* then the 16 higher bits, masked out */
779 		ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_P_FACTOR_CFG_2,
780 					(wl18xx_clk_table[clk_freq].p >> 16) &
781 					PLLSH_WCS_PLL_P_FACTOR_CFG_2_MASK);
782 	} else {
783 		ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_SWALLOW_EN,
784 					   PLLSH_WCS_PLL_SWALLOW_EN_VAL2);
785 	}
786 
787 	/* choose WCS PLL */
788 	ret = wl18xx_top_reg_write(wl, PLLSH_WL_PLL_SEL,
789 				   PLLSH_WL_PLL_SEL_WCS_PLL);
790 	if (ret < 0)
791 		goto out;
792 
793 	/* enable both PLLs */
794 	ret = wl18xx_top_reg_write(wl, PLLSH_WL_PLL_EN, PLLSH_WL_PLL_EN_VAL1);
795 	if (ret < 0)
796 		goto out;
797 
798 	udelay(1000);
799 
800 	/* disable coex PLL */
801 	ret = wl18xx_top_reg_write(wl, PLLSH_WL_PLL_EN, PLLSH_WL_PLL_EN_VAL2);
802 	if (ret < 0)
803 		goto out;
804 
805 	/* reset the swallowing logic */
806 	ret = wl18xx_top_reg_write(wl, PLLSH_COEX_PLL_SWALLOW_EN,
807 				   PLLSH_COEX_PLL_SWALLOW_EN_VAL2);
808 	if (ret < 0)
809 		goto out;
810 
811 out:
812 	return ret;
813 }
814 
815 static int wl18xx_boot_soft_reset(struct wl1271 *wl)
816 {
817 	int ret;
818 
819 	/* disable Rx/Tx */
820 	ret = wlcore_write32(wl, WL18XX_ENABLE, 0x0);
821 	if (ret < 0)
822 		goto out;
823 
824 	/* disable auto calibration on start*/
825 	ret = wlcore_write32(wl, WL18XX_SPARE_A2, 0xffff);
826 
827 out:
828 	return ret;
829 }
830 
831 static int wl18xx_pre_boot(struct wl1271 *wl)
832 {
833 	int ret;
834 
835 	ret = wl18xx_set_clk(wl);
836 	if (ret < 0)
837 		goto out;
838 
839 	/* Continue the ELP wake up sequence */
840 	ret = wlcore_write32(wl, WL18XX_WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL);
841 	if (ret < 0)
842 		goto out;
843 
844 	udelay(500);
845 
846 	ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
847 	if (ret < 0)
848 		goto out;
849 
850 	/* Disable interrupts */
851 	ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
852 	if (ret < 0)
853 		goto out;
854 
855 	ret = wl18xx_boot_soft_reset(wl);
856 
857 out:
858 	return ret;
859 }
860 
861 static int wl18xx_pre_upload(struct wl1271 *wl)
862 {
863 	u32 tmp;
864 	int ret;
865 
866 	BUILD_BUG_ON(sizeof(struct wl18xx_mac_and_phy_params) >
867 		WL18XX_PHY_INIT_MEM_SIZE);
868 
869 	ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
870 	if (ret < 0)
871 		goto out;
872 
873 	/* TODO: check if this is all needed */
874 	ret = wlcore_write32(wl, WL18XX_EEPROMLESS_IND, WL18XX_EEPROMLESS_IND);
875 	if (ret < 0)
876 		goto out;
877 
878 	ret = wlcore_read_reg(wl, REG_CHIP_ID_B, &tmp);
879 	if (ret < 0)
880 		goto out;
881 
882 	wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp);
883 
884 	ret = wlcore_read32(wl, WL18XX_SCR_PAD2, &tmp);
885 	if (ret < 0)
886 		goto out;
887 
888 	/*
889 	 * Workaround for FDSP code RAM corruption (needed for PG2.1
890 	 * and newer; for older chips it's a NOP).  Change FDSP clock
891 	 * settings so that it's muxed to the ATGP clock instead of
892 	 * its own clock.
893 	 */
894 
895 	ret = wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]);
896 	if (ret < 0)
897 		goto out;
898 
899 	/* disable FDSP clock */
900 	ret = wlcore_write32(wl, WL18XX_PHY_FPGA_SPARE_1,
901 			     MEM_FDSP_CLK_120_DISABLE);
902 	if (ret < 0)
903 		goto out;
904 
905 	/* set ATPG clock toward FDSP Code RAM rather than its own clock */
906 	ret = wlcore_write32(wl, WL18XX_PHY_FPGA_SPARE_1,
907 			     MEM_FDSP_CODERAM_FUNC_CLK_SEL);
908 	if (ret < 0)
909 		goto out;
910 
911 	/* re-enable FDSP clock */
912 	ret = wlcore_write32(wl, WL18XX_PHY_FPGA_SPARE_1,
913 			     MEM_FDSP_CLK_120_ENABLE);
914 
915 out:
916 	return ret;
917 }
918 
919 static int wl18xx_set_mac_and_phy(struct wl1271 *wl)
920 {
921 	struct wl18xx_priv *priv = wl->priv;
922 	struct wl18xx_mac_and_phy_params *params;
923 	int ret;
924 
925 	params = kmemdup(&priv->conf.phy, sizeof(*params), GFP_KERNEL);
926 	if (!params) {
927 		ret = -ENOMEM;
928 		goto out;
929 	}
930 
931 	ret = wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]);
932 	if (ret < 0)
933 		goto out;
934 
935 	ret = wlcore_write(wl, WL18XX_PHY_INIT_MEM_ADDR, params,
936 			   sizeof(*params), false);
937 
938 out:
939 	kfree(params);
940 	return ret;
941 }
942 
943 static int wl18xx_enable_interrupts(struct wl1271 *wl)
944 {
945 	u32 event_mask, intr_mask;
946 	int ret;
947 
948 	event_mask = WL18XX_ACX_EVENTS_VECTOR;
949 	intr_mask = WL18XX_INTR_MASK;
950 
951 	ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK, event_mask);
952 	if (ret < 0)
953 		goto out;
954 
955 	wlcore_enable_interrupts(wl);
956 
957 	ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK,
958 			       WL1271_ACX_INTR_ALL & ~intr_mask);
959 	if (ret < 0)
960 		goto disable_interrupts;
961 
962 	return ret;
963 
964 disable_interrupts:
965 	wlcore_disable_interrupts(wl);
966 
967 out:
968 	return ret;
969 }
970 
971 static int wl18xx_boot(struct wl1271 *wl)
972 {
973 	int ret;
974 
975 	ret = wl18xx_pre_boot(wl);
976 	if (ret < 0)
977 		goto out;
978 
979 	ret = wl18xx_pre_upload(wl);
980 	if (ret < 0)
981 		goto out;
982 
983 	ret = wlcore_boot_upload_firmware(wl);
984 	if (ret < 0)
985 		goto out;
986 
987 	ret = wl18xx_set_mac_and_phy(wl);
988 	if (ret < 0)
989 		goto out;
990 
991 	wl->event_mask = BSS_LOSS_EVENT_ID |
992 		SCAN_COMPLETE_EVENT_ID |
993 		RADAR_DETECTED_EVENT_ID |
994 		RSSI_SNR_TRIGGER_0_EVENT_ID |
995 		PERIODIC_SCAN_COMPLETE_EVENT_ID |
996 		PERIODIC_SCAN_REPORT_EVENT_ID |
997 		DUMMY_PACKET_EVENT_ID |
998 		PEER_REMOVE_COMPLETE_EVENT_ID |
999 		BA_SESSION_RX_CONSTRAINT_EVENT_ID |
1000 		REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID |
1001 		INACTIVE_STA_EVENT_ID |
1002 		CHANNEL_SWITCH_COMPLETE_EVENT_ID |
1003 		DFS_CHANNELS_CONFIG_COMPLETE_EVENT |
1004 		SMART_CONFIG_SYNC_EVENT_ID |
1005 		SMART_CONFIG_DECODE_EVENT_ID;
1006 ;
1007 
1008 	wl->ap_event_mask = MAX_TX_FAILURE_EVENT_ID;
1009 
1010 	ret = wlcore_boot_run_firmware(wl);
1011 	if (ret < 0)
1012 		goto out;
1013 
1014 	ret = wl18xx_enable_interrupts(wl);
1015 
1016 out:
1017 	return ret;
1018 }
1019 
1020 static int wl18xx_trigger_cmd(struct wl1271 *wl, int cmd_box_addr,
1021 			       void *buf, size_t len)
1022 {
1023 	struct wl18xx_priv *priv = wl->priv;
1024 
1025 	memcpy(priv->cmd_buf, buf, len);
1026 	memset(priv->cmd_buf + len, 0, WL18XX_CMD_MAX_SIZE - len);
1027 
1028 	return wlcore_write(wl, cmd_box_addr, priv->cmd_buf,
1029 			    WL18XX_CMD_MAX_SIZE, false);
1030 }
1031 
1032 static int wl18xx_ack_event(struct wl1271 *wl)
1033 {
1034 	return wlcore_write_reg(wl, REG_INTERRUPT_TRIG,
1035 				WL18XX_INTR_TRIG_EVENT_ACK);
1036 }
1037 
1038 static u32 wl18xx_calc_tx_blocks(struct wl1271 *wl, u32 len, u32 spare_blks)
1039 {
1040 	u32 blk_size = WL18XX_TX_HW_BLOCK_SIZE;
1041 	return (len + blk_size - 1) / blk_size + spare_blks;
1042 }
1043 
1044 static void
1045 wl18xx_set_tx_desc_blocks(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc,
1046 			  u32 blks, u32 spare_blks)
1047 {
1048 	desc->wl18xx_mem.total_mem_blocks = blks;
1049 }
1050 
1051 static void
1052 wl18xx_set_tx_desc_data_len(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc,
1053 			    struct sk_buff *skb)
1054 {
1055 	desc->length = cpu_to_le16(skb->len);
1056 
1057 	/* if only the last frame is to be padded, we unset this bit on Tx */
1058 	if (wl->quirks & WLCORE_QUIRK_TX_PAD_LAST_FRAME)
1059 		desc->wl18xx_mem.ctrl = WL18XX_TX_CTRL_NOT_PADDED;
1060 	else
1061 		desc->wl18xx_mem.ctrl = 0;
1062 
1063 	wl1271_debug(DEBUG_TX, "tx_fill_hdr: hlid: %d "
1064 		     "len: %d life: %d mem: %d", desc->hlid,
1065 		     le16_to_cpu(desc->length),
1066 		     le16_to_cpu(desc->life_time),
1067 		     desc->wl18xx_mem.total_mem_blocks);
1068 }
1069 
1070 static enum wl_rx_buf_align
1071 wl18xx_get_rx_buf_align(struct wl1271 *wl, u32 rx_desc)
1072 {
1073 	if (rx_desc & RX_BUF_PADDED_PAYLOAD)
1074 		return WLCORE_RX_BUF_PADDED;
1075 
1076 	return WLCORE_RX_BUF_ALIGNED;
1077 }
1078 
1079 static u32 wl18xx_get_rx_packet_len(struct wl1271 *wl, void *rx_data,
1080 				    u32 data_len)
1081 {
1082 	struct wl1271_rx_descriptor *desc = rx_data;
1083 
1084 	/* invalid packet */
1085 	if (data_len < sizeof(*desc))
1086 		return 0;
1087 
1088 	return data_len - sizeof(*desc);
1089 }
1090 
1091 static void wl18xx_tx_immediate_completion(struct wl1271 *wl)
1092 {
1093 	wl18xx_tx_immediate_complete(wl);
1094 }
1095 
1096 static int wl18xx_set_host_cfg_bitmap(struct wl1271 *wl, u32 extra_mem_blk)
1097 {
1098 	int ret;
1099 	u32 sdio_align_size = 0;
1100 	u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE |
1101 			      HOST_IF_CFG_ADD_RX_ALIGNMENT;
1102 
1103 	/* Enable Tx SDIO padding */
1104 	if (wl->quirks & WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN) {
1105 		host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK;
1106 		sdio_align_size = WL12XX_BUS_BLOCK_SIZE;
1107 	}
1108 
1109 	/* Enable Rx SDIO padding */
1110 	if (wl->quirks & WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN) {
1111 		host_cfg_bitmap |= HOST_IF_CFG_RX_PAD_TO_SDIO_BLK;
1112 		sdio_align_size = WL12XX_BUS_BLOCK_SIZE;
1113 	}
1114 
1115 	ret = wl18xx_acx_host_if_cfg_bitmap(wl, host_cfg_bitmap,
1116 					    sdio_align_size, extra_mem_blk,
1117 					    WL18XX_HOST_IF_LEN_SIZE_FIELD);
1118 	if (ret < 0)
1119 		return ret;
1120 
1121 	return 0;
1122 }
1123 
1124 static int wl18xx_hw_init(struct wl1271 *wl)
1125 {
1126 	int ret;
1127 	struct wl18xx_priv *priv = wl->priv;
1128 
1129 	/* (re)init private structures. Relevant on recovery as well. */
1130 	priv->last_fw_rls_idx = 0;
1131 	priv->extra_spare_key_count = 0;
1132 
1133 	/* set the default amount of spare blocks in the bitmap */
1134 	ret = wl18xx_set_host_cfg_bitmap(wl, WL18XX_TX_HW_BLOCK_SPARE);
1135 	if (ret < 0)
1136 		return ret;
1137 
1138 	if (checksum_param) {
1139 		ret = wl18xx_acx_set_checksum_state(wl);
1140 		if (ret != 0)
1141 			return ret;
1142 	}
1143 
1144 	return ret;
1145 }
1146 
1147 static void wl18xx_convert_fw_status(struct wl1271 *wl, void *raw_fw_status,
1148 				     struct wl_fw_status *fw_status)
1149 {
1150 	struct wl18xx_fw_status *int_fw_status = raw_fw_status;
1151 
1152 	fw_status->intr = le32_to_cpu(int_fw_status->intr);
1153 	fw_status->fw_rx_counter = int_fw_status->fw_rx_counter;
1154 	fw_status->drv_rx_counter = int_fw_status->drv_rx_counter;
1155 	fw_status->tx_results_counter = int_fw_status->tx_results_counter;
1156 	fw_status->rx_pkt_descs = int_fw_status->rx_pkt_descs;
1157 
1158 	fw_status->fw_localtime = le32_to_cpu(int_fw_status->fw_localtime);
1159 	fw_status->link_ps_bitmap = le32_to_cpu(int_fw_status->link_ps_bitmap);
1160 	fw_status->link_fast_bitmap =
1161 			le32_to_cpu(int_fw_status->link_fast_bitmap);
1162 	fw_status->total_released_blks =
1163 			le32_to_cpu(int_fw_status->total_released_blks);
1164 	fw_status->tx_total = le32_to_cpu(int_fw_status->tx_total);
1165 
1166 	fw_status->counters.tx_released_pkts =
1167 			int_fw_status->counters.tx_released_pkts;
1168 	fw_status->counters.tx_lnk_free_pkts =
1169 			int_fw_status->counters.tx_lnk_free_pkts;
1170 	fw_status->counters.tx_voice_released_blks =
1171 			int_fw_status->counters.tx_voice_released_blks;
1172 	fw_status->counters.tx_last_rate =
1173 			int_fw_status->counters.tx_last_rate;
1174 
1175 	fw_status->log_start_addr = le32_to_cpu(int_fw_status->log_start_addr);
1176 
1177 	fw_status->priv = &int_fw_status->priv;
1178 }
1179 
1180 static void wl18xx_set_tx_desc_csum(struct wl1271 *wl,
1181 				    struct wl1271_tx_hw_descr *desc,
1182 				    struct sk_buff *skb)
1183 {
1184 	u32 ip_hdr_offset;
1185 	struct iphdr *ip_hdr;
1186 
1187 	if (!checksum_param) {
1188 		desc->wl18xx_checksum_data = 0;
1189 		return;
1190 	}
1191 
1192 	if (skb->ip_summed != CHECKSUM_PARTIAL) {
1193 		desc->wl18xx_checksum_data = 0;
1194 		return;
1195 	}
1196 
1197 	ip_hdr_offset = skb_network_header(skb) - skb_mac_header(skb);
1198 	if (WARN_ON(ip_hdr_offset >= (1<<7))) {
1199 		desc->wl18xx_checksum_data = 0;
1200 		return;
1201 	}
1202 
1203 	desc->wl18xx_checksum_data = ip_hdr_offset << 1;
1204 
1205 	/* FW is interested only in the LSB of the protocol  TCP=0 UDP=1 */
1206 	ip_hdr = (void *)skb_network_header(skb);
1207 	desc->wl18xx_checksum_data |= (ip_hdr->protocol & 0x01);
1208 }
1209 
1210 static void wl18xx_set_rx_csum(struct wl1271 *wl,
1211 			       struct wl1271_rx_descriptor *desc,
1212 			       struct sk_buff *skb)
1213 {
1214 	if (desc->status & WL18XX_RX_CHECKSUM_MASK)
1215 		skb->ip_summed = CHECKSUM_UNNECESSARY;
1216 }
1217 
1218 static bool wl18xx_is_mimo_supported(struct wl1271 *wl)
1219 {
1220 	struct wl18xx_priv *priv = wl->priv;
1221 
1222 	/* only support MIMO with multiple antennas, and when SISO
1223 	 * is not forced through config
1224 	 */
1225 	return (priv->conf.phy.number_of_assembled_ant2_4 >= 2) &&
1226 	       (priv->conf.ht.mode != HT_MODE_WIDE) &&
1227 	       (priv->conf.ht.mode != HT_MODE_SISO20);
1228 }
1229 
1230 /*
1231  * TODO: instead of having these two functions to get the rate mask,
1232  * we should modify the wlvif->rate_set instead
1233  */
1234 static u32 wl18xx_sta_get_ap_rate_mask(struct wl1271 *wl,
1235 				       struct wl12xx_vif *wlvif)
1236 {
1237 	u32 hw_rate_set = wlvif->rate_set;
1238 
1239 	if (wlvif->channel_type == NL80211_CHAN_HT40MINUS ||
1240 	    wlvif->channel_type == NL80211_CHAN_HT40PLUS) {
1241 		wl1271_debug(DEBUG_ACX, "using wide channel rate mask");
1242 		hw_rate_set |= CONF_TX_RATE_USE_WIDE_CHAN;
1243 
1244 		/* we don't support MIMO in wide-channel mode */
1245 		hw_rate_set &= ~CONF_TX_MIMO_RATES;
1246 	} else if (wl18xx_is_mimo_supported(wl)) {
1247 		wl1271_debug(DEBUG_ACX, "using MIMO channel rate mask");
1248 		hw_rate_set |= CONF_TX_MIMO_RATES;
1249 	}
1250 
1251 	return hw_rate_set;
1252 }
1253 
1254 static u32 wl18xx_ap_get_mimo_wide_rate_mask(struct wl1271 *wl,
1255 					     struct wl12xx_vif *wlvif)
1256 {
1257 	if (wlvif->channel_type == NL80211_CHAN_HT40MINUS ||
1258 	    wlvif->channel_type == NL80211_CHAN_HT40PLUS) {
1259 		wl1271_debug(DEBUG_ACX, "using wide channel rate mask");
1260 
1261 		/* sanity check - we don't support this */
1262 		if (WARN_ON(wlvif->band != IEEE80211_BAND_5GHZ))
1263 			return 0;
1264 
1265 		return CONF_TX_RATE_USE_WIDE_CHAN;
1266 	} else if (wl18xx_is_mimo_supported(wl) &&
1267 		   wlvif->band == IEEE80211_BAND_2GHZ) {
1268 		wl1271_debug(DEBUG_ACX, "using MIMO rate mask");
1269 		/*
1270 		 * we don't care about HT channel here - if a peer doesn't
1271 		 * support MIMO, we won't enable it in its rates
1272 		 */
1273 		return CONF_TX_MIMO_RATES;
1274 	} else {
1275 		return 0;
1276 	}
1277 }
1278 
1279 static const char *wl18xx_rdl_name(enum wl18xx_rdl_num rdl_num)
1280 {
1281 	switch (rdl_num) {
1282 	case RDL_1_HP:
1283 		return "183xH";
1284 	case RDL_2_SP:
1285 		return "183x or 180x";
1286 	case RDL_3_HP:
1287 		return "187xH";
1288 	case RDL_4_SP:
1289 		return "187x";
1290 	case RDL_5_SP:
1291 		return "RDL11 - Not Supported";
1292 	case RDL_6_SP:
1293 		return "180xD";
1294 	case RDL_7_SP:
1295 		return "RDL13 - Not Supported (1893Q)";
1296 	case RDL_8_SP:
1297 		return "18xxQ";
1298 	case RDL_NONE:
1299 		return "UNTRIMMED";
1300 	default:
1301 		return "UNKNOWN";
1302 	}
1303 }
1304 
1305 static int wl18xx_get_pg_ver(struct wl1271 *wl, s8 *ver)
1306 {
1307 	u32 fuse;
1308 	s8 rom = 0, metal = 0, pg_ver = 0, rdl_ver = 0, package_type = 0;
1309 	int ret;
1310 
1311 	ret = wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]);
1312 	if (ret < 0)
1313 		goto out;
1314 
1315 	ret = wlcore_read32(wl, WL18XX_REG_FUSE_DATA_2_3, &fuse);
1316 	if (ret < 0)
1317 		goto out;
1318 
1319 	package_type = (fuse >> WL18XX_PACKAGE_TYPE_OFFSET) & 1;
1320 
1321 	ret = wlcore_read32(wl, WL18XX_REG_FUSE_DATA_1_3, &fuse);
1322 	if (ret < 0)
1323 		goto out;
1324 
1325 	pg_ver = (fuse & WL18XX_PG_VER_MASK) >> WL18XX_PG_VER_OFFSET;
1326 	rom = (fuse & WL18XX_ROM_VER_MASK) >> WL18XX_ROM_VER_OFFSET;
1327 
1328 	if ((rom <= 0xE) && (package_type == WL18XX_PACKAGE_TYPE_WSP))
1329 		metal = (fuse & WL18XX_METAL_VER_MASK) >>
1330 			WL18XX_METAL_VER_OFFSET;
1331 	else
1332 		metal = (fuse & WL18XX_NEW_METAL_VER_MASK) >>
1333 			WL18XX_NEW_METAL_VER_OFFSET;
1334 
1335 	ret = wlcore_read32(wl, WL18XX_REG_FUSE_DATA_2_3, &fuse);
1336 	if (ret < 0)
1337 		goto out;
1338 
1339 	rdl_ver = (fuse & WL18XX_RDL_VER_MASK) >> WL18XX_RDL_VER_OFFSET;
1340 
1341 	wl1271_info("wl18xx HW: %s, PG %d.%d (ROM 0x%x)",
1342 		    wl18xx_rdl_name(rdl_ver), pg_ver, metal, rom);
1343 
1344 	if (ver)
1345 		*ver = pg_ver;
1346 
1347 	ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
1348 
1349 out:
1350 	return ret;
1351 }
1352 
1353 #define WL18XX_CONF_FILE_NAME "ti-connectivity/wl18xx-conf.bin"
1354 static int wl18xx_conf_init(struct wl1271 *wl, struct device *dev)
1355 {
1356 	struct wl18xx_priv *priv = wl->priv;
1357 	struct wlcore_conf_file *conf_file;
1358 	const struct firmware *fw;
1359 	int ret;
1360 
1361 	ret = request_firmware(&fw, WL18XX_CONF_FILE_NAME, dev);
1362 	if (ret < 0) {
1363 		wl1271_error("could not get configuration binary %s: %d",
1364 			     WL18XX_CONF_FILE_NAME, ret);
1365 		goto out_fallback;
1366 	}
1367 
1368 	if (fw->size != WL18XX_CONF_SIZE) {
1369 		wl1271_error("configuration binary file size is wrong, expected %zu got %zu",
1370 			     WL18XX_CONF_SIZE, fw->size);
1371 		ret = -EINVAL;
1372 		goto out;
1373 	}
1374 
1375 	conf_file = (struct wlcore_conf_file *) fw->data;
1376 
1377 	if (conf_file->header.magic != cpu_to_le32(WL18XX_CONF_MAGIC)) {
1378 		wl1271_error("configuration binary file magic number mismatch, "
1379 			     "expected 0x%0x got 0x%0x", WL18XX_CONF_MAGIC,
1380 			     conf_file->header.magic);
1381 		ret = -EINVAL;
1382 		goto out;
1383 	}
1384 
1385 	if (conf_file->header.version != cpu_to_le32(WL18XX_CONF_VERSION)) {
1386 		wl1271_error("configuration binary file version not supported, "
1387 			     "expected 0x%08x got 0x%08x",
1388 			     WL18XX_CONF_VERSION, conf_file->header.version);
1389 		ret = -EINVAL;
1390 		goto out;
1391 	}
1392 
1393 	memcpy(&wl->conf, &conf_file->core, sizeof(wl18xx_conf));
1394 	memcpy(&priv->conf, &conf_file->priv, sizeof(priv->conf));
1395 
1396 	goto out;
1397 
1398 out_fallback:
1399 	wl1271_warning("falling back to default config");
1400 
1401 	/* apply driver default configuration */
1402 	memcpy(&wl->conf, &wl18xx_conf, sizeof(wl18xx_conf));
1403 	/* apply default private configuration */
1404 	memcpy(&priv->conf, &wl18xx_default_priv_conf, sizeof(priv->conf));
1405 
1406 	/* For now we just fallback */
1407 	return 0;
1408 
1409 out:
1410 	release_firmware(fw);
1411 	return ret;
1412 }
1413 
1414 static int wl18xx_plt_init(struct wl1271 *wl)
1415 {
1416 	int ret;
1417 
1418 	/* calibrator based auto/fem detect not supported for 18xx */
1419 	if (wl->plt_mode == PLT_FEM_DETECT) {
1420 		wl1271_error("wl18xx_plt_init: PLT FEM_DETECT not supported");
1421 		return -EINVAL;
1422 	}
1423 
1424 	ret = wlcore_write32(wl, WL18XX_SCR_PAD8, WL18XX_SCR_PAD8_PLT);
1425 	if (ret < 0)
1426 		return ret;
1427 
1428 	return wl->ops->boot(wl);
1429 }
1430 
1431 static int wl18xx_get_mac(struct wl1271 *wl)
1432 {
1433 	u32 mac1, mac2;
1434 	int ret;
1435 
1436 	ret = wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]);
1437 	if (ret < 0)
1438 		goto out;
1439 
1440 	ret = wlcore_read32(wl, WL18XX_REG_FUSE_BD_ADDR_1, &mac1);
1441 	if (ret < 0)
1442 		goto out;
1443 
1444 	ret = wlcore_read32(wl, WL18XX_REG_FUSE_BD_ADDR_2, &mac2);
1445 	if (ret < 0)
1446 		goto out;
1447 
1448 	/* these are the two parts of the BD_ADDR */
1449 	wl->fuse_oui_addr = ((mac2 & 0xffff) << 8) +
1450 		((mac1 & 0xff000000) >> 24);
1451 	wl->fuse_nic_addr = (mac1 & 0xffffff);
1452 
1453 	if (!wl->fuse_oui_addr && !wl->fuse_nic_addr) {
1454 		u8 mac[ETH_ALEN];
1455 
1456 		eth_random_addr(mac);
1457 
1458 		wl->fuse_oui_addr = (mac[0] << 16) + (mac[1] << 8) + mac[2];
1459 		wl->fuse_nic_addr = (mac[3] << 16) + (mac[4] << 8) + mac[5];
1460 		wl1271_warning("MAC address from fuse not available, using random locally administered addresses.");
1461 	}
1462 
1463 	ret = wlcore_set_partition(wl, &wl->ptable[PART_DOWN]);
1464 
1465 out:
1466 	return ret;
1467 }
1468 
1469 static int wl18xx_handle_static_data(struct wl1271 *wl,
1470 				     struct wl1271_static_data *static_data)
1471 {
1472 	struct wl18xx_static_data_priv *static_data_priv =
1473 		(struct wl18xx_static_data_priv *) static_data->priv;
1474 
1475 	strncpy(wl->chip.phy_fw_ver_str, static_data_priv->phy_version,
1476 		sizeof(wl->chip.phy_fw_ver_str));
1477 
1478 	/* make sure the string is NULL-terminated */
1479 	wl->chip.phy_fw_ver_str[sizeof(wl->chip.phy_fw_ver_str) - 1] = '\0';
1480 
1481 	wl1271_info("PHY firmware version: %s", static_data_priv->phy_version);
1482 
1483 	return 0;
1484 }
1485 
1486 static int wl18xx_get_spare_blocks(struct wl1271 *wl, bool is_gem)
1487 {
1488 	struct wl18xx_priv *priv = wl->priv;
1489 
1490 	/* If we have keys requiring extra spare, indulge them */
1491 	if (priv->extra_spare_key_count)
1492 		return WL18XX_TX_HW_EXTRA_BLOCK_SPARE;
1493 
1494 	return WL18XX_TX_HW_BLOCK_SPARE;
1495 }
1496 
1497 static int wl18xx_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
1498 			  struct ieee80211_vif *vif,
1499 			  struct ieee80211_sta *sta,
1500 			  struct ieee80211_key_conf *key_conf)
1501 {
1502 	struct wl18xx_priv *priv = wl->priv;
1503 	bool change_spare = false, special_enc;
1504 	int ret;
1505 
1506 	wl1271_debug(DEBUG_CRYPT, "extra spare keys before: %d",
1507 		     priv->extra_spare_key_count);
1508 
1509 	special_enc = key_conf->cipher == WL1271_CIPHER_SUITE_GEM ||
1510 		      key_conf->cipher == WLAN_CIPHER_SUITE_TKIP;
1511 
1512 	ret = wlcore_set_key(wl, cmd, vif, sta, key_conf);
1513 	if (ret < 0)
1514 		goto out;
1515 
1516 	/*
1517 	 * when adding the first or removing the last GEM/TKIP key,
1518 	 * we have to adjust the number of spare blocks.
1519 	 */
1520 	if (special_enc) {
1521 		if (cmd == SET_KEY) {
1522 			/* first key */
1523 			change_spare = (priv->extra_spare_key_count == 0);
1524 			priv->extra_spare_key_count++;
1525 		} else if (cmd == DISABLE_KEY) {
1526 			/* last key */
1527 			change_spare = (priv->extra_spare_key_count == 1);
1528 			priv->extra_spare_key_count--;
1529 		}
1530 	}
1531 
1532 	wl1271_debug(DEBUG_CRYPT, "extra spare keys after: %d",
1533 		     priv->extra_spare_key_count);
1534 
1535 	if (!change_spare)
1536 		goto out;
1537 
1538 	/* key is now set, change the spare blocks */
1539 	if (priv->extra_spare_key_count)
1540 		ret = wl18xx_set_host_cfg_bitmap(wl,
1541 					WL18XX_TX_HW_EXTRA_BLOCK_SPARE);
1542 	else
1543 		ret = wl18xx_set_host_cfg_bitmap(wl,
1544 					WL18XX_TX_HW_BLOCK_SPARE);
1545 
1546 out:
1547 	return ret;
1548 }
1549 
1550 static u32 wl18xx_pre_pkt_send(struct wl1271 *wl,
1551 			       u32 buf_offset, u32 last_len)
1552 {
1553 	if (wl->quirks & WLCORE_QUIRK_TX_PAD_LAST_FRAME) {
1554 		struct wl1271_tx_hw_descr *last_desc;
1555 
1556 		/* get the last TX HW descriptor written to the aggr buf */
1557 		last_desc = (struct wl1271_tx_hw_descr *)(wl->aggr_buf +
1558 							buf_offset - last_len);
1559 
1560 		/* the last frame is padded up to an SDIO block */
1561 		last_desc->wl18xx_mem.ctrl &= ~WL18XX_TX_CTRL_NOT_PADDED;
1562 		return ALIGN(buf_offset, WL12XX_BUS_BLOCK_SIZE);
1563 	}
1564 
1565 	/* no modifications */
1566 	return buf_offset;
1567 }
1568 
1569 static void wl18xx_sta_rc_update(struct wl1271 *wl,
1570 				 struct wl12xx_vif *wlvif)
1571 {
1572 	bool wide = wlvif->rc_update_bw >= IEEE80211_STA_RX_BW_40;
1573 
1574 	wl1271_debug(DEBUG_MAC80211, "mac80211 sta_rc_update wide %d", wide);
1575 
1576 	/* sanity */
1577 	if (WARN_ON(wlvif->bss_type != BSS_TYPE_STA_BSS))
1578 		return;
1579 
1580 	/* ignore the change before association */
1581 	if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
1582 		return;
1583 
1584 	/*
1585 	 * If we started out as wide, we can change the operation mode. If we
1586 	 * thought this was a 20mhz AP, we have to reconnect
1587 	 */
1588 	if (wlvif->sta.role_chan_type == NL80211_CHAN_HT40MINUS ||
1589 	    wlvif->sta.role_chan_type == NL80211_CHAN_HT40PLUS)
1590 		wl18xx_acx_peer_ht_operation_mode(wl, wlvif->sta.hlid, wide);
1591 	else
1592 		ieee80211_connection_loss(wl12xx_wlvif_to_vif(wlvif));
1593 }
1594 
1595 static int wl18xx_set_peer_cap(struct wl1271 *wl,
1596 			       struct ieee80211_sta_ht_cap *ht_cap,
1597 			       bool allow_ht_operation,
1598 			       u32 rate_set, u8 hlid)
1599 {
1600 	return wl18xx_acx_set_peer_cap(wl, ht_cap, allow_ht_operation,
1601 				       rate_set, hlid);
1602 }
1603 
1604 static bool wl18xx_lnk_high_prio(struct wl1271 *wl, u8 hlid,
1605 				 struct wl1271_link *lnk)
1606 {
1607 	u8 thold;
1608 	struct wl18xx_fw_status_priv *status_priv =
1609 		(struct wl18xx_fw_status_priv *)wl->fw_status->priv;
1610 	unsigned long suspend_bitmap;
1611 
1612 	/* if we don't have the link map yet, assume they all low prio */
1613 	if (!status_priv)
1614 		return false;
1615 
1616 	/* suspended links are never high priority */
1617 	suspend_bitmap = le32_to_cpu(status_priv->link_suspend_bitmap);
1618 	if (test_bit(hlid, &suspend_bitmap))
1619 		return false;
1620 
1621 	/* the priority thresholds are taken from FW */
1622 	if (test_bit(hlid, &wl->fw_fast_lnk_map) &&
1623 	    !test_bit(hlid, &wl->ap_fw_ps_map))
1624 		thold = status_priv->tx_fast_link_prio_threshold;
1625 	else
1626 		thold = status_priv->tx_slow_link_prio_threshold;
1627 
1628 	return lnk->allocated_pkts < thold;
1629 }
1630 
1631 static bool wl18xx_lnk_low_prio(struct wl1271 *wl, u8 hlid,
1632 				struct wl1271_link *lnk)
1633 {
1634 	u8 thold;
1635 	struct wl18xx_fw_status_priv *status_priv =
1636 		(struct wl18xx_fw_status_priv *)wl->fw_status->priv;
1637 	unsigned long suspend_bitmap;
1638 
1639 	/* if we don't have the link map yet, assume they all low prio */
1640 	if (!status_priv)
1641 		return true;
1642 
1643 	suspend_bitmap = le32_to_cpu(status_priv->link_suspend_bitmap);
1644 	if (test_bit(hlid, &suspend_bitmap))
1645 		thold = status_priv->tx_suspend_threshold;
1646 	else if (test_bit(hlid, &wl->fw_fast_lnk_map) &&
1647 		 !test_bit(hlid, &wl->ap_fw_ps_map))
1648 		thold = status_priv->tx_fast_stop_threshold;
1649 	else
1650 		thold = status_priv->tx_slow_stop_threshold;
1651 
1652 	return lnk->allocated_pkts < thold;
1653 }
1654 
1655 static u32 wl18xx_convert_hwaddr(struct wl1271 *wl, u32 hwaddr)
1656 {
1657 	return hwaddr & ~0x80000000;
1658 }
1659 
1660 static int wl18xx_setup(struct wl1271 *wl);
1661 
1662 static struct wlcore_ops wl18xx_ops = {
1663 	.setup		= wl18xx_setup,
1664 	.identify_chip	= wl18xx_identify_chip,
1665 	.boot		= wl18xx_boot,
1666 	.plt_init	= wl18xx_plt_init,
1667 	.trigger_cmd	= wl18xx_trigger_cmd,
1668 	.ack_event	= wl18xx_ack_event,
1669 	.wait_for_event	= wl18xx_wait_for_event,
1670 	.process_mailbox_events = wl18xx_process_mailbox_events,
1671 	.calc_tx_blocks = wl18xx_calc_tx_blocks,
1672 	.set_tx_desc_blocks = wl18xx_set_tx_desc_blocks,
1673 	.set_tx_desc_data_len = wl18xx_set_tx_desc_data_len,
1674 	.get_rx_buf_align = wl18xx_get_rx_buf_align,
1675 	.get_rx_packet_len = wl18xx_get_rx_packet_len,
1676 	.tx_immediate_compl = wl18xx_tx_immediate_completion,
1677 	.tx_delayed_compl = NULL,
1678 	.hw_init	= wl18xx_hw_init,
1679 	.convert_fw_status = wl18xx_convert_fw_status,
1680 	.set_tx_desc_csum = wl18xx_set_tx_desc_csum,
1681 	.get_pg_ver	= wl18xx_get_pg_ver,
1682 	.set_rx_csum = wl18xx_set_rx_csum,
1683 	.sta_get_ap_rate_mask = wl18xx_sta_get_ap_rate_mask,
1684 	.ap_get_mimo_wide_rate_mask = wl18xx_ap_get_mimo_wide_rate_mask,
1685 	.get_mac	= wl18xx_get_mac,
1686 	.debugfs_init	= wl18xx_debugfs_add_files,
1687 	.scan_start	= wl18xx_scan_start,
1688 	.scan_stop	= wl18xx_scan_stop,
1689 	.sched_scan_start	= wl18xx_sched_scan_start,
1690 	.sched_scan_stop	= wl18xx_scan_sched_scan_stop,
1691 	.handle_static_data	= wl18xx_handle_static_data,
1692 	.get_spare_blocks = wl18xx_get_spare_blocks,
1693 	.set_key	= wl18xx_set_key,
1694 	.channel_switch	= wl18xx_cmd_channel_switch,
1695 	.pre_pkt_send	= wl18xx_pre_pkt_send,
1696 	.sta_rc_update	= wl18xx_sta_rc_update,
1697 	.set_peer_cap	= wl18xx_set_peer_cap,
1698 	.convert_hwaddr = wl18xx_convert_hwaddr,
1699 	.lnk_high_prio	= wl18xx_lnk_high_prio,
1700 	.lnk_low_prio	= wl18xx_lnk_low_prio,
1701 	.smart_config_start = wl18xx_cmd_smart_config_start,
1702 	.smart_config_stop  = wl18xx_cmd_smart_config_stop,
1703 	.smart_config_set_group_key = wl18xx_cmd_smart_config_set_group_key,
1704 	.interrupt_notify = wl18xx_acx_interrupt_notify_config,
1705 	.rx_ba_filter	= wl18xx_acx_rx_ba_filter,
1706 	.ap_sleep	= wl18xx_acx_ap_sleep,
1707 	.set_cac	= wl18xx_cmd_set_cac,
1708 	.dfs_master_restart	= wl18xx_cmd_dfs_master_restart,
1709 };
1710 
1711 /* HT cap appropriate for wide channels in 2Ghz */
1712 static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_2ghz = {
1713 	.cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 |
1714 	       IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_DSSSCCK40 |
1715 	       IEEE80211_HT_CAP_GRN_FLD,
1716 	.ht_supported = true,
1717 	.ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
1718 	.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
1719 	.mcs = {
1720 		.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
1721 		.rx_highest = cpu_to_le16(150),
1722 		.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
1723 		},
1724 };
1725 
1726 /* HT cap appropriate for wide channels in 5Ghz */
1727 static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_5ghz = {
1728 	.cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 |
1729 	       IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
1730 	       IEEE80211_HT_CAP_GRN_FLD,
1731 	.ht_supported = true,
1732 	.ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
1733 	.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
1734 	.mcs = {
1735 		.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
1736 		.rx_highest = cpu_to_le16(150),
1737 		.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
1738 		},
1739 };
1740 
1741 /* HT cap appropriate for SISO 20 */
1742 static struct ieee80211_sta_ht_cap wl18xx_siso20_ht_cap = {
1743 	.cap = IEEE80211_HT_CAP_SGI_20 |
1744 	       IEEE80211_HT_CAP_GRN_FLD,
1745 	.ht_supported = true,
1746 	.ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
1747 	.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
1748 	.mcs = {
1749 		.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
1750 		.rx_highest = cpu_to_le16(72),
1751 		.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
1752 		},
1753 };
1754 
1755 /* HT cap appropriate for MIMO rates in 20mhz channel */
1756 static struct ieee80211_sta_ht_cap wl18xx_mimo_ht_cap_2ghz = {
1757 	.cap = IEEE80211_HT_CAP_SGI_20 |
1758 	       IEEE80211_HT_CAP_GRN_FLD,
1759 	.ht_supported = true,
1760 	.ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
1761 	.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
1762 	.mcs = {
1763 		.rx_mask = { 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, },
1764 		.rx_highest = cpu_to_le16(144),
1765 		.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
1766 		},
1767 };
1768 
1769 static const struct ieee80211_iface_limit wl18xx_iface_limits[] = {
1770 	{
1771 		.max = 3,
1772 		.types = BIT(NL80211_IFTYPE_STATION),
1773 	},
1774 	{
1775 		.max = 1,
1776 		.types = BIT(NL80211_IFTYPE_AP) |
1777 			 BIT(NL80211_IFTYPE_P2P_GO) |
1778 			 BIT(NL80211_IFTYPE_P2P_CLIENT),
1779 	},
1780 };
1781 
1782 static const struct ieee80211_iface_limit wl18xx_iface_ap_limits[] = {
1783 	{
1784 		.max = 2,
1785 		.types = BIT(NL80211_IFTYPE_AP),
1786 	},
1787 };
1788 
1789 static const struct ieee80211_iface_combination
1790 wl18xx_iface_combinations[] = {
1791 	{
1792 		.max_interfaces = 3,
1793 		.limits = wl18xx_iface_limits,
1794 		.n_limits = ARRAY_SIZE(wl18xx_iface_limits),
1795 		.num_different_channels = 2,
1796 	},
1797 	{
1798 		.max_interfaces = 2,
1799 		.limits = wl18xx_iface_ap_limits,
1800 		.n_limits = ARRAY_SIZE(wl18xx_iface_ap_limits),
1801 		.num_different_channels = 1,
1802 		.radar_detect_widths =	BIT(NL80211_CHAN_NO_HT) |
1803 					BIT(NL80211_CHAN_HT20) |
1804 					BIT(NL80211_CHAN_HT40MINUS) |
1805 					BIT(NL80211_CHAN_HT40PLUS),
1806 	}
1807 };
1808 
1809 static int wl18xx_setup(struct wl1271 *wl)
1810 {
1811 	struct wl18xx_priv *priv = wl->priv;
1812 	int ret;
1813 
1814 	BUILD_BUG_ON(WL18XX_MAX_LINKS > WLCORE_MAX_LINKS);
1815 	BUILD_BUG_ON(WL18XX_MAX_AP_STATIONS > WL18XX_MAX_LINKS);
1816 
1817 	wl->rtable = wl18xx_rtable;
1818 	wl->num_tx_desc = WL18XX_NUM_TX_DESCRIPTORS;
1819 	wl->num_rx_desc = WL18XX_NUM_RX_DESCRIPTORS;
1820 	wl->num_links = WL18XX_MAX_LINKS;
1821 	wl->max_ap_stations = WL18XX_MAX_AP_STATIONS;
1822 	wl->iface_combinations = wl18xx_iface_combinations;
1823 	wl->n_iface_combinations = ARRAY_SIZE(wl18xx_iface_combinations);
1824 	wl->num_mac_addr = WL18XX_NUM_MAC_ADDRESSES;
1825 	wl->band_rate_to_idx = wl18xx_band_rate_to_idx;
1826 	wl->hw_tx_rate_tbl_size = WL18XX_CONF_HW_RXTX_RATE_MAX;
1827 	wl->hw_min_ht_rate = WL18XX_CONF_HW_RXTX_RATE_MCS0;
1828 	wl->fw_status_len = sizeof(struct wl18xx_fw_status);
1829 	wl->fw_status_priv_len = sizeof(struct wl18xx_fw_status_priv);
1830 	wl->stats.fw_stats_len = sizeof(struct wl18xx_acx_statistics);
1831 	wl->static_data_priv_len = sizeof(struct wl18xx_static_data_priv);
1832 
1833 	if (num_rx_desc_param != -1)
1834 		wl->num_rx_desc = num_rx_desc_param;
1835 
1836 	ret = wl18xx_conf_init(wl, wl->dev);
1837 	if (ret < 0)
1838 		return ret;
1839 
1840 	/* If the module param is set, update it in conf */
1841 	if (board_type_param) {
1842 		if (!strcmp(board_type_param, "fpga")) {
1843 			priv->conf.phy.board_type = BOARD_TYPE_FPGA_18XX;
1844 		} else if (!strcmp(board_type_param, "hdk")) {
1845 			priv->conf.phy.board_type = BOARD_TYPE_HDK_18XX;
1846 		} else if (!strcmp(board_type_param, "dvp")) {
1847 			priv->conf.phy.board_type = BOARD_TYPE_DVP_18XX;
1848 		} else if (!strcmp(board_type_param, "evb")) {
1849 			priv->conf.phy.board_type = BOARD_TYPE_EVB_18XX;
1850 		} else if (!strcmp(board_type_param, "com8")) {
1851 			priv->conf.phy.board_type = BOARD_TYPE_COM8_18XX;
1852 		} else {
1853 			wl1271_error("invalid board type '%s'",
1854 				board_type_param);
1855 			return -EINVAL;
1856 		}
1857 	}
1858 
1859 	if (priv->conf.phy.board_type >= NUM_BOARD_TYPES) {
1860 		wl1271_error("invalid board type '%d'",
1861 			priv->conf.phy.board_type);
1862 		return -EINVAL;
1863 	}
1864 
1865 	if (low_band_component_param != -1)
1866 		priv->conf.phy.low_band_component = low_band_component_param;
1867 	if (low_band_component_type_param != -1)
1868 		priv->conf.phy.low_band_component_type =
1869 			low_band_component_type_param;
1870 	if (high_band_component_param != -1)
1871 		priv->conf.phy.high_band_component = high_band_component_param;
1872 	if (high_band_component_type_param != -1)
1873 		priv->conf.phy.high_band_component_type =
1874 			high_band_component_type_param;
1875 	if (pwr_limit_reference_11_abg_param != -1)
1876 		priv->conf.phy.pwr_limit_reference_11_abg =
1877 			pwr_limit_reference_11_abg_param;
1878 	if (n_antennas_2_param != -1)
1879 		priv->conf.phy.number_of_assembled_ant2_4 = n_antennas_2_param;
1880 	if (n_antennas_5_param != -1)
1881 		priv->conf.phy.number_of_assembled_ant5 = n_antennas_5_param;
1882 	if (dc2dc_param != -1)
1883 		priv->conf.phy.external_pa_dc2dc = dc2dc_param;
1884 
1885 	if (ht_mode_param) {
1886 		if (!strcmp(ht_mode_param, "default"))
1887 			priv->conf.ht.mode = HT_MODE_DEFAULT;
1888 		else if (!strcmp(ht_mode_param, "wide"))
1889 			priv->conf.ht.mode = HT_MODE_WIDE;
1890 		else if (!strcmp(ht_mode_param, "siso20"))
1891 			priv->conf.ht.mode = HT_MODE_SISO20;
1892 		else {
1893 			wl1271_error("invalid ht_mode '%s'", ht_mode_param);
1894 			return -EINVAL;
1895 		}
1896 	}
1897 
1898 	if (priv->conf.ht.mode == HT_MODE_DEFAULT) {
1899 		/*
1900 		 * Only support mimo with multiple antennas. Fall back to
1901 		 * siso40.
1902 		 */
1903 		if (wl18xx_is_mimo_supported(wl))
1904 			wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ,
1905 					  &wl18xx_mimo_ht_cap_2ghz);
1906 		else
1907 			wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ,
1908 					  &wl18xx_siso40_ht_cap_2ghz);
1909 
1910 		/* 5Ghz is always wide */
1911 		wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ,
1912 				  &wl18xx_siso40_ht_cap_5ghz);
1913 	} else if (priv->conf.ht.mode == HT_MODE_WIDE) {
1914 		wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ,
1915 				  &wl18xx_siso40_ht_cap_2ghz);
1916 		wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ,
1917 				  &wl18xx_siso40_ht_cap_5ghz);
1918 	} else if (priv->conf.ht.mode == HT_MODE_SISO20) {
1919 		wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ,
1920 				  &wl18xx_siso20_ht_cap);
1921 		wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ,
1922 				  &wl18xx_siso20_ht_cap);
1923 	}
1924 
1925 	if (!checksum_param) {
1926 		wl18xx_ops.set_rx_csum = NULL;
1927 		wl18xx_ops.init_vif = NULL;
1928 	}
1929 
1930 	/* Enable 11a Band only if we have 5G antennas */
1931 	wl->enable_11a = (priv->conf.phy.number_of_assembled_ant5 != 0);
1932 
1933 	return 0;
1934 }
1935 
1936 static int wl18xx_probe(struct platform_device *pdev)
1937 {
1938 	struct wl1271 *wl;
1939 	struct ieee80211_hw *hw;
1940 	int ret;
1941 
1942 	hw = wlcore_alloc_hw(sizeof(struct wl18xx_priv),
1943 			     WL18XX_AGGR_BUFFER_SIZE,
1944 			     sizeof(struct wl18xx_event_mailbox));
1945 	if (IS_ERR(hw)) {
1946 		wl1271_error("can't allocate hw");
1947 		ret = PTR_ERR(hw);
1948 		goto out;
1949 	}
1950 
1951 	wl = hw->priv;
1952 	wl->ops = &wl18xx_ops;
1953 	wl->ptable = wl18xx_ptable;
1954 	ret = wlcore_probe(wl, pdev);
1955 	if (ret)
1956 		goto out_free;
1957 
1958 	return ret;
1959 
1960 out_free:
1961 	wlcore_free_hw(wl);
1962 out:
1963 	return ret;
1964 }
1965 
1966 static const struct platform_device_id wl18xx_id_table[] = {
1967 	{ "wl18xx", 0 },
1968 	{  } /* Terminating Entry */
1969 };
1970 MODULE_DEVICE_TABLE(platform, wl18xx_id_table);
1971 
1972 static struct platform_driver wl18xx_driver = {
1973 	.probe		= wl18xx_probe,
1974 	.remove		= wlcore_remove,
1975 	.id_table	= wl18xx_id_table,
1976 	.driver = {
1977 		.name	= "wl18xx_driver",
1978 	}
1979 };
1980 
1981 module_platform_driver(wl18xx_driver);
1982 module_param_named(ht_mode, ht_mode_param, charp, S_IRUSR);
1983 MODULE_PARM_DESC(ht_mode, "Force HT mode: wide or siso20");
1984 
1985 module_param_named(board_type, board_type_param, charp, S_IRUSR);
1986 MODULE_PARM_DESC(board_type, "Board type: fpga, hdk (default), evb, com8 or "
1987 		 "dvp");
1988 
1989 module_param_named(checksum, checksum_param, bool, S_IRUSR);
1990 MODULE_PARM_DESC(checksum, "Enable TCP checksum: boolean (defaults to false)");
1991 
1992 module_param_named(dc2dc, dc2dc_param, int, S_IRUSR);
1993 MODULE_PARM_DESC(dc2dc, "External DC2DC: u8 (defaults to 0)");
1994 
1995 module_param_named(n_antennas_2, n_antennas_2_param, int, S_IRUSR);
1996 MODULE_PARM_DESC(n_antennas_2,
1997 		 "Number of installed 2.4GHz antennas: 1 (default) or 2");
1998 
1999 module_param_named(n_antennas_5, n_antennas_5_param, int, S_IRUSR);
2000 MODULE_PARM_DESC(n_antennas_5,
2001 		 "Number of installed 5GHz antennas: 1 (default) or 2");
2002 
2003 module_param_named(low_band_component, low_band_component_param, int,
2004 		   S_IRUSR);
2005 MODULE_PARM_DESC(low_band_component, "Low band component: u8 "
2006 		 "(default is 0x01)");
2007 
2008 module_param_named(low_band_component_type, low_band_component_type_param,
2009 		   int, S_IRUSR);
2010 MODULE_PARM_DESC(low_band_component_type, "Low band component type: u8 "
2011 		 "(default is 0x05 or 0x06 depending on the board_type)");
2012 
2013 module_param_named(high_band_component, high_band_component_param, int,
2014 		   S_IRUSR);
2015 MODULE_PARM_DESC(high_band_component, "High band component: u8, "
2016 		 "(default is 0x01)");
2017 
2018 module_param_named(high_band_component_type, high_band_component_type_param,
2019 		   int, S_IRUSR);
2020 MODULE_PARM_DESC(high_band_component_type, "High band component type: u8 "
2021 		 "(default is 0x09)");
2022 
2023 module_param_named(pwr_limit_reference_11_abg,
2024 		   pwr_limit_reference_11_abg_param, int, S_IRUSR);
2025 MODULE_PARM_DESC(pwr_limit_reference_11_abg, "Power limit reference: u8 "
2026 		 "(default is 0xc8)");
2027 
2028 module_param_named(num_rx_desc,
2029 		   num_rx_desc_param, int, S_IRUSR);
2030 MODULE_PARM_DESC(num_rx_desc_param,
2031 		 "Number of Rx descriptors: u8 (default is 32)");
2032 
2033 MODULE_LICENSE("GPL v2");
2034 MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
2035 MODULE_FIRMWARE(WL18XX_FW_NAME);
2036