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