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 <linux/wl12xx.h>
28
29#include "../wlcore/wlcore.h"
30#include "../wlcore/debug.h"
31#include "../wlcore/io.h"
32#include "../wlcore/acx.h"
33#include "../wlcore/tx.h"
34#include "../wlcore/rx.h"
35#include "../wlcore/boot.h"
36
37#include "wl12xx.h"
38#include "reg.h"
39#include "cmd.h"
40#include "acx.h"
41#include "scan.h"
42#include "event.h"
43#include "debugfs.h"
44
45static char *fref_param;
46static char *tcxo_param;
47
48static struct wlcore_conf wl12xx_conf = {
49 .sg = {
50 .params = {
51 [CONF_SG_ACL_BT_MASTER_MIN_BR] = 10,
52 [CONF_SG_ACL_BT_MASTER_MAX_BR] = 180,
53 [CONF_SG_ACL_BT_SLAVE_MIN_BR] = 10,
54 [CONF_SG_ACL_BT_SLAVE_MAX_BR] = 180,
55 [CONF_SG_ACL_BT_MASTER_MIN_EDR] = 10,
56 [CONF_SG_ACL_BT_MASTER_MAX_EDR] = 80,
57 [CONF_SG_ACL_BT_SLAVE_MIN_EDR] = 10,
58 [CONF_SG_ACL_BT_SLAVE_MAX_EDR] = 80,
59 [CONF_SG_ACL_WLAN_PS_MASTER_BR] = 8,
60 [CONF_SG_ACL_WLAN_PS_SLAVE_BR] = 8,
61 [CONF_SG_ACL_WLAN_PS_MASTER_EDR] = 20,
62 [CONF_SG_ACL_WLAN_PS_SLAVE_EDR] = 20,
63 [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_BR] = 20,
64 [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_BR] = 35,
65 [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_BR] = 16,
66 [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_BR] = 35,
67 [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_EDR] = 32,
68 [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_EDR] = 50,
69 [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_EDR] = 28,
70 [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_EDR] = 50,
71 [CONF_SG_ACL_ACTIVE_SCAN_WLAN_BR] = 10,
72 [CONF_SG_ACL_ACTIVE_SCAN_WLAN_EDR] = 20,
73 [CONF_SG_ACL_PASSIVE_SCAN_BT_BR] = 75,
74 [CONF_SG_ACL_PASSIVE_SCAN_WLAN_BR] = 15,
75 [CONF_SG_ACL_PASSIVE_SCAN_BT_EDR] = 27,
76 [CONF_SG_ACL_PASSIVE_SCAN_WLAN_EDR] = 17,
77
78 [CONF_SG_AUTO_SCAN_PROBE_REQ] = 170,
79 [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3] = 50,
80 [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP] = 100,
81
82 [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP_BR] = 800,
83 [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP_EDR] = 200,
84 [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3] = 200,
85
86 [CONF_SG_CONSECUTIVE_HV3_IN_PASSIVE_SCAN] = 0,
87 [CONF_SG_BCN_HV3_COLLISION_THRESH_IN_PASSIVE_SCAN] = 0,
88 [CONF_SG_TX_RX_PROTECTION_BWIDTH_IN_PASSIVE_SCAN] = 0,
89
90 [CONF_SG_STA_FORCE_PS_IN_BT_SCO] = 1,
91 [CONF_SG_ANTENNA_CONFIGURATION] = 0,
92 [CONF_SG_BEACON_MISS_PERCENT] = 60,
93 [CONF_SG_DHCP_TIME] = 5000,
94 [CONF_SG_RXT] = 1200,
95 [CONF_SG_TXT] = 1000,
96 [CONF_SG_ADAPTIVE_RXT_TXT] = 1,
97 [CONF_SG_GENERAL_USAGE_BIT_MAP] = 3,
98 [CONF_SG_HV3_MAX_SERVED] = 6,
99 [CONF_SG_PS_POLL_TIMEOUT] = 10,
100 [CONF_SG_UPSD_TIMEOUT] = 10,
101 [CONF_SG_CONSECUTIVE_CTS_THRESHOLD] = 2,
102 [CONF_SG_STA_RX_WINDOW_AFTER_DTIM] = 5,
103 [CONF_SG_STA_CONNECTION_PROTECTION_TIME] = 30,
104
105 [CONF_AP_BEACON_MISS_TX] = 3,
106 [CONF_AP_RX_WINDOW_AFTER_BEACON] = 10,
107 [CONF_AP_BEACON_WINDOW_INTERVAL] = 2,
108 [CONF_AP_CONNECTION_PROTECTION_TIME] = 0,
109 [CONF_AP_BT_ACL_VAL_BT_SERVE_TIME] = 25,
110 [CONF_AP_BT_ACL_VAL_WL_SERVE_TIME] = 25,
111
112 [CONF_SG_CTS_DILUTED_BAD_RX_PACKETS_TH] = 0,
113 [CONF_SG_CTS_CHOP_IN_DUAL_ANT_SCO_MASTER] = 0,
114 },
115 .state = CONF_SG_PROTECTIVE,
116 },
117 .rx = {
118 .rx_msdu_life_time = 512000,
119 .packet_detection_threshold = 0,
120 .ps_poll_timeout = 15,
121 .upsd_timeout = 15,
122 .rts_threshold = IEEE80211_MAX_RTS_THRESHOLD,
123 .rx_cca_threshold = 0,
124 .irq_blk_threshold = 0xFFFF,
125 .irq_pkt_threshold = 0,
126 .irq_timeout = 600,
127 .queue_type = CONF_RX_QUEUE_TYPE_LOW_PRIORITY,
128 },
129 .tx = {
130 .tx_energy_detection = 0,
131 .sta_rc_conf = {
132 .enabled_rates = 0,
133 .short_retry_limit = 10,
134 .long_retry_limit = 10,
135 .aflags = 0,
136 },
137 .ac_conf_count = 4,
138 .ac_conf = {
139 [CONF_TX_AC_BE] = {
140 .ac = CONF_TX_AC_BE,
141 .cw_min = 15,
142 .cw_max = 63,
143 .aifsn = 3,
144 .tx_op_limit = 0,
145 },
146 [CONF_TX_AC_BK] = {
147 .ac = CONF_TX_AC_BK,
148 .cw_min = 15,
149 .cw_max = 63,
150 .aifsn = 7,
151 .tx_op_limit = 0,
152 },
153 [CONF_TX_AC_VI] = {
154 .ac = CONF_TX_AC_VI,
155 .cw_min = 15,
156 .cw_max = 63,
157 .aifsn = CONF_TX_AIFS_PIFS,
158 .tx_op_limit = 3008,
159 },
160 [CONF_TX_AC_VO] = {
161 .ac = CONF_TX_AC_VO,
162 .cw_min = 15,
163 .cw_max = 63,
164 .aifsn = CONF_TX_AIFS_PIFS,
165 .tx_op_limit = 1504,
166 },
167 },
168 .max_tx_retries = 100,
169 .ap_aging_period = 300,
170 .tid_conf_count = 4,
171 .tid_conf = {
172 [CONF_TX_AC_BE] = {
173 .queue_id = CONF_TX_AC_BE,
174 .channel_type = CONF_CHANNEL_TYPE_EDCF,
175 .tsid = CONF_TX_AC_BE,
176 .ps_scheme = CONF_PS_SCHEME_LEGACY,
177 .ack_policy = CONF_ACK_POLICY_LEGACY,
178 .apsd_conf = {0, 0},
179 },
180 [CONF_TX_AC_BK] = {
181 .queue_id = CONF_TX_AC_BK,
182 .channel_type = CONF_CHANNEL_TYPE_EDCF,
183 .tsid = CONF_TX_AC_BK,
184 .ps_scheme = CONF_PS_SCHEME_LEGACY,
185 .ack_policy = CONF_ACK_POLICY_LEGACY,
186 .apsd_conf = {0, 0},
187 },
188 [CONF_TX_AC_VI] = {
189 .queue_id = CONF_TX_AC_VI,
190 .channel_type = CONF_CHANNEL_TYPE_EDCF,
191 .tsid = CONF_TX_AC_VI,
192 .ps_scheme = CONF_PS_SCHEME_LEGACY,
193 .ack_policy = CONF_ACK_POLICY_LEGACY,
194 .apsd_conf = {0, 0},
195 },
196 [CONF_TX_AC_VO] = {
197 .queue_id = CONF_TX_AC_VO,
198 .channel_type = CONF_CHANNEL_TYPE_EDCF,
199 .tsid = CONF_TX_AC_VO,
200 .ps_scheme = CONF_PS_SCHEME_LEGACY,
201 .ack_policy = CONF_ACK_POLICY_LEGACY,
202 .apsd_conf = {0, 0},
203 },
204 },
205 .frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD,
206 .tx_compl_timeout = 700,
207 .tx_compl_threshold = 4,
208 .basic_rate = CONF_HW_BIT_RATE_1MBPS,
209 .basic_rate_5 = CONF_HW_BIT_RATE_6MBPS,
210 .tmpl_short_retry_limit = 10,
211 .tmpl_long_retry_limit = 10,
212 .tx_watchdog_timeout = 5000,
213 .slow_link_thold = 3,
214 .fast_link_thold = 10,
215 },
216 .conn = {
217 .wake_up_event = CONF_WAKE_UP_EVENT_DTIM,
218 .listen_interval = 1,
219 .suspend_wake_up_event = CONF_WAKE_UP_EVENT_N_DTIM,
220 .suspend_listen_interval = 3,
221 .bcn_filt_mode = CONF_BCN_FILT_MODE_ENABLED,
222 .bcn_filt_ie_count = 3,
223 .bcn_filt_ie = {
224 [0] = {
225 .ie = WLAN_EID_CHANNEL_SWITCH,
226 .rule = CONF_BCN_RULE_PASS_ON_APPEARANCE,
227 },
228 [1] = {
229 .ie = WLAN_EID_HT_OPERATION,
230 .rule = CONF_BCN_RULE_PASS_ON_CHANGE,
231 },
232 [2] = {
233 .ie = WLAN_EID_ERP_INFO,
234 .rule = CONF_BCN_RULE_PASS_ON_CHANGE,
235 },
236 },
237 .synch_fail_thold = 12,
238 .bss_lose_timeout = 400,
239 .beacon_rx_timeout = 10000,
240 .broadcast_timeout = 20000,
241 .rx_broadcast_in_ps = 1,
242 .ps_poll_threshold = 10,
243 .bet_enable = CONF_BET_MODE_ENABLE,
244 .bet_max_consecutive = 50,
245 .psm_entry_retries = 8,
246 .psm_exit_retries = 16,
247 .psm_entry_nullfunc_retries = 3,
248 .dynamic_ps_timeout = 1500,
249 .forced_ps = false,
250 .keep_alive_interval = 55000,
251 .max_listen_interval = 20,
252 .sta_sleep_auth = WL1271_PSM_ILLEGAL,
253 },
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_ON_DEMAND,
337 .mem_blocks = 2,
338 .severity = 0,
339 .timestamp = WL12XX_FWLOG_TIMESTAMP_DISABLED,
340 .output = WL12XX_FWLOG_OUTPUT_HOST,
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
721 wl->scan_templ_id_2_4 = CMD_TEMPL_APP_PROBE_REQ_2_4_LEGACY;
722 wl->scan_templ_id_5 = CMD_TEMPL_APP_PROBE_REQ_5_LEGACY;
723 wl->sched_scan_templ_id_2_4 = CMD_TEMPL_CFG_PROBE_REQ_2_4;
724 wl->sched_scan_templ_id_5 = CMD_TEMPL_CFG_PROBE_REQ_5;
725 wl->max_channels_5 = WL12XX_MAX_CHANNELS_5GHZ;
726out:
727 return ret;
728}
729
730static int __must_check wl12xx_top_reg_write(struct wl1271 *wl, int addr,
731 u16 val)
732{
733 int ret;
734
735
736 addr = (addr >> 1) + 0x30000;
737 ret = wlcore_write32(wl, WL12XX_OCP_POR_CTR, addr);
738 if (ret < 0)
739 goto out;
740
741
742 ret = wlcore_write32(wl, WL12XX_OCP_DATA_WRITE, val);
743 if (ret < 0)
744 goto out;
745
746
747 ret = wlcore_write32(wl, WL12XX_OCP_CMD, OCP_CMD_WRITE);
748 if (ret < 0)
749 goto out;
750
751out:
752 return ret;
753}
754
755static int __must_check wl12xx_top_reg_read(struct wl1271 *wl, int addr,
756 u16 *out)
757{
758 u32 val;
759 int timeout = OCP_CMD_LOOP;
760 int ret;
761
762
763 addr = (addr >> 1) + 0x30000;
764 ret = wlcore_write32(wl, WL12XX_OCP_POR_CTR, addr);
765 if (ret < 0)
766 return ret;
767
768
769 ret = wlcore_write32(wl, WL12XX_OCP_CMD, OCP_CMD_READ);
770 if (ret < 0)
771 return ret;
772
773
774 do {
775 ret = wlcore_read32(wl, WL12XX_OCP_DATA_READ, &val);
776 if (ret < 0)
777 return ret;
778 } while (!(val & OCP_READY_MASK) && --timeout);
779
780 if (!timeout) {
781 wl1271_warning("Top register access timed out.");
782 return -ETIMEDOUT;
783 }
784
785
786 if ((val & OCP_STATUS_MASK) != OCP_STATUS_OK) {
787 wl1271_warning("Top register access returned error.");
788 return -EIO;
789 }
790
791 if (out)
792 *out = val & 0xffff;
793
794 return 0;
795}
796
797static int wl128x_switch_tcxo_to_fref(struct wl1271 *wl)
798{
799 u16 spare_reg;
800 int ret;
801
802
803 ret = wl12xx_top_reg_read(wl, WL_SPARE_REG, &spare_reg);
804 if (ret < 0)
805 return ret;
806
807 if (spare_reg == 0xFFFF)
808 return -EFAULT;
809 spare_reg |= (BIT(3) | BIT(5) | BIT(6));
810 ret = wl12xx_top_reg_write(wl, WL_SPARE_REG, spare_reg);
811 if (ret < 0)
812 return ret;
813
814
815 ret = wl12xx_top_reg_write(wl, SYS_CLK_CFG_REG,
816 WL_CLK_REQ_TYPE_PG2 | MCS_PLL_CLK_SEL_FREF);
817 if (ret < 0)
818 return ret;
819
820
821 mdelay(15);
822
823 return 0;
824}
825
826static bool wl128x_is_tcxo_valid(struct wl1271 *wl)
827{
828 u16 tcxo_detection;
829 int ret;
830
831 ret = wl12xx_top_reg_read(wl, TCXO_CLK_DETECT_REG, &tcxo_detection);
832 if (ret < 0)
833 return false;
834
835 if (tcxo_detection & TCXO_DET_FAILED)
836 return false;
837
838 return true;
839}
840
841static bool wl128x_is_fref_valid(struct wl1271 *wl)
842{
843 u16 fref_detection;
844 int ret;
845
846 ret = wl12xx_top_reg_read(wl, FREF_CLK_DETECT_REG, &fref_detection);
847 if (ret < 0)
848 return false;
849
850 if (fref_detection & FREF_CLK_DETECT_FAIL)
851 return false;
852
853 return true;
854}
855
856static int wl128x_manually_configure_mcs_pll(struct wl1271 *wl)
857{
858 int ret;
859
860 ret = wl12xx_top_reg_write(wl, MCS_PLL_M_REG, MCS_PLL_M_REG_VAL);
861 if (ret < 0)
862 goto out;
863
864 ret = wl12xx_top_reg_write(wl, MCS_PLL_N_REG, MCS_PLL_N_REG_VAL);
865 if (ret < 0)
866 goto out;
867
868 ret = wl12xx_top_reg_write(wl, MCS_PLL_CONFIG_REG,
869 MCS_PLL_CONFIG_REG_VAL);
870
871out:
872 return ret;
873}
874
875static int wl128x_configure_mcs_pll(struct wl1271 *wl, int clk)
876{
877 u16 spare_reg;
878 u16 pll_config;
879 u8 input_freq;
880 struct wl12xx_priv *priv = wl->priv;
881 int ret;
882
883
884 ret = wl12xx_top_reg_read(wl, WL_SPARE_REG, &spare_reg);
885 if (ret < 0)
886 return ret;
887
888 if (spare_reg == 0xFFFF)
889 return -EFAULT;
890 spare_reg |= BIT(2);
891 ret = wl12xx_top_reg_write(wl, WL_SPARE_REG, spare_reg);
892 if (ret < 0)
893 return ret;
894
895
896 if (priv->tcxo_clock == WL12XX_TCXOCLOCK_16_8 ||
897 priv->tcxo_clock == WL12XX_TCXOCLOCK_33_6)
898 return wl128x_manually_configure_mcs_pll(wl);
899
900
901 input_freq = (clk & 1) + 1;
902
903 ret = wl12xx_top_reg_read(wl, MCS_PLL_CONFIG_REG, &pll_config);
904 if (ret < 0)
905 return ret;
906
907 if (pll_config == 0xFFFF)
908 return -EFAULT;
909 pll_config |= (input_freq << MCS_SEL_IN_FREQ_SHIFT);
910 pll_config |= MCS_PLL_ENABLE_HP;
911 ret = wl12xx_top_reg_write(wl, MCS_PLL_CONFIG_REG, pll_config);
912
913 return ret;
914}
915
916
917
918
919
920
921
922
923static int wl128x_boot_clk(struct wl1271 *wl, int *selected_clock)
924{
925 struct wl12xx_priv *priv = wl->priv;
926 u16 sys_clk_cfg;
927 int ret;
928
929
930 if (priv->ref_clock == WL12XX_REFCLOCK_26_XTAL ||
931 priv->ref_clock == WL12XX_REFCLOCK_38_XTAL) {
932 if (!wl128x_switch_tcxo_to_fref(wl))
933 return -EINVAL;
934 goto fref_clk;
935 }
936
937
938 ret = wl12xx_top_reg_read(wl, SYS_CLK_CFG_REG, &sys_clk_cfg);
939 if (ret < 0)
940 return ret;
941
942 if (sys_clk_cfg == 0xFFFF)
943 return -EINVAL;
944 if (sys_clk_cfg & PRCM_CM_EN_MUX_WLAN_FREF)
945 goto fref_clk;
946
947
948 if (priv->tcxo_clock == WL12XX_TCXOCLOCK_16_368 ||
949 priv->tcxo_clock == WL12XX_TCXOCLOCK_32_736) {
950 if (!wl128x_switch_tcxo_to_fref(wl))
951 return -EINVAL;
952 goto fref_clk;
953 }
954
955
956 if (!wl128x_is_tcxo_valid(wl))
957 return -EINVAL;
958 *selected_clock = priv->tcxo_clock;
959 goto config_mcs_pll;
960
961fref_clk:
962
963 if (!wl128x_is_fref_valid(wl))
964 return -EINVAL;
965 *selected_clock = priv->ref_clock;
966
967config_mcs_pll:
968 return wl128x_configure_mcs_pll(wl, *selected_clock);
969}
970
971static int wl127x_boot_clk(struct wl1271 *wl)
972{
973 struct wl12xx_priv *priv = wl->priv;
974 u32 pause;
975 u32 clk;
976 int ret;
977
978 if (WL127X_PG_GET_MAJOR(wl->hw_pg_ver) < 3)
979 wl->quirks |= WLCORE_QUIRK_END_OF_TRANSACTION;
980
981 if (priv->ref_clock == CONF_REF_CLK_19_2_E ||
982 priv->ref_clock == CONF_REF_CLK_38_4_E ||
983 priv->ref_clock == CONF_REF_CLK_38_4_M_XTAL)
984
985 clk = 0x3;
986 else if (priv->ref_clock == CONF_REF_CLK_26_E ||
987 priv->ref_clock == CONF_REF_CLK_26_M_XTAL ||
988 priv->ref_clock == CONF_REF_CLK_52_E)
989
990 clk = 0x5;
991 else
992 return -EINVAL;
993
994 if (priv->ref_clock != CONF_REF_CLK_19_2_E) {
995 u16 val;
996
997 ret = wl12xx_top_reg_read(wl, OCP_REG_CLK_TYPE, &val);
998 if (ret < 0)
999 goto out;
1000
1001 val &= FREF_CLK_TYPE_BITS;
1002 ret = wl12xx_top_reg_write(wl, OCP_REG_CLK_TYPE, val);
1003 if (ret < 0)
1004 goto out;
1005
1006
1007 ret = wl12xx_top_reg_read(wl, OCP_REG_CLK_PULL, &val);
1008 if (ret < 0)
1009 goto out;
1010
1011 val |= NO_PULL;
1012 ret = wl12xx_top_reg_write(wl, OCP_REG_CLK_PULL, val);
1013 if (ret < 0)
1014 goto out;
1015 } else {
1016 u16 val;
1017
1018 ret = wl12xx_top_reg_read(wl, OCP_REG_CLK_POLARITY, &val);
1019 if (ret < 0)
1020 goto out;
1021
1022 val &= FREF_CLK_POLARITY_BITS;
1023 val |= CLK_REQ_OUTN_SEL;
1024 ret = wl12xx_top_reg_write(wl, OCP_REG_CLK_POLARITY, val);
1025 if (ret < 0)
1026 goto out;
1027 }
1028
1029 ret = wlcore_write32(wl, WL12XX_PLL_PARAMETERS, clk);
1030 if (ret < 0)
1031 goto out;
1032
1033 ret = wlcore_read32(wl, WL12XX_PLL_PARAMETERS, &pause);
1034 if (ret < 0)
1035 goto out;
1036
1037 wl1271_debug(DEBUG_BOOT, "pause1 0x%x", pause);
1038
1039 pause &= ~(WU_COUNTER_PAUSE_VAL);
1040 pause |= WU_COUNTER_PAUSE_VAL;
1041 ret = wlcore_write32(wl, WL12XX_WU_COUNTER_PAUSE, pause);
1042
1043out:
1044 return ret;
1045}
1046
1047static int wl1271_boot_soft_reset(struct wl1271 *wl)
1048{
1049 unsigned long timeout;
1050 u32 boot_data;
1051 int ret = 0;
1052
1053
1054 ret = wlcore_write32(wl, WL12XX_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT);
1055 if (ret < 0)
1056 goto out;
1057
1058
1059 timeout = jiffies + usecs_to_jiffies(SOFT_RESET_MAX_TIME);
1060 while (1) {
1061 ret = wlcore_read32(wl, WL12XX_SLV_SOFT_RESET, &boot_data);
1062 if (ret < 0)
1063 goto out;
1064
1065 wl1271_debug(DEBUG_BOOT, "soft reset bootdata 0x%x", boot_data);
1066 if ((boot_data & ACX_SLV_SOFT_RESET_BIT) == 0)
1067 break;
1068
1069 if (time_after(jiffies, timeout)) {
1070
1071
1072 wl1271_error("soft reset timeout");
1073 return -1;
1074 }
1075
1076 udelay(SOFT_RESET_STALL_TIME);
1077 }
1078
1079
1080 ret = wlcore_write32(wl, WL12XX_ENABLE, 0x0);
1081 if (ret < 0)
1082 goto out;
1083
1084
1085 ret = wlcore_write32(wl, WL12XX_SPARE_A2, 0xffff);
1086
1087out:
1088 return ret;
1089}
1090
1091static int wl12xx_pre_boot(struct wl1271 *wl)
1092{
1093 struct wl12xx_priv *priv = wl->priv;
1094 int ret = 0;
1095 u32 clk;
1096 int selected_clock = -1;
1097
1098 if (wl->chip.id == CHIP_ID_128X_PG20) {
1099 ret = wl128x_boot_clk(wl, &selected_clock);
1100 if (ret < 0)
1101 goto out;
1102 } else {
1103 ret = wl127x_boot_clk(wl);
1104 if (ret < 0)
1105 goto out;
1106 }
1107
1108
1109 ret = wlcore_write32(wl, WL12XX_WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL);
1110 if (ret < 0)
1111 goto out;
1112
1113 udelay(500);
1114
1115 ret = wlcore_set_partition(wl, &wl->ptable[PART_DRPW]);
1116 if (ret < 0)
1117 goto out;
1118
1119
1120
1121
1122
1123 ret = wlcore_read32(wl, WL12XX_DRPW_SCRATCH_START, &clk);
1124 if (ret < 0)
1125 goto out;
1126
1127 wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk);
1128
1129 if (wl->chip.id == CHIP_ID_128X_PG20)
1130 clk |= ((selected_clock & 0x3) << 1) << 4;
1131 else
1132 clk |= (priv->ref_clock << 1) << 4;
1133
1134 ret = wlcore_write32(wl, WL12XX_DRPW_SCRATCH_START, clk);
1135 if (ret < 0)
1136 goto out;
1137
1138 ret = wlcore_set_partition(wl, &wl->ptable[PART_WORK]);
1139 if (ret < 0)
1140 goto out;
1141
1142
1143 ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
1144 if (ret < 0)
1145 goto out;
1146
1147 ret = wl1271_boot_soft_reset(wl);
1148 if (ret < 0)
1149 goto out;
1150
1151out:
1152 return ret;
1153}
1154
1155static int wl12xx_pre_upload(struct wl1271 *wl)
1156{
1157 u32 tmp;
1158 u16 polarity;
1159 int ret;
1160
1161
1162
1163 wl1271_debug(DEBUG_BOOT, "ACX_EEPROMLESS_IND_REG");
1164
1165 ret = wlcore_write32(wl, WL12XX_EEPROMLESS_IND, WL12XX_EEPROMLESS_IND);
1166 if (ret < 0)
1167 goto out;
1168
1169 ret = wlcore_read_reg(wl, REG_CHIP_ID_B, &tmp);
1170 if (ret < 0)
1171 goto out;
1172
1173 wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp);
1174
1175
1176 ret = wlcore_read32(wl, WL12XX_SCR_PAD2, &tmp);
1177 if (ret < 0)
1178 goto out;
1179
1180
1181
1182
1183 if (wl->chip.id == CHIP_ID_128X_PG20) {
1184 ret = wl12xx_top_reg_write(wl, SDIO_IO_DS, HCI_IO_DS_6MA);
1185 if (ret < 0)
1186 goto out;
1187 }
1188
1189
1190 ret = wl12xx_top_reg_read(wl, OCP_REG_POLARITY, &polarity);
1191 if (ret < 0)
1192 goto out;
1193
1194
1195 polarity &= ~POLARITY_LOW;
1196 ret = wl12xx_top_reg_write(wl, OCP_REG_POLARITY, polarity);
1197
1198out:
1199 return ret;
1200}
1201
1202static int wl12xx_enable_interrupts(struct wl1271 *wl)
1203{
1204 int ret;
1205
1206 ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK,
1207 WL12XX_ACX_ALL_EVENTS_VECTOR);
1208 if (ret < 0)
1209 goto out;
1210
1211 wlcore_enable_interrupts(wl);
1212 ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK,
1213 WL1271_ACX_INTR_ALL & ~(WL12XX_INTR_MASK));
1214 if (ret < 0)
1215 goto disable_interrupts;
1216
1217 ret = wlcore_write32(wl, WL12XX_HI_CFG, HI_CFG_DEF_VAL);
1218 if (ret < 0)
1219 goto disable_interrupts;
1220
1221 return ret;
1222
1223disable_interrupts:
1224 wlcore_disable_interrupts(wl);
1225
1226out:
1227 return ret;
1228}
1229
1230static int wl12xx_boot(struct wl1271 *wl)
1231{
1232 int ret;
1233
1234 ret = wl12xx_pre_boot(wl);
1235 if (ret < 0)
1236 goto out;
1237
1238 ret = wlcore_boot_upload_nvs(wl);
1239 if (ret < 0)
1240 goto out;
1241
1242 ret = wl12xx_pre_upload(wl);
1243 if (ret < 0)
1244 goto out;
1245
1246 ret = wlcore_boot_upload_firmware(wl);
1247 if (ret < 0)
1248 goto out;
1249
1250 wl->event_mask = BSS_LOSE_EVENT_ID |
1251 REGAINED_BSS_EVENT_ID |
1252 SCAN_COMPLETE_EVENT_ID |
1253 ROLE_STOP_COMPLETE_EVENT_ID |
1254 RSSI_SNR_TRIGGER_0_EVENT_ID |
1255 PSPOLL_DELIVERY_FAILURE_EVENT_ID |
1256 SOFT_GEMINI_SENSE_EVENT_ID |
1257 PERIODIC_SCAN_REPORT_EVENT_ID |
1258 PERIODIC_SCAN_COMPLETE_EVENT_ID |
1259 DUMMY_PACKET_EVENT_ID |
1260 PEER_REMOVE_COMPLETE_EVENT_ID |
1261 BA_SESSION_RX_CONSTRAINT_EVENT_ID |
1262 REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID |
1263 INACTIVE_STA_EVENT_ID |
1264 MAX_TX_RETRY_EVENT_ID |
1265 CHANNEL_SWITCH_COMPLETE_EVENT_ID;
1266
1267 ret = wlcore_boot_run_firmware(wl);
1268 if (ret < 0)
1269 goto out;
1270
1271 ret = wl12xx_enable_interrupts(wl);
1272
1273out:
1274 return ret;
1275}
1276
1277static int wl12xx_trigger_cmd(struct wl1271 *wl, int cmd_box_addr,
1278 void *buf, size_t len)
1279{
1280 int ret;
1281
1282 ret = wlcore_write(wl, cmd_box_addr, buf, len, false);
1283 if (ret < 0)
1284 return ret;
1285
1286 ret = wlcore_write_reg(wl, REG_INTERRUPT_TRIG, WL12XX_INTR_TRIG_CMD);
1287
1288 return ret;
1289}
1290
1291static int wl12xx_ack_event(struct wl1271 *wl)
1292{
1293 return wlcore_write_reg(wl, REG_INTERRUPT_TRIG,
1294 WL12XX_INTR_TRIG_EVENT_ACK);
1295}
1296
1297static u32 wl12xx_calc_tx_blocks(struct wl1271 *wl, u32 len, u32 spare_blks)
1298{
1299 u32 blk_size = WL12XX_TX_HW_BLOCK_SIZE;
1300 u32 align_len = wlcore_calc_packet_alignment(wl, len);
1301
1302 return (align_len + blk_size - 1) / blk_size + spare_blks;
1303}
1304
1305static void
1306wl12xx_set_tx_desc_blocks(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc,
1307 u32 blks, u32 spare_blks)
1308{
1309 if (wl->chip.id == CHIP_ID_128X_PG20) {
1310 desc->wl128x_mem.total_mem_blocks = blks;
1311 } else {
1312 desc->wl127x_mem.extra_blocks = spare_blks;
1313 desc->wl127x_mem.total_mem_blocks = blks;
1314 }
1315}
1316
1317static void
1318wl12xx_set_tx_desc_data_len(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc,
1319 struct sk_buff *skb)
1320{
1321 u32 aligned_len = wlcore_calc_packet_alignment(wl, skb->len);
1322
1323 if (wl->chip.id == CHIP_ID_128X_PG20) {
1324 desc->wl128x_mem.extra_bytes = aligned_len - skb->len;
1325 desc->length = cpu_to_le16(aligned_len >> 2);
1326
1327 wl1271_debug(DEBUG_TX,
1328 "tx_fill_hdr: hlid: %d len: %d life: %d mem: %d extra: %d",
1329 desc->hlid,
1330 le16_to_cpu(desc->length),
1331 le16_to_cpu(desc->life_time),
1332 desc->wl128x_mem.total_mem_blocks,
1333 desc->wl128x_mem.extra_bytes);
1334 } else {
1335
1336 int pad = aligned_len - skb->len;
1337 desc->tx_attr |=
1338 cpu_to_le16(pad << TX_HW_ATTR_OFST_LAST_WORD_PAD);
1339
1340
1341 desc->length = cpu_to_le16(aligned_len >> 2);
1342
1343 wl1271_debug(DEBUG_TX,
1344 "tx_fill_hdr: pad: %d hlid: %d len: %d life: %d mem: %d",
1345 pad, desc->hlid,
1346 le16_to_cpu(desc->length),
1347 le16_to_cpu(desc->life_time),
1348 desc->wl127x_mem.total_mem_blocks);
1349 }
1350}
1351
1352static enum wl_rx_buf_align
1353wl12xx_get_rx_buf_align(struct wl1271 *wl, u32 rx_desc)
1354{
1355 if (rx_desc & RX_BUF_UNALIGNED_PAYLOAD)
1356 return WLCORE_RX_BUF_UNALIGNED;
1357
1358 return WLCORE_RX_BUF_ALIGNED;
1359}
1360
1361static u32 wl12xx_get_rx_packet_len(struct wl1271 *wl, void *rx_data,
1362 u32 data_len)
1363{
1364 struct wl1271_rx_descriptor *desc = rx_data;
1365
1366
1367 if (data_len < sizeof(*desc) ||
1368 data_len < sizeof(*desc) + desc->pad_len)
1369 return 0;
1370
1371 return data_len - sizeof(*desc) - desc->pad_len;
1372}
1373
1374static int wl12xx_tx_delayed_compl(struct wl1271 *wl)
1375{
1376 if (wl->fw_status_1->tx_results_counter ==
1377 (wl->tx_results_count & 0xff))
1378 return 0;
1379
1380 return wlcore_tx_complete(wl);
1381}
1382
1383static int wl12xx_hw_init(struct wl1271 *wl)
1384{
1385 int ret;
1386
1387 if (wl->chip.id == CHIP_ID_128X_PG20) {
1388 u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE;
1389
1390 ret = wl128x_cmd_general_parms(wl);
1391 if (ret < 0)
1392 goto out;
1393
1394
1395
1396
1397
1398 if (wl->plt_mode == PLT_FEM_DETECT)
1399 goto out;
1400
1401 ret = wl128x_cmd_radio_parms(wl);
1402 if (ret < 0)
1403 goto out;
1404
1405 if (wl->quirks & WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN)
1406
1407 host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK;
1408
1409
1410 ret = wl1271_acx_host_if_cfg_bitmap(wl, host_cfg_bitmap);
1411 if (ret < 0)
1412 goto out;
1413 } else {
1414 ret = wl1271_cmd_general_parms(wl);
1415 if (ret < 0)
1416 goto out;
1417
1418
1419
1420
1421
1422 if (wl->plt_mode == PLT_FEM_DETECT)
1423 goto out;
1424
1425 ret = wl1271_cmd_radio_parms(wl);
1426 if (ret < 0)
1427 goto out;
1428 ret = wl1271_cmd_ext_radio_parms(wl);
1429 if (ret < 0)
1430 goto out;
1431 }
1432out:
1433 return ret;
1434}
1435
1436static u32 wl12xx_sta_get_ap_rate_mask(struct wl1271 *wl,
1437 struct wl12xx_vif *wlvif)
1438{
1439 return wlvif->rate_set;
1440}
1441
1442static void wl12xx_conf_init(struct wl1271 *wl)
1443{
1444 struct wl12xx_priv *priv = wl->priv;
1445
1446
1447 memcpy(&wl->conf, &wl12xx_conf, sizeof(wl12xx_conf));
1448
1449
1450 memcpy(&priv->conf, &wl12xx_default_priv_conf, sizeof(priv->conf));
1451}
1452
1453static bool wl12xx_mac_in_fuse(struct wl1271 *wl)
1454{
1455 bool supported = false;
1456 u8 major, minor;
1457
1458 if (wl->chip.id == CHIP_ID_128X_PG20) {
1459 major = WL128X_PG_GET_MAJOR(wl->hw_pg_ver);
1460 minor = WL128X_PG_GET_MINOR(wl->hw_pg_ver);
1461
1462
1463 if (major > 2 || (major == 2 && minor >= 1))
1464 supported = true;
1465 } else {
1466 major = WL127X_PG_GET_MAJOR(wl->hw_pg_ver);
1467 minor = WL127X_PG_GET_MINOR(wl->hw_pg_ver);
1468
1469
1470 if (major == 3 && minor >= 1)
1471 supported = true;
1472 }
1473
1474 wl1271_debug(DEBUG_PROBE,
1475 "PG Ver major = %d minor = %d, MAC %s present",
1476 major, minor, supported ? "is" : "is not");
1477
1478 return supported;
1479}
1480
1481static int wl12xx_get_fuse_mac(struct wl1271 *wl)
1482{
1483 u32 mac1, mac2;
1484 int ret;
1485
1486 ret = wlcore_set_partition(wl, &wl->ptable[PART_DRPW]);
1487 if (ret < 0)
1488 goto out;
1489
1490 ret = wlcore_read32(wl, WL12XX_REG_FUSE_BD_ADDR_1, &mac1);
1491 if (ret < 0)
1492 goto out;
1493
1494 ret = wlcore_read32(wl, WL12XX_REG_FUSE_BD_ADDR_2, &mac2);
1495 if (ret < 0)
1496 goto out;
1497
1498
1499 wl->fuse_oui_addr = ((mac2 & 0xffff) << 8) +
1500 ((mac1 & 0xff000000) >> 24);
1501 wl->fuse_nic_addr = mac1 & 0xffffff;
1502
1503 ret = wlcore_set_partition(wl, &wl->ptable[PART_DOWN]);
1504
1505out:
1506 return ret;
1507}
1508
1509static int wl12xx_get_pg_ver(struct wl1271 *wl, s8 *ver)
1510{
1511 u16 die_info;
1512 int ret;
1513
1514 if (wl->chip.id == CHIP_ID_128X_PG20)
1515 ret = wl12xx_top_reg_read(wl, WL128X_REG_FUSE_DATA_2_1,
1516 &die_info);
1517 else
1518 ret = wl12xx_top_reg_read(wl, WL127X_REG_FUSE_DATA_2_1,
1519 &die_info);
1520
1521 if (ret >= 0 && ver)
1522 *ver = (s8)((die_info & PG_VER_MASK) >> PG_VER_OFFSET);
1523
1524 return ret;
1525}
1526
1527static int wl12xx_get_mac(struct wl1271 *wl)
1528{
1529 if (wl12xx_mac_in_fuse(wl))
1530 return wl12xx_get_fuse_mac(wl);
1531
1532 return 0;
1533}
1534
1535static void wl12xx_set_tx_desc_csum(struct wl1271 *wl,
1536 struct wl1271_tx_hw_descr *desc,
1537 struct sk_buff *skb)
1538{
1539 desc->wl12xx_reserved = 0;
1540}
1541
1542static int wl12xx_plt_init(struct wl1271 *wl)
1543{
1544 int ret;
1545
1546 ret = wl->ops->boot(wl);
1547 if (ret < 0)
1548 goto out;
1549
1550 ret = wl->ops->hw_init(wl);
1551 if (ret < 0)
1552 goto out_irq_disable;
1553
1554
1555
1556
1557
1558 if (wl->plt_mode == PLT_FEM_DETECT)
1559 goto out;
1560
1561 ret = wl1271_acx_init_mem_config(wl);
1562 if (ret < 0)
1563 goto out_irq_disable;
1564
1565 ret = wl12xx_acx_mem_cfg(wl);
1566 if (ret < 0)
1567 goto out_free_memmap;
1568
1569
1570 ret = wl1271_cmd_data_path(wl, 1);
1571 if (ret < 0)
1572 goto out_free_memmap;
1573
1574
1575 ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM);
1576 if (ret < 0)
1577 goto out_free_memmap;
1578
1579
1580 ret = wl1271_acx_pm_config(wl);
1581 if (ret < 0)
1582 goto out_free_memmap;
1583
1584 goto out;
1585
1586out_free_memmap:
1587 kfree(wl->target_mem_map);
1588 wl->target_mem_map = NULL;
1589
1590out_irq_disable:
1591 mutex_unlock(&wl->mutex);
1592
1593
1594
1595
1596
1597
1598
1599 wlcore_disable_interrupts(wl);
1600 mutex_lock(&wl->mutex);
1601out:
1602 return ret;
1603}
1604
1605static int wl12xx_get_spare_blocks(struct wl1271 *wl, bool is_gem)
1606{
1607 if (is_gem)
1608 return WL12XX_TX_HW_BLOCK_GEM_SPARE;
1609
1610 return WL12XX_TX_HW_BLOCK_SPARE_DEFAULT;
1611}
1612
1613static int wl12xx_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
1614 struct ieee80211_vif *vif,
1615 struct ieee80211_sta *sta,
1616 struct ieee80211_key_conf *key_conf)
1617{
1618 return wlcore_set_key(wl, cmd, vif, sta, key_conf);
1619}
1620
1621static int wl12xx_set_peer_cap(struct wl1271 *wl,
1622 struct ieee80211_sta_ht_cap *ht_cap,
1623 bool allow_ht_operation,
1624 u32 rate_set, u8 hlid)
1625{
1626 return wl1271_acx_set_ht_capabilities(wl, ht_cap, allow_ht_operation,
1627 hlid);
1628}
1629
1630static bool wl12xx_lnk_high_prio(struct wl1271 *wl, u8 hlid,
1631 struct wl1271_link *lnk)
1632{
1633 u8 thold;
1634
1635 if (test_bit(hlid, (unsigned long *)&wl->fw_fast_lnk_map))
1636 thold = wl->conf.tx.fast_link_thold;
1637 else
1638 thold = wl->conf.tx.slow_link_thold;
1639
1640 return lnk->allocated_pkts < thold;
1641}
1642
1643static bool wl12xx_lnk_low_prio(struct wl1271 *wl, u8 hlid,
1644 struct wl1271_link *lnk)
1645{
1646
1647 return true;
1648}
1649
1650static int wl12xx_setup(struct wl1271 *wl);
1651
1652static struct wlcore_ops wl12xx_ops = {
1653 .setup = wl12xx_setup,
1654 .identify_chip = wl12xx_identify_chip,
1655 .boot = wl12xx_boot,
1656 .plt_init = wl12xx_plt_init,
1657 .trigger_cmd = wl12xx_trigger_cmd,
1658 .ack_event = wl12xx_ack_event,
1659 .wait_for_event = wl12xx_wait_for_event,
1660 .process_mailbox_events = wl12xx_process_mailbox_events,
1661 .calc_tx_blocks = wl12xx_calc_tx_blocks,
1662 .set_tx_desc_blocks = wl12xx_set_tx_desc_blocks,
1663 .set_tx_desc_data_len = wl12xx_set_tx_desc_data_len,
1664 .get_rx_buf_align = wl12xx_get_rx_buf_align,
1665 .get_rx_packet_len = wl12xx_get_rx_packet_len,
1666 .tx_immediate_compl = NULL,
1667 .tx_delayed_compl = wl12xx_tx_delayed_compl,
1668 .hw_init = wl12xx_hw_init,
1669 .init_vif = NULL,
1670 .sta_get_ap_rate_mask = wl12xx_sta_get_ap_rate_mask,
1671 .get_pg_ver = wl12xx_get_pg_ver,
1672 .get_mac = wl12xx_get_mac,
1673 .set_tx_desc_csum = wl12xx_set_tx_desc_csum,
1674 .set_rx_csum = NULL,
1675 .ap_get_mimo_wide_rate_mask = NULL,
1676 .debugfs_init = wl12xx_debugfs_add_files,
1677 .scan_start = wl12xx_scan_start,
1678 .scan_stop = wl12xx_scan_stop,
1679 .sched_scan_start = wl12xx_sched_scan_start,
1680 .sched_scan_stop = wl12xx_scan_sched_scan_stop,
1681 .get_spare_blocks = wl12xx_get_spare_blocks,
1682 .set_key = wl12xx_set_key,
1683 .channel_switch = wl12xx_cmd_channel_switch,
1684 .pre_pkt_send = NULL,
1685 .set_peer_cap = wl12xx_set_peer_cap,
1686 .lnk_high_prio = wl12xx_lnk_high_prio,
1687 .lnk_low_prio = wl12xx_lnk_low_prio,
1688};
1689
1690static struct ieee80211_sta_ht_cap wl12xx_ht_cap = {
1691 .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 |
1692 (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT),
1693 .ht_supported = true,
1694 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K,
1695 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_8,
1696 .mcs = {
1697 .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
1698 .rx_highest = cpu_to_le16(72),
1699 .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
1700 },
1701};
1702
1703static int wl12xx_setup(struct wl1271 *wl)
1704{
1705 struct wl12xx_priv *priv = wl->priv;
1706 struct wlcore_platdev_data *pdev_data = wl->pdev->dev.platform_data;
1707 struct wl12xx_platform_data *pdata = pdev_data->pdata;
1708
1709 wl->rtable = wl12xx_rtable;
1710 wl->num_tx_desc = WL12XX_NUM_TX_DESCRIPTORS;
1711 wl->num_rx_desc = WL12XX_NUM_RX_DESCRIPTORS;
1712 wl->num_channels = 1;
1713 wl->num_mac_addr = WL12XX_NUM_MAC_ADDRESSES;
1714 wl->band_rate_to_idx = wl12xx_band_rate_to_idx;
1715 wl->hw_tx_rate_tbl_size = WL12XX_CONF_HW_RXTX_RATE_MAX;
1716 wl->hw_min_ht_rate = WL12XX_CONF_HW_RXTX_RATE_MCS0;
1717 wl->fw_status_priv_len = 0;
1718 wl->stats.fw_stats_len = sizeof(struct wl12xx_acx_statistics);
1719 wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ, &wl12xx_ht_cap);
1720 wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ, &wl12xx_ht_cap);
1721 wl12xx_conf_init(wl);
1722
1723 if (!fref_param) {
1724 priv->ref_clock = pdata->board_ref_clock;
1725 } else {
1726 if (!strcmp(fref_param, "19.2"))
1727 priv->ref_clock = WL12XX_REFCLOCK_19;
1728 else if (!strcmp(fref_param, "26"))
1729 priv->ref_clock = WL12XX_REFCLOCK_26;
1730 else if (!strcmp(fref_param, "26x"))
1731 priv->ref_clock = WL12XX_REFCLOCK_26_XTAL;
1732 else if (!strcmp(fref_param, "38.4"))
1733 priv->ref_clock = WL12XX_REFCLOCK_38;
1734 else if (!strcmp(fref_param, "38.4x"))
1735 priv->ref_clock = WL12XX_REFCLOCK_38_XTAL;
1736 else if (!strcmp(fref_param, "52"))
1737 priv->ref_clock = WL12XX_REFCLOCK_52;
1738 else
1739 wl1271_error("Invalid fref parameter %s", fref_param);
1740 }
1741
1742 if (!tcxo_param) {
1743 priv->tcxo_clock = pdata->board_tcxo_clock;
1744 } else {
1745 if (!strcmp(tcxo_param, "19.2"))
1746 priv->tcxo_clock = WL12XX_TCXOCLOCK_19_2;
1747 else if (!strcmp(tcxo_param, "26"))
1748 priv->tcxo_clock = WL12XX_TCXOCLOCK_26;
1749 else if (!strcmp(tcxo_param, "38.4"))
1750 priv->tcxo_clock = WL12XX_TCXOCLOCK_38_4;
1751 else if (!strcmp(tcxo_param, "52"))
1752 priv->tcxo_clock = WL12XX_TCXOCLOCK_52;
1753 else if (!strcmp(tcxo_param, "16.368"))
1754 priv->tcxo_clock = WL12XX_TCXOCLOCK_16_368;
1755 else if (!strcmp(tcxo_param, "32.736"))
1756 priv->tcxo_clock = WL12XX_TCXOCLOCK_32_736;
1757 else if (!strcmp(tcxo_param, "16.8"))
1758 priv->tcxo_clock = WL12XX_TCXOCLOCK_16_8;
1759 else if (!strcmp(tcxo_param, "33.6"))
1760 priv->tcxo_clock = WL12XX_TCXOCLOCK_33_6;
1761 else
1762 wl1271_error("Invalid tcxo parameter %s", tcxo_param);
1763 }
1764
1765 priv->rx_mem_addr = kmalloc(sizeof(*priv->rx_mem_addr), GFP_KERNEL);
1766 if (!priv->rx_mem_addr)
1767 return -ENOMEM;
1768
1769 return 0;
1770}
1771
1772static int wl12xx_probe(struct platform_device *pdev)
1773{
1774 struct wl1271 *wl;
1775 struct ieee80211_hw *hw;
1776 int ret;
1777
1778 hw = wlcore_alloc_hw(sizeof(struct wl12xx_priv),
1779 WL12XX_AGGR_BUFFER_SIZE,
1780 sizeof(struct wl12xx_event_mailbox));
1781 if (IS_ERR(hw)) {
1782 wl1271_error("can't allocate hw");
1783 ret = PTR_ERR(hw);
1784 goto out;
1785 }
1786
1787 wl = hw->priv;
1788 wl->ops = &wl12xx_ops;
1789 wl->ptable = wl12xx_ptable;
1790 ret = wlcore_probe(wl, pdev);
1791 if (ret)
1792 goto out_free;
1793
1794 return ret;
1795
1796out_free:
1797 wlcore_free_hw(wl);
1798out:
1799 return ret;
1800}
1801
1802static int wl12xx_remove(struct platform_device *pdev)
1803{
1804 struct wl1271 *wl = platform_get_drvdata(pdev);
1805 struct wl12xx_priv *priv;
1806
1807 if (!wl)
1808 goto out;
1809 priv = wl->priv;
1810
1811 kfree(priv->rx_mem_addr);
1812
1813out:
1814 return wlcore_remove(pdev);
1815}
1816
1817static const struct platform_device_id wl12xx_id_table[] = {
1818 { "wl12xx", 0 },
1819 { }
1820};
1821MODULE_DEVICE_TABLE(platform, wl12xx_id_table);
1822
1823static struct platform_driver wl12xx_driver = {
1824 .probe = wl12xx_probe,
1825 .remove = wl12xx_remove,
1826 .id_table = wl12xx_id_table,
1827 .driver = {
1828 .name = "wl12xx_driver",
1829 .owner = THIS_MODULE,
1830 }
1831};
1832
1833module_platform_driver(wl12xx_driver);
1834
1835module_param_named(fref, fref_param, charp, 0);
1836MODULE_PARM_DESC(fref, "FREF clock: 19.2, 26, 26x, 38.4, 38.4x, 52");
1837
1838module_param_named(tcxo, tcxo_param, charp, 0);
1839MODULE_PARM_DESC(tcxo,
1840 "TCXO clock: 19.2, 26, 38.4, 52, 16.368, 32.736, 16.8, 33.6");
1841
1842MODULE_LICENSE("GPL v2");
1843MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
1844MODULE_FIRMWARE(WL127X_FW_NAME_SINGLE);
1845MODULE_FIRMWARE(WL127X_FW_NAME_MULTI);
1846MODULE_FIRMWARE(WL127X_PLT_FW_NAME);
1847MODULE_FIRMWARE(WL128X_FW_NAME_SINGLE);
1848MODULE_FIRMWARE(WL128X_FW_NAME_MULTI);
1849MODULE_FIRMWARE(WL128X_PLT_FW_NAME);
1850