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;
726 wl->ba_rx_session_count_max = WL12XX_RX_BA_MAX_SESSIONS;
727out:
728 return ret;
729}
730
731static int __must_check wl12xx_top_reg_write(struct wl1271 *wl, int addr,
732 u16 val)
733{
734 int ret;
735
736
737 addr = (addr >> 1) + 0x30000;
738 ret = wlcore_write32(wl, WL12XX_OCP_POR_CTR, addr);
739 if (ret < 0)
740 goto out;
741
742
743 ret = wlcore_write32(wl, WL12XX_OCP_DATA_WRITE, val);
744 if (ret < 0)
745 goto out;
746
747
748 ret = wlcore_write32(wl, WL12XX_OCP_CMD, OCP_CMD_WRITE);
749 if (ret < 0)
750 goto out;
751
752out:
753 return ret;
754}
755
756static int __must_check wl12xx_top_reg_read(struct wl1271 *wl, int addr,
757 u16 *out)
758{
759 u32 val;
760 int timeout = OCP_CMD_LOOP;
761 int ret;
762
763
764 addr = (addr >> 1) + 0x30000;
765 ret = wlcore_write32(wl, WL12XX_OCP_POR_CTR, addr);
766 if (ret < 0)
767 return ret;
768
769
770 ret = wlcore_write32(wl, WL12XX_OCP_CMD, OCP_CMD_READ);
771 if (ret < 0)
772 return ret;
773
774
775 do {
776 ret = wlcore_read32(wl, WL12XX_OCP_DATA_READ, &val);
777 if (ret < 0)
778 return ret;
779 } while (!(val & OCP_READY_MASK) && --timeout);
780
781 if (!timeout) {
782 wl1271_warning("Top register access timed out.");
783 return -ETIMEDOUT;
784 }
785
786
787 if ((val & OCP_STATUS_MASK) != OCP_STATUS_OK) {
788 wl1271_warning("Top register access returned error.");
789 return -EIO;
790 }
791
792 if (out)
793 *out = val & 0xffff;
794
795 return 0;
796}
797
798static int wl128x_switch_tcxo_to_fref(struct wl1271 *wl)
799{
800 u16 spare_reg;
801 int ret;
802
803
804 ret = wl12xx_top_reg_read(wl, WL_SPARE_REG, &spare_reg);
805 if (ret < 0)
806 return ret;
807
808 if (spare_reg == 0xFFFF)
809 return -EFAULT;
810 spare_reg |= (BIT(3) | BIT(5) | BIT(6));
811 ret = wl12xx_top_reg_write(wl, WL_SPARE_REG, spare_reg);
812 if (ret < 0)
813 return ret;
814
815
816 ret = wl12xx_top_reg_write(wl, SYS_CLK_CFG_REG,
817 WL_CLK_REQ_TYPE_PG2 | MCS_PLL_CLK_SEL_FREF);
818 if (ret < 0)
819 return ret;
820
821
822 mdelay(15);
823
824 return 0;
825}
826
827static bool wl128x_is_tcxo_valid(struct wl1271 *wl)
828{
829 u16 tcxo_detection;
830 int ret;
831
832 ret = wl12xx_top_reg_read(wl, TCXO_CLK_DETECT_REG, &tcxo_detection);
833 if (ret < 0)
834 return false;
835
836 if (tcxo_detection & TCXO_DET_FAILED)
837 return false;
838
839 return true;
840}
841
842static bool wl128x_is_fref_valid(struct wl1271 *wl)
843{
844 u16 fref_detection;
845 int ret;
846
847 ret = wl12xx_top_reg_read(wl, FREF_CLK_DETECT_REG, &fref_detection);
848 if (ret < 0)
849 return false;
850
851 if (fref_detection & FREF_CLK_DETECT_FAIL)
852 return false;
853
854 return true;
855}
856
857static int wl128x_manually_configure_mcs_pll(struct wl1271 *wl)
858{
859 int ret;
860
861 ret = wl12xx_top_reg_write(wl, MCS_PLL_M_REG, MCS_PLL_M_REG_VAL);
862 if (ret < 0)
863 goto out;
864
865 ret = wl12xx_top_reg_write(wl, MCS_PLL_N_REG, MCS_PLL_N_REG_VAL);
866 if (ret < 0)
867 goto out;
868
869 ret = wl12xx_top_reg_write(wl, MCS_PLL_CONFIG_REG,
870 MCS_PLL_CONFIG_REG_VAL);
871
872out:
873 return ret;
874}
875
876static int wl128x_configure_mcs_pll(struct wl1271 *wl, int clk)
877{
878 u16 spare_reg;
879 u16 pll_config;
880 u8 input_freq;
881 struct wl12xx_priv *priv = wl->priv;
882 int ret;
883
884
885 ret = wl12xx_top_reg_read(wl, WL_SPARE_REG, &spare_reg);
886 if (ret < 0)
887 return ret;
888
889 if (spare_reg == 0xFFFF)
890 return -EFAULT;
891 spare_reg |= BIT(2);
892 ret = wl12xx_top_reg_write(wl, WL_SPARE_REG, spare_reg);
893 if (ret < 0)
894 return ret;
895
896
897 if (priv->tcxo_clock == WL12XX_TCXOCLOCK_16_8 ||
898 priv->tcxo_clock == WL12XX_TCXOCLOCK_33_6)
899 return wl128x_manually_configure_mcs_pll(wl);
900
901
902 input_freq = (clk & 1) + 1;
903
904 ret = wl12xx_top_reg_read(wl, MCS_PLL_CONFIG_REG, &pll_config);
905 if (ret < 0)
906 return ret;
907
908 if (pll_config == 0xFFFF)
909 return -EFAULT;
910 pll_config |= (input_freq << MCS_SEL_IN_FREQ_SHIFT);
911 pll_config |= MCS_PLL_ENABLE_HP;
912 ret = wl12xx_top_reg_write(wl, MCS_PLL_CONFIG_REG, pll_config);
913
914 return ret;
915}
916
917
918
919
920
921
922
923
924static int wl128x_boot_clk(struct wl1271 *wl, int *selected_clock)
925{
926 struct wl12xx_priv *priv = wl->priv;
927 u16 sys_clk_cfg;
928 int ret;
929
930
931 if (priv->ref_clock == WL12XX_REFCLOCK_26_XTAL ||
932 priv->ref_clock == WL12XX_REFCLOCK_38_XTAL) {
933 if (!wl128x_switch_tcxo_to_fref(wl))
934 return -EINVAL;
935 goto fref_clk;
936 }
937
938
939 ret = wl12xx_top_reg_read(wl, SYS_CLK_CFG_REG, &sys_clk_cfg);
940 if (ret < 0)
941 return ret;
942
943 if (sys_clk_cfg == 0xFFFF)
944 return -EINVAL;
945 if (sys_clk_cfg & PRCM_CM_EN_MUX_WLAN_FREF)
946 goto fref_clk;
947
948
949 if (priv->tcxo_clock == WL12XX_TCXOCLOCK_16_368 ||
950 priv->tcxo_clock == WL12XX_TCXOCLOCK_32_736) {
951 if (!wl128x_switch_tcxo_to_fref(wl))
952 return -EINVAL;
953 goto fref_clk;
954 }
955
956
957 if (!wl128x_is_tcxo_valid(wl))
958 return -EINVAL;
959 *selected_clock = priv->tcxo_clock;
960 goto config_mcs_pll;
961
962fref_clk:
963
964 if (!wl128x_is_fref_valid(wl))
965 return -EINVAL;
966 *selected_clock = priv->ref_clock;
967
968config_mcs_pll:
969 return wl128x_configure_mcs_pll(wl, *selected_clock);
970}
971
972static int wl127x_boot_clk(struct wl1271 *wl)
973{
974 struct wl12xx_priv *priv = wl->priv;
975 u32 pause;
976 u32 clk;
977 int ret;
978
979 if (WL127X_PG_GET_MAJOR(wl->hw_pg_ver) < 3)
980 wl->quirks |= WLCORE_QUIRK_END_OF_TRANSACTION;
981
982 if (priv->ref_clock == CONF_REF_CLK_19_2_E ||
983 priv->ref_clock == CONF_REF_CLK_38_4_E ||
984 priv->ref_clock == CONF_REF_CLK_38_4_M_XTAL)
985
986 clk = 0x3;
987 else if (priv->ref_clock == CONF_REF_CLK_26_E ||
988 priv->ref_clock == CONF_REF_CLK_26_M_XTAL ||
989 priv->ref_clock == CONF_REF_CLK_52_E)
990
991 clk = 0x5;
992 else
993 return -EINVAL;
994
995 if (priv->ref_clock != CONF_REF_CLK_19_2_E) {
996 u16 val;
997
998 ret = wl12xx_top_reg_read(wl, OCP_REG_CLK_TYPE, &val);
999 if (ret < 0)
1000 goto out;
1001
1002 val &= FREF_CLK_TYPE_BITS;
1003 ret = wl12xx_top_reg_write(wl, OCP_REG_CLK_TYPE, val);
1004 if (ret < 0)
1005 goto out;
1006
1007
1008 ret = wl12xx_top_reg_read(wl, OCP_REG_CLK_PULL, &val);
1009 if (ret < 0)
1010 goto out;
1011
1012 val |= NO_PULL;
1013 ret = wl12xx_top_reg_write(wl, OCP_REG_CLK_PULL, val);
1014 if (ret < 0)
1015 goto out;
1016 } else {
1017 u16 val;
1018
1019 ret = wl12xx_top_reg_read(wl, OCP_REG_CLK_POLARITY, &val);
1020 if (ret < 0)
1021 goto out;
1022
1023 val &= FREF_CLK_POLARITY_BITS;
1024 val |= CLK_REQ_OUTN_SEL;
1025 ret = wl12xx_top_reg_write(wl, OCP_REG_CLK_POLARITY, val);
1026 if (ret < 0)
1027 goto out;
1028 }
1029
1030 ret = wlcore_write32(wl, WL12XX_PLL_PARAMETERS, clk);
1031 if (ret < 0)
1032 goto out;
1033
1034 ret = wlcore_read32(wl, WL12XX_PLL_PARAMETERS, &pause);
1035 if (ret < 0)
1036 goto out;
1037
1038 wl1271_debug(DEBUG_BOOT, "pause1 0x%x", pause);
1039
1040 pause &= ~(WU_COUNTER_PAUSE_VAL);
1041 pause |= WU_COUNTER_PAUSE_VAL;
1042 ret = wlcore_write32(wl, WL12XX_WU_COUNTER_PAUSE, pause);
1043
1044out:
1045 return ret;
1046}
1047
1048static int wl1271_boot_soft_reset(struct wl1271 *wl)
1049{
1050 unsigned long timeout;
1051 u32 boot_data;
1052 int ret = 0;
1053
1054
1055 ret = wlcore_write32(wl, WL12XX_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT);
1056 if (ret < 0)
1057 goto out;
1058
1059
1060 timeout = jiffies + usecs_to_jiffies(SOFT_RESET_MAX_TIME);
1061 while (1) {
1062 ret = wlcore_read32(wl, WL12XX_SLV_SOFT_RESET, &boot_data);
1063 if (ret < 0)
1064 goto out;
1065
1066 wl1271_debug(DEBUG_BOOT, "soft reset bootdata 0x%x", boot_data);
1067 if ((boot_data & ACX_SLV_SOFT_RESET_BIT) == 0)
1068 break;
1069
1070 if (time_after(jiffies, timeout)) {
1071
1072
1073 wl1271_error("soft reset timeout");
1074 return -1;
1075 }
1076
1077 udelay(SOFT_RESET_STALL_TIME);
1078 }
1079
1080
1081 ret = wlcore_write32(wl, WL12XX_ENABLE, 0x0);
1082 if (ret < 0)
1083 goto out;
1084
1085
1086 ret = wlcore_write32(wl, WL12XX_SPARE_A2, 0xffff);
1087
1088out:
1089 return ret;
1090}
1091
1092static int wl12xx_pre_boot(struct wl1271 *wl)
1093{
1094 struct wl12xx_priv *priv = wl->priv;
1095 int ret = 0;
1096 u32 clk;
1097 int selected_clock = -1;
1098
1099 if (wl->chip.id == CHIP_ID_128X_PG20) {
1100 ret = wl128x_boot_clk(wl, &selected_clock);
1101 if (ret < 0)
1102 goto out;
1103 } else {
1104 ret = wl127x_boot_clk(wl);
1105 if (ret < 0)
1106 goto out;
1107 }
1108
1109
1110 ret = wlcore_write32(wl, WL12XX_WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL);
1111 if (ret < 0)
1112 goto out;
1113
1114 udelay(500);
1115
1116 ret = wlcore_set_partition(wl, &wl->ptable[PART_DRPW]);
1117 if (ret < 0)
1118 goto out;
1119
1120
1121
1122
1123
1124 ret = wlcore_read32(wl, WL12XX_DRPW_SCRATCH_START, &clk);
1125 if (ret < 0)
1126 goto out;
1127
1128 wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk);
1129
1130 if (wl->chip.id == CHIP_ID_128X_PG20)
1131 clk |= ((selected_clock & 0x3) << 1) << 4;
1132 else
1133 clk |= (priv->ref_clock << 1) << 4;
1134
1135 ret = wlcore_write32(wl, WL12XX_DRPW_SCRATCH_START, clk);
1136 if (ret < 0)
1137 goto out;
1138
1139 ret = wlcore_set_partition(wl, &wl->ptable[PART_WORK]);
1140 if (ret < 0)
1141 goto out;
1142
1143
1144 ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
1145 if (ret < 0)
1146 goto out;
1147
1148 ret = wl1271_boot_soft_reset(wl);
1149 if (ret < 0)
1150 goto out;
1151
1152out:
1153 return ret;
1154}
1155
1156static int wl12xx_pre_upload(struct wl1271 *wl)
1157{
1158 u32 tmp;
1159 u16 polarity;
1160 int ret;
1161
1162
1163
1164 wl1271_debug(DEBUG_BOOT, "ACX_EEPROMLESS_IND_REG");
1165
1166 ret = wlcore_write32(wl, WL12XX_EEPROMLESS_IND, WL12XX_EEPROMLESS_IND);
1167 if (ret < 0)
1168 goto out;
1169
1170 ret = wlcore_read_reg(wl, REG_CHIP_ID_B, &tmp);
1171 if (ret < 0)
1172 goto out;
1173
1174 wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp);
1175
1176
1177 ret = wlcore_read32(wl, WL12XX_SCR_PAD2, &tmp);
1178 if (ret < 0)
1179 goto out;
1180
1181
1182
1183
1184 if (wl->chip.id == CHIP_ID_128X_PG20) {
1185 ret = wl12xx_top_reg_write(wl, SDIO_IO_DS, HCI_IO_DS_6MA);
1186 if (ret < 0)
1187 goto out;
1188 }
1189
1190
1191 ret = wl12xx_top_reg_read(wl, OCP_REG_POLARITY, &polarity);
1192 if (ret < 0)
1193 goto out;
1194
1195
1196 polarity &= ~POLARITY_LOW;
1197 ret = wl12xx_top_reg_write(wl, OCP_REG_POLARITY, polarity);
1198
1199out:
1200 return ret;
1201}
1202
1203static int wl12xx_enable_interrupts(struct wl1271 *wl)
1204{
1205 int ret;
1206
1207 ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK,
1208 WL12XX_ACX_ALL_EVENTS_VECTOR);
1209 if (ret < 0)
1210 goto out;
1211
1212 wlcore_enable_interrupts(wl);
1213 ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK,
1214 WL1271_ACX_INTR_ALL & ~(WL12XX_INTR_MASK));
1215 if (ret < 0)
1216 goto disable_interrupts;
1217
1218 ret = wlcore_write32(wl, WL12XX_HI_CFG, HI_CFG_DEF_VAL);
1219 if (ret < 0)
1220 goto disable_interrupts;
1221
1222 return ret;
1223
1224disable_interrupts:
1225 wlcore_disable_interrupts(wl);
1226
1227out:
1228 return ret;
1229}
1230
1231static int wl12xx_boot(struct wl1271 *wl)
1232{
1233 int ret;
1234
1235 ret = wl12xx_pre_boot(wl);
1236 if (ret < 0)
1237 goto out;
1238
1239 ret = wlcore_boot_upload_nvs(wl);
1240 if (ret < 0)
1241 goto out;
1242
1243 ret = wl12xx_pre_upload(wl);
1244 if (ret < 0)
1245 goto out;
1246
1247 ret = wlcore_boot_upload_firmware(wl);
1248 if (ret < 0)
1249 goto out;
1250
1251 wl->event_mask = BSS_LOSE_EVENT_ID |
1252 REGAINED_BSS_EVENT_ID |
1253 SCAN_COMPLETE_EVENT_ID |
1254 ROLE_STOP_COMPLETE_EVENT_ID |
1255 RSSI_SNR_TRIGGER_0_EVENT_ID |
1256 PSPOLL_DELIVERY_FAILURE_EVENT_ID |
1257 SOFT_GEMINI_SENSE_EVENT_ID |
1258 PERIODIC_SCAN_REPORT_EVENT_ID |
1259 PERIODIC_SCAN_COMPLETE_EVENT_ID |
1260 DUMMY_PACKET_EVENT_ID |
1261 PEER_REMOVE_COMPLETE_EVENT_ID |
1262 BA_SESSION_RX_CONSTRAINT_EVENT_ID |
1263 REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID |
1264 INACTIVE_STA_EVENT_ID |
1265 MAX_TX_RETRY_EVENT_ID |
1266 CHANNEL_SWITCH_COMPLETE_EVENT_ID;
1267
1268 ret = wlcore_boot_run_firmware(wl);
1269 if (ret < 0)
1270 goto out;
1271
1272 ret = wl12xx_enable_interrupts(wl);
1273
1274out:
1275 return ret;
1276}
1277
1278static int wl12xx_trigger_cmd(struct wl1271 *wl, int cmd_box_addr,
1279 void *buf, size_t len)
1280{
1281 int ret;
1282
1283 ret = wlcore_write(wl, cmd_box_addr, buf, len, false);
1284 if (ret < 0)
1285 return ret;
1286
1287 ret = wlcore_write_reg(wl, REG_INTERRUPT_TRIG, WL12XX_INTR_TRIG_CMD);
1288
1289 return ret;
1290}
1291
1292static int wl12xx_ack_event(struct wl1271 *wl)
1293{
1294 return wlcore_write_reg(wl, REG_INTERRUPT_TRIG,
1295 WL12XX_INTR_TRIG_EVENT_ACK);
1296}
1297
1298static u32 wl12xx_calc_tx_blocks(struct wl1271 *wl, u32 len, u32 spare_blks)
1299{
1300 u32 blk_size = WL12XX_TX_HW_BLOCK_SIZE;
1301 u32 align_len = wlcore_calc_packet_alignment(wl, len);
1302
1303 return (align_len + blk_size - 1) / blk_size + spare_blks;
1304}
1305
1306static void
1307wl12xx_set_tx_desc_blocks(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc,
1308 u32 blks, u32 spare_blks)
1309{
1310 if (wl->chip.id == CHIP_ID_128X_PG20) {
1311 desc->wl128x_mem.total_mem_blocks = blks;
1312 } else {
1313 desc->wl127x_mem.extra_blocks = spare_blks;
1314 desc->wl127x_mem.total_mem_blocks = blks;
1315 }
1316}
1317
1318static void
1319wl12xx_set_tx_desc_data_len(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc,
1320 struct sk_buff *skb)
1321{
1322 u32 aligned_len = wlcore_calc_packet_alignment(wl, skb->len);
1323
1324 if (wl->chip.id == CHIP_ID_128X_PG20) {
1325 desc->wl128x_mem.extra_bytes = aligned_len - skb->len;
1326 desc->length = cpu_to_le16(aligned_len >> 2);
1327
1328 wl1271_debug(DEBUG_TX,
1329 "tx_fill_hdr: hlid: %d len: %d life: %d mem: %d extra: %d",
1330 desc->hlid,
1331 le16_to_cpu(desc->length),
1332 le16_to_cpu(desc->life_time),
1333 desc->wl128x_mem.total_mem_blocks,
1334 desc->wl128x_mem.extra_bytes);
1335 } else {
1336
1337 int pad = aligned_len - skb->len;
1338 desc->tx_attr |=
1339 cpu_to_le16(pad << TX_HW_ATTR_OFST_LAST_WORD_PAD);
1340
1341
1342 desc->length = cpu_to_le16(aligned_len >> 2);
1343
1344 wl1271_debug(DEBUG_TX,
1345 "tx_fill_hdr: pad: %d hlid: %d len: %d life: %d mem: %d",
1346 pad, desc->hlid,
1347 le16_to_cpu(desc->length),
1348 le16_to_cpu(desc->life_time),
1349 desc->wl127x_mem.total_mem_blocks);
1350 }
1351}
1352
1353static enum wl_rx_buf_align
1354wl12xx_get_rx_buf_align(struct wl1271 *wl, u32 rx_desc)
1355{
1356 if (rx_desc & RX_BUF_UNALIGNED_PAYLOAD)
1357 return WLCORE_RX_BUF_UNALIGNED;
1358
1359 return WLCORE_RX_BUF_ALIGNED;
1360}
1361
1362static u32 wl12xx_get_rx_packet_len(struct wl1271 *wl, void *rx_data,
1363 u32 data_len)
1364{
1365 struct wl1271_rx_descriptor *desc = rx_data;
1366
1367
1368 if (data_len < sizeof(*desc) ||
1369 data_len < sizeof(*desc) + desc->pad_len)
1370 return 0;
1371
1372 return data_len - sizeof(*desc) - desc->pad_len;
1373}
1374
1375static int wl12xx_tx_delayed_compl(struct wl1271 *wl)
1376{
1377 if (wl->fw_status_1->tx_results_counter ==
1378 (wl->tx_results_count & 0xff))
1379 return 0;
1380
1381 return wlcore_tx_complete(wl);
1382}
1383
1384static int wl12xx_hw_init(struct wl1271 *wl)
1385{
1386 int ret;
1387
1388 if (wl->chip.id == CHIP_ID_128X_PG20) {
1389 u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE;
1390
1391 ret = wl128x_cmd_general_parms(wl);
1392 if (ret < 0)
1393 goto out;
1394
1395
1396
1397
1398
1399 if (wl->plt_mode == PLT_FEM_DETECT)
1400 goto out;
1401
1402 ret = wl128x_cmd_radio_parms(wl);
1403 if (ret < 0)
1404 goto out;
1405
1406 if (wl->quirks & WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN)
1407
1408 host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK;
1409
1410
1411 ret = wl1271_acx_host_if_cfg_bitmap(wl, host_cfg_bitmap);
1412 if (ret < 0)
1413 goto out;
1414 } else {
1415 ret = wl1271_cmd_general_parms(wl);
1416 if (ret < 0)
1417 goto out;
1418
1419
1420
1421
1422
1423 if (wl->plt_mode == PLT_FEM_DETECT)
1424 goto out;
1425
1426 ret = wl1271_cmd_radio_parms(wl);
1427 if (ret < 0)
1428 goto out;
1429 ret = wl1271_cmd_ext_radio_parms(wl);
1430 if (ret < 0)
1431 goto out;
1432 }
1433out:
1434 return ret;
1435}
1436
1437static u32 wl12xx_sta_get_ap_rate_mask(struct wl1271 *wl,
1438 struct wl12xx_vif *wlvif)
1439{
1440 return wlvif->rate_set;
1441}
1442
1443static void wl12xx_conf_init(struct wl1271 *wl)
1444{
1445 struct wl12xx_priv *priv = wl->priv;
1446
1447
1448 memcpy(&wl->conf, &wl12xx_conf, sizeof(wl12xx_conf));
1449
1450
1451 memcpy(&priv->conf, &wl12xx_default_priv_conf, sizeof(priv->conf));
1452}
1453
1454static bool wl12xx_mac_in_fuse(struct wl1271 *wl)
1455{
1456 bool supported = false;
1457 u8 major, minor;
1458
1459 if (wl->chip.id == CHIP_ID_128X_PG20) {
1460 major = WL128X_PG_GET_MAJOR(wl->hw_pg_ver);
1461 minor = WL128X_PG_GET_MINOR(wl->hw_pg_ver);
1462
1463
1464 if (major > 2 || (major == 2 && minor >= 1))
1465 supported = true;
1466 } else {
1467 major = WL127X_PG_GET_MAJOR(wl->hw_pg_ver);
1468 minor = WL127X_PG_GET_MINOR(wl->hw_pg_ver);
1469
1470
1471 if (major == 3 && minor >= 1)
1472 supported = true;
1473 }
1474
1475 wl1271_debug(DEBUG_PROBE,
1476 "PG Ver major = %d minor = %d, MAC %s present",
1477 major, minor, supported ? "is" : "is not");
1478
1479 return supported;
1480}
1481
1482static int wl12xx_get_fuse_mac(struct wl1271 *wl)
1483{
1484 u32 mac1, mac2;
1485 int ret;
1486
1487 ret = wlcore_set_partition(wl, &wl->ptable[PART_DRPW]);
1488 if (ret < 0)
1489 goto out;
1490
1491 ret = wlcore_read32(wl, WL12XX_REG_FUSE_BD_ADDR_1, &mac1);
1492 if (ret < 0)
1493 goto out;
1494
1495 ret = wlcore_read32(wl, WL12XX_REG_FUSE_BD_ADDR_2, &mac2);
1496 if (ret < 0)
1497 goto out;
1498
1499
1500 wl->fuse_oui_addr = ((mac2 & 0xffff) << 8) +
1501 ((mac1 & 0xff000000) >> 24);
1502 wl->fuse_nic_addr = mac1 & 0xffffff;
1503
1504 ret = wlcore_set_partition(wl, &wl->ptable[PART_DOWN]);
1505
1506out:
1507 return ret;
1508}
1509
1510static int wl12xx_get_pg_ver(struct wl1271 *wl, s8 *ver)
1511{
1512 u16 die_info;
1513 int ret;
1514
1515 if (wl->chip.id == CHIP_ID_128X_PG20)
1516 ret = wl12xx_top_reg_read(wl, WL128X_REG_FUSE_DATA_2_1,
1517 &die_info);
1518 else
1519 ret = wl12xx_top_reg_read(wl, WL127X_REG_FUSE_DATA_2_1,
1520 &die_info);
1521
1522 if (ret >= 0 && ver)
1523 *ver = (s8)((die_info & PG_VER_MASK) >> PG_VER_OFFSET);
1524
1525 return ret;
1526}
1527
1528static int wl12xx_get_mac(struct wl1271 *wl)
1529{
1530 if (wl12xx_mac_in_fuse(wl))
1531 return wl12xx_get_fuse_mac(wl);
1532
1533 return 0;
1534}
1535
1536static void wl12xx_set_tx_desc_csum(struct wl1271 *wl,
1537 struct wl1271_tx_hw_descr *desc,
1538 struct sk_buff *skb)
1539{
1540 desc->wl12xx_reserved = 0;
1541}
1542
1543static int wl12xx_plt_init(struct wl1271 *wl)
1544{
1545 int ret;
1546
1547 ret = wl->ops->boot(wl);
1548 if (ret < 0)
1549 goto out;
1550
1551 ret = wl->ops->hw_init(wl);
1552 if (ret < 0)
1553 goto out_irq_disable;
1554
1555
1556
1557
1558
1559 if (wl->plt_mode == PLT_FEM_DETECT)
1560 goto out;
1561
1562 ret = wl1271_acx_init_mem_config(wl);
1563 if (ret < 0)
1564 goto out_irq_disable;
1565
1566 ret = wl12xx_acx_mem_cfg(wl);
1567 if (ret < 0)
1568 goto out_free_memmap;
1569
1570
1571 ret = wl1271_cmd_data_path(wl, 1);
1572 if (ret < 0)
1573 goto out_free_memmap;
1574
1575
1576 ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM);
1577 if (ret < 0)
1578 goto out_free_memmap;
1579
1580
1581 ret = wl1271_acx_pm_config(wl);
1582 if (ret < 0)
1583 goto out_free_memmap;
1584
1585 goto out;
1586
1587out_free_memmap:
1588 kfree(wl->target_mem_map);
1589 wl->target_mem_map = NULL;
1590
1591out_irq_disable:
1592 mutex_unlock(&wl->mutex);
1593
1594
1595
1596
1597
1598
1599
1600 wlcore_disable_interrupts(wl);
1601 mutex_lock(&wl->mutex);
1602out:
1603 return ret;
1604}
1605
1606static int wl12xx_get_spare_blocks(struct wl1271 *wl, bool is_gem)
1607{
1608 if (is_gem)
1609 return WL12XX_TX_HW_BLOCK_GEM_SPARE;
1610
1611 return WL12XX_TX_HW_BLOCK_SPARE_DEFAULT;
1612}
1613
1614static int wl12xx_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
1615 struct ieee80211_vif *vif,
1616 struct ieee80211_sta *sta,
1617 struct ieee80211_key_conf *key_conf)
1618{
1619 return wlcore_set_key(wl, cmd, vif, sta, key_conf);
1620}
1621
1622static int wl12xx_set_peer_cap(struct wl1271 *wl,
1623 struct ieee80211_sta_ht_cap *ht_cap,
1624 bool allow_ht_operation,
1625 u32 rate_set, u8 hlid)
1626{
1627 return wl1271_acx_set_ht_capabilities(wl, ht_cap, allow_ht_operation,
1628 hlid);
1629}
1630
1631static bool wl12xx_lnk_high_prio(struct wl1271 *wl, u8 hlid,
1632 struct wl1271_link *lnk)
1633{
1634 u8 thold;
1635
1636 if (test_bit(hlid, (unsigned long *)&wl->fw_fast_lnk_map))
1637 thold = wl->conf.tx.fast_link_thold;
1638 else
1639 thold = wl->conf.tx.slow_link_thold;
1640
1641 return lnk->allocated_pkts < thold;
1642}
1643
1644static bool wl12xx_lnk_low_prio(struct wl1271 *wl, u8 hlid,
1645 struct wl1271_link *lnk)
1646{
1647
1648 return true;
1649}
1650
1651static int wl12xx_setup(struct wl1271 *wl);
1652
1653static struct wlcore_ops wl12xx_ops = {
1654 .setup = wl12xx_setup,
1655 .identify_chip = wl12xx_identify_chip,
1656 .boot = wl12xx_boot,
1657 .plt_init = wl12xx_plt_init,
1658 .trigger_cmd = wl12xx_trigger_cmd,
1659 .ack_event = wl12xx_ack_event,
1660 .wait_for_event = wl12xx_wait_for_event,
1661 .process_mailbox_events = wl12xx_process_mailbox_events,
1662 .calc_tx_blocks = wl12xx_calc_tx_blocks,
1663 .set_tx_desc_blocks = wl12xx_set_tx_desc_blocks,
1664 .set_tx_desc_data_len = wl12xx_set_tx_desc_data_len,
1665 .get_rx_buf_align = wl12xx_get_rx_buf_align,
1666 .get_rx_packet_len = wl12xx_get_rx_packet_len,
1667 .tx_immediate_compl = NULL,
1668 .tx_delayed_compl = wl12xx_tx_delayed_compl,
1669 .hw_init = wl12xx_hw_init,
1670 .init_vif = NULL,
1671 .sta_get_ap_rate_mask = wl12xx_sta_get_ap_rate_mask,
1672 .get_pg_ver = wl12xx_get_pg_ver,
1673 .get_mac = wl12xx_get_mac,
1674 .set_tx_desc_csum = wl12xx_set_tx_desc_csum,
1675 .set_rx_csum = NULL,
1676 .ap_get_mimo_wide_rate_mask = NULL,
1677 .debugfs_init = wl12xx_debugfs_add_files,
1678 .scan_start = wl12xx_scan_start,
1679 .scan_stop = wl12xx_scan_stop,
1680 .sched_scan_start = wl12xx_sched_scan_start,
1681 .sched_scan_stop = wl12xx_scan_sched_scan_stop,
1682 .get_spare_blocks = wl12xx_get_spare_blocks,
1683 .set_key = wl12xx_set_key,
1684 .channel_switch = wl12xx_cmd_channel_switch,
1685 .pre_pkt_send = NULL,
1686 .set_peer_cap = wl12xx_set_peer_cap,
1687 .lnk_high_prio = wl12xx_lnk_high_prio,
1688 .lnk_low_prio = wl12xx_lnk_low_prio,
1689};
1690
1691static struct ieee80211_sta_ht_cap wl12xx_ht_cap = {
1692 .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 |
1693 (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT),
1694 .ht_supported = true,
1695 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K,
1696 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_8,
1697 .mcs = {
1698 .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
1699 .rx_highest = cpu_to_le16(72),
1700 .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
1701 },
1702};
1703
1704static int wl12xx_setup(struct wl1271 *wl)
1705{
1706 struct wl12xx_priv *priv = wl->priv;
1707 struct wlcore_platdev_data *pdev_data = wl->pdev->dev.platform_data;
1708 struct wl12xx_platform_data *pdata = pdev_data->pdata;
1709
1710 wl->rtable = wl12xx_rtable;
1711 wl->num_tx_desc = WL12XX_NUM_TX_DESCRIPTORS;
1712 wl->num_rx_desc = WL12XX_NUM_RX_DESCRIPTORS;
1713 wl->num_channels = 1;
1714 wl->num_mac_addr = WL12XX_NUM_MAC_ADDRESSES;
1715 wl->band_rate_to_idx = wl12xx_band_rate_to_idx;
1716 wl->hw_tx_rate_tbl_size = WL12XX_CONF_HW_RXTX_RATE_MAX;
1717 wl->hw_min_ht_rate = WL12XX_CONF_HW_RXTX_RATE_MCS0;
1718 wl->fw_status_priv_len = 0;
1719 wl->stats.fw_stats_len = sizeof(struct wl12xx_acx_statistics);
1720 wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ, &wl12xx_ht_cap);
1721 wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ, &wl12xx_ht_cap);
1722 wl12xx_conf_init(wl);
1723
1724 if (!fref_param) {
1725 priv->ref_clock = pdata->board_ref_clock;
1726 } else {
1727 if (!strcmp(fref_param, "19.2"))
1728 priv->ref_clock = WL12XX_REFCLOCK_19;
1729 else if (!strcmp(fref_param, "26"))
1730 priv->ref_clock = WL12XX_REFCLOCK_26;
1731 else if (!strcmp(fref_param, "26x"))
1732 priv->ref_clock = WL12XX_REFCLOCK_26_XTAL;
1733 else if (!strcmp(fref_param, "38.4"))
1734 priv->ref_clock = WL12XX_REFCLOCK_38;
1735 else if (!strcmp(fref_param, "38.4x"))
1736 priv->ref_clock = WL12XX_REFCLOCK_38_XTAL;
1737 else if (!strcmp(fref_param, "52"))
1738 priv->ref_clock = WL12XX_REFCLOCK_52;
1739 else
1740 wl1271_error("Invalid fref parameter %s", fref_param);
1741 }
1742
1743 if (!tcxo_param) {
1744 priv->tcxo_clock = pdata->board_tcxo_clock;
1745 } else {
1746 if (!strcmp(tcxo_param, "19.2"))
1747 priv->tcxo_clock = WL12XX_TCXOCLOCK_19_2;
1748 else if (!strcmp(tcxo_param, "26"))
1749 priv->tcxo_clock = WL12XX_TCXOCLOCK_26;
1750 else if (!strcmp(tcxo_param, "38.4"))
1751 priv->tcxo_clock = WL12XX_TCXOCLOCK_38_4;
1752 else if (!strcmp(tcxo_param, "52"))
1753 priv->tcxo_clock = WL12XX_TCXOCLOCK_52;
1754 else if (!strcmp(tcxo_param, "16.368"))
1755 priv->tcxo_clock = WL12XX_TCXOCLOCK_16_368;
1756 else if (!strcmp(tcxo_param, "32.736"))
1757 priv->tcxo_clock = WL12XX_TCXOCLOCK_32_736;
1758 else if (!strcmp(tcxo_param, "16.8"))
1759 priv->tcxo_clock = WL12XX_TCXOCLOCK_16_8;
1760 else if (!strcmp(tcxo_param, "33.6"))
1761 priv->tcxo_clock = WL12XX_TCXOCLOCK_33_6;
1762 else
1763 wl1271_error("Invalid tcxo parameter %s", tcxo_param);
1764 }
1765
1766 priv->rx_mem_addr = kmalloc(sizeof(*priv->rx_mem_addr), GFP_KERNEL);
1767 if (!priv->rx_mem_addr)
1768 return -ENOMEM;
1769
1770 return 0;
1771}
1772
1773static int wl12xx_probe(struct platform_device *pdev)
1774{
1775 struct wl1271 *wl;
1776 struct ieee80211_hw *hw;
1777 int ret;
1778
1779 hw = wlcore_alloc_hw(sizeof(struct wl12xx_priv),
1780 WL12XX_AGGR_BUFFER_SIZE,
1781 sizeof(struct wl12xx_event_mailbox));
1782 if (IS_ERR(hw)) {
1783 wl1271_error("can't allocate hw");
1784 ret = PTR_ERR(hw);
1785 goto out;
1786 }
1787
1788 wl = hw->priv;
1789 wl->ops = &wl12xx_ops;
1790 wl->ptable = wl12xx_ptable;
1791 ret = wlcore_probe(wl, pdev);
1792 if (ret)
1793 goto out_free;
1794
1795 return ret;
1796
1797out_free:
1798 wlcore_free_hw(wl);
1799out:
1800 return ret;
1801}
1802
1803static int wl12xx_remove(struct platform_device *pdev)
1804{
1805 struct wl1271 *wl = platform_get_drvdata(pdev);
1806 struct wl12xx_priv *priv;
1807
1808 if (!wl)
1809 goto out;
1810 priv = wl->priv;
1811
1812 kfree(priv->rx_mem_addr);
1813
1814out:
1815 return wlcore_remove(pdev);
1816}
1817
1818static const struct platform_device_id wl12xx_id_table[] = {
1819 { "wl12xx", 0 },
1820 { }
1821};
1822MODULE_DEVICE_TABLE(platform, wl12xx_id_table);
1823
1824static struct platform_driver wl12xx_driver = {
1825 .probe = wl12xx_probe,
1826 .remove = wl12xx_remove,
1827 .id_table = wl12xx_id_table,
1828 .driver = {
1829 .name = "wl12xx_driver",
1830 .owner = THIS_MODULE,
1831 }
1832};
1833
1834module_platform_driver(wl12xx_driver);
1835
1836module_param_named(fref, fref_param, charp, 0);
1837MODULE_PARM_DESC(fref, "FREF clock: 19.2, 26, 26x, 38.4, 38.4x, 52");
1838
1839module_param_named(tcxo, tcxo_param, charp, 0);
1840MODULE_PARM_DESC(tcxo,
1841 "TCXO clock: 19.2, 26, 38.4, 52, 16.368, 32.736, 16.8, 33.6");
1842
1843MODULE_LICENSE("GPL v2");
1844MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
1845MODULE_FIRMWARE(WL127X_FW_NAME_SINGLE);
1846MODULE_FIRMWARE(WL127X_FW_NAME_MULTI);
1847MODULE_FIRMWARE(WL127X_PLT_FW_NAME);
1848MODULE_FIRMWARE(WL128X_FW_NAME_SINGLE);
1849MODULE_FIRMWARE(WL128X_FW_NAME_MULTI);
1850MODULE_FIRMWARE(WL128X_PLT_FW_NAME);
1851