Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright (c) 2010 Broadcom Corporation
0003  * Copyright (c) 2013 Hauke Mehrtens <hauke@hauke-m.de>
0004  *
0005  * Permission to use, copy, modify, and/or distribute this software for any
0006  * purpose with or without fee is hereby granted, provided that the above
0007  * copyright notice and this permission notice appear in all copies.
0008  *
0009  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
0010  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
0011  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
0012  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
0013  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
0014  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
0015  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
0016  */
0017 
0018 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0019 
0020 #include <linux/pci_ids.h>
0021 #include <linux/if_ether.h>
0022 #include <net/cfg80211.h>
0023 #include <net/mac80211.h>
0024 #include <brcm_hw_ids.h>
0025 #include <aiutils.h>
0026 #include <chipcommon.h>
0027 #include "rate.h"
0028 #include "scb.h"
0029 #include "phy/phy_hal.h"
0030 #include "channel.h"
0031 #include "antsel.h"
0032 #include "stf.h"
0033 #include "ampdu.h"
0034 #include "mac80211_if.h"
0035 #include "ucode_loader.h"
0036 #include "main.h"
0037 #include "soc.h"
0038 #include "dma.h"
0039 #include "debug.h"
0040 #include "brcms_trace_events.h"
0041 
0042 /* watchdog timer, in unit of ms */
0043 #define TIMER_INTERVAL_WATCHDOG     1000
0044 /* radio monitor timer, in unit of ms */
0045 #define TIMER_INTERVAL_RADIOCHK     800
0046 
0047 /* beacon interval, in unit of 1024TU */
0048 #define BEACON_INTERVAL_DEFAULT     100
0049 
0050 /* n-mode support capability */
0051 /* 2x2 includes both 1x1 & 2x2 devices
0052  * reserved #define 2 for future when we want to separate 1x1 & 2x2 and
0053  * control it independently
0054  */
0055 #define WL_11N_2x2          1
0056 #define WL_11N_3x3          3
0057 #define WL_11N_4x4          4
0058 
0059 #define EDCF_ACI_MASK           0x60
0060 #define EDCF_ACI_SHIFT          5
0061 #define EDCF_ECWMIN_MASK        0x0f
0062 #define EDCF_ECWMAX_SHIFT       4
0063 #define EDCF_AIFSN_MASK         0x0f
0064 #define EDCF_AIFSN_MAX          15
0065 #define EDCF_ECWMAX_MASK        0xf0
0066 
0067 #define EDCF_AC_BE_TXOP_STA     0x0000
0068 #define EDCF_AC_BK_TXOP_STA     0x0000
0069 #define EDCF_AC_VO_ACI_STA      0x62
0070 #define EDCF_AC_VO_ECW_STA      0x32
0071 #define EDCF_AC_VI_ACI_STA      0x42
0072 #define EDCF_AC_VI_ECW_STA      0x43
0073 #define EDCF_AC_BK_ECW_STA      0xA4
0074 #define EDCF_AC_VI_TXOP_STA     0x005e
0075 #define EDCF_AC_VO_TXOP_STA     0x002f
0076 #define EDCF_AC_BE_ACI_STA      0x03
0077 #define EDCF_AC_BE_ECW_STA      0xA4
0078 #define EDCF_AC_BK_ACI_STA      0x27
0079 #define EDCF_AC_VO_TXOP_AP      0x002f
0080 
0081 #define EDCF_TXOP2USEC(txop)        ((txop) << 5)
0082 #define EDCF_ECW2CW(exp)        ((1 << (exp)) - 1)
0083 
0084 #define APHY_SYMBOL_TIME        4
0085 #define APHY_PREAMBLE_TIME      16
0086 #define APHY_SIGNAL_TIME        4
0087 #define APHY_SIFS_TIME          16
0088 #define APHY_SERVICE_NBITS      16
0089 #define APHY_TAIL_NBITS         6
0090 #define BPHY_SIFS_TIME          10
0091 #define BPHY_PLCP_SHORT_TIME        96
0092 
0093 #define PREN_PREAMBLE           24
0094 #define PREN_MM_EXT         12
0095 #define PREN_PREAMBLE_EXT       4
0096 
0097 #define DOT11_MAC_HDR_LEN       24
0098 #define DOT11_ACK_LEN           10
0099 #define DOT11_BA_LEN            4
0100 #define DOT11_OFDM_SIGNAL_EXTENSION 6
0101 #define DOT11_MIN_FRAG_LEN      256
0102 #define DOT11_RTS_LEN           16
0103 #define DOT11_CTS_LEN           10
0104 #define DOT11_BA_BITMAP_LEN     128
0105 #define DOT11_MAXNUMFRAGS       16
0106 #define DOT11_MAX_FRAG_LEN      2346
0107 
0108 #define BPHY_PLCP_TIME          192
0109 #define RIFS_11N_TIME           2
0110 
0111 /* length of the BCN template area */
0112 #define BCN_TMPL_LEN            512
0113 
0114 /* brcms_bss_info flag bit values */
0115 #define BRCMS_BSS_HT            0x0020  /* BSS is HT (MIMO) capable */
0116 
0117 /* chip rx buffer offset */
0118 #define BRCMS_HWRXOFF           38
0119 
0120 /* rfdisable delay timer 500 ms, runs of ALP clock */
0121 #define RFDISABLE_DEFAULT       10000000
0122 
0123 #define BRCMS_TEMPSENSE_PERIOD      10  /* 10 second timeout */
0124 
0125 /* synthpu_dly times in us */
0126 #define SYNTHPU_DLY_APHY_US     3700
0127 #define SYNTHPU_DLY_BPHY_US     1050
0128 #define SYNTHPU_DLY_NPHY_US     2048
0129 #define SYNTHPU_DLY_LPPHY_US        300
0130 
0131 #define ANTCNT              10  /* vanilla M_MAX_ANTCNT val */
0132 
0133 /* Per-AC retry limit register definitions; uses defs.h bitfield macros */
0134 #define EDCF_SHORT_S            0
0135 #define EDCF_SFB_S          4
0136 #define EDCF_LONG_S         8
0137 #define EDCF_LFB_S          12
0138 #define EDCF_SHORT_M            BITFIELD_MASK(4)
0139 #define EDCF_SFB_M          BITFIELD_MASK(4)
0140 #define EDCF_LONG_M         BITFIELD_MASK(4)
0141 #define EDCF_LFB_M          BITFIELD_MASK(4)
0142 
0143 #define RETRY_SHORT_DEF         7   /* Default Short retry Limit */
0144 #define RETRY_SHORT_MAX         255 /* Maximum Short retry Limit */
0145 #define RETRY_LONG_DEF          4   /* Default Long retry count */
0146 #define RETRY_SHORT_FB          3   /* Short count for fb rate */
0147 #define RETRY_LONG_FB           2   /* Long count for fb rate */
0148 
0149 #define APHY_CWMIN          15
0150 #define PHY_CWMAX           1023
0151 
0152 #define EDCF_AIFSN_MIN          1
0153 
0154 #define FRAGNUM_MASK            0xF
0155 
0156 #define APHY_SLOT_TIME          9
0157 #define BPHY_SLOT_TIME          20
0158 
0159 #define WL_SPURAVOID_OFF        0
0160 #define WL_SPURAVOID_ON1        1
0161 #define WL_SPURAVOID_ON2        2
0162 
0163 /* invalid core flags, use the saved coreflags */
0164 #define BRCMS_USE_COREFLAGS     0xffffffff
0165 
0166 /* values for PLCPHdr_override */
0167 #define BRCMS_PLCP_AUTO         -1
0168 #define BRCMS_PLCP_SHORT        0
0169 #define BRCMS_PLCP_LONG         1
0170 
0171 /* values for g_protection_override and n_protection_override */
0172 #define BRCMS_PROTECTION_AUTO       -1
0173 #define BRCMS_PROTECTION_OFF        0
0174 #define BRCMS_PROTECTION_ON     1
0175 #define BRCMS_PROTECTION_MMHDR_ONLY 2
0176 #define BRCMS_PROTECTION_CTS_ONLY   3
0177 
0178 /* values for g_protection_control and n_protection_control */
0179 #define BRCMS_PROTECTION_CTL_OFF    0
0180 #define BRCMS_PROTECTION_CTL_LOCAL  1
0181 #define BRCMS_PROTECTION_CTL_OVERLAP    2
0182 
0183 /* values for n_protection */
0184 #define BRCMS_N_PROTECTION_OFF      0
0185 #define BRCMS_N_PROTECTION_OPTIONAL 1
0186 #define BRCMS_N_PROTECTION_20IN40   2
0187 #define BRCMS_N_PROTECTION_MIXEDMODE    3
0188 
0189 /* values for band specific 40MHz capabilities */
0190 #define BRCMS_N_BW_20ALL        0
0191 #define BRCMS_N_BW_40ALL        1
0192 #define BRCMS_N_BW_20IN2G_40IN5G    2
0193 
0194 /* bitflags for SGI support (sgi_rx iovar) */
0195 #define BRCMS_N_SGI_20          0x01
0196 #define BRCMS_N_SGI_40          0x02
0197 
0198 /* defines used by the nrate iovar */
0199 /* MSC in use,indicates b0-6 holds an mcs */
0200 #define NRATE_MCS_INUSE         0x00000080
0201 /* rate/mcs value */
0202 #define NRATE_RATE_MASK         0x0000007f
0203 /* stf mode mask: siso, cdd, stbc, sdm */
0204 #define NRATE_STF_MASK          0x0000ff00
0205 /* stf mode shift */
0206 #define NRATE_STF_SHIFT         8
0207 /* bit indicate to override mcs only */
0208 #define NRATE_OVERRIDE_MCS_ONLY     0x40000000
0209 #define NRATE_SGI_MASK          0x00800000  /* sgi mode */
0210 #define NRATE_SGI_SHIFT         23      /* sgi mode */
0211 #define NRATE_LDPC_CODING       0x00400000  /* adv coding in use */
0212 #define NRATE_LDPC_SHIFT        22      /* ldpc shift */
0213 
0214 #define NRATE_STF_SISO          0       /* stf mode SISO */
0215 #define NRATE_STF_CDD           1       /* stf mode CDD */
0216 #define NRATE_STF_STBC          2       /* stf mode STBC */
0217 #define NRATE_STF_SDM           3       /* stf mode SDM */
0218 
0219 #define MAX_DMA_SEGS            4
0220 
0221 /* # of entries in Tx FIFO */
0222 #define NTXD                64
0223 /* Max # of entries in Rx FIFO based on 4kb page size */
0224 #define NRXD                256
0225 
0226 /* Amount of headroom to leave in Tx FIFO */
0227 #define TX_HEADROOM         4
0228 
0229 /* try to keep this # rbufs posted to the chip */
0230 #define NRXBUFPOST          32
0231 
0232 /* max # frames to process in brcms_c_recv() */
0233 #define RXBND               8
0234 /* max # tx status to process in wlc_txstatus() */
0235 #define TXSBND              8
0236 
0237 /* brcmu_format_flags() bit description structure */
0238 struct brcms_c_bit_desc {
0239     u32 bit;
0240     const char *name;
0241 };
0242 
0243 /*
0244  * The following table lists the buffer memory allocated to xmt fifos in HW.
0245  * the size is in units of 256bytes(one block), total size is HW dependent
0246  * ucode has default fifo partition, sw can overwrite if necessary
0247  *
0248  * This is documented in twiki under the topic UcodeTxFifo. Please ensure
0249  * the twiki is updated before making changes.
0250  */
0251 
0252 /* Starting corerev for the fifo size table */
0253 #define XMTFIFOTBL_STARTREV 17
0254 
0255 struct d11init {
0256     __le16 addr;
0257     __le16 size;
0258     __le32 value;
0259 };
0260 
0261 struct edcf_acparam {
0262     u8 ACI;
0263     u8 ECW;
0264     u16 TXOP;
0265 } __packed;
0266 
0267 /* debug/trace */
0268 uint brcm_msg_level;
0269 
0270 /* TX FIFO number to WME/802.1E Access Category */
0271 static const u8 wme_fifo2ac[] = {
0272     IEEE80211_AC_BK,
0273     IEEE80211_AC_BE,
0274     IEEE80211_AC_VI,
0275     IEEE80211_AC_VO,
0276     IEEE80211_AC_BE,
0277     IEEE80211_AC_BE
0278 };
0279 
0280 /* ieee80211 Access Category to TX FIFO number */
0281 static const u8 wme_ac2fifo[] = {
0282     TX_AC_VO_FIFO,
0283     TX_AC_VI_FIFO,
0284     TX_AC_BE_FIFO,
0285     TX_AC_BK_FIFO
0286 };
0287 
0288 static const u16 xmtfifo_sz[][NFIFO] = {
0289     /* corerev 17: 5120, 49152, 49152, 5376, 4352, 1280 */
0290     {20, 192, 192, 21, 17, 5},
0291     /* corerev 18: */
0292     {0, 0, 0, 0, 0, 0},
0293     /* corerev 19: */
0294     {0, 0, 0, 0, 0, 0},
0295     /* corerev 20: 5120, 49152, 49152, 5376, 4352, 1280 */
0296     {20, 192, 192, 21, 17, 5},
0297     /* corerev 21: 2304, 14848, 5632, 3584, 3584, 1280 */
0298     {9, 58, 22, 14, 14, 5},
0299     /* corerev 22: 5120, 49152, 49152, 5376, 4352, 1280 */
0300     {20, 192, 192, 21, 17, 5},
0301     /* corerev 23: 5120, 49152, 49152, 5376, 4352, 1280 */
0302     {20, 192, 192, 21, 17, 5},
0303     /* corerev 24: 2304, 14848, 5632, 3584, 3584, 1280 */
0304     {9, 58, 22, 14, 14, 5},
0305     /* corerev 25: */
0306     {0, 0, 0, 0, 0, 0},
0307     /* corerev 26: */
0308     {0, 0, 0, 0, 0, 0},
0309     /* corerev 27: */
0310     {0, 0, 0, 0, 0, 0},
0311     /* corerev 28: 2304, 14848, 5632, 3584, 3584, 1280 */
0312     {9, 58, 22, 14, 14, 5},
0313 };
0314 
0315 #ifdef DEBUG
0316 static const char * const fifo_names[] = {
0317     "AC_BK", "AC_BE", "AC_VI", "AC_VO", "BCMC", "ATIM" };
0318 #else
0319 static const char fifo_names[6][1];
0320 #endif
0321 
0322 #ifdef DEBUG
0323 /* pointer to most recently allocated wl/wlc */
0324 static struct brcms_c_info *wlc_info_dbg = (struct brcms_c_info *) (NULL);
0325 #endif
0326 
0327 /* Mapping of ieee80211 AC numbers to tx fifos */
0328 static const u8 ac_to_fifo_mapping[IEEE80211_NUM_ACS] = {
0329     [IEEE80211_AC_VO]   = TX_AC_VO_FIFO,
0330     [IEEE80211_AC_VI]   = TX_AC_VI_FIFO,
0331     [IEEE80211_AC_BE]   = TX_AC_BE_FIFO,
0332     [IEEE80211_AC_BK]   = TX_AC_BK_FIFO,
0333 };
0334 
0335 /* Mapping of tx fifos to ieee80211 AC numbers */
0336 static const u8 fifo_to_ac_mapping[IEEE80211_NUM_ACS] = {
0337     [TX_AC_BK_FIFO] = IEEE80211_AC_BK,
0338     [TX_AC_BE_FIFO] = IEEE80211_AC_BE,
0339     [TX_AC_VI_FIFO] = IEEE80211_AC_VI,
0340     [TX_AC_VO_FIFO] = IEEE80211_AC_VO,
0341 };
0342 
0343 static u8 brcms_ac_to_fifo(u8 ac)
0344 {
0345     if (ac >= ARRAY_SIZE(ac_to_fifo_mapping))
0346         return TX_AC_BE_FIFO;
0347     return ac_to_fifo_mapping[ac];
0348 }
0349 
0350 static u8 brcms_fifo_to_ac(u8 fifo)
0351 {
0352     if (fifo >= ARRAY_SIZE(fifo_to_ac_mapping))
0353         return IEEE80211_AC_BE;
0354     return fifo_to_ac_mapping[fifo];
0355 }
0356 
0357 /* Find basic rate for a given rate */
0358 static u8 brcms_basic_rate(struct brcms_c_info *wlc, u32 rspec)
0359 {
0360     if (is_mcs_rate(rspec))
0361         return wlc->band->basic_rate[mcs_table[rspec & RSPEC_RATE_MASK]
0362                .leg_ofdm];
0363     return wlc->band->basic_rate[rspec & RSPEC_RATE_MASK];
0364 }
0365 
0366 static u16 frametype(u32 rspec, u8 mimoframe)
0367 {
0368     if (is_mcs_rate(rspec))
0369         return mimoframe;
0370     return is_cck_rate(rspec) ? FT_CCK : FT_OFDM;
0371 }
0372 
0373 /* currently the best mechanism for determining SIFS is the band in use */
0374 static u16 get_sifs(struct brcms_band *band)
0375 {
0376     return band->bandtype == BRCM_BAND_5G ? APHY_SIFS_TIME :
0377                  BPHY_SIFS_TIME;
0378 }
0379 
0380 /*
0381  * Detect Card removed.
0382  * Even checking an sbconfig register read will not false trigger when the core
0383  * is in reset it breaks CF address mechanism. Accessing gphy phyversion will
0384  * cause SB error if aphy is in reset on 4306B0-DB. Need a simple accessible
0385  * reg with fixed 0/1 pattern (some platforms return all 0).
0386  * If clocks are present, call the sb routine which will figure out if the
0387  * device is removed.
0388  */
0389 static bool brcms_deviceremoved(struct brcms_c_info *wlc)
0390 {
0391     u32 macctrl;
0392 
0393     if (!wlc->hw->clk)
0394         return ai_deviceremoved(wlc->hw->sih);
0395     macctrl = bcma_read32(wlc->hw->d11core,
0396                   D11REGOFFS(maccontrol));
0397     return (macctrl & (MCTL_PSM_JMP_0 | MCTL_IHR_EN)) != MCTL_IHR_EN;
0398 }
0399 
0400 /* sum the individual fifo tx pending packet counts */
0401 static int brcms_txpktpendtot(struct brcms_c_info *wlc)
0402 {
0403     int i;
0404     int pending = 0;
0405 
0406     for (i = 0; i < ARRAY_SIZE(wlc->hw->di); i++)
0407         if (wlc->hw->di[i])
0408             pending += dma_txpending(wlc->hw->di[i]);
0409     return pending;
0410 }
0411 
0412 static bool brcms_is_mband_unlocked(struct brcms_c_info *wlc)
0413 {
0414     return wlc->pub->_nbands > 1 && !wlc->bandlocked;
0415 }
0416 
0417 static int brcms_chspec_bw(u16 chanspec)
0418 {
0419     if (CHSPEC_IS40(chanspec))
0420         return BRCMS_40_MHZ;
0421     if (CHSPEC_IS20(chanspec))
0422         return BRCMS_20_MHZ;
0423 
0424     return BRCMS_10_MHZ;
0425 }
0426 
0427 static void brcms_c_bsscfg_mfree(struct brcms_bss_cfg *cfg)
0428 {
0429     if (cfg == NULL)
0430         return;
0431 
0432     kfree(cfg->current_bss);
0433     kfree(cfg);
0434 }
0435 
0436 static void brcms_c_detach_mfree(struct brcms_c_info *wlc)
0437 {
0438     if (wlc == NULL)
0439         return;
0440 
0441     brcms_c_bsscfg_mfree(wlc->bsscfg);
0442     kfree(wlc->pub);
0443     kfree(wlc->modulecb);
0444     kfree(wlc->default_bss);
0445     kfree(wlc->protection);
0446     kfree(wlc->stf);
0447     kfree(wlc->bandstate[0]);
0448     if (wlc->corestate)
0449         kfree(wlc->corestate->macstat_snapshot);
0450     kfree(wlc->corestate);
0451     if (wlc->hw)
0452         kfree(wlc->hw->bandstate[0]);
0453     kfree(wlc->hw);
0454     if (wlc->beacon)
0455         dev_kfree_skb_any(wlc->beacon);
0456     if (wlc->probe_resp)
0457         dev_kfree_skb_any(wlc->probe_resp);
0458 
0459     kfree(wlc);
0460 }
0461 
0462 static struct brcms_bss_cfg *brcms_c_bsscfg_malloc(uint unit)
0463 {
0464     struct brcms_bss_cfg *cfg;
0465 
0466     cfg = kzalloc(sizeof(struct brcms_bss_cfg), GFP_ATOMIC);
0467     if (cfg == NULL)
0468         goto fail;
0469 
0470     cfg->current_bss = kzalloc(sizeof(struct brcms_bss_info), GFP_ATOMIC);
0471     if (cfg->current_bss == NULL)
0472         goto fail;
0473 
0474     return cfg;
0475 
0476  fail:
0477     brcms_c_bsscfg_mfree(cfg);
0478     return NULL;
0479 }
0480 
0481 static struct brcms_c_info *
0482 brcms_c_attach_malloc(uint unit, uint *err, uint devid)
0483 {
0484     struct brcms_c_info *wlc;
0485 
0486     wlc = kzalloc(sizeof(struct brcms_c_info), GFP_ATOMIC);
0487     if (wlc == NULL) {
0488         *err = 1002;
0489         goto fail;
0490     }
0491 
0492     /* allocate struct brcms_c_pub state structure */
0493     wlc->pub = kzalloc(sizeof(struct brcms_pub), GFP_ATOMIC);
0494     if (wlc->pub == NULL) {
0495         *err = 1003;
0496         goto fail;
0497     }
0498     wlc->pub->wlc = wlc;
0499 
0500     /* allocate struct brcms_hardware state structure */
0501 
0502     wlc->hw = kzalloc(sizeof(struct brcms_hardware), GFP_ATOMIC);
0503     if (wlc->hw == NULL) {
0504         *err = 1005;
0505         goto fail;
0506     }
0507     wlc->hw->wlc = wlc;
0508 
0509     wlc->hw->bandstate[0] =
0510         kcalloc(MAXBANDS, sizeof(struct brcms_hw_band), GFP_ATOMIC);
0511     if (wlc->hw->bandstate[0] == NULL) {
0512         *err = 1006;
0513         goto fail;
0514     } else {
0515         int i;
0516 
0517         for (i = 1; i < MAXBANDS; i++)
0518             wlc->hw->bandstate[i] = (struct brcms_hw_band *)
0519                 ((unsigned long)wlc->hw->bandstate[0] +
0520                  (sizeof(struct brcms_hw_band) * i));
0521     }
0522 
0523     wlc->modulecb =
0524         kcalloc(BRCMS_MAXMODULES, sizeof(struct modulecb),
0525             GFP_ATOMIC);
0526     if (wlc->modulecb == NULL) {
0527         *err = 1009;
0528         goto fail;
0529     }
0530 
0531     wlc->default_bss = kzalloc(sizeof(struct brcms_bss_info), GFP_ATOMIC);
0532     if (wlc->default_bss == NULL) {
0533         *err = 1010;
0534         goto fail;
0535     }
0536 
0537     wlc->bsscfg = brcms_c_bsscfg_malloc(unit);
0538     if (wlc->bsscfg == NULL) {
0539         *err = 1011;
0540         goto fail;
0541     }
0542 
0543     wlc->protection = kzalloc(sizeof(struct brcms_protection),
0544                   GFP_ATOMIC);
0545     if (wlc->protection == NULL) {
0546         *err = 1016;
0547         goto fail;
0548     }
0549 
0550     wlc->stf = kzalloc(sizeof(struct brcms_stf), GFP_ATOMIC);
0551     if (wlc->stf == NULL) {
0552         *err = 1017;
0553         goto fail;
0554     }
0555 
0556     wlc->bandstate[0] =
0557         kcalloc(MAXBANDS, sizeof(struct brcms_band), GFP_ATOMIC);
0558     if (wlc->bandstate[0] == NULL) {
0559         *err = 1025;
0560         goto fail;
0561     } else {
0562         int i;
0563 
0564         for (i = 1; i < MAXBANDS; i++)
0565             wlc->bandstate[i] = (struct brcms_band *)
0566                 ((unsigned long)wlc->bandstate[0]
0567                 + (sizeof(struct brcms_band)*i));
0568     }
0569 
0570     wlc->corestate = kzalloc(sizeof(struct brcms_core), GFP_ATOMIC);
0571     if (wlc->corestate == NULL) {
0572         *err = 1026;
0573         goto fail;
0574     }
0575 
0576     wlc->corestate->macstat_snapshot =
0577         kzalloc(sizeof(struct macstat), GFP_ATOMIC);
0578     if (wlc->corestate->macstat_snapshot == NULL) {
0579         *err = 1027;
0580         goto fail;
0581     }
0582 
0583     return wlc;
0584 
0585  fail:
0586     brcms_c_detach_mfree(wlc);
0587     return NULL;
0588 }
0589 
0590 /*
0591  * Update the slot timing for standard 11b/g (20us slots)
0592  * or shortslot 11g (9us slots)
0593  * The PSM needs to be suspended for this call.
0594  */
0595 static void brcms_b_update_slot_timing(struct brcms_hardware *wlc_hw,
0596                     bool shortslot)
0597 {
0598     struct bcma_device *core = wlc_hw->d11core;
0599 
0600     if (shortslot) {
0601         /* 11g short slot: 11a timing */
0602         bcma_write16(core, D11REGOFFS(ifs_slot), 0x0207);
0603         brcms_b_write_shm(wlc_hw, M_DOT11_SLOT, APHY_SLOT_TIME);
0604     } else {
0605         /* 11g long slot: 11b timing */
0606         bcma_write16(core, D11REGOFFS(ifs_slot), 0x0212);
0607         brcms_b_write_shm(wlc_hw, M_DOT11_SLOT, BPHY_SLOT_TIME);
0608     }
0609 }
0610 
0611 /*
0612  * calculate frame duration of a given rate and length, return
0613  * time in usec unit
0614  */
0615 static uint brcms_c_calc_frame_time(struct brcms_c_info *wlc, u32 ratespec,
0616                     u8 preamble_type, uint mac_len)
0617 {
0618     uint nsyms, dur = 0, Ndps, kNdps;
0619     uint rate = rspec2rate(ratespec);
0620 
0621     if (rate == 0) {
0622         brcms_err(wlc->hw->d11core, "wl%d: WAR: using rate of 1 mbps\n",
0623               wlc->pub->unit);
0624         rate = BRCM_RATE_1M;
0625     }
0626 
0627     if (is_mcs_rate(ratespec)) {
0628         uint mcs = ratespec & RSPEC_RATE_MASK;
0629         int tot_streams = mcs_2_txstreams(mcs) + rspec_stc(ratespec);
0630 
0631         dur = PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT);
0632         if (preamble_type == BRCMS_MM_PREAMBLE)
0633             dur += PREN_MM_EXT;
0634         /* 1000Ndbps = kbps * 4 */
0635         kNdps = mcs_2_rate(mcs, rspec_is40mhz(ratespec),
0636                    rspec_issgi(ratespec)) * 4;
0637 
0638         if (rspec_stc(ratespec) == 0)
0639             nsyms =
0640                 CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
0641                   APHY_TAIL_NBITS) * 1000, kNdps);
0642         else
0643             /* STBC needs to have even number of symbols */
0644             nsyms =
0645                 2 *
0646                 CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
0647                   APHY_TAIL_NBITS) * 1000, 2 * kNdps);
0648 
0649         dur += APHY_SYMBOL_TIME * nsyms;
0650         if (wlc->band->bandtype == BRCM_BAND_2G)
0651             dur += DOT11_OFDM_SIGNAL_EXTENSION;
0652     } else if (is_ofdm_rate(rate)) {
0653         dur = APHY_PREAMBLE_TIME;
0654         dur += APHY_SIGNAL_TIME;
0655         /* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */
0656         Ndps = rate * 2;
0657         /* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */
0658         nsyms =
0659             CEIL((APHY_SERVICE_NBITS + 8 * mac_len + APHY_TAIL_NBITS),
0660              Ndps);
0661         dur += APHY_SYMBOL_TIME * nsyms;
0662         if (wlc->band->bandtype == BRCM_BAND_2G)
0663             dur += DOT11_OFDM_SIGNAL_EXTENSION;
0664     } else {
0665         /*
0666          * calc # bits * 2 so factor of 2 in rate (1/2 mbps)
0667          * will divide out
0668          */
0669         mac_len = mac_len * 8 * 2;
0670         /* calc ceiling of bits/rate = microseconds of air time */
0671         dur = (mac_len + rate - 1) / rate;
0672         if (preamble_type & BRCMS_SHORT_PREAMBLE)
0673             dur += BPHY_PLCP_SHORT_TIME;
0674         else
0675             dur += BPHY_PLCP_TIME;
0676     }
0677     return dur;
0678 }
0679 
0680 static void brcms_c_write_inits(struct brcms_hardware *wlc_hw,
0681                 const struct d11init *inits)
0682 {
0683     struct bcma_device *core = wlc_hw->d11core;
0684     int i;
0685     uint offset;
0686     u16 size;
0687     u32 value;
0688 
0689     brcms_dbg_info(wlc_hw->d11core, "wl%d\n", wlc_hw->unit);
0690 
0691     for (i = 0; inits[i].addr != cpu_to_le16(0xffff); i++) {
0692         size = le16_to_cpu(inits[i].size);
0693         offset = le16_to_cpu(inits[i].addr);
0694         value = le32_to_cpu(inits[i].value);
0695         if (size == 2)
0696             bcma_write16(core, offset, value);
0697         else if (size == 4)
0698             bcma_write32(core, offset, value);
0699         else
0700             break;
0701     }
0702 }
0703 
0704 static void brcms_c_write_mhf(struct brcms_hardware *wlc_hw, u16 *mhfs)
0705 {
0706     u8 idx;
0707     static const u16 addr[] = {
0708         M_HOST_FLAGS1, M_HOST_FLAGS2, M_HOST_FLAGS3, M_HOST_FLAGS4,
0709         M_HOST_FLAGS5
0710     };
0711 
0712     for (idx = 0; idx < MHFMAX; idx++)
0713         brcms_b_write_shm(wlc_hw, addr[idx], mhfs[idx]);
0714 }
0715 
0716 static void brcms_c_ucode_bsinit(struct brcms_hardware *wlc_hw)
0717 {
0718     struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode;
0719 
0720     /* init microcode host flags */
0721     brcms_c_write_mhf(wlc_hw, wlc_hw->band->mhfs);
0722 
0723     /* do band-specific ucode IHR, SHM, and SCR inits */
0724     if (D11REV_IS(wlc_hw->corerev, 17) || D11REV_IS(wlc_hw->corerev, 23)) {
0725         if (BRCMS_ISNPHY(wlc_hw->band))
0726             brcms_c_write_inits(wlc_hw, ucode->d11n0bsinitvals16);
0727         else
0728             brcms_err(wlc_hw->d11core,
0729                   "%s: wl%d: unsupported phy in corerev %d\n",
0730                   __func__, wlc_hw->unit,
0731                   wlc_hw->corerev);
0732     } else {
0733         if (D11REV_IS(wlc_hw->corerev, 24)) {
0734             if (BRCMS_ISLCNPHY(wlc_hw->band))
0735                 brcms_c_write_inits(wlc_hw,
0736                             ucode->d11lcn0bsinitvals24);
0737             else
0738                 brcms_err(wlc_hw->d11core,
0739                       "%s: wl%d: unsupported phy in core rev %d\n",
0740                       __func__, wlc_hw->unit,
0741                       wlc_hw->corerev);
0742         } else {
0743             brcms_err(wlc_hw->d11core,
0744                   "%s: wl%d: unsupported corerev %d\n",
0745                   __func__, wlc_hw->unit, wlc_hw->corerev);
0746         }
0747     }
0748 }
0749 
0750 static void brcms_b_core_ioctl(struct brcms_hardware *wlc_hw, u32 m, u32 v)
0751 {
0752     struct bcma_device *core = wlc_hw->d11core;
0753     u32 ioctl = bcma_aread32(core, BCMA_IOCTL) & ~m;
0754 
0755     bcma_awrite32(core, BCMA_IOCTL, ioctl | v);
0756 }
0757 
0758 static void brcms_b_core_phy_clk(struct brcms_hardware *wlc_hw, bool clk)
0759 {
0760     brcms_dbg_info(wlc_hw->d11core, "wl%d: clk %d\n", wlc_hw->unit, clk);
0761 
0762     wlc_hw->phyclk = clk;
0763 
0764     if (OFF == clk) {   /* clear gmode bit, put phy into reset */
0765 
0766         brcms_b_core_ioctl(wlc_hw, (SICF_PRST | SICF_FGC | SICF_GMODE),
0767                    (SICF_PRST | SICF_FGC));
0768         udelay(1);
0769         brcms_b_core_ioctl(wlc_hw, (SICF_PRST | SICF_FGC), SICF_PRST);
0770         udelay(1);
0771 
0772     } else {        /* take phy out of reset */
0773 
0774         brcms_b_core_ioctl(wlc_hw, (SICF_PRST | SICF_FGC), SICF_FGC);
0775         udelay(1);
0776         brcms_b_core_ioctl(wlc_hw, SICF_FGC, 0);
0777         udelay(1);
0778 
0779     }
0780 }
0781 
0782 /* low-level band switch utility routine */
0783 static void brcms_c_setxband(struct brcms_hardware *wlc_hw, uint bandunit)
0784 {
0785     brcms_dbg_mac80211(wlc_hw->d11core, "wl%d: bandunit %d\n", wlc_hw->unit,
0786                bandunit);
0787 
0788     wlc_hw->band = wlc_hw->bandstate[bandunit];
0789 
0790     /*
0791      * BMAC_NOTE:
0792      *   until we eliminate need for wlc->band refs in low level code
0793      */
0794     wlc_hw->wlc->band = wlc_hw->wlc->bandstate[bandunit];
0795 
0796     /* set gmode core flag */
0797     if (wlc_hw->sbclk && !wlc_hw->noreset) {
0798         u32 gmode = 0;
0799 
0800         if (bandunit == 0)
0801             gmode = SICF_GMODE;
0802 
0803         brcms_b_core_ioctl(wlc_hw, SICF_GMODE, gmode);
0804     }
0805 }
0806 
0807 /* switch to new band but leave it inactive */
0808 static u32 brcms_c_setband_inact(struct brcms_c_info *wlc, uint bandunit)
0809 {
0810     struct brcms_hardware *wlc_hw = wlc->hw;
0811     u32 macintmask;
0812     u32 macctrl;
0813 
0814     brcms_dbg_mac80211(wlc_hw->d11core, "wl%d\n", wlc_hw->unit);
0815     macctrl = bcma_read32(wlc_hw->d11core,
0816                   D11REGOFFS(maccontrol));
0817     WARN_ON((macctrl & MCTL_EN_MAC) != 0);
0818 
0819     /* disable interrupts */
0820     macintmask = brcms_intrsoff(wlc->wl);
0821 
0822     /* radio off */
0823     wlc_phy_switch_radio(wlc_hw->band->pi, OFF);
0824 
0825     brcms_b_core_phy_clk(wlc_hw, OFF);
0826 
0827     brcms_c_setxband(wlc_hw, bandunit);
0828 
0829     return macintmask;
0830 }
0831 
0832 /* process an individual struct tx_status */
0833 static bool
0834 brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
0835 {
0836     struct sk_buff *p = NULL;
0837     uint queue = NFIFO;
0838     struct dma_pub *dma = NULL;
0839     struct d11txh *txh = NULL;
0840     struct scb *scb = NULL;
0841     int tx_frame_count;
0842     uint supr_status;
0843     bool lastframe;
0844     struct ieee80211_hdr *h;
0845     struct ieee80211_tx_info *tx_info;
0846     struct ieee80211_tx_rate *txrate;
0847     int i;
0848     bool fatal = true;
0849 
0850     trace_brcms_txstatus(&wlc->hw->d11core->dev, txs->framelen,
0851                  txs->frameid, txs->status, txs->lasttxtime,
0852                  txs->sequence, txs->phyerr, txs->ackphyrxsh);
0853 
0854     /* discard intermediate indications for ucode with one legitimate case:
0855      *   e.g. if "useRTS" is set. ucode did a successful rts/cts exchange,
0856      *   but the subsequent tx of DATA failed. so it will start rts/cts
0857      *   from the beginning (resetting the rts transmission count)
0858      */
0859     if (!(txs->status & TX_STATUS_AMPDU)
0860         && (txs->status & TX_STATUS_INTERMEDIATE)) {
0861         brcms_dbg_tx(wlc->hw->d11core, "INTERMEDIATE but not AMPDU\n");
0862         fatal = false;
0863         goto out;
0864     }
0865 
0866     queue = txs->frameid & TXFID_QUEUE_MASK;
0867     if (queue >= NFIFO) {
0868         brcms_err(wlc->hw->d11core, "queue %u >= NFIFO\n", queue);
0869         goto out;
0870     }
0871 
0872     dma = wlc->hw->di[queue];
0873 
0874     p = dma_getnexttxp(wlc->hw->di[queue], DMA_RANGE_TRANSMITTED);
0875     if (p == NULL) {
0876         brcms_err(wlc->hw->d11core, "dma_getnexttxp returned null!\n");
0877         goto out;
0878     }
0879 
0880     txh = (struct d11txh *) (p->data);
0881 
0882     if (txs->phyerr)
0883         brcms_dbg_tx(wlc->hw->d11core, "phyerr 0x%x, rate 0x%x\n",
0884                  txs->phyerr, txh->MainRates);
0885 
0886     if (txs->frameid != le16_to_cpu(txh->TxFrameID)) {
0887         brcms_err(wlc->hw->d11core, "frameid != txh->TxFrameID\n");
0888         goto out;
0889     }
0890     tx_info = IEEE80211_SKB_CB(p);
0891     h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN);
0892 
0893     if (tx_info->rate_driver_data[0])
0894         scb = &wlc->pri_scb;
0895 
0896     if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
0897         brcms_c_ampdu_dotxstatus(wlc->ampdu, scb, p, txs);
0898         fatal = false;
0899         goto out;
0900     }
0901 
0902     /*
0903      * brcms_c_ampdu_dotxstatus() will trace tx descriptors for AMPDU
0904      * frames; this traces them for the rest.
0905      */
0906     trace_brcms_txdesc(&wlc->hw->d11core->dev, txh, sizeof(*txh));
0907 
0908     supr_status = txs->status & TX_STATUS_SUPR_MASK;
0909     if (supr_status == TX_STATUS_SUPR_BADCH) {
0910         unsigned xfts = le16_to_cpu(txh->XtraFrameTypes);
0911         brcms_dbg_tx(wlc->hw->d11core,
0912                  "Pkt tx suppressed, dest chan %u, current %d\n",
0913                  (xfts >> XFTS_CHANNEL_SHIFT) & 0xff,
0914                  CHSPEC_CHANNEL(wlc->default_bss->chanspec));
0915     }
0916 
0917     tx_frame_count =
0918         (txs->status & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT;
0919 
0920     lastframe = !ieee80211_has_morefrags(h->frame_control);
0921 
0922     if (!lastframe) {
0923         brcms_err(wlc->hw->d11core, "Not last frame!\n");
0924     } else {
0925         /*
0926          * Set information to be consumed by Minstrel ht.
0927          *
0928          * The "fallback limit" is the number of tx attempts a given
0929          * MPDU is sent at the "primary" rate. Tx attempts beyond that
0930          * limit are sent at the "secondary" rate.
0931          * A 'short frame' does not exceed RTS treshold.
0932          */
0933         u16 sfbl,   /* Short Frame Rate Fallback Limit */
0934             lfbl,   /* Long Frame Rate Fallback Limit */
0935             fbl;
0936 
0937         if (queue < IEEE80211_NUM_ACS) {
0938             sfbl = GFIELD(wlc->wme_retries[wme_fifo2ac[queue]],
0939                       EDCF_SFB);
0940             lfbl = GFIELD(wlc->wme_retries[wme_fifo2ac[queue]],
0941                       EDCF_LFB);
0942         } else {
0943             sfbl = wlc->SFBL;
0944             lfbl = wlc->LFBL;
0945         }
0946 
0947         txrate = tx_info->status.rates;
0948         if (txrate[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
0949             fbl = lfbl;
0950         else
0951             fbl = sfbl;
0952 
0953         ieee80211_tx_info_clear_status(tx_info);
0954 
0955         if ((tx_frame_count > fbl) && (txrate[1].idx >= 0)) {
0956             /*
0957              * rate selection requested a fallback rate
0958              * and we used it
0959              */
0960             txrate[0].count = fbl;
0961             txrate[1].count = tx_frame_count - fbl;
0962         } else {
0963             /*
0964              * rate selection did not request fallback rate, or
0965              * we didn't need it
0966              */
0967             txrate[0].count = tx_frame_count;
0968             /*
0969              * rc80211_minstrel.c:minstrel_tx_status() expects
0970              * unused rates to be marked with idx = -1
0971              */
0972             txrate[1].idx = -1;
0973             txrate[1].count = 0;
0974         }
0975 
0976         /* clear the rest of the rates */
0977         for (i = 2; i < IEEE80211_TX_MAX_RATES; i++) {
0978             txrate[i].idx = -1;
0979             txrate[i].count = 0;
0980         }
0981 
0982         if (txs->status & TX_STATUS_ACK_RCV)
0983             tx_info->flags |= IEEE80211_TX_STAT_ACK;
0984     }
0985 
0986     if (lastframe) {
0987         /* remove PLCP & Broadcom tx descriptor header */
0988         skb_pull(p, D11_PHY_HDR_LEN);
0989         skb_pull(p, D11_TXH_LEN);
0990         ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p);
0991     } else {
0992         brcms_err(wlc->hw->d11core,
0993               "%s: Not last frame => not calling tx_status\n",
0994               __func__);
0995     }
0996 
0997     fatal = false;
0998 
0999  out:
1000     if (fatal) {
1001         if (txh)
1002             trace_brcms_txdesc(&wlc->hw->d11core->dev, txh,
1003                        sizeof(*txh));
1004         brcmu_pkt_buf_free_skb(p);
1005     }
1006 
1007     if (dma && queue < NFIFO) {
1008         u16 ac_queue = brcms_fifo_to_ac(queue);
1009         if (dma->txavail > TX_HEADROOM && queue < TX_BCMC_FIFO &&
1010             ieee80211_queue_stopped(wlc->pub->ieee_hw, ac_queue))
1011             ieee80211_wake_queue(wlc->pub->ieee_hw, ac_queue);
1012         dma_kick_tx(dma);
1013     }
1014 
1015     return fatal;
1016 }
1017 
1018 /* process tx completion events in BMAC
1019  * Return true if more tx status need to be processed. false otherwise.
1020  */
1021 static bool
1022 brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
1023 {
1024     struct bcma_device *core;
1025     struct tx_status txstatus, *txs;
1026     u32 s1, s2;
1027     uint n = 0;
1028     /*
1029      * Param 'max_tx_num' indicates max. # tx status to process before
1030      * break out.
1031      */
1032     uint max_tx_num = bound ? TXSBND : -1;
1033 
1034     txs = &txstatus;
1035     core = wlc_hw->d11core;
1036     *fatal = false;
1037 
1038     while (n < max_tx_num) {
1039         s1 = bcma_read32(core, D11REGOFFS(frmtxstatus));
1040         if (s1 == 0xffffffff) {
1041             brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit,
1042                   __func__);
1043             *fatal = true;
1044             return false;
1045         }
1046         /* only process when valid */
1047         if (!(s1 & TXS_V))
1048             break;
1049 
1050         s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2));
1051         txs->status = s1 & TXS_STATUS_MASK;
1052         txs->frameid = (s1 & TXS_FID_MASK) >> TXS_FID_SHIFT;
1053         txs->sequence = s2 & TXS_SEQ_MASK;
1054         txs->phyerr = (s2 & TXS_PTX_MASK) >> TXS_PTX_SHIFT;
1055         txs->lasttxtime = 0;
1056 
1057         *fatal = brcms_c_dotxstatus(wlc_hw->wlc, txs);
1058         if (*fatal)
1059             return false;
1060         n++;
1061     }
1062 
1063     return n >= max_tx_num;
1064 }
1065 
1066 static void brcms_c_tbtt(struct brcms_c_info *wlc)
1067 {
1068     if (wlc->bsscfg->type == BRCMS_TYPE_ADHOC)
1069         /*
1070          * DirFrmQ is now valid...defer setting until end
1071          * of ATIM window
1072          */
1073         wlc->qvalid |= MCMD_DIRFRMQVAL;
1074 }
1075 
1076 /* set initial host flags value */
1077 static void
1078 brcms_c_mhfdef(struct brcms_c_info *wlc, u16 *mhfs, u16 mhf2_init)
1079 {
1080     struct brcms_hardware *wlc_hw = wlc->hw;
1081 
1082     memset(mhfs, 0, MHFMAX * sizeof(u16));
1083 
1084     mhfs[MHF2] |= mhf2_init;
1085 
1086     /* prohibit use of slowclock on multifunction boards */
1087     if (wlc_hw->boardflags & BFL_NOPLLDOWN)
1088         mhfs[MHF1] |= MHF1_FORCEFASTCLK;
1089 
1090     if (BRCMS_ISNPHY(wlc_hw->band) && NREV_LT(wlc_hw->band->phyrev, 2)) {
1091         mhfs[MHF2] |= MHF2_NPHY40MHZ_WAR;
1092         mhfs[MHF1] |= MHF1_IQSWAP_WAR;
1093     }
1094 }
1095 
1096 static uint
1097 dmareg(uint direction, uint fifonum)
1098 {
1099     if (direction == DMA_TX)
1100         return offsetof(struct d11regs, fifo64regs[fifonum].dmaxmt);
1101     return offsetof(struct d11regs, fifo64regs[fifonum].dmarcv);
1102 }
1103 
1104 static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme)
1105 {
1106     uint i;
1107     char name[8];
1108     /*
1109      * ucode host flag 2 needed for pio mode, independent of band and fifo
1110      */
1111     u16 pio_mhf2 = 0;
1112     struct brcms_hardware *wlc_hw = wlc->hw;
1113     uint unit = wlc_hw->unit;
1114 
1115     /* name and offsets for dma_attach */
1116     snprintf(name, sizeof(name), "wl%d", unit);
1117 
1118     if (wlc_hw->di[0] == NULL) {    /* Init FIFOs */
1119         int dma_attach_err = 0;
1120 
1121         /*
1122          * FIFO 0
1123          * TX: TX_AC_BK_FIFO (TX AC Background data packets)
1124          * RX: RX_FIFO (RX data packets)
1125          */
1126         wlc_hw->di[0] = dma_attach(name, wlc,
1127                        (wme ? dmareg(DMA_TX, 0) : 0),
1128                        dmareg(DMA_RX, 0),
1129                        (wme ? NTXD : 0), NRXD,
1130                        RXBUFSZ, -1, NRXBUFPOST,
1131                        BRCMS_HWRXOFF);
1132         dma_attach_err |= (NULL == wlc_hw->di[0]);
1133 
1134         /*
1135          * FIFO 1
1136          * TX: TX_AC_BE_FIFO (TX AC Best-Effort data packets)
1137          *   (legacy) TX_DATA_FIFO (TX data packets)
1138          * RX: UNUSED
1139          */
1140         wlc_hw->di[1] = dma_attach(name, wlc,
1141                        dmareg(DMA_TX, 1), 0,
1142                        NTXD, 0, 0, -1, 0, 0);
1143         dma_attach_err |= (NULL == wlc_hw->di[1]);
1144 
1145         /*
1146          * FIFO 2
1147          * TX: TX_AC_VI_FIFO (TX AC Video data packets)
1148          * RX: UNUSED
1149          */
1150         wlc_hw->di[2] = dma_attach(name, wlc,
1151                        dmareg(DMA_TX, 2), 0,
1152                        NTXD, 0, 0, -1, 0, 0);
1153         dma_attach_err |= (NULL == wlc_hw->di[2]);
1154         /*
1155          * FIFO 3
1156          * TX: TX_AC_VO_FIFO (TX AC Voice data packets)
1157          *   (legacy) TX_CTL_FIFO (TX control & mgmt packets)
1158          */
1159         wlc_hw->di[3] = dma_attach(name, wlc,
1160                        dmareg(DMA_TX, 3),
1161                        0, NTXD, 0, 0, -1,
1162                        0, 0);
1163         dma_attach_err |= (NULL == wlc_hw->di[3]);
1164 /* Cleaner to leave this as if with AP defined */
1165 
1166         if (dma_attach_err) {
1167             brcms_err(wlc_hw->d11core,
1168                   "wl%d: wlc_attach: dma_attach failed\n",
1169                   unit);
1170             return false;
1171         }
1172 
1173         /* get pointer to dma engine tx flow control variable */
1174         for (i = 0; i < NFIFO; i++)
1175             if (wlc_hw->di[i])
1176                 wlc_hw->txavail[i] =
1177                     (uint *) dma_getvar(wlc_hw->di[i],
1178                             "&txavail");
1179     }
1180 
1181     /* initial ucode host flags */
1182     brcms_c_mhfdef(wlc, wlc_hw->band->mhfs, pio_mhf2);
1183 
1184     return true;
1185 }
1186 
1187 static void brcms_b_detach_dmapio(struct brcms_hardware *wlc_hw)
1188 {
1189     uint j;
1190 
1191     for (j = 0; j < NFIFO; j++) {
1192         if (wlc_hw->di[j]) {
1193             dma_detach(wlc_hw->di[j]);
1194             wlc_hw->di[j] = NULL;
1195         }
1196     }
1197 }
1198 
1199 /*
1200  * Initialize brcms_c_info default values ...
1201  * may get overrides later in this function
1202  *  BMAC_NOTES, move low out and resolve the dangling ones
1203  */
1204 static void brcms_b_info_init(struct brcms_hardware *wlc_hw)
1205 {
1206     struct brcms_c_info *wlc = wlc_hw->wlc;
1207 
1208     /* set default sw macintmask value */
1209     wlc->defmacintmask = DEF_MACINTMASK;
1210 
1211     /* various 802.11g modes */
1212     wlc_hw->shortslot = false;
1213 
1214     wlc_hw->SFBL = RETRY_SHORT_FB;
1215     wlc_hw->LFBL = RETRY_LONG_FB;
1216 
1217     /* default mac retry limits */
1218     wlc_hw->SRL = RETRY_SHORT_DEF;
1219     wlc_hw->LRL = RETRY_LONG_DEF;
1220     wlc_hw->chanspec = ch20mhz_chspec(1);
1221 }
1222 
1223 static void brcms_b_wait_for_wake(struct brcms_hardware *wlc_hw)
1224 {
1225     /* delay before first read of ucode state */
1226     udelay(40);
1227 
1228     /* wait until ucode is no longer asleep */
1229     SPINWAIT((brcms_b_read_shm(wlc_hw, M_UCODE_DBGST) ==
1230           DBGST_ASLEEP), wlc_hw->wlc->fastpwrup_dly);
1231 }
1232 
1233 /* control chip clock to save power, enable dynamic clock or force fast clock */
1234 static void brcms_b_clkctl_clk(struct brcms_hardware *wlc_hw, enum bcma_clkmode mode)
1235 {
1236     if (ai_get_cccaps(wlc_hw->sih) & CC_CAP_PMU) {
1237         /* new chips with PMU, CCS_FORCEHT will distribute the HT clock
1238          * on backplane, but mac core will still run on ALP(not HT) when
1239          * it enters powersave mode, which means the FCA bit may not be
1240          * set. Should wakeup mac if driver wants it to run on HT.
1241          */
1242 
1243         if (wlc_hw->clk) {
1244             if (mode == BCMA_CLKMODE_FAST) {
1245                 bcma_set32(wlc_hw->d11core,
1246                        D11REGOFFS(clk_ctl_st),
1247                        CCS_FORCEHT);
1248 
1249                 udelay(64);
1250 
1251                 SPINWAIT(
1252                     ((bcma_read32(wlc_hw->d11core,
1253                       D11REGOFFS(clk_ctl_st)) &
1254                       CCS_HTAVAIL) == 0),
1255                       PMU_MAX_TRANSITION_DLY);
1256                 WARN_ON(!(bcma_read32(wlc_hw->d11core,
1257                     D11REGOFFS(clk_ctl_st)) &
1258                     CCS_HTAVAIL));
1259             } else {
1260                 if ((ai_get_pmurev(wlc_hw->sih) == 0) &&
1261                     (bcma_read32(wlc_hw->d11core,
1262                     D11REGOFFS(clk_ctl_st)) &
1263                     (CCS_FORCEHT | CCS_HTAREQ)))
1264                     SPINWAIT(
1265                         ((bcma_read32(wlc_hw->d11core,
1266                           offsetof(struct d11regs,
1267                                clk_ctl_st)) &
1268                           CCS_HTAVAIL) == 0),
1269                           PMU_MAX_TRANSITION_DLY);
1270                 bcma_mask32(wlc_hw->d11core,
1271                     D11REGOFFS(clk_ctl_st),
1272                     ~CCS_FORCEHT);
1273             }
1274         }
1275         wlc_hw->forcefastclk = (mode == BCMA_CLKMODE_FAST);
1276     } else {
1277 
1278         /* old chips w/o PMU, force HT through cc,
1279          * then use FCA to verify mac is running fast clock
1280          */
1281 
1282         wlc_hw->forcefastclk = ai_clkctl_cc(wlc_hw->sih, mode);
1283 
1284         /* check fast clock is available (if core is not in reset) */
1285         if (wlc_hw->forcefastclk && wlc_hw->clk)
1286             WARN_ON(!(bcma_aread32(wlc_hw->d11core, BCMA_IOST) &
1287                   SISF_FCLKA));
1288 
1289         /*
1290          * keep the ucode wake bit on if forcefastclk is on since we
1291          * do not want ucode to put us back to slow clock when it dozes
1292          * for PM mode. Code below matches the wake override bit with
1293          * current forcefastclk state. Only setting bit in wake_override
1294          * instead of waking ucode immediately since old code had this
1295          * behavior. Older code set wlc->forcefastclk but only had the
1296          * wake happen if the wakup_ucode work (protected by an up
1297          * check) was executed just below.
1298          */
1299         if (wlc_hw->forcefastclk)
1300             mboolset(wlc_hw->wake_override,
1301                  BRCMS_WAKE_OVERRIDE_FORCEFAST);
1302         else
1303             mboolclr(wlc_hw->wake_override,
1304                  BRCMS_WAKE_OVERRIDE_FORCEFAST);
1305     }
1306 }
1307 
1308 /* set or clear ucode host flag bits
1309  * it has an optimization for no-change write
1310  * it only writes through shared memory when the core has clock;
1311  * pre-CLK changes should use wlc_write_mhf to get around the optimization
1312  *
1313  *
1314  * bands values are: BRCM_BAND_AUTO <--- Current band only
1315  *                   BRCM_BAND_5G   <--- 5G band only
1316  *                   BRCM_BAND_2G   <--- 2G band only
1317  *                   BRCM_BAND_ALL  <--- All bands
1318  */
1319 void
1320 brcms_b_mhf(struct brcms_hardware *wlc_hw, u8 idx, u16 mask, u16 val,
1321          int bands)
1322 {
1323     u16 save;
1324     u16 addr[MHFMAX] = {
1325         M_HOST_FLAGS1, M_HOST_FLAGS2, M_HOST_FLAGS3, M_HOST_FLAGS4,
1326         M_HOST_FLAGS5
1327     };
1328     struct brcms_hw_band *band;
1329 
1330     if ((val & ~mask) || idx >= MHFMAX)
1331         return; /* error condition */
1332 
1333     switch (bands) {
1334         /* Current band only or all bands,
1335          * then set the band to current band
1336          */
1337     case BRCM_BAND_AUTO:
1338     case BRCM_BAND_ALL:
1339         band = wlc_hw->band;
1340         break;
1341     case BRCM_BAND_5G:
1342         band = wlc_hw->bandstate[BAND_5G_INDEX];
1343         break;
1344     case BRCM_BAND_2G:
1345         band = wlc_hw->bandstate[BAND_2G_INDEX];
1346         break;
1347     default:
1348         band = NULL;    /* error condition */
1349     }
1350 
1351     if (band) {
1352         save = band->mhfs[idx];
1353         band->mhfs[idx] = (band->mhfs[idx] & ~mask) | val;
1354 
1355         /* optimization: only write through if changed, and
1356          * changed band is the current band
1357          */
1358         if (wlc_hw->clk && (band->mhfs[idx] != save)
1359             && (band == wlc_hw->band))
1360             brcms_b_write_shm(wlc_hw, addr[idx],
1361                        (u16) band->mhfs[idx]);
1362     }
1363 
1364     if (bands == BRCM_BAND_ALL) {
1365         wlc_hw->bandstate[0]->mhfs[idx] =
1366             (wlc_hw->bandstate[0]->mhfs[idx] & ~mask) | val;
1367         wlc_hw->bandstate[1]->mhfs[idx] =
1368             (wlc_hw->bandstate[1]->mhfs[idx] & ~mask) | val;
1369     }
1370 }
1371 
1372 /* set the maccontrol register to desired reset state and
1373  * initialize the sw cache of the register
1374  */
1375 static void brcms_c_mctrl_reset(struct brcms_hardware *wlc_hw)
1376 {
1377     /* IHR accesses are always enabled, PSM disabled, HPS off and WAKE on */
1378     wlc_hw->maccontrol = 0;
1379     wlc_hw->suspended_fifos = 0;
1380     wlc_hw->wake_override = 0;
1381     wlc_hw->mute_override = 0;
1382     brcms_b_mctrl(wlc_hw, ~0, MCTL_IHR_EN | MCTL_WAKE);
1383 }
1384 
1385 /*
1386  * write the software state of maccontrol and
1387  * overrides to the maccontrol register
1388  */
1389 static void brcms_c_mctrl_write(struct brcms_hardware *wlc_hw)
1390 {
1391     u32 maccontrol = wlc_hw->maccontrol;
1392 
1393     /* OR in the wake bit if overridden */
1394     if (wlc_hw->wake_override)
1395         maccontrol |= MCTL_WAKE;
1396 
1397     /* set AP and INFRA bits for mute if needed */
1398     if (wlc_hw->mute_override) {
1399         maccontrol &= ~(MCTL_AP);
1400         maccontrol |= MCTL_INFRA;
1401     }
1402 
1403     bcma_write32(wlc_hw->d11core, D11REGOFFS(maccontrol),
1404              maccontrol);
1405 }
1406 
1407 /* set or clear maccontrol bits */
1408 void brcms_b_mctrl(struct brcms_hardware *wlc_hw, u32 mask, u32 val)
1409 {
1410     u32 maccontrol;
1411     u32 new_maccontrol;
1412 
1413     if (val & ~mask)
1414         return; /* error condition */
1415     maccontrol = wlc_hw->maccontrol;
1416     new_maccontrol = (maccontrol & ~mask) | val;
1417 
1418     /* if the new maccontrol value is the same as the old, nothing to do */
1419     if (new_maccontrol == maccontrol)
1420         return;
1421 
1422     /* something changed, cache the new value */
1423     wlc_hw->maccontrol = new_maccontrol;
1424 
1425     /* write the new values with overrides applied */
1426     brcms_c_mctrl_write(wlc_hw);
1427 }
1428 
1429 void brcms_c_ucode_wake_override_set(struct brcms_hardware *wlc_hw,
1430                  u32 override_bit)
1431 {
1432     if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE)) {
1433         mboolset(wlc_hw->wake_override, override_bit);
1434         return;
1435     }
1436 
1437     mboolset(wlc_hw->wake_override, override_bit);
1438 
1439     brcms_c_mctrl_write(wlc_hw);
1440     brcms_b_wait_for_wake(wlc_hw);
1441 }
1442 
1443 void brcms_c_ucode_wake_override_clear(struct brcms_hardware *wlc_hw,
1444                    u32 override_bit)
1445 {
1446     mboolclr(wlc_hw->wake_override, override_bit);
1447 
1448     if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE))
1449         return;
1450 
1451     brcms_c_mctrl_write(wlc_hw);
1452 }
1453 
1454 /* When driver needs ucode to stop beaconing, it has to make sure that
1455  * MCTL_AP is clear and MCTL_INFRA is set
1456  * Mode           MCTL_AP        MCTL_INFRA
1457  * AP                1              1
1458  * STA               0              1 <--- This will ensure no beacons
1459  * IBSS              0              0
1460  */
1461 static void brcms_c_ucode_mute_override_set(struct brcms_hardware *wlc_hw)
1462 {
1463     wlc_hw->mute_override = 1;
1464 
1465     /* if maccontrol already has AP == 0 and INFRA == 1 without this
1466      * override, then there is no change to write
1467      */
1468     if ((wlc_hw->maccontrol & (MCTL_AP | MCTL_INFRA)) == MCTL_INFRA)
1469         return;
1470 
1471     brcms_c_mctrl_write(wlc_hw);
1472 }
1473 
1474 /* Clear the override on AP and INFRA bits */
1475 static void brcms_c_ucode_mute_override_clear(struct brcms_hardware *wlc_hw)
1476 {
1477     if (wlc_hw->mute_override == 0)
1478         return;
1479 
1480     wlc_hw->mute_override = 0;
1481 
1482     /* if maccontrol already has AP == 0 and INFRA == 1 without this
1483      * override, then there is no change to write
1484      */
1485     if ((wlc_hw->maccontrol & (MCTL_AP | MCTL_INFRA)) == MCTL_INFRA)
1486         return;
1487 
1488     brcms_c_mctrl_write(wlc_hw);
1489 }
1490 
1491 /*
1492  * Write a MAC address to the given match reg offset in the RXE match engine.
1493  */
1494 static void
1495 brcms_b_set_addrmatch(struct brcms_hardware *wlc_hw, int match_reg_offset,
1496                const u8 *addr)
1497 {
1498     struct bcma_device *core = wlc_hw->d11core;
1499     u16 mac_l;
1500     u16 mac_m;
1501     u16 mac_h;
1502 
1503     brcms_dbg_rx(core, "wl%d: brcms_b_set_addrmatch\n", wlc_hw->unit);
1504 
1505     mac_l = addr[0] | (addr[1] << 8);
1506     mac_m = addr[2] | (addr[3] << 8);
1507     mac_h = addr[4] | (addr[5] << 8);
1508 
1509     /* enter the MAC addr into the RXE match registers */
1510     bcma_write16(core, D11REGOFFS(rcm_ctl),
1511              RCM_INC_DATA | match_reg_offset);
1512     bcma_write16(core, D11REGOFFS(rcm_mat_data), mac_l);
1513     bcma_write16(core, D11REGOFFS(rcm_mat_data), mac_m);
1514     bcma_write16(core, D11REGOFFS(rcm_mat_data), mac_h);
1515 }
1516 
1517 void
1518 brcms_b_write_template_ram(struct brcms_hardware *wlc_hw, int offset, int len,
1519                 void *buf)
1520 {
1521     struct bcma_device *core = wlc_hw->d11core;
1522     u32 word;
1523     __le32 word_le;
1524     __be32 word_be;
1525     bool be_bit;
1526     brcms_dbg_info(core, "wl%d\n", wlc_hw->unit);
1527 
1528     bcma_write32(core, D11REGOFFS(tplatewrptr), offset);
1529 
1530     /* if MCTL_BIGEND bit set in mac control register,
1531      * the chip swaps data in fifo, as well as data in
1532      * template ram
1533      */
1534     be_bit = (bcma_read32(core, D11REGOFFS(maccontrol)) & MCTL_BIGEND) != 0;
1535 
1536     while (len > 0) {
1537         memcpy(&word, buf, sizeof(u32));
1538 
1539         if (be_bit) {
1540             word_be = cpu_to_be32(word);
1541             word = *(u32 *)&word_be;
1542         } else {
1543             word_le = cpu_to_le32(word);
1544             word = *(u32 *)&word_le;
1545         }
1546 
1547         bcma_write32(core, D11REGOFFS(tplatewrdata), word);
1548 
1549         buf = (u8 *) buf + sizeof(u32);
1550         len -= sizeof(u32);
1551     }
1552 }
1553 
1554 static void brcms_b_set_cwmin(struct brcms_hardware *wlc_hw, u16 newmin)
1555 {
1556     wlc_hw->band->CWmin = newmin;
1557 
1558     bcma_write32(wlc_hw->d11core, D11REGOFFS(objaddr),
1559              OBJADDR_SCR_SEL | S_DOT11_CWMIN);
1560     (void)bcma_read32(wlc_hw->d11core, D11REGOFFS(objaddr));
1561     bcma_write32(wlc_hw->d11core, D11REGOFFS(objdata), newmin);
1562 }
1563 
1564 static void brcms_b_set_cwmax(struct brcms_hardware *wlc_hw, u16 newmax)
1565 {
1566     wlc_hw->band->CWmax = newmax;
1567 
1568     bcma_write32(wlc_hw->d11core, D11REGOFFS(objaddr),
1569              OBJADDR_SCR_SEL | S_DOT11_CWMAX);
1570     (void)bcma_read32(wlc_hw->d11core, D11REGOFFS(objaddr));
1571     bcma_write32(wlc_hw->d11core, D11REGOFFS(objdata), newmax);
1572 }
1573 
1574 void brcms_b_bw_set(struct brcms_hardware *wlc_hw, u16 bw)
1575 {
1576     bool fastclk;
1577 
1578     /* request FAST clock if not on */
1579     fastclk = wlc_hw->forcefastclk;
1580     if (!fastclk)
1581         brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
1582 
1583     wlc_phy_bw_state_set(wlc_hw->band->pi, bw);
1584 
1585     brcms_b_phy_reset(wlc_hw);
1586     wlc_phy_init(wlc_hw->band->pi, wlc_phy_chanspec_get(wlc_hw->band->pi));
1587 
1588     /* restore the clk */
1589     if (!fastclk)
1590         brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_DYNAMIC);
1591 }
1592 
1593 static void brcms_b_upd_synthpu(struct brcms_hardware *wlc_hw)
1594 {
1595     u16 v;
1596     struct brcms_c_info *wlc = wlc_hw->wlc;
1597     /* update SYNTHPU_DLY */
1598 
1599     if (BRCMS_ISLCNPHY(wlc->band))
1600         v = SYNTHPU_DLY_LPPHY_US;
1601     else if (BRCMS_ISNPHY(wlc->band) && (NREV_GE(wlc->band->phyrev, 3)))
1602         v = SYNTHPU_DLY_NPHY_US;
1603     else
1604         v = SYNTHPU_DLY_BPHY_US;
1605 
1606     brcms_b_write_shm(wlc_hw, M_SYNTHPU_DLY, v);
1607 }
1608 
1609 static void brcms_c_ucode_txant_set(struct brcms_hardware *wlc_hw)
1610 {
1611     u16 phyctl;
1612     u16 phytxant = wlc_hw->bmac_phytxant;
1613     u16 mask = PHY_TXC_ANT_MASK;
1614 
1615     /* set the Probe Response frame phy control word */
1616     phyctl = brcms_b_read_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS);
1617     phyctl = (phyctl & ~mask) | phytxant;
1618     brcms_b_write_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS, phyctl);
1619 
1620     /* set the Response (ACK/CTS) frame phy control word */
1621     phyctl = brcms_b_read_shm(wlc_hw, M_RSP_PCTLWD);
1622     phyctl = (phyctl & ~mask) | phytxant;
1623     brcms_b_write_shm(wlc_hw, M_RSP_PCTLWD, phyctl);
1624 }
1625 
1626 static u16 brcms_b_ofdm_ratetable_offset(struct brcms_hardware *wlc_hw,
1627                      u8 rate)
1628 {
1629     uint i;
1630     u8 plcp_rate = 0;
1631     struct plcp_signal_rate_lookup {
1632         u8 rate;
1633         u8 signal_rate;
1634     };
1635     /* OFDM RATE sub-field of PLCP SIGNAL field, per 802.11 sec 17.3.4.1 */
1636     const struct plcp_signal_rate_lookup rate_lookup[] = {
1637         {BRCM_RATE_6M, 0xB},
1638         {BRCM_RATE_9M, 0xF},
1639         {BRCM_RATE_12M, 0xA},
1640         {BRCM_RATE_18M, 0xE},
1641         {BRCM_RATE_24M, 0x9},
1642         {BRCM_RATE_36M, 0xD},
1643         {BRCM_RATE_48M, 0x8},
1644         {BRCM_RATE_54M, 0xC}
1645     };
1646 
1647     for (i = 0; i < ARRAY_SIZE(rate_lookup); i++) {
1648         if (rate == rate_lookup[i].rate) {
1649             plcp_rate = rate_lookup[i].signal_rate;
1650             break;
1651         }
1652     }
1653 
1654     /* Find the SHM pointer to the rate table entry by looking in the
1655      * Direct-map Table
1656      */
1657     return 2 * brcms_b_read_shm(wlc_hw, M_RT_DIRMAP_A + (plcp_rate * 2));
1658 }
1659 
1660 static void brcms_upd_ofdm_pctl1_table(struct brcms_hardware *wlc_hw)
1661 {
1662     u8 rate;
1663     u8 rates[8] = {
1664         BRCM_RATE_6M, BRCM_RATE_9M, BRCM_RATE_12M, BRCM_RATE_18M,
1665         BRCM_RATE_24M, BRCM_RATE_36M, BRCM_RATE_48M, BRCM_RATE_54M
1666     };
1667     u16 entry_ptr;
1668     u16 pctl1;
1669     uint i;
1670 
1671     if (!BRCMS_PHY_11N_CAP(wlc_hw->band))
1672         return;
1673 
1674     /* walk the phy rate table and update the entries */
1675     for (i = 0; i < ARRAY_SIZE(rates); i++) {
1676         rate = rates[i];
1677 
1678         entry_ptr = brcms_b_ofdm_ratetable_offset(wlc_hw, rate);
1679 
1680         /* read the SHM Rate Table entry OFDM PCTL1 values */
1681         pctl1 =
1682             brcms_b_read_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS);
1683 
1684         /* modify the value */
1685         pctl1 &= ~PHY_TXC1_MODE_MASK;
1686         pctl1 |= (wlc_hw->hw_stf_ss_opmode << PHY_TXC1_MODE_SHIFT);
1687 
1688         /* Update the SHM Rate Table entry OFDM PCTL1 values */
1689         brcms_b_write_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS,
1690                    pctl1);
1691     }
1692 }
1693 
1694 /* band-specific init */
1695 static void brcms_b_bsinit(struct brcms_c_info *wlc, u16 chanspec)
1696 {
1697     struct brcms_hardware *wlc_hw = wlc->hw;
1698 
1699     brcms_dbg_mac80211(wlc_hw->d11core, "wl%d: bandunit %d\n", wlc_hw->unit,
1700                wlc_hw->band->bandunit);
1701 
1702     brcms_c_ucode_bsinit(wlc_hw);
1703 
1704     wlc_phy_init(wlc_hw->band->pi, chanspec);
1705 
1706     brcms_c_ucode_txant_set(wlc_hw);
1707 
1708     /*
1709      * cwmin is band-specific, update hardware
1710      * with value for current band
1711      */
1712     brcms_b_set_cwmin(wlc_hw, wlc_hw->band->CWmin);
1713     brcms_b_set_cwmax(wlc_hw, wlc_hw->band->CWmax);
1714 
1715     brcms_b_update_slot_timing(wlc_hw,
1716                    wlc_hw->band->bandtype == BRCM_BAND_5G ?
1717                    true : wlc_hw->shortslot);
1718 
1719     /* write phytype and phyvers */
1720     brcms_b_write_shm(wlc_hw, M_PHYTYPE, (u16) wlc_hw->band->phytype);
1721     brcms_b_write_shm(wlc_hw, M_PHYVER, (u16) wlc_hw->band->phyrev);
1722 
1723     /*
1724      * initialize the txphyctl1 rate table since
1725      * shmem is shared between bands
1726      */
1727     brcms_upd_ofdm_pctl1_table(wlc_hw);
1728 
1729     brcms_b_upd_synthpu(wlc_hw);
1730 }
1731 
1732 /* Perform a soft reset of the PHY PLL */
1733 void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw)
1734 {
1735     ai_cc_reg(wlc_hw->sih, offsetof(struct chipcregs, chipcontrol_addr),
1736           ~0, 0);
1737     udelay(1);
1738     ai_cc_reg(wlc_hw->sih, offsetof(struct chipcregs, chipcontrol_data),
1739           0x4, 0);
1740     udelay(1);
1741     ai_cc_reg(wlc_hw->sih, offsetof(struct chipcregs, chipcontrol_data),
1742           0x4, 4);
1743     udelay(1);
1744     ai_cc_reg(wlc_hw->sih, offsetof(struct chipcregs, chipcontrol_data),
1745           0x4, 0);
1746     udelay(1);
1747 }
1748 
1749 /* light way to turn on phy clock without reset for NPHY only
1750  *  refer to brcms_b_core_phy_clk for full version
1751  */
1752 void brcms_b_phyclk_fgc(struct brcms_hardware *wlc_hw, bool clk)
1753 {
1754     /* support(necessary for NPHY and HYPHY) only */
1755     if (!BRCMS_ISNPHY(wlc_hw->band))
1756         return;
1757 
1758     if (ON == clk)
1759         brcms_b_core_ioctl(wlc_hw, SICF_FGC, SICF_FGC);
1760     else
1761         brcms_b_core_ioctl(wlc_hw, SICF_FGC, 0);
1762 
1763 }
1764 
1765 void brcms_b_macphyclk_set(struct brcms_hardware *wlc_hw, bool clk)
1766 {
1767     if (ON == clk)
1768         brcms_b_core_ioctl(wlc_hw, SICF_MPCLKE, SICF_MPCLKE);
1769     else
1770         brcms_b_core_ioctl(wlc_hw, SICF_MPCLKE, 0);
1771 }
1772 
1773 void brcms_b_phy_reset(struct brcms_hardware *wlc_hw)
1774 {
1775     struct brcms_phy_pub *pih = wlc_hw->band->pi;
1776     u32 phy_bw_clkbits;
1777 
1778     brcms_dbg_info(wlc_hw->d11core, "wl%d: reset phy\n", wlc_hw->unit);
1779 
1780     if (pih == NULL)
1781         return;
1782 
1783     phy_bw_clkbits = wlc_phy_clk_bwbits(wlc_hw->band->pi);
1784 
1785     /* Specific reset sequence required for NPHY rev 3 and 4 */
1786     if (BRCMS_ISNPHY(wlc_hw->band) && NREV_GE(wlc_hw->band->phyrev, 3) &&
1787         NREV_LE(wlc_hw->band->phyrev, 4)) {
1788         /* Set the PHY bandwidth */
1789         brcms_b_core_ioctl(wlc_hw, SICF_BWMASK, phy_bw_clkbits);
1790 
1791         udelay(1);
1792 
1793         /* Perform a soft reset of the PHY PLL */
1794         brcms_b_core_phypll_reset(wlc_hw);
1795 
1796         /* reset the PHY */
1797         brcms_b_core_ioctl(wlc_hw, (SICF_PRST | SICF_PCLKE),
1798                    (SICF_PRST | SICF_PCLKE));
1799     } else {
1800         brcms_b_core_ioctl(wlc_hw,
1801                    (SICF_PRST | SICF_PCLKE | SICF_BWMASK),
1802                    (SICF_PRST | SICF_PCLKE | phy_bw_clkbits));
1803     }
1804 
1805     udelay(2);
1806     brcms_b_core_phy_clk(wlc_hw, ON);
1807 
1808     wlc_phy_anacore(pih, ON);
1809 }
1810 
1811 /* switch to and initialize new band */
1812 static void brcms_b_setband(struct brcms_hardware *wlc_hw, uint bandunit,
1813                 u16 chanspec) {
1814     struct brcms_c_info *wlc = wlc_hw->wlc;
1815     u32 macintmask;
1816 
1817     /* Enable the d11 core before accessing it */
1818     if (!bcma_core_is_enabled(wlc_hw->d11core)) {
1819         bcma_core_enable(wlc_hw->d11core, 0);
1820         brcms_c_mctrl_reset(wlc_hw);
1821     }
1822 
1823     macintmask = brcms_c_setband_inact(wlc, bandunit);
1824 
1825     if (!wlc_hw->up)
1826         return;
1827 
1828     brcms_b_core_phy_clk(wlc_hw, ON);
1829 
1830     /* band-specific initializations */
1831     brcms_b_bsinit(wlc, chanspec);
1832 
1833     /*
1834      * If there are any pending software interrupt bits,
1835      * then replace these with a harmless nonzero value
1836      * so brcms_c_dpc() will re-enable interrupts when done.
1837      */
1838     if (wlc->macintstatus)
1839         wlc->macintstatus = MI_DMAINT;
1840 
1841     /* restore macintmask */
1842     brcms_intrsrestore(wlc->wl, macintmask);
1843 
1844     /* ucode should still be suspended.. */
1845     WARN_ON((bcma_read32(wlc_hw->d11core, D11REGOFFS(maccontrol)) &
1846          MCTL_EN_MAC) != 0);
1847 }
1848 
1849 static bool brcms_c_isgoodchip(struct brcms_hardware *wlc_hw)
1850 {
1851 
1852     /* reject unsupported corerev */
1853     if (!CONF_HAS(D11CONF, wlc_hw->corerev)) {
1854         wiphy_err(wlc_hw->wlc->wiphy, "unsupported core rev %d\n",
1855               wlc_hw->corerev);
1856         return false;
1857     }
1858 
1859     return true;
1860 }
1861 
1862 /* Validate some board info parameters */
1863 static bool brcms_c_validboardtype(struct brcms_hardware *wlc_hw)
1864 {
1865     uint boardrev = wlc_hw->boardrev;
1866 
1867     /* 4 bits each for board type, major, minor, and tiny version */
1868     uint brt = (boardrev & 0xf000) >> 12;
1869     uint b0 = (boardrev & 0xf00) >> 8;
1870     uint b1 = (boardrev & 0xf0) >> 4;
1871     uint b2 = boardrev & 0xf;
1872 
1873     /* voards from other vendors are always considered valid */
1874     if (ai_get_boardvendor(wlc_hw->sih) != PCI_VENDOR_ID_BROADCOM)
1875         return true;
1876 
1877     /* do some boardrev sanity checks when boardvendor is Broadcom */
1878     if (boardrev == 0)
1879         return false;
1880 
1881     if (boardrev <= 0xff)
1882         return true;
1883 
1884     if ((brt > 2) || (brt == 0) || (b0 > 9) || (b0 == 0) || (b1 > 9)
1885         || (b2 > 9))
1886         return false;
1887 
1888     return true;
1889 }
1890 
1891 static void brcms_c_get_macaddr(struct brcms_hardware *wlc_hw, u8 etheraddr[ETH_ALEN])
1892 {
1893     struct ssb_sprom *sprom = &wlc_hw->d11core->bus->sprom;
1894 
1895     /* If macaddr exists, use it (Sromrev4, CIS, ...). */
1896     if (!is_zero_ether_addr(sprom->il0mac)) {
1897         memcpy(etheraddr, sprom->il0mac, ETH_ALEN);
1898         return;
1899     }
1900 
1901     if (wlc_hw->_nbands > 1)
1902         memcpy(etheraddr, sprom->et1mac, ETH_ALEN);
1903     else
1904         memcpy(etheraddr, sprom->il0mac, ETH_ALEN);
1905 }
1906 
1907 /* power both the pll and external oscillator on/off */
1908 static void brcms_b_xtal(struct brcms_hardware *wlc_hw, bool want)
1909 {
1910     brcms_dbg_info(wlc_hw->d11core, "wl%d: want %d\n", wlc_hw->unit, want);
1911 
1912     /*
1913      * dont power down if plldown is false or
1914      * we must poll hw radio disable
1915      */
1916     if (!want && wlc_hw->pllreq)
1917         return;
1918 
1919     wlc_hw->sbclk = want;
1920     if (!wlc_hw->sbclk) {
1921         wlc_hw->clk = false;
1922         if (wlc_hw->band && wlc_hw->band->pi)
1923             wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false);
1924     }
1925 }
1926 
1927 /*
1928  * Return true if radio is disabled, otherwise false.
1929  * hw radio disable signal is an external pin, users activate it asynchronously
1930  * this function could be called when driver is down and w/o clock
1931  * it operates on different registers depending on corerev and boardflag.
1932  */
1933 static bool brcms_b_radio_read_hwdisabled(struct brcms_hardware *wlc_hw)
1934 {
1935     bool v, clk, xtal;
1936     u32 flags = 0;
1937 
1938     xtal = wlc_hw->sbclk;
1939     if (!xtal)
1940         brcms_b_xtal(wlc_hw, ON);
1941 
1942     /* may need to take core out of reset first */
1943     clk = wlc_hw->clk;
1944     if (!clk) {
1945         /*
1946          * mac no longer enables phyclk automatically when driver
1947          * accesses phyreg throughput mac. This can be skipped since
1948          * only mac reg is accessed below
1949          */
1950         if (D11REV_GE(wlc_hw->corerev, 18))
1951             flags |= SICF_PCLKE;
1952 
1953         /*
1954          * TODO: test suspend/resume
1955          *
1956          * AI chip doesn't restore bar0win2 on
1957          * hibernation/resume, need sw fixup
1958          */
1959 
1960         bcma_core_enable(wlc_hw->d11core, flags);
1961         brcms_c_mctrl_reset(wlc_hw);
1962     }
1963 
1964     v = ((bcma_read32(wlc_hw->d11core,
1965               D11REGOFFS(phydebug)) & PDBG_RFD) != 0);
1966 
1967     /* put core back into reset */
1968     if (!clk)
1969         bcma_core_disable(wlc_hw->d11core, 0);
1970 
1971     if (!xtal)
1972         brcms_b_xtal(wlc_hw, OFF);
1973 
1974     return v;
1975 }
1976 
1977 static bool wlc_dma_rxreset(struct brcms_hardware *wlc_hw, uint fifo)
1978 {
1979     struct dma_pub *di = wlc_hw->di[fifo];
1980     return dma_rxreset(di);
1981 }
1982 
1983 /* d11 core reset
1984  *   ensure fask clock during reset
1985  *   reset dma
1986  *   reset d11(out of reset)
1987  *   reset phy(out of reset)
1988  *   clear software macintstatus for fresh new start
1989  * one testing hack wlc_hw->noreset will bypass the d11/phy reset
1990  */
1991 void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags)
1992 {
1993     uint i;
1994     bool fastclk;
1995 
1996     if (flags == BRCMS_USE_COREFLAGS)
1997         flags = (wlc_hw->band->pi ? wlc_hw->band->core_flags : 0);
1998 
1999     brcms_dbg_info(wlc_hw->d11core, "wl%d: core reset\n", wlc_hw->unit);
2000 
2001     /* request FAST clock if not on  */
2002     fastclk = wlc_hw->forcefastclk;
2003     if (!fastclk)
2004         brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
2005 
2006     /* reset the dma engines except first time thru */
2007     if (bcma_core_is_enabled(wlc_hw->d11core)) {
2008         for (i = 0; i < NFIFO; i++)
2009             if ((wlc_hw->di[i]) && (!dma_txreset(wlc_hw->di[i])))
2010                 brcms_err(wlc_hw->d11core, "wl%d: %s: "
2011                       "dma_txreset[%d]: cannot stop dma\n",
2012                        wlc_hw->unit, __func__, i);
2013 
2014         if ((wlc_hw->di[RX_FIFO])
2015             && (!wlc_dma_rxreset(wlc_hw, RX_FIFO)))
2016             brcms_err(wlc_hw->d11core, "wl%d: %s: dma_rxreset"
2017                   "[%d]: cannot stop dma\n",
2018                   wlc_hw->unit, __func__, RX_FIFO);
2019     }
2020     /* if noreset, just stop the psm and return */
2021     if (wlc_hw->noreset) {
2022         wlc_hw->wlc->macintstatus = 0;  /* skip wl_dpc after down */
2023         brcms_b_mctrl(wlc_hw, MCTL_PSM_RUN | MCTL_EN_MAC, 0);
2024         return;
2025     }
2026 
2027     /*
2028      * mac no longer enables phyclk automatically when driver accesses
2029      * phyreg throughput mac, AND phy_reset is skipped at early stage when
2030      * band->pi is invalid. need to enable PHY CLK
2031      */
2032     if (D11REV_GE(wlc_hw->corerev, 18))
2033         flags |= SICF_PCLKE;
2034 
2035     /*
2036      * reset the core
2037      * In chips with PMU, the fastclk request goes through d11 core
2038      * reg 0x1e0, which is cleared by the core_reset. have to re-request it.
2039      *
2040      * This adds some delay and we can optimize it by also requesting
2041      * fastclk through chipcommon during this period if necessary. But
2042      * that has to work coordinate with other driver like mips/arm since
2043      * they may touch chipcommon as well.
2044      */
2045     wlc_hw->clk = false;
2046     bcma_core_enable(wlc_hw->d11core, flags);
2047     wlc_hw->clk = true;
2048     if (wlc_hw->band && wlc_hw->band->pi)
2049         wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, true);
2050 
2051     brcms_c_mctrl_reset(wlc_hw);
2052 
2053     if (ai_get_cccaps(wlc_hw->sih) & CC_CAP_PMU)
2054         brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
2055 
2056     brcms_b_phy_reset(wlc_hw);
2057 
2058     /* turn on PHY_PLL */
2059     brcms_b_core_phypll_ctl(wlc_hw, true);
2060 
2061     /* clear sw intstatus */
2062     wlc_hw->wlc->macintstatus = 0;
2063 
2064     /* restore the clk setting */
2065     if (!fastclk)
2066         brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_DYNAMIC);
2067 }
2068 
2069 /* txfifo sizes needs to be modified(increased) since the newer cores
2070  * have more memory.
2071  */
2072 static void brcms_b_corerev_fifofixup(struct brcms_hardware *wlc_hw)
2073 {
2074     struct bcma_device *core = wlc_hw->d11core;
2075     u16 fifo_nu;
2076     u16 txfifo_startblk = TXFIFO_START_BLK, txfifo_endblk;
2077     u16 txfifo_def, txfifo_def1;
2078     u16 txfifo_cmd;
2079 
2080     /* tx fifos start at TXFIFO_START_BLK from the Base address */
2081     txfifo_startblk = TXFIFO_START_BLK;
2082 
2083     /* sequence of operations:  reset fifo, set fifo size, reset fifo */
2084     for (fifo_nu = 0; fifo_nu < NFIFO; fifo_nu++) {
2085 
2086         txfifo_endblk = txfifo_startblk + wlc_hw->xmtfifo_sz[fifo_nu];
2087         txfifo_def = (txfifo_startblk & 0xff) |
2088             (((txfifo_endblk - 1) & 0xff) << TXFIFO_FIFOTOP_SHIFT);
2089         txfifo_def1 = ((txfifo_startblk >> 8) & 0x1) |
2090             ((((txfifo_endblk -
2091             1) >> 8) & 0x1) << TXFIFO_FIFOTOP_SHIFT);
2092         txfifo_cmd =
2093             TXFIFOCMD_RESET_MASK | (fifo_nu << TXFIFOCMD_FIFOSEL_SHIFT);
2094 
2095         bcma_write16(core, D11REGOFFS(xmtfifocmd), txfifo_cmd);
2096         bcma_write16(core, D11REGOFFS(xmtfifodef), txfifo_def);
2097         bcma_write16(core, D11REGOFFS(xmtfifodef1), txfifo_def1);
2098 
2099         bcma_write16(core, D11REGOFFS(xmtfifocmd), txfifo_cmd);
2100 
2101         txfifo_startblk += wlc_hw->xmtfifo_sz[fifo_nu];
2102     }
2103     /*
2104      * need to propagate to shm location to be in sync since ucode/hw won't
2105      * do this
2106      */
2107     brcms_b_write_shm(wlc_hw, M_FIFOSIZE0,
2108                wlc_hw->xmtfifo_sz[TX_AC_BE_FIFO]);
2109     brcms_b_write_shm(wlc_hw, M_FIFOSIZE1,
2110                wlc_hw->xmtfifo_sz[TX_AC_VI_FIFO]);
2111     brcms_b_write_shm(wlc_hw, M_FIFOSIZE2,
2112                ((wlc_hw->xmtfifo_sz[TX_AC_VO_FIFO] << 8) | wlc_hw->
2113                 xmtfifo_sz[TX_AC_BK_FIFO]));
2114     brcms_b_write_shm(wlc_hw, M_FIFOSIZE3,
2115                ((wlc_hw->xmtfifo_sz[TX_ATIM_FIFO] << 8) | wlc_hw->
2116                 xmtfifo_sz[TX_BCMC_FIFO]));
2117 }
2118 
2119 /* This function is used for changing the tsf frac register
2120  * If spur avoidance mode is off, the mac freq will be 80/120/160Mhz
2121  * If spur avoidance mode is on1, the mac freq will be 82/123/164Mhz
2122  * If spur avoidance mode is on2, the mac freq will be 84/126/168Mhz
2123  * HTPHY Formula is 2^26/freq(MHz) e.g.
2124  * For spuron2 - 126MHz -> 2^26/126 = 532610.0
2125  *  - 532610 = 0x82082 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x2082
2126  * For spuron: 123MHz -> 2^26/123    = 545600.5
2127  *  - 545601 = 0x85341 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x5341
2128  * For spur off: 120MHz -> 2^26/120    = 559240.5
2129  *  - 559241 = 0x88889 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x8889
2130  */
2131 
2132 void brcms_b_switch_macfreq(struct brcms_hardware *wlc_hw, u8 spurmode)
2133 {
2134     struct bcma_device *core = wlc_hw->d11core;
2135 
2136     if ((ai_get_chip_id(wlc_hw->sih) == BCMA_CHIP_ID_BCM43224) ||
2137         (ai_get_chip_id(wlc_hw->sih) == BCMA_CHIP_ID_BCM43225)) {
2138         if (spurmode == WL_SPURAVOID_ON2) { /* 126Mhz */
2139             bcma_write16(core, D11REGOFFS(tsf_clk_frac_l), 0x2082);
2140             bcma_write16(core, D11REGOFFS(tsf_clk_frac_h), 0x8);
2141         } else if (spurmode == WL_SPURAVOID_ON1) {  /* 123Mhz */
2142             bcma_write16(core, D11REGOFFS(tsf_clk_frac_l), 0x5341);
2143             bcma_write16(core, D11REGOFFS(tsf_clk_frac_h), 0x8);
2144         } else {    /* 120Mhz */
2145             bcma_write16(core, D11REGOFFS(tsf_clk_frac_l), 0x8889);
2146             bcma_write16(core, D11REGOFFS(tsf_clk_frac_h), 0x8);
2147         }
2148     } else if (BRCMS_ISLCNPHY(wlc_hw->band)) {
2149         if (spurmode == WL_SPURAVOID_ON1) { /* 82Mhz */
2150             bcma_write16(core, D11REGOFFS(tsf_clk_frac_l), 0x7CE0);
2151             bcma_write16(core, D11REGOFFS(tsf_clk_frac_h), 0xC);
2152         } else {    /* 80Mhz */
2153             bcma_write16(core, D11REGOFFS(tsf_clk_frac_l), 0xCCCD);
2154             bcma_write16(core, D11REGOFFS(tsf_clk_frac_h), 0xC);
2155         }
2156     }
2157 }
2158 
2159 void brcms_c_start_station(struct brcms_c_info *wlc, u8 *addr)
2160 {
2161     memcpy(wlc->pub->cur_etheraddr, addr, sizeof(wlc->pub->cur_etheraddr));
2162     wlc->bsscfg->type = BRCMS_TYPE_STATION;
2163 }
2164 
2165 void brcms_c_start_ap(struct brcms_c_info *wlc, u8 *addr, const u8 *bssid,
2166               u8 *ssid, size_t ssid_len)
2167 {
2168     brcms_c_set_ssid(wlc, ssid, ssid_len);
2169 
2170     memcpy(wlc->pub->cur_etheraddr, addr, sizeof(wlc->pub->cur_etheraddr));
2171     memcpy(wlc->bsscfg->BSSID, bssid, sizeof(wlc->bsscfg->BSSID));
2172     wlc->bsscfg->type = BRCMS_TYPE_AP;
2173 
2174     brcms_b_mctrl(wlc->hw, MCTL_AP | MCTL_INFRA, MCTL_AP | MCTL_INFRA);
2175 }
2176 
2177 void brcms_c_start_adhoc(struct brcms_c_info *wlc, u8 *addr)
2178 {
2179     memcpy(wlc->pub->cur_etheraddr, addr, sizeof(wlc->pub->cur_etheraddr));
2180     wlc->bsscfg->type = BRCMS_TYPE_ADHOC;
2181 
2182     brcms_b_mctrl(wlc->hw, MCTL_AP | MCTL_INFRA, 0);
2183 }
2184 
2185 /* Initialize GPIOs that are controlled by D11 core */
2186 static void brcms_c_gpio_init(struct brcms_c_info *wlc)
2187 {
2188     struct brcms_hardware *wlc_hw = wlc->hw;
2189     u32 gc, gm;
2190 
2191     /* use GPIO select 0 to get all gpio signals from the gpio out reg */
2192     brcms_b_mctrl(wlc_hw, MCTL_GPOUT_SEL_MASK, 0);
2193 
2194     /*
2195      * Common GPIO setup:
2196      *      G0 = LED 0 = WLAN Activity
2197      *      G1 = LED 1 = WLAN 2.4 GHz Radio State
2198      *      G2 = LED 2 = WLAN 5 GHz Radio State
2199      *      G4 = radio disable input (HI enabled, LO disabled)
2200      */
2201 
2202     gc = gm = 0;
2203 
2204     /* Allocate GPIOs for mimo antenna diversity feature */
2205     if (wlc_hw->antsel_type == ANTSEL_2x3) {
2206         /* Enable antenna diversity, use 2x3 mode */
2207         brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN,
2208                  MHF3_ANTSEL_EN, BRCM_BAND_ALL);
2209         brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE,
2210                  MHF3_ANTSEL_MODE, BRCM_BAND_ALL);
2211 
2212         /* init superswitch control */
2213         wlc_phy_antsel_init(wlc_hw->band->pi, false);
2214 
2215     } else if (wlc_hw->antsel_type == ANTSEL_2x4) {
2216         gm |= gc |= (BOARD_GPIO_12 | BOARD_GPIO_13);
2217         /*
2218          * The board itself is powered by these GPIOs
2219          * (when not sending pattern) so set them high
2220          */
2221         bcma_set16(wlc_hw->d11core, D11REGOFFS(psm_gpio_oe),
2222                (BOARD_GPIO_12 | BOARD_GPIO_13));
2223         bcma_set16(wlc_hw->d11core, D11REGOFFS(psm_gpio_out),
2224                (BOARD_GPIO_12 | BOARD_GPIO_13));
2225 
2226         /* Enable antenna diversity, use 2x4 mode */
2227         brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN,
2228                  MHF3_ANTSEL_EN, BRCM_BAND_ALL);
2229         brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE, 0,
2230                  BRCM_BAND_ALL);
2231 
2232         /* Configure the desired clock to be 4Mhz */
2233         brcms_b_write_shm(wlc_hw, M_ANTSEL_CLKDIV,
2234                    ANTSEL_CLKDIV_4MHZ);
2235     }
2236 
2237     /*
2238      * gpio 9 controls the PA. ucode is responsible
2239      * for wiggling out and oe
2240      */
2241     if (wlc_hw->boardflags & BFL_PACTRL)
2242         gm |= gc |= BOARD_GPIO_PACTRL;
2243 
2244     /* apply to gpiocontrol register */
2245     bcma_chipco_gpio_control(&wlc_hw->d11core->bus->drv_cc, gm, gc);
2246 }
2247 
2248 static void brcms_ucode_write(struct brcms_hardware *wlc_hw,
2249                   const __le32 ucode[], const size_t nbytes)
2250 {
2251     struct bcma_device *core = wlc_hw->d11core;
2252     uint i;
2253     uint count;
2254 
2255     brcms_dbg_info(wlc_hw->d11core, "wl%d\n", wlc_hw->unit);
2256 
2257     count = (nbytes / sizeof(u32));
2258 
2259     bcma_write32(core, D11REGOFFS(objaddr),
2260              OBJADDR_AUTO_INC | OBJADDR_UCM_SEL);
2261     (void)bcma_read32(core, D11REGOFFS(objaddr));
2262     for (i = 0; i < count; i++)
2263         bcma_write32(core, D11REGOFFS(objdata), le32_to_cpu(ucode[i]));
2264 
2265 }
2266 
2267 static void brcms_ucode_download(struct brcms_hardware *wlc_hw)
2268 {
2269     struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode;
2270 
2271     if (wlc_hw->ucode_loaded)
2272         return;
2273 
2274     if (D11REV_IS(wlc_hw->corerev, 17) || D11REV_IS(wlc_hw->corerev, 23)) {
2275         if (BRCMS_ISNPHY(wlc_hw->band)) {
2276             brcms_ucode_write(wlc_hw, ucode->bcm43xx_16_mimo,
2277                       ucode->bcm43xx_16_mimosz);
2278             wlc_hw->ucode_loaded = true;
2279         } else
2280             brcms_err(wlc_hw->d11core,
2281                   "%s: wl%d: unsupported phy in corerev %d\n",
2282                   __func__, wlc_hw->unit, wlc_hw->corerev);
2283     } else if (D11REV_IS(wlc_hw->corerev, 24)) {
2284         if (BRCMS_ISLCNPHY(wlc_hw->band)) {
2285             brcms_ucode_write(wlc_hw, ucode->bcm43xx_24_lcn,
2286                       ucode->bcm43xx_24_lcnsz);
2287             wlc_hw->ucode_loaded = true;
2288         } else {
2289             brcms_err(wlc_hw->d11core,
2290                   "%s: wl%d: unsupported phy in corerev %d\n",
2291                   __func__, wlc_hw->unit, wlc_hw->corerev);
2292         }
2293     }
2294 }
2295 
2296 void brcms_b_txant_set(struct brcms_hardware *wlc_hw, u16 phytxant)
2297 {
2298     /* update sw state */
2299     wlc_hw->bmac_phytxant = phytxant;
2300 
2301     /* push to ucode if up */
2302     if (!wlc_hw->up)
2303         return;
2304     brcms_c_ucode_txant_set(wlc_hw);
2305 
2306 }
2307 
2308 u16 brcms_b_get_txant(struct brcms_hardware *wlc_hw)
2309 {
2310     return (u16) wlc_hw->wlc->stf->txant;
2311 }
2312 
2313 void brcms_b_antsel_type_set(struct brcms_hardware *wlc_hw, u8 antsel_type)
2314 {
2315     wlc_hw->antsel_type = antsel_type;
2316 
2317     /* Update the antsel type for phy module to use */
2318     wlc_phy_antsel_type_set(wlc_hw->band->pi, antsel_type);
2319 }
2320 
2321 static void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw)
2322 {
2323     bool fatal = false;
2324     uint unit;
2325     uint intstatus, idx;
2326     struct bcma_device *core = wlc_hw->d11core;
2327 
2328     unit = wlc_hw->unit;
2329 
2330     for (idx = 0; idx < NFIFO; idx++) {
2331         /* read intstatus register and ignore any non-error bits */
2332         intstatus =
2333             bcma_read32(core,
2334                     D11REGOFFS(intctrlregs[idx].intstatus)) &
2335             I_ERRORS;
2336         if (!intstatus)
2337             continue;
2338 
2339         brcms_dbg_int(core, "wl%d: intstatus%d 0x%x\n",
2340                   unit, idx, intstatus);
2341 
2342         if (intstatus & I_RO) {
2343             brcms_err(core, "wl%d: fifo %d: receive fifo "
2344                   "overflow\n", unit, idx);
2345             fatal = true;
2346         }
2347 
2348         if (intstatus & I_PC) {
2349             brcms_err(core, "wl%d: fifo %d: descriptor error\n",
2350                   unit, idx);
2351             fatal = true;
2352         }
2353 
2354         if (intstatus & I_PD) {
2355             brcms_err(core, "wl%d: fifo %d: data error\n", unit,
2356                   idx);
2357             fatal = true;
2358         }
2359 
2360         if (intstatus & I_DE) {
2361             brcms_err(core, "wl%d: fifo %d: descriptor protocol "
2362                   "error\n", unit, idx);
2363             fatal = true;
2364         }
2365 
2366         if (intstatus & I_RU)
2367             brcms_err(core, "wl%d: fifo %d: receive descriptor "
2368                   "underflow\n", idx, unit);
2369 
2370         if (intstatus & I_XU) {
2371             brcms_err(core, "wl%d: fifo %d: transmit fifo "
2372                   "underflow\n", idx, unit);
2373             fatal = true;
2374         }
2375 
2376         if (fatal) {
2377             brcms_fatal_error(wlc_hw->wlc->wl); /* big hammer */
2378             break;
2379         } else
2380             bcma_write32(core,
2381                      D11REGOFFS(intctrlregs[idx].intstatus),
2382                      intstatus);
2383     }
2384 }
2385 
2386 void brcms_c_intrson(struct brcms_c_info *wlc)
2387 {
2388     struct brcms_hardware *wlc_hw = wlc->hw;
2389     wlc->macintmask = wlc->defmacintmask;
2390     bcma_write32(wlc_hw->d11core, D11REGOFFS(macintmask), wlc->macintmask);
2391 }
2392 
2393 u32 brcms_c_intrsoff(struct brcms_c_info *wlc)
2394 {
2395     struct brcms_hardware *wlc_hw = wlc->hw;
2396     u32 macintmask;
2397 
2398     if (!wlc_hw->clk)
2399         return 0;
2400 
2401     macintmask = wlc->macintmask;   /* isr can still happen */
2402 
2403     bcma_write32(wlc_hw->d11core, D11REGOFFS(macintmask), 0);
2404     (void)bcma_read32(wlc_hw->d11core, D11REGOFFS(macintmask));
2405     udelay(1);      /* ensure int line is no longer driven */
2406     wlc->macintmask = 0;
2407 
2408     /* return previous macintmask; resolve race between us and our isr */
2409     return wlc->macintstatus ? 0 : macintmask;
2410 }
2411 
2412 void brcms_c_intrsrestore(struct brcms_c_info *wlc, u32 macintmask)
2413 {
2414     struct brcms_hardware *wlc_hw = wlc->hw;
2415     if (!wlc_hw->clk)
2416         return;
2417 
2418     wlc->macintmask = macintmask;
2419     bcma_write32(wlc_hw->d11core, D11REGOFFS(macintmask), wlc->macintmask);
2420 }
2421 
2422 /* assumes that the d11 MAC is enabled */
2423 static void brcms_b_tx_fifo_suspend(struct brcms_hardware *wlc_hw,
2424                     uint tx_fifo)
2425 {
2426     u8 fifo = 1 << tx_fifo;
2427 
2428     /* Two clients of this code, 11h Quiet period and scanning. */
2429 
2430     /* only suspend if not already suspended */
2431     if ((wlc_hw->suspended_fifos & fifo) == fifo)
2432         return;
2433 
2434     /* force the core awake only if not already */
2435     if (wlc_hw->suspended_fifos == 0)
2436         brcms_c_ucode_wake_override_set(wlc_hw,
2437                         BRCMS_WAKE_OVERRIDE_TXFIFO);
2438 
2439     wlc_hw->suspended_fifos |= fifo;
2440 
2441     if (wlc_hw->di[tx_fifo]) {
2442         /*
2443          * Suspending AMPDU transmissions in the middle can cause
2444          * underflow which may result in mismatch between ucode and
2445          * driver so suspend the mac before suspending the FIFO
2446          */
2447         if (BRCMS_PHY_11N_CAP(wlc_hw->band))
2448             brcms_c_suspend_mac_and_wait(wlc_hw->wlc);
2449 
2450         dma_txsuspend(wlc_hw->di[tx_fifo]);
2451 
2452         if (BRCMS_PHY_11N_CAP(wlc_hw->band))
2453             brcms_c_enable_mac(wlc_hw->wlc);
2454     }
2455 }
2456 
2457 static void brcms_b_tx_fifo_resume(struct brcms_hardware *wlc_hw,
2458                    uint tx_fifo)
2459 {
2460     /* BMAC_NOTE: BRCMS_TX_FIFO_ENAB is done in brcms_c_dpc() for DMA case
2461      * but need to be done here for PIO otherwise the watchdog will catch
2462      * the inconsistency and fire
2463      */
2464     /* Two clients of this code, 11h Quiet period and scanning. */
2465     if (wlc_hw->di[tx_fifo])
2466         dma_txresume(wlc_hw->di[tx_fifo]);
2467 
2468     /* allow core to sleep again */
2469     if (wlc_hw->suspended_fifos == 0)
2470         return;
2471     else {
2472         wlc_hw->suspended_fifos &= ~(1 << tx_fifo);
2473         if (wlc_hw->suspended_fifos == 0)
2474             brcms_c_ucode_wake_override_clear(wlc_hw,
2475                         BRCMS_WAKE_OVERRIDE_TXFIFO);
2476     }
2477 }
2478 
2479 /* precondition: requires the mac core to be enabled */
2480 static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool mute_tx)
2481 {
2482     static const u8 null_ether_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
2483     u8 *ethaddr = wlc_hw->wlc->pub->cur_etheraddr;
2484 
2485     if (mute_tx) {
2486         /* suspend tx fifos */
2487         brcms_b_tx_fifo_suspend(wlc_hw, TX_DATA_FIFO);
2488         brcms_b_tx_fifo_suspend(wlc_hw, TX_CTL_FIFO);
2489         brcms_b_tx_fifo_suspend(wlc_hw, TX_AC_BK_FIFO);
2490         brcms_b_tx_fifo_suspend(wlc_hw, TX_AC_VI_FIFO);
2491 
2492         /* zero the address match register so we do not send ACKs */
2493         brcms_b_set_addrmatch(wlc_hw, RCM_MAC_OFFSET, null_ether_addr);
2494     } else {
2495         /* resume tx fifos */
2496         brcms_b_tx_fifo_resume(wlc_hw, TX_DATA_FIFO);
2497         brcms_b_tx_fifo_resume(wlc_hw, TX_CTL_FIFO);
2498         brcms_b_tx_fifo_resume(wlc_hw, TX_AC_BK_FIFO);
2499         brcms_b_tx_fifo_resume(wlc_hw, TX_AC_VI_FIFO);
2500 
2501         /* Restore address */
2502         brcms_b_set_addrmatch(wlc_hw, RCM_MAC_OFFSET, ethaddr);
2503     }
2504 
2505     wlc_phy_mute_upd(wlc_hw->band->pi, mute_tx, 0);
2506 
2507     if (mute_tx)
2508         brcms_c_ucode_mute_override_set(wlc_hw);
2509     else
2510         brcms_c_ucode_mute_override_clear(wlc_hw);
2511 }
2512 
2513 void
2514 brcms_c_mute(struct brcms_c_info *wlc, bool mute_tx)
2515 {
2516     brcms_b_mute(wlc->hw, mute_tx);
2517 }
2518 
2519 /*
2520  * Read and clear macintmask and macintstatus and intstatus registers.
2521  * This routine should be called with interrupts off
2522  * Return:
2523  *   -1 if brcms_deviceremoved(wlc) evaluates to true;
2524  *   0 if the interrupt is not for us, or we are in some special cases;
2525  *   device interrupt status bits otherwise.
2526  */
2527 static inline u32 wlc_intstatus(struct brcms_c_info *wlc, bool in_isr)
2528 {
2529     struct brcms_hardware *wlc_hw = wlc->hw;
2530     struct bcma_device *core = wlc_hw->d11core;
2531     u32 macintstatus, mask;
2532 
2533     /* macintstatus includes a DMA interrupt summary bit */
2534     macintstatus = bcma_read32(core, D11REGOFFS(macintstatus));
2535     mask = in_isr ? wlc->macintmask : wlc->defmacintmask;
2536 
2537     trace_brcms_macintstatus(&core->dev, in_isr, macintstatus, mask);
2538 
2539     /* detect cardbus removed, in power down(suspend) and in reset */
2540     if (brcms_deviceremoved(wlc))
2541         return -1;
2542 
2543     /* brcms_deviceremoved() succeeds even when the core is still resetting,
2544      * handle that case here.
2545      */
2546     if (macintstatus == 0xffffffff)
2547         return 0;
2548 
2549     /* defer unsolicited interrupts */
2550     macintstatus &= mask;
2551 
2552     /* if not for us */
2553     if (macintstatus == 0)
2554         return 0;
2555 
2556     /* turn off the interrupts */
2557     bcma_write32(core, D11REGOFFS(macintmask), 0);
2558     (void)bcma_read32(core, D11REGOFFS(macintmask));
2559     wlc->macintmask = 0;
2560 
2561     /* clear device interrupts */
2562     bcma_write32(core, D11REGOFFS(macintstatus), macintstatus);
2563 
2564     /* MI_DMAINT is indication of non-zero intstatus */
2565     if (macintstatus & MI_DMAINT)
2566         /*
2567          * only fifo interrupt enabled is I_RI in
2568          * RX_FIFO. If MI_DMAINT is set, assume it
2569          * is set and clear the interrupt.
2570          */
2571         bcma_write32(core, D11REGOFFS(intctrlregs[RX_FIFO].intstatus),
2572                  DEF_RXINTMASK);
2573 
2574     return macintstatus;
2575 }
2576 
2577 /* Update wlc->macintstatus and wlc->intstatus[]. */
2578 /* Return true if they are updated successfully. false otherwise */
2579 bool brcms_c_intrsupd(struct brcms_c_info *wlc)
2580 {
2581     u32 macintstatus;
2582 
2583     /* read and clear macintstatus and intstatus registers */
2584     macintstatus = wlc_intstatus(wlc, false);
2585 
2586     /* device is removed */
2587     if (macintstatus == 0xffffffff)
2588         return false;
2589 
2590     /* update interrupt status in software */
2591     wlc->macintstatus |= macintstatus;
2592 
2593     return true;
2594 }
2595 
2596 /*
2597  * First-level interrupt processing.
2598  * Return true if this was our interrupt
2599  * and if further brcms_c_dpc() processing is required,
2600  * false otherwise.
2601  */
2602 bool brcms_c_isr(struct brcms_c_info *wlc)
2603 {
2604     struct brcms_hardware *wlc_hw = wlc->hw;
2605     u32 macintstatus;
2606 
2607     if (!wlc_hw->up || !wlc->macintmask)
2608         return false;
2609 
2610     /* read and clear macintstatus and intstatus registers */
2611     macintstatus = wlc_intstatus(wlc, true);
2612 
2613     if (macintstatus == 0xffffffff) {
2614         brcms_err(wlc_hw->d11core,
2615               "DEVICEREMOVED detected in the ISR code path\n");
2616         return false;
2617     }
2618 
2619     /* it is not for us */
2620     if (macintstatus == 0)
2621         return false;
2622 
2623     /* save interrupt status bits */
2624     wlc->macintstatus = macintstatus;
2625 
2626     return true;
2627 
2628 }
2629 
2630 void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc)
2631 {
2632     struct brcms_hardware *wlc_hw = wlc->hw;
2633     struct bcma_device *core = wlc_hw->d11core;
2634     u32 mc, mi;
2635 
2636     brcms_dbg_mac80211(core, "wl%d: bandunit %d\n", wlc_hw->unit,
2637                wlc_hw->band->bandunit);
2638 
2639     /*
2640      * Track overlapping suspend requests
2641      */
2642     wlc_hw->mac_suspend_depth++;
2643     if (wlc_hw->mac_suspend_depth > 1)
2644         return;
2645 
2646     /* force the core awake */
2647     brcms_c_ucode_wake_override_set(wlc_hw, BRCMS_WAKE_OVERRIDE_MACSUSPEND);
2648 
2649     mc = bcma_read32(core, D11REGOFFS(maccontrol));
2650 
2651     if (mc == 0xffffffff) {
2652         brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit,
2653               __func__);
2654         brcms_down(wlc->wl);
2655         return;
2656     }
2657     WARN_ON(mc & MCTL_PSM_JMP_0);
2658     WARN_ON(!(mc & MCTL_PSM_RUN));
2659     WARN_ON(!(mc & MCTL_EN_MAC));
2660 
2661     mi = bcma_read32(core, D11REGOFFS(macintstatus));
2662     if (mi == 0xffffffff) {
2663         brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit,
2664               __func__);
2665         brcms_down(wlc->wl);
2666         return;
2667     }
2668     WARN_ON(mi & MI_MACSSPNDD);
2669 
2670     brcms_b_mctrl(wlc_hw, MCTL_EN_MAC, 0);
2671 
2672     SPINWAIT(!(bcma_read32(core, D11REGOFFS(macintstatus)) & MI_MACSSPNDD),
2673          BRCMS_MAX_MAC_SUSPEND);
2674 
2675     if (!(bcma_read32(core, D11REGOFFS(macintstatus)) & MI_MACSSPNDD)) {
2676         brcms_err(core, "wl%d: wlc_suspend_mac_and_wait: waited %d uS"
2677               " and MI_MACSSPNDD is still not on.\n",
2678               wlc_hw->unit, BRCMS_MAX_MAC_SUSPEND);
2679         brcms_err(core, "wl%d: psmdebug 0x%08x, phydebug 0x%08x, "
2680               "psm_brc 0x%04x\n", wlc_hw->unit,
2681               bcma_read32(core, D11REGOFFS(psmdebug)),
2682               bcma_read32(core, D11REGOFFS(phydebug)),
2683               bcma_read16(core, D11REGOFFS(psm_brc)));
2684     }
2685 
2686     mc = bcma_read32(core, D11REGOFFS(maccontrol));
2687     if (mc == 0xffffffff) {
2688         brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit,
2689               __func__);
2690         brcms_down(wlc->wl);
2691         return;
2692     }
2693     WARN_ON(mc & MCTL_PSM_JMP_0);
2694     WARN_ON(!(mc & MCTL_PSM_RUN));
2695     WARN_ON(mc & MCTL_EN_MAC);
2696 }
2697 
2698 void brcms_c_enable_mac(struct brcms_c_info *wlc)
2699 {
2700     struct brcms_hardware *wlc_hw = wlc->hw;
2701     struct bcma_device *core = wlc_hw->d11core;
2702     u32 mc, mi;
2703 
2704     brcms_dbg_mac80211(core, "wl%d: bandunit %d\n", wlc_hw->unit,
2705                wlc->band->bandunit);
2706 
2707     /*
2708      * Track overlapping suspend requests
2709      */
2710     wlc_hw->mac_suspend_depth--;
2711     if (wlc_hw->mac_suspend_depth > 0)
2712         return;
2713 
2714     mc = bcma_read32(core, D11REGOFFS(maccontrol));
2715     WARN_ON(mc & MCTL_PSM_JMP_0);
2716     WARN_ON(mc & MCTL_EN_MAC);
2717     WARN_ON(!(mc & MCTL_PSM_RUN));
2718 
2719     brcms_b_mctrl(wlc_hw, MCTL_EN_MAC, MCTL_EN_MAC);
2720     bcma_write32(core, D11REGOFFS(macintstatus), MI_MACSSPNDD);
2721 
2722     mc = bcma_read32(core, D11REGOFFS(maccontrol));
2723     WARN_ON(mc & MCTL_PSM_JMP_0);
2724     WARN_ON(!(mc & MCTL_EN_MAC));
2725     WARN_ON(!(mc & MCTL_PSM_RUN));
2726 
2727     mi = bcma_read32(core, D11REGOFFS(macintstatus));
2728     WARN_ON(mi & MI_MACSSPNDD);
2729 
2730     brcms_c_ucode_wake_override_clear(wlc_hw,
2731                       BRCMS_WAKE_OVERRIDE_MACSUSPEND);
2732 }
2733 
2734 void brcms_b_band_stf_ss_set(struct brcms_hardware *wlc_hw, u8 stf_mode)
2735 {
2736     wlc_hw->hw_stf_ss_opmode = stf_mode;
2737 
2738     if (wlc_hw->clk)
2739         brcms_upd_ofdm_pctl1_table(wlc_hw);
2740 }
2741 
2742 static bool brcms_b_validate_chip_access(struct brcms_hardware *wlc_hw)
2743 {
2744     struct bcma_device *core = wlc_hw->d11core;
2745     u32 w, val;
2746     struct wiphy *wiphy = wlc_hw->wlc->wiphy;
2747 
2748     /* Validate dchip register access */
2749 
2750     bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0);
2751     (void)bcma_read32(core, D11REGOFFS(objaddr));
2752     w = bcma_read32(core, D11REGOFFS(objdata));
2753 
2754     /* Can we write and read back a 32bit register? */
2755     bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0);
2756     (void)bcma_read32(core, D11REGOFFS(objaddr));
2757     bcma_write32(core, D11REGOFFS(objdata), (u32) 0xaa5555aa);
2758 
2759     bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0);
2760     (void)bcma_read32(core, D11REGOFFS(objaddr));
2761     val = bcma_read32(core, D11REGOFFS(objdata));
2762     if (val != (u32) 0xaa5555aa) {
2763         wiphy_err(wiphy, "wl%d: validate_chip_access: SHM = 0x%x, "
2764               "expected 0xaa5555aa\n", wlc_hw->unit, val);
2765         return false;
2766     }
2767 
2768     bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0);
2769     (void)bcma_read32(core, D11REGOFFS(objaddr));
2770     bcma_write32(core, D11REGOFFS(objdata), (u32) 0x55aaaa55);
2771 
2772     bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0);
2773     (void)bcma_read32(core, D11REGOFFS(objaddr));
2774     val = bcma_read32(core, D11REGOFFS(objdata));
2775     if (val != (u32) 0x55aaaa55) {
2776         wiphy_err(wiphy, "wl%d: validate_chip_access: SHM = 0x%x, "
2777               "expected 0x55aaaa55\n", wlc_hw->unit, val);
2778         return false;
2779     }
2780 
2781     bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0);
2782     (void)bcma_read32(core, D11REGOFFS(objaddr));
2783     bcma_write32(core, D11REGOFFS(objdata), w);
2784 
2785     /* clear CFPStart */
2786     bcma_write32(core, D11REGOFFS(tsf_cfpstart), 0);
2787 
2788     w = bcma_read32(core, D11REGOFFS(maccontrol));
2789     if ((w != (MCTL_IHR_EN | MCTL_WAKE)) &&
2790         (w != (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE))) {
2791         wiphy_err(wiphy, "wl%d: validate_chip_access: maccontrol = "
2792               "0x%x, expected 0x%x or 0x%x\n", wlc_hw->unit, w,
2793               (MCTL_IHR_EN | MCTL_WAKE),
2794               (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE));
2795         return false;
2796     }
2797 
2798     return true;
2799 }
2800 
2801 #define PHYPLL_WAIT_US  100000
2802 
2803 void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on)
2804 {
2805     struct bcma_device *core = wlc_hw->d11core;
2806     u32 tmp;
2807 
2808     brcms_dbg_info(core, "wl%d\n", wlc_hw->unit);
2809 
2810     tmp = 0;
2811 
2812     if (on) {
2813         if ((ai_get_chip_id(wlc_hw->sih) == BCMA_CHIP_ID_BCM4313)) {
2814             bcma_set32(core, D11REGOFFS(clk_ctl_st),
2815                    CCS_ERSRC_REQ_HT |
2816                    CCS_ERSRC_REQ_D11PLL |
2817                    CCS_ERSRC_REQ_PHYPLL);
2818             SPINWAIT((bcma_read32(core, D11REGOFFS(clk_ctl_st)) &
2819                   CCS_ERSRC_AVAIL_HT) != CCS_ERSRC_AVAIL_HT,
2820                  PHYPLL_WAIT_US);
2821 
2822             tmp = bcma_read32(core, D11REGOFFS(clk_ctl_st));
2823             if ((tmp & CCS_ERSRC_AVAIL_HT) != CCS_ERSRC_AVAIL_HT)
2824                 brcms_err(core, "%s: turn on PHY PLL failed\n",
2825                       __func__);
2826         } else {
2827             bcma_set32(core, D11REGOFFS(clk_ctl_st),
2828                    tmp | CCS_ERSRC_REQ_D11PLL |
2829                    CCS_ERSRC_REQ_PHYPLL);
2830             SPINWAIT((bcma_read32(core, D11REGOFFS(clk_ctl_st)) &
2831                   (CCS_ERSRC_AVAIL_D11PLL |
2832                    CCS_ERSRC_AVAIL_PHYPLL)) !=
2833                  (CCS_ERSRC_AVAIL_D11PLL |
2834                   CCS_ERSRC_AVAIL_PHYPLL), PHYPLL_WAIT_US);
2835 
2836             tmp = bcma_read32(core, D11REGOFFS(clk_ctl_st));
2837             if ((tmp &
2838                  (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL))
2839                 !=
2840                 (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL))
2841                 brcms_err(core, "%s: turn on PHY PLL failed\n",
2842                       __func__);
2843         }
2844     } else {
2845         /*
2846          * Since the PLL may be shared, other cores can still
2847          * be requesting it; so we'll deassert the request but
2848          * not wait for status to comply.
2849          */
2850         bcma_mask32(core, D11REGOFFS(clk_ctl_st),
2851                 ~CCS_ERSRC_REQ_PHYPLL);
2852         (void)bcma_read32(core, D11REGOFFS(clk_ctl_st));
2853     }
2854 }
2855 
2856 static void brcms_c_coredisable(struct brcms_hardware *wlc_hw)
2857 {
2858     bool dev_gone;
2859 
2860     brcms_dbg_info(wlc_hw->d11core, "wl%d: disable core\n", wlc_hw->unit);
2861 
2862     dev_gone = brcms_deviceremoved(wlc_hw->wlc);
2863 
2864     if (dev_gone)
2865         return;
2866 
2867     if (wlc_hw->noreset)
2868         return;
2869 
2870     /* radio off */
2871     wlc_phy_switch_radio(wlc_hw->band->pi, OFF);
2872 
2873     /* turn off analog core */
2874     wlc_phy_anacore(wlc_hw->band->pi, OFF);
2875 
2876     /* turn off PHYPLL to save power */
2877     brcms_b_core_phypll_ctl(wlc_hw, false);
2878 
2879     wlc_hw->clk = false;
2880     bcma_core_disable(wlc_hw->d11core, 0);
2881     wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false);
2882 }
2883 
2884 static void brcms_c_flushqueues(struct brcms_c_info *wlc)
2885 {
2886     struct brcms_hardware *wlc_hw = wlc->hw;
2887     uint i;
2888 
2889     /* free any posted tx packets */
2890     for (i = 0; i < NFIFO; i++) {
2891         if (wlc_hw->di[i]) {
2892             dma_txreclaim(wlc_hw->di[i], DMA_RANGE_ALL);
2893             if (i < TX_BCMC_FIFO)
2894                 ieee80211_wake_queue(wlc->pub->ieee_hw,
2895                              brcms_fifo_to_ac(i));
2896         }
2897     }
2898 
2899     /* free any posted rx packets */
2900     dma_rxreclaim(wlc_hw->di[RX_FIFO]);
2901 }
2902 
2903 static u16
2904 brcms_b_read_objmem(struct brcms_hardware *wlc_hw, uint offset, u32 sel)
2905 {
2906     struct bcma_device *core = wlc_hw->d11core;
2907     u16 objoff = D11REGOFFS(objdata);
2908 
2909     bcma_write32(core, D11REGOFFS(objaddr), sel | (offset >> 2));
2910     (void)bcma_read32(core, D11REGOFFS(objaddr));
2911     if (offset & 2)
2912         objoff += 2;
2913 
2914     return bcma_read16(core, objoff);
2915 }
2916 
2917 static void
2918 brcms_b_write_objmem(struct brcms_hardware *wlc_hw, uint offset, u16 v,
2919              u32 sel)
2920 {
2921     struct bcma_device *core = wlc_hw->d11core;
2922     u16 objoff = D11REGOFFS(objdata);
2923 
2924     bcma_write32(core, D11REGOFFS(objaddr), sel | (offset >> 2));
2925     (void)bcma_read32(core, D11REGOFFS(objaddr));
2926     if (offset & 2)
2927         objoff += 2;
2928 
2929     bcma_wflush16(core, objoff, v);
2930 }
2931 
2932 /*
2933  * Read a single u16 from shared memory.
2934  * SHM 'offset' needs to be an even address
2935  */
2936 u16 brcms_b_read_shm(struct brcms_hardware *wlc_hw, uint offset)
2937 {
2938     return brcms_b_read_objmem(wlc_hw, offset, OBJADDR_SHM_SEL);
2939 }
2940 
2941 /*
2942  * Write a single u16 to shared memory.
2943  * SHM 'offset' needs to be an even address
2944  */
2945 void brcms_b_write_shm(struct brcms_hardware *wlc_hw, uint offset, u16 v)
2946 {
2947     brcms_b_write_objmem(wlc_hw, offset, v, OBJADDR_SHM_SEL);
2948 }
2949 
2950 /*
2951  * Copy a buffer to shared memory of specified type .
2952  * SHM 'offset' needs to be an even address and
2953  * Buffer length 'len' must be an even number of bytes
2954  * 'sel' selects the type of memory
2955  */
2956 void
2957 brcms_b_copyto_objmem(struct brcms_hardware *wlc_hw, uint offset,
2958               const void *buf, int len, u32 sel)
2959 {
2960     u16 v;
2961     const u8 *p = (const u8 *)buf;
2962     int i;
2963 
2964     if (len <= 0 || (offset & 1) || (len & 1))
2965         return;
2966 
2967     for (i = 0; i < len; i += 2) {
2968         v = p[i] | (p[i + 1] << 8);
2969         brcms_b_write_objmem(wlc_hw, offset + i, v, sel);
2970     }
2971 }
2972 
2973 /*
2974  * Copy a piece of shared memory of specified type to a buffer .
2975  * SHM 'offset' needs to be an even address and
2976  * Buffer length 'len' must be an even number of bytes
2977  * 'sel' selects the type of memory
2978  */
2979 void
2980 brcms_b_copyfrom_objmem(struct brcms_hardware *wlc_hw, uint offset, void *buf,
2981              int len, u32 sel)
2982 {
2983     u16 v;
2984     u8 *p = (u8 *) buf;
2985     int i;
2986 
2987     if (len <= 0 || (offset & 1) || (len & 1))
2988         return;
2989 
2990     for (i = 0; i < len; i += 2) {
2991         v = brcms_b_read_objmem(wlc_hw, offset + i, sel);
2992         p[i] = v & 0xFF;
2993         p[i + 1] = (v >> 8) & 0xFF;
2994     }
2995 }
2996 
2997 /* Copy a buffer to shared memory.
2998  * SHM 'offset' needs to be an even address and
2999  * Buffer length 'len' must be an even number of bytes
3000  */
3001 static void brcms_c_copyto_shm(struct brcms_c_info *wlc, uint offset,
3002             const void *buf, int len)
3003 {
3004     brcms_b_copyto_objmem(wlc->hw, offset, buf, len, OBJADDR_SHM_SEL);
3005 }
3006 
3007 static void brcms_b_retrylimit_upd(struct brcms_hardware *wlc_hw,
3008                    u16 SRL, u16 LRL)
3009 {
3010     wlc_hw->SRL = SRL;
3011     wlc_hw->LRL = LRL;
3012 
3013     /* write retry limit to SCR, shouldn't need to suspend */
3014     if (wlc_hw->up) {
3015         bcma_write32(wlc_hw->d11core, D11REGOFFS(objaddr),
3016                  OBJADDR_SCR_SEL | S_DOT11_SRC_LMT);
3017         (void)bcma_read32(wlc_hw->d11core, D11REGOFFS(objaddr));
3018         bcma_write32(wlc_hw->d11core, D11REGOFFS(objdata), wlc_hw->SRL);
3019         bcma_write32(wlc_hw->d11core, D11REGOFFS(objaddr),
3020                  OBJADDR_SCR_SEL | S_DOT11_LRC_LMT);
3021         (void)bcma_read32(wlc_hw->d11core, D11REGOFFS(objaddr));
3022         bcma_write32(wlc_hw->d11core, D11REGOFFS(objdata), wlc_hw->LRL);
3023     }
3024 }
3025 
3026 static void brcms_b_pllreq(struct brcms_hardware *wlc_hw, bool set, u32 req_bit)
3027 {
3028     if (set) {
3029         if (mboolisset(wlc_hw->pllreq, req_bit))
3030             return;
3031 
3032         mboolset(wlc_hw->pllreq, req_bit);
3033 
3034         if (mboolisset(wlc_hw->pllreq, BRCMS_PLLREQ_FLIP)) {
3035             if (!wlc_hw->sbclk)
3036                 brcms_b_xtal(wlc_hw, ON);
3037         }
3038     } else {
3039         if (!mboolisset(wlc_hw->pllreq, req_bit))
3040             return;
3041 
3042         mboolclr(wlc_hw->pllreq, req_bit);
3043 
3044         if (mboolisset(wlc_hw->pllreq, BRCMS_PLLREQ_FLIP)) {
3045             if (wlc_hw->sbclk)
3046                 brcms_b_xtal(wlc_hw, OFF);
3047         }
3048     }
3049 }
3050 
3051 static void brcms_b_antsel_set(struct brcms_hardware *wlc_hw, u32 antsel_avail)
3052 {
3053     wlc_hw->antsel_avail = antsel_avail;
3054 }
3055 
3056 /*
3057  * conditions under which the PM bit should be set in outgoing frames
3058  * and STAY_AWAKE is meaningful
3059  */
3060 static bool brcms_c_ps_allowed(struct brcms_c_info *wlc)
3061 {
3062     /* not supporting PS so always return false for now */
3063     return false;
3064 }
3065 
3066 static void brcms_c_statsupd(struct brcms_c_info *wlc)
3067 {
3068     int i;
3069     struct macstat *macstats;
3070 #ifdef DEBUG
3071     u16 delta;
3072     u16 rxf0ovfl;
3073     u16 txfunfl[NFIFO];
3074 #endif              /* DEBUG */
3075 
3076     /* if driver down, make no sense to update stats */
3077     if (!wlc->pub->up)
3078         return;
3079 
3080     macstats = wlc->core->macstat_snapshot;
3081 
3082 #ifdef DEBUG
3083     /* save last rx fifo 0 overflow count */
3084     rxf0ovfl = macstats->rxf0ovfl;
3085 
3086     /* save last tx fifo  underflow count */
3087     for (i = 0; i < NFIFO; i++)
3088         txfunfl[i] = macstats->txfunfl[i];
3089 #endif              /* DEBUG */
3090 
3091     /* Read mac stats from contiguous shared memory */
3092     brcms_b_copyfrom_objmem(wlc->hw, M_UCODE_MACSTAT, macstats,
3093                 sizeof(*macstats), OBJADDR_SHM_SEL);
3094 
3095 #ifdef DEBUG
3096     /* check for rx fifo 0 overflow */
3097     delta = (u16)(macstats->rxf0ovfl - rxf0ovfl);
3098     if (delta)
3099         brcms_err(wlc->hw->d11core, "wl%d: %u rx fifo 0 overflows!\n",
3100               wlc->pub->unit, delta);
3101 
3102     /* check for tx fifo underflows */
3103     for (i = 0; i < NFIFO; i++) {
3104         delta = macstats->txfunfl[i] - txfunfl[i];
3105         if (delta)
3106             brcms_err(wlc->hw->d11core,
3107                   "wl%d: %u tx fifo %d underflows!\n",
3108                   wlc->pub->unit, delta, i);
3109     }
3110 #endif              /* DEBUG */
3111 
3112     /* merge counters from dma module */
3113     for (i = 0; i < NFIFO; i++) {
3114         if (wlc->hw->di[i])
3115             dma_counterreset(wlc->hw->di[i]);
3116     }
3117 }
3118 
3119 static void brcms_b_reset(struct brcms_hardware *wlc_hw)
3120 {
3121     /* reset the core */
3122     if (!brcms_deviceremoved(wlc_hw->wlc))
3123         brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS);
3124 
3125     /* purge the dma rings */
3126     brcms_c_flushqueues(wlc_hw->wlc);
3127 }
3128 
3129 void brcms_c_reset(struct brcms_c_info *wlc)
3130 {
3131     brcms_dbg_info(wlc->hw->d11core, "wl%d\n", wlc->pub->unit);
3132 
3133     /* slurp up hw mac counters before core reset */
3134     brcms_c_statsupd(wlc);
3135 
3136     /* reset our snapshot of macstat counters */
3137     memset(wlc->core->macstat_snapshot, 0, sizeof(struct macstat));
3138 
3139     brcms_b_reset(wlc->hw);
3140 }
3141 
3142 void brcms_c_init_scb(struct scb *scb)
3143 {
3144     int i;
3145 
3146     memset(scb, 0, sizeof(struct scb));
3147     scb->flags = SCB_WMECAP | SCB_HTCAP;
3148     for (i = 0; i < NUMPRIO; i++) {
3149         scb->seqnum[i] = 0;
3150         scb->seqctl[i] = 0xFFFF;
3151     }
3152 
3153     scb->seqctl_nonqos = 0xFFFF;
3154     scb->magic = SCB_MAGIC;
3155 }
3156 
3157 /* d11 core init
3158  *   reset PSM
3159  *   download ucode/PCM
3160  *   let ucode run to suspended
3161  *   download ucode inits
3162  *   config other core registers
3163  *   init dma
3164  */
3165 static void brcms_b_coreinit(struct brcms_c_info *wlc)
3166 {
3167     struct brcms_hardware *wlc_hw = wlc->hw;
3168     struct bcma_device *core = wlc_hw->d11core;
3169     u32 bcnint_us;
3170     uint i = 0;
3171     bool fifosz_fixup = false;
3172     int err = 0;
3173     u16 buf[NFIFO];
3174     struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode;
3175 
3176     brcms_dbg_info(core, "wl%d: core init\n", wlc_hw->unit);
3177 
3178     /* reset PSM */
3179     brcms_b_mctrl(wlc_hw, ~0, (MCTL_IHR_EN | MCTL_PSM_JMP_0 | MCTL_WAKE));
3180 
3181     brcms_ucode_download(wlc_hw);
3182     /*
3183      * FIFOSZ fixup. driver wants to controls the fifo allocation.
3184      */
3185     fifosz_fixup = true;
3186 
3187     /* let the PSM run to the suspended state, set mode to BSS STA */
3188     bcma_write32(core, D11REGOFFS(macintstatus), -1);
3189     brcms_b_mctrl(wlc_hw, ~0,
3190                (MCTL_IHR_EN | MCTL_INFRA | MCTL_PSM_RUN | MCTL_WAKE));
3191 
3192     /* wait for ucode to self-suspend after auto-init */
3193     SPINWAIT(((bcma_read32(core, D11REGOFFS(macintstatus)) &
3194            MI_MACSSPNDD) == 0), 1000 * 1000);
3195     if ((bcma_read32(core, D11REGOFFS(macintstatus)) & MI_MACSSPNDD) == 0)
3196         brcms_err(core, "wl%d: wlc_coreinit: ucode did not self-"
3197               "suspend!\n", wlc_hw->unit);
3198 
3199     brcms_c_gpio_init(wlc);
3200 
3201     bcma_aread32(core, BCMA_IOST);
3202 
3203     if (D11REV_IS(wlc_hw->corerev, 17) || D11REV_IS(wlc_hw->corerev, 23)) {
3204         if (BRCMS_ISNPHY(wlc_hw->band))
3205             brcms_c_write_inits(wlc_hw, ucode->d11n0initvals16);
3206         else
3207             brcms_err(core, "%s: wl%d: unsupported phy in corerev"
3208                   " %d\n", __func__, wlc_hw->unit,
3209                   wlc_hw->corerev);
3210     } else if (D11REV_IS(wlc_hw->corerev, 24)) {
3211         if (BRCMS_ISLCNPHY(wlc_hw->band))
3212             brcms_c_write_inits(wlc_hw, ucode->d11lcn0initvals24);
3213         else
3214             brcms_err(core, "%s: wl%d: unsupported phy in corerev"
3215                   " %d\n", __func__, wlc_hw->unit,
3216                   wlc_hw->corerev);
3217     } else {
3218         brcms_err(core, "%s: wl%d: unsupported corerev %d\n",
3219               __func__, wlc_hw->unit, wlc_hw->corerev);
3220     }
3221 
3222     /* For old ucode, txfifo sizes needs to be modified(increased) */
3223     if (fifosz_fixup)
3224         brcms_b_corerev_fifofixup(wlc_hw);
3225 
3226     /* check txfifo allocations match between ucode and driver */
3227     buf[TX_AC_BE_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE0);
3228     if (buf[TX_AC_BE_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_BE_FIFO]) {
3229         i = TX_AC_BE_FIFO;
3230         err = -1;
3231     }
3232     buf[TX_AC_VI_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE1);
3233     if (buf[TX_AC_VI_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_VI_FIFO]) {
3234         i = TX_AC_VI_FIFO;
3235         err = -1;
3236     }
3237     buf[TX_AC_BK_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE2);
3238     buf[TX_AC_VO_FIFO] = (buf[TX_AC_BK_FIFO] >> 8) & 0xff;
3239     buf[TX_AC_BK_FIFO] &= 0xff;
3240     if (buf[TX_AC_BK_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_BK_FIFO]) {
3241         i = TX_AC_BK_FIFO;
3242         err = -1;
3243     }
3244     if (buf[TX_AC_VO_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_VO_FIFO]) {
3245         i = TX_AC_VO_FIFO;
3246         err = -1;
3247     }
3248     buf[TX_BCMC_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE3);
3249     buf[TX_ATIM_FIFO] = (buf[TX_BCMC_FIFO] >> 8) & 0xff;
3250     buf[TX_BCMC_FIFO] &= 0xff;
3251     if (buf[TX_BCMC_FIFO] != wlc_hw->xmtfifo_sz[TX_BCMC_FIFO]) {
3252         i = TX_BCMC_FIFO;
3253         err = -1;
3254     }
3255     if (buf[TX_ATIM_FIFO] != wlc_hw->xmtfifo_sz[TX_ATIM_FIFO]) {
3256         i = TX_ATIM_FIFO;
3257         err = -1;
3258     }
3259     if (err != 0)
3260         brcms_err(core, "wlc_coreinit: txfifo mismatch: ucode size %d"
3261               " driver size %d index %d\n", buf[i],
3262               wlc_hw->xmtfifo_sz[i], i);
3263 
3264     /* make sure we can still talk to the mac */
3265     WARN_ON(bcma_read32(core, D11REGOFFS(maccontrol)) == 0xffffffff);
3266 
3267     /* band-specific inits done by wlc_bsinit() */
3268 
3269     /* Set up frame burst size and antenna swap threshold init values */
3270     brcms_b_write_shm(wlc_hw, M_MBURST_SIZE, MAXTXFRAMEBURST);
3271     brcms_b_write_shm(wlc_hw, M_MAX_ANTCNT, ANTCNT);
3272 
3273     /* enable one rx interrupt per received frame */
3274     bcma_write32(core, D11REGOFFS(intrcvlazy[0]), (1 << IRL_FC_SHIFT));
3275 
3276     /* set the station mode (BSS STA) */
3277     brcms_b_mctrl(wlc_hw,
3278                (MCTL_INFRA | MCTL_DISCARD_PMQ | MCTL_AP),
3279                (MCTL_INFRA | MCTL_DISCARD_PMQ));
3280 
3281     /* set up Beacon interval */
3282     bcnint_us = 0x8000 << 10;
3283     bcma_write32(core, D11REGOFFS(tsf_cfprep),
3284              (bcnint_us << CFPREP_CBI_SHIFT));
3285     bcma_write32(core, D11REGOFFS(tsf_cfpstart), bcnint_us);
3286     bcma_write32(core, D11REGOFFS(macintstatus), MI_GP1);
3287 
3288     /* write interrupt mask */
3289     bcma_write32(core, D11REGOFFS(intctrlregs[RX_FIFO].intmask),
3290              DEF_RXINTMASK);
3291 
3292     /* allow the MAC to control the PHY clock (dynamic on/off) */
3293     brcms_b_macphyclk_set(wlc_hw, ON);
3294 
3295     /* program dynamic clock control fast powerup delay register */
3296     wlc->fastpwrup_dly = ai_clkctl_fast_pwrup_delay(wlc_hw->sih);
3297     bcma_write16(core, D11REGOFFS(scc_fastpwrup_dly), wlc->fastpwrup_dly);
3298 
3299     /* tell the ucode the corerev */
3300     brcms_b_write_shm(wlc_hw, M_MACHW_VER, (u16) wlc_hw->corerev);
3301 
3302     /* tell the ucode MAC capabilities */
3303     brcms_b_write_shm(wlc_hw, M_MACHW_CAP_L,
3304                (u16) (wlc_hw->machwcap & 0xffff));
3305     brcms_b_write_shm(wlc_hw, M_MACHW_CAP_H,
3306                (u16) ((wlc_hw->
3307                       machwcap >> 16) & 0xffff));
3308 
3309     /* write retry limits to SCR, this done after PSM init */
3310     bcma_write32(core, D11REGOFFS(objaddr),
3311              OBJADDR_SCR_SEL | S_DOT11_SRC_LMT);
3312     (void)bcma_read32(core, D11REGOFFS(objaddr));
3313     bcma_write32(core, D11REGOFFS(objdata), wlc_hw->SRL);
3314     bcma_write32(core, D11REGOFFS(objaddr),
3315              OBJADDR_SCR_SEL | S_DOT11_LRC_LMT);
3316     (void)bcma_read32(core, D11REGOFFS(objaddr));
3317     bcma_write32(core, D11REGOFFS(objdata), wlc_hw->LRL);
3318 
3319     /* write rate fallback retry limits */
3320     brcms_b_write_shm(wlc_hw, M_SFRMTXCNTFBRTHSD, wlc_hw->SFBL);
3321     brcms_b_write_shm(wlc_hw, M_LFRMTXCNTFBRTHSD, wlc_hw->LFBL);
3322 
3323     bcma_mask16(core, D11REGOFFS(ifs_ctl), 0x0FFF);
3324     bcma_write16(core, D11REGOFFS(ifs_aifsn), EDCF_AIFSN_MIN);
3325 
3326     /* init the tx dma engines */
3327     for (i = 0; i < NFIFO; i++) {
3328         if (wlc_hw->di[i])
3329             dma_txinit(wlc_hw->di[i]);
3330     }
3331 
3332     /* init the rx dma engine(s) and post receive buffers */
3333     dma_rxinit(wlc_hw->di[RX_FIFO]);
3334     dma_rxfill(wlc_hw->di[RX_FIFO]);
3335 }
3336 
3337 static void brcms_b_init(struct brcms_hardware *wlc_hw, u16 chanspec)
3338 {
3339     u32 macintmask;
3340     bool fastclk;
3341     struct brcms_c_info *wlc = wlc_hw->wlc;
3342 
3343     /* request FAST clock if not on */
3344     fastclk = wlc_hw->forcefastclk;
3345     if (!fastclk)
3346         brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
3347 
3348     /* disable interrupts */
3349     macintmask = brcms_intrsoff(wlc->wl);
3350 
3351     /* set up the specified band and chanspec */
3352     brcms_c_setxband(wlc_hw, chspec_bandunit(chanspec));
3353     wlc_phy_chanspec_radio_set(wlc_hw->band->pi, chanspec);
3354 
3355     /* do one-time phy inits and calibration */
3356     wlc_phy_cal_init(wlc_hw->band->pi);
3357 
3358     /* core-specific initialization */
3359     brcms_b_coreinit(wlc);
3360 
3361     /* band-specific inits */
3362     brcms_b_bsinit(wlc, chanspec);
3363 
3364     /* restore macintmask */
3365     brcms_intrsrestore(wlc->wl, macintmask);
3366 
3367     /* seed wake_override with BRCMS_WAKE_OVERRIDE_MACSUSPEND since the mac
3368      * is suspended and brcms_c_enable_mac() will clear this override bit.
3369      */
3370     mboolset(wlc_hw->wake_override, BRCMS_WAKE_OVERRIDE_MACSUSPEND);
3371 
3372     /*
3373      * initialize mac_suspend_depth to 1 to match ucode
3374      * initial suspended state
3375      */
3376     wlc_hw->mac_suspend_depth = 1;
3377 
3378     /* restore the clk */
3379     if (!fastclk)
3380         brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_DYNAMIC);
3381 }
3382 
3383 static void brcms_c_set_phy_chanspec(struct brcms_c_info *wlc,
3384                      u16 chanspec)
3385 {
3386     /* Save our copy of the chanspec */
3387     wlc->chanspec = chanspec;
3388 
3389     /* Set the chanspec and power limits for this locale */
3390     brcms_c_channel_set_chanspec(wlc->cmi, chanspec, BRCMS_TXPWR_MAX);
3391 
3392     if (wlc->stf->ss_algosel_auto)
3393         brcms_c_stf_ss_algo_channel_get(wlc, &wlc->stf->ss_algo_channel,
3394                         chanspec);
3395 
3396     brcms_c_stf_ss_update(wlc, wlc->band);
3397 }
3398 
3399 static void
3400 brcms_default_rateset(struct brcms_c_info *wlc, struct brcms_c_rateset *rs)
3401 {
3402     brcms_c_rateset_default(rs, NULL, wlc->band->phytype,
3403         wlc->band->bandtype, false, BRCMS_RATE_MASK_FULL,
3404         (bool) (wlc->pub->_n_enab & SUPPORT_11N),
3405         brcms_chspec_bw(wlc->default_bss->chanspec),
3406         wlc->stf->txstreams);
3407 }
3408 
3409 /* derive wlc->band->basic_rate[] table from 'rateset' */
3410 static void brcms_c_rate_lookup_init(struct brcms_c_info *wlc,
3411                   struct brcms_c_rateset *rateset)
3412 {
3413     u8 rate;
3414     u8 mandatory;
3415     u8 cck_basic = 0;
3416     u8 ofdm_basic = 0;
3417     u8 *br = wlc->band->basic_rate;
3418     uint i;
3419 
3420     /* incoming rates are in 500kbps units as in 802.11 Supported Rates */
3421     memset(br, 0, BRCM_MAXRATE + 1);
3422 
3423     /* For each basic rate in the rates list, make an entry in the
3424      * best basic lookup.
3425      */
3426     for (i = 0; i < rateset->count; i++) {
3427         /* only make an entry for a basic rate */
3428         if (!(rateset->rates[i] & BRCMS_RATE_FLAG))
3429             continue;
3430 
3431         /* mask off basic bit */
3432         rate = (rateset->rates[i] & BRCMS_RATE_MASK);
3433 
3434         if (rate > BRCM_MAXRATE) {
3435             brcms_err(wlc->hw->d11core, "brcms_c_rate_lookup_init: "
3436                   "invalid rate 0x%X in rate set\n",
3437                   rateset->rates[i]);
3438             continue;
3439         }
3440 
3441         br[rate] = rate;
3442     }
3443 
3444     /* The rate lookup table now has non-zero entries for each
3445      * basic rate, equal to the basic rate: br[basicN] = basicN
3446      *
3447      * To look up the best basic rate corresponding to any
3448      * particular rate, code can use the basic_rate table
3449      * like this
3450      *
3451      * basic_rate = wlc->band->basic_rate[tx_rate]
3452      *
3453      * Make sure there is a best basic rate entry for
3454      * every rate by walking up the table from low rates
3455      * to high, filling in holes in the lookup table
3456      */
3457 
3458     for (i = 0; i < wlc->band->hw_rateset.count; i++) {
3459         rate = wlc->band->hw_rateset.rates[i];
3460 
3461         if (br[rate] != 0) {
3462             /* This rate is a basic rate.
3463              * Keep track of the best basic rate so far by
3464              * modulation type.
3465              */
3466             if (is_ofdm_rate(rate))
3467                 ofdm_basic = rate;
3468             else
3469                 cck_basic = rate;
3470 
3471             continue;
3472         }
3473 
3474         /* This rate is not a basic rate so figure out the
3475          * best basic rate less than this rate and fill in
3476          * the hole in the table
3477          */
3478 
3479         br[rate] = is_ofdm_rate(rate) ? ofdm_basic : cck_basic;
3480 
3481         if (br[rate] != 0)
3482             continue;
3483 
3484         if (is_ofdm_rate(rate)) {
3485             /*
3486              * In 11g and 11a, the OFDM mandatory rates
3487              * are 6, 12, and 24 Mbps
3488              */
3489             if (rate >= BRCM_RATE_24M)
3490                 mandatory = BRCM_RATE_24M;
3491             else if (rate >= BRCM_RATE_12M)
3492                 mandatory = BRCM_RATE_12M;
3493             else
3494                 mandatory = BRCM_RATE_6M;
3495         } else {
3496             /* In 11b, all CCK rates are mandatory 1 - 11 Mbps */
3497             mandatory = rate;
3498         }
3499 
3500         br[rate] = mandatory;
3501     }
3502 }
3503 
3504 static void brcms_c_bandinit_ordered(struct brcms_c_info *wlc,
3505                      u16 chanspec)
3506 {
3507     struct brcms_c_rateset default_rateset;
3508     uint parkband;
3509     uint i, band_order[2];
3510 
3511     /*
3512      * We might have been bandlocked during down and the chip
3513      * power-cycled (hibernate). Figure out the right band to park on
3514      */
3515     if (wlc->bandlocked || wlc->pub->_nbands == 1) {
3516         /* updated in brcms_c_bandlock() */
3517         parkband = wlc->band->bandunit;
3518         band_order[0] = band_order[1] = parkband;
3519     } else {
3520         /* park on the band of the specified chanspec */
3521         parkband = chspec_bandunit(chanspec);
3522 
3523         /* order so that parkband initialize last */
3524         band_order[0] = parkband ^ 1;
3525         band_order[1] = parkband;
3526     }
3527 
3528     /* make each band operational, software state init */
3529     for (i = 0; i < wlc->pub->_nbands; i++) {
3530         uint j = band_order[i];
3531 
3532         wlc->band = wlc->bandstate[j];
3533 
3534         brcms_default_rateset(wlc, &default_rateset);
3535 
3536         /* fill in hw_rate */
3537         brcms_c_rateset_filter(&default_rateset, &wlc->band->hw_rateset,
3538                    false, BRCMS_RATES_CCK_OFDM, BRCMS_RATE_MASK,
3539                    (bool) (wlc->pub->_n_enab & SUPPORT_11N));
3540 
3541         /* init basic rate lookup */
3542         brcms_c_rate_lookup_init(wlc, &default_rateset);
3543     }
3544 
3545     /* sync up phy/radio chanspec */
3546     brcms_c_set_phy_chanspec(wlc, chanspec);
3547 }
3548 
3549 /*
3550  * Set or clear filtering related maccontrol bits based on
3551  * specified filter flags
3552  */
3553 void brcms_c_mac_promisc(struct brcms_c_info *wlc, uint filter_flags)
3554 {
3555     u32 promisc_bits = 0;
3556 
3557     wlc->filter_flags = filter_flags;
3558 
3559     if (filter_flags & FIF_OTHER_BSS)
3560         promisc_bits |= MCTL_PROMISC;
3561 
3562     if (filter_flags & FIF_BCN_PRBRESP_PROMISC)
3563         promisc_bits |= MCTL_BCNS_PROMISC;
3564 
3565     if (filter_flags & FIF_FCSFAIL)
3566         promisc_bits |= MCTL_KEEPBADFCS;
3567 
3568     if (filter_flags & (FIF_CONTROL | FIF_PSPOLL))
3569         promisc_bits |= MCTL_KEEPCONTROL;
3570 
3571     brcms_b_mctrl(wlc->hw,
3572         MCTL_PROMISC | MCTL_BCNS_PROMISC |
3573         MCTL_KEEPCONTROL | MCTL_KEEPBADFCS,
3574         promisc_bits);
3575 }
3576 
3577 /*
3578  * ucode, hwmac update
3579  *    Channel dependent updates for ucode and hw
3580  */
3581 static void brcms_c_ucode_mac_upd(struct brcms_c_info *wlc)
3582 {
3583     /* enable or disable any active IBSSs depending on whether or not
3584      * we are on the home channel
3585      */
3586     if (wlc->home_chanspec == wlc_phy_chanspec_get(wlc->band->pi)) {
3587         if (wlc->pub->associated) {
3588             /*
3589              * BMAC_NOTE: This is something that should be fixed
3590              * in ucode inits. I think that the ucode inits set
3591              * up the bcn templates and shm values with a bogus
3592              * beacon. This should not be done in the inits. If
3593              * ucode needs to set up a beacon for testing, the
3594              * test routines should write it down, not expect the
3595              * inits to populate a bogus beacon.
3596              */
3597             if (BRCMS_PHY_11N_CAP(wlc->band))
3598                 brcms_b_write_shm(wlc->hw,
3599                         M_BCN_TXTSF_OFFSET, 0);
3600         }
3601     } else {
3602         /* disable an active IBSS if we are not on the home channel */
3603     }
3604 }
3605 
3606 static void brcms_c_write_rate_shm(struct brcms_c_info *wlc, u8 rate,
3607                    u8 basic_rate)
3608 {
3609     u8 phy_rate, index;
3610     u8 basic_phy_rate, basic_index;
3611     u16 dir_table, basic_table;
3612     u16 basic_ptr;
3613 
3614     /* Shared memory address for the table we are reading */
3615     dir_table = is_ofdm_rate(basic_rate) ? M_RT_DIRMAP_A : M_RT_DIRMAP_B;
3616 
3617     /* Shared memory address for the table we are writing */
3618     basic_table = is_ofdm_rate(rate) ? M_RT_BBRSMAP_A : M_RT_BBRSMAP_B;
3619 
3620     /*
3621      * for a given rate, the LS-nibble of the PLCP SIGNAL field is
3622      * the index into the rate table.
3623      */
3624     phy_rate = rate_info[rate] & BRCMS_RATE_MASK;
3625     basic_phy_rate = rate_info[basic_rate] & BRCMS_RATE_MASK;
3626     index = phy_rate & 0xf;
3627     basic_index = basic_phy_rate & 0xf;
3628 
3629     /* Find the SHM pointer to the ACK rate entry by looking in the
3630      * Direct-map Table
3631      */
3632     basic_ptr = brcms_b_read_shm(wlc->hw, (dir_table + basic_index * 2));
3633 
3634     /* Update the SHM BSS-basic-rate-set mapping table with the pointer
3635      * to the correct basic rate for the given incoming rate
3636      */
3637     brcms_b_write_shm(wlc->hw, (basic_table + index * 2), basic_ptr);
3638 }
3639 
3640 static const struct brcms_c_rateset *
3641 brcms_c_rateset_get_hwrs(struct brcms_c_info *wlc)
3642 {
3643     const struct brcms_c_rateset *rs_dflt;
3644 
3645     if (BRCMS_PHY_11N_CAP(wlc->band)) {
3646         if (wlc->band->bandtype == BRCM_BAND_5G)
3647             rs_dflt = &ofdm_mimo_rates;
3648         else
3649             rs_dflt = &cck_ofdm_mimo_rates;
3650     } else if (wlc->band->gmode)
3651         rs_dflt = &cck_ofdm_rates;
3652     else
3653         rs_dflt = &cck_rates;
3654 
3655     return rs_dflt;
3656 }
3657 
3658 static void brcms_c_set_ratetable(struct brcms_c_info *wlc)
3659 {
3660     const struct brcms_c_rateset *rs_dflt;
3661     struct brcms_c_rateset rs;
3662     u8 rate, basic_rate;
3663     uint i;
3664 
3665     rs_dflt = brcms_c_rateset_get_hwrs(wlc);
3666 
3667     brcms_c_rateset_copy(rs_dflt, &rs);
3668     brcms_c_rateset_mcs_upd(&rs, wlc->stf->txstreams);
3669 
3670     /* walk the phy rate table and update SHM basic rate lookup table */
3671     for (i = 0; i < rs.count; i++) {
3672         rate = rs.rates[i] & BRCMS_RATE_MASK;
3673 
3674         /* for a given rate brcms_basic_rate returns the rate at
3675          * which a response ACK/CTS should be sent.
3676          */
3677         basic_rate = brcms_basic_rate(wlc, rate);
3678         if (basic_rate == 0)
3679             /* This should only happen if we are using a
3680              * restricted rateset.
3681              */
3682             basic_rate = rs.rates[0] & BRCMS_RATE_MASK;
3683 
3684         brcms_c_write_rate_shm(wlc, rate, basic_rate);
3685     }
3686 }
3687 
3688 /* band-specific init */
3689 static void brcms_c_bsinit(struct brcms_c_info *wlc)
3690 {
3691     brcms_dbg_info(wlc->hw->d11core, "wl%d: bandunit %d\n",
3692                wlc->pub->unit, wlc->band->bandunit);
3693 
3694     /* write ucode ACK/CTS rate table */
3695     brcms_c_set_ratetable(wlc);
3696 
3697     /* update some band specific mac configuration */
3698     brcms_c_ucode_mac_upd(wlc);
3699 
3700     /* init antenna selection */
3701     brcms_c_antsel_init(wlc->asi);
3702 
3703 }
3704 
3705 /* formula:  IDLE_BUSY_RATIO_X_16 = (100-duty_cycle)/duty_cycle*16 */
3706 static int
3707 brcms_c_duty_cycle_set(struct brcms_c_info *wlc, int duty_cycle, bool isOFDM,
3708            bool writeToShm)
3709 {
3710     int idle_busy_ratio_x_16 = 0;
3711     uint offset =
3712         isOFDM ? M_TX_IDLE_BUSY_RATIO_X_16_OFDM :
3713         M_TX_IDLE_BUSY_RATIO_X_16_CCK;
3714     if (duty_cycle > 100 || duty_cycle < 0) {
3715         brcms_err(wlc->hw->d11core,
3716               "wl%d:  duty cycle value off limit\n",
3717               wlc->pub->unit);
3718         return -EINVAL;
3719     }
3720     if (duty_cycle)
3721         idle_busy_ratio_x_16 = (100 - duty_cycle) * 16 / duty_cycle;
3722     /* Only write to shared memory  when wl is up */
3723     if (writeToShm)
3724         brcms_b_write_shm(wlc->hw, offset, (u16) idle_busy_ratio_x_16);
3725 
3726     if (isOFDM)
3727         wlc->tx_duty_cycle_ofdm = (u16) duty_cycle;
3728     else
3729         wlc->tx_duty_cycle_cck = (u16) duty_cycle;
3730 
3731     return 0;
3732 }
3733 
3734 /* push sw hps and wake state through hardware */
3735 static void brcms_c_set_ps_ctrl(struct brcms_c_info *wlc)
3736 {
3737     u32 v1, v2;
3738     bool hps;
3739     bool awake_before;
3740 
3741     hps = brcms_c_ps_allowed(wlc);
3742 
3743     brcms_dbg_mac80211(wlc->hw->d11core, "wl%d: hps %d\n", wlc->pub->unit,
3744                hps);
3745 
3746     v1 = bcma_read32(wlc->hw->d11core, D11REGOFFS(maccontrol));
3747     v2 = MCTL_WAKE;
3748     if (hps)
3749         v2 |= MCTL_HPS;
3750 
3751     brcms_b_mctrl(wlc->hw, MCTL_WAKE | MCTL_HPS, v2);
3752 
3753     awake_before = ((v1 & MCTL_WAKE) || ((v1 & MCTL_HPS) == 0));
3754 
3755     if (!awake_before)
3756         brcms_b_wait_for_wake(wlc->hw);
3757 }
3758 
3759 /*
3760  * Write this BSS config's MAC address to core.
3761  * Updates RXE match engine.
3762  */
3763 static void brcms_c_set_mac(struct brcms_bss_cfg *bsscfg)
3764 {
3765     struct brcms_c_info *wlc = bsscfg->wlc;
3766 
3767     /* enter the MAC addr into the RXE match registers */
3768     brcms_c_set_addrmatch(wlc, RCM_MAC_OFFSET, wlc->pub->cur_etheraddr);
3769 
3770     brcms_c_ampdu_macaddr_upd(wlc);
3771 }
3772 
3773 /* Write the BSS config's BSSID address to core (set_bssid in d11procs.tcl).
3774  * Updates RXE match engine.
3775  */
3776 static void brcms_c_set_bssid(struct brcms_bss_cfg *bsscfg)
3777 {
3778     /* we need to update BSSID in RXE match registers */
3779     brcms_c_set_addrmatch(bsscfg->wlc, RCM_BSSID_OFFSET, bsscfg->BSSID);
3780 }
3781 
3782 void brcms_c_set_ssid(struct brcms_c_info *wlc, u8 *ssid, size_t ssid_len)
3783 {
3784     u8 len = min_t(u8, sizeof(wlc->bsscfg->SSID), ssid_len);
3785     memset(wlc->bsscfg->SSID, 0, sizeof(wlc->bsscfg->SSID));
3786 
3787     memcpy(wlc->bsscfg->SSID, ssid, len);
3788     wlc->bsscfg->SSID_len = len;
3789 }
3790 
3791 static void brcms_b_set_shortslot(struct brcms_hardware *wlc_hw, bool shortslot)
3792 {
3793     wlc_hw->shortslot = shortslot;
3794 
3795     if (wlc_hw->band->bandtype == BRCM_BAND_2G && wlc_hw->up) {
3796         brcms_c_suspend_mac_and_wait(wlc_hw->wlc);
3797         brcms_b_update_slot_timing(wlc_hw, shortslot);
3798         brcms_c_enable_mac(wlc_hw->wlc);
3799     }
3800 }
3801 
3802 /*
3803  * Suspend the MAC and update the slot timing
3804  * for standard 11b/g (20us slots) or shortslot 11g (9us slots).
3805  */
3806 static void brcms_c_switch_shortslot(struct brcms_c_info *wlc, bool shortslot)
3807 {
3808     /* use the override if it is set */
3809     if (wlc->shortslot_override != BRCMS_SHORTSLOT_AUTO)
3810         shortslot = (wlc->shortslot_override == BRCMS_SHORTSLOT_ON);
3811 
3812     if (wlc->shortslot == shortslot)
3813         return;
3814 
3815     wlc->shortslot = shortslot;
3816 
3817     brcms_b_set_shortslot(wlc->hw, shortslot);
3818 }
3819 
3820 static void brcms_c_set_home_chanspec(struct brcms_c_info *wlc, u16 chanspec)
3821 {
3822     if (wlc->home_chanspec != chanspec) {
3823         wlc->home_chanspec = chanspec;
3824 
3825         if (wlc->pub->associated)
3826             wlc->bsscfg->current_bss->chanspec = chanspec;
3827     }
3828 }
3829 
3830 void
3831 brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, u16 chanspec,
3832               bool mute_tx, struct txpwr_limits *txpwr)
3833 {
3834     uint bandunit;
3835 
3836     brcms_dbg_mac80211(wlc_hw->d11core, "wl%d: 0x%x\n", wlc_hw->unit,
3837                chanspec);
3838 
3839     wlc_hw->chanspec = chanspec;
3840 
3841     /* Switch bands if necessary */
3842     if (wlc_hw->_nbands > 1) {
3843         bandunit = chspec_bandunit(chanspec);
3844         if (wlc_hw->band->bandunit != bandunit) {
3845             /* brcms_b_setband disables other bandunit,
3846              *  use light band switch if not up yet
3847              */
3848             if (wlc_hw->up) {
3849                 wlc_phy_chanspec_radio_set(wlc_hw->
3850                                bandstate[bandunit]->
3851                                pi, chanspec);
3852                 brcms_b_setband(wlc_hw, bandunit, chanspec);
3853             } else {
3854                 brcms_c_setxband(wlc_hw, bandunit);
3855             }
3856         }
3857     }
3858 
3859     wlc_phy_initcal_enable(wlc_hw->band->pi, !mute_tx);
3860 
3861     if (!wlc_hw->up) {
3862         if (wlc_hw->clk)
3863             wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr,
3864                           chanspec);
3865         wlc_phy_chanspec_radio_set(wlc_hw->band->pi, chanspec);
3866     } else {
3867         wlc_phy_chanspec_set(wlc_hw->band->pi, chanspec);
3868         wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr, chanspec);
3869 
3870         /* Update muting of the channel */
3871         brcms_b_mute(wlc_hw, mute_tx);
3872     }
3873 }
3874 
3875 /* switch to and initialize new band */
3876 static void brcms_c_setband(struct brcms_c_info *wlc,
3877                        uint bandunit)
3878 {
3879     wlc->band = wlc->bandstate[bandunit];
3880 
3881     if (!wlc->pub->up)
3882         return;
3883 
3884     /* wait for at least one beacon before entering sleeping state */
3885     brcms_c_set_ps_ctrl(wlc);
3886 
3887     /* band-specific initializations */
3888     brcms_c_bsinit(wlc);
3889 }
3890 
3891 static void brcms_c_set_chanspec(struct brcms_c_info *wlc, u16 chanspec)
3892 {
3893     uint bandunit;
3894     u16 old_chanspec = wlc->chanspec;
3895 
3896     if (!brcms_c_valid_chanspec_db(wlc->cmi, chanspec)) {
3897         brcms_err(wlc->hw->d11core, "wl%d: %s: Bad channel %d\n",
3898               wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec));
3899         return;
3900     }
3901 
3902     /* Switch bands if necessary */
3903     if (wlc->pub->_nbands > 1) {
3904         bandunit = chspec_bandunit(chanspec);
3905         if (wlc->band->bandunit != bandunit || wlc->bandinit_pending) {
3906             if (wlc->bandlocked) {
3907                 brcms_err(wlc->hw->d11core,
3908                       "wl%d: %s: chspec %d band is locked!\n",
3909                       wlc->pub->unit, __func__,
3910                       CHSPEC_CHANNEL(chanspec));
3911                 return;
3912             }
3913             /*
3914              * should the setband call come after the
3915              * brcms_b_chanspec() ? if the setband updates
3916              * (brcms_c_bsinit) use low level calls to inspect and
3917              * set state, the state inspected may be from the wrong
3918              * band, or the following brcms_b_set_chanspec() may
3919              * undo the work.
3920              */
3921             brcms_c_setband(wlc, bandunit);
3922         }
3923     }
3924 
3925     /* sync up phy/radio chanspec */
3926     brcms_c_set_phy_chanspec(wlc, chanspec);
3927 
3928     /* init antenna selection */
3929     if (brcms_chspec_bw(old_chanspec) != brcms_chspec_bw(chanspec)) {
3930         brcms_c_antsel_init(wlc->asi);
3931 
3932         /* Fix the hardware rateset based on bw.
3933          * Mainly add MCS32 for 40Mhz, remove MCS 32 for 20Mhz
3934          */
3935         brcms_c_rateset_bw_mcs_filter(&wlc->band->hw_rateset,
3936             wlc->band->mimo_cap_40 ? brcms_chspec_bw(chanspec) : 0);
3937     }
3938 
3939     /* update some mac configuration since chanspec changed */
3940     brcms_c_ucode_mac_upd(wlc);
3941 }
3942 
3943 /*
3944  * This function changes the phytxctl for beacon based on current
3945  * beacon ratespec AND txant setting as per this table:
3946  *  ratespec     CCK        ant = wlc->stf->txant
3947  *      OFDM        ant = 3
3948  */
3949 void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc,
3950                        u32 bcn_rspec)
3951 {
3952     u16 phyctl;
3953     u16 phytxant = wlc->stf->phytxant;
3954     u16 mask = PHY_TXC_ANT_MASK;
3955 
3956     /* for non-siso rates or default setting, use the available chains */
3957     if (BRCMS_PHY_11N_CAP(wlc->band))
3958         phytxant = brcms_c_stf_phytxchain_sel(wlc, bcn_rspec);
3959 
3960     phyctl = brcms_b_read_shm(wlc->hw, M_BCN_PCTLWD);
3961     phyctl = (phyctl & ~mask) | phytxant;
3962     brcms_b_write_shm(wlc->hw, M_BCN_PCTLWD, phyctl);
3963 }
3964 
3965 /*
3966  * centralized protection config change function to simplify debugging, no
3967  * consistency checking this should be called only on changes to avoid overhead
3968  * in periodic function
3969  */
3970 void brcms_c_protection_upd(struct brcms_c_info *wlc, uint idx, int val)
3971 {
3972     /*
3973      * Cannot use brcms_dbg_* here because this function is called
3974      * before wlc is sufficiently initialized.
3975      */
3976     BCMMSG(wlc->wiphy, "idx %d, val %d\n", idx, val);
3977 
3978     switch (idx) {
3979     case BRCMS_PROT_G_SPEC:
3980         wlc->protection->_g = (bool) val;
3981         break;
3982     case BRCMS_PROT_G_OVR:
3983         wlc->protection->g_override = (s8) val;
3984         break;
3985     case BRCMS_PROT_G_USER:
3986         wlc->protection->gmode_user = (u8) val;
3987         break;
3988     case BRCMS_PROT_OVERLAP:
3989         wlc->protection->overlap = (s8) val;
3990         break;
3991     case BRCMS_PROT_N_USER:
3992         wlc->protection->nmode_user = (s8) val;
3993         break;
3994     case BRCMS_PROT_N_CFG:
3995         wlc->protection->n_cfg = (s8) val;
3996         break;
3997     case BRCMS_PROT_N_CFG_OVR:
3998         wlc->protection->n_cfg_override = (s8) val;
3999         break;
4000     case BRCMS_PROT_N_NONGF:
4001         wlc->protection->nongf = (bool) val;
4002         break;
4003     case BRCMS_PROT_N_NONGF_OVR:
4004         wlc->protection->nongf_override = (s8) val;
4005         break;
4006     case BRCMS_PROT_N_PAM_OVR:
4007         wlc->protection->n_pam_override = (s8) val;
4008         break;
4009     case BRCMS_PROT_N_OBSS:
4010         wlc->protection->n_obss = (bool) val;
4011         break;
4012 
4013     default:
4014         break;
4015     }
4016 
4017 }
4018 
4019 static void brcms_c_ht_update_sgi_rx(struct brcms_c_info *wlc, int val)
4020 {
4021     if (wlc->pub->up) {
4022         brcms_c_update_beacon(wlc);
4023         brcms_c_update_probe_resp(wlc, true);
4024     }
4025 }
4026 
4027 static void brcms_c_ht_update_ldpc(struct brcms_c_info *wlc, s8 val)
4028 {
4029     wlc->stf->ldpc = val;
4030 
4031     if (wlc->pub->up) {
4032         brcms_c_update_beacon(wlc);
4033         brcms_c_update_probe_resp(wlc, true);
4034         wlc_phy_ldpc_override_set(wlc->band->pi, (val ? true : false));
4035     }
4036 }
4037 
4038 void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci,
4039                const struct ieee80211_tx_queue_params *params,
4040                bool suspend)
4041 {
4042     int i;
4043     struct shm_acparams acp_shm;
4044     u16 *shm_entry;
4045 
4046     /* Only apply params if the core is out of reset and has clocks */
4047     if (!wlc->clk) {
4048         brcms_err(wlc->hw->d11core, "wl%d: %s : no-clock\n",
4049               wlc->pub->unit, __func__);
4050         return;
4051     }
4052 
4053     memset(&acp_shm, 0, sizeof(struct shm_acparams));
4054     /* fill in shm ac params struct */
4055     acp_shm.txop = params->txop;
4056     /* convert from units of 32us to us for ucode */
4057     wlc->edcf_txop[aci & 0x3] = acp_shm.txop =
4058         EDCF_TXOP2USEC(acp_shm.txop);
4059     acp_shm.aifs = (params->aifs & EDCF_AIFSN_MASK);
4060 
4061     if (aci == IEEE80211_AC_VI && acp_shm.txop == 0
4062         && acp_shm.aifs < EDCF_AIFSN_MAX)
4063         acp_shm.aifs++;
4064 
4065     if (acp_shm.aifs < EDCF_AIFSN_MIN
4066         || acp_shm.aifs > EDCF_AIFSN_MAX) {
4067         brcms_err(wlc->hw->d11core, "wl%d: edcf_setparams: bad "
4068               "aifs %d\n", wlc->pub->unit, acp_shm.aifs);
4069     } else {
4070         acp_shm.cwmin = params->cw_min;
4071         acp_shm.cwmax = params->cw_max;
4072         acp_shm.cwcur = acp_shm.cwmin;
4073         acp_shm.bslots =
4074             bcma_read16(wlc->hw->d11core, D11REGOFFS(tsf_random)) &
4075             acp_shm.cwcur;
4076         acp_shm.reggap = acp_shm.bslots + acp_shm.aifs;
4077         /* Indicate the new params to the ucode */
4078         acp_shm.status = brcms_b_read_shm(wlc->hw, (M_EDCF_QINFO +
4079                           wme_ac2fifo[aci] *
4080                           M_EDCF_QLEN +
4081                           M_EDCF_STATUS_OFF));
4082         acp_shm.status |= WME_STATUS_NEWAC;
4083 
4084         /* Fill in shm acparam table */
4085         shm_entry = (u16 *) &acp_shm;
4086         for (i = 0; i < (int)sizeof(struct shm_acparams); i += 2)
4087             brcms_b_write_shm(wlc->hw,
4088                       M_EDCF_QINFO +
4089                       wme_ac2fifo[aci] * M_EDCF_QLEN + i,
4090                       *shm_entry++);
4091     }
4092 
4093     if (suspend)
4094         brcms_c_suspend_mac_and_wait(wlc);
4095 
4096     brcms_c_update_beacon(wlc);
4097     brcms_c_update_probe_resp(wlc, false);
4098 
4099     if (suspend)
4100         brcms_c_enable_mac(wlc);
4101 }
4102 
4103 static void brcms_c_edcf_setparams(struct brcms_c_info *wlc, bool suspend)
4104 {
4105     u16 aci;
4106     int i_ac;
4107     struct ieee80211_tx_queue_params txq_pars;
4108     static const struct edcf_acparam default_edcf_acparams[] = {
4109          {EDCF_AC_BE_ACI_STA, EDCF_AC_BE_ECW_STA, EDCF_AC_BE_TXOP_STA},
4110          {EDCF_AC_BK_ACI_STA, EDCF_AC_BK_ECW_STA, EDCF_AC_BK_TXOP_STA},
4111          {EDCF_AC_VI_ACI_STA, EDCF_AC_VI_ECW_STA, EDCF_AC_VI_TXOP_STA},
4112          {EDCF_AC_VO_ACI_STA, EDCF_AC_VO_ECW_STA, EDCF_AC_VO_TXOP_STA}
4113     }; /* ucode needs these parameters during its initialization */
4114     const struct edcf_acparam *edcf_acp = &default_edcf_acparams[0];
4115 
4116     for (i_ac = 0; i_ac < IEEE80211_NUM_ACS; i_ac++, edcf_acp++) {
4117         /* find out which ac this set of params applies to */
4118         aci = (edcf_acp->ACI & EDCF_ACI_MASK) >> EDCF_ACI_SHIFT;
4119 
4120         /* fill in shm ac params struct */
4121         txq_pars.txop = edcf_acp->TXOP;
4122         txq_pars.aifs = edcf_acp->ACI;
4123 
4124         /* CWmin = 2^(ECWmin) - 1 */
4125         txq_pars.cw_min = EDCF_ECW2CW(edcf_acp->ECW & EDCF_ECWMIN_MASK);
4126         /* CWmax = 2^(ECWmax) - 1 */
4127         txq_pars.cw_max = EDCF_ECW2CW((edcf_acp->ECW & EDCF_ECWMAX_MASK)
4128                         >> EDCF_ECWMAX_SHIFT);
4129         brcms_c_wme_setparams(wlc, aci, &txq_pars, suspend);
4130     }
4131 
4132     if (suspend) {
4133         brcms_c_suspend_mac_and_wait(wlc);
4134         brcms_c_enable_mac(wlc);
4135     }
4136 }
4137 
4138 static void brcms_c_radio_monitor_start(struct brcms_c_info *wlc)
4139 {
4140     /* Don't start the timer if HWRADIO feature is disabled */
4141     if (wlc->radio_monitor)
4142         return;
4143 
4144     wlc->radio_monitor = true;
4145     brcms_b_pllreq(wlc->hw, true, BRCMS_PLLREQ_RADIO_MON);
4146     brcms_add_timer(wlc->radio_timer, TIMER_INTERVAL_RADIOCHK, true);
4147 }
4148 
4149 static bool brcms_c_radio_monitor_stop(struct brcms_c_info *wlc)
4150 {
4151     if (!wlc->radio_monitor)
4152         return true;
4153 
4154     wlc->radio_monitor = false;
4155     brcms_b_pllreq(wlc->hw, false, BRCMS_PLLREQ_RADIO_MON);
4156     return brcms_del_timer(wlc->radio_timer);
4157 }
4158 
4159 /* read hwdisable state and propagate to wlc flag */
4160 static void brcms_c_radio_hwdisable_upd(struct brcms_c_info *wlc)
4161 {
4162     if (wlc->pub->hw_off)
4163         return;
4164 
4165     if (brcms_b_radio_read_hwdisabled(wlc->hw))
4166         mboolset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE);
4167     else
4168         mboolclr(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE);
4169 }
4170 
4171 /* update hwradio status and return it */
4172 bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc)
4173 {
4174     brcms_c_radio_hwdisable_upd(wlc);
4175 
4176     return mboolisset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE) ?
4177             true : false;
4178 }
4179 
4180 /* periodical query hw radio button while driver is "down" */
4181 static void brcms_c_radio_timer(void *arg)
4182 {
4183     struct brcms_c_info *wlc = (struct brcms_c_info *) arg;
4184 
4185     if (brcms_deviceremoved(wlc)) {
4186         brcms_err(wlc->hw->d11core, "wl%d: %s: dead chip\n",
4187               wlc->pub->unit, __func__);
4188         brcms_down(wlc->wl);
4189         return;
4190     }
4191 
4192     brcms_c_radio_hwdisable_upd(wlc);
4193 }
4194 
4195 /* common low-level watchdog code */
4196 static void brcms_b_watchdog(struct brcms_c_info *wlc)
4197 {
4198     struct brcms_hardware *wlc_hw = wlc->hw;
4199 
4200     if (!wlc_hw->up)
4201         return;
4202 
4203     /* increment second count */
4204     wlc_hw->now++;
4205 
4206     /* Check for FIFO error interrupts */
4207     brcms_b_fifoerrors(wlc_hw);
4208 
4209     /* make sure RX dma has buffers */
4210     dma_rxfill(wlc->hw->di[RX_FIFO]);
4211 
4212     wlc_phy_watchdog(wlc_hw->band->pi);
4213 }
4214 
4215 /* common watchdog code */
4216 static void brcms_c_watchdog(struct brcms_c_info *wlc)
4217 {
4218     brcms_dbg_info(wlc->hw->d11core, "wl%d\n", wlc->pub->unit);
4219 
4220     if (!wlc->pub->up)
4221         return;
4222 
4223     if (brcms_deviceremoved(wlc)) {
4224         brcms_err(wlc->hw->d11core, "wl%d: %s: dead chip\n",
4225               wlc->pub->unit, __func__);
4226         brcms_down(wlc->wl);
4227         return;
4228     }
4229 
4230     /* increment second count */
4231     wlc->pub->now++;
4232 
4233     brcms_c_radio_hwdisable_upd(wlc);
4234     /* if radio is disable, driver may be down, quit here */
4235     if (wlc->pub->radio_disabled)
4236         return;
4237 
4238     brcms_b_watchdog(wlc);
4239 
4240     /*
4241      * occasionally sample mac stat counters to
4242      * detect 16-bit counter wrap
4243      */
4244     if ((wlc->pub->now % SW_TIMER_MAC_STAT_UPD) == 0)
4245         brcms_c_statsupd(wlc);
4246 
4247     if (BRCMS_ISNPHY(wlc->band) &&
4248         ((wlc->pub->now - wlc->tempsense_lasttime) >=
4249          BRCMS_TEMPSENSE_PERIOD)) {
4250         wlc->tempsense_lasttime = wlc->pub->now;
4251         brcms_c_tempsense_upd(wlc);
4252     }
4253 }
4254 
4255 static void brcms_c_watchdog_by_timer(void *arg)
4256 {
4257     struct brcms_c_info *wlc = (struct brcms_c_info *) arg;
4258 
4259     brcms_c_watchdog(wlc);
4260 }
4261 
4262 static bool brcms_c_timers_init(struct brcms_c_info *wlc, int unit)
4263 {
4264     wlc->wdtimer = brcms_init_timer(wlc->wl, brcms_c_watchdog_by_timer,
4265         wlc, "watchdog");
4266     if (!wlc->wdtimer) {
4267         wiphy_err(wlc->wiphy, "wl%d:  wl_init_timer for wdtimer "
4268               "failed\n", unit);
4269         goto fail;
4270     }
4271 
4272     wlc->radio_timer = brcms_init_timer(wlc->wl, brcms_c_radio_timer,
4273         wlc, "radio");
4274     if (!wlc->radio_timer) {
4275         wiphy_err(wlc->wiphy, "wl%d:  wl_init_timer for radio_timer "
4276               "failed\n", unit);
4277         goto fail;
4278     }
4279 
4280     return true;
4281 
4282  fail:
4283     return false;
4284 }
4285 
4286 /*
4287  * Initialize brcms_c_info default values ...
4288  * may get overrides later in this function
4289  */
4290 static void brcms_c_info_init(struct brcms_c_info *wlc, int unit)
4291 {
4292     int i;
4293 
4294     /* Save our copy of the chanspec */
4295     wlc->chanspec = ch20mhz_chspec(1);
4296 
4297     /* various 802.11g modes */
4298     wlc->shortslot = false;
4299     wlc->shortslot_override = BRCMS_SHORTSLOT_AUTO;
4300 
4301     brcms_c_protection_upd(wlc, BRCMS_PROT_G_OVR, BRCMS_PROTECTION_AUTO);
4302     brcms_c_protection_upd(wlc, BRCMS_PROT_G_SPEC, false);
4303 
4304     brcms_c_protection_upd(wlc, BRCMS_PROT_N_CFG_OVR,
4305                    BRCMS_PROTECTION_AUTO);
4306     brcms_c_protection_upd(wlc, BRCMS_PROT_N_CFG, BRCMS_N_PROTECTION_OFF);
4307     brcms_c_protection_upd(wlc, BRCMS_PROT_N_NONGF_OVR,
4308                    BRCMS_PROTECTION_AUTO);
4309     brcms_c_protection_upd(wlc, BRCMS_PROT_N_NONGF, false);
4310     brcms_c_protection_upd(wlc, BRCMS_PROT_N_PAM_OVR, AUTO);
4311 
4312     brcms_c_protection_upd(wlc, BRCMS_PROT_OVERLAP,
4313                    BRCMS_PROTECTION_CTL_OVERLAP);
4314 
4315     /* 802.11g draft 4.0 NonERP elt advertisement */
4316     wlc->include_legacy_erp = true;
4317 
4318     wlc->stf->ant_rx_ovr = ANT_RX_DIV_DEF;
4319     wlc->stf->txant = ANT_TX_DEF;
4320 
4321     wlc->prb_resp_timeout = BRCMS_PRB_RESP_TIMEOUT;
4322 
4323     wlc->usr_fragthresh = DOT11_DEFAULT_FRAG_LEN;
4324     for (i = 0; i < NFIFO; i++)
4325         wlc->fragthresh[i] = DOT11_DEFAULT_FRAG_LEN;
4326     wlc->RTSThresh = DOT11_DEFAULT_RTS_LEN;
4327 
4328     /* default rate fallback retry limits */
4329     wlc->SFBL = RETRY_SHORT_FB;
4330     wlc->LFBL = RETRY_LONG_FB;
4331 
4332     /* default mac retry limits */
4333     wlc->SRL = RETRY_SHORT_DEF;
4334     wlc->LRL = RETRY_LONG_DEF;
4335 
4336     /* WME QoS mode is Auto by default */
4337     wlc->pub->_ampdu = AMPDU_AGG_HOST;
4338 }
4339 
4340 static uint brcms_c_attach_module(struct brcms_c_info *wlc)
4341 {
4342     uint err = 0;
4343     uint unit;
4344     unit = wlc->pub->unit;
4345 
4346     wlc->asi = brcms_c_antsel_attach(wlc);
4347     if (wlc->asi == NULL) {
4348         wiphy_err(wlc->wiphy, "wl%d: attach: antsel_attach "
4349               "failed\n", unit);
4350         err = 44;
4351         goto fail;
4352     }
4353 
4354     wlc->ampdu = brcms_c_ampdu_attach(wlc);
4355     if (wlc->ampdu == NULL) {
4356         wiphy_err(wlc->wiphy, "wl%d: attach: ampdu_attach "
4357               "failed\n", unit);
4358         err = 50;
4359         goto fail;
4360     }
4361 
4362     if ((brcms_c_stf_attach(wlc) != 0)) {
4363         wiphy_err(wlc->wiphy, "wl%d: attach: stf_attach "
4364               "failed\n", unit);
4365         err = 68;
4366         goto fail;
4367     }
4368  fail:
4369     return err;
4370 }
4371 
4372 struct brcms_pub *brcms_c_pub(struct brcms_c_info *wlc)
4373 {
4374     return wlc->pub;
4375 }
4376 
4377 /* low level attach
4378  *    run backplane attach, init nvram
4379  *    run phy attach
4380  *    initialize software state for each core and band
4381  *    put the whole chip in reset(driver down state), no clock
4382  */
4383 static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core,
4384               uint unit, bool piomode)
4385 {
4386     struct brcms_hardware *wlc_hw;
4387     uint err = 0;
4388     uint j;
4389     bool wme = false;
4390     struct shared_phy_params sha_params;
4391     struct wiphy *wiphy = wlc->wiphy;
4392     struct pci_dev *pcidev = core->bus->host_pci;
4393     struct ssb_sprom *sprom = &core->bus->sprom;
4394 
4395     if (core->bus->hosttype == BCMA_HOSTTYPE_PCI)
4396         brcms_dbg_info(core, "wl%d: vendor 0x%x device 0x%x\n", unit,
4397                    pcidev->vendor,
4398                    pcidev->device);
4399     else
4400         brcms_dbg_info(core, "wl%d: vendor 0x%x device 0x%x\n", unit,
4401                    core->bus->boardinfo.vendor,
4402                    core->bus->boardinfo.type);
4403 
4404     wme = true;
4405 
4406     wlc_hw = wlc->hw;
4407     wlc_hw->wlc = wlc;
4408     wlc_hw->unit = unit;
4409     wlc_hw->band = wlc_hw->bandstate[0];
4410     wlc_hw->_piomode = piomode;
4411 
4412     /* populate struct brcms_hardware with default values  */
4413     brcms_b_info_init(wlc_hw);
4414 
4415     /*
4416      * Do the hardware portion of the attach. Also initialize software
4417      * state that depends on the particular hardware we are running.
4418      */
4419     wlc_hw->sih = ai_attach(core->bus);
4420     if (wlc_hw->sih == NULL) {
4421         wiphy_err(wiphy, "wl%d: brcms_b_attach: si_attach failed\n",
4422               unit);
4423         err = 11;
4424         goto fail;
4425     }
4426 
4427     /* verify again the device is supported */
4428     if (!brcms_c_chipmatch(core)) {
4429         wiphy_err(wiphy, "wl%d: brcms_b_attach: Unsupported device\n",
4430              unit);
4431         err = 12;
4432         goto fail;
4433     }
4434 
4435     if (core->bus->hosttype == BCMA_HOSTTYPE_PCI) {
4436         wlc_hw->vendorid = pcidev->vendor;
4437         wlc_hw->deviceid = pcidev->device;
4438     } else {
4439         wlc_hw->vendorid = core->bus->boardinfo.vendor;
4440         wlc_hw->deviceid = core->bus->boardinfo.type;
4441     }
4442 
4443     wlc_hw->d11core = core;
4444     wlc_hw->corerev = core->id.rev;
4445 
4446     /* validate chip, chiprev and corerev */
4447     if (!brcms_c_isgoodchip(wlc_hw)) {
4448         err = 13;
4449         goto fail;
4450     }
4451 
4452     /* initialize power control registers */
4453     ai_clkctl_init(wlc_hw->sih);
4454 
4455     /* request fastclock and force fastclock for the rest of attach
4456      * bring the d11 core out of reset.
4457      *   For PMU chips, the first wlc_clkctl_clk is no-op since core-clk
4458      *   is still false; But it will be called again inside wlc_corereset,
4459      *   after d11 is out of reset.
4460      */
4461     brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
4462     brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS);
4463 
4464     if (!brcms_b_validate_chip_access(wlc_hw)) {
4465         wiphy_err(wiphy, "wl%d: brcms_b_attach: validate_chip_access "
4466             "failed\n", unit);
4467         err = 14;
4468         goto fail;
4469     }
4470 
4471     /* get the board rev, used just below */
4472     j = sprom->board_rev;
4473     /* promote srom boardrev of 0xFF to 1 */
4474     if (j == BOARDREV_PROMOTABLE)
4475         j = BOARDREV_PROMOTED;
4476     wlc_hw->boardrev = (u16) j;
4477     if (!brcms_c_validboardtype(wlc_hw)) {
4478         wiphy_err(wiphy, "wl%d: brcms_b_attach: Unsupported Broadcom "
4479               "board type (0x%x)" " or revision level (0x%x)\n",
4480               unit, ai_get_boardtype(wlc_hw->sih),
4481               wlc_hw->boardrev);
4482         err = 15;
4483         goto fail;
4484     }
4485     wlc_hw->sromrev = sprom->revision;
4486     wlc_hw->boardflags = sprom->boardflags_lo + (sprom->boardflags_hi << 16);
4487     wlc_hw->boardflags2 = sprom->boardflags2_lo + (sprom->boardflags2_hi << 16);
4488 
4489     if (wlc_hw->boardflags & BFL_NOPLLDOWN)
4490         brcms_b_pllreq(wlc_hw, true, BRCMS_PLLREQ_SHARED);
4491 
4492     /* check device id(srom, nvram etc.) to set bands */
4493     if (wlc_hw->deviceid == BCM43224_D11N_ID ||
4494         wlc_hw->deviceid == BCM43224_D11N_ID_VEN1 ||
4495         wlc_hw->deviceid == BCM43224_CHIP_ID)
4496         /* Dualband boards */
4497         wlc_hw->_nbands = 2;
4498     else
4499         wlc_hw->_nbands = 1;
4500 
4501     if ((ai_get_chip_id(wlc_hw->sih) == BCMA_CHIP_ID_BCM43225))
4502         wlc_hw->_nbands = 1;
4503 
4504     /* BMAC_NOTE: remove init of pub values when brcms_c_attach()
4505      * unconditionally does the init of these values
4506      */
4507     wlc->vendorid = wlc_hw->vendorid;
4508     wlc->deviceid = wlc_hw->deviceid;
4509     wlc->pub->sih = wlc_hw->sih;
4510     wlc->pub->corerev = wlc_hw->corerev;
4511     wlc->pub->sromrev = wlc_hw->sromrev;
4512     wlc->pub->boardrev = wlc_hw->boardrev;
4513     wlc->pub->boardflags = wlc_hw->boardflags;
4514     wlc->pub->boardflags2 = wlc_hw->boardflags2;
4515     wlc->pub->_nbands = wlc_hw->_nbands;
4516 
4517     wlc_hw->physhim = wlc_phy_shim_attach(wlc_hw, wlc->wl, wlc);
4518 
4519     if (wlc_hw->physhim == NULL) {
4520         wiphy_err(wiphy, "wl%d: brcms_b_attach: wlc_phy_shim_attach "
4521             "failed\n", unit);
4522         err = 25;
4523         goto fail;
4524     }
4525 
4526     /* pass all the parameters to wlc_phy_shared_attach in one struct */
4527     sha_params.sih = wlc_hw->sih;
4528     sha_params.physhim = wlc_hw->physhim;
4529     sha_params.unit = unit;
4530     sha_params.corerev = wlc_hw->corerev;
4531     sha_params.vid = wlc_hw->vendorid;
4532     sha_params.did = wlc_hw->deviceid;
4533     sha_params.chip = ai_get_chip_id(wlc_hw->sih);
4534     sha_params.chiprev = ai_get_chiprev(wlc_hw->sih);
4535     sha_params.chippkg = ai_get_chippkg(wlc_hw->sih);
4536     sha_params.sromrev = wlc_hw->sromrev;
4537     sha_params.boardtype = ai_get_boardtype(wlc_hw->sih);
4538     sha_params.boardrev = wlc_hw->boardrev;
4539     sha_params.boardflags = wlc_hw->boardflags;
4540     sha_params.boardflags2 = wlc_hw->boardflags2;
4541 
4542     /* alloc and save pointer to shared phy state area */
4543     wlc_hw->phy_sh = wlc_phy_shared_attach(&sha_params);
4544     if (!wlc_hw->phy_sh) {
4545         err = 16;
4546         goto fail;
4547     }
4548 
4549     /* initialize software state for each core and band */
4550     for (j = 0; j < wlc_hw->_nbands; j++) {
4551         /*
4552          * band0 is always 2.4Ghz
4553          * band1, if present, is 5Ghz
4554          */
4555 
4556         brcms_c_setxband(wlc_hw, j);
4557 
4558         wlc_hw->band->bandunit = j;
4559         wlc_hw->band->bandtype = j ? BRCM_BAND_5G : BRCM_BAND_2G;
4560         wlc->band->bandunit = j;
4561         wlc->band->bandtype = j ? BRCM_BAND_5G : BRCM_BAND_2G;
4562         wlc->core->coreidx = core->core_index;
4563 
4564         wlc_hw->machwcap = bcma_read32(core, D11REGOFFS(machwcap));
4565         wlc_hw->machwcap_backup = wlc_hw->machwcap;
4566 
4567         /* init tx fifo size */
4568         WARN_ON(wlc_hw->corerev < XMTFIFOTBL_STARTREV ||
4569             (wlc_hw->corerev - XMTFIFOTBL_STARTREV) >
4570                 ARRAY_SIZE(xmtfifo_sz));
4571         wlc_hw->xmtfifo_sz =
4572             xmtfifo_sz[(wlc_hw->corerev - XMTFIFOTBL_STARTREV)];
4573         WARN_ON(!wlc_hw->xmtfifo_sz[0]);
4574 
4575         /* Get a phy for this band */
4576         wlc_hw->band->pi =
4577             wlc_phy_attach(wlc_hw->phy_sh, core,
4578                        wlc_hw->band->bandtype,
4579                        wlc->wiphy);
4580         if (wlc_hw->band->pi == NULL) {
4581             wiphy_err(wiphy, "wl%d: brcms_b_attach: wlc_phy_"
4582                   "attach failed\n", unit);
4583             err = 17;
4584             goto fail;
4585         }
4586 
4587         wlc_phy_machwcap_set(wlc_hw->band->pi, wlc_hw->machwcap);
4588 
4589         wlc_phy_get_phyversion(wlc_hw->band->pi, &wlc_hw->band->phytype,
4590                        &wlc_hw->band->phyrev,
4591                        &wlc_hw->band->radioid,
4592                        &wlc_hw->band->radiorev);
4593         wlc_hw->band->abgphy_encore =
4594             wlc_phy_get_encore(wlc_hw->band->pi);
4595         wlc->band->abgphy_encore = wlc_phy_get_encore(wlc_hw->band->pi);
4596         wlc_hw->band->core_flags =
4597             wlc_phy_get_coreflags(wlc_hw->band->pi);
4598 
4599         /* verify good phy_type & supported phy revision */
4600         if (BRCMS_ISNPHY(wlc_hw->band)) {
4601             if (NCONF_HAS(wlc_hw->band->phyrev))
4602                 goto good_phy;
4603             else
4604                 goto bad_phy;
4605         } else if (BRCMS_ISLCNPHY(wlc_hw->band)) {
4606             if (LCNCONF_HAS(wlc_hw->band->phyrev))
4607                 goto good_phy;
4608             else
4609                 goto bad_phy;
4610         } else {
4611  bad_phy:
4612             wiphy_err(wiphy, "wl%d: brcms_b_attach: unsupported "
4613                   "phy type/rev (%d/%d)\n", unit,
4614                   wlc_hw->band->phytype, wlc_hw->band->phyrev);
4615             err = 18;
4616             goto fail;
4617         }
4618 
4619  good_phy:
4620         /*
4621          * BMAC_NOTE: wlc->band->pi should not be set below and should
4622          * be done in the high level attach. However we can not make
4623          * that change until all low level access is changed to
4624          * wlc_hw->band->pi. Instead do the wlc->band->pi init below,
4625          * keeping wlc_hw->band->pi as well for incremental update of
4626          * low level fns, and cut over low only init when all fns
4627          * updated.
4628          */
4629         wlc->band->pi = wlc_hw->band->pi;
4630         wlc->band->phytype = wlc_hw->band->phytype;
4631         wlc->band->phyrev = wlc_hw->band->phyrev;
4632         wlc->band->radioid = wlc_hw->band->radioid;
4633         wlc->band->radiorev = wlc_hw->band->radiorev;
4634         brcms_dbg_info(core, "wl%d: phy %u/%u radio %x/%u\n", unit,
4635                    wlc->band->phytype, wlc->band->phyrev,
4636                    wlc->band->radioid, wlc->band->radiorev);
4637         /* default contention windows size limits */
4638         wlc_hw->band->CWmin = APHY_CWMIN;
4639         wlc_hw->band->CWmax = PHY_CWMAX;
4640 
4641         if (!brcms_b_attach_dmapio(wlc, j, wme)) {
4642             err = 19;
4643             goto fail;
4644         }
4645     }
4646 
4647     /* disable core to match driver "down" state */
4648     brcms_c_coredisable(wlc_hw);
4649 
4650     /* Match driver "down" state */
4651     bcma_host_pci_down(wlc_hw->d11core->bus);
4652 
4653     /* turn off pll and xtal to match driver "down" state */
4654     brcms_b_xtal(wlc_hw, OFF);
4655 
4656     /* *******************************************************************
4657      * The hardware is in the DOWN state at this point. D11 core
4658      * or cores are in reset with clocks off, and the board PLLs
4659      * are off if possible.
4660      *
4661      * Beyond this point, wlc->sbclk == false and chip registers
4662      * should not be touched.
4663      *********************************************************************
4664      */
4665 
4666     /* init etheraddr state variables */
4667     brcms_c_get_macaddr(wlc_hw, wlc_hw->etheraddr);
4668 
4669     if (is_broadcast_ether_addr(wlc_hw->etheraddr) ||
4670         is_zero_ether_addr(wlc_hw->etheraddr)) {
4671         wiphy_err(wiphy, "wl%d: brcms_b_attach: bad macaddr\n",
4672               unit);
4673         err = 22;
4674         goto fail;
4675     }
4676 
4677     brcms_dbg_info(wlc_hw->d11core, "deviceid 0x%x nbands %d board 0x%x\n",
4678                wlc_hw->deviceid, wlc_hw->_nbands,
4679                ai_get_boardtype(wlc_hw->sih));
4680 
4681     return err;
4682 
4683  fail:
4684     wiphy_err(wiphy, "wl%d: brcms_b_attach: failed with err %d\n", unit,
4685           err);
4686     return err;
4687 }
4688 
4689 static bool brcms_c_attach_stf_ant_init(struct brcms_c_info *wlc)
4690 {
4691     int aa;
4692     uint unit;
4693     int bandtype;
4694     struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom;
4695 
4696     unit = wlc->pub->unit;
4697     bandtype = wlc->band->bandtype;
4698 
4699     /* get antennas available */
4700     if (bandtype == BRCM_BAND_5G)
4701         aa = sprom->ant_available_a;
4702     else
4703         aa = sprom->ant_available_bg;
4704 
4705     if ((aa < 1) || (aa > 15)) {
4706         wiphy_err(wlc->wiphy, "wl%d: %s: Invalid antennas available in"
4707               " srom (0x%x), using 3\n", unit, __func__, aa);
4708         aa = 3;
4709     }
4710 
4711     /* reset the defaults if we have a single antenna */
4712     if (aa == 1) {
4713         wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_0;
4714         wlc->stf->txant = ANT_TX_FORCE_0;
4715     } else if (aa == 2) {
4716         wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_1;
4717         wlc->stf->txant = ANT_TX_FORCE_1;
4718     } else {
4719     }
4720 
4721     /* Compute Antenna Gain */
4722     if (bandtype == BRCM_BAND_5G)
4723         wlc->band->antgain = sprom->antenna_gain.a1;
4724     else
4725         wlc->band->antgain = sprom->antenna_gain.a0;
4726 
4727     return true;
4728 }
4729 
4730 static void brcms_c_bss_default_init(struct brcms_c_info *wlc)
4731 {
4732     u16 chanspec;
4733     struct brcms_band *band;
4734     struct brcms_bss_info *bi = wlc->default_bss;
4735 
4736     /* init default and target BSS with some sane initial values */
4737     memset(bi, 0, sizeof(*bi));
4738     bi->beacon_period = BEACON_INTERVAL_DEFAULT;
4739 
4740     /* fill the default channel as the first valid channel
4741      * starting from the 2G channels
4742      */
4743     chanspec = ch20mhz_chspec(1);
4744     wlc->home_chanspec = bi->chanspec = chanspec;
4745 
4746     /* find the band of our default channel */
4747     band = wlc->band;
4748     if (wlc->pub->_nbands > 1 &&
4749         band->bandunit != chspec_bandunit(chanspec))
4750         band = wlc->bandstate[OTHERBANDUNIT(wlc)];
4751 
4752     /* init bss rates to the band specific default rate set */
4753     brcms_c_rateset_default(&bi->rateset, NULL, band->phytype,
4754         band->bandtype, false, BRCMS_RATE_MASK_FULL,
4755         (bool) (wlc->pub->_n_enab & SUPPORT_11N),
4756         brcms_chspec_bw(chanspec), wlc->stf->txstreams);
4757 
4758     if (wlc->pub->_n_enab & SUPPORT_11N)
4759         bi->flags |= BRCMS_BSS_HT;
4760 }
4761 
4762 static void brcms_c_update_mimo_band_bwcap(struct brcms_c_info *wlc, u8 bwcap)
4763 {
4764     uint i;
4765     struct brcms_band *band;
4766 
4767     for (i = 0; i < wlc->pub->_nbands; i++) {
4768         band = wlc->bandstate[i];
4769         if (band->bandtype == BRCM_BAND_5G) {
4770             if ((bwcap == BRCMS_N_BW_40ALL)
4771                 || (bwcap == BRCMS_N_BW_20IN2G_40IN5G))
4772                 band->mimo_cap_40 = true;
4773             else
4774                 band->mimo_cap_40 = false;
4775         } else {
4776             if (bwcap == BRCMS_N_BW_40ALL)
4777                 band->mimo_cap_40 = true;
4778             else
4779                 band->mimo_cap_40 = false;
4780         }
4781     }
4782 }
4783 
4784 static void brcms_c_timers_deinit(struct brcms_c_info *wlc)
4785 {
4786     /* free timer state */
4787     if (wlc->wdtimer) {
4788         brcms_free_timer(wlc->wdtimer);
4789         wlc->wdtimer = NULL;
4790     }
4791     if (wlc->radio_timer) {
4792         brcms_free_timer(wlc->radio_timer);
4793         wlc->radio_timer = NULL;
4794     }
4795 }
4796 
4797 static void brcms_c_detach_module(struct brcms_c_info *wlc)
4798 {
4799     if (wlc->asi) {
4800         brcms_c_antsel_detach(wlc->asi);
4801         wlc->asi = NULL;
4802     }
4803 
4804     if (wlc->ampdu) {
4805         brcms_c_ampdu_detach(wlc->ampdu);
4806         wlc->ampdu = NULL;
4807     }
4808 
4809     brcms_c_stf_detach(wlc);
4810 }
4811 
4812 /*
4813  * low level detach
4814  */
4815 static void brcms_b_detach(struct brcms_c_info *wlc)
4816 {
4817     uint i;
4818     struct brcms_hw_band *band;
4819     struct brcms_hardware *wlc_hw = wlc->hw;
4820 
4821     brcms_b_detach_dmapio(wlc_hw);
4822 
4823     band = wlc_hw->band;
4824     for (i = 0; i < wlc_hw->_nbands; i++) {
4825         if (band->pi) {
4826             /* Detach this band's phy */
4827             wlc_phy_detach(band->pi);
4828             band->pi = NULL;
4829         }
4830         band = wlc_hw->bandstate[OTHERBANDUNIT(wlc)];
4831     }
4832 
4833     /* Free shared phy state */
4834     kfree(wlc_hw->phy_sh);
4835 
4836     wlc_phy_shim_detach(wlc_hw->physhim);
4837 
4838     if (wlc_hw->sih) {
4839         ai_detach(wlc_hw->sih);
4840         wlc_hw->sih = NULL;
4841     }
4842 }
4843 
4844 /*
4845  * Return a count of the number of driver callbacks still pending.
4846  *
4847  * General policy is that brcms_c_detach can only dealloc/free software states.
4848  * It can NOT touch hardware registers since the d11core may be in reset and
4849  * clock may not be available.
4850  * One exception is sb register access, which is possible if crystal is turned
4851  * on after "down" state, driver should avoid software timer with the exception
4852  * of radio_monitor.
4853  */
4854 uint brcms_c_detach(struct brcms_c_info *wlc)
4855 {
4856     uint callbacks;
4857 
4858     if (wlc == NULL)
4859         return 0;
4860 
4861     brcms_b_detach(wlc);
4862 
4863     /* delete software timers */
4864     callbacks = 0;
4865     if (!brcms_c_radio_monitor_stop(wlc))
4866         callbacks++;
4867 
4868     brcms_c_channel_mgr_detach(wlc->cmi);
4869 
4870     brcms_c_timers_deinit(wlc);
4871 
4872     brcms_c_detach_module(wlc);
4873 
4874     brcms_c_detach_mfree(wlc);
4875     return callbacks;
4876 }
4877 
4878 /* update state that depends on the current value of "ap" */
4879 static void brcms_c_ap_upd(struct brcms_c_info *wlc)
4880 {
4881     /* STA-BSS; short capable */
4882     wlc->PLCPHdr_override = BRCMS_PLCP_SHORT;
4883 }
4884 
4885 /* Initialize just the hardware when coming out of POR or S3/S5 system states */
4886 static void brcms_b_hw_up(struct brcms_hardware *wlc_hw)
4887 {
4888     if (wlc_hw->wlc->pub->hw_up)
4889         return;
4890 
4891     brcms_dbg_info(wlc_hw->d11core, "wl%d\n", wlc_hw->unit);
4892 
4893     /*
4894      * Enable pll and xtal, initialize the power control registers,
4895      * and force fastclock for the remainder of brcms_c_up().
4896      */
4897     brcms_b_xtal(wlc_hw, ON);
4898     ai_clkctl_init(wlc_hw->sih);
4899     brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
4900 
4901     /*
4902      * TODO: test suspend/resume
4903      *
4904      * AI chip doesn't restore bar0win2 on
4905      * hibernation/resume, need sw fixup
4906      */
4907 
4908     /*
4909      * Inform phy that a POR reset has occurred so
4910      * it does a complete phy init
4911      */
4912     wlc_phy_por_inform(wlc_hw->band->pi);
4913 
4914     wlc_hw->ucode_loaded = false;
4915     wlc_hw->wlc->pub->hw_up = true;
4916 
4917     if ((wlc_hw->boardflags & BFL_FEM)
4918         && (ai_get_chip_id(wlc_hw->sih) == BCMA_CHIP_ID_BCM4313)) {
4919         if (!
4920             (wlc_hw->boardrev >= 0x1250
4921              && (wlc_hw->boardflags & BFL_FEM_BT)))
4922             ai_epa_4313war(wlc_hw->sih);
4923     }
4924 }
4925 
4926 static int brcms_b_up_prep(struct brcms_hardware *wlc_hw)
4927 {
4928     brcms_dbg_info(wlc_hw->d11core, "wl%d\n", wlc_hw->unit);
4929 
4930     /*
4931      * Enable pll and xtal, initialize the power control registers,
4932      * and force fastclock for the remainder of brcms_c_up().
4933      */
4934     brcms_b_xtal(wlc_hw, ON);
4935     ai_clkctl_init(wlc_hw->sih);
4936     brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
4937 
4938     /*
4939      * Configure pci/pcmcia here instead of in brcms_c_attach()
4940      * to allow mfg hotswap:  down, hotswap (chip power cycle), up.
4941      */
4942     bcma_host_pci_irq_ctl(wlc_hw->d11core->bus, wlc_hw->d11core,
4943                   true);
4944 
4945     /*
4946      * Need to read the hwradio status here to cover the case where the
4947      * system is loaded with the hw radio disabled. We do not want to
4948      * bring the driver up in this case.
4949      */
4950     if (brcms_b_radio_read_hwdisabled(wlc_hw)) {
4951         /* put SB PCI in down state again */
4952         bcma_host_pci_down(wlc_hw->d11core->bus);
4953         brcms_b_xtal(wlc_hw, OFF);
4954         return -ENOMEDIUM;
4955     }
4956 
4957     bcma_host_pci_up(wlc_hw->d11core->bus);
4958 
4959     /* reset the d11 core */
4960     brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS);
4961 
4962     return 0;
4963 }
4964 
4965 static int brcms_b_up_finish(struct brcms_hardware *wlc_hw)
4966 {
4967     wlc_hw->up = true;
4968     wlc_phy_hw_state_upd(wlc_hw->band->pi, true);
4969 
4970     /* FULLY enable dynamic power control and d11 core interrupt */
4971     brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_DYNAMIC);
4972     brcms_intrson(wlc_hw->wlc->wl);
4973     return 0;
4974 }
4975 
4976 /*
4977  * Write WME tunable parameters for retransmit/max rate
4978  * from wlc struct to ucode
4979  */
4980 static void brcms_c_wme_retries_write(struct brcms_c_info *wlc)
4981 {
4982     int ac;
4983 
4984     /* Need clock to do this */
4985     if (!wlc->clk)
4986         return;
4987 
4988     for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
4989         brcms_b_write_shm(wlc->hw, M_AC_TXLMT_ADDR(ac),
4990                   wlc->wme_retries[ac]);
4991 }
4992 
4993 /* make interface operational */
4994 int brcms_c_up(struct brcms_c_info *wlc)
4995 {
4996     struct ieee80211_channel *ch;
4997 
4998     brcms_dbg_info(wlc->hw->d11core, "wl%d\n", wlc->pub->unit);
4999 
5000     /* HW is turned off so don't try to access it */
5001     if (wlc->pub->hw_off || brcms_deviceremoved(wlc))
5002         return -ENOMEDIUM;
5003 
5004     if (!wlc->pub->hw_up) {
5005         brcms_b_hw_up(wlc->hw);
5006         wlc->pub->hw_up = true;
5007     }
5008 
5009     if ((wlc->pub->boardflags & BFL_FEM)
5010         && (ai_get_chip_id(wlc->hw->sih) == BCMA_CHIP_ID_BCM4313)) {
5011         if (wlc->pub->boardrev >= 0x1250
5012             && (wlc->pub->boardflags & BFL_FEM_BT))
5013             brcms_b_mhf(wlc->hw, MHF5, MHF5_4313_GPIOCTRL,
5014                 MHF5_4313_GPIOCTRL, BRCM_BAND_ALL);
5015         else
5016             brcms_b_mhf(wlc->hw, MHF4, MHF4_EXTPA_ENABLE,
5017                     MHF4_EXTPA_ENABLE, BRCM_BAND_ALL);
5018     }
5019 
5020     /*
5021      * Need to read the hwradio status here to cover the case where the
5022      * system is loaded with the hw radio disabled. We do not want to bring
5023      * the driver up in this case. If radio is disabled, abort up, lower
5024      * power, start radio timer and return 0(for NDIS) don't call
5025      * radio_update to avoid looping brcms_c_up.
5026      *
5027      * brcms_b_up_prep() returns either 0 or -BCME_RADIOOFF only
5028      */
5029     if (!wlc->pub->radio_disabled) {
5030         int status = brcms_b_up_prep(wlc->hw);
5031         if (status == -ENOMEDIUM) {
5032             if (!mboolisset
5033                 (wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE)) {
5034                 struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
5035                 mboolset(wlc->pub->radio_disabled,
5036                      WL_RADIO_HW_DISABLE);
5037                 if (bsscfg->type == BRCMS_TYPE_STATION ||
5038                     bsscfg->type == BRCMS_TYPE_ADHOC)
5039                     brcms_err(wlc->hw->d11core,
5040                           "wl%d: up: rfdisable -> "
5041                           "bsscfg_disable()\n",
5042                            wlc->pub->unit);
5043             }
5044         }
5045     }
5046 
5047     if (wlc->pub->radio_disabled) {
5048         brcms_c_radio_monitor_start(wlc);
5049         return 0;
5050     }
5051 
5052     /* brcms_b_up_prep has done brcms_c_corereset(). so clk is on, set it */
5053     wlc->clk = true;
5054 
5055     brcms_c_radio_monitor_stop(wlc);
5056 
5057     /* Set EDCF hostflags */
5058     brcms_b_mhf(wlc->hw, MHF1, MHF1_EDCF, MHF1_EDCF, BRCM_BAND_ALL);
5059 
5060     brcms_init(wlc->wl);
5061     wlc->pub->up = true;
5062 
5063     if (wlc->bandinit_pending) {
5064         ch = wlc->pub->ieee_hw->conf.chandef.chan;
5065         brcms_c_suspend_mac_and_wait(wlc);
5066         brcms_c_set_chanspec(wlc, ch20mhz_chspec(ch->hw_value));
5067         wlc->bandinit_pending = false;
5068         brcms_c_enable_mac(wlc);
5069     }
5070 
5071     brcms_b_up_finish(wlc->hw);
5072 
5073     /* Program the TX wme params with the current settings */
5074     brcms_c_wme_retries_write(wlc);
5075 
5076     /* start one second watchdog timer */
5077     brcms_add_timer(wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, true);
5078     wlc->WDarmed = true;
5079 
5080     /* ensure antenna config is up to date */
5081     brcms_c_stf_phy_txant_upd(wlc);
5082     /* ensure LDPC config is in sync */
5083     brcms_c_ht_update_ldpc(wlc, wlc->stf->ldpc);
5084 
5085     return 0;
5086 }
5087 
5088 static int brcms_b_bmac_down_prep(struct brcms_hardware *wlc_hw)
5089 {
5090     bool dev_gone;
5091     uint callbacks = 0;
5092 
5093     if (!wlc_hw->up)
5094         return callbacks;
5095 
5096     dev_gone = brcms_deviceremoved(wlc_hw->wlc);
5097 
5098     /* disable interrupts */
5099     if (dev_gone)
5100         wlc_hw->wlc->macintmask = 0;
5101     else {
5102         /* now disable interrupts */
5103         brcms_intrsoff(wlc_hw->wlc->wl);
5104 
5105         /* ensure we're running on the pll clock again */
5106         brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
5107     }
5108     /* down phy at the last of this stage */
5109     callbacks += wlc_phy_down(wlc_hw->band->pi);
5110 
5111     return callbacks;
5112 }
5113 
5114 static int brcms_b_down_finish(struct brcms_hardware *wlc_hw)
5115 {
5116     uint callbacks = 0;
5117     bool dev_gone;
5118 
5119     if (!wlc_hw->up)
5120         return callbacks;
5121 
5122     wlc_hw->up = false;
5123     wlc_phy_hw_state_upd(wlc_hw->band->pi, false);
5124 
5125     dev_gone = brcms_deviceremoved(wlc_hw->wlc);
5126 
5127     if (dev_gone) {
5128         wlc_hw->sbclk = false;
5129         wlc_hw->clk = false;
5130         wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false);
5131 
5132         /* reclaim any posted packets */
5133         brcms_c_flushqueues(wlc_hw->wlc);
5134     } else {
5135 
5136         /* Reset and disable the core */
5137         if (bcma_core_is_enabled(wlc_hw->d11core)) {
5138             if (bcma_read32(wlc_hw->d11core,
5139                     D11REGOFFS(maccontrol)) & MCTL_EN_MAC)
5140                 brcms_c_suspend_mac_and_wait(wlc_hw->wlc);
5141             callbacks += brcms_reset(wlc_hw->wlc->wl);
5142             brcms_c_coredisable(wlc_hw);
5143         }
5144 
5145         /* turn off primary xtal and pll */
5146         if (!wlc_hw->noreset) {
5147             bcma_host_pci_down(wlc_hw->d11core->bus);
5148             brcms_b_xtal(wlc_hw, OFF);
5149         }
5150     }
5151 
5152     return callbacks;
5153 }
5154 
5155 /*
5156  * Mark the interface nonoperational, stop the software mechanisms,
5157  * disable the hardware, free any transient buffer state.
5158  * Return a count of the number of driver callbacks still pending.
5159  */
5160 uint brcms_c_down(struct brcms_c_info *wlc)
5161 {
5162 
5163     uint callbacks = 0;
5164     int i;
5165 
5166     brcms_dbg_info(wlc->hw->d11core, "wl%d\n", wlc->pub->unit);
5167 
5168     /* check if we are already in the going down path */
5169     if (wlc->going_down) {
5170         brcms_err(wlc->hw->d11core,
5171               "wl%d: %s: Driver going down so return\n",
5172               wlc->pub->unit, __func__);
5173         return 0;
5174     }
5175     if (!wlc->pub->up)
5176         return callbacks;
5177 
5178     wlc->going_down = true;
5179 
5180     callbacks += brcms_b_bmac_down_prep(wlc->hw);
5181 
5182     brcms_deviceremoved(wlc);
5183 
5184     /* Call any registered down handlers */
5185     for (i = 0; i < BRCMS_MAXMODULES; i++) {
5186         if (wlc->modulecb[i].down_fn)
5187             callbacks +=
5188                 wlc->modulecb[i].down_fn(wlc->modulecb[i].hdl);
5189     }
5190 
5191     /* cancel the watchdog timer */
5192     if (wlc->WDarmed) {
5193         if (!brcms_del_timer(wlc->wdtimer))
5194             callbacks++;
5195         wlc->WDarmed = false;
5196     }
5197 
5198     wlc->pub->up = false;
5199 
5200     wlc_phy_mute_upd(wlc->band->pi, false, PHY_MUTE_ALL);
5201 
5202     callbacks += brcms_b_down_finish(wlc->hw);
5203 
5204     /* brcms_b_down_finish has done brcms_c_coredisable(). so clk is off */
5205     wlc->clk = false;
5206 
5207     wlc->going_down = false;
5208     return callbacks;
5209 }
5210 
5211 /* Set the current gmode configuration */
5212 int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config)
5213 {
5214     int ret = 0;
5215     uint i;
5216     struct brcms_c_rateset rs;
5217     /* Default to 54g Auto */
5218     /* Advertise and use shortslot (-1/0/1 Auto/Off/On) */
5219     s8 shortslot = BRCMS_SHORTSLOT_AUTO;
5220     bool ofdm_basic = false;    /* Make 6, 12, and 24 basic rates */
5221     struct brcms_band *band;
5222 
5223     /* if N-support is enabled, allow Gmode set as long as requested
5224      * Gmode is not GMODE_LEGACY_B
5225      */
5226     if ((wlc->pub->_n_enab & SUPPORT_11N) && gmode == GMODE_LEGACY_B)
5227         return -ENOTSUPP;
5228 
5229     /* verify that we are dealing with 2G band and grab the band pointer */
5230     if (wlc->band->bandtype == BRCM_BAND_2G)
5231         band = wlc->band;
5232     else if ((wlc->pub->_nbands > 1) &&
5233          (wlc->bandstate[OTHERBANDUNIT(wlc)]->bandtype == BRCM_BAND_2G))
5234         band = wlc->bandstate[OTHERBANDUNIT(wlc)];
5235     else
5236         return -EINVAL;
5237 
5238     /* update configuration value */
5239     if (config)
5240         brcms_c_protection_upd(wlc, BRCMS_PROT_G_USER, gmode);
5241 
5242     /* Clear rateset override */
5243     memset(&rs, 0, sizeof(rs));
5244 
5245     switch (gmode) {
5246     case GMODE_LEGACY_B:
5247         shortslot = BRCMS_SHORTSLOT_OFF;
5248         brcms_c_rateset_copy(&gphy_legacy_rates, &rs);
5249 
5250         break;
5251 
5252     case GMODE_LRS:
5253         break;
5254 
5255     case GMODE_AUTO:
5256         /* Accept defaults */
5257         break;
5258 
5259     case GMODE_ONLY:
5260         ofdm_basic = true;
5261         break;
5262 
5263     case GMODE_PERFORMANCE:
5264         shortslot = BRCMS_SHORTSLOT_ON;
5265         ofdm_basic = true;
5266         break;
5267 
5268     default:
5269         /* Error */
5270         brcms_err(wlc->hw->d11core, "wl%d: %s: invalid gmode %d\n",
5271               wlc->pub->unit, __func__, gmode);
5272         return -ENOTSUPP;
5273     }
5274 
5275     band->gmode = gmode;
5276 
5277     wlc->shortslot_override = shortslot;
5278 
5279     /* Use the default 11g rateset */
5280     if (!rs.count)
5281         brcms_c_rateset_copy(&cck_ofdm_rates, &rs);
5282 
5283     if (ofdm_basic) {
5284         for (i = 0; i < rs.count; i++) {
5285             if (rs.rates[i] == BRCM_RATE_6M
5286                 || rs.rates[i] == BRCM_RATE_12M
5287                 || rs.rates[i] == BRCM_RATE_24M)
5288                 rs.rates[i] |= BRCMS_RATE_FLAG;
5289         }
5290     }
5291 
5292     /* Set default bss rateset */
5293     wlc->default_bss->rateset.count = rs.count;
5294     memcpy(wlc->default_bss->rateset.rates, rs.rates,
5295            sizeof(wlc->default_bss->rateset.rates));
5296 
5297     return ret;
5298 }
5299 
5300 int brcms_c_set_nmode(struct brcms_c_info *wlc)
5301 {
5302     uint i;
5303     s32 nmode = AUTO;
5304 
5305     if (wlc->stf->txstreams == WL_11N_3x3)
5306         nmode = WL_11N_3x3;
5307     else
5308         nmode = WL_11N_2x2;
5309 
5310     /* force GMODE_AUTO if NMODE is ON */
5311     brcms_c_set_gmode(wlc, GMODE_AUTO, true);
5312     if (nmode == WL_11N_3x3)
5313         wlc->pub->_n_enab = SUPPORT_HT;
5314     else
5315         wlc->pub->_n_enab = SUPPORT_11N;
5316     wlc->default_bss->flags |= BRCMS_BSS_HT;
5317     /* add the mcs rates to the default and hw ratesets */
5318     brcms_c_rateset_mcs_build(&wlc->default_bss->rateset,
5319                   wlc->stf->txstreams);
5320     for (i = 0; i < wlc->pub->_nbands; i++)
5321         memcpy(wlc->bandstate[i]->hw_rateset.mcs,
5322                wlc->default_bss->rateset.mcs, MCSSET_LEN);
5323 
5324     return 0;
5325 }
5326 
5327 static int
5328 brcms_c_set_internal_rateset(struct brcms_c_info *wlc,
5329                  struct brcms_c_rateset *rs_arg)
5330 {
5331     struct brcms_c_rateset rs, new;
5332     uint bandunit;
5333 
5334     memcpy(&rs, rs_arg, sizeof(struct brcms_c_rateset));
5335 
5336     /* check for bad count value */
5337     if ((rs.count == 0) || (rs.count > BRCMS_NUMRATES))
5338         return -EINVAL;
5339 
5340     /* try the current band */
5341     bandunit = wlc->band->bandunit;
5342     memcpy(&new, &rs, sizeof(struct brcms_c_rateset));
5343     if (brcms_c_rate_hwrs_filter_sort_validate
5344         (&new, &wlc->bandstate[bandunit]->hw_rateset, true,
5345          wlc->stf->txstreams))
5346         goto good;
5347 
5348     /* try the other band */
5349     if (brcms_is_mband_unlocked(wlc)) {
5350         bandunit = OTHERBANDUNIT(wlc);
5351         memcpy(&new, &rs, sizeof(struct brcms_c_rateset));
5352         if (brcms_c_rate_hwrs_filter_sort_validate(&new,
5353                                &wlc->
5354                                bandstate[bandunit]->
5355                                hw_rateset, true,
5356                                wlc->stf->txstreams))
5357             goto good;
5358     }
5359 
5360     return -EBADE;
5361 
5362  good:
5363     /* apply new rateset */
5364     memcpy(&wlc->default_bss->rateset, &new,
5365            sizeof(struct brcms_c_rateset));
5366     memcpy(&wlc->bandstate[bandunit]->defrateset, &new,
5367            sizeof(struct brcms_c_rateset));
5368     return 0;
5369 }
5370 
5371 static void brcms_c_ofdm_rateset_war(struct brcms_c_info *wlc)
5372 {
5373     wlc_phy_ofdm_rateset_war(wlc->band->pi, false);
5374 }
5375 
5376 int brcms_c_set_channel(struct brcms_c_info *wlc, u16 channel)
5377 {
5378     u16 chspec = ch20mhz_chspec(channel);
5379 
5380     if (channel > MAXCHANNEL)
5381         return -EINVAL;
5382 
5383     if (!brcms_c_valid_chanspec_db(wlc->cmi, chspec))
5384         return -EINVAL;
5385 
5386 
5387     if (!wlc->pub->up && brcms_is_mband_unlocked(wlc)) {
5388         if (wlc->band->bandunit != chspec_bandunit(chspec))
5389             wlc->bandinit_pending = true;
5390         else
5391             wlc->bandinit_pending = false;
5392     }
5393 
5394     wlc->default_bss->chanspec = chspec;
5395     /* brcms_c_BSSinit() will sanitize the rateset before
5396      * using it.. */
5397     if (wlc->pub->up && (wlc_phy_chanspec_get(wlc->band->pi) != chspec)) {
5398         brcms_c_set_home_chanspec(wlc, chspec);
5399         brcms_c_suspend_mac_and_wait(wlc);
5400         brcms_c_set_chanspec(wlc, chspec);
5401         brcms_c_enable_mac(wlc);
5402     }
5403     return 0;
5404 }
5405 
5406 int brcms_c_set_rate_limit(struct brcms_c_info *wlc, u16 srl, u16 lrl)
5407 {
5408     int ac;
5409 
5410     if (srl < 1 || srl > RETRY_SHORT_MAX ||
5411         lrl < 1 || lrl > RETRY_SHORT_MAX)
5412         return -EINVAL;
5413 
5414     wlc->SRL = srl;
5415     wlc->LRL = lrl;
5416 
5417     brcms_b_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL);
5418 
5419     for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
5420         wlc->wme_retries[ac] =  SFIELD(wlc->wme_retries[ac],
5421                            EDCF_SHORT,  wlc->SRL);
5422         wlc->wme_retries[ac] =  SFIELD(wlc->wme_retries[ac],
5423                            EDCF_LONG, wlc->LRL);
5424     }
5425     brcms_c_wme_retries_write(wlc);
5426 
5427     return 0;
5428 }
5429 
5430 void brcms_c_get_current_rateset(struct brcms_c_info *wlc,
5431                  struct brcm_rateset *currs)
5432 {
5433     struct brcms_c_rateset *rs;
5434 
5435     if (wlc->pub->associated)
5436         rs = &wlc->bsscfg->current_bss->rateset;
5437     else
5438         rs = &wlc->default_bss->rateset;
5439 
5440     /* Copy only legacy rateset section */
5441     currs->count = rs->count;
5442     memcpy(&currs->rates, &rs->rates, rs->count);
5443 }
5444 
5445 int brcms_c_set_rateset(struct brcms_c_info *wlc, struct brcm_rateset *rs)
5446 {
5447     struct brcms_c_rateset internal_rs;
5448     int bcmerror;
5449 
5450     if (rs->count > BRCMS_NUMRATES)
5451         return -ENOBUFS;
5452 
5453     memset(&internal_rs, 0, sizeof(internal_rs));
5454 
5455     /* Copy only legacy rateset section */
5456     internal_rs.count = rs->count;
5457     memcpy(&internal_rs.rates, &rs->rates, internal_rs.count);
5458 
5459     /* merge rateset coming in with the current mcsset */
5460     if (wlc->pub->_n_enab & SUPPORT_11N) {
5461         struct brcms_bss_info *mcsset_bss;
5462         if (wlc->pub->associated)
5463             mcsset_bss = wlc->bsscfg->current_bss;
5464         else
5465             mcsset_bss = wlc->default_bss;
5466         memcpy(internal_rs.mcs, &mcsset_bss->rateset.mcs[0],
5467                MCSSET_LEN);
5468     }
5469 
5470     bcmerror = brcms_c_set_internal_rateset(wlc, &internal_rs);
5471     if (!bcmerror)
5472         brcms_c_ofdm_rateset_war(wlc);
5473 
5474     return bcmerror;
5475 }
5476 
5477 static void brcms_c_time_lock(struct brcms_c_info *wlc)
5478 {
5479     bcma_set32(wlc->hw->d11core, D11REGOFFS(maccontrol), MCTL_TBTTHOLD);
5480     /* Commit the write */
5481     bcma_read32(wlc->hw->d11core, D11REGOFFS(maccontrol));
5482 }
5483 
5484 static void brcms_c_time_unlock(struct brcms_c_info *wlc)
5485 {
5486     bcma_mask32(wlc->hw->d11core, D11REGOFFS(maccontrol), ~MCTL_TBTTHOLD);
5487     /* Commit the write */
5488     bcma_read32(wlc->hw->d11core, D11REGOFFS(maccontrol));
5489 }
5490 
5491 int brcms_c_set_beacon_period(struct brcms_c_info *wlc, u16 period)
5492 {
5493     u32 bcnint_us;
5494 
5495     if (period == 0)
5496         return -EINVAL;
5497 
5498     wlc->default_bss->beacon_period = period;
5499 
5500     bcnint_us = period << 10;
5501     brcms_c_time_lock(wlc);
5502     bcma_write32(wlc->hw->d11core, D11REGOFFS(tsf_cfprep),
5503              (bcnint_us << CFPREP_CBI_SHIFT));
5504     bcma_write32(wlc->hw->d11core, D11REGOFFS(tsf_cfpstart), bcnint_us);
5505     brcms_c_time_unlock(wlc);
5506 
5507     return 0;
5508 }
5509 
5510 u16 brcms_c_get_phy_type(struct brcms_c_info *wlc, int phyidx)
5511 {
5512     return wlc->band->phytype;
5513 }
5514 
5515 void brcms_c_set_shortslot_override(struct brcms_c_info *wlc, s8 sslot_override)
5516 {
5517     wlc->shortslot_override = sslot_override;
5518 
5519     /*
5520      * shortslot is an 11g feature, so no more work if we are
5521      * currently on the 5G band
5522      */
5523     if (wlc->band->bandtype == BRCM_BAND_5G)
5524         return;
5525 
5526     if (wlc->pub->up && wlc->pub->associated) {
5527         /* let watchdog or beacon processing update shortslot */
5528     } else if (wlc->pub->up) {
5529         /* unassociated shortslot is off */
5530         brcms_c_switch_shortslot(wlc, false);
5531     } else {
5532         /* driver is down, so just update the brcms_c_info
5533          * value */
5534         if (wlc->shortslot_override == BRCMS_SHORTSLOT_AUTO)
5535             wlc->shortslot = false;
5536         else
5537             wlc->shortslot =
5538                 (wlc->shortslot_override ==
5539                  BRCMS_SHORTSLOT_ON);
5540     }
5541 }
5542 
5543 /*
5544  * register watchdog and down handlers.
5545  */
5546 int brcms_c_module_register(struct brcms_pub *pub,
5547                 const char *name, struct brcms_info *hdl,
5548                 int (*d_fn)(void *handle))
5549 {
5550     struct brcms_c_info *wlc = (struct brcms_c_info *) pub->wlc;
5551     int i;
5552 
5553     /* find an empty entry and just add, no duplication check! */
5554     for (i = 0; i < BRCMS_MAXMODULES; i++) {
5555         if (wlc->modulecb[i].name[0] == '\0') {
5556             strncpy(wlc->modulecb[i].name, name,
5557                 sizeof(wlc->modulecb[i].name) - 1);
5558             wlc->modulecb[i].hdl = hdl;
5559             wlc->modulecb[i].down_fn = d_fn;
5560             return 0;
5561         }
5562     }
5563 
5564     return -ENOSR;
5565 }
5566 
5567 /* unregister module callbacks */
5568 int brcms_c_module_unregister(struct brcms_pub *pub, const char *name,
5569                   struct brcms_info *hdl)
5570 {
5571     struct brcms_c_info *wlc = (struct brcms_c_info *) pub->wlc;
5572     int i;
5573 
5574     if (wlc == NULL)
5575         return -ENODATA;
5576 
5577     for (i = 0; i < BRCMS_MAXMODULES; i++) {
5578         if (!strcmp(wlc->modulecb[i].name, name) &&
5579             (wlc->modulecb[i].hdl == hdl)) {
5580             memset(&wlc->modulecb[i], 0, sizeof(wlc->modulecb[i]));
5581             return 0;
5582         }
5583     }
5584 
5585     /* table not found! */
5586     return -ENODATA;
5587 }
5588 
5589 static bool brcms_c_chipmatch_pci(struct bcma_device *core)
5590 {
5591     struct pci_dev *pcidev = core->bus->host_pci;
5592     u16 vendor = pcidev->vendor;
5593     u16 device = pcidev->device;
5594 
5595     if (vendor != PCI_VENDOR_ID_BROADCOM) {
5596         pr_err("unknown vendor id %04x\n", vendor);
5597         return false;
5598     }
5599 
5600     if (device == BCM43224_D11N_ID_VEN1 || device == BCM43224_CHIP_ID)
5601         return true;
5602     if ((device == BCM43224_D11N_ID) || (device == BCM43225_D11N2G_ID))
5603         return true;
5604     if (device == BCM4313_D11N2G_ID || device == BCM4313_CHIP_ID)
5605         return true;
5606     if ((device == BCM43236_D11N_ID) || (device == BCM43236_D11N2G_ID))
5607         return true;
5608 
5609     pr_err("unknown device id %04x\n", device);
5610     return false;
5611 }
5612 
5613 static bool brcms_c_chipmatch_soc(struct bcma_device *core)
5614 {
5615     struct bcma_chipinfo *chipinfo = &core->bus->chipinfo;
5616 
5617     if (chipinfo->id == BCMA_CHIP_ID_BCM4716)
5618         return true;
5619 
5620     pr_err("unknown chip id %04x\n", chipinfo->id);
5621     return false;
5622 }
5623 
5624 bool brcms_c_chipmatch(struct bcma_device *core)
5625 {
5626     switch (core->bus->hosttype) {
5627     case BCMA_HOSTTYPE_PCI:
5628         return brcms_c_chipmatch_pci(core);
5629     case BCMA_HOSTTYPE_SOC:
5630         return brcms_c_chipmatch_soc(core);
5631     default:
5632         pr_err("unknown host type: %i\n", core->bus->hosttype);
5633         return false;
5634     }
5635 }
5636 
5637 u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate)
5638 {
5639     u16 table_ptr;
5640     u8 phy_rate, index;
5641 
5642     /* get the phy specific rate encoding for the PLCP SIGNAL field */
5643     if (is_ofdm_rate(rate))
5644         table_ptr = M_RT_DIRMAP_A;
5645     else
5646         table_ptr = M_RT_DIRMAP_B;
5647 
5648     /* for a given rate, the LS-nibble of the PLCP SIGNAL field is
5649      * the index into the rate table.
5650      */
5651     phy_rate = rate_info[rate] & BRCMS_RATE_MASK;
5652     index = phy_rate & 0xf;
5653 
5654     /* Find the SHM pointer to the rate table entry by looking in the
5655      * Direct-map Table
5656      */
5657     return 2 * brcms_b_read_shm(wlc_hw, table_ptr + (index * 2));
5658 }
5659 
5660 /*
5661  * bcmc_fid_generate:
5662  * Generate frame ID for a BCMC packet.  The frag field is not used
5663  * for MC frames so is used as part of the sequence number.
5664  */
5665 static inline u16
5666 bcmc_fid_generate(struct brcms_c_info *wlc, struct brcms_bss_cfg *bsscfg,
5667           struct d11txh *txh)
5668 {
5669     u16 frameid;
5670 
5671     frameid = le16_to_cpu(txh->TxFrameID) & ~(TXFID_SEQ_MASK |
5672                           TXFID_QUEUE_MASK);
5673     frameid |=
5674         (((wlc->
5675            mc_fid_counter++) << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) |
5676         TX_BCMC_FIFO;
5677 
5678     return frameid;
5679 }
5680 
5681 static uint
5682 brcms_c_calc_ack_time(struct brcms_c_info *wlc, u32 rspec,
5683               u8 preamble_type)
5684 {
5685     uint dur = 0;
5686 
5687     /*
5688      * Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that
5689      * is less than or equal to the rate of the immediately previous
5690      * frame in the FES
5691      */
5692     rspec = brcms_basic_rate(wlc, rspec);
5693     /* ACK frame len == 14 == 2(fc) + 2(dur) + 6(ra) + 4(fcs) */
5694     dur =
5695         brcms_c_calc_frame_time(wlc, rspec, preamble_type,
5696                 (DOT11_ACK_LEN + FCS_LEN));
5697     return dur;
5698 }
5699 
5700 static uint
5701 brcms_c_calc_cts_time(struct brcms_c_info *wlc, u32 rspec,
5702               u8 preamble_type)
5703 {
5704     return brcms_c_calc_ack_time(wlc, rspec, preamble_type);
5705 }
5706 
5707 static uint
5708 brcms_c_calc_ba_time(struct brcms_c_info *wlc, u32 rspec,
5709              u8 preamble_type)
5710 {
5711     /*
5712      * Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that
5713      * is less than or equal to the rate of the immediately previous
5714      * frame in the FES
5715      */
5716     rspec = brcms_basic_rate(wlc, rspec);
5717     /* BA len == 32 == 16(ctl hdr) + 4(ba len) + 8(bitmap) + 4(fcs) */
5718     return brcms_c_calc_frame_time(wlc, rspec, preamble_type,
5719                    (DOT11_BA_LEN + DOT11_BA_BITMAP_LEN +
5720                     FCS_LEN));
5721 }
5722 
5723 /* brcms_c_compute_frame_dur()
5724  *
5725  * Calculate the 802.11 MAC header DUR field for MPDU
5726  * DUR for a single frame = 1 SIFS + 1 ACK
5727  * DUR for a frame with following frags = 3 SIFS + 2 ACK + next frag time
5728  *
5729  * rate         MPDU rate in unit of 500kbps
5730  * next_frag_len    next MPDU length in bytes
5731  * preamble_type    use short/GF or long/MM PLCP header
5732  */
5733 static u16
5734 brcms_c_compute_frame_dur(struct brcms_c_info *wlc, u32 rate,
5735               u8 preamble_type, uint next_frag_len)
5736 {
5737     u16 dur, sifs;
5738 
5739     sifs = get_sifs(wlc->band);
5740 
5741     dur = sifs;
5742     dur += (u16) brcms_c_calc_ack_time(wlc, rate, preamble_type);
5743 
5744     if (next_frag_len) {
5745         /* Double the current DUR to get 2 SIFS + 2 ACKs */
5746         dur *= 2;
5747         /* add another SIFS and the frag time */
5748         dur += sifs;
5749         dur +=
5750             (u16) brcms_c_calc_frame_time(wlc, rate, preamble_type,
5751                          next_frag_len);
5752     }
5753     return dur;
5754 }
5755 
5756 /* The opposite of brcms_c_calc_frame_time */
5757 static uint
5758 brcms_c_calc_frame_len(struct brcms_c_info *wlc, u32 ratespec,
5759            u8 preamble_type, uint dur)
5760 {
5761     uint nsyms, mac_len, Ndps, kNdps;
5762     uint rate = rspec2rate(ratespec);
5763 
5764     if (is_mcs_rate(ratespec)) {
5765         uint mcs = ratespec & RSPEC_RATE_MASK;
5766         int tot_streams = mcs_2_txstreams(mcs) + rspec_stc(ratespec);
5767         dur -= PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT);
5768         /* payload calculation matches that of regular ofdm */
5769         if (wlc->band->bandtype == BRCM_BAND_2G)
5770             dur -= DOT11_OFDM_SIGNAL_EXTENSION;
5771         /* kNdbps = kbps * 4 */
5772         kNdps = mcs_2_rate(mcs, rspec_is40mhz(ratespec),
5773                    rspec_issgi(ratespec)) * 4;
5774         nsyms = dur / APHY_SYMBOL_TIME;
5775         mac_len =
5776             ((nsyms * kNdps) -
5777              ((APHY_SERVICE_NBITS + APHY_TAIL_NBITS) * 1000)) / 8000;
5778     } else if (is_ofdm_rate(ratespec)) {
5779         dur -= APHY_PREAMBLE_TIME;
5780         dur -= APHY_SIGNAL_TIME;
5781         /* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */
5782         Ndps = rate * 2;
5783         nsyms = dur / APHY_SYMBOL_TIME;
5784         mac_len =
5785             ((nsyms * Ndps) -
5786              (APHY_SERVICE_NBITS + APHY_TAIL_NBITS)) / 8;
5787     } else {
5788         if (preamble_type & BRCMS_SHORT_PREAMBLE)
5789             dur -= BPHY_PLCP_SHORT_TIME;
5790         else
5791             dur -= BPHY_PLCP_TIME;
5792         mac_len = dur * rate;
5793         /* divide out factor of 2 in rate (1/2 mbps) */
5794         mac_len = mac_len / 8 / 2;
5795     }
5796     return mac_len;
5797 }
5798 
5799 /*
5800  * Return true if the specified rate is supported by the specified band.
5801  * BRCM_BAND_AUTO indicates the current band.
5802  */
5803 static bool brcms_c_valid_rate(struct brcms_c_info *wlc, u32 rspec, int band,
5804             bool verbose)
5805 {
5806     struct brcms_c_rateset *hw_rateset;
5807     uint i;
5808 
5809     if ((band == BRCM_BAND_AUTO) || (band == wlc->band->bandtype))
5810         hw_rateset = &wlc->band->hw_rateset;
5811     else if (wlc->pub->_nbands > 1)
5812         hw_rateset = &wlc->bandstate[OTHERBANDUNIT(wlc)]->hw_rateset;
5813     else
5814         /* other band specified and we are a single band device */
5815         return false;
5816 
5817     /* check if this is a mimo rate */
5818     if (is_mcs_rate(rspec)) {
5819         if ((rspec & RSPEC_RATE_MASK) >= MCS_TABLE_SIZE)
5820             goto error;
5821 
5822         return isset(hw_rateset->mcs, (rspec & RSPEC_RATE_MASK));
5823     }
5824 
5825     for (i = 0; i < hw_rateset->count; i++)
5826         if (hw_rateset->rates[i] == rspec2rate(rspec))
5827             return true;
5828  error:
5829     if (verbose)
5830         brcms_err(wlc->hw->d11core, "wl%d: valid_rate: rate spec 0x%x "
5831               "not in hw_rateset\n", wlc->pub->unit, rspec);
5832 
5833     return false;
5834 }
5835 
5836 static u32
5837 mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band,
5838                u32 int_val)
5839 {
5840     struct bcma_device *core = wlc->hw->d11core;
5841     u8 stf = (int_val & NRATE_STF_MASK) >> NRATE_STF_SHIFT;
5842     u8 rate = int_val & NRATE_RATE_MASK;
5843     u32 rspec;
5844     bool ismcs = ((int_val & NRATE_MCS_INUSE) == NRATE_MCS_INUSE);
5845     bool issgi = ((int_val & NRATE_SGI_MASK) >> NRATE_SGI_SHIFT);
5846     bool override_mcs_only = ((int_val & NRATE_OVERRIDE_MCS_ONLY)
5847                   == NRATE_OVERRIDE_MCS_ONLY);
5848 
5849     if (!ismcs)
5850         return (u32) rate;
5851 
5852     /* validate the combination of rate/mcs/stf is allowed */
5853     if ((wlc->pub->_n_enab & SUPPORT_11N) && ismcs) {
5854         /* mcs only allowed when nmode */
5855         if (stf > PHY_TXC1_MODE_SDM) {
5856             brcms_err(core, "wl%d: %s: Invalid stf\n",
5857                   wlc->pub->unit, __func__);
5858             goto done;
5859         }
5860 
5861         /* mcs 32 is a special case, DUP mode 40 only */
5862         if (rate == 32) {
5863             if (!CHSPEC_IS40(wlc->home_chanspec) ||
5864                 ((stf != PHY_TXC1_MODE_SISO)
5865                  && (stf != PHY_TXC1_MODE_CDD))) {
5866                 brcms_err(core, "wl%d: %s: Invalid mcs 32\n",
5867                       wlc->pub->unit, __func__);
5868                 goto done;
5869             }
5870             /* mcs > 7 must use stf SDM */
5871         } else if (rate > HIGHEST_SINGLE_STREAM_MCS) {
5872             /* mcs > 7 must use stf SDM */
5873             if (stf != PHY_TXC1_MODE_SDM) {
5874                 brcms_dbg_mac80211(core, "wl%d: enabling "
5875                            "SDM mode for mcs %d\n",
5876                            wlc->pub->unit, rate);
5877                 stf = PHY_TXC1_MODE_SDM;
5878             }
5879         } else {
5880             /*
5881              * MCS 0-7 may use SISO, CDD, and for
5882              * phy_rev >= 3 STBC
5883              */
5884             if ((stf > PHY_TXC1_MODE_STBC) ||
5885                 (!BRCMS_STBC_CAP_PHY(wlc)
5886                  && (stf == PHY_TXC1_MODE_STBC))) {
5887                 brcms_err(core, "wl%d: %s: Invalid STBC\n",
5888                       wlc->pub->unit, __func__);
5889                 goto done;
5890             }
5891         }
5892     } else if (is_ofdm_rate(rate)) {
5893         if ((stf != PHY_TXC1_MODE_CDD) && (stf != PHY_TXC1_MODE_SISO)) {
5894             brcms_err(core, "wl%d: %s: Invalid OFDM\n",
5895                   wlc->pub->unit, __func__);
5896             goto done;
5897         }
5898     } else if (is_cck_rate(rate)) {
5899         if ((cur_band->bandtype != BRCM_BAND_2G)
5900             || (stf != PHY_TXC1_MODE_SISO)) {
5901             brcms_err(core, "wl%d: %s: Invalid CCK\n",
5902                   wlc->pub->unit, __func__);
5903             goto done;
5904         }
5905     } else {
5906         brcms_err(core, "wl%d: %s: Unknown rate type\n",
5907               wlc->pub->unit, __func__);
5908         goto done;
5909     }
5910     /* make sure multiple antennae are available for non-siso rates */
5911     if ((stf != PHY_TXC1_MODE_SISO) && (wlc->stf->txstreams == 1)) {
5912         brcms_err(core, "wl%d: %s: SISO antenna but !SISO "
5913               "request\n", wlc->pub->unit, __func__);
5914         goto done;
5915     }
5916 
5917     rspec = rate;
5918     if (ismcs) {
5919         rspec |= RSPEC_MIMORATE;
5920         /* For STBC populate the STC field of the ratespec */
5921         if (stf == PHY_TXC1_MODE_STBC) {
5922             u8 stc;
5923             stc = 1;    /* Nss for single stream is always 1 */
5924             rspec |= (stc << RSPEC_STC_SHIFT);
5925         }
5926     }
5927 
5928     rspec |= (stf << RSPEC_STF_SHIFT);
5929 
5930     if (override_mcs_only)
5931         rspec |= RSPEC_OVERRIDE_MCS_ONLY;
5932 
5933     if (issgi)
5934         rspec |= RSPEC_SHORT_GI;
5935 
5936     if ((rate != 0)
5937         && !brcms_c_valid_rate(wlc, rspec, cur_band->bandtype, true))
5938         return rate;
5939 
5940     return rspec;
5941 done:
5942     return rate;
5943 }
5944 
5945 /*
5946  * Compute PLCP, but only requires actual rate and length of pkt.
5947  * Rate is given in the driver standard multiple of 500 kbps.
5948  * le is set for 11 Mbps rate if necessary.
5949  * Broken out for PRQ.
5950  */
5951 
5952 static void brcms_c_cck_plcp_set(struct brcms_c_info *wlc, int rate_500,
5953                  uint length, u8 *plcp)
5954 {
5955     u16 usec = 0;
5956     u8 le = 0;
5957 
5958     switch (rate_500) {
5959     case BRCM_RATE_1M:
5960         usec = length << 3;
5961         break;
5962     case BRCM_RATE_2M:
5963         usec = length << 2;
5964         break;
5965     case BRCM_RATE_5M5:
5966         usec = (length << 4) / 11;
5967         if ((length << 4) - (usec * 11) > 0)
5968             usec++;
5969         break;
5970     case BRCM_RATE_11M:
5971         usec = (length << 3) / 11;
5972         if ((length << 3) - (usec * 11) > 0) {
5973             usec++;
5974             if ((usec * 11) - (length << 3) >= 8)
5975                 le = D11B_PLCP_SIGNAL_LE;
5976         }
5977         break;
5978 
5979     default:
5980         brcms_err(wlc->hw->d11core,
5981               "brcms_c_cck_plcp_set: unsupported rate %d\n",
5982               rate_500);
5983         rate_500 = BRCM_RATE_1M;
5984         usec = length << 3;
5985         break;
5986     }
5987     /* PLCP signal byte */
5988     plcp[0] = rate_500 * 5; /* r (500kbps) * 5 == r (100kbps) */
5989     /* PLCP service byte */
5990     plcp[1] = (u8) (le | D11B_PLCP_SIGNAL_LOCKED);
5991     /* PLCP length u16, little endian */
5992     plcp[2] = usec & 0xff;
5993     plcp[3] = (usec >> 8) & 0xff;
5994     /* PLCP CRC16 */
5995     plcp[4] = 0;
5996     plcp[5] = 0;
5997 }
5998 
5999 /* Rate: 802.11 rate code, length: PSDU length in octets */
6000 static void brcms_c_compute_mimo_plcp(u32 rspec, uint length, u8 *plcp)
6001 {
6002     u8 mcs = (u8) (rspec & RSPEC_RATE_MASK);
6003     plcp[0] = mcs;
6004     if (rspec_is40mhz(rspec) || (mcs == 32))
6005         plcp[0] |= MIMO_PLCP_40MHZ;
6006     BRCMS_SET_MIMO_PLCP_LEN(plcp, length);
6007     plcp[3] = rspec_mimoplcp3(rspec); /* rspec already holds this byte */
6008     plcp[3] |= 0x7; /* set smoothing, not sounding ppdu & reserved */
6009     plcp[4] = 0; /* number of extension spatial streams bit 0 & 1 */
6010     plcp[5] = 0;
6011 }
6012 
6013 /* Rate: 802.11 rate code, length: PSDU length in octets */
6014 static void
6015 brcms_c_compute_ofdm_plcp(u32 rspec, u32 length, u8 *plcp)
6016 {
6017     u8 rate_signal;
6018     u32 tmp = 0;
6019     int rate = rspec2rate(rspec);
6020 
6021     /*
6022      * encode rate per 802.11a-1999 sec 17.3.4.1, with lsb
6023      * transmitted first
6024      */
6025     rate_signal = rate_info[rate] & BRCMS_RATE_MASK;
6026     memset(plcp, 0, D11_PHY_HDR_LEN);
6027     D11A_PHY_HDR_SRATE((struct ofdm_phy_hdr *) plcp, rate_signal);
6028 
6029     tmp = (length & 0xfff) << 5;
6030     plcp[2] |= (tmp >> 16) & 0xff;
6031     plcp[1] |= (tmp >> 8) & 0xff;
6032     plcp[0] |= tmp & 0xff;
6033 }
6034 
6035 /* Rate: 802.11 rate code, length: PSDU length in octets */
6036 static void brcms_c_compute_cck_plcp(struct brcms_c_info *wlc, u32 rspec,
6037                  uint length, u8 *plcp)
6038 {
6039     int rate = rspec2rate(rspec);
6040 
6041     brcms_c_cck_plcp_set(wlc, rate, length, plcp);
6042 }
6043 
6044 static void
6045 brcms_c_compute_plcp(struct brcms_c_info *wlc, u32 rspec,
6046              uint length, u8 *plcp)
6047 {
6048     if (is_mcs_rate(rspec))
6049         brcms_c_compute_mimo_plcp(rspec, length, plcp);
6050     else if (is_ofdm_rate(rspec))
6051         brcms_c_compute_ofdm_plcp(rspec, length, plcp);
6052     else
6053         brcms_c_compute_cck_plcp(wlc, rspec, length, plcp);
6054 }
6055 
6056 /* brcms_c_compute_rtscts_dur()
6057  *
6058  * Calculate the 802.11 MAC header DUR field for an RTS or CTS frame
6059  * DUR for normal RTS/CTS w/ frame = 3 SIFS + 1 CTS + next frame time + 1 ACK
6060  * DUR for CTS-TO-SELF w/ frame    = 2 SIFS         + next frame time + 1 ACK
6061  *
6062  * cts          cts-to-self or rts/cts
6063  * rts_rate     rts or cts rate in unit of 500kbps
6064  * rate         next MPDU rate in unit of 500kbps
6065  * frame_len        next MPDU frame length in bytes
6066  */
6067 u16
6068 brcms_c_compute_rtscts_dur(struct brcms_c_info *wlc, bool cts_only,
6069                u32 rts_rate,
6070                u32 frame_rate, u8 rts_preamble_type,
6071                u8 frame_preamble_type, uint frame_len, bool ba)
6072 {
6073     u16 dur, sifs;
6074 
6075     sifs = get_sifs(wlc->band);
6076 
6077     if (!cts_only) {
6078         /* RTS/CTS */
6079         dur = 3 * sifs;
6080         dur +=
6081             (u16) brcms_c_calc_cts_time(wlc, rts_rate,
6082                            rts_preamble_type);
6083     } else {
6084         /* CTS-TO-SELF */
6085         dur = 2 * sifs;
6086     }
6087 
6088     dur +=
6089         (u16) brcms_c_calc_frame_time(wlc, frame_rate, frame_preamble_type,
6090                      frame_len);
6091     if (ba)
6092         dur +=
6093             (u16) brcms_c_calc_ba_time(wlc, frame_rate,
6094                           BRCMS_SHORT_PREAMBLE);
6095     else
6096         dur +=
6097             (u16) brcms_c_calc_ack_time(wlc, frame_rate,
6098                            frame_preamble_type);
6099     return dur;
6100 }
6101 
6102 static u16 brcms_c_phytxctl1_calc(struct brcms_c_info *wlc, u32 rspec)
6103 {
6104     u16 phyctl1 = 0;
6105     u16 bw;
6106 
6107     if (BRCMS_ISLCNPHY(wlc->band)) {
6108         bw = PHY_TXC1_BW_20MHZ;
6109     } else {
6110         bw = rspec_get_bw(rspec);
6111         /* 10Mhz is not supported yet */
6112         if (bw < PHY_TXC1_BW_20MHZ) {
6113             brcms_err(wlc->hw->d11core, "phytxctl1_calc: bw %d is "
6114                   "not supported yet, set to 20L\n", bw);
6115             bw = PHY_TXC1_BW_20MHZ;
6116         }
6117     }
6118 
6119     if (is_mcs_rate(rspec)) {
6120         uint mcs = rspec & RSPEC_RATE_MASK;
6121 
6122         /* bw, stf, coding-type is part of rspec_phytxbyte2 returns */
6123         phyctl1 = rspec_phytxbyte2(rspec);
6124         /* set the upper byte of phyctl1 */
6125         phyctl1 |= (mcs_table[mcs].tx_phy_ctl3 << 8);
6126     } else if (is_cck_rate(rspec) && !BRCMS_ISLCNPHY(wlc->band)
6127            && !BRCMS_ISSSLPNPHY(wlc->band)) {
6128         /*
6129          * In CCK mode LPPHY overloads OFDM Modulation bits with CCK
6130          * Data Rate. Eventually MIMOPHY would also be converted to
6131          * this format
6132          */
6133         /* 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps */
6134         phyctl1 = (bw | (rspec_stf(rspec) << PHY_TXC1_MODE_SHIFT));
6135     } else {        /* legacy OFDM/CCK */
6136         s16 phycfg;
6137         /* get the phyctl byte from rate phycfg table */
6138         phycfg = brcms_c_rate_legacy_phyctl(rspec2rate(rspec));
6139         if (phycfg == -1) {
6140             brcms_err(wlc->hw->d11core, "phytxctl1_calc: wrong "
6141                   "legacy OFDM/CCK rate\n");
6142             phycfg = 0;
6143         }
6144         /* set the upper byte of phyctl1 */
6145         phyctl1 =
6146             (bw | (phycfg << 8) |
6147              (rspec_stf(rspec) << PHY_TXC1_MODE_SHIFT));
6148     }
6149     return phyctl1;
6150 }
6151 
6152 /*
6153  * Add struct d11txh, struct cck_phy_hdr.
6154  *
6155  * 'p' data must start with 802.11 MAC header
6156  * 'p' must allow enough bytes of local headers to be "pushed" onto the packet
6157  *
6158  * headroom == D11_PHY_HDR_LEN + D11_TXH_LEN (D11_TXH_LEN is now 104 bytes)
6159  *
6160  */
6161 static u16
6162 brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw,
6163              struct sk_buff *p, struct scb *scb, uint frag,
6164              uint nfrags, uint queue, uint next_frag_len)
6165 {
6166     struct ieee80211_hdr *h;
6167     struct d11txh *txh;
6168     u8 *plcp, plcp_fallback[D11_PHY_HDR_LEN];
6169     int len, phylen, rts_phylen;
6170     u16 mch, phyctl, xfts, mainrates;
6171     u16 seq = 0, mcl = 0, status = 0, frameid = 0;
6172     u32 rspec[2] = { BRCM_RATE_1M, BRCM_RATE_1M };
6173     u32 rts_rspec[2] = { BRCM_RATE_1M, BRCM_RATE_1M };
6174     bool use_rts = false;
6175     bool use_cts = false;
6176     bool use_rifs = false;
6177     u8 preamble_type[2] = { BRCMS_LONG_PREAMBLE, BRCMS_LONG_PREAMBLE };
6178     u8 rts_preamble_type[2] = { BRCMS_LONG_PREAMBLE, BRCMS_LONG_PREAMBLE };
6179     u8 *rts_plcp, rts_plcp_fallback[D11_PHY_HDR_LEN];
6180     struct ieee80211_rts *rts = NULL;
6181     bool qos;
6182     uint ac;
6183     bool hwtkmic = false;
6184     u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ;
6185 #define ANTCFG_NONE 0xFF
6186     u8 antcfg = ANTCFG_NONE;
6187     u8 fbantcfg = ANTCFG_NONE;
6188     uint phyctl1_stf = 0;
6189     u16 durid = 0;
6190     struct ieee80211_tx_rate *txrate[2];
6191     int k;
6192     struct ieee80211_tx_info *tx_info;
6193     bool is_mcs;
6194     u16 mimo_txbw;
6195     u8 mimo_preamble_type;
6196 
6197     /* locate 802.11 MAC header */
6198     h = (struct ieee80211_hdr *)(p->data);
6199     qos = ieee80211_is_data_qos(h->frame_control);
6200 
6201     /* compute length of frame in bytes for use in PLCP computations */
6202     len = p->len;
6203     phylen = len + FCS_LEN;
6204 
6205     /* Get tx_info */
6206     tx_info = IEEE80211_SKB_CB(p);
6207 
6208     /* add PLCP */
6209     plcp = skb_push(p, D11_PHY_HDR_LEN);
6210 
6211     /* add Broadcom tx descriptor header */
6212     txh = (struct d11txh *) skb_push(p, D11_TXH_LEN);
6213     memset(txh, 0, D11_TXH_LEN);
6214 
6215     /* setup frameid */
6216     if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
6217         /* non-AP STA should never use BCMC queue */
6218         if (queue == TX_BCMC_FIFO) {
6219             brcms_err(wlc->hw->d11core,
6220                   "wl%d: %s: ASSERT queue == TX_BCMC!\n",
6221                   wlc->pub->unit, __func__);
6222             frameid = bcmc_fid_generate(wlc, NULL, txh);
6223         } else {
6224             /* Increment the counter for first fragment */
6225             if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
6226                 scb->seqnum[p->priority]++;
6227 
6228             /* extract fragment number from frame first */
6229             seq = le16_to_cpu(h->seq_ctrl) & FRAGNUM_MASK;
6230             seq |= (scb->seqnum[p->priority] << SEQNUM_SHIFT);
6231             h->seq_ctrl = cpu_to_le16(seq);
6232 
6233             frameid = ((seq << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) |
6234                 (queue & TXFID_QUEUE_MASK);
6235         }
6236     }
6237     frameid |= queue & TXFID_QUEUE_MASK;
6238 
6239     /* set the ignpmq bit for all pkts tx'd in PS mode and for beacons */
6240     if (ieee80211_is_beacon(h->frame_control))
6241         mcl |= TXC_IGNOREPMQ;
6242 
6243     txrate[0] = tx_info->control.rates;
6244     txrate[1] = txrate[0] + 1;
6245 
6246     /*
6247      * if rate control algorithm didn't give us a fallback
6248      * rate, use the primary rate
6249      */
6250     if (txrate[1]->idx < 0)
6251         txrate[1] = txrate[0];
6252 
6253     for (k = 0; k < hw->max_rates; k++) {
6254         is_mcs = txrate[k]->flags & IEEE80211_TX_RC_MCS ? true : false;
6255         if (!is_mcs) {
6256             if ((txrate[k]->idx >= 0)
6257                 && (txrate[k]->idx <
6258                 hw->wiphy->bands[tx_info->band]->n_bitrates)) {
6259                 rspec[k] =
6260                     hw->wiphy->bands[tx_info->band]->
6261                     bitrates[txrate[k]->idx].hw_value;
6262             } else {
6263                 rspec[k] = BRCM_RATE_1M;
6264             }
6265         } else {
6266             rspec[k] = mac80211_wlc_set_nrate(wlc, wlc->band,
6267                     NRATE_MCS_INUSE | txrate[k]->idx);
6268         }
6269 
6270         /*
6271          * Currently only support same setting for primay and
6272          * fallback rates. Unify flags for each rate into a
6273          * single value for the frame
6274          */
6275         use_rts |=
6276             txrate[k]->
6277             flags & IEEE80211_TX_RC_USE_RTS_CTS ? true : false;
6278         use_cts |=
6279             txrate[k]->
6280             flags & IEEE80211_TX_RC_USE_CTS_PROTECT ? true : false;
6281 
6282 
6283         /*
6284          * (1) RATE:
6285          *   determine and validate primary rate
6286          *   and fallback rates
6287          */
6288         if (!rspec_active(rspec[k])) {
6289             rspec[k] = BRCM_RATE_1M;
6290         } else {
6291             if (!is_multicast_ether_addr(h->addr1)) {
6292                 /* set tx antenna config */
6293                 brcms_c_antsel_antcfg_get(wlc->asi, false,
6294                     false, 0, 0, &antcfg, &fbantcfg);
6295             }
6296         }
6297     }
6298 
6299     phyctl1_stf = wlc->stf->ss_opmode;
6300 
6301     if (wlc->pub->_n_enab & SUPPORT_11N) {
6302         for (k = 0; k < hw->max_rates; k++) {
6303             /*
6304              * apply siso/cdd to single stream mcs's or ofdm
6305              * if rspec is auto selected
6306              */
6307             if (((is_mcs_rate(rspec[k]) &&
6308                   is_single_stream(rspec[k] & RSPEC_RATE_MASK)) ||
6309                  is_ofdm_rate(rspec[k]))
6310                 && ((rspec[k] & RSPEC_OVERRIDE_MCS_ONLY)
6311                 || !(rspec[k] & RSPEC_OVERRIDE))) {
6312                 rspec[k] &= ~(RSPEC_STF_MASK | RSPEC_STC_MASK);
6313 
6314                 /* For SISO MCS use STBC if possible */
6315                 if (is_mcs_rate(rspec[k])
6316                     && BRCMS_STF_SS_STBC_TX(wlc, scb)) {
6317                     u8 stc;
6318 
6319                     /* Nss for single stream is always 1 */
6320                     stc = 1;
6321                     rspec[k] |= (PHY_TXC1_MODE_STBC <<
6322                             RSPEC_STF_SHIFT) |
6323                             (stc << RSPEC_STC_SHIFT);
6324                 } else
6325                     rspec[k] |=
6326                         (phyctl1_stf << RSPEC_STF_SHIFT);
6327             }
6328 
6329             /*
6330              * Is the phy configured to use 40MHZ frames? If
6331              * so then pick the desired txbw
6332              */
6333             if (brcms_chspec_bw(wlc->chanspec) == BRCMS_40_MHZ) {
6334                 /* default txbw is 20in40 SB */
6335                 mimo_ctlchbw = mimo_txbw =
6336                    CHSPEC_SB_UPPER(wlc_phy_chanspec_get(
6337                                  wlc->band->pi))
6338                    ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ;
6339 
6340                 if (is_mcs_rate(rspec[k])) {
6341                     /* mcs 32 must be 40b/w DUP */
6342                     if ((rspec[k] & RSPEC_RATE_MASK)
6343                         == 32) {
6344                         mimo_txbw =
6345                             PHY_TXC1_BW_40MHZ_DUP;
6346                         /* use override */
6347                     } else if (wlc->mimo_40txbw != AUTO)
6348                         mimo_txbw = wlc->mimo_40txbw;
6349                     /* else check if dst is using 40 Mhz */
6350                     else if (scb->flags & SCB_IS40)
6351                         mimo_txbw = PHY_TXC1_BW_40MHZ;
6352                 } else if (is_ofdm_rate(rspec[k])) {
6353                     if (wlc->ofdm_40txbw != AUTO)
6354                         mimo_txbw = wlc->ofdm_40txbw;
6355                 } else if (wlc->cck_40txbw != AUTO) {
6356                     mimo_txbw = wlc->cck_40txbw;
6357                 }
6358             } else {
6359                 /*
6360                  * mcs32 is 40 b/w only.
6361                  * This is possible for probe packets on
6362                  * a STA during SCAN
6363                  */
6364                 if ((rspec[k] & RSPEC_RATE_MASK) == 32)
6365                     /* mcs 0 */
6366                     rspec[k] = RSPEC_MIMORATE;
6367 
6368                 mimo_txbw = PHY_TXC1_BW_20MHZ;
6369             }
6370 
6371             /* Set channel width */
6372             rspec[k] &= ~RSPEC_BW_MASK;
6373             if ((k == 0) || ((k > 0) && is_mcs_rate(rspec[k])))
6374                 rspec[k] |= (mimo_txbw << RSPEC_BW_SHIFT);
6375             else
6376                 rspec[k] |= (mimo_ctlchbw << RSPEC_BW_SHIFT);
6377 
6378             /* Disable short GI, not supported yet */
6379             rspec[k] &= ~RSPEC_SHORT_GI;
6380 
6381             mimo_preamble_type = BRCMS_MM_PREAMBLE;
6382             if (txrate[k]->flags & IEEE80211_TX_RC_GREEN_FIELD)
6383                 mimo_preamble_type = BRCMS_GF_PREAMBLE;
6384 
6385             if ((txrate[k]->flags & IEEE80211_TX_RC_MCS)
6386                 && (!is_mcs_rate(rspec[k]))) {
6387                 brcms_warn(wlc->hw->d11core,
6388                        "wl%d: %s: IEEE80211_TX_RC_MCS != is_mcs_rate(rspec)\n",
6389                        wlc->pub->unit, __func__);
6390             }
6391 
6392             if (is_mcs_rate(rspec[k])) {
6393                 preamble_type[k] = mimo_preamble_type;
6394 
6395                 /*
6396                  * if SGI is selected, then forced mm
6397                  * for single stream
6398                  */
6399                 if ((rspec[k] & RSPEC_SHORT_GI)
6400                     && is_single_stream(rspec[k] &
6401                             RSPEC_RATE_MASK))
6402                     preamble_type[k] = BRCMS_MM_PREAMBLE;
6403             }
6404 
6405             /* should be better conditionalized */
6406             if (!is_mcs_rate(rspec[0])
6407                 && (tx_info->control.rates[0].
6408                 flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE))
6409                 preamble_type[k] = BRCMS_SHORT_PREAMBLE;
6410         }
6411     } else {
6412         for (k = 0; k < hw->max_rates; k++) {
6413             /* Set ctrlchbw as 20Mhz */
6414             rspec[k] &= ~RSPEC_BW_MASK;
6415             rspec[k] |= (PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT);
6416 
6417             /* for nphy, stf of ofdm frames must follow policies */
6418             if (BRCMS_ISNPHY(wlc->band) && is_ofdm_rate(rspec[k])) {
6419                 rspec[k] &= ~RSPEC_STF_MASK;
6420                 rspec[k] |= phyctl1_stf << RSPEC_STF_SHIFT;
6421             }
6422         }
6423     }
6424 
6425     /* Reset these for use with AMPDU's */
6426     txrate[0]->count = 0;
6427     txrate[1]->count = 0;
6428 
6429     /* (2) PROTECTION, may change rspec */
6430     if ((ieee80211_is_data(h->frame_control) ||
6431         ieee80211_is_mgmt(h->frame_control)) &&
6432         (phylen > wlc->RTSThresh) && !is_multicast_ether_addr(h->addr1))
6433         use_rts = true;
6434 
6435     /* (3) PLCP: determine PLCP header and MAC duration,
6436      * fill struct d11txh */
6437     brcms_c_compute_plcp(wlc, rspec[0], phylen, plcp);
6438     brcms_c_compute_plcp(wlc, rspec[1], phylen, plcp_fallback);
6439     memcpy(&txh->FragPLCPFallback,
6440            plcp_fallback, sizeof(txh->FragPLCPFallback));
6441 
6442     /* Length field now put in CCK FBR CRC field */
6443     if (is_cck_rate(rspec[1])) {
6444         txh->FragPLCPFallback[4] = phylen & 0xff;
6445         txh->FragPLCPFallback[5] = (phylen & 0xff00) >> 8;
6446     }
6447 
6448     /* MIMO-RATE: need validation ?? */
6449     mainrates = is_ofdm_rate(rspec[0]) ?
6450             D11A_PHY_HDR_GRATE((struct ofdm_phy_hdr *) plcp) :
6451             plcp[0];
6452 
6453     /* DUR field for main rate */
6454     if (!ieee80211_is_pspoll(h->frame_control) &&
6455         !is_multicast_ether_addr(h->addr1) && !use_rifs) {
6456         durid =
6457             brcms_c_compute_frame_dur(wlc, rspec[0], preamble_type[0],
6458                       next_frag_len);
6459         h->duration_id = cpu_to_le16(durid);
6460     } else if (use_rifs) {
6461         /* NAV protect to end of next max packet size */
6462         durid =
6463             (u16) brcms_c_calc_frame_time(wlc, rspec[0],
6464                          preamble_type[0],
6465                          DOT11_MAX_FRAG_LEN);
6466         durid += RIFS_11N_TIME;
6467         h->duration_id = cpu_to_le16(durid);
6468     }
6469 
6470     /* DUR field for fallback rate */
6471     if (ieee80211_is_pspoll(h->frame_control))
6472         txh->FragDurFallback = h->duration_id;
6473     else if (is_multicast_ether_addr(h->addr1) || use_rifs)
6474         txh->FragDurFallback = 0;
6475     else {
6476         durid = brcms_c_compute_frame_dur(wlc, rspec[1],
6477                           preamble_type[1], next_frag_len);
6478         txh->FragDurFallback = cpu_to_le16(durid);
6479     }
6480 
6481     /* (4) MAC-HDR: MacTxControlLow */
6482     if (frag == 0)
6483         mcl |= TXC_STARTMSDU;
6484 
6485     if (!is_multicast_ether_addr(h->addr1))
6486         mcl |= TXC_IMMEDACK;
6487 
6488     if (wlc->band->bandtype == BRCM_BAND_5G)
6489         mcl |= TXC_FREQBAND_5G;
6490 
6491     if (CHSPEC_IS40(wlc_phy_chanspec_get(wlc->band->pi)))
6492         mcl |= TXC_BW_40;
6493 
6494     /* set AMIC bit if using hardware TKIP MIC */
6495     if (hwtkmic)
6496         mcl |= TXC_AMIC;
6497 
6498     txh->MacTxControlLow = cpu_to_le16(mcl);
6499 
6500     /* MacTxControlHigh */
6501     mch = 0;
6502 
6503     /* Set fallback rate preamble type */
6504     if ((preamble_type[1] == BRCMS_SHORT_PREAMBLE) ||
6505         (preamble_type[1] == BRCMS_GF_PREAMBLE)) {
6506         if (rspec2rate(rspec[1]) != BRCM_RATE_1M)
6507             mch |= TXC_PREAMBLE_DATA_FB_SHORT;
6508     }
6509 
6510     /* MacFrameControl */
6511     memcpy(&txh->MacFrameControl, &h->frame_control, sizeof(u16));
6512     txh->TxFesTimeNormal = cpu_to_le16(0);
6513 
6514     txh->TxFesTimeFallback = cpu_to_le16(0);
6515 
6516     /* TxFrameRA */
6517     memcpy(&txh->TxFrameRA, &h->addr1, ETH_ALEN);
6518 
6519     /* TxFrameID */
6520     txh->TxFrameID = cpu_to_le16(frameid);
6521 
6522     /*
6523      * TxStatus, Note the case of recreating the first frag of a suppressed
6524      * frame then we may need to reset the retry cnt's via the status reg
6525      */
6526     txh->TxStatus = cpu_to_le16(status);
6527 
6528     /*
6529      * extra fields for ucode AMPDU aggregation, the new fields are added to
6530      * the END of previous structure so that it's compatible in driver.
6531      */
6532     txh->MaxNMpdus = cpu_to_le16(0);
6533     txh->MaxABytes_MRT = cpu_to_le16(0);
6534     txh->MaxABytes_FBR = cpu_to_le16(0);
6535     txh->MinMBytes = cpu_to_le16(0);
6536 
6537     /* (5) RTS/CTS: determine RTS/CTS PLCP header and MAC duration,
6538      * furnish struct d11txh */
6539     /* RTS PLCP header and RTS frame */
6540     if (use_rts || use_cts) {
6541         if (use_rts && use_cts)
6542             use_cts = false;
6543 
6544         for (k = 0; k < 2; k++) {
6545             rts_rspec[k] = brcms_c_rspec_to_rts_rspec(wlc, rspec[k],
6546                                   false,
6547                                   mimo_ctlchbw);
6548         }
6549 
6550         if (!is_ofdm_rate(rts_rspec[0]) &&
6551             !((rspec2rate(rts_rspec[0]) == BRCM_RATE_1M) ||
6552               (wlc->PLCPHdr_override == BRCMS_PLCP_LONG))) {
6553             rts_preamble_type[0] = BRCMS_SHORT_PREAMBLE;
6554             mch |= TXC_PREAMBLE_RTS_MAIN_SHORT;
6555         }
6556 
6557         if (!is_ofdm_rate(rts_rspec[1]) &&
6558             !((rspec2rate(rts_rspec[1]) == BRCM_RATE_1M) ||
6559               (wlc->PLCPHdr_override == BRCMS_PLCP_LONG))) {
6560             rts_preamble_type[1] = BRCMS_SHORT_PREAMBLE;
6561             mch |= TXC_PREAMBLE_RTS_FB_SHORT;
6562         }
6563 
6564         /* RTS/CTS additions to MacTxControlLow */
6565         if (use_cts) {
6566             txh->MacTxControlLow |= cpu_to_le16(TXC_SENDCTS);
6567         } else {
6568             txh->MacTxControlLow |= cpu_to_le16(TXC_SENDRTS);
6569             txh->MacTxControlLow |= cpu_to_le16(TXC_LONGFRAME);
6570         }
6571 
6572         /* RTS PLCP header */
6573         rts_plcp = txh->RTSPhyHeader;
6574         if (use_cts)
6575             rts_phylen = DOT11_CTS_LEN + FCS_LEN;
6576         else
6577             rts_phylen = DOT11_RTS_LEN + FCS_LEN;
6578 
6579         brcms_c_compute_plcp(wlc, rts_rspec[0], rts_phylen, rts_plcp);
6580 
6581         /* fallback rate version of RTS PLCP header */
6582         brcms_c_compute_plcp(wlc, rts_rspec[1], rts_phylen,
6583                  rts_plcp_fallback);
6584         memcpy(&txh->RTSPLCPFallback, rts_plcp_fallback,
6585                sizeof(txh->RTSPLCPFallback));
6586 
6587         /* RTS frame fields... */
6588         rts = (struct ieee80211_rts *)&txh->rts_frame;
6589 
6590         durid = brcms_c_compute_rtscts_dur(wlc, use_cts, rts_rspec[0],
6591                            rspec[0], rts_preamble_type[0],
6592                            preamble_type[0], phylen, false);
6593         rts->duration = cpu_to_le16(durid);
6594         /* fallback rate version of RTS DUR field */
6595         durid = brcms_c_compute_rtscts_dur(wlc, use_cts,
6596                            rts_rspec[1], rspec[1],
6597                            rts_preamble_type[1],
6598                            preamble_type[1], phylen, false);
6599         txh->RTSDurFallback = cpu_to_le16(durid);
6600 
6601         if (use_cts) {
6602             rts->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
6603                              IEEE80211_STYPE_CTS);
6604 
6605             memcpy(&rts->ra, &h->addr2, ETH_ALEN);
6606         } else {
6607             rts->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
6608                              IEEE80211_STYPE_RTS);
6609 
6610             memcpy(&rts->ra, &h->addr1, ETH_ALEN);
6611             memcpy(&rts->ta, &h->addr2, ETH_ALEN);
6612         }
6613 
6614         /* mainrate
6615          *    low 8 bits: main frag rate/mcs,
6616          *    high 8 bits: rts/cts rate/mcs
6617          */
6618         mainrates |= (is_ofdm_rate(rts_rspec[0]) ?
6619                 D11A_PHY_HDR_GRATE(
6620                     (struct ofdm_phy_hdr *) rts_plcp) :
6621                 rts_plcp[0]) << 8;
6622     } else {
6623         memset(txh->RTSPhyHeader, 0, D11_PHY_HDR_LEN);
6624         memset(&txh->rts_frame, 0, sizeof(struct ieee80211_rts));
6625         memset(txh->RTSPLCPFallback, 0, sizeof(txh->RTSPLCPFallback));
6626         txh->RTSDurFallback = 0;
6627     }
6628 
6629 #ifdef SUPPORT_40MHZ
6630     /* add null delimiter count */
6631     if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && is_mcs_rate(rspec))
6632         txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] =
6633            brcm_c_ampdu_null_delim_cnt(wlc->ampdu, scb, rspec, phylen);
6634 
6635 #endif
6636 
6637     /*
6638      * Now that RTS/RTS FB preamble types are updated, write
6639      * the final value
6640      */
6641     txh->MacTxControlHigh = cpu_to_le16(mch);
6642 
6643     /*
6644      * MainRates (both the rts and frag plcp rates have
6645      * been calculated now)
6646      */
6647     txh->MainRates = cpu_to_le16(mainrates);
6648 
6649     /* XtraFrameTypes */
6650     xfts = frametype(rspec[1], wlc->mimoft);
6651     xfts |= (frametype(rts_rspec[0], wlc->mimoft) << XFTS_RTS_FT_SHIFT);
6652     xfts |= (frametype(rts_rspec[1], wlc->mimoft) << XFTS_FBRRTS_FT_SHIFT);
6653     xfts |= CHSPEC_CHANNEL(wlc_phy_chanspec_get(wlc->band->pi)) <<
6654                                  XFTS_CHANNEL_SHIFT;
6655     txh->XtraFrameTypes = cpu_to_le16(xfts);
6656 
6657     /* PhyTxControlWord */
6658     phyctl = frametype(rspec[0], wlc->mimoft);
6659     if ((preamble_type[0] == BRCMS_SHORT_PREAMBLE) ||
6660         (preamble_type[0] == BRCMS_GF_PREAMBLE)) {
6661         if (rspec2rate(rspec[0]) != BRCM_RATE_1M)
6662             phyctl |= PHY_TXC_SHORT_HDR;
6663     }
6664 
6665     /* phytxant is properly bit shifted */
6666     phyctl |= brcms_c_stf_d11hdrs_phyctl_txant(wlc, rspec[0]);
6667     txh->PhyTxControlWord = cpu_to_le16(phyctl);
6668 
6669     /* PhyTxControlWord_1 */
6670     if (BRCMS_PHY_11N_CAP(wlc->band)) {
6671         u16 phyctl1 = 0;
6672 
6673         phyctl1 = brcms_c_phytxctl1_calc(wlc, rspec[0]);
6674         txh->PhyTxControlWord_1 = cpu_to_le16(phyctl1);
6675         phyctl1 = brcms_c_phytxctl1_calc(wlc, rspec[1]);
6676         txh->PhyTxControlWord_1_Fbr = cpu_to_le16(phyctl1);
6677 
6678         if (use_rts || use_cts) {
6679             phyctl1 = brcms_c_phytxctl1_calc(wlc, rts_rspec[0]);
6680             txh->PhyTxControlWord_1_Rts = cpu_to_le16(phyctl1);
6681             phyctl1 = brcms_c_phytxctl1_calc(wlc, rts_rspec[1]);
6682             txh->PhyTxControlWord_1_FbrRts = cpu_to_le16(phyctl1);
6683         }
6684 
6685         /*
6686          * For mcs frames, if mixedmode(overloaded with long preamble)
6687          * is going to be set, fill in non-zero MModeLen and/or
6688          * MModeFbrLen it will be unnecessary if they are separated
6689          */
6690         if (is_mcs_rate(rspec[0]) &&
6691             (preamble_type[0] == BRCMS_MM_PREAMBLE)) {
6692             u16 mmodelen =
6693                 brcms_c_calc_lsig_len(wlc, rspec[0], phylen);
6694             txh->MModeLen = cpu_to_le16(mmodelen);
6695         }
6696 
6697         if (is_mcs_rate(rspec[1]) &&
6698             (preamble_type[1] == BRCMS_MM_PREAMBLE)) {
6699             u16 mmodefbrlen =
6700                 brcms_c_calc_lsig_len(wlc, rspec[1], phylen);
6701             txh->MModeFbrLen = cpu_to_le16(mmodefbrlen);
6702         }
6703     }
6704 
6705     ac = skb_get_queue_mapping(p);
6706     if ((scb->flags & SCB_WMECAP) && qos && wlc->edcf_txop[ac]) {
6707         uint frag_dur, dur, dur_fallback;
6708 
6709         /* WME: Update TXOP threshold */
6710         if (!(tx_info->flags & IEEE80211_TX_CTL_AMPDU) && frag == 0) {
6711             frag_dur =
6712                 brcms_c_calc_frame_time(wlc, rspec[0],
6713                     preamble_type[0], phylen);
6714 
6715             if (rts) {
6716                 /* 1 RTS or CTS-to-self frame */
6717                 dur =
6718                     brcms_c_calc_cts_time(wlc, rts_rspec[0],
6719                               rts_preamble_type[0]);
6720                 dur_fallback =
6721                     brcms_c_calc_cts_time(wlc, rts_rspec[1],
6722                               rts_preamble_type[1]);
6723                 /* (SIFS + CTS) + SIFS + frame + SIFS + ACK */
6724                 dur += le16_to_cpu(rts->duration);
6725                 dur_fallback +=
6726                     le16_to_cpu(txh->RTSDurFallback);
6727             } else if (use_rifs) {
6728                 dur = frag_dur;
6729                 dur_fallback = 0;
6730             } else {
6731                 /* frame + SIFS + ACK */
6732                 dur = frag_dur;
6733                 dur +=
6734                     brcms_c_compute_frame_dur(wlc, rspec[0],
6735                               preamble_type[0], 0);
6736 
6737                 dur_fallback =
6738                     brcms_c_calc_frame_time(wlc, rspec[1],
6739                             preamble_type[1],
6740                             phylen);
6741                 dur_fallback +=
6742                     brcms_c_compute_frame_dur(wlc, rspec[1],
6743                               preamble_type[1], 0);
6744             }
6745             /* NEED to set TxFesTimeNormal (hard) */
6746             txh->TxFesTimeNormal = cpu_to_le16((u16) dur);
6747             /*
6748              * NEED to set fallback rate version of
6749              * TxFesTimeNormal (hard)
6750              */
6751             txh->TxFesTimeFallback =
6752                 cpu_to_le16((u16) dur_fallback);
6753 
6754             /*
6755              * update txop byte threshold (txop minus intraframe
6756              * overhead)
6757              */
6758             if (wlc->edcf_txop[ac] >= (dur - frag_dur)) {
6759                 uint newfragthresh;
6760 
6761                 newfragthresh =
6762                     brcms_c_calc_frame_len(wlc,
6763                     rspec[0], preamble_type[0],
6764                     (wlc->edcf_txop[ac] -
6765                         (dur - frag_dur)));
6766                 /* range bound the fragthreshold */
6767                 if (newfragthresh < DOT11_MIN_FRAG_LEN)
6768                     newfragthresh =
6769                         DOT11_MIN_FRAG_LEN;
6770                 else if (newfragthresh >
6771                      wlc->usr_fragthresh)
6772                     newfragthresh =
6773                         wlc->usr_fragthresh;
6774                 /* update the fragthresh and do txc update */
6775                 if (wlc->fragthresh[queue] !=
6776                     (u16) newfragthresh)
6777                     wlc->fragthresh[queue] =
6778                         (u16) newfragthresh;
6779             } else {
6780                 brcms_warn(wlc->hw->d11core,
6781                        "wl%d: %s txop invalid for rate %d\n",
6782                        wlc->pub->unit, fifo_names[queue],
6783                        rspec2rate(rspec[0]));
6784             }
6785 
6786             if (dur > wlc->edcf_txop[ac])
6787                 brcms_warn(wlc->hw->d11core,
6788                        "wl%d: %s: %s txop exceeded phylen %d/%d dur %d/%d\n",
6789                        wlc->pub->unit, __func__,
6790                        fifo_names[queue],
6791                        phylen, wlc->fragthresh[queue],
6792                        dur, wlc->edcf_txop[ac]);
6793         }
6794     }
6795 
6796     return 0;
6797 }
6798 
6799 static int brcms_c_tx(struct brcms_c_info *wlc, struct sk_buff *skb)
6800 {
6801     struct dma_pub *dma;
6802     int fifo, ret = -ENOSPC;
6803     struct d11txh *txh;
6804     u16 frameid = INVALIDFID;
6805 
6806     fifo = brcms_ac_to_fifo(skb_get_queue_mapping(skb));
6807     dma = wlc->hw->di[fifo];
6808     txh = (struct d11txh *)(skb->data);
6809 
6810     if (dma->txavail == 0) {
6811         /*
6812          * We sometimes get a frame from mac80211 after stopping
6813          * the queues. This only ever seems to be a single frame
6814          * and is seems likely to be a race. TX_HEADROOM should
6815          * ensure that we have enough space to handle these stray
6816          * packets, so warn if there isn't. If we're out of space
6817          * in the tx ring and the tx queue isn't stopped then
6818          * we've really got a bug; warn loudly if that happens.
6819          */
6820         brcms_warn(wlc->hw->d11core,
6821                "Received frame for tx with no space in DMA ring\n");
6822         WARN_ON(!ieee80211_queue_stopped(wlc->pub->ieee_hw,
6823                          skb_get_queue_mapping(skb)));
6824         return -ENOSPC;
6825     }
6826 
6827     /* When a BC/MC frame is being committed to the BCMC fifo
6828      * via DMA (NOT PIO), update ucode or BSS info as appropriate.
6829      */
6830     if (fifo == TX_BCMC_FIFO)
6831         frameid = le16_to_cpu(txh->TxFrameID);
6832 
6833     /* Commit BCMC sequence number in the SHM frame ID location */
6834     if (frameid != INVALIDFID) {
6835         /*
6836          * To inform the ucode of the last mcast frame posted
6837          * so that it can clear moredata bit
6838          */
6839         brcms_b_write_shm(wlc->hw, M_BCMC_FID, frameid);
6840     }
6841 
6842     ret = brcms_c_txfifo(wlc, fifo, skb);
6843     /*
6844      * The only reason for brcms_c_txfifo to fail is because
6845      * there weren't any DMA descriptors, but we've already
6846      * checked for that. So if it does fail yell loudly.
6847      */
6848     WARN_ON_ONCE(ret);
6849 
6850     return ret;
6851 }
6852 
6853 bool brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu,
6854                   struct ieee80211_hw *hw)
6855 {
6856     uint fifo;
6857     struct scb *scb = &wlc->pri_scb;
6858 
6859     fifo = brcms_ac_to_fifo(skb_get_queue_mapping(sdu));
6860     brcms_c_d11hdrs_mac80211(wlc, hw, sdu, scb, 0, 1, fifo, 0);
6861     if (!brcms_c_tx(wlc, sdu))
6862         return true;
6863 
6864     /* packet discarded */
6865     dev_kfree_skb_any(sdu);
6866     return false;
6867 }
6868 
6869 int
6870 brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p)
6871 {
6872     struct dma_pub *dma = wlc->hw->di[fifo];
6873     int ret;
6874     u16 queue;
6875 
6876     ret = dma_txfast(wlc, dma, p);
6877     if (ret < 0)
6878         wiphy_err(wlc->wiphy, "txfifo: fatal, toss frames !!!\n");
6879 
6880     /*
6881      * Stop queue if DMA ring is full. Reserve some free descriptors,
6882      * as we sometimes receive a frame from mac80211 after the queues
6883      * are stopped.
6884      */
6885     queue = skb_get_queue_mapping(p);
6886     if (dma->txavail <= TX_HEADROOM && fifo < TX_BCMC_FIFO &&
6887         !ieee80211_queue_stopped(wlc->pub->ieee_hw, queue))
6888         ieee80211_stop_queue(wlc->pub->ieee_hw, queue);
6889 
6890     return ret;
6891 }
6892 
6893 u32
6894 brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, u32 rspec,
6895                bool use_rspec, u16 mimo_ctlchbw)
6896 {
6897     u32 rts_rspec = 0;
6898 
6899     if (use_rspec)
6900         /* use frame rate as rts rate */
6901         rts_rspec = rspec;
6902     else if (wlc->band->gmode && wlc->protection->_g && !is_cck_rate(rspec))
6903         /* Use 11Mbps as the g protection RTS target rate and fallback.
6904          * Use the brcms_basic_rate() lookup to find the best basic rate
6905          * under the target in case 11 Mbps is not Basic.
6906          * 6 and 9 Mbps are not usually selected by rate selection, but
6907          * even if the OFDM rate we are protecting is 6 or 9 Mbps, 11
6908          * is more robust.
6909          */
6910         rts_rspec = brcms_basic_rate(wlc, BRCM_RATE_11M);
6911     else
6912         /* calculate RTS rate and fallback rate based on the frame rate
6913          * RTS must be sent at a basic rate since it is a
6914          * control frame, sec 9.6 of 802.11 spec
6915          */
6916         rts_rspec = brcms_basic_rate(wlc, rspec);
6917 
6918     if (BRCMS_PHY_11N_CAP(wlc->band)) {
6919         /* set rts txbw to correct side band */
6920         rts_rspec &= ~RSPEC_BW_MASK;
6921 
6922         /*
6923          * if rspec/rspec_fallback is 40MHz, then send RTS on both
6924          * 20MHz channel (DUP), otherwise send RTS on control channel
6925          */
6926         if (rspec_is40mhz(rspec) && !is_cck_rate(rts_rspec))
6927             rts_rspec |= (PHY_TXC1_BW_40MHZ_DUP << RSPEC_BW_SHIFT);
6928         else
6929             rts_rspec |= (mimo_ctlchbw << RSPEC_BW_SHIFT);
6930 
6931         /* pick siso/cdd as default for ofdm */
6932         if (is_ofdm_rate(rts_rspec)) {
6933             rts_rspec &= ~RSPEC_STF_MASK;
6934             rts_rspec |= (wlc->stf->ss_opmode << RSPEC_STF_SHIFT);
6935         }
6936     }
6937     return rts_rspec;
6938 }
6939 
6940 /* Update beacon listen interval in shared memory */
6941 static void brcms_c_bcn_li_upd(struct brcms_c_info *wlc)
6942 {
6943     /* wake up every DTIM is the default */
6944     if (wlc->bcn_li_dtim == 1)
6945         brcms_b_write_shm(wlc->hw, M_BCN_LI, 0);
6946     else
6947         brcms_b_write_shm(wlc->hw, M_BCN_LI,
6948                   (wlc->bcn_li_dtim << 8) | wlc->bcn_li_bcn);
6949 }
6950 
6951 static void
6952 brcms_b_read_tsf(struct brcms_hardware *wlc_hw, u32 *tsf_l_ptr,
6953           u32 *tsf_h_ptr)
6954 {
6955     struct bcma_device *core = wlc_hw->d11core;
6956 
6957     /* read the tsf timer low, then high to get an atomic read */
6958     *tsf_l_ptr = bcma_read32(core, D11REGOFFS(tsf_timerlow));
6959     *tsf_h_ptr = bcma_read32(core, D11REGOFFS(tsf_timerhigh));
6960 }
6961 
6962 /*
6963  * recover 64bit TSF value from the 16bit TSF value in the rx header
6964  * given the assumption that the TSF passed in header is within 65ms
6965  * of the current tsf.
6966  *
6967  * 6       5       4       4       3       2       1
6968  * 3.......6.......8.......0.......2.......4.......6.......8......0
6969  * |<---------- tsf_h ----------->||<--- tsf_l -->||<-RxTSFTime ->|
6970  *
6971  * The RxTSFTime are the lowest 16 bits and provided by the ucode. The
6972  * tsf_l is filled in by brcms_b_recv, which is done earlier in the
6973  * receive call sequence after rx interrupt. Only the higher 16 bits
6974  * are used. Finally, the tsf_h is read from the tsf register.
6975  */
6976 static u64 brcms_c_recover_tsf64(struct brcms_c_info *wlc,
6977                  struct d11rxhdr *rxh)
6978 {
6979     u32 tsf_h, tsf_l;
6980     u16 rx_tsf_0_15, rx_tsf_16_31;
6981 
6982     brcms_b_read_tsf(wlc->hw, &tsf_l, &tsf_h);
6983 
6984     rx_tsf_16_31 = (u16)(tsf_l >> 16);
6985     rx_tsf_0_15 = rxh->RxTSFTime;
6986 
6987     /*
6988      * a greater tsf time indicates the low 16 bits of
6989      * tsf_l wrapped, so decrement the high 16 bits.
6990      */
6991     if ((u16)tsf_l < rx_tsf_0_15) {
6992         rx_tsf_16_31 -= 1;
6993         if (rx_tsf_16_31 == 0xffff)
6994             tsf_h -= 1;
6995     }
6996 
6997     return ((u64)tsf_h << 32) | (((u32)rx_tsf_16_31 << 16) + rx_tsf_0_15);
6998 }
6999 
7000 static void
7001 prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
7002              struct sk_buff *p,
7003              struct ieee80211_rx_status *rx_status)
7004 {
7005     int channel;
7006     u32 rspec;
7007     unsigned char *plcp;
7008 
7009     /* fill in TSF and flag its presence */
7010     rx_status->mactime = brcms_c_recover_tsf64(wlc, rxh);
7011     rx_status->flag |= RX_FLAG_MACTIME_START;
7012 
7013     channel = BRCMS_CHAN_CHANNEL(rxh->RxChan);
7014 
7015     rx_status->band =
7016         channel > 14 ? NL80211_BAND_5GHZ : NL80211_BAND_2GHZ;
7017     rx_status->freq =
7018         ieee80211_channel_to_frequency(channel, rx_status->band);
7019 
7020     rx_status->signal = wlc_phy_rssi_compute(wlc->hw->band->pi, rxh);
7021 
7022     /* noise */
7023     /* qual */
7024     rx_status->antenna =
7025         (rxh->PhyRxStatus_0 & PRXS0_RXANT_UPSUBBAND) ? 1 : 0;
7026 
7027     plcp = p->data;
7028 
7029     rspec = brcms_c_compute_rspec(rxh, plcp);
7030     if (is_mcs_rate(rspec)) {
7031         rx_status->rate_idx = rspec & RSPEC_RATE_MASK;
7032         rx_status->encoding = RX_ENC_HT;
7033         if (rspec_is40mhz(rspec))
7034             rx_status->bw = RATE_INFO_BW_40;
7035     } else {
7036         switch (rspec2rate(rspec)) {
7037         case BRCM_RATE_1M:
7038             rx_status->rate_idx = 0;
7039             break;
7040         case BRCM_RATE_2M:
7041             rx_status->rate_idx = 1;
7042             break;
7043         case BRCM_RATE_5M5:
7044             rx_status->rate_idx = 2;
7045             break;
7046         case BRCM_RATE_11M:
7047             rx_status->rate_idx = 3;
7048             break;
7049         case BRCM_RATE_6M:
7050             rx_status->rate_idx = 4;
7051             break;
7052         case BRCM_RATE_9M:
7053             rx_status->rate_idx = 5;
7054             break;
7055         case BRCM_RATE_12M:
7056             rx_status->rate_idx = 6;
7057             break;
7058         case BRCM_RATE_18M:
7059             rx_status->rate_idx = 7;
7060             break;
7061         case BRCM_RATE_24M:
7062             rx_status->rate_idx = 8;
7063             break;
7064         case BRCM_RATE_36M:
7065             rx_status->rate_idx = 9;
7066             break;
7067         case BRCM_RATE_48M:
7068             rx_status->rate_idx = 10;
7069             break;
7070         case BRCM_RATE_54M:
7071             rx_status->rate_idx = 11;
7072             break;
7073         default:
7074             brcms_err(wlc->hw->d11core,
7075                   "%s: Unknown rate\n", __func__);
7076         }
7077 
7078         /*
7079          * For 5GHz, we should decrease the index as it is
7080          * a subset of the 2.4G rates. See bitrates field
7081          * of brcms_band_5GHz_nphy (in mac80211_if.c).
7082          */
7083         if (rx_status->band == NL80211_BAND_5GHZ)
7084             rx_status->rate_idx -= BRCMS_LEGACY_5G_RATE_OFFSET;
7085 
7086         /* Determine short preamble and rate_idx */
7087         if (is_cck_rate(rspec)) {
7088             if (rxh->PhyRxStatus_0 & PRXS0_SHORTH)
7089                 rx_status->enc_flags |= RX_ENC_FLAG_SHORTPRE;
7090         } else if (is_ofdm_rate(rspec)) {
7091             rx_status->enc_flags |= RX_ENC_FLAG_SHORTPRE;
7092         } else {
7093             brcms_err(wlc->hw->d11core, "%s: Unknown modulation\n",
7094                   __func__);
7095         }
7096     }
7097 
7098     if (plcp3_issgi(plcp[3]))
7099         rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
7100 
7101     if (rxh->RxStatus1 & RXS_DECERR) {
7102         rx_status->flag |= RX_FLAG_FAILED_PLCP_CRC;
7103         brcms_err(wlc->hw->d11core, "%s:  RX_FLAG_FAILED_PLCP_CRC\n",
7104               __func__);
7105     }
7106     if (rxh->RxStatus1 & RXS_FCSERR) {
7107         rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
7108         brcms_err(wlc->hw->d11core, "%s:  RX_FLAG_FAILED_FCS_CRC\n",
7109               __func__);
7110     }
7111 }
7112 
7113 static void
7114 brcms_c_recvctl(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
7115         struct sk_buff *p)
7116 {
7117     int len_mpdu;
7118     struct ieee80211_rx_status rx_status;
7119     struct ieee80211_hdr *hdr;
7120 
7121     memset(&rx_status, 0, sizeof(rx_status));
7122     prep_mac80211_status(wlc, rxh, p, &rx_status);
7123 
7124     /* mac header+body length, exclude CRC and plcp header */
7125     len_mpdu = p->len - D11_PHY_HDR_LEN - FCS_LEN;
7126     skb_pull(p, D11_PHY_HDR_LEN);
7127     __skb_trim(p, len_mpdu);
7128 
7129     /* unmute transmit */
7130     if (wlc->hw->suspended_fifos) {
7131         hdr = (struct ieee80211_hdr *)p->data;
7132         if (ieee80211_is_beacon(hdr->frame_control))
7133             brcms_b_mute(wlc->hw, false);
7134     }
7135 
7136     memcpy(IEEE80211_SKB_RXCB(p), &rx_status, sizeof(rx_status));
7137     ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p);
7138 }
7139 
7140 /* calculate frame duration for Mixed-mode L-SIG spoofing, return
7141  * number of bytes goes in the length field
7142  *
7143  * Formula given by HT PHY Spec v 1.13
7144  *   len = 3(nsyms + nstream + 3) - 3
7145  */
7146 u16
7147 brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec,
7148               uint mac_len)
7149 {
7150     uint nsyms, len = 0, kNdps;
7151 
7152     if (is_mcs_rate(ratespec)) {
7153         uint mcs = ratespec & RSPEC_RATE_MASK;
7154         int tot_streams = (mcs_2_txstreams(mcs) + 1) +
7155                   rspec_stc(ratespec);
7156 
7157         /*
7158          * the payload duration calculation matches that
7159          * of regular ofdm
7160          */
7161         /* 1000Ndbps = kbps * 4 */
7162         kNdps = mcs_2_rate(mcs, rspec_is40mhz(ratespec),
7163                    rspec_issgi(ratespec)) * 4;
7164 
7165         if (rspec_stc(ratespec) == 0)
7166             nsyms =
7167                 CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
7168                   APHY_TAIL_NBITS) * 1000, kNdps);
7169         else
7170             /* STBC needs to have even number of symbols */
7171             nsyms =
7172                 2 *
7173                 CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
7174                   APHY_TAIL_NBITS) * 1000, 2 * kNdps);
7175 
7176         /* (+3) account for HT-SIG(2) and HT-STF(1) */
7177         nsyms += (tot_streams + 3);
7178         /*
7179          * 3 bytes/symbol @ legacy 6Mbps rate
7180          * (-3) excluding service bits and tail bits
7181          */
7182         len = (3 * nsyms) - 3;
7183     }
7184 
7185     return (u16) len;
7186 }
7187 
7188 static void
7189 brcms_c_mod_prb_rsp_rate_table(struct brcms_c_info *wlc, uint frame_len)
7190 {
7191     const struct brcms_c_rateset *rs_dflt;
7192     struct brcms_c_rateset rs;
7193     u8 rate;
7194     u16 entry_ptr;
7195     u8 plcp[D11_PHY_HDR_LEN];
7196     u16 dur, sifs;
7197     uint i;
7198 
7199     sifs = get_sifs(wlc->band);
7200 
7201     rs_dflt = brcms_c_rateset_get_hwrs(wlc);
7202 
7203     brcms_c_rateset_copy(rs_dflt, &rs);
7204     brcms_c_rateset_mcs_upd(&rs, wlc->stf->txstreams);
7205 
7206     /*
7207      * walk the phy rate table and update MAC core SHM
7208      * basic rate table entries
7209      */
7210     for (i = 0; i < rs.count; i++) {
7211         rate = rs.rates[i] & BRCMS_RATE_MASK;
7212 
7213         entry_ptr = brcms_b_rate_shm_offset(wlc->hw, rate);
7214 
7215         /* Calculate the Probe Response PLCP for the given rate */
7216         brcms_c_compute_plcp(wlc, rate, frame_len, plcp);
7217 
7218         /*
7219          * Calculate the duration of the Probe Response
7220          * frame plus SIFS for the MAC
7221          */
7222         dur = (u16) brcms_c_calc_frame_time(wlc, rate,
7223                         BRCMS_LONG_PREAMBLE, frame_len);
7224         dur += sifs;
7225 
7226         /* Update the SHM Rate Table entry Probe Response values */
7227         brcms_b_write_shm(wlc->hw, entry_ptr + M_RT_PRS_PLCP_POS,
7228                   (u16) (plcp[0] + (plcp[1] << 8)));
7229         brcms_b_write_shm(wlc->hw, entry_ptr + M_RT_PRS_PLCP_POS + 2,
7230                   (u16) (plcp[2] + (plcp[3] << 8)));
7231         brcms_b_write_shm(wlc->hw, entry_ptr + M_RT_PRS_DUR_POS, dur);
7232     }
7233 }
7234 
7235 int brcms_c_get_header_len(void)
7236 {
7237     return TXOFF;
7238 }
7239 
7240 static void brcms_c_beacon_write(struct brcms_c_info *wlc,
7241                  struct sk_buff *beacon, u16 tim_offset,
7242                  u16 dtim_period, bool bcn0, bool bcn1)
7243 {
7244     size_t len;
7245     struct ieee80211_tx_info *tx_info;
7246     struct brcms_hardware *wlc_hw = wlc->hw;
7247     struct ieee80211_hw *ieee_hw = brcms_c_pub(wlc)->ieee_hw;
7248 
7249     /* Get tx_info */
7250     tx_info = IEEE80211_SKB_CB(beacon);
7251 
7252     len = min_t(size_t, beacon->len, BCN_TMPL_LEN);
7253     wlc->bcn_rspec = ieee80211_get_tx_rate(ieee_hw, tx_info)->hw_value;
7254 
7255     brcms_c_compute_plcp(wlc, wlc->bcn_rspec,
7256                  len + FCS_LEN - D11_PHY_HDR_LEN, beacon->data);
7257 
7258     /* "Regular" and 16 MBSS but not for 4 MBSS */
7259     /* Update the phytxctl for the beacon based on the rspec */
7260     brcms_c_beacon_phytxctl_txant_upd(wlc, wlc->bcn_rspec);
7261 
7262     if (bcn0) {
7263         /* write the probe response into the template region */
7264         brcms_b_write_template_ram(wlc_hw, T_BCN0_TPL_BASE,
7265                         (len + 3) & ~3, beacon->data);
7266 
7267         /* write beacon length to SCR */
7268         brcms_b_write_shm(wlc_hw, M_BCN0_FRM_BYTESZ, (u16) len);
7269     }
7270     if (bcn1) {
7271         /* write the probe response into the template region */
7272         brcms_b_write_template_ram(wlc_hw, T_BCN1_TPL_BASE,
7273                         (len + 3) & ~3, beacon->data);
7274 
7275         /* write beacon length to SCR */
7276         brcms_b_write_shm(wlc_hw, M_BCN1_FRM_BYTESZ, (u16) len);
7277     }
7278 
7279     if (tim_offset != 0) {
7280         brcms_b_write_shm(wlc_hw, M_TIMBPOS_INBEACON,
7281                   tim_offset + D11B_PHY_HDR_LEN);
7282         brcms_b_write_shm(wlc_hw, M_DOT11_DTIMPERIOD, dtim_period);
7283     } else {
7284         brcms_b_write_shm(wlc_hw, M_TIMBPOS_INBEACON,
7285                   len + D11B_PHY_HDR_LEN);
7286         brcms_b_write_shm(wlc_hw, M_DOT11_DTIMPERIOD, 0);
7287     }
7288 }
7289 
7290 static void brcms_c_update_beacon_hw(struct brcms_c_info *wlc,
7291                      struct sk_buff *beacon, u16 tim_offset,
7292                      u16 dtim_period)
7293 {
7294     struct brcms_hardware *wlc_hw = wlc->hw;
7295     struct bcma_device *core = wlc_hw->d11core;
7296 
7297     /* Hardware beaconing for this config */
7298     u32 both_valid = MCMD_BCN0VLD | MCMD_BCN1VLD;
7299 
7300     /* Check if both templates are in use, if so sched. an interrupt
7301      *      that will call back into this routine
7302      */
7303     if ((bcma_read32(core, D11REGOFFS(maccommand)) & both_valid) == both_valid)
7304         /* clear any previous status */
7305         bcma_write32(core, D11REGOFFS(macintstatus), MI_BCNTPL);
7306 
7307     if (wlc->beacon_template_virgin) {
7308         wlc->beacon_template_virgin = false;
7309         brcms_c_beacon_write(wlc, beacon, tim_offset, dtim_period, true,
7310                      true);
7311         /* mark beacon0 valid */
7312         bcma_set32(core, D11REGOFFS(maccommand), MCMD_BCN0VLD);
7313         return;
7314     }
7315 
7316     /* Check that after scheduling the interrupt both of the
7317      *      templates are still busy. if not clear the int. & remask
7318      */
7319     if ((bcma_read32(core, D11REGOFFS(maccommand)) & both_valid) == both_valid) {
7320         wlc->defmacintmask |= MI_BCNTPL;
7321         return;
7322     }
7323 
7324     if (!(bcma_read32(core, D11REGOFFS(maccommand)) & MCMD_BCN0VLD)) {
7325         brcms_c_beacon_write(wlc, beacon, tim_offset, dtim_period, true,
7326                      false);
7327         /* mark beacon0 valid */
7328         bcma_set32(core, D11REGOFFS(maccommand), MCMD_BCN0VLD);
7329         return;
7330     }
7331     if (!(bcma_read32(core, D11REGOFFS(maccommand)) & MCMD_BCN1VLD)) {
7332         brcms_c_beacon_write(wlc, beacon, tim_offset, dtim_period,
7333                      false, true);
7334         /* mark beacon0 valid */
7335         bcma_set32(core, D11REGOFFS(maccommand), MCMD_BCN1VLD);
7336     }
7337 }
7338 
7339 /*
7340  * Update all beacons for the system.
7341  */
7342 void brcms_c_update_beacon(struct brcms_c_info *wlc)
7343 {
7344     struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
7345 
7346     if (wlc->pub->up && (bsscfg->type == BRCMS_TYPE_AP ||
7347                  bsscfg->type == BRCMS_TYPE_ADHOC)) {
7348         /* Clear the soft intmask */
7349         wlc->defmacintmask &= ~MI_BCNTPL;
7350         if (!wlc->beacon)
7351             return;
7352         brcms_c_update_beacon_hw(wlc, wlc->beacon,
7353                      wlc->beacon_tim_offset,
7354                      wlc->beacon_dtim_period);
7355     }
7356 }
7357 
7358 void brcms_c_set_new_beacon(struct brcms_c_info *wlc, struct sk_buff *beacon,
7359                 u16 tim_offset, u16 dtim_period)
7360 {
7361     if (!beacon)
7362         return;
7363     if (wlc->beacon)
7364         dev_kfree_skb_any(wlc->beacon);
7365     wlc->beacon = beacon;
7366 
7367     /* add PLCP */
7368     skb_push(wlc->beacon, D11_PHY_HDR_LEN);
7369     wlc->beacon_tim_offset = tim_offset;
7370     wlc->beacon_dtim_period = dtim_period;
7371     brcms_c_update_beacon(wlc);
7372 }
7373 
7374 void brcms_c_set_new_probe_resp(struct brcms_c_info *wlc,
7375                 struct sk_buff *probe_resp)
7376 {
7377     if (!probe_resp)
7378         return;
7379     if (wlc->probe_resp)
7380         dev_kfree_skb_any(wlc->probe_resp);
7381     wlc->probe_resp = probe_resp;
7382 
7383     /* add PLCP */
7384     skb_push(wlc->probe_resp, D11_PHY_HDR_LEN);
7385     brcms_c_update_probe_resp(wlc, false);
7386 }
7387 
7388 void brcms_c_enable_probe_resp(struct brcms_c_info *wlc, bool enable)
7389 {
7390     /*
7391      * prevent ucode from sending probe responses by setting the timeout
7392      * to 1, it can not send it in that time frame.
7393      */
7394     wlc->prb_resp_timeout = enable ? BRCMS_PRB_RESP_TIMEOUT : 1;
7395     brcms_b_write_shm(wlc->hw, M_PRS_MAXTIME, wlc->prb_resp_timeout);
7396     /* TODO: if (enable) => also deactivate receiving of probe request */
7397 }
7398 
7399 /* Write ssid into shared memory */
7400 static void
7401 brcms_c_shm_ssid_upd(struct brcms_c_info *wlc, struct brcms_bss_cfg *cfg)
7402 {
7403     u8 *ssidptr = cfg->SSID;
7404     u16 base = M_SSID;
7405     u8 ssidbuf[IEEE80211_MAX_SSID_LEN];
7406 
7407     /* padding the ssid with zero and copy it into shm */
7408     memset(ssidbuf, 0, IEEE80211_MAX_SSID_LEN);
7409     memcpy(ssidbuf, ssidptr, cfg->SSID_len);
7410 
7411     brcms_c_copyto_shm(wlc, base, ssidbuf, IEEE80211_MAX_SSID_LEN);
7412     brcms_b_write_shm(wlc->hw, M_SSIDLEN, (u16) cfg->SSID_len);
7413 }
7414 
7415 static void
7416 brcms_c_bss_update_probe_resp(struct brcms_c_info *wlc,
7417                   struct brcms_bss_cfg *cfg,
7418                   struct sk_buff *probe_resp,
7419                   bool suspend)
7420 {
7421     int len;
7422 
7423     len = min_t(size_t, probe_resp->len, BCN_TMPL_LEN);
7424 
7425     if (suspend)
7426         brcms_c_suspend_mac_and_wait(wlc);
7427 
7428     /* write the probe response into the template region */
7429     brcms_b_write_template_ram(wlc->hw, T_PRS_TPL_BASE,
7430                     (len + 3) & ~3, probe_resp->data);
7431 
7432     /* write the length of the probe response frame (+PLCP/-FCS) */
7433     brcms_b_write_shm(wlc->hw, M_PRB_RESP_FRM_LEN, (u16) len);
7434 
7435     /* write the SSID and SSID length */
7436     brcms_c_shm_ssid_upd(wlc, cfg);
7437 
7438     /*
7439      * Write PLCP headers and durations for probe response frames
7440      * at all rates. Use the actual frame length covered by the
7441      * PLCP header for the call to brcms_c_mod_prb_rsp_rate_table()
7442      * by subtracting the PLCP len and adding the FCS.
7443      */
7444     brcms_c_mod_prb_rsp_rate_table(wlc,
7445                       (u16)len + FCS_LEN - D11_PHY_HDR_LEN);
7446 
7447     if (suspend)
7448         brcms_c_enable_mac(wlc);
7449 }
7450 
7451 void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend)
7452 {
7453     struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
7454 
7455     /* update AP or IBSS probe responses */
7456     if (wlc->pub->up && (bsscfg->type == BRCMS_TYPE_AP ||
7457                  bsscfg->type == BRCMS_TYPE_ADHOC)) {
7458         if (!wlc->probe_resp)
7459             return;
7460         brcms_c_bss_update_probe_resp(wlc, bsscfg, wlc->probe_resp,
7461                           suspend);
7462     }
7463 }
7464 
7465 int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo,
7466                uint *blocks)
7467 {
7468     if (fifo >= NFIFO)
7469         return -EINVAL;
7470 
7471     *blocks = wlc_hw->xmtfifo_sz[fifo];
7472 
7473     return 0;
7474 }
7475 
7476 void
7477 brcms_c_set_addrmatch(struct brcms_c_info *wlc, int match_reg_offset,
7478           const u8 *addr)
7479 {
7480     brcms_b_set_addrmatch(wlc->hw, match_reg_offset, addr);
7481     if (match_reg_offset == RCM_BSSID_OFFSET)
7482         memcpy(wlc->bsscfg->BSSID, addr, ETH_ALEN);
7483 }
7484 
7485 /*
7486  * Flag 'scan in progress' to withhold dynamic phy calibration
7487  */
7488 void brcms_c_scan_start(struct brcms_c_info *wlc)
7489 {
7490     wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, true);
7491 }
7492 
7493 void brcms_c_scan_stop(struct brcms_c_info *wlc)
7494 {
7495     wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, false);
7496 }
7497 
7498 void brcms_c_associate_upd(struct brcms_c_info *wlc, bool state)
7499 {
7500     wlc->pub->associated = state;
7501 }
7502 
7503 /*
7504  * When a remote STA/AP is removed by Mac80211, or when it can no longer accept
7505  * AMPDU traffic, packets pending in hardware have to be invalidated so that
7506  * when later on hardware releases them, they can be handled appropriately.
7507  */
7508 void brcms_c_inval_dma_pkts(struct brcms_hardware *hw,
7509                    struct ieee80211_sta *sta,
7510                    void (*dma_callback_fn))
7511 {
7512     struct dma_pub *dmah;
7513     int i;
7514     for (i = 0; i < NFIFO; i++) {
7515         dmah = hw->di[i];
7516         if (dmah != NULL)
7517             dma_walk_packets(dmah, dma_callback_fn, sta);
7518     }
7519 }
7520 
7521 int brcms_c_get_curband(struct brcms_c_info *wlc)
7522 {
7523     return wlc->band->bandunit;
7524 }
7525 
7526 bool brcms_c_tx_flush_completed(struct brcms_c_info *wlc)
7527 {
7528     int i;
7529 
7530     /* Kick DMA to send any pending AMPDU */
7531     for (i = 0; i < ARRAY_SIZE(wlc->hw->di); i++)
7532         if (wlc->hw->di[i])
7533             dma_kick_tx(wlc->hw->di[i]);
7534 
7535     return !brcms_txpktpendtot(wlc);
7536 }
7537 
7538 void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, u8 interval)
7539 {
7540     wlc->bcn_li_bcn = interval;
7541     if (wlc->pub->up)
7542         brcms_c_bcn_li_upd(wlc);
7543 }
7544 
7545 u64 brcms_c_tsf_get(struct brcms_c_info *wlc)
7546 {
7547     u32 tsf_h, tsf_l;
7548     u64 tsf;
7549 
7550     brcms_b_read_tsf(wlc->hw, &tsf_l, &tsf_h);
7551 
7552     tsf = tsf_h;
7553     tsf <<= 32;
7554     tsf |= tsf_l;
7555 
7556     return tsf;
7557 }
7558 
7559 void brcms_c_tsf_set(struct brcms_c_info *wlc, u64 tsf)
7560 {
7561     u32 tsf_h, tsf_l;
7562 
7563     brcms_c_time_lock(wlc);
7564 
7565     tsf_l = tsf;
7566     tsf_h = (tsf >> 32);
7567 
7568     /* read the tsf timer low, then high to get an atomic read */
7569     bcma_write32(wlc->hw->d11core, D11REGOFFS(tsf_timerlow), tsf_l);
7570     bcma_write32(wlc->hw->d11core, D11REGOFFS(tsf_timerhigh), tsf_h);
7571 
7572     brcms_c_time_unlock(wlc);
7573 }
7574 
7575 int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr)
7576 {
7577     uint qdbm;
7578 
7579     /* Remove override bit and clip to max qdbm value */
7580     qdbm = min_t(uint, txpwr * BRCMS_TXPWR_DB_FACTOR, 0xff);
7581     return wlc_phy_txpower_set(wlc->band->pi, qdbm, false);
7582 }
7583 
7584 int brcms_c_get_tx_power(struct brcms_c_info *wlc)
7585 {
7586     uint qdbm;
7587     bool override;
7588 
7589     wlc_phy_txpower_get(wlc->band->pi, &qdbm, &override);
7590 
7591     /* Return qdbm units */
7592     return (int)(qdbm / BRCMS_TXPWR_DB_FACTOR);
7593 }
7594 
7595 /* Process received frames */
7596 /*
7597  * Return true if more frames need to be processed. false otherwise.
7598  * Param 'bound' indicates max. # frames to process before break out.
7599  */
7600 static void brcms_c_recv(struct brcms_c_info *wlc, struct sk_buff *p)
7601 {
7602     struct d11rxhdr *rxh;
7603     struct ieee80211_hdr *h;
7604     uint len;
7605     bool is_amsdu;
7606 
7607     /* frame starts with rxhdr */
7608     rxh = (struct d11rxhdr *) (p->data);
7609 
7610     /* strip off rxhdr */
7611     skb_pull(p, BRCMS_HWRXOFF);
7612 
7613     /* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */
7614     if (rxh->RxStatus1 & RXS_PBPRES) {
7615         if (p->len < 2) {
7616             brcms_err(wlc->hw->d11core,
7617                   "wl%d: recv: rcvd runt of len %d\n",
7618                   wlc->pub->unit, p->len);
7619             goto toss;
7620         }
7621         skb_pull(p, 2);
7622     }
7623 
7624     h = (struct ieee80211_hdr *)(p->data + D11_PHY_HDR_LEN);
7625     len = p->len;
7626 
7627     if (rxh->RxStatus1 & RXS_FCSERR) {
7628         if (!(wlc->filter_flags & FIF_FCSFAIL))
7629             goto toss;
7630     }
7631 
7632     /* check received pkt has at least frame control field */
7633     if (len < D11_PHY_HDR_LEN + sizeof(h->frame_control))
7634         goto toss;
7635 
7636     /* not supporting A-MSDU */
7637     is_amsdu = rxh->RxStatus2 & RXS_AMSDU_MASK;
7638     if (is_amsdu)
7639         goto toss;
7640 
7641     brcms_c_recvctl(wlc, rxh, p);
7642     return;
7643 
7644  toss:
7645     brcmu_pkt_buf_free_skb(p);
7646 }
7647 
7648 /* Process received frames */
7649 /*
7650  * Return true if more frames need to be processed. false otherwise.
7651  * Param 'bound' indicates max. # frames to process before break out.
7652  */
7653 static bool
7654 brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound)
7655 {
7656     struct sk_buff *p;
7657     struct sk_buff *next = NULL;
7658     struct sk_buff_head recv_frames;
7659 
7660     uint n = 0;
7661     uint bound_limit = bound ? RXBND : -1;
7662     bool morepending = false;
7663 
7664     skb_queue_head_init(&recv_frames);
7665 
7666     /* gather received frames */
7667     do {
7668         /* !give others some time to run! */
7669         if (n >= bound_limit)
7670             break;
7671 
7672         morepending = dma_rx(wlc_hw->di[fifo], &recv_frames);
7673         n++;
7674     } while (morepending);
7675 
7676     /* post more rbufs */
7677     dma_rxfill(wlc_hw->di[fifo]);
7678 
7679     /* process each frame */
7680     skb_queue_walk_safe(&recv_frames, p, next) {
7681         struct d11rxhdr_le *rxh_le;
7682         struct d11rxhdr *rxh;
7683 
7684         skb_unlink(p, &recv_frames);
7685         rxh_le = (struct d11rxhdr_le *)p->data;
7686         rxh = (struct d11rxhdr *)p->data;
7687 
7688         /* fixup rx header endianness */
7689         rxh->RxFrameSize = le16_to_cpu(rxh_le->RxFrameSize);
7690         rxh->PhyRxStatus_0 = le16_to_cpu(rxh_le->PhyRxStatus_0);
7691         rxh->PhyRxStatus_1 = le16_to_cpu(rxh_le->PhyRxStatus_1);
7692         rxh->PhyRxStatus_2 = le16_to_cpu(rxh_le->PhyRxStatus_2);
7693         rxh->PhyRxStatus_3 = le16_to_cpu(rxh_le->PhyRxStatus_3);
7694         rxh->PhyRxStatus_4 = le16_to_cpu(rxh_le->PhyRxStatus_4);
7695         rxh->PhyRxStatus_5 = le16_to_cpu(rxh_le->PhyRxStatus_5);
7696         rxh->RxStatus1 = le16_to_cpu(rxh_le->RxStatus1);
7697         rxh->RxStatus2 = le16_to_cpu(rxh_le->RxStatus2);
7698         rxh->RxTSFTime = le16_to_cpu(rxh_le->RxTSFTime);
7699         rxh->RxChan = le16_to_cpu(rxh_le->RxChan);
7700 
7701         brcms_c_recv(wlc_hw->wlc, p);
7702     }
7703 
7704     return morepending;
7705 }
7706 
7707 /* second-level interrupt processing
7708  *   Return true if another dpc needs to be re-scheduled. false otherwise.
7709  *   Param 'bounded' indicates if applicable loops should be bounded.
7710  */
7711 bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded)
7712 {
7713     u32 macintstatus;
7714     struct brcms_hardware *wlc_hw = wlc->hw;
7715     struct bcma_device *core = wlc_hw->d11core;
7716 
7717     if (brcms_deviceremoved(wlc)) {
7718         brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit,
7719               __func__);
7720         brcms_down(wlc->wl);
7721         return false;
7722     }
7723 
7724     /* grab and clear the saved software intstatus bits */
7725     macintstatus = wlc->macintstatus;
7726     wlc->macintstatus = 0;
7727 
7728     brcms_dbg_int(core, "wl%d: macintstatus 0x%x\n",
7729               wlc_hw->unit, macintstatus);
7730 
7731     WARN_ON(macintstatus & MI_PRQ); /* PRQ Interrupt in non-MBSS */
7732 
7733     /* tx status */
7734     if (macintstatus & MI_TFS) {
7735         bool fatal;
7736         if (brcms_b_txstatus(wlc->hw, bounded, &fatal))
7737             wlc->macintstatus |= MI_TFS;
7738         if (fatal) {
7739             brcms_err(core, "MI_TFS: fatal\n");
7740             goto fatal;
7741         }
7742     }
7743 
7744     if (macintstatus & (MI_TBTT | MI_DTIM_TBTT))
7745         brcms_c_tbtt(wlc);
7746 
7747     /* ATIM window end */
7748     if (macintstatus & MI_ATIMWINEND) {
7749         brcms_dbg_info(core, "end of ATIM window\n");
7750         bcma_set32(core, D11REGOFFS(maccommand), wlc->qvalid);
7751         wlc->qvalid = 0;
7752     }
7753 
7754     /*
7755      * received data or control frame, MI_DMAINT is
7756      * indication of RX_FIFO interrupt
7757      */
7758     if (macintstatus & MI_DMAINT)
7759         if (brcms_b_recv(wlc_hw, RX_FIFO, bounded))
7760             wlc->macintstatus |= MI_DMAINT;
7761 
7762     /* noise sample collected */
7763     if (macintstatus & MI_BG_NOISE)
7764         wlc_phy_noise_sample_intr(wlc_hw->band->pi);
7765 
7766     if (macintstatus & MI_GP0) {
7767         brcms_err(core, "wl%d: PSM microcode watchdog fired at %d "
7768               "(seconds). Resetting.\n", wlc_hw->unit, wlc_hw->now);
7769 
7770         printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n",
7771                 __func__, ai_get_chip_id(wlc_hw->sih),
7772                 ai_get_chiprev(wlc_hw->sih));
7773         brcms_fatal_error(wlc_hw->wlc->wl);
7774     }
7775 
7776     /* gptimer timeout */
7777     if (macintstatus & MI_TO)
7778         bcma_write32(core, D11REGOFFS(gptimer), 0);
7779 
7780     if (macintstatus & MI_RFDISABLE) {
7781         brcms_dbg_info(core, "wl%d: BMAC Detected a change on the"
7782                    " RF Disable Input\n", wlc_hw->unit);
7783         brcms_rfkill_set_hw_state(wlc->wl);
7784     }
7785 
7786     /* BCN template is available */
7787     if (macintstatus & MI_BCNTPL)
7788         brcms_c_update_beacon(wlc);
7789 
7790     /* it isn't done and needs to be resched if macintstatus is non-zero */
7791     return wlc->macintstatus != 0;
7792 
7793  fatal:
7794     brcms_fatal_error(wlc_hw->wlc->wl);
7795     return wlc->macintstatus != 0;
7796 }
7797 
7798 void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx)
7799 {
7800     struct bcma_device *core = wlc->hw->d11core;
7801     struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.chandef.chan;
7802     u16 chanspec;
7803 
7804     brcms_dbg_info(core, "wl%d\n", wlc->pub->unit);
7805 
7806     chanspec = ch20mhz_chspec(ch->hw_value);
7807 
7808     brcms_b_init(wlc->hw, chanspec);
7809 
7810     /* update beacon listen interval */
7811     brcms_c_bcn_li_upd(wlc);
7812 
7813     /* write ethernet address to core */
7814     brcms_c_set_mac(wlc->bsscfg);
7815     brcms_c_set_bssid(wlc->bsscfg);
7816 
7817     /* Update tsf_cfprep if associated and up */
7818     if (wlc->pub->associated && wlc->pub->up) {
7819         u32 bi;
7820 
7821         /* get beacon period and convert to uS */
7822         bi = wlc->bsscfg->current_bss->beacon_period << 10;
7823         /*
7824          * update since init path would reset
7825          * to default value
7826          */
7827         bcma_write32(core, D11REGOFFS(tsf_cfprep),
7828                  bi << CFPREP_CBI_SHIFT);
7829 
7830         /* Update maccontrol PM related bits */
7831         brcms_c_set_ps_ctrl(wlc);
7832     }
7833 
7834     brcms_c_bandinit_ordered(wlc, chanspec);
7835 
7836     /* init probe response timeout */
7837     brcms_b_write_shm(wlc->hw, M_PRS_MAXTIME, wlc->prb_resp_timeout);
7838 
7839     /* init max burst txop (framebursting) */
7840     brcms_b_write_shm(wlc->hw, M_MBURST_TXOP,
7841               (wlc->
7842                _rifs ? (EDCF_AC_VO_TXOP_AP << 5) : MAXFRAMEBURST_TXOP));
7843 
7844     /* initialize maximum allowed duty cycle */
7845     brcms_c_duty_cycle_set(wlc, wlc->tx_duty_cycle_ofdm, true, true);
7846     brcms_c_duty_cycle_set(wlc, wlc->tx_duty_cycle_cck, false, true);
7847 
7848     /*
7849      * Update some shared memory locations related to
7850      * max AMPDU size allowed to received
7851      */
7852     brcms_c_ampdu_shm_upd(wlc->ampdu);
7853 
7854     /* band-specific inits */
7855     brcms_c_bsinit(wlc);
7856 
7857     /* Enable EDCF mode (while the MAC is suspended) */
7858     bcma_set16(core, D11REGOFFS(ifs_ctl), IFS_USEEDCF);
7859     brcms_c_edcf_setparams(wlc, false);
7860 
7861     /* read the ucode version if we have not yet done so */
7862     if (wlc->ucode_rev == 0) {
7863         u16 rev;
7864         u16 patch;
7865 
7866         rev = brcms_b_read_shm(wlc->hw, M_BOM_REV_MAJOR);
7867         patch = brcms_b_read_shm(wlc->hw, M_BOM_REV_MINOR);
7868         wlc->ucode_rev = (rev << NBITS(u16)) | patch;
7869         snprintf(wlc->wiphy->fw_version,
7870              sizeof(wlc->wiphy->fw_version), "%u.%u", rev, patch);
7871     }
7872 
7873     /* ..now really unleash hell (allow the MAC out of suspend) */
7874     brcms_c_enable_mac(wlc);
7875 
7876     /* suspend the tx fifos and mute the phy for preism cac time */
7877     if (mute_tx)
7878         brcms_b_mute(wlc->hw, true);
7879 
7880     /* enable the RF Disable Delay timer */
7881     bcma_write32(core, D11REGOFFS(rfdisabledly), RFDISABLE_DEFAULT);
7882 
7883     /*
7884      * Initialize WME parameters; if they haven't been set by some other
7885      * mechanism (IOVar, etc) then read them from the hardware.
7886      */
7887     if (GFIELD(wlc->wme_retries[0], EDCF_SHORT) == 0) {
7888         /* Uninitialized; read from HW */
7889         int ac;
7890 
7891         for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
7892             wlc->wme_retries[ac] =
7893                 brcms_b_read_shm(wlc->hw, M_AC_TXLMT_ADDR(ac));
7894     }
7895 }
7896 
7897 /*
7898  * The common driver entry routine. Error codes should be unique
7899  */
7900 struct brcms_c_info *
7901 brcms_c_attach(struct brcms_info *wl, struct bcma_device *core, uint unit,
7902            bool piomode, uint *perr)
7903 {
7904     struct brcms_c_info *wlc;
7905     uint err = 0;
7906     uint i, j;
7907     struct brcms_pub *pub;
7908 
7909     /* allocate struct brcms_c_info state and its substructures */
7910     wlc = brcms_c_attach_malloc(unit, &err, 0);
7911     if (wlc == NULL)
7912         goto fail;
7913     wlc->wiphy = wl->wiphy;
7914     pub = wlc->pub;
7915 
7916 #if defined(DEBUG)
7917     wlc_info_dbg = wlc;
7918 #endif
7919 
7920     wlc->band = wlc->bandstate[0];
7921     wlc->core = wlc->corestate;
7922     wlc->wl = wl;
7923     pub->unit = unit;
7924     pub->_piomode = piomode;
7925     wlc->bandinit_pending = false;
7926     wlc->beacon_template_virgin = true;
7927 
7928     /* populate struct brcms_c_info with default values  */
7929     brcms_c_info_init(wlc, unit);
7930 
7931     /* update sta/ap related parameters */
7932     brcms_c_ap_upd(wlc);
7933 
7934     /*
7935      * low level attach steps(all hw accesses go
7936      * inside, no more in rest of the attach)
7937      */
7938     err = brcms_b_attach(wlc, core, unit, piomode);
7939     if (err)
7940         goto fail;
7941 
7942     brcms_c_protection_upd(wlc, BRCMS_PROT_N_PAM_OVR, OFF);
7943 
7944     pub->phy_11ncapable = BRCMS_PHY_11N_CAP(wlc->band);
7945 
7946     /* disable allowed duty cycle */
7947     wlc->tx_duty_cycle_ofdm = 0;
7948     wlc->tx_duty_cycle_cck = 0;
7949 
7950     brcms_c_stf_phy_chain_calc(wlc);
7951 
7952     /* txchain 1: txant 0, txchain 2: txant 1 */
7953     if (BRCMS_ISNPHY(wlc->band) && (wlc->stf->txstreams == 1))
7954         wlc->stf->txant = wlc->stf->hw_txchain - 1;
7955 
7956     /* push to BMAC driver */
7957     wlc_phy_stf_chain_init(wlc->band->pi, wlc->stf->hw_txchain,
7958                    wlc->stf->hw_rxchain);
7959 
7960     /* pull up some info resulting from the low attach */
7961     for (i = 0; i < NFIFO; i++)
7962         wlc->core->txavail[i] = wlc->hw->txavail[i];
7963 
7964     memcpy(&wlc->perm_etheraddr, &wlc->hw->etheraddr, ETH_ALEN);
7965     memcpy(&pub->cur_etheraddr, &wlc->hw->etheraddr, ETH_ALEN);
7966 
7967     for (j = 0; j < wlc->pub->_nbands; j++) {
7968         wlc->band = wlc->bandstate[j];
7969 
7970         if (!brcms_c_attach_stf_ant_init(wlc)) {
7971             err = 24;
7972             goto fail;
7973         }
7974 
7975         /* default contention windows size limits */
7976         wlc->band->CWmin = APHY_CWMIN;
7977         wlc->band->CWmax = PHY_CWMAX;
7978 
7979         /* init gmode value */
7980         if (wlc->band->bandtype == BRCM_BAND_2G) {
7981             wlc->band->gmode = GMODE_AUTO;
7982             brcms_c_protection_upd(wlc, BRCMS_PROT_G_USER,
7983                        wlc->band->gmode);
7984         }
7985 
7986         /* init _n_enab supported mode */
7987         if (BRCMS_PHY_11N_CAP(wlc->band)) {
7988             pub->_n_enab = SUPPORT_11N;
7989             brcms_c_protection_upd(wlc, BRCMS_PROT_N_USER,
7990                            ((pub->_n_enab ==
7991                              SUPPORT_11N) ? WL_11N_2x2 :
7992                             WL_11N_3x3));
7993         }
7994 
7995         /* init per-band default rateset, depend on band->gmode */
7996         brcms_default_rateset(wlc, &wlc->band->defrateset);
7997 
7998         /* fill in hw_rateset */
7999         brcms_c_rateset_filter(&wlc->band->defrateset,
8000                    &wlc->band->hw_rateset, false,
8001                    BRCMS_RATES_CCK_OFDM, BRCMS_RATE_MASK,
8002                    (bool) (wlc->pub->_n_enab & SUPPORT_11N));
8003     }
8004 
8005     /*
8006      * update antenna config due to
8007      * wlc->stf->txant/txchain/ant_rx_ovr change
8008      */
8009     brcms_c_stf_phy_txant_upd(wlc);
8010 
8011     /* attach each modules */
8012     err = brcms_c_attach_module(wlc);
8013     if (err != 0)
8014         goto fail;
8015 
8016     if (!brcms_c_timers_init(wlc, unit)) {
8017         wiphy_err(wl->wiphy, "wl%d: %s: init_timer failed\n", unit,
8018               __func__);
8019         err = 32;
8020         goto fail;
8021     }
8022 
8023     /* depend on rateset, gmode */
8024     wlc->cmi = brcms_c_channel_mgr_attach(wlc);
8025     if (!wlc->cmi) {
8026         wiphy_err(wl->wiphy, "wl%d: %s: channel_mgr_attach failed"
8027               "\n", unit, __func__);
8028         err = 33;
8029         goto fail;
8030     }
8031 
8032     /* init default when all parameters are ready, i.e. ->rateset */
8033     brcms_c_bss_default_init(wlc);
8034 
8035     /*
8036      * Complete the wlc default state initializations..
8037      */
8038 
8039     wlc->bsscfg->wlc = wlc;
8040 
8041     wlc->mimoft = FT_HT;
8042     wlc->mimo_40txbw = AUTO;
8043     wlc->ofdm_40txbw = AUTO;
8044     wlc->cck_40txbw = AUTO;
8045     brcms_c_update_mimo_band_bwcap(wlc, BRCMS_N_BW_20IN2G_40IN5G);
8046 
8047     /* Set default values of SGI */
8048     if (BRCMS_SGI_CAP_PHY(wlc)) {
8049         brcms_c_ht_update_sgi_rx(wlc, (BRCMS_N_SGI_20 |
8050                            BRCMS_N_SGI_40));
8051     } else if (BRCMS_ISSSLPNPHY(wlc->band)) {
8052         brcms_c_ht_update_sgi_rx(wlc, (BRCMS_N_SGI_20 |
8053                            BRCMS_N_SGI_40));
8054     } else {
8055         brcms_c_ht_update_sgi_rx(wlc, 0);
8056     }
8057 
8058     brcms_b_antsel_set(wlc->hw, wlc->asi->antsel_avail);
8059 
8060     if (perr)
8061         *perr = 0;
8062 
8063     return wlc;
8064 
8065  fail:
8066     wiphy_err(wl->wiphy, "wl%d: %s: failed with err %d\n",
8067           unit, __func__, err);
8068     if (wlc)
8069         brcms_c_detach(wlc);
8070 
8071     if (perr)
8072         *perr = err;
8073     return NULL;
8074 }