linux/drivers/net/wireless/ti/wl18xx/main.c
<<
>>
Prefs
   1/*
   2 * This file is part of wl18xx
   3 *
   4 * Copyright (C) 2011 Texas Instruments
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public License
   8 * version 2 as published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope that it will be useful, but
  11 * WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13 * General Public License for more details.
  14 *
  15 * You should have received a copy of the GNU General Public License
  16 * along with this program; if not, write to the Free Software
  17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  18 * 02110-1301 USA
  19 *
  20 */
  21
  22#include <linux/module.h>
  23#include <linux/platform_device.h>
  24#include <linux/ip.h>
  25#include <linux/firmware.h>
  26
  27#include "../wlcore/wlcore.h"
  28#include "../wlcore/debug.h"
  29#include "../wlcore/io.h"
  30#include "../wlcore/acx.h"
  31#include "../wlcore/tx.h"
  32#include "../wlcore/rx.h"
  33#include "../wlcore/boot.h"
  34
  35#include "reg.h"
  36#include "conf.h"
  37#include "cmd.h"
  38#include "acx.h"
  39#include "tx.h"
  40#include "wl18xx.h"
  41#include "io.h"
  42#include "scan.h"
  43#include "event.h"
  44#include "debugfs.h"
  45
  46#define WL18XX_RX_CHECKSUM_MASK      0x40
  47
  48static char *ht_mode_param = NULL;
  49static char *board_type_param = NULL;
  50static bool checksum_param = false;
  51static int num_rx_desc_param = -1;
  52
  53/* phy paramters */
  54static int dc2dc_param = -1;
  55static int n_antennas_2_param = -1;
  56static int n_antennas_5_param = -1;
  57static int low_band_component_param = -1;
  58static int low_band_component_type_param = -1;
  59static int high_band_component_param = -1;
  60static int high_band_component_type_param = -1;
  61static int pwr_limit_reference_11_abg_param = -1;
  62
  63static const u8 wl18xx_rate_to_idx_2ghz[] = {
  64        /* MCS rates are used only with 11n */
  65        15,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS15 */
  66        14,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS14 */
  67        13,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS13 */
  68        12,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS12 */
  69        11,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS11 */
  70        10,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS10 */
  71        9,                             /* WL18XX_CONF_HW_RXTX_RATE_MCS9 */
  72        8,                             /* WL18XX_CONF_HW_RXTX_RATE_MCS8 */
  73        7,                             /* WL18XX_CONF_HW_RXTX_RATE_MCS7 */
  74        6,                             /* WL18XX_CONF_HW_RXTX_RATE_MCS6 */
  75        5,                             /* WL18XX_CONF_HW_RXTX_RATE_MCS5 */
  76        4,                             /* WL18XX_CONF_HW_RXTX_RATE_MCS4 */
  77        3,                             /* WL18XX_CONF_HW_RXTX_RATE_MCS3 */
  78        2,                             /* WL18XX_CONF_HW_RXTX_RATE_MCS2 */
  79        1,                             /* WL18XX_CONF_HW_RXTX_RATE_MCS1 */
  80        0,                             /* WL18XX_CONF_HW_RXTX_RATE_MCS0 */
  81
  82        11,                            /* WL18XX_CONF_HW_RXTX_RATE_54   */
  83        10,                            /* WL18XX_CONF_HW_RXTX_RATE_48   */
  84        9,                             /* WL18XX_CONF_HW_RXTX_RATE_36   */
  85        8,                             /* WL18XX_CONF_HW_RXTX_RATE_24   */
  86
  87        /* TI-specific rate */
  88        CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_22   */
  89
  90        7,                             /* WL18XX_CONF_HW_RXTX_RATE_18   */
  91        6,                             /* WL18XX_CONF_HW_RXTX_RATE_12   */
  92        3,                             /* WL18XX_CONF_HW_RXTX_RATE_11   */
  93        5,                             /* WL18XX_CONF_HW_RXTX_RATE_9    */
  94        4,                             /* WL18XX_CONF_HW_RXTX_RATE_6    */
  95        2,                             /* WL18XX_CONF_HW_RXTX_RATE_5_5  */
  96        1,                             /* WL18XX_CONF_HW_RXTX_RATE_2    */
  97        0                              /* WL18XX_CONF_HW_RXTX_RATE_1    */
  98};
  99
 100static const u8 wl18xx_rate_to_idx_5ghz[] = {
 101        /* MCS rates are used only with 11n */
 102        15,                           /* WL18XX_CONF_HW_RXTX_RATE_MCS15 */
 103        14,                           /* WL18XX_CONF_HW_RXTX_RATE_MCS14 */
 104        13,                           /* WL18XX_CONF_HW_RXTX_RATE_MCS13 */
 105        12,                           /* WL18XX_CONF_HW_RXTX_RATE_MCS12 */
 106        11,                           /* WL18XX_CONF_HW_RXTX_RATE_MCS11 */
 107        10,                           /* WL18XX_CONF_HW_RXTX_RATE_MCS10 */
 108        9,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS9 */
 109        8,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS8 */
 110        7,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS7 */
 111        6,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS6 */
 112        5,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS5 */
 113        4,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS4 */
 114        3,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS3 */
 115        2,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS2 */
 116        1,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS1 */
 117        0,                            /* WL18XX_CONF_HW_RXTX_RATE_MCS0 */
 118
 119        7,                             /* WL18XX_CONF_HW_RXTX_RATE_54   */
 120        6,                             /* WL18XX_CONF_HW_RXTX_RATE_48   */
 121        5,                             /* WL18XX_CONF_HW_RXTX_RATE_36   */
 122        4,                             /* WL18XX_CONF_HW_RXTX_RATE_24   */
 123
 124        /* TI-specific rate */
 125        CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_22   */
 126
 127        3,                             /* WL18XX_CONF_HW_RXTX_RATE_18   */
 128        2,                             /* WL18XX_CONF_HW_RXTX_RATE_12   */
 129        CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_11   */
 130        1,                             /* WL18XX_CONF_HW_RXTX_RATE_9    */
 131        0,                             /* WL18XX_CONF_HW_RXTX_RATE_6    */
 132        CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_5_5  */
 133        CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_2    */
 134        CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_1    */
 135};
 136
 137static const u8 *wl18xx_band_rate_to_idx[] = {
 138        [IEEE80211_BAND_2GHZ] = wl18xx_rate_to_idx_2ghz,
 139        [IEEE80211_BAND_5GHZ] = wl18xx_rate_to_idx_5ghz
 140};
 141
 142enum wl18xx_hw_rates {
 143        WL18XX_CONF_HW_RXTX_RATE_MCS15 = 0,
 144        WL18XX_CONF_HW_RXTX_RATE_MCS14,
 145        WL18XX_CONF_HW_RXTX_RATE_MCS13,
 146        WL18XX_CONF_HW_RXTX_RATE_MCS12,
 147        WL18XX_CONF_HW_RXTX_RATE_MCS11,
 148        WL18XX_CONF_HW_RXTX_RATE_MCS10,
 149        WL18XX_CONF_HW_RXTX_RATE_MCS9,
 150        WL18XX_CONF_HW_RXTX_RATE_MCS8,
 151        WL18XX_CONF_HW_RXTX_RATE_MCS7,
 152        WL18XX_CONF_HW_RXTX_RATE_MCS6,
 153        WL18XX_CONF_HW_RXTX_RATE_MCS5,
 154        WL18XX_CONF_HW_RXTX_RATE_MCS4,
 155        WL18XX_CONF_HW_RXTX_RATE_MCS3,
 156        WL18XX_CONF_HW_RXTX_RATE_MCS2,
 157        WL18XX_CONF_HW_RXTX_RATE_MCS1,
 158        WL18XX_CONF_HW_RXTX_RATE_MCS0,
 159        WL18XX_CONF_HW_RXTX_RATE_54,
 160        WL18XX_CONF_HW_RXTX_RATE_48,
 161        WL18XX_CONF_HW_RXTX_RATE_36,
 162        WL18XX_CONF_HW_RXTX_RATE_24,
 163        WL18XX_CONF_HW_RXTX_RATE_22,
 164        WL18XX_CONF_HW_RXTX_RATE_18,
 165        WL18XX_CONF_HW_RXTX_RATE_12,
 166        WL18XX_CONF_HW_RXTX_RATE_11,
 167        WL18XX_CONF_HW_RXTX_RATE_9,
 168        WL18XX_CONF_HW_RXTX_RATE_6,
 169        WL18XX_CONF_HW_RXTX_RATE_5_5,
 170        WL18XX_CONF_HW_RXTX_RATE_2,
 171        WL18XX_CONF_HW_RXTX_RATE_1,
 172        WL18XX_CONF_HW_RXTX_RATE_MAX,
 173};
 174
 175static struct wlcore_conf wl18xx_conf = {
 176        .sg = {
 177                .params = {
 178                        [CONF_SG_ACL_BT_MASTER_MIN_BR] = 10,
 179                        [CONF_SG_ACL_BT_MASTER_MAX_BR] = 180,
 180                        [CONF_SG_ACL_BT_SLAVE_MIN_BR] = 10,
 181                        [CONF_SG_ACL_BT_SLAVE_MAX_BR] = 180,
 182                        [CONF_SG_ACL_BT_MASTER_MIN_EDR] = 10,
 183                        [CONF_SG_ACL_BT_MASTER_MAX_EDR] = 80,
 184                        [CONF_SG_ACL_BT_SLAVE_MIN_EDR] = 10,
 185                        [CONF_SG_ACL_BT_SLAVE_MAX_EDR] = 80,
 186                        [CONF_SG_ACL_WLAN_PS_MASTER_BR] = 8,
 187                        [CONF_SG_ACL_WLAN_PS_SLAVE_BR] = 8,
 188                        [CONF_SG_ACL_WLAN_PS_MASTER_EDR] = 20,
 189                        [CONF_SG_ACL_WLAN_PS_SLAVE_EDR] = 20,
 190                        [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_BR] = 20,
 191                        [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_BR] = 35,
 192                        [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_BR] = 16,
 193                        [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_BR] = 35,
 194                        [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_EDR] = 32,
 195                        [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_EDR] = 50,
 196                        [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_EDR] = 28,
 197                        [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_EDR] = 50,
 198                        [CONF_SG_ACL_ACTIVE_SCAN_WLAN_BR] = 10,
 199                        [CONF_SG_ACL_ACTIVE_SCAN_WLAN_EDR] = 20,
 200                        [CONF_SG_ACL_PASSIVE_SCAN_BT_BR] = 75,
 201                        [CONF_SG_ACL_PASSIVE_SCAN_WLAN_BR] = 15,
 202                        [CONF_SG_ACL_PASSIVE_SCAN_BT_EDR] = 27,
 203                        [CONF_SG_ACL_PASSIVE_SCAN_WLAN_EDR] = 17,
 204                        /* active scan params */
 205                        [CONF_SG_AUTO_SCAN_PROBE_REQ] = 170,
 206                        [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3] = 50,
 207                        [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP] = 100,
 208                        /* passive scan params */
 209                        [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP_BR] = 800,
 210                        [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP_EDR] = 200,
 211                        [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3] = 200,
 212                        /* passive scan in dual antenna params */
 213                        [CONF_SG_CONSECUTIVE_HV3_IN_PASSIVE_SCAN] = 0,
 214                        [CONF_SG_BCN_HV3_COLLISION_THRESH_IN_PASSIVE_SCAN] = 0,
 215                        [CONF_SG_TX_RX_PROTECTION_BWIDTH_IN_PASSIVE_SCAN] = 0,
 216                        /* general params */
 217                        [CONF_SG_STA_FORCE_PS_IN_BT_SCO] = 1,
 218                        [CONF_SG_ANTENNA_CONFIGURATION] = 0,
 219                        [CONF_SG_BEACON_MISS_PERCENT] = 60,
 220                        [CONF_SG_DHCP_TIME] = 5000,
 221                        [CONF_SG_RXT] = 1200,
 222                        [CONF_SG_TXT] = 1000,
 223                        [CONF_SG_ADAPTIVE_RXT_TXT] = 1,
 224                        [CONF_SG_GENERAL_USAGE_BIT_MAP] = 3,
 225                        [CONF_SG_HV3_MAX_SERVED] = 6,
 226                        [CONF_SG_PS_POLL_TIMEOUT] = 10,
 227                        [CONF_SG_UPSD_TIMEOUT] = 10,
 228                        [CONF_SG_CONSECUTIVE_CTS_THRESHOLD] = 2,
 229                        [CONF_SG_STA_RX_WINDOW_AFTER_DTIM] = 5,
 230                        [CONF_SG_STA_CONNECTION_PROTECTION_TIME] = 30,
 231                        /* AP params */
 232                        [CONF_AP_BEACON_MISS_TX] = 3,
 233                        [CONF_AP_RX_WINDOW_AFTER_BEACON] = 10,
 234                        [CONF_AP_BEACON_WINDOW_INTERVAL] = 2,
 235                        [CONF_AP_CONNECTION_PROTECTION_TIME] = 0,
 236                        [CONF_AP_BT_ACL_VAL_BT_SERVE_TIME] = 25,
 237                        [CONF_AP_BT_ACL_VAL_WL_SERVE_TIME] = 25,
 238                        /* CTS Diluting params */
 239                        [CONF_SG_CTS_DILUTED_BAD_RX_PACKETS_TH] = 0,
 240                        [CONF_SG_CTS_CHOP_IN_DUAL_ANT_SCO_MASTER] = 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        },
 381        .itrim = {
 382                .enable = false,
 383                .timeout = 50000,
 384        },
 385        .pm_config = {
 386                .host_clk_settling_time = 5000,
 387                .host_fast_wakeup_support = CONF_FAST_WAKEUP_DISABLE,
 388        },
 389        .roam_trigger = {
 390                .trigger_pacing               = 1,
 391                .avg_weight_rssi_beacon       = 20,
 392                .avg_weight_rssi_data         = 10,
 393                .avg_weight_snr_beacon        = 20,
 394                .avg_weight_snr_data          = 10,
 395        },
 396        .scan = {
 397                .min_dwell_time_active        = 7500,
 398                .max_dwell_time_active        = 30000,
 399                .min_dwell_time_active_long   = 25000,
 400                .max_dwell_time_active_long   = 50000,
 401                .dwell_time_passive           = 100000,
 402                .dwell_time_dfs               = 150000,
 403                .num_probe_reqs               = 2,
 404                .split_scan_timeout           = 50000,
 405        },
 406        .sched_scan = {
 407                /*
 408                 * Values are in TU/1000 but since sched scan FW command
 409                 * params are in TUs rounding up may occur.
 410                 */
 411                .base_dwell_time                = 7500,
 412                .max_dwell_time_delta           = 22500,
 413                /* based on 250bits per probe @1Mbps */
 414                .dwell_time_delta_per_probe     = 2000,
 415                /* based on 250bits per probe @6Mbps (plus a bit more) */
 416                .dwell_time_delta_per_probe_5   = 350,
 417                .dwell_time_passive             = 100000,
 418                .dwell_time_dfs                 = 150000,
 419                .num_probe_reqs                 = 2,
 420                .rssi_threshold                 = -90,
 421                .snr_threshold                  = 0,
 422        },
 423        .ht = {
 424                .rx_ba_win_size = 32,
 425                .tx_ba_win_size = 64,
 426                .inactivity_timeout = 10000,
 427                .tx_ba_tid_bitmap = CONF_TX_BA_ENABLED_TID_BITMAP,
 428        },
 429        .mem = {
 430                .num_stations                 = 1,
 431                .ssid_profiles                = 1,
 432                .rx_block_num                 = 40,
 433                .tx_min_block_num             = 40,
 434                .dynamic_memory               = 1,
 435                .min_req_tx_blocks            = 45,
 436                .min_req_rx_blocks            = 22,
 437                .tx_min                       = 27,
 438        },
 439        .fm_coex = {
 440                .enable                       = true,
 441                .swallow_period               = 5,
 442                .n_divider_fref_set_1         = 0xff,       /* default */
 443                .n_divider_fref_set_2         = 12,
 444                .m_divider_fref_set_1         = 0xffff,
 445                .m_divider_fref_set_2         = 148,        /* default */
 446                .coex_pll_stabilization_time  = 0xffffffff, /* default */
 447                .ldo_stabilization_time       = 0xffff,     /* default */
 448                .fm_disturbed_band_margin     = 0xff,       /* default */
 449                .swallow_clk_diff             = 0xff,       /* default */
 450        },
 451        .rx_streaming = {
 452                .duration                      = 150,
 453                .queues                        = 0x1,
 454                .interval                      = 20,
 455                .always                        = 0,
 456        },
 457        .fwlog = {
 458                .mode                         = WL12XX_FWLOG_ON_DEMAND,
 459                .mem_blocks                   = 2,
 460                .severity                     = 0,
 461                .timestamp                    = WL12XX_FWLOG_TIMESTAMP_DISABLED,
 462                .output                       = WL12XX_FWLOG_OUTPUT_HOST,
 463                .threshold                    = 0,
 464        },
 465        .rate = {
 466                .rate_retry_score = 32000,
 467                .per_add = 8192,
 468                .per_th1 = 2048,
 469                .per_th2 = 4096,
 470                .max_per = 8100,
 471                .inverse_curiosity_factor = 5,
 472                .tx_fail_low_th = 4,
 473                .tx_fail_high_th = 10,
 474                .per_alpha_shift = 4,
 475                .per_add_shift = 13,
 476                .per_beta1_shift = 10,
 477                .per_beta2_shift = 8,
 478                .rate_check_up = 2,
 479                .rate_check_down = 12,
 480                .rate_retry_policy = {
 481                        0x00, 0x00, 0x00, 0x00, 0x00,
 482                        0x00, 0x00, 0x00, 0x00, 0x00,
 483                        0x00, 0x00, 0x00,
 484                },
 485        },
 486        .hangover = {
 487                .recover_time               = 0,
 488                .hangover_period            = 20,
 489                .dynamic_mode               = 1,
 490                .early_termination_mode     = 1,
 491                .max_period                 = 20,
 492                .min_period                 = 1,
 493                .increase_delta             = 1,
 494                .decrease_delta             = 2,
 495                .quiet_time                 = 4,
 496                .increase_time              = 1,
 497                .window_size                = 16,
 498        },
 499        .recovery = {
 500                .bug_on_recovery            = 0,
 501                .no_recovery                = 0,
 502        },
 503};
 504
 505static struct wl18xx_priv_conf wl18xx_default_priv_conf = {
 506        .ht = {
 507                .mode                           = HT_MODE_DEFAULT,
 508        },
 509        .phy = {
 510                .phy_standalone                 = 0x00,
 511                .primary_clock_setting_time     = 0x05,
 512                .clock_valid_on_wake_up         = 0x00,
 513                .secondary_clock_setting_time   = 0x05,
 514                .board_type                     = BOARD_TYPE_HDK_18XX,
 515                .auto_detect                    = 0x00,
 516                .dedicated_fem                  = FEM_NONE,
 517                .low_band_component             = COMPONENT_3_WAY_SWITCH,
 518                .low_band_component_type        = 0x04,
 519                .high_band_component            = COMPONENT_2_WAY_SWITCH,
 520                .high_band_component_type       = 0x09,
 521                .tcxo_ldo_voltage               = 0x00,
 522                .xtal_itrim_val                 = 0x04,
 523                .srf_state                      = 0x00,
 524                .io_configuration               = 0x01,
 525                .sdio_configuration             = 0x00,
 526                .settings                       = 0x00,
 527                .enable_clpc                    = 0x00,
 528                .enable_tx_low_pwr_on_siso_rdl  = 0x00,
 529                .rx_profile                     = 0x00,
 530                .pwr_limit_reference_11_abg     = 0x64,
 531                .per_chan_pwr_limit_arr_11abg   = {
 532                        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
 533                        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
 534                        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
 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 },
 549                .pwr_limit_reference_11p        = 0x64,
 550                .per_chan_bo_mode_11_abg        = { 0x00, 0x00, 0x00, 0x00,
 551                                                    0x00, 0x00, 0x00, 0x00,
 552                                                    0x00, 0x00, 0x00, 0x00,
 553                                                    0x00 },
 554                .per_chan_bo_mode_11_p          = { 0x00, 0x00, 0x00, 0x00 },
 555                .per_chan_pwr_limit_arr_11p     = { 0xff, 0xff, 0xff, 0xff,
 556                                                    0xff, 0xff, 0xff },
 557                .psat                           = 0,
 558                .low_power_val                  = 0x08,
 559                .med_power_val                  = 0x12,
 560                .high_power_val                 = 0x18,
 561                .low_power_val_2nd              = 0x05,
 562                .med_power_val_2nd              = 0x0a,
 563                .high_power_val_2nd             = 0x14,
 564                .external_pa_dc2dc              = 0,
 565                .number_of_assembled_ant2_4     = 2,
 566                .number_of_assembled_ant5       = 1,
 567                .tx_rf_margin                   = 1,
 568        },
 569};
 570
 571static const struct wlcore_partition_set wl18xx_ptable[PART_TABLE_LEN] = {
 572        [PART_TOP_PRCM_ELP_SOC] = {
 573                .mem  = { .start = 0x00A02000, .size  = 0x00010000 },
 574                .reg  = { .start = 0x00807000, .size  = 0x00005000 },
 575                .mem2 = { .start = 0x00800000, .size  = 0x0000B000 },
 576                .mem3 = { .start = 0x00000000, .size  = 0x00000000 },
 577        },
 578        [PART_DOWN] = {
 579                .mem  = { .start = 0x00000000, .size  = 0x00014000 },
 580                .reg  = { .start = 0x00810000, .size  = 0x0000BFFF },
 581                .mem2 = { .start = 0x00000000, .size  = 0x00000000 },
 582                .mem3 = { .start = 0x00000000, .size  = 0x00000000 },
 583        },
 584        [PART_BOOT] = {
 585                .mem  = { .start = 0x00700000, .size = 0x0000030c },
 586                .reg  = { .start = 0x00802000, .size = 0x00014578 },
 587                .mem2 = { .start = 0x00B00404, .size = 0x00001000 },
 588                .mem3 = { .start = 0x00C00000, .size = 0x00000400 },
 589        },
 590        [PART_WORK] = {
 591                .mem  = { .start = 0x00800000, .size  = 0x000050FC },
 592                .reg  = { .start = 0x00B00404, .size  = 0x00001000 },
 593                .mem2 = { .start = 0x00C00000, .size  = 0x00000400 },
 594                .mem3 = { .start = 0x00000000, .size  = 0x00000000 },
 595        },
 596        [PART_PHY_INIT] = {
 597                .mem  = { .start = 0x80926000,
 598                          .size = sizeof(struct wl18xx_mac_and_phy_params) },
 599                .reg  = { .start = 0x00000000, .size = 0x00000000 },
 600                .mem2 = { .start = 0x00000000, .size = 0x00000000 },
 601                .mem3 = { .start = 0x00000000, .size = 0x00000000 },
 602        },
 603};
 604
 605static const int wl18xx_rtable[REG_TABLE_LEN] = {
 606        [REG_ECPU_CONTROL]              = WL18XX_REG_ECPU_CONTROL,
 607        [REG_INTERRUPT_NO_CLEAR]        = WL18XX_REG_INTERRUPT_NO_CLEAR,
 608        [REG_INTERRUPT_ACK]             = WL18XX_REG_INTERRUPT_ACK,
 609        [REG_COMMAND_MAILBOX_PTR]       = WL18XX_REG_COMMAND_MAILBOX_PTR,
 610        [REG_EVENT_MAILBOX_PTR]         = WL18XX_REG_EVENT_MAILBOX_PTR,
 611        [REG_INTERRUPT_TRIG]            = WL18XX_REG_INTERRUPT_TRIG_H,
 612        [REG_INTERRUPT_MASK]            = WL18XX_REG_INTERRUPT_MASK,
 613        [REG_PC_ON_RECOVERY]            = WL18XX_SCR_PAD4,
 614        [REG_CHIP_ID_B]                 = WL18XX_REG_CHIP_ID_B,
 615        [REG_CMD_MBOX_ADDRESS]          = WL18XX_CMD_MBOX_ADDRESS,
 616
 617        /* data access memory addresses, used with partition translation */
 618        [REG_SLV_MEM_DATA]              = WL18XX_SLV_MEM_DATA,
 619        [REG_SLV_REG_DATA]              = WL18XX_SLV_REG_DATA,
 620
 621        /* raw data access memory addresses */
 622        [REG_RAW_FW_STATUS_ADDR]        = WL18XX_FW_STATUS_ADDR,
 623};
 624
 625static const struct wl18xx_clk_cfg wl18xx_clk_table[NUM_CLOCK_CONFIGS] = {
 626        [CLOCK_CONFIG_16_2_M]   = { 7,  104,  801, 4,  true },
 627        [CLOCK_CONFIG_16_368_M] = { 9,  132, 3751, 4,  true },
 628        [CLOCK_CONFIG_16_8_M]   = { 7,  100,    0, 0, false },
 629        [CLOCK_CONFIG_19_2_M]   = { 8,  100,    0, 0, false },
 630        [CLOCK_CONFIG_26_M]     = { 13, 120,    0, 0, false },
 631        [CLOCK_CONFIG_32_736_M] = { 9,  132, 3751, 4,  true },
 632        [CLOCK_CONFIG_33_6_M]   = { 7,  100,    0, 0, false },
 633        [CLOCK_CONFIG_38_468_M] = { 8,  100,    0, 0, false },
 634        [CLOCK_CONFIG_52_M]     = { 13, 120,    0, 0, false },
 635};
 636
 637/* TODO: maybe move to a new header file? */
 638#define WL18XX_FW_NAME "ti-connectivity/wl18xx-fw-2.bin"
 639
 640static int wl18xx_identify_chip(struct wl1271 *wl)
 641{
 642        int ret = 0;
 643
 644        switch (wl->chip.id) {
 645        case CHIP_ID_185x_PG20:
 646                wl1271_debug(DEBUG_BOOT, "chip id 0x%x (185x PG20)",
 647                                 wl->chip.id);
 648                wl->sr_fw_name = WL18XX_FW_NAME;
 649                /* wl18xx uses the same firmware for PLT */
 650                wl->plt_fw_name = WL18XX_FW_NAME;
 651                wl->quirks |= WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN |
 652                              WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN |
 653                              WLCORE_QUIRK_NO_SCHED_SCAN_WHILE_CONN |
 654                              WLCORE_QUIRK_TX_PAD_LAST_FRAME |
 655                              WLCORE_QUIRK_REGDOMAIN_CONF |
 656                              WLCORE_QUIRK_DUAL_PROBE_TMPL;
 657
 658                wlcore_set_min_fw_ver(wl, WL18XX_CHIP_VER,
 659                                      WL18XX_IFTYPE_VER,  WL18XX_MAJOR_VER,
 660                                      WL18XX_SUBTYPE_VER, WL18XX_MINOR_VER,
 661                                      /* there's no separate multi-role FW */
 662                                      0, 0, 0, 0);
 663                break;
 664        case CHIP_ID_185x_PG10:
 665                wl1271_warning("chip id 0x%x (185x PG10) is deprecated",
 666                               wl->chip.id);
 667                ret = -ENODEV;
 668                goto out;
 669
 670        default:
 671                wl1271_warning("unsupported chip id: 0x%x", wl->chip.id);
 672                ret = -ENODEV;
 673                goto out;
 674        }
 675
 676        wl->scan_templ_id_2_4 = CMD_TEMPL_CFG_PROBE_REQ_2_4;
 677        wl->scan_templ_id_5 = CMD_TEMPL_CFG_PROBE_REQ_5;
 678        wl->sched_scan_templ_id_2_4 = CMD_TEMPL_PROBE_REQ_2_4_PERIODIC;
 679        wl->sched_scan_templ_id_5 = CMD_TEMPL_PROBE_REQ_5_PERIODIC;
 680        wl->max_channels_5 = WL18XX_MAX_CHANNELS_5GHZ;
 681        wl->ba_rx_session_count_max = WL18XX_RX_BA_MAX_SESSIONS;
 682out:
 683        return ret;
 684}
 685
 686static int wl18xx_set_clk(struct wl1271 *wl)
 687{
 688        u16 clk_freq;
 689        int ret;
 690
 691        ret = wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]);
 692        if (ret < 0)
 693                goto out;
 694
 695        /* TODO: PG2: apparently we need to read the clk type */
 696
 697        ret = wl18xx_top_reg_read(wl, PRIMARY_CLK_DETECT, &clk_freq);
 698        if (ret < 0)
 699                goto out;
 700
 701        wl1271_debug(DEBUG_BOOT, "clock freq %d (%d, %d, %d, %d, %s)", clk_freq,
 702                     wl18xx_clk_table[clk_freq].n, wl18xx_clk_table[clk_freq].m,
 703                     wl18xx_clk_table[clk_freq].p, wl18xx_clk_table[clk_freq].q,
 704                     wl18xx_clk_table[clk_freq].swallow ? "swallow" : "spit");
 705
 706        ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_N,
 707                                   wl18xx_clk_table[clk_freq].n);
 708        if (ret < 0)
 709                goto out;
 710
 711        ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_M,
 712                                   wl18xx_clk_table[clk_freq].m);
 713        if (ret < 0)
 714                goto out;
 715
 716        if (wl18xx_clk_table[clk_freq].swallow) {
 717                /* first the 16 lower bits */
 718                ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_Q_FACTOR_CFG_1,
 719                                           wl18xx_clk_table[clk_freq].q &
 720                                           PLLSH_WCS_PLL_Q_FACTOR_CFG_1_MASK);
 721                if (ret < 0)
 722                        goto out;
 723
 724                /* then the 16 higher bits, masked out */
 725                ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_Q_FACTOR_CFG_2,
 726                                        (wl18xx_clk_table[clk_freq].q >> 16) &
 727                                        PLLSH_WCS_PLL_Q_FACTOR_CFG_2_MASK);
 728                if (ret < 0)
 729                        goto out;
 730
 731                /* first the 16 lower bits */
 732                ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_P_FACTOR_CFG_1,
 733                                           wl18xx_clk_table[clk_freq].p &
 734                                           PLLSH_WCS_PLL_P_FACTOR_CFG_1_MASK);
 735                if (ret < 0)
 736                        goto out;
 737
 738                /* then the 16 higher bits, masked out */
 739                ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_P_FACTOR_CFG_2,
 740                                        (wl18xx_clk_table[clk_freq].p >> 16) &
 741                                        PLLSH_WCS_PLL_P_FACTOR_CFG_2_MASK);
 742        } else {
 743                ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_SWALLOW_EN,
 744                                           PLLSH_WCS_PLL_SWALLOW_EN_VAL2);
 745        }
 746
 747out:
 748        return ret;
 749}
 750
 751static int wl18xx_boot_soft_reset(struct wl1271 *wl)
 752{
 753        int ret;
 754
 755        /* disable Rx/Tx */
 756        ret = wlcore_write32(wl, WL18XX_ENABLE, 0x0);
 757        if (ret < 0)
 758                goto out;
 759
 760        /* disable auto calibration on start*/
 761        ret = wlcore_write32(wl, WL18XX_SPARE_A2, 0xffff);
 762
 763out:
 764        return ret;
 765}
 766
 767static int wl18xx_pre_boot(struct wl1271 *wl)
 768{
 769        int ret;
 770
 771        ret = wl18xx_set_clk(wl);
 772        if (ret < 0)
 773                goto out;
 774
 775        /* Continue the ELP wake up sequence */
 776        ret = wlcore_write32(wl, WL18XX_WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL);
 777        if (ret < 0)
 778                goto out;
 779
 780        udelay(500);
 781
 782        ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
 783        if (ret < 0)
 784                goto out;
 785
 786        /* Disable interrupts */
 787        ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
 788        if (ret < 0)
 789                goto out;
 790
 791        ret = wl18xx_boot_soft_reset(wl);
 792
 793out:
 794        return ret;
 795}
 796
 797static int wl18xx_pre_upload(struct wl1271 *wl)
 798{
 799        u32 tmp;
 800        int ret;
 801
 802        ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
 803        if (ret < 0)
 804                goto out;
 805
 806        /* TODO: check if this is all needed */
 807        ret = wlcore_write32(wl, WL18XX_EEPROMLESS_IND, WL18XX_EEPROMLESS_IND);
 808        if (ret < 0)
 809                goto out;
 810
 811        ret = wlcore_read_reg(wl, REG_CHIP_ID_B, &tmp);
 812        if (ret < 0)
 813                goto out;
 814
 815        wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp);
 816
 817        ret = wlcore_read32(wl, WL18XX_SCR_PAD2, &tmp);
 818
 819out:
 820        return ret;
 821}
 822
 823static int wl18xx_set_mac_and_phy(struct wl1271 *wl)
 824{
 825        struct wl18xx_priv *priv = wl->priv;
 826        struct wl18xx_mac_and_phy_params *params;
 827        int ret;
 828
 829        params = kmemdup(&priv->conf.phy, sizeof(*params), GFP_KERNEL);
 830        if (!params) {
 831                ret = -ENOMEM;
 832                goto out;
 833        }
 834
 835        ret = wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]);
 836        if (ret < 0)
 837                goto out;
 838
 839        ret = wlcore_write(wl, WL18XX_PHY_INIT_MEM_ADDR, params,
 840                           sizeof(*params), false);
 841
 842out:
 843        kfree(params);
 844        return ret;
 845}
 846
 847static int wl18xx_enable_interrupts(struct wl1271 *wl)
 848{
 849        u32 event_mask, intr_mask;
 850        int ret;
 851
 852        event_mask = WL18XX_ACX_EVENTS_VECTOR;
 853        intr_mask = WL18XX_INTR_MASK;
 854
 855        ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK, event_mask);
 856        if (ret < 0)
 857                goto out;
 858
 859        wlcore_enable_interrupts(wl);
 860
 861        ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK,
 862                               WL1271_ACX_INTR_ALL & ~intr_mask);
 863        if (ret < 0)
 864                goto disable_interrupts;
 865
 866        return ret;
 867
 868disable_interrupts:
 869        wlcore_disable_interrupts(wl);
 870
 871out:
 872        return ret;
 873}
 874
 875static int wl18xx_boot(struct wl1271 *wl)
 876{
 877        int ret;
 878
 879        ret = wl18xx_pre_boot(wl);
 880        if (ret < 0)
 881                goto out;
 882
 883        ret = wl18xx_pre_upload(wl);
 884        if (ret < 0)
 885                goto out;
 886
 887        ret = wlcore_boot_upload_firmware(wl);
 888        if (ret < 0)
 889                goto out;
 890
 891        ret = wl18xx_set_mac_and_phy(wl);
 892        if (ret < 0)
 893                goto out;
 894
 895        wl->event_mask = BSS_LOSS_EVENT_ID |
 896                SCAN_COMPLETE_EVENT_ID |
 897                RSSI_SNR_TRIGGER_0_EVENT_ID |
 898                PERIODIC_SCAN_COMPLETE_EVENT_ID |
 899                PERIODIC_SCAN_REPORT_EVENT_ID |
 900                DUMMY_PACKET_EVENT_ID |
 901                PEER_REMOVE_COMPLETE_EVENT_ID |
 902                BA_SESSION_RX_CONSTRAINT_EVENT_ID |
 903                REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID |
 904                INACTIVE_STA_EVENT_ID |
 905                MAX_TX_FAILURE_EVENT_ID |
 906                CHANNEL_SWITCH_COMPLETE_EVENT_ID |
 907                DFS_CHANNELS_CONFIG_COMPLETE_EVENT;
 908
 909        ret = wlcore_boot_run_firmware(wl);
 910        if (ret < 0)
 911                goto out;
 912
 913        ret = wl18xx_enable_interrupts(wl);
 914
 915out:
 916        return ret;
 917}
 918
 919static int wl18xx_trigger_cmd(struct wl1271 *wl, int cmd_box_addr,
 920                               void *buf, size_t len)
 921{
 922        struct wl18xx_priv *priv = wl->priv;
 923
 924        memcpy(priv->cmd_buf, buf, len);
 925        memset(priv->cmd_buf + len, 0, WL18XX_CMD_MAX_SIZE - len);
 926
 927        return wlcore_write(wl, cmd_box_addr, priv->cmd_buf,
 928                            WL18XX_CMD_MAX_SIZE, false);
 929}
 930
 931static int wl18xx_ack_event(struct wl1271 *wl)
 932{
 933        return wlcore_write_reg(wl, REG_INTERRUPT_TRIG,
 934                                WL18XX_INTR_TRIG_EVENT_ACK);
 935}
 936
 937static u32 wl18xx_calc_tx_blocks(struct wl1271 *wl, u32 len, u32 spare_blks)
 938{
 939        u32 blk_size = WL18XX_TX_HW_BLOCK_SIZE;
 940        return (len + blk_size - 1) / blk_size + spare_blks;
 941}
 942
 943static void
 944wl18xx_set_tx_desc_blocks(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc,
 945                          u32 blks, u32 spare_blks)
 946{
 947        desc->wl18xx_mem.total_mem_blocks = blks;
 948}
 949
 950static void
 951wl18xx_set_tx_desc_data_len(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc,
 952                            struct sk_buff *skb)
 953{
 954        desc->length = cpu_to_le16(skb->len);
 955
 956        /* if only the last frame is to be padded, we unset this bit on Tx */
 957        if (wl->quirks & WLCORE_QUIRK_TX_PAD_LAST_FRAME)
 958                desc->wl18xx_mem.ctrl = WL18XX_TX_CTRL_NOT_PADDED;
 959        else
 960                desc->wl18xx_mem.ctrl = 0;
 961
 962        wl1271_debug(DEBUG_TX, "tx_fill_hdr: hlid: %d "
 963                     "len: %d life: %d mem: %d", desc->hlid,
 964                     le16_to_cpu(desc->length),
 965                     le16_to_cpu(desc->life_time),
 966                     desc->wl18xx_mem.total_mem_blocks);
 967}
 968
 969static enum wl_rx_buf_align
 970wl18xx_get_rx_buf_align(struct wl1271 *wl, u32 rx_desc)
 971{
 972        if (rx_desc & RX_BUF_PADDED_PAYLOAD)
 973                return WLCORE_RX_BUF_PADDED;
 974
 975        return WLCORE_RX_BUF_ALIGNED;
 976}
 977
 978static u32 wl18xx_get_rx_packet_len(struct wl1271 *wl, void *rx_data,
 979                                    u32 data_len)
 980{
 981        struct wl1271_rx_descriptor *desc = rx_data;
 982
 983        /* invalid packet */
 984        if (data_len < sizeof(*desc))
 985                return 0;
 986
 987        return data_len - sizeof(*desc);
 988}
 989
 990static void wl18xx_tx_immediate_completion(struct wl1271 *wl)
 991{
 992        wl18xx_tx_immediate_complete(wl);
 993}
 994
 995static int wl18xx_set_host_cfg_bitmap(struct wl1271 *wl, u32 extra_mem_blk)
 996{
 997        int ret;
 998        u32 sdio_align_size = 0;
 999        u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE |
1000                              HOST_IF_CFG_ADD_RX_ALIGNMENT;
1001
1002        /* Enable Tx SDIO padding */
1003        if (wl->quirks & WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN) {
1004                host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK;
1005                sdio_align_size = WL12XX_BUS_BLOCK_SIZE;
1006        }
1007
1008        /* Enable Rx SDIO padding */
1009        if (wl->quirks & WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN) {
1010                host_cfg_bitmap |= HOST_IF_CFG_RX_PAD_TO_SDIO_BLK;
1011                sdio_align_size = WL12XX_BUS_BLOCK_SIZE;
1012        }
1013
1014        ret = wl18xx_acx_host_if_cfg_bitmap(wl, host_cfg_bitmap,
1015                                            sdio_align_size, extra_mem_blk,
1016                                            WL18XX_HOST_IF_LEN_SIZE_FIELD);
1017        if (ret < 0)
1018                return ret;
1019
1020        return 0;
1021}
1022
1023static int wl18xx_hw_init(struct wl1271 *wl)
1024{
1025        int ret;
1026        struct wl18xx_priv *priv = wl->priv;
1027
1028        /* (re)init private structures. Relevant on recovery as well. */
1029        priv->last_fw_rls_idx = 0;
1030        priv->extra_spare_key_count = 0;
1031
1032        /* set the default amount of spare blocks in the bitmap */
1033        ret = wl18xx_set_host_cfg_bitmap(wl, WL18XX_TX_HW_BLOCK_SPARE);
1034        if (ret < 0)
1035                return ret;
1036
1037        if (checksum_param) {
1038                ret = wl18xx_acx_set_checksum_state(wl);
1039                if (ret != 0)
1040                        return ret;
1041        }
1042
1043        return ret;
1044}
1045
1046static void wl18xx_set_tx_desc_csum(struct wl1271 *wl,
1047                                    struct wl1271_tx_hw_descr *desc,
1048                                    struct sk_buff *skb)
1049{
1050        u32 ip_hdr_offset;
1051        struct iphdr *ip_hdr;
1052
1053        if (!checksum_param) {
1054                desc->wl18xx_checksum_data = 0;
1055                return;
1056        }
1057
1058        if (skb->ip_summed != CHECKSUM_PARTIAL) {
1059                desc->wl18xx_checksum_data = 0;
1060                return;
1061        }
1062
1063        ip_hdr_offset = skb_network_header(skb) - skb_mac_header(skb);
1064        if (WARN_ON(ip_hdr_offset >= (1<<7))) {
1065                desc->wl18xx_checksum_data = 0;
1066                return;
1067        }
1068
1069        desc->wl18xx_checksum_data = ip_hdr_offset << 1;
1070
1071        /* FW is interested only in the LSB of the protocol  TCP=0 UDP=1 */
1072        ip_hdr = (void *)skb_network_header(skb);
1073        desc->wl18xx_checksum_data |= (ip_hdr->protocol & 0x01);
1074}
1075
1076static void wl18xx_set_rx_csum(struct wl1271 *wl,
1077                               struct wl1271_rx_descriptor *desc,
1078                               struct sk_buff *skb)
1079{
1080        if (desc->status & WL18XX_RX_CHECKSUM_MASK)
1081                skb->ip_summed = CHECKSUM_UNNECESSARY;
1082}
1083
1084static bool wl18xx_is_mimo_supported(struct wl1271 *wl)
1085{
1086        struct wl18xx_priv *priv = wl->priv;
1087
1088        /* only support MIMO with multiple antennas, and when SISO
1089         * is not forced through config
1090         */
1091        return (priv->conf.phy.number_of_assembled_ant2_4 >= 2) &&
1092               (priv->conf.ht.mode != HT_MODE_WIDE) &&
1093               (priv->conf.ht.mode != HT_MODE_SISO20);
1094}
1095
1096/*
1097 * TODO: instead of having these two functions to get the rate mask,
1098 * we should modify the wlvif->rate_set instead
1099 */
1100static u32 wl18xx_sta_get_ap_rate_mask(struct wl1271 *wl,
1101                                       struct wl12xx_vif *wlvif)
1102{
1103        u32 hw_rate_set = wlvif->rate_set;
1104
1105        if (wlvif->channel_type == NL80211_CHAN_HT40MINUS ||
1106            wlvif->channel_type == NL80211_CHAN_HT40PLUS) {
1107                wl1271_debug(DEBUG_ACX, "using wide channel rate mask");
1108                hw_rate_set |= CONF_TX_RATE_USE_WIDE_CHAN;
1109
1110                /* we don't support MIMO in wide-channel mode */
1111                hw_rate_set &= ~CONF_TX_MIMO_RATES;
1112        } else if (wl18xx_is_mimo_supported(wl)) {
1113                wl1271_debug(DEBUG_ACX, "using MIMO channel rate mask");
1114                hw_rate_set |= CONF_TX_MIMO_RATES;
1115        }
1116
1117        return hw_rate_set;
1118}
1119
1120static u32 wl18xx_ap_get_mimo_wide_rate_mask(struct wl1271 *wl,
1121                                             struct wl12xx_vif *wlvif)
1122{
1123        if (wlvif->channel_type == NL80211_CHAN_HT40MINUS ||
1124            wlvif->channel_type == NL80211_CHAN_HT40PLUS) {
1125                wl1271_debug(DEBUG_ACX, "using wide channel rate mask");
1126
1127                /* sanity check - we don't support this */
1128                if (WARN_ON(wlvif->band != IEEE80211_BAND_5GHZ))
1129                        return 0;
1130
1131                return CONF_TX_RATE_USE_WIDE_CHAN;
1132        } else if (wl18xx_is_mimo_supported(wl) &&
1133                   wlvif->band == IEEE80211_BAND_2GHZ) {
1134                wl1271_debug(DEBUG_ACX, "using MIMO rate mask");
1135                /*
1136                 * we don't care about HT channel here - if a peer doesn't
1137                 * support MIMO, we won't enable it in its rates
1138                 */
1139                return CONF_TX_MIMO_RATES;
1140        } else {
1141                return 0;
1142        }
1143}
1144
1145static int wl18xx_get_pg_ver(struct wl1271 *wl, s8 *ver)
1146{
1147        u32 fuse;
1148        s8 rom = 0, metal = 0, pg_ver = 0, rdl_ver = 0;
1149        int ret;
1150
1151        ret = wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]);
1152        if (ret < 0)
1153                goto out;
1154
1155        ret = wlcore_read32(wl, WL18XX_REG_FUSE_DATA_1_3, &fuse);
1156        if (ret < 0)
1157                goto out;
1158
1159        pg_ver = (fuse & WL18XX_PG_VER_MASK) >> WL18XX_PG_VER_OFFSET;
1160        rom = (fuse & WL18XX_ROM_VER_MASK) >> WL18XX_ROM_VER_OFFSET;
1161
1162        if (rom <= 0xE)
1163                metal = (fuse & WL18XX_METAL_VER_MASK) >>
1164                        WL18XX_METAL_VER_OFFSET;
1165        else
1166                metal = (fuse & WL18XX_NEW_METAL_VER_MASK) >>
1167                        WL18XX_NEW_METAL_VER_OFFSET;
1168
1169        ret = wlcore_read32(wl, WL18XX_REG_FUSE_DATA_2_3, &fuse);
1170        if (ret < 0)
1171                goto out;
1172
1173        rdl_ver = (fuse & WL18XX_RDL_VER_MASK) >> WL18XX_RDL_VER_OFFSET;
1174        if (rdl_ver > RDL_MAX)
1175                rdl_ver = RDL_NONE;
1176
1177        wl1271_info("wl18xx HW: RDL %d, %s, PG %x.%x (ROM %x)",
1178                    rdl_ver, rdl_names[rdl_ver], pg_ver, metal, rom);
1179
1180        if (ver)
1181                *ver = pg_ver;
1182
1183        ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
1184
1185out:
1186        return ret;
1187}
1188
1189#define WL18XX_CONF_FILE_NAME "ti-connectivity/wl18xx-conf.bin"
1190static int wl18xx_conf_init(struct wl1271 *wl, struct device *dev)
1191{
1192        struct wl18xx_priv *priv = wl->priv;
1193        struct wlcore_conf_file *conf_file;
1194        const struct firmware *fw;
1195        int ret;
1196
1197        ret = request_firmware(&fw, WL18XX_CONF_FILE_NAME, dev);
1198        if (ret < 0) {
1199                wl1271_error("could not get configuration binary %s: %d",
1200                             WL18XX_CONF_FILE_NAME, ret);
1201                goto out_fallback;
1202        }
1203
1204        if (fw->size != WL18XX_CONF_SIZE) {
1205                wl1271_error("configuration binary file size is wrong, expected %zu got %zu",
1206                             WL18XX_CONF_SIZE, fw->size);
1207                ret = -EINVAL;
1208                goto out;
1209        }
1210
1211        conf_file = (struct wlcore_conf_file *) fw->data;
1212
1213        if (conf_file->header.magic != cpu_to_le32(WL18XX_CONF_MAGIC)) {
1214                wl1271_error("configuration binary file magic number mismatch, "
1215                             "expected 0x%0x got 0x%0x", WL18XX_CONF_MAGIC,
1216                             conf_file->header.magic);
1217                ret = -EINVAL;
1218                goto out;
1219        }
1220
1221        if (conf_file->header.version != cpu_to_le32(WL18XX_CONF_VERSION)) {
1222                wl1271_error("configuration binary file version not supported, "
1223                             "expected 0x%08x got 0x%08x",
1224                             WL18XX_CONF_VERSION, conf_file->header.version);
1225                ret = -EINVAL;
1226                goto out;
1227        }
1228
1229        memcpy(&wl->conf, &conf_file->core, sizeof(wl18xx_conf));
1230        memcpy(&priv->conf, &conf_file->priv, sizeof(priv->conf));
1231
1232        goto out;
1233
1234out_fallback:
1235        wl1271_warning("falling back to default config");
1236
1237        /* apply driver default configuration */
1238        memcpy(&wl->conf, &wl18xx_conf, sizeof(wl18xx_conf));
1239        /* apply default private configuration */
1240        memcpy(&priv->conf, &wl18xx_default_priv_conf, sizeof(priv->conf));
1241
1242        /* For now we just fallback */
1243        return 0;
1244
1245out:
1246        release_firmware(fw);
1247        return ret;
1248}
1249
1250static int wl18xx_plt_init(struct wl1271 *wl)
1251{
1252        int ret;
1253
1254        /* calibrator based auto/fem detect not supported for 18xx */
1255        if (wl->plt_mode == PLT_FEM_DETECT) {
1256                wl1271_error("wl18xx_plt_init: PLT FEM_DETECT not supported");
1257                return -EINVAL;
1258        }
1259
1260        ret = wlcore_write32(wl, WL18XX_SCR_PAD8, WL18XX_SCR_PAD8_PLT);
1261        if (ret < 0)
1262                return ret;
1263
1264        return wl->ops->boot(wl);
1265}
1266
1267static int wl18xx_get_mac(struct wl1271 *wl)
1268{
1269        u32 mac1, mac2;
1270        int ret;
1271
1272        ret = wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]);
1273        if (ret < 0)
1274                goto out;
1275
1276        ret = wlcore_read32(wl, WL18XX_REG_FUSE_BD_ADDR_1, &mac1);
1277        if (ret < 0)
1278                goto out;
1279
1280        ret = wlcore_read32(wl, WL18XX_REG_FUSE_BD_ADDR_2, &mac2);
1281        if (ret < 0)
1282                goto out;
1283
1284        /* these are the two parts of the BD_ADDR */
1285        wl->fuse_oui_addr = ((mac2 & 0xffff) << 8) +
1286                ((mac1 & 0xff000000) >> 24);
1287        wl->fuse_nic_addr = (mac1 & 0xffffff);
1288
1289        ret = wlcore_set_partition(wl, &wl->ptable[PART_DOWN]);
1290
1291out:
1292        return ret;
1293}
1294
1295static int wl18xx_handle_static_data(struct wl1271 *wl,
1296                                     struct wl1271_static_data *static_data)
1297{
1298        struct wl18xx_static_data_priv *static_data_priv =
1299                (struct wl18xx_static_data_priv *) static_data->priv;
1300
1301        strncpy(wl->chip.phy_fw_ver_str, static_data_priv->phy_version,
1302                sizeof(wl->chip.phy_fw_ver_str));
1303
1304        /* make sure the string is NULL-terminated */
1305        wl->chip.phy_fw_ver_str[sizeof(wl->chip.phy_fw_ver_str) - 1] = '\0';
1306
1307        wl1271_info("PHY firmware version: %s", static_data_priv->phy_version);
1308
1309        return 0;
1310}
1311
1312static int wl18xx_get_spare_blocks(struct wl1271 *wl, bool is_gem)
1313{
1314        struct wl18xx_priv *priv = wl->priv;
1315
1316        /* If we have keys requiring extra spare, indulge them */
1317        if (priv->extra_spare_key_count)
1318                return WL18XX_TX_HW_EXTRA_BLOCK_SPARE;
1319
1320        return WL18XX_TX_HW_BLOCK_SPARE;
1321}
1322
1323static int wl18xx_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
1324                          struct ieee80211_vif *vif,
1325                          struct ieee80211_sta *sta,
1326                          struct ieee80211_key_conf *key_conf)
1327{
1328        struct wl18xx_priv *priv = wl->priv;
1329        bool change_spare = false, special_enc;
1330        int ret;
1331
1332        wl1271_debug(DEBUG_CRYPT, "extra spare keys before: %d",
1333                     priv->extra_spare_key_count);
1334
1335        special_enc = key_conf->cipher == WL1271_CIPHER_SUITE_GEM ||
1336                      key_conf->cipher == WLAN_CIPHER_SUITE_TKIP;
1337
1338        ret = wlcore_set_key(wl, cmd, vif, sta, key_conf);
1339        if (ret < 0)
1340                goto out;
1341
1342        /*
1343         * when adding the first or removing the last GEM/TKIP key,
1344         * we have to adjust the number of spare blocks.
1345         */
1346        if (special_enc) {
1347                if (cmd == SET_KEY) {
1348                        /* first key */
1349                        change_spare = (priv->extra_spare_key_count == 0);
1350                        priv->extra_spare_key_count++;
1351                } else if (cmd == DISABLE_KEY) {
1352                        /* last key */
1353                        change_spare = (priv->extra_spare_key_count == 1);
1354                        priv->extra_spare_key_count--;
1355                }
1356        }
1357
1358        wl1271_debug(DEBUG_CRYPT, "extra spare keys after: %d",
1359                     priv->extra_spare_key_count);
1360
1361        if (!change_spare)
1362                goto out;
1363
1364        /* key is now set, change the spare blocks */
1365        if (priv->extra_spare_key_count)
1366                ret = wl18xx_set_host_cfg_bitmap(wl,
1367                                        WL18XX_TX_HW_EXTRA_BLOCK_SPARE);
1368        else
1369                ret = wl18xx_set_host_cfg_bitmap(wl,
1370                                        WL18XX_TX_HW_BLOCK_SPARE);
1371
1372out:
1373        return ret;
1374}
1375
1376static u32 wl18xx_pre_pkt_send(struct wl1271 *wl,
1377                               u32 buf_offset, u32 last_len)
1378{
1379        if (wl->quirks & WLCORE_QUIRK_TX_PAD_LAST_FRAME) {
1380                struct wl1271_tx_hw_descr *last_desc;
1381
1382                /* get the last TX HW descriptor written to the aggr buf */
1383                last_desc = (struct wl1271_tx_hw_descr *)(wl->aggr_buf +
1384                                                        buf_offset - last_len);
1385
1386                /* the last frame is padded up to an SDIO block */
1387                last_desc->wl18xx_mem.ctrl &= ~WL18XX_TX_CTRL_NOT_PADDED;
1388                return ALIGN(buf_offset, WL12XX_BUS_BLOCK_SIZE);
1389        }
1390
1391        /* no modifications */
1392        return buf_offset;
1393}
1394
1395static void wl18xx_sta_rc_update(struct wl1271 *wl,
1396                                 struct wl12xx_vif *wlvif,
1397                                 struct ieee80211_sta *sta,
1398                                 u32 changed)
1399{
1400        bool wide = sta->bandwidth >= IEEE80211_STA_RX_BW_40;
1401
1402        wl1271_debug(DEBUG_MAC80211, "mac80211 sta_rc_update wide %d", wide);
1403
1404        if (!(changed & IEEE80211_RC_BW_CHANGED))
1405                return;
1406
1407        mutex_lock(&wl->mutex);
1408
1409        /* sanity */
1410        if (WARN_ON(wlvif->bss_type != BSS_TYPE_STA_BSS))
1411                goto out;
1412
1413        /* ignore the change before association */
1414        if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
1415                goto out;
1416
1417        /*
1418         * If we started out as wide, we can change the operation mode. If we
1419         * thought this was a 20mhz AP, we have to reconnect
1420         */
1421        if (wlvif->sta.role_chan_type == NL80211_CHAN_HT40MINUS ||
1422            wlvif->sta.role_chan_type == NL80211_CHAN_HT40PLUS)
1423                wl18xx_acx_peer_ht_operation_mode(wl, wlvif->sta.hlid, wide);
1424        else
1425                ieee80211_connection_loss(wl12xx_wlvif_to_vif(wlvif));
1426
1427out:
1428        mutex_unlock(&wl->mutex);
1429}
1430
1431static int wl18xx_set_peer_cap(struct wl1271 *wl,
1432                               struct ieee80211_sta_ht_cap *ht_cap,
1433                               bool allow_ht_operation,
1434                               u32 rate_set, u8 hlid)
1435{
1436        return wl18xx_acx_set_peer_cap(wl, ht_cap, allow_ht_operation,
1437                                       rate_set, hlid);
1438}
1439
1440static bool wl18xx_lnk_high_prio(struct wl1271 *wl, u8 hlid,
1441                                 struct wl1271_link *lnk)
1442{
1443        u8 thold;
1444        struct wl18xx_fw_status_priv *status_priv =
1445                (struct wl18xx_fw_status_priv *)wl->fw_status_2->priv;
1446        u32 suspend_bitmap = le32_to_cpu(status_priv->link_suspend_bitmap);
1447
1448        /* suspended links are never high priority */
1449        if (test_bit(hlid, (unsigned long *)&suspend_bitmap))
1450                return false;
1451
1452        /* the priority thresholds are taken from FW */
1453        if (test_bit(hlid, (unsigned long *)&wl->fw_fast_lnk_map) &&
1454            !test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map))
1455                thold = status_priv->tx_fast_link_prio_threshold;
1456        else
1457                thold = status_priv->tx_slow_link_prio_threshold;
1458
1459        return lnk->allocated_pkts < thold;
1460}
1461
1462static bool wl18xx_lnk_low_prio(struct wl1271 *wl, u8 hlid,
1463                                struct wl1271_link *lnk)
1464{
1465        u8 thold;
1466        struct wl18xx_fw_status_priv *status_priv =
1467                (struct wl18xx_fw_status_priv *)wl->fw_status_2->priv;
1468        u32 suspend_bitmap = le32_to_cpu(status_priv->link_suspend_bitmap);
1469
1470        if (test_bit(hlid, (unsigned long *)&suspend_bitmap))
1471                thold = status_priv->tx_suspend_threshold;
1472        else if (test_bit(hlid, (unsigned long *)&wl->fw_fast_lnk_map) &&
1473                 !test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map))
1474                thold = status_priv->tx_fast_stop_threshold;
1475        else
1476                thold = status_priv->tx_slow_stop_threshold;
1477
1478        return lnk->allocated_pkts < thold;
1479}
1480
1481static int wl18xx_setup(struct wl1271 *wl);
1482
1483static struct wlcore_ops wl18xx_ops = {
1484        .setup          = wl18xx_setup,
1485        .identify_chip  = wl18xx_identify_chip,
1486        .boot           = wl18xx_boot,
1487        .plt_init       = wl18xx_plt_init,
1488        .trigger_cmd    = wl18xx_trigger_cmd,
1489        .ack_event      = wl18xx_ack_event,
1490        .wait_for_event = wl18xx_wait_for_event,
1491        .process_mailbox_events = wl18xx_process_mailbox_events,
1492        .calc_tx_blocks = wl18xx_calc_tx_blocks,
1493        .set_tx_desc_blocks = wl18xx_set_tx_desc_blocks,
1494        .set_tx_desc_data_len = wl18xx_set_tx_desc_data_len,
1495        .get_rx_buf_align = wl18xx_get_rx_buf_align,
1496        .get_rx_packet_len = wl18xx_get_rx_packet_len,
1497        .tx_immediate_compl = wl18xx_tx_immediate_completion,
1498        .tx_delayed_compl = NULL,
1499        .hw_init        = wl18xx_hw_init,
1500        .set_tx_desc_csum = wl18xx_set_tx_desc_csum,
1501        .get_pg_ver     = wl18xx_get_pg_ver,
1502        .set_rx_csum = wl18xx_set_rx_csum,
1503        .sta_get_ap_rate_mask = wl18xx_sta_get_ap_rate_mask,
1504        .ap_get_mimo_wide_rate_mask = wl18xx_ap_get_mimo_wide_rate_mask,
1505        .get_mac        = wl18xx_get_mac,
1506        .debugfs_init   = wl18xx_debugfs_add_files,
1507        .scan_start     = wl18xx_scan_start,
1508        .scan_stop      = wl18xx_scan_stop,
1509        .sched_scan_start       = wl18xx_sched_scan_start,
1510        .sched_scan_stop        = wl18xx_scan_sched_scan_stop,
1511        .handle_static_data     = wl18xx_handle_static_data,
1512        .get_spare_blocks = wl18xx_get_spare_blocks,
1513        .set_key        = wl18xx_set_key,
1514        .channel_switch = wl18xx_cmd_channel_switch,
1515        .pre_pkt_send   = wl18xx_pre_pkt_send,
1516        .sta_rc_update  = wl18xx_sta_rc_update,
1517        .set_peer_cap   = wl18xx_set_peer_cap,
1518        .lnk_high_prio  = wl18xx_lnk_high_prio,
1519        .lnk_low_prio   = wl18xx_lnk_low_prio,
1520};
1521
1522/* HT cap appropriate for wide channels in 2Ghz */
1523static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_2ghz = {
1524        .cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 |
1525               IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_DSSSCCK40 |
1526               IEEE80211_HT_CAP_GRN_FLD,
1527        .ht_supported = true,
1528        .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
1529        .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
1530        .mcs = {
1531                .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
1532                .rx_highest = cpu_to_le16(150),
1533                .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
1534                },
1535};
1536
1537/* HT cap appropriate for wide channels in 5Ghz */
1538static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_5ghz = {
1539        .cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 |
1540               IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
1541               IEEE80211_HT_CAP_GRN_FLD,
1542        .ht_supported = true,
1543        .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
1544        .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
1545        .mcs = {
1546                .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
1547                .rx_highest = cpu_to_le16(150),
1548                .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
1549                },
1550};
1551
1552/* HT cap appropriate for SISO 20 */
1553static struct ieee80211_sta_ht_cap wl18xx_siso20_ht_cap = {
1554        .cap = IEEE80211_HT_CAP_SGI_20 |
1555               IEEE80211_HT_CAP_GRN_FLD,
1556        .ht_supported = true,
1557        .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
1558        .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
1559        .mcs = {
1560                .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
1561                .rx_highest = cpu_to_le16(72),
1562                .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
1563                },
1564};
1565
1566/* HT cap appropriate for MIMO rates in 20mhz channel */
1567static struct ieee80211_sta_ht_cap wl18xx_mimo_ht_cap_2ghz = {
1568        .cap = IEEE80211_HT_CAP_SGI_20 |
1569               IEEE80211_HT_CAP_GRN_FLD,
1570        .ht_supported = true,
1571        .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
1572        .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
1573        .mcs = {
1574                .rx_mask = { 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, },
1575                .rx_highest = cpu_to_le16(144),
1576                .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
1577                },
1578};
1579
1580static int wl18xx_setup(struct wl1271 *wl)
1581{
1582        struct wl18xx_priv *priv = wl->priv;
1583        int ret;
1584
1585        wl->rtable = wl18xx_rtable;
1586        wl->num_tx_desc = WL18XX_NUM_TX_DESCRIPTORS;
1587        wl->num_rx_desc = WL18XX_NUM_RX_DESCRIPTORS;
1588        wl->num_channels = 2;
1589        wl->num_mac_addr = WL18XX_NUM_MAC_ADDRESSES;
1590        wl->band_rate_to_idx = wl18xx_band_rate_to_idx;
1591        wl->hw_tx_rate_tbl_size = WL18XX_CONF_HW_RXTX_RATE_MAX;
1592        wl->hw_min_ht_rate = WL18XX_CONF_HW_RXTX_RATE_MCS0;
1593        wl->fw_status_priv_len = sizeof(struct wl18xx_fw_status_priv);
1594        wl->stats.fw_stats_len = sizeof(struct wl18xx_acx_statistics);
1595        wl->static_data_priv_len = sizeof(struct wl18xx_static_data_priv);
1596
1597        if (num_rx_desc_param != -1)
1598                wl->num_rx_desc = num_rx_desc_param;
1599
1600        ret = wl18xx_conf_init(wl, wl->dev);
1601        if (ret < 0)
1602                return ret;
1603
1604        /* If the module param is set, update it in conf */
1605        if (board_type_param) {
1606                if (!strcmp(board_type_param, "fpga")) {
1607                        priv->conf.phy.board_type = BOARD_TYPE_FPGA_18XX;
1608                } else if (!strcmp(board_type_param, "hdk")) {
1609                        priv->conf.phy.board_type = BOARD_TYPE_HDK_18XX;
1610                } else if (!strcmp(board_type_param, "dvp")) {
1611                        priv->conf.phy.board_type = BOARD_TYPE_DVP_18XX;
1612                } else if (!strcmp(board_type_param, "evb")) {
1613                        priv->conf.phy.board_type = BOARD_TYPE_EVB_18XX;
1614                } else if (!strcmp(board_type_param, "com8")) {
1615                        priv->conf.phy.board_type = BOARD_TYPE_COM8_18XX;
1616                } else {
1617                        wl1271_error("invalid board type '%s'",
1618                                board_type_param);
1619                        return -EINVAL;
1620                }
1621        }
1622
1623        if (priv->conf.phy.board_type >= NUM_BOARD_TYPES) {
1624                wl1271_error("invalid board type '%d'",
1625                        priv->conf.phy.board_type);
1626                return -EINVAL;
1627        }
1628
1629        if (low_band_component_param != -1)
1630                priv->conf.phy.low_band_component = low_band_component_param;
1631        if (low_band_component_type_param != -1)
1632                priv->conf.phy.low_band_component_type =
1633                        low_band_component_type_param;
1634        if (high_band_component_param != -1)
1635                priv->conf.phy.high_band_component = high_band_component_param;
1636        if (high_band_component_type_param != -1)
1637                priv->conf.phy.high_band_component_type =
1638                        high_band_component_type_param;
1639        if (pwr_limit_reference_11_abg_param != -1)
1640                priv->conf.phy.pwr_limit_reference_11_abg =
1641                        pwr_limit_reference_11_abg_param;
1642        if (n_antennas_2_param != -1)
1643                priv->conf.phy.number_of_assembled_ant2_4 = n_antennas_2_param;
1644        if (n_antennas_5_param != -1)
1645                priv->conf.phy.number_of_assembled_ant5 = n_antennas_5_param;
1646        if (dc2dc_param != -1)
1647                priv->conf.phy.external_pa_dc2dc = dc2dc_param;
1648
1649        if (ht_mode_param) {
1650                if (!strcmp(ht_mode_param, "default"))
1651                        priv->conf.ht.mode = HT_MODE_DEFAULT;
1652                else if (!strcmp(ht_mode_param, "wide"))
1653                        priv->conf.ht.mode = HT_MODE_WIDE;
1654                else if (!strcmp(ht_mode_param, "siso20"))
1655                        priv->conf.ht.mode = HT_MODE_SISO20;
1656                else {
1657                        wl1271_error("invalid ht_mode '%s'", ht_mode_param);
1658                        return -EINVAL;
1659                }
1660        }
1661
1662        if (priv->conf.ht.mode == HT_MODE_DEFAULT) {
1663                /*
1664                 * Only support mimo with multiple antennas. Fall back to
1665                 * siso40.
1666                 */
1667                if (wl18xx_is_mimo_supported(wl))
1668                        wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ,
1669                                          &wl18xx_mimo_ht_cap_2ghz);
1670                else
1671                        wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ,
1672                                          &wl18xx_siso40_ht_cap_2ghz);
1673
1674                /* 5Ghz is always wide */
1675                wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ,
1676                                  &wl18xx_siso40_ht_cap_5ghz);
1677        } else if (priv->conf.ht.mode == HT_MODE_WIDE) {
1678                wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ,
1679                                  &wl18xx_siso40_ht_cap_2ghz);
1680                wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ,
1681                                  &wl18xx_siso40_ht_cap_5ghz);
1682        } else if (priv->conf.ht.mode == HT_MODE_SISO20) {
1683                wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ,
1684                                  &wl18xx_siso20_ht_cap);
1685                wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ,
1686                                  &wl18xx_siso20_ht_cap);
1687        }
1688
1689        if (!checksum_param) {
1690                wl18xx_ops.set_rx_csum = NULL;
1691                wl18xx_ops.init_vif = NULL;
1692        }
1693
1694        /* Enable 11a Band only if we have 5G antennas */
1695        wl->enable_11a = (priv->conf.phy.number_of_assembled_ant5 != 0);
1696
1697        return 0;
1698}
1699
1700static int wl18xx_probe(struct platform_device *pdev)
1701{
1702        struct wl1271 *wl;
1703        struct ieee80211_hw *hw;
1704        int ret;
1705
1706        hw = wlcore_alloc_hw(sizeof(struct wl18xx_priv),
1707                             WL18XX_AGGR_BUFFER_SIZE,
1708                             sizeof(struct wl18xx_event_mailbox));
1709        if (IS_ERR(hw)) {
1710                wl1271_error("can't allocate hw");
1711                ret = PTR_ERR(hw);
1712                goto out;
1713        }
1714
1715        wl = hw->priv;
1716        wl->ops = &wl18xx_ops;
1717        wl->ptable = wl18xx_ptable;
1718        ret = wlcore_probe(wl, pdev);
1719        if (ret)
1720                goto out_free;
1721
1722        return ret;
1723
1724out_free:
1725        wlcore_free_hw(wl);
1726out:
1727        return ret;
1728}
1729
1730static const struct platform_device_id wl18xx_id_table[] = {
1731        { "wl18xx", 0 },
1732        {  } /* Terminating Entry */
1733};
1734MODULE_DEVICE_TABLE(platform, wl18xx_id_table);
1735
1736static struct platform_driver wl18xx_driver = {
1737        .probe          = wl18xx_probe,
1738        .remove         = wlcore_remove,
1739        .id_table       = wl18xx_id_table,
1740        .driver = {
1741                .name   = "wl18xx_driver",
1742                .owner  = THIS_MODULE,
1743        }
1744};
1745
1746module_platform_driver(wl18xx_driver);
1747module_param_named(ht_mode, ht_mode_param, charp, S_IRUSR);
1748MODULE_PARM_DESC(ht_mode, "Force HT mode: wide or siso20");
1749
1750module_param_named(board_type, board_type_param, charp, S_IRUSR);
1751MODULE_PARM_DESC(board_type, "Board type: fpga, hdk (default), evb, com8 or "
1752                 "dvp");
1753
1754module_param_named(checksum, checksum_param, bool, S_IRUSR);
1755MODULE_PARM_DESC(checksum, "Enable TCP checksum: boolean (defaults to false)");
1756
1757module_param_named(dc2dc, dc2dc_param, int, S_IRUSR);
1758MODULE_PARM_DESC(dc2dc, "External DC2DC: u8 (defaults to 0)");
1759
1760module_param_named(n_antennas_2, n_antennas_2_param, int, S_IRUSR);
1761MODULE_PARM_DESC(n_antennas_2,
1762                 "Number of installed 2.4GHz antennas: 1 (default) or 2");
1763
1764module_param_named(n_antennas_5, n_antennas_5_param, int, S_IRUSR);
1765MODULE_PARM_DESC(n_antennas_5,
1766                 "Number of installed 5GHz antennas: 1 (default) or 2");
1767
1768module_param_named(low_band_component, low_band_component_param, int,
1769                   S_IRUSR);
1770MODULE_PARM_DESC(low_band_component, "Low band component: u8 "
1771                 "(default is 0x01)");
1772
1773module_param_named(low_band_component_type, low_band_component_type_param,
1774                   int, S_IRUSR);
1775MODULE_PARM_DESC(low_band_component_type, "Low band component type: u8 "
1776                 "(default is 0x05 or 0x06 depending on the board_type)");
1777
1778module_param_named(high_band_component, high_band_component_param, int,
1779                   S_IRUSR);
1780MODULE_PARM_DESC(high_band_component, "High band component: u8, "
1781                 "(default is 0x01)");
1782
1783module_param_named(high_band_component_type, high_band_component_type_param,
1784                   int, S_IRUSR);
1785MODULE_PARM_DESC(high_band_component_type, "High band component type: u8 "
1786                 "(default is 0x09)");
1787
1788module_param_named(pwr_limit_reference_11_abg,
1789                   pwr_limit_reference_11_abg_param, int, S_IRUSR);
1790MODULE_PARM_DESC(pwr_limit_reference_11_abg, "Power limit reference: u8 "
1791                 "(default is 0xc8)");
1792
1793module_param_named(num_rx_desc,
1794                   num_rx_desc_param, int, S_IRUSR);
1795MODULE_PARM_DESC(num_rx_desc_param,
1796                 "Number of Rx descriptors: u8 (default is 32)");
1797
1798MODULE_LICENSE("GPL v2");
1799MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
1800MODULE_FIRMWARE(WL18XX_FW_NAME);
1801