Version:  2.0.40 2.2.26 2.4.37 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8

Linux/drivers/net/wireless/ti/wl18xx/main.c

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

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us