]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - android-sdk/kernel-video.git/blob - drivers/net/wireless/ti/wl12xx/main.c
Merge branch 'wl12xx-next' into for-linville
[android-sdk/kernel-video.git] / drivers / net / wireless / ti / wl12xx / main.c
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  */
22 #include <linux/module.h>
23 #include <linux/platform_device.h>
25 #include <linux/err.h>
27 #include <linux/wl12xx.h>
29 #include "../wlcore/wlcore.h"
30 #include "../wlcore/debug.h"
31 #include "../wlcore/io.h"
32 #include "../wlcore/acx.h"
33 #include "../wlcore/tx.h"
34 #include "../wlcore/rx.h"
35 #include "../wlcore/boot.h"
37 #include "wl12xx.h"
38 #include "reg.h"
39 #include "cmd.h"
40 #include "acx.h"
41 #include "scan.h"
42 #include "event.h"
43 #include "debugfs.h"
45 static char *fref_param;
46 static char *tcxo_param;
48 static struct wlcore_conf wl12xx_conf = {
49         .sg = {
50                 .params = {
51                         [CONF_SG_ACL_BT_MASTER_MIN_BR] = 10,
52                         [CONF_SG_ACL_BT_MASTER_MAX_BR] = 180,
53                         [CONF_SG_ACL_BT_SLAVE_MIN_BR] = 10,
54                         [CONF_SG_ACL_BT_SLAVE_MAX_BR] = 180,
55                         [CONF_SG_ACL_BT_MASTER_MIN_EDR] = 10,
56                         [CONF_SG_ACL_BT_MASTER_MAX_EDR] = 80,
57                         [CONF_SG_ACL_BT_SLAVE_MIN_EDR] = 10,
58                         [CONF_SG_ACL_BT_SLAVE_MAX_EDR] = 80,
59                         [CONF_SG_ACL_WLAN_PS_MASTER_BR] = 8,
60                         [CONF_SG_ACL_WLAN_PS_SLAVE_BR] = 8,
61                         [CONF_SG_ACL_WLAN_PS_MASTER_EDR] = 20,
62                         [CONF_SG_ACL_WLAN_PS_SLAVE_EDR] = 20,
63                         [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_BR] = 20,
64                         [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_BR] = 35,
65                         [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_BR] = 16,
66                         [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_BR] = 35,
67                         [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_EDR] = 32,
68                         [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_EDR] = 50,
69                         [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_EDR] = 28,
70                         [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_EDR] = 50,
71                         [CONF_SG_ACL_ACTIVE_SCAN_WLAN_BR] = 10,
72                         [CONF_SG_ACL_ACTIVE_SCAN_WLAN_EDR] = 20,
73                         [CONF_SG_ACL_PASSIVE_SCAN_BT_BR] = 75,
74                         [CONF_SG_ACL_PASSIVE_SCAN_WLAN_BR] = 15,
75                         [CONF_SG_ACL_PASSIVE_SCAN_BT_EDR] = 27,
76                         [CONF_SG_ACL_PASSIVE_SCAN_WLAN_EDR] = 17,
77                         /* active scan params */
78                         [CONF_SG_AUTO_SCAN_PROBE_REQ] = 170,
79                         [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3] = 50,
80                         [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP] = 100,
81                         /* passive scan params */
82                         [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP_BR] = 800,
83                         [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP_EDR] = 200,
84                         [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3] = 200,
85                         /* passive scan in dual antenna params */
86                         [CONF_SG_CONSECUTIVE_HV3_IN_PASSIVE_SCAN] = 0,
87                         [CONF_SG_BCN_HV3_COLLISION_THRESH_IN_PASSIVE_SCAN] = 0,
88                         [CONF_SG_TX_RX_PROTECTION_BWIDTH_IN_PASSIVE_SCAN] = 0,
89                         /* general params */
90                         [CONF_SG_STA_FORCE_PS_IN_BT_SCO] = 1,
91                         [CONF_SG_ANTENNA_CONFIGURATION] = 0,
92                         [CONF_SG_BEACON_MISS_PERCENT] = 60,
93                         [CONF_SG_DHCP_TIME] = 5000,
94                         [CONF_SG_RXT] = 1200,
95                         [CONF_SG_TXT] = 1000,
96                         [CONF_SG_ADAPTIVE_RXT_TXT] = 1,
97                         [CONF_SG_GENERAL_USAGE_BIT_MAP] = 3,
98                         [CONF_SG_HV3_MAX_SERVED] = 6,
99                         [CONF_SG_PS_POLL_TIMEOUT] = 10,
100                         [CONF_SG_UPSD_TIMEOUT] = 10,
101                         [CONF_SG_CONSECUTIVE_CTS_THRESHOLD] = 2,
102                         [CONF_SG_STA_RX_WINDOW_AFTER_DTIM] = 5,
103                         [CONF_SG_STA_CONNECTION_PROTECTION_TIME] = 30,
104                         /* AP params */
105                         [CONF_AP_BEACON_MISS_TX] = 3,
106                         [CONF_AP_RX_WINDOW_AFTER_BEACON] = 10,
107                         [CONF_AP_BEACON_WINDOW_INTERVAL] = 2,
108                         [CONF_AP_CONNECTION_PROTECTION_TIME] = 0,
109                         [CONF_AP_BT_ACL_VAL_BT_SERVE_TIME] = 25,
110                         [CONF_AP_BT_ACL_VAL_WL_SERVE_TIME] = 25,
111                         /* CTS Diluting params */
112                         [CONF_SG_CTS_DILUTED_BAD_RX_PACKETS_TH] = 0,
113                         [CONF_SG_CTS_CHOP_IN_DUAL_ANT_SCO_MASTER] = 0,
114                 },
115                 .state = CONF_SG_PROTECTIVE,
116         },
117         .rx = {
118                 .rx_msdu_life_time           = 512000,
119                 .packet_detection_threshold  = 0,
120                 .ps_poll_timeout             = 15,
121                 .upsd_timeout                = 15,
122                 .rts_threshold               = IEEE80211_MAX_RTS_THRESHOLD,
123                 .rx_cca_threshold            = 0,
124                 .irq_blk_threshold           = 0xFFFF,
125                 .irq_pkt_threshold           = 0,
126                 .irq_timeout                 = 600,
127                 .queue_type                  = CONF_RX_QUEUE_TYPE_LOW_PRIORITY,
128         },
129         .tx = {
130                 .tx_energy_detection         = 0,
131                 .sta_rc_conf                 = {
132                         .enabled_rates       = 0,
133                         .short_retry_limit   = 10,
134                         .long_retry_limit    = 10,
135                         .aflags              = 0,
136                 },
137                 .ac_conf_count               = 4,
138                 .ac_conf                     = {
139                         [CONF_TX_AC_BE] = {
140                                 .ac          = CONF_TX_AC_BE,
141                                 .cw_min      = 15,
142                                 .cw_max      = 63,
143                                 .aifsn       = 3,
144                                 .tx_op_limit = 0,
145                         },
146                         [CONF_TX_AC_BK] = {
147                                 .ac          = CONF_TX_AC_BK,
148                                 .cw_min      = 15,
149                                 .cw_max      = 63,
150                                 .aifsn       = 7,
151                                 .tx_op_limit = 0,
152                         },
153                         [CONF_TX_AC_VI] = {
154                                 .ac          = CONF_TX_AC_VI,
155                                 .cw_min      = 15,
156                                 .cw_max      = 63,
157                                 .aifsn       = CONF_TX_AIFS_PIFS,
158                                 .tx_op_limit = 3008,
159                         },
160                         [CONF_TX_AC_VO] = {
161                                 .ac          = CONF_TX_AC_VO,
162                                 .cw_min      = 15,
163                                 .cw_max      = 63,
164                                 .aifsn       = CONF_TX_AIFS_PIFS,
165                                 .tx_op_limit = 1504,
166                         },
167                 },
168                 .max_tx_retries = 100,
169                 .ap_aging_period = 300,
170                 .tid_conf_count = 4,
171                 .tid_conf = {
172                         [CONF_TX_AC_BE] = {
173                                 .queue_id    = CONF_TX_AC_BE,
174                                 .channel_type = CONF_CHANNEL_TYPE_EDCF,
175                                 .tsid        = CONF_TX_AC_BE,
176                                 .ps_scheme   = CONF_PS_SCHEME_LEGACY,
177                                 .ack_policy  = CONF_ACK_POLICY_LEGACY,
178                                 .apsd_conf   = {0, 0},
179                         },
180                         [CONF_TX_AC_BK] = {
181                                 .queue_id    = CONF_TX_AC_BK,
182                                 .channel_type = CONF_CHANNEL_TYPE_EDCF,
183                                 .tsid        = CONF_TX_AC_BK,
184                                 .ps_scheme   = CONF_PS_SCHEME_LEGACY,
185                                 .ack_policy  = CONF_ACK_POLICY_LEGACY,
186                                 .apsd_conf   = {0, 0},
187                         },
188                         [CONF_TX_AC_VI] = {
189                                 .queue_id    = CONF_TX_AC_VI,
190                                 .channel_type = CONF_CHANNEL_TYPE_EDCF,
191                                 .tsid        = CONF_TX_AC_VI,
192                                 .ps_scheme   = CONF_PS_SCHEME_LEGACY,
193                                 .ack_policy  = CONF_ACK_POLICY_LEGACY,
194                                 .apsd_conf   = {0, 0},
195                         },
196                         [CONF_TX_AC_VO] = {
197                                 .queue_id    = CONF_TX_AC_VO,
198                                 .channel_type = CONF_CHANNEL_TYPE_EDCF,
199                                 .tsid        = CONF_TX_AC_VO,
200                                 .ps_scheme   = CONF_PS_SCHEME_LEGACY,
201                                 .ack_policy  = CONF_ACK_POLICY_LEGACY,
202                                 .apsd_conf   = {0, 0},
203                         },
204                 },
205                 .frag_threshold              = IEEE80211_MAX_FRAG_THRESHOLD,
206                 .tx_compl_timeout            = 700,
207                 .tx_compl_threshold          = 4,
208                 .basic_rate                  = CONF_HW_BIT_RATE_1MBPS,
209                 .basic_rate_5                = CONF_HW_BIT_RATE_6MBPS,
210                 .tmpl_short_retry_limit      = 10,
211                 .tmpl_long_retry_limit       = 10,
212                 .tx_watchdog_timeout         = 5000,
213                 .slow_link_thold             = 3,
214                 .fast_link_thold             = 10,
215         },
216         .conn = {
217                 .wake_up_event               = CONF_WAKE_UP_EVENT_DTIM,
218                 .listen_interval             = 1,
219                 .suspend_wake_up_event       = CONF_WAKE_UP_EVENT_N_DTIM,
220                 .suspend_listen_interval     = 3,
221                 .bcn_filt_mode               = CONF_BCN_FILT_MODE_ENABLED,
222                 .bcn_filt_ie_count           = 3,
223                 .bcn_filt_ie = {
224                         [0] = {
225                                 .ie          = WLAN_EID_CHANNEL_SWITCH,
226                                 .rule        = CONF_BCN_RULE_PASS_ON_APPEARANCE,
227                         },
228                         [1] = {
229                                 .ie          = WLAN_EID_HT_OPERATION,
230                                 .rule        = CONF_BCN_RULE_PASS_ON_CHANGE,
231                         },
232                         [2] = {
233                                 .ie          = WLAN_EID_ERP_INFO,
234                                 .rule        = CONF_BCN_RULE_PASS_ON_CHANGE,
235                         },
236                 },
237                 .synch_fail_thold            = 12,
238                 .bss_lose_timeout            = 400,
239                 .beacon_rx_timeout           = 10000,
240                 .broadcast_timeout           = 20000,
241                 .rx_broadcast_in_ps          = 1,
242                 .ps_poll_threshold           = 10,
243                 .bet_enable                  = CONF_BET_MODE_ENABLE,
244                 .bet_max_consecutive         = 50,
245                 .psm_entry_retries           = 8,
246                 .psm_exit_retries            = 16,
247                 .psm_entry_nullfunc_retries  = 3,
248                 .dynamic_ps_timeout          = 1500,
249                 .forced_ps                   = false,
250                 .keep_alive_interval         = 55000,
251                 .max_listen_interval         = 20,
252                 .sta_sleep_auth              = WL1271_PSM_ILLEGAL,
253         },
254         .itrim = {
255                 .enable = false,
256                 .timeout = 50000,
257         },
258         .pm_config = {
259                 .host_clk_settling_time = 5000,
260                 .host_fast_wakeup_support = CONF_FAST_WAKEUP_DISABLE,
261         },
262         .roam_trigger = {
263                 .trigger_pacing               = 1,
264                 .avg_weight_rssi_beacon       = 20,
265                 .avg_weight_rssi_data         = 10,
266                 .avg_weight_snr_beacon        = 20,
267                 .avg_weight_snr_data          = 10,
268         },
269         .scan = {
270                 .min_dwell_time_active        = 7500,
271                 .max_dwell_time_active        = 30000,
272                 .min_dwell_time_active_long   = 25000,
273                 .max_dwell_time_active_long   = 50000,
274                 .dwell_time_passive           = 100000,
275                 .dwell_time_dfs               = 150000,
276                 .num_probe_reqs               = 2,
277                 .split_scan_timeout           = 50000,
278         },
279         .sched_scan = {
280                 /*
281                  * Values are in TU/1000 but since sched scan FW command
282                  * params are in TUs rounding up may occur.
283                  */
284                 .base_dwell_time                = 7500,
285                 .max_dwell_time_delta           = 22500,
286                 /* based on 250bits per probe @1Mbps */
287                 .dwell_time_delta_per_probe     = 2000,
288                 /* based on 250bits per probe @6Mbps (plus a bit more) */
289                 .dwell_time_delta_per_probe_5   = 350,
290                 .dwell_time_passive             = 100000,
291                 .dwell_time_dfs                 = 150000,
292                 .num_probe_reqs                 = 2,
293                 .rssi_threshold                 = -90,
294                 .snr_threshold                  = 0,
295         },
296         .ht = {
297                 .rx_ba_win_size = 8,
298                 .tx_ba_win_size = 64,
299                 .inactivity_timeout = 10000,
300                 .tx_ba_tid_bitmap = CONF_TX_BA_ENABLED_TID_BITMAP,
301         },
302         /*
303          * Memory config for wl127x chips is given in the
304          * wl12xx_default_priv_conf struct. The below configuration is
305          * for wl128x chips.
306          */
307         .mem = {
308                 .num_stations                 = 1,
309                 .ssid_profiles                = 1,
310                 .rx_block_num                 = 40,
311                 .tx_min_block_num             = 40,
312                 .dynamic_memory               = 1,
313                 .min_req_tx_blocks            = 45,
314                 .min_req_rx_blocks            = 22,
315                 .tx_min                       = 27,
316         },
317         .fm_coex = {
318                 .enable                       = true,
319                 .swallow_period               = 5,
320                 .n_divider_fref_set_1         = 0xff,       /* default */
321                 .n_divider_fref_set_2         = 12,
322                 .m_divider_fref_set_1         = 0xffff,
323                 .m_divider_fref_set_2         = 148,        /* default */
324                 .coex_pll_stabilization_time  = 0xffffffff, /* default */
325                 .ldo_stabilization_time       = 0xffff,     /* default */
326                 .fm_disturbed_band_margin     = 0xff,       /* default */
327                 .swallow_clk_diff             = 0xff,       /* default */
328         },
329         .rx_streaming = {
330                 .duration                      = 150,
331                 .queues                        = 0x1,
332                 .interval                      = 20,
333                 .always                        = 0,
334         },
335         .fwlog = {
336                 .mode                         = WL12XX_FWLOG_ON_DEMAND,
337                 .mem_blocks                   = 2,
338                 .severity                     = 0,
339                 .timestamp                    = WL12XX_FWLOG_TIMESTAMP_DISABLED,
340                 .output                       = WL12XX_FWLOG_OUTPUT_HOST,
341                 .threshold                    = 0,
342         },
343         .rate = {
344                 .rate_retry_score = 32000,
345                 .per_add = 8192,
346                 .per_th1 = 2048,
347                 .per_th2 = 4096,
348                 .max_per = 8100,
349                 .inverse_curiosity_factor = 5,
350                 .tx_fail_low_th = 4,
351                 .tx_fail_high_th = 10,
352                 .per_alpha_shift = 4,
353                 .per_add_shift = 13,
354                 .per_beta1_shift = 10,
355                 .per_beta2_shift = 8,
356                 .rate_check_up = 2,
357                 .rate_check_down = 12,
358                 .rate_retry_policy = {
359                         0x00, 0x00, 0x00, 0x00, 0x00,
360                         0x00, 0x00, 0x00, 0x00, 0x00,
361                         0x00, 0x00, 0x00,
362                 },
363         },
364         .hangover = {
365                 .recover_time               = 0,
366                 .hangover_period            = 20,
367                 .dynamic_mode               = 1,
368                 .early_termination_mode     = 1,
369                 .max_period                 = 20,
370                 .min_period                 = 1,
371                 .increase_delta             = 1,
372                 .decrease_delta             = 2,
373                 .quiet_time                 = 4,
374                 .increase_time              = 1,
375                 .window_size                = 16,
376         },
377         .recovery = {
378                 .bug_on_recovery            = 0,
379                 .no_recovery                = 0,
380         },
381 };
383 static struct wl12xx_priv_conf wl12xx_default_priv_conf = {
384         .rf = {
385                 .tx_per_channel_power_compensation_2 = {
386                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
387                 },
388                 .tx_per_channel_power_compensation_5 = {
389                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
390                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
391                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
392                 },
393         },
394         .mem_wl127x = {
395                 .num_stations                 = 1,
396                 .ssid_profiles                = 1,
397                 .rx_block_num                 = 70,
398                 .tx_min_block_num             = 40,
399                 .dynamic_memory               = 1,
400                 .min_req_tx_blocks            = 100,
401                 .min_req_rx_blocks            = 22,
402                 .tx_min                       = 27,
403         },
405 };
407 #define WL12XX_TX_HW_BLOCK_SPARE_DEFAULT        1
408 #define WL12XX_TX_HW_BLOCK_GEM_SPARE            2
409 #define WL12XX_TX_HW_BLOCK_SIZE                 252
411 static const u8 wl12xx_rate_to_idx_2ghz[] = {
412         /* MCS rates are used only with 11n */
413         7,                             /* WL12XX_CONF_HW_RXTX_RATE_MCS7_SGI */
414         7,                             /* WL12XX_CONF_HW_RXTX_RATE_MCS7 */
415         6,                             /* WL12XX_CONF_HW_RXTX_RATE_MCS6 */
416         5,                             /* WL12XX_CONF_HW_RXTX_RATE_MCS5 */
417         4,                             /* WL12XX_CONF_HW_RXTX_RATE_MCS4 */
418         3,                             /* WL12XX_CONF_HW_RXTX_RATE_MCS3 */
419         2,                             /* WL12XX_CONF_HW_RXTX_RATE_MCS2 */
420         1,                             /* WL12XX_CONF_HW_RXTX_RATE_MCS1 */
421         0,                             /* WL12XX_CONF_HW_RXTX_RATE_MCS0 */
423         11,                            /* WL12XX_CONF_HW_RXTX_RATE_54   */
424         10,                            /* WL12XX_CONF_HW_RXTX_RATE_48   */
425         9,                             /* WL12XX_CONF_HW_RXTX_RATE_36   */
426         8,                             /* WL12XX_CONF_HW_RXTX_RATE_24   */
428         /* TI-specific rate */
429         CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL12XX_CONF_HW_RXTX_RATE_22   */
431         7,                             /* WL12XX_CONF_HW_RXTX_RATE_18   */
432         6,                             /* WL12XX_CONF_HW_RXTX_RATE_12   */
433         3,                             /* WL12XX_CONF_HW_RXTX_RATE_11   */
434         5,                             /* WL12XX_CONF_HW_RXTX_RATE_9    */
435         4,                             /* WL12XX_CONF_HW_RXTX_RATE_6    */
436         2,                             /* WL12XX_CONF_HW_RXTX_RATE_5_5  */
437         1,                             /* WL12XX_CONF_HW_RXTX_RATE_2    */
438         0                              /* WL12XX_CONF_HW_RXTX_RATE_1    */
439 };
441 static const u8 wl12xx_rate_to_idx_5ghz[] = {
442         /* MCS rates are used only with 11n */
443         7,                             /* WL12XX_CONF_HW_RXTX_RATE_MCS7_SGI */
444         7,                             /* WL12XX_CONF_HW_RXTX_RATE_MCS7 */
445         6,                             /* WL12XX_CONF_HW_RXTX_RATE_MCS6 */
446         5,                             /* WL12XX_CONF_HW_RXTX_RATE_MCS5 */
447         4,                             /* WL12XX_CONF_HW_RXTX_RATE_MCS4 */
448         3,                             /* WL12XX_CONF_HW_RXTX_RATE_MCS3 */
449         2,                             /* WL12XX_CONF_HW_RXTX_RATE_MCS2 */
450         1,                             /* WL12XX_CONF_HW_RXTX_RATE_MCS1 */
451         0,                             /* WL12XX_CONF_HW_RXTX_RATE_MCS0 */
453         7,                             /* WL12XX_CONF_HW_RXTX_RATE_54   */
454         6,                             /* WL12XX_CONF_HW_RXTX_RATE_48   */
455         5,                             /* WL12XX_CONF_HW_RXTX_RATE_36   */
456         4,                             /* WL12XX_CONF_HW_RXTX_RATE_24   */
458         /* TI-specific rate */
459         CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL12XX_CONF_HW_RXTX_RATE_22   */
461         3,                             /* WL12XX_CONF_HW_RXTX_RATE_18   */
462         2,                             /* WL12XX_CONF_HW_RXTX_RATE_12   */
463         CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL12XX_CONF_HW_RXTX_RATE_11   */
464         1,                             /* WL12XX_CONF_HW_RXTX_RATE_9    */
465         0,                             /* WL12XX_CONF_HW_RXTX_RATE_6    */
466         CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL12XX_CONF_HW_RXTX_RATE_5_5  */
467         CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL12XX_CONF_HW_RXTX_RATE_2    */
468         CONF_HW_RXTX_RATE_UNSUPPORTED  /* WL12XX_CONF_HW_RXTX_RATE_1    */
469 };
471 static const u8 *wl12xx_band_rate_to_idx[] = {
472         [IEEE80211_BAND_2GHZ] = wl12xx_rate_to_idx_2ghz,
473         [IEEE80211_BAND_5GHZ] = wl12xx_rate_to_idx_5ghz
474 };
476 enum wl12xx_hw_rates {
477         WL12XX_CONF_HW_RXTX_RATE_MCS7_SGI = 0,
478         WL12XX_CONF_HW_RXTX_RATE_MCS7,
479         WL12XX_CONF_HW_RXTX_RATE_MCS6,
480         WL12XX_CONF_HW_RXTX_RATE_MCS5,
481         WL12XX_CONF_HW_RXTX_RATE_MCS4,
482         WL12XX_CONF_HW_RXTX_RATE_MCS3,
483         WL12XX_CONF_HW_RXTX_RATE_MCS2,
484         WL12XX_CONF_HW_RXTX_RATE_MCS1,
485         WL12XX_CONF_HW_RXTX_RATE_MCS0,
486         WL12XX_CONF_HW_RXTX_RATE_54,
487         WL12XX_CONF_HW_RXTX_RATE_48,
488         WL12XX_CONF_HW_RXTX_RATE_36,
489         WL12XX_CONF_HW_RXTX_RATE_24,
490         WL12XX_CONF_HW_RXTX_RATE_22,
491         WL12XX_CONF_HW_RXTX_RATE_18,
492         WL12XX_CONF_HW_RXTX_RATE_12,
493         WL12XX_CONF_HW_RXTX_RATE_11,
494         WL12XX_CONF_HW_RXTX_RATE_9,
495         WL12XX_CONF_HW_RXTX_RATE_6,
496         WL12XX_CONF_HW_RXTX_RATE_5_5,
497         WL12XX_CONF_HW_RXTX_RATE_2,
498         WL12XX_CONF_HW_RXTX_RATE_1,
499         WL12XX_CONF_HW_RXTX_RATE_MAX,
500 };
502 static struct wlcore_partition_set wl12xx_ptable[PART_TABLE_LEN] = {
503         [PART_DOWN] = {
504                 .mem = {
505                         .start = 0x00000000,
506                         .size  = 0x000177c0
507                 },
508                 .reg = {
509                         .start = REGISTERS_BASE,
510                         .size  = 0x00008800
511                 },
512                 .mem2 = {
513                         .start = 0x00000000,
514                         .size  = 0x00000000
515                 },
516                 .mem3 = {
517                         .start = 0x00000000,
518                         .size  = 0x00000000
519                 },
520         },
522         [PART_BOOT] = { /* in wl12xx we can use a mix of work and down
523                          * partition here */
524                 .mem = {
525                         .start = 0x00040000,
526                         .size  = 0x00014fc0
527                 },
528                 .reg = {
529                         .start = REGISTERS_BASE,
530                         .size  = 0x00008800
531                 },
532                 .mem2 = {
533                         .start = 0x00000000,
534                         .size  = 0x00000000
535                 },
536                 .mem3 = {
537                         .start = 0x00000000,
538                         .size  = 0x00000000
539                 },
540         },
542         [PART_WORK] = {
543                 .mem = {
544                         .start = 0x00040000,
545                         .size  = 0x00014fc0
546                 },
547                 .reg = {
548                         .start = REGISTERS_BASE,
549                         .size  = 0x0000a000
550                 },
551                 .mem2 = {
552                         .start = 0x003004f8,
553                         .size  = 0x00000004
554                 },
555                 .mem3 = {
556                         .start = 0x00040404,
557                         .size  = 0x00000000
558                 },
559         },
561         [PART_DRPW] = {
562                 .mem = {
563                         .start = 0x00040000,
564                         .size  = 0x00014fc0
565                 },
566                 .reg = {
567                         .start = DRPW_BASE,
568                         .size  = 0x00006000
569                 },
570                 .mem2 = {
571                         .start = 0x00000000,
572                         .size  = 0x00000000
573                 },
574                 .mem3 = {
575                         .start = 0x00000000,
576                         .size  = 0x00000000
577                 }
578         }
579 };
581 static const int wl12xx_rtable[REG_TABLE_LEN] = {
582         [REG_ECPU_CONTROL]              = WL12XX_REG_ECPU_CONTROL,
583         [REG_INTERRUPT_NO_CLEAR]        = WL12XX_REG_INTERRUPT_NO_CLEAR,
584         [REG_INTERRUPT_ACK]             = WL12XX_REG_INTERRUPT_ACK,
585         [REG_COMMAND_MAILBOX_PTR]       = WL12XX_REG_COMMAND_MAILBOX_PTR,
586         [REG_EVENT_MAILBOX_PTR]         = WL12XX_REG_EVENT_MAILBOX_PTR,
587         [REG_INTERRUPT_TRIG]            = WL12XX_REG_INTERRUPT_TRIG,
588         [REG_INTERRUPT_MASK]            = WL12XX_REG_INTERRUPT_MASK,
589         [REG_PC_ON_RECOVERY]            = WL12XX_SCR_PAD4,
590         [REG_CHIP_ID_B]                 = WL12XX_CHIP_ID_B,
591         [REG_CMD_MBOX_ADDRESS]          = WL12XX_CMD_MBOX_ADDRESS,
593         /* data access memory addresses, used with partition translation */
594         [REG_SLV_MEM_DATA]              = WL1271_SLV_MEM_DATA,
595         [REG_SLV_REG_DATA]              = WL1271_SLV_REG_DATA,
597         /* raw data access memory addresses */
598         [REG_RAW_FW_STATUS_ADDR]        = FW_STATUS_ADDR,
599 };
601 /* TODO: maybe move to a new header file? */
602 #define WL127X_FW_NAME_MULTI    "ti-connectivity/wl127x-fw-5-mr.bin"
603 #define WL127X_FW_NAME_SINGLE   "ti-connectivity/wl127x-fw-5-sr.bin"
604 #define WL127X_PLT_FW_NAME      "ti-connectivity/wl127x-fw-5-plt.bin"
606 #define WL128X_FW_NAME_MULTI    "ti-connectivity/wl128x-fw-5-mr.bin"
607 #define WL128X_FW_NAME_SINGLE   "ti-connectivity/wl128x-fw-5-sr.bin"
608 #define WL128X_PLT_FW_NAME      "ti-connectivity/wl128x-fw-5-plt.bin"
610 static int wl127x_prepare_read(struct wl1271 *wl, u32 rx_desc, u32 len)
612         int ret;
614         if (wl->chip.id != CHIP_ID_128X_PG20) {
615                 struct wl1271_acx_mem_map *wl_mem_map = wl->target_mem_map;
616                 struct wl12xx_priv *priv = wl->priv;
618                 /*
619                  * Choose the block we want to read
620                  * For aggregated packets, only the first memory block
621                  * should be retrieved. The FW takes care of the rest.
622                  */
623                 u32 mem_block = rx_desc & RX_MEM_BLOCK_MASK;
625                 priv->rx_mem_addr->addr = (mem_block << 8) +
626                         le32_to_cpu(wl_mem_map->packet_memory_pool_start);
628                 priv->rx_mem_addr->addr_extra = priv->rx_mem_addr->addr + 4;
630                 ret = wlcore_write(wl, WL1271_SLV_REG_DATA, priv->rx_mem_addr,
631                                    sizeof(*priv->rx_mem_addr), false);
632                 if (ret < 0)
633                         return ret;
634         }
636         return 0;
639 static int wl12xx_identify_chip(struct wl1271 *wl)
641         int ret = 0;
643         switch (wl->chip.id) {
644         case CHIP_ID_127X_PG10:
645                 wl1271_warning("chip id 0x%x (1271 PG10) support is obsolete",
646                                wl->chip.id);
648                 wl->quirks |= WLCORE_QUIRK_LEGACY_NVS |
649                               WLCORE_QUIRK_DUAL_PROBE_TMPL |
650                               WLCORE_QUIRK_TKIP_HEADER_SPACE |
651                               WLCORE_QUIRK_START_STA_FAILS |
652                               WLCORE_QUIRK_AP_ZERO_SESSION_ID;
653                 wl->sr_fw_name = WL127X_FW_NAME_SINGLE;
654                 wl->mr_fw_name = WL127X_FW_NAME_MULTI;
655                 memcpy(&wl->conf.mem, &wl12xx_default_priv_conf.mem_wl127x,
656                        sizeof(wl->conf.mem));
658                 /* read data preparation is only needed by wl127x */
659                 wl->ops->prepare_read = wl127x_prepare_read;
661                 wlcore_set_min_fw_ver(wl, WL127X_CHIP_VER,
662                               WL127X_IFTYPE_SR_VER,  WL127X_MAJOR_SR_VER,
663                               WL127X_SUBTYPE_SR_VER, WL127X_MINOR_SR_VER,
664                               WL127X_IFTYPE_MR_VER,  WL127X_MAJOR_MR_VER,
665                               WL127X_SUBTYPE_MR_VER, WL127X_MINOR_MR_VER);
666                 break;
668         case CHIP_ID_127X_PG20:
669                 wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)",
670                              wl->chip.id);
672                 wl->quirks |= WLCORE_QUIRK_LEGACY_NVS |
673                               WLCORE_QUIRK_DUAL_PROBE_TMPL |
674                               WLCORE_QUIRK_TKIP_HEADER_SPACE |
675                               WLCORE_QUIRK_START_STA_FAILS |
676                               WLCORE_QUIRK_AP_ZERO_SESSION_ID;
677                 wl->plt_fw_name = WL127X_PLT_FW_NAME;
678                 wl->sr_fw_name = WL127X_FW_NAME_SINGLE;
679                 wl->mr_fw_name = WL127X_FW_NAME_MULTI;
680                 memcpy(&wl->conf.mem, &wl12xx_default_priv_conf.mem_wl127x,
681                        sizeof(wl->conf.mem));
683                 /* read data preparation is only needed by wl127x */
684                 wl->ops->prepare_read = wl127x_prepare_read;
686                 wlcore_set_min_fw_ver(wl, WL127X_CHIP_VER,
687                               WL127X_IFTYPE_SR_VER,  WL127X_MAJOR_SR_VER,
688                               WL127X_SUBTYPE_SR_VER, WL127X_MINOR_SR_VER,
689                               WL127X_IFTYPE_MR_VER,  WL127X_MAJOR_MR_VER,
690                               WL127X_SUBTYPE_MR_VER, WL127X_MINOR_MR_VER);
691                 break;
693         case CHIP_ID_128X_PG20:
694                 wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1283 PG20)",
695                              wl->chip.id);
696                 wl->plt_fw_name = WL128X_PLT_FW_NAME;
697                 wl->sr_fw_name = WL128X_FW_NAME_SINGLE;
698                 wl->mr_fw_name = WL128X_FW_NAME_MULTI;
700                 /* wl128x requires TX blocksize alignment */
701                 wl->quirks |= WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN |
702                               WLCORE_QUIRK_DUAL_PROBE_TMPL |
703                               WLCORE_QUIRK_TKIP_HEADER_SPACE |
704                               WLCORE_QUIRK_START_STA_FAILS |
705                               WLCORE_QUIRK_AP_ZERO_SESSION_ID;
707                 wlcore_set_min_fw_ver(wl, WL128X_CHIP_VER,
708                               WL128X_IFTYPE_SR_VER,  WL128X_MAJOR_SR_VER,
709                               WL128X_SUBTYPE_SR_VER, WL128X_MINOR_SR_VER,
710                               WL128X_IFTYPE_MR_VER,  WL128X_MAJOR_MR_VER,
711                               WL128X_SUBTYPE_MR_VER, WL128X_MINOR_MR_VER);
712                 break;
713         case CHIP_ID_128X_PG10:
714         default:
715                 wl1271_warning("unsupported chip id: 0x%x", wl->chip.id);
716                 ret = -ENODEV;
717                 goto out;
718         }
720         /* common settings */
721         wl->scan_templ_id_2_4 = CMD_TEMPL_APP_PROBE_REQ_2_4_LEGACY;
722         wl->scan_templ_id_5 = CMD_TEMPL_APP_PROBE_REQ_5_LEGACY;
723         wl->sched_scan_templ_id_2_4 = CMD_TEMPL_CFG_PROBE_REQ_2_4;
724         wl->sched_scan_templ_id_5 = CMD_TEMPL_CFG_PROBE_REQ_5;
725         wl->max_channels_5 = WL12XX_MAX_CHANNELS_5GHZ;
726 out:
727         return ret;
730 static int __must_check wl12xx_top_reg_write(struct wl1271 *wl, int addr,
731                                              u16 val)
733         int ret;
735         /* write address >> 1 + 0x30000 to OCP_POR_CTR */
736         addr = (addr >> 1) + 0x30000;
737         ret = wlcore_write32(wl, WL12XX_OCP_POR_CTR, addr);
738         if (ret < 0)
739                 goto out;
741         /* write value to OCP_POR_WDATA */
742         ret = wlcore_write32(wl, WL12XX_OCP_DATA_WRITE, val);
743         if (ret < 0)
744                 goto out;
746         /* write 1 to OCP_CMD */
747         ret = wlcore_write32(wl, WL12XX_OCP_CMD, OCP_CMD_WRITE);
748         if (ret < 0)
749                 goto out;
751 out:
752         return ret;
755 static int __must_check wl12xx_top_reg_read(struct wl1271 *wl, int addr,
756                                             u16 *out)
758         u32 val;
759         int timeout = OCP_CMD_LOOP;
760         int ret;
762         /* write address >> 1 + 0x30000 to OCP_POR_CTR */
763         addr = (addr >> 1) + 0x30000;
764         ret = wlcore_write32(wl, WL12XX_OCP_POR_CTR, addr);
765         if (ret < 0)
766                 return ret;
768         /* write 2 to OCP_CMD */
769         ret = wlcore_write32(wl, WL12XX_OCP_CMD, OCP_CMD_READ);
770         if (ret < 0)
771                 return ret;
773         /* poll for data ready */
774         do {
775                 ret = wlcore_read32(wl, WL12XX_OCP_DATA_READ, &val);
776                 if (ret < 0)
777                         return ret;
778         } while (!(val & OCP_READY_MASK) && --timeout);
780         if (!timeout) {
781                 wl1271_warning("Top register access timed out.");
782                 return -ETIMEDOUT;
783         }
785         /* check data status and return if OK */
786         if ((val & OCP_STATUS_MASK) != OCP_STATUS_OK) {
787                 wl1271_warning("Top register access returned error.");
788                 return -EIO;
789         }
791         if (out)
792                 *out = val & 0xffff;
794         return 0;
797 static int wl128x_switch_tcxo_to_fref(struct wl1271 *wl)
799         u16 spare_reg;
800         int ret;
802         /* Mask bits [2] & [8:4] in the sys_clk_cfg register */
803         ret = wl12xx_top_reg_read(wl, WL_SPARE_REG, &spare_reg);
804         if (ret < 0)
805                 return ret;
807         if (spare_reg == 0xFFFF)
808                 return -EFAULT;
809         spare_reg |= (BIT(3) | BIT(5) | BIT(6));
810         ret = wl12xx_top_reg_write(wl, WL_SPARE_REG, spare_reg);
811         if (ret < 0)
812                 return ret;
814         /* Enable FREF_CLK_REQ & mux MCS and coex PLLs to FREF */
815         ret = wl12xx_top_reg_write(wl, SYS_CLK_CFG_REG,
816                                    WL_CLK_REQ_TYPE_PG2 | MCS_PLL_CLK_SEL_FREF);
817         if (ret < 0)
818                 return ret;
820         /* Delay execution for 15msec, to let the HW settle */
821         mdelay(15);
823         return 0;
826 static bool wl128x_is_tcxo_valid(struct wl1271 *wl)
828         u16 tcxo_detection;
829         int ret;
831         ret = wl12xx_top_reg_read(wl, TCXO_CLK_DETECT_REG, &tcxo_detection);
832         if (ret < 0)
833                 return false;
835         if (tcxo_detection & TCXO_DET_FAILED)
836                 return false;
838         return true;
841 static bool wl128x_is_fref_valid(struct wl1271 *wl)
843         u16 fref_detection;
844         int ret;
846         ret = wl12xx_top_reg_read(wl, FREF_CLK_DETECT_REG, &fref_detection);
847         if (ret < 0)
848                 return false;
850         if (fref_detection & FREF_CLK_DETECT_FAIL)
851                 return false;
853         return true;
856 static int wl128x_manually_configure_mcs_pll(struct wl1271 *wl)
858         int ret;
860         ret = wl12xx_top_reg_write(wl, MCS_PLL_M_REG, MCS_PLL_M_REG_VAL);
861         if (ret < 0)
862                 goto out;
864         ret = wl12xx_top_reg_write(wl, MCS_PLL_N_REG, MCS_PLL_N_REG_VAL);
865         if (ret < 0)
866                 goto out;
868         ret = wl12xx_top_reg_write(wl, MCS_PLL_CONFIG_REG,
869                                    MCS_PLL_CONFIG_REG_VAL);
871 out:
872         return ret;
875 static int wl128x_configure_mcs_pll(struct wl1271 *wl, int clk)
877         u16 spare_reg;
878         u16 pll_config;
879         u8 input_freq;
880         struct wl12xx_priv *priv = wl->priv;
881         int ret;
883         /* Mask bits [3:1] in the sys_clk_cfg register */
884         ret = wl12xx_top_reg_read(wl, WL_SPARE_REG, &spare_reg);
885         if (ret < 0)
886                 return ret;
888         if (spare_reg == 0xFFFF)
889                 return -EFAULT;
890         spare_reg |= BIT(2);
891         ret = wl12xx_top_reg_write(wl, WL_SPARE_REG, spare_reg);
892         if (ret < 0)
893                 return ret;
895         /* Handle special cases of the TCXO clock */
896         if (priv->tcxo_clock == WL12XX_TCXOCLOCK_16_8 ||
897             priv->tcxo_clock == WL12XX_TCXOCLOCK_33_6)
898                 return wl128x_manually_configure_mcs_pll(wl);
900         /* Set the input frequency according to the selected clock source */
901         input_freq = (clk & 1) + 1;
903         ret = wl12xx_top_reg_read(wl, MCS_PLL_CONFIG_REG, &pll_config);
904         if (ret < 0)
905                 return ret;
907         if (pll_config == 0xFFFF)
908                 return -EFAULT;
909         pll_config |= (input_freq << MCS_SEL_IN_FREQ_SHIFT);
910         pll_config |= MCS_PLL_ENABLE_HP;
911         ret = wl12xx_top_reg_write(wl, MCS_PLL_CONFIG_REG, pll_config);
913         return ret;
916 /*
917  * WL128x has two clocks input - TCXO and FREF.
918  * TCXO is the main clock of the device, while FREF is used to sync
919  * between the GPS and the cellular modem.
920  * In cases where TCXO is 32.736MHz or 16.368MHz, the FREF will be used
921  * as the WLAN/BT main clock.
922  */
923 static int wl128x_boot_clk(struct wl1271 *wl, int *selected_clock)
925         struct wl12xx_priv *priv = wl->priv;
926         u16 sys_clk_cfg;
927         int ret;
929         /* For XTAL-only modes, FREF will be used after switching from TCXO */
930         if (priv->ref_clock == WL12XX_REFCLOCK_26_XTAL ||
931             priv->ref_clock == WL12XX_REFCLOCK_38_XTAL) {
932                 if (!wl128x_switch_tcxo_to_fref(wl))
933                         return -EINVAL;
934                 goto fref_clk;
935         }
937         /* Query the HW, to determine which clock source we should use */
938         ret = wl12xx_top_reg_read(wl, SYS_CLK_CFG_REG, &sys_clk_cfg);
939         if (ret < 0)
940                 return ret;
942         if (sys_clk_cfg == 0xFFFF)
943                 return -EINVAL;
944         if (sys_clk_cfg & PRCM_CM_EN_MUX_WLAN_FREF)
945                 goto fref_clk;
947         /* If TCXO is either 32.736MHz or 16.368MHz, switch to FREF */
948         if (priv->tcxo_clock == WL12XX_TCXOCLOCK_16_368 ||
949             priv->tcxo_clock == WL12XX_TCXOCLOCK_32_736) {
950                 if (!wl128x_switch_tcxo_to_fref(wl))
951                         return -EINVAL;
952                 goto fref_clk;
953         }
955         /* TCXO clock is selected */
956         if (!wl128x_is_tcxo_valid(wl))
957                 return -EINVAL;
958         *selected_clock = priv->tcxo_clock;
959         goto config_mcs_pll;
961 fref_clk:
962         /* FREF clock is selected */
963         if (!wl128x_is_fref_valid(wl))
964                 return -EINVAL;
965         *selected_clock = priv->ref_clock;
967 config_mcs_pll:
968         return wl128x_configure_mcs_pll(wl, *selected_clock);
971 static int wl127x_boot_clk(struct wl1271 *wl)
973         struct wl12xx_priv *priv = wl->priv;
974         u32 pause;
975         u32 clk;
976         int ret;
978         if (WL127X_PG_GET_MAJOR(wl->hw_pg_ver) < 3)
979                 wl->quirks |= WLCORE_QUIRK_END_OF_TRANSACTION;
981         if (priv->ref_clock == CONF_REF_CLK_19_2_E ||
982             priv->ref_clock == CONF_REF_CLK_38_4_E ||
983             priv->ref_clock == CONF_REF_CLK_38_4_M_XTAL)
984                 /* ref clk: 19.2/38.4/38.4-XTAL */
985                 clk = 0x3;
986         else if (priv->ref_clock == CONF_REF_CLK_26_E ||
987                  priv->ref_clock == CONF_REF_CLK_26_M_XTAL ||
988                  priv->ref_clock == CONF_REF_CLK_52_E)
989                 /* ref clk: 26/52 */
990                 clk = 0x5;
991         else
992                 return -EINVAL;
994         if (priv->ref_clock != CONF_REF_CLK_19_2_E) {
995                 u16 val;
996                 /* Set clock type (open drain) */
997                 ret = wl12xx_top_reg_read(wl, OCP_REG_CLK_TYPE, &val);
998                 if (ret < 0)
999                         goto out;
1001                 val &= FREF_CLK_TYPE_BITS;
1002                 ret = wl12xx_top_reg_write(wl, OCP_REG_CLK_TYPE, val);
1003                 if (ret < 0)
1004                         goto out;
1006                 /* Set clock pull mode (no pull) */
1007                 ret = wl12xx_top_reg_read(wl, OCP_REG_CLK_PULL, &val);
1008                 if (ret < 0)
1009                         goto out;
1011                 val |= NO_PULL;
1012                 ret = wl12xx_top_reg_write(wl, OCP_REG_CLK_PULL, val);
1013                 if (ret < 0)
1014                         goto out;
1015         } else {
1016                 u16 val;
1017                 /* Set clock polarity */
1018                 ret = wl12xx_top_reg_read(wl, OCP_REG_CLK_POLARITY, &val);
1019                 if (ret < 0)
1020                         goto out;
1022                 val &= FREF_CLK_POLARITY_BITS;
1023                 val |= CLK_REQ_OUTN_SEL;
1024                 ret = wl12xx_top_reg_write(wl, OCP_REG_CLK_POLARITY, val);
1025                 if (ret < 0)
1026                         goto out;
1027         }
1029         ret = wlcore_write32(wl, WL12XX_PLL_PARAMETERS, clk);
1030         if (ret < 0)
1031                 goto out;
1033         ret = wlcore_read32(wl, WL12XX_PLL_PARAMETERS, &pause);
1034         if (ret < 0)
1035                 goto out;
1037         wl1271_debug(DEBUG_BOOT, "pause1 0x%x", pause);
1039         pause &= ~(WU_COUNTER_PAUSE_VAL);
1040         pause |= WU_COUNTER_PAUSE_VAL;
1041         ret = wlcore_write32(wl, WL12XX_WU_COUNTER_PAUSE, pause);
1043 out:
1044         return ret;
1047 static int wl1271_boot_soft_reset(struct wl1271 *wl)
1049         unsigned long timeout;
1050         u32 boot_data;
1051         int ret = 0;
1053         /* perform soft reset */
1054         ret = wlcore_write32(wl, WL12XX_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT);
1055         if (ret < 0)
1056                 goto out;
1058         /* SOFT_RESET is self clearing */
1059         timeout = jiffies + usecs_to_jiffies(SOFT_RESET_MAX_TIME);
1060         while (1) {
1061                 ret = wlcore_read32(wl, WL12XX_SLV_SOFT_RESET, &boot_data);
1062                 if (ret < 0)
1063                         goto out;
1065                 wl1271_debug(DEBUG_BOOT, "soft reset bootdata 0x%x", boot_data);
1066                 if ((boot_data & ACX_SLV_SOFT_RESET_BIT) == 0)
1067                         break;
1069                 if (time_after(jiffies, timeout)) {
1070                         /* 1.2 check pWhalBus->uSelfClearTime if the
1071                          * timeout was reached */
1072                         wl1271_error("soft reset timeout");
1073                         return -1;
1074                 }
1076                 udelay(SOFT_RESET_STALL_TIME);
1077         }
1079         /* disable Rx/Tx */
1080         ret = wlcore_write32(wl, WL12XX_ENABLE, 0x0);
1081         if (ret < 0)
1082                 goto out;
1084         /* disable auto calibration on start*/
1085         ret = wlcore_write32(wl, WL12XX_SPARE_A2, 0xffff);
1087 out:
1088         return ret;
1091 static int wl12xx_pre_boot(struct wl1271 *wl)
1093         struct wl12xx_priv *priv = wl->priv;
1094         int ret = 0;
1095         u32 clk;
1096         int selected_clock = -1;
1098         if (wl->chip.id == CHIP_ID_128X_PG20) {
1099                 ret = wl128x_boot_clk(wl, &selected_clock);
1100                 if (ret < 0)
1101                         goto out;
1102         } else {
1103                 ret = wl127x_boot_clk(wl);
1104                 if (ret < 0)
1105                         goto out;
1106         }
1108         /* Continue the ELP wake up sequence */
1109         ret = wlcore_write32(wl, WL12XX_WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL);
1110         if (ret < 0)
1111                 goto out;
1113         udelay(500);
1115         ret = wlcore_set_partition(wl, &wl->ptable[PART_DRPW]);
1116         if (ret < 0)
1117                 goto out;
1119         /* Read-modify-write DRPW_SCRATCH_START register (see next state)
1120            to be used by DRPw FW. The RTRIM value will be added by the FW
1121            before taking DRPw out of reset */
1123         ret = wlcore_read32(wl, WL12XX_DRPW_SCRATCH_START, &clk);
1124         if (ret < 0)
1125                 goto out;
1127         wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk);
1129         if (wl->chip.id == CHIP_ID_128X_PG20)
1130                 clk |= ((selected_clock & 0x3) << 1) << 4;
1131         else
1132                 clk |= (priv->ref_clock << 1) << 4;
1134         ret = wlcore_write32(wl, WL12XX_DRPW_SCRATCH_START, clk);
1135         if (ret < 0)
1136                 goto out;
1138         ret = wlcore_set_partition(wl, &wl->ptable[PART_WORK]);
1139         if (ret < 0)
1140                 goto out;
1142         /* Disable interrupts */
1143         ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
1144         if (ret < 0)
1145                 goto out;
1147         ret = wl1271_boot_soft_reset(wl);
1148         if (ret < 0)
1149                 goto out;
1151 out:
1152         return ret;
1155 static int wl12xx_pre_upload(struct wl1271 *wl)
1157         u32 tmp;
1158         u16 polarity;
1159         int ret;
1161         /* write firmware's last address (ie. it's length) to
1162          * ACX_EEPROMLESS_IND_REG */
1163         wl1271_debug(DEBUG_BOOT, "ACX_EEPROMLESS_IND_REG");
1165         ret = wlcore_write32(wl, WL12XX_EEPROMLESS_IND, WL12XX_EEPROMLESS_IND);
1166         if (ret < 0)
1167                 goto out;
1169         ret = wlcore_read_reg(wl, REG_CHIP_ID_B, &tmp);
1170         if (ret < 0)
1171                 goto out;
1173         wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp);
1175         /* 6. read the EEPROM parameters */
1176         ret = wlcore_read32(wl, WL12XX_SCR_PAD2, &tmp);
1177         if (ret < 0)
1178                 goto out;
1180         /* WL1271: The reference driver skips steps 7 to 10 (jumps directly
1181          * to upload_fw) */
1183         if (wl->chip.id == CHIP_ID_128X_PG20) {
1184                 ret = wl12xx_top_reg_write(wl, SDIO_IO_DS, HCI_IO_DS_6MA);
1185                 if (ret < 0)
1186                         goto out;
1187         }
1189         /* polarity must be set before the firmware is loaded */
1190         ret = wl12xx_top_reg_read(wl, OCP_REG_POLARITY, &polarity);
1191         if (ret < 0)
1192                 goto out;
1194         /* We use HIGH polarity, so unset the LOW bit */
1195         polarity &= ~POLARITY_LOW;
1196         ret = wl12xx_top_reg_write(wl, OCP_REG_POLARITY, polarity);
1198 out:
1199         return ret;
1202 static int wl12xx_enable_interrupts(struct wl1271 *wl)
1204         int ret;
1206         ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK,
1207                                WL12XX_ACX_ALL_EVENTS_VECTOR);
1208         if (ret < 0)
1209                 goto out;
1211         wlcore_enable_interrupts(wl);
1212         ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK,
1213                                WL1271_ACX_INTR_ALL & ~(WL12XX_INTR_MASK));
1214         if (ret < 0)
1215                 goto disable_interrupts;
1217         ret = wlcore_write32(wl, WL12XX_HI_CFG, HI_CFG_DEF_VAL);
1218         if (ret < 0)
1219                 goto disable_interrupts;
1221         return ret;
1223 disable_interrupts:
1224         wlcore_disable_interrupts(wl);
1226 out:
1227         return ret;
1230 static int wl12xx_boot(struct wl1271 *wl)
1232         int ret;
1234         ret = wl12xx_pre_boot(wl);
1235         if (ret < 0)
1236                 goto out;
1238         ret = wlcore_boot_upload_nvs(wl);
1239         if (ret < 0)
1240                 goto out;
1242         ret = wl12xx_pre_upload(wl);
1243         if (ret < 0)
1244                 goto out;
1246         ret = wlcore_boot_upload_firmware(wl);
1247         if (ret < 0)
1248                 goto out;
1250         wl->event_mask = BSS_LOSE_EVENT_ID |
1251                 REGAINED_BSS_EVENT_ID |
1252                 SCAN_COMPLETE_EVENT_ID |
1253                 ROLE_STOP_COMPLETE_EVENT_ID |
1254                 RSSI_SNR_TRIGGER_0_EVENT_ID |
1255                 PSPOLL_DELIVERY_FAILURE_EVENT_ID |
1256                 SOFT_GEMINI_SENSE_EVENT_ID |
1257                 PERIODIC_SCAN_REPORT_EVENT_ID |
1258                 PERIODIC_SCAN_COMPLETE_EVENT_ID |
1259                 DUMMY_PACKET_EVENT_ID |
1260                 PEER_REMOVE_COMPLETE_EVENT_ID |
1261                 BA_SESSION_RX_CONSTRAINT_EVENT_ID |
1262                 REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID |
1263                 INACTIVE_STA_EVENT_ID |
1264                 MAX_TX_RETRY_EVENT_ID |
1265                 CHANNEL_SWITCH_COMPLETE_EVENT_ID;
1267         ret = wlcore_boot_run_firmware(wl);
1268         if (ret < 0)
1269                 goto out;
1271         ret = wl12xx_enable_interrupts(wl);
1273 out:
1274         return ret;
1277 static int wl12xx_trigger_cmd(struct wl1271 *wl, int cmd_box_addr,
1278                                void *buf, size_t len)
1280         int ret;
1282         ret = wlcore_write(wl, cmd_box_addr, buf, len, false);
1283         if (ret < 0)
1284                 return ret;
1286         ret = wlcore_write_reg(wl, REG_INTERRUPT_TRIG, WL12XX_INTR_TRIG_CMD);
1288         return ret;
1291 static int wl12xx_ack_event(struct wl1271 *wl)
1293         return wlcore_write_reg(wl, REG_INTERRUPT_TRIG,
1294                                 WL12XX_INTR_TRIG_EVENT_ACK);
1297 static u32 wl12xx_calc_tx_blocks(struct wl1271 *wl, u32 len, u32 spare_blks)
1299         u32 blk_size = WL12XX_TX_HW_BLOCK_SIZE;
1300         u32 align_len = wlcore_calc_packet_alignment(wl, len);
1302         return (align_len + blk_size - 1) / blk_size + spare_blks;
1305 static void
1306 wl12xx_set_tx_desc_blocks(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc,
1307                           u32 blks, u32 spare_blks)
1309         if (wl->chip.id == CHIP_ID_128X_PG20) {
1310                 desc->wl128x_mem.total_mem_blocks = blks;
1311         } else {
1312                 desc->wl127x_mem.extra_blocks = spare_blks;
1313                 desc->wl127x_mem.total_mem_blocks = blks;
1314         }
1317 static void
1318 wl12xx_set_tx_desc_data_len(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc,
1319                             struct sk_buff *skb)
1321         u32 aligned_len = wlcore_calc_packet_alignment(wl, skb->len);
1323         if (wl->chip.id == CHIP_ID_128X_PG20) {
1324                 desc->wl128x_mem.extra_bytes = aligned_len - skb->len;
1325                 desc->length = cpu_to_le16(aligned_len >> 2);
1327                 wl1271_debug(DEBUG_TX,
1328                              "tx_fill_hdr: hlid: %d len: %d life: %d mem: %d extra: %d",
1329                              desc->hlid,
1330                              le16_to_cpu(desc->length),
1331                              le16_to_cpu(desc->life_time),
1332                              desc->wl128x_mem.total_mem_blocks,
1333                              desc->wl128x_mem.extra_bytes);
1334         } else {
1335                 /* calculate number of padding bytes */
1336                 int pad = aligned_len - skb->len;
1337                 desc->tx_attr |=
1338                         cpu_to_le16(pad << TX_HW_ATTR_OFST_LAST_WORD_PAD);
1340                 /* Store the aligned length in terms of words */
1341                 desc->length = cpu_to_le16(aligned_len >> 2);
1343                 wl1271_debug(DEBUG_TX,
1344                              "tx_fill_hdr: pad: %d hlid: %d len: %d life: %d mem: %d",
1345                              pad, desc->hlid,
1346                              le16_to_cpu(desc->length),
1347                              le16_to_cpu(desc->life_time),
1348                              desc->wl127x_mem.total_mem_blocks);
1349         }
1352 static enum wl_rx_buf_align
1353 wl12xx_get_rx_buf_align(struct wl1271 *wl, u32 rx_desc)
1355         if (rx_desc & RX_BUF_UNALIGNED_PAYLOAD)
1356                 return WLCORE_RX_BUF_UNALIGNED;
1358         return WLCORE_RX_BUF_ALIGNED;
1361 static u32 wl12xx_get_rx_packet_len(struct wl1271 *wl, void *rx_data,
1362                                     u32 data_len)
1364         struct wl1271_rx_descriptor *desc = rx_data;
1366         /* invalid packet */
1367         if (data_len < sizeof(*desc) ||
1368             data_len < sizeof(*desc) + desc->pad_len)
1369                 return 0;
1371         return data_len - sizeof(*desc) - desc->pad_len;
1374 static int wl12xx_tx_delayed_compl(struct wl1271 *wl)
1376         if (wl->fw_status_1->tx_results_counter ==
1377             (wl->tx_results_count & 0xff))
1378                 return 0;
1380         return wlcore_tx_complete(wl);
1383 static int wl12xx_hw_init(struct wl1271 *wl)
1385         int ret;
1387         if (wl->chip.id == CHIP_ID_128X_PG20) {
1388                 u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE;
1390                 ret = wl128x_cmd_general_parms(wl);
1391                 if (ret < 0)
1392                         goto out;
1394                 /*
1395                  * If we are in calibrator based auto detect then we got the FEM nr
1396                  * in wl->fem_manuf. No need to continue further
1397                  */
1398                 if (wl->plt_mode == PLT_FEM_DETECT)
1399                         goto out;
1401                 ret = wl128x_cmd_radio_parms(wl);
1402                 if (ret < 0)
1403                         goto out;
1405                 if (wl->quirks & WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN)
1406                         /* Enable SDIO padding */
1407                         host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK;
1409                 /* Must be before wl1271_acx_init_mem_config() */
1410                 ret = wl1271_acx_host_if_cfg_bitmap(wl, host_cfg_bitmap);
1411                 if (ret < 0)
1412                         goto out;
1413         } else {
1414                 ret = wl1271_cmd_general_parms(wl);
1415                 if (ret < 0)
1416                         goto out;
1418                 /*
1419                  * If we are in calibrator based auto detect then we got the FEM nr
1420                  * in wl->fem_manuf. No need to continue further
1421                  */
1422                 if (wl->plt_mode == PLT_FEM_DETECT)
1423                         goto out;
1425                 ret = wl1271_cmd_radio_parms(wl);
1426                 if (ret < 0)
1427                         goto out;
1428                 ret = wl1271_cmd_ext_radio_parms(wl);
1429                 if (ret < 0)
1430                         goto out;
1431         }
1432 out:
1433         return ret;
1436 static u32 wl12xx_sta_get_ap_rate_mask(struct wl1271 *wl,
1437                                        struct wl12xx_vif *wlvif)
1439         return wlvif->rate_set;
1442 static void wl12xx_conf_init(struct wl1271 *wl)
1444         struct wl12xx_priv *priv = wl->priv;
1446         /* apply driver default configuration */
1447         memcpy(&wl->conf, &wl12xx_conf, sizeof(wl12xx_conf));
1449         /* apply default private configuration */
1450         memcpy(&priv->conf, &wl12xx_default_priv_conf, sizeof(priv->conf));
1453 static bool wl12xx_mac_in_fuse(struct wl1271 *wl)
1455         bool supported = false;
1456         u8 major, minor;
1458         if (wl->chip.id == CHIP_ID_128X_PG20) {
1459                 major = WL128X_PG_GET_MAJOR(wl->hw_pg_ver);
1460                 minor = WL128X_PG_GET_MINOR(wl->hw_pg_ver);
1462                 /* in wl128x we have the MAC address if the PG is >= (2, 1) */
1463                 if (major > 2 || (major == 2 && minor >= 1))
1464                         supported = true;
1465         } else {
1466                 major = WL127X_PG_GET_MAJOR(wl->hw_pg_ver);
1467                 minor = WL127X_PG_GET_MINOR(wl->hw_pg_ver);
1469                 /* in wl127x we have the MAC address if the PG is >= (3, 1) */
1470                 if (major == 3 && minor >= 1)
1471                         supported = true;
1472         }
1474         wl1271_debug(DEBUG_PROBE,
1475                      "PG Ver major = %d minor = %d, MAC %s present",
1476                      major, minor, supported ? "is" : "is not");
1478         return supported;
1481 static int wl12xx_get_fuse_mac(struct wl1271 *wl)
1483         u32 mac1, mac2;
1484         int ret;
1486         ret = wlcore_set_partition(wl, &wl->ptable[PART_DRPW]);
1487         if (ret < 0)
1488                 goto out;
1490         ret = wlcore_read32(wl, WL12XX_REG_FUSE_BD_ADDR_1, &mac1);
1491         if (ret < 0)
1492                 goto out;
1494         ret = wlcore_read32(wl, WL12XX_REG_FUSE_BD_ADDR_2, &mac2);
1495         if (ret < 0)
1496                 goto out;
1498         /* these are the two parts of the BD_ADDR */
1499         wl->fuse_oui_addr = ((mac2 & 0xffff) << 8) +
1500                 ((mac1 & 0xff000000) >> 24);
1501         wl->fuse_nic_addr = mac1 & 0xffffff;
1503         ret = wlcore_set_partition(wl, &wl->ptable[PART_DOWN]);
1505 out:
1506         return ret;
1509 static int wl12xx_get_pg_ver(struct wl1271 *wl, s8 *ver)
1511         u16 die_info;
1512         int ret;
1514         if (wl->chip.id == CHIP_ID_128X_PG20)
1515                 ret = wl12xx_top_reg_read(wl, WL128X_REG_FUSE_DATA_2_1,
1516                                           &die_info);
1517         else
1518                 ret = wl12xx_top_reg_read(wl, WL127X_REG_FUSE_DATA_2_1,
1519                                           &die_info);
1521         if (ret >= 0 && ver)
1522                 *ver = (s8)((die_info & PG_VER_MASK) >> PG_VER_OFFSET);
1524         return ret;
1527 static int wl12xx_get_mac(struct wl1271 *wl)
1529         if (wl12xx_mac_in_fuse(wl))
1530                 return wl12xx_get_fuse_mac(wl);
1532         return 0;
1535 static void wl12xx_set_tx_desc_csum(struct wl1271 *wl,
1536                                     struct wl1271_tx_hw_descr *desc,
1537                                     struct sk_buff *skb)
1539         desc->wl12xx_reserved = 0;
1542 static int wl12xx_plt_init(struct wl1271 *wl)
1544         int ret;
1546         ret = wl->ops->boot(wl);
1547         if (ret < 0)
1548                 goto out;
1550         ret = wl->ops->hw_init(wl);
1551         if (ret < 0)
1552                 goto out_irq_disable;
1554         /*
1555          * If we are in calibrator based auto detect then we got the FEM nr
1556          * in wl->fem_manuf. No need to continue further
1557          */
1558         if (wl->plt_mode == PLT_FEM_DETECT)
1559                 goto out;
1561         ret = wl1271_acx_init_mem_config(wl);
1562         if (ret < 0)
1563                 goto out_irq_disable;
1565         ret = wl12xx_acx_mem_cfg(wl);
1566         if (ret < 0)
1567                 goto out_free_memmap;
1569         /* Enable data path */
1570         ret = wl1271_cmd_data_path(wl, 1);
1571         if (ret < 0)
1572                 goto out_free_memmap;
1574         /* Configure for CAM power saving (ie. always active) */
1575         ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM);
1576         if (ret < 0)
1577                 goto out_free_memmap;
1579         /* configure PM */
1580         ret = wl1271_acx_pm_config(wl);
1581         if (ret < 0)
1582                 goto out_free_memmap;
1584         goto out;
1586 out_free_memmap:
1587         kfree(wl->target_mem_map);
1588         wl->target_mem_map = NULL;
1590 out_irq_disable:
1591         mutex_unlock(&wl->mutex);
1592         /* Unlocking the mutex in the middle of handling is
1593            inherently unsafe. In this case we deem it safe to do,
1594            because we need to let any possibly pending IRQ out of
1595            the system (and while we are WL1271_STATE_OFF the IRQ
1596            work function will not do anything.) Also, any other
1597            possible concurrent operations will fail due to the
1598            current state, hence the wl1271 struct should be safe. */
1599         wlcore_disable_interrupts(wl);
1600         mutex_lock(&wl->mutex);
1601 out:
1602         return ret;
1605 static int wl12xx_get_spare_blocks(struct wl1271 *wl, bool is_gem)
1607         if (is_gem)
1608                 return WL12XX_TX_HW_BLOCK_GEM_SPARE;
1610         return WL12XX_TX_HW_BLOCK_SPARE_DEFAULT;
1613 static int wl12xx_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
1614                           struct ieee80211_vif *vif,
1615                           struct ieee80211_sta *sta,
1616                           struct ieee80211_key_conf *key_conf)
1618         return wlcore_set_key(wl, cmd, vif, sta, key_conf);
1621 static int wl12xx_set_peer_cap(struct wl1271 *wl,
1622                                struct ieee80211_sta_ht_cap *ht_cap,
1623                                bool allow_ht_operation,
1624                                u32 rate_set, u8 hlid)
1626         return wl1271_acx_set_ht_capabilities(wl, ht_cap, allow_ht_operation,
1627                                               hlid);
1630 static bool wl12xx_lnk_high_prio(struct wl1271 *wl, u8 hlid,
1631                                  struct wl1271_link *lnk)
1633         u8 thold;
1635         if (test_bit(hlid, (unsigned long *)&wl->fw_fast_lnk_map))
1636                 thold = wl->conf.tx.fast_link_thold;
1637         else
1638                 thold = wl->conf.tx.slow_link_thold;
1640         return lnk->allocated_pkts < thold;
1643 static bool wl12xx_lnk_low_prio(struct wl1271 *wl, u8 hlid,
1644                                 struct wl1271_link *lnk)
1646         /* any link is good for low priority */
1647         return true;
1650 static int wl12xx_setup(struct wl1271 *wl);
1652 static struct wlcore_ops wl12xx_ops = {
1653         .setup                  = wl12xx_setup,
1654         .identify_chip          = wl12xx_identify_chip,
1655         .boot                   = wl12xx_boot,
1656         .plt_init               = wl12xx_plt_init,
1657         .trigger_cmd            = wl12xx_trigger_cmd,
1658         .ack_event              = wl12xx_ack_event,
1659         .wait_for_event         = wl12xx_wait_for_event,
1660         .process_mailbox_events = wl12xx_process_mailbox_events,
1661         .calc_tx_blocks         = wl12xx_calc_tx_blocks,
1662         .set_tx_desc_blocks     = wl12xx_set_tx_desc_blocks,
1663         .set_tx_desc_data_len   = wl12xx_set_tx_desc_data_len,
1664         .get_rx_buf_align       = wl12xx_get_rx_buf_align,
1665         .get_rx_packet_len      = wl12xx_get_rx_packet_len,
1666         .tx_immediate_compl     = NULL,
1667         .tx_delayed_compl       = wl12xx_tx_delayed_compl,
1668         .hw_init                = wl12xx_hw_init,
1669         .init_vif               = NULL,
1670         .sta_get_ap_rate_mask   = wl12xx_sta_get_ap_rate_mask,
1671         .get_pg_ver             = wl12xx_get_pg_ver,
1672         .get_mac                = wl12xx_get_mac,
1673         .set_tx_desc_csum       = wl12xx_set_tx_desc_csum,
1674         .set_rx_csum            = NULL,
1675         .ap_get_mimo_wide_rate_mask = NULL,
1676         .debugfs_init           = wl12xx_debugfs_add_files,
1677         .scan_start             = wl12xx_scan_start,
1678         .scan_stop              = wl12xx_scan_stop,
1679         .sched_scan_start       = wl12xx_sched_scan_start,
1680         .sched_scan_stop        = wl12xx_scan_sched_scan_stop,
1681         .get_spare_blocks       = wl12xx_get_spare_blocks,
1682         .set_key                = wl12xx_set_key,
1683         .channel_switch         = wl12xx_cmd_channel_switch,
1684         .pre_pkt_send           = NULL,
1685         .set_peer_cap           = wl12xx_set_peer_cap,
1686         .lnk_high_prio          = wl12xx_lnk_high_prio,
1687         .lnk_low_prio           = wl12xx_lnk_low_prio,
1688 };
1690 static struct ieee80211_sta_ht_cap wl12xx_ht_cap = {
1691         .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 |
1692                (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT),
1693         .ht_supported = true,
1694         .ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K,
1695         .ampdu_density = IEEE80211_HT_MPDU_DENSITY_8,
1696         .mcs = {
1697                 .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
1698                 .rx_highest = cpu_to_le16(72),
1699                 .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
1700                 },
1701 };
1703 static int wl12xx_setup(struct wl1271 *wl)
1705         struct wl12xx_priv *priv = wl->priv;
1706         struct wl12xx_platform_data *pdata = wl->pdev->dev.platform_data;
1708         wl->rtable = wl12xx_rtable;
1709         wl->num_tx_desc = WL12XX_NUM_TX_DESCRIPTORS;
1710         wl->num_rx_desc = WL12XX_NUM_RX_DESCRIPTORS;
1711         wl->num_channels = 1;
1712         wl->num_mac_addr = WL12XX_NUM_MAC_ADDRESSES;
1713         wl->band_rate_to_idx = wl12xx_band_rate_to_idx;
1714         wl->hw_tx_rate_tbl_size = WL12XX_CONF_HW_RXTX_RATE_MAX;
1715         wl->hw_min_ht_rate = WL12XX_CONF_HW_RXTX_RATE_MCS0;
1716         wl->fw_status_priv_len = 0;
1717         wl->stats.fw_stats_len = sizeof(struct wl12xx_acx_statistics);
1718         wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ, &wl12xx_ht_cap);
1719         wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ, &wl12xx_ht_cap);
1720         wl12xx_conf_init(wl);
1722         if (!fref_param) {
1723                 priv->ref_clock = pdata->board_ref_clock;
1724         } else {
1725                 if (!strcmp(fref_param, "19.2"))
1726                         priv->ref_clock = WL12XX_REFCLOCK_19;
1727                 else if (!strcmp(fref_param, "26"))
1728                         priv->ref_clock = WL12XX_REFCLOCK_26;
1729                 else if (!strcmp(fref_param, "26x"))
1730                         priv->ref_clock = WL12XX_REFCLOCK_26_XTAL;
1731                 else if (!strcmp(fref_param, "38.4"))
1732                         priv->ref_clock = WL12XX_REFCLOCK_38;
1733                 else if (!strcmp(fref_param, "38.4x"))
1734                         priv->ref_clock = WL12XX_REFCLOCK_38_XTAL;
1735                 else if (!strcmp(fref_param, "52"))
1736                         priv->ref_clock = WL12XX_REFCLOCK_52;
1737                 else
1738                         wl1271_error("Invalid fref parameter %s", fref_param);
1739         }
1741         if (!tcxo_param) {
1742                 priv->tcxo_clock = pdata->board_tcxo_clock;
1743         } else {
1744                 if (!strcmp(tcxo_param, "19.2"))
1745                         priv->tcxo_clock = WL12XX_TCXOCLOCK_19_2;
1746                 else if (!strcmp(tcxo_param, "26"))
1747                         priv->tcxo_clock = WL12XX_TCXOCLOCK_26;
1748                 else if (!strcmp(tcxo_param, "38.4"))
1749                         priv->tcxo_clock = WL12XX_TCXOCLOCK_38_4;
1750                 else if (!strcmp(tcxo_param, "52"))
1751                         priv->tcxo_clock = WL12XX_TCXOCLOCK_52;
1752                 else if (!strcmp(tcxo_param, "16.368"))
1753                         priv->tcxo_clock = WL12XX_TCXOCLOCK_16_368;
1754                 else if (!strcmp(tcxo_param, "32.736"))
1755                         priv->tcxo_clock = WL12XX_TCXOCLOCK_32_736;
1756                 else if (!strcmp(tcxo_param, "16.8"))
1757                         priv->tcxo_clock = WL12XX_TCXOCLOCK_16_8;
1758                 else if (!strcmp(tcxo_param, "33.6"))
1759                         priv->tcxo_clock = WL12XX_TCXOCLOCK_33_6;
1760                 else
1761                         wl1271_error("Invalid tcxo parameter %s", tcxo_param);
1762         }
1764         priv->rx_mem_addr = kmalloc(sizeof(*priv->rx_mem_addr), GFP_KERNEL);
1765         if (!priv->rx_mem_addr)
1766                 return -ENOMEM;
1768         return 0;
1771 static int wl12xx_probe(struct platform_device *pdev)
1773         struct wl1271 *wl;
1774         struct ieee80211_hw *hw;
1775         int ret;
1777         hw = wlcore_alloc_hw(sizeof(struct wl12xx_priv),
1778                              WL12XX_AGGR_BUFFER_SIZE,
1779                              sizeof(struct wl12xx_event_mailbox));
1780         if (IS_ERR(hw)) {
1781                 wl1271_error("can't allocate hw");
1782                 ret = PTR_ERR(hw);
1783                 goto out;
1784         }
1786         wl = hw->priv;
1787         wl->ops = &wl12xx_ops;
1788         wl->ptable = wl12xx_ptable;
1789         ret = wlcore_probe(wl, pdev);
1790         if (ret)
1791                 goto out_free;
1793         return ret;
1795 out_free:
1796         wlcore_free_hw(wl);
1797 out:
1798         return ret;
1801 static int wl12xx_remove(struct platform_device *pdev)
1803         struct wl1271 *wl = platform_get_drvdata(pdev);
1804         struct wl12xx_priv *priv;
1806         if (!wl)
1807                 goto out;
1808         priv = wl->priv;
1810         kfree(priv->rx_mem_addr);
1812 out:
1813         return wlcore_remove(pdev);
1816 static const struct platform_device_id wl12xx_id_table[] = {
1817         { "wl12xx", 0 },
1818         {  } /* Terminating Entry */
1819 };
1820 MODULE_DEVICE_TABLE(platform, wl12xx_id_table);
1822 static struct platform_driver wl12xx_driver = {
1823         .probe          = wl12xx_probe,
1824         .remove         = wl12xx_remove,
1825         .id_table       = wl12xx_id_table,
1826         .driver = {
1827                 .name   = "wl12xx_driver",
1828                 .owner  = THIS_MODULE,
1829         }
1830 };
1832 module_platform_driver(wl12xx_driver);
1834 module_param_named(fref, fref_param, charp, 0);
1835 MODULE_PARM_DESC(fref, "FREF clock: 19.2, 26, 26x, 38.4, 38.4x, 52");
1837 module_param_named(tcxo, tcxo_param, charp, 0);
1838 MODULE_PARM_DESC(tcxo,
1839                  "TCXO clock: 19.2, 26, 38.4, 52, 16.368, 32.736, 16.8, 33.6");
1841 MODULE_LICENSE("GPL v2");
1842 MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
1843 MODULE_FIRMWARE(WL127X_FW_NAME_SINGLE);
1844 MODULE_FIRMWARE(WL127X_FW_NAME_MULTI);
1845 MODULE_FIRMWARE(WL127X_PLT_FW_NAME);
1846 MODULE_FIRMWARE(WL128X_FW_NAME_SINGLE);
1847 MODULE_FIRMWARE(WL128X_FW_NAME_MULTI);
1848 MODULE_FIRMWARE(WL128X_PLT_FW_NAME);