Version:  2.0.40 2.2.26 2.4.37 3.8 3.9 3.10 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

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

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