treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 336
[linux-2.6-microblaze.git] / drivers / net / wireless / ti / wl18xx / main.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * This file is part of wl18xx
4  *
5  * Copyright (C) 2011 Texas Instruments
6  */
7
8 #include <linux/module.h>
9 #include <linux/mod_devicetable.h>
10 #include <linux/platform_device.h>
11 #include <linux/ip.h>
12 #include <linux/firmware.h>
13 #include <linux/etherdevice.h>
14 #include <linux/irq.h>
15
16 #include "../wlcore/wlcore.h"
17 #include "../wlcore/debug.h"
18 #include "../wlcore/io.h"
19 #include "../wlcore/acx.h"
20 #include "../wlcore/tx.h"
21 #include "../wlcore/rx.h"
22 #include "../wlcore/boot.h"
23
24 #include "reg.h"
25 #include "conf.h"
26 #include "cmd.h"
27 #include "acx.h"
28 #include "tx.h"
29 #include "wl18xx.h"
30 #include "io.h"
31 #include "scan.h"
32 #include "event.h"
33 #include "debugfs.h"
34
35 #define WL18XX_RX_CHECKSUM_MASK      0x40
36
37 static char *ht_mode_param = NULL;
38 static char *board_type_param = NULL;
39 static bool checksum_param = false;
40 static int num_rx_desc_param = -1;
41
42 /* phy paramters */
43 static int dc2dc_param = -1;
44 static int n_antennas_2_param = -1;
45 static int n_antennas_5_param = -1;
46 static int low_band_component_param = -1;
47 static int low_band_component_type_param = -1;
48 static int high_band_component_param = -1;
49 static int high_band_component_type_param = -1;
50 static int pwr_limit_reference_11_abg_param = -1;
51
52 static const u8 wl18xx_rate_to_idx_2ghz[] = {
53         /* MCS rates are used only with 11n */
54         15,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS15 */
55         14,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS14 */
56         13,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS13 */
57         12,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS12 */
58         11,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS11 */
59         10,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS10 */
60         9,                             /* WL18XX_CONF_HW_RXTX_RATE_MCS9 */
61         8,                             /* WL18XX_CONF_HW_RXTX_RATE_MCS8 */
62         7,                             /* WL18XX_CONF_HW_RXTX_RATE_MCS7 */
63         6,                             /* WL18XX_CONF_HW_RXTX_RATE_MCS6 */
64         5,                             /* WL18XX_CONF_HW_RXTX_RATE_MCS5 */
65         4,                             /* WL18XX_CONF_HW_RXTX_RATE_MCS4 */
66         3,                             /* WL18XX_CONF_HW_RXTX_RATE_MCS3 */
67         2,                             /* WL18XX_CONF_HW_RXTX_RATE_MCS2 */
68         1,                             /* WL18XX_CONF_HW_RXTX_RATE_MCS1 */
69         0,                             /* WL18XX_CONF_HW_RXTX_RATE_MCS0 */
70
71         11,                            /* WL18XX_CONF_HW_RXTX_RATE_54   */
72         10,                            /* WL18XX_CONF_HW_RXTX_RATE_48   */
73         9,                             /* WL18XX_CONF_HW_RXTX_RATE_36   */
74         8,                             /* WL18XX_CONF_HW_RXTX_RATE_24   */
75
76         /* TI-specific rate */
77         CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_22   */
78
79         7,                             /* WL18XX_CONF_HW_RXTX_RATE_18   */
80         6,                             /* WL18XX_CONF_HW_RXTX_RATE_12   */
81         3,                             /* WL18XX_CONF_HW_RXTX_RATE_11   */
82         5,                             /* WL18XX_CONF_HW_RXTX_RATE_9    */
83         4,                             /* WL18XX_CONF_HW_RXTX_RATE_6    */
84         2,                             /* WL18XX_CONF_HW_RXTX_RATE_5_5  */
85         1,                             /* WL18XX_CONF_HW_RXTX_RATE_2    */
86         0                              /* WL18XX_CONF_HW_RXTX_RATE_1    */
87 };
88
89 static const u8 wl18xx_rate_to_idx_5ghz[] = {
90         /* MCS rates are used only with 11n */
91         15,                           /* WL18XX_CONF_HW_RXTX_RATE_MCS15 */
92         14,                           /* WL18XX_CONF_HW_RXTX_RATE_MCS14 */
93         13,                           /* WL18XX_CONF_HW_RXTX_RATE_MCS13 */
94         12,                           /* WL18XX_CONF_HW_RXTX_RATE_MCS12 */
95         11,                           /* WL18XX_CONF_HW_RXTX_RATE_MCS11 */
96         10,                           /* WL18XX_CONF_HW_RXTX_RATE_MCS10 */
97         9,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS9 */
98         8,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS8 */
99         7,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS7 */
100         6,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS6 */
101         5,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS5 */
102         4,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS4 */
103         3,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS3 */
104         2,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS2 */
105         1,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS1 */
106         0,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS0 */
107
108         7,                             /* WL18XX_CONF_HW_RXTX_RATE_54   */
109         6,                             /* WL18XX_CONF_HW_RXTX_RATE_48   */
110         5,                             /* WL18XX_CONF_HW_RXTX_RATE_36   */
111         4,                             /* WL18XX_CONF_HW_RXTX_RATE_24   */
112
113         /* TI-specific rate */
114         CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_22   */
115
116         3,                             /* WL18XX_CONF_HW_RXTX_RATE_18   */
117         2,                             /* WL18XX_CONF_HW_RXTX_RATE_12   */
118         CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_11   */
119         1,                             /* WL18XX_CONF_HW_RXTX_RATE_9    */
120         0,                             /* WL18XX_CONF_HW_RXTX_RATE_6    */
121         CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_5_5  */
122         CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_2    */
123         CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_1    */
124 };
125
126 static const u8 *wl18xx_band_rate_to_idx[] = {
127         [NL80211_BAND_2GHZ] = wl18xx_rate_to_idx_2ghz,
128         [NL80211_BAND_5GHZ] = wl18xx_rate_to_idx_5ghz
129 };
130
131 enum wl18xx_hw_rates {
132         WL18XX_CONF_HW_RXTX_RATE_MCS15 = 0,
133         WL18XX_CONF_HW_RXTX_RATE_MCS14,
134         WL18XX_CONF_HW_RXTX_RATE_MCS13,
135         WL18XX_CONF_HW_RXTX_RATE_MCS12,
136         WL18XX_CONF_HW_RXTX_RATE_MCS11,
137         WL18XX_CONF_HW_RXTX_RATE_MCS10,
138         WL18XX_CONF_HW_RXTX_RATE_MCS9,
139         WL18XX_CONF_HW_RXTX_RATE_MCS8,
140         WL18XX_CONF_HW_RXTX_RATE_MCS7,
141         WL18XX_CONF_HW_RXTX_RATE_MCS6,
142         WL18XX_CONF_HW_RXTX_RATE_MCS5,
143         WL18XX_CONF_HW_RXTX_RATE_MCS4,
144         WL18XX_CONF_HW_RXTX_RATE_MCS3,
145         WL18XX_CONF_HW_RXTX_RATE_MCS2,
146         WL18XX_CONF_HW_RXTX_RATE_MCS1,
147         WL18XX_CONF_HW_RXTX_RATE_MCS0,
148         WL18XX_CONF_HW_RXTX_RATE_54,
149         WL18XX_CONF_HW_RXTX_RATE_48,
150         WL18XX_CONF_HW_RXTX_RATE_36,
151         WL18XX_CONF_HW_RXTX_RATE_24,
152         WL18XX_CONF_HW_RXTX_RATE_22,
153         WL18XX_CONF_HW_RXTX_RATE_18,
154         WL18XX_CONF_HW_RXTX_RATE_12,
155         WL18XX_CONF_HW_RXTX_RATE_11,
156         WL18XX_CONF_HW_RXTX_RATE_9,
157         WL18XX_CONF_HW_RXTX_RATE_6,
158         WL18XX_CONF_HW_RXTX_RATE_5_5,
159         WL18XX_CONF_HW_RXTX_RATE_2,
160         WL18XX_CONF_HW_RXTX_RATE_1,
161         WL18XX_CONF_HW_RXTX_RATE_MAX,
162 };
163
164 static struct wlcore_conf wl18xx_conf = {
165         .sg = {
166                 .params = {
167                         [WL18XX_CONF_SG_PARAM_0] = 0,
168                         /* Configuration Parameters */
169                         [WL18XX_CONF_SG_ANTENNA_CONFIGURATION] = 0,
170                         [WL18XX_CONF_SG_ZIGBEE_COEX] = 0,
171                         [WL18XX_CONF_SG_TIME_SYNC] = 0,
172                         [WL18XX_CONF_SG_PARAM_4] = 0,
173                         [WL18XX_CONF_SG_PARAM_5] = 0,
174                         [WL18XX_CONF_SG_PARAM_6] = 0,
175                         [WL18XX_CONF_SG_PARAM_7] = 0,
176                         [WL18XX_CONF_SG_PARAM_8] = 0,
177                         [WL18XX_CONF_SG_PARAM_9] = 0,
178                         [WL18XX_CONF_SG_PARAM_10] = 0,
179                         [WL18XX_CONF_SG_PARAM_11] = 0,
180                         [WL18XX_CONF_SG_PARAM_12] = 0,
181                         [WL18XX_CONF_SG_PARAM_13] = 0,
182                         [WL18XX_CONF_SG_PARAM_14] = 0,
183                         [WL18XX_CONF_SG_PARAM_15] = 0,
184                         [WL18XX_CONF_SG_PARAM_16] = 0,
185                         [WL18XX_CONF_SG_PARAM_17] = 0,
186                         [WL18XX_CONF_SG_PARAM_18] = 0,
187                         [WL18XX_CONF_SG_PARAM_19] = 0,
188                         [WL18XX_CONF_SG_PARAM_20] = 0,
189                         [WL18XX_CONF_SG_PARAM_21] = 0,
190                         [WL18XX_CONF_SG_PARAM_22] = 0,
191                         [WL18XX_CONF_SG_PARAM_23] = 0,
192                         [WL18XX_CONF_SG_PARAM_24] = 0,
193                         [WL18XX_CONF_SG_PARAM_25] = 0,
194                         /* Active Scan Parameters */
195                         [WL18XX_CONF_SG_AUTO_SCAN_PROBE_REQ] = 170,
196                         [WL18XX_CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3] = 50,
197                         [WL18XX_CONF_SG_PARAM_28] = 0,
198                         /* Passive Scan Parameters */
199                         [WL18XX_CONF_SG_PARAM_29] = 0,
200                         [WL18XX_CONF_SG_PARAM_30] = 0,
201                         [WL18XX_CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3] = 200,
202                         /* Passive Scan in Dual Antenna Parameters */
203                         [WL18XX_CONF_SG_CONSECUTIVE_HV3_IN_PASSIVE_SCAN] = 0,
204                         [WL18XX_CONF_SG_BEACON_HV3_COLL_TH_IN_PASSIVE_SCAN] = 0,
205                         [WL18XX_CONF_SG_TX_RX_PROTECT_BW_IN_PASSIVE_SCAN] = 0,
206                         /* General Parameters */
207                         [WL18XX_CONF_SG_STA_FORCE_PS_IN_BT_SCO] = 1,
208                         [WL18XX_CONF_SG_PARAM_36] = 0,
209                         [WL18XX_CONF_SG_BEACON_MISS_PERCENT] = 60,
210                         [WL18XX_CONF_SG_PARAM_38] = 0,
211                         [WL18XX_CONF_SG_RXT] = 1200,
212                         [WL18XX_CONF_SG_UNUSED] = 0,
213                         [WL18XX_CONF_SG_ADAPTIVE_RXT_TXT] = 1,
214                         [WL18XX_CONF_SG_GENERAL_USAGE_BIT_MAP] = 3,
215                         [WL18XX_CONF_SG_HV3_MAX_SERVED] = 6,
216                         [WL18XX_CONF_SG_PARAM_44] = 0,
217                         [WL18XX_CONF_SG_PARAM_45] = 0,
218                         [WL18XX_CONF_SG_CONSECUTIVE_CTS_THRESHOLD] = 2,
219                         [WL18XX_CONF_SG_GEMINI_PARAM_47] = 0,
220                         [WL18XX_CONF_SG_STA_CONNECTION_PROTECTION_TIME] = 0,
221                         /* AP Parameters */
222                         [WL18XX_CONF_SG_AP_BEACON_MISS_TX] = 3,
223                         [WL18XX_CONF_SG_PARAM_50] = 0,
224                         [WL18XX_CONF_SG_AP_BEACON_WINDOW_INTERVAL] = 2,
225                         [WL18XX_CONF_SG_AP_CONNECTION_PROTECTION_TIME] = 30,
226                         [WL18XX_CONF_SG_PARAM_53] = 0,
227                         [WL18XX_CONF_SG_PARAM_54] = 0,
228                         /* CTS Diluting Parameters */
229                         [WL18XX_CONF_SG_CTS_DILUTED_BAD_RX_PACKETS_TH] = 0,
230                         [WL18XX_CONF_SG_CTS_CHOP_IN_DUAL_ANT_SCO_MASTER] = 0,
231                         [WL18XX_CONF_SG_TEMP_PARAM_1] = 0,
232                         [WL18XX_CONF_SG_TEMP_PARAM_2] = 0,
233                         [WL18XX_CONF_SG_TEMP_PARAM_3] = 0,
234                         [WL18XX_CONF_SG_TEMP_PARAM_4] = 0,
235                         [WL18XX_CONF_SG_TEMP_PARAM_5] = 0,
236                         [WL18XX_CONF_SG_TEMP_PARAM_6] = 0,
237                         [WL18XX_CONF_SG_TEMP_PARAM_7] = 0,
238                         [WL18XX_CONF_SG_TEMP_PARAM_8] = 0,
239                         [WL18XX_CONF_SG_TEMP_PARAM_9] = 0,
240                         [WL18XX_CONF_SG_TEMP_PARAM_10] = 0,
241                 },
242                 .state = CONF_SG_PROTECTIVE,
243         },
244         .rx = {
245                 .rx_msdu_life_time           = 512000,
246                 .packet_detection_threshold  = 0,
247                 .ps_poll_timeout             = 15,
248                 .upsd_timeout                = 15,
249                 .rts_threshold               = IEEE80211_MAX_RTS_THRESHOLD,
250                 .rx_cca_threshold            = 0,
251                 .irq_blk_threshold           = 0xFFFF,
252                 .irq_pkt_threshold           = 0,
253                 .irq_timeout                 = 600,
254                 .queue_type                  = CONF_RX_QUEUE_TYPE_LOW_PRIORITY,
255         },
256         .tx = {
257                 .tx_energy_detection         = 0,
258                 .sta_rc_conf                 = {
259                         .enabled_rates       = 0,
260                         .short_retry_limit   = 10,
261                         .long_retry_limit    = 10,
262                         .aflags              = 0,
263                 },
264                 .ac_conf_count               = 4,
265                 .ac_conf                     = {
266                         [CONF_TX_AC_BE] = {
267                                 .ac          = CONF_TX_AC_BE,
268                                 .cw_min      = 15,
269                                 .cw_max      = 63,
270                                 .aifsn       = 3,
271                                 .tx_op_limit = 0,
272                         },
273                         [CONF_TX_AC_BK] = {
274                                 .ac          = CONF_TX_AC_BK,
275                                 .cw_min      = 15,
276                                 .cw_max      = 63,
277                                 .aifsn       = 7,
278                                 .tx_op_limit = 0,
279                         },
280                         [CONF_TX_AC_VI] = {
281                                 .ac          = CONF_TX_AC_VI,
282                                 .cw_min      = 15,
283                                 .cw_max      = 63,
284                                 .aifsn       = CONF_TX_AIFS_PIFS,
285                                 .tx_op_limit = 3008,
286                         },
287                         [CONF_TX_AC_VO] = {
288                                 .ac          = CONF_TX_AC_VO,
289                                 .cw_min      = 15,
290                                 .cw_max      = 63,
291                                 .aifsn       = CONF_TX_AIFS_PIFS,
292                                 .tx_op_limit = 1504,
293                         },
294                 },
295                 .max_tx_retries = 100,
296                 .ap_aging_period = 300,
297                 .tid_conf_count = 4,
298                 .tid_conf = {
299                         [CONF_TX_AC_BE] = {
300                                 .queue_id    = CONF_TX_AC_BE,
301                                 .channel_type = CONF_CHANNEL_TYPE_EDCF,
302                                 .tsid        = CONF_TX_AC_BE,
303                                 .ps_scheme   = CONF_PS_SCHEME_LEGACY,
304                                 .ack_policy  = CONF_ACK_POLICY_LEGACY,
305                                 .apsd_conf   = {0, 0},
306                         },
307                         [CONF_TX_AC_BK] = {
308                                 .queue_id    = CONF_TX_AC_BK,
309                                 .channel_type = CONF_CHANNEL_TYPE_EDCF,
310                                 .tsid        = CONF_TX_AC_BK,
311                                 .ps_scheme   = CONF_PS_SCHEME_LEGACY,
312                                 .ack_policy  = CONF_ACK_POLICY_LEGACY,
313                                 .apsd_conf   = {0, 0},
314                         },
315                         [CONF_TX_AC_VI] = {
316                                 .queue_id    = CONF_TX_AC_VI,
317                                 .channel_type = CONF_CHANNEL_TYPE_EDCF,
318                                 .tsid        = CONF_TX_AC_VI,
319                                 .ps_scheme   = CONF_PS_SCHEME_LEGACY,
320                                 .ack_policy  = CONF_ACK_POLICY_LEGACY,
321                                 .apsd_conf   = {0, 0},
322                         },
323                         [CONF_TX_AC_VO] = {
324                                 .queue_id    = CONF_TX_AC_VO,
325                                 .channel_type = CONF_CHANNEL_TYPE_EDCF,
326                                 .tsid        = CONF_TX_AC_VO,
327                                 .ps_scheme   = CONF_PS_SCHEME_LEGACY,
328                                 .ack_policy  = CONF_ACK_POLICY_LEGACY,
329                                 .apsd_conf   = {0, 0},
330                         },
331                 },
332                 .frag_threshold              = IEEE80211_MAX_FRAG_THRESHOLD,
333                 .tx_compl_timeout            = 350,
334                 .tx_compl_threshold          = 10,
335                 .basic_rate                  = CONF_HW_BIT_RATE_1MBPS,
336                 .basic_rate_5                = CONF_HW_BIT_RATE_6MBPS,
337                 .tmpl_short_retry_limit      = 10,
338                 .tmpl_long_retry_limit       = 10,
339                 .tx_watchdog_timeout         = 5000,
340                 .slow_link_thold             = 3,
341                 .fast_link_thold             = 30,
342         },
343         .conn = {
344                 .wake_up_event               = CONF_WAKE_UP_EVENT_DTIM,
345                 .listen_interval             = 1,
346                 .suspend_wake_up_event       = CONF_WAKE_UP_EVENT_N_DTIM,
347                 .suspend_listen_interval     = 3,
348                 .bcn_filt_mode               = CONF_BCN_FILT_MODE_ENABLED,
349                 .bcn_filt_ie_count           = 3,
350                 .bcn_filt_ie = {
351                         [0] = {
352                                 .ie          = WLAN_EID_CHANNEL_SWITCH,
353                                 .rule        = CONF_BCN_RULE_PASS_ON_APPEARANCE,
354                         },
355                         [1] = {
356                                 .ie          = WLAN_EID_HT_OPERATION,
357                                 .rule        = CONF_BCN_RULE_PASS_ON_CHANGE,
358                         },
359                         [2] = {
360                                 .ie          = WLAN_EID_ERP_INFO,
361                                 .rule        = CONF_BCN_RULE_PASS_ON_CHANGE,
362                         },
363                 },
364                 .synch_fail_thold            = 12,
365                 .bss_lose_timeout            = 400,
366                 .beacon_rx_timeout           = 10000,
367                 .broadcast_timeout           = 20000,
368                 .rx_broadcast_in_ps          = 1,
369                 .ps_poll_threshold           = 10,
370                 .bet_enable                  = CONF_BET_MODE_ENABLE,
371                 .bet_max_consecutive         = 50,
372                 .psm_entry_retries           = 8,
373                 .psm_exit_retries            = 16,
374                 .psm_entry_nullfunc_retries  = 3,
375                 .dynamic_ps_timeout          = 1500,
376                 .forced_ps                   = false,
377                 .keep_alive_interval         = 55000,
378                 .max_listen_interval         = 20,
379                 .sta_sleep_auth              = WL1271_PSM_ILLEGAL,
380                 .suspend_rx_ba_activity      = 0,
381         },
382         .itrim = {
383                 .enable = false,
384                 .timeout = 50000,
385         },
386         .pm_config = {
387                 .host_clk_settling_time = 5000,
388                 .host_fast_wakeup_support = CONF_FAST_WAKEUP_DISABLE,
389         },
390         .roam_trigger = {
391                 .trigger_pacing               = 1,
392                 .avg_weight_rssi_beacon       = 20,
393                 .avg_weight_rssi_data         = 10,
394                 .avg_weight_snr_beacon        = 20,
395                 .avg_weight_snr_data          = 10,
396         },
397         .scan = {
398                 .min_dwell_time_active        = 7500,
399                 .max_dwell_time_active        = 30000,
400                 .min_dwell_time_active_long   = 25000,
401                 .max_dwell_time_active_long   = 50000,
402                 .dwell_time_passive           = 100000,
403                 .dwell_time_dfs               = 150000,
404                 .num_probe_reqs               = 2,
405                 .split_scan_timeout           = 50000,
406         },
407         .sched_scan = {
408                 /*
409                  * Values are in TU/1000 but since sched scan FW command
410                  * params are in TUs rounding up may occur.
411                  */
412                 .base_dwell_time                = 7500,
413                 .max_dwell_time_delta           = 22500,
414                 /* based on 250bits per probe @1Mbps */
415                 .dwell_time_delta_per_probe     = 2000,
416                 /* based on 250bits per probe @6Mbps (plus a bit more) */
417                 .dwell_time_delta_per_probe_5   = 350,
418                 .dwell_time_passive             = 100000,
419                 .dwell_time_dfs                 = 150000,
420                 .num_probe_reqs                 = 2,
421                 .rssi_threshold                 = -90,
422                 .snr_threshold                  = 0,
423                 .num_short_intervals            = SCAN_MAX_SHORT_INTERVALS,
424                 .long_interval                  = 30000,
425         },
426         .ht = {
427                 .rx_ba_win_size = 32,
428                 .tx_ba_win_size = 64,
429                 .inactivity_timeout = 10000,
430                 .tx_ba_tid_bitmap = CONF_TX_BA_ENABLED_TID_BITMAP,
431         },
432         .mem = {
433                 .num_stations                 = 1,
434                 .ssid_profiles                = 1,
435                 .rx_block_num                 = 40,
436                 .tx_min_block_num             = 40,
437                 .dynamic_memory               = 1,
438                 .min_req_tx_blocks            = 45,
439                 .min_req_rx_blocks            = 22,
440                 .tx_min                       = 27,
441         },
442         .fm_coex = {
443                 .enable                       = true,
444                 .swallow_period               = 5,
445                 .n_divider_fref_set_1         = 0xff,       /* default */
446                 .n_divider_fref_set_2         = 12,
447                 .m_divider_fref_set_1         = 0xffff,
448                 .m_divider_fref_set_2         = 148,        /* default */
449                 .coex_pll_stabilization_time  = 0xffffffff, /* default */
450                 .ldo_stabilization_time       = 0xffff,     /* default */
451                 .fm_disturbed_band_margin     = 0xff,       /* default */
452                 .swallow_clk_diff             = 0xff,       /* default */
453         },
454         .rx_streaming = {
455                 .duration                      = 150,
456                 .queues                        = 0x1,
457                 .interval                      = 20,
458                 .always                        = 0,
459         },
460         .fwlog = {
461                 .mode                         = WL12XX_FWLOG_CONTINUOUS,
462                 .mem_blocks                   = 0,
463                 .severity                     = 0,
464                 .timestamp                    = WL12XX_FWLOG_TIMESTAMP_DISABLED,
465                 .output                       = WL12XX_FWLOG_OUTPUT_DBG_PINS,
466                 .threshold                    = 0,
467         },
468         .rate = {
469                 .rate_retry_score = 32000,
470                 .per_add = 8192,
471                 .per_th1 = 2048,
472                 .per_th2 = 4096,
473                 .max_per = 8100,
474                 .inverse_curiosity_factor = 5,
475                 .tx_fail_low_th = 4,
476                 .tx_fail_high_th = 10,
477                 .per_alpha_shift = 4,
478                 .per_add_shift = 13,
479                 .per_beta1_shift = 10,
480                 .per_beta2_shift = 8,
481                 .rate_check_up = 2,
482                 .rate_check_down = 12,
483                 .rate_retry_policy = {
484                         0x00, 0x00, 0x00, 0x00, 0x00,
485                         0x00, 0x00, 0x00, 0x00, 0x00,
486                         0x00, 0x00, 0x00,
487                 },
488         },
489         .hangover = {
490                 .recover_time               = 0,
491                 .hangover_period            = 20,
492                 .dynamic_mode               = 1,
493                 .early_termination_mode     = 1,
494                 .max_period                 = 20,
495                 .min_period                 = 1,
496                 .increase_delta             = 1,
497                 .decrease_delta             = 2,
498                 .quiet_time                 = 4,
499                 .increase_time              = 1,
500                 .window_size                = 16,
501         },
502         .recovery = {
503                 .bug_on_recovery            = 0,
504                 .no_recovery                = 0,
505         },
506 };
507
508 static struct wl18xx_priv_conf wl18xx_default_priv_conf = {
509         .ht = {
510                 .mode                           = HT_MODE_WIDE,
511         },
512         .phy = {
513                 .phy_standalone                 = 0x00,
514                 .primary_clock_setting_time     = 0x05,
515                 .clock_valid_on_wake_up         = 0x00,
516                 .secondary_clock_setting_time   = 0x05,
517                 .board_type                     = BOARD_TYPE_HDK_18XX,
518                 .auto_detect                    = 0x00,
519                 .dedicated_fem                  = FEM_NONE,
520                 .low_band_component             = COMPONENT_3_WAY_SWITCH,
521                 .low_band_component_type        = 0x05,
522                 .high_band_component            = COMPONENT_2_WAY_SWITCH,
523                 .high_band_component_type       = 0x09,
524                 .tcxo_ldo_voltage               = 0x00,
525                 .xtal_itrim_val                 = 0x04,
526                 .srf_state                      = 0x00,
527                 .io_configuration               = 0x01,
528                 .sdio_configuration             = 0x00,
529                 .settings                       = 0x00,
530                 .enable_clpc                    = 0x00,
531                 .enable_tx_low_pwr_on_siso_rdl  = 0x00,
532                 .rx_profile                     = 0x00,
533                 .pwr_limit_reference_11_abg     = 0x64,
534                 .per_chan_pwr_limit_arr_11abg   = {
535                         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
536                         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
537                         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
538                         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
539                         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
540                         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
541                         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
542                         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
543                         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
544                         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
545                         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
546                         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
547                         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
548                         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
549                         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
550                         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
551                         0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
552                 .pwr_limit_reference_11p        = 0x64,
553                 .per_chan_bo_mode_11_abg        = { 0x00, 0x00, 0x00, 0x00,
554                                                     0x00, 0x00, 0x00, 0x00,
555                                                     0x00, 0x00, 0x00, 0x00,
556                                                     0x00 },
557                 .per_chan_bo_mode_11_p          = { 0x00, 0x00, 0x00, 0x00 },
558                 .per_chan_pwr_limit_arr_11p     = { 0xff, 0xff, 0xff, 0xff,
559                                                     0xff, 0xff, 0xff },
560                 .psat                           = 0,
561                 .external_pa_dc2dc              = 0,
562                 .number_of_assembled_ant2_4     = 2,
563                 .number_of_assembled_ant5       = 1,
564                 .low_power_val                  = 0xff,
565                 .med_power_val                  = 0xff,
566                 .high_power_val                 = 0xff,
567                 .low_power_val_2nd              = 0xff,
568                 .med_power_val_2nd              = 0xff,
569                 .high_power_val_2nd             = 0xff,
570                 .tx_rf_margin                   = 1,
571         },
572         .ap_sleep = {               /* disabled by default */
573                 .idle_duty_cycle        = 0,
574                 .connected_duty_cycle   = 0,
575                 .max_stations_thresh    = 0,
576                 .idle_conn_thresh       = 0,
577         },
578 };
579
580 static const struct wlcore_partition_set wl18xx_ptable[PART_TABLE_LEN] = {
581         [PART_TOP_PRCM_ELP_SOC] = {
582                 .mem  = { .start = 0x00A00000, .size  = 0x00012000 },
583                 .reg  = { .start = 0x00807000, .size  = 0x00005000 },
584                 .mem2 = { .start = 0x00800000, .size  = 0x0000B000 },
585                 .mem3 = { .start = 0x00401594, .size  = 0x00001020 },
586         },
587         [PART_DOWN] = {
588                 .mem  = { .start = 0x00000000, .size  = 0x00014000 },
589                 .reg  = { .start = 0x00810000, .size  = 0x0000BFFF },
590                 .mem2 = { .start = 0x00000000, .size  = 0x00000000 },
591                 .mem3 = { .start = 0x00000000, .size  = 0x00000000 },
592         },
593         [PART_BOOT] = {
594                 .mem  = { .start = 0x00700000, .size = 0x0000030c },
595                 .reg  = { .start = 0x00802000, .size = 0x00014578 },
596                 .mem2 = { .start = 0x00B00404, .size = 0x00001000 },
597                 .mem3 = { .start = 0x00C00000, .size = 0x00000400 },
598         },
599         [PART_WORK] = {
600                 .mem  = { .start = 0x00800000, .size  = 0x000050FC },
601                 .reg  = { .start = 0x00B00404, .size  = 0x00001000 },
602                 .mem2 = { .start = 0x00C00000, .size  = 0x00000400 },
603                 .mem3 = { .start = 0x00401594, .size  = 0x00001020 },
604         },
605         [PART_PHY_INIT] = {
606                 .mem  = { .start = WL18XX_PHY_INIT_MEM_ADDR,
607                           .size  = WL18XX_PHY_INIT_MEM_SIZE },
608                 .reg  = { .start = 0x00000000, .size = 0x00000000 },
609                 .mem2 = { .start = 0x00000000, .size = 0x00000000 },
610                 .mem3 = { .start = 0x00000000, .size = 0x00000000 },
611         },
612 };
613
614 static const int wl18xx_rtable[REG_TABLE_LEN] = {
615         [REG_ECPU_CONTROL]              = WL18XX_REG_ECPU_CONTROL,
616         [REG_INTERRUPT_NO_CLEAR]        = WL18XX_REG_INTERRUPT_NO_CLEAR,
617         [REG_INTERRUPT_ACK]             = WL18XX_REG_INTERRUPT_ACK,
618         [REG_COMMAND_MAILBOX_PTR]       = WL18XX_REG_COMMAND_MAILBOX_PTR,
619         [REG_EVENT_MAILBOX_PTR]         = WL18XX_REG_EVENT_MAILBOX_PTR,
620         [REG_INTERRUPT_TRIG]            = WL18XX_REG_INTERRUPT_TRIG_H,
621         [REG_INTERRUPT_MASK]            = WL18XX_REG_INTERRUPT_MASK,
622         [REG_PC_ON_RECOVERY]            = WL18XX_SCR_PAD4,
623         [REG_CHIP_ID_B]                 = WL18XX_REG_CHIP_ID_B,
624         [REG_CMD_MBOX_ADDRESS]          = WL18XX_CMD_MBOX_ADDRESS,
625
626         /* data access memory addresses, used with partition translation */
627         [REG_SLV_MEM_DATA]              = WL18XX_SLV_MEM_DATA,
628         [REG_SLV_REG_DATA]              = WL18XX_SLV_REG_DATA,
629
630         /* raw data access memory addresses */
631         [REG_RAW_FW_STATUS_ADDR]        = WL18XX_FW_STATUS_ADDR,
632 };
633
634 static const struct wl18xx_clk_cfg wl18xx_clk_table_coex[NUM_CLOCK_CONFIGS] = {
635         [CLOCK_CONFIG_16_2_M]   = { 8,  121, 0, 0, false },
636         [CLOCK_CONFIG_16_368_M] = { 8,  120, 0, 0, false },
637         [CLOCK_CONFIG_16_8_M]   = { 8,  117, 0, 0, false },
638         [CLOCK_CONFIG_19_2_M]   = { 10, 128, 0, 0, false },
639         [CLOCK_CONFIG_26_M]     = { 11, 104, 0, 0, false },
640         [CLOCK_CONFIG_32_736_M] = { 8,  120, 0, 0, false },
641         [CLOCK_CONFIG_33_6_M]   = { 8,  117, 0, 0, false },
642         [CLOCK_CONFIG_38_468_M] = { 10, 128, 0, 0, false },
643         [CLOCK_CONFIG_52_M]     = { 11, 104, 0, 0, false },
644 };
645
646 static const struct wl18xx_clk_cfg wl18xx_clk_table[NUM_CLOCK_CONFIGS] = {
647         [CLOCK_CONFIG_16_2_M]   = { 7,  104,  801, 4,  true },
648         [CLOCK_CONFIG_16_368_M] = { 9,  132, 3751, 4,  true },
649         [CLOCK_CONFIG_16_8_M]   = { 7,  100,    0, 0, false },
650         [CLOCK_CONFIG_19_2_M]   = { 8,  100,    0, 0, false },
651         [CLOCK_CONFIG_26_M]     = { 13, 120,    0, 0, false },
652         [CLOCK_CONFIG_32_736_M] = { 9,  132, 3751, 4,  true },
653         [CLOCK_CONFIG_33_6_M]   = { 7,  100,    0, 0, false },
654         [CLOCK_CONFIG_38_468_M] = { 8,  100,    0, 0, false },
655         [CLOCK_CONFIG_52_M]     = { 13, 120,    0, 0, false },
656 };
657
658 /* TODO: maybe move to a new header file? */
659 #define WL18XX_FW_NAME "ti-connectivity/wl18xx-fw-4.bin"
660
661 static int wl18xx_identify_chip(struct wl1271 *wl)
662 {
663         int ret = 0;
664
665         switch (wl->chip.id) {
666         case CHIP_ID_185x_PG20:
667                 wl1271_debug(DEBUG_BOOT, "chip id 0x%x (185x PG20)",
668                                  wl->chip.id);
669                 wl->sr_fw_name = WL18XX_FW_NAME;
670                 /* wl18xx uses the same firmware for PLT */
671                 wl->plt_fw_name = WL18XX_FW_NAME;
672                 wl->quirks |= WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN |
673                               WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN |
674                               WLCORE_QUIRK_NO_SCHED_SCAN_WHILE_CONN |
675                               WLCORE_QUIRK_TX_PAD_LAST_FRAME |
676                               WLCORE_QUIRK_REGDOMAIN_CONF |
677                               WLCORE_QUIRK_DUAL_PROBE_TMPL;
678
679                 wlcore_set_min_fw_ver(wl, WL18XX_CHIP_VER,
680                                       WL18XX_IFTYPE_VER,  WL18XX_MAJOR_VER,
681                                       WL18XX_SUBTYPE_VER, WL18XX_MINOR_VER,
682                                       /* there's no separate multi-role FW */
683                                       0, 0, 0, 0);
684                 break;
685         case CHIP_ID_185x_PG10:
686                 wl1271_warning("chip id 0x%x (185x PG10) is deprecated",
687                                wl->chip.id);
688                 ret = -ENODEV;
689                 goto out;
690
691         default:
692                 wl1271_warning("unsupported chip id: 0x%x", wl->chip.id);
693                 ret = -ENODEV;
694                 goto out;
695         }
696
697         wl->fw_mem_block_size = 272;
698         wl->fwlog_end = 0x40000000;
699
700         wl->scan_templ_id_2_4 = CMD_TEMPL_CFG_PROBE_REQ_2_4;
701         wl->scan_templ_id_5 = CMD_TEMPL_CFG_PROBE_REQ_5;
702         wl->sched_scan_templ_id_2_4 = CMD_TEMPL_PROBE_REQ_2_4_PERIODIC;
703         wl->sched_scan_templ_id_5 = CMD_TEMPL_PROBE_REQ_5_PERIODIC;
704         wl->max_channels_5 = WL18XX_MAX_CHANNELS_5GHZ;
705         wl->ba_rx_session_count_max = WL18XX_RX_BA_MAX_SESSIONS;
706 out:
707         return ret;
708 }
709
710 static int wl18xx_set_clk(struct wl1271 *wl)
711 {
712         u16 clk_freq;
713         int ret;
714
715         ret = wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]);
716         if (ret < 0)
717                 goto out;
718
719         /* TODO: PG2: apparently we need to read the clk type */
720
721         ret = wl18xx_top_reg_read(wl, PRIMARY_CLK_DETECT, &clk_freq);
722         if (ret < 0)
723                 goto out;
724
725         wl1271_debug(DEBUG_BOOT, "clock freq %d (%d, %d, %d, %d, %s)", clk_freq,
726                      wl18xx_clk_table[clk_freq].n, wl18xx_clk_table[clk_freq].m,
727                      wl18xx_clk_table[clk_freq].p, wl18xx_clk_table[clk_freq].q,
728                      wl18xx_clk_table[clk_freq].swallow ? "swallow" : "spit");
729
730         /* coex PLL configuration */
731         ret = wl18xx_top_reg_write(wl, PLLSH_COEX_PLL_N,
732                                    wl18xx_clk_table_coex[clk_freq].n);
733         if (ret < 0)
734                 goto out;
735
736         ret = wl18xx_top_reg_write(wl, PLLSH_COEX_PLL_M,
737                                    wl18xx_clk_table_coex[clk_freq].m);
738         if (ret < 0)
739                 goto out;
740
741         /* bypass the swallowing logic */
742         ret = wl18xx_top_reg_write(wl, PLLSH_COEX_PLL_SWALLOW_EN,
743                                    PLLSH_COEX_PLL_SWALLOW_EN_VAL1);
744         if (ret < 0)
745                 goto out;
746
747         ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_N,
748                                    wl18xx_clk_table[clk_freq].n);
749         if (ret < 0)
750                 goto out;
751
752         ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_M,
753                                    wl18xx_clk_table[clk_freq].m);
754         if (ret < 0)
755                 goto out;
756
757         if (wl18xx_clk_table[clk_freq].swallow) {
758                 /* first the 16 lower bits */
759                 ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_Q_FACTOR_CFG_1,
760                                            wl18xx_clk_table[clk_freq].q &
761                                            PLLSH_WCS_PLL_Q_FACTOR_CFG_1_MASK);
762                 if (ret < 0)
763                         goto out;
764
765                 /* then the 16 higher bits, masked out */
766                 ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_Q_FACTOR_CFG_2,
767                                         (wl18xx_clk_table[clk_freq].q >> 16) &
768                                         PLLSH_WCS_PLL_Q_FACTOR_CFG_2_MASK);
769                 if (ret < 0)
770                         goto out;
771
772                 /* first the 16 lower bits */
773                 ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_P_FACTOR_CFG_1,
774                                            wl18xx_clk_table[clk_freq].p &
775                                            PLLSH_WCS_PLL_P_FACTOR_CFG_1_MASK);
776                 if (ret < 0)
777                         goto out;
778
779                 /* then the 16 higher bits, masked out */
780                 ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_P_FACTOR_CFG_2,
781                                         (wl18xx_clk_table[clk_freq].p >> 16) &
782                                         PLLSH_WCS_PLL_P_FACTOR_CFG_2_MASK);
783                 if (ret < 0)
784                         goto out;
785         } else {
786                 ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_SWALLOW_EN,
787                                            PLLSH_WCS_PLL_SWALLOW_EN_VAL2);
788                 if (ret < 0)
789                         goto out;
790         }
791
792         /* choose WCS PLL */
793         ret = wl18xx_top_reg_write(wl, PLLSH_WL_PLL_SEL,
794                                    PLLSH_WL_PLL_SEL_WCS_PLL);
795         if (ret < 0)
796                 goto out;
797
798         /* enable both PLLs */
799         ret = wl18xx_top_reg_write(wl, PLLSH_WL_PLL_EN, PLLSH_WL_PLL_EN_VAL1);
800         if (ret < 0)
801                 goto out;
802
803         udelay(1000);
804
805         /* disable coex PLL */
806         ret = wl18xx_top_reg_write(wl, PLLSH_WL_PLL_EN, PLLSH_WL_PLL_EN_VAL2);
807         if (ret < 0)
808                 goto out;
809
810         /* reset the swallowing logic */
811         ret = wl18xx_top_reg_write(wl, PLLSH_COEX_PLL_SWALLOW_EN,
812                                    PLLSH_COEX_PLL_SWALLOW_EN_VAL2);
813
814 out:
815         return ret;
816 }
817
818 static int wl18xx_boot_soft_reset(struct wl1271 *wl)
819 {
820         int ret;
821
822         /* disable Rx/Tx */
823         ret = wlcore_write32(wl, WL18XX_ENABLE, 0x0);
824         if (ret < 0)
825                 goto out;
826
827         /* disable auto calibration on start*/
828         ret = wlcore_write32(wl, WL18XX_SPARE_A2, 0xffff);
829
830 out:
831         return ret;
832 }
833
834 static int wl18xx_pre_boot(struct wl1271 *wl)
835 {
836         int ret;
837
838         ret = wl18xx_set_clk(wl);
839         if (ret < 0)
840                 goto out;
841
842         /* Continue the ELP wake up sequence */
843         ret = wlcore_write32(wl, WL18XX_WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL);
844         if (ret < 0)
845                 goto out;
846
847         udelay(500);
848
849         ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
850         if (ret < 0)
851                 goto out;
852
853         /* Disable interrupts */
854         ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
855         if (ret < 0)
856                 goto out;
857
858         ret = wl18xx_boot_soft_reset(wl);
859
860 out:
861         return ret;
862 }
863
864 static int wl18xx_pre_upload(struct wl1271 *wl)
865 {
866         u32 tmp;
867         int ret;
868         u16 irq_invert;
869
870         BUILD_BUG_ON(sizeof(struct wl18xx_mac_and_phy_params) >
871                 WL18XX_PHY_INIT_MEM_SIZE);
872
873         ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
874         if (ret < 0)
875                 goto out;
876
877         /* TODO: check if this is all needed */
878         ret = wlcore_write32(wl, WL18XX_EEPROMLESS_IND, WL18XX_EEPROMLESS_IND);
879         if (ret < 0)
880                 goto out;
881
882         ret = wlcore_read_reg(wl, REG_CHIP_ID_B, &tmp);
883         if (ret < 0)
884                 goto out;
885
886         wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp);
887
888         ret = wlcore_read32(wl, WL18XX_SCR_PAD2, &tmp);
889         if (ret < 0)
890                 goto out;
891
892         /*
893          * Workaround for FDSP code RAM corruption (needed for PG2.1
894          * and newer; for older chips it's a NOP).  Change FDSP clock
895          * settings so that it's muxed to the ATGP clock instead of
896          * its own clock.
897          */
898
899         ret = wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]);
900         if (ret < 0)
901                 goto out;
902
903         /* disable FDSP clock */
904         ret = wlcore_write32(wl, WL18XX_PHY_FPGA_SPARE_1,
905                              MEM_FDSP_CLK_120_DISABLE);
906         if (ret < 0)
907                 goto out;
908
909         /* set ATPG clock toward FDSP Code RAM rather than its own clock */
910         ret = wlcore_write32(wl, WL18XX_PHY_FPGA_SPARE_1,
911                              MEM_FDSP_CODERAM_FUNC_CLK_SEL);
912         if (ret < 0)
913                 goto out;
914
915         /* re-enable FDSP clock */
916         ret = wlcore_write32(wl, WL18XX_PHY_FPGA_SPARE_1,
917                              MEM_FDSP_CLK_120_ENABLE);
918         if (ret < 0)
919                 goto out;
920
921         ret = irq_get_trigger_type(wl->irq);
922         if ((ret == IRQ_TYPE_LEVEL_LOW) || (ret == IRQ_TYPE_EDGE_FALLING)) {
923                 wl1271_info("using inverted interrupt logic: %d", ret);
924                 ret = wlcore_set_partition(wl,
925                                            &wl->ptable[PART_TOP_PRCM_ELP_SOC]);
926                 if (ret < 0)
927                         goto out;
928
929                 ret = wl18xx_top_reg_read(wl, TOP_FN0_CCCR_REG_32, &irq_invert);
930                 if (ret < 0)
931                         goto out;
932
933                 irq_invert |= BIT(1);
934                 ret = wl18xx_top_reg_write(wl, TOP_FN0_CCCR_REG_32, irq_invert);
935                 if (ret < 0)
936                         goto out;
937
938                 ret = wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]);
939         }
940
941 out:
942         return ret;
943 }
944
945 static int wl18xx_set_mac_and_phy(struct wl1271 *wl)
946 {
947         struct wl18xx_priv *priv = wl->priv;
948         struct wl18xx_mac_and_phy_params *params;
949         int ret;
950
951         params = kmemdup(&priv->conf.phy, sizeof(*params), GFP_KERNEL);
952         if (!params) {
953                 ret = -ENOMEM;
954                 goto out;
955         }
956
957         ret = wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]);
958         if (ret < 0)
959                 goto out;
960
961         ret = wlcore_write(wl, WL18XX_PHY_INIT_MEM_ADDR, params,
962                            sizeof(*params), false);
963
964 out:
965         kfree(params);
966         return ret;
967 }
968
969 static int wl18xx_enable_interrupts(struct wl1271 *wl)
970 {
971         u32 event_mask, intr_mask;
972         int ret;
973
974         event_mask = WL18XX_ACX_EVENTS_VECTOR;
975         intr_mask = WL18XX_INTR_MASK;
976
977         ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK, event_mask);
978         if (ret < 0)
979                 goto out;
980
981         wlcore_enable_interrupts(wl);
982
983         ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK,
984                                WL1271_ACX_INTR_ALL & ~intr_mask);
985         if (ret < 0)
986                 goto disable_interrupts;
987
988         return ret;
989
990 disable_interrupts:
991         wlcore_disable_interrupts(wl);
992
993 out:
994         return ret;
995 }
996
997 static int wl18xx_boot(struct wl1271 *wl)
998 {
999         int ret;
1000
1001         ret = wl18xx_pre_boot(wl);
1002         if (ret < 0)
1003                 goto out;
1004
1005         ret = wl18xx_pre_upload(wl);
1006         if (ret < 0)
1007                 goto out;
1008
1009         ret = wlcore_boot_upload_firmware(wl);
1010         if (ret < 0)
1011                 goto out;
1012
1013         ret = wl18xx_set_mac_and_phy(wl);
1014         if (ret < 0)
1015                 goto out;
1016
1017         wl->event_mask = BSS_LOSS_EVENT_ID |
1018                 SCAN_COMPLETE_EVENT_ID |
1019                 RADAR_DETECTED_EVENT_ID |
1020                 RSSI_SNR_TRIGGER_0_EVENT_ID |
1021                 PERIODIC_SCAN_COMPLETE_EVENT_ID |
1022                 PERIODIC_SCAN_REPORT_EVENT_ID |
1023                 DUMMY_PACKET_EVENT_ID |
1024                 PEER_REMOVE_COMPLETE_EVENT_ID |
1025                 BA_SESSION_RX_CONSTRAINT_EVENT_ID |
1026                 REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID |
1027                 INACTIVE_STA_EVENT_ID |
1028                 CHANNEL_SWITCH_COMPLETE_EVENT_ID |
1029                 DFS_CHANNELS_CONFIG_COMPLETE_EVENT |
1030                 SMART_CONFIG_SYNC_EVENT_ID |
1031                 SMART_CONFIG_DECODE_EVENT_ID |
1032                 TIME_SYNC_EVENT_ID |
1033                 FW_LOGGER_INDICATION |
1034                 RX_BA_WIN_SIZE_CHANGE_EVENT_ID;
1035
1036         wl->ap_event_mask = MAX_TX_FAILURE_EVENT_ID;
1037
1038         ret = wlcore_boot_run_firmware(wl);
1039         if (ret < 0)
1040                 goto out;
1041
1042         ret = wl18xx_enable_interrupts(wl);
1043
1044 out:
1045         return ret;
1046 }
1047
1048 static int wl18xx_trigger_cmd(struct wl1271 *wl, int cmd_box_addr,
1049                                void *buf, size_t len)
1050 {
1051         struct wl18xx_priv *priv = wl->priv;
1052
1053         memcpy(priv->cmd_buf, buf, len);
1054         memset(priv->cmd_buf + len, 0, WL18XX_CMD_MAX_SIZE - len);
1055
1056         return wlcore_write(wl, cmd_box_addr, priv->cmd_buf,
1057                             WL18XX_CMD_MAX_SIZE, false);
1058 }
1059
1060 static int wl18xx_ack_event(struct wl1271 *wl)
1061 {
1062         return wlcore_write_reg(wl, REG_INTERRUPT_TRIG,
1063                                 WL18XX_INTR_TRIG_EVENT_ACK);
1064 }
1065
1066 static u32 wl18xx_calc_tx_blocks(struct wl1271 *wl, u32 len, u32 spare_blks)
1067 {
1068         u32 blk_size = WL18XX_TX_HW_BLOCK_SIZE;
1069         return (len + blk_size - 1) / blk_size + spare_blks;
1070 }
1071
1072 static void
1073 wl18xx_set_tx_desc_blocks(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc,
1074                           u32 blks, u32 spare_blks)
1075 {
1076         desc->wl18xx_mem.total_mem_blocks = blks;
1077 }
1078
1079 static void
1080 wl18xx_set_tx_desc_data_len(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc,
1081                             struct sk_buff *skb)
1082 {
1083         desc->length = cpu_to_le16(skb->len);
1084
1085         /* if only the last frame is to be padded, we unset this bit on Tx */
1086         if (wl->quirks & WLCORE_QUIRK_TX_PAD_LAST_FRAME)
1087                 desc->wl18xx_mem.ctrl = WL18XX_TX_CTRL_NOT_PADDED;
1088         else
1089                 desc->wl18xx_mem.ctrl = 0;
1090
1091         wl1271_debug(DEBUG_TX, "tx_fill_hdr: hlid: %d "
1092                      "len: %d life: %d mem: %d", desc->hlid,
1093                      le16_to_cpu(desc->length),
1094                      le16_to_cpu(desc->life_time),
1095                      desc->wl18xx_mem.total_mem_blocks);
1096 }
1097
1098 static enum wl_rx_buf_align
1099 wl18xx_get_rx_buf_align(struct wl1271 *wl, u32 rx_desc)
1100 {
1101         if (rx_desc & RX_BUF_PADDED_PAYLOAD)
1102                 return WLCORE_RX_BUF_PADDED;
1103
1104         return WLCORE_RX_BUF_ALIGNED;
1105 }
1106
1107 static u32 wl18xx_get_rx_packet_len(struct wl1271 *wl, void *rx_data,
1108                                     u32 data_len)
1109 {
1110         struct wl1271_rx_descriptor *desc = rx_data;
1111
1112         /* invalid packet */
1113         if (data_len < sizeof(*desc))
1114                 return 0;
1115
1116         return data_len - sizeof(*desc);
1117 }
1118
1119 static void wl18xx_tx_immediate_completion(struct wl1271 *wl)
1120 {
1121         wl18xx_tx_immediate_complete(wl);
1122 }
1123
1124 static int wl18xx_set_host_cfg_bitmap(struct wl1271 *wl, u32 extra_mem_blk)
1125 {
1126         int ret;
1127         u32 sdio_align_size = 0;
1128         u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE |
1129                               HOST_IF_CFG_ADD_RX_ALIGNMENT;
1130
1131         /* Enable Tx SDIO padding */
1132         if (wl->quirks & WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN) {
1133                 host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK;
1134                 sdio_align_size = WL12XX_BUS_BLOCK_SIZE;
1135         }
1136
1137         /* Enable Rx SDIO padding */
1138         if (wl->quirks & WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN) {
1139                 host_cfg_bitmap |= HOST_IF_CFG_RX_PAD_TO_SDIO_BLK;
1140                 sdio_align_size = WL12XX_BUS_BLOCK_SIZE;
1141         }
1142
1143         ret = wl18xx_acx_host_if_cfg_bitmap(wl, host_cfg_bitmap,
1144                                             sdio_align_size, extra_mem_blk,
1145                                             WL18XX_HOST_IF_LEN_SIZE_FIELD);
1146         if (ret < 0)
1147                 return ret;
1148
1149         return 0;
1150 }
1151
1152 static int wl18xx_hw_init(struct wl1271 *wl)
1153 {
1154         int ret;
1155         struct wl18xx_priv *priv = wl->priv;
1156
1157         /* (re)init private structures. Relevant on recovery as well. */
1158         priv->last_fw_rls_idx = 0;
1159         priv->extra_spare_key_count = 0;
1160
1161         /* set the default amount of spare blocks in the bitmap */
1162         ret = wl18xx_set_host_cfg_bitmap(wl, WL18XX_TX_HW_BLOCK_SPARE);
1163         if (ret < 0)
1164                 return ret;
1165
1166         /* set the dynamic fw traces bitmap */
1167         ret = wl18xx_acx_dynamic_fw_traces(wl);
1168         if (ret < 0)
1169                 return ret;
1170
1171         if (checksum_param) {
1172                 ret = wl18xx_acx_set_checksum_state(wl);
1173                 if (ret != 0)
1174                         return ret;
1175         }
1176
1177         return ret;
1178 }
1179
1180 static void wl18xx_convert_fw_status(struct wl1271 *wl, void *raw_fw_status,
1181                                      struct wl_fw_status *fw_status)
1182 {
1183         struct wl18xx_fw_status *int_fw_status = raw_fw_status;
1184
1185         fw_status->intr = le32_to_cpu(int_fw_status->intr);
1186         fw_status->fw_rx_counter = int_fw_status->fw_rx_counter;
1187         fw_status->drv_rx_counter = int_fw_status->drv_rx_counter;
1188         fw_status->tx_results_counter = int_fw_status->tx_results_counter;
1189         fw_status->rx_pkt_descs = int_fw_status->rx_pkt_descs;
1190
1191         fw_status->fw_localtime = le32_to_cpu(int_fw_status->fw_localtime);
1192         fw_status->link_ps_bitmap = le32_to_cpu(int_fw_status->link_ps_bitmap);
1193         fw_status->link_fast_bitmap =
1194                         le32_to_cpu(int_fw_status->link_fast_bitmap);
1195         fw_status->total_released_blks =
1196                         le32_to_cpu(int_fw_status->total_released_blks);
1197         fw_status->tx_total = le32_to_cpu(int_fw_status->tx_total);
1198
1199         fw_status->counters.tx_released_pkts =
1200                         int_fw_status->counters.tx_released_pkts;
1201         fw_status->counters.tx_lnk_free_pkts =
1202                         int_fw_status->counters.tx_lnk_free_pkts;
1203         fw_status->counters.tx_voice_released_blks =
1204                         int_fw_status->counters.tx_voice_released_blks;
1205         fw_status->counters.tx_last_rate =
1206                         int_fw_status->counters.tx_last_rate;
1207         fw_status->counters.tx_last_rate_mbps =
1208                         int_fw_status->counters.tx_last_rate_mbps;
1209         fw_status->counters.hlid =
1210                         int_fw_status->counters.hlid;
1211
1212         fw_status->log_start_addr = le32_to_cpu(int_fw_status->log_start_addr);
1213
1214         fw_status->priv = &int_fw_status->priv;
1215 }
1216
1217 static void wl18xx_set_tx_desc_csum(struct wl1271 *wl,
1218                                     struct wl1271_tx_hw_descr *desc,
1219                                     struct sk_buff *skb)
1220 {
1221         u32 ip_hdr_offset;
1222         struct iphdr *ip_hdr;
1223
1224         if (!checksum_param) {
1225                 desc->wl18xx_checksum_data = 0;
1226                 return;
1227         }
1228
1229         if (skb->ip_summed != CHECKSUM_PARTIAL) {
1230                 desc->wl18xx_checksum_data = 0;
1231                 return;
1232         }
1233
1234         ip_hdr_offset = skb_network_header(skb) - skb_mac_header(skb);
1235         if (WARN_ON(ip_hdr_offset >= (1<<7))) {
1236                 desc->wl18xx_checksum_data = 0;
1237                 return;
1238         }
1239
1240         desc->wl18xx_checksum_data = ip_hdr_offset << 1;
1241
1242         /* FW is interested only in the LSB of the protocol  TCP=0 UDP=1 */
1243         ip_hdr = (void *)skb_network_header(skb);
1244         desc->wl18xx_checksum_data |= (ip_hdr->protocol & 0x01);
1245 }
1246
1247 static void wl18xx_set_rx_csum(struct wl1271 *wl,
1248                                struct wl1271_rx_descriptor *desc,
1249                                struct sk_buff *skb)
1250 {
1251         if (desc->status & WL18XX_RX_CHECKSUM_MASK)
1252                 skb->ip_summed = CHECKSUM_UNNECESSARY;
1253 }
1254
1255 static bool wl18xx_is_mimo_supported(struct wl1271 *wl)
1256 {
1257         struct wl18xx_priv *priv = wl->priv;
1258
1259         /* only support MIMO with multiple antennas, and when SISO
1260          * is not forced through config
1261          */
1262         return (priv->conf.phy.number_of_assembled_ant2_4 >= 2) &&
1263                (priv->conf.ht.mode != HT_MODE_WIDE) &&
1264                (priv->conf.ht.mode != HT_MODE_SISO20);
1265 }
1266
1267 /*
1268  * TODO: instead of having these two functions to get the rate mask,
1269  * we should modify the wlvif->rate_set instead
1270  */
1271 static u32 wl18xx_sta_get_ap_rate_mask(struct wl1271 *wl,
1272                                        struct wl12xx_vif *wlvif)
1273 {
1274         u32 hw_rate_set = wlvif->rate_set;
1275
1276         if (wlvif->channel_type == NL80211_CHAN_HT40MINUS ||
1277             wlvif->channel_type == NL80211_CHAN_HT40PLUS) {
1278                 wl1271_debug(DEBUG_ACX, "using wide channel rate mask");
1279                 hw_rate_set |= CONF_TX_RATE_USE_WIDE_CHAN;
1280
1281                 /* we don't support MIMO in wide-channel mode */
1282                 hw_rate_set &= ~CONF_TX_MIMO_RATES;
1283         } else if (wl18xx_is_mimo_supported(wl)) {
1284                 wl1271_debug(DEBUG_ACX, "using MIMO channel rate mask");
1285                 hw_rate_set |= CONF_TX_MIMO_RATES;
1286         }
1287
1288         return hw_rate_set;
1289 }
1290
1291 static u32 wl18xx_ap_get_mimo_wide_rate_mask(struct wl1271 *wl,
1292                                              struct wl12xx_vif *wlvif)
1293 {
1294         if (wlvif->channel_type == NL80211_CHAN_HT40MINUS ||
1295             wlvif->channel_type == NL80211_CHAN_HT40PLUS) {
1296                 wl1271_debug(DEBUG_ACX, "using wide channel rate mask");
1297
1298                 /* sanity check - we don't support this */
1299                 if (WARN_ON(wlvif->band != NL80211_BAND_5GHZ))
1300                         return 0;
1301
1302                 return CONF_TX_RATE_USE_WIDE_CHAN;
1303         } else if (wl18xx_is_mimo_supported(wl) &&
1304                    wlvif->band == NL80211_BAND_2GHZ) {
1305                 wl1271_debug(DEBUG_ACX, "using MIMO rate mask");
1306                 /*
1307                  * we don't care about HT channel here - if a peer doesn't
1308                  * support MIMO, we won't enable it in its rates
1309                  */
1310                 return CONF_TX_MIMO_RATES;
1311         } else {
1312                 return 0;
1313         }
1314 }
1315
1316 static const char *wl18xx_rdl_name(enum wl18xx_rdl_num rdl_num)
1317 {
1318         switch (rdl_num) {
1319         case RDL_1_HP:
1320                 return "183xH";
1321         case RDL_2_SP:
1322                 return "183x or 180x";
1323         case RDL_3_HP:
1324                 return "187xH";
1325         case RDL_4_SP:
1326                 return "187x";
1327         case RDL_5_SP:
1328                 return "RDL11 - Not Supported";
1329         case RDL_6_SP:
1330                 return "180xD";
1331         case RDL_7_SP:
1332                 return "RDL13 - Not Supported (1893Q)";
1333         case RDL_8_SP:
1334                 return "18xxQ";
1335         case RDL_NONE:
1336                 return "UNTRIMMED";
1337         default:
1338                 return "UNKNOWN";
1339         }
1340 }
1341
1342 static int wl18xx_get_pg_ver(struct wl1271 *wl, s8 *ver)
1343 {
1344         u32 fuse;
1345         s8 rom = 0, metal = 0, pg_ver = 0, rdl_ver = 0, package_type = 0;
1346         int ret;
1347
1348         ret = wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]);
1349         if (ret < 0)
1350                 goto out;
1351
1352         ret = wlcore_read32(wl, WL18XX_REG_FUSE_DATA_2_3, &fuse);
1353         if (ret < 0)
1354                 goto out;
1355
1356         package_type = (fuse >> WL18XX_PACKAGE_TYPE_OFFSET) & 1;
1357
1358         ret = wlcore_read32(wl, WL18XX_REG_FUSE_DATA_1_3, &fuse);
1359         if (ret < 0)
1360                 goto out;
1361
1362         pg_ver = (fuse & WL18XX_PG_VER_MASK) >> WL18XX_PG_VER_OFFSET;
1363         rom = (fuse & WL18XX_ROM_VER_MASK) >> WL18XX_ROM_VER_OFFSET;
1364
1365         if ((rom <= 0xE) && (package_type == WL18XX_PACKAGE_TYPE_WSP))
1366                 metal = (fuse & WL18XX_METAL_VER_MASK) >>
1367                         WL18XX_METAL_VER_OFFSET;
1368         else
1369                 metal = (fuse & WL18XX_NEW_METAL_VER_MASK) >>
1370                         WL18XX_NEW_METAL_VER_OFFSET;
1371
1372         ret = wlcore_read32(wl, WL18XX_REG_FUSE_DATA_2_3, &fuse);
1373         if (ret < 0)
1374                 goto out;
1375
1376         rdl_ver = (fuse & WL18XX_RDL_VER_MASK) >> WL18XX_RDL_VER_OFFSET;
1377
1378         wl1271_info("wl18xx HW: %s, PG %d.%d (ROM 0x%x)",
1379                     wl18xx_rdl_name(rdl_ver), pg_ver, metal, rom);
1380
1381         if (ver)
1382                 *ver = pg_ver;
1383
1384         ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
1385
1386 out:
1387         return ret;
1388 }
1389
1390 static int wl18xx_load_conf_file(struct device *dev, struct wlcore_conf *conf,
1391                                  struct wl18xx_priv_conf *priv_conf,
1392                                  const char *file)
1393 {
1394         struct wlcore_conf_file *conf_file;
1395         const struct firmware *fw;
1396         int ret;
1397
1398         ret = request_firmware(&fw, file, dev);
1399         if (ret < 0) {
1400                 wl1271_error("could not get configuration binary %s: %d",
1401                              file, ret);
1402                 return ret;
1403         }
1404
1405         if (fw->size != WL18XX_CONF_SIZE) {
1406                 wl1271_error("%s configuration binary size is wrong, expected %zu got %zu",
1407                              file, WL18XX_CONF_SIZE, fw->size);
1408                 ret = -EINVAL;
1409                 goto out_release;
1410         }
1411
1412         conf_file = (struct wlcore_conf_file *) fw->data;
1413
1414         if (conf_file->header.magic != cpu_to_le32(WL18XX_CONF_MAGIC)) {
1415                 wl1271_error("configuration binary file magic number mismatch, "
1416                              "expected 0x%0x got 0x%0x", WL18XX_CONF_MAGIC,
1417                              conf_file->header.magic);
1418                 ret = -EINVAL;
1419                 goto out_release;
1420         }
1421
1422         if (conf_file->header.version != cpu_to_le32(WL18XX_CONF_VERSION)) {
1423                 wl1271_error("configuration binary file version not supported, "
1424                              "expected 0x%08x got 0x%08x",
1425                              WL18XX_CONF_VERSION, conf_file->header.version);
1426                 ret = -EINVAL;
1427                 goto out_release;
1428         }
1429
1430         memcpy(conf, &conf_file->core, sizeof(*conf));
1431         memcpy(priv_conf, &conf_file->priv, sizeof(*priv_conf));
1432
1433 out_release:
1434         release_firmware(fw);
1435         return ret;
1436 }
1437
1438 static int wl18xx_conf_init(struct wl1271 *wl, struct device *dev)
1439 {
1440         struct platform_device *pdev = wl->pdev;
1441         struct wlcore_platdev_data *pdata = dev_get_platdata(&pdev->dev);
1442         struct wl18xx_priv *priv = wl->priv;
1443
1444         if (wl18xx_load_conf_file(dev, &wl->conf, &priv->conf,
1445                                   pdata->family->cfg_name) < 0) {
1446                 wl1271_warning("falling back to default config");
1447
1448                 /* apply driver default configuration */
1449                 memcpy(&wl->conf, &wl18xx_conf, sizeof(wl->conf));
1450                 /* apply default private configuration */
1451                 memcpy(&priv->conf, &wl18xx_default_priv_conf,
1452                        sizeof(priv->conf));
1453         }
1454
1455         return 0;
1456 }
1457
1458 static int wl18xx_plt_init(struct wl1271 *wl)
1459 {
1460         int ret;
1461
1462         /* calibrator based auto/fem detect not supported for 18xx */
1463         if (wl->plt_mode == PLT_FEM_DETECT) {
1464                 wl1271_error("wl18xx_plt_init: PLT FEM_DETECT not supported");
1465                 return -EINVAL;
1466         }
1467
1468         ret = wlcore_write32(wl, WL18XX_SCR_PAD8, WL18XX_SCR_PAD8_PLT);
1469         if (ret < 0)
1470                 return ret;
1471
1472         return wl->ops->boot(wl);
1473 }
1474
1475 static int wl18xx_get_mac(struct wl1271 *wl)
1476 {
1477         u32 mac1, mac2;
1478         int ret;
1479
1480         ret = wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]);
1481         if (ret < 0)
1482                 goto out;
1483
1484         ret = wlcore_read32(wl, WL18XX_REG_FUSE_BD_ADDR_1, &mac1);
1485         if (ret < 0)
1486                 goto out;
1487
1488         ret = wlcore_read32(wl, WL18XX_REG_FUSE_BD_ADDR_2, &mac2);
1489         if (ret < 0)
1490                 goto out;
1491
1492         /* these are the two parts of the BD_ADDR */
1493         wl->fuse_oui_addr = ((mac2 & 0xffff) << 8) +
1494                 ((mac1 & 0xff000000) >> 24);
1495         wl->fuse_nic_addr = (mac1 & 0xffffff);
1496
1497         if (!wl->fuse_oui_addr && !wl->fuse_nic_addr) {
1498                 u8 mac[ETH_ALEN];
1499
1500                 eth_random_addr(mac);
1501
1502                 wl->fuse_oui_addr = (mac[0] << 16) + (mac[1] << 8) + mac[2];
1503                 wl->fuse_nic_addr = (mac[3] << 16) + (mac[4] << 8) + mac[5];
1504                 wl1271_warning("MAC address from fuse not available, using random locally administered addresses.");
1505         }
1506
1507         ret = wlcore_set_partition(wl, &wl->ptable[PART_DOWN]);
1508
1509 out:
1510         return ret;
1511 }
1512
1513 static int wl18xx_handle_static_data(struct wl1271 *wl,
1514                                      struct wl1271_static_data *static_data)
1515 {
1516         struct wl18xx_static_data_priv *static_data_priv =
1517                 (struct wl18xx_static_data_priv *) static_data->priv;
1518
1519         strncpy(wl->chip.phy_fw_ver_str, static_data_priv->phy_version,
1520                 sizeof(wl->chip.phy_fw_ver_str));
1521
1522         /* make sure the string is NULL-terminated */
1523         wl->chip.phy_fw_ver_str[sizeof(wl->chip.phy_fw_ver_str) - 1] = '\0';
1524
1525         wl1271_info("PHY firmware version: %s", static_data_priv->phy_version);
1526
1527         return 0;
1528 }
1529
1530 static int wl18xx_get_spare_blocks(struct wl1271 *wl, bool is_gem)
1531 {
1532         struct wl18xx_priv *priv = wl->priv;
1533
1534         /* If we have keys requiring extra spare, indulge them */
1535         if (priv->extra_spare_key_count)
1536                 return WL18XX_TX_HW_EXTRA_BLOCK_SPARE;
1537
1538         return WL18XX_TX_HW_BLOCK_SPARE;
1539 }
1540
1541 static int wl18xx_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
1542                           struct ieee80211_vif *vif,
1543                           struct ieee80211_sta *sta,
1544                           struct ieee80211_key_conf *key_conf)
1545 {
1546         struct wl18xx_priv *priv = wl->priv;
1547         bool change_spare = false, special_enc;
1548         int ret;
1549
1550         wl1271_debug(DEBUG_CRYPT, "extra spare keys before: %d",
1551                      priv->extra_spare_key_count);
1552
1553         special_enc = key_conf->cipher == WL1271_CIPHER_SUITE_GEM ||
1554                       key_conf->cipher == WLAN_CIPHER_SUITE_TKIP;
1555
1556         ret = wlcore_set_key(wl, cmd, vif, sta, key_conf);
1557         if (ret < 0)
1558                 goto out;
1559
1560         /*
1561          * when adding the first or removing the last GEM/TKIP key,
1562          * we have to adjust the number of spare blocks.
1563          */
1564         if (special_enc) {
1565                 if (cmd == SET_KEY) {
1566                         /* first key */
1567                         change_spare = (priv->extra_spare_key_count == 0);
1568                         priv->extra_spare_key_count++;
1569                 } else if (cmd == DISABLE_KEY) {
1570                         /* last key */
1571                         change_spare = (priv->extra_spare_key_count == 1);
1572                         priv->extra_spare_key_count--;
1573                 }
1574         }
1575
1576         wl1271_debug(DEBUG_CRYPT, "extra spare keys after: %d",
1577                      priv->extra_spare_key_count);
1578
1579         if (!change_spare)
1580                 goto out;
1581
1582         /* key is now set, change the spare blocks */
1583         if (priv->extra_spare_key_count)
1584                 ret = wl18xx_set_host_cfg_bitmap(wl,
1585                                         WL18XX_TX_HW_EXTRA_BLOCK_SPARE);
1586         else
1587                 ret = wl18xx_set_host_cfg_bitmap(wl,
1588                                         WL18XX_TX_HW_BLOCK_SPARE);
1589
1590 out:
1591         return ret;
1592 }
1593
1594 static u32 wl18xx_pre_pkt_send(struct wl1271 *wl,
1595                                u32 buf_offset, u32 last_len)
1596 {
1597         if (wl->quirks & WLCORE_QUIRK_TX_PAD_LAST_FRAME) {
1598                 struct wl1271_tx_hw_descr *last_desc;
1599
1600                 /* get the last TX HW descriptor written to the aggr buf */
1601                 last_desc = (struct wl1271_tx_hw_descr *)(wl->aggr_buf +
1602                                                         buf_offset - last_len);
1603
1604                 /* the last frame is padded up to an SDIO block */
1605                 last_desc->wl18xx_mem.ctrl &= ~WL18XX_TX_CTRL_NOT_PADDED;
1606                 return ALIGN(buf_offset, WL12XX_BUS_BLOCK_SIZE);
1607         }
1608
1609         /* no modifications */
1610         return buf_offset;
1611 }
1612
1613 static void wl18xx_sta_rc_update(struct wl1271 *wl,
1614                                  struct wl12xx_vif *wlvif)
1615 {
1616         bool wide = wlvif->rc_update_bw >= IEEE80211_STA_RX_BW_40;
1617
1618         wl1271_debug(DEBUG_MAC80211, "mac80211 sta_rc_update wide %d", wide);
1619
1620         /* sanity */
1621         if (WARN_ON(wlvif->bss_type != BSS_TYPE_STA_BSS))
1622                 return;
1623
1624         /* ignore the change before association */
1625         if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
1626                 return;
1627
1628         /*
1629          * If we started out as wide, we can change the operation mode. If we
1630          * thought this was a 20mhz AP, we have to reconnect
1631          */
1632         if (wlvif->sta.role_chan_type == NL80211_CHAN_HT40MINUS ||
1633             wlvif->sta.role_chan_type == NL80211_CHAN_HT40PLUS)
1634                 wl18xx_acx_peer_ht_operation_mode(wl, wlvif->sta.hlid, wide);
1635         else
1636                 ieee80211_connection_loss(wl12xx_wlvif_to_vif(wlvif));
1637 }
1638
1639 static int wl18xx_set_peer_cap(struct wl1271 *wl,
1640                                struct ieee80211_sta_ht_cap *ht_cap,
1641                                bool allow_ht_operation,
1642                                u32 rate_set, u8 hlid)
1643 {
1644         return wl18xx_acx_set_peer_cap(wl, ht_cap, allow_ht_operation,
1645                                        rate_set, hlid);
1646 }
1647
1648 static bool wl18xx_lnk_high_prio(struct wl1271 *wl, u8 hlid,
1649                                  struct wl1271_link *lnk)
1650 {
1651         u8 thold;
1652         struct wl18xx_fw_status_priv *status_priv =
1653                 (struct wl18xx_fw_status_priv *)wl->fw_status->priv;
1654         unsigned long suspend_bitmap;
1655
1656         /* if we don't have the link map yet, assume they all low prio */
1657         if (!status_priv)
1658                 return false;
1659
1660         /* suspended links are never high priority */
1661         suspend_bitmap = le32_to_cpu(status_priv->link_suspend_bitmap);
1662         if (test_bit(hlid, &suspend_bitmap))
1663                 return false;
1664
1665         /* the priority thresholds are taken from FW */
1666         if (test_bit(hlid, &wl->fw_fast_lnk_map) &&
1667             !test_bit(hlid, &wl->ap_fw_ps_map))
1668                 thold = status_priv->tx_fast_link_prio_threshold;
1669         else
1670                 thold = status_priv->tx_slow_link_prio_threshold;
1671
1672         return lnk->allocated_pkts < thold;
1673 }
1674
1675 static bool wl18xx_lnk_low_prio(struct wl1271 *wl, u8 hlid,
1676                                 struct wl1271_link *lnk)
1677 {
1678         u8 thold;
1679         struct wl18xx_fw_status_priv *status_priv =
1680                 (struct wl18xx_fw_status_priv *)wl->fw_status->priv;
1681         unsigned long suspend_bitmap;
1682
1683         /* if we don't have the link map yet, assume they all low prio */
1684         if (!status_priv)
1685                 return true;
1686
1687         suspend_bitmap = le32_to_cpu(status_priv->link_suspend_bitmap);
1688         if (test_bit(hlid, &suspend_bitmap))
1689                 thold = status_priv->tx_suspend_threshold;
1690         else if (test_bit(hlid, &wl->fw_fast_lnk_map) &&
1691                  !test_bit(hlid, &wl->ap_fw_ps_map))
1692                 thold = status_priv->tx_fast_stop_threshold;
1693         else
1694                 thold = status_priv->tx_slow_stop_threshold;
1695
1696         return lnk->allocated_pkts < thold;
1697 }
1698
1699 static u32 wl18xx_convert_hwaddr(struct wl1271 *wl, u32 hwaddr)
1700 {
1701         return hwaddr & ~0x80000000;
1702 }
1703
1704 static int wl18xx_setup(struct wl1271 *wl);
1705
1706 static struct wlcore_ops wl18xx_ops = {
1707         .setup          = wl18xx_setup,
1708         .identify_chip  = wl18xx_identify_chip,
1709         .boot           = wl18xx_boot,
1710         .plt_init       = wl18xx_plt_init,
1711         .trigger_cmd    = wl18xx_trigger_cmd,
1712         .ack_event      = wl18xx_ack_event,
1713         .wait_for_event = wl18xx_wait_for_event,
1714         .process_mailbox_events = wl18xx_process_mailbox_events,
1715         .calc_tx_blocks = wl18xx_calc_tx_blocks,
1716         .set_tx_desc_blocks = wl18xx_set_tx_desc_blocks,
1717         .set_tx_desc_data_len = wl18xx_set_tx_desc_data_len,
1718         .get_rx_buf_align = wl18xx_get_rx_buf_align,
1719         .get_rx_packet_len = wl18xx_get_rx_packet_len,
1720         .tx_immediate_compl = wl18xx_tx_immediate_completion,
1721         .tx_delayed_compl = NULL,
1722         .hw_init        = wl18xx_hw_init,
1723         .convert_fw_status = wl18xx_convert_fw_status,
1724         .set_tx_desc_csum = wl18xx_set_tx_desc_csum,
1725         .get_pg_ver     = wl18xx_get_pg_ver,
1726         .set_rx_csum = wl18xx_set_rx_csum,
1727         .sta_get_ap_rate_mask = wl18xx_sta_get_ap_rate_mask,
1728         .ap_get_mimo_wide_rate_mask = wl18xx_ap_get_mimo_wide_rate_mask,
1729         .get_mac        = wl18xx_get_mac,
1730         .debugfs_init   = wl18xx_debugfs_add_files,
1731         .scan_start     = wl18xx_scan_start,
1732         .scan_stop      = wl18xx_scan_stop,
1733         .sched_scan_start       = wl18xx_sched_scan_start,
1734         .sched_scan_stop        = wl18xx_scan_sched_scan_stop,
1735         .handle_static_data     = wl18xx_handle_static_data,
1736         .get_spare_blocks = wl18xx_get_spare_blocks,
1737         .set_key        = wl18xx_set_key,
1738         .channel_switch = wl18xx_cmd_channel_switch,
1739         .pre_pkt_send   = wl18xx_pre_pkt_send,
1740         .sta_rc_update  = wl18xx_sta_rc_update,
1741         .set_peer_cap   = wl18xx_set_peer_cap,
1742         .convert_hwaddr = wl18xx_convert_hwaddr,
1743         .lnk_high_prio  = wl18xx_lnk_high_prio,
1744         .lnk_low_prio   = wl18xx_lnk_low_prio,
1745         .smart_config_start = wl18xx_cmd_smart_config_start,
1746         .smart_config_stop  = wl18xx_cmd_smart_config_stop,
1747         .smart_config_set_group_key = wl18xx_cmd_smart_config_set_group_key,
1748         .interrupt_notify = wl18xx_acx_interrupt_notify_config,
1749         .rx_ba_filter   = wl18xx_acx_rx_ba_filter,
1750         .ap_sleep       = wl18xx_acx_ap_sleep,
1751         .set_cac        = wl18xx_cmd_set_cac,
1752         .dfs_master_restart     = wl18xx_cmd_dfs_master_restart,
1753 };
1754
1755 /* HT cap appropriate for wide channels in 2Ghz */
1756 static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_2ghz = {
1757         .cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 |
1758                IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_DSSSCCK40 |
1759                IEEE80211_HT_CAP_GRN_FLD,
1760         .ht_supported = true,
1761         .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
1762         .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
1763         .mcs = {
1764                 .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
1765                 .rx_highest = cpu_to_le16(150),
1766                 .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
1767                 },
1768 };
1769
1770 /* HT cap appropriate for wide channels in 5Ghz */
1771 static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_5ghz = {
1772         .cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 |
1773                IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
1774                IEEE80211_HT_CAP_GRN_FLD,
1775         .ht_supported = true,
1776         .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
1777         .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
1778         .mcs = {
1779                 .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
1780                 .rx_highest = cpu_to_le16(150),
1781                 .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
1782                 },
1783 };
1784
1785 /* HT cap appropriate for SISO 20 */
1786 static struct ieee80211_sta_ht_cap wl18xx_siso20_ht_cap = {
1787         .cap = IEEE80211_HT_CAP_SGI_20 |
1788                IEEE80211_HT_CAP_GRN_FLD,
1789         .ht_supported = true,
1790         .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
1791         .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
1792         .mcs = {
1793                 .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
1794                 .rx_highest = cpu_to_le16(72),
1795                 .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
1796                 },
1797 };
1798
1799 /* HT cap appropriate for MIMO rates in 20mhz channel */
1800 static struct ieee80211_sta_ht_cap wl18xx_mimo_ht_cap_2ghz = {
1801         .cap = IEEE80211_HT_CAP_SGI_20 |
1802                IEEE80211_HT_CAP_GRN_FLD,
1803         .ht_supported = true,
1804         .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
1805         .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
1806         .mcs = {
1807                 .rx_mask = { 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, },
1808                 .rx_highest = cpu_to_le16(144),
1809                 .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
1810                 },
1811 };
1812
1813 static const struct ieee80211_iface_limit wl18xx_iface_limits[] = {
1814         {
1815                 .max = 2,
1816                 .types = BIT(NL80211_IFTYPE_STATION),
1817         },
1818         {
1819                 .max = 1,
1820                 .types =   BIT(NL80211_IFTYPE_AP)
1821                          | BIT(NL80211_IFTYPE_P2P_GO)
1822                          | BIT(NL80211_IFTYPE_P2P_CLIENT)
1823 #ifdef CONFIG_MAC80211_MESH
1824                          | BIT(NL80211_IFTYPE_MESH_POINT)
1825 #endif
1826         },
1827         {
1828                 .max = 1,
1829                 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
1830         },
1831 };
1832
1833 static const struct ieee80211_iface_limit wl18xx_iface_ap_limits[] = {
1834         {
1835                 .max = 2,
1836                 .types = BIT(NL80211_IFTYPE_AP),
1837         },
1838 #ifdef CONFIG_MAC80211_MESH
1839         {
1840                 .max = 1,
1841                 .types = BIT(NL80211_IFTYPE_MESH_POINT),
1842         },
1843 #endif
1844         {
1845                 .max = 1,
1846                 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
1847         },
1848 };
1849
1850 static const struct ieee80211_iface_limit wl18xx_iface_ap_cl_limits[] = {
1851         {
1852                 .max = 1,
1853                 .types = BIT(NL80211_IFTYPE_STATION),
1854         },
1855         {
1856                 .max = 1,
1857                 .types = BIT(NL80211_IFTYPE_AP),
1858         },
1859         {
1860                 .max = 1,
1861                 .types = BIT(NL80211_IFTYPE_P2P_CLIENT),
1862         },
1863         {
1864                 .max = 1,
1865                 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
1866         },
1867 };
1868
1869 static const struct ieee80211_iface_limit wl18xx_iface_ap_go_limits[] = {
1870         {
1871                 .max = 1,
1872                 .types = BIT(NL80211_IFTYPE_STATION),
1873         },
1874         {
1875                 .max = 1,
1876                 .types = BIT(NL80211_IFTYPE_AP),
1877         },
1878         {
1879                 .max = 1,
1880                 .types = BIT(NL80211_IFTYPE_P2P_GO),
1881         },
1882         {
1883                 .max = 1,
1884                 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
1885         },
1886 };
1887
1888 static const struct ieee80211_iface_combination
1889 wl18xx_iface_combinations[] = {
1890         {
1891                 .max_interfaces = 3,
1892                 .limits = wl18xx_iface_limits,
1893                 .n_limits = ARRAY_SIZE(wl18xx_iface_limits),
1894                 .num_different_channels = 2,
1895         },
1896         {
1897                 .max_interfaces = 2,
1898                 .limits = wl18xx_iface_ap_limits,
1899                 .n_limits = ARRAY_SIZE(wl18xx_iface_ap_limits),
1900                 .num_different_channels = 1,
1901                 .radar_detect_widths =  BIT(NL80211_CHAN_NO_HT) |
1902                                         BIT(NL80211_CHAN_HT20) |
1903                                         BIT(NL80211_CHAN_HT40MINUS) |
1904                                         BIT(NL80211_CHAN_HT40PLUS),
1905         }
1906 };
1907
1908 static int wl18xx_setup(struct wl1271 *wl)
1909 {
1910         struct wl18xx_priv *priv = wl->priv;
1911         int ret;
1912
1913         BUILD_BUG_ON(WL18XX_MAX_LINKS > WLCORE_MAX_LINKS);
1914         BUILD_BUG_ON(WL18XX_MAX_AP_STATIONS > WL18XX_MAX_LINKS);
1915         BUILD_BUG_ON(WL18XX_CONF_SG_PARAMS_MAX > WLCORE_CONF_SG_PARAMS_MAX);
1916
1917         wl->rtable = wl18xx_rtable;
1918         wl->num_tx_desc = WL18XX_NUM_TX_DESCRIPTORS;
1919         wl->num_rx_desc = WL18XX_NUM_RX_DESCRIPTORS;
1920         wl->num_links = WL18XX_MAX_LINKS;
1921         wl->max_ap_stations = WL18XX_MAX_AP_STATIONS;
1922         wl->iface_combinations = wl18xx_iface_combinations;
1923         wl->n_iface_combinations = ARRAY_SIZE(wl18xx_iface_combinations);
1924         wl->num_mac_addr = WL18XX_NUM_MAC_ADDRESSES;
1925         wl->band_rate_to_idx = wl18xx_band_rate_to_idx;
1926         wl->hw_tx_rate_tbl_size = WL18XX_CONF_HW_RXTX_RATE_MAX;
1927         wl->hw_min_ht_rate = WL18XX_CONF_HW_RXTX_RATE_MCS0;
1928         wl->fw_status_len = sizeof(struct wl18xx_fw_status);
1929         wl->fw_status_priv_len = sizeof(struct wl18xx_fw_status_priv);
1930         wl->stats.fw_stats_len = sizeof(struct wl18xx_acx_statistics);
1931         wl->static_data_priv_len = sizeof(struct wl18xx_static_data_priv);
1932
1933         if (num_rx_desc_param != -1)
1934                 wl->num_rx_desc = num_rx_desc_param;
1935
1936         ret = wl18xx_conf_init(wl, wl->dev);
1937         if (ret < 0)
1938                 return ret;
1939
1940         /* If the module param is set, update it in conf */
1941         if (board_type_param) {
1942                 if (!strcmp(board_type_param, "fpga")) {
1943                         priv->conf.phy.board_type = BOARD_TYPE_FPGA_18XX;
1944                 } else if (!strcmp(board_type_param, "hdk")) {
1945                         priv->conf.phy.board_type = BOARD_TYPE_HDK_18XX;
1946                 } else if (!strcmp(board_type_param, "dvp")) {
1947                         priv->conf.phy.board_type = BOARD_TYPE_DVP_18XX;
1948                 } else if (!strcmp(board_type_param, "evb")) {
1949                         priv->conf.phy.board_type = BOARD_TYPE_EVB_18XX;
1950                 } else if (!strcmp(board_type_param, "com8")) {
1951                         priv->conf.phy.board_type = BOARD_TYPE_COM8_18XX;
1952                 } else {
1953                         wl1271_error("invalid board type '%s'",
1954                                 board_type_param);
1955                         return -EINVAL;
1956                 }
1957         }
1958
1959         if (priv->conf.phy.board_type >= NUM_BOARD_TYPES) {
1960                 wl1271_error("invalid board type '%d'",
1961                         priv->conf.phy.board_type);
1962                 return -EINVAL;
1963         }
1964
1965         if (low_band_component_param != -1)
1966                 priv->conf.phy.low_band_component = low_band_component_param;
1967         if (low_band_component_type_param != -1)
1968                 priv->conf.phy.low_band_component_type =
1969                         low_band_component_type_param;
1970         if (high_band_component_param != -1)
1971                 priv->conf.phy.high_band_component = high_band_component_param;
1972         if (high_band_component_type_param != -1)
1973                 priv->conf.phy.high_band_component_type =
1974                         high_band_component_type_param;
1975         if (pwr_limit_reference_11_abg_param != -1)
1976                 priv->conf.phy.pwr_limit_reference_11_abg =
1977                         pwr_limit_reference_11_abg_param;
1978         if (n_antennas_2_param != -1)
1979                 priv->conf.phy.number_of_assembled_ant2_4 = n_antennas_2_param;
1980         if (n_antennas_5_param != -1)
1981                 priv->conf.phy.number_of_assembled_ant5 = n_antennas_5_param;
1982         if (dc2dc_param != -1)
1983                 priv->conf.phy.external_pa_dc2dc = dc2dc_param;
1984
1985         if (ht_mode_param) {
1986                 if (!strcmp(ht_mode_param, "default"))
1987                         priv->conf.ht.mode = HT_MODE_DEFAULT;
1988                 else if (!strcmp(ht_mode_param, "wide"))
1989                         priv->conf.ht.mode = HT_MODE_WIDE;
1990                 else if (!strcmp(ht_mode_param, "siso20"))
1991                         priv->conf.ht.mode = HT_MODE_SISO20;
1992                 else {
1993                         wl1271_error("invalid ht_mode '%s'", ht_mode_param);
1994                         return -EINVAL;
1995                 }
1996         }
1997
1998         if (priv->conf.ht.mode == HT_MODE_DEFAULT) {
1999                 /*
2000                  * Only support mimo with multiple antennas. Fall back to
2001                  * siso40.
2002                  */
2003                 if (wl18xx_is_mimo_supported(wl))
2004                         wlcore_set_ht_cap(wl, NL80211_BAND_2GHZ,
2005                                           &wl18xx_mimo_ht_cap_2ghz);
2006                 else
2007                         wlcore_set_ht_cap(wl, NL80211_BAND_2GHZ,
2008                                           &wl18xx_siso40_ht_cap_2ghz);
2009
2010                 /* 5Ghz is always wide */
2011                 wlcore_set_ht_cap(wl, NL80211_BAND_5GHZ,
2012                                   &wl18xx_siso40_ht_cap_5ghz);
2013         } else if (priv->conf.ht.mode == HT_MODE_WIDE) {
2014                 wlcore_set_ht_cap(wl, NL80211_BAND_2GHZ,
2015                                   &wl18xx_siso40_ht_cap_2ghz);
2016                 wlcore_set_ht_cap(wl, NL80211_BAND_5GHZ,
2017                                   &wl18xx_siso40_ht_cap_5ghz);
2018         } else if (priv->conf.ht.mode == HT_MODE_SISO20) {
2019                 wlcore_set_ht_cap(wl, NL80211_BAND_2GHZ,
2020                                   &wl18xx_siso20_ht_cap);
2021                 wlcore_set_ht_cap(wl, NL80211_BAND_5GHZ,
2022                                   &wl18xx_siso20_ht_cap);
2023         }
2024
2025         if (!checksum_param) {
2026                 wl18xx_ops.set_rx_csum = NULL;
2027                 wl18xx_ops.init_vif = NULL;
2028         }
2029
2030         /* Enable 11a Band only if we have 5G antennas */
2031         wl->enable_11a = (priv->conf.phy.number_of_assembled_ant5 != 0);
2032
2033         return 0;
2034 }
2035
2036 static int wl18xx_probe(struct platform_device *pdev)
2037 {
2038         struct wl1271 *wl;
2039         struct ieee80211_hw *hw;
2040         int ret;
2041
2042         hw = wlcore_alloc_hw(sizeof(struct wl18xx_priv),
2043                              WL18XX_AGGR_BUFFER_SIZE,
2044                              sizeof(struct wl18xx_event_mailbox));
2045         if (IS_ERR(hw)) {
2046                 wl1271_error("can't allocate hw");
2047                 ret = PTR_ERR(hw);
2048                 goto out;
2049         }
2050
2051         wl = hw->priv;
2052         wl->ops = &wl18xx_ops;
2053         wl->ptable = wl18xx_ptable;
2054         ret = wlcore_probe(wl, pdev);
2055         if (ret)
2056                 goto out_free;
2057
2058         return ret;
2059
2060 out_free:
2061         wlcore_free_hw(wl);
2062 out:
2063         return ret;
2064 }
2065
2066 static const struct platform_device_id wl18xx_id_table[] = {
2067         { "wl18xx", 0 },
2068         {  } /* Terminating Entry */
2069 };
2070 MODULE_DEVICE_TABLE(platform, wl18xx_id_table);
2071
2072 static struct platform_driver wl18xx_driver = {
2073         .probe          = wl18xx_probe,
2074         .remove         = wlcore_remove,
2075         .id_table       = wl18xx_id_table,
2076         .driver = {
2077                 .name   = "wl18xx_driver",
2078         }
2079 };
2080
2081 module_platform_driver(wl18xx_driver);
2082 module_param_named(ht_mode, ht_mode_param, charp, 0400);
2083 MODULE_PARM_DESC(ht_mode, "Force HT mode: wide or siso20");
2084
2085 module_param_named(board_type, board_type_param, charp, 0400);
2086 MODULE_PARM_DESC(board_type, "Board type: fpga, hdk (default), evb, com8 or "
2087                  "dvp");
2088
2089 module_param_named(checksum, checksum_param, bool, 0400);
2090 MODULE_PARM_DESC(checksum, "Enable TCP checksum: boolean (defaults to false)");
2091
2092 module_param_named(dc2dc, dc2dc_param, int, 0400);
2093 MODULE_PARM_DESC(dc2dc, "External DC2DC: u8 (defaults to 0)");
2094
2095 module_param_named(n_antennas_2, n_antennas_2_param, int, 0400);
2096 MODULE_PARM_DESC(n_antennas_2,
2097                  "Number of installed 2.4GHz antennas: 1 (default) or 2");
2098
2099 module_param_named(n_antennas_5, n_antennas_5_param, int, 0400);
2100 MODULE_PARM_DESC(n_antennas_5,
2101                  "Number of installed 5GHz antennas: 1 (default) or 2");
2102
2103 module_param_named(low_band_component, low_band_component_param, int, 0400);
2104 MODULE_PARM_DESC(low_band_component, "Low band component: u8 "
2105                  "(default is 0x01)");
2106
2107 module_param_named(low_band_component_type, low_band_component_type_param,
2108                    int, 0400);
2109 MODULE_PARM_DESC(low_band_component_type, "Low band component type: u8 "
2110                  "(default is 0x05 or 0x06 depending on the board_type)");
2111
2112 module_param_named(high_band_component, high_band_component_param, int, 0400);
2113 MODULE_PARM_DESC(high_band_component, "High band component: u8, "
2114                  "(default is 0x01)");
2115
2116 module_param_named(high_band_component_type, high_band_component_type_param,
2117                    int, 0400);
2118 MODULE_PARM_DESC(high_band_component_type, "High band component type: u8 "
2119                  "(default is 0x09)");
2120
2121 module_param_named(pwr_limit_reference_11_abg,
2122                    pwr_limit_reference_11_abg_param, int, 0400);
2123 MODULE_PARM_DESC(pwr_limit_reference_11_abg, "Power limit reference: u8 "
2124                  "(default is 0xc8)");
2125
2126 module_param_named(num_rx_desc, num_rx_desc_param, int, 0400);
2127 MODULE_PARM_DESC(num_rx_desc_param,
2128                  "Number of Rx descriptors: u8 (default is 32)");
2129
2130 MODULE_LICENSE("GPL v2");
2131 MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
2132 MODULE_FIRMWARE(WL18XX_FW_NAME);