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