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