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