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