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