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/mod_devicetable.h>
24#include <linux/platform_device.h>
25
26#include <linux/err.h>
27
28#include "../wlcore/wlcore.h"
29#include "../wlcore/debug.h"
30#include "../wlcore/io.h"
31#include "../wlcore/acx.h"
32#include "../wlcore/tx.h"
33#include "../wlcore/rx.h"
34#include "../wlcore/boot.h"
35
36#include "wl12xx.h"
37#include "reg.h"
38#include "cmd.h"
39#include "acx.h"
40#include "scan.h"
41#include "event.h"
42#include "debugfs.h"
43#include "conf.h"
44
45static char *fref_param;
46static char *tcxo_param;
47
48static struct wlcore_conf wl12xx_conf = {
49 .sg = {
50 .params = {
51 [WL12XX_CONF_SG_ACL_BT_MASTER_MIN_BR] = 10,
52 [WL12XX_CONF_SG_ACL_BT_MASTER_MAX_BR] = 180,
53 [WL12XX_CONF_SG_ACL_BT_SLAVE_MIN_BR] = 10,
54 [WL12XX_CONF_SG_ACL_BT_SLAVE_MAX_BR] = 180,
55 [WL12XX_CONF_SG_ACL_BT_MASTER_MIN_EDR] = 10,
56 [WL12XX_CONF_SG_ACL_BT_MASTER_MAX_EDR] = 80,
57 [WL12XX_CONF_SG_ACL_BT_SLAVE_MIN_EDR] = 10,
58 [WL12XX_CONF_SG_ACL_BT_SLAVE_MAX_EDR] = 80,
59 [WL12XX_CONF_SG_ACL_WLAN_PS_MASTER_BR] = 8,
60 [WL12XX_CONF_SG_ACL_WLAN_PS_SLAVE_BR] = 8,
61 [WL12XX_CONF_SG_ACL_WLAN_PS_MASTER_EDR] = 20,
62 [WL12XX_CONF_SG_ACL_WLAN_PS_SLAVE_EDR] = 20,
63 [WL12XX_CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_BR] = 20,
64 [WL12XX_CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_BR] = 35,
65 [WL12XX_CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_BR] = 16,
66 [WL12XX_CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_BR] = 35,
67 [WL12XX_CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_EDR] = 32,
68 [WL12XX_CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_EDR] = 50,
69 [WL12XX_CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_EDR] = 28,
70 [WL12XX_CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_EDR] = 50,
71 [WL12XX_CONF_SG_ACL_ACTIVE_SCAN_WLAN_BR] = 10,
72 [WL12XX_CONF_SG_ACL_ACTIVE_SCAN_WLAN_EDR] = 20,
73 [WL12XX_CONF_SG_ACL_PASSIVE_SCAN_BT_BR] = 75,
74 [WL12XX_CONF_SG_ACL_PASSIVE_SCAN_WLAN_BR] = 15,
75 [WL12XX_CONF_SG_ACL_PASSIVE_SCAN_BT_EDR] = 27,
76 [WL12XX_CONF_SG_ACL_PASSIVE_SCAN_WLAN_EDR] = 17,
77
78 [WL12XX_CONF_SG_AUTO_SCAN_PROBE_REQ] = 170,
79 [WL12XX_CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3] = 50,
80 [WL12XX_CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP] = 100,
81
82 [WL12XX_CONF_SG_PASSIVE_SCAN_DUR_FACTOR_A2DP_BR] = 800,
83 [WL12XX_CONF_SG_PASSIVE_SCAN_DUR_FACTOR_A2DP_EDR] = 200,
84 [WL12XX_CONF_SG_PASSIVE_SCAN_DUR_FACTOR_HV3] = 200,
85
86 [WL12XX_CONF_SG_CONSECUTIVE_HV3_IN_PASSIVE_SCAN] = 0,
87 [WL12XX_CONF_SG_BCN_HV3_COLL_THR_IN_PASSIVE_SCAN] = 0,
88 [WL12XX_CONF_SG_TX_RX_PROTECT_BW_IN_PASSIVE_SCAN] = 0,
89
90 [WL12XX_CONF_SG_STA_FORCE_PS_IN_BT_SCO] = 1,
91 [WL12XX_CONF_SG_ANTENNA_CONFIGURATION] = 0,
92 [WL12XX_CONF_SG_BEACON_MISS_PERCENT] = 60,
93 [WL12XX_CONF_SG_DHCP_TIME] = 5000,
94 [WL12XX_CONF_SG_RXT] = 1200,
95 [WL12XX_CONF_SG_TXT] = 1000,
96 [WL12XX_CONF_SG_ADAPTIVE_RXT_TXT] = 1,
97 [WL12XX_CONF_SG_GENERAL_USAGE_BIT_MAP] = 3,
98 [WL12XX_CONF_SG_HV3_MAX_SERVED] = 6,
99 [WL12XX_CONF_SG_PS_POLL_TIMEOUT] = 10,
100 [WL12XX_CONF_SG_UPSD_TIMEOUT] = 10,
101 [WL12XX_CONF_SG_CONSECUTIVE_CTS_THRESHOLD] = 2,
102 [WL12XX_CONF_SG_STA_RX_WINDOW_AFTER_DTIM] = 5,
103 [WL12XX_CONF_SG_STA_CONNECTION_PROTECTION_TIME] = 30,
104
105 [WL12XX_CONF_AP_BEACON_MISS_TX] = 3,
106 [WL12XX_CONF_AP_RX_WINDOW_AFTER_BEACON] = 10,
107 [WL12XX_CONF_AP_BEACON_WINDOW_INTERVAL] = 2,
108 [WL12XX_CONF_AP_CONNECTION_PROTECTION_TIME] = 0,
109 [WL12XX_CONF_AP_BT_ACL_VAL_BT_SERVE_TIME] = 25,
110 [WL12XX_CONF_AP_BT_ACL_VAL_WL_SERVE_TIME] = 25,
111
112 [WL12XX_CONF_SG_CTS_DILUTED_BAD_RX_PACKETS_TH] = 0,
113 [WL12XX_CONF_SG_CTS_CHOP_IN_DUAL_ANT_SCO_MASTER] = 0,
114 },
115 .state = CONF_SG_PROTECTIVE,
116 },
117 .rx = {
118 .rx_msdu_life_time = 512000,
119 .packet_detection_threshold = 0,
120 .ps_poll_timeout = 15,
121 .upsd_timeout = 15,
122 .rts_threshold = IEEE80211_MAX_RTS_THRESHOLD,
123 .rx_cca_threshold = 0,
124 .irq_blk_threshold = 0xFFFF,
125 .irq_pkt_threshold = 0,
126 .irq_timeout = 600,
127 .queue_type = CONF_RX_QUEUE_TYPE_LOW_PRIORITY,
128 },
129 .tx = {
130 .tx_energy_detection = 0,
131 .sta_rc_conf = {
132 .enabled_rates = 0,
133 .short_retry_limit = 10,
134 .long_retry_limit = 10,
135 .aflags = 0,
136 },
137 .ac_conf_count = 4,
138 .ac_conf = {
139 [CONF_TX_AC_BE] = {
140 .ac = CONF_TX_AC_BE,
141 .cw_min = 15,
142 .cw_max = 63,
143 .aifsn = 3,
144 .tx_op_limit = 0,
145 },
146 [CONF_TX_AC_BK] = {
147 .ac = CONF_TX_AC_BK,
148 .cw_min = 15,
149 .cw_max = 63,
150 .aifsn = 7,
151 .tx_op_limit = 0,
152 },
153 [CONF_TX_AC_VI] = {
154 .ac = CONF_TX_AC_VI,
155 .cw_min = 15,
156 .cw_max = 63,
157 .aifsn = CONF_TX_AIFS_PIFS,
158 .tx_op_limit = 3008,
159 },
160 [CONF_TX_AC_VO] = {
161 .ac = CONF_TX_AC_VO,
162 .cw_min = 15,
163 .cw_max = 63,
164 .aifsn = CONF_TX_AIFS_PIFS,
165 .tx_op_limit = 1504,
166 },
167 },
168 .max_tx_retries = 100,
169 .ap_aging_period = 300,
170 .tid_conf_count = 4,
171 .tid_conf = {
172 [CONF_TX_AC_BE] = {
173 .queue_id = CONF_TX_AC_BE,
174 .channel_type = CONF_CHANNEL_TYPE_EDCF,
175 .tsid = CONF_TX_AC_BE,
176 .ps_scheme = CONF_PS_SCHEME_LEGACY,
177 .ack_policy = CONF_ACK_POLICY_LEGACY,
178 .apsd_conf = {0, 0},
179 },
180 [CONF_TX_AC_BK] = {
181 .queue_id = CONF_TX_AC_BK,
182 .channel_type = CONF_CHANNEL_TYPE_EDCF,
183 .tsid = CONF_TX_AC_BK,
184 .ps_scheme = CONF_PS_SCHEME_LEGACY,
185 .ack_policy = CONF_ACK_POLICY_LEGACY,
186 .apsd_conf = {0, 0},
187 },
188 [CONF_TX_AC_VI] = {
189 .queue_id = CONF_TX_AC_VI,
190 .channel_type = CONF_CHANNEL_TYPE_EDCF,
191 .tsid = CONF_TX_AC_VI,
192 .ps_scheme = CONF_PS_SCHEME_LEGACY,
193 .ack_policy = CONF_ACK_POLICY_LEGACY,
194 .apsd_conf = {0, 0},
195 },
196 [CONF_TX_AC_VO] = {
197 .queue_id = CONF_TX_AC_VO,
198 .channel_type = CONF_CHANNEL_TYPE_EDCF,
199 .tsid = CONF_TX_AC_VO,
200 .ps_scheme = CONF_PS_SCHEME_LEGACY,
201 .ack_policy = CONF_ACK_POLICY_LEGACY,
202 .apsd_conf = {0, 0},
203 },
204 },
205 .frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD,
206 .tx_compl_timeout = 700,
207 .tx_compl_threshold = 4,
208 .basic_rate = CONF_HW_BIT_RATE_1MBPS,
209 .basic_rate_5 = CONF_HW_BIT_RATE_6MBPS,
210 .tmpl_short_retry_limit = 10,
211 .tmpl_long_retry_limit = 10,
212 .tx_watchdog_timeout = 5000,
213 .slow_link_thold = 3,
214 .fast_link_thold = 10,
215 },
216 .conn = {
217 .wake_up_event = CONF_WAKE_UP_EVENT_DTIM,
218 .listen_interval = 1,
219 .suspend_wake_up_event = CONF_WAKE_UP_EVENT_N_DTIM,
220 .suspend_listen_interval = 3,
221 .bcn_filt_mode = CONF_BCN_FILT_MODE_ENABLED,
222 .bcn_filt_ie_count = 3,
223 .bcn_filt_ie = {
224 [0] = {
225 .ie = WLAN_EID_CHANNEL_SWITCH,
226 .rule = CONF_BCN_RULE_PASS_ON_APPEARANCE,
227 },
228 [1] = {
229 .ie = WLAN_EID_HT_OPERATION,
230 .rule = CONF_BCN_RULE_PASS_ON_CHANGE,
231 },
232 [2] = {
233 .ie = WLAN_EID_ERP_INFO,
234 .rule = CONF_BCN_RULE_PASS_ON_CHANGE,
235 },
236 },
237 .synch_fail_thold = 12,
238 .bss_lose_timeout = 400,
239 .beacon_rx_timeout = 10000,
240 .broadcast_timeout = 20000,
241 .rx_broadcast_in_ps = 1,
242 .ps_poll_threshold = 10,
243 .bet_enable = CONF_BET_MODE_ENABLE,
244 .bet_max_consecutive = 50,
245 .psm_entry_retries = 8,
246 .psm_exit_retries = 16,
247 .psm_entry_nullfunc_retries = 3,
248 .dynamic_ps_timeout = 1500,
249 .forced_ps = false,
250 .keep_alive_interval = 55000,
251 .max_listen_interval = 20,
252 .sta_sleep_auth = WL1271_PSM_ILLEGAL,
253 .suspend_rx_ba_activity = 0,
254 },
255 .itrim = {
256 .enable = false,
257 .timeout = 50000,
258 },
259 .pm_config = {
260 .host_clk_settling_time = 5000,
261 .host_fast_wakeup_support = CONF_FAST_WAKEUP_DISABLE,
262 },
263 .roam_trigger = {
264 .trigger_pacing = 1,
265 .avg_weight_rssi_beacon = 20,
266 .avg_weight_rssi_data = 10,
267 .avg_weight_snr_beacon = 20,
268 .avg_weight_snr_data = 10,
269 },
270 .scan = {
271 .min_dwell_time_active = 7500,
272 .max_dwell_time_active = 30000,
273 .min_dwell_time_active_long = 25000,
274 .max_dwell_time_active_long = 50000,
275 .dwell_time_passive = 100000,
276 .dwell_time_dfs = 150000,
277 .num_probe_reqs = 2,
278 .split_scan_timeout = 50000,
279 },
280 .sched_scan = {
281
282
283
284
285 .base_dwell_time = 7500,
286 .max_dwell_time_delta = 22500,
287
288 .dwell_time_delta_per_probe = 2000,
289
290 .dwell_time_delta_per_probe_5 = 350,
291 .dwell_time_passive = 100000,
292 .dwell_time_dfs = 150000,
293 .num_probe_reqs = 2,
294 .rssi_threshold = -90,
295 .snr_threshold = 0,
296 },
297 .ht = {
298 .rx_ba_win_size = 8,
299 .tx_ba_win_size = 64,
300 .inactivity_timeout = 10000,
301 .tx_ba_tid_bitmap = CONF_TX_BA_ENABLED_TID_BITMAP,
302 },
303
304
305
306
307
308 .mem = {
309 .num_stations = 1,
310 .ssid_profiles = 1,
311 .rx_block_num = 40,
312 .tx_min_block_num = 40,
313 .dynamic_memory = 1,
314 .min_req_tx_blocks = 45,
315 .min_req_rx_blocks = 22,
316 .tx_min = 27,
317 },
318 .fm_coex = {
319 .enable = true,
320 .swallow_period = 5,
321 .n_divider_fref_set_1 = 0xff,
322 .n_divider_fref_set_2 = 12,
323 .m_divider_fref_set_1 = 0xffff,
324 .m_divider_fref_set_2 = 148,
325 .coex_pll_stabilization_time = 0xffffffff,
326 .ldo_stabilization_time = 0xffff,
327 .fm_disturbed_band_margin = 0xff,
328 .swallow_clk_diff = 0xff,
329 },
330 .rx_streaming = {
331 .duration = 150,
332 .queues = 0x1,
333 .interval = 20,
334 .always = 0,
335 },
336 .fwlog = {
337 .mode = WL12XX_FWLOG_CONTINUOUS,
338 .mem_blocks = 2,
339 .severity = 0,
340 .timestamp = WL12XX_FWLOG_TIMESTAMP_DISABLED,
341 .output = WL12XX_FWLOG_OUTPUT_DBG_PINS,
342 .threshold = 0,
343 },
344 .rate = {
345 .rate_retry_score = 32000,
346 .per_add = 8192,
347 .per_th1 = 2048,
348 .per_th2 = 4096,
349 .max_per = 8100,
350 .inverse_curiosity_factor = 5,
351 .tx_fail_low_th = 4,
352 .tx_fail_high_th = 10,
353 .per_alpha_shift = 4,
354 .per_add_shift = 13,
355 .per_beta1_shift = 10,
356 .per_beta2_shift = 8,
357 .rate_check_up = 2,
358 .rate_check_down = 12,
359 .rate_retry_policy = {
360 0x00, 0x00, 0x00, 0x00, 0x00,
361 0x00, 0x00, 0x00, 0x00, 0x00,
362 0x00, 0x00, 0x00,
363 },
364 },
365 .hangover = {
366 .recover_time = 0,
367 .hangover_period = 20,
368 .dynamic_mode = 1,
369 .early_termination_mode = 1,
370 .max_period = 20,
371 .min_period = 1,
372 .increase_delta = 1,
373 .decrease_delta = 2,
374 .quiet_time = 4,
375 .increase_time = 1,
376 .window_size = 16,
377 },
378 .recovery = {
379 .bug_on_recovery = 0,
380 .no_recovery = 0,
381 },
382};
383
384static struct wl12xx_priv_conf wl12xx_default_priv_conf = {
385 .rf = {
386 .tx_per_channel_power_compensation_2 = {
387 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
388 },
389 .tx_per_channel_power_compensation_5 = {
390 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
391 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
392 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
393 },
394 },
395 .mem_wl127x = {
396 .num_stations = 1,
397 .ssid_profiles = 1,
398 .rx_block_num = 70,
399 .tx_min_block_num = 40,
400 .dynamic_memory = 1,
401 .min_req_tx_blocks = 100,
402 .min_req_rx_blocks = 22,
403 .tx_min = 27,
404 },
405
406};
407
408#define WL12XX_TX_HW_BLOCK_SPARE_DEFAULT 1
409#define WL12XX_TX_HW_BLOCK_GEM_SPARE 2
410#define WL12XX_TX_HW_BLOCK_SIZE 252
411
412static const u8 wl12xx_rate_to_idx_2ghz[] = {
413
414 7,
415 7,
416 6,
417 5,
418 4,
419 3,
420 2,
421 1,
422 0,
423
424 11,
425 10,
426 9,
427 8,
428
429
430 CONF_HW_RXTX_RATE_UNSUPPORTED,
431
432 7,
433 6,
434 3,
435 5,
436 4,
437 2,
438 1,
439 0
440};
441
442static const u8 wl12xx_rate_to_idx_5ghz[] = {
443
444 7,
445 7,
446 6,
447 5,
448 4,
449 3,
450 2,
451 1,
452 0,
453
454 7,
455 6,
456 5,
457 4,
458
459
460 CONF_HW_RXTX_RATE_UNSUPPORTED,
461
462 3,
463 2,
464 CONF_HW_RXTX_RATE_UNSUPPORTED,
465 1,
466 0,
467 CONF_HW_RXTX_RATE_UNSUPPORTED,
468 CONF_HW_RXTX_RATE_UNSUPPORTED,
469 CONF_HW_RXTX_RATE_UNSUPPORTED
470};
471
472static const u8 *wl12xx_band_rate_to_idx[] = {
473 [NL80211_BAND_2GHZ] = wl12xx_rate_to_idx_2ghz,
474 [NL80211_BAND_5GHZ] = wl12xx_rate_to_idx_5ghz
475};
476
477enum wl12xx_hw_rates {
478 WL12XX_CONF_HW_RXTX_RATE_MCS7_SGI = 0,
479 WL12XX_CONF_HW_RXTX_RATE_MCS7,
480 WL12XX_CONF_HW_RXTX_RATE_MCS6,
481 WL12XX_CONF_HW_RXTX_RATE_MCS5,
482 WL12XX_CONF_HW_RXTX_RATE_MCS4,
483 WL12XX_CONF_HW_RXTX_RATE_MCS3,
484 WL12XX_CONF_HW_RXTX_RATE_MCS2,
485 WL12XX_CONF_HW_RXTX_RATE_MCS1,
486 WL12XX_CONF_HW_RXTX_RATE_MCS0,
487 WL12XX_CONF_HW_RXTX_RATE_54,
488 WL12XX_CONF_HW_RXTX_RATE_48,
489 WL12XX_CONF_HW_RXTX_RATE_36,
490 WL12XX_CONF_HW_RXTX_RATE_24,
491 WL12XX_CONF_HW_RXTX_RATE_22,
492 WL12XX_CONF_HW_RXTX_RATE_18,
493 WL12XX_CONF_HW_RXTX_RATE_12,
494 WL12XX_CONF_HW_RXTX_RATE_11,
495 WL12XX_CONF_HW_RXTX_RATE_9,
496 WL12XX_CONF_HW_RXTX_RATE_6,
497 WL12XX_CONF_HW_RXTX_RATE_5_5,
498 WL12XX_CONF_HW_RXTX_RATE_2,
499 WL12XX_CONF_HW_RXTX_RATE_1,
500 WL12XX_CONF_HW_RXTX_RATE_MAX,
501};
502
503static struct wlcore_partition_set wl12xx_ptable[PART_TABLE_LEN] = {
504 [PART_DOWN] = {
505 .mem = {
506 .start = 0x00000000,
507 .size = 0x000177c0
508 },
509 .reg = {
510 .start = REGISTERS_BASE,
511 .size = 0x00008800
512 },
513 .mem2 = {
514 .start = 0x00000000,
515 .size = 0x00000000
516 },
517 .mem3 = {
518 .start = 0x00000000,
519 .size = 0x00000000
520 },
521 },
522
523 [PART_BOOT] = {
524
525 .mem = {
526 .start = 0x00040000,
527 .size = 0x00014fc0
528 },
529 .reg = {
530 .start = REGISTERS_BASE,
531 .size = 0x00008800
532 },
533 .mem2 = {
534 .start = 0x00000000,
535 .size = 0x00000000
536 },
537 .mem3 = {
538 .start = 0x00000000,
539 .size = 0x00000000
540 },
541 },
542
543 [PART_WORK] = {
544 .mem = {
545 .start = 0x00040000,
546 .size = 0x00014fc0
547 },
548 .reg = {
549 .start = REGISTERS_BASE,
550 .size = 0x0000a000
551 },
552 .mem2 = {
553 .start = 0x003004f8,
554 .size = 0x00000004
555 },
556 .mem3 = {
557 .start = 0x00000000,
558 .size = 0x00040404
559 },
560 },
561
562 [PART_DRPW] = {
563 .mem = {
564 .start = 0x00040000,
565 .size = 0x00014fc0
566 },
567 .reg = {
568 .start = DRPW_BASE,
569 .size = 0x00006000
570 },
571 .mem2 = {
572 .start = 0x00000000,
573 .size = 0x00000000
574 },
575 .mem3 = {
576 .start = 0x00000000,
577 .size = 0x00000000
578 }
579 }
580};
581
582static const int wl12xx_rtable[REG_TABLE_LEN] = {
583 [REG_ECPU_CONTROL] = WL12XX_REG_ECPU_CONTROL,
584 [REG_INTERRUPT_NO_CLEAR] = WL12XX_REG_INTERRUPT_NO_CLEAR,
585 [REG_INTERRUPT_ACK] = WL12XX_REG_INTERRUPT_ACK,
586 [REG_COMMAND_MAILBOX_PTR] = WL12XX_REG_COMMAND_MAILBOX_PTR,
587 [REG_EVENT_MAILBOX_PTR] = WL12XX_REG_EVENT_MAILBOX_PTR,
588 [REG_INTERRUPT_TRIG] = WL12XX_REG_INTERRUPT_TRIG,
589 [REG_INTERRUPT_MASK] = WL12XX_REG_INTERRUPT_MASK,
590 [REG_PC_ON_RECOVERY] = WL12XX_SCR_PAD4,
591 [REG_CHIP_ID_B] = WL12XX_CHIP_ID_B,
592 [REG_CMD_MBOX_ADDRESS] = WL12XX_CMD_MBOX_ADDRESS,
593
594
595 [REG_SLV_MEM_DATA] = WL1271_SLV_MEM_DATA,
596 [REG_SLV_REG_DATA] = WL1271_SLV_REG_DATA,
597
598
599 [REG_RAW_FW_STATUS_ADDR] = FW_STATUS_ADDR,
600};
601
602
603#define WL127X_FW_NAME_MULTI "ti-connectivity/wl127x-fw-5-mr.bin"
604#define WL127X_FW_NAME_SINGLE "ti-connectivity/wl127x-fw-5-sr.bin"
605#define WL127X_PLT_FW_NAME "ti-connectivity/wl127x-fw-5-plt.bin"
606
607#define WL128X_FW_NAME_MULTI "ti-connectivity/wl128x-fw-5-mr.bin"
608#define WL128X_FW_NAME_SINGLE "ti-connectivity/wl128x-fw-5-sr.bin"
609#define WL128X_PLT_FW_NAME "ti-connectivity/wl128x-fw-5-plt.bin"
610
611static int wl127x_prepare_read(struct wl1271 *wl, u32 rx_desc, u32 len)
612{
613 int ret;
614
615 if (wl->chip.id != CHIP_ID_128X_PG20) {
616 struct wl1271_acx_mem_map *wl_mem_map = wl->target_mem_map;
617 struct wl12xx_priv *priv = wl->priv;
618
619
620
621
622
623
624 u32 mem_block = rx_desc & RX_MEM_BLOCK_MASK;
625
626 priv->rx_mem_addr->addr = (mem_block << 8) +
627 le32_to_cpu(wl_mem_map->packet_memory_pool_start);
628
629 priv->rx_mem_addr->addr_extra = priv->rx_mem_addr->addr + 4;
630
631 ret = wlcore_write(wl, WL1271_SLV_REG_DATA, priv->rx_mem_addr,
632 sizeof(*priv->rx_mem_addr), false);
633 if (ret < 0)
634 return ret;
635 }
636
637 return 0;
638}
639
640static int wl12xx_identify_chip(struct wl1271 *wl)
641{
642 int ret = 0;
643
644 switch (wl->chip.id) {
645 case CHIP_ID_127X_PG10:
646 wl1271_warning("chip id 0x%x (1271 PG10) support is obsolete",
647 wl->chip.id);
648
649 wl->quirks |= WLCORE_QUIRK_LEGACY_NVS |
650 WLCORE_QUIRK_DUAL_PROBE_TMPL |
651 WLCORE_QUIRK_TKIP_HEADER_SPACE |
652 WLCORE_QUIRK_START_STA_FAILS |
653 WLCORE_QUIRK_AP_ZERO_SESSION_ID;
654 wl->sr_fw_name = WL127X_FW_NAME_SINGLE;
655 wl->mr_fw_name = WL127X_FW_NAME_MULTI;
656 memcpy(&wl->conf.mem, &wl12xx_default_priv_conf.mem_wl127x,
657 sizeof(wl->conf.mem));
658
659
660 wl->ops->prepare_read = wl127x_prepare_read;
661
662 wlcore_set_min_fw_ver(wl, WL127X_CHIP_VER,
663 WL127X_IFTYPE_SR_VER, WL127X_MAJOR_SR_VER,
664 WL127X_SUBTYPE_SR_VER, WL127X_MINOR_SR_VER,
665 WL127X_IFTYPE_MR_VER, WL127X_MAJOR_MR_VER,
666 WL127X_SUBTYPE_MR_VER, WL127X_MINOR_MR_VER);
667 break;
668
669 case CHIP_ID_127X_PG20:
670 wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)",
671 wl->chip.id);
672
673 wl->quirks |= WLCORE_QUIRK_LEGACY_NVS |
674 WLCORE_QUIRK_DUAL_PROBE_TMPL |
675 WLCORE_QUIRK_TKIP_HEADER_SPACE |
676 WLCORE_QUIRK_START_STA_FAILS |
677 WLCORE_QUIRK_AP_ZERO_SESSION_ID;
678 wl->plt_fw_name = WL127X_PLT_FW_NAME;
679 wl->sr_fw_name = WL127X_FW_NAME_SINGLE;
680 wl->mr_fw_name = WL127X_FW_NAME_MULTI;
681 memcpy(&wl->conf.mem, &wl12xx_default_priv_conf.mem_wl127x,
682 sizeof(wl->conf.mem));
683
684
685 wl->ops->prepare_read = wl127x_prepare_read;
686
687 wlcore_set_min_fw_ver(wl, WL127X_CHIP_VER,
688 WL127X_IFTYPE_SR_VER, WL127X_MAJOR_SR_VER,
689 WL127X_SUBTYPE_SR_VER, WL127X_MINOR_SR_VER,
690 WL127X_IFTYPE_MR_VER, WL127X_MAJOR_MR_VER,
691 WL127X_SUBTYPE_MR_VER, WL127X_MINOR_MR_VER);
692 break;
693
694 case CHIP_ID_128X_PG20:
695 wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1283 PG20)",
696 wl->chip.id);
697 wl->plt_fw_name = WL128X_PLT_FW_NAME;
698 wl->sr_fw_name = WL128X_FW_NAME_SINGLE;
699 wl->mr_fw_name = WL128X_FW_NAME_MULTI;
700
701
702 wl->quirks |= WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN |
703 WLCORE_QUIRK_DUAL_PROBE_TMPL |
704 WLCORE_QUIRK_TKIP_HEADER_SPACE |
705 WLCORE_QUIRK_START_STA_FAILS |
706 WLCORE_QUIRK_AP_ZERO_SESSION_ID;
707
708 wlcore_set_min_fw_ver(wl, WL128X_CHIP_VER,
709 WL128X_IFTYPE_SR_VER, WL128X_MAJOR_SR_VER,
710 WL128X_SUBTYPE_SR_VER, WL128X_MINOR_SR_VER,
711 WL128X_IFTYPE_MR_VER, WL128X_MAJOR_MR_VER,
712 WL128X_SUBTYPE_MR_VER, WL128X_MINOR_MR_VER);
713 break;
714 case CHIP_ID_128X_PG10:
715 default:
716 wl1271_warning("unsupported chip id: 0x%x", wl->chip.id);
717 ret = -ENODEV;
718 goto out;
719 }
720
721 wl->fw_mem_block_size = 256;
722 wl->fwlog_end = 0x2000000;
723
724
725 wl->scan_templ_id_2_4 = CMD_TEMPL_APP_PROBE_REQ_2_4_LEGACY;
726 wl->scan_templ_id_5 = CMD_TEMPL_APP_PROBE_REQ_5_LEGACY;
727 wl->sched_scan_templ_id_2_4 = CMD_TEMPL_CFG_PROBE_REQ_2_4;
728 wl->sched_scan_templ_id_5 = CMD_TEMPL_CFG_PROBE_REQ_5;
729 wl->max_channels_5 = WL12XX_MAX_CHANNELS_5GHZ;
730 wl->ba_rx_session_count_max = WL12XX_RX_BA_MAX_SESSIONS;
731out:
732 return ret;
733}
734
735static int __must_check wl12xx_top_reg_write(struct wl1271 *wl, int addr,
736 u16 val)
737{
738 int ret;
739
740
741 addr = (addr >> 1) + 0x30000;
742 ret = wlcore_write32(wl, WL12XX_OCP_POR_CTR, addr);
743 if (ret < 0)
744 goto out;
745
746
747 ret = wlcore_write32(wl, WL12XX_OCP_DATA_WRITE, val);
748 if (ret < 0)
749 goto out;
750
751
752 ret = wlcore_write32(wl, WL12XX_OCP_CMD, OCP_CMD_WRITE);
753 if (ret < 0)
754 goto out;
755
756out:
757 return ret;
758}
759
760static int __must_check wl12xx_top_reg_read(struct wl1271 *wl, int addr,
761 u16 *out)
762{
763 u32 val;
764 int timeout = OCP_CMD_LOOP;
765 int ret;
766
767
768 addr = (addr >> 1) + 0x30000;
769 ret = wlcore_write32(wl, WL12XX_OCP_POR_CTR, addr);
770 if (ret < 0)
771 return ret;
772
773
774 ret = wlcore_write32(wl, WL12XX_OCP_CMD, OCP_CMD_READ);
775 if (ret < 0)
776 return ret;
777
778
779 do {
780 ret = wlcore_read32(wl, WL12XX_OCP_DATA_READ, &val);
781 if (ret < 0)
782 return ret;
783 } while (!(val & OCP_READY_MASK) && --timeout);
784
785 if (!timeout) {
786 wl1271_warning("Top register access timed out.");
787 return -ETIMEDOUT;
788 }
789
790
791 if ((val & OCP_STATUS_MASK) != OCP_STATUS_OK) {
792 wl1271_warning("Top register access returned error.");
793 return -EIO;
794 }
795
796 if (out)
797 *out = val & 0xffff;
798
799 return 0;
800}
801
802static int wl128x_switch_tcxo_to_fref(struct wl1271 *wl)
803{
804 u16 spare_reg;
805 int ret;
806
807
808 ret = wl12xx_top_reg_read(wl, WL_SPARE_REG, &spare_reg);
809 if (ret < 0)
810 return ret;
811
812 if (spare_reg == 0xFFFF)
813 return -EFAULT;
814 spare_reg |= (BIT(3) | BIT(5) | BIT(6));
815 ret = wl12xx_top_reg_write(wl, WL_SPARE_REG, spare_reg);
816 if (ret < 0)
817 return ret;
818
819
820 ret = wl12xx_top_reg_write(wl, SYS_CLK_CFG_REG,
821 WL_CLK_REQ_TYPE_PG2 | MCS_PLL_CLK_SEL_FREF);
822 if (ret < 0)
823 return ret;
824
825
826 mdelay(15);
827
828 return 0;
829}
830
831static bool wl128x_is_tcxo_valid(struct wl1271 *wl)
832{
833 u16 tcxo_detection;
834 int ret;
835
836 ret = wl12xx_top_reg_read(wl, TCXO_CLK_DETECT_REG, &tcxo_detection);
837 if (ret < 0)
838 return false;
839
840 if (tcxo_detection & TCXO_DET_FAILED)
841 return false;
842
843 return true;
844}
845
846static bool wl128x_is_fref_valid(struct wl1271 *wl)
847{
848 u16 fref_detection;
849 int ret;
850
851 ret = wl12xx_top_reg_read(wl, FREF_CLK_DETECT_REG, &fref_detection);
852 if (ret < 0)
853 return false;
854
855 if (fref_detection & FREF_CLK_DETECT_FAIL)
856 return false;
857
858 return true;
859}
860
861static int wl128x_manually_configure_mcs_pll(struct wl1271 *wl)
862{
863 int ret;
864
865 ret = wl12xx_top_reg_write(wl, MCS_PLL_M_REG, MCS_PLL_M_REG_VAL);
866 if (ret < 0)
867 goto out;
868
869 ret = wl12xx_top_reg_write(wl, MCS_PLL_N_REG, MCS_PLL_N_REG_VAL);
870 if (ret < 0)
871 goto out;
872
873 ret = wl12xx_top_reg_write(wl, MCS_PLL_CONFIG_REG,
874 MCS_PLL_CONFIG_REG_VAL);
875
876out:
877 return ret;
878}
879
880static int wl128x_configure_mcs_pll(struct wl1271 *wl, int clk)
881{
882 u16 spare_reg;
883 u16 pll_config;
884 u8 input_freq;
885 struct wl12xx_priv *priv = wl->priv;
886 int ret;
887
888
889 ret = wl12xx_top_reg_read(wl, WL_SPARE_REG, &spare_reg);
890 if (ret < 0)
891 return ret;
892
893 if (spare_reg == 0xFFFF)
894 return -EFAULT;
895 spare_reg |= BIT(2);
896 ret = wl12xx_top_reg_write(wl, WL_SPARE_REG, spare_reg);
897 if (ret < 0)
898 return ret;
899
900
901 if (priv->tcxo_clock == WL12XX_TCXOCLOCK_16_8 ||
902 priv->tcxo_clock == WL12XX_TCXOCLOCK_33_6)
903 return wl128x_manually_configure_mcs_pll(wl);
904
905
906 input_freq = (clk & 1) + 1;
907
908 ret = wl12xx_top_reg_read(wl, MCS_PLL_CONFIG_REG, &pll_config);
909 if (ret < 0)
910 return ret;
911
912 if (pll_config == 0xFFFF)
913 return -EFAULT;
914 pll_config |= (input_freq << MCS_SEL_IN_FREQ_SHIFT);
915 pll_config |= MCS_PLL_ENABLE_HP;
916 ret = wl12xx_top_reg_write(wl, MCS_PLL_CONFIG_REG, pll_config);
917
918 return ret;
919}
920
921
922
923
924
925
926
927
928static int wl128x_boot_clk(struct wl1271 *wl, int *selected_clock)
929{
930 struct wl12xx_priv *priv = wl->priv;
931 u16 sys_clk_cfg;
932 int ret;
933
934
935 if (priv->ref_clock == WL12XX_REFCLOCK_26_XTAL ||
936 priv->ref_clock == WL12XX_REFCLOCK_38_XTAL) {
937 if (!wl128x_switch_tcxo_to_fref(wl))
938 return -EINVAL;
939 goto fref_clk;
940 }
941
942
943 ret = wl12xx_top_reg_read(wl, SYS_CLK_CFG_REG, &sys_clk_cfg);
944 if (ret < 0)
945 return ret;
946
947 if (sys_clk_cfg == 0xFFFF)
948 return -EINVAL;
949 if (sys_clk_cfg & PRCM_CM_EN_MUX_WLAN_FREF)
950 goto fref_clk;
951
952
953 if (priv->tcxo_clock == WL12XX_TCXOCLOCK_16_368 ||
954 priv->tcxo_clock == WL12XX_TCXOCLOCK_32_736) {
955 if (!wl128x_switch_tcxo_to_fref(wl))
956 return -EINVAL;
957 goto fref_clk;
958 }
959
960
961 if (!wl128x_is_tcxo_valid(wl))
962 return -EINVAL;
963 *selected_clock = priv->tcxo_clock;
964 goto config_mcs_pll;
965
966fref_clk:
967
968 if (!wl128x_is_fref_valid(wl))
969 return -EINVAL;
970 *selected_clock = priv->ref_clock;
971
972config_mcs_pll:
973 return wl128x_configure_mcs_pll(wl, *selected_clock);
974}
975
976static int wl127x_boot_clk(struct wl1271 *wl)
977{
978 struct wl12xx_priv *priv = wl->priv;
979 u32 pause;
980 u32 clk;
981 int ret;
982
983 if (WL127X_PG_GET_MAJOR(wl->hw_pg_ver) < 3)
984 wl->quirks |= WLCORE_QUIRK_END_OF_TRANSACTION;
985
986 if (priv->ref_clock == CONF_REF_CLK_19_2_E ||
987 priv->ref_clock == CONF_REF_CLK_38_4_E ||
988 priv->ref_clock == CONF_REF_CLK_38_4_M_XTAL)
989
990 clk = 0x3;
991 else if (priv->ref_clock == CONF_REF_CLK_26_E ||
992 priv->ref_clock == CONF_REF_CLK_26_M_XTAL ||
993 priv->ref_clock == CONF_REF_CLK_52_E)
994
995 clk = 0x5;
996 else
997 return -EINVAL;
998
999 if (priv->ref_clock != CONF_REF_CLK_19_2_E) {
1000 u16 val;
1001
1002 ret = wl12xx_top_reg_read(wl, OCP_REG_CLK_TYPE, &val);
1003 if (ret < 0)
1004 goto out;
1005
1006 val &= FREF_CLK_TYPE_BITS;
1007 ret = wl12xx_top_reg_write(wl, OCP_REG_CLK_TYPE, val);
1008 if (ret < 0)
1009 goto out;
1010
1011
1012 ret = wl12xx_top_reg_read(wl, OCP_REG_CLK_PULL, &val);
1013 if (ret < 0)
1014 goto out;
1015
1016 val |= NO_PULL;
1017 ret = wl12xx_top_reg_write(wl, OCP_REG_CLK_PULL, val);
1018 if (ret < 0)
1019 goto out;
1020 } else {
1021 u16 val;
1022
1023 ret = wl12xx_top_reg_read(wl, OCP_REG_CLK_POLARITY, &val);
1024 if (ret < 0)
1025 goto out;
1026
1027 val &= FREF_CLK_POLARITY_BITS;
1028 val |= CLK_REQ_OUTN_SEL;
1029 ret = wl12xx_top_reg_write(wl, OCP_REG_CLK_POLARITY, val);
1030 if (ret < 0)
1031 goto out;
1032 }
1033
1034 ret = wlcore_write32(wl, WL12XX_PLL_PARAMETERS, clk);
1035 if (ret < 0)
1036 goto out;
1037
1038 ret = wlcore_read32(wl, WL12XX_PLL_PARAMETERS, &pause);
1039 if (ret < 0)
1040 goto out;
1041
1042 wl1271_debug(DEBUG_BOOT, "pause1 0x%x", pause);
1043
1044 pause &= ~(WU_COUNTER_PAUSE_VAL);
1045 pause |= WU_COUNTER_PAUSE_VAL;
1046 ret = wlcore_write32(wl, WL12XX_WU_COUNTER_PAUSE, pause);
1047
1048out:
1049 return ret;
1050}
1051
1052static int wl1271_boot_soft_reset(struct wl1271 *wl)
1053{
1054 unsigned long timeout;
1055 u32 boot_data;
1056 int ret = 0;
1057
1058
1059 ret = wlcore_write32(wl, WL12XX_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT);
1060 if (ret < 0)
1061 goto out;
1062
1063
1064 timeout = jiffies + usecs_to_jiffies(SOFT_RESET_MAX_TIME);
1065 while (1) {
1066 ret = wlcore_read32(wl, WL12XX_SLV_SOFT_RESET, &boot_data);
1067 if (ret < 0)
1068 goto out;
1069
1070 wl1271_debug(DEBUG_BOOT, "soft reset bootdata 0x%x", boot_data);
1071 if ((boot_data & ACX_SLV_SOFT_RESET_BIT) == 0)
1072 break;
1073
1074 if (time_after(jiffies, timeout)) {
1075
1076
1077 wl1271_error("soft reset timeout");
1078 return -1;
1079 }
1080
1081 udelay(SOFT_RESET_STALL_TIME);
1082 }
1083
1084
1085 ret = wlcore_write32(wl, WL12XX_ENABLE, 0x0);
1086 if (ret < 0)
1087 goto out;
1088
1089
1090 ret = wlcore_write32(wl, WL12XX_SPARE_A2, 0xffff);
1091
1092out:
1093 return ret;
1094}
1095
1096static int wl12xx_pre_boot(struct wl1271 *wl)
1097{
1098 struct wl12xx_priv *priv = wl->priv;
1099 int ret = 0;
1100 u32 clk;
1101 int selected_clock = -1;
1102
1103 if (wl->chip.id == CHIP_ID_128X_PG20) {
1104 ret = wl128x_boot_clk(wl, &selected_clock);
1105 if (ret < 0)
1106 goto out;
1107 } else {
1108 ret = wl127x_boot_clk(wl);
1109 if (ret < 0)
1110 goto out;
1111 }
1112
1113
1114 ret = wlcore_write32(wl, WL12XX_WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL);
1115 if (ret < 0)
1116 goto out;
1117
1118 udelay(500);
1119
1120 ret = wlcore_set_partition(wl, &wl->ptable[PART_DRPW]);
1121 if (ret < 0)
1122 goto out;
1123
1124
1125
1126
1127
1128 ret = wlcore_read32(wl, WL12XX_DRPW_SCRATCH_START, &clk);
1129 if (ret < 0)
1130 goto out;
1131
1132 wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk);
1133
1134 if (wl->chip.id == CHIP_ID_128X_PG20)
1135 clk |= ((selected_clock & 0x3) << 1) << 4;
1136 else
1137 clk |= (priv->ref_clock << 1) << 4;
1138
1139 ret = wlcore_write32(wl, WL12XX_DRPW_SCRATCH_START, clk);
1140 if (ret < 0)
1141 goto out;
1142
1143 ret = wlcore_set_partition(wl, &wl->ptable[PART_WORK]);
1144 if (ret < 0)
1145 goto out;
1146
1147
1148 ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
1149 if (ret < 0)
1150 goto out;
1151
1152 ret = wl1271_boot_soft_reset(wl);
1153 if (ret < 0)
1154 goto out;
1155
1156out:
1157 return ret;
1158}
1159
1160static int wl12xx_pre_upload(struct wl1271 *wl)
1161{
1162 u32 tmp;
1163 u16 polarity;
1164 int ret;
1165
1166
1167
1168 wl1271_debug(DEBUG_BOOT, "ACX_EEPROMLESS_IND_REG");
1169
1170 ret = wlcore_write32(wl, WL12XX_EEPROMLESS_IND, WL12XX_EEPROMLESS_IND);
1171 if (ret < 0)
1172 goto out;
1173
1174 ret = wlcore_read_reg(wl, REG_CHIP_ID_B, &tmp);
1175 if (ret < 0)
1176 goto out;
1177
1178 wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp);
1179
1180
1181 ret = wlcore_read32(wl, WL12XX_SCR_PAD2, &tmp);
1182 if (ret < 0)
1183 goto out;
1184
1185
1186
1187
1188 if (wl->chip.id == CHIP_ID_128X_PG20) {
1189 ret = wl12xx_top_reg_write(wl, SDIO_IO_DS, HCI_IO_DS_6MA);
1190 if (ret < 0)
1191 goto out;
1192 }
1193
1194
1195 ret = wl12xx_top_reg_read(wl, OCP_REG_POLARITY, &polarity);
1196 if (ret < 0)
1197 goto out;
1198
1199
1200 polarity &= ~POLARITY_LOW;
1201 ret = wl12xx_top_reg_write(wl, OCP_REG_POLARITY, polarity);
1202
1203out:
1204 return ret;
1205}
1206
1207static int wl12xx_enable_interrupts(struct wl1271 *wl)
1208{
1209 int ret;
1210
1211 ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK,
1212 WL12XX_ACX_ALL_EVENTS_VECTOR);
1213 if (ret < 0)
1214 goto out;
1215
1216 wlcore_enable_interrupts(wl);
1217 ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK,
1218 WL1271_ACX_INTR_ALL & ~(WL12XX_INTR_MASK));
1219 if (ret < 0)
1220 goto disable_interrupts;
1221
1222 ret = wlcore_write32(wl, WL12XX_HI_CFG, HI_CFG_DEF_VAL);
1223 if (ret < 0)
1224 goto disable_interrupts;
1225
1226 return ret;
1227
1228disable_interrupts:
1229 wlcore_disable_interrupts(wl);
1230
1231out:
1232 return ret;
1233}
1234
1235static int wl12xx_boot(struct wl1271 *wl)
1236{
1237 int ret;
1238
1239 ret = wl12xx_pre_boot(wl);
1240 if (ret < 0)
1241 goto out;
1242
1243 ret = wlcore_boot_upload_nvs(wl);
1244 if (ret < 0)
1245 goto out;
1246
1247 ret = wl12xx_pre_upload(wl);
1248 if (ret < 0)
1249 goto out;
1250
1251 ret = wlcore_boot_upload_firmware(wl);
1252 if (ret < 0)
1253 goto out;
1254
1255 wl->event_mask = BSS_LOSE_EVENT_ID |
1256 REGAINED_BSS_EVENT_ID |
1257 SCAN_COMPLETE_EVENT_ID |
1258 ROLE_STOP_COMPLETE_EVENT_ID |
1259 RSSI_SNR_TRIGGER_0_EVENT_ID |
1260 PSPOLL_DELIVERY_FAILURE_EVENT_ID |
1261 SOFT_GEMINI_SENSE_EVENT_ID |
1262 PERIODIC_SCAN_REPORT_EVENT_ID |
1263 PERIODIC_SCAN_COMPLETE_EVENT_ID |
1264 DUMMY_PACKET_EVENT_ID |
1265 PEER_REMOVE_COMPLETE_EVENT_ID |
1266 BA_SESSION_RX_CONSTRAINT_EVENT_ID |
1267 REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID |
1268 INACTIVE_STA_EVENT_ID |
1269 CHANNEL_SWITCH_COMPLETE_EVENT_ID;
1270
1271 wl->ap_event_mask = MAX_TX_RETRY_EVENT_ID;
1272
1273 ret = wlcore_boot_run_firmware(wl);
1274 if (ret < 0)
1275 goto out;
1276
1277 ret = wl12xx_enable_interrupts(wl);
1278
1279out:
1280 return ret;
1281}
1282
1283static int wl12xx_trigger_cmd(struct wl1271 *wl, int cmd_box_addr,
1284 void *buf, size_t len)
1285{
1286 int ret;
1287
1288 ret = wlcore_write(wl, cmd_box_addr, buf, len, false);
1289 if (ret < 0)
1290 return ret;
1291
1292 ret = wlcore_write_reg(wl, REG_INTERRUPT_TRIG, WL12XX_INTR_TRIG_CMD);
1293
1294 return ret;
1295}
1296
1297static int wl12xx_ack_event(struct wl1271 *wl)
1298{
1299 return wlcore_write_reg(wl, REG_INTERRUPT_TRIG,
1300 WL12XX_INTR_TRIG_EVENT_ACK);
1301}
1302
1303static u32 wl12xx_calc_tx_blocks(struct wl1271 *wl, u32 len, u32 spare_blks)
1304{
1305 u32 blk_size = WL12XX_TX_HW_BLOCK_SIZE;
1306 u32 align_len = wlcore_calc_packet_alignment(wl, len);
1307
1308 return (align_len + blk_size - 1) / blk_size + spare_blks;
1309}
1310
1311static void
1312wl12xx_set_tx_desc_blocks(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc,
1313 u32 blks, u32 spare_blks)
1314{
1315 if (wl->chip.id == CHIP_ID_128X_PG20) {
1316 desc->wl128x_mem.total_mem_blocks = blks;
1317 } else {
1318 desc->wl127x_mem.extra_blocks = spare_blks;
1319 desc->wl127x_mem.total_mem_blocks = blks;
1320 }
1321}
1322
1323static void
1324wl12xx_set_tx_desc_data_len(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc,
1325 struct sk_buff *skb)
1326{
1327 u32 aligned_len = wlcore_calc_packet_alignment(wl, skb->len);
1328
1329 if (wl->chip.id == CHIP_ID_128X_PG20) {
1330 desc->wl128x_mem.extra_bytes = aligned_len - skb->len;
1331 desc->length = cpu_to_le16(aligned_len >> 2);
1332
1333 wl1271_debug(DEBUG_TX,
1334 "tx_fill_hdr: hlid: %d len: %d life: %d mem: %d extra: %d",
1335 desc->hlid,
1336 le16_to_cpu(desc->length),
1337 le16_to_cpu(desc->life_time),
1338 desc->wl128x_mem.total_mem_blocks,
1339 desc->wl128x_mem.extra_bytes);
1340 } else {
1341
1342 int pad = aligned_len - skb->len;
1343 desc->tx_attr |=
1344 cpu_to_le16(pad << TX_HW_ATTR_OFST_LAST_WORD_PAD);
1345
1346
1347 desc->length = cpu_to_le16(aligned_len >> 2);
1348
1349 wl1271_debug(DEBUG_TX,
1350 "tx_fill_hdr: pad: %d hlid: %d len: %d life: %d mem: %d",
1351 pad, desc->hlid,
1352 le16_to_cpu(desc->length),
1353 le16_to_cpu(desc->life_time),
1354 desc->wl127x_mem.total_mem_blocks);
1355 }
1356}
1357
1358static enum wl_rx_buf_align
1359wl12xx_get_rx_buf_align(struct wl1271 *wl, u32 rx_desc)
1360{
1361 if (rx_desc & RX_BUF_UNALIGNED_PAYLOAD)
1362 return WLCORE_RX_BUF_UNALIGNED;
1363
1364 return WLCORE_RX_BUF_ALIGNED;
1365}
1366
1367static u32 wl12xx_get_rx_packet_len(struct wl1271 *wl, void *rx_data,
1368 u32 data_len)
1369{
1370 struct wl1271_rx_descriptor *desc = rx_data;
1371
1372
1373 if (data_len < sizeof(*desc) ||
1374 data_len < sizeof(*desc) + desc->pad_len)
1375 return 0;
1376
1377 return data_len - sizeof(*desc) - desc->pad_len;
1378}
1379
1380static int wl12xx_tx_delayed_compl(struct wl1271 *wl)
1381{
1382 if (wl->fw_status->tx_results_counter ==
1383 (wl->tx_results_count & 0xff))
1384 return 0;
1385
1386 return wlcore_tx_complete(wl);
1387}
1388
1389static int wl12xx_hw_init(struct wl1271 *wl)
1390{
1391 int ret;
1392
1393 if (wl->chip.id == CHIP_ID_128X_PG20) {
1394 u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE;
1395
1396 ret = wl128x_cmd_general_parms(wl);
1397 if (ret < 0)
1398 goto out;
1399
1400
1401
1402
1403
1404 if (wl->plt_mode == PLT_FEM_DETECT)
1405 goto out;
1406
1407 ret = wl128x_cmd_radio_parms(wl);
1408 if (ret < 0)
1409 goto out;
1410
1411 if (wl->quirks & WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN)
1412
1413 host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK;
1414
1415
1416 ret = wl1271_acx_host_if_cfg_bitmap(wl, host_cfg_bitmap);
1417 if (ret < 0)
1418 goto out;
1419 } else {
1420 ret = wl1271_cmd_general_parms(wl);
1421 if (ret < 0)
1422 goto out;
1423
1424
1425
1426
1427
1428 if (wl->plt_mode == PLT_FEM_DETECT)
1429 goto out;
1430
1431 ret = wl1271_cmd_radio_parms(wl);
1432 if (ret < 0)
1433 goto out;
1434 ret = wl1271_cmd_ext_radio_parms(wl);
1435 if (ret < 0)
1436 goto out;
1437 }
1438out:
1439 return ret;
1440}
1441
1442static void wl12xx_convert_fw_status(struct wl1271 *wl, void *raw_fw_status,
1443 struct wl_fw_status *fw_status)
1444{
1445 struct wl12xx_fw_status *int_fw_status = raw_fw_status;
1446
1447 fw_status->intr = le32_to_cpu(int_fw_status->intr);
1448 fw_status->fw_rx_counter = int_fw_status->fw_rx_counter;
1449 fw_status->drv_rx_counter = int_fw_status->drv_rx_counter;
1450 fw_status->tx_results_counter = int_fw_status->tx_results_counter;
1451 fw_status->rx_pkt_descs = int_fw_status->rx_pkt_descs;
1452
1453 fw_status->fw_localtime = le32_to_cpu(int_fw_status->fw_localtime);
1454 fw_status->link_ps_bitmap = le32_to_cpu(int_fw_status->link_ps_bitmap);
1455 fw_status->link_fast_bitmap =
1456 le32_to_cpu(int_fw_status->link_fast_bitmap);
1457 fw_status->total_released_blks =
1458 le32_to_cpu(int_fw_status->total_released_blks);
1459 fw_status->tx_total = le32_to_cpu(int_fw_status->tx_total);
1460
1461 fw_status->counters.tx_released_pkts =
1462 int_fw_status->counters.tx_released_pkts;
1463 fw_status->counters.tx_lnk_free_pkts =
1464 int_fw_status->counters.tx_lnk_free_pkts;
1465 fw_status->counters.tx_voice_released_blks =
1466 int_fw_status->counters.tx_voice_released_blks;
1467 fw_status->counters.tx_last_rate =
1468 int_fw_status->counters.tx_last_rate;
1469
1470 fw_status->log_start_addr = le32_to_cpu(int_fw_status->log_start_addr);
1471}
1472
1473static u32 wl12xx_sta_get_ap_rate_mask(struct wl1271 *wl,
1474 struct wl12xx_vif *wlvif)
1475{
1476 return wlvif->rate_set;
1477}
1478
1479static void wl12xx_conf_init(struct wl1271 *wl)
1480{
1481 struct wl12xx_priv *priv = wl->priv;
1482
1483
1484 memcpy(&wl->conf, &wl12xx_conf, sizeof(wl12xx_conf));
1485
1486
1487 memcpy(&priv->conf, &wl12xx_default_priv_conf, sizeof(priv->conf));
1488}
1489
1490static bool wl12xx_mac_in_fuse(struct wl1271 *wl)
1491{
1492 bool supported = false;
1493 u8 major, minor;
1494
1495 if (wl->chip.id == CHIP_ID_128X_PG20) {
1496 major = WL128X_PG_GET_MAJOR(wl->hw_pg_ver);
1497 minor = WL128X_PG_GET_MINOR(wl->hw_pg_ver);
1498
1499
1500 if (major > 2 || (major == 2 && minor >= 1))
1501 supported = true;
1502 } else {
1503 major = WL127X_PG_GET_MAJOR(wl->hw_pg_ver);
1504 minor = WL127X_PG_GET_MINOR(wl->hw_pg_ver);
1505
1506
1507 if (major == 3 && minor >= 1)
1508 supported = true;
1509 }
1510
1511 wl1271_debug(DEBUG_PROBE,
1512 "PG Ver major = %d minor = %d, MAC %s present",
1513 major, minor, supported ? "is" : "is not");
1514
1515 return supported;
1516}
1517
1518static int wl12xx_get_fuse_mac(struct wl1271 *wl)
1519{
1520 u32 mac1, mac2;
1521 int ret;
1522
1523 ret = wlcore_set_partition(wl, &wl->ptable[PART_DRPW]);
1524 if (ret < 0)
1525 goto out;
1526
1527 ret = wlcore_read32(wl, WL12XX_REG_FUSE_BD_ADDR_1, &mac1);
1528 if (ret < 0)
1529 goto out;
1530
1531 ret = wlcore_read32(wl, WL12XX_REG_FUSE_BD_ADDR_2, &mac2);
1532 if (ret < 0)
1533 goto out;
1534
1535
1536 wl->fuse_oui_addr = ((mac2 & 0xffff) << 8) +
1537 ((mac1 & 0xff000000) >> 24);
1538 wl->fuse_nic_addr = mac1 & 0xffffff;
1539
1540 ret = wlcore_set_partition(wl, &wl->ptable[PART_DOWN]);
1541
1542out:
1543 return ret;
1544}
1545
1546static int wl12xx_get_pg_ver(struct wl1271 *wl, s8 *ver)
1547{
1548 u16 die_info;
1549 int ret;
1550
1551 if (wl->chip.id == CHIP_ID_128X_PG20)
1552 ret = wl12xx_top_reg_read(wl, WL128X_REG_FUSE_DATA_2_1,
1553 &die_info);
1554 else
1555 ret = wl12xx_top_reg_read(wl, WL127X_REG_FUSE_DATA_2_1,
1556 &die_info);
1557
1558 if (ret >= 0 && ver)
1559 *ver = (s8)((die_info & PG_VER_MASK) >> PG_VER_OFFSET);
1560
1561 return ret;
1562}
1563
1564static int wl12xx_get_mac(struct wl1271 *wl)
1565{
1566 if (wl12xx_mac_in_fuse(wl))
1567 return wl12xx_get_fuse_mac(wl);
1568
1569 return 0;
1570}
1571
1572static void wl12xx_set_tx_desc_csum(struct wl1271 *wl,
1573 struct wl1271_tx_hw_descr *desc,
1574 struct sk_buff *skb)
1575{
1576 desc->wl12xx_reserved = 0;
1577}
1578
1579static int wl12xx_plt_init(struct wl1271 *wl)
1580{
1581 int ret;
1582
1583 ret = wl->ops->boot(wl);
1584 if (ret < 0)
1585 goto out;
1586
1587 ret = wl->ops->hw_init(wl);
1588 if (ret < 0)
1589 goto out_irq_disable;
1590
1591
1592
1593
1594
1595 if (wl->plt_mode == PLT_FEM_DETECT)
1596 goto out;
1597
1598 ret = wl1271_acx_init_mem_config(wl);
1599 if (ret < 0)
1600 goto out_irq_disable;
1601
1602 ret = wl12xx_acx_mem_cfg(wl);
1603 if (ret < 0)
1604 goto out_free_memmap;
1605
1606
1607 ret = wl1271_cmd_data_path(wl, 1);
1608 if (ret < 0)
1609 goto out_free_memmap;
1610
1611
1612 ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM);
1613 if (ret < 0)
1614 goto out_free_memmap;
1615
1616
1617 ret = wl1271_acx_pm_config(wl);
1618 if (ret < 0)
1619 goto out_free_memmap;
1620
1621 goto out;
1622
1623out_free_memmap:
1624 kfree(wl->target_mem_map);
1625 wl->target_mem_map = NULL;
1626
1627out_irq_disable:
1628 mutex_unlock(&wl->mutex);
1629
1630
1631
1632
1633
1634
1635
1636 wlcore_disable_interrupts(wl);
1637 mutex_lock(&wl->mutex);
1638out:
1639 return ret;
1640}
1641
1642static int wl12xx_get_spare_blocks(struct wl1271 *wl, bool is_gem)
1643{
1644 if (is_gem)
1645 return WL12XX_TX_HW_BLOCK_GEM_SPARE;
1646
1647 return WL12XX_TX_HW_BLOCK_SPARE_DEFAULT;
1648}
1649
1650static int wl12xx_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
1651 struct ieee80211_vif *vif,
1652 struct ieee80211_sta *sta,
1653 struct ieee80211_key_conf *key_conf)
1654{
1655 return wlcore_set_key(wl, cmd, vif, sta, key_conf);
1656}
1657
1658static int wl12xx_set_peer_cap(struct wl1271 *wl,
1659 struct ieee80211_sta_ht_cap *ht_cap,
1660 bool allow_ht_operation,
1661 u32 rate_set, u8 hlid)
1662{
1663 return wl1271_acx_set_ht_capabilities(wl, ht_cap, allow_ht_operation,
1664 hlid);
1665}
1666
1667static bool wl12xx_lnk_high_prio(struct wl1271 *wl, u8 hlid,
1668 struct wl1271_link *lnk)
1669{
1670 u8 thold;
1671
1672 if (test_bit(hlid, &wl->fw_fast_lnk_map))
1673 thold = wl->conf.tx.fast_link_thold;
1674 else
1675 thold = wl->conf.tx.slow_link_thold;
1676
1677 return lnk->allocated_pkts < thold;
1678}
1679
1680static bool wl12xx_lnk_low_prio(struct wl1271 *wl, u8 hlid,
1681 struct wl1271_link *lnk)
1682{
1683
1684 return true;
1685}
1686
1687static u32 wl12xx_convert_hwaddr(struct wl1271 *wl, u32 hwaddr)
1688{
1689 return hwaddr << 5;
1690}
1691
1692static int wl12xx_setup(struct wl1271 *wl);
1693
1694static struct wlcore_ops wl12xx_ops = {
1695 .setup = wl12xx_setup,
1696 .identify_chip = wl12xx_identify_chip,
1697 .boot = wl12xx_boot,
1698 .plt_init = wl12xx_plt_init,
1699 .trigger_cmd = wl12xx_trigger_cmd,
1700 .ack_event = wl12xx_ack_event,
1701 .wait_for_event = wl12xx_wait_for_event,
1702 .process_mailbox_events = wl12xx_process_mailbox_events,
1703 .calc_tx_blocks = wl12xx_calc_tx_blocks,
1704 .set_tx_desc_blocks = wl12xx_set_tx_desc_blocks,
1705 .set_tx_desc_data_len = wl12xx_set_tx_desc_data_len,
1706 .get_rx_buf_align = wl12xx_get_rx_buf_align,
1707 .get_rx_packet_len = wl12xx_get_rx_packet_len,
1708 .tx_immediate_compl = NULL,
1709 .tx_delayed_compl = wl12xx_tx_delayed_compl,
1710 .hw_init = wl12xx_hw_init,
1711 .init_vif = NULL,
1712 .convert_fw_status = wl12xx_convert_fw_status,
1713 .sta_get_ap_rate_mask = wl12xx_sta_get_ap_rate_mask,
1714 .get_pg_ver = wl12xx_get_pg_ver,
1715 .get_mac = wl12xx_get_mac,
1716 .set_tx_desc_csum = wl12xx_set_tx_desc_csum,
1717 .set_rx_csum = NULL,
1718 .ap_get_mimo_wide_rate_mask = NULL,
1719 .debugfs_init = wl12xx_debugfs_add_files,
1720 .scan_start = wl12xx_scan_start,
1721 .scan_stop = wl12xx_scan_stop,
1722 .sched_scan_start = wl12xx_sched_scan_start,
1723 .sched_scan_stop = wl12xx_scan_sched_scan_stop,
1724 .get_spare_blocks = wl12xx_get_spare_blocks,
1725 .set_key = wl12xx_set_key,
1726 .channel_switch = wl12xx_cmd_channel_switch,
1727 .pre_pkt_send = NULL,
1728 .set_peer_cap = wl12xx_set_peer_cap,
1729 .convert_hwaddr = wl12xx_convert_hwaddr,
1730 .lnk_high_prio = wl12xx_lnk_high_prio,
1731 .lnk_low_prio = wl12xx_lnk_low_prio,
1732 .interrupt_notify = NULL,
1733 .rx_ba_filter = NULL,
1734 .ap_sleep = NULL,
1735};
1736
1737static struct ieee80211_sta_ht_cap wl12xx_ht_cap = {
1738 .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 |
1739 (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT),
1740 .ht_supported = true,
1741 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K,
1742 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_8,
1743 .mcs = {
1744 .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
1745 .rx_highest = cpu_to_le16(72),
1746 .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
1747 },
1748};
1749
1750static const struct ieee80211_iface_limit wl12xx_iface_limits[] = {
1751 {
1752 .max = 3,
1753 .types = BIT(NL80211_IFTYPE_STATION),
1754 },
1755 {
1756 .max = 1,
1757 .types = BIT(NL80211_IFTYPE_AP) |
1758 BIT(NL80211_IFTYPE_P2P_GO) |
1759 BIT(NL80211_IFTYPE_P2P_CLIENT),
1760 },
1761};
1762
1763static const struct ieee80211_iface_combination
1764wl12xx_iface_combinations[] = {
1765 {
1766 .max_interfaces = 3,
1767 .limits = wl12xx_iface_limits,
1768 .n_limits = ARRAY_SIZE(wl12xx_iface_limits),
1769 .num_different_channels = 1,
1770 },
1771};
1772
1773static const struct wl12xx_clock wl12xx_refclock_table[] = {
1774 { 19200000, false, WL12XX_REFCLOCK_19 },
1775 { 26000000, false, WL12XX_REFCLOCK_26 },
1776 { 26000000, true, WL12XX_REFCLOCK_26_XTAL },
1777 { 38400000, false, WL12XX_REFCLOCK_38 },
1778 { 38400000, true, WL12XX_REFCLOCK_38_XTAL },
1779 { 52000000, false, WL12XX_REFCLOCK_52 },
1780 { 0, false, 0 }
1781};
1782
1783static const struct wl12xx_clock wl12xx_tcxoclock_table[] = {
1784 { 16368000, true, WL12XX_TCXOCLOCK_16_368 },
1785 { 16800000, true, WL12XX_TCXOCLOCK_16_8 },
1786 { 19200000, true, WL12XX_TCXOCLOCK_19_2 },
1787 { 26000000, true, WL12XX_TCXOCLOCK_26 },
1788 { 32736000, true, WL12XX_TCXOCLOCK_32_736 },
1789 { 33600000, true, WL12XX_TCXOCLOCK_33_6 },
1790 { 38400000, true, WL12XX_TCXOCLOCK_38_4 },
1791 { 52000000, true, WL12XX_TCXOCLOCK_52 },
1792 { 0, false, 0 }
1793};
1794
1795static int wl12xx_get_clock_idx(const struct wl12xx_clock *table,
1796 u32 freq, bool xtal)
1797{
1798 int i;
1799
1800 for (i = 0; table[i].freq != 0; i++)
1801 if ((table[i].freq == freq) && (table[i].xtal == xtal))
1802 return table[i].hw_idx;
1803
1804 return -EINVAL;
1805}
1806
1807static int wl12xx_setup(struct wl1271 *wl)
1808{
1809 struct wl12xx_priv *priv = wl->priv;
1810 struct wlcore_platdev_data *pdev_data = dev_get_platdata(&wl->pdev->dev);
1811
1812 BUILD_BUG_ON(WL12XX_MAX_LINKS > WLCORE_MAX_LINKS);
1813 BUILD_BUG_ON(WL12XX_MAX_AP_STATIONS > WL12XX_MAX_LINKS);
1814 BUILD_BUG_ON(WL12XX_CONF_SG_PARAMS_MAX > WLCORE_CONF_SG_PARAMS_MAX);
1815
1816 wl->rtable = wl12xx_rtable;
1817 wl->num_tx_desc = WL12XX_NUM_TX_DESCRIPTORS;
1818 wl->num_rx_desc = WL12XX_NUM_RX_DESCRIPTORS;
1819 wl->num_links = WL12XX_MAX_LINKS;
1820 wl->max_ap_stations = WL12XX_MAX_AP_STATIONS;
1821 wl->iface_combinations = wl12xx_iface_combinations;
1822 wl->n_iface_combinations = ARRAY_SIZE(wl12xx_iface_combinations);
1823 wl->num_mac_addr = WL12XX_NUM_MAC_ADDRESSES;
1824 wl->band_rate_to_idx = wl12xx_band_rate_to_idx;
1825 wl->hw_tx_rate_tbl_size = WL12XX_CONF_HW_RXTX_RATE_MAX;
1826 wl->hw_min_ht_rate = WL12XX_CONF_HW_RXTX_RATE_MCS0;
1827 wl->fw_status_len = sizeof(struct wl12xx_fw_status);
1828 wl->fw_status_priv_len = 0;
1829 wl->stats.fw_stats_len = sizeof(struct wl12xx_acx_statistics);
1830 wl->ofdm_only_ap = true;
1831 wlcore_set_ht_cap(wl, NL80211_BAND_2GHZ, &wl12xx_ht_cap);
1832 wlcore_set_ht_cap(wl, NL80211_BAND_5GHZ, &wl12xx_ht_cap);
1833 wl12xx_conf_init(wl);
1834
1835 if (!fref_param) {
1836 priv->ref_clock = wl12xx_get_clock_idx(wl12xx_refclock_table,
1837 pdev_data->ref_clock_freq,
1838 pdev_data->ref_clock_xtal);
1839 if (priv->ref_clock < 0) {
1840 wl1271_error("Invalid ref_clock frequency (%d Hz, %s)",
1841 pdev_data->ref_clock_freq,
1842 pdev_data->ref_clock_xtal ?
1843 "XTAL" : "not XTAL");
1844
1845 return priv->ref_clock;
1846 }
1847 } else {
1848 if (!strcmp(fref_param, "19.2"))
1849 priv->ref_clock = WL12XX_REFCLOCK_19;
1850 else if (!strcmp(fref_param, "26"))
1851 priv->ref_clock = WL12XX_REFCLOCK_26;
1852 else if (!strcmp(fref_param, "26x"))
1853 priv->ref_clock = WL12XX_REFCLOCK_26_XTAL;
1854 else if (!strcmp(fref_param, "38.4"))
1855 priv->ref_clock = WL12XX_REFCLOCK_38;
1856 else if (!strcmp(fref_param, "38.4x"))
1857 priv->ref_clock = WL12XX_REFCLOCK_38_XTAL;
1858 else if (!strcmp(fref_param, "52"))
1859 priv->ref_clock = WL12XX_REFCLOCK_52;
1860 else
1861 wl1271_error("Invalid fref parameter %s", fref_param);
1862 }
1863
1864 if (!tcxo_param && pdev_data->tcxo_clock_freq) {
1865 priv->tcxo_clock = wl12xx_get_clock_idx(wl12xx_tcxoclock_table,
1866 pdev_data->tcxo_clock_freq,
1867 true);
1868 if (priv->tcxo_clock < 0) {
1869 wl1271_error("Invalid tcxo_clock frequency (%d Hz)",
1870 pdev_data->tcxo_clock_freq);
1871
1872 return priv->tcxo_clock;
1873 }
1874 } else if (tcxo_param) {
1875 if (!strcmp(tcxo_param, "19.2"))
1876 priv->tcxo_clock = WL12XX_TCXOCLOCK_19_2;
1877 else if (!strcmp(tcxo_param, "26"))
1878 priv->tcxo_clock = WL12XX_TCXOCLOCK_26;
1879 else if (!strcmp(tcxo_param, "38.4"))
1880 priv->tcxo_clock = WL12XX_TCXOCLOCK_38_4;
1881 else if (!strcmp(tcxo_param, "52"))
1882 priv->tcxo_clock = WL12XX_TCXOCLOCK_52;
1883 else if (!strcmp(tcxo_param, "16.368"))
1884 priv->tcxo_clock = WL12XX_TCXOCLOCK_16_368;
1885 else if (!strcmp(tcxo_param, "32.736"))
1886 priv->tcxo_clock = WL12XX_TCXOCLOCK_32_736;
1887 else if (!strcmp(tcxo_param, "16.8"))
1888 priv->tcxo_clock = WL12XX_TCXOCLOCK_16_8;
1889 else if (!strcmp(tcxo_param, "33.6"))
1890 priv->tcxo_clock = WL12XX_TCXOCLOCK_33_6;
1891 else
1892 wl1271_error("Invalid tcxo parameter %s", tcxo_param);
1893 }
1894
1895 priv->rx_mem_addr = kmalloc(sizeof(*priv->rx_mem_addr), GFP_KERNEL);
1896 if (!priv->rx_mem_addr)
1897 return -ENOMEM;
1898
1899 return 0;
1900}
1901
1902static int wl12xx_probe(struct platform_device *pdev)
1903{
1904 struct wl1271 *wl;
1905 struct ieee80211_hw *hw;
1906 int ret;
1907
1908 hw = wlcore_alloc_hw(sizeof(struct wl12xx_priv),
1909 WL12XX_AGGR_BUFFER_SIZE,
1910 sizeof(struct wl12xx_event_mailbox));
1911 if (IS_ERR(hw)) {
1912 wl1271_error("can't allocate hw");
1913 ret = PTR_ERR(hw);
1914 goto out;
1915 }
1916
1917 wl = hw->priv;
1918 wl->ops = &wl12xx_ops;
1919 wl->ptable = wl12xx_ptable;
1920 ret = wlcore_probe(wl, pdev);
1921 if (ret)
1922 goto out_free;
1923
1924 return ret;
1925
1926out_free:
1927 wlcore_free_hw(wl);
1928out:
1929 return ret;
1930}
1931
1932static int wl12xx_remove(struct platform_device *pdev)
1933{
1934 struct wl1271 *wl = platform_get_drvdata(pdev);
1935 struct wl12xx_priv *priv;
1936
1937 if (!wl)
1938 goto out;
1939 priv = wl->priv;
1940
1941 kfree(priv->rx_mem_addr);
1942
1943out:
1944 return wlcore_remove(pdev);
1945}
1946
1947static const struct platform_device_id wl12xx_id_table[] = {
1948 { "wl12xx", 0 },
1949 { }
1950};
1951MODULE_DEVICE_TABLE(platform, wl12xx_id_table);
1952
1953static struct platform_driver wl12xx_driver = {
1954 .probe = wl12xx_probe,
1955 .remove = wl12xx_remove,
1956 .id_table = wl12xx_id_table,
1957 .driver = {
1958 .name = "wl12xx_driver",
1959 }
1960};
1961
1962module_platform_driver(wl12xx_driver);
1963
1964module_param_named(fref, fref_param, charp, 0);
1965MODULE_PARM_DESC(fref, "FREF clock: 19.2, 26, 26x, 38.4, 38.4x, 52");
1966
1967module_param_named(tcxo, tcxo_param, charp, 0);
1968MODULE_PARM_DESC(tcxo,
1969 "TCXO clock: 19.2, 26, 38.4, 52, 16.368, 32.736, 16.8, 33.6");
1970
1971MODULE_LICENSE("GPL v2");
1972MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
1973MODULE_FIRMWARE(WL127X_FW_NAME_SINGLE);
1974MODULE_FIRMWARE(WL127X_FW_NAME_MULTI);
1975MODULE_FIRMWARE(WL127X_PLT_FW_NAME);
1976MODULE_FIRMWARE(WL128X_FW_NAME_SINGLE);
1977MODULE_FIRMWARE(WL128X_FW_NAME_MULTI);
1978MODULE_FIRMWARE(WL128X_PLT_FW_NAME);
1979