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