wlcore: modify bss loss parameters
[deliverable/linux.git] / drivers / net / wireless / ti / wl12xx / main.c
CommitLineData
b2ba99ff
LC
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2008-2010 Nokia Corporation
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#include <linux/module.h>
23#include <linux/platform_device.h>
24
ffeb501c
LC
25#include <linux/err.h>
26
dd5512eb
LC
27#include <linux/wl12xx.h>
28
b2ba99ff 29#include "../wlcore/wlcore.h"
ffeb501c 30#include "../wlcore/debug.h"
4ded91ce 31#include "../wlcore/io.h"
dd5512eb 32#include "../wlcore/acx.h"
b3b4b4b8 33#include "../wlcore/tx.h"
cd70f6a4 34#include "../wlcore/rx.h"
b14684a0 35#include "../wlcore/io.h"
dd5512eb 36#include "../wlcore/boot.h"
ffeb501c 37
166b2136 38#include "wl12xx.h"
00782136 39#include "reg.h"
9d68d1ee
LC
40#include "cmd.h"
41#include "acx.h"
10b1e8a2 42#include "debugfs.h"
25a43d78 43
a5d751bb
LC
44static char *fref_param;
45static char *tcxo_param;
46
e87288f0
LC
47static struct wlcore_conf wl12xx_conf = {
48 .sg = {
49 .params = {
50 [CONF_SG_ACL_BT_MASTER_MIN_BR] = 10,
51 [CONF_SG_ACL_BT_MASTER_MAX_BR] = 180,
52 [CONF_SG_ACL_BT_SLAVE_MIN_BR] = 10,
53 [CONF_SG_ACL_BT_SLAVE_MAX_BR] = 180,
54 [CONF_SG_ACL_BT_MASTER_MIN_EDR] = 10,
55 [CONF_SG_ACL_BT_MASTER_MAX_EDR] = 80,
56 [CONF_SG_ACL_BT_SLAVE_MIN_EDR] = 10,
57 [CONF_SG_ACL_BT_SLAVE_MAX_EDR] = 80,
58 [CONF_SG_ACL_WLAN_PS_MASTER_BR] = 8,
59 [CONF_SG_ACL_WLAN_PS_SLAVE_BR] = 8,
60 [CONF_SG_ACL_WLAN_PS_MASTER_EDR] = 20,
61 [CONF_SG_ACL_WLAN_PS_SLAVE_EDR] = 20,
62 [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_BR] = 20,
63 [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_BR] = 35,
64 [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_BR] = 16,
65 [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_BR] = 35,
66 [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_EDR] = 32,
67 [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_EDR] = 50,
68 [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_EDR] = 28,
69 [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_EDR] = 50,
70 [CONF_SG_ACL_ACTIVE_SCAN_WLAN_BR] = 10,
71 [CONF_SG_ACL_ACTIVE_SCAN_WLAN_EDR] = 20,
72 [CONF_SG_ACL_PASSIVE_SCAN_BT_BR] = 75,
73 [CONF_SG_ACL_PASSIVE_SCAN_WLAN_BR] = 15,
74 [CONF_SG_ACL_PASSIVE_SCAN_BT_EDR] = 27,
75 [CONF_SG_ACL_PASSIVE_SCAN_WLAN_EDR] = 17,
76 /* active scan params */
77 [CONF_SG_AUTO_SCAN_PROBE_REQ] = 170,
78 [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3] = 50,
79 [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP] = 100,
80 /* passive scan params */
81 [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP_BR] = 800,
82 [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP_EDR] = 200,
83 [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3] = 200,
84 /* passive scan in dual antenna params */
85 [CONF_SG_CONSECUTIVE_HV3_IN_PASSIVE_SCAN] = 0,
86 [CONF_SG_BCN_HV3_COLLISION_THRESH_IN_PASSIVE_SCAN] = 0,
87 [CONF_SG_TX_RX_PROTECTION_BWIDTH_IN_PASSIVE_SCAN] = 0,
88 /* general params */
89 [CONF_SG_STA_FORCE_PS_IN_BT_SCO] = 1,
90 [CONF_SG_ANTENNA_CONFIGURATION] = 0,
91 [CONF_SG_BEACON_MISS_PERCENT] = 60,
92 [CONF_SG_DHCP_TIME] = 5000,
93 [CONF_SG_RXT] = 1200,
94 [CONF_SG_TXT] = 1000,
95 [CONF_SG_ADAPTIVE_RXT_TXT] = 1,
96 [CONF_SG_GENERAL_USAGE_BIT_MAP] = 3,
97 [CONF_SG_HV3_MAX_SERVED] = 6,
98 [CONF_SG_PS_POLL_TIMEOUT] = 10,
99 [CONF_SG_UPSD_TIMEOUT] = 10,
100 [CONF_SG_CONSECUTIVE_CTS_THRESHOLD] = 2,
101 [CONF_SG_STA_RX_WINDOW_AFTER_DTIM] = 5,
102 [CONF_SG_STA_CONNECTION_PROTECTION_TIME] = 30,
103 /* AP params */
104 [CONF_AP_BEACON_MISS_TX] = 3,
105 [CONF_AP_RX_WINDOW_AFTER_BEACON] = 10,
106 [CONF_AP_BEACON_WINDOW_INTERVAL] = 2,
107 [CONF_AP_CONNECTION_PROTECTION_TIME] = 0,
108 [CONF_AP_BT_ACL_VAL_BT_SERVE_TIME] = 25,
109 [CONF_AP_BT_ACL_VAL_WL_SERVE_TIME] = 25,
110 /* CTS Diluting params */
111 [CONF_SG_CTS_DILUTED_BAD_RX_PACKETS_TH] = 0,
112 [CONF_SG_CTS_CHOP_IN_DUAL_ANT_SCO_MASTER] = 0,
113 },
114 .state = CONF_SG_PROTECTIVE,
115 },
116 .rx = {
117 .rx_msdu_life_time = 512000,
118 .packet_detection_threshold = 0,
119 .ps_poll_timeout = 15,
120 .upsd_timeout = 15,
121 .rts_threshold = IEEE80211_MAX_RTS_THRESHOLD,
122 .rx_cca_threshold = 0,
123 .irq_blk_threshold = 0xFFFF,
124 .irq_pkt_threshold = 0,
125 .irq_timeout = 600,
126 .queue_type = CONF_RX_QUEUE_TYPE_LOW_PRIORITY,
127 },
128 .tx = {
129 .tx_energy_detection = 0,
130 .sta_rc_conf = {
131 .enabled_rates = 0,
132 .short_retry_limit = 10,
133 .long_retry_limit = 10,
134 .aflags = 0,
135 },
136 .ac_conf_count = 4,
137 .ac_conf = {
138 [CONF_TX_AC_BE] = {
139 .ac = CONF_TX_AC_BE,
140 .cw_min = 15,
141 .cw_max = 63,
142 .aifsn = 3,
143 .tx_op_limit = 0,
144 },
145 [CONF_TX_AC_BK] = {
146 .ac = CONF_TX_AC_BK,
147 .cw_min = 15,
148 .cw_max = 63,
149 .aifsn = 7,
150 .tx_op_limit = 0,
151 },
152 [CONF_TX_AC_VI] = {
153 .ac = CONF_TX_AC_VI,
154 .cw_min = 15,
155 .cw_max = 63,
156 .aifsn = CONF_TX_AIFS_PIFS,
157 .tx_op_limit = 3008,
158 },
159 [CONF_TX_AC_VO] = {
160 .ac = CONF_TX_AC_VO,
161 .cw_min = 15,
162 .cw_max = 63,
163 .aifsn = CONF_TX_AIFS_PIFS,
164 .tx_op_limit = 1504,
165 },
166 },
167 .max_tx_retries = 100,
168 .ap_aging_period = 300,
169 .tid_conf_count = 4,
170 .tid_conf = {
171 [CONF_TX_AC_BE] = {
172 .queue_id = CONF_TX_AC_BE,
173 .channel_type = CONF_CHANNEL_TYPE_EDCF,
174 .tsid = CONF_TX_AC_BE,
175 .ps_scheme = CONF_PS_SCHEME_LEGACY,
176 .ack_policy = CONF_ACK_POLICY_LEGACY,
177 .apsd_conf = {0, 0},
178 },
179 [CONF_TX_AC_BK] = {
180 .queue_id = CONF_TX_AC_BK,
181 .channel_type = CONF_CHANNEL_TYPE_EDCF,
182 .tsid = CONF_TX_AC_BK,
183 .ps_scheme = CONF_PS_SCHEME_LEGACY,
184 .ack_policy = CONF_ACK_POLICY_LEGACY,
185 .apsd_conf = {0, 0},
186 },
187 [CONF_TX_AC_VI] = {
188 .queue_id = CONF_TX_AC_VI,
189 .channel_type = CONF_CHANNEL_TYPE_EDCF,
190 .tsid = CONF_TX_AC_VI,
191 .ps_scheme = CONF_PS_SCHEME_LEGACY,
192 .ack_policy = CONF_ACK_POLICY_LEGACY,
193 .apsd_conf = {0, 0},
194 },
195 [CONF_TX_AC_VO] = {
196 .queue_id = CONF_TX_AC_VO,
197 .channel_type = CONF_CHANNEL_TYPE_EDCF,
198 .tsid = CONF_TX_AC_VO,
199 .ps_scheme = CONF_PS_SCHEME_LEGACY,
200 .ack_policy = CONF_ACK_POLICY_LEGACY,
201 .apsd_conf = {0, 0},
202 },
203 },
204 .frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD,
205 .tx_compl_timeout = 700,
206 .tx_compl_threshold = 4,
207 .basic_rate = CONF_HW_BIT_RATE_1MBPS,
208 .basic_rate_5 = CONF_HW_BIT_RATE_6MBPS,
209 .tmpl_short_retry_limit = 10,
210 .tmpl_long_retry_limit = 10,
211 .tx_watchdog_timeout = 5000,
212 },
213 .conn = {
214 .wake_up_event = CONF_WAKE_UP_EVENT_DTIM,
215 .listen_interval = 1,
216 .suspend_wake_up_event = CONF_WAKE_UP_EVENT_N_DTIM,
217 .suspend_listen_interval = 3,
218 .bcn_filt_mode = CONF_BCN_FILT_MODE_ENABLED,
219 .bcn_filt_ie_count = 2,
220 .bcn_filt_ie = {
221 [0] = {
222 .ie = WLAN_EID_CHANNEL_SWITCH,
223 .rule = CONF_BCN_RULE_PASS_ON_APPEARANCE,
224 },
225 [1] = {
226 .ie = WLAN_EID_HT_OPERATION,
227 .rule = CONF_BCN_RULE_PASS_ON_CHANGE,
228 },
229 },
7b052214
IC
230 .synch_fail_thold = 12,
231 .bss_lose_timeout = 400,
e87288f0
LC
232 .beacon_rx_timeout = 10000,
233 .broadcast_timeout = 20000,
234 .rx_broadcast_in_ps = 1,
235 .ps_poll_threshold = 10,
236 .bet_enable = CONF_BET_MODE_ENABLE,
237 .bet_max_consecutive = 50,
238 .psm_entry_retries = 8,
239 .psm_exit_retries = 16,
240 .psm_entry_nullfunc_retries = 3,
6e066921 241 .dynamic_ps_timeout = 200,
e87288f0
LC
242 .forced_ps = false,
243 .keep_alive_interval = 55000,
244 .max_listen_interval = 20,
245 },
246 .itrim = {
247 .enable = false,
248 .timeout = 50000,
249 },
250 .pm_config = {
251 .host_clk_settling_time = 5000,
252 .host_fast_wakeup_support = false
253 },
254 .roam_trigger = {
255 .trigger_pacing = 1,
256 .avg_weight_rssi_beacon = 20,
257 .avg_weight_rssi_data = 10,
258 .avg_weight_snr_beacon = 20,
259 .avg_weight_snr_data = 10,
260 },
261 .scan = {
262 .min_dwell_time_active = 7500,
263 .max_dwell_time_active = 30000,
264 .min_dwell_time_passive = 100000,
265 .max_dwell_time_passive = 100000,
266 .num_probe_reqs = 2,
267 .split_scan_timeout = 50000,
268 },
269 .sched_scan = {
270 /*
271 * Values are in TU/1000 but since sched scan FW command
272 * params are in TUs rounding up may occur.
273 */
274 .base_dwell_time = 7500,
275 .max_dwell_time_delta = 22500,
276 /* based on 250bits per probe @1Mbps */
277 .dwell_time_delta_per_probe = 2000,
278 /* based on 250bits per probe @6Mbps (plus a bit more) */
279 .dwell_time_delta_per_probe_5 = 350,
280 .dwell_time_passive = 100000,
281 .dwell_time_dfs = 150000,
282 .num_probe_reqs = 2,
283 .rssi_threshold = -90,
284 .snr_threshold = 0,
285 },
e87288f0
LC
286 .ht = {
287 .rx_ba_win_size = 8,
288 .tx_ba_win_size = 64,
289 .inactivity_timeout = 10000,
290 .tx_ba_tid_bitmap = CONF_TX_BA_ENABLED_TID_BITMAP,
291 },
5453dc10
LC
292 /*
293 * Memory config for wl127x chips is given in the
294 * wl12xx_default_priv_conf struct. The below configuration is
295 * for wl128x chips.
296 */
297 .mem = {
e87288f0
LC
298 .num_stations = 1,
299 .ssid_profiles = 1,
300 .rx_block_num = 40,
301 .tx_min_block_num = 40,
302 .dynamic_memory = 1,
303 .min_req_tx_blocks = 45,
304 .min_req_rx_blocks = 22,
305 .tx_min = 27,
306 },
307 .fm_coex = {
308 .enable = true,
309 .swallow_period = 5,
310 .n_divider_fref_set_1 = 0xff, /* default */
311 .n_divider_fref_set_2 = 12,
312 .m_divider_fref_set_1 = 148,
313 .m_divider_fref_set_2 = 0xffff, /* default */
314 .coex_pll_stabilization_time = 0xffffffff, /* default */
315 .ldo_stabilization_time = 0xffff, /* default */
316 .fm_disturbed_band_margin = 0xff, /* default */
317 .swallow_clk_diff = 0xff, /* default */
318 },
319 .rx_streaming = {
320 .duration = 150,
321 .queues = 0x1,
322 .interval = 20,
323 .always = 0,
324 },
325 .fwlog = {
326 .mode = WL12XX_FWLOG_ON_DEMAND,
327 .mem_blocks = 2,
328 .severity = 0,
329 .timestamp = WL12XX_FWLOG_TIMESTAMP_DISABLED,
330 .output = WL12XX_FWLOG_OUTPUT_HOST,
331 .threshold = 0,
332 },
333 .rate = {
334 .rate_retry_score = 32000,
335 .per_add = 8192,
336 .per_th1 = 2048,
337 .per_th2 = 4096,
338 .max_per = 8100,
339 .inverse_curiosity_factor = 5,
340 .tx_fail_low_th = 4,
341 .tx_fail_high_th = 10,
342 .per_alpha_shift = 4,
343 .per_add_shift = 13,
344 .per_beta1_shift = 10,
345 .per_beta2_shift = 8,
346 .rate_check_up = 2,
347 .rate_check_down = 12,
348 .rate_retry_policy = {
349 0x00, 0x00, 0x00, 0x00, 0x00,
350 0x00, 0x00, 0x00, 0x00, 0x00,
351 0x00, 0x00, 0x00,
352 },
353 },
354 .hangover = {
355 .recover_time = 0,
356 .hangover_period = 20,
357 .dynamic_mode = 1,
358 .early_termination_mode = 1,
359 .max_period = 20,
360 .min_period = 1,
361 .increase_delta = 1,
362 .decrease_delta = 2,
363 .quiet_time = 4,
364 .increase_time = 1,
365 .window_size = 16,
366 },
367};
368
5453dc10
LC
369static struct wl12xx_priv_conf wl12xx_default_priv_conf = {
370 .rf = {
371 .tx_per_channel_power_compensation_2 = {
372 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
373 },
374 .tx_per_channel_power_compensation_5 = {
375 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
376 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
377 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
378 },
379 },
380 .mem_wl127x = {
381 .num_stations = 1,
382 .ssid_profiles = 1,
383 .rx_block_num = 70,
384 .tx_min_block_num = 40,
385 .dynamic_memory = 1,
386 .min_req_tx_blocks = 100,
387 .min_req_rx_blocks = 22,
388 .tx_min = 27,
389 },
390
391};
e87288f0 392
3edab305
AN
393#define WL12XX_TX_HW_BLOCK_SPARE_DEFAULT 1
394#define WL12XX_TX_HW_BLOCK_GEM_SPARE 2
b3b4b4b8 395#define WL12XX_TX_HW_BLOCK_SIZE 252
3edab305 396
43a8bc5a
AN
397static const u8 wl12xx_rate_to_idx_2ghz[] = {
398 /* MCS rates are used only with 11n */
399 7, /* WL12XX_CONF_HW_RXTX_RATE_MCS7_SGI */
400 7, /* WL12XX_CONF_HW_RXTX_RATE_MCS7 */
401 6, /* WL12XX_CONF_HW_RXTX_RATE_MCS6 */
402 5, /* WL12XX_CONF_HW_RXTX_RATE_MCS5 */
403 4, /* WL12XX_CONF_HW_RXTX_RATE_MCS4 */
404 3, /* WL12XX_CONF_HW_RXTX_RATE_MCS3 */
405 2, /* WL12XX_CONF_HW_RXTX_RATE_MCS2 */
406 1, /* WL12XX_CONF_HW_RXTX_RATE_MCS1 */
407 0, /* WL12XX_CONF_HW_RXTX_RATE_MCS0 */
408
409 11, /* WL12XX_CONF_HW_RXTX_RATE_54 */
410 10, /* WL12XX_CONF_HW_RXTX_RATE_48 */
411 9, /* WL12XX_CONF_HW_RXTX_RATE_36 */
412 8, /* WL12XX_CONF_HW_RXTX_RATE_24 */
413
414 /* TI-specific rate */
415 CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL12XX_CONF_HW_RXTX_RATE_22 */
416
417 7, /* WL12XX_CONF_HW_RXTX_RATE_18 */
418 6, /* WL12XX_CONF_HW_RXTX_RATE_12 */
419 3, /* WL12XX_CONF_HW_RXTX_RATE_11 */
420 5, /* WL12XX_CONF_HW_RXTX_RATE_9 */
421 4, /* WL12XX_CONF_HW_RXTX_RATE_6 */
422 2, /* WL12XX_CONF_HW_RXTX_RATE_5_5 */
423 1, /* WL12XX_CONF_HW_RXTX_RATE_2 */
424 0 /* WL12XX_CONF_HW_RXTX_RATE_1 */
425};
426
427static const u8 wl12xx_rate_to_idx_5ghz[] = {
428 /* MCS rates are used only with 11n */
429 7, /* WL12XX_CONF_HW_RXTX_RATE_MCS7_SGI */
430 7, /* WL12XX_CONF_HW_RXTX_RATE_MCS7 */
431 6, /* WL12XX_CONF_HW_RXTX_RATE_MCS6 */
432 5, /* WL12XX_CONF_HW_RXTX_RATE_MCS5 */
433 4, /* WL12XX_CONF_HW_RXTX_RATE_MCS4 */
434 3, /* WL12XX_CONF_HW_RXTX_RATE_MCS3 */
435 2, /* WL12XX_CONF_HW_RXTX_RATE_MCS2 */
436 1, /* WL12XX_CONF_HW_RXTX_RATE_MCS1 */
437 0, /* WL12XX_CONF_HW_RXTX_RATE_MCS0 */
438
439 7, /* WL12XX_CONF_HW_RXTX_RATE_54 */
440 6, /* WL12XX_CONF_HW_RXTX_RATE_48 */
441 5, /* WL12XX_CONF_HW_RXTX_RATE_36 */
442 4, /* WL12XX_CONF_HW_RXTX_RATE_24 */
443
444 /* TI-specific rate */
445 CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL12XX_CONF_HW_RXTX_RATE_22 */
446
447 3, /* WL12XX_CONF_HW_RXTX_RATE_18 */
448 2, /* WL12XX_CONF_HW_RXTX_RATE_12 */
449 CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL12XX_CONF_HW_RXTX_RATE_11 */
450 1, /* WL12XX_CONF_HW_RXTX_RATE_9 */
451 0, /* WL12XX_CONF_HW_RXTX_RATE_6 */
452 CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL12XX_CONF_HW_RXTX_RATE_5_5 */
453 CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL12XX_CONF_HW_RXTX_RATE_2 */
454 CONF_HW_RXTX_RATE_UNSUPPORTED /* WL12XX_CONF_HW_RXTX_RATE_1 */
455};
456
457static const u8 *wl12xx_band_rate_to_idx[] = {
458 [IEEE80211_BAND_2GHZ] = wl12xx_rate_to_idx_2ghz,
459 [IEEE80211_BAND_5GHZ] = wl12xx_rate_to_idx_5ghz
460};
461
462enum wl12xx_hw_rates {
463 WL12XX_CONF_HW_RXTX_RATE_MCS7_SGI = 0,
464 WL12XX_CONF_HW_RXTX_RATE_MCS7,
465 WL12XX_CONF_HW_RXTX_RATE_MCS6,
466 WL12XX_CONF_HW_RXTX_RATE_MCS5,
467 WL12XX_CONF_HW_RXTX_RATE_MCS4,
468 WL12XX_CONF_HW_RXTX_RATE_MCS3,
469 WL12XX_CONF_HW_RXTX_RATE_MCS2,
470 WL12XX_CONF_HW_RXTX_RATE_MCS1,
471 WL12XX_CONF_HW_RXTX_RATE_MCS0,
472 WL12XX_CONF_HW_RXTX_RATE_54,
473 WL12XX_CONF_HW_RXTX_RATE_48,
474 WL12XX_CONF_HW_RXTX_RATE_36,
475 WL12XX_CONF_HW_RXTX_RATE_24,
476 WL12XX_CONF_HW_RXTX_RATE_22,
477 WL12XX_CONF_HW_RXTX_RATE_18,
478 WL12XX_CONF_HW_RXTX_RATE_12,
479 WL12XX_CONF_HW_RXTX_RATE_11,
480 WL12XX_CONF_HW_RXTX_RATE_9,
481 WL12XX_CONF_HW_RXTX_RATE_6,
482 WL12XX_CONF_HW_RXTX_RATE_5_5,
483 WL12XX_CONF_HW_RXTX_RATE_2,
484 WL12XX_CONF_HW_RXTX_RATE_1,
485 WL12XX_CONF_HW_RXTX_RATE_MAX,
486};
3edab305 487
25a43d78
LC
488static struct wlcore_partition_set wl12xx_ptable[PART_TABLE_LEN] = {
489 [PART_DOWN] = {
490 .mem = {
491 .start = 0x00000000,
492 .size = 0x000177c0
493 },
494 .reg = {
495 .start = REGISTERS_BASE,
496 .size = 0x00008800
497 },
498 .mem2 = {
499 .start = 0x00000000,
500 .size = 0x00000000
501 },
502 .mem3 = {
503 .start = 0x00000000,
504 .size = 0x00000000
505 },
506 },
507
00782136
LC
508 [PART_BOOT] = { /* in wl12xx we can use a mix of work and down
509 * partition here */
510 .mem = {
511 .start = 0x00040000,
512 .size = 0x00014fc0
513 },
514 .reg = {
515 .start = REGISTERS_BASE,
516 .size = 0x00008800
517 },
518 .mem2 = {
519 .start = 0x00000000,
520 .size = 0x00000000
521 },
522 .mem3 = {
523 .start = 0x00000000,
524 .size = 0x00000000
525 },
526 },
527
25a43d78
LC
528 [PART_WORK] = {
529 .mem = {
530 .start = 0x00040000,
531 .size = 0x00014fc0
532 },
533 .reg = {
534 .start = REGISTERS_BASE,
535 .size = 0x0000a000
536 },
537 .mem2 = {
538 .start = 0x003004f8,
539 .size = 0x00000004
540 },
541 .mem3 = {
542 .start = 0x00040404,
543 .size = 0x00000000
544 },
545 },
546
547 [PART_DRPW] = {
548 .mem = {
549 .start = 0x00040000,
550 .size = 0x00014fc0
551 },
552 .reg = {
553 .start = DRPW_BASE,
554 .size = 0x00006000
555 },
556 .mem2 = {
557 .start = 0x00000000,
558 .size = 0x00000000
559 },
560 .mem3 = {
561 .start = 0x00000000,
562 .size = 0x00000000
563 }
564 }
565};
566
00782136
LC
567static const int wl12xx_rtable[REG_TABLE_LEN] = {
568 [REG_ECPU_CONTROL] = WL12XX_REG_ECPU_CONTROL,
569 [REG_INTERRUPT_NO_CLEAR] = WL12XX_REG_INTERRUPT_NO_CLEAR,
570 [REG_INTERRUPT_ACK] = WL12XX_REG_INTERRUPT_ACK,
571 [REG_COMMAND_MAILBOX_PTR] = WL12XX_REG_COMMAND_MAILBOX_PTR,
572 [REG_EVENT_MAILBOX_PTR] = WL12XX_REG_EVENT_MAILBOX_PTR,
573 [REG_INTERRUPT_TRIG] = WL12XX_REG_INTERRUPT_TRIG,
574 [REG_INTERRUPT_MASK] = WL12XX_REG_INTERRUPT_MASK,
575 [REG_PC_ON_RECOVERY] = WL12XX_SCR_PAD4,
576 [REG_CHIP_ID_B] = WL12XX_CHIP_ID_B,
577 [REG_CMD_MBOX_ADDRESS] = WL12XX_CMD_MBOX_ADDRESS,
578
579 /* data access memory addresses, used with partition translation */
580 [REG_SLV_MEM_DATA] = WL1271_SLV_MEM_DATA,
581 [REG_SLV_REG_DATA] = WL1271_SLV_REG_DATA,
582
583 /* raw data access memory addresses */
584 [REG_RAW_FW_STATUS_ADDR] = FW_STATUS_ADDR,
585};
586
6f7dd16c
LC
587/* TODO: maybe move to a new header file? */
588#define WL127X_FW_NAME_MULTI "ti-connectivity/wl127x-fw-4-mr.bin"
589#define WL127X_FW_NAME_SINGLE "ti-connectivity/wl127x-fw-4-sr.bin"
590#define WL127X_PLT_FW_NAME "ti-connectivity/wl127x-fw-4-plt.bin"
591
592#define WL128X_FW_NAME_MULTI "ti-connectivity/wl128x-fw-4-mr.bin"
593#define WL128X_FW_NAME_SINGLE "ti-connectivity/wl128x-fw-4-sr.bin"
594#define WL128X_PLT_FW_NAME "ti-connectivity/wl128x-fw-4-plt.bin"
595
b14684a0
LC
596static void wl127x_prepare_read(struct wl1271 *wl, u32 rx_desc, u32 len)
597{
598 if (wl->chip.id != CHIP_ID_1283_PG20) {
599 struct wl1271_acx_mem_map *wl_mem_map = wl->target_mem_map;
4b4887e9 600 struct wl127x_rx_mem_pool_addr rx_mem_addr;
b14684a0
LC
601
602 /*
603 * Choose the block we want to read
604 * For aggregated packets, only the first memory block
605 * should be retrieved. The FW takes care of the rest.
606 */
607 u32 mem_block = rx_desc & RX_MEM_BLOCK_MASK;
608
609 rx_mem_addr.addr = (mem_block << 8) +
610 le32_to_cpu(wl_mem_map->packet_memory_pool_start);
611
612 rx_mem_addr.addr_extra = rx_mem_addr.addr + 4;
613
614 wl1271_write(wl, WL1271_SLV_REG_DATA,
615 &rx_mem_addr, sizeof(rx_mem_addr), false);
616 }
617}
618
6f7dd16c
LC
619static int wl12xx_identify_chip(struct wl1271 *wl)
620{
621 int ret = 0;
622
623 switch (wl->chip.id) {
624 case CHIP_ID_1271_PG10:
625 wl1271_warning("chip id 0x%x (1271 PG10) support is obsolete",
626 wl->chip.id);
627
f83985bb 628 wl->quirks |= WLCORE_QUIRK_LEGACY_NVS;
6f7dd16c
LC
629 wl->sr_fw_name = WL127X_FW_NAME_SINGLE;
630 wl->mr_fw_name = WL127X_FW_NAME_MULTI;
5453dc10
LC
631 memcpy(&wl->conf.mem, &wl12xx_default_priv_conf.mem_wl127x,
632 sizeof(wl->conf.mem));
b14684a0
LC
633
634 /* read data preparation is only needed by wl127x */
635 wl->ops->prepare_read = wl127x_prepare_read;
636
6f7dd16c
LC
637 break;
638
639 case CHIP_ID_1271_PG20:
640 wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)",
641 wl->chip.id);
642
f83985bb 643 wl->quirks |= WLCORE_QUIRK_LEGACY_NVS;
6f7dd16c
LC
644 wl->plt_fw_name = WL127X_PLT_FW_NAME;
645 wl->sr_fw_name = WL127X_FW_NAME_SINGLE;
646 wl->mr_fw_name = WL127X_FW_NAME_MULTI;
5453dc10
LC
647 memcpy(&wl->conf.mem, &wl12xx_default_priv_conf.mem_wl127x,
648 sizeof(wl->conf.mem));
b14684a0
LC
649
650 /* read data preparation is only needed by wl127x */
651 wl->ops->prepare_read = wl127x_prepare_read;
652
6f7dd16c
LC
653 break;
654
655 case CHIP_ID_1283_PG20:
656 wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1283 PG20)",
657 wl->chip.id);
658 wl->plt_fw_name = WL128X_PLT_FW_NAME;
659 wl->sr_fw_name = WL128X_FW_NAME_SINGLE;
660 wl->mr_fw_name = WL128X_FW_NAME_MULTI;
b5d6d9b2
LC
661
662 /* wl128x requires TX blocksize alignment */
663 wl->quirks |= WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN;
664
6f7dd16c
LC
665 break;
666 case CHIP_ID_1283_PG10:
667 default:
668 wl1271_warning("unsupported chip id: 0x%x", wl->chip.id);
669 ret = -ENODEV;
670 goto out;
671 }
672
673out:
674 return ret;
675}
676
dd5512eb
LC
677static void wl12xx_top_reg_write(struct wl1271 *wl, int addr, u16 val)
678{
679 /* write address >> 1 + 0x30000 to OCP_POR_CTR */
680 addr = (addr >> 1) + 0x30000;
681 wl1271_write32(wl, WL12XX_OCP_POR_CTR, addr);
682
683 /* write value to OCP_POR_WDATA */
684 wl1271_write32(wl, WL12XX_OCP_DATA_WRITE, val);
685
686 /* write 1 to OCP_CMD */
687 wl1271_write32(wl, WL12XX_OCP_CMD, OCP_CMD_WRITE);
688}
689
690static u16 wl12xx_top_reg_read(struct wl1271 *wl, int addr)
691{
692 u32 val;
693 int timeout = OCP_CMD_LOOP;
694
695 /* write address >> 1 + 0x30000 to OCP_POR_CTR */
696 addr = (addr >> 1) + 0x30000;
697 wl1271_write32(wl, WL12XX_OCP_POR_CTR, addr);
698
699 /* write 2 to OCP_CMD */
700 wl1271_write32(wl, WL12XX_OCP_CMD, OCP_CMD_READ);
701
702 /* poll for data ready */
703 do {
704 val = wl1271_read32(wl, WL12XX_OCP_DATA_READ);
705 } while (!(val & OCP_READY_MASK) && --timeout);
706
707 if (!timeout) {
708 wl1271_warning("Top register access timed out.");
709 return 0xffff;
710 }
711
712 /* check data status and return if OK */
713 if ((val & OCP_STATUS_MASK) == OCP_STATUS_OK)
714 return val & 0xffff;
715 else {
716 wl1271_warning("Top register access returned error.");
717 return 0xffff;
718 }
719}
720
721static int wl128x_switch_tcxo_to_fref(struct wl1271 *wl)
722{
723 u16 spare_reg;
724
725 /* Mask bits [2] & [8:4] in the sys_clk_cfg register */
726 spare_reg = wl12xx_top_reg_read(wl, WL_SPARE_REG);
727 if (spare_reg == 0xFFFF)
728 return -EFAULT;
729 spare_reg |= (BIT(3) | BIT(5) | BIT(6));
730 wl12xx_top_reg_write(wl, WL_SPARE_REG, spare_reg);
731
732 /* Enable FREF_CLK_REQ & mux MCS and coex PLLs to FREF */
733 wl12xx_top_reg_write(wl, SYS_CLK_CFG_REG,
734 WL_CLK_REQ_TYPE_PG2 | MCS_PLL_CLK_SEL_FREF);
735
736 /* Delay execution for 15msec, to let the HW settle */
737 mdelay(15);
738
739 return 0;
740}
741
742static bool wl128x_is_tcxo_valid(struct wl1271 *wl)
743{
744 u16 tcxo_detection;
745
746 tcxo_detection = wl12xx_top_reg_read(wl, TCXO_CLK_DETECT_REG);
747 if (tcxo_detection & TCXO_DET_FAILED)
748 return false;
749
750 return true;
751}
752
753static bool wl128x_is_fref_valid(struct wl1271 *wl)
754{
755 u16 fref_detection;
756
757 fref_detection = wl12xx_top_reg_read(wl, FREF_CLK_DETECT_REG);
758 if (fref_detection & FREF_CLK_DETECT_FAIL)
759 return false;
760
761 return true;
762}
763
764static int wl128x_manually_configure_mcs_pll(struct wl1271 *wl)
765{
766 wl12xx_top_reg_write(wl, MCS_PLL_M_REG, MCS_PLL_M_REG_VAL);
767 wl12xx_top_reg_write(wl, MCS_PLL_N_REG, MCS_PLL_N_REG_VAL);
768 wl12xx_top_reg_write(wl, MCS_PLL_CONFIG_REG, MCS_PLL_CONFIG_REG_VAL);
769
770 return 0;
771}
772
773static int wl128x_configure_mcs_pll(struct wl1271 *wl, int clk)
774{
775 u16 spare_reg;
776 u16 pll_config;
777 u8 input_freq;
a5d751bb 778 struct wl12xx_priv *priv = wl->priv;
dd5512eb
LC
779
780 /* Mask bits [3:1] in the sys_clk_cfg register */
781 spare_reg = wl12xx_top_reg_read(wl, WL_SPARE_REG);
782 if (spare_reg == 0xFFFF)
783 return -EFAULT;
784 spare_reg |= BIT(2);
785 wl12xx_top_reg_write(wl, WL_SPARE_REG, spare_reg);
786
787 /* Handle special cases of the TCXO clock */
a5d751bb
LC
788 if (priv->tcxo_clock == WL12XX_TCXOCLOCK_16_8 ||
789 priv->tcxo_clock == WL12XX_TCXOCLOCK_33_6)
dd5512eb
LC
790 return wl128x_manually_configure_mcs_pll(wl);
791
792 /* Set the input frequency according to the selected clock source */
793 input_freq = (clk & 1) + 1;
794
795 pll_config = wl12xx_top_reg_read(wl, MCS_PLL_CONFIG_REG);
796 if (pll_config == 0xFFFF)
797 return -EFAULT;
798 pll_config |= (input_freq << MCS_SEL_IN_FREQ_SHIFT);
799 pll_config |= MCS_PLL_ENABLE_HP;
800 wl12xx_top_reg_write(wl, MCS_PLL_CONFIG_REG, pll_config);
801
802 return 0;
803}
804
805/*
806 * WL128x has two clocks input - TCXO and FREF.
807 * TCXO is the main clock of the device, while FREF is used to sync
808 * between the GPS and the cellular modem.
809 * In cases where TCXO is 32.736MHz or 16.368MHz, the FREF will be used
810 * as the WLAN/BT main clock.
811 */
812static int wl128x_boot_clk(struct wl1271 *wl, int *selected_clock)
813{
a5d751bb 814 struct wl12xx_priv *priv = wl->priv;
dd5512eb
LC
815 u16 sys_clk_cfg;
816
817 /* For XTAL-only modes, FREF will be used after switching from TCXO */
a5d751bb
LC
818 if (priv->ref_clock == WL12XX_REFCLOCK_26_XTAL ||
819 priv->ref_clock == WL12XX_REFCLOCK_38_XTAL) {
dd5512eb
LC
820 if (!wl128x_switch_tcxo_to_fref(wl))
821 return -EINVAL;
822 goto fref_clk;
823 }
824
825 /* Query the HW, to determine which clock source we should use */
826 sys_clk_cfg = wl12xx_top_reg_read(wl, SYS_CLK_CFG_REG);
827 if (sys_clk_cfg == 0xFFFF)
828 return -EINVAL;
829 if (sys_clk_cfg & PRCM_CM_EN_MUX_WLAN_FREF)
830 goto fref_clk;
831
832 /* If TCXO is either 32.736MHz or 16.368MHz, switch to FREF */
a5d751bb
LC
833 if (priv->tcxo_clock == WL12XX_TCXOCLOCK_16_368 ||
834 priv->tcxo_clock == WL12XX_TCXOCLOCK_32_736) {
dd5512eb
LC
835 if (!wl128x_switch_tcxo_to_fref(wl))
836 return -EINVAL;
837 goto fref_clk;
838 }
839
840 /* TCXO clock is selected */
841 if (!wl128x_is_tcxo_valid(wl))
842 return -EINVAL;
a5d751bb 843 *selected_clock = priv->tcxo_clock;
dd5512eb
LC
844 goto config_mcs_pll;
845
846fref_clk:
847 /* FREF clock is selected */
848 if (!wl128x_is_fref_valid(wl))
849 return -EINVAL;
a5d751bb 850 *selected_clock = priv->ref_clock;
dd5512eb
LC
851
852config_mcs_pll:
853 return wl128x_configure_mcs_pll(wl, *selected_clock);
854}
855
856static int wl127x_boot_clk(struct wl1271 *wl)
857{
a5d751bb 858 struct wl12xx_priv *priv = wl->priv;
dd5512eb
LC
859 u32 pause;
860 u32 clk;
861
862 if (WL127X_PG_GET_MAJOR(wl->hw_pg_ver) < 3)
863 wl->quirks |= WLCORE_QUIRK_END_OF_TRANSACTION;
864
a5d751bb
LC
865 if (priv->ref_clock == CONF_REF_CLK_19_2_E ||
866 priv->ref_clock == CONF_REF_CLK_38_4_E ||
867 priv->ref_clock == CONF_REF_CLK_38_4_M_XTAL)
dd5512eb
LC
868 /* ref clk: 19.2/38.4/38.4-XTAL */
869 clk = 0x3;
a5d751bb
LC
870 else if (priv->ref_clock == CONF_REF_CLK_26_E ||
871 priv->ref_clock == CONF_REF_CLK_52_E)
dd5512eb
LC
872 /* ref clk: 26/52 */
873 clk = 0x5;
874 else
875 return -EINVAL;
876
a5d751bb 877 if (priv->ref_clock != CONF_REF_CLK_19_2_E) {
dd5512eb
LC
878 u16 val;
879 /* Set clock type (open drain) */
880 val = wl12xx_top_reg_read(wl, OCP_REG_CLK_TYPE);
881 val &= FREF_CLK_TYPE_BITS;
882 wl12xx_top_reg_write(wl, OCP_REG_CLK_TYPE, val);
883
884 /* Set clock pull mode (no pull) */
885 val = wl12xx_top_reg_read(wl, OCP_REG_CLK_PULL);
886 val |= NO_PULL;
887 wl12xx_top_reg_write(wl, OCP_REG_CLK_PULL, val);
888 } else {
889 u16 val;
890 /* Set clock polarity */
891 val = wl12xx_top_reg_read(wl, OCP_REG_CLK_POLARITY);
892 val &= FREF_CLK_POLARITY_BITS;
893 val |= CLK_REQ_OUTN_SEL;
894 wl12xx_top_reg_write(wl, OCP_REG_CLK_POLARITY, val);
895 }
896
897 wl1271_write32(wl, WL12XX_PLL_PARAMETERS, clk);
898
899 pause = wl1271_read32(wl, WL12XX_PLL_PARAMETERS);
900
901 wl1271_debug(DEBUG_BOOT, "pause1 0x%x", pause);
902
903 pause &= ~(WU_COUNTER_PAUSE_VAL);
904 pause |= WU_COUNTER_PAUSE_VAL;
905 wl1271_write32(wl, WL12XX_WU_COUNTER_PAUSE, pause);
906
907 return 0;
908}
909
910static int wl1271_boot_soft_reset(struct wl1271 *wl)
911{
912 unsigned long timeout;
913 u32 boot_data;
914
915 /* perform soft reset */
916 wl1271_write32(wl, WL12XX_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT);
917
918 /* SOFT_RESET is self clearing */
919 timeout = jiffies + usecs_to_jiffies(SOFT_RESET_MAX_TIME);
920 while (1) {
921 boot_data = wl1271_read32(wl, WL12XX_SLV_SOFT_RESET);
922 wl1271_debug(DEBUG_BOOT, "soft reset bootdata 0x%x", boot_data);
923 if ((boot_data & ACX_SLV_SOFT_RESET_BIT) == 0)
924 break;
925
926 if (time_after(jiffies, timeout)) {
927 /* 1.2 check pWhalBus->uSelfClearTime if the
928 * timeout was reached */
929 wl1271_error("soft reset timeout");
930 return -1;
931 }
932
933 udelay(SOFT_RESET_STALL_TIME);
934 }
935
936 /* disable Rx/Tx */
937 wl1271_write32(wl, WL12XX_ENABLE, 0x0);
938
939 /* disable auto calibration on start*/
940 wl1271_write32(wl, WL12XX_SPARE_A2, 0xffff);
941
942 return 0;
943}
944
945static int wl12xx_pre_boot(struct wl1271 *wl)
946{
a5d751bb 947 struct wl12xx_priv *priv = wl->priv;
dd5512eb
LC
948 int ret = 0;
949 u32 clk;
950 int selected_clock = -1;
951
952 if (wl->chip.id == CHIP_ID_1283_PG20) {
953 ret = wl128x_boot_clk(wl, &selected_clock);
954 if (ret < 0)
955 goto out;
956 } else {
957 ret = wl127x_boot_clk(wl);
958 if (ret < 0)
959 goto out;
960 }
961
962 /* Continue the ELP wake up sequence */
963 wl1271_write32(wl, WL12XX_WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL);
964 udelay(500);
965
966 wlcore_set_partition(wl, &wl->ptable[PART_DRPW]);
967
968 /* Read-modify-write DRPW_SCRATCH_START register (see next state)
969 to be used by DRPw FW. The RTRIM value will be added by the FW
970 before taking DRPw out of reset */
971
972 clk = wl1271_read32(wl, WL12XX_DRPW_SCRATCH_START);
973
974 wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk);
975
976 if (wl->chip.id == CHIP_ID_1283_PG20)
977 clk |= ((selected_clock & 0x3) << 1) << 4;
978 else
a5d751bb 979 clk |= (priv->ref_clock << 1) << 4;
dd5512eb
LC
980
981 wl1271_write32(wl, WL12XX_DRPW_SCRATCH_START, clk);
982
983 wlcore_set_partition(wl, &wl->ptable[PART_WORK]);
984
985 /* Disable interrupts */
986 wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
987
988 ret = wl1271_boot_soft_reset(wl);
989 if (ret < 0)
990 goto out;
991
992out:
993 return ret;
994}
995
996static void wl12xx_pre_upload(struct wl1271 *wl)
997{
998 u32 tmp;
999
1000 /* write firmware's last address (ie. it's length) to
1001 * ACX_EEPROMLESS_IND_REG */
1002 wl1271_debug(DEBUG_BOOT, "ACX_EEPROMLESS_IND_REG");
1003
1004 wl1271_write32(wl, WL12XX_EEPROMLESS_IND, WL12XX_EEPROMLESS_IND);
1005
1006 tmp = wlcore_read_reg(wl, REG_CHIP_ID_B);
1007
1008 wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp);
1009
1010 /* 6. read the EEPROM parameters */
1011 tmp = wl1271_read32(wl, WL12XX_SCR_PAD2);
1012
1013 /* WL1271: The reference driver skips steps 7 to 10 (jumps directly
1014 * to upload_fw) */
1015
1016 if (wl->chip.id == CHIP_ID_1283_PG20)
1017 wl12xx_top_reg_write(wl, SDIO_IO_DS, HCI_IO_DS_6MA);
1018}
1019
1020static void wl12xx_enable_interrupts(struct wl1271 *wl)
1021{
1022 u32 polarity;
1023
1024 polarity = wl12xx_top_reg_read(wl, OCP_REG_POLARITY);
1025
1026 /* We use HIGH polarity, so unset the LOW bit */
1027 polarity &= ~POLARITY_LOW;
1028 wl12xx_top_reg_write(wl, OCP_REG_POLARITY, polarity);
1029
1030 wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_ALL_EVENTS_VECTOR);
1031
1032 wlcore_enable_interrupts(wl);
1033 wlcore_write_reg(wl, REG_INTERRUPT_MASK,
1034 WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK));
1035
1036 wl1271_write32(wl, WL12XX_HI_CFG, HI_CFG_DEF_VAL);
1037}
1038
1039static int wl12xx_boot(struct wl1271 *wl)
1040{
1041 int ret;
1042
1043 ret = wl12xx_pre_boot(wl);
1044 if (ret < 0)
1045 goto out;
1046
1047 ret = wlcore_boot_upload_nvs(wl);
1048 if (ret < 0)
1049 goto out;
1050
1051 wl12xx_pre_upload(wl);
1052
1053 ret = wlcore_boot_upload_firmware(wl);
1054 if (ret < 0)
1055 goto out;
1056
1057 ret = wlcore_boot_run_firmware(wl);
1058 if (ret < 0)
1059 goto out;
1060
1061 wl12xx_enable_interrupts(wl);
1062
1063out:
1064 return ret;
1065}
1066
5d10b195
AN
1067static void wl12xx_trigger_cmd(struct wl1271 *wl, int cmd_box_addr,
1068 void *buf, size_t len)
f16ff758 1069{
5d10b195 1070 wl1271_write(wl, cmd_box_addr, buf, len, false);
f16ff758
LC
1071 wlcore_write_reg(wl, REG_INTERRUPT_TRIG, WL12XX_INTR_TRIG_CMD);
1072}
1073
1074static void wl12xx_ack_event(struct wl1271 *wl)
1075{
1076 wlcore_write_reg(wl, REG_INTERRUPT_TRIG, WL12XX_INTR_TRIG_EVENT_ACK);
1077}
1078
b3b4b4b8
AN
1079static u32 wl12xx_calc_tx_blocks(struct wl1271 *wl, u32 len, u32 spare_blks)
1080{
1081 u32 blk_size = WL12XX_TX_HW_BLOCK_SIZE;
1082 u32 align_len = wlcore_calc_packet_alignment(wl, len);
1083
1084 return (align_len + blk_size - 1) / blk_size + spare_blks;
1085}
1086
4a3b97ee
AN
1087static void
1088wl12xx_set_tx_desc_blocks(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc,
1089 u32 blks, u32 spare_blks)
1090{
1091 if (wl->chip.id == CHIP_ID_1283_PG20) {
1092 desc->wl128x_mem.total_mem_blocks = blks;
1093 } else {
1094 desc->wl127x_mem.extra_blocks = spare_blks;
1095 desc->wl127x_mem.total_mem_blocks = blks;
1096 }
1097}
1098
6f266e91
AN
1099static void
1100wl12xx_set_tx_desc_data_len(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc,
1101 struct sk_buff *skb)
1102{
1103 u32 aligned_len = wlcore_calc_packet_alignment(wl, skb->len);
1104
1105 if (wl->chip.id == CHIP_ID_1283_PG20) {
1106 desc->wl128x_mem.extra_bytes = aligned_len - skb->len;
1107 desc->length = cpu_to_le16(aligned_len >> 2);
1108
1109 wl1271_debug(DEBUG_TX,
1110 "tx_fill_hdr: hlid: %d len: %d life: %d mem: %d extra: %d",
1111 desc->hlid,
1112 le16_to_cpu(desc->length),
1113 le16_to_cpu(desc->life_time),
1114 desc->wl128x_mem.total_mem_blocks,
1115 desc->wl128x_mem.extra_bytes);
1116 } else {
1117 /* calculate number of padding bytes */
1118 int pad = aligned_len - skb->len;
1119 desc->tx_attr |=
1120 cpu_to_le16(pad << TX_HW_ATTR_OFST_LAST_WORD_PAD);
1121
1122 /* Store the aligned length in terms of words */
1123 desc->length = cpu_to_le16(aligned_len >> 2);
1124
1125 wl1271_debug(DEBUG_TX,
1126 "tx_fill_hdr: pad: %d hlid: %d len: %d life: %d mem: %d",
1127 pad, desc->hlid,
1128 le16_to_cpu(desc->length),
1129 le16_to_cpu(desc->life_time),
1130 desc->wl127x_mem.total_mem_blocks);
1131 }
1132}
1133
cd70f6a4
AN
1134static enum wl_rx_buf_align
1135wl12xx_get_rx_buf_align(struct wl1271 *wl, u32 rx_desc)
1136{
1137 if (rx_desc & RX_BUF_UNALIGNED_PAYLOAD)
1138 return WLCORE_RX_BUF_UNALIGNED;
1139
1140 return WLCORE_RX_BUF_ALIGNED;
1141}
1142
4158149c
AN
1143static u32 wl12xx_get_rx_packet_len(struct wl1271 *wl, void *rx_data,
1144 u32 data_len)
1145{
1146 struct wl1271_rx_descriptor *desc = rx_data;
1147
1148 /* invalid packet */
1149 if (data_len < sizeof(*desc) ||
1150 data_len < sizeof(*desc) + desc->pad_len)
1151 return 0;
1152
1153 return data_len - sizeof(*desc) - desc->pad_len;
1154}
1155
53d67a50
AN
1156static void wl12xx_tx_delayed_compl(struct wl1271 *wl)
1157{
0afd04e5
AN
1158 if (wl->fw_status_1->tx_results_counter ==
1159 (wl->tx_results_count & 0xff))
53d67a50
AN
1160 return;
1161
1162 wl1271_tx_complete(wl);
1163}
1164
9d68d1ee
LC
1165static int wl12xx_hw_init(struct wl1271 *wl)
1166{
1167 int ret;
1168
1169 if (wl->chip.id == CHIP_ID_1283_PG20) {
1170 u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE;
1171
1172 ret = wl128x_cmd_general_parms(wl);
1173 if (ret < 0)
1174 goto out;
1175 ret = wl128x_cmd_radio_parms(wl);
1176 if (ret < 0)
1177 goto out;
1178
1179 if (wl->quirks & WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN)
1180 /* Enable SDIO padding */
1181 host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK;
1182
1183 /* Must be before wl1271_acx_init_mem_config() */
1184 ret = wl1271_acx_host_if_cfg_bitmap(wl, host_cfg_bitmap);
1185 if (ret < 0)
1186 goto out;
1187 } else {
1188 ret = wl1271_cmd_general_parms(wl);
1189 if (ret < 0)
1190 goto out;
1191 ret = wl1271_cmd_radio_parms(wl);
1192 if (ret < 0)
1193 goto out;
1194 ret = wl1271_cmd_ext_radio_parms(wl);
1195 if (ret < 0)
1196 goto out;
1197 }
1198out:
1199 return ret;
1200}
1201
fa7930af
AN
1202static u32 wl12xx_sta_get_ap_rate_mask(struct wl1271 *wl,
1203 struct wl12xx_vif *wlvif)
1204{
1205 return wlvif->rate_set;
1206}
1207
80cd6610
LC
1208static int wl12xx_identify_fw(struct wl1271 *wl)
1209{
1210 unsigned int *fw_ver = wl->chip.fw_ver;
1211
1212 /* Only new station firmwares support routing fw logs to the host */
1213 if ((fw_ver[FW_VER_IF_TYPE] == FW_VER_IF_TYPE_STA) &&
1214 (fw_ver[FW_VER_MINOR] < FW_VER_MINOR_FWLOG_STA_MIN))
1215 wl->quirks |= WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED;
1216
1217 /* This feature is not yet supported for AP mode */
1218 if (fw_ver[FW_VER_IF_TYPE] == FW_VER_IF_TYPE_AP)
1219 wl->quirks |= WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED;
1220
1221 return 0;
1222}
1223
e87288f0
LC
1224static void wl12xx_conf_init(struct wl1271 *wl)
1225{
5453dc10
LC
1226 struct wl12xx_priv *priv = wl->priv;
1227
e87288f0
LC
1228 /* apply driver default configuration */
1229 memcpy(&wl->conf, &wl12xx_conf, sizeof(wl12xx_conf));
5453dc10
LC
1230
1231 /* apply default private configuration */
1232 memcpy(&priv->conf, &wl12xx_default_priv_conf, sizeof(priv->conf));
e87288f0
LC
1233}
1234
30d9b4a5
LC
1235static bool wl12xx_mac_in_fuse(struct wl1271 *wl)
1236{
1237 bool supported = false;
1238 u8 major, minor;
1239
1240 if (wl->chip.id == CHIP_ID_1283_PG20) {
1241 major = WL128X_PG_GET_MAJOR(wl->hw_pg_ver);
1242 minor = WL128X_PG_GET_MINOR(wl->hw_pg_ver);
1243
1244 /* in wl128x we have the MAC address if the PG is >= (2, 1) */
1245 if (major > 2 || (major == 2 && minor >= 1))
1246 supported = true;
1247 } else {
1248 major = WL127X_PG_GET_MAJOR(wl->hw_pg_ver);
1249 minor = WL127X_PG_GET_MINOR(wl->hw_pg_ver);
1250
1251 /* in wl127x we have the MAC address if the PG is >= (3, 1) */
1252 if (major == 3 && minor >= 1)
1253 supported = true;
1254 }
1255
1256 wl1271_debug(DEBUG_PROBE,
1257 "PG Ver major = %d minor = %d, MAC %s present",
1258 major, minor, supported ? "is" : "is not");
1259
1260 return supported;
1261}
1262
1263static void wl12xx_get_fuse_mac(struct wl1271 *wl)
1264{
1265 u32 mac1, mac2;
1266
1267 wlcore_set_partition(wl, &wl->ptable[PART_DRPW]);
1268
1269 mac1 = wl1271_read32(wl, WL12XX_REG_FUSE_BD_ADDR_1);
1270 mac2 = wl1271_read32(wl, WL12XX_REG_FUSE_BD_ADDR_2);
1271
1272 /* these are the two parts of the BD_ADDR */
1273 wl->fuse_oui_addr = ((mac2 & 0xffff) << 8) +
1274 ((mac1 & 0xff000000) >> 24);
1275 wl->fuse_nic_addr = mac1 & 0xffffff;
1276
1277 wlcore_set_partition(wl, &wl->ptable[PART_DOWN]);
1278}
1279
4ded91ce
LC
1280static s8 wl12xx_get_pg_ver(struct wl1271 *wl)
1281{
1282 u32 die_info;
1283
1284 if (wl->chip.id == CHIP_ID_1283_PG20)
dd5512eb 1285 die_info = wl12xx_top_reg_read(wl, WL128X_REG_FUSE_DATA_2_1);
4ded91ce 1286 else
dd5512eb 1287 die_info = wl12xx_top_reg_read(wl, WL127X_REG_FUSE_DATA_2_1);
4ded91ce
LC
1288
1289 return (s8) (die_info & PG_VER_MASK) >> PG_VER_OFFSET;
1290}
1291
30d9b4a5
LC
1292static void wl12xx_get_mac(struct wl1271 *wl)
1293{
1294 if (wl12xx_mac_in_fuse(wl))
1295 wl12xx_get_fuse_mac(wl);
1296}
1297
2fc28de5
AN
1298static void wl12xx_set_tx_desc_csum(struct wl1271 *wl,
1299 struct wl1271_tx_hw_descr *desc,
1300 struct sk_buff *skb)
1301{
1302 desc->wl12xx_reserved = 0;
1303}
1304
c331b344
LC
1305static int wl12xx_plt_init(struct wl1271 *wl)
1306{
1307 int ret;
1308
1309 ret = wl->ops->boot(wl);
1310 if (ret < 0)
1311 goto out;
1312
1313 ret = wl->ops->hw_init(wl);
1314 if (ret < 0)
1315 goto out_irq_disable;
1316
1317 ret = wl1271_acx_init_mem_config(wl);
1318 if (ret < 0)
1319 goto out_irq_disable;
1320
1321 ret = wl12xx_acx_mem_cfg(wl);
1322 if (ret < 0)
1323 goto out_free_memmap;
1324
1325 /* Enable data path */
1326 ret = wl1271_cmd_data_path(wl, 1);
1327 if (ret < 0)
1328 goto out_free_memmap;
1329
1330 /* Configure for CAM power saving (ie. always active) */
1331 ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM);
1332 if (ret < 0)
1333 goto out_free_memmap;
1334
1335 /* configure PM */
1336 ret = wl1271_acx_pm_config(wl);
1337 if (ret < 0)
1338 goto out_free_memmap;
1339
1340 goto out;
1341
1342out_free_memmap:
1343 kfree(wl->target_mem_map);
1344 wl->target_mem_map = NULL;
1345
1346out_irq_disable:
1347 mutex_unlock(&wl->mutex);
1348 /* Unlocking the mutex in the middle of handling is
1349 inherently unsafe. In this case we deem it safe to do,
1350 because we need to let any possibly pending IRQ out of
1351 the system (and while we are WL1271_STATE_OFF the IRQ
1352 work function will not do anything.) Also, any other
1353 possible concurrent operations will fail due to the
1354 current state, hence the wl1271 struct should be safe. */
1355 wlcore_disable_interrupts(wl);
1356 mutex_lock(&wl->mutex);
1357out:
1358 return ret;
1359}
1360
6f7dd16c 1361static struct wlcore_ops wl12xx_ops = {
4a3b97ee 1362 .identify_chip = wl12xx_identify_chip,
80cd6610 1363 .identify_fw = wl12xx_identify_fw,
4a3b97ee 1364 .boot = wl12xx_boot,
c331b344 1365 .plt_init = wl12xx_plt_init,
4a3b97ee
AN
1366 .trigger_cmd = wl12xx_trigger_cmd,
1367 .ack_event = wl12xx_ack_event,
1368 .calc_tx_blocks = wl12xx_calc_tx_blocks,
1369 .set_tx_desc_blocks = wl12xx_set_tx_desc_blocks,
6f266e91 1370 .set_tx_desc_data_len = wl12xx_set_tx_desc_data_len,
cd70f6a4 1371 .get_rx_buf_align = wl12xx_get_rx_buf_align,
4158149c 1372 .get_rx_packet_len = wl12xx_get_rx_packet_len,
53d67a50
AN
1373 .tx_immediate_compl = NULL,
1374 .tx_delayed_compl = wl12xx_tx_delayed_compl,
9d68d1ee 1375 .hw_init = wl12xx_hw_init,
8a9affc0 1376 .init_vif = NULL,
fa7930af 1377 .sta_get_ap_rate_mask = wl12xx_sta_get_ap_rate_mask,
4a3b97ee
AN
1378 .get_pg_ver = wl12xx_get_pg_ver,
1379 .get_mac = wl12xx_get_mac,
2fc28de5 1380 .set_tx_desc_csum = wl12xx_set_tx_desc_csum,
169da04f 1381 .set_rx_csum = NULL,
ebc7e57d 1382 .ap_get_mimo_wide_rate_mask = NULL,
ad62d81a 1383 .debugfs_init = wl12xx_debugfs_add_files,
6f7dd16c
LC
1384};
1385
4a589a6f
AN
1386static struct ieee80211_sta_ht_cap wl12xx_ht_cap = {
1387 .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 |
1388 (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT),
1389 .ht_supported = true,
1390 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K,
1391 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_8,
1392 .mcs = {
1393 .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
1394 .rx_highest = cpu_to_le16(72),
1395 .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
1396 },
1397};
1398
ffeb501c
LC
1399static int __devinit wl12xx_probe(struct platform_device *pdev)
1400{
a5d751bb 1401 struct wl12xx_platform_data *pdata = pdev->dev.platform_data;
ffeb501c
LC
1402 struct wl1271 *wl;
1403 struct ieee80211_hw *hw;
96e0c683 1404 struct wl12xx_priv *priv;
ffeb501c 1405
96e0c683 1406 hw = wlcore_alloc_hw(sizeof(*priv));
ffeb501c
LC
1407 if (IS_ERR(hw)) {
1408 wl1271_error("can't allocate hw");
1409 return PTR_ERR(hw);
1410 }
1411
1412 wl = hw->priv;
a5d751bb 1413 priv = wl->priv;
c31be25a 1414 wl->ops = &wl12xx_ops;
25a43d78 1415 wl->ptable = wl12xx_ptable;
00782136 1416 wl->rtable = wl12xx_rtable;
72b0624f 1417 wl->num_tx_desc = 16;
0afd04e5 1418 wl->num_rx_desc = 8;
3edab305
AN
1419 wl->normal_tx_spare = WL12XX_TX_HW_BLOCK_SPARE_DEFAULT;
1420 wl->gem_tx_spare = WL12XX_TX_HW_BLOCK_GEM_SPARE;
43a8bc5a
AN
1421 wl->band_rate_to_idx = wl12xx_band_rate_to_idx;
1422 wl->hw_tx_rate_tbl_size = WL12XX_CONF_HW_RXTX_RATE_MAX;
1423 wl->hw_min_ht_rate = WL12XX_CONF_HW_RXTX_RATE_MCS0;
6bac40a6 1424 wl->fw_status_priv_len = 0;
10b1e8a2 1425 wl->stats.fw_stats_len = sizeof(struct wl12xx_acx_statistics);
4a589a6f 1426 memcpy(&wl->ht_cap, &wl12xx_ht_cap, sizeof(wl12xx_ht_cap));
e87288f0 1427 wl12xx_conf_init(wl);
ffeb501c 1428
a5d751bb
LC
1429 if (!fref_param) {
1430 priv->ref_clock = pdata->board_ref_clock;
1431 } else {
1432 if (!strcmp(fref_param, "19.2"))
1433 priv->ref_clock = WL12XX_REFCLOCK_19;
1434 else if (!strcmp(fref_param, "26"))
1435 priv->ref_clock = WL12XX_REFCLOCK_26;
1436 else if (!strcmp(fref_param, "26x"))
1437 priv->ref_clock = WL12XX_REFCLOCK_26_XTAL;
1438 else if (!strcmp(fref_param, "38.4"))
1439 priv->ref_clock = WL12XX_REFCLOCK_38;
1440 else if (!strcmp(fref_param, "38.4x"))
1441 priv->ref_clock = WL12XX_REFCLOCK_38_XTAL;
1442 else if (!strcmp(fref_param, "52"))
1443 priv->ref_clock = WL12XX_REFCLOCK_52;
1444 else
1445 wl1271_error("Invalid fref parameter %s", fref_param);
1446 }
1447
1448 if (!tcxo_param) {
1449 priv->tcxo_clock = pdata->board_tcxo_clock;
1450 } else {
1451 if (!strcmp(tcxo_param, "19.2"))
1452 priv->tcxo_clock = WL12XX_TCXOCLOCK_19_2;
1453 else if (!strcmp(tcxo_param, "26"))
1454 priv->tcxo_clock = WL12XX_TCXOCLOCK_26;
1455 else if (!strcmp(tcxo_param, "38.4"))
1456 priv->tcxo_clock = WL12XX_TCXOCLOCK_38_4;
1457 else if (!strcmp(tcxo_param, "52"))
1458 priv->tcxo_clock = WL12XX_TCXOCLOCK_52;
1459 else if (!strcmp(tcxo_param, "16.368"))
1460 priv->tcxo_clock = WL12XX_TCXOCLOCK_16_368;
1461 else if (!strcmp(tcxo_param, "32.736"))
1462 priv->tcxo_clock = WL12XX_TCXOCLOCK_32_736;
1463 else if (!strcmp(tcxo_param, "16.8"))
1464 priv->tcxo_clock = WL12XX_TCXOCLOCK_16_8;
1465 else if (!strcmp(tcxo_param, "33.6"))
1466 priv->tcxo_clock = WL12XX_TCXOCLOCK_33_6;
1467 else
1468 wl1271_error("Invalid tcxo parameter %s", tcxo_param);
1469 }
1470
ffeb501c
LC
1471 return wlcore_probe(wl, pdev);
1472}
b2ba99ff
LC
1473
1474static const struct platform_device_id wl12xx_id_table[] __devinitconst = {
1475 { "wl12xx", 0 },
1476 { } /* Terminating Entry */
1477};
1478MODULE_DEVICE_TABLE(platform, wl12xx_id_table);
1479
1480static struct platform_driver wl12xx_driver = {
ffeb501c 1481 .probe = wl12xx_probe,
b2ba99ff
LC
1482 .remove = __devexit_p(wlcore_remove),
1483 .id_table = wl12xx_id_table,
1484 .driver = {
1485 .name = "wl12xx_driver",
1486 .owner = THIS_MODULE,
1487 }
1488};
1489
1490static int __init wl12xx_init(void)
1491{
1492 return platform_driver_register(&wl12xx_driver);
1493}
1494module_init(wl12xx_init);
1495
1496static void __exit wl12xx_exit(void)
1497{
1498 platform_driver_unregister(&wl12xx_driver);
1499}
1500module_exit(wl12xx_exit);
1501
a5d751bb
LC
1502module_param_named(fref, fref_param, charp, 0);
1503MODULE_PARM_DESC(fref, "FREF clock: 19.2, 26, 26x, 38.4, 38.4x, 52");
1504
1505module_param_named(tcxo, tcxo_param, charp, 0);
1506MODULE_PARM_DESC(tcxo,
1507 "TCXO clock: 19.2, 26, 38.4, 52, 16.368, 32.736, 16.8, 33.6");
1508
b2ba99ff
LC
1509MODULE_LICENSE("GPL v2");
1510MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
6f7dd16c
LC
1511MODULE_FIRMWARE(WL127X_FW_NAME_SINGLE);
1512MODULE_FIRMWARE(WL127X_FW_NAME_MULTI);
1513MODULE_FIRMWARE(WL127X_PLT_FW_NAME);
1514MODULE_FIRMWARE(WL128X_FW_NAME_SINGLE);
1515MODULE_FIRMWARE(WL128X_FW_NAME_MULTI);
1516MODULE_FIRMWARE(WL128X_PLT_FW_NAME);
This page took 0.190522 seconds and 5 git commands to generate.