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

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. wl18xx_identify_chip
  2. wl18xx_set_clk
  3. wl18xx_boot_soft_reset
  4. wl18xx_pre_boot
  5. wl18xx_pre_upload
  6. wl18xx_set_mac_and_phy
  7. wl18xx_enable_interrupts
  8. wl18xx_boot
  9. wl18xx_trigger_cmd
  10. wl18xx_ack_event
  11. wl18xx_calc_tx_blocks
  12. wl18xx_set_tx_desc_blocks
  13. wl18xx_set_tx_desc_data_len
  14. wl18xx_get_rx_buf_align
  15. wl18xx_get_rx_packet_len
  16. wl18xx_tx_immediate_completion
  17. wl18xx_set_host_cfg_bitmap
  18. wl18xx_hw_init
  19. wl18xx_convert_fw_status
  20. wl18xx_set_tx_desc_csum
  21. wl18xx_set_rx_csum
  22. wl18xx_is_mimo_supported
  23. wl18xx_sta_get_ap_rate_mask
  24. wl18xx_ap_get_mimo_wide_rate_mask
  25. wl18xx_rdl_name
  26. wl18xx_get_pg_ver
  27. wl18xx_load_conf_file
  28. wl18xx_conf_init
  29. wl18xx_plt_init
  30. wl18xx_get_mac
  31. wl18xx_handle_static_data
  32. wl18xx_get_spare_blocks
  33. wl18xx_set_key
  34. wl18xx_pre_pkt_send
  35. wl18xx_sta_rc_update
  36. wl18xx_set_peer_cap
  37. wl18xx_lnk_high_prio
  38. wl18xx_lnk_low_prio
  39. wl18xx_convert_hwaddr
  40. wl18xx_setup
  41. wl18xx_probe

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

/* [<][>][^][v][top][bottom][index][help] */