linux/drivers/staging/brcm80211/brcmsmac/main.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2010 Broadcom Corporation
   3 *
   4 * Permission to use, copy, modify, and/or distribute this software for any
   5 * purpose with or without fee is hereby granted, provided that the above
   6 * copyright notice and this permission notice appear in all copies.
   7 *
   8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15 */
  16
  17#include <linux/pci_ids.h>
  18#include <net/mac80211.h>
  19
  20#include <brcm_hw_ids.h>
  21#include <aiutils.h>
  22#include "rate.h"
  23#include "scb.h"
  24#include "phy/phy_hal.h"
  25#include "channel.h"
  26#include "bmac.h"
  27#include "antsel.h"
  28#include "stf.h"
  29#include "ampdu.h"
  30#include "alloc.h"
  31#include "mac80211_if.h"
  32#include "main.h"
  33
  34/*
  35 * WPA(2) definitions
  36 */
  37#define RSN_CAP_4_REPLAY_CNTRS          2
  38#define RSN_CAP_16_REPLAY_CNTRS         3
  39
  40#define WPA_CAP_4_REPLAY_CNTRS          RSN_CAP_4_REPLAY_CNTRS
  41#define WPA_CAP_16_REPLAY_CNTRS         RSN_CAP_16_REPLAY_CNTRS
  42
  43/*
  44 * Indication for txflowcontrol that all priority bits in
  45 * TXQ_STOP_FOR_PRIOFC_MASK are to be considered.
  46 */
  47#define ALLPRIO         -1
  48
  49/*
  50 * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL.
  51 */
  52#define SSID_FMT_BUF_LEN        ((4 * IEEE80211_MAX_SSID_LEN) + 1)
  53
  54#define TIMER_INTERVAL_WATCHDOG 1000    /* watchdog timer, in unit of ms */
  55#define TIMER_INTERVAL_RADIOCHK 800     /* radio monitor timer, in unit of ms */
  56
  57/* Max MPC timeout, in unit of watchdog */
  58#ifndef BRCMS_MPC_MAX_DELAYCNT
  59#define BRCMS_MPC_MAX_DELAYCNT  10
  60#endif
  61
  62/* Min MPC timeout, in unit of watchdog */
  63#define BRCMS_MPC_MIN_DELAYCNT  1
  64#define BRCMS_MPC_THRESHOLD     3       /* MPC count threshold level */
  65
  66#define BEACON_INTERVAL_DEFAULT 100     /* beacon interval, in unit of 1024TU */
  67#define DTIM_INTERVAL_DEFAULT   3       /* DTIM interval, in unit of beacon interval */
  68
  69/* Scale down delays to accommodate QT slow speed */
  70#define BEACON_INTERVAL_DEF_QT  20      /* beacon interval, in unit of 1024TU */
  71#define DTIM_INTERVAL_DEF_QT    1       /* DTIM interval, in unit of beacon interval */
  72
  73#define TBTT_ALIGN_LEEWAY_US    100     /* min leeway before first TBTT in us */
  74
  75/* Software feature flag defines used by wlfeatureflag */
  76#define WL_SWFL_NOHWRADIO       0x0004
  77#define WL_SWFL_FLOWCONTROL     0x0008  /* Enable backpressure to OS stack */
  78#define WL_SWFL_WLBSSSORT       0x0010  /* Per-port supports sorting of BSS */
  79
  80/* n-mode support capability */
  81/* 2x2 includes both 1x1 & 2x2 devices
  82 * reserved #define 2 for future when we want to separate 1x1 & 2x2 and
  83 * control it independently
  84 */
  85#define WL_11N_2x2                      1
  86#define WL_11N_3x3                      3
  87#define WL_11N_4x4                      4
  88
  89/* define 11n feature disable flags */
  90#define WLFEATURE_DISABLE_11N           0x00000001
  91#define WLFEATURE_DISABLE_11N_STBC_TX   0x00000002
  92#define WLFEATURE_DISABLE_11N_STBC_RX   0x00000004
  93#define WLFEATURE_DISABLE_11N_SGI_TX    0x00000008
  94#define WLFEATURE_DISABLE_11N_SGI_RX    0x00000010
  95#define WLFEATURE_DISABLE_11N_AMPDU_TX  0x00000020
  96#define WLFEATURE_DISABLE_11N_AMPDU_RX  0x00000040
  97#define WLFEATURE_DISABLE_11N_GF        0x00000080
  98
  99#define EDCF_ACI_MASK                0x60
 100#define EDCF_ACI_SHIFT               5
 101#define EDCF_ECWMIN_MASK             0x0f
 102#define EDCF_ECWMAX_SHIFT            4
 103#define EDCF_AIFSN_MASK              0x0f
 104#define EDCF_AIFSN_MAX               15
 105#define EDCF_ECWMAX_MASK             0xf0
 106
 107#define EDCF_AC_BE_TXOP_STA          0x0000
 108#define EDCF_AC_BK_TXOP_STA          0x0000
 109#define EDCF_AC_VO_ACI_STA           0x62
 110#define EDCF_AC_VO_ECW_STA           0x32
 111#define EDCF_AC_VI_ACI_STA           0x42
 112#define EDCF_AC_VI_ECW_STA           0x43
 113#define EDCF_AC_BK_ECW_STA           0xA4
 114#define EDCF_AC_VI_TXOP_STA          0x005e
 115#define EDCF_AC_VO_TXOP_STA          0x002f
 116#define EDCF_AC_BE_ACI_STA           0x03
 117#define EDCF_AC_BE_ECW_STA           0xA4
 118#define EDCF_AC_BK_ACI_STA           0x27
 119#define EDCF_AC_VO_TXOP_AP           0x002f
 120
 121#define EDCF_TXOP2USEC(txop)         ((txop) << 5)
 122#define EDCF_ECW2CW(exp)             ((1 << (exp)) - 1)
 123
 124#define APHY_SYMBOL_TIME        4
 125#define APHY_PREAMBLE_TIME      16
 126#define APHY_SIGNAL_TIME        4
 127#define APHY_SIFS_TIME          16
 128#define APHY_SERVICE_NBITS      16
 129#define APHY_TAIL_NBITS         6
 130#define BPHY_SIFS_TIME          10
 131#define BPHY_PLCP_SHORT_TIME    96
 132
 133#define PREN_PREAMBLE           24
 134#define PREN_MM_EXT             12
 135#define PREN_PREAMBLE_EXT       4
 136
 137#define DOT11_MAC_HDR_LEN               24
 138#define DOT11_ACK_LEN           10
 139#define DOT11_BA_LEN            4
 140#define DOT11_OFDM_SIGNAL_EXTENSION     6
 141#define DOT11_MIN_FRAG_LEN              256
 142#define DOT11_RTS_LEN           16
 143#define DOT11_CTS_LEN           10
 144#define DOT11_BA_BITMAP_LEN             128
 145#define DOT11_MIN_BEACON_PERIOD         1
 146#define DOT11_MAX_BEACON_PERIOD         0xFFFF
 147#define DOT11_MAXNUMFRAGS       16
 148#define DOT11_MAX_FRAG_LEN              2346
 149
 150#define BPHY_PLCP_TIME          192
 151#define RIFS_11N_TIME           2
 152
 153#define WME_VER                 1
 154#define WME_SUBTYPE_PARAM_IE    1
 155#define WME_TYPE                2
 156#define WME_OUI                 "\x00\x50\xf2"
 157
 158#define AC_BE                   0
 159#define AC_BK                   1
 160#define AC_VI                   2
 161#define AC_VO                   3
 162
 163/*
 164 * driver maintains internal 'tick'(wlc->pub->now) which increments in 1s OS timer(soft
 165 * watchdog) it is not a wall clock and won't increment when driver is in "down" state
 166 * this low resolution driver tick can be used for maintenance tasks such as phy
 167 * calibration and scb update
 168 */
 169
 170/* To inform the ucode of the last mcast frame posted so that it can clear moredata bit */
 171#define BCMCFID(wlc, fid) brcms_b_write_shm((wlc)->hw, M_BCMC_FID, (fid))
 172
 173#define BRCMS_WAR16165(wlc) (wlc->pub->sih->bustype == PCI_BUS && \
 174                                (!AP_ENAB(wlc->pub)) && (wlc->war16165))
 175
 176/* debug/trace */
 177uint brcm_msg_level =
 178#if defined(BCMDBG)
 179        LOG_ERROR_VAL;
 180#else
 181        0;
 182#endif                          /* BCMDBG */
 183
 184/* Find basic rate for a given rate */
 185#define BRCMS_BASIC_RATE(wlc, rspec)    (IS_MCS(rspec) ? \
 186                        (wlc)->band->basic_rate[mcs_table[rspec & RSPEC_RATE_MASK].leg_ofdm] : \
 187                        (wlc)->band->basic_rate[rspec & RSPEC_RATE_MASK])
 188
 189#define FRAMETYPE(r, mimoframe) (IS_MCS(r) ? mimoframe  : (IS_CCK(r) ? FT_CCK : FT_OFDM))
 190
 191#define RFDISABLE_DEFAULT       10000000        /* rfdisable delay timer 500 ms, runs of ALP clock */
 192
 193#define BRCMS_TEMPSENSE_PERIOD          10      /* 10 second timeout */
 194
 195#define SCAN_IN_PROGRESS(x)     0
 196
 197#define EPI_VERSION_NUM         0x054b0b00
 198
 199#ifdef BCMDBG
 200/* pointer to most recently allocated wl/wlc */
 201static struct brcms_c_info *wlc_info_dbg = (struct brcms_c_info *) (NULL);
 202#endif
 203
 204const u8 prio2fifo[NUMPRIO] = {
 205        TX_AC_BE_FIFO,          /* 0    BE      AC_BE   Best Effort */
 206        TX_AC_BK_FIFO,          /* 1    BK      AC_BK   Background */
 207        TX_AC_BK_FIFO,          /* 2    --      AC_BK   Background */
 208        TX_AC_BE_FIFO,          /* 3    EE      AC_BE   Best Effort */
 209        TX_AC_VI_FIFO,          /* 4    CL      AC_VI   Video */
 210        TX_AC_VI_FIFO,          /* 5    VI      AC_VI   Video */
 211        TX_AC_VO_FIFO,          /* 6    VO      AC_VO   Voice */
 212        TX_AC_VO_FIFO           /* 7    NC      AC_VO   Voice */
 213};
 214
 215/* precedences numbers for wlc queues. These are twice as may levels as
 216 * 802.1D priorities.
 217 * Odd numbers are used for HI priority traffic at same precedence levels
 218 * These constants are used ONLY by wlc_prio2prec_map.  Do not use them elsewhere.
 219 */
 220#define _BRCMS_PREC_NONE                0       /* None = - */
 221#define _BRCMS_PREC_BK          2       /* BK - Background */
 222#define _BRCMS_PREC_BE          4       /* BE - Best-effort */
 223#define _BRCMS_PREC_EE          6       /* EE - Excellent-effort */
 224#define _BRCMS_PREC_CL          8       /* CL - Controlled Load */
 225#define _BRCMS_PREC_VI          10      /* Vi - Video */
 226#define _BRCMS_PREC_VO          12      /* Vo - Voice */
 227#define _BRCMS_PREC_NC          14      /* NC - Network Control */
 228
 229#define MAXMACLIST              64      /* max # source MAC matches */
 230#define BCN_TEMPLATE_COUNT      2
 231
 232/* The BSS is generating beacons in HW */
 233#define BRCMS_BSSCFG_HW_BCN     0x20
 234
 235#define HWBCN_ENAB(cfg)         (((cfg)->flags & BRCMS_BSSCFG_HW_BCN) != 0)
 236
 237#define MBSS_BCN_ENAB(cfg)       0
 238#define MBSS_PRB_ENAB(cfg)       0
 239#define SOFTBCN_ENAB(pub)    (0)
 240
 241/* 802.1D Priority to precedence queue mapping */
 242const u8 wlc_prio2prec_map[] = {
 243        _BRCMS_PREC_BE,         /* 0 BE - Best-effort */
 244        _BRCMS_PREC_BK,         /* 1 BK - Background */
 245        _BRCMS_PREC_NONE,               /* 2 None = - */
 246        _BRCMS_PREC_EE,         /* 3 EE - Excellent-effort */
 247        _BRCMS_PREC_CL,         /* 4 CL - Controlled Load */
 248        _BRCMS_PREC_VI,         /* 5 Vi - Video */
 249        _BRCMS_PREC_VO,         /* 6 Vo - Voice */
 250        _BRCMS_PREC_NC,         /* 7 NC - Network Control */
 251};
 252
 253/* Check if a particular BSS config is AP or STA */
 254#define BSSCFG_AP(cfg)          (0)
 255#define BSSCFG_STA(cfg)         (1)
 256#define BSSCFG_IBSS(cfg)        (!(cfg)->BSS)
 257
 258/* As above for all non-NULL BSS configs */
 259#define FOREACH_BSS(wlc, idx, cfg) \
 260        for (idx = 0; (int) idx < BRCMS_MAXBSSCFG; idx++) \
 261                if ((cfg = (wlc)->bsscfg[idx]))
 262
 263/* TX FIFO number to WME/802.1E Access Category */
 264const u8 wme_fifo2ac[] = { AC_BK, AC_BE, AC_VI, AC_VO, AC_BE, AC_BE };
 265
 266/* WME/802.1E Access Category to TX FIFO number */
 267static const u8 wme_ac2fifo[] = { 1, 0, 2, 3 };
 268
 269static bool in_send_q;
 270
 271/* Shared memory location index for various AC params */
 272#define wme_shmemacindex(ac)    wme_ac2fifo[ac]
 273
 274#ifdef BCMDBG
 275static const char * const fifo_names[] = {
 276        "AC_BK", "AC_BE", "AC_VI", "AC_VO", "BCMC", "ATIM" };
 277#else
 278static const char fifo_names[6][0];
 279#endif
 280
 281static const u8 acbitmap2maxprio[] = {
 282        PRIO_8021D_BE, PRIO_8021D_BE, PRIO_8021D_BK, PRIO_8021D_BK,
 283        PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI,
 284        PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO,
 285        PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO
 286};
 287
 288/* currently the best mechanism for determining SIFS is the band in use */
 289#define SIFS(band) ((band)->bandtype == BRCM_BAND_5G ? APHY_SIFS_TIME : \
 290                                                       BPHY_SIFS_TIME);
 291
 292/* local prototypes */
 293static u16 brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc,
 294                                               struct ieee80211_hw *hw,
 295                                               struct sk_buff *p,
 296                                               struct scb *scb, uint frag,
 297                                               uint nfrags, uint queue,
 298                                               uint next_frag_len,
 299                                               struct wsec_key *key,
 300                                               ratespec_t rspec_override);
 301static void brcms_c_bss_default_init(struct brcms_c_info *wlc);
 302static void brcms_c_ucode_mac_upd(struct brcms_c_info *wlc);
 303static ratespec_t mac80211_wlc_set_nrate(struct brcms_c_info *wlc,
 304                                         struct brcms_band *cur_band,
 305                                         u32 int_val);
 306static void brcms_c_tx_prec_map_init(struct brcms_c_info *wlc);
 307static void brcms_c_watchdog(void *arg);
 308static void brcms_c_watchdog_by_timer(void *arg);
 309static u16 brcms_c_rate_shm_offset(struct brcms_c_info *wlc, u8 rate);
 310static int brcms_c_set_rateset(struct brcms_c_info *wlc, wlc_rateset_t *rs_arg);
 311static u8 brcms_c_local_constraint_qdbm(struct brcms_c_info *wlc);
 312
 313/* send and receive */
 314static struct brcms_txq_info *brcms_c_txq_alloc(struct brcms_c_info *wlc);
 315static void brcms_c_txq_free(struct brcms_c_info *wlc,
 316                         struct brcms_txq_info *qi);
 317static void brcms_c_txflowcontrol_signal(struct brcms_c_info *wlc,
 318                                     struct brcms_txq_info *qi,
 319                                     bool on, int prio);
 320static void brcms_c_txflowcontrol_reset(struct brcms_c_info *wlc);
 321static void brcms_c_compute_cck_plcp(struct brcms_c_info *wlc, ratespec_t rate,
 322                                 uint length, u8 *plcp);
 323static void brcms_c_compute_ofdm_plcp(ratespec_t rate, uint length, u8 *plcp);
 324static void brcms_c_compute_mimo_plcp(ratespec_t rate, uint length, u8 *plcp);
 325static u16 brcms_c_compute_frame_dur(struct brcms_c_info *wlc, ratespec_t rate,
 326                                    u8 preamble_type, uint next_frag_len);
 327static u64 brcms_c_recover_tsf64(struct brcms_c_info *wlc,
 328                             struct brcms_d11rxhdr *rxh);
 329static void brcms_c_recvctl(struct brcms_c_info *wlc,
 330                        struct d11rxhdr *rxh, struct sk_buff *p);
 331static uint brcms_c_calc_frame_len(struct brcms_c_info *wlc, ratespec_t rate,
 332                               u8 preamble_type, uint dur);
 333static uint brcms_c_calc_ack_time(struct brcms_c_info *wlc, ratespec_t rate,
 334                              u8 preamble_type);
 335static uint brcms_c_calc_cts_time(struct brcms_c_info *wlc, ratespec_t rate,
 336                              u8 preamble_type);
 337/* interrupt, up/down, band */
 338static void brcms_c_setband(struct brcms_c_info *wlc, uint bandunit);
 339static chanspec_t brcms_c_init_chanspec(struct brcms_c_info *wlc);
 340static void brcms_c_bandinit_ordered(struct brcms_c_info *wlc,
 341                                     chanspec_t chanspec);
 342static void brcms_c_bsinit(struct brcms_c_info *wlc);
 343static int brcms_c_duty_cycle_set(struct brcms_c_info *wlc, int duty_cycle,
 344                              bool isOFDM, bool writeToShm);
 345static void brcms_c_radio_hwdisable_upd(struct brcms_c_info *wlc);
 346static bool brcms_c_radio_monitor_start(struct brcms_c_info *wlc);
 347static void brcms_c_radio_timer(void *arg);
 348static void brcms_c_radio_enable(struct brcms_c_info *wlc);
 349static void brcms_c_radio_upd(struct brcms_c_info *wlc);
 350
 351/* scan, association, BSS */
 352static uint brcms_c_calc_ba_time(struct brcms_c_info *wlc, ratespec_t rate,
 353                             u8 preamble_type);
 354static void brcms_c_update_mimo_band_bwcap(struct brcms_c_info *wlc, u8 bwcap);
 355static void brcms_c_ht_update_sgi_rx(struct brcms_c_info *wlc, int val);
 356static void brcms_c_ht_update_ldpc(struct brcms_c_info *wlc, s8 val);
 357static void brcms_c_war16165(struct brcms_c_info *wlc, bool tx);
 358
 359static void brcms_c_wme_retries_write(struct brcms_c_info *wlc);
 360static bool brcms_c_attach_stf_ant_init(struct brcms_c_info *wlc);
 361static uint brcms_c_attach_module(struct brcms_c_info *wlc);
 362static void brcms_c_detach_module(struct brcms_c_info *wlc);
 363static void brcms_c_timers_deinit(struct brcms_c_info *wlc);
 364static void brcms_c_down_led_upd(struct brcms_c_info *wlc);
 365static uint brcms_c_down_del_timer(struct brcms_c_info *wlc);
 366static void brcms_c_ofdm_rateset_war(struct brcms_c_info *wlc);
 367static int _brcms_c_ioctl(struct brcms_c_info *wlc, int cmd, void *arg, int len,
 368                      struct brcms_c_if *wlcif);
 369
 370/* conditions under which the PM bit should be set in outgoing frames and STAY_AWAKE is meaningful
 371 */
 372bool brcms_c_ps_allowed(struct brcms_c_info *wlc)
 373{
 374        int idx;
 375        struct brcms_bss_cfg *cfg;
 376
 377        /* disallow PS when one of the following global conditions meets */
 378        if (!wlc->pub->associated)
 379                return false;
 380
 381        /* disallow PS when one of these meets when not scanning */
 382        if (AP_ACTIVE(wlc) || wlc->monitor)
 383                return false;
 384
 385        for (idx = 0; idx < BRCMS_MAXBSSCFG; idx++) {
 386                cfg = wlc->bsscfg[idx];
 387                if (cfg && BSSCFG_STA(cfg) && cfg->associated) {
 388                        /*
 389                         * disallow PS when one of the following
 390                         * bsscfg specific conditions meets
 391                         */
 392                        if (!cfg->BSS || !BRCMS_PORTOPEN(cfg))
 393                                return false;
 394
 395                        if (!cfg->dtim_programmed)
 396                                return false;
 397                }
 398        }
 399
 400        return true;
 401}
 402
 403void brcms_c_reset(struct brcms_c_info *wlc)
 404{
 405        BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
 406
 407        /* slurp up hw mac counters before core reset */
 408        brcms_c_statsupd(wlc);
 409
 410        /* reset our snapshot of macstat counters */
 411        memset((char *)wlc->core->macstat_snapshot, 0,
 412                sizeof(struct macstat));
 413
 414        brcms_b_reset(wlc->hw);
 415}
 416
 417void brcms_c_fatal_error(struct brcms_c_info *wlc)
 418{
 419        wiphy_err(wlc->wiphy, "wl%d: fatal error, reinitializing\n",
 420                  wlc->pub->unit);
 421        brcms_init(wlc->wl);
 422}
 423
 424/* Return the channel the driver should initialize during brcms_c_init.
 425 * the channel may have to be changed from the currently configured channel
 426 * if other configurations are in conflict (bandlocked, 11n mode disabled,
 427 * invalid channel for current country, etc.)
 428 */
 429static chanspec_t brcms_c_init_chanspec(struct brcms_c_info *wlc)
 430{
 431        chanspec_t chanspec =
 432            1 | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE |
 433            WL_CHANSPEC_BAND_2G;
 434
 435        return chanspec;
 436}
 437
 438struct scb global_scb;
 439
 440static void brcms_c_init_scb(struct brcms_c_info *wlc, struct scb *scb)
 441{
 442        int i;
 443        scb->flags = SCB_WMECAP | SCB_HTCAP;
 444        for (i = 0; i < NUMPRIO; i++)
 445                scb->seqnum[i] = 0;
 446}
 447
 448void brcms_c_init(struct brcms_c_info *wlc)
 449{
 450        d11regs_t *regs;
 451        chanspec_t chanspec;
 452        int i;
 453        struct brcms_bss_cfg *bsscfg;
 454        bool mute = false;
 455
 456        BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
 457
 458        regs = wlc->regs;
 459
 460        /* This will happen if a big-hammer was executed. In that case, we want to go back
 461         * to the channel that we were on and not new channel
 462         */
 463        if (wlc->pub->associated)
 464                chanspec = wlc->home_chanspec;
 465        else
 466                chanspec = brcms_c_init_chanspec(wlc);
 467
 468        brcms_b_init(wlc->hw, chanspec, mute);
 469
 470        /* update beacon listen interval */
 471        brcms_c_bcn_li_upd(wlc);
 472
 473        /* the world is new again, so is our reported rate */
 474        brcms_c_reprate_init(wlc);
 475
 476        /* write ethernet address to core */
 477        FOREACH_BSS(wlc, i, bsscfg) {
 478                brcms_c_set_mac(bsscfg);
 479                brcms_c_set_bssid(bsscfg);
 480        }
 481
 482        /* Update tsf_cfprep if associated and up */
 483        if (wlc->pub->associated) {
 484                FOREACH_BSS(wlc, i, bsscfg) {
 485                        if (bsscfg->up) {
 486                                u32 bi;
 487
 488                                /* get beacon period and convert to uS */
 489                                bi = bsscfg->current_bss->beacon_period << 10;
 490                                /*
 491                                 * update since init path would reset
 492                                 * to default value
 493                                 */
 494                                W_REG(&regs->tsf_cfprep,
 495                                      (bi << CFPREP_CBI_SHIFT));
 496
 497                                /* Update maccontrol PM related bits */
 498                                brcms_c_set_ps_ctrl(wlc);
 499
 500                                break;
 501                        }
 502                }
 503        }
 504
 505        brcms_c_bandinit_ordered(wlc, chanspec);
 506
 507        brcms_c_init_scb(wlc, &global_scb);
 508
 509        /* init probe response timeout */
 510        brcms_c_write_shm(wlc, M_PRS_MAXTIME, wlc->prb_resp_timeout);
 511
 512        /* init max burst txop (framebursting) */
 513        brcms_c_write_shm(wlc, M_MBURST_TXOP,
 514                      (wlc->
 515                       _rifs ? (EDCF_AC_VO_TXOP_AP << 5) : MAXFRAMEBURST_TXOP));
 516
 517        /* initialize maximum allowed duty cycle */
 518        brcms_c_duty_cycle_set(wlc, wlc->tx_duty_cycle_ofdm, true, true);
 519        brcms_c_duty_cycle_set(wlc, wlc->tx_duty_cycle_cck, false, true);
 520
 521        /* Update some shared memory locations related to max AMPDU size allowed to received */
 522        brcms_c_ampdu_shm_upd(wlc->ampdu);
 523
 524        /* band-specific inits */
 525        brcms_c_bsinit(wlc);
 526
 527        /* Enable EDCF mode (while the MAC is suspended) */
 528        if (EDCF_ENAB(wlc->pub)) {
 529                OR_REG(&regs->ifs_ctl, IFS_USEEDCF);
 530                brcms_c_edcf_setparams(wlc, false);
 531        }
 532
 533        /* Init precedence maps for empty FIFOs */
 534        brcms_c_tx_prec_map_init(wlc);
 535
 536        /* read the ucode version if we have not yet done so */
 537        if (wlc->ucode_rev == 0) {
 538                wlc->ucode_rev =
 539                    brcms_c_read_shm(wlc, M_BOM_REV_MAJOR) << NBITS(u16);
 540                wlc->ucode_rev |= brcms_c_read_shm(wlc, M_BOM_REV_MINOR);
 541        }
 542
 543        /* ..now really unleash hell (allow the MAC out of suspend) */
 544        brcms_c_enable_mac(wlc);
 545
 546        /* clear tx flow control */
 547        brcms_c_txflowcontrol_reset(wlc);
 548
 549        /* clear tx data fifo suspends */
 550        wlc->tx_suspended = false;
 551
 552        /* enable the RF Disable Delay timer */
 553        W_REG(&wlc->regs->rfdisabledly, RFDISABLE_DEFAULT);
 554
 555        /* initialize mpc delay */
 556        wlc->mpc_delay_off = wlc->mpc_dlycnt = BRCMS_MPC_MIN_DELAYCNT;
 557
 558        /*
 559         * Initialize WME parameters; if they haven't been set by some other
 560         * mechanism (IOVar, etc) then read them from the hardware.
 561         */
 562        if (BRCMS_WME_RETRY_SHORT_GET(wlc, 0) == 0) {
 563                /* Uninitialized; read from HW */
 564                int ac;
 565
 566                for (ac = 0; ac < AC_COUNT; ac++) {
 567                        wlc->wme_retries[ac] =
 568                            brcms_c_read_shm(wlc, M_AC_TXLMT_ADDR(ac));
 569                }
 570        }
 571}
 572
 573void brcms_c_mac_bcn_promisc_change(struct brcms_c_info *wlc, bool promisc)
 574{
 575        wlc->bcnmisc_monitor = promisc;
 576        brcms_c_mac_bcn_promisc(wlc);
 577}
 578
 579void brcms_c_mac_bcn_promisc(struct brcms_c_info *wlc)
 580{
 581        if ((AP_ENAB(wlc->pub) && (N_ENAB(wlc->pub) || wlc->band->gmode)) ||
 582            wlc->bcnmisc_ibss || wlc->bcnmisc_scan || wlc->bcnmisc_monitor)
 583                brcms_c_mctrl(wlc, MCTL_BCNS_PROMISC, MCTL_BCNS_PROMISC);
 584        else
 585                brcms_c_mctrl(wlc, MCTL_BCNS_PROMISC, 0);
 586}
 587
 588/* set or clear maccontrol bits MCTL_PROMISC and MCTL_KEEPCONTROL */
 589void brcms_c_mac_promisc(struct brcms_c_info *wlc)
 590{
 591        u32 promisc_bits = 0;
 592
 593        /* promiscuous mode just sets MCTL_PROMISC
 594         * Note: APs get all BSS traffic without the need to set the MCTL_PROMISC bit
 595         * since all BSS data traffic is directed at the AP
 596         */
 597        if (PROMISC_ENAB(wlc->pub) && !AP_ENAB(wlc->pub))
 598                promisc_bits |= MCTL_PROMISC;
 599
 600        /* monitor mode needs both MCTL_PROMISC and MCTL_KEEPCONTROL
 601         * Note: monitor mode also needs MCTL_BCNS_PROMISC, but that is
 602         * handled in brcms_c_mac_bcn_promisc()
 603         */
 604        if (MONITOR_ENAB(wlc))
 605                promisc_bits |= MCTL_PROMISC | MCTL_KEEPCONTROL;
 606
 607        brcms_c_mctrl(wlc, MCTL_PROMISC | MCTL_KEEPCONTROL, promisc_bits);
 608}
 609
 610/* push sw hps and wake state through hardware */
 611void brcms_c_set_ps_ctrl(struct brcms_c_info *wlc)
 612{
 613        u32 v1, v2;
 614        bool hps;
 615        bool awake_before;
 616
 617        hps = PS_ALLOWED(wlc);
 618
 619        BCMMSG(wlc->wiphy, "wl%d: hps %d\n", wlc->pub->unit, hps);
 620
 621        v1 = R_REG(&wlc->regs->maccontrol);
 622        v2 = MCTL_WAKE;
 623        if (hps)
 624                v2 |= MCTL_HPS;
 625
 626        brcms_c_mctrl(wlc, MCTL_WAKE | MCTL_HPS, v2);
 627
 628        awake_before = ((v1 & MCTL_WAKE) || ((v1 & MCTL_HPS) == 0));
 629
 630        if (!awake_before)
 631                brcms_b_wait_for_wake(wlc->hw);
 632
 633}
 634
 635/*
 636 * Write this BSS config's MAC address to core.
 637 * Updates RXE match engine.
 638 */
 639int brcms_c_set_mac(struct brcms_bss_cfg *cfg)
 640{
 641        int err = 0;
 642        struct brcms_c_info *wlc = cfg->wlc;
 643
 644        if (cfg == wlc->cfg) {
 645                /* enter the MAC addr into the RXE match registers */
 646                brcms_c_set_addrmatch(wlc, RCM_MAC_OFFSET, cfg->cur_etheraddr);
 647        }
 648
 649        brcms_c_ampdu_macaddr_upd(wlc);
 650
 651        return err;
 652}
 653
 654/* Write the BSS config's BSSID address to core (set_bssid in d11procs.tcl).
 655 * Updates RXE match engine.
 656 */
 657void brcms_c_set_bssid(struct brcms_bss_cfg *cfg)
 658{
 659        struct brcms_c_info *wlc = cfg->wlc;
 660
 661        /* if primary config, we need to update BSSID in RXE match registers */
 662        if (cfg == wlc->cfg) {
 663                brcms_c_set_addrmatch(wlc, RCM_BSSID_OFFSET, cfg->BSSID);
 664        }
 665#ifdef SUPPORT_HWKEYS
 666        else if (BSSCFG_STA(cfg) && cfg->BSS) {
 667                brcms_c_rcmta_add_bssid(wlc, cfg);
 668        }
 669#endif
 670}
 671
 672/*
 673 * Suspend the the MAC and update the slot timing
 674 * for standard 11b/g (20us slots) or shortslot 11g (9us slots).
 675 */
 676void brcms_c_switch_shortslot(struct brcms_c_info *wlc, bool shortslot)
 677{
 678        int idx;
 679        struct brcms_bss_cfg *cfg;
 680
 681        /* use the override if it is set */
 682        if (wlc->shortslot_override != BRCMS_SHORTSLOT_AUTO)
 683                shortslot = (wlc->shortslot_override == BRCMS_SHORTSLOT_ON);
 684
 685        if (wlc->shortslot == shortslot)
 686                return;
 687
 688        wlc->shortslot = shortslot;
 689
 690        /* update the capability based on current shortslot mode */
 691        FOREACH_BSS(wlc, idx, cfg) {
 692                if (!cfg->associated)
 693                        continue;
 694                cfg->current_bss->capability &=
 695                                        ~WLAN_CAPABILITY_SHORT_SLOT_TIME;
 696                if (wlc->shortslot)
 697                        cfg->current_bss->capability |=
 698                                        WLAN_CAPABILITY_SHORT_SLOT_TIME;
 699        }
 700
 701        brcms_b_set_shortslot(wlc->hw, shortslot);
 702}
 703
 704static u8 brcms_c_local_constraint_qdbm(struct brcms_c_info *wlc)
 705{
 706        u8 local;
 707        s16 local_max;
 708
 709        local = BRCMS_TXPWR_MAX;
 710        if (wlc->pub->associated &&
 711            (brcmu_chspec_ctlchan(wlc->chanspec) ==
 712             brcmu_chspec_ctlchan(wlc->home_chanspec))) {
 713
 714                /* get the local power constraint if we are on the AP's
 715                 * channel [802.11h, 7.3.2.13]
 716                 */
 717                /* Clamp the value between 0 and BRCMS_TXPWR_MAX w/o
 718                 * overflowing the target */
 719                local_max =
 720                    (wlc->txpwr_local_max -
 721                     wlc->txpwr_local_constraint) * BRCMS_TXPWR_DB_FACTOR;
 722                if (local_max > 0 && local_max < BRCMS_TXPWR_MAX)
 723                        return (u8) local_max;
 724                if (local_max < 0)
 725                        return 0;
 726        }
 727
 728        return local;
 729}
 730
 731/* propagate home chanspec to all bsscfgs in case bsscfg->current_bss->chanspec is referenced */
 732void brcms_c_set_home_chanspec(struct brcms_c_info *wlc, chanspec_t chanspec)
 733{
 734        if (wlc->home_chanspec != chanspec) {
 735                int idx;
 736                struct brcms_bss_cfg *cfg;
 737
 738                wlc->home_chanspec = chanspec;
 739
 740                FOREACH_BSS(wlc, idx, cfg) {
 741                        if (!cfg->associated)
 742                                continue;
 743
 744                        cfg->current_bss->chanspec = chanspec;
 745                }
 746
 747        }
 748}
 749
 750static void brcms_c_set_phy_chanspec(struct brcms_c_info *wlc,
 751                                     chanspec_t chanspec)
 752{
 753        /* Save our copy of the chanspec */
 754        wlc->chanspec = chanspec;
 755
 756        /* Set the chanspec and power limits for this locale after computing
 757         * any 11h local tx power constraints.
 758         */
 759        brcms_c_channel_set_chanspec(wlc->cmi, chanspec,
 760                                 brcms_c_local_constraint_qdbm(wlc));
 761
 762        if (wlc->stf->ss_algosel_auto)
 763                brcms_c_stf_ss_algo_channel_get(wlc, &wlc->stf->ss_algo_channel,
 764                                            chanspec);
 765
 766        brcms_c_stf_ss_update(wlc, wlc->band);
 767
 768}
 769
 770void brcms_c_set_chanspec(struct brcms_c_info *wlc, chanspec_t chanspec)
 771{
 772        uint bandunit;
 773        bool switchband = false;
 774        chanspec_t old_chanspec = wlc->chanspec;
 775
 776        if (!brcms_c_valid_chanspec_db(wlc->cmi, chanspec)) {
 777                wiphy_err(wlc->wiphy, "wl%d: %s: Bad channel %d\n",
 778                          wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec));
 779                return;
 780        }
 781
 782        /* Switch bands if necessary */
 783        if (NBANDS(wlc) > 1) {
 784                bandunit = CHSPEC_BANDUNIT(chanspec);
 785                if (wlc->band->bandunit != bandunit || wlc->bandinit_pending) {
 786                        switchband = true;
 787                        if (wlc->bandlocked) {
 788                                wiphy_err(wlc->wiphy, "wl%d: %s: chspec %d "
 789                                          "band is locked!\n",
 790                                          wlc->pub->unit, __func__,
 791                                          CHSPEC_CHANNEL(chanspec));
 792                                return;
 793                        }
 794                        /*
 795                         * should the setband call come after the
 796                         * brcms_b_chanspec() ? if the setband updates
 797                         * (brcms_c_bsinit) use low level calls to inspect and
 798                         * set state, the state inspected may be from the wrong
 799                         * band, or the following brcms_b_set_chanspec() may
 800                         * undo the work.
 801                         */
 802                        brcms_c_setband(wlc, bandunit);
 803                }
 804        }
 805
 806        /* sync up phy/radio chanspec */
 807        brcms_c_set_phy_chanspec(wlc, chanspec);
 808
 809        /* init antenna selection */
 810        if (CHSPEC_WLC_BW(old_chanspec) != CHSPEC_WLC_BW(chanspec)) {
 811                brcms_c_antsel_init(wlc->asi);
 812
 813                /* Fix the hardware rateset based on bw.
 814                 * Mainly add MCS32 for 40Mhz, remove MCS 32 for 20Mhz
 815                 */
 816                brcms_c_rateset_bw_mcs_filter(&wlc->band->hw_rateset,
 817                                          wlc->band->
 818                                          mimo_cap_40 ? CHSPEC_WLC_BW(chanspec)
 819                                          : 0);
 820        }
 821
 822        /* update some mac configuration since chanspec changed */
 823        brcms_c_ucode_mac_upd(wlc);
 824}
 825
 826ratespec_t brcms_c_lowest_basic_rspec(struct brcms_c_info *wlc,
 827                                      wlc_rateset_t *rs)
 828{
 829        ratespec_t lowest_basic_rspec;
 830        uint i;
 831
 832        /* Use the lowest basic rate */
 833        lowest_basic_rspec = rs->rates[0] & BRCMS_RATE_MASK;
 834        for (i = 0; i < rs->count; i++) {
 835                if (rs->rates[i] & BRCMS_RATE_FLAG) {
 836                        lowest_basic_rspec = rs->rates[i] & BRCMS_RATE_MASK;
 837                        break;
 838                }
 839        }
 840#if NCONF
 841        /* pick siso/cdd as default for OFDM (note no basic rate MCSs are supported yet) */
 842        if (IS_OFDM(lowest_basic_rspec)) {
 843                lowest_basic_rspec |= (wlc->stf->ss_opmode << RSPEC_STF_SHIFT);
 844        }
 845#endif
 846
 847        return lowest_basic_rspec;
 848}
 849
 850/* This function changes the phytxctl for beacon based on current beacon ratespec AND txant
 851 * setting as per this table:
 852 *  ratespec     CCK            ant = wlc->stf->txant
 853 *              OFDM            ant = 3
 854 */
 855void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc,
 856                                       ratespec_t bcn_rspec)
 857{
 858        u16 phyctl;
 859        u16 phytxant = wlc->stf->phytxant;
 860        u16 mask = PHY_TXC_ANT_MASK;
 861
 862        /* for non-siso rates or default setting, use the available chains */
 863        if (BRCMS_PHY_11N_CAP(wlc->band))
 864                phytxant = brcms_c_stf_phytxchain_sel(wlc, bcn_rspec);
 865
 866        phyctl = brcms_c_read_shm(wlc, M_BCN_PCTLWD);
 867        phyctl = (phyctl & ~mask) | phytxant;
 868        brcms_c_write_shm(wlc, M_BCN_PCTLWD, phyctl);
 869}
 870
 871/* centralized protection config change function to simplify debugging, no consistency checking
 872 * this should be called only on changes to avoid overhead in periodic function
 873*/
 874void brcms_c_protection_upd(struct brcms_c_info *wlc, uint idx, int val)
 875{
 876        BCMMSG(wlc->wiphy, "idx %d, val %d\n", idx, val);
 877
 878        switch (idx) {
 879        case BRCMS_PROT_G_SPEC:
 880                wlc->protection->_g = (bool) val;
 881                break;
 882        case BRCMS_PROT_G_OVR:
 883                wlc->protection->g_override = (s8) val;
 884                break;
 885        case BRCMS_PROT_G_USER:
 886                wlc->protection->gmode_user = (u8) val;
 887                break;
 888        case BRCMS_PROT_OVERLAP:
 889                wlc->protection->overlap = (s8) val;
 890                break;
 891        case BRCMS_PROT_N_USER:
 892                wlc->protection->nmode_user = (s8) val;
 893                break;
 894        case BRCMS_PROT_N_CFG:
 895                wlc->protection->n_cfg = (s8) val;
 896                break;
 897        case BRCMS_PROT_N_CFG_OVR:
 898                wlc->protection->n_cfg_override = (s8) val;
 899                break;
 900        case BRCMS_PROT_N_NONGF:
 901                wlc->protection->nongf = (bool) val;
 902                break;
 903        case BRCMS_PROT_N_NONGF_OVR:
 904                wlc->protection->nongf_override = (s8) val;
 905                break;
 906        case BRCMS_PROT_N_PAM_OVR:
 907                wlc->protection->n_pam_override = (s8) val;
 908                break;
 909        case BRCMS_PROT_N_OBSS:
 910                wlc->protection->n_obss = (bool) val;
 911                break;
 912
 913        default:
 914                break;
 915        }
 916
 917}
 918
 919static void brcms_c_ht_update_sgi_rx(struct brcms_c_info *wlc, int val)
 920{
 921        wlc->ht_cap.cap_info &= ~(IEEE80211_HT_CAP_SGI_20 |
 922                                        IEEE80211_HT_CAP_SGI_40);
 923        wlc->ht_cap.cap_info |= (val & BRCMS_N_SGI_20) ?
 924                                        IEEE80211_HT_CAP_SGI_20 : 0;
 925        wlc->ht_cap.cap_info |= (val & BRCMS_N_SGI_40) ?
 926                                        IEEE80211_HT_CAP_SGI_40 : 0;
 927
 928        if (wlc->pub->up) {
 929                brcms_c_update_beacon(wlc);
 930                brcms_c_update_probe_resp(wlc, true);
 931        }
 932}
 933
 934static void brcms_c_ht_update_ldpc(struct brcms_c_info *wlc, s8 val)
 935{
 936        wlc->stf->ldpc = val;
 937
 938        wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_LDPC_CODING;
 939        if (wlc->stf->ldpc != OFF)
 940                wlc->ht_cap.cap_info |= IEEE80211_HT_CAP_LDPC_CODING;
 941
 942        if (wlc->pub->up) {
 943                brcms_c_update_beacon(wlc);
 944                brcms_c_update_probe_resp(wlc, true);
 945                wlc_phy_ldpc_override_set(wlc->band->pi, (val ? true : false));
 946        }
 947}
 948
 949/*
 950 * ucode, hwmac update
 951 *    Channel dependent updates for ucode and hw
 952 */
 953static void brcms_c_ucode_mac_upd(struct brcms_c_info *wlc)
 954{
 955        /* enable or disable any active IBSSs depending on whether or not
 956         * we are on the home channel
 957         */
 958        if (wlc->home_chanspec == BRCMS_BAND_PI_RADIO_CHANSPEC) {
 959                if (wlc->pub->associated) {
 960                        /* BMAC_NOTE: This is something that should be fixed in ucode inits.
 961                         * I think that the ucode inits set up the bcn templates and shm values
 962                         * with a bogus beacon. This should not be done in the inits. If ucode needs
 963                         * to set up a beacon for testing, the test routines should write it down,
 964                         * not expect the inits to populate a bogus beacon.
 965                         */
 966                        if (BRCMS_PHY_11N_CAP(wlc->band)) {
 967                                brcms_c_write_shm(wlc, M_BCN_TXTSF_OFFSET,
 968                                              wlc->band->bcntsfoff);
 969                        }
 970                }
 971        } else {
 972                /* disable an active IBSS if we are not on the home channel */
 973        }
 974
 975        /* update the various promisc bits */
 976        brcms_c_mac_bcn_promisc(wlc);
 977        brcms_c_mac_promisc(wlc);
 978}
 979
 980static void brcms_c_bandinit_ordered(struct brcms_c_info *wlc,
 981                                     chanspec_t chanspec)
 982{
 983        wlc_rateset_t default_rateset;
 984        uint parkband;
 985        uint i, band_order[2];
 986
 987        BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
 988        /*
 989         * We might have been bandlocked during down and the chip power-cycled (hibernate).
 990         * figure out the right band to park on
 991         */
 992        if (wlc->bandlocked || NBANDS(wlc) == 1) {
 993                /* updated in brcms_c_bandlock() */
 994                parkband = wlc->band->bandunit;
 995                band_order[0] = band_order[1] = parkband;
 996        } else {
 997                /* park on the band of the specified chanspec */
 998                parkband = CHSPEC_BANDUNIT(chanspec);
 999
1000                /* order so that parkband initialize last */
1001                band_order[0] = parkband ^ 1;
1002                band_order[1] = parkband;
1003        }
1004
1005        /* make each band operational, software state init */
1006        for (i = 0; i < NBANDS(wlc); i++) {
1007                uint j = band_order[i];
1008
1009                wlc->band = wlc->bandstate[j];
1010
1011                brcms_default_rateset(wlc, &default_rateset);
1012
1013                /* fill in hw_rate */
1014                brcms_c_rateset_filter(&default_rateset, &wlc->band->hw_rateset,
1015                                   false, BRCMS_RATES_CCK_OFDM, BRCMS_RATE_MASK,
1016                                   (bool) N_ENAB(wlc->pub));
1017
1018                /* init basic rate lookup */
1019                brcms_c_rate_lookup_init(wlc, &default_rateset);
1020        }
1021
1022        /* sync up phy/radio chanspec */
1023        brcms_c_set_phy_chanspec(wlc, chanspec);
1024}
1025
1026/* band-specific init */
1027static void brcms_c_bsinit(struct brcms_c_info *wlc)
1028{
1029        BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n",
1030                 wlc->pub->unit, wlc->band->bandunit);
1031
1032        /* write ucode ACK/CTS rate table */
1033        brcms_c_set_ratetable(wlc);
1034
1035        /* update some band specific mac configuration */
1036        brcms_c_ucode_mac_upd(wlc);
1037
1038        /* init antenna selection */
1039        brcms_c_antsel_init(wlc->asi);
1040
1041}
1042
1043/* switch to and initialize new band */
1044static void brcms_c_setband(struct brcms_c_info *wlc,
1045                                           uint bandunit)
1046{
1047        int idx;
1048        struct brcms_bss_cfg *cfg;
1049
1050        wlc->band = wlc->bandstate[bandunit];
1051
1052        if (!wlc->pub->up)
1053                return;
1054
1055        /* wait for at least one beacon before entering sleeping state */
1056        for (idx = 0; idx < BRCMS_MAXBSSCFG; idx++) {
1057                cfg = wlc->bsscfg[idx];
1058                if (cfg && BSSCFG_STA(cfg) && cfg->associated)
1059                        cfg->PMawakebcn = true;
1060        }
1061        brcms_c_set_ps_ctrl(wlc);
1062
1063        /* band-specific initializations */
1064        brcms_c_bsinit(wlc);
1065}
1066
1067/* Initialize a WME Parameter Info Element with default STA parameters from WMM Spec, Table 12 */
1068void
1069brcms_c_wme_initparams_sta(struct brcms_c_info *wlc, struct wme_param_ie *pe)
1070{
1071        static const struct wme_param_ie stadef = {
1072                WME_OUI,
1073                WME_TYPE,
1074                WME_SUBTYPE_PARAM_IE,
1075                WME_VER,
1076                0,
1077                0,
1078                {
1079                 {EDCF_AC_BE_ACI_STA, EDCF_AC_BE_ECW_STA,
1080                  cpu_to_le16(EDCF_AC_BE_TXOP_STA)},
1081                 {EDCF_AC_BK_ACI_STA, EDCF_AC_BK_ECW_STA,
1082                  cpu_to_le16(EDCF_AC_BK_TXOP_STA)},
1083                 {EDCF_AC_VI_ACI_STA, EDCF_AC_VI_ECW_STA,
1084                  cpu_to_le16(EDCF_AC_VI_TXOP_STA)},
1085                 {EDCF_AC_VO_ACI_STA, EDCF_AC_VO_ECW_STA,
1086                  cpu_to_le16(EDCF_AC_VO_TXOP_STA)}
1087                 }
1088        };
1089        memcpy(pe, &stadef, sizeof(*pe));
1090}
1091
1092void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci,
1093                       const struct ieee80211_tx_queue_params *params,
1094                       bool suspend)
1095{
1096        int i;
1097        struct shm_acparams acp_shm;
1098        u16 *shm_entry;
1099
1100        /* Only apply params if the core is out of reset and has clocks */
1101        if (!wlc->clk) {
1102                wiphy_err(wlc->wiphy, "wl%d: %s : no-clock\n", wlc->pub->unit,
1103                          __func__);
1104                return;
1105        }
1106
1107        do {
1108                memset((char *)&acp_shm, 0, sizeof(struct shm_acparams));
1109                /* fill in shm ac params struct */
1110                acp_shm.txop = le16_to_cpu(params->txop);
1111                /* convert from units of 32us to us for ucode */
1112                wlc->edcf_txop[aci & 0x3] = acp_shm.txop =
1113                    EDCF_TXOP2USEC(acp_shm.txop);
1114                acp_shm.aifs = (params->aifs & EDCF_AIFSN_MASK);
1115
1116                if (aci == AC_VI && acp_shm.txop == 0
1117                    && acp_shm.aifs < EDCF_AIFSN_MAX)
1118                        acp_shm.aifs++;
1119
1120                if (acp_shm.aifs < EDCF_AIFSN_MIN
1121                    || acp_shm.aifs > EDCF_AIFSN_MAX) {
1122                        wiphy_err(wlc->wiphy, "wl%d: edcf_setparams: bad "
1123                                  "aifs %d\n", wlc->pub->unit, acp_shm.aifs);
1124                        continue;
1125                }
1126
1127                acp_shm.cwmin = params->cw_min;
1128                acp_shm.cwmax = params->cw_max;
1129                acp_shm.cwcur = acp_shm.cwmin;
1130                acp_shm.bslots =
1131                    R_REG(&wlc->regs->tsf_random) & acp_shm.cwcur;
1132                acp_shm.reggap = acp_shm.bslots + acp_shm.aifs;
1133                /* Indicate the new params to the ucode */
1134                acp_shm.status = brcms_c_read_shm(wlc, (M_EDCF_QINFO +
1135                                                    wme_shmemacindex(aci) *
1136                                                    M_EDCF_QLEN +
1137                                                    M_EDCF_STATUS_OFF));
1138                acp_shm.status |= WME_STATUS_NEWAC;
1139
1140                /* Fill in shm acparam table */
1141                shm_entry = (u16 *) &acp_shm;
1142                for (i = 0; i < (int)sizeof(struct shm_acparams); i += 2)
1143                        brcms_c_write_shm(wlc,
1144                                      M_EDCF_QINFO +
1145                                      wme_shmemacindex(aci) * M_EDCF_QLEN + i,
1146                                      *shm_entry++);
1147
1148        } while (0);
1149
1150        if (suspend)
1151                brcms_c_suspend_mac_and_wait(wlc);
1152
1153        if (suspend)
1154                brcms_c_enable_mac(wlc);
1155
1156}
1157
1158void brcms_c_edcf_setparams(struct brcms_c_info *wlc, bool suspend)
1159{
1160        u16 aci;
1161        int i_ac;
1162        struct edcf_acparam *edcf_acp;
1163
1164        struct ieee80211_tx_queue_params txq_pars;
1165        struct ieee80211_tx_queue_params *params = &txq_pars;
1166
1167        /*
1168         * AP uses AC params from wme_param_ie_ap.
1169         * AP advertises AC params from wme_param_ie.
1170         * STA uses AC params from wme_param_ie.
1171         */
1172
1173        edcf_acp = (struct edcf_acparam *) &wlc->wme_param_ie.acparam[0];
1174
1175        for (i_ac = 0; i_ac < AC_COUNT; i_ac++, edcf_acp++) {
1176                /* find out which ac this set of params applies to */
1177                aci = (edcf_acp->ACI & EDCF_ACI_MASK) >> EDCF_ACI_SHIFT;
1178
1179                /* fill in shm ac params struct */
1180                params->txop = edcf_acp->TXOP;
1181                params->aifs = edcf_acp->ACI;
1182
1183                /* CWmin = 2^(ECWmin) - 1 */
1184                params->cw_min = EDCF_ECW2CW(edcf_acp->ECW & EDCF_ECWMIN_MASK);
1185                /* CWmax = 2^(ECWmax) - 1 */
1186                params->cw_max = EDCF_ECW2CW((edcf_acp->ECW & EDCF_ECWMAX_MASK)
1187                                            >> EDCF_ECWMAX_SHIFT);
1188                brcms_c_wme_setparams(wlc, aci, params, suspend);
1189        }
1190
1191        if (suspend)
1192                brcms_c_suspend_mac_and_wait(wlc);
1193
1194        if (AP_ENAB(wlc->pub) && WME_ENAB(wlc->pub)) {
1195                brcms_c_update_beacon(wlc);
1196                brcms_c_update_probe_resp(wlc, false);
1197        }
1198
1199        if (suspend)
1200                brcms_c_enable_mac(wlc);
1201
1202}
1203
1204bool brcms_c_timers_init(struct brcms_c_info *wlc, int unit)
1205{
1206        wlc->wdtimer = brcms_init_timer(wlc->wl, brcms_c_watchdog_by_timer,
1207                wlc, "watchdog");
1208        if (!wlc->wdtimer) {
1209                wiphy_err(wlc->wiphy, "wl%d:  wl_init_timer for wdtimer "
1210                          "failed\n", unit);
1211                goto fail;
1212        }
1213
1214        wlc->radio_timer = brcms_init_timer(wlc->wl, brcms_c_radio_timer,
1215                wlc, "radio");
1216        if (!wlc->radio_timer) {
1217                wiphy_err(wlc->wiphy, "wl%d:  wl_init_timer for radio_timer "
1218                          "failed\n", unit);
1219                goto fail;
1220        }
1221
1222        return true;
1223
1224 fail:
1225        return false;
1226}
1227
1228/*
1229 * Initialize brcms_c_info default values ...
1230 * may get overrides later in this function
1231 */
1232void brcms_c_info_init(struct brcms_c_info *wlc, int unit)
1233{
1234        int i;
1235        /* Assume the device is there until proven otherwise */
1236        wlc->device_present = true;
1237
1238        /* Save our copy of the chanspec */
1239        wlc->chanspec = CH20MHZ_CHSPEC(1);
1240
1241        /* various 802.11g modes */
1242        wlc->shortslot = false;
1243        wlc->shortslot_override = BRCMS_SHORTSLOT_AUTO;
1244
1245        brcms_c_protection_upd(wlc, BRCMS_PROT_G_OVR, BRCMS_PROTECTION_AUTO);
1246        brcms_c_protection_upd(wlc, BRCMS_PROT_G_SPEC, false);
1247
1248        brcms_c_protection_upd(wlc, BRCMS_PROT_N_CFG_OVR,
1249                               BRCMS_PROTECTION_AUTO);
1250        brcms_c_protection_upd(wlc, BRCMS_PROT_N_CFG, BRCMS_N_PROTECTION_OFF);
1251        brcms_c_protection_upd(wlc, BRCMS_PROT_N_NONGF_OVR,
1252                               BRCMS_PROTECTION_AUTO);
1253        brcms_c_protection_upd(wlc, BRCMS_PROT_N_NONGF, false);
1254        brcms_c_protection_upd(wlc, BRCMS_PROT_N_PAM_OVR, AUTO);
1255
1256        brcms_c_protection_upd(wlc, BRCMS_PROT_OVERLAP,
1257                               BRCMS_PROTECTION_CTL_OVERLAP);
1258
1259        /* 802.11g draft 4.0 NonERP elt advertisement */
1260        wlc->include_legacy_erp = true;
1261
1262        wlc->stf->ant_rx_ovr = ANT_RX_DIV_DEF;
1263        wlc->stf->txant = ANT_TX_DEF;
1264
1265        wlc->prb_resp_timeout = BRCMS_PRB_RESP_TIMEOUT;
1266
1267        wlc->usr_fragthresh = DOT11_DEFAULT_FRAG_LEN;
1268        for (i = 0; i < NFIFO; i++)
1269                wlc->fragthresh[i] = DOT11_DEFAULT_FRAG_LEN;
1270        wlc->RTSThresh = DOT11_DEFAULT_RTS_LEN;
1271
1272        /* default rate fallback retry limits */
1273        wlc->SFBL = RETRY_SHORT_FB;
1274        wlc->LFBL = RETRY_LONG_FB;
1275
1276        /* default mac retry limits */
1277        wlc->SRL = RETRY_SHORT_DEF;
1278        wlc->LRL = RETRY_LONG_DEF;
1279
1280        /* Set flag to indicate that hw keys should be used when available. */
1281        wlc->wsec_swkeys = false;
1282
1283        /* init the 4 static WEP default keys */
1284        for (i = 0; i < WSEC_MAX_DEFAULT_KEYS; i++) {
1285                wlc->wsec_keys[i] = wlc->wsec_def_keys[i];
1286                wlc->wsec_keys[i]->idx = (u8) i;
1287        }
1288
1289        /* WME QoS mode is Auto by default */
1290        wlc->pub->_wme = AUTO;
1291
1292#ifdef BCMSDIODEV_ENABLED
1293        wlc->pub->_priofc = true;       /* enable priority flow control for sdio dongle */
1294#endif
1295
1296        wlc->pub->_ampdu = AMPDU_AGG_HOST;
1297        wlc->pub->bcmerror = 0;
1298        wlc->pub->_coex = ON;
1299
1300        /* initialize mpc delay */
1301        wlc->mpc_delay_off = wlc->mpc_dlycnt = BRCMS_MPC_MIN_DELAYCNT;
1302}
1303
1304static bool brcms_c_state_bmac_sync(struct brcms_c_info *wlc)
1305{
1306        struct brcms_b_state state_bmac;
1307
1308        if (brcms_b_state_get(wlc->hw, &state_bmac) != 0)
1309                return false;
1310
1311        wlc->machwcap = state_bmac.machwcap;
1312        brcms_c_protection_upd(wlc, BRCMS_PROT_N_PAM_OVR,
1313                           (s8) state_bmac.preamble_ovr);
1314
1315        return true;
1316}
1317
1318static uint brcms_c_attach_module(struct brcms_c_info *wlc)
1319{
1320        uint err = 0;
1321        uint unit;
1322        unit = wlc->pub->unit;
1323
1324        wlc->asi = brcms_c_antsel_attach(wlc);
1325        if (wlc->asi == NULL) {
1326                wiphy_err(wlc->wiphy, "wl%d: attach: antsel_attach "
1327                          "failed\n", unit);
1328                err = 44;
1329                goto fail;
1330        }
1331
1332        wlc->ampdu = brcms_c_ampdu_attach(wlc);
1333        if (wlc->ampdu == NULL) {
1334                wiphy_err(wlc->wiphy, "wl%d: attach: ampdu_attach "
1335                          "failed\n", unit);
1336                err = 50;
1337                goto fail;
1338        }
1339
1340        if ((brcms_c_stf_attach(wlc) != 0)) {
1341                wiphy_err(wlc->wiphy, "wl%d: attach: stf_attach "
1342                          "failed\n", unit);
1343                err = 68;
1344                goto fail;
1345        }
1346 fail:
1347        return err;
1348}
1349
1350struct brcms_pub *brcms_c_pub(void *wlc)
1351{
1352        return ((struct brcms_c_info *) wlc)->pub;
1353}
1354
1355#define CHIP_SUPPORTS_11N(wlc)  1
1356
1357/*
1358 * The common driver entry routine. Error codes should be unique
1359 */
1360void *brcms_c_attach(struct brcms_info *wl, u16 vendor, u16 device, uint unit,
1361                 bool piomode, void *regsva, uint bustype, void *btparam,
1362                 uint *perr)
1363{
1364        struct brcms_c_info *wlc;
1365        uint err = 0;
1366        uint j;
1367        struct brcms_pub *pub;
1368        uint n_disabled;
1369
1370        /* allocate struct brcms_c_info state and its substructures */
1371        wlc = (struct brcms_c_info *) brcms_c_attach_malloc(unit, &err, device);
1372        if (wlc == NULL)
1373                goto fail;
1374        wlc->wiphy = wl->wiphy;
1375        pub = wlc->pub;
1376
1377#if defined(BCMDBG)
1378        wlc_info_dbg = wlc;
1379#endif
1380
1381        wlc->band = wlc->bandstate[0];
1382        wlc->core = wlc->corestate;
1383        wlc->wl = wl;
1384        pub->unit = unit;
1385        pub->_piomode = piomode;
1386        wlc->bandinit_pending = false;
1387
1388        /* populate struct brcms_c_info with default values  */
1389        brcms_c_info_init(wlc, unit);
1390
1391        /* update sta/ap related parameters */
1392        brcms_c_ap_upd(wlc);
1393
1394        /* 11n_disable nvram */
1395        n_disabled = getintvar(pub->vars, "11n_disable");
1396
1397        /*
1398         * low level attach steps(all hw accesses go
1399         * inside, no more in rest of the attach)
1400         */
1401        err = brcms_b_attach(wlc, vendor, device, unit, piomode, regsva,
1402                              bustype, btparam);
1403        if (err)
1404                goto fail;
1405
1406        /* for some states, due to different info pointer(e,g, wlc, wlc_hw) or master/slave split,
1407         * HIGH driver(both monolithic and HIGH_ONLY) needs to sync states FROM BMAC portion driver
1408         */
1409        if (!brcms_c_state_bmac_sync(wlc)) {
1410                err = 20;
1411                goto fail;
1412        }
1413
1414        pub->phy_11ncapable = BRCMS_PHY_11N_CAP(wlc->band);
1415
1416        /* propagate *vars* from BMAC driver to high driver */
1417        brcms_b_copyfrom_vars(wlc->hw, &pub->vars, &wlc->vars_size);
1418
1419
1420        /* set maximum allowed duty cycle */
1421        wlc->tx_duty_cycle_ofdm =
1422            (u16) getintvar(pub->vars, "tx_duty_cycle_ofdm");
1423        wlc->tx_duty_cycle_cck =
1424            (u16) getintvar(pub->vars, "tx_duty_cycle_cck");
1425
1426        brcms_c_stf_phy_chain_calc(wlc);
1427
1428        /* txchain 1: txant 0, txchain 2: txant 1 */
1429        if (BRCMS_ISNPHY(wlc->band) && (wlc->stf->txstreams == 1))
1430                wlc->stf->txant = wlc->stf->hw_txchain - 1;
1431
1432        /* push to BMAC driver */
1433        wlc_phy_stf_chain_init(wlc->band->pi, wlc->stf->hw_txchain,
1434                               wlc->stf->hw_rxchain);
1435
1436        /* pull up some info resulting from the low attach */
1437        {
1438                int i;
1439                for (i = 0; i < NFIFO; i++)
1440                        wlc->core->txavail[i] = wlc->hw->txavail[i];
1441        }
1442
1443        brcms_b_hw_etheraddr(wlc->hw, wlc->perm_etheraddr);
1444
1445        memcpy(&pub->cur_etheraddr, &wlc->perm_etheraddr, ETH_ALEN);
1446
1447        for (j = 0; j < NBANDS(wlc); j++) {
1448                /* Use band 1 for single band 11a */
1449                if (IS_SINGLEBAND_5G(wlc->deviceid))
1450                        j = BAND_5G_INDEX;
1451
1452                wlc->band = wlc->bandstate[j];
1453
1454                if (!brcms_c_attach_stf_ant_init(wlc)) {
1455                        err = 24;
1456                        goto fail;
1457                }
1458
1459                /* default contention windows size limits */
1460                wlc->band->CWmin = APHY_CWMIN;
1461                wlc->band->CWmax = PHY_CWMAX;
1462
1463                /* init gmode value */
1464                if (BAND_2G(wlc->band->bandtype)) {
1465                        wlc->band->gmode = GMODE_AUTO;
1466                        brcms_c_protection_upd(wlc, BRCMS_PROT_G_USER,
1467                                           wlc->band->gmode);
1468                }
1469
1470                /* init _n_enab supported mode */
1471                if (BRCMS_PHY_11N_CAP(wlc->band) && CHIP_SUPPORTS_11N(wlc)) {
1472                        if (n_disabled & WLFEATURE_DISABLE_11N) {
1473                                pub->_n_enab = OFF;
1474                                brcms_c_protection_upd(wlc, BRCMS_PROT_N_USER,
1475                                                       OFF);
1476                        } else {
1477                                pub->_n_enab = SUPPORT_11N;
1478                                brcms_c_protection_upd(wlc, BRCMS_PROT_N_USER,
1479                                                   ((pub->_n_enab ==
1480                                                     SUPPORT_11N) ? WL_11N_2x2 :
1481                                                    WL_11N_3x3));
1482                        }
1483                }
1484
1485                /* init per-band default rateset, depend on band->gmode */
1486                brcms_default_rateset(wlc, &wlc->band->defrateset);
1487
1488                /* fill in hw_rateset (used early by BRCM_SET_RATESET) */
1489                brcms_c_rateset_filter(&wlc->band->defrateset,
1490                                   &wlc->band->hw_rateset, false,
1491                                   BRCMS_RATES_CCK_OFDM, BRCMS_RATE_MASK,
1492                                   (bool) N_ENAB(wlc->pub));
1493        }
1494
1495        /* update antenna config due to wlc->stf->txant/txchain/ant_rx_ovr change */
1496        brcms_c_stf_phy_txant_upd(wlc);
1497
1498        /* attach each modules */
1499        err = brcms_c_attach_module(wlc);
1500        if (err != 0)
1501                goto fail;
1502
1503        if (!brcms_c_timers_init(wlc, unit)) {
1504                wiphy_err(wl->wiphy, "wl%d: %s: init_timer failed\n", unit,
1505                          __func__);
1506                err = 32;
1507                goto fail;
1508        }
1509
1510        /* depend on rateset, gmode */
1511        wlc->cmi = brcms_c_channel_mgr_attach(wlc);
1512        if (!wlc->cmi) {
1513                wiphy_err(wl->wiphy, "wl%d: %s: channel_mgr_attach failed"
1514                          "\n", unit, __func__);
1515                err = 33;
1516                goto fail;
1517        }
1518
1519        /* init default when all parameters are ready, i.e. ->rateset */
1520        brcms_c_bss_default_init(wlc);
1521
1522        /*
1523         * Complete the wlc default state initializations..
1524         */
1525
1526        /* allocate our initial queue */
1527        wlc->pkt_queue = brcms_c_txq_alloc(wlc);
1528        if (wlc->pkt_queue == NULL) {
1529                wiphy_err(wl->wiphy, "wl%d: %s: failed to malloc tx queue\n",
1530                          unit, __func__);
1531                err = 100;
1532                goto fail;
1533        }
1534
1535        wlc->bsscfg[0] = wlc->cfg;
1536        wlc->cfg->_idx = 0;
1537        wlc->cfg->wlc = wlc;
1538        pub->txmaxpkts = MAXTXPKTS;
1539
1540        brcms_c_wme_initparams_sta(wlc, &wlc->wme_param_ie);
1541
1542        wlc->mimoft = FT_HT;
1543        wlc->ht_cap.cap_info = HT_CAP;
1544        if (HT_ENAB(wlc->pub))
1545                wlc->stf->ldpc = AUTO;
1546
1547        wlc->mimo_40txbw = AUTO;
1548        wlc->ofdm_40txbw = AUTO;
1549        wlc->cck_40txbw = AUTO;
1550        brcms_c_update_mimo_band_bwcap(wlc, BRCMS_N_BW_20IN2G_40IN5G);
1551
1552        /* Set default values of SGI */
1553        if (BRCMS_SGI_CAP_PHY(wlc)) {
1554                brcms_c_ht_update_sgi_rx(wlc, (BRCMS_N_SGI_20 |
1555                                               BRCMS_N_SGI_40));
1556                wlc->sgi_tx = AUTO;
1557        } else if (BRCMS_ISSSLPNPHY(wlc->band)) {
1558                brcms_c_ht_update_sgi_rx(wlc, (BRCMS_N_SGI_20 |
1559                                               BRCMS_N_SGI_40));
1560                wlc->sgi_tx = AUTO;
1561        } else {
1562                brcms_c_ht_update_sgi_rx(wlc, 0);
1563                wlc->sgi_tx = OFF;
1564        }
1565
1566        /* *******nvram 11n config overrides Start ********* */
1567
1568        /* apply the sgi override from nvram conf */
1569        if (n_disabled & WLFEATURE_DISABLE_11N_SGI_TX)
1570                wlc->sgi_tx = OFF;
1571
1572        if (n_disabled & WLFEATURE_DISABLE_11N_SGI_RX)
1573                brcms_c_ht_update_sgi_rx(wlc, 0);
1574
1575        /* apply the stbc override from nvram conf */
1576        if (n_disabled & WLFEATURE_DISABLE_11N_STBC_TX) {
1577                wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = OFF;
1578                wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = OFF;
1579                wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_TX_STBC;
1580        }
1581        if (n_disabled & WLFEATURE_DISABLE_11N_STBC_RX)
1582                brcms_c_stf_stbc_rx_set(wlc, HT_CAP_RX_STBC_NO);
1583
1584        /* apply the GF override from nvram conf */
1585        if (n_disabled & WLFEATURE_DISABLE_11N_GF)
1586                wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_GRN_FLD;
1587
1588        /* initialize radio_mpc_disable according to wlc->mpc */
1589        brcms_c_radio_mpc_upd(wlc);
1590        brcms_b_antsel_set(wlc->hw, wlc->asi->antsel_avail);
1591
1592        if (perr)
1593                *perr = 0;
1594
1595        return (void *)wlc;
1596
1597 fail:
1598        wiphy_err(wl->wiphy, "wl%d: %s: failed with err %d\n",
1599                  unit, __func__, err);
1600        if (wlc)
1601                brcms_c_detach(wlc);
1602
1603        if (perr)
1604                *perr = err;
1605        return NULL;
1606}
1607
1608static void brcms_c_attach_antgain_init(struct brcms_c_info *wlc)
1609{
1610        uint unit;
1611        unit = wlc->pub->unit;
1612
1613        if ((wlc->band->antgain == -1) && (wlc->pub->sromrev == 1)) {
1614                /* default antenna gain for srom rev 1 is 2 dBm (8 qdbm) */
1615                wlc->band->antgain = 8;
1616        } else if (wlc->band->antgain == -1) {
1617                wiphy_err(wlc->wiphy, "wl%d: %s: Invalid antennas available in"
1618                          " srom, using 2dB\n", unit, __func__);
1619                wlc->band->antgain = 8;
1620        } else {
1621                s8 gain, fract;
1622                /* Older sroms specified gain in whole dbm only.  In order
1623                 * be able to specify qdbm granularity and remain backward compatible
1624                 * the whole dbms are now encoded in only low 6 bits and remaining qdbms
1625                 * are encoded in the hi 2 bits. 6 bit signed number ranges from
1626                 * -32 - 31. Examples: 0x1 = 1 db,
1627                 * 0xc1 = 1.75 db (1 + 3 quarters),
1628                 * 0x3f = -1 (-1 + 0 quarters),
1629                 * 0x7f = -.75 (-1 in low 6 bits + 1 quarters in hi 2 bits) = -3 qdbm.
1630                 * 0xbf = -.50 (-1 in low 6 bits + 2 quarters in hi 2 bits) = -2 qdbm.
1631                 */
1632                gain = wlc->band->antgain & 0x3f;
1633                gain <<= 2;     /* Sign extend */
1634                gain >>= 2;
1635                fract = (wlc->band->antgain & 0xc0) >> 6;
1636                wlc->band->antgain = 4 * gain + fract;
1637        }
1638}
1639
1640static bool brcms_c_attach_stf_ant_init(struct brcms_c_info *wlc)
1641{
1642        int aa;
1643        uint unit;
1644        char *vars;
1645        int bandtype;
1646
1647        unit = wlc->pub->unit;
1648        vars = wlc->pub->vars;
1649        bandtype = wlc->band->bandtype;
1650
1651        /* get antennas available */
1652        aa = (s8) getintvar(vars, (BAND_5G(bandtype) ? "aa5g" : "aa2g"));
1653        if (aa == 0)
1654                aa = (s8) getintvar(vars,
1655                                      (BAND_5G(bandtype) ? "aa1" : "aa0"));
1656        if ((aa < 1) || (aa > 15)) {
1657                wiphy_err(wlc->wiphy, "wl%d: %s: Invalid antennas available in"
1658                          " srom (0x%x), using 3\n", unit, __func__, aa);
1659                aa = 3;
1660        }
1661
1662        /* reset the defaults if we have a single antenna */
1663        if (aa == 1) {
1664                wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_0;
1665                wlc->stf->txant = ANT_TX_FORCE_0;
1666        } else if (aa == 2) {
1667                wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_1;
1668                wlc->stf->txant = ANT_TX_FORCE_1;
1669        } else {
1670        }
1671
1672        /* Compute Antenna Gain */
1673        wlc->band->antgain =
1674            (s8) getintvar(vars, (BAND_5G(bandtype) ? "ag1" : "ag0"));
1675        brcms_c_attach_antgain_init(wlc);
1676
1677        return true;
1678}
1679
1680
1681static void brcms_c_timers_deinit(struct brcms_c_info *wlc)
1682{
1683        /* free timer state */
1684        if (wlc->wdtimer) {
1685                brcms_free_timer(wlc->wl, wlc->wdtimer);
1686                wlc->wdtimer = NULL;
1687        }
1688        if (wlc->radio_timer) {
1689                brcms_free_timer(wlc->wl, wlc->radio_timer);
1690                wlc->radio_timer = NULL;
1691        }
1692}
1693
1694static void brcms_c_detach_module(struct brcms_c_info *wlc)
1695{
1696        if (wlc->asi) {
1697                brcms_c_antsel_detach(wlc->asi);
1698                wlc->asi = NULL;
1699        }
1700
1701        if (wlc->ampdu) {
1702                brcms_c_ampdu_detach(wlc->ampdu);
1703                wlc->ampdu = NULL;
1704        }
1705
1706        brcms_c_stf_detach(wlc);
1707}
1708
1709/*
1710 * Return a count of the number of driver callbacks still pending.
1711 *
1712 * General policy is that brcms_c_detach can only dealloc/free software states.
1713 * It can NOT touch hardware registers since the d11core may be in reset and
1714 * clock may not be available.
1715 * One exception is sb register access, which is possible if crystal is turned
1716 * on after "down" state, driver should avoid software timer with the exception
1717 * of radio_monitor.
1718 */
1719uint brcms_c_detach(struct brcms_c_info *wlc)
1720{
1721        uint callbacks = 0;
1722
1723        if (wlc == NULL)
1724                return 0;
1725
1726        BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
1727
1728        callbacks += brcms_b_detach(wlc);
1729
1730        /* delete software timers */
1731        if (!brcms_c_radio_monitor_stop(wlc))
1732                callbacks++;
1733
1734        brcms_c_channel_mgr_detach(wlc->cmi);
1735
1736        brcms_c_timers_deinit(wlc);
1737
1738        brcms_c_detach_module(wlc);
1739
1740
1741        while (wlc->tx_queues != NULL)
1742                brcms_c_txq_free(wlc, wlc->tx_queues);
1743
1744        brcms_c_detach_mfree(wlc);
1745        return callbacks;
1746}
1747
1748/* update state that depends on the current value of "ap" */
1749void brcms_c_ap_upd(struct brcms_c_info *wlc)
1750{
1751        if (AP_ENAB(wlc->pub))
1752                /* AP: short not allowed, but not enforced */
1753                wlc->PLCPHdr_override = BRCMS_PLCP_AUTO;
1754        else
1755                /* STA-BSS; short capable */
1756                wlc->PLCPHdr_override = BRCMS_PLCP_SHORT;
1757
1758        /* fixup mpc */
1759        wlc->mpc = true;
1760}
1761
1762/* read hwdisable state and propagate to wlc flag */
1763static void brcms_c_radio_hwdisable_upd(struct brcms_c_info *wlc)
1764{
1765        if (wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO || wlc->pub->hw_off)
1766                return;
1767
1768        if (brcms_b_radio_read_hwdisabled(wlc->hw)) {
1769                mboolset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE);
1770        } else {
1771                mboolclr(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE);
1772        }
1773}
1774
1775/* return true if Minimum Power Consumption should be entered, false otherwise */
1776bool brcms_c_is_non_delay_mpc(struct brcms_c_info *wlc)
1777{
1778        return false;
1779}
1780
1781bool brcms_c_ismpc(struct brcms_c_info *wlc)
1782{
1783        return (wlc->mpc_delay_off == 0) && (brcms_c_is_non_delay_mpc(wlc));
1784}
1785
1786void brcms_c_radio_mpc_upd(struct brcms_c_info *wlc)
1787{
1788        bool mpc_radio, radio_state;
1789
1790        /*
1791         * Clear the WL_RADIO_MPC_DISABLE bit when mpc feature is disabled
1792         * in case the WL_RADIO_MPC_DISABLE bit was set. Stop the radio
1793         * monitor also when WL_RADIO_MPC_DISABLE is the only reason that
1794         * the radio is going down.
1795         */
1796        if (!wlc->mpc) {
1797                if (!wlc->pub->radio_disabled)
1798                        return;
1799                mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE);
1800                brcms_c_radio_upd(wlc);
1801                if (!wlc->pub->radio_disabled)
1802                        brcms_c_radio_monitor_stop(wlc);
1803                return;
1804        }
1805
1806        /*
1807         * sync ismpc logic with WL_RADIO_MPC_DISABLE bit in wlc->pub->radio_disabled
1808         * to go ON, always call radio_upd synchronously
1809         * to go OFF, postpone radio_upd to later when context is safe(e.g. watchdog)
1810         */
1811        radio_state =
1812            (mboolisset(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE) ? OFF :
1813             ON);
1814        mpc_radio = (brcms_c_ismpc(wlc) == true) ? OFF : ON;
1815
1816        if (radio_state == ON && mpc_radio == OFF)
1817                wlc->mpc_delay_off = wlc->mpc_dlycnt;
1818        else if (radio_state == OFF && mpc_radio == ON) {
1819                mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE);
1820                brcms_c_radio_upd(wlc);
1821                if (wlc->mpc_offcnt < BRCMS_MPC_THRESHOLD)
1822                        wlc->mpc_dlycnt = BRCMS_MPC_MAX_DELAYCNT;
1823                else
1824                        wlc->mpc_dlycnt = BRCMS_MPC_MIN_DELAYCNT;
1825                wlc->mpc_dur += OSL_SYSUPTIME() - wlc->mpc_laston_ts;
1826        }
1827        /* Below logic is meant to capture the transition from mpc off to mpc on for reasons
1828         * other than wlc->mpc_delay_off keeping the mpc off. In that case reset
1829         * wlc->mpc_delay_off to wlc->mpc_dlycnt, so that we restart the countdown of mpc_delay_off
1830         */
1831        if ((wlc->prev_non_delay_mpc == false) &&
1832            (brcms_c_is_non_delay_mpc(wlc) == true) && wlc->mpc_delay_off) {
1833                wlc->mpc_delay_off = wlc->mpc_dlycnt;
1834        }
1835        wlc->prev_non_delay_mpc = brcms_c_is_non_delay_mpc(wlc);
1836}
1837
1838/*
1839 * centralized radio disable/enable function,
1840 * invoke radio enable/disable after updating hwradio status
1841 */
1842static void brcms_c_radio_upd(struct brcms_c_info *wlc)
1843{
1844        if (wlc->pub->radio_disabled) {
1845                brcms_c_radio_disable(wlc);
1846        } else {
1847                brcms_c_radio_enable(wlc);
1848        }
1849}
1850
1851/* maintain LED behavior in down state */
1852static void brcms_c_down_led_upd(struct brcms_c_info *wlc)
1853{
1854        /* maintain LEDs while in down state, turn on sbclk if not available yet */
1855        /* turn on sbclk if necessary */
1856        if (!AP_ENAB(wlc->pub)) {
1857                brcms_c_pllreq(wlc, true, BRCMS_PLLREQ_FLIP);
1858
1859                brcms_c_pllreq(wlc, false, BRCMS_PLLREQ_FLIP);
1860        }
1861}
1862
1863/* update hwradio status and return it */
1864bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc)
1865{
1866        brcms_c_radio_hwdisable_upd(wlc);
1867
1868        return mboolisset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE) ? true : false;
1869}
1870
1871void brcms_c_radio_disable(struct brcms_c_info *wlc)
1872{
1873        if (!wlc->pub->up) {
1874                brcms_c_down_led_upd(wlc);
1875                return;
1876        }
1877
1878        brcms_c_radio_monitor_start(wlc);
1879        brcms_down(wlc->wl);
1880}
1881
1882static void brcms_c_radio_enable(struct brcms_c_info *wlc)
1883{
1884        if (wlc->pub->up)
1885                return;
1886
1887        if (DEVICEREMOVED(wlc))
1888                return;
1889
1890        brcms_up(wlc->wl);
1891}
1892
1893/* periodical query hw radio button while driver is "down" */
1894static void brcms_c_radio_timer(void *arg)
1895{
1896        struct brcms_c_info *wlc = (struct brcms_c_info *) arg;
1897
1898        if (DEVICEREMOVED(wlc)) {
1899                wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit,
1900                        __func__);
1901                brcms_down(wlc->wl);
1902                return;
1903        }
1904
1905        /* cap mpc off count */
1906        if (wlc->mpc_offcnt < BRCMS_MPC_MAX_DELAYCNT)
1907                wlc->mpc_offcnt++;
1908
1909        brcms_c_radio_hwdisable_upd(wlc);
1910        brcms_c_radio_upd(wlc);
1911}
1912
1913static bool brcms_c_radio_monitor_start(struct brcms_c_info *wlc)
1914{
1915        /* Don't start the timer if HWRADIO feature is disabled */
1916        if (wlc->radio_monitor || (wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO))
1917                return true;
1918
1919        wlc->radio_monitor = true;
1920        brcms_c_pllreq(wlc, true, BRCMS_PLLREQ_RADIO_MON);
1921        brcms_add_timer(wlc->wl, wlc->radio_timer, TIMER_INTERVAL_RADIOCHK,
1922                        true);
1923        return true;
1924}
1925
1926bool brcms_c_radio_monitor_stop(struct brcms_c_info *wlc)
1927{
1928        if (!wlc->radio_monitor)
1929                return true;
1930
1931        wlc->radio_monitor = false;
1932        brcms_c_pllreq(wlc, false, BRCMS_PLLREQ_RADIO_MON);
1933        return brcms_del_timer(wlc->wl, wlc->radio_timer);
1934}
1935
1936static void brcms_c_watchdog_by_timer(void *arg)
1937{
1938        brcms_c_watchdog(arg);
1939}
1940
1941/* common watchdog code */
1942static void brcms_c_watchdog(void *arg)
1943{
1944        struct brcms_c_info *wlc = (struct brcms_c_info *) arg;
1945        int i;
1946        struct brcms_bss_cfg *cfg;
1947
1948        BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
1949
1950        if (!wlc->pub->up)
1951                return;
1952
1953        if (DEVICEREMOVED(wlc)) {
1954                wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit,
1955                          __func__);
1956                brcms_down(wlc->wl);
1957                return;
1958        }
1959
1960        /* increment second count */
1961        wlc->pub->now++;
1962
1963        /* delay radio disable */
1964        if (wlc->mpc_delay_off) {
1965                if (--wlc->mpc_delay_off == 0) {
1966                        mboolset(wlc->pub->radio_disabled,
1967                                 WL_RADIO_MPC_DISABLE);
1968                        if (wlc->mpc && brcms_c_ismpc(wlc))
1969                                wlc->mpc_offcnt = 0;
1970                        wlc->mpc_laston_ts = OSL_SYSUPTIME();
1971                }
1972        }
1973
1974        /* mpc sync */
1975        brcms_c_radio_mpc_upd(wlc);
1976        /* radio sync: sw/hw/mpc --> radio_disable/radio_enable */
1977        brcms_c_radio_hwdisable_upd(wlc);
1978        brcms_c_radio_upd(wlc);
1979        /* if radio is disable, driver may be down, quit here */
1980        if (wlc->pub->radio_disabled)
1981                return;
1982
1983        brcms_b_watchdog(wlc);
1984
1985        /* occasionally sample mac stat counters to detect 16-bit counter wrap */
1986        if ((wlc->pub->now % SW_TIMER_MAC_STAT_UPD) == 0)
1987                brcms_c_statsupd(wlc);
1988
1989        /* Manage TKIP countermeasures timers */
1990        FOREACH_BSS(wlc, i, cfg) {
1991                if (cfg->tk_cm_dt) {
1992                        cfg->tk_cm_dt--;
1993                }
1994                if (cfg->tk_cm_bt) {
1995                        cfg->tk_cm_bt--;
1996                }
1997        }
1998
1999        /* Call any registered watchdog handlers */
2000        for (i = 0; i < BRCMS_MAXMODULES; i++) {
2001                if (wlc->modulecb[i].watchdog_fn)
2002                        wlc->modulecb[i].watchdog_fn(wlc->modulecb[i].hdl);
2003        }
2004
2005        if (BRCMS_ISNPHY(wlc->band) && !wlc->pub->tempsense_disable &&
2006            ((wlc->pub->now - wlc->tempsense_lasttime) >=
2007             BRCMS_TEMPSENSE_PERIOD)) {
2008                wlc->tempsense_lasttime = wlc->pub->now;
2009                brcms_c_tempsense_upd(wlc);
2010        }
2011}
2012
2013/* make interface operational */
2014int brcms_c_up(struct brcms_c_info *wlc)
2015{
2016        BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
2017
2018        /* HW is turned off so don't try to access it */
2019        if (wlc->pub->hw_off || DEVICEREMOVED(wlc))
2020                return -ENOMEDIUM;
2021
2022        if (!wlc->pub->hw_up) {
2023                brcms_b_hw_up(wlc->hw);
2024                wlc->pub->hw_up = true;
2025        }
2026
2027        if ((wlc->pub->boardflags & BFL_FEM)
2028            && (wlc->pub->sih->chip == BCM4313_CHIP_ID)) {
2029                if (wlc->pub->boardrev >= 0x1250
2030                    && (wlc->pub->boardflags & BFL_FEM_BT)) {
2031                        brcms_c_mhf(wlc, MHF5, MHF5_4313_GPIOCTRL,
2032                                MHF5_4313_GPIOCTRL, BRCM_BAND_ALL);
2033                } else {
2034                        brcms_c_mhf(wlc, MHF4, MHF4_EXTPA_ENABLE,
2035                                    MHF4_EXTPA_ENABLE, BRCM_BAND_ALL);
2036                }
2037        }
2038
2039        /*
2040         * Need to read the hwradio status here to cover the case where the system
2041         * is loaded with the hw radio disabled. We do not want to bring the driver up in this case.
2042         * if radio is disabled, abort up, lower power, start radio timer and return 0(for NDIS)
2043         * don't call radio_update to avoid looping brcms_c_up.
2044         *
2045         * brcms_b_up_prep() returns either 0 or -BCME_RADIOOFF only
2046         */
2047        if (!wlc->pub->radio_disabled) {
2048                int status = brcms_b_up_prep(wlc->hw);
2049                if (status == -ENOMEDIUM) {
2050                        if (!mboolisset
2051                            (wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE)) {
2052                                int idx;
2053                                struct brcms_bss_cfg *bsscfg;
2054                                mboolset(wlc->pub->radio_disabled,
2055                                         WL_RADIO_HW_DISABLE);
2056
2057                                FOREACH_BSS(wlc, idx, bsscfg) {
2058                                        if (!BSSCFG_STA(bsscfg)
2059                                            || !bsscfg->enable || !bsscfg->BSS)
2060                                                continue;
2061                                        wiphy_err(wlc->wiphy, "wl%d.%d: up"
2062                                                  ": rfdisable -> "
2063                                                  "bsscfg_disable()\n",
2064                                                   wlc->pub->unit, idx);
2065                                }
2066                        }
2067                }
2068        }
2069
2070        if (wlc->pub->radio_disabled) {
2071                brcms_c_radio_monitor_start(wlc);
2072                return 0;
2073        }
2074
2075        /* brcms_b_up_prep has done brcms_c_corereset(). so clk is on, set it */
2076        wlc->clk = true;
2077
2078        brcms_c_radio_monitor_stop(wlc);
2079
2080        /* Set EDCF hostflags */
2081        if (EDCF_ENAB(wlc->pub)) {
2082                brcms_c_mhf(wlc, MHF1, MHF1_EDCF, MHF1_EDCF, BRCM_BAND_ALL);
2083        } else {
2084                brcms_c_mhf(wlc, MHF1, MHF1_EDCF, 0, BRCM_BAND_ALL);
2085        }
2086
2087        if (BRCMS_WAR16165(wlc))
2088                brcms_c_mhf(wlc, MHF2, MHF2_PCISLOWCLKWAR, MHF2_PCISLOWCLKWAR,
2089                        BRCM_BAND_ALL);
2090
2091        brcms_init(wlc->wl);
2092        wlc->pub->up = true;
2093
2094        if (wlc->bandinit_pending) {
2095                brcms_c_suspend_mac_and_wait(wlc);
2096                brcms_c_set_chanspec(wlc, wlc->default_bss->chanspec);
2097                wlc->bandinit_pending = false;
2098                brcms_c_enable_mac(wlc);
2099        }
2100
2101        brcms_b_up_finish(wlc->hw);
2102
2103        /* other software states up after ISR is running */
2104        /* start APs that were to be brought up but are not up  yet */
2105        /* if (AP_ENAB(wlc->pub)) brcms_c_restart_ap(wlc->ap); */
2106
2107        /* Program the TX wme params with the current settings */
2108        brcms_c_wme_retries_write(wlc);
2109
2110        /* start one second watchdog timer */
2111        brcms_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, true);
2112        wlc->WDarmed = true;
2113
2114        /* ensure antenna config is up to date */
2115        brcms_c_stf_phy_txant_upd(wlc);
2116        /* ensure LDPC config is in sync */
2117        brcms_c_ht_update_ldpc(wlc, wlc->stf->ldpc);
2118
2119        return 0;
2120}
2121
2122/* Initialize the base precedence map for dequeueing from txq based on WME settings */
2123static void brcms_c_tx_prec_map_init(struct brcms_c_info *wlc)
2124{
2125        wlc->tx_prec_map = BRCMS_PREC_BMP_ALL;
2126        memset(wlc->fifo2prec_map, 0, NFIFO * sizeof(u16));
2127
2128        /* For non-WME, both fifos have overlapping MAXPRIO. So just disable all precedences
2129         * if either is full.
2130         */
2131        if (!EDCF_ENAB(wlc->pub)) {
2132                wlc->fifo2prec_map[TX_DATA_FIFO] = BRCMS_PREC_BMP_ALL;
2133                wlc->fifo2prec_map[TX_CTL_FIFO] = BRCMS_PREC_BMP_ALL;
2134        } else {
2135                wlc->fifo2prec_map[TX_AC_BK_FIFO] = BRCMS_PREC_BMP_AC_BK;
2136                wlc->fifo2prec_map[TX_AC_BE_FIFO] = BRCMS_PREC_BMP_AC_BE;
2137                wlc->fifo2prec_map[TX_AC_VI_FIFO] = BRCMS_PREC_BMP_AC_VI;
2138                wlc->fifo2prec_map[TX_AC_VO_FIFO] = BRCMS_PREC_BMP_AC_VO;
2139        }
2140}
2141
2142static uint brcms_c_down_del_timer(struct brcms_c_info *wlc)
2143{
2144        uint callbacks = 0;
2145
2146        return callbacks;
2147}
2148
2149/*
2150 * Mark the interface nonoperational, stop the software mechanisms,
2151 * disable the hardware, free any transient buffer state.
2152 * Return a count of the number of driver callbacks still pending.
2153 */
2154uint brcms_c_down(struct brcms_c_info *wlc)
2155{
2156
2157        uint callbacks = 0;
2158        int i;
2159        bool dev_gone = false;
2160        struct brcms_txq_info *qi;
2161
2162        BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
2163
2164        /* check if we are already in the going down path */
2165        if (wlc->going_down) {
2166                wiphy_err(wlc->wiphy, "wl%d: %s: Driver going down so return"
2167                          "\n", wlc->pub->unit, __func__);
2168                return 0;
2169        }
2170        if (!wlc->pub->up)
2171                return callbacks;
2172
2173        /* in between, mpc could try to bring down again.. */
2174        wlc->going_down = true;
2175
2176        callbacks += brcms_b_bmac_down_prep(wlc->hw);
2177
2178        dev_gone = DEVICEREMOVED(wlc);
2179
2180        /* Call any registered down handlers */
2181        for (i = 0; i < BRCMS_MAXMODULES; i++) {
2182                if (wlc->modulecb[i].down_fn)
2183                        callbacks +=
2184                            wlc->modulecb[i].down_fn(wlc->modulecb[i].hdl);
2185        }
2186
2187        /* cancel the watchdog timer */
2188        if (wlc->WDarmed) {
2189                if (!brcms_del_timer(wlc->wl, wlc->wdtimer))
2190                        callbacks++;
2191                wlc->WDarmed = false;
2192        }
2193        /* cancel all other timers */
2194        callbacks += brcms_c_down_del_timer(wlc);
2195
2196        wlc->pub->up = false;
2197
2198        wlc_phy_mute_upd(wlc->band->pi, false, PHY_MUTE_ALL);
2199
2200        /* clear txq flow control */
2201        brcms_c_txflowcontrol_reset(wlc);
2202
2203        /* flush tx queues */
2204        for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) {
2205                brcmu_pktq_flush(&qi->q, true, NULL, NULL);
2206        }
2207
2208        callbacks += brcms_b_down_finish(wlc->hw);
2209
2210        /* brcms_b_down_finish has done brcms_c_coredisable(). so clk is off */
2211        wlc->clk = false;
2212
2213        wlc->going_down = false;
2214        return callbacks;
2215}
2216
2217/* Set the current gmode configuration */
2218int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config)
2219{
2220        int ret = 0;
2221        uint i;
2222        wlc_rateset_t rs;
2223        /* Default to 54g Auto */
2224        /* Advertise and use shortslot (-1/0/1 Auto/Off/On) */
2225        s8 shortslot = BRCMS_SHORTSLOT_AUTO;
2226        bool shortslot_restrict = false;        /* Restrict association to stations that support shortslot
2227                                                 */
2228        bool ofdm_basic = false;        /* Make 6, 12, and 24 basic rates */
2229        /* Advertise and use short preambles (-1/0/1 Auto/Off/On) */
2230        int preamble = BRCMS_PLCP_LONG;
2231        bool preamble_restrict = false; /* Restrict association to stations that support short
2232                                         * preambles
2233                                         */
2234        struct brcms_band *band;
2235
2236        /* if N-support is enabled, allow Gmode set as long as requested
2237         * Gmode is not GMODE_LEGACY_B
2238         */
2239        if (N_ENAB(wlc->pub) && gmode == GMODE_LEGACY_B)
2240                return -ENOTSUPP;
2241
2242        /* verify that we are dealing with 2G band and grab the band pointer */
2243        if (wlc->band->bandtype == BRCM_BAND_2G)
2244                band = wlc->band;
2245        else if ((NBANDS(wlc) > 1) &&
2246                 (wlc->bandstate[OTHERBANDUNIT(wlc)]->bandtype == BRCM_BAND_2G))
2247                band = wlc->bandstate[OTHERBANDUNIT(wlc)];
2248        else
2249                return -EINVAL;
2250
2251        /* Legacy or bust when no OFDM is supported by regulatory */
2252        if ((brcms_c_channel_locale_flags_in_band(wlc->cmi, band->bandunit) &
2253             BRCMS_NO_OFDM) && (gmode != GMODE_LEGACY_B))
2254                return -EINVAL;
2255
2256        /* update configuration value */
2257        if (config == true)
2258                brcms_c_protection_upd(wlc, BRCMS_PROT_G_USER, gmode);
2259
2260        /* Clear supported rates filter */
2261        memset(&wlc->sup_rates_override, 0, sizeof(wlc_rateset_t));
2262
2263        /* Clear rateset override */
2264        memset(&rs, 0, sizeof(wlc_rateset_t));
2265
2266        switch (gmode) {
2267        case GMODE_LEGACY_B:
2268                shortslot = BRCMS_SHORTSLOT_OFF;
2269                brcms_c_rateset_copy(&gphy_legacy_rates, &rs);
2270
2271                break;
2272
2273        case GMODE_LRS:
2274                if (AP_ENAB(wlc->pub))
2275                        brcms_c_rateset_copy(&cck_rates,
2276                                             &wlc->sup_rates_override);
2277                break;
2278
2279        case GMODE_AUTO:
2280                /* Accept defaults */
2281                break;
2282
2283        case GMODE_ONLY:
2284                ofdm_basic = true;
2285                preamble = BRCMS_PLCP_SHORT;
2286                preamble_restrict = true;
2287                break;
2288
2289        case GMODE_PERFORMANCE:
2290                if (AP_ENAB(wlc->pub))  /* Put all rates into the Supported Rates element */
2291                        brcms_c_rateset_copy(&cck_ofdm_rates,
2292                                         &wlc->sup_rates_override);
2293
2294                shortslot = BRCMS_SHORTSLOT_ON;
2295                shortslot_restrict = true;
2296                ofdm_basic = true;
2297                preamble = BRCMS_PLCP_SHORT;
2298                preamble_restrict = true;
2299                break;
2300
2301        default:
2302                /* Error */
2303                wiphy_err(wlc->wiphy, "wl%d: %s: invalid gmode %d\n",
2304                          wlc->pub->unit, __func__, gmode);
2305                return -ENOTSUPP;
2306        }
2307
2308        /*
2309         * If we are switching to gmode == GMODE_LEGACY_B,
2310         * clean up rate info that may refer to OFDM rates.
2311         */
2312        if ((gmode == GMODE_LEGACY_B) && (band->gmode != GMODE_LEGACY_B)) {
2313                band->gmode = gmode;
2314                if (band->rspec_override && !IS_CCK(band->rspec_override)) {
2315                        band->rspec_override = 0;
2316                        brcms_c_reprate_init(wlc);
2317                }
2318                if (band->mrspec_override && !IS_CCK(band->mrspec_override)) {
2319                        band->mrspec_override = 0;
2320                }
2321        }
2322
2323        band->gmode = gmode;
2324
2325        wlc->shortslot_override = shortslot;
2326
2327        if (AP_ENAB(wlc->pub)) {
2328                /* wlc->ap->shortslot_restrict = shortslot_restrict; */
2329                wlc->PLCPHdr_override =
2330                    (preamble !=
2331                     BRCMS_PLCP_LONG) ? BRCMS_PLCP_SHORT : BRCMS_PLCP_AUTO;
2332        }
2333
2334        if ((AP_ENAB(wlc->pub) && preamble != BRCMS_PLCP_LONG)
2335            || preamble == BRCMS_PLCP_SHORT)
2336                wlc->default_bss->capability |= WLAN_CAPABILITY_SHORT_PREAMBLE;
2337        else
2338                wlc->default_bss->capability &= ~WLAN_CAPABILITY_SHORT_PREAMBLE;
2339
2340        /* Update shortslot capability bit for AP and IBSS */
2341        if ((AP_ENAB(wlc->pub) && shortslot == BRCMS_SHORTSLOT_AUTO) ||
2342            shortslot == BRCMS_SHORTSLOT_ON)
2343                wlc->default_bss->capability |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
2344        else
2345                wlc->default_bss->capability &=
2346                                        ~WLAN_CAPABILITY_SHORT_SLOT_TIME;
2347
2348        /* Use the default 11g rateset */
2349        if (!rs.count)
2350                brcms_c_rateset_copy(&cck_ofdm_rates, &rs);
2351
2352        if (ofdm_basic) {
2353                for (i = 0; i < rs.count; i++) {
2354                        if (rs.rates[i] == BRCM_RATE_6M
2355                            || rs.rates[i] == BRCM_RATE_12M
2356                            || rs.rates[i] == BRCM_RATE_24M)
2357                                rs.rates[i] |= BRCMS_RATE_FLAG;
2358                }
2359        }
2360
2361        /* Set default bss rateset */
2362        wlc->default_bss->rateset.count = rs.count;
2363        memcpy(wlc->default_bss->rateset.rates, rs.rates,
2364               sizeof(wlc->default_bss->rateset.rates));
2365
2366        return ret;
2367}
2368
2369static int brcms_c_nmode_validate(struct brcms_c_info *wlc, s32 nmode)
2370{
2371        int err = 0;
2372
2373        switch (nmode) {
2374
2375        case OFF:
2376                break;
2377
2378        case AUTO:
2379        case WL_11N_2x2:
2380        case WL_11N_3x3:
2381                if (!(BRCMS_PHY_11N_CAP(wlc->band)))
2382                        err = -EINVAL;
2383                break;
2384
2385        default:
2386                err = -EINVAL;
2387                break;
2388        }
2389
2390        return err;
2391}
2392
2393int brcms_c_set_nmode(struct brcms_c_info *wlc, s32 nmode)
2394{
2395        uint i;
2396        int err;
2397
2398        err = brcms_c_nmode_validate(wlc, nmode);
2399        if (err)
2400                return err;
2401
2402        switch (nmode) {
2403        case OFF:
2404                wlc->pub->_n_enab = OFF;
2405                wlc->default_bss->flags &= ~BRCMS_BSS_HT;
2406                /* delete the mcs rates from the default and hw ratesets */
2407                brcms_c_rateset_mcs_clear(&wlc->default_bss->rateset);
2408                for (i = 0; i < NBANDS(wlc); i++) {
2409                        memset(wlc->bandstate[i]->hw_rateset.mcs, 0,
2410                               MCSSET_LEN);
2411                        if (IS_MCS(wlc->band->rspec_override)) {
2412                                wlc->bandstate[i]->rspec_override = 0;
2413                                brcms_c_reprate_init(wlc);
2414                        }
2415                        if (IS_MCS(wlc->band->mrspec_override))
2416                                wlc->bandstate[i]->mrspec_override = 0;
2417                }
2418                break;
2419
2420        case AUTO:
2421                if (wlc->stf->txstreams == WL_11N_3x3)
2422                        nmode = WL_11N_3x3;
2423                else
2424                        nmode = WL_11N_2x2;
2425        case WL_11N_2x2:
2426        case WL_11N_3x3:
2427                /* force GMODE_AUTO if NMODE is ON */
2428                brcms_c_set_gmode(wlc, GMODE_AUTO, true);
2429                if (nmode == WL_11N_3x3)
2430                        wlc->pub->_n_enab = SUPPORT_HT;
2431                else
2432                        wlc->pub->_n_enab = SUPPORT_11N;
2433                wlc->default_bss->flags |= BRCMS_BSS_HT;
2434                /* add the mcs rates to the default and hw ratesets */
2435                brcms_c_rateset_mcs_build(&wlc->default_bss->rateset,
2436                                      wlc->stf->txstreams);
2437                for (i = 0; i < NBANDS(wlc); i++)
2438                        memcpy(wlc->bandstate[i]->hw_rateset.mcs,
2439                               wlc->default_bss->rateset.mcs, MCSSET_LEN);
2440                break;
2441
2442        default:
2443                break;
2444        }
2445
2446        return err;
2447}
2448
2449static int brcms_c_set_rateset(struct brcms_c_info *wlc, wlc_rateset_t *rs_arg)
2450{
2451        wlc_rateset_t rs, new;
2452        uint bandunit;
2453
2454        memcpy(&rs, rs_arg, sizeof(wlc_rateset_t));
2455
2456        /* check for bad count value */
2457        if ((rs.count == 0) || (rs.count > BRCMS_NUMRATES))
2458                return -EINVAL;
2459
2460        /* try the current band */
2461        bandunit = wlc->band->bandunit;
2462        memcpy(&new, &rs, sizeof(wlc_rateset_t));
2463        if (brcms_c_rate_hwrs_filter_sort_validate
2464            (&new, &wlc->bandstate[bandunit]->hw_rateset, true,
2465             wlc->stf->txstreams))
2466                goto good;
2467
2468        /* try the other band */
2469        if (IS_MBAND_UNLOCKED(wlc)) {
2470                bandunit = OTHERBANDUNIT(wlc);
2471                memcpy(&new, &rs, sizeof(wlc_rateset_t));
2472                if (brcms_c_rate_hwrs_filter_sort_validate(&new,
2473                                                       &wlc->
2474                                                       bandstate[bandunit]->
2475                                                       hw_rateset, true,
2476                                                       wlc->stf->txstreams))
2477                        goto good;
2478        }
2479
2480        return -EBADE;
2481
2482 good:
2483        /* apply new rateset */
2484        memcpy(&wlc->default_bss->rateset, &new, sizeof(wlc_rateset_t));
2485        memcpy(&wlc->bandstate[bandunit]->defrateset, &new,
2486               sizeof(wlc_rateset_t));
2487        return 0;
2488}
2489
2490/* simplified integer set interface for common ioctl handler */
2491int brcms_c_set(struct brcms_c_info *wlc, int cmd, int arg)
2492{
2493        return brcms_c_ioctl(wlc, cmd, (void *)&arg, sizeof(arg), NULL);
2494}
2495
2496/* simplified integer get interface for common ioctl handler */
2497int brcms_c_get(struct brcms_c_info *wlc, int cmd, int *arg)
2498{
2499        return brcms_c_ioctl(wlc, cmd, arg, sizeof(int), NULL);
2500}
2501
2502static void brcms_c_ofdm_rateset_war(struct brcms_c_info *wlc)
2503{
2504        u8 r;
2505        bool war = false;
2506
2507        if (wlc->cfg->associated)
2508                r = wlc->cfg->current_bss->rateset.rates[0];
2509        else
2510                r = wlc->default_bss->rateset.rates[0];
2511
2512        wlc_phy_ofdm_rateset_war(wlc->band->pi, war);
2513
2514        return;
2515}
2516
2517int
2518brcms_c_ioctl(struct brcms_c_info *wlc, int cmd, void *arg, int len,
2519              struct brcms_c_if *wlcif)
2520{
2521        return _brcms_c_ioctl(wlc, cmd, arg, len, wlcif);
2522}
2523
2524/* common ioctl handler. return: 0=ok, -1=error, positive=particular error */
2525static int
2526_brcms_c_ioctl(struct brcms_c_info *wlc, int cmd, void *arg, int len,
2527               struct brcms_c_if *wlcif)
2528{
2529        int val, *pval;
2530        bool bool_val;
2531        int bcmerror;
2532        struct scb *nextscb;
2533        bool ta_ok;
2534        uint band;
2535        struct brcms_bss_cfg *bsscfg;
2536        struct brcms_bss_info *current_bss;
2537
2538        /* update bsscfg pointer */
2539        bsscfg = wlc->cfg;
2540        current_bss = bsscfg->current_bss;
2541
2542        /* initialize the following to get rid of compiler warning */
2543        nextscb = NULL;
2544        ta_ok = false;
2545        band = 0;
2546
2547        /* If the device is turned off, then it's not "removed" */
2548        if (!wlc->pub->hw_off && DEVICEREMOVED(wlc)) {
2549                wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit,
2550                          __func__);
2551                brcms_down(wlc->wl);
2552                return -EBADE;
2553        }
2554
2555        /* default argument is generic integer */
2556        pval = arg ? (int *)arg : NULL;
2557
2558        /* This will prevent the misaligned access */
2559        if (pval && (u32) len >= sizeof(val))
2560                memcpy(&val, pval, sizeof(val));
2561        else
2562                val = 0;
2563
2564        /* bool conversion to avoid duplication below */
2565        bool_val = val != 0;
2566        bcmerror = 0;
2567
2568        if ((arg == NULL) || (len <= 0)) {
2569                wiphy_err(wlc->wiphy, "wl%d: %s: Command %d needs arguments\n",
2570                          wlc->pub->unit, __func__, cmd);
2571                bcmerror = -EINVAL;
2572                goto done;
2573        }
2574
2575        switch (cmd) {
2576
2577        case BRCM_SET_CHANNEL:{
2578                        chanspec_t chspec = CH20MHZ_CHSPEC(val);
2579
2580                        if (val < 0 || val > MAXCHANNEL) {
2581                                bcmerror = -EINVAL;
2582                                break;
2583                        }
2584
2585                        if (!brcms_c_valid_chanspec_db(wlc->cmi, chspec)) {
2586                                bcmerror = -EINVAL;
2587                                break;
2588                        }
2589
2590                        if (!wlc->pub->up && IS_MBAND_UNLOCKED(wlc)) {
2591                                if (wlc->band->bandunit !=
2592                                    CHSPEC_BANDUNIT(chspec))
2593                                        wlc->bandinit_pending = true;
2594                                else
2595                                        wlc->bandinit_pending = false;
2596                        }
2597
2598                        wlc->default_bss->chanspec = chspec;
2599                        /* brcms_c_BSSinit() will sanitize the rateset before
2600                         * using it.. */
2601                        if (wlc->pub->up &&
2602                            (BRCMS_BAND_PI_RADIO_CHANSPEC != chspec)) {
2603                                brcms_c_set_home_chanspec(wlc, chspec);
2604                                brcms_c_suspend_mac_and_wait(wlc);
2605                                brcms_c_set_chanspec(wlc, chspec);
2606                                brcms_c_enable_mac(wlc);
2607                        }
2608                        break;
2609                }
2610
2611        case BRCM_SET_SRL:
2612                if (val >= 1 && val <= RETRY_SHORT_MAX) {
2613                        int ac;
2614                        wlc->SRL = (u16) val;
2615
2616                        brcms_b_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL);
2617
2618                        for (ac = 0; ac < AC_COUNT; ac++) {
2619                                BRCMS_WME_RETRY_SHORT_SET(wlc, ac, wlc->SRL);
2620                        }
2621                        brcms_c_wme_retries_write(wlc);
2622                } else
2623                        bcmerror = -EINVAL;
2624                break;
2625
2626        case BRCM_SET_LRL:
2627                if (val >= 1 && val <= 255) {
2628                        int ac;
2629                        wlc->LRL = (u16) val;
2630
2631                        brcms_b_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL);
2632
2633                        for (ac = 0; ac < AC_COUNT; ac++) {
2634                                BRCMS_WME_RETRY_LONG_SET(wlc, ac, wlc->LRL);
2635                        }
2636                        brcms_c_wme_retries_write(wlc);
2637                } else
2638                        bcmerror = -EINVAL;
2639                break;
2640
2641        case BRCM_GET_CURR_RATESET:{
2642                        wl_rateset_t *ret_rs = (wl_rateset_t *) arg;
2643                        wlc_rateset_t *rs;
2644
2645                        if (wlc->pub->associated)
2646                                rs = &current_bss->rateset;
2647                        else
2648                                rs = &wlc->default_bss->rateset;
2649
2650                        if (len < (int)(rs->count + sizeof(rs->count))) {
2651                                bcmerror = -EOVERFLOW;
2652                                break;
2653                        }
2654
2655                        /* Copy only legacy rateset section */
2656                        ret_rs->count = rs->count;
2657                        memcpy(&ret_rs->rates, &rs->rates, rs->count);
2658                        break;
2659                }
2660
2661        case BRCM_SET_RATESET:{
2662                        wlc_rateset_t rs;
2663                        wl_rateset_t *in_rs = (wl_rateset_t *) arg;
2664
2665                        if (len < (int)(in_rs->count + sizeof(in_rs->count))) {
2666                                bcmerror = -EOVERFLOW;
2667                                break;
2668                        }
2669
2670                        if (in_rs->count > BRCMS_NUMRATES) {
2671                                bcmerror = -ENOBUFS;
2672                                break;
2673                        }
2674
2675                        memset(&rs, 0, sizeof(wlc_rateset_t));
2676
2677                        /* Copy only legacy rateset section */
2678                        rs.count = in_rs->count;
2679                        memcpy(&rs.rates, &in_rs->rates, rs.count);
2680
2681                        /* merge rateset coming in with the current mcsset */
2682                        if (N_ENAB(wlc->pub)) {
2683                                if (bsscfg->associated)
2684                                        memcpy(rs.mcs,
2685                                               &current_bss->rateset.mcs[0],
2686                                               MCSSET_LEN);
2687                                else
2688                                        memcpy(rs.mcs,
2689                                               &wlc->default_bss->rateset.mcs[0],
2690                                               MCSSET_LEN);
2691                        }
2692
2693                        bcmerror = brcms_c_set_rateset(wlc, &rs);
2694
2695                        if (!bcmerror)
2696                                brcms_c_ofdm_rateset_war(wlc);
2697
2698                        break;
2699                }
2700
2701        case BRCM_SET_BCNPRD:
2702                /* range [1, 0xffff] */
2703                if (val >= DOT11_MIN_BEACON_PERIOD
2704                    && val <= DOT11_MAX_BEACON_PERIOD)
2705                        wlc->default_bss->beacon_period = (u16) val;
2706                else
2707                        bcmerror = -EINVAL;
2708                break;
2709
2710        case BRCM_GET_PHYLIST:
2711                {
2712                        unsigned char *cp = arg;
2713                        if (len < 3) {
2714                                bcmerror = -EOVERFLOW;
2715                                break;
2716                        }
2717
2718                        if (BRCMS_ISNPHY(wlc->band))
2719                                *cp++ = 'n';
2720                        else if (BRCMS_ISLCNPHY(wlc->band))
2721                                *cp++ = 'c';
2722                        else if (BRCMS_ISSSLPNPHY(wlc->band))
2723                                *cp++ = 's';
2724                        *cp = '\0';
2725                        break;
2726                }
2727
2728        case BRCMS_SET_SHORTSLOT_OVERRIDE:
2729                if (val != BRCMS_SHORTSLOT_AUTO && val != BRCMS_SHORTSLOT_OFF &&
2730                    val != BRCMS_SHORTSLOT_ON) {
2731                        bcmerror = -EINVAL;
2732                        break;
2733                }
2734
2735                wlc->shortslot_override = (s8) val;
2736
2737                /* shortslot is an 11g feature, so no more work if we are
2738                 * currently on the 5G band
2739                 */
2740                if (BAND_5G(wlc->band->bandtype))
2741                        break;
2742
2743                if (wlc->pub->up && wlc->pub->associated) {
2744                        /* let watchdog or beacon processing update shortslot */
2745                } else if (wlc->pub->up) {
2746                        /* unassociated shortslot is off */
2747                        brcms_c_switch_shortslot(wlc, false);
2748                } else {
2749                        /* driver is down, so just update the brcms_c_info
2750                         * value */
2751                        if (wlc->shortslot_override == BRCMS_SHORTSLOT_AUTO) {
2752                                wlc->shortslot = false;
2753                        } else {
2754                                wlc->shortslot =
2755                                    (wlc->shortslot_override ==
2756                                     BRCMS_SHORTSLOT_ON);
2757                        }
2758                }
2759
2760                break;
2761
2762        }
2763 done:
2764
2765        if (bcmerror)
2766                wlc->pub->bcmerror = bcmerror;
2767
2768        return bcmerror;
2769}
2770
2771/*
2772 * register watchdog and down handlers.
2773 */
2774int brcms_c_module_register(struct brcms_pub *pub,
2775                        const char *name, void *hdl,
2776                        watchdog_fn_t w_fn, down_fn_t d_fn)
2777{
2778        struct brcms_c_info *wlc = (struct brcms_c_info *) pub->wlc;
2779        int i;
2780
2781        /* find an empty entry and just add, no duplication check! */
2782        for (i = 0; i < BRCMS_MAXMODULES; i++) {
2783                if (wlc->modulecb[i].name[0] == '\0') {
2784                        strncpy(wlc->modulecb[i].name, name,
2785                                sizeof(wlc->modulecb[i].name) - 1);
2786                        wlc->modulecb[i].hdl = hdl;
2787                        wlc->modulecb[i].watchdog_fn = w_fn;
2788                        wlc->modulecb[i].down_fn = d_fn;
2789                        return 0;
2790                }
2791        }
2792
2793        return -ENOSR;
2794}
2795
2796/* unregister module callbacks */
2797int
2798brcms_c_module_unregister(struct brcms_pub *pub, const char *name, void *hdl)
2799{
2800        struct brcms_c_info *wlc = (struct brcms_c_info *) pub->wlc;
2801        int i;
2802
2803        if (wlc == NULL)
2804                return -ENODATA;
2805
2806        for (i = 0; i < BRCMS_MAXMODULES; i++) {
2807                if (!strcmp(wlc->modulecb[i].name, name) &&
2808                    (wlc->modulecb[i].hdl == hdl)) {
2809                        memset(&wlc->modulecb[i], 0, sizeof(struct modulecb));
2810                        return 0;
2811                }
2812        }
2813
2814        /* table not found! */
2815        return -ENODATA;
2816}
2817
2818/* Write WME tunable parameters for retransmit/max rate from wlc struct to ucode */
2819static void brcms_c_wme_retries_write(struct brcms_c_info *wlc)
2820{
2821        int ac;
2822
2823        /* Need clock to do this */
2824        if (!wlc->clk)
2825                return;
2826
2827        for (ac = 0; ac < AC_COUNT; ac++) {
2828                brcms_c_write_shm(wlc, M_AC_TXLMT_ADDR(ac),
2829                                  wlc->wme_retries[ac]);
2830        }
2831}
2832
2833#ifdef BCMDBG
2834static const char * const supr_reason[] = {
2835        "None", "PMQ Entry", "Flush request",
2836        "Previous frag failure", "Channel mismatch",
2837        "Lifetime Expiry", "Underflow"
2838};
2839
2840static void brcms_c_print_txs_status(u16 s)
2841{
2842        printk(KERN_DEBUG "[15:12]  %d  frame attempts\n",
2843               (s & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT);
2844        printk(KERN_DEBUG " [11:8]  %d  rts attempts\n",
2845               (s & TX_STATUS_RTS_RTX_MASK) >> TX_STATUS_RTS_RTX_SHIFT);
2846        printk(KERN_DEBUG "    [7]  %d  PM mode indicated\n",
2847               ((s & TX_STATUS_PMINDCTD) ? 1 : 0));
2848        printk(KERN_DEBUG "    [6]  %d  intermediate status\n",
2849               ((s & TX_STATUS_INTERMEDIATE) ? 1 : 0));
2850        printk(KERN_DEBUG "    [5]  %d  AMPDU\n",
2851               (s & TX_STATUS_AMPDU) ? 1 : 0);
2852        printk(KERN_DEBUG "  [4:2]  %d  Frame Suppressed Reason (%s)\n",
2853               ((s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT),
2854               supr_reason[(s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT]);
2855        printk(KERN_DEBUG "    [1]  %d  acked\n",
2856               ((s & TX_STATUS_ACK_RCV) ? 1 : 0));
2857}
2858#endif                          /* BCMDBG */
2859
2860void brcms_c_print_txstatus(struct tx_status *txs)
2861{
2862#if defined(BCMDBG)
2863        u16 s = txs->status;
2864        u16 ackphyrxsh = txs->ackphyrxsh;
2865
2866        printk(KERN_DEBUG "\ntxpkt (MPDU) Complete\n");
2867
2868        printk(KERN_DEBUG "FrameID: %04x   ", txs->frameid);
2869        printk(KERN_DEBUG "TxStatus: %04x", s);
2870        printk(KERN_DEBUG "\n");
2871
2872        brcms_c_print_txs_status(s);
2873
2874        printk(KERN_DEBUG "LastTxTime: %04x ", txs->lasttxtime);
2875        printk(KERN_DEBUG "Seq: %04x ", txs->sequence);
2876        printk(KERN_DEBUG "PHYTxStatus: %04x ", txs->phyerr);
2877        printk(KERN_DEBUG "RxAckRSSI: %04x ",
2878               (ackphyrxsh & PRXS1_JSSI_MASK) >> PRXS1_JSSI_SHIFT);
2879        printk(KERN_DEBUG "RxAckSQ: %04x",
2880               (ackphyrxsh & PRXS1_SQ_MASK) >> PRXS1_SQ_SHIFT);
2881        printk(KERN_DEBUG "\n");
2882#endif                          /* defined(BCMDBG) */
2883}
2884
2885void brcms_c_statsupd(struct brcms_c_info *wlc)
2886{
2887        int i;
2888        struct macstat macstats;
2889#ifdef BCMDBG
2890        u16 delta;
2891        u16 rxf0ovfl;
2892        u16 txfunfl[NFIFO];
2893#endif                          /* BCMDBG */
2894
2895        /* if driver down, make no sense to update stats */
2896        if (!wlc->pub->up)
2897                return;
2898
2899#ifdef BCMDBG
2900        /* save last rx fifo 0 overflow count */
2901        rxf0ovfl = wlc->core->macstat_snapshot->rxf0ovfl;
2902
2903        /* save last tx fifo  underflow count */
2904        for (i = 0; i < NFIFO; i++)
2905                txfunfl[i] = wlc->core->macstat_snapshot->txfunfl[i];
2906#endif                          /* BCMDBG */
2907
2908        /* Read mac stats from contiguous shared memory */
2909        brcms_b_copyfrom_shm(wlc->hw, M_UCODE_MACSTAT,
2910                             &macstats, sizeof(struct macstat));
2911
2912#ifdef BCMDBG
2913        /* check for rx fifo 0 overflow */
2914        delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl);
2915        if (delta)
2916                wiphy_err(wlc->wiphy, "wl%d: %u rx fifo 0 overflows!\n",
2917                          wlc->pub->unit, delta);
2918
2919        /* check for tx fifo underflows */
2920        for (i = 0; i < NFIFO; i++) {
2921                delta =
2922                    (u16) (wlc->core->macstat_snapshot->txfunfl[i] -
2923                              txfunfl[i]);
2924                if (delta)
2925                        wiphy_err(wlc->wiphy, "wl%d: %u tx fifo %d underflows!"
2926                                  "\n", wlc->pub->unit, delta, i);
2927        }
2928#endif                          /* BCMDBG */
2929
2930        /* merge counters from dma module */
2931        for (i = 0; i < NFIFO; i++) {
2932                if (wlc->hw->di[i]) {
2933                        dma_counterreset(wlc->hw->di[i]);
2934                }
2935        }
2936}
2937
2938bool brcms_c_chipmatch(u16 vendor, u16 device)
2939{
2940        if (vendor != PCI_VENDOR_ID_BROADCOM) {
2941                pr_err("chipmatch: unknown vendor id %04x\n", vendor);
2942                return false;
2943        }
2944
2945        if (device == BCM43224_D11N_ID_VEN1)
2946                return true;
2947        if ((device == BCM43224_D11N_ID) || (device == BCM43225_D11N2G_ID))
2948                return true;
2949        if (device == BCM4313_D11N2G_ID)
2950                return true;
2951        if ((device == BCM43236_D11N_ID) || (device == BCM43236_D11N2G_ID))
2952                return true;
2953
2954        pr_err("chipmatch: unknown device id %04x\n", device);
2955        return false;
2956}
2957
2958#if defined(BCMDBG)
2959void brcms_c_print_txdesc(struct d11txh *txh)
2960{
2961        u16 mtcl = le16_to_cpu(txh->MacTxControlLow);
2962        u16 mtch = le16_to_cpu(txh->MacTxControlHigh);
2963        u16 mfc = le16_to_cpu(txh->MacFrameControl);
2964        u16 tfest = le16_to_cpu(txh->TxFesTimeNormal);
2965        u16 ptcw = le16_to_cpu(txh->PhyTxControlWord);
2966        u16 ptcw_1 = le16_to_cpu(txh->PhyTxControlWord_1);
2967        u16 ptcw_1_Fbr = le16_to_cpu(txh->PhyTxControlWord_1_Fbr);
2968        u16 ptcw_1_Rts = le16_to_cpu(txh->PhyTxControlWord_1_Rts);
2969        u16 ptcw_1_FbrRts = le16_to_cpu(txh->PhyTxControlWord_1_FbrRts);
2970        u16 mainrates = le16_to_cpu(txh->MainRates);
2971        u16 xtraft = le16_to_cpu(txh->XtraFrameTypes);
2972        u8 *iv = txh->IV;
2973        u8 *ra = txh->TxFrameRA;
2974        u16 tfestfb = le16_to_cpu(txh->TxFesTimeFallback);
2975        u8 *rtspfb = txh->RTSPLCPFallback;
2976        u16 rtsdfb = le16_to_cpu(txh->RTSDurFallback);
2977        u8 *fragpfb = txh->FragPLCPFallback;
2978        u16 fragdfb = le16_to_cpu(txh->FragDurFallback);
2979        u16 mmodelen = le16_to_cpu(txh->MModeLen);
2980        u16 mmodefbrlen = le16_to_cpu(txh->MModeFbrLen);
2981        u16 tfid = le16_to_cpu(txh->TxFrameID);
2982        u16 txs = le16_to_cpu(txh->TxStatus);
2983        u16 mnmpdu = le16_to_cpu(txh->MaxNMpdus);
2984        u16 mabyte = le16_to_cpu(txh->MaxABytes_MRT);
2985        u16 mabyte_f = le16_to_cpu(txh->MaxABytes_FBR);
2986        u16 mmbyte = le16_to_cpu(txh->MinMBytes);
2987
2988        u8 *rtsph = txh->RTSPhyHeader;
2989        struct ieee80211_rts rts = txh->rts_frame;
2990        char hexbuf[256];
2991
2992        /* add plcp header along with txh descriptor */
2993        printk(KERN_DEBUG "Raw TxDesc + plcp header:\n");
2994        print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
2995                             txh, sizeof(struct d11txh) + 48);
2996
2997        printk(KERN_DEBUG "TxCtlLow: %04x ", mtcl);
2998        printk(KERN_DEBUG "TxCtlHigh: %04x ", mtch);
2999        printk(KERN_DEBUG "FC: %04x ", mfc);
3000        printk(KERN_DEBUG "FES Time: %04x\n", tfest);
3001        printk(KERN_DEBUG "PhyCtl: %04x%s ", ptcw,
3002               (ptcw & PHY_TXC_SHORT_HDR) ? " short" : "");
3003        printk(KERN_DEBUG "PhyCtl_1: %04x ", ptcw_1);
3004        printk(KERN_DEBUG "PhyCtl_1_Fbr: %04x\n", ptcw_1_Fbr);
3005        printk(KERN_DEBUG "PhyCtl_1_Rts: %04x ", ptcw_1_Rts);
3006        printk(KERN_DEBUG "PhyCtl_1_Fbr_Rts: %04x\n", ptcw_1_FbrRts);
3007        printk(KERN_DEBUG "MainRates: %04x ", mainrates);
3008        printk(KERN_DEBUG "XtraFrameTypes: %04x ", xtraft);
3009        printk(KERN_DEBUG "\n");
3010
3011        brcmu_format_hex(hexbuf, iv, sizeof(txh->IV));
3012        printk(KERN_DEBUG "SecIV:       %s\n", hexbuf);
3013        brcmu_format_hex(hexbuf, ra, sizeof(txh->TxFrameRA));
3014        printk(KERN_DEBUG "RA:          %s\n", hexbuf);
3015
3016        printk(KERN_DEBUG "Fb FES Time: %04x ", tfestfb);
3017        brcmu_format_hex(hexbuf, rtspfb, sizeof(txh->RTSPLCPFallback));
3018        printk(KERN_DEBUG "RTS PLCP: %s ", hexbuf);
3019        printk(KERN_DEBUG "RTS DUR: %04x ", rtsdfb);
3020        brcmu_format_hex(hexbuf, fragpfb, sizeof(txh->FragPLCPFallback));
3021        printk(KERN_DEBUG "PLCP: %s ", hexbuf);
3022        printk(KERN_DEBUG "DUR: %04x", fragdfb);
3023        printk(KERN_DEBUG "\n");
3024
3025        printk(KERN_DEBUG "MModeLen: %04x ", mmodelen);
3026        printk(KERN_DEBUG "MModeFbrLen: %04x\n", mmodefbrlen);
3027
3028        printk(KERN_DEBUG "FrameID:     %04x\n", tfid);
3029        printk(KERN_DEBUG "TxStatus:    %04x\n", txs);
3030
3031        printk(KERN_DEBUG "MaxNumMpdu:  %04x\n", mnmpdu);
3032        printk(KERN_DEBUG "MaxAggbyte:  %04x\n", mabyte);
3033        printk(KERN_DEBUG "MaxAggbyte_fb:  %04x\n", mabyte_f);
3034        printk(KERN_DEBUG "MinByte:     %04x\n", mmbyte);
3035
3036        brcmu_format_hex(hexbuf, rtsph, sizeof(txh->RTSPhyHeader));
3037        printk(KERN_DEBUG "RTS PLCP: %s ", hexbuf);
3038        brcmu_format_hex(hexbuf, (u8 *) &rts, sizeof(txh->rts_frame));
3039        printk(KERN_DEBUG "RTS Frame: %s", hexbuf);
3040        printk(KERN_DEBUG "\n");
3041}
3042#endif                          /* defined(BCMDBG) */
3043
3044#if defined(BCMDBG)
3045void brcms_c_print_rxh(struct d11rxhdr *rxh)
3046{
3047        u16 len = rxh->RxFrameSize;
3048        u16 phystatus_0 = rxh->PhyRxStatus_0;
3049        u16 phystatus_1 = rxh->PhyRxStatus_1;
3050        u16 phystatus_2 = rxh->PhyRxStatus_2;
3051        u16 phystatus_3 = rxh->PhyRxStatus_3;
3052        u16 macstatus1 = rxh->RxStatus1;
3053        u16 macstatus2 = rxh->RxStatus2;
3054        char flagstr[64];
3055        char lenbuf[20];
3056        static const struct brcmu_bit_desc macstat_flags[] = {
3057                {RXS_FCSERR, "FCSErr"},
3058                {RXS_RESPFRAMETX, "Reply"},
3059                {RXS_PBPRES, "PADDING"},
3060                {RXS_DECATMPT, "DeCr"},
3061                {RXS_DECERR, "DeCrErr"},
3062                {RXS_BCNSENT, "Bcn"},
3063                {0, NULL}
3064        };
3065
3066        printk(KERN_DEBUG "Raw RxDesc:\n");
3067        print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, rxh,
3068                             sizeof(struct d11rxhdr));
3069
3070        brcmu_format_flags(macstat_flags, macstatus1, flagstr, 64);
3071
3072        snprintf(lenbuf, sizeof(lenbuf), "0x%x", len);
3073
3074        printk(KERN_DEBUG "RxFrameSize:     %6s (%d)%s\n", lenbuf, len,
3075               (rxh->PhyRxStatus_0 & PRXS0_SHORTH) ? " short preamble" : "");
3076        printk(KERN_DEBUG "RxPHYStatus:     %04x %04x %04x %04x\n",
3077               phystatus_0, phystatus_1, phystatus_2, phystatus_3);
3078        printk(KERN_DEBUG "RxMACStatus:     %x %s\n", macstatus1, flagstr);
3079        printk(KERN_DEBUG "RXMACaggtype:    %x\n",
3080               (macstatus2 & RXS_AGGTYPE_MASK));
3081        printk(KERN_DEBUG "RxTSFTime:       %04x\n", rxh->RxTSFTime);
3082}
3083#endif                          /* defined(BCMDBG) */
3084
3085static u16 brcms_c_rate_shm_offset(struct brcms_c_info *wlc, u8 rate)
3086{
3087        return brcms_b_rate_shm_offset(wlc->hw, rate);
3088}
3089
3090/* Callback for device removed */
3091
3092/*
3093 * Attempts to queue a packet onto a multiple-precedence queue,
3094 * if necessary evicting a lower precedence packet from the queue.
3095 *
3096 * 'prec' is the precedence number that has already been mapped
3097 * from the packet priority.
3098 *
3099 * Returns true if packet consumed (queued), false if not.
3100 */
3101bool
3102brcms_c_prec_enq(struct brcms_c_info *wlc, struct pktq *q, void *pkt, int prec)
3103{
3104        return brcms_c_prec_enq_head(wlc, q, pkt, prec, false);
3105}
3106
3107bool
3108brcms_c_prec_enq_head(struct brcms_c_info *wlc, struct pktq *q,
3109                      struct sk_buff *pkt, int prec, bool head)
3110{
3111        struct sk_buff *p;
3112        int eprec = -1;         /* precedence to evict from */
3113
3114        /* Determine precedence from which to evict packet, if any */
3115        if (pktq_pfull(q, prec))
3116                eprec = prec;
3117        else if (pktq_full(q)) {
3118                p = brcmu_pktq_peek_tail(q, &eprec);
3119                if (eprec > prec) {
3120                        wiphy_err(wlc->wiphy, "%s: Failing: eprec %d > prec %d"
3121                                  "\n", __func__, eprec, prec);
3122                        return false;
3123                }
3124        }
3125
3126        /* Evict if needed */
3127        if (eprec >= 0) {
3128                bool discard_oldest;
3129
3130                discard_oldest = AC_BITMAP_TST(wlc->wme_dp, eprec);
3131
3132                /* Refuse newer packet unless configured to discard oldest */
3133                if (eprec == prec && !discard_oldest) {
3134                        wiphy_err(wlc->wiphy, "%s: No where to go, prec == %d"
3135                                  "\n", __func__, prec);
3136                        return false;
3137                }
3138
3139                /* Evict packet according to discard policy */
3140                p = discard_oldest ? brcmu_pktq_pdeq(q, eprec) :
3141                        brcmu_pktq_pdeq_tail(q, eprec);
3142                brcmu_pkt_buf_free_skb(p);
3143        }
3144
3145        /* Enqueue */
3146        if (head)
3147                p = brcmu_pktq_penq_head(q, prec, pkt);
3148        else
3149                p = brcmu_pktq_penq(q, prec, pkt);
3150
3151        return true;
3152}
3153
3154void brcms_c_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu,
3155                             uint prec)
3156{
3157        struct brcms_c_info *wlc = (struct brcms_c_info *) ctx;
3158        struct brcms_txq_info *qi = wlc->pkt_queue;     /* Check me */
3159        struct pktq *q = &qi->q;
3160        int prio;
3161
3162        prio = sdu->priority;
3163
3164        if (!brcms_c_prec_enq(wlc, q, sdu, prec)) {
3165                if (!EDCF_ENAB(wlc->pub)
3166                    || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL))
3167                        wiphy_err(wlc->wiphy, "wl%d: txq_enq: txq overflow"
3168                                  "\n", wlc->pub->unit);
3169
3170                /*
3171                 * we might hit this condtion in case
3172                 * packet flooding from mac80211 stack
3173                 */
3174                brcmu_pkt_buf_free_skb(sdu);
3175        }
3176
3177        /* Check if flow control needs to be turned on after enqueuing the packet
3178         *   Don't turn on flow control if EDCF is enabled. Driver would make the decision on what
3179         *   to drop instead of relying on stack to make the right decision
3180         */
3181        if (!EDCF_ENAB(wlc->pub)
3182            || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL)) {
3183                if (pktq_len(q) >= wlc->pub->tunables->datahiwat) {
3184                        brcms_c_txflowcontrol(wlc, qi, ON, ALLPRIO);
3185                }
3186        } else if (wlc->pub->_priofc) {
3187                if (pktq_plen(q, wlc_prio2prec_map[prio]) >=
3188                    wlc->pub->tunables->datahiwat) {
3189                        brcms_c_txflowcontrol(wlc, qi, ON, prio);
3190                }
3191        }
3192}
3193
3194bool
3195brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu,
3196                     struct ieee80211_hw *hw)
3197{
3198        u8 prio;
3199        uint fifo;
3200        void *pkt;
3201        struct scb *scb = &global_scb;
3202        struct ieee80211_hdr *d11_header = (struct ieee80211_hdr *)(sdu->data);
3203
3204        /* 802.11 standard requires management traffic to go at highest priority */
3205        prio = ieee80211_is_data(d11_header->frame_control) ? sdu->priority :
3206                MAXPRIO;
3207        fifo = prio2fifo[prio];
3208        pkt = sdu;
3209        if (unlikely
3210            (brcms_c_d11hdrs_mac80211(
3211                wlc, hw, pkt, scb, 0, 1, fifo, 0, NULL, 0)))
3212                return -EINVAL;
3213        brcms_c_txq_enq(wlc, scb, pkt, BRCMS_PRIO_TO_PREC(prio));
3214        brcms_c_send_q(wlc);
3215        return 0;
3216}
3217
3218void brcms_c_send_q(struct brcms_c_info *wlc)
3219{
3220        struct sk_buff *pkt[DOT11_MAXNUMFRAGS];
3221        int prec;
3222        u16 prec_map;
3223        int err = 0, i, count;
3224        uint fifo;
3225        struct brcms_txq_info *qi = wlc->pkt_queue;
3226        struct pktq *q = &qi->q;
3227        struct ieee80211_tx_info *tx_info;
3228
3229        if (in_send_q)
3230                return;
3231        else
3232                in_send_q = true;
3233
3234        prec_map = wlc->tx_prec_map;
3235
3236        /* Send all the enq'd pkts that we can.
3237         * Dequeue packets with precedence with empty HW fifo only
3238         */
3239        while (prec_map && (pkt[0] = brcmu_pktq_mdeq(q, prec_map, &prec))) {
3240                tx_info = IEEE80211_SKB_CB(pkt[0]);
3241                if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
3242                        err = brcms_c_sendampdu(wlc->ampdu, qi, pkt, prec);
3243                } else {
3244                        count = 1;
3245                        err = brcms_c_prep_pdu(wlc, pkt[0], &fifo);
3246                        if (!err) {
3247                                for (i = 0; i < count; i++) {
3248                                        brcms_c_txfifo(wlc, fifo, pkt[i], true,
3249                                                       1);
3250                                }
3251                        }
3252                }
3253
3254                if (err == -EBUSY) {
3255                        brcmu_pktq_penq_head(q, prec, pkt[0]);
3256                        /* If send failed due to any other reason than a change in
3257                         * HW FIFO condition, quit. Otherwise, read the new prec_map!
3258                         */
3259                        if (prec_map == wlc->tx_prec_map)
3260                                break;
3261                        prec_map = wlc->tx_prec_map;
3262                }
3263        }
3264
3265        /* Check if flow control needs to be turned off after sending the packet */
3266        if (!EDCF_ENAB(wlc->pub)
3267            || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL)) {
3268                if (brcms_c_txflowcontrol_prio_isset(wlc, qi, ALLPRIO)
3269                    && (pktq_len(q) < wlc->pub->tunables->datahiwat / 2)) {
3270                        brcms_c_txflowcontrol(wlc, qi, OFF, ALLPRIO);
3271                }
3272        } else if (wlc->pub->_priofc) {
3273                int prio;
3274                for (prio = MAXPRIO; prio >= 0; prio--) {
3275                        if (brcms_c_txflowcontrol_prio_isset(wlc, qi, prio) &&
3276                            (pktq_plen(q, wlc_prio2prec_map[prio]) <
3277                             wlc->pub->tunables->datahiwat / 2)) {
3278                                brcms_c_txflowcontrol(wlc, qi, OFF, prio);
3279                        }
3280                }
3281        }
3282        in_send_q = false;
3283}
3284
3285/*
3286 * bcmc_fid_generate:
3287 * Generate frame ID for a BCMC packet.  The frag field is not used
3288 * for MC frames so is used as part of the sequence number.
3289 */
3290static inline u16
3291bcmc_fid_generate(struct brcms_c_info *wlc, struct brcms_bss_cfg *bsscfg,
3292                  struct d11txh *txh)
3293{
3294        u16 frameid;
3295
3296        frameid = le16_to_cpu(txh->TxFrameID) & ~(TXFID_SEQ_MASK |
3297                                                  TXFID_QUEUE_MASK);
3298        frameid |=
3299            (((wlc->
3300               mc_fid_counter++) << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) |
3301            TX_BCMC_FIFO;
3302
3303        return frameid;
3304}
3305
3306void
3307brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p,
3308               bool commit, s8 txpktpend)
3309{
3310        u16 frameid = INVALIDFID;
3311        struct d11txh *txh;
3312
3313        txh = (struct d11txh *) (p->data);
3314
3315        /* When a BC/MC frame is being committed to the BCMC fifo via DMA (NOT PIO), update
3316         * ucode or BSS info as appropriate.
3317         */
3318        if (fifo == TX_BCMC_FIFO) {
3319                frameid = le16_to_cpu(txh->TxFrameID);
3320
3321        }
3322
3323        if (BRCMS_WAR16165(wlc))
3324                brcms_c_war16165(wlc, true);
3325
3326
3327        /* Bump up pending count for if not using rpc. If rpc is used, this will be handled
3328         * in brcms_b_txfifo()
3329         */
3330        if (commit) {
3331                TXPKTPENDINC(wlc, fifo, txpktpend);
3332                BCMMSG(wlc->wiphy, "pktpend inc %d to %d\n",
3333                         txpktpend, TXPKTPENDGET(wlc, fifo));
3334        }
3335
3336        /* Commit BCMC sequence number in the SHM frame ID location */
3337        if (frameid != INVALIDFID)
3338                BCMCFID(wlc, frameid);
3339
3340        if (dma_txfast(wlc->hw->di[fifo], p, commit) < 0) {
3341                wiphy_err(wlc->wiphy, "txfifo: fatal, toss frames !!!\n");
3342        }
3343}
3344
3345void
3346brcms_c_compute_plcp(struct brcms_c_info *wlc, ratespec_t rspec,
3347                     uint length, u8 *plcp)
3348{
3349        if (IS_MCS(rspec)) {
3350                brcms_c_compute_mimo_plcp(rspec, length, plcp);
3351        } else if (IS_OFDM(rspec)) {
3352                brcms_c_compute_ofdm_plcp(rspec, length, plcp);
3353        } else {
3354                brcms_c_compute_cck_plcp(wlc, rspec, length, plcp);
3355        }
3356        return;
3357}
3358
3359/* Rate: 802.11 rate code, length: PSDU length in octets */
3360static void brcms_c_compute_mimo_plcp(ratespec_t rspec, uint length, u8 *plcp)
3361{
3362        u8 mcs = (u8) (rspec & RSPEC_RATE_MASK);
3363        plcp[0] = mcs;
3364        if (RSPEC_IS40MHZ(rspec) || (mcs == 32))
3365                plcp[0] |= MIMO_PLCP_40MHZ;
3366        BRCMS_SET_MIMO_PLCP_LEN(plcp, length);
3367        plcp[3] = RSPEC_MIMOPLCP3(rspec);       /* rspec already holds this byte */
3368        plcp[3] |= 0x7;         /* set smoothing, not sounding ppdu & reserved */
3369        plcp[4] = 0;            /* number of extension spatial streams bit 0 & 1 */
3370        plcp[5] = 0;
3371}
3372
3373/* Rate: 802.11 rate code, length: PSDU length in octets */
3374static void
3375brcms_c_compute_ofdm_plcp(ratespec_t rspec, u32 length, u8 *plcp)
3376{
3377        u8 rate_signal;
3378        u32 tmp = 0;
3379        int rate = RSPEC2RATE(rspec);
3380
3381        /* encode rate per 802.11a-1999 sec 17.3.4.1, with lsb transmitted first */
3382        rate_signal = rate_info[rate] & BRCMS_RATE_MASK;
3383        memset(plcp, 0, D11_PHY_HDR_LEN);
3384        D11A_PHY_HDR_SRATE((struct ofdm_phy_hdr *) plcp, rate_signal);
3385
3386        tmp = (length & 0xfff) << 5;
3387        plcp[2] |= (tmp >> 16) & 0xff;
3388        plcp[1] |= (tmp >> 8) & 0xff;
3389        plcp[0] |= tmp & 0xff;
3390
3391        return;
3392}
3393
3394/*
3395 * Compute PLCP, but only requires actual rate and length of pkt.
3396 * Rate is given in the driver standard multiple of 500 kbps.
3397 * le is set for 11 Mbps rate if necessary.
3398 * Broken out for PRQ.
3399 */
3400
3401static void brcms_c_cck_plcp_set(struct brcms_c_info *wlc, int rate_500,
3402                             uint length, u8 *plcp)
3403{
3404        u16 usec = 0;
3405        u8 le = 0;
3406
3407        switch (rate_500) {
3408        case BRCM_RATE_1M:
3409                usec = length << 3;
3410                break;
3411        case BRCM_RATE_2M:
3412                usec = length << 2;
3413                break;
3414        case BRCM_RATE_5M5:
3415                usec = (length << 4) / 11;
3416                if ((length << 4) - (usec * 11) > 0)
3417                        usec++;
3418                break;
3419        case BRCM_RATE_11M:
3420                usec = (length << 3) / 11;
3421                if ((length << 3) - (usec * 11) > 0) {
3422                        usec++;
3423                        if ((usec * 11) - (length << 3) >= 8)
3424                                le = D11B_PLCP_SIGNAL_LE;
3425                }
3426                break;
3427
3428        default:
3429                wiphy_err(wlc->wiphy, "brcms_c_cck_plcp_set: unsupported rate %d"
3430                          "\n", rate_500);
3431                rate_500 = BRCM_RATE_1M;
3432                usec = length << 3;
3433                break;
3434        }
3435        /* PLCP signal byte */
3436        plcp[0] = rate_500 * 5; /* r (500kbps) * 5 == r (100kbps) */
3437        /* PLCP service byte */
3438        plcp[1] = (u8) (le | D11B_PLCP_SIGNAL_LOCKED);
3439        /* PLCP length u16, little endian */
3440        plcp[2] = usec & 0xff;
3441        plcp[3] = (usec >> 8) & 0xff;
3442        /* PLCP CRC16 */
3443        plcp[4] = 0;
3444        plcp[5] = 0;
3445}
3446
3447/* Rate: 802.11 rate code, length: PSDU length in octets */
3448static void brcms_c_compute_cck_plcp(struct brcms_c_info *wlc, ratespec_t rspec,
3449                                 uint length, u8 *plcp)
3450{
3451        int rate = RSPEC2RATE(rspec);
3452
3453        brcms_c_cck_plcp_set(wlc, rate, length, plcp);
3454}
3455
3456/* brcms_c_compute_frame_dur()
3457 *
3458 * Calculate the 802.11 MAC header DUR field for MPDU
3459 * DUR for a single frame = 1 SIFS + 1 ACK
3460 * DUR for a frame with following frags = 3 SIFS + 2 ACK + next frag time
3461 *
3462 * rate                 MPDU rate in unit of 500kbps
3463 * next_frag_len        next MPDU length in bytes
3464 * preamble_type        use short/GF or long/MM PLCP header
3465 */
3466static u16
3467brcms_c_compute_frame_dur(struct brcms_c_info *wlc, ratespec_t rate,
3468                      u8 preamble_type, uint next_frag_len)
3469{
3470        u16 dur, sifs;
3471
3472        sifs = SIFS(wlc->band);
3473
3474        dur = sifs;
3475        dur += (u16) brcms_c_calc_ack_time(wlc, rate, preamble_type);
3476
3477        if (next_frag_len) {
3478                /* Double the current DUR to get 2 SIFS + 2 ACKs */
3479                dur *= 2;
3480                /* add another SIFS and the frag time */
3481                dur += sifs;
3482                dur +=
3483                    (u16) brcms_c_calc_frame_time(wlc, rate, preamble_type,
3484                                                 next_frag_len);
3485        }
3486        return dur;
3487}
3488
3489/* brcms_c_compute_rtscts_dur()
3490 *
3491 * Calculate the 802.11 MAC header DUR field for an RTS or CTS frame
3492 * DUR for normal RTS/CTS w/ frame = 3 SIFS + 1 CTS + next frame time + 1 ACK
3493 * DUR for CTS-TO-SELF w/ frame    = 2 SIFS         + next frame time + 1 ACK
3494 *
3495 * cts                  cts-to-self or rts/cts
3496 * rts_rate             rts or cts rate in unit of 500kbps
3497 * rate                 next MPDU rate in unit of 500kbps
3498 * frame_len            next MPDU frame length in bytes
3499 */
3500u16
3501brcms_c_compute_rtscts_dur(struct brcms_c_info *wlc, bool cts_only,
3502                           ratespec_t rts_rate,
3503                           ratespec_t frame_rate, u8 rts_preamble_type,
3504                           u8 frame_preamble_type, uint frame_len, bool ba)
3505{
3506        u16 dur, sifs;
3507
3508        sifs = SIFS(wlc->band);
3509
3510        if (!cts_only) {        /* RTS/CTS */
3511                dur = 3 * sifs;
3512                dur +=
3513                    (u16) brcms_c_calc_cts_time(wlc, rts_rate,
3514                                               rts_preamble_type);
3515        } else {                /* CTS-TO-SELF */
3516                dur = 2 * sifs;
3517        }
3518
3519        dur +=
3520            (u16) brcms_c_calc_frame_time(wlc, frame_rate, frame_preamble_type,
3521                                         frame_len);
3522        if (ba)
3523                dur +=
3524                    (u16) brcms_c_calc_ba_time(wlc, frame_rate,
3525                                              BRCMS_SHORT_PREAMBLE);
3526        else
3527                dur +=
3528                    (u16) brcms_c_calc_ack_time(wlc, frame_rate,
3529                                               frame_preamble_type);
3530        return dur;
3531}
3532
3533u16 brcms_c_phytxctl1_calc(struct brcms_c_info *wlc, ratespec_t rspec)
3534{
3535        u16 phyctl1 = 0;
3536        u16 bw;
3537
3538        if (BRCMS_ISLCNPHY(wlc->band)) {
3539                bw = PHY_TXC1_BW_20MHZ;
3540        } else {
3541                bw = RSPEC_GET_BW(rspec);
3542                /* 10Mhz is not supported yet */
3543                if (bw < PHY_TXC1_BW_20MHZ) {
3544                        wiphy_err(wlc->wiphy, "phytxctl1_calc: bw %d is "
3545                                  "not supported yet, set to 20L\n", bw);
3546                        bw = PHY_TXC1_BW_20MHZ;
3547                }
3548        }
3549
3550        if (IS_MCS(rspec)) {
3551                uint mcs = rspec & RSPEC_RATE_MASK;
3552
3553                /* bw, stf, coding-type is part of RSPEC_PHYTXBYTE2 returns */
3554                phyctl1 = RSPEC_PHYTXBYTE2(rspec);
3555                /* set the upper byte of phyctl1 */
3556                phyctl1 |= (mcs_table[mcs].tx_phy_ctl3 << 8);
3557        } else if (IS_CCK(rspec) && !BRCMS_ISLCNPHY(wlc->band)
3558                   && !BRCMS_ISSSLPNPHY(wlc->band)) {
3559                /* In CCK mode LPPHY overloads OFDM Modulation bits with CCK Data Rate */
3560                /* Eventually MIMOPHY would also be converted to this format */
3561                /* 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps */
3562                phyctl1 = (bw | (RSPEC_STF(rspec) << PHY_TXC1_MODE_SHIFT));
3563        } else {                /* legacy OFDM/CCK */
3564                s16 phycfg;
3565                /* get the phyctl byte from rate phycfg table */
3566                phycfg = brcms_c_rate_legacy_phyctl(RSPEC2RATE(rspec));
3567                if (phycfg == -1) {
3568                        wiphy_err(wlc->wiphy, "phytxctl1_calc: wrong "
3569                                  "legacy OFDM/CCK rate\n");
3570                        phycfg = 0;
3571                }
3572                /* set the upper byte of phyctl1 */
3573                phyctl1 =
3574                    (bw | (phycfg << 8) |
3575                     (RSPEC_STF(rspec) << PHY_TXC1_MODE_SHIFT));
3576        }
3577        return phyctl1;
3578}
3579
3580ratespec_t
3581brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, ratespec_t rspec,
3582                           bool use_rspec, u16 mimo_ctlchbw)
3583{
3584        ratespec_t rts_rspec = 0;
3585
3586        if (use_rspec) {
3587                /* use frame rate as rts rate */
3588                rts_rspec = rspec;
3589
3590        } else if (wlc->band->gmode && wlc->protection->_g && !IS_CCK(rspec)) {
3591                /* Use 11Mbps as the g protection RTS target rate and fallback.
3592                 * Use the BRCMS_BASIC_RATE() lookup to find the best basic rate
3593                 * under the target in case 11 Mbps is not Basic.
3594                 * 6 and 9 Mbps are not usually selected by rate selection, but even
3595                 * if the OFDM rate we are protecting is 6 or 9 Mbps, 11 is more robust.
3596                 */
3597                rts_rspec = BRCMS_BASIC_RATE(wlc, BRCM_RATE_11M);
3598        } else {
3599                /* calculate RTS rate and fallback rate based on the frame rate
3600                 * RTS must be sent at a basic rate since it is a
3601                 * control frame, sec 9.6 of 802.11 spec
3602                 */
3603                rts_rspec = BRCMS_BASIC_RATE(wlc, rspec);
3604        }
3605
3606        if (BRCMS_PHY_11N_CAP(wlc->band)) {
3607                /* set rts txbw to correct side band */
3608                rts_rspec &= ~RSPEC_BW_MASK;
3609
3610                /* if rspec/rspec_fallback is 40MHz, then send RTS on both 20MHz channel
3611                 * (DUP), otherwise send RTS on control channel
3612                 */
3613                if (RSPEC_IS40MHZ(rspec) && !IS_CCK(rts_rspec))
3614                        rts_rspec |= (PHY_TXC1_BW_40MHZ_DUP << RSPEC_BW_SHIFT);
3615                else
3616                        rts_rspec |= (mimo_ctlchbw << RSPEC_BW_SHIFT);
3617
3618                /* pick siso/cdd as default for ofdm */
3619                if (IS_OFDM(rts_rspec)) {
3620                        rts_rspec &= ~RSPEC_STF_MASK;
3621                        rts_rspec |= (wlc->stf->ss_opmode << RSPEC_STF_SHIFT);
3622                }
3623        }
3624        return rts_rspec;
3625}
3626
3627/*
3628 * Add struct d11txh, struct cck_phy_hdr.
3629 *
3630 * 'p' data must start with 802.11 MAC header
3631 * 'p' must allow enough bytes of local headers to be "pushed" onto the packet
3632 *
3633 * headroom == D11_PHY_HDR_LEN + D11_TXH_LEN (D11_TXH_LEN is now 104 bytes)
3634 *
3635 */
3636static u16
3637brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw,
3638                     struct sk_buff *p, struct scb *scb, uint frag,
3639                     uint nfrags, uint queue, uint next_frag_len,
3640                     struct wsec_key *key, ratespec_t rspec_override)
3641{
3642        struct ieee80211_hdr *h;
3643        struct d11txh *txh;
3644        u8 *plcp, plcp_fallback[D11_PHY_HDR_LEN];
3645        int len, phylen, rts_phylen;
3646        u16 mch, phyctl, xfts, mainrates;
3647        u16 seq = 0, mcl = 0, status = 0, frameid = 0;
3648        ratespec_t rspec[2] = { BRCM_RATE_1M, BRCM_RATE_1M }, rts_rspec[2] = {
3649        BRCM_RATE_1M, BRCM_RATE_1M};
3650        bool use_rts = false;
3651        bool use_cts = false;
3652        bool use_rifs = false;
3653        bool short_preamble[2] = { false, false };
3654        u8 preamble_type[2] = { BRCMS_LONG_PREAMBLE, BRCMS_LONG_PREAMBLE };
3655        u8 rts_preamble_type[2] = { BRCMS_LONG_PREAMBLE, BRCMS_LONG_PREAMBLE };
3656        u8 *rts_plcp, rts_plcp_fallback[D11_PHY_HDR_LEN];
3657        struct ieee80211_rts *rts = NULL;
3658        bool qos;
3659        uint ac;
3660        u32 rate_val[2];
3661        bool hwtkmic = false;
3662        u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ;
3663#define ANTCFG_NONE 0xFF
3664        u8 antcfg = ANTCFG_NONE;
3665        u8 fbantcfg = ANTCFG_NONE;
3666        uint phyctl1_stf = 0;
3667        u16 durid = 0;
3668        struct ieee80211_tx_rate *txrate[2];
3669        int k;
3670        struct ieee80211_tx_info *tx_info;
3671        bool is_mcs[2];
3672        u16 mimo_txbw;
3673        u8 mimo_preamble_type;
3674
3675        /* locate 802.11 MAC header */
3676        h = (struct ieee80211_hdr *)(p->data);
3677        qos = ieee80211_is_data_qos(h->frame_control);
3678
3679        /* compute length of frame in bytes for use in PLCP computations */
3680        len = brcmu_pkttotlen(p);
3681        phylen = len + FCS_LEN;
3682
3683        /* If WEP enabled, add room in phylen for the additional bytes of
3684         * ICV which MAC generates.  We do NOT add the additional bytes to
3685         * the packet itself, thus phylen = packet length + ICV_LEN + FCS_LEN
3686         * in this case
3687         */
3688        if (key) {
3689                phylen += key->icv_len;
3690        }
3691
3692        /* Get tx_info */
3693        tx_info = IEEE80211_SKB_CB(p);
3694
3695        /* add PLCP */
3696        plcp = skb_push(p, D11_PHY_HDR_LEN);
3697
3698        /* add Broadcom tx descriptor header */
3699        txh = (struct d11txh *) skb_push(p, D11_TXH_LEN);
3700        memset(txh, 0, D11_TXH_LEN);
3701
3702        /* setup frameid */
3703        if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
3704                /* non-AP STA should never use BCMC queue */
3705                if (queue == TX_BCMC_FIFO) {
3706                        wiphy_err(wlc->wiphy, "wl%d: %s: ASSERT queue == "
3707                                  "TX_BCMC!\n", BRCMS_UNIT(wlc), __func__);
3708                        frameid = bcmc_fid_generate(wlc, NULL, txh);
3709                } else {
3710                        /* Increment the counter for first fragment */
3711                        if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) {
3712                                SCB_SEQNUM(scb, p->priority)++;
3713                        }
3714
3715                        /* extract fragment number from frame first */
3716                        seq = le16_to_cpu(seq) & FRAGNUM_MASK;
3717                        seq |= (SCB_SEQNUM(scb, p->priority) << SEQNUM_SHIFT);
3718                        h->seq_ctrl = cpu_to_le16(seq);
3719
3720                        frameid = ((seq << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) |
3721                            (queue & TXFID_QUEUE_MASK);
3722                }
3723        }
3724        frameid |= queue & TXFID_QUEUE_MASK;
3725
3726        /* set the ignpmq bit for all pkts tx'd in PS mode and for beacons */
3727        if (SCB_PS(scb) || ieee80211_is_beacon(h->frame_control))
3728                mcl |= TXC_IGNOREPMQ;
3729
3730        txrate[0] = tx_info->control.rates;
3731        txrate[1] = txrate[0] + 1;
3732
3733        /* if rate control algorithm didn't give us a fallback rate, use the primary rate */
3734        if (txrate[1]->idx < 0) {
3735                txrate[1] = txrate[0];
3736        }
3737
3738        for (k = 0; k < hw->max_rates; k++) {
3739                is_mcs[k] =
3740                    txrate[k]->flags & IEEE80211_TX_RC_MCS ? true : false;
3741                if (!is_mcs[k]) {
3742                        if ((txrate[k]->idx >= 0)
3743                            && (txrate[k]->idx <
3744                                hw->wiphy->bands[tx_info->band]->n_bitrates)) {
3745                                rate_val[k] =
3746                                    hw->wiphy->bands[tx_info->band]->
3747                                    bitrates[txrate[k]->idx].hw_value;
3748                                short_preamble[k] =
3749                                    txrate[k]->
3750                                    flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE ?
3751                                    true : false;
3752                        } else {
3753                                rate_val[k] = BRCM_RATE_1M;
3754                        }
3755                } else {
3756                        rate_val[k] = txrate[k]->idx;
3757                }
3758                /* Currently only support same setting for primay and fallback rates.
3759                 * Unify flags for each rate into a single value for the frame
3760                 */
3761                use_rts |=
3762                    txrate[k]->
3763                    flags & IEEE80211_TX_RC_USE_RTS_CTS ? true : false;
3764                use_cts |=
3765                    txrate[k]->
3766                    flags & IEEE80211_TX_RC_USE_CTS_PROTECT ? true : false;
3767
3768                if (is_mcs[k])
3769                        rate_val[k] |= NRATE_MCS_INUSE;
3770
3771                rspec[k] = mac80211_wlc_set_nrate(wlc, wlc->band, rate_val[k]);
3772
3773                /* (1) RATE: determine and validate primary rate and fallback rates */
3774                if (!RSPEC_ACTIVE(rspec[k])) {
3775                        rspec[k] = BRCM_RATE_1M;
3776                } else {
3777                        if (!is_multicast_ether_addr(h->addr1)) {
3778                                /* set tx antenna config */
3779                                brcms_c_antsel_antcfg_get(wlc->asi, false,
3780                                        false, 0, 0, &antcfg, &fbantcfg);
3781                        }
3782                }
3783        }
3784
3785        phyctl1_stf = wlc->stf->ss_opmode;
3786
3787        if (N_ENAB(wlc->pub)) {
3788                for (k = 0; k < hw->max_rates; k++) {
3789                        /* apply siso/cdd to single stream mcs's or ofdm if rspec is auto selected */
3790                        if (((IS_MCS(rspec[k]) &&
3791                              IS_SINGLE_STREAM(rspec[k] & RSPEC_RATE_MASK)) ||
3792                             IS_OFDM(rspec[k]))
3793                            && ((rspec[k] & RSPEC_OVERRIDE_MCS_ONLY)
3794                                || !(rspec[k] & RSPEC_OVERRIDE))) {
3795                                rspec[k] &= ~(RSPEC_STF_MASK | RSPEC_STC_MASK);
3796
3797                                /* For SISO MCS use STBC if possible */
3798                                if (IS_MCS(rspec[k])
3799                                    && BRCMS_STF_SS_STBC_TX(wlc, scb)) {
3800                                        u8 stc;
3801
3802                                        stc = 1;        /* Nss for single stream is always 1 */
3803                                        rspec[k] |=
3804                                            (PHY_TXC1_MODE_STBC <<
3805                                             RSPEC_STF_SHIFT) | (stc <<
3806                                                                 RSPEC_STC_SHIFT);
3807                                } else
3808                                        rspec[k] |=
3809                                            (phyctl1_stf << RSPEC_STF_SHIFT);
3810                        }
3811
3812                        /* Is the phy configured to use 40MHZ frames? If so then pick the desired txbw */
3813                        if (CHSPEC_WLC_BW(wlc->chanspec) == BRCMS_40_MHZ) {
3814                                /* default txbw is 20in40 SB */
3815                                mimo_ctlchbw = mimo_txbw =
3816                                   CHSPEC_SB_UPPER(BRCMS_BAND_PI_RADIO_CHANSPEC)
3817                                   ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ;
3818
3819                                if (IS_MCS(rspec[k])) {
3820                                        /* mcs 32 must be 40b/w DUP */
3821                                        if ((rspec[k] & RSPEC_RATE_MASK) == 32) {
3822                                                mimo_txbw =
3823                                                    PHY_TXC1_BW_40MHZ_DUP;
3824                                                /* use override */
3825                                        } else if (wlc->mimo_40txbw != AUTO)
3826                                                mimo_txbw = wlc->mimo_40txbw;
3827                                        /* else check if dst is using 40 Mhz */
3828                                        else if (scb->flags & SCB_IS40)
3829                                                mimo_txbw = PHY_TXC1_BW_40MHZ;
3830                                } else if (IS_OFDM(rspec[k])) {
3831                                        if (wlc->ofdm_40txbw != AUTO)
3832                                                mimo_txbw = wlc->ofdm_40txbw;
3833                                } else {
3834                                        if (wlc->cck_40txbw != AUTO)
3835                                                mimo_txbw = wlc->cck_40txbw;
3836                                }
3837                        } else {
3838                                /* mcs32 is 40 b/w only.
3839                                 * This is possible for probe packets on a STA during SCAN
3840                                 */
3841                                if ((rspec[k] & RSPEC_RATE_MASK) == 32) {
3842                                        /* mcs 0 */
3843                                        rspec[k] = RSPEC_MIMORATE;
3844                                }
3845                                mimo_txbw = PHY_TXC1_BW_20MHZ;
3846                        }
3847
3848                        /* Set channel width */
3849                        rspec[k] &= ~RSPEC_BW_MASK;
3850                        if ((k == 0) || ((k > 0) && IS_MCS(rspec[k])))
3851                                rspec[k] |= (mimo_txbw << RSPEC_BW_SHIFT);
3852                        else
3853                                rspec[k] |= (mimo_ctlchbw << RSPEC_BW_SHIFT);
3854
3855                        /* Set Short GI */
3856#ifdef NOSGIYET
3857                        if (IS_MCS(rspec[k])
3858                            && (txrate[k]->flags & IEEE80211_TX_RC_SHORT_GI))
3859                                rspec[k] |= RSPEC_SHORT_GI;
3860                        else if (!(txrate[k]->flags & IEEE80211_TX_RC_SHORT_GI))
3861                                rspec[k] &= ~RSPEC_SHORT_GI;
3862#else
3863                        rspec[k] &= ~RSPEC_SHORT_GI;
3864#endif
3865
3866                        mimo_preamble_type = BRCMS_MM_PREAMBLE;
3867                        if (txrate[k]->flags & IEEE80211_TX_RC_GREEN_FIELD)
3868                                mimo_preamble_type = BRCMS_GF_PREAMBLE;
3869
3870                        if ((txrate[k]->flags & IEEE80211_TX_RC_MCS)
3871                            && (!IS_MCS(rspec[k]))) {
3872                                wiphy_err(wlc->wiphy, "wl%d: %s: IEEE80211_TX_"
3873                                          "RC_MCS != IS_MCS(rspec)\n",
3874                                          BRCMS_UNIT(wlc), __func__);
3875                        }
3876
3877                        if (IS_MCS(rspec[k])) {
3878                                preamble_type[k] = mimo_preamble_type;
3879
3880                                /* if SGI is selected, then forced mm for single stream */
3881                                if ((rspec[k] & RSPEC_SHORT_GI)
3882                                    && IS_SINGLE_STREAM(rspec[k] &
3883                                                        RSPEC_RATE_MASK)) {
3884                                        preamble_type[k] = BRCMS_MM_PREAMBLE;
3885                                }
3886                        }
3887
3888                        /* should be better conditionalized */
3889                        if (!IS_MCS(rspec[0])
3890                            && (tx_info->control.rates[0].
3891                                flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE))
3892                                preamble_type[k] = BRCMS_SHORT_PREAMBLE;
3893                }
3894        } else {
3895                for (k = 0; k < hw->max_rates; k++) {
3896                        /* Set ctrlchbw as 20Mhz */
3897                        rspec[k] &= ~RSPEC_BW_MASK;
3898                        rspec[k] |= (PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT);
3899
3900                        /* for nphy, stf of ofdm frames must follow policies */
3901                        if (BRCMS_ISNPHY(wlc->band) && IS_OFDM(rspec[k])) {
3902                                rspec[k] &= ~RSPEC_STF_MASK;
3903                                rspec[k] |= phyctl1_stf << RSPEC_STF_SHIFT;
3904                        }
3905                }
3906        }
3907
3908        /* Reset these for use with AMPDU's */
3909        txrate[0]->count = 0;
3910        txrate[1]->count = 0;
3911
3912        /* (2) PROTECTION, may change rspec */
3913        if ((ieee80211_is_data(h->frame_control) ||
3914            ieee80211_is_mgmt(h->frame_control)) &&
3915            (phylen > wlc->RTSThresh) && !is_multicast_ether_addr(h->addr1))
3916                use_rts = true;
3917
3918        /* (3) PLCP: determine PLCP header and MAC duration,
3919         * fill struct d11txh */
3920        brcms_c_compute_plcp(wlc, rspec[0], phylen, plcp);
3921        brcms_c_compute_plcp(wlc, rspec[1], phylen, plcp_fallback);
3922        memcpy(&txh->FragPLCPFallback,
3923               plcp_fallback, sizeof(txh->FragPLCPFallback));
3924
3925        /* Length field now put in CCK FBR CRC field */
3926        if (IS_CCK(rspec[1])) {
3927                txh->FragPLCPFallback[4] = phylen & 0xff;
3928                txh->FragPLCPFallback[5] = (phylen & 0xff00) >> 8;
3929        }
3930
3931        /* MIMO-RATE: need validation ?? */
3932        mainrates = IS_OFDM(rspec[0]) ?
3933                        D11A_PHY_HDR_GRATE((struct ofdm_phy_hdr *) plcp) :
3934                        plcp[0];
3935
3936        /* DUR field for main rate */
3937        if (!ieee80211_is_pspoll(h->frame_control) &&
3938            !is_multicast_ether_addr(h->addr1) && !use_rifs) {
3939                durid =
3940                    brcms_c_compute_frame_dur(wlc, rspec[0], preamble_type[0],
3941                                          next_frag_len);
3942                h->duration_id = cpu_to_le16(durid);
3943        } else if (use_rifs) {
3944                /* NAV protect to end of next max packet size */
3945                durid =
3946                    (u16) brcms_c_calc_frame_time(wlc, rspec[0],
3947                                                 preamble_type[0],
3948                                                 DOT11_MAX_FRAG_LEN);
3949                durid += RIFS_11N_TIME;
3950                h->duration_id = cpu_to_le16(durid);
3951        }
3952
3953        /* DUR field for fallback rate */
3954        if (ieee80211_is_pspoll(h->frame_control))
3955                txh->FragDurFallback = h->duration_id;
3956        else if (is_multicast_ether_addr(h->addr1) || use_rifs)
3957                txh->FragDurFallback = 0;
3958        else {
3959                durid = brcms_c_compute_frame_dur(wlc, rspec[1],
3960                                              preamble_type[1], next_frag_len);
3961                txh->FragDurFallback = cpu_to_le16(durid);
3962        }
3963
3964        /* (4) MAC-HDR: MacTxControlLow */
3965        if (frag == 0)
3966                mcl |= TXC_STARTMSDU;
3967
3968        if (!is_multicast_ether_addr(h->addr1))
3969                mcl |= TXC_IMMEDACK;
3970
3971        if (BAND_5G(wlc->band->bandtype))
3972                mcl |= TXC_FREQBAND_5G;
3973
3974        if (CHSPEC_IS40(BRCMS_BAND_PI_RADIO_CHANSPEC))
3975                mcl |= TXC_BW_40;
3976
3977        /* set AMIC bit if using hardware TKIP MIC */
3978        if (hwtkmic)
3979                mcl |= TXC_AMIC;
3980
3981        txh->MacTxControlLow = cpu_to_le16(mcl);
3982
3983        /* MacTxControlHigh */
3984        mch = 0;
3985
3986        /* Set fallback rate preamble type */
3987        if ((preamble_type[1] == BRCMS_SHORT_PREAMBLE) ||
3988            (preamble_type[1] == BRCMS_GF_PREAMBLE)) {
3989                if (RSPEC2RATE(rspec[1]) != BRCM_RATE_1M)
3990                        mch |= TXC_PREAMBLE_DATA_FB_SHORT;
3991        }
3992
3993        /* MacFrameControl */
3994        memcpy(&txh->MacFrameControl, &h->frame_control, sizeof(u16));
3995        txh->TxFesTimeNormal = cpu_to_le16(0);
3996
3997        txh->TxFesTimeFallback = cpu_to_le16(0);
3998
3999        /* TxFrameRA */
4000        memcpy(&txh->TxFrameRA, &h->addr1, ETH_ALEN);
4001
4002        /* TxFrameID */
4003        txh->TxFrameID = cpu_to_le16(frameid);
4004
4005        /* TxStatus, Note the case of recreating the first frag of a suppressed frame
4006         * then we may need to reset the retry cnt's via the status reg
4007         */
4008        txh->TxStatus = cpu_to_le16(status);
4009
4010        /* extra fields for ucode AMPDU aggregation, the new fields are added to
4011         * the END of previous structure so that it's compatible in driver.
4012         */
4013        txh->MaxNMpdus = cpu_to_le16(0);
4014        txh->MaxABytes_MRT = cpu_to_le16(0);
4015        txh->MaxABytes_FBR = cpu_to_le16(0);
4016        txh->MinMBytes = cpu_to_le16(0);
4017
4018        /* (5) RTS/CTS: determine RTS/CTS PLCP header and MAC duration,
4019         * furnish struct d11txh */
4020        /* RTS PLCP header and RTS frame */
4021        if (use_rts || use_cts) {
4022                if (use_rts && use_cts)
4023                        use_cts = false;
4024
4025                for (k = 0; k < 2; k++) {
4026                        rts_rspec[k] = brcms_c_rspec_to_rts_rspec(wlc, rspec[k],
4027                                                              false,
4028                                                              mimo_ctlchbw);
4029                }
4030
4031                if (!IS_OFDM(rts_rspec[0]) &&
4032                    !((RSPEC2RATE(rts_rspec[0]) == BRCM_RATE_1M) ||
4033                      (wlc->PLCPHdr_override == BRCMS_PLCP_LONG))) {
4034                        rts_preamble_type[0] = BRCMS_SHORT_PREAMBLE;
4035                        mch |= TXC_PREAMBLE_RTS_MAIN_SHORT;
4036                }
4037
4038                if (!IS_OFDM(rts_rspec[1]) &&
4039                    !((RSPEC2RATE(rts_rspec[1]) == BRCM_RATE_1M) ||
4040                      (wlc->PLCPHdr_override == BRCMS_PLCP_LONG))) {
4041                        rts_preamble_type[1] = BRCMS_SHORT_PREAMBLE;
4042                        mch |= TXC_PREAMBLE_RTS_FB_SHORT;
4043                }
4044
4045                /* RTS/CTS additions to MacTxControlLow */
4046                if (use_cts) {
4047                        txh->MacTxControlLow |= cpu_to_le16(TXC_SENDCTS);
4048                } else {
4049                        txh->MacTxControlLow |= cpu_to_le16(TXC_SENDRTS);
4050                        txh->MacTxControlLow |= cpu_to_le16(TXC_LONGFRAME);
4051                }
4052
4053                /* RTS PLCP header */
4054                rts_plcp = txh->RTSPhyHeader;
4055                if (use_cts)
4056                        rts_phylen = DOT11_CTS_LEN + FCS_LEN;
4057                else
4058                        rts_phylen = DOT11_RTS_LEN + FCS_LEN;
4059
4060                brcms_c_compute_plcp(wlc, rts_rspec[0], rts_phylen, rts_plcp);
4061
4062                /* fallback rate version of RTS PLCP header */
4063                brcms_c_compute_plcp(wlc, rts_rspec[1], rts_phylen,
4064                                 rts_plcp_fallback);
4065                memcpy(&txh->RTSPLCPFallback, rts_plcp_fallback,
4066                       sizeof(txh->RTSPLCPFallback));
4067
4068                /* RTS frame fields... */
4069                rts = (struct ieee80211_rts *)&txh->rts_frame;
4070
4071                durid = brcms_c_compute_rtscts_dur(wlc, use_cts, rts_rspec[0],
4072                                               rspec[0], rts_preamble_type[0],
4073                                               preamble_type[0], phylen, false);
4074                rts->duration = cpu_to_le16(durid);
4075                /* fallback rate version of RTS DUR field */
4076                durid = brcms_c_compute_rtscts_dur(wlc, use_cts,
4077                                               rts_rspec[1], rspec[1],
4078                                               rts_preamble_type[1],
4079                                               preamble_type[1], phylen, false);
4080                txh->RTSDurFallback = cpu_to_le16(durid);
4081
4082                if (use_cts) {
4083                        rts->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
4084                                                         IEEE80211_STYPE_CTS);
4085
4086                        memcpy(&rts->ra, &h->addr2, ETH_ALEN);
4087                } else {
4088                        rts->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
4089                                                         IEEE80211_STYPE_RTS);
4090
4091                        memcpy(&rts->ra, &h->addr1, 2 * ETH_ALEN);
4092                }
4093
4094                /* mainrate
4095                 *    low 8 bits: main frag rate/mcs,
4096                 *    high 8 bits: rts/cts rate/mcs
4097                 */
4098                mainrates |= (IS_OFDM(rts_rspec[0]) ?
4099                                D11A_PHY_HDR_GRATE(
4100                                        (struct ofdm_phy_hdr *) rts_plcp) :
4101                                rts_plcp[0]) << 8;
4102        } else {
4103                memset((char *)txh->RTSPhyHeader, 0, D11_PHY_HDR_LEN);
4104                memset((char *)&txh->rts_frame, 0,
4105                        sizeof(struct ieee80211_rts));
4106                memset((char *)txh->RTSPLCPFallback, 0,
4107                      sizeof(txh->RTSPLCPFallback));
4108                txh->RTSDurFallback = 0;
4109        }
4110
4111#ifdef SUPPORT_40MHZ
4112        /* add null delimiter count */
4113        if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && IS_MCS(rspec)) {
4114                txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] =
4115                   brcm_c_ampdu_null_delim_cnt(wlc->ampdu, scb, rspec, phylen);
4116        }
4117#endif
4118
4119        /* Now that RTS/RTS FB preamble types are updated, write the final value */
4120        txh->MacTxControlHigh = cpu_to_le16(mch);
4121
4122        /* MainRates (both the rts and frag plcp rates have been calculated now) */
4123        txh->MainRates = cpu_to_le16(mainrates);
4124
4125        /* XtraFrameTypes */
4126        xfts = FRAMETYPE(rspec[1], wlc->mimoft);
4127        xfts |= (FRAMETYPE(rts_rspec[0], wlc->mimoft) << XFTS_RTS_FT_SHIFT);
4128        xfts |= (FRAMETYPE(rts_rspec[1], wlc->mimoft) << XFTS_FBRRTS_FT_SHIFT);
4129        xfts |=
4130            CHSPEC_CHANNEL(BRCMS_BAND_PI_RADIO_CHANSPEC) << XFTS_CHANNEL_SHIFT;
4131        txh->XtraFrameTypes = cpu_to_le16(xfts);
4132
4133        /* PhyTxControlWord */
4134        phyctl = FRAMETYPE(rspec[0], wlc->mimoft);
4135        if ((preamble_type[0] == BRCMS_SHORT_PREAMBLE) ||
4136            (preamble_type[0] == BRCMS_GF_PREAMBLE)) {
4137                if (RSPEC2RATE(rspec[0]) != BRCM_RATE_1M)
4138                        phyctl |= PHY_TXC_SHORT_HDR;
4139        }
4140
4141        /* phytxant is properly bit shifted */
4142        phyctl |= brcms_c_stf_d11hdrs_phyctl_txant(wlc, rspec[0]);
4143        txh->PhyTxControlWord = cpu_to_le16(phyctl);
4144
4145        /* PhyTxControlWord_1 */
4146        if (BRCMS_PHY_11N_CAP(wlc->band)) {
4147                u16 phyctl1 = 0;
4148
4149                phyctl1 = brcms_c_phytxctl1_calc(wlc, rspec[0]);
4150                txh->PhyTxControlWord_1 = cpu_to_le16(phyctl1);
4151                phyctl1 = brcms_c_phytxctl1_calc(wlc, rspec[1]);
4152                txh->PhyTxControlWord_1_Fbr = cpu_to_le16(phyctl1);
4153
4154                if (use_rts || use_cts) {
4155                        phyctl1 = brcms_c_phytxctl1_calc(wlc, rts_rspec[0]);
4156                        txh->PhyTxControlWord_1_Rts = cpu_to_le16(phyctl1);
4157                        phyctl1 = brcms_c_phytxctl1_calc(wlc, rts_rspec[1]);
4158                        txh->PhyTxControlWord_1_FbrRts = cpu_to_le16(phyctl1);
4159                }
4160
4161                /*
4162                 * For mcs frames, if mixedmode(overloaded with long preamble) is going to be set,
4163                 * fill in non-zero MModeLen and/or MModeFbrLen
4164                 *  it will be unnecessary if they are separated
4165                 */
4166                if (IS_MCS(rspec[0]) &&
4167                    (preamble_type[0] == BRCMS_MM_PREAMBLE)) {
4168                        u16 mmodelen =
4169                            brcms_c_calc_lsig_len(wlc, rspec[0], phylen);
4170                        txh->MModeLen = cpu_to_le16(mmodelen);
4171                }
4172
4173                if (IS_MCS(rspec[1]) &&
4174                    (preamble_type[1] == BRCMS_MM_PREAMBLE)) {
4175                        u16 mmodefbrlen =
4176                            brcms_c_calc_lsig_len(wlc, rspec[1], phylen);
4177                        txh->MModeFbrLen = cpu_to_le16(mmodefbrlen);
4178                }
4179        }
4180
4181        ac = skb_get_queue_mapping(p);
4182        if (SCB_WME(scb) && qos && wlc->edcf_txop[ac]) {
4183                uint frag_dur, dur, dur_fallback;
4184
4185                /* WME: Update TXOP threshold */
4186                if ((!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) && (frag == 0)) {
4187                        frag_dur =
4188                            brcms_c_calc_frame_time(wlc, rspec[0],
4189                                        preamble_type[0], phylen);
4190
4191                        if (rts) {
4192                                /* 1 RTS or CTS-to-self frame */
4193                                dur =
4194                                    brcms_c_calc_cts_time(wlc, rts_rspec[0],
4195                                                      rts_preamble_type[0]);
4196                                dur_fallback =
4197                                    brcms_c_calc_cts_time(wlc, rts_rspec[1],
4198                                                      rts_preamble_type[1]);
4199                                /* (SIFS + CTS) + SIFS + frame + SIFS + ACK */
4200                                dur += le16_to_cpu(rts->duration);
4201                                dur_fallback +=
4202                                        le16_to_cpu(txh->RTSDurFallback);
4203                        } else if (use_rifs) {
4204                                dur = frag_dur;
4205                                dur_fallback = 0;
4206                        } else {
4207                                /* frame + SIFS + ACK */
4208                                dur = frag_dur;
4209                                dur +=
4210                                    brcms_c_compute_frame_dur(wlc, rspec[0],
4211                                                          preamble_type[0], 0);
4212
4213                                dur_fallback =
4214                                    brcms_c_calc_frame_time(wlc, rspec[1],
4215                                                        preamble_type[1],
4216                                                        phylen);
4217                                dur_fallback +=
4218                                    brcms_c_compute_frame_dur(wlc, rspec[1],
4219                                                          preamble_type[1], 0);
4220                        }
4221                        /* NEED to set TxFesTimeNormal (hard) */
4222                        txh->TxFesTimeNormal = cpu_to_le16((u16) dur);
4223                        /* NEED to set fallback rate version of TxFesTimeNormal (hard) */
4224                        txh->TxFesTimeFallback =
4225                                cpu_to_le16((u16) dur_fallback);
4226
4227                        /* update txop byte threshold (txop minus intraframe overhead) */
4228                        if (wlc->edcf_txop[ac] >= (dur - frag_dur)) {
4229                                {
4230                                        uint newfragthresh;
4231
4232                                        newfragthresh =
4233                                            brcms_c_calc_frame_len(wlc,
4234                                                rspec[0], preamble_type[0],
4235                                                (wlc->edcf_txop[ac] -
4236                                                        (dur - frag_dur)));
4237                                        /* range bound the fragthreshold */
4238                                        if (newfragthresh < DOT11_MIN_FRAG_LEN)
4239                                                newfragthresh =
4240                                                    DOT11_MIN_FRAG_LEN;
4241                                        else if (newfragthresh >
4242                                                 wlc->usr_fragthresh)
4243                                                newfragthresh =
4244                                                    wlc->usr_fragthresh;
4245                                        /* update the fragthresh and do txc update */
4246                                        if (wlc->fragthresh[queue] !=
4247                                            (u16) newfragthresh) {
4248                                                wlc->fragthresh[queue] =
4249                                                    (u16) newfragthresh;
4250                                        }
4251                                }
4252                        } else
4253                                wiphy_err(wlc->wiphy, "wl%d: %s txop invalid "
4254                                          "for rate %d\n",
4255                                          wlc->pub->unit, fifo_names[queue],
4256                                          RSPEC2RATE(rspec[0]));
4257
4258                        if (dur > wlc->edcf_txop[ac])
4259                                wiphy_err(wlc->wiphy, "wl%d: %s: %s txop "
4260                                          "exceeded phylen %d/%d dur %d/%d\n",
4261                                          wlc->pub->unit, __func__,
4262                                          fifo_names[queue],
4263                                          phylen, wlc->fragthresh[queue],
4264                                          dur, wlc->edcf_txop[ac]);
4265                }
4266        }
4267
4268        return 0;
4269}
4270
4271void brcms_c_tbtt(struct brcms_c_info *wlc)
4272{
4273        struct brcms_bss_cfg *cfg = wlc->cfg;
4274
4275        if (!cfg->BSS) {
4276                /* DirFrmQ is now valid...defer setting until end of ATIM window */
4277                wlc->qvalid |= MCMD_DIRFRMQVAL;
4278        }
4279}
4280
4281static void brcms_c_war16165(struct brcms_c_info *wlc, bool tx)
4282{
4283        if (tx) {
4284                /* the post-increment is used in STAY_AWAKE macro */
4285                if (wlc->txpend16165war++ == 0)
4286                        brcms_c_set_ps_ctrl(wlc);
4287        } else {
4288                wlc->txpend16165war--;
4289                if (wlc->txpend16165war == 0)
4290                        brcms_c_set_ps_ctrl(wlc);
4291        }
4292}
4293
4294/* process an individual struct tx_status */
4295bool
4296brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs, u32 frm_tx2)
4297{
4298        struct sk_buff *p;
4299        uint queue;
4300        struct d11txh *txh;
4301        struct scb *scb = NULL;
4302        bool free_pdu;
4303        int tx_rts, tx_frame_count, tx_rts_count;
4304        uint totlen, supr_status;
4305        bool lastframe;
4306        struct ieee80211_hdr *h;
4307        u16 mcl;
4308        struct ieee80211_tx_info *tx_info;
4309        struct ieee80211_tx_rate *txrate;
4310        int i;
4311
4312        (void)(frm_tx2);        /* Compiler reference to avoid unused variable warning */
4313
4314        /* discard intermediate indications for ucode with one legitimate case:
4315         *   e.g. if "useRTS" is set. ucode did a successful rts/cts exchange, but the subsequent
4316         *   tx of DATA failed. so it will start rts/cts from the beginning (resetting the rts
4317         *   transmission count)
4318         */
4319        if (!(txs->status & TX_STATUS_AMPDU)
4320            && (txs->status & TX_STATUS_INTERMEDIATE)) {
4321                wiphy_err(wlc->wiphy, "%s: INTERMEDIATE but not AMPDU\n",
4322                          __func__);
4323                return false;
4324        }
4325
4326        queue = txs->frameid & TXFID_QUEUE_MASK;
4327        if (queue >= NFIFO) {
4328                p = NULL;
4329                goto fatal;
4330        }
4331
4332        p = GETNEXTTXP(wlc, queue);
4333        if (BRCMS_WAR16165(wlc))
4334                brcms_c_war16165(wlc, false);
4335        if (p == NULL)
4336                goto fatal;
4337
4338        txh = (struct d11txh *) (p->data);
4339        mcl = le16_to_cpu(txh->MacTxControlLow);
4340
4341        if (txs->phyerr) {
4342                if (WL_ERROR_ON()) {
4343                        wiphy_err(wlc->wiphy, "phyerr 0x%x, rate 0x%x\n",
4344                                  txs->phyerr, txh->MainRates);
4345                        brcms_c_print_txdesc(txh);
4346                }
4347                brcms_c_print_txstatus(txs);
4348        }
4349
4350        if (txs->frameid != cpu_to_le16(txh->TxFrameID))
4351                goto fatal;
4352        tx_info = IEEE80211_SKB_CB(p);
4353        h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN);
4354
4355        if (tx_info->control.sta)
4356                scb = (struct scb *)tx_info->control.sta->drv_priv;
4357
4358        if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
4359                brcms_c_ampdu_dotxstatus(wlc->ampdu, scb, p, txs);
4360                return false;
4361        }
4362
4363        supr_status = txs->status & TX_STATUS_SUPR_MASK;
4364        if (supr_status == TX_STATUS_SUPR_BADCH)
4365                BCMMSG(wlc->wiphy,
4366                       "%s: Pkt tx suppressed, possibly channel %d\n",
4367                       __func__, CHSPEC_CHANNEL(wlc->default_bss->chanspec));
4368
4369        tx_rts = cpu_to_le16(txh->MacTxControlLow) & TXC_SENDRTS;
4370        tx_frame_count =
4371            (txs->status & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT;
4372        tx_rts_count =
4373            (txs->status & TX_STATUS_RTS_RTX_MASK) >> TX_STATUS_RTS_RTX_SHIFT;
4374
4375        lastframe = !ieee80211_has_morefrags(h->frame_control);
4376
4377        if (!lastframe) {
4378                wiphy_err(wlc->wiphy, "Not last frame!\n");
4379        } else {
4380                /*
4381                 * Set information to be consumed by Minstrel ht.
4382                 *
4383                 * The "fallback limit" is the number of tx attempts a given
4384                 * MPDU is sent at the "primary" rate. Tx attempts beyond that
4385                 * limit are sent at the "secondary" rate.
4386                 * A 'short frame' does not exceed RTS treshold.
4387                 */
4388                u16 sfbl,       /* Short Frame Rate Fallback Limit */
4389                    lfbl,       /* Long Frame Rate Fallback Limit */
4390                    fbl;
4391
4392                if (queue < AC_COUNT) {
4393                        sfbl = BRCMS_WME_RETRY_SFB_GET(wlc, wme_fifo2ac[queue]);
4394                        lfbl = BRCMS_WME_RETRY_LFB_GET(wlc, wme_fifo2ac[queue]);
4395                } else {
4396                        sfbl = wlc->SFBL;
4397                        lfbl = wlc->LFBL;
4398                }
4399
4400                txrate = tx_info->status.rates;
4401                if (txrate[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
4402                        fbl = lfbl;
4403                else
4404                        fbl = sfbl;
4405
4406                ieee80211_tx_info_clear_status(tx_info);
4407
4408                if ((tx_frame_count > fbl) && (txrate[1].idx >= 0)) {
4409                        /* rate selection requested a fallback rate and we used it */
4410                        txrate[0].count = fbl;
4411                        txrate[1].count = tx_frame_count - fbl;
4412                } else {
4413                        /* rate selection did not request fallback rate, or we didn't need it */
4414                        txrate[0].count = tx_frame_count;
4415                        /* rc80211_minstrel.c:minstrel_tx_status() expects unused rates to be marked with idx = -1 */
4416                        txrate[1].idx = -1;
4417                        txrate[1].count = 0;
4418                }
4419
4420                /* clear the rest of the rates */
4421                for (i = 2; i < IEEE80211_TX_MAX_RATES; i++) {
4422                        txrate[i].idx = -1;
4423                        txrate[i].count = 0;
4424                }
4425
4426                if (txs->status & TX_STATUS_ACK_RCV)
4427                        tx_info->flags |= IEEE80211_TX_STAT_ACK;
4428        }
4429
4430        totlen = brcmu_pkttotlen(p);
4431        free_pdu = true;
4432
4433        brcms_c_txfifo_complete(wlc, queue, 1);
4434
4435        if (lastframe) {
4436                p->next = NULL;
4437                p->prev = NULL;
4438                /* remove PLCP & Broadcom tx descriptor header */
4439                skb_pull(p, D11_PHY_HDR_LEN);
4440                skb_pull(p, D11_TXH_LEN);
4441                ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p);
4442        } else {
4443                wiphy_err(wlc->wiphy, "%s: Not last frame => not calling "
4444                          "tx_status\n", __func__);
4445        }
4446
4447        return false;
4448
4449 fatal:
4450        if (p)
4451                brcmu_pkt_buf_free_skb(p);
4452
4453        return true;
4454
4455}
4456
4457void
4458brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo, s8 txpktpend)
4459{
4460        TXPKTPENDDEC(wlc, fifo, txpktpend);
4461        BCMMSG(wlc->wiphy, "pktpend dec %d to %d\n", txpktpend,
4462                TXPKTPENDGET(wlc, fifo));
4463
4464        /* There is more room; mark precedences related to this FIFO sendable */
4465        BRCMS_TX_FIFO_ENAB(wlc, fifo);
4466
4467        /* Clear MHF2_TXBCMC_NOW flag if BCMC fifo has drained */
4468        if (AP_ENAB(wlc->pub) &&
4469            !TXPKTPENDGET(wlc, TX_BCMC_FIFO)) {
4470                brcms_c_mhf(wlc, MHF2, MHF2_TXBCMC_NOW, 0, BRCM_BAND_AUTO);
4471        }
4472
4473        /* figure out which bsscfg is being worked on... */
4474}
4475
4476/* Update beacon listen interval in shared memory */
4477void brcms_c_bcn_li_upd(struct brcms_c_info *wlc)
4478{
4479        if (AP_ENAB(wlc->pub))
4480                return;
4481
4482        /* wake up every DTIM is the default */
4483        if (wlc->bcn_li_dtim == 1)
4484                brcms_c_write_shm(wlc, M_BCN_LI, 0);
4485        else
4486                brcms_c_write_shm(wlc, M_BCN_LI,
4487                              (wlc->bcn_li_dtim << 8) | wlc->bcn_li_bcn);
4488}
4489
4490/*
4491 * recover 64bit TSF value from the 16bit TSF value in the rx header
4492 * given the assumption that the TSF passed in header is within 65ms
4493 * of the current tsf.
4494 *
4495 * 6       5       4       4       3       2       1
4496 * 3.......6.......8.......0.......2.......4.......6.......8......0
4497 * |<---------- tsf_h ----------->||<--- tsf_l -->||<-RxTSFTime ->|
4498 *
4499 * The RxTSFTime are the lowest 16 bits and provided by the ucode. The
4500 * tsf_l is filled in by brcms_b_recv, which is done earlier in the
4501 * receive call sequence after rx interrupt. Only the higher 16 bits
4502 * are used. Finally, the tsf_h is read from the tsf register.
4503 */
4504static u64 brcms_c_recover_tsf64(struct brcms_c_info *wlc,
4505                                 struct brcms_d11rxhdr *rxh)
4506{
4507        u32 tsf_h, tsf_l;
4508        u16 rx_tsf_0_15, rx_tsf_16_31;
4509
4510        brcms_b_read_tsf(wlc->hw, &tsf_l, &tsf_h);
4511
4512        rx_tsf_16_31 = (u16)(tsf_l >> 16);
4513        rx_tsf_0_15 = rxh->rxhdr.RxTSFTime;
4514
4515        /*
4516         * a greater tsf time indicates the low 16 bits of
4517         * tsf_l wrapped, so decrement the high 16 bits.
4518         */
4519        if ((u16)tsf_l < rx_tsf_0_15) {
4520                rx_tsf_16_31 -= 1;
4521                if (rx_tsf_16_31 == 0xffff)
4522                        tsf_h -= 1;
4523        }
4524
4525        return ((u64)tsf_h << 32) | (((u32)rx_tsf_16_31 << 16) + rx_tsf_0_15);
4526}
4527
4528static void
4529prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
4530                     struct sk_buff *p,
4531                     struct ieee80211_rx_status *rx_status)
4532{
4533        struct brcms_d11rxhdr *wlc_rxh = (struct brcms_d11rxhdr *) rxh;
4534        int preamble;
4535        int channel;
4536        ratespec_t rspec;
4537        unsigned char *plcp;
4538
4539        /* fill in TSF and flag its presence */
4540        rx_status->mactime = brcms_c_recover_tsf64(wlc, wlc_rxh);
4541        rx_status->flag |= RX_FLAG_MACTIME_MPDU;
4542
4543        channel = BRCMS_CHAN_CHANNEL(rxh->RxChan);
4544
4545        if (channel > 14) {
4546                rx_status->band = IEEE80211_BAND_5GHZ;
4547                rx_status->freq = ieee80211_ofdm_chan_to_freq(
4548                                        WF_CHAN_FACTOR_5_G/2, channel);
4549
4550        } else {
4551                rx_status->band = IEEE80211_BAND_2GHZ;
4552                rx_status->freq = ieee80211_dsss_chan_to_freq(channel);
4553        }
4554
4555        rx_status->signal = wlc_rxh->rssi;      /* signal */
4556
4557        /* noise */
4558        /* qual */
4559        rx_status->antenna = (rxh->PhyRxStatus_0 & PRXS0_RXANT_UPSUBBAND) ? 1 : 0;      /* ant */
4560
4561        plcp = p->data;
4562
4563        rspec = brcms_c_compute_rspec(rxh, plcp);
4564        if (IS_MCS(rspec)) {
4565                rx_status->rate_idx = rspec & RSPEC_RATE_MASK;
4566                rx_status->flag |= RX_FLAG_HT;
4567                if (RSPEC_IS40MHZ(rspec))
4568                        rx_status->flag |= RX_FLAG_40MHZ;
4569        } else {
4570                switch (RSPEC2RATE(rspec)) {
4571                case BRCM_RATE_1M:
4572                        rx_status->rate_idx = 0;
4573                        break;
4574                case BRCM_RATE_2M:
4575                        rx_status->rate_idx = 1;
4576                        break;
4577                case BRCM_RATE_5M5:
4578                        rx_status->rate_idx = 2;
4579                        break;
4580                case BRCM_RATE_11M:
4581                        rx_status->rate_idx = 3;
4582                        break;
4583                case BRCM_RATE_6M:
4584                        rx_status->rate_idx = 4;
4585                        break;
4586                case BRCM_RATE_9M:
4587                        rx_status->rate_idx = 5;
4588                        break;
4589                case BRCM_RATE_12M:
4590                        rx_status->rate_idx = 6;
4591                        break;
4592                case BRCM_RATE_18M:
4593                        rx_status->rate_idx = 7;
4594                        break;
4595                case BRCM_RATE_24M:
4596                        rx_status->rate_idx = 8;
4597                        break;
4598                case BRCM_RATE_36M:
4599                        rx_status->rate_idx = 9;
4600                        break;
4601                case BRCM_RATE_48M:
4602                        rx_status->rate_idx = 10;
4603                        break;
4604                case BRCM_RATE_54M:
4605                        rx_status->rate_idx = 11;
4606                        break;
4607                default:
4608                        wiphy_err(wlc->wiphy, "%s: Unknown rate\n", __func__);
4609                }
4610
4611                /* Determine short preamble and rate_idx */
4612                preamble = 0;
4613                if (IS_CCK(rspec)) {
4614                        if (rxh->PhyRxStatus_0 & PRXS0_SHORTH)
4615                                rx_status->flag |= RX_FLAG_SHORTPRE;
4616                } else if (IS_OFDM(rspec)) {
4617                        rx_status->flag |= RX_FLAG_SHORTPRE;
4618                } else {
4619                        wiphy_err(wlc->wiphy, "%s: Unknown modulation\n",
4620                                  __func__);
4621                }
4622        }
4623
4624        if (PLCP3_ISSGI(plcp[3]))
4625                rx_status->flag |= RX_FLAG_SHORT_GI;
4626
4627        if (rxh->RxStatus1 & RXS_DECERR) {
4628                rx_status->flag |= RX_FLAG_FAILED_PLCP_CRC;
4629                wiphy_err(wlc->wiphy, "%s:  RX_FLAG_FAILED_PLCP_CRC\n",
4630                          __func__);
4631        }
4632        if (rxh->RxStatus1 & RXS_FCSERR) {
4633                rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
4634                wiphy_err(wlc->wiphy, "%s:  RX_FLAG_FAILED_FCS_CRC\n",
4635                          __func__);
4636        }
4637}
4638
4639static void
4640brcms_c_recvctl(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
4641                struct sk_buff *p)
4642{
4643        int len_mpdu;
4644        struct ieee80211_rx_status rx_status;
4645
4646        memset(&rx_status, 0, sizeof(rx_status));
4647        prep_mac80211_status(wlc, rxh, p, &rx_status);
4648
4649        /* mac header+body length, exclude CRC and plcp header */
4650        len_mpdu = p->len - D11_PHY_HDR_LEN - FCS_LEN;
4651        skb_pull(p, D11_PHY_HDR_LEN);
4652        __skb_trim(p, len_mpdu);
4653
4654        memcpy(IEEE80211_SKB_RXCB(p), &rx_status, sizeof(rx_status));
4655        ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p);
4656        return;
4657}
4658
4659/* Process received frames */
4660/*
4661 * Return true if more frames need to be processed. false otherwise.
4662 * Param 'bound' indicates max. # frames to process before break out.
4663 */
4664void brcms_c_recv(struct brcms_c_info *wlc, struct sk_buff *p)
4665{
4666        struct d11rxhdr *rxh;
4667        struct ieee80211_hdr *h;
4668        uint len;
4669        bool is_amsdu;
4670
4671        BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
4672
4673        /* frame starts with rxhdr */
4674        rxh = (struct d11rxhdr *) (p->data);
4675
4676        /* strip off rxhdr */
4677        skb_pull(p, BRCMS_HWRXOFF);
4678
4679        /* fixup rx header endianness */
4680        rxh->RxFrameSize = le16_to_cpu(rxh->RxFrameSize);
4681        rxh->PhyRxStatus_0 = le16_to_cpu(rxh->PhyRxStatus_0);
4682        rxh->PhyRxStatus_1 = le16_to_cpu(rxh->PhyRxStatus_1);
4683        rxh->PhyRxStatus_2 = le16_to_cpu(rxh->PhyRxStatus_2);
4684        rxh->PhyRxStatus_3 = le16_to_cpu(rxh->PhyRxStatus_3);
4685        rxh->PhyRxStatus_4 = le16_to_cpu(rxh->PhyRxStatus_4);
4686        rxh->PhyRxStatus_5 = le16_to_cpu(rxh->PhyRxStatus_5);
4687        rxh->RxStatus1 = le16_to_cpu(rxh->RxStatus1);
4688        rxh->RxStatus2 = le16_to_cpu(rxh->RxStatus2);
4689        rxh->RxTSFTime = le16_to_cpu(rxh->RxTSFTime);
4690        rxh->RxChan = le16_to_cpu(rxh->RxChan);
4691
4692        /* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */
4693        if (rxh->RxStatus1 & RXS_PBPRES) {
4694                if (p->len < 2) {
4695                        wiphy_err(wlc->wiphy, "wl%d: recv: rcvd runt of "
4696                                  "len %d\n", wlc->pub->unit, p->len);
4697                        goto toss;
4698                }
4699                skb_pull(p, 2);
4700        }
4701
4702        h = (struct ieee80211_hdr *)(p->data + D11_PHY_HDR_LEN);
4703        len = p->len;
4704
4705        if (rxh->RxStatus1 & RXS_FCSERR) {
4706                if (wlc->pub->mac80211_state & MAC80211_PROMISC_BCNS) {
4707                        wiphy_err(wlc->wiphy, "FCSERR while scanning******* -"
4708                                  " tossing\n");
4709                        goto toss;
4710                } else {
4711                        wiphy_err(wlc->wiphy, "RCSERR!!!\n");
4712                        goto toss;
4713                }
4714        }
4715
4716        /* check received pkt has at least frame control field */
4717        if (len < D11_PHY_HDR_LEN + sizeof(h->frame_control)) {
4718                goto toss;
4719        }
4720
4721        is_amsdu = rxh->RxStatus2 & RXS_AMSDU_MASK;
4722
4723        /* explicitly test bad src address to avoid sending bad deauth */
4724        if (!is_amsdu) {
4725                /* CTS and ACK CTL frames are w/o a2 */
4726
4727                if (ieee80211_is_data(h->frame_control) ||
4728                    ieee80211_is_mgmt(h->frame_control)) {
4729                        if ((is_zero_ether_addr(h->addr2) ||
4730                             is_multicast_ether_addr(h->addr2))) {
4731                                wiphy_err(wlc->wiphy, "wl%d: %s: dropping a "
4732                                          "frame with invalid src mac address,"
4733                                          " a2: %pM\n",
4734                                         wlc->pub->unit, __func__, h->addr2);
4735                                goto toss;
4736                        }
4737                }
4738        }
4739
4740        /* due to sheer numbers, toss out probe reqs for now */
4741        if (ieee80211_is_probe_req(h->frame_control))
4742                goto toss;
4743
4744        if (is_amsdu)
4745                goto toss;
4746
4747        brcms_c_recvctl(wlc, rxh, p);
4748        return;
4749
4750 toss:
4751        brcmu_pkt_buf_free_skb(p);
4752}
4753
4754/* calculate frame duration for Mixed-mode L-SIG spoofing, return
4755 * number of bytes goes in the length field
4756 *
4757 * Formula given by HT PHY Spec v 1.13
4758 *   len = 3(nsyms + nstream + 3) - 3
4759 */
4760u16
4761brcms_c_calc_lsig_len(struct brcms_c_info *wlc, ratespec_t ratespec,
4762                      uint mac_len)
4763{
4764        uint nsyms, len = 0, kNdps;
4765
4766        BCMMSG(wlc->wiphy, "wl%d: rate %d, len%d\n",
4767                 wlc->pub->unit, RSPEC2RATE(ratespec), mac_len);
4768
4769        if (IS_MCS(ratespec)) {
4770                uint mcs = ratespec & RSPEC_RATE_MASK;
4771                /* MCS_TXS(mcs) returns num tx streams - 1 */
4772                int tot_streams = (MCS_TXS(mcs) + 1) + RSPEC_STC(ratespec);
4773
4774                /* the payload duration calculation matches that of regular ofdm */
4775                /* 1000Ndbps = kbps * 4 */
4776                kNdps =
4777                    MCS_RATE(mcs, RSPEC_IS40MHZ(ratespec),
4778                             RSPEC_ISSGI(ratespec)) * 4;
4779
4780                if (RSPEC_STC(ratespec) == 0)
4781                        /* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */
4782                        nsyms =
4783                            CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
4784                                  APHY_TAIL_NBITS) * 1000, kNdps);
4785                else
4786                        /* STBC needs to have even number of symbols */
4787                        nsyms =
4788                            2 *
4789                            CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
4790                                  APHY_TAIL_NBITS) * 1000, 2 * kNdps);
4791
4792                nsyms += (tot_streams + 3);     /* (+3) account for HT-SIG(2) and HT-STF(1) */
4793                /* 3 bytes/symbol @ legacy 6Mbps rate */
4794                len = (3 * nsyms) - 3;  /* (-3) excluding service bits and tail bits */
4795        }
4796
4797        return (u16) len;
4798}
4799
4800/* calculate frame duration of a given rate and length, return time in usec unit */
4801uint
4802brcms_c_calc_frame_time(struct brcms_c_info *wlc, ratespec_t ratespec,
4803                        u8 preamble_type, uint mac_len)
4804{
4805        uint nsyms, dur = 0, Ndps, kNdps;
4806        uint rate = RSPEC2RATE(ratespec);
4807
4808        if (rate == 0) {
4809                wiphy_err(wlc->wiphy, "wl%d: WAR: using rate of 1 mbps\n",
4810                          wlc->pub->unit);
4811                rate = BRCM_RATE_1M;
4812        }
4813
4814        BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d, len%d\n",
4815                 wlc->pub->unit, ratespec, preamble_type, mac_len);
4816
4817        if (IS_MCS(ratespec)) {
4818                uint mcs = ratespec & RSPEC_RATE_MASK;
4819                int tot_streams = MCS_TXS(mcs) + RSPEC_STC(ratespec);
4820
4821                dur = PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT);
4822                if (preamble_type == BRCMS_MM_PREAMBLE)
4823                        dur += PREN_MM_EXT;
4824                /* 1000Ndbps = kbps * 4 */
4825                kNdps =
4826                    MCS_RATE(mcs, RSPEC_IS40MHZ(ratespec),
4827                             RSPEC_ISSGI(ratespec)) * 4;
4828
4829                if (RSPEC_STC(ratespec) == 0)
4830                        /* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */
4831                        nsyms =
4832                            CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
4833                                  APHY_TAIL_NBITS) * 1000, kNdps);
4834                else
4835                        /* STBC needs to have even number of symbols */
4836                        nsyms =
4837                            2 *
4838                            CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
4839                                  APHY_TAIL_NBITS) * 1000, 2 * kNdps);
4840
4841                dur += APHY_SYMBOL_TIME * nsyms;
4842                if (BAND_2G(wlc->band->bandtype))
4843                        dur += DOT11_OFDM_SIGNAL_EXTENSION;
4844        } else if (IS_OFDM(rate)) {
4845                dur = APHY_PREAMBLE_TIME;
4846                dur += APHY_SIGNAL_TIME;
4847                /* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */
4848                Ndps = rate * 2;
4849                /* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */
4850                nsyms =
4851                    CEIL((APHY_SERVICE_NBITS + 8 * mac_len + APHY_TAIL_NBITS),
4852                         Ndps);
4853                dur += APHY_SYMBOL_TIME * nsyms;
4854                if (BAND_2G(wlc->band->bandtype))
4855                        dur += DOT11_OFDM_SIGNAL_EXTENSION;
4856        } else {
4857                /* calc # bits * 2 so factor of 2 in rate (1/2 mbps) will divide out */
4858                mac_len = mac_len * 8 * 2;
4859                /* calc ceiling of bits/rate = microseconds of air time */
4860                dur = (mac_len + rate - 1) / rate;
4861                if (preamble_type & BRCMS_SHORT_PREAMBLE)
4862                        dur += BPHY_PLCP_SHORT_TIME;
4863                else
4864                        dur += BPHY_PLCP_TIME;
4865        }
4866        return dur;
4867}
4868
4869/* The opposite of brcms_c_calc_frame_time */
4870static uint
4871brcms_c_calc_frame_len(struct brcms_c_info *wlc, ratespec_t ratespec,
4872                   u8 preamble_type, uint dur)
4873{
4874        uint nsyms, mac_len, Ndps, kNdps;
4875        uint rate = RSPEC2RATE(ratespec);
4876
4877        BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d, dur %d\n",
4878                 wlc->pub->unit, ratespec, preamble_type, dur);
4879
4880        if (IS_MCS(ratespec)) {
4881                uint mcs = ratespec & RSPEC_RATE_MASK;
4882                int tot_streams = MCS_TXS(mcs) + RSPEC_STC(ratespec);
4883                dur -= PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT);
4884                /* payload calculation matches that of regular ofdm */
4885                if (BAND_2G(wlc->band->bandtype))
4886                        dur -= DOT11_OFDM_SIGNAL_EXTENSION;
4887                /* kNdbps = kbps * 4 */
4888                kNdps =
4889                    MCS_RATE(mcs, RSPEC_IS40MHZ(ratespec),
4890                             RSPEC_ISSGI(ratespec)) * 4;
4891                nsyms = dur / APHY_SYMBOL_TIME;
4892                mac_len =
4893                    ((nsyms * kNdps) -
4894                     ((APHY_SERVICE_NBITS + APHY_TAIL_NBITS) * 1000)) / 8000;
4895        } else if (IS_OFDM(ratespec)) {
4896                dur -= APHY_PREAMBLE_TIME;
4897                dur -= APHY_SIGNAL_TIME;
4898                /* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */
4899                Ndps = rate * 2;
4900                nsyms = dur / APHY_SYMBOL_TIME;
4901                mac_len =
4902                    ((nsyms * Ndps) -
4903                     (APHY_SERVICE_NBITS + APHY_TAIL_NBITS)) / 8;
4904        } else {
4905                if (preamble_type & BRCMS_SHORT_PREAMBLE)
4906                        dur -= BPHY_PLCP_SHORT_TIME;
4907                else
4908                        dur -= BPHY_PLCP_TIME;
4909                mac_len = dur * rate;
4910                /* divide out factor of 2 in rate (1/2 mbps) */
4911                mac_len = mac_len / 8 / 2;
4912        }
4913        return mac_len;
4914}
4915
4916static uint
4917brcms_c_calc_ba_time(struct brcms_c_info *wlc, ratespec_t rspec,
4918                     u8 preamble_type)
4919{
4920        BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, "
4921                 "preamble_type %d\n", wlc->pub->unit, rspec, preamble_type);
4922        /* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that is less than
4923         * or equal to the rate of the immediately previous frame in the FES
4924         */
4925        rspec = BRCMS_BASIC_RATE(wlc, rspec);
4926        /* BA len == 32 == 16(ctl hdr) + 4(ba len) + 8(bitmap) + 4(fcs) */
4927        return brcms_c_calc_frame_time(wlc, rspec, preamble_type,
4928                                   (DOT11_BA_LEN + DOT11_BA_BITMAP_LEN +
4929                                    FCS_LEN));
4930}
4931
4932static uint
4933brcms_c_calc_ack_time(struct brcms_c_info *wlc, ratespec_t rspec,
4934                      u8 preamble_type)
4935{
4936        uint dur = 0;
4937
4938        BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d\n",
4939                wlc->pub->unit, rspec, preamble_type);
4940        /* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that is less than
4941         * or equal to the rate of the immediately previous frame in the FES
4942         */
4943        rspec = BRCMS_BASIC_RATE(wlc, rspec);
4944        /* ACK frame len == 14 == 2(fc) + 2(dur) + 6(ra) + 4(fcs) */
4945        dur =
4946            brcms_c_calc_frame_time(wlc, rspec, preamble_type,
4947                                (DOT11_ACK_LEN + FCS_LEN));
4948        return dur;
4949}
4950
4951static uint
4952brcms_c_calc_cts_time(struct brcms_c_info *wlc, ratespec_t rspec,
4953                      u8 preamble_type)
4954{
4955        BCMMSG(wlc->wiphy, "wl%d: ratespec 0x%x, preamble_type %d\n",
4956                wlc->pub->unit, rspec, preamble_type);
4957        return brcms_c_calc_ack_time(wlc, rspec, preamble_type);
4958}
4959
4960/* derive wlc->band->basic_rate[] table from 'rateset' */
4961void brcms_c_rate_lookup_init(struct brcms_c_info *wlc, wlc_rateset_t *rateset)
4962{
4963        u8 rate;
4964        u8 mandatory;
4965        u8 cck_basic = 0;
4966        u8 ofdm_basic = 0;
4967        u8 *br = wlc->band->basic_rate;
4968        uint i;
4969
4970        /* incoming rates are in 500kbps units as in 802.11 Supported Rates */
4971        memset(br, 0, BRCM_MAXRATE + 1);
4972
4973        /* For each basic rate in the rates list, make an entry in the
4974         * best basic lookup.
4975         */
4976        for (i = 0; i < rateset->count; i++) {
4977                /* only make an entry for a basic rate */
4978                if (!(rateset->rates[i] & BRCMS_RATE_FLAG))
4979                        continue;
4980
4981                /* mask off basic bit */
4982                rate = (rateset->rates[i] & BRCMS_RATE_MASK);
4983
4984                if (rate > BRCM_MAXRATE) {
4985                        wiphy_err(wlc->wiphy, "brcms_c_rate_lookup_init: "
4986                                  "invalid rate 0x%X in rate set\n",
4987                                  rateset->rates[i]);
4988                        continue;
4989                }
4990
4991                br[rate] = rate;
4992        }
4993
4994        /* The rate lookup table now has non-zero entries for each
4995         * basic rate, equal to the basic rate: br[basicN] = basicN
4996         *
4997         * To look up the best basic rate corresponding to any
4998         * particular rate, code can use the basic_rate table
4999         * like this
5000         *
5001         * basic_rate = wlc->band->basic_rate[tx_rate]
5002         *
5003         * Make sure there is a best basic rate entry for
5004         * every rate by walking up the table from low rates
5005         * to high, filling in holes in the lookup table
5006         */
5007
5008        for (i = 0; i < wlc->band->hw_rateset.count; i++) {
5009                rate = wlc->band->hw_rateset.rates[i];
5010
5011                if (br[rate] != 0) {
5012                        /* This rate is a basic rate.
5013                         * Keep track of the best basic rate so far by
5014                         * modulation type.
5015                         */
5016                        if (IS_OFDM(rate))
5017                                ofdm_basic = rate;
5018                        else
5019                                cck_basic = rate;
5020
5021                        continue;
5022                }
5023
5024                /* This rate is not a basic rate so figure out the
5025                 * best basic rate less than this rate and fill in
5026                 * the hole in the table
5027                 */
5028
5029                br[rate] = IS_OFDM(rate) ? ofdm_basic : cck_basic;
5030
5031                if (br[rate] != 0)
5032                        continue;
5033
5034                if (IS_OFDM(rate)) {
5035                        /* In 11g and 11a, the OFDM mandatory rates are 6, 12, and 24 Mbps */
5036                        if (rate >= BRCM_RATE_24M)
5037                                mandatory = BRCM_RATE_24M;
5038                        else if (rate >= BRCM_RATE_12M)
5039                                mandatory = BRCM_RATE_12M;
5040                        else
5041                                mandatory = BRCM_RATE_6M;
5042                } else {
5043                        /* In 11b, all the CCK rates are mandatory 1 - 11 Mbps */
5044                        mandatory = rate;
5045                }
5046
5047                br[rate] = mandatory;
5048        }
5049}
5050
5051static void brcms_c_write_rate_shm(struct brcms_c_info *wlc, u8 rate,
5052                                   u8 basic_rate)
5053{
5054        u8 phy_rate, index;
5055        u8 basic_phy_rate, basic_index;
5056        u16 dir_table, basic_table;
5057        u16 basic_ptr;
5058
5059        /* Shared memory address for the table we are reading */
5060        dir_table = IS_OFDM(basic_rate) ? M_RT_DIRMAP_A : M_RT_DIRMAP_B;
5061
5062        /* Shared memory address for the table we are writing */
5063        basic_table = IS_OFDM(rate) ? M_RT_BBRSMAP_A : M_RT_BBRSMAP_B;
5064
5065        /*
5066         * for a given rate, the LS-nibble of the PLCP SIGNAL field is
5067         * the index into the rate table.
5068         */
5069        phy_rate = rate_info[rate] & BRCMS_RATE_MASK;
5070        basic_phy_rate = rate_info[basic_rate] & BRCMS_RATE_MASK;
5071        index = phy_rate & 0xf;
5072        basic_index = basic_phy_rate & 0xf;
5073
5074        /* Find the SHM pointer to the ACK rate entry by looking in the
5075         * Direct-map Table
5076         */
5077        basic_ptr = brcms_c_read_shm(wlc, (dir_table + basic_index * 2));
5078
5079        /* Update the SHM BSS-basic-rate-set mapping table with the pointer
5080         * to the correct basic rate for the given incoming rate
5081         */
5082        brcms_c_write_shm(wlc, (basic_table + index * 2), basic_ptr);
5083}
5084
5085static const wlc_rateset_t *brcms_c_rateset_get_hwrs(struct brcms_c_info *wlc)
5086{
5087        const wlc_rateset_t *rs_dflt;
5088
5089        if (BRCMS_PHY_11N_CAP(wlc->band)) {
5090                if (BAND_5G(wlc->band->bandtype))
5091                        rs_dflt = &ofdm_mimo_rates;
5092                else
5093                        rs_dflt = &cck_ofdm_mimo_rates;
5094        } else if (wlc->band->gmode)
5095                rs_dflt = &cck_ofdm_rates;
5096        else
5097                rs_dflt = &cck_rates;
5098
5099        return rs_dflt;
5100}
5101
5102void brcms_c_set_ratetable(struct brcms_c_info *wlc)
5103{
5104        const wlc_rateset_t *rs_dflt;
5105        wlc_rateset_t rs;
5106        u8 rate, basic_rate;
5107        uint i;
5108
5109        rs_dflt = brcms_c_rateset_get_hwrs(wlc);
5110
5111        brcms_c_rateset_copy(rs_dflt, &rs);
5112        brcms_c_rateset_mcs_upd(&rs, wlc->stf->txstreams);
5113
5114        /* walk the phy rate table and update SHM basic rate lookup table */
5115        for (i = 0; i < rs.count; i++) {
5116                rate = rs.rates[i] & BRCMS_RATE_MASK;
5117
5118                /* for a given rate BRCMS_BASIC_RATE returns the rate at
5119                 * which a response ACK/CTS should be sent.
5120                 */
5121                basic_rate = BRCMS_BASIC_RATE(wlc, rate);
5122                if (basic_rate == 0) {
5123                        /* This should only happen if we are using a
5124                         * restricted rateset.
5125                         */
5126                        basic_rate = rs.rates[0] & BRCMS_RATE_MASK;
5127                }
5128
5129                brcms_c_write_rate_shm(wlc, rate, basic_rate);
5130        }
5131}
5132
5133/*
5134 * Return true if the specified rate is supported by the specified band.
5135 * BRCM_BAND_AUTO indicates the current band.
5136 */
5137bool brcms_c_valid_rate(struct brcms_c_info *wlc, ratespec_t rspec, int band,
5138                    bool verbose)
5139{
5140        wlc_rateset_t *hw_rateset;
5141        uint i;
5142
5143        if ((band == BRCM_BAND_AUTO) || (band == wlc->band->bandtype)) {
5144                hw_rateset = &wlc->band->hw_rateset;
5145        } else if (NBANDS(wlc) > 1) {
5146                hw_rateset = &wlc->bandstate[OTHERBANDUNIT(wlc)]->hw_rateset;
5147        } else {
5148                /* other band specified and we are a single band device */
5149                return false;
5150        }
5151
5152        /* check if this is a mimo rate */
5153        if (IS_MCS(rspec)) {
5154                if (!VALID_MCS((rspec & RSPEC_RATE_MASK)))
5155                        goto error;
5156
5157                return isset(hw_rateset->mcs, (rspec & RSPEC_RATE_MASK));
5158        }
5159
5160        for (i = 0; i < hw_rateset->count; i++)
5161                if (hw_rateset->rates[i] == RSPEC2RATE(rspec))
5162                        return true;
5163 error:
5164        if (verbose) {
5165                wiphy_err(wlc->wiphy, "wl%d: valid_rate: rate spec 0x%x "
5166                          "not in hw_rateset\n", wlc->pub->unit, rspec);
5167        }
5168
5169        return false;
5170}
5171
5172static void brcms_c_update_mimo_band_bwcap(struct brcms_c_info *wlc, u8 bwcap)
5173{
5174        uint i;
5175        struct brcms_band *band;
5176
5177        for (i = 0; i < NBANDS(wlc); i++) {
5178                if (IS_SINGLEBAND_5G(wlc->deviceid))
5179                        i = BAND_5G_INDEX;
5180                band = wlc->bandstate[i];
5181                if (band->bandtype == BRCM_BAND_5G) {
5182                        if ((bwcap == BRCMS_N_BW_40ALL)
5183                            || (bwcap == BRCMS_N_BW_20IN2G_40IN5G))
5184                                band->mimo_cap_40 = true;
5185                        else
5186                                band->mimo_cap_40 = false;
5187                } else {
5188                        if (bwcap == BRCMS_N_BW_40ALL)
5189                                band->mimo_cap_40 = true;
5190                        else
5191                                band->mimo_cap_40 = false;
5192                }
5193        }
5194}
5195
5196void brcms_c_mod_prb_rsp_rate_table(struct brcms_c_info *wlc, uint frame_len)
5197{
5198        const wlc_rateset_t *rs_dflt;
5199        wlc_rateset_t rs;
5200        u8 rate;
5201        u16 entry_ptr;
5202        u8 plcp[D11_PHY_HDR_LEN];
5203        u16 dur, sifs;
5204        uint i;
5205
5206        sifs = SIFS(wlc->band);
5207
5208        rs_dflt = brcms_c_rateset_get_hwrs(wlc);
5209
5210        brcms_c_rateset_copy(rs_dflt, &rs);
5211        brcms_c_rateset_mcs_upd(&rs, wlc->stf->txstreams);
5212
5213        /* walk the phy rate table and update MAC core SHM basic rate table entries */
5214        for (i = 0; i < rs.count; i++) {
5215                rate = rs.rates[i] & BRCMS_RATE_MASK;
5216
5217                entry_ptr = brcms_c_rate_shm_offset(wlc, rate);
5218
5219                /* Calculate the Probe Response PLCP for the given rate */
5220                brcms_c_compute_plcp(wlc, rate, frame_len, plcp);
5221
5222                /* Calculate the duration of the Probe Response frame plus SIFS for the MAC */
5223                dur = (u16) brcms_c_calc_frame_time(wlc, rate,
5224                                                BRCMS_LONG_PREAMBLE, frame_len);
5225                dur += sifs;
5226
5227                /* Update the SHM Rate Table entry Probe Response values */
5228                brcms_c_write_shm(wlc, entry_ptr + M_RT_PRS_PLCP_POS,
5229                              (u16) (plcp[0] + (plcp[1] << 8)));
5230                brcms_c_write_shm(wlc, entry_ptr + M_RT_PRS_PLCP_POS + 2,
5231                              (u16) (plcp[2] + (plcp[3] << 8)));
5232                brcms_c_write_shm(wlc, entry_ptr + M_RT_PRS_DUR_POS, dur);
5233        }
5234}
5235
5236/*      Max buffering needed for beacon template/prb resp template is 142 bytes.
5237 *
5238 *      PLCP header is 6 bytes.
5239 *      802.11 A3 header is 24 bytes.
5240 *      Max beacon frame body template length is 112 bytes.
5241 *      Max probe resp frame body template length is 110 bytes.
5242 *
5243 *      *len on input contains the max length of the packet available.
5244 *
5245 *      The *len value is set to the number of bytes in buf used, and starts with the PLCP
5246 *      and included up to, but not including, the 4 byte FCS.
5247 */
5248static void
5249brcms_c_bcn_prb_template(struct brcms_c_info *wlc, u16 type,
5250                         ratespec_t bcn_rspec,
5251                         struct brcms_bss_cfg *cfg, u16 *buf, int *len)
5252{
5253        static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
5254        struct cck_phy_hdr *plcp;
5255        struct ieee80211_mgmt *h;
5256        int hdr_len, body_len;
5257
5258        if (MBSS_BCN_ENAB(cfg) && type == IEEE80211_STYPE_BEACON)
5259                hdr_len = DOT11_MAC_HDR_LEN;
5260        else
5261                hdr_len = D11_PHY_HDR_LEN + DOT11_MAC_HDR_LEN;
5262        body_len = *len - hdr_len;      /* calc buffer size provided for frame body */
5263
5264        *len = hdr_len + body_len;      /* return actual size */
5265
5266        /* format PHY and MAC headers */
5267        memset((char *)buf, 0, hdr_len);
5268
5269        plcp = (struct cck_phy_hdr *) buf;
5270
5271        /* PLCP for Probe Response frames are filled in from core's rate table */
5272        if (type == IEEE80211_STYPE_BEACON && !MBSS_BCN_ENAB(cfg)) {
5273                /* fill in PLCP */
5274                brcms_c_compute_plcp(wlc, bcn_rspec,
5275                                 (DOT11_MAC_HDR_LEN + body_len + FCS_LEN),
5276                                 (u8 *) plcp);
5277
5278        }
5279        /* "Regular" and 16 MBSS but not for 4 MBSS */
5280        /* Update the phytxctl for the beacon based on the rspec */
5281        if (!SOFTBCN_ENAB(cfg))
5282                brcms_c_beacon_phytxctl_txant_upd(wlc, bcn_rspec);
5283
5284        if (MBSS_BCN_ENAB(cfg) && type == IEEE80211_STYPE_BEACON)
5285                h = (struct ieee80211_mgmt *)&plcp[0];
5286        else
5287                h = (struct ieee80211_mgmt *)&plcp[1];
5288
5289        /* fill in 802.11 header */
5290        h->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | type);
5291
5292        /* DUR is 0 for multicast bcn, or filled in by MAC for prb resp */
5293        /* A1 filled in by MAC for prb resp, broadcast for bcn */
5294        if (type == IEEE80211_STYPE_BEACON)
5295                memcpy(&h->da, &ether_bcast, ETH_ALEN);
5296        memcpy(&h->sa, &cfg->cur_etheraddr, ETH_ALEN);
5297        memcpy(&h->bssid, &cfg->BSSID, ETH_ALEN);
5298
5299        /* SEQ filled in by MAC */
5300
5301        return;
5302}
5303
5304int brcms_c_get_header_len()
5305{
5306        return TXOFF;
5307}
5308
5309/* Update a beacon for a particular BSS
5310 * For MBSS, this updates the software template and sets "latest" to the index of the
5311 * template updated.
5312 * Otherwise, it updates the hardware template.
5313 */
5314void brcms_c_bss_update_beacon(struct brcms_c_info *wlc,
5315                               struct brcms_bss_cfg *cfg)
5316{
5317        int len = BCN_TMPL_LEN;
5318
5319        /* Clear the soft intmask */
5320        wlc->defmacintmask &= ~MI_BCNTPL;
5321
5322        if (!cfg->up) {         /* Only allow updates on an UP bss */
5323                return;
5324        }
5325
5326        /* Optimize:  Some of if/else could be combined */
5327        if (!MBSS_BCN_ENAB(cfg) && HWBCN_ENAB(cfg)) {
5328                /* Hardware beaconing for this config */
5329                u16 bcn[BCN_TMPL_LEN / 2];
5330                u32 both_valid = MCMD_BCN0VLD | MCMD_BCN1VLD;
5331                d11regs_t *regs = wlc->regs;
5332
5333                /* Check if both templates are in use, if so sched. an interrupt
5334                 *      that will call back into this routine
5335                 */
5336                if ((R_REG(&regs->maccommand) & both_valid) == both_valid) {
5337                        /* clear any previous status */
5338                        W_REG(&regs->macintstatus, MI_BCNTPL);
5339                }
5340                /* Check that after scheduling the interrupt both of the
5341                 *      templates are still busy. if not clear the int. & remask
5342                 */
5343                if ((R_REG(&regs->maccommand) & both_valid) == both_valid) {
5344                        wlc->defmacintmask |= MI_BCNTPL;
5345                        return;
5346                }
5347
5348                wlc->bcn_rspec =
5349                    brcms_c_lowest_basic_rspec(wlc, &cfg->current_bss->rateset);
5350                /* update the template and ucode shm */
5351                brcms_c_bcn_prb_template(wlc, IEEE80211_STYPE_BEACON,
5352                                     wlc->bcn_rspec, cfg, bcn, &len);
5353                brcms_c_write_hw_bcntemplates(wlc, bcn, len, false);
5354        }
5355}
5356
5357/*
5358 * Update all beacons for the system.
5359 */
5360void brcms_c_update_beacon(struct brcms_c_info *wlc)
5361{
5362        int idx;
5363        struct brcms_bss_cfg *bsscfg;
5364
5365        /* update AP or IBSS beacons */
5366        FOREACH_BSS(wlc, idx, bsscfg) {
5367                if (bsscfg->up && (BSSCFG_AP(bsscfg) || !bsscfg->BSS))
5368                        brcms_c_bss_update_beacon(wlc, bsscfg);
5369        }
5370}
5371
5372/* Write ssid into shared memory */
5373void brcms_c_shm_ssid_upd(struct brcms_c_info *wlc, struct brcms_bss_cfg *cfg)
5374{
5375        u8 *ssidptr = cfg->SSID;
5376        u16 base = M_SSID;
5377        u8 ssidbuf[IEEE80211_MAX_SSID_LEN];
5378
5379        /* padding the ssid with zero and copy it into shm */
5380        memset(ssidbuf, 0, IEEE80211_MAX_SSID_LEN);
5381        memcpy(ssidbuf, ssidptr, cfg->SSID_len);
5382
5383        brcms_c_copyto_shm(wlc, base, ssidbuf, IEEE80211_MAX_SSID_LEN);
5384
5385        if (!MBSS_BCN_ENAB(cfg))
5386                brcms_c_write_shm(wlc, M_SSIDLEN, (u16) cfg->SSID_len);
5387}
5388
5389void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend)
5390{
5391        int idx;
5392        struct brcms_bss_cfg *bsscfg;
5393
5394        /* update AP or IBSS probe responses */
5395        FOREACH_BSS(wlc, idx, bsscfg) {
5396                if (bsscfg->up && (BSSCFG_AP(bsscfg) || !bsscfg->BSS))
5397                        brcms_c_bss_update_probe_resp(wlc, bsscfg, suspend);
5398        }
5399}
5400
5401void
5402brcms_c_bss_update_probe_resp(struct brcms_c_info *wlc,
5403                              struct brcms_bss_cfg *cfg,
5404                              bool suspend)
5405{
5406        u16 prb_resp[BCN_TMPL_LEN / 2];
5407        int len = BCN_TMPL_LEN;
5408
5409        /* write the probe response to hardware, or save in the config structure */
5410        if (!MBSS_PRB_ENAB(cfg)) {
5411
5412                /* create the probe response template */
5413                brcms_c_bcn_prb_template(wlc, IEEE80211_STYPE_PROBE_RESP, 0,
5414                                         cfg, prb_resp, &len);
5415
5416                if (suspend)
5417                        brcms_c_suspend_mac_and_wait(wlc);
5418
5419                /* write the probe response into the template region */
5420                brcms_b_write_template_ram(wlc->hw, T_PRS_TPL_BASE,
5421                                            (len + 3) & ~3, prb_resp);
5422
5423                /* write the length of the probe response frame (+PLCP/-FCS) */
5424                brcms_c_write_shm(wlc, M_PRB_RESP_FRM_LEN, (u16) len);
5425
5426                /* write the SSID and SSID length */
5427                brcms_c_shm_ssid_upd(wlc, cfg);
5428
5429                /*
5430                 * Write PLCP headers and durations for probe response frames at all rates.
5431                 * Use the actual frame length covered by the PLCP header for the call to
5432                 * brcms_c_mod_prb_rsp_rate_table() by subtracting the PLCP len
5433                 * and adding the FCS.
5434                 */
5435                len += (-D11_PHY_HDR_LEN + FCS_LEN);
5436                brcms_c_mod_prb_rsp_rate_table(wlc, (u16) len);
5437
5438                if (suspend)
5439                        brcms_c_enable_mac(wlc);
5440        } else {                /* Generating probe resp in sw; update local template */
5441                /* error: No software probe response support without MBSS */
5442        }
5443}
5444
5445/* prepares pdu for transmission. returns BCM error codes */
5446int brcms_c_prep_pdu(struct brcms_c_info *wlc, struct sk_buff *pdu, uint *fifop)
5447{
5448        uint fifo;
5449        struct d11txh *txh;
5450        struct ieee80211_hdr *h;
5451        struct scb *scb;
5452
5453        txh = (struct d11txh *) (pdu->data);
5454        h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN);
5455
5456        /* get the pkt queue info. This was put at brcms_c_sendctl or
5457         * brcms_c_send for PDU */
5458        fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK;
5459
5460        scb = NULL;
5461
5462        *fifop = fifo;
5463
5464        /* return if insufficient dma resources */
5465        if (TXAVAIL(wlc, fifo) < MAX_DMA_SEGS) {
5466                /* Mark precedences related to this FIFO, unsendable */
5467                BRCMS_TX_FIFO_CLEAR(wlc, fifo);
5468                return -EBUSY;
5469        }
5470        return 0;
5471}
5472
5473/* init tx reported rate mechanism */
5474void brcms_c_reprate_init(struct brcms_c_info *wlc)
5475{
5476        int i;
5477        struct brcms_bss_cfg *bsscfg;
5478
5479        FOREACH_BSS(wlc, i, bsscfg) {
5480                brcms_c_bsscfg_reprate_init(bsscfg);
5481        }
5482}
5483
5484/* per bsscfg init tx reported rate mechanism */
5485void brcms_c_bsscfg_reprate_init(struct brcms_bss_cfg *bsscfg)
5486{
5487        bsscfg->txrspecidx = 0;
5488        memset((char *)bsscfg->txrspec, 0, sizeof(bsscfg->txrspec));
5489}
5490
5491void brcms_default_rateset(struct brcms_c_info *wlc, wlc_rateset_t *rs)
5492{
5493        brcms_c_rateset_default(rs, NULL, wlc->band->phytype,
5494                wlc->band->bandtype, false, BRCMS_RATE_MASK_FULL,
5495                (bool) N_ENAB(wlc->pub),
5496                CHSPEC_WLC_BW(wlc->default_bss->chanspec),
5497                wlc->stf->txstreams);
5498}
5499
5500static void brcms_c_bss_default_init(struct brcms_c_info *wlc)
5501{
5502        chanspec_t chanspec;
5503        struct brcms_band *band;
5504        struct brcms_bss_info *bi = wlc->default_bss;
5505
5506        /* init default and target BSS with some sane initial values */
5507        memset((char *)(bi), 0, sizeof(struct brcms_bss_info));
5508        bi->beacon_period = BEACON_INTERVAL_DEFAULT;
5509        bi->dtim_period = DTIM_INTERVAL_DEFAULT;
5510
5511        /* fill the default channel as the first valid channel
5512         * starting from the 2G channels
5513         */
5514        chanspec = CH20MHZ_CHSPEC(1);
5515        wlc->home_chanspec = bi->chanspec = chanspec;
5516
5517        /* find the band of our default channel */
5518        band = wlc->band;
5519        if (NBANDS(wlc) > 1 && band->bandunit != CHSPEC_BANDUNIT(chanspec))
5520                band = wlc->bandstate[OTHERBANDUNIT(wlc)];
5521
5522        /* init bss rates to the band specific default rate set */
5523        brcms_c_rateset_default(&bi->rateset, NULL, band->phytype,
5524                band->bandtype, false, BRCMS_RATE_MASK_FULL,
5525                (bool) N_ENAB(wlc->pub), CHSPEC_WLC_BW(chanspec),
5526                wlc->stf->txstreams);
5527
5528        if (N_ENAB(wlc->pub))
5529                bi->flags |= BRCMS_BSS_HT;
5530}
5531
5532static ratespec_t
5533mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band,
5534                       u32 int_val)
5535{
5536        u8 stf = (int_val & NRATE_STF_MASK) >> NRATE_STF_SHIFT;
5537        u8 rate = int_val & NRATE_RATE_MASK;
5538        ratespec_t rspec;
5539        bool ismcs = ((int_val & NRATE_MCS_INUSE) == NRATE_MCS_INUSE);
5540        bool issgi = ((int_val & NRATE_SGI_MASK) >> NRATE_SGI_SHIFT);
5541        bool override_mcs_only = ((int_val & NRATE_OVERRIDE_MCS_ONLY)
5542                                  == NRATE_OVERRIDE_MCS_ONLY);
5543        int bcmerror = 0;
5544
5545        if (!ismcs) {
5546                return (ratespec_t) rate;
5547        }
5548
5549        /* validate the combination of rate/mcs/stf is allowed */
5550        if (N_ENAB(wlc->pub) && ismcs) {
5551                /* mcs only allowed when nmode */
5552                if (stf > PHY_TXC1_MODE_SDM) {
5553                        wiphy_err(wlc->wiphy, "wl%d: %s: Invalid stf\n",
5554                                 BRCMS_UNIT(wlc), __func__);
5555                        bcmerror = -EINVAL;
5556                        goto done;
5557                }
5558
5559                /* mcs 32 is a special case, DUP mode 40 only */
5560                if (rate == 32) {
5561                        if (!CHSPEC_IS40(wlc->home_chanspec) ||
5562                            ((stf != PHY_TXC1_MODE_SISO)
5563                             && (stf != PHY_TXC1_MODE_CDD))) {
5564                                wiphy_err(wlc->wiphy, "wl%d: %s: Invalid mcs "
5565                                          "32\n", BRCMS_UNIT(wlc), __func__);
5566                                bcmerror = -EINVAL;
5567                                goto done;
5568                        }
5569                        /* mcs > 7 must use stf SDM */
5570                } else if (rate > HIGHEST_SINGLE_STREAM_MCS) {
5571                        /* mcs > 7 must use stf SDM */
5572                        if (stf != PHY_TXC1_MODE_SDM) {
5573                                BCMMSG(wlc->wiphy, "wl%d: enabling "
5574                                         "SDM mode for mcs %d\n",
5575                                         BRCMS_UNIT(wlc), rate);
5576                                stf = PHY_TXC1_MODE_SDM;
5577                        }
5578                } else {
5579                        /* MCS 0-7 may use SISO, CDD, and for phy_rev >= 3 STBC */
5580                        if ((stf > PHY_TXC1_MODE_STBC) ||
5581                            (!BRCMS_STBC_CAP_PHY(wlc)
5582                             && (stf == PHY_TXC1_MODE_STBC))) {
5583                                wiphy_err(wlc->wiphy, "wl%d: %s: Invalid STBC"
5584                                          "\n", BRCMS_UNIT(wlc), __func__);
5585                                bcmerror = -EINVAL;
5586                                goto done;
5587                        }
5588                }
5589        } else if (IS_OFDM(rate)) {
5590                if ((stf != PHY_TXC1_MODE_CDD) && (stf != PHY_TXC1_MODE_SISO)) {
5591                        wiphy_err(wlc->wiphy, "wl%d: %s: Invalid OFDM\n",
5592                                  BRCMS_UNIT(wlc), __func__);
5593                        bcmerror = -EINVAL;
5594                        goto done;
5595                }
5596        } else if (IS_CCK(rate)) {
5597                if ((cur_band->bandtype != BRCM_BAND_2G)
5598                    || (stf != PHY_TXC1_MODE_SISO)) {
5599                        wiphy_err(wlc->wiphy, "wl%d: %s: Invalid CCK\n",
5600                                  BRCMS_UNIT(wlc), __func__);
5601                        bcmerror = -EINVAL;
5602                        goto done;
5603                }
5604        } else {
5605                wiphy_err(wlc->wiphy, "wl%d: %s: Unknown rate type\n",
5606                          BRCMS_UNIT(wlc), __func__);
5607                bcmerror = -EINVAL;
5608                goto done;
5609        }
5610        /* make sure multiple antennae are available for non-siso rates */
5611        if ((stf != PHY_TXC1_MODE_SISO) && (wlc->stf->txstreams == 1)) {
5612                wiphy_err(wlc->wiphy, "wl%d: %s: SISO antenna but !SISO "
5613                          "request\n", BRCMS_UNIT(wlc), __func__);
5614                bcmerror = -EINVAL;
5615                goto done;
5616        }
5617
5618        rspec = rate;
5619        if (ismcs) {
5620                rspec |= RSPEC_MIMORATE;
5621                /* For STBC populate the STC field of the ratespec */
5622                if (stf == PHY_TXC1_MODE_STBC) {
5623                        u8 stc;
5624                        stc = 1;        /* Nss for single stream is always 1 */
5625                        rspec |= (stc << RSPEC_STC_SHIFT);
5626                }
5627        }
5628
5629        rspec |= (stf << RSPEC_STF_SHIFT);
5630
5631        if (override_mcs_only)
5632                rspec |= RSPEC_OVERRIDE_MCS_ONLY;
5633
5634        if (issgi)
5635                rspec |= RSPEC_SHORT_GI;
5636
5637        if ((rate != 0)
5638            && !brcms_c_valid_rate(wlc, rspec, cur_band->bandtype, true)) {
5639                return rate;
5640        }
5641
5642        return rspec;
5643done:
5644        return rate;
5645}
5646
5647/* formula:  IDLE_BUSY_RATIO_X_16 = (100-duty_cycle)/duty_cycle*16 */
5648static int
5649brcms_c_duty_cycle_set(struct brcms_c_info *wlc, int duty_cycle, bool isOFDM,
5650                   bool writeToShm)
5651{
5652        int idle_busy_ratio_x_16 = 0;
5653        uint offset =
5654            isOFDM ? M_TX_IDLE_BUSY_RATIO_X_16_OFDM :
5655            M_TX_IDLE_BUSY_RATIO_X_16_CCK;
5656        if (duty_cycle > 100 || duty_cycle < 0) {
5657                wiphy_err(wlc->wiphy, "wl%d:  duty cycle value off limit\n",
5658                          wlc->pub->unit);
5659                return -EINVAL;
5660        }
5661        if (duty_cycle)
5662                idle_busy_ratio_x_16 = (100 - duty_cycle) * 16 / duty_cycle;
5663        /* Only write to shared memory  when wl is up */
5664        if (writeToShm)
5665                brcms_c_write_shm(wlc, offset, (u16) idle_busy_ratio_x_16);
5666
5667        if (isOFDM)
5668                wlc->tx_duty_cycle_ofdm = (u16) duty_cycle;
5669        else
5670                wlc->tx_duty_cycle_cck = (u16) duty_cycle;
5671
5672        return 0;
5673}
5674
5675/* Read a single u16 from shared memory.
5676 * SHM 'offset' needs to be an even address
5677 */
5678u16 brcms_c_read_shm(struct brcms_c_info *wlc, uint offset)
5679{
5680        return brcms_b_read_shm(wlc->hw, offset);
5681}
5682
5683/* Write a single u16 to shared memory.
5684 * SHM 'offset' needs to be an even address
5685 */
5686void brcms_c_write_shm(struct brcms_c_info *wlc, uint offset, u16 v)
5687{
5688        brcms_b_write_shm(wlc->hw, offset, v);
5689}
5690
5691/* Copy a buffer to shared memory.
5692 * SHM 'offset' needs to be an even address and
5693 * Buffer length 'len' must be an even number of bytes
5694 */
5695void brcms_c_copyto_shm(struct brcms_c_info *wlc, uint offset, const void *buf,
5696                        int len)
5697{
5698        /* offset and len need to be even */
5699        if (len <= 0 || (offset & 1) || (len & 1))
5700                return;
5701
5702        brcms_b_copyto_objmem(wlc->hw, offset, buf, len, OBJADDR_SHM_SEL);
5703
5704}
5705
5706/* wrapper BMAC functions to for HIGH driver access */
5707void brcms_c_mctrl(struct brcms_c_info *wlc, u32 mask, u32 val)
5708{
5709        brcms_b_mctrl(wlc->hw, mask, val);
5710}
5711
5712void brcms_c_mhf(struct brcms_c_info *wlc, u8 idx, u16 mask, u16 val, int bands)
5713{
5714        brcms_b_mhf(wlc->hw, idx, mask, val, bands);
5715}
5716
5717int brcms_c_xmtfifo_sz_get(struct brcms_c_info *wlc, uint fifo, uint *blocks)
5718{
5719        return brcms_b_xmtfifo_sz_get(wlc->hw, fifo, blocks);
5720}
5721
5722void brcms_c_write_template_ram(struct brcms_c_info *wlc, int offset, int len,
5723                            void *buf)
5724{
5725        brcms_b_write_template_ram(wlc->hw, offset, len, buf);
5726}
5727
5728void brcms_c_write_hw_bcntemplates(struct brcms_c_info *wlc, void *bcn, int len,
5729                               bool both)
5730{
5731        brcms_b_write_hw_bcntemplates(wlc->hw, bcn, len, both);
5732}
5733
5734void
5735brcms_c_set_addrmatch(struct brcms_c_info *wlc, int match_reg_offset,
5736                  const u8 *addr)
5737{
5738        brcms_b_set_addrmatch(wlc->hw, match_reg_offset, addr);
5739        if (match_reg_offset == RCM_BSSID_OFFSET)
5740                memcpy(wlc->cfg->BSSID, addr, ETH_ALEN);
5741}
5742
5743void brcms_c_pllreq(struct brcms_c_info *wlc, bool set, mbool req_bit)
5744{
5745        brcms_b_pllreq(wlc->hw, set, req_bit);
5746}
5747
5748void brcms_c_reset_bmac_done(struct brcms_c_info *wlc)
5749{
5750}
5751
5752/* check for the particular priority flow control bit being set */
5753bool
5754brcms_c_txflowcontrol_prio_isset(struct brcms_c_info *wlc,
5755                                 struct brcms_txq_info *q,
5756                                 int prio)
5757{
5758        uint prio_mask;
5759
5760        if (prio == ALLPRIO) {
5761                prio_mask = TXQ_STOP_FOR_PRIOFC_MASK;
5762        } else {
5763                prio_mask = NBITVAL(prio);
5764        }
5765
5766        return (q->stopped & prio_mask) == prio_mask;
5767}
5768
5769/* propagate the flow control to all interfaces using the given tx queue */
5770void brcms_c_txflowcontrol(struct brcms_c_info *wlc,
5771                           struct brcms_txq_info *qi,
5772                           bool on, int prio)
5773{
5774        uint prio_bits;
5775        uint cur_bits;
5776
5777        BCMMSG(wlc->wiphy, "flow control kicks in\n");
5778
5779        if (prio == ALLPRIO) {
5780                prio_bits = TXQ_STOP_FOR_PRIOFC_MASK;
5781        } else {
5782                prio_bits = NBITVAL(prio);
5783        }
5784
5785        cur_bits = qi->stopped & prio_bits;
5786
5787        /* Check for the case of no change and return early
5788         * Otherwise update the bit and continue
5789         */
5790        if (on) {
5791                if (cur_bits == prio_bits) {
5792                        return;
5793                }
5794                mboolset(qi->stopped, prio_bits);
5795        } else {
5796                if (cur_bits == 0) {
5797                        return;
5798                }
5799                mboolclr(qi->stopped, prio_bits);
5800        }
5801
5802        /* If there is a flow control override we will not change the external
5803         * flow control state.
5804         */
5805        if (qi->stopped & ~TXQ_STOP_FOR_PRIOFC_MASK) {
5806                return;
5807        }
5808
5809        brcms_c_txflowcontrol_signal(wlc, qi, on, prio);
5810}
5811
5812void
5813brcms_c_txflowcontrol_override(struct brcms_c_info *wlc,
5814                               struct brcms_txq_info *qi,
5815                               bool on, uint override)
5816{
5817        uint prev_override;
5818
5819        prev_override = (qi->stopped & ~TXQ_STOP_FOR_PRIOFC_MASK);
5820
5821        /* Update the flow control bits and do an early return if there is
5822         * no change in the external flow control state.
5823         */
5824        if (on) {
5825                mboolset(qi->stopped, override);
5826                /* if there was a previous override bit on, then setting this
5827                 * makes no difference.
5828                 */
5829                if (prev_override) {
5830                        return;
5831                }
5832
5833                brcms_c_txflowcontrol_signal(wlc, qi, ON, ALLPRIO);
5834        } else {
5835                mboolclr(qi->stopped, override);
5836                /* clearing an override bit will only make a difference for
5837                 * flow control if it was the only bit set. For any other
5838                 * override setting, just return
5839                 */
5840                if (prev_override != override) {
5841                        return;
5842                }
5843
5844                if (qi->stopped == 0) {
5845                        brcms_c_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO);
5846                } else {
5847                        int prio;
5848
5849                        for (prio = MAXPRIO; prio >= 0; prio--) {
5850                                if (!mboolisset(qi->stopped, NBITVAL(prio)))
5851                                        brcms_c_txflowcontrol_signal(
5852                                                wlc, qi, OFF, prio);
5853                        }
5854                }
5855        }
5856}
5857
5858static void brcms_c_txflowcontrol_reset(struct brcms_c_info *wlc)
5859{
5860        struct brcms_txq_info *qi;
5861
5862        for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) {
5863                if (qi->stopped) {
5864                        brcms_c_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO);
5865                        qi->stopped = 0;
5866                }
5867        }
5868}
5869
5870static void
5871brcms_c_txflowcontrol_signal(struct brcms_c_info *wlc,
5872                             struct brcms_txq_info *qi, bool on, int prio)
5873{
5874#ifdef NON_FUNCTIONAL
5875        /* wlcif_list is never filled so this function is not functional */
5876        struct brcms_c_if *wlcif;
5877
5878        for (wlcif = wlc->wlcif_list; wlcif != NULL; wlcif = wlcif->next) {
5879                if (wlcif->qi == qi && wlcif->flags & BRCMS_IF_LINKED)
5880                        brcms_txflowcontrol(wlc->wl, wlcif->wlif, on, prio);
5881        }
5882#endif
5883}
5884
5885static struct brcms_txq_info *brcms_c_txq_alloc(struct brcms_c_info *wlc)
5886{
5887        struct brcms_txq_info *qi, *p;
5888
5889        qi = kzalloc(sizeof(struct brcms_txq_info), GFP_ATOMIC);
5890        if (qi != NULL) {
5891                /*
5892                 * Have enough room for control packets along with HI watermark
5893                 * Also, add room to txq for total psq packets if all the SCBs
5894                 * leave PS mode. The watermark for flowcontrol to OS packets
5895                 * will remain the same
5896                 */
5897                brcmu_pktq_init(&qi->q, BRCMS_PREC_COUNT,
5898                          (2 * wlc->pub->tunables->datahiwat) + PKTQ_LEN_DEFAULT
5899                          + wlc->pub->psq_pkts_total);
5900
5901                /* add this queue to the the global list */
5902                p = wlc->tx_queues;
5903                if (p == NULL) {
5904                        wlc->tx_queues = qi;
5905                } else {
5906                        while (p->next != NULL)
5907                                p = p->next;
5908                        p->next = qi;
5909                }
5910        }
5911        return qi;
5912}
5913
5914static void brcms_c_txq_free(struct brcms_c_info *wlc,
5915                             struct brcms_txq_info *qi)
5916{
5917        struct brcms_txq_info *p;
5918
5919        if (qi == NULL)
5920                return;
5921
5922        /* remove the queue from the linked list */
5923        p = wlc->tx_queues;
5924        if (p == qi)
5925                wlc->tx_queues = p->next;
5926        else {
5927                while (p != NULL && p->next != qi)
5928                        p = p->next;
5929                if (p != NULL)
5930                        p->next = p->next->next;
5931        }
5932
5933        kfree(qi);
5934}
5935
5936/*
5937 * Flag 'scan in progress' to withhold dynamic phy calibration
5938 */
5939void brcms_c_scan_start(struct brcms_c_info *wlc)
5940{
5941        wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, true);
5942}
5943
5944void brcms_c_scan_stop(struct brcms_c_info *wlc)
5945{
5946        wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, false);
5947}
5948
5949void brcms_c_associate_upd(struct brcms_c_info *wlc, bool state)
5950{
5951        wlc->pub->associated = state;
5952        wlc->cfg->associated = state;
5953}
5954
5955/*
5956 * When a remote STA/AP is removed by Mac80211, or when it can no longer accept
5957 * AMPDU traffic, packets pending in hardware have to be invalidated so that
5958 * when later on hardware releases them, they can be handled appropriately.
5959 */
5960void brcms_c_inval_dma_pkts(struct brcms_hardware *hw,
5961                               struct ieee80211_sta *sta,
5962                               void (*dma_callback_fn))
5963{
5964        struct dma_pub *dmah;
5965        int i;
5966        for (i = 0; i < NFIFO; i++) {
5967                dmah = hw->di[i];
5968                if (dmah != NULL)
5969                        dma_walk_packets(dmah, dma_callback_fn, sta);
5970        }
5971}
5972
5973int brcms_c_get_curband(struct brcms_c_info *wlc)
5974{
5975        return wlc->band->bandunit;
5976}
5977
5978void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, bool drop)
5979{
5980        /* flush packet queue when requested */
5981        if (drop)
5982                brcmu_pktq_flush(&wlc->pkt_queue->q, false, NULL, NULL);
5983
5984        /* wait for queue and DMA fifos to run dry */
5985        while (!pktq_empty(&wlc->pkt_queue->q) ||
5986               TXPKTPENDTOT(wlc) > 0) {
5987                brcms_msleep(wlc->wl, 1);
5988        }
5989}
5990
5991int brcms_c_set_par(struct brcms_c_info *wlc, enum wlc_par_id par_id,
5992                    int int_val)
5993{
5994        int err = 0;
5995
5996        switch (par_id) {
5997        case IOV_BCN_LI_BCN:
5998                wlc->bcn_li_bcn = (u8) int_val;
5999                if (wlc->pub->up)
6000                        brcms_c_bcn_li_upd(wlc);
6001                break;
6002                /* As long as override is false, this only sets the *user*
6003                   targets. User can twiddle this all he wants with no harm.
6004                   wlc_phy_txpower_set() explicitly sets override to false if
6005                   not internal or test.
6006                 */
6007        case IOV_QTXPOWER:{
6008                u8 qdbm;
6009                bool override;
6010
6011                /* Remove override bit and clip to max qdbm value */
6012                qdbm = (u8)min_t(u32, (int_val & ~WL_TXPWR_OVERRIDE), 0xff);
6013                /* Extract override setting */
6014                override = (int_val & WL_TXPWR_OVERRIDE) ? true : false;
6015                err =
6016                    wlc_phy_txpower_set(wlc->band->pi, qdbm, override);
6017                break;
6018                }
6019        case IOV_MPC:
6020                wlc->mpc = (bool)int_val;
6021                brcms_c_radio_mpc_upd(wlc);
6022                break;
6023        default:
6024                err = -ENOTSUPP;
6025        }
6026        return err;
6027}
6028
6029int brcms_c_get_par(struct brcms_c_info *wlc, enum wlc_par_id par_id,
6030                    int *ret_int_ptr)
6031{
6032        int err = 0;
6033
6034        switch (par_id) {
6035        case IOV_BCN_LI_BCN:
6036                *ret_int_ptr = wlc->bcn_li_bcn;
6037                break;
6038        case IOV_QTXPOWER: {
6039                uint qdbm;
6040                bool override;
6041
6042                err = wlc_phy_txpower_get(wlc->band->pi, &qdbm,
6043                        &override);
6044                if (err != 0)
6045                        return err;
6046
6047                /* Return qdbm units */
6048                *ret_int_ptr =
6049                    qdbm | (override ? WL_TXPWR_OVERRIDE : 0);
6050                break;
6051                }
6052        case IOV_MPC:
6053                *ret_int_ptr = (s32) wlc->mpc;
6054                break;
6055        default:
6056                err = -ENOTSUPP;
6057        }
6058        return err;
6059}
6060
6061/*
6062 * Search the name=value vars for a specific one and return its value.
6063 * Returns NULL if not found.
6064 */
6065char *getvar(char *vars, const char *name)
6066{
6067        char *s;
6068        int len;
6069
6070        if (!name)
6071                return NULL;
6072
6073        len = strlen(name);
6074        if (len == 0)
6075                return NULL;
6076
6077        /* first look in vars[] */
6078        for (s = vars; s && *s;) {
6079                if ((memcmp(s, name, len) == 0) && (s[len] == '='))
6080                        return &s[len + 1];
6081
6082                while (*s++)
6083                        ;
6084        }
6085        /* nothing found */
6086        return NULL;
6087}
6088
6089/*
6090 * Search the vars for a specific one and return its value as
6091 * an integer. Returns 0 if not found.
6092 */
6093int getintvar(char *vars, const char *name)
6094{
6095        char *val;
6096
6097        val = getvar(vars, name);
6098        if (val == NULL)
6099                return 0;
6100
6101        return simple_strtoul(val, NULL, 0);
6102}
6103