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