]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/staging/brcm80211/brcmsmac/main.c
staging: brcm80211: reduced softmac sparse warnings
[karo-tx-linux.git] / drivers / staging / brcm80211 / brcmsmac / main.c
1 /*
2  * Copyright (c) 2010 Broadcom Corporation
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 #include <linux/pci_ids.h>
18 #include <linux/if_ether.h>
19 #include <net/mac80211.h>
20 #include <brcm_hw_ids.h>
21 #include <aiutils.h>
22 #include <chipcommon.h>
23 #include "rate.h"
24 #include "scb.h"
25 #include "phy/phy_hal.h"
26 #include "channel.h"
27 #include "antsel.h"
28 #include "stf.h"
29 #include "ampdu.h"
30 #include "mac80211_if.h"
31 #include "ucode_loader.h"
32 #include "main.h"
33
34 /*
35  * Indication for txflowcontrol that all priority bits in
36  * TXQ_STOP_FOR_PRIOFC_MASK are to be considered.
37  */
38 #define ALLPRIO         -1
39
40 /*
41  * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL.
42  */
43 #define SSID_FMT_BUF_LEN        ((4 * IEEE80211_MAX_SSID_LEN) + 1)
44
45 /* watchdog timer, in unit of ms */
46 #define TIMER_INTERVAL_WATCHDOG 1000
47 /* radio monitor timer, in unit of ms */
48 #define TIMER_INTERVAL_RADIOCHK 800
49
50 /* Max MPC timeout, in unit of watchdog */
51 #ifndef BRCMS_MPC_MAX_DELAYCNT
52 #define BRCMS_MPC_MAX_DELAYCNT  10
53 #endif
54
55 /* Min MPC timeout, in unit of watchdog */
56 #define BRCMS_MPC_MIN_DELAYCNT  1
57 #define BRCMS_MPC_THRESHOLD     3       /* MPC count threshold level */
58
59 /* beacon interval, in unit of 1024TU */
60 #define BEACON_INTERVAL_DEFAULT 100
61 /* DTIM interval, in unit of beacon interval */
62 #define DTIM_INTERVAL_DEFAULT   3
63
64 /* Scale down delays to accommodate QT slow speed */
65 /* beacon interval, in unit of 1024TU */
66 #define BEACON_INTERVAL_DEF_QT  20
67 /* DTIM interval, in unit of beacon interval */
68 #define DTIM_INTERVAL_DEF_QT    1
69
70 #define TBTT_ALIGN_LEEWAY_US    100     /* min leeway before first TBTT in us */
71
72 /* n-mode support capability */
73 /* 2x2 includes both 1x1 & 2x2 devices
74  * reserved #define 2 for future when we want to separate 1x1 & 2x2 and
75  * control it independently
76  */
77 #define WL_11N_2x2                      1
78 #define WL_11N_3x3                      3
79 #define WL_11N_4x4                      4
80
81 /* define 11n feature disable flags */
82 #define WLFEATURE_DISABLE_11N           0x00000001
83 #define WLFEATURE_DISABLE_11N_STBC_TX   0x00000002
84 #define WLFEATURE_DISABLE_11N_STBC_RX   0x00000004
85 #define WLFEATURE_DISABLE_11N_SGI_TX    0x00000008
86 #define WLFEATURE_DISABLE_11N_SGI_RX    0x00000010
87 #define WLFEATURE_DISABLE_11N_AMPDU_TX  0x00000020
88 #define WLFEATURE_DISABLE_11N_AMPDU_RX  0x00000040
89 #define WLFEATURE_DISABLE_11N_GF        0x00000080
90
91 #define EDCF_ACI_MASK                0x60
92 #define EDCF_ACI_SHIFT               5
93 #define EDCF_ECWMIN_MASK             0x0f
94 #define EDCF_ECWMAX_SHIFT            4
95 #define EDCF_AIFSN_MASK              0x0f
96 #define EDCF_AIFSN_MAX               15
97 #define EDCF_ECWMAX_MASK             0xf0
98
99 #define EDCF_AC_BE_TXOP_STA          0x0000
100 #define EDCF_AC_BK_TXOP_STA          0x0000
101 #define EDCF_AC_VO_ACI_STA           0x62
102 #define EDCF_AC_VO_ECW_STA           0x32
103 #define EDCF_AC_VI_ACI_STA           0x42
104 #define EDCF_AC_VI_ECW_STA           0x43
105 #define EDCF_AC_BK_ECW_STA           0xA4
106 #define EDCF_AC_VI_TXOP_STA          0x005e
107 #define EDCF_AC_VO_TXOP_STA          0x002f
108 #define EDCF_AC_BE_ACI_STA           0x03
109 #define EDCF_AC_BE_ECW_STA           0xA4
110 #define EDCF_AC_BK_ACI_STA           0x27
111 #define EDCF_AC_VO_TXOP_AP           0x002f
112
113 #define EDCF_TXOP2USEC(txop)         ((txop) << 5)
114 #define EDCF_ECW2CW(exp)             ((1 << (exp)) - 1)
115
116 #define APHY_SYMBOL_TIME        4
117 #define APHY_PREAMBLE_TIME      16
118 #define APHY_SIGNAL_TIME        4
119 #define APHY_SIFS_TIME          16
120 #define APHY_SERVICE_NBITS      16
121 #define APHY_TAIL_NBITS         6
122 #define BPHY_SIFS_TIME          10
123 #define BPHY_PLCP_SHORT_TIME    96
124
125 #define PREN_PREAMBLE           24
126 #define PREN_MM_EXT             12
127 #define PREN_PREAMBLE_EXT       4
128
129 #define DOT11_MAC_HDR_LEN               24
130 #define DOT11_ACK_LEN           10
131 #define DOT11_BA_LEN            4
132 #define DOT11_OFDM_SIGNAL_EXTENSION     6
133 #define DOT11_MIN_FRAG_LEN              256
134 #define DOT11_RTS_LEN           16
135 #define DOT11_CTS_LEN           10
136 #define DOT11_BA_BITMAP_LEN             128
137 #define DOT11_MIN_BEACON_PERIOD         1
138 #define DOT11_MAX_BEACON_PERIOD         0xFFFF
139 #define DOT11_MAXNUMFRAGS       16
140 #define DOT11_MAX_FRAG_LEN              2346
141
142 #define BPHY_PLCP_TIME          192
143 #define RIFS_11N_TIME           2
144
145 #define WME_VER                 1
146 #define WME_SUBTYPE_PARAM_IE    1
147 #define WME_TYPE                2
148 #define WME_OUI                 "\x00\x50\xf2"
149
150 #define AC_BE                   0
151 #define AC_BK                   1
152 #define AC_VI                   2
153 #define AC_VO                   3
154
155 #define BCN_TMPL_LEN            512     /* length of the BCN template area */
156
157 /* brcms_bss_info flag bit values */
158 #define BRCMS_BSS_HT            0x0020  /* BSS is HT (MIMO) capable */
159
160 /* Flags used in brcms_c_txq_info.stopped */
161 /* per prio flow control bits */
162 #define TXQ_STOP_FOR_PRIOFC_MASK        0x000000FF
163 /* stop txq enqueue for packet drain */
164 #define TXQ_STOP_FOR_PKT_DRAIN          0x00000100
165 /* stop txq enqueue for ampdu flow control */
166 #define TXQ_STOP_FOR_AMPDU_FLOW_CNTRL   0x00000200
167
168 #define BRCMS_HWRXOFF           38      /* chip rx buffer offset */
169
170 /* Find basic rate for a given rate */
171 static u8 brcms_basic_rate(struct brcms_c_info *wlc, u32 rspec)
172 {
173         if (is_mcs_rate(rspec))
174                 return wlc->band->basic_rate[mcs_table[rspec & RSPEC_RATE_MASK]
175                        .leg_ofdm];
176         return wlc->band->basic_rate[rspec & RSPEC_RATE_MASK];
177 }
178
179 static u16 frametype(u32 rspec, u8 mimoframe)
180 {
181         if (is_mcs_rate(rspec))
182                 return mimoframe;
183         return is_cck_rate(rspec) ? FT_CCK : FT_OFDM;
184 }
185
186 /* rfdisable delay timer 500 ms, runs of ALP clock */
187 #define RFDISABLE_DEFAULT       10000000
188
189 #define BRCMS_TEMPSENSE_PERIOD          10      /* 10 second timeout */
190
191 /* precedences numbers for wlc queues. These are twice as may levels as
192  * 802.1D priorities.
193  * Odd numbers are used for HI priority traffic at same precedence levels
194  * These constants are used ONLY by wlc_prio2prec_map.  Do not use them
195  * elsewhere.
196  */
197 #define _BRCMS_PREC_NONE                0       /* None = - */
198 #define _BRCMS_PREC_BK          2       /* BK - Background */
199 #define _BRCMS_PREC_BE          4       /* BE - Best-effort */
200 #define _BRCMS_PREC_EE          6       /* EE - Excellent-effort */
201 #define _BRCMS_PREC_CL          8       /* CL - Controlled Load */
202 #define _BRCMS_PREC_VI          10      /* Vi - Video */
203 #define _BRCMS_PREC_VO          12      /* Vo - Voice */
204 #define _BRCMS_PREC_NC          14      /* NC - Network Control */
205
206 /* The BSS is generating beacons in HW */
207 #define BRCMS_BSSCFG_HW_BCN     0x20
208
209 #define SYNTHPU_DLY_APHY_US     3700    /* a phy synthpu_dly time in us */
210 #define SYNTHPU_DLY_BPHY_US     1050    /* b/g phy synthpu_dly time in us */
211 #define SYNTHPU_DLY_NPHY_US     2048    /* n phy REV3 synthpu_dly time in us */
212 #define SYNTHPU_DLY_LPPHY_US    300     /* lpphy synthpu_dly time in us */
213
214 #define SYNTHPU_DLY_PHY_US_QT   100     /* QT synthpu_dly time in us */
215
216 #define ANTCNT                  10      /* vanilla M_MAX_ANTCNT value */
217
218 /* Per-AC retry limit register definitions; uses defs.h bitfield macros */
219 #define EDCF_SHORT_S            0
220 #define EDCF_SFB_S              4
221 #define EDCF_LONG_S             8
222 #define EDCF_LFB_S              12
223 #define EDCF_SHORT_M            BITFIELD_MASK(4)
224 #define EDCF_SFB_M              BITFIELD_MASK(4)
225 #define EDCF_LONG_M             BITFIELD_MASK(4)
226 #define EDCF_LFB_M              BITFIELD_MASK(4)
227
228 #define RETRY_SHORT_DEF                 7       /* Default Short retry Limit */
229 #define RETRY_SHORT_MAX                 255     /* Maximum Short retry Limit */
230 #define RETRY_LONG_DEF                  4       /* Default Long retry count */
231 #define RETRY_SHORT_FB                  3 /* Short count for fallback rate */
232 #define RETRY_LONG_FB                   2 /* Long count for fallback rate */
233
234 #define APHY_CWMIN              15
235 #define PHY_CWMAX               1023
236
237 #define EDCF_AIFSN_MIN               1
238
239 #define FRAGNUM_MASK            0xF
240
241 #define APHY_SLOT_TIME          9
242 #define BPHY_SLOT_TIME          20
243
244 #define WL_SPURAVOID_OFF        0
245 #define WL_SPURAVOID_ON1        1
246 #define WL_SPURAVOID_ON2        2
247
248 /* invalid core flags, use the saved coreflags */
249 #define BRCMS_USE_COREFLAGS     0xffffffff
250
251 /* values for PLCPHdr_override */
252 #define BRCMS_PLCP_AUTO -1
253 #define BRCMS_PLCP_SHORT        0
254 #define BRCMS_PLCP_LONG 1
255
256 /* values for g_protection_override and n_protection_override */
257 #define BRCMS_PROTECTION_AUTO           -1
258 #define BRCMS_PROTECTION_OFF            0
259 #define BRCMS_PROTECTION_ON             1
260 #define BRCMS_PROTECTION_MMHDR_ONLY     2
261 #define BRCMS_PROTECTION_CTS_ONLY               3
262
263 /* values for g_protection_control and n_protection_control */
264 #define BRCMS_PROTECTION_CTL_OFF                0
265 #define BRCMS_PROTECTION_CTL_LOCAL      1
266 #define BRCMS_PROTECTION_CTL_OVERLAP    2
267
268 /* values for n_protection */
269 #define BRCMS_N_PROTECTION_OFF          0
270 #define BRCMS_N_PROTECTION_OPTIONAL     1
271 #define BRCMS_N_PROTECTION_20IN40               2
272 #define BRCMS_N_PROTECTION_MIXEDMODE    3
273
274 /* values for band specific 40MHz capabilities */
275 #define BRCMS_N_BW_20ALL                        0
276 #define BRCMS_N_BW_40ALL                        1
277 #define BRCMS_N_BW_20IN2G_40IN5G                2
278
279 /* bitflags for SGI support (sgi_rx iovar) */
280 #define BRCMS_N_SGI_20                  0x01
281 #define BRCMS_N_SGI_40                  0x02
282
283 /* defines used by the nrate iovar */
284 /* MSC in use,indicates b0-6 holds an mcs */
285 #define NRATE_MCS_INUSE 0x00000080
286 /* rate/mcs value */
287 #define NRATE_RATE_MASK 0x0000007f
288 /* stf mode mask: siso, cdd, stbc, sdm */
289 #define NRATE_STF_MASK  0x0000ff00
290 /* stf mode shift */
291 #define NRATE_STF_SHIFT 8
292 /* bit indicates override both rate & mode */
293 #define NRATE_OVERRIDE  0x80000000
294 /* bit indicate to override mcs only */
295 #define NRATE_OVERRIDE_MCS_ONLY 0x40000000
296 #define NRATE_SGI_MASK  0x00800000      /* sgi mode */
297 #define NRATE_SGI_SHIFT 23      /* sgi mode */
298 #define NRATE_LDPC_CODING 0x00400000    /* bit indicates adv coding in use */
299 #define NRATE_LDPC_SHIFT 22     /* ldpc shift */
300
301 #define NRATE_STF_SISO  0       /* stf mode SISO */
302 #define NRATE_STF_CDD   1       /* stf mode CDD */
303 #define NRATE_STF_STBC  2       /* stf mode STBC */
304 #define NRATE_STF_SDM   3       /* stf mode SDM */
305
306 #define MAX_DMA_SEGS 4
307
308 /* Max # of entries in Tx FIFO based on 4kb page size */
309 #define NTXD            256
310 /* Max # of entries in Rx FIFO based on 4kb page size */
311 #define NRXD            256
312
313 /* try to keep this # rbufs posted to the chip */
314 #define NRXBUFPOST      32
315
316 /* data msg txq hiwat mark */
317 #define BRCMS_DATAHIWAT         50
318
319 /* bounded rx loops */
320 #define RXBND           8 /* max # frames to process in brcms_c_recv() */
321 #define TXSBND          8 /* max # tx status to process in wlc_txstatus() */
322
323 /*
324  * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL.
325  */
326 #define SSID_FMT_BUF_LEN        ((4 * IEEE80211_MAX_SSID_LEN) + 1)
327
328 /*
329  * The following table lists the buffer memory allocated to xmt fifos in HW.
330  * the size is in units of 256bytes(one block), total size is HW dependent
331  * ucode has default fifo partition, sw can overwrite if necessary
332  *
333  * This is documented in twiki under the topic UcodeTxFifo. Please ensure
334  * the twiki is updated before making changes.
335  */
336
337 /* Starting corerev for the fifo size table */
338 #define XMTFIFOTBL_STARTREV     20
339
340 struct d11init {
341         __le16 addr;
342         __le16 size;
343         __le32 value;
344 };
345
346 /* currently the best mechanism for determining SIFS is the band in use */
347 static u16 get_sifs(struct brcms_band *band)
348 {
349         return band->bandtype == BRCM_BAND_5G ? APHY_SIFS_TIME :
350                                  BPHY_SIFS_TIME;
351 }
352
353
354 /*
355  * Detect Card removed.
356  * Even checking an sbconfig register read will not false trigger when the core
357  * is in reset it breaks CF address mechanism. Accessing gphy phyversion will
358  * cause SB error if aphy is in reset on 4306B0-DB. Need a simple accessible
359  * reg with fixed 0/1 pattern (some platforms return all 0).
360  * If clocks are present, call the sb routine which will figure out if the
361  * device is removed.
362  */
363 static bool brcms_deviceremoved(struct brcms_c_info *wlc)
364 {
365         if (!wlc->hw->clk)
366                 return ai_deviceremoved(wlc->hw->sih);
367         return (R_REG(&wlc->hw->regs->maccontrol) &
368                 (MCTL_PSM_JMP_0 | MCTL_IHR_EN)) != MCTL_IHR_EN;
369 }
370
371 /* sum the individual fifo tx pending packet counts */
372 static s16 brcms_txpktpendtot(struct brcms_c_info *wlc)
373 {
374         return wlc->core->txpktpend[0] + wlc->core->txpktpend[1] +
375                wlc->core->txpktpend[2] + wlc->core->txpktpend[3];
376 }
377
378 static bool brcms_is_mband_unlocked(struct brcms_c_info *wlc)
379 {
380         return wlc->pub->_nbands > 1 && !wlc->bandlocked;
381 }
382
383 static int brcms_chspec_bw(u16 chanspec)
384 {
385         if (CHSPEC_IS40(chanspec))
386                 return BRCMS_40_MHZ;
387         if (CHSPEC_IS20(chanspec))
388                 return BRCMS_20_MHZ;
389
390         return BRCMS_10_MHZ;
391 }
392
393 /* dup state between BMAC(struct brcms_hardware) and HIGH(struct brcms_c_info)
394    driver */
395 struct brcms_b_state {
396         u32 machwcap;   /* mac hw capibility */
397         u32 preamble_ovr;       /* preamble override */
398 };
399
400 struct edcf_acparam {
401         u8 ACI;
402         u8 ECW;
403         u16 TXOP;
404 } __packed;
405
406 const u8 prio2fifo[NUMPRIO] = {
407         TX_AC_BE_FIFO,          /* 0    BE      AC_BE   Best Effort */
408         TX_AC_BK_FIFO,          /* 1    BK      AC_BK   Background */
409         TX_AC_BK_FIFO,          /* 2    --      AC_BK   Background */
410         TX_AC_BE_FIFO,          /* 3    EE      AC_BE   Best Effort */
411         TX_AC_VI_FIFO,          /* 4    CL      AC_VI   Video */
412         TX_AC_VI_FIFO,          /* 5    VI      AC_VI   Video */
413         TX_AC_VO_FIFO,          /* 6    VO      AC_VO   Voice */
414         TX_AC_VO_FIFO           /* 7    NC      AC_VO   Voice */
415 };
416
417 /* debug/trace */
418 uint brcm_msg_level =
419 #if defined(BCMDBG)
420         LOG_ERROR_VAL;
421 #else
422         0;
423 #endif                          /* BCMDBG */
424
425 /* TX FIFO number to WME/802.1E Access Category */
426 static const u8 wme_fifo2ac[] = { AC_BK, AC_BE, AC_VI, AC_VO, AC_BE, AC_BE };
427
428 /* WME/802.1E Access Category to TX FIFO number */
429 static const u8 wme_ac2fifo[] = { 1, 0, 2, 3 };
430
431 /* 802.1D Priority to precedence queue mapping */
432 const u8 wlc_prio2prec_map[] = {
433         _BRCMS_PREC_BE,         /* 0 BE - Best-effort */
434         _BRCMS_PREC_BK,         /* 1 BK - Background */
435         _BRCMS_PREC_NONE,               /* 2 None = - */
436         _BRCMS_PREC_EE,         /* 3 EE - Excellent-effort */
437         _BRCMS_PREC_CL,         /* 4 CL - Controlled Load */
438         _BRCMS_PREC_VI,         /* 5 Vi - Video */
439         _BRCMS_PREC_VO,         /* 6 Vo - Voice */
440         _BRCMS_PREC_NC,         /* 7 NC - Network Control */
441 };
442
443 static const u16 xmtfifo_sz[][NFIFO] = {
444         /* corerev 20: 5120, 49152, 49152, 5376, 4352, 1280 */
445         {20, 192, 192, 21, 17, 5},
446         /* corerev 21: 2304, 14848, 5632, 3584, 3584, 1280 */
447         {9, 58, 22, 14, 14, 5},
448         /* corerev 22: 5120, 49152, 49152, 5376, 4352, 1280 */
449         {20, 192, 192, 21, 17, 5},
450         /* corerev 23: 5120, 49152, 49152, 5376, 4352, 1280 */
451         {20, 192, 192, 21, 17, 5},
452         /* corerev 24: 2304, 14848, 5632, 3584, 3584, 1280 */
453         {9, 58, 22, 14, 14, 5},
454 };
455
456 static const u8 acbitmap2maxprio[] = {
457         PRIO_8021D_BE, PRIO_8021D_BE, PRIO_8021D_BK, PRIO_8021D_BK,
458         PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI,
459         PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO,
460         PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO
461 };
462
463 #ifdef BCMDBG
464 static const char * const fifo_names[] = {
465         "AC_BK", "AC_BE", "AC_VI", "AC_VO", "BCMC", "ATIM" };
466 #else
467 static const char fifo_names[6][0];
468 #endif
469
470 #ifdef BCMDBG
471 /* pointer to most recently allocated wl/wlc */
472 static struct brcms_c_info *wlc_info_dbg = (struct brcms_c_info *) (NULL);
473 #endif
474
475 static void brcms_c_bsscfg_mfree(struct brcms_bss_cfg *cfg)
476 {
477         if (cfg == NULL)
478                 return;
479
480         kfree(cfg->current_bss);
481         kfree(cfg);
482 }
483
484 static void brcms_c_detach_mfree(struct brcms_c_info *wlc)
485 {
486         if (wlc == NULL)
487                 return;
488
489         brcms_c_bsscfg_mfree(wlc->bsscfg);
490         kfree(wlc->pub);
491         kfree(wlc->modulecb);
492         kfree(wlc->default_bss);
493         kfree(wlc->protection);
494         kfree(wlc->stf);
495         kfree(wlc->bandstate[0]);
496         kfree(wlc->corestate->macstat_snapshot);
497         kfree(wlc->corestate);
498         kfree(wlc->hw->bandstate[0]);
499         kfree(wlc->hw);
500
501         /* free the wlc */
502         kfree(wlc);
503         wlc = NULL;
504 }
505
506 static struct brcms_bss_cfg *brcms_c_bsscfg_malloc(uint unit)
507 {
508         struct brcms_bss_cfg *cfg;
509
510         cfg = kzalloc(sizeof(struct brcms_bss_cfg), GFP_ATOMIC);
511         if (cfg == NULL)
512                 goto fail;
513
514         cfg->current_bss = kzalloc(sizeof(struct brcms_bss_info), GFP_ATOMIC);
515         if (cfg->current_bss == NULL)
516                 goto fail;
517
518         return cfg;
519
520  fail:
521         brcms_c_bsscfg_mfree(cfg);
522         return NULL;
523 }
524
525 static struct brcms_c_info *
526 brcms_c_attach_malloc(uint unit, uint *err, uint devid)
527 {
528         struct brcms_c_info *wlc;
529
530         wlc = kzalloc(sizeof(struct brcms_c_info), GFP_ATOMIC);
531         if (wlc == NULL) {
532                 *err = 1002;
533                 goto fail;
534         }
535
536         /* allocate struct brcms_c_pub state structure */
537         wlc->pub = kzalloc(sizeof(struct brcms_pub), GFP_ATOMIC);
538         if (wlc->pub == NULL) {
539                 *err = 1003;
540                 goto fail;
541         }
542         wlc->pub->wlc = wlc;
543
544         /* allocate struct brcms_hardware state structure */
545
546         wlc->hw = kzalloc(sizeof(struct brcms_hardware), GFP_ATOMIC);
547         if (wlc->hw == NULL) {
548                 *err = 1005;
549                 goto fail;
550         }
551         wlc->hw->wlc = wlc;
552
553         wlc->hw->bandstate[0] =
554                 kzalloc(sizeof(struct brcms_hw_band) * MAXBANDS, GFP_ATOMIC);
555         if (wlc->hw->bandstate[0] == NULL) {
556                 *err = 1006;
557                 goto fail;
558         } else {
559                 int i;
560
561                 for (i = 1; i < MAXBANDS; i++)
562                         wlc->hw->bandstate[i] = (struct brcms_hw_band *)
563                             ((unsigned long)wlc->hw->bandstate[0] +
564                              (sizeof(struct brcms_hw_band) * i));
565         }
566
567         wlc->modulecb =
568                 kzalloc(sizeof(struct modulecb) * BRCMS_MAXMODULES, GFP_ATOMIC);
569         if (wlc->modulecb == NULL) {
570                 *err = 1009;
571                 goto fail;
572         }
573
574         wlc->default_bss = kzalloc(sizeof(struct brcms_bss_info), GFP_ATOMIC);
575         if (wlc->default_bss == NULL) {
576                 *err = 1010;
577                 goto fail;
578         }
579
580         wlc->bsscfg = brcms_c_bsscfg_malloc(unit);
581         if (wlc->bsscfg == NULL) {
582                 *err = 1011;
583                 goto fail;
584         }
585
586         wlc->protection = kzalloc(sizeof(struct brcms_protection),
587                                   GFP_ATOMIC);
588         if (wlc->protection == NULL) {
589                 *err = 1016;
590                 goto fail;
591         }
592
593         wlc->stf = kzalloc(sizeof(struct brcms_stf), GFP_ATOMIC);
594         if (wlc->stf == NULL) {
595                 *err = 1017;
596                 goto fail;
597         }
598
599         wlc->bandstate[0] =
600                 kzalloc(sizeof(struct brcms_band)*MAXBANDS, GFP_ATOMIC);
601         if (wlc->bandstate[0] == NULL) {
602                 *err = 1025;
603                 goto fail;
604         } else {
605                 int i;
606
607                 for (i = 1; i < MAXBANDS; i++)
608                         wlc->bandstate[i] = (struct brcms_band *)
609                                 ((unsigned long)wlc->bandstate[0]
610                                 + (sizeof(struct brcms_band)*i));
611         }
612
613         wlc->corestate = kzalloc(sizeof(struct brcms_core), GFP_ATOMIC);
614         if (wlc->corestate == NULL) {
615                 *err = 1026;
616                 goto fail;
617         }
618
619         wlc->corestate->macstat_snapshot =
620                 kzalloc(sizeof(struct macstat), GFP_ATOMIC);
621         if (wlc->corestate->macstat_snapshot == NULL) {
622                 *err = 1027;
623                 goto fail;
624         }
625
626         return wlc;
627
628  fail:
629         brcms_c_detach_mfree(wlc);
630         return NULL;
631 }
632
633 /*
634  * Update the slot timing for standard 11b/g (20us slots)
635  * or shortslot 11g (9us slots)
636  * The PSM needs to be suspended for this call.
637  */
638 static void brcms_b_update_slot_timing(struct brcms_hardware *wlc_hw,
639                                         bool shortslot)
640 {
641         struct d11regs *regs;
642
643         regs = wlc_hw->regs;
644
645         if (shortslot) {
646                 /* 11g short slot: 11a timing */
647                 W_REG(&regs->ifs_slot, 0x0207); /* APHY_SLOT_TIME */
648                 brcms_b_write_shm(wlc_hw, M_DOT11_SLOT, APHY_SLOT_TIME);
649         } else {
650                 /* 11g long slot: 11b timing */
651                 W_REG(&regs->ifs_slot, 0x0212); /* BPHY_SLOT_TIME */
652                 brcms_b_write_shm(wlc_hw, M_DOT11_SLOT, BPHY_SLOT_TIME);
653         }
654 }
655
656 static void brcms_c_write_inits(struct brcms_hardware *wlc_hw,
657                                 const struct d11init *inits)
658 {
659         int i;
660         u8 *base;
661         u8 *addr;
662         u16 size;
663         u32 value;
664
665         BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
666
667         base = (u8 *)wlc_hw->regs;
668
669         for (i = 0; inits[i].addr != cpu_to_le16(0xffff); i++) {
670                 size = le16_to_cpu(inits[i].size);
671                 addr = base + le16_to_cpu(inits[i].addr);
672                 value = le32_to_cpu(inits[i].value);
673                 if (size == 2)
674                         W_REG((u16 *)addr, value);
675                 else if (size == 4)
676                         W_REG((u32 *)addr, value);
677                 else
678                         break;
679         }
680 }
681
682 static void brcms_c_write_mhf(struct brcms_hardware *wlc_hw, u16 *mhfs)
683 {
684         u8 idx;
685         u16 addr[] = {
686                 M_HOST_FLAGS1, M_HOST_FLAGS2, M_HOST_FLAGS3, M_HOST_FLAGS4,
687                 M_HOST_FLAGS5
688         };
689
690         for (idx = 0; idx < MHFMAX; idx++)
691                 brcms_b_write_shm(wlc_hw, addr[idx], mhfs[idx]);
692 }
693
694 static void brcms_c_ucode_bsinit(struct brcms_hardware *wlc_hw)
695 {
696         struct wiphy *wiphy = wlc_hw->wlc->wiphy;
697         struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode;
698
699         /* init microcode host flags */
700         brcms_c_write_mhf(wlc_hw, wlc_hw->band->mhfs);
701
702         /* do band-specific ucode IHR, SHM, and SCR inits */
703         if (D11REV_IS(wlc_hw->corerev, 23)) {
704                 if (BRCMS_ISNPHY(wlc_hw->band))
705                         brcms_c_write_inits(wlc_hw, ucode->d11n0bsinitvals16);
706                 else
707                         wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev"
708                                   " %d\n", __func__, wlc_hw->unit,
709                                   wlc_hw->corerev);
710         } else {
711                 if (D11REV_IS(wlc_hw->corerev, 24)) {
712                         if (BRCMS_ISLCNPHY(wlc_hw->band))
713                                 brcms_c_write_inits(wlc_hw,
714                                                     ucode->d11lcn0bsinitvals24);
715                         else
716                                 wiphy_err(wiphy, "%s: wl%d: unsupported phy in"
717                                           " core rev %d\n", __func__,
718                                           wlc_hw->unit, wlc_hw->corerev);
719                 } else {
720                         wiphy_err(wiphy, "%s: wl%d: unsupported corerev %d\n",
721                                 __func__, wlc_hw->unit, wlc_hw->corerev);
722                 }
723         }
724 }
725
726 static void brcms_b_core_phy_clk(struct brcms_hardware *wlc_hw, bool clk)
727 {
728         BCMMSG(wlc_hw->wlc->wiphy, "wl%d: clk %d\n", wlc_hw->unit, clk);
729
730         wlc_hw->phyclk = clk;
731
732         if (OFF == clk) {       /* clear gmode bit, put phy into reset */
733
734                 ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC | SICF_GMODE),
735                                (SICF_PRST | SICF_FGC));
736                 udelay(1);
737                 ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC), SICF_PRST);
738                 udelay(1);
739
740         } else {                /* take phy out of reset */
741
742                 ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC), SICF_FGC);
743                 udelay(1);
744                 ai_core_cflags(wlc_hw->sih, (SICF_FGC), 0);
745                 udelay(1);
746
747         }
748 }
749
750 /* switch to new band but leave it inactive */
751 static u32 brcms_c_setband_inact(struct brcms_c_info *wlc, uint bandunit)
752 {
753         struct brcms_hardware *wlc_hw = wlc->hw;
754         u32 macintmask;
755
756         BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
757
758         WARN_ON((R_REG(&wlc_hw->regs->maccontrol) & MCTL_EN_MAC) != 0);
759
760         /* disable interrupts */
761         macintmask = brcms_intrsoff(wlc->wl);
762
763         /* radio off */
764         wlc_phy_switch_radio(wlc_hw->band->pi, OFF);
765
766         brcms_b_core_phy_clk(wlc_hw, OFF);
767
768         brcms_c_setxband(wlc_hw, bandunit);
769
770         return macintmask;
771 }
772
773 /* Process received frames */
774 /*
775  * Return true if more frames need to be processed. false otherwise.
776  * Param 'bound' indicates max. # frames to process before break out.
777  */
778 static bool
779 brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound)
780 {
781         struct sk_buff *p;
782         struct sk_buff *head = NULL;
783         struct sk_buff *tail = NULL;
784         uint n = 0;
785         uint bound_limit = bound ? RXBND : -1;
786
787         BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
788         /* gather received frames */
789         while ((p = dma_rx(wlc_hw->di[fifo]))) {
790
791                 if (!tail)
792                         head = tail = p;
793                 else {
794                         tail->prev = p;
795                         tail = p;
796                 }
797
798                 /* !give others some time to run! */
799                 if (++n >= bound_limit)
800                         break;
801         }
802
803         /* post more rbufs */
804         dma_rxfill(wlc_hw->di[fifo]);
805
806         /* process each frame */
807         while ((p = head) != NULL) {
808                 struct d11rxhdr_le *rxh_le;
809                 struct d11rxhdr *rxh;
810                 head = head->prev;
811                 p->prev = NULL;
812
813                 rxh_le = (struct d11rxhdr_le *)p->data;
814                 rxh = (struct d11rxhdr *)p->data;
815
816                 /* fixup rx header endianness */
817                 rxh->RxFrameSize = le16_to_cpu(rxh_le->RxFrameSize);
818                 rxh->PhyRxStatus_0 = le16_to_cpu(rxh_le->PhyRxStatus_0);
819                 rxh->PhyRxStatus_1 = le16_to_cpu(rxh_le->PhyRxStatus_1);
820                 rxh->PhyRxStatus_2 = le16_to_cpu(rxh_le->PhyRxStatus_2);
821                 rxh->PhyRxStatus_3 = le16_to_cpu(rxh_le->PhyRxStatus_3);
822                 rxh->PhyRxStatus_4 = le16_to_cpu(rxh_le->PhyRxStatus_4);
823                 rxh->PhyRxStatus_5 = le16_to_cpu(rxh_le->PhyRxStatus_5);
824                 rxh->RxStatus1 = le16_to_cpu(rxh_le->RxStatus1);
825                 rxh->RxStatus2 = le16_to_cpu(rxh_le->RxStatus2);
826                 rxh->RxTSFTime = le16_to_cpu(rxh_le->RxTSFTime);
827                 rxh->RxChan = le16_to_cpu(rxh_le->RxChan);
828
829                 brcms_c_recv(wlc_hw->wlc, p);
830         }
831
832         return n >= bound_limit;
833 }
834
835 /* process an individual struct tx_status */
836 static bool
837 brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
838 {
839         struct sk_buff *p;
840         uint queue;
841         struct d11txh *txh;
842         struct scb *scb = NULL;
843         bool free_pdu;
844         int tx_rts, tx_frame_count, tx_rts_count;
845         uint totlen, supr_status;
846         bool lastframe;
847         struct ieee80211_hdr *h;
848         u16 mcl;
849         struct ieee80211_tx_info *tx_info;
850         struct ieee80211_tx_rate *txrate;
851         int i;
852
853         /* discard intermediate indications for ucode with one legitimate case:
854          *   e.g. if "useRTS" is set. ucode did a successful rts/cts exchange,
855          *   but the subsequent tx of DATA failed. so it will start rts/cts
856          *   from the beginning (resetting the rts transmission count)
857          */
858         if (!(txs->status & TX_STATUS_AMPDU)
859             && (txs->status & TX_STATUS_INTERMEDIATE)) {
860                 wiphy_err(wlc->wiphy, "%s: INTERMEDIATE but not AMPDU\n",
861                           __func__);
862                 return false;
863         }
864
865         queue = txs->frameid & TXFID_QUEUE_MASK;
866         if (queue >= NFIFO) {
867                 p = NULL;
868                 goto fatal;
869         }
870
871         p = dma_getnexttxp(wlc->hw->di[queue], DMA_RANGE_TRANSMITTED);
872         if (p == NULL)
873                 goto fatal;
874
875         txh = (struct d11txh *) (p->data);
876         mcl = le16_to_cpu(txh->MacTxControlLow);
877
878         if (txs->phyerr) {
879                 if (brcm_msg_level & LOG_ERROR_VAL) {
880                         wiphy_err(wlc->wiphy, "phyerr 0x%x, rate 0x%x\n",
881                                   txs->phyerr, txh->MainRates);
882                         brcms_c_print_txdesc(txh);
883                 }
884                 brcms_c_print_txstatus(txs);
885         }
886
887         if (txs->frameid != le16_to_cpu(txh->TxFrameID))
888                 goto fatal;
889         tx_info = IEEE80211_SKB_CB(p);
890         h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN);
891
892         if (tx_info->control.sta)
893                 scb = &wlc->pri_scb;
894
895         if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
896                 brcms_c_ampdu_dotxstatus(wlc->ampdu, scb, p, txs);
897                 return false;
898         }
899
900         supr_status = txs->status & TX_STATUS_SUPR_MASK;
901         if (supr_status == TX_STATUS_SUPR_BADCH)
902                 BCMMSG(wlc->wiphy,
903                        "%s: Pkt tx suppressed, possibly channel %d\n",
904                        __func__, CHSPEC_CHANNEL(wlc->default_bss->chanspec));
905
906         tx_rts = le16_to_cpu(txh->MacTxControlLow) & TXC_SENDRTS;
907         tx_frame_count =
908             (txs->status & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT;
909         tx_rts_count =
910             (txs->status & TX_STATUS_RTS_RTX_MASK) >> TX_STATUS_RTS_RTX_SHIFT;
911
912         lastframe = !ieee80211_has_morefrags(h->frame_control);
913
914         if (!lastframe) {
915                 wiphy_err(wlc->wiphy, "Not last frame!\n");
916         } else {
917                 /*
918                  * Set information to be consumed by Minstrel ht.
919                  *
920                  * The "fallback limit" is the number of tx attempts a given
921                  * MPDU is sent at the "primary" rate. Tx attempts beyond that
922                  * limit are sent at the "secondary" rate.
923                  * A 'short frame' does not exceed RTS treshold.
924                  */
925                 u16 sfbl,       /* Short Frame Rate Fallback Limit */
926                     lfbl,       /* Long Frame Rate Fallback Limit */
927                     fbl;
928
929                 if (queue < AC_COUNT) {
930                         sfbl = GFIELD(wlc->wme_retries[wme_fifo2ac[queue]],
931                                       EDCF_SFB);
932                         lfbl = GFIELD(wlc->wme_retries[wme_fifo2ac[queue]],
933                                       EDCF_LFB);
934                 } else {
935                         sfbl = wlc->SFBL;
936                         lfbl = wlc->LFBL;
937                 }
938
939                 txrate = tx_info->status.rates;
940                 if (txrate[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
941                         fbl = lfbl;
942                 else
943                         fbl = sfbl;
944
945                 ieee80211_tx_info_clear_status(tx_info);
946
947                 if ((tx_frame_count > fbl) && (txrate[1].idx >= 0)) {
948                         /*
949                          * rate selection requested a fallback rate
950                          * and we used it
951                          */
952                         txrate[0].count = fbl;
953                         txrate[1].count = tx_frame_count - fbl;
954                 } else {
955                         /*
956                          * rate selection did not request fallback rate, or
957                          * we didn't need it
958                          */
959                         txrate[0].count = tx_frame_count;
960                         /*
961                          * rc80211_minstrel.c:minstrel_tx_status() expects
962                          * unused rates to be marked with idx = -1
963                          */
964                         txrate[1].idx = -1;
965                         txrate[1].count = 0;
966                 }
967
968                 /* clear the rest of the rates */
969                 for (i = 2; i < IEEE80211_TX_MAX_RATES; i++) {
970                         txrate[i].idx = -1;
971                         txrate[i].count = 0;
972                 }
973
974                 if (txs->status & TX_STATUS_ACK_RCV)
975                         tx_info->flags |= IEEE80211_TX_STAT_ACK;
976         }
977
978         totlen = brcmu_pkttotlen(p);
979         free_pdu = true;
980
981         brcms_c_txfifo_complete(wlc, queue, 1);
982
983         if (lastframe) {
984                 p->next = NULL;
985                 p->prev = NULL;
986                 /* remove PLCP & Broadcom tx descriptor header */
987                 skb_pull(p, D11_PHY_HDR_LEN);
988                 skb_pull(p, D11_TXH_LEN);
989                 ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p);
990         } else {
991                 wiphy_err(wlc->wiphy, "%s: Not last frame => not calling "
992                           "tx_status\n", __func__);
993         }
994
995         return false;
996
997  fatal:
998         if (p)
999                 brcmu_pkt_buf_free_skb(p);
1000
1001         return true;
1002
1003 }
1004
1005 static bool
1006 brcms_b_dotxstatus(struct brcms_hardware *wlc_hw, struct tx_status *txs)
1007 {
1008         /* discard intermediate indications for ucode with one legitimate case:
1009          *   e.g. if "useRTS" is set. ucode did a successful rts/cts exchange,
1010          *   but the subsequent tx of DATA failed. so it will start rts/cts from
1011          *   the beginning (resetting the rts transmission count)
1012          */
1013         if (!(txs->status & TX_STATUS_AMPDU)
1014             && (txs->status & TX_STATUS_INTERMEDIATE))
1015                 return false;
1016
1017         return brcms_c_dotxstatus(wlc_hw->wlc, txs);
1018 }
1019
1020 /* process tx completion events in BMAC
1021  * Return true if more tx status need to be processed. false otherwise.
1022  */
1023 static bool
1024 brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
1025 {
1026         bool morepending = false;
1027         struct brcms_c_info *wlc = wlc_hw->wlc;
1028         struct d11regs *regs;
1029         struct tx_status txstatus, *txs;
1030         u32 s1, s2;
1031         uint n = 0;
1032         /*
1033          * Param 'max_tx_num' indicates max. # tx status to process before
1034          * break out.
1035          */
1036         uint max_tx_num = bound ? TXSBND : -1;
1037
1038         BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
1039
1040         txs = &txstatus;
1041         regs = wlc_hw->regs;
1042         while (!(*fatal)
1043                && (s1 = R_REG(&regs->frmtxstatus)) & TXS_V) {
1044
1045                 if (s1 == 0xffffffff) {
1046                         wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n",
1047                                 wlc_hw->unit, __func__);
1048                         return morepending;
1049                 }
1050
1051                         s2 = R_REG(&regs->frmtxstatus2);
1052
1053                 txs->status = s1 & TXS_STATUS_MASK;
1054                 txs->frameid = (s1 & TXS_FID_MASK) >> TXS_FID_SHIFT;
1055                 txs->sequence = s2 & TXS_SEQ_MASK;
1056                 txs->phyerr = (s2 & TXS_PTX_MASK) >> TXS_PTX_SHIFT;
1057                 txs->lasttxtime = 0;
1058
1059                 *fatal = brcms_b_dotxstatus(wlc_hw, txs);
1060
1061                 /* !give others some time to run! */
1062                 if (++n >= max_tx_num)
1063                         break;
1064         }
1065
1066         if (*fatal)
1067                 return 0;
1068
1069         if (n >= max_tx_num)
1070                 morepending = true;
1071
1072         if (!pktq_empty(&wlc->pkt_queue->q))
1073                 brcms_c_send_q(wlc);
1074
1075         return morepending;
1076 }
1077
1078 /* brcms_b_tx_fifo_suspended:
1079  * Check the MAC's tx suspend status for a tx fifo.
1080  *
1081  * When the MAC acknowledges a tx suspend, it indicates that no more
1082  * packets will be transmitted out the radio. This is independent of
1083  * DMA channel suspension---the DMA may have finished suspending, or may still
1084  * be pulling data into a tx fifo, by the time the MAC acks the suspend
1085  * request.
1086  */
1087 static bool brcms_b_tx_fifo_suspended(struct brcms_hardware *wlc_hw,
1088                                       uint tx_fifo)
1089 {
1090         /* check that a suspend has been requested and is no longer pending */
1091
1092         /*
1093          * for DMA mode, the suspend request is set in xmtcontrol of the DMA
1094          * engine, and the tx fifo suspend at the lower end of the MAC is
1095          * acknowledged in the chnstatus register.
1096          *
1097          * The tx fifo suspend completion is independent of the DMA suspend
1098          * completion and may be acked before or after the DMA is suspended.
1099          */
1100         if (dma_txsuspended(wlc_hw->di[tx_fifo]) &&
1101             (R_REG(&wlc_hw->regs->chnstatus) &
1102              (1 << tx_fifo)) == 0)
1103                 return true;
1104
1105         return false;
1106 }
1107
1108 /* second-level interrupt processing
1109  *   Return true if another dpc needs to be re-scheduled. false otherwise.
1110  *   Param 'bounded' indicates if applicable loops should be bounded.
1111  */
1112 bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded)
1113 {
1114         u32 macintstatus;
1115         struct brcms_hardware *wlc_hw = wlc->hw;
1116         struct d11regs *regs = wlc_hw->regs;
1117         bool fatal = false;
1118         struct wiphy *wiphy = wlc->wiphy;
1119
1120         if (brcms_deviceremoved(wlc)) {
1121                 wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
1122                           __func__);
1123                 brcms_down(wlc->wl);
1124                 return false;
1125         }
1126
1127         /* grab and clear the saved software intstatus bits */
1128         macintstatus = wlc->macintstatus;
1129         wlc->macintstatus = 0;
1130
1131         BCMMSG(wlc->wiphy, "wl%d: macintstatus 0x%x\n",
1132                wlc_hw->unit, macintstatus);
1133
1134         WARN_ON(macintstatus & MI_PRQ); /* PRQ Interrupt in non-MBSS */
1135
1136         /* tx status */
1137         if (macintstatus & MI_TFS) {
1138                 if (brcms_b_txstatus(wlc->hw, bounded, &fatal))
1139                         wlc->macintstatus |= MI_TFS;
1140                 if (fatal) {
1141                         wiphy_err(wiphy, "MI_TFS: fatal\n");
1142                         goto fatal;
1143                 }
1144         }
1145
1146         if (macintstatus & (MI_TBTT | MI_DTIM_TBTT))
1147                 brcms_c_tbtt(wlc);
1148
1149         /* ATIM window end */
1150         if (macintstatus & MI_ATIMWINEND) {
1151                 BCMMSG(wlc->wiphy, "end of ATIM window\n");
1152                 OR_REG(&regs->maccommand, wlc->qvalid);
1153                 wlc->qvalid = 0;
1154         }
1155
1156         /*
1157          * received data or control frame, MI_DMAINT is
1158          * indication of RX_FIFO interrupt
1159          */
1160         if (macintstatus & MI_DMAINT)
1161                 if (brcms_b_recv(wlc_hw, RX_FIFO, bounded))
1162                         wlc->macintstatus |= MI_DMAINT;
1163
1164         /* TX FIFO suspend/flush completion */
1165         if (macintstatus & MI_TXSTOP)
1166                 brcms_b_tx_fifo_suspended(wlc_hw, TX_DATA_FIFO);
1167
1168         /* noise sample collected */
1169         if (macintstatus & MI_BG_NOISE)
1170                 wlc_phy_noise_sample_intr(wlc_hw->band->pi);
1171
1172         if (macintstatus & MI_GP0) {
1173                 wiphy_err(wiphy, "wl%d: PSM microcode watchdog fired at %d "
1174                         "(seconds). Resetting.\n", wlc_hw->unit, wlc_hw->now);
1175
1176                 printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n",
1177                                         __func__, wlc_hw->sih->chip,
1178                                         wlc_hw->sih->chiprev);
1179                 /* big hammer */
1180                 brcms_init(wlc->wl);
1181         }
1182
1183         /* gptimer timeout */
1184         if (macintstatus & MI_TO)
1185                 W_REG(&regs->gptimer, 0);
1186
1187         if (macintstatus & MI_RFDISABLE) {
1188                 BCMMSG(wlc->wiphy, "wl%d: BMAC Detected a change on the"
1189                        " RF Disable Input\n", wlc_hw->unit);
1190                 brcms_rfkill_set_hw_state(wlc->wl);
1191         }
1192
1193         /* send any enq'd tx packets. Just makes sure to jump start tx */
1194         if (!pktq_empty(&wlc->pkt_queue->q))
1195                 brcms_c_send_q(wlc);
1196
1197         /* it isn't done and needs to be resched if macintstatus is non-zero */
1198         return wlc->macintstatus != 0;
1199
1200  fatal:
1201         brcms_init(wlc->wl);
1202         return wlc->macintstatus != 0;
1203 }
1204
1205 static int brcms_b_state_get(struct brcms_hardware *wlc_hw,
1206                       struct brcms_b_state *state)
1207 {
1208         state->machwcap = wlc_hw->machwcap;
1209
1210         return 0;
1211 }
1212
1213 /* set initial host flags value */
1214 static void
1215 brcms_c_mhfdef(struct brcms_c_info *wlc, u16 *mhfs, u16 mhf2_init)
1216 {
1217         struct brcms_hardware *wlc_hw = wlc->hw;
1218
1219         memset(mhfs, 0, MHFMAX * sizeof(u16));
1220
1221         mhfs[MHF2] |= mhf2_init;
1222
1223         /* prohibit use of slowclock on multifunction boards */
1224         if (wlc_hw->boardflags & BFL_NOPLLDOWN)
1225                 mhfs[MHF1] |= MHF1_FORCEFASTCLK;
1226
1227         if (BRCMS_ISNPHY(wlc_hw->band) && NREV_LT(wlc_hw->band->phyrev, 2)) {
1228                 mhfs[MHF2] |= MHF2_NPHY40MHZ_WAR;
1229                 mhfs[MHF1] |= MHF1_IQSWAP_WAR;
1230         }
1231 }
1232
1233 static struct dma64regs *
1234 dmareg(struct brcms_hardware *hw, uint direction, uint fifonum)
1235 {
1236         if (direction == DMA_TX)
1237                 return &(hw->regs->fifo64regs[fifonum].dmaxmt);
1238         return &(hw->regs->fifo64regs[fifonum].dmarcv);
1239 }
1240
1241 static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme)
1242 {
1243         uint i;
1244         char name[8];
1245         /*
1246          * ucode host flag 2 needed for pio mode, independent of band and fifo
1247          */
1248         u16 pio_mhf2 = 0;
1249         struct brcms_hardware *wlc_hw = wlc->hw;
1250         uint unit = wlc_hw->unit;
1251         struct wiphy *wiphy = wlc->wiphy;
1252
1253         /* name and offsets for dma_attach */
1254         snprintf(name, sizeof(name), "wl%d", unit);
1255
1256         if (wlc_hw->di[0] == NULL) {    /* Init FIFOs */
1257                 int dma_attach_err = 0;
1258
1259                 /*
1260                  * FIFO 0
1261                  * TX: TX_AC_BK_FIFO (TX AC Background data packets)
1262                  * RX: RX_FIFO (RX data packets)
1263                  */
1264                 wlc_hw->di[0] = dma_attach(name, wlc_hw->sih,
1265                                            (wme ? dmareg(wlc_hw, DMA_TX, 0) :
1266                                             NULL), dmareg(wlc_hw, DMA_RX, 0),
1267                                            (wme ? NTXD : 0), NRXD,
1268                                            RXBUFSZ, -1, NRXBUFPOST,
1269                                            BRCMS_HWRXOFF, &brcm_msg_level);
1270                 dma_attach_err |= (NULL == wlc_hw->di[0]);
1271
1272                 /*
1273                  * FIFO 1
1274                  * TX: TX_AC_BE_FIFO (TX AC Best-Effort data packets)
1275                  *   (legacy) TX_DATA_FIFO (TX data packets)
1276                  * RX: UNUSED
1277                  */
1278                 wlc_hw->di[1] = dma_attach(name, wlc_hw->sih,
1279                                            dmareg(wlc_hw, DMA_TX, 1), NULL,
1280                                            NTXD, 0, 0, -1, 0, 0,
1281                                            &brcm_msg_level);
1282                 dma_attach_err |= (NULL == wlc_hw->di[1]);
1283
1284                 /*
1285                  * FIFO 2
1286                  * TX: TX_AC_VI_FIFO (TX AC Video data packets)
1287                  * RX: UNUSED
1288                  */
1289                 wlc_hw->di[2] = dma_attach(name, wlc_hw->sih,
1290                                            dmareg(wlc_hw, DMA_TX, 2), NULL,
1291                                            NTXD, 0, 0, -1, 0, 0,
1292                                            &brcm_msg_level);
1293                 dma_attach_err |= (NULL == wlc_hw->di[2]);
1294                 /*
1295                  * FIFO 3
1296                  * TX: TX_AC_VO_FIFO (TX AC Voice data packets)
1297                  *   (legacy) TX_CTL_FIFO (TX control & mgmt packets)
1298                  */
1299                 wlc_hw->di[3] = dma_attach(name, wlc_hw->sih,
1300                                            dmareg(wlc_hw, DMA_TX, 3),
1301                                            NULL, NTXD, 0, 0, -1,
1302                                            0, 0, &brcm_msg_level);
1303                 dma_attach_err |= (NULL == wlc_hw->di[3]);
1304 /* Cleaner to leave this as if with AP defined */
1305
1306                 if (dma_attach_err) {
1307                         wiphy_err(wiphy, "wl%d: wlc_attach: dma_attach failed"
1308                                   "\n", unit);
1309                         return false;
1310                 }
1311
1312                 /* get pointer to dma engine tx flow control variable */
1313                 for (i = 0; i < NFIFO; i++)
1314                         if (wlc_hw->di[i])
1315                                 wlc_hw->txavail[i] =
1316                                     (uint *) dma_getvar(wlc_hw->di[i],
1317                                                         "&txavail");
1318         }
1319
1320         /* initial ucode host flags */
1321         brcms_c_mhfdef(wlc, wlc_hw->band->mhfs, pio_mhf2);
1322
1323         return true;
1324 }
1325
1326 static void brcms_b_detach_dmapio(struct brcms_hardware *wlc_hw)
1327 {
1328         uint j;
1329
1330         for (j = 0; j < NFIFO; j++) {
1331                 if (wlc_hw->di[j]) {
1332                         dma_detach(wlc_hw->di[j]);
1333                         wlc_hw->di[j] = NULL;
1334                 }
1335         }
1336 }
1337
1338 /*
1339  * Initialize brcms_c_info default values ...
1340  * may get overrides later in this function
1341  *  BMAC_NOTES, move low out and resolve the dangling ones
1342  */
1343 static void brcms_b_info_init(struct brcms_hardware *wlc_hw)
1344 {
1345         struct brcms_c_info *wlc = wlc_hw->wlc;
1346
1347         /* set default sw macintmask value */
1348         wlc->defmacintmask = DEF_MACINTMASK;
1349
1350         /* various 802.11g modes */
1351         wlc_hw->shortslot = false;
1352
1353         wlc_hw->SFBL = RETRY_SHORT_FB;
1354         wlc_hw->LFBL = RETRY_LONG_FB;
1355
1356         /* default mac retry limits */
1357         wlc_hw->SRL = RETRY_SHORT_DEF;
1358         wlc_hw->LRL = RETRY_LONG_DEF;
1359         wlc_hw->chanspec = ch20mhz_chspec(1);
1360 }
1361
1362 static void brcms_b_wait_for_wake(struct brcms_hardware *wlc_hw)
1363 {
1364         /* delay before first read of ucode state */
1365         udelay(40);
1366
1367         /* wait until ucode is no longer asleep */
1368         SPINWAIT((brcms_b_read_shm(wlc_hw, M_UCODE_DBGST) ==
1369                   DBGST_ASLEEP), wlc_hw->wlc->fastpwrup_dly);
1370 }
1371
1372 static void brcms_b_hw_etheraddr(struct brcms_hardware *wlc_hw, u8 *ea)
1373 {
1374         memcpy(ea, wlc_hw->etheraddr, ETH_ALEN);
1375 }
1376
1377 static int brcms_b_bandtype(struct brcms_hardware *wlc_hw)
1378 {
1379         return wlc_hw->band->bandtype;
1380 }
1381
1382 /* control chip clock to save power, enable dynamic clock or force fast clock */
1383 static void brcms_b_clkctl_clk(struct brcms_hardware *wlc_hw, uint mode)
1384 {
1385         if (wlc_hw->sih->cccaps & CC_CAP_PMU) {
1386                 /* new chips with PMU, CCS_FORCEHT will distribute the HT clock
1387                  * on backplane, but mac core will still run on ALP(not HT) when
1388                  * it enters powersave mode, which means the FCA bit may not be
1389                  * set. Should wakeup mac if driver wants it to run on HT.
1390                  */
1391
1392                 if (wlc_hw->clk) {
1393                         if (mode == CLK_FAST) {
1394                                 OR_REG(&wlc_hw->regs->clk_ctl_st,
1395                                        CCS_FORCEHT);
1396
1397                                 udelay(64);
1398
1399                                 SPINWAIT(((R_REG
1400                                            (&wlc_hw->regs->
1401                                             clk_ctl_st) & CCS_HTAVAIL) == 0),
1402                                          PMU_MAX_TRANSITION_DLY);
1403                                 WARN_ON(!(R_REG
1404                                           (&wlc_hw->regs->
1405                                            clk_ctl_st) & CCS_HTAVAIL));
1406                         } else {
1407                                 if ((wlc_hw->sih->pmurev == 0) &&
1408                                     (R_REG
1409                                      (&wlc_hw->regs->
1410                                       clk_ctl_st) & (CCS_FORCEHT | CCS_HTAREQ)))
1411                                         SPINWAIT(((R_REG
1412                                                    (&wlc_hw->regs->
1413                                                     clk_ctl_st) & CCS_HTAVAIL)
1414                                                   == 0),
1415                                                  PMU_MAX_TRANSITION_DLY);
1416                                 AND_REG(&wlc_hw->regs->clk_ctl_st,
1417                                         ~CCS_FORCEHT);
1418                         }
1419                 }
1420                 wlc_hw->forcefastclk = (mode == CLK_FAST);
1421         } else {
1422
1423                 /* old chips w/o PMU, force HT through cc,
1424                  * then use FCA to verify mac is running fast clock
1425                  */
1426
1427                 wlc_hw->forcefastclk = ai_clkctl_cc(wlc_hw->sih, mode);
1428
1429                 /* check fast clock is available (if core is not in reset) */
1430                 if (wlc_hw->forcefastclk && wlc_hw->clk)
1431                         WARN_ON(!(ai_core_sflags(wlc_hw->sih, 0, 0) &
1432                                   SISF_FCLKA));
1433
1434                 /*
1435                  * keep the ucode wake bit on if forcefastclk is on since we
1436                  * do not want ucode to put us back to slow clock when it dozes
1437                  * for PM mode. Code below matches the wake override bit with
1438                  * current forcefastclk state. Only setting bit in wake_override
1439                  * instead of waking ucode immediately since old code had this
1440                  * behavior. Older code set wlc->forcefastclk but only had the
1441                  * wake happen if the wakup_ucode work (protected by an up
1442                  * check) was executed just below.
1443                  */
1444                 if (wlc_hw->forcefastclk)
1445                         mboolset(wlc_hw->wake_override,
1446                                  BRCMS_WAKE_OVERRIDE_FORCEFAST);
1447                 else
1448                         mboolclr(wlc_hw->wake_override,
1449                                  BRCMS_WAKE_OVERRIDE_FORCEFAST);
1450         }
1451 }
1452
1453 /* set or clear ucode host flag bits
1454  * it has an optimization for no-change write
1455  * it only writes through shared memory when the core has clock;
1456  * pre-CLK changes should use wlc_write_mhf to get around the optimization
1457  *
1458  *
1459  * bands values are: BRCM_BAND_AUTO <--- Current band only
1460  *                   BRCM_BAND_5G   <--- 5G band only
1461  *                   BRCM_BAND_2G   <--- 2G band only
1462  *                   BRCM_BAND_ALL  <--- All bands
1463  */
1464 void
1465 brcms_b_mhf(struct brcms_hardware *wlc_hw, u8 idx, u16 mask, u16 val,
1466              int bands)
1467 {
1468         u16 save;
1469         u16 addr[MHFMAX] = {
1470                 M_HOST_FLAGS1, M_HOST_FLAGS2, M_HOST_FLAGS3, M_HOST_FLAGS4,
1471                 M_HOST_FLAGS5
1472         };
1473         struct brcms_hw_band *band;
1474
1475         if ((val & ~mask) || idx >= MHFMAX)
1476                 return; /* error condition */
1477
1478         switch (bands) {
1479                 /* Current band only or all bands,
1480                  * then set the band to current band
1481                  */
1482         case BRCM_BAND_AUTO:
1483         case BRCM_BAND_ALL:
1484                 band = wlc_hw->band;
1485                 break;
1486         case BRCM_BAND_5G:
1487                 band = wlc_hw->bandstate[BAND_5G_INDEX];
1488                 break;
1489         case BRCM_BAND_2G:
1490                 band = wlc_hw->bandstate[BAND_2G_INDEX];
1491                 break;
1492         default:
1493                 band = NULL;    /* error condition */
1494         }
1495
1496         if (band) {
1497                 save = band->mhfs[idx];
1498                 band->mhfs[idx] = (band->mhfs[idx] & ~mask) | val;
1499
1500                 /* optimization: only write through if changed, and
1501                  * changed band is the current band
1502                  */
1503                 if (wlc_hw->clk && (band->mhfs[idx] != save)
1504                     && (band == wlc_hw->band))
1505                         brcms_b_write_shm(wlc_hw, addr[idx],
1506                                            (u16) band->mhfs[idx]);
1507         }
1508
1509         if (bands == BRCM_BAND_ALL) {
1510                 wlc_hw->bandstate[0]->mhfs[idx] =
1511                     (wlc_hw->bandstate[0]->mhfs[idx] & ~mask) | val;
1512                 wlc_hw->bandstate[1]->mhfs[idx] =
1513                     (wlc_hw->bandstate[1]->mhfs[idx] & ~mask) | val;
1514         }
1515 }
1516
1517 /* set the maccontrol register to desired reset state and
1518  * initialize the sw cache of the register
1519  */
1520 static void brcms_c_mctrl_reset(struct brcms_hardware *wlc_hw)
1521 {
1522         /* IHR accesses are always enabled, PSM disabled, HPS off and WAKE on */
1523         wlc_hw->maccontrol = 0;
1524         wlc_hw->suspended_fifos = 0;
1525         wlc_hw->wake_override = 0;
1526         wlc_hw->mute_override = 0;
1527         brcms_b_mctrl(wlc_hw, ~0, MCTL_IHR_EN | MCTL_WAKE);
1528 }
1529
1530 /*
1531  * write the software state of maccontrol and
1532  * overrides to the maccontrol register
1533  */
1534 static void brcms_c_mctrl_write(struct brcms_hardware *wlc_hw)
1535 {
1536         u32 maccontrol = wlc_hw->maccontrol;
1537
1538         /* OR in the wake bit if overridden */
1539         if (wlc_hw->wake_override)
1540                 maccontrol |= MCTL_WAKE;
1541
1542         /* set AP and INFRA bits for mute if needed */
1543         if (wlc_hw->mute_override) {
1544                 maccontrol &= ~(MCTL_AP);
1545                 maccontrol |= MCTL_INFRA;
1546         }
1547
1548         W_REG(&wlc_hw->regs->maccontrol, maccontrol);
1549 }
1550
1551 /* set or clear maccontrol bits */
1552 void brcms_b_mctrl(struct brcms_hardware *wlc_hw, u32 mask, u32 val)
1553 {
1554         u32 maccontrol;
1555         u32 new_maccontrol;
1556
1557         if (val & ~mask)
1558                 return; /* error condition */
1559         maccontrol = wlc_hw->maccontrol;
1560         new_maccontrol = (maccontrol & ~mask) | val;
1561
1562         /* if the new maccontrol value is the same as the old, nothing to do */
1563         if (new_maccontrol == maccontrol)
1564                 return;
1565
1566         /* something changed, cache the new value */
1567         wlc_hw->maccontrol = new_maccontrol;
1568
1569         /* write the new values with overrides applied */
1570         brcms_c_mctrl_write(wlc_hw);
1571 }
1572
1573 void brcms_c_ucode_wake_override_set(struct brcms_hardware *wlc_hw,
1574                                  u32 override_bit)
1575 {
1576         if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE)) {
1577                 mboolset(wlc_hw->wake_override, override_bit);
1578                 return;
1579         }
1580
1581         mboolset(wlc_hw->wake_override, override_bit);
1582
1583         brcms_c_mctrl_write(wlc_hw);
1584         brcms_b_wait_for_wake(wlc_hw);
1585
1586         return;
1587 }
1588
1589 void brcms_c_ucode_wake_override_clear(struct brcms_hardware *wlc_hw,
1590                                    u32 override_bit)
1591 {
1592         mboolclr(wlc_hw->wake_override, override_bit);
1593
1594         if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE))
1595                 return;
1596
1597         brcms_c_mctrl_write(wlc_hw);
1598
1599         return;
1600 }
1601
1602 /* When driver needs ucode to stop beaconing, it has to make sure that
1603  * MCTL_AP is clear and MCTL_INFRA is set
1604  * Mode           MCTL_AP        MCTL_INFRA
1605  * AP                1              1
1606  * STA               0              1 <--- This will ensure no beacons
1607  * IBSS              0              0
1608  */
1609 static void brcms_c_ucode_mute_override_set(struct brcms_hardware *wlc_hw)
1610 {
1611         wlc_hw->mute_override = 1;
1612
1613         /* if maccontrol already has AP == 0 and INFRA == 1 without this
1614          * override, then there is no change to write
1615          */
1616         if ((wlc_hw->maccontrol & (MCTL_AP | MCTL_INFRA)) == MCTL_INFRA)
1617                 return;
1618
1619         brcms_c_mctrl_write(wlc_hw);
1620
1621         return;
1622 }
1623
1624 /* Clear the override on AP and INFRA bits */
1625 static void brcms_c_ucode_mute_override_clear(struct brcms_hardware *wlc_hw)
1626 {
1627         if (wlc_hw->mute_override == 0)
1628                 return;
1629
1630         wlc_hw->mute_override = 0;
1631
1632         /* if maccontrol already has AP == 0 and INFRA == 1 without this
1633          * override, then there is no change to write
1634          */
1635         if ((wlc_hw->maccontrol & (MCTL_AP | MCTL_INFRA)) == MCTL_INFRA)
1636                 return;
1637
1638         brcms_c_mctrl_write(wlc_hw);
1639 }
1640
1641 /*
1642  * Write a MAC address to the given match reg offset in the RXE match engine.
1643  */
1644 static void
1645 brcms_b_set_addrmatch(struct brcms_hardware *wlc_hw, int match_reg_offset,
1646                        const u8 *addr)
1647 {
1648         struct d11regs *regs;
1649         u16 mac_l;
1650         u16 mac_m;
1651         u16 mac_h;
1652
1653         BCMMSG(wlc_hw->wlc->wiphy, "wl%d: brcms_b_set_addrmatch\n",
1654                  wlc_hw->unit);
1655
1656         regs = wlc_hw->regs;
1657         mac_l = addr[0] | (addr[1] << 8);
1658         mac_m = addr[2] | (addr[3] << 8);
1659         mac_h = addr[4] | (addr[5] << 8);
1660
1661         /* enter the MAC addr into the RXE match registers */
1662         W_REG(&regs->rcm_ctl, RCM_INC_DATA | match_reg_offset);
1663         W_REG(&regs->rcm_mat_data, mac_l);
1664         W_REG(&regs->rcm_mat_data, mac_m);
1665         W_REG(&regs->rcm_mat_data, mac_h);
1666
1667 }
1668
1669 void
1670 brcms_b_write_template_ram(struct brcms_hardware *wlc_hw, int offset, int len,
1671                             void *buf)
1672 {
1673         struct d11regs *regs;
1674         u32 word;
1675         __le32 word_le;
1676         __be32 word_be;
1677         bool be_bit;
1678         BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
1679
1680         regs = wlc_hw->regs;
1681         W_REG(&regs->tplatewrptr, offset);
1682
1683         /* if MCTL_BIGEND bit set in mac control register,
1684          * the chip swaps data in fifo, as well as data in
1685          * template ram
1686          */
1687         be_bit = (R_REG(&regs->maccontrol) & MCTL_BIGEND) != 0;
1688
1689         while (len > 0) {
1690                 memcpy(&word, buf, sizeof(u32));
1691
1692                 if (be_bit) {
1693                         word_be = cpu_to_be32(word);
1694                         word = *(u32 *)&word_be;
1695                 } else {
1696                         word_le = cpu_to_le32(word);
1697                         word = *(u32 *)&word_le;
1698                 }
1699
1700                 W_REG(&regs->tplatewrdata, word);
1701
1702                 buf = (u8 *) buf + sizeof(u32);
1703                 len -= sizeof(u32);
1704         }
1705 }
1706
1707 static void brcms_b_set_cwmin(struct brcms_hardware *wlc_hw, u16 newmin)
1708 {
1709         wlc_hw->band->CWmin = newmin;
1710
1711         W_REG(&wlc_hw->regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_CWMIN);
1712         (void)R_REG(&wlc_hw->regs->objaddr);
1713         W_REG(&wlc_hw->regs->objdata, newmin);
1714 }
1715
1716 static void brcms_b_set_cwmax(struct brcms_hardware *wlc_hw, u16 newmax)
1717 {
1718         wlc_hw->band->CWmax = newmax;
1719
1720         W_REG(&wlc_hw->regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_CWMAX);
1721         (void)R_REG(&wlc_hw->regs->objaddr);
1722         W_REG(&wlc_hw->regs->objdata, newmax);
1723 }
1724
1725 void brcms_b_bw_set(struct brcms_hardware *wlc_hw, u16 bw)
1726 {
1727         bool fastclk;
1728
1729         /* request FAST clock if not on */
1730         fastclk = wlc_hw->forcefastclk;
1731         if (!fastclk)
1732                 brcms_b_clkctl_clk(wlc_hw, CLK_FAST);
1733
1734         wlc_phy_bw_state_set(wlc_hw->band->pi, bw);
1735
1736         brcms_b_phy_reset(wlc_hw);
1737         wlc_phy_init(wlc_hw->band->pi, wlc_phy_chanspec_get(wlc_hw->band->pi));
1738
1739         /* restore the clk */
1740         if (!fastclk)
1741                 brcms_b_clkctl_clk(wlc_hw, CLK_DYNAMIC);
1742 }
1743
1744 static void
1745 brcms_c_write_hw_bcntemplate0(struct brcms_hardware *wlc_hw, u16 bcn[],
1746                               int len)
1747 {
1748         struct d11regs *regs = wlc_hw->regs;
1749
1750         brcms_b_write_template_ram(wlc_hw, T_BCN0_TPL_BASE, (len + 3) & ~3,
1751                                     bcn);
1752         /* write beacon length to SCR */
1753         brcms_b_write_shm(wlc_hw, M_BCN0_FRM_BYTESZ, (u16) len);
1754         /* mark beacon0 valid */
1755         OR_REG(&regs->maccommand, MCMD_BCN0VLD);
1756 }
1757
1758 static void
1759 brcms_c_write_hw_bcntemplate1(struct brcms_hardware *wlc_hw, u16 bcn[],
1760                               int len)
1761 {
1762         struct d11regs *regs = wlc_hw->regs;
1763
1764         brcms_b_write_template_ram(wlc_hw, T_BCN1_TPL_BASE, (len + 3) & ~3,
1765                                     bcn);
1766         /* write beacon length to SCR */
1767         brcms_b_write_shm(wlc_hw, M_BCN1_FRM_BYTESZ, (u16) len);
1768         /* mark beacon1 valid */
1769         OR_REG(&regs->maccommand, MCMD_BCN1VLD);
1770 }
1771
1772 static void brcms_b_upd_synthpu(struct brcms_hardware *wlc_hw)
1773 {
1774         u16 v;
1775         struct brcms_c_info *wlc = wlc_hw->wlc;
1776         /* update SYNTHPU_DLY */
1777
1778         if (BRCMS_ISLCNPHY(wlc->band))
1779                 v = SYNTHPU_DLY_LPPHY_US;
1780         else if (BRCMS_ISNPHY(wlc->band) && (NREV_GE(wlc->band->phyrev, 3)))
1781                 v = SYNTHPU_DLY_NPHY_US;
1782         else
1783                 v = SYNTHPU_DLY_BPHY_US;
1784
1785         brcms_b_write_shm(wlc_hw, M_SYNTHPU_DLY, v);
1786 }
1787
1788 static void brcms_c_ucode_txant_set(struct brcms_hardware *wlc_hw)
1789 {
1790         u16 phyctl;
1791         u16 phytxant = wlc_hw->bmac_phytxant;
1792         u16 mask = PHY_TXC_ANT_MASK;
1793
1794         /* set the Probe Response frame phy control word */
1795         phyctl = brcms_b_read_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS);
1796         phyctl = (phyctl & ~mask) | phytxant;
1797         brcms_b_write_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS, phyctl);
1798
1799         /* set the Response (ACK/CTS) frame phy control word */
1800         phyctl = brcms_b_read_shm(wlc_hw, M_RSP_PCTLWD);
1801         phyctl = (phyctl & ~mask) | phytxant;
1802         brcms_b_write_shm(wlc_hw, M_RSP_PCTLWD, phyctl);
1803 }
1804
1805 static u16 brcms_b_ofdm_ratetable_offset(struct brcms_hardware *wlc_hw,
1806                                          u8 rate)
1807 {
1808         uint i;
1809         u8 plcp_rate = 0;
1810         struct plcp_signal_rate_lookup {
1811                 u8 rate;
1812                 u8 signal_rate;
1813         };
1814         /* OFDM RATE sub-field of PLCP SIGNAL field, per 802.11 sec 17.3.4.1 */
1815         const struct plcp_signal_rate_lookup rate_lookup[] = {
1816                 {BRCM_RATE_6M, 0xB},
1817                 {BRCM_RATE_9M, 0xF},
1818                 {BRCM_RATE_12M, 0xA},
1819                 {BRCM_RATE_18M, 0xE},
1820                 {BRCM_RATE_24M, 0x9},
1821                 {BRCM_RATE_36M, 0xD},
1822                 {BRCM_RATE_48M, 0x8},
1823                 {BRCM_RATE_54M, 0xC}
1824         };
1825
1826         for (i = 0; i < ARRAY_SIZE(rate_lookup); i++) {
1827                 if (rate == rate_lookup[i].rate) {
1828                         plcp_rate = rate_lookup[i].signal_rate;
1829                         break;
1830                 }
1831         }
1832
1833         /* Find the SHM pointer to the rate table entry by looking in the
1834          * Direct-map Table
1835          */
1836         return 2 * brcms_b_read_shm(wlc_hw, M_RT_DIRMAP_A + (plcp_rate * 2));
1837 }
1838
1839 static void brcms_upd_ofdm_pctl1_table(struct brcms_hardware *wlc_hw)
1840 {
1841         u8 rate;
1842         u8 rates[8] = {
1843                 BRCM_RATE_6M, BRCM_RATE_9M, BRCM_RATE_12M, BRCM_RATE_18M,
1844                 BRCM_RATE_24M, BRCM_RATE_36M, BRCM_RATE_48M, BRCM_RATE_54M
1845         };
1846         u16 entry_ptr;
1847         u16 pctl1;
1848         uint i;
1849
1850         if (!BRCMS_PHY_11N_CAP(wlc_hw->band))
1851                 return;
1852
1853         /* walk the phy rate table and update the entries */
1854         for (i = 0; i < ARRAY_SIZE(rates); i++) {
1855                 rate = rates[i];
1856
1857                 entry_ptr = brcms_b_ofdm_ratetable_offset(wlc_hw, rate);
1858
1859                 /* read the SHM Rate Table entry OFDM PCTL1 values */
1860                 pctl1 =
1861                     brcms_b_read_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS);
1862
1863                 /* modify the value */
1864                 pctl1 &= ~PHY_TXC1_MODE_MASK;
1865                 pctl1 |= (wlc_hw->hw_stf_ss_opmode << PHY_TXC1_MODE_SHIFT);
1866
1867                 /* Update the SHM Rate Table entry OFDM PCTL1 values */
1868                 brcms_b_write_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS,
1869                                    pctl1);
1870         }
1871 }
1872
1873 /* band-specific init */
1874 static void brcms_b_bsinit(struct brcms_c_info *wlc, u16 chanspec)
1875 {
1876         struct brcms_hardware *wlc_hw = wlc->hw;
1877
1878         BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
1879                 wlc_hw->band->bandunit);
1880
1881         brcms_c_ucode_bsinit(wlc_hw);
1882
1883         wlc_phy_init(wlc_hw->band->pi, chanspec);
1884
1885         brcms_c_ucode_txant_set(wlc_hw);
1886
1887         /*
1888          * cwmin is band-specific, update hardware
1889          * with value for current band
1890          */
1891         brcms_b_set_cwmin(wlc_hw, wlc_hw->band->CWmin);
1892         brcms_b_set_cwmax(wlc_hw, wlc_hw->band->CWmax);
1893
1894         brcms_b_update_slot_timing(wlc_hw,
1895                                    wlc_hw->band->bandtype == BRCM_BAND_5G ?
1896                                    true : wlc_hw->shortslot);
1897
1898         /* write phytype and phyvers */
1899         brcms_b_write_shm(wlc_hw, M_PHYTYPE, (u16) wlc_hw->band->phytype);
1900         brcms_b_write_shm(wlc_hw, M_PHYVER, (u16) wlc_hw->band->phyrev);
1901
1902         /*
1903          * initialize the txphyctl1 rate table since
1904          * shmem is shared between bands
1905          */
1906         brcms_upd_ofdm_pctl1_table(wlc_hw);
1907
1908         brcms_b_upd_synthpu(wlc_hw);
1909 }
1910
1911 /* Perform a soft reset of the PHY PLL */
1912 void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw)
1913 {
1914         BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
1915
1916         ai_corereg(wlc_hw->sih, SI_CC_IDX,
1917                    offsetof(struct chipcregs, chipcontrol_addr), ~0, 0);
1918         udelay(1);
1919         ai_corereg(wlc_hw->sih, SI_CC_IDX,
1920                    offsetof(struct chipcregs, chipcontrol_data), 0x4, 0);
1921         udelay(1);
1922         ai_corereg(wlc_hw->sih, SI_CC_IDX,
1923                    offsetof(struct chipcregs, chipcontrol_data), 0x4, 4);
1924         udelay(1);
1925         ai_corereg(wlc_hw->sih, SI_CC_IDX,
1926                    offsetof(struct chipcregs, chipcontrol_data), 0x4, 0);
1927         udelay(1);
1928 }
1929
1930 /* light way to turn on phy clock without reset for NPHY only
1931  *  refer to brcms_b_core_phy_clk for full version
1932  */
1933 void brcms_b_phyclk_fgc(struct brcms_hardware *wlc_hw, bool clk)
1934 {
1935         /* support(necessary for NPHY and HYPHY) only */
1936         if (!BRCMS_ISNPHY(wlc_hw->band))
1937                 return;
1938
1939         if (ON == clk)
1940                 ai_core_cflags(wlc_hw->sih, SICF_FGC, SICF_FGC);
1941         else
1942                 ai_core_cflags(wlc_hw->sih, SICF_FGC, 0);
1943
1944 }
1945
1946 void brcms_b_macphyclk_set(struct brcms_hardware *wlc_hw, bool clk)
1947 {
1948         if (ON == clk)
1949                 ai_core_cflags(wlc_hw->sih, SICF_MPCLKE, SICF_MPCLKE);
1950         else
1951                 ai_core_cflags(wlc_hw->sih, SICF_MPCLKE, 0);
1952 }
1953
1954 void brcms_b_phy_reset(struct brcms_hardware *wlc_hw)
1955 {
1956         struct brcms_phy_pub *pih = wlc_hw->band->pi;
1957         u32 phy_bw_clkbits;
1958         bool phy_in_reset = false;
1959
1960         BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
1961
1962         if (pih == NULL)
1963                 return;
1964
1965         phy_bw_clkbits = wlc_phy_clk_bwbits(wlc_hw->band->pi);
1966
1967         /* Specific reset sequence required for NPHY rev 3 and 4 */
1968         if (BRCMS_ISNPHY(wlc_hw->band) && NREV_GE(wlc_hw->band->phyrev, 3) &&
1969             NREV_LE(wlc_hw->band->phyrev, 4)) {
1970                 /* Set the PHY bandwidth */
1971                 ai_core_cflags(wlc_hw->sih, SICF_BWMASK, phy_bw_clkbits);
1972
1973                 udelay(1);
1974
1975                 /* Perform a soft reset of the PHY PLL */
1976                 brcms_b_core_phypll_reset(wlc_hw);
1977
1978                 /* reset the PHY */
1979                 ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_PCLKE),
1980                                (SICF_PRST | SICF_PCLKE));
1981                 phy_in_reset = true;
1982         } else {
1983                 ai_core_cflags(wlc_hw->sih,
1984                                (SICF_PRST | SICF_PCLKE | SICF_BWMASK),
1985                                (SICF_PRST | SICF_PCLKE | phy_bw_clkbits));
1986         }
1987
1988         udelay(2);
1989         brcms_b_core_phy_clk(wlc_hw, ON);
1990
1991         if (pih)
1992                 wlc_phy_anacore(pih, ON);
1993 }
1994
1995 /* switch to and initialize new band */
1996 static void brcms_b_setband(struct brcms_hardware *wlc_hw, uint bandunit,
1997                             u16 chanspec) {
1998         struct brcms_c_info *wlc = wlc_hw->wlc;
1999         u32 macintmask;
2000
2001         /* Enable the d11 core before accessing it */
2002         if (!ai_iscoreup(wlc_hw->sih)) {
2003                 ai_core_reset(wlc_hw->sih, 0, 0);
2004                 brcms_c_mctrl_reset(wlc_hw);
2005         }
2006
2007         macintmask = brcms_c_setband_inact(wlc, bandunit);
2008
2009         if (!wlc_hw->up)
2010                 return;
2011
2012         brcms_b_core_phy_clk(wlc_hw, ON);
2013
2014         /* band-specific initializations */
2015         brcms_b_bsinit(wlc, chanspec);
2016
2017         /*
2018          * If there are any pending software interrupt bits,
2019          * then replace these with a harmless nonzero value
2020          * so brcms_c_dpc() will re-enable interrupts when done.
2021          */
2022         if (wlc->macintstatus)
2023                 wlc->macintstatus = MI_DMAINT;
2024
2025         /* restore macintmask */
2026         brcms_intrsrestore(wlc->wl, macintmask);
2027
2028         /* ucode should still be suspended.. */
2029         WARN_ON((R_REG(&wlc_hw->regs->maccontrol) & MCTL_EN_MAC) != 0);
2030 }
2031
2032 /* low-level band switch utility routine */
2033 void brcms_c_setxband(struct brcms_hardware *wlc_hw, uint bandunit)
2034 {
2035         BCMMSG(wlc_hw->wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
2036                 bandunit);
2037
2038         wlc_hw->band = wlc_hw->bandstate[bandunit];
2039
2040         /*
2041          * BMAC_NOTE:
2042          *   until we eliminate need for wlc->band refs in low level code
2043          */
2044         wlc_hw->wlc->band = wlc_hw->wlc->bandstate[bandunit];
2045
2046         /* set gmode core flag */
2047         if (wlc_hw->sbclk && !wlc_hw->noreset)
2048                 ai_core_cflags(wlc_hw->sih, SICF_GMODE,
2049                                ((bandunit == 0) ? SICF_GMODE : 0));
2050 }
2051
2052 static bool brcms_c_isgoodchip(struct brcms_hardware *wlc_hw)
2053 {
2054
2055         /* reject unsupported corerev */
2056         if (!CONF_HAS(D11CONF, wlc_hw->corerev)) {
2057                 wiphy_err(wlc_hw->wlc->wiphy, "unsupported core rev %d\n",
2058                           wlc_hw->corerev);
2059                 return false;
2060         }
2061
2062         return true;
2063 }
2064
2065 /* Validate some board info parameters */
2066 static bool brcms_c_validboardtype(struct brcms_hardware *wlc_hw)
2067 {
2068         uint boardrev = wlc_hw->boardrev;
2069
2070         /* 4 bits each for board type, major, minor, and tiny version */
2071         uint brt = (boardrev & 0xf000) >> 12;
2072         uint b0 = (boardrev & 0xf00) >> 8;
2073         uint b1 = (boardrev & 0xf0) >> 4;
2074         uint b2 = boardrev & 0xf;
2075
2076         /* voards from other vendors are always considered valid */
2077         if (wlc_hw->sih->boardvendor != PCI_VENDOR_ID_BROADCOM)
2078                 return true;
2079
2080         /* do some boardrev sanity checks when boardvendor is Broadcom */
2081         if (boardrev == 0)
2082                 return false;
2083
2084         if (boardrev <= 0xff)
2085                 return true;
2086
2087         if ((brt > 2) || (brt == 0) || (b0 > 9) || (b0 == 0) || (b1 > 9)
2088                 || (b2 > 9))
2089                 return false;
2090
2091         return true;
2092 }
2093
2094 static char *brcms_c_get_macaddr(struct brcms_hardware *wlc_hw)
2095 {
2096         const char *varname = "macaddr";
2097         char *macaddr;
2098
2099         /* If macaddr exists, use it (Sromrev4, CIS, ...). */
2100         macaddr = getvar(wlc_hw->vars, varname);
2101         if (macaddr != NULL)
2102                 return macaddr;
2103
2104         if (wlc_hw->_nbands > 1)
2105                 varname = "et1macaddr";
2106         else
2107                 varname = "il0macaddr";
2108
2109         macaddr = getvar(wlc_hw->vars, varname);
2110         if (macaddr == NULL)
2111                 wiphy_err(wlc_hw->wlc->wiphy, "wl%d: wlc_get_macaddr: macaddr "
2112                           "getvar(%s) not found\n", wlc_hw->unit, varname);
2113
2114         return macaddr;
2115 }
2116
2117 /* power both the pll and external oscillator on/off */
2118 static void brcms_b_xtal(struct brcms_hardware *wlc_hw, bool want)
2119 {
2120         BCMMSG(wlc_hw->wlc->wiphy, "wl%d: want %d\n", wlc_hw->unit, want);
2121
2122         /*
2123          * dont power down if plldown is false or
2124          * we must poll hw radio disable
2125          */
2126         if (!want && wlc_hw->pllreq)
2127                 return;
2128
2129         if (wlc_hw->sih)
2130                 ai_clkctl_xtal(wlc_hw->sih, XTAL | PLL, want);
2131
2132         wlc_hw->sbclk = want;
2133         if (!wlc_hw->sbclk) {
2134                 wlc_hw->clk = false;
2135                 if (wlc_hw->band && wlc_hw->band->pi)
2136                         wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false);
2137         }
2138 }
2139
2140 /*
2141  * Return true if radio is disabled, otherwise false.
2142  * hw radio disable signal is an external pin, users activate it asynchronously
2143  * this function could be called when driver is down and w/o clock
2144  * it operates on different registers depending on corerev and boardflag.
2145  */
2146 static bool brcms_b_radio_read_hwdisabled(struct brcms_hardware *wlc_hw)
2147 {
2148         bool v, clk, xtal;
2149         u32 resetbits = 0, flags = 0;
2150
2151         xtal = wlc_hw->sbclk;
2152         if (!xtal)
2153                 brcms_b_xtal(wlc_hw, ON);
2154
2155         /* may need to take core out of reset first */
2156         clk = wlc_hw->clk;
2157         if (!clk) {
2158                 /*
2159                  * mac no longer enables phyclk automatically when driver
2160                  * accesses phyreg throughput mac. This can be skipped since
2161                  * only mac reg is accessed below
2162                  */
2163                 flags |= SICF_PCLKE;
2164
2165                 /*
2166                  * AI chip doesn't restore bar0win2 on
2167                  * hibernation/resume, need sw fixup
2168                  */
2169                 if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) ||
2170                     (wlc_hw->sih->chip == BCM43225_CHIP_ID))
2171                         wlc_hw->regs = (struct d11regs *)
2172                                         ai_setcore(wlc_hw->sih, D11_CORE_ID, 0);
2173                 ai_core_reset(wlc_hw->sih, flags, resetbits);
2174                 brcms_c_mctrl_reset(wlc_hw);
2175         }
2176
2177         v = ((R_REG(&wlc_hw->regs->phydebug) & PDBG_RFD) != 0);
2178
2179         /* put core back into reset */
2180         if (!clk)
2181                 ai_core_disable(wlc_hw->sih, 0);
2182
2183         if (!xtal)
2184                 brcms_b_xtal(wlc_hw, OFF);
2185
2186         return v;
2187 }
2188
2189 static bool wlc_dma_rxreset(struct brcms_hardware *wlc_hw, uint fifo)
2190 {
2191         struct dma_pub *di = wlc_hw->di[fifo];
2192         return dma_rxreset(di);
2193 }
2194
2195 /* d11 core reset
2196  *   ensure fask clock during reset
2197  *   reset dma
2198  *   reset d11(out of reset)
2199  *   reset phy(out of reset)
2200  *   clear software macintstatus for fresh new start
2201  * one testing hack wlc_hw->noreset will bypass the d11/phy reset
2202  */
2203 void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags)
2204 {
2205         struct d11regs *regs;
2206         uint i;
2207         bool fastclk;
2208         u32 resetbits = 0;
2209
2210         if (flags == BRCMS_USE_COREFLAGS)
2211                 flags = (wlc_hw->band->pi ? wlc_hw->band->core_flags : 0);
2212
2213         BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
2214
2215         regs = wlc_hw->regs;
2216
2217         /* request FAST clock if not on  */
2218         fastclk = wlc_hw->forcefastclk;
2219         if (!fastclk)
2220                 brcms_b_clkctl_clk(wlc_hw, CLK_FAST);
2221
2222         /* reset the dma engines except first time thru */
2223         if (ai_iscoreup(wlc_hw->sih)) {
2224                 for (i = 0; i < NFIFO; i++)
2225                         if ((wlc_hw->di[i]) && (!dma_txreset(wlc_hw->di[i])))
2226                                 wiphy_err(wlc_hw->wlc->wiphy, "wl%d: %s: "
2227                                           "dma_txreset[%d]: cannot stop dma\n",
2228                                            wlc_hw->unit, __func__, i);
2229
2230                 if ((wlc_hw->di[RX_FIFO])
2231                     && (!wlc_dma_rxreset(wlc_hw, RX_FIFO)))
2232                         wiphy_err(wlc_hw->wlc->wiphy, "wl%d: %s: dma_rxreset"
2233                                   "[%d]: cannot stop dma\n",
2234                                   wlc_hw->unit, __func__, RX_FIFO);
2235         }
2236         /* if noreset, just stop the psm and return */
2237         if (wlc_hw->noreset) {
2238                 wlc_hw->wlc->macintstatus = 0;  /* skip wl_dpc after down */
2239                 brcms_b_mctrl(wlc_hw, MCTL_PSM_RUN | MCTL_EN_MAC, 0);
2240                 return;
2241         }
2242
2243         /*
2244          * mac no longer enables phyclk automatically when driver accesses
2245          * phyreg throughput mac, AND phy_reset is skipped at early stage when
2246          * band->pi is invalid. need to enable PHY CLK
2247          */
2248         flags |= SICF_PCLKE;
2249
2250         /*
2251          * reset the core
2252          * In chips with PMU, the fastclk request goes through d11 core
2253          * reg 0x1e0, which is cleared by the core_reset. have to re-request it.
2254          *
2255          * This adds some delay and we can optimize it by also requesting
2256          * fastclk through chipcommon during this period if necessary. But
2257          * that has to work coordinate with other driver like mips/arm since
2258          * they may touch chipcommon as well.
2259          */
2260         wlc_hw->clk = false;
2261         ai_core_reset(wlc_hw->sih, flags, resetbits);
2262         wlc_hw->clk = true;
2263         if (wlc_hw->band && wlc_hw->band->pi)
2264                 wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, true);
2265
2266         brcms_c_mctrl_reset(wlc_hw);
2267
2268         if (wlc_hw->sih->cccaps & CC_CAP_PMU)
2269                 brcms_b_clkctl_clk(wlc_hw, CLK_FAST);
2270
2271         brcms_b_phy_reset(wlc_hw);
2272
2273         /* turn on PHY_PLL */
2274         brcms_b_core_phypll_ctl(wlc_hw, true);
2275
2276         /* clear sw intstatus */
2277         wlc_hw->wlc->macintstatus = 0;
2278
2279         /* restore the clk setting */
2280         if (!fastclk)
2281                 brcms_b_clkctl_clk(wlc_hw, CLK_DYNAMIC);
2282 }
2283
2284 /* txfifo sizes needs to be modified(increased) since the newer cores
2285  * have more memory.
2286  */
2287 static void brcms_b_corerev_fifofixup(struct brcms_hardware *wlc_hw)
2288 {
2289         struct d11regs *regs = wlc_hw->regs;
2290         u16 fifo_nu;
2291         u16 txfifo_startblk = TXFIFO_START_BLK, txfifo_endblk;
2292         u16 txfifo_def, txfifo_def1;
2293         u16 txfifo_cmd;
2294
2295         /* tx fifos start at TXFIFO_START_BLK from the Base address */
2296         txfifo_startblk = TXFIFO_START_BLK;
2297
2298         /* sequence of operations:  reset fifo, set fifo size, reset fifo */
2299         for (fifo_nu = 0; fifo_nu < NFIFO; fifo_nu++) {
2300
2301                 txfifo_endblk = txfifo_startblk + wlc_hw->xmtfifo_sz[fifo_nu];
2302                 txfifo_def = (txfifo_startblk & 0xff) |
2303                     (((txfifo_endblk - 1) & 0xff) << TXFIFO_FIFOTOP_SHIFT);
2304                 txfifo_def1 = ((txfifo_startblk >> 8) & 0x1) |
2305                     ((((txfifo_endblk -
2306                         1) >> 8) & 0x1) << TXFIFO_FIFOTOP_SHIFT);
2307                 txfifo_cmd =
2308                     TXFIFOCMD_RESET_MASK | (fifo_nu << TXFIFOCMD_FIFOSEL_SHIFT);
2309
2310                 W_REG(&regs->xmtfifocmd, txfifo_cmd);
2311                 W_REG(&regs->xmtfifodef, txfifo_def);
2312                 W_REG(&regs->xmtfifodef1, txfifo_def1);
2313
2314                 W_REG(&regs->xmtfifocmd, txfifo_cmd);
2315
2316                 txfifo_startblk += wlc_hw->xmtfifo_sz[fifo_nu];
2317         }
2318         /*
2319          * need to propagate to shm location to be in sync since ucode/hw won't
2320          * do this
2321          */
2322         brcms_b_write_shm(wlc_hw, M_FIFOSIZE0,
2323                            wlc_hw->xmtfifo_sz[TX_AC_BE_FIFO]);
2324         brcms_b_write_shm(wlc_hw, M_FIFOSIZE1,
2325                            wlc_hw->xmtfifo_sz[TX_AC_VI_FIFO]);
2326         brcms_b_write_shm(wlc_hw, M_FIFOSIZE2,
2327                            ((wlc_hw->xmtfifo_sz[TX_AC_VO_FIFO] << 8) | wlc_hw->
2328                             xmtfifo_sz[TX_AC_BK_FIFO]));
2329         brcms_b_write_shm(wlc_hw, M_FIFOSIZE3,
2330                            ((wlc_hw->xmtfifo_sz[TX_ATIM_FIFO] << 8) | wlc_hw->
2331                             xmtfifo_sz[TX_BCMC_FIFO]));
2332 }
2333
2334 /* This function is used for changing the tsf frac register
2335  * If spur avoidance mode is off, the mac freq will be 80/120/160Mhz
2336  * If spur avoidance mode is on1, the mac freq will be 82/123/164Mhz
2337  * If spur avoidance mode is on2, the mac freq will be 84/126/168Mhz
2338  * HTPHY Formula is 2^26/freq(MHz) e.g.
2339  * For spuron2 - 126MHz -> 2^26/126 = 532610.0
2340  *  - 532610 = 0x82082 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x2082
2341  * For spuron: 123MHz -> 2^26/123    = 545600.5
2342  *  - 545601 = 0x85341 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x5341
2343  * For spur off: 120MHz -> 2^26/120    = 559240.5
2344  *  - 559241 = 0x88889 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x8889
2345  */
2346
2347 void brcms_b_switch_macfreq(struct brcms_hardware *wlc_hw, u8 spurmode)
2348 {
2349         struct d11regs *regs;
2350         regs = wlc_hw->regs;
2351
2352         if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) ||
2353             (wlc_hw->sih->chip == BCM43225_CHIP_ID)) {
2354                 if (spurmode == WL_SPURAVOID_ON2) {     /* 126Mhz */
2355                         W_REG(&regs->tsf_clk_frac_l, 0x2082);
2356                         W_REG(&regs->tsf_clk_frac_h, 0x8);
2357                 } else if (spurmode == WL_SPURAVOID_ON1) {      /* 123Mhz */
2358                         W_REG(&regs->tsf_clk_frac_l, 0x5341);
2359                         W_REG(&regs->tsf_clk_frac_h, 0x8);
2360                 } else {        /* 120Mhz */
2361                         W_REG(&regs->tsf_clk_frac_l, 0x8889);
2362                         W_REG(&regs->tsf_clk_frac_h, 0x8);
2363                 }
2364         } else if (BRCMS_ISLCNPHY(wlc_hw->band)) {
2365                 if (spurmode == WL_SPURAVOID_ON1) {     /* 82Mhz */
2366                         W_REG(&regs->tsf_clk_frac_l, 0x7CE0);
2367                         W_REG(&regs->tsf_clk_frac_h, 0xC);
2368                 } else {        /* 80Mhz */
2369                         W_REG(&regs->tsf_clk_frac_l, 0xCCCD);
2370                         W_REG(&regs->tsf_clk_frac_h, 0xC);
2371                 }
2372         }
2373 }
2374
2375 /* Initialize GPIOs that are controlled by D11 core */
2376 static void brcms_c_gpio_init(struct brcms_c_info *wlc)
2377 {
2378         struct brcms_hardware *wlc_hw = wlc->hw;
2379         struct d11regs *regs;
2380         u32 gc, gm;
2381
2382         regs = wlc_hw->regs;
2383
2384         /* use GPIO select 0 to get all gpio signals from the gpio out reg */
2385         brcms_b_mctrl(wlc_hw, MCTL_GPOUT_SEL_MASK, 0);
2386
2387         /*
2388          * Common GPIO setup:
2389          *      G0 = LED 0 = WLAN Activity
2390          *      G1 = LED 1 = WLAN 2.4 GHz Radio State
2391          *      G2 = LED 2 = WLAN 5 GHz Radio State
2392          *      G4 = radio disable input (HI enabled, LO disabled)
2393          */
2394
2395         gc = gm = 0;
2396
2397         /* Allocate GPIOs for mimo antenna diversity feature */
2398         if (wlc_hw->antsel_type == ANTSEL_2x3) {
2399                 /* Enable antenna diversity, use 2x3 mode */
2400                 brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN,
2401                              MHF3_ANTSEL_EN, BRCM_BAND_ALL);
2402                 brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE,
2403                              MHF3_ANTSEL_MODE, BRCM_BAND_ALL);
2404
2405                 /* init superswitch control */
2406                 wlc_phy_antsel_init(wlc_hw->band->pi, false);
2407
2408         } else if (wlc_hw->antsel_type == ANTSEL_2x4) {
2409                 gm |= gc |= (BOARD_GPIO_12 | BOARD_GPIO_13);
2410                 /*
2411                  * The board itself is powered by these GPIOs
2412                  * (when not sending pattern) so set them high
2413                  */
2414                 OR_REG(&regs->psm_gpio_oe,
2415                        (BOARD_GPIO_12 | BOARD_GPIO_13));
2416                 OR_REG(&regs->psm_gpio_out,
2417                        (BOARD_GPIO_12 | BOARD_GPIO_13));
2418
2419                 /* Enable antenna diversity, use 2x4 mode */
2420                 brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN,
2421                              MHF3_ANTSEL_EN, BRCM_BAND_ALL);
2422                 brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE, 0,
2423                              BRCM_BAND_ALL);
2424
2425                 /* Configure the desired clock to be 4Mhz */
2426                 brcms_b_write_shm(wlc_hw, M_ANTSEL_CLKDIV,
2427                                    ANTSEL_CLKDIV_4MHZ);
2428         }
2429
2430         /*
2431          * gpio 9 controls the PA. ucode is responsible
2432          * for wiggling out and oe
2433          */
2434         if (wlc_hw->boardflags & BFL_PACTRL)
2435                 gm |= gc |= BOARD_GPIO_PACTRL;
2436
2437         /* apply to gpiocontrol register */
2438         ai_gpiocontrol(wlc_hw->sih, gm, gc, GPIO_DRV_PRIORITY);
2439 }
2440
2441 static void brcms_ucode_write(struct brcms_hardware *wlc_hw,
2442                               const __le32 ucode[], const size_t nbytes)
2443 {
2444         struct d11regs *regs = wlc_hw->regs;
2445         uint i;
2446         uint count;
2447
2448         BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
2449
2450         count = (nbytes / sizeof(u32));
2451
2452         W_REG(&regs->objaddr, (OBJADDR_AUTO_INC | OBJADDR_UCM_SEL));
2453         (void)R_REG(&regs->objaddr);
2454         for (i = 0; i < count; i++)
2455                 W_REG(&regs->objdata, le32_to_cpu(ucode[i]));
2456
2457 }
2458
2459 static void brcms_ucode_download(struct brcms_hardware *wlc_hw)
2460 {
2461         struct brcms_c_info *wlc;
2462         struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode;
2463
2464         wlc = wlc_hw->wlc;
2465
2466         if (wlc_hw->ucode_loaded)
2467                 return;
2468
2469         if (D11REV_IS(wlc_hw->corerev, 23)) {
2470                 if (BRCMS_ISNPHY(wlc_hw->band)) {
2471                         brcms_ucode_write(wlc_hw, ucode->bcm43xx_16_mimo,
2472                                           ucode->bcm43xx_16_mimosz);
2473                         wlc_hw->ucode_loaded = true;
2474                 } else
2475                         wiphy_err(wlc->wiphy, "%s: wl%d: unsupported phy in "
2476                                   "corerev %d\n",
2477                                   __func__, wlc_hw->unit, wlc_hw->corerev);
2478         } else if (D11REV_IS(wlc_hw->corerev, 24)) {
2479                 if (BRCMS_ISLCNPHY(wlc_hw->band)) {
2480                         brcms_ucode_write(wlc_hw, ucode->bcm43xx_24_lcn,
2481                                           ucode->bcm43xx_24_lcnsz);
2482                         wlc_hw->ucode_loaded = true;
2483                 } else {
2484                         wiphy_err(wlc->wiphy, "%s: wl%d: unsupported phy in "
2485                                   "corerev %d\n",
2486                                   __func__, wlc_hw->unit, wlc_hw->corerev);
2487                 }
2488         }
2489 }
2490
2491 void brcms_b_txant_set(struct brcms_hardware *wlc_hw, u16 phytxant)
2492 {
2493         /* update sw state */
2494         wlc_hw->bmac_phytxant = phytxant;
2495
2496         /* push to ucode if up */
2497         if (!wlc_hw->up)
2498                 return;
2499         brcms_c_ucode_txant_set(wlc_hw);
2500
2501 }
2502
2503 u16 brcms_b_get_txant(struct brcms_hardware *wlc_hw)
2504 {
2505         return (u16) wlc_hw->wlc->stf->txant;
2506 }
2507
2508 void brcms_b_antsel_type_set(struct brcms_hardware *wlc_hw, u8 antsel_type)
2509 {
2510         wlc_hw->antsel_type = antsel_type;
2511
2512         /* Update the antsel type for phy module to use */
2513         wlc_phy_antsel_type_set(wlc_hw->band->pi, antsel_type);
2514 }
2515
2516 static void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw)
2517 {
2518         bool fatal = false;
2519         uint unit;
2520         uint intstatus, idx;
2521         struct d11regs *regs = wlc_hw->regs;
2522         struct wiphy *wiphy = wlc_hw->wlc->wiphy;
2523
2524         unit = wlc_hw->unit;
2525
2526         for (idx = 0; idx < NFIFO; idx++) {
2527                 /* read intstatus register and ignore any non-error bits */
2528                 intstatus =
2529                     R_REG(&regs->intctrlregs[idx].intstatus) & I_ERRORS;
2530                 if (!intstatus)
2531                         continue;
2532
2533                 BCMMSG(wlc_hw->wlc->wiphy, "wl%d: intstatus%d 0x%x\n",
2534                         unit, idx, intstatus);
2535
2536                 if (intstatus & I_RO) {
2537                         wiphy_err(wiphy, "wl%d: fifo %d: receive fifo "
2538                                   "overflow\n", unit, idx);
2539                         fatal = true;
2540                 }
2541
2542                 if (intstatus & I_PC) {
2543                         wiphy_err(wiphy, "wl%d: fifo %d: descriptor error\n",
2544                                  unit, idx);
2545                         fatal = true;
2546                 }
2547
2548                 if (intstatus & I_PD) {
2549                         wiphy_err(wiphy, "wl%d: fifo %d: data error\n", unit,
2550                                   idx);
2551                         fatal = true;
2552                 }
2553
2554                 if (intstatus & I_DE) {
2555                         wiphy_err(wiphy, "wl%d: fifo %d: descriptor protocol "
2556                                   "error\n", unit, idx);
2557                         fatal = true;
2558                 }
2559
2560                 if (intstatus & I_RU)
2561                         wiphy_err(wiphy, "wl%d: fifo %d: receive descriptor "
2562                                   "underflow\n", idx, unit);
2563
2564                 if (intstatus & I_XU) {
2565                         wiphy_err(wiphy, "wl%d: fifo %d: transmit fifo "
2566                                   "underflow\n", idx, unit);
2567                         fatal = true;
2568                 }
2569
2570                 if (fatal) {
2571                         brcms_c_fatal_error(wlc_hw->wlc);       /* big hammer */
2572                         break;
2573                 } else
2574                         W_REG(&regs->intctrlregs[idx].intstatus,
2575                               intstatus);
2576         }
2577 }
2578
2579 void brcms_c_intrson(struct brcms_c_info *wlc)
2580 {
2581         struct brcms_hardware *wlc_hw = wlc->hw;
2582         wlc->macintmask = wlc->defmacintmask;
2583         W_REG(&wlc_hw->regs->macintmask, wlc->macintmask);
2584 }
2585
2586 /*
2587  * callback for siutils.c, which has only wlc handler, no wl they both check
2588  * up, not only because there is no need to off/restore d11 interrupt but also
2589  * because per-port code may require sync with valid interrupt.
2590  */
2591 static u32 brcms_c_wlintrsoff(struct brcms_c_info *wlc)
2592 {
2593         if (!wlc->hw->up)
2594                 return 0;
2595
2596         return brcms_intrsoff(wlc->wl);
2597 }
2598
2599 static void brcms_c_wlintrsrestore(struct brcms_c_info *wlc, u32 macintmask)
2600 {
2601         if (!wlc->hw->up)
2602                 return;
2603
2604         brcms_intrsrestore(wlc->wl, macintmask);
2605 }
2606
2607 u32 brcms_c_intrsoff(struct brcms_c_info *wlc)
2608 {
2609         struct brcms_hardware *wlc_hw = wlc->hw;
2610         u32 macintmask;
2611
2612         if (!wlc_hw->clk)
2613                 return 0;
2614
2615         macintmask = wlc->macintmask;   /* isr can still happen */
2616
2617         W_REG(&wlc_hw->regs->macintmask, 0);
2618         (void)R_REG(&wlc_hw->regs->macintmask); /* sync readback */
2619         udelay(1);              /* ensure int line is no longer driven */
2620         wlc->macintmask = 0;
2621
2622         /* return previous macintmask; resolve race between us and our isr */
2623         return wlc->macintstatus ? 0 : macintmask;
2624 }
2625
2626 void brcms_c_intrsrestore(struct brcms_c_info *wlc, u32 macintmask)
2627 {
2628         struct brcms_hardware *wlc_hw = wlc->hw;
2629         if (!wlc_hw->clk)
2630                 return;
2631
2632         wlc->macintmask = macintmask;
2633         W_REG(&wlc_hw->regs->macintmask, wlc->macintmask);
2634 }
2635
2636 static void brcms_b_tx_fifo_suspend(struct brcms_hardware *wlc_hw,
2637                                     uint tx_fifo)
2638 {
2639         u8 fifo = 1 << tx_fifo;
2640
2641         /* Two clients of this code, 11h Quiet period and scanning. */
2642
2643         /* only suspend if not already suspended */
2644         if ((wlc_hw->suspended_fifos & fifo) == fifo)
2645                 return;
2646
2647         /* force the core awake only if not already */
2648         if (wlc_hw->suspended_fifos == 0)
2649                 brcms_c_ucode_wake_override_set(wlc_hw,
2650                                                 BRCMS_WAKE_OVERRIDE_TXFIFO);
2651
2652         wlc_hw->suspended_fifos |= fifo;
2653
2654         if (wlc_hw->di[tx_fifo]) {
2655                 /*
2656                  * Suspending AMPDU transmissions in the middle can cause
2657                  * underflow which may result in mismatch between ucode and
2658                  * driver so suspend the mac before suspending the FIFO
2659                  */
2660                 if (BRCMS_PHY_11N_CAP(wlc_hw->band))
2661                         brcms_c_suspend_mac_and_wait(wlc_hw->wlc);
2662
2663                 dma_txsuspend(wlc_hw->di[tx_fifo]);
2664
2665                 if (BRCMS_PHY_11N_CAP(wlc_hw->band))
2666                         brcms_c_enable_mac(wlc_hw->wlc);
2667         }
2668 }
2669
2670 static void brcms_b_tx_fifo_resume(struct brcms_hardware *wlc_hw,
2671                                    uint tx_fifo)
2672 {
2673         /* BMAC_NOTE: BRCMS_TX_FIFO_ENAB is done in brcms_c_dpc() for DMA case
2674          * but need to be done here for PIO otherwise the watchdog will catch
2675          * the inconsistency and fire
2676          */
2677         /* Two clients of this code, 11h Quiet period and scanning. */
2678         if (wlc_hw->di[tx_fifo])
2679                 dma_txresume(wlc_hw->di[tx_fifo]);
2680
2681         /* allow core to sleep again */
2682         if (wlc_hw->suspended_fifos == 0)
2683                 return;
2684         else {
2685                 wlc_hw->suspended_fifos &= ~(1 << tx_fifo);
2686                 if (wlc_hw->suspended_fifos == 0)
2687                         brcms_c_ucode_wake_override_clear(wlc_hw,
2688                                                 BRCMS_WAKE_OVERRIDE_TXFIFO);
2689         }
2690 }
2691
2692 static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool on, u32 flags)
2693 {
2694         u8 null_ether_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
2695
2696         if (on) {
2697                 /* suspend tx fifos */
2698                 brcms_b_tx_fifo_suspend(wlc_hw, TX_DATA_FIFO);
2699                 brcms_b_tx_fifo_suspend(wlc_hw, TX_CTL_FIFO);
2700                 brcms_b_tx_fifo_suspend(wlc_hw, TX_AC_BK_FIFO);
2701                 brcms_b_tx_fifo_suspend(wlc_hw, TX_AC_VI_FIFO);
2702
2703                 /* zero the address match register so we do not send ACKs */
2704                 brcms_b_set_addrmatch(wlc_hw, RCM_MAC_OFFSET,
2705                                        null_ether_addr);
2706         } else {
2707                 /* resume tx fifos */
2708                 brcms_b_tx_fifo_resume(wlc_hw, TX_DATA_FIFO);
2709                 brcms_b_tx_fifo_resume(wlc_hw, TX_CTL_FIFO);
2710                 brcms_b_tx_fifo_resume(wlc_hw, TX_AC_BK_FIFO);
2711                 brcms_b_tx_fifo_resume(wlc_hw, TX_AC_VI_FIFO);
2712
2713                 /* Restore address */
2714                 brcms_b_set_addrmatch(wlc_hw, RCM_MAC_OFFSET,
2715                                        wlc_hw->etheraddr);
2716         }
2717
2718         wlc_phy_mute_upd(wlc_hw->band->pi, on, flags);
2719
2720         if (on)
2721                 brcms_c_ucode_mute_override_set(wlc_hw);
2722         else
2723                 brcms_c_ucode_mute_override_clear(wlc_hw);
2724 }
2725
2726 /*
2727  * Read and clear macintmask and macintstatus and intstatus registers.
2728  * This routine should be called with interrupts off
2729  * Return:
2730  *   -1 if brcms_deviceremoved(wlc) evaluates to true;
2731  *   0 if the interrupt is not for us, or we are in some special cases;
2732  *   device interrupt status bits otherwise.
2733  */
2734 static inline u32 wlc_intstatus(struct brcms_c_info *wlc, bool in_isr)
2735 {
2736         struct brcms_hardware *wlc_hw = wlc->hw;
2737         struct d11regs *regs = wlc_hw->regs;
2738         u32 macintstatus;
2739
2740         /* macintstatus includes a DMA interrupt summary bit */
2741         macintstatus = R_REG(&regs->macintstatus);
2742
2743         BCMMSG(wlc->wiphy, "wl%d: macintstatus: 0x%x\n", wlc_hw->unit,
2744                  macintstatus);
2745
2746         /* detect cardbus removed, in power down(suspend) and in reset */
2747         if (brcms_deviceremoved(wlc))
2748                 return -1;
2749
2750         /* brcms_deviceremoved() succeeds even when the core is still resetting,
2751          * handle that case here.
2752          */
2753         if (macintstatus == 0xffffffff)
2754                 return 0;
2755
2756         /* defer unsolicited interrupts */
2757         macintstatus &= (in_isr ? wlc->macintmask : wlc->defmacintmask);
2758
2759         /* if not for us */
2760         if (macintstatus == 0)
2761                 return 0;
2762
2763         /* interrupts are already turned off for CFE build
2764          * Caution: For CFE Turning off the interrupts again has some undesired
2765          * consequences
2766          */
2767         /* turn off the interrupts */
2768         W_REG(&regs->macintmask, 0);
2769         (void)R_REG(&regs->macintmask); /* sync readback */
2770         wlc->macintmask = 0;
2771
2772         /* clear device interrupts */
2773         W_REG(&regs->macintstatus, macintstatus);
2774
2775         /* MI_DMAINT is indication of non-zero intstatus */
2776         if (macintstatus & MI_DMAINT)
2777                 /*
2778                  * only fifo interrupt enabled is I_RI in
2779                  * RX_FIFO. If MI_DMAINT is set, assume it
2780                  * is set and clear the interrupt.
2781                  */
2782                 W_REG(&regs->intctrlregs[RX_FIFO].intstatus,
2783                       DEF_RXINTMASK);
2784
2785         return macintstatus;
2786 }
2787
2788 /* Update wlc->macintstatus and wlc->intstatus[]. */
2789 /* Return true if they are updated successfully. false otherwise */
2790 bool brcms_c_intrsupd(struct brcms_c_info *wlc)
2791 {
2792         u32 macintstatus;
2793
2794         /* read and clear macintstatus and intstatus registers */
2795         macintstatus = wlc_intstatus(wlc, false);
2796
2797         /* device is removed */
2798         if (macintstatus == 0xffffffff)
2799                 return false;
2800
2801         /* update interrupt status in software */
2802         wlc->macintstatus |= macintstatus;
2803
2804         return true;
2805 }
2806
2807 /*
2808  * First-level interrupt processing.
2809  * Return true if this was our interrupt, false otherwise.
2810  * *wantdpc will be set to true if further brcms_c_dpc() processing is required,
2811  * false otherwise.
2812  */
2813 bool brcms_c_isr(struct brcms_c_info *wlc, bool *wantdpc)
2814 {
2815         struct brcms_hardware *wlc_hw = wlc->hw;
2816         u32 macintstatus;
2817
2818         *wantdpc = false;
2819
2820         if (!wlc_hw->up || !wlc->macintmask)
2821                 return false;
2822
2823         /* read and clear macintstatus and intstatus registers */
2824         macintstatus = wlc_intstatus(wlc, true);
2825
2826         if (macintstatus == 0xffffffff)
2827                 wiphy_err(wlc->wiphy, "DEVICEREMOVED detected in the ISR code"
2828                           " path\n");
2829
2830         /* it is not for us */
2831         if (macintstatus == 0)
2832                 return false;
2833
2834         *wantdpc = true;
2835
2836         /* save interrupt status bits */
2837         wlc->macintstatus = macintstatus;
2838
2839         return true;
2840
2841 }
2842
2843 void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc)
2844 {
2845         struct brcms_hardware *wlc_hw = wlc->hw;
2846         struct d11regs *regs = wlc_hw->regs;
2847         u32 mc, mi;
2848         struct wiphy *wiphy = wlc->wiphy;
2849
2850         BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
2851                 wlc_hw->band->bandunit);
2852
2853         /*
2854          * Track overlapping suspend requests
2855          */
2856         wlc_hw->mac_suspend_depth++;
2857         if (wlc_hw->mac_suspend_depth > 1)
2858                 return;
2859
2860         /* force the core awake */
2861         brcms_c_ucode_wake_override_set(wlc_hw, BRCMS_WAKE_OVERRIDE_MACSUSPEND);
2862
2863         mc = R_REG(&regs->maccontrol);
2864
2865         if (mc == 0xffffffff) {
2866                 wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
2867                           __func__);
2868                 brcms_down(wlc->wl);
2869                 return;
2870         }
2871         WARN_ON(mc & MCTL_PSM_JMP_0);
2872         WARN_ON(!(mc & MCTL_PSM_RUN));
2873         WARN_ON(!(mc & MCTL_EN_MAC));
2874
2875         mi = R_REG(&regs->macintstatus);
2876         if (mi == 0xffffffff) {
2877                 wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
2878                           __func__);
2879                 brcms_down(wlc->wl);
2880                 return;
2881         }
2882         WARN_ON(mi & MI_MACSSPNDD);
2883
2884         brcms_b_mctrl(wlc_hw, MCTL_EN_MAC, 0);
2885
2886         SPINWAIT(!(R_REG(&regs->macintstatus) & MI_MACSSPNDD),
2887                  BRCMS_MAX_MAC_SUSPEND);
2888
2889         if (!(R_REG(&regs->macintstatus) & MI_MACSSPNDD)) {
2890                 wiphy_err(wiphy, "wl%d: wlc_suspend_mac_and_wait: waited %d uS"
2891                           " and MI_MACSSPNDD is still not on.\n",
2892                           wlc_hw->unit, BRCMS_MAX_MAC_SUSPEND);
2893                 wiphy_err(wiphy, "wl%d: psmdebug 0x%08x, phydebug 0x%08x, "
2894                           "psm_brc 0x%04x\n", wlc_hw->unit,
2895                           R_REG(&regs->psmdebug),
2896                           R_REG(&regs->phydebug),
2897                           R_REG(&regs->psm_brc));
2898         }
2899
2900         mc = R_REG(&regs->maccontrol);
2901         if (mc == 0xffffffff) {
2902                 wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
2903                           __func__);
2904                 brcms_down(wlc->wl);
2905                 return;
2906         }
2907         WARN_ON(mc & MCTL_PSM_JMP_0);
2908         WARN_ON(!(mc & MCTL_PSM_RUN));
2909         WARN_ON(mc & MCTL_EN_MAC);
2910 }
2911
2912 void brcms_c_enable_mac(struct brcms_c_info *wlc)
2913 {
2914         struct brcms_hardware *wlc_hw = wlc->hw;
2915         struct d11regs *regs = wlc_hw->regs;
2916         u32 mc, mi;
2917
2918         BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
2919                 wlc->band->bandunit);
2920
2921         /*
2922          * Track overlapping suspend requests
2923          */
2924         wlc_hw->mac_suspend_depth--;
2925         if (wlc_hw->mac_suspend_depth > 0)
2926                 return;
2927
2928         mc = R_REG(&regs->maccontrol);
2929         WARN_ON(mc & MCTL_PSM_JMP_0);
2930         WARN_ON(mc & MCTL_EN_MAC);
2931         WARN_ON(!(mc & MCTL_PSM_RUN));
2932
2933         brcms_b_mctrl(wlc_hw, MCTL_EN_MAC, MCTL_EN_MAC);
2934         W_REG(&regs->macintstatus, MI_MACSSPNDD);
2935
2936         mc = R_REG(&regs->maccontrol);
2937         WARN_ON(mc & MCTL_PSM_JMP_0);
2938         WARN_ON(!(mc & MCTL_EN_MAC));
2939         WARN_ON(!(mc & MCTL_PSM_RUN));
2940
2941         mi = R_REG(&regs->macintstatus);
2942         WARN_ON(mi & MI_MACSSPNDD);
2943
2944         brcms_c_ucode_wake_override_clear(wlc_hw,
2945                                           BRCMS_WAKE_OVERRIDE_MACSUSPEND);
2946 }
2947
2948 void brcms_b_band_stf_ss_set(struct brcms_hardware *wlc_hw, u8 stf_mode)
2949 {
2950         wlc_hw->hw_stf_ss_opmode = stf_mode;
2951
2952         if (wlc_hw->clk)
2953                 brcms_upd_ofdm_pctl1_table(wlc_hw);
2954 }
2955
2956 static bool brcms_b_validate_chip_access(struct brcms_hardware *wlc_hw)
2957 {
2958         struct d11regs *regs;
2959         u32 w, val;
2960         struct wiphy *wiphy = wlc_hw->wlc->wiphy;
2961
2962         BCMMSG(wiphy, "wl%d\n", wlc_hw->unit);
2963
2964         regs = wlc_hw->regs;
2965
2966         /* Validate dchip register access */
2967
2968         W_REG(&regs->objaddr, OBJADDR_SHM_SEL | 0);
2969         (void)R_REG(&regs->objaddr);
2970         w = R_REG(&regs->objdata);
2971
2972         /* Can we write and read back a 32bit register? */
2973         W_REG(&regs->objaddr, OBJADDR_SHM_SEL | 0);
2974         (void)R_REG(&regs->objaddr);
2975         W_REG(&regs->objdata, (u32) 0xaa5555aa);
2976
2977         W_REG(&regs->objaddr, OBJADDR_SHM_SEL | 0);
2978         (void)R_REG(&regs->objaddr);
2979         val = R_REG(&regs->objdata);
2980         if (val != (u32) 0xaa5555aa) {
2981                 wiphy_err(wiphy, "wl%d: validate_chip_access: SHM = 0x%x, "
2982                           "expected 0xaa5555aa\n", wlc_hw->unit, val);
2983                 return false;
2984         }
2985
2986         W_REG(&regs->objaddr, OBJADDR_SHM_SEL | 0);
2987         (void)R_REG(&regs->objaddr);
2988         W_REG(&regs->objdata, (u32) 0x55aaaa55);
2989
2990         W_REG(&regs->objaddr, OBJADDR_SHM_SEL | 0);
2991         (void)R_REG(&regs->objaddr);
2992         val = R_REG(&regs->objdata);
2993         if (val != (u32) 0x55aaaa55) {
2994                 wiphy_err(wiphy, "wl%d: validate_chip_access: SHM = 0x%x, "
2995                           "expected 0x55aaaa55\n", wlc_hw->unit, val);
2996                 return false;
2997         }
2998
2999         W_REG(&regs->objaddr, OBJADDR_SHM_SEL | 0);
3000         (void)R_REG(&regs->objaddr);
3001         W_REG(&regs->objdata, w);
3002
3003         /* clear CFPStart */
3004         W_REG(&regs->tsf_cfpstart, 0);
3005
3006         w = R_REG(&regs->maccontrol);
3007         if ((w != (MCTL_IHR_EN | MCTL_WAKE)) &&
3008             (w != (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE))) {
3009                 wiphy_err(wiphy, "wl%d: validate_chip_access: maccontrol = "
3010                           "0x%x, expected 0x%x or 0x%x\n", wlc_hw->unit, w,
3011                           (MCTL_IHR_EN | MCTL_WAKE),
3012                           (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE));
3013                 return false;
3014         }
3015
3016         return true;
3017 }
3018
3019 #define PHYPLL_WAIT_US  100000
3020
3021 void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on)
3022 {
3023         struct d11regs *regs;
3024         u32 tmp;
3025
3026         BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
3027
3028         tmp = 0;
3029         regs = wlc_hw->regs;
3030
3031         if (on) {
3032                 if ((wlc_hw->sih->chip == BCM4313_CHIP_ID)) {
3033                         OR_REG(&regs->clk_ctl_st,
3034                                (CCS_ERSRC_REQ_HT | CCS_ERSRC_REQ_D11PLL |
3035                                 CCS_ERSRC_REQ_PHYPLL));
3036                         SPINWAIT((R_REG(&regs->clk_ctl_st) &
3037                                   (CCS_ERSRC_AVAIL_HT)) != (CCS_ERSRC_AVAIL_HT),
3038                                  PHYPLL_WAIT_US);
3039
3040                         tmp = R_REG(&regs->clk_ctl_st);
3041                         if ((tmp & (CCS_ERSRC_AVAIL_HT)) !=
3042                             (CCS_ERSRC_AVAIL_HT))
3043                                 wiphy_err(wlc_hw->wlc->wiphy, "%s: turn on PHY"
3044                                           " PLL failed\n", __func__);
3045                 } else {
3046                         OR_REG(&regs->clk_ctl_st,
3047                                (CCS_ERSRC_REQ_D11PLL | CCS_ERSRC_REQ_PHYPLL));
3048                         SPINWAIT((R_REG(&regs->clk_ctl_st) &
3049                                   (CCS_ERSRC_AVAIL_D11PLL |
3050                                    CCS_ERSRC_AVAIL_PHYPLL)) !=
3051                                  (CCS_ERSRC_AVAIL_D11PLL |
3052                                   CCS_ERSRC_AVAIL_PHYPLL), PHYPLL_WAIT_US);
3053
3054                         tmp = R_REG(&regs->clk_ctl_st);
3055                         if ((tmp &
3056                              (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL))
3057                             !=
3058                             (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL))
3059                                 wiphy_err(wlc_hw->wlc->wiphy, "%s: turn on "
3060                                           "PHY PLL failed\n", __func__);
3061                 }
3062         } else {
3063                 /*
3064                  * Since the PLL may be shared, other cores can still
3065                  * be requesting it; so we'll deassert the request but
3066                  * not wait for status to comply.
3067                  */
3068                 AND_REG(&regs->clk_ctl_st, ~CCS_ERSRC_REQ_PHYPLL);
3069                 tmp = R_REG(&regs->clk_ctl_st);
3070         }
3071 }
3072
3073 void brcms_c_coredisable(struct brcms_hardware *wlc_hw)
3074 {
3075         bool dev_gone;
3076
3077         BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
3078
3079         dev_gone = brcms_deviceremoved(wlc_hw->wlc);
3080
3081         if (dev_gone)
3082                 return;
3083
3084         if (wlc_hw->noreset)
3085                 return;
3086
3087         /* radio off */
3088         wlc_phy_switch_radio(wlc_hw->band->pi, OFF);
3089
3090         /* turn off analog core */
3091         wlc_phy_anacore(wlc_hw->band->pi, OFF);
3092
3093         /* turn off PHYPLL to save power */
3094         brcms_b_core_phypll_ctl(wlc_hw, false);
3095
3096         wlc_hw->clk = false;
3097         ai_core_disable(wlc_hw->sih, 0);
3098         wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false);
3099 }
3100
3101 static void brcms_c_flushqueues(struct brcms_c_info *wlc)
3102 {
3103         struct brcms_hardware *wlc_hw = wlc->hw;
3104         uint i;
3105
3106         /* free any posted tx packets */
3107         for (i = 0; i < NFIFO; i++)
3108                 if (wlc_hw->di[i]) {
3109                         dma_txreclaim(wlc_hw->di[i], DMA_RANGE_ALL);
3110                         wlc->core->txpktpend[i] = 0;
3111                         BCMMSG(wlc->wiphy, "pktpend fifo %d clrd\n", i);
3112                 }
3113
3114         /* free any posted rx packets */
3115         dma_rxreclaim(wlc_hw->di[RX_FIFO]);
3116 }
3117
3118 static u16
3119 brcms_b_read_objmem(struct brcms_hardware *wlc_hw, uint offset, u32 sel)
3120 {
3121         struct d11regs *regs = wlc_hw->regs;
3122         u16 *objdata_lo = (u16 *)&regs->objdata;
3123         u16 *objdata_hi = objdata_lo + 1;
3124         u16 v;
3125
3126         W_REG(&regs->objaddr, sel | (offset >> 2));
3127         (void)R_REG(&regs->objaddr);
3128         if (offset & 2)
3129                 v = R_REG(objdata_hi);
3130         else
3131                 v = R_REG(objdata_lo);
3132
3133         return v;
3134 }
3135
3136 static void
3137 brcms_b_write_objmem(struct brcms_hardware *wlc_hw, uint offset, u16 v,
3138                      u32 sel)
3139 {
3140         struct d11regs *regs = wlc_hw->regs;
3141         u16 *objdata_lo = (u16 *)&regs->objdata;
3142         u16 *objdata_hi = objdata_lo + 1;
3143
3144         W_REG(&regs->objaddr, sel | (offset >> 2));
3145         (void)R_REG(&regs->objaddr);
3146         if (offset & 2)
3147                 W_REG(objdata_hi, v);
3148         else
3149                 W_REG(objdata_lo, v);
3150 }
3151
3152 u16 brcms_b_read_shm(struct brcms_hardware *wlc_hw, uint offset)
3153 {
3154         return brcms_b_read_objmem(wlc_hw, offset, OBJADDR_SHM_SEL);
3155 }
3156
3157 void brcms_b_write_shm(struct brcms_hardware *wlc_hw, uint offset, u16 v)
3158 {
3159         brcms_b_write_objmem(wlc_hw, offset, v, OBJADDR_SHM_SEL);
3160 }
3161
3162 /* Copy a buffer to shared memory of specified type .
3163  * SHM 'offset' needs to be an even address and
3164  * Buffer length 'len' must be an even number of bytes
3165  * 'sel' selects the type of memory
3166  */
3167 void
3168 brcms_b_copyto_objmem(struct brcms_hardware *wlc_hw, uint offset,
3169                       const void *buf, int len, u32 sel)
3170 {
3171         u16 v;
3172         const u8 *p = (const u8 *)buf;
3173         int i;
3174
3175         if (len <= 0 || (offset & 1) || (len & 1))
3176                 return;
3177
3178         for (i = 0; i < len; i += 2) {
3179                 v = p[i] | (p[i + 1] << 8);
3180                 brcms_b_write_objmem(wlc_hw, offset + i, v, sel);
3181         }
3182 }
3183
3184 /* Copy a piece of shared memory of specified type to a buffer .
3185  * SHM 'offset' needs to be an even address and
3186  * Buffer length 'len' must be an even number of bytes
3187  * 'sel' selects the type of memory
3188  */
3189 void
3190 brcms_b_copyfrom_objmem(struct brcms_hardware *wlc_hw, uint offset, void *buf,
3191                          int len, u32 sel)
3192 {
3193         u16 v;
3194         u8 *p = (u8 *) buf;
3195         int i;
3196
3197         if (len <= 0 || (offset & 1) || (len & 1))
3198                 return;
3199
3200         for (i = 0; i < len; i += 2) {
3201                 v = brcms_b_read_objmem(wlc_hw, offset + i, sel);
3202                 p[i] = v & 0xFF;
3203                 p[i + 1] = (v >> 8) & 0xFF;
3204         }
3205 }
3206
3207 static void brcms_b_copyfrom_vars(struct brcms_hardware *wlc_hw, char **buf,
3208                            uint *len)
3209 {
3210         BCMMSG(wlc_hw->wlc->wiphy, "nvram vars totlen=%d\n",
3211                 wlc_hw->vars_size);
3212
3213         *buf = wlc_hw->vars;
3214         *len = wlc_hw->vars_size;
3215 }
3216
3217 static void brcms_b_retrylimit_upd(struct brcms_hardware *wlc_hw,
3218                                    u16 SRL, u16 LRL)
3219 {
3220         wlc_hw->SRL = SRL;
3221         wlc_hw->LRL = LRL;
3222
3223         /* write retry limit to SCR, shouldn't need to suspend */
3224         if (wlc_hw->up) {
3225                 W_REG(&wlc_hw->regs->objaddr,
3226                       OBJADDR_SCR_SEL | S_DOT11_SRC_LMT);
3227                 (void)R_REG(&wlc_hw->regs->objaddr);
3228                 W_REG(&wlc_hw->regs->objdata, wlc_hw->SRL);
3229                 W_REG(&wlc_hw->regs->objaddr,
3230                       OBJADDR_SCR_SEL | S_DOT11_LRC_LMT);
3231                 (void)R_REG(&wlc_hw->regs->objaddr);
3232                 W_REG(&wlc_hw->regs->objdata, wlc_hw->LRL);
3233         }
3234 }
3235
3236 static void brcms_b_pllreq(struct brcms_hardware *wlc_hw, bool set, u32 req_bit)
3237 {
3238         if (set) {
3239                 if (mboolisset(wlc_hw->pllreq, req_bit))
3240                         return;
3241
3242                 mboolset(wlc_hw->pllreq, req_bit);
3243
3244                 if (mboolisset(wlc_hw->pllreq, BRCMS_PLLREQ_FLIP)) {
3245                         if (!wlc_hw->sbclk)
3246                                 brcms_b_xtal(wlc_hw, ON);
3247                 }
3248         } else {
3249                 if (!mboolisset(wlc_hw->pllreq, req_bit))
3250                         return;
3251
3252                 mboolclr(wlc_hw->pllreq, req_bit);
3253
3254                 if (mboolisset(wlc_hw->pllreq, BRCMS_PLLREQ_FLIP)) {
3255                         if (wlc_hw->sbclk)
3256                                 brcms_b_xtal(wlc_hw, OFF);
3257                 }
3258         }
3259
3260         return;
3261 }
3262
3263 static void brcms_b_antsel_set(struct brcms_hardware *wlc_hw, u32 antsel_avail)
3264 {
3265         wlc_hw->antsel_avail = antsel_avail;
3266 }
3267
3268 /*
3269  * conditions under which the PM bit should be set in outgoing frames
3270  * and STAY_AWAKE is meaningful
3271  */
3272 bool brcms_c_ps_allowed(struct brcms_c_info *wlc)
3273 {
3274         struct brcms_bss_cfg *cfg = wlc->bsscfg;
3275
3276         /* disallow PS when one of the following global conditions meets */
3277         if (!wlc->pub->associated)
3278                 return false;
3279
3280         /* disallow PS when one of these meets when not scanning */
3281         if (wlc->monitor)
3282                 return false;
3283
3284         if (cfg->associated) {
3285                 /*
3286                  * disallow PS when one of the following
3287                  * bsscfg specific conditions meets
3288                  */
3289                 if (!cfg->BSS)
3290                         return false;
3291
3292                 if (!cfg->dtim_programmed)
3293                         return false;
3294         }
3295
3296         return true;
3297 }
3298
3299 static void brcms_b_reset(struct brcms_hardware *wlc_hw)
3300 {
3301         BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
3302
3303         /* reset the core */
3304         if (!brcms_deviceremoved(wlc_hw->wlc))
3305                 brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS);
3306
3307         /* purge the dma rings */
3308         brcms_c_flushqueues(wlc_hw->wlc);
3309
3310         brcms_c_reset_bmac_done(wlc_hw->wlc);
3311 }
3312
3313 void brcms_c_reset(struct brcms_c_info *wlc)
3314 {
3315         BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
3316
3317         /* slurp up hw mac counters before core reset */
3318         brcms_c_statsupd(wlc);
3319
3320         /* reset our snapshot of macstat counters */
3321         memset((char *)wlc->core->macstat_snapshot, 0,
3322                 sizeof(struct macstat));
3323
3324         brcms_b_reset(wlc->hw);
3325 }
3326
3327 void brcms_c_fatal_error(struct brcms_c_info *wlc)
3328 {
3329         wiphy_err(wlc->wiphy, "wl%d: fatal error, reinitializing\n",
3330                   wlc->pub->unit);
3331         brcms_init(wlc->wl);
3332 }
3333
3334 /* Return the channel the driver should initialize during brcms_c_init.
3335  * the channel may have to be changed from the currently configured channel
3336  * if other configurations are in conflict (bandlocked, 11n mode disabled,
3337  * invalid channel for current country, etc.)
3338  */
3339 static u16 brcms_c_init_chanspec(struct brcms_c_info *wlc)
3340 {
3341         u16 chanspec =
3342             1 | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE |
3343             WL_CHANSPEC_BAND_2G;
3344
3345         return chanspec;
3346 }
3347
3348 void brcms_c_init_scb(struct scb *scb)
3349 {
3350         int i;
3351
3352         memset(scb, 0, sizeof(struct scb));
3353         scb->flags = SCB_WMECAP | SCB_HTCAP;
3354         for (i = 0; i < NUMPRIO; i++) {
3355                 scb->seqnum[i] = 0;
3356                 scb->seqctl[i] = 0xFFFF;
3357         }
3358
3359         scb->seqctl_nonqos = 0xFFFF;
3360         scb->magic = SCB_MAGIC;
3361 }
3362
3363 /* d11 core init
3364  *   reset PSM
3365  *   download ucode/PCM
3366  *   let ucode run to suspended
3367  *   download ucode inits
3368  *   config other core registers
3369  *   init dma
3370  */
3371 static void brcms_b_coreinit(struct brcms_c_info *wlc)
3372 {
3373         struct brcms_hardware *wlc_hw = wlc->hw;
3374         struct d11regs *regs;
3375         u32 sflags;
3376         uint bcnint_us;
3377         uint i = 0;
3378         bool fifosz_fixup = false;
3379         int err = 0;
3380         u16 buf[NFIFO];
3381         struct wiphy *wiphy = wlc->wiphy;
3382         struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode;
3383
3384         regs = wlc_hw->regs;
3385
3386         BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
3387
3388         /* reset PSM */
3389         brcms_b_mctrl(wlc_hw, ~0, (MCTL_IHR_EN | MCTL_PSM_JMP_0 | MCTL_WAKE));
3390
3391         brcms_ucode_download(wlc_hw);
3392         /*
3393          * FIFOSZ fixup. driver wants to controls the fifo allocation.
3394          */
3395         fifosz_fixup = true;
3396
3397         /* let the PSM run to the suspended state, set mode to BSS STA */
3398         W_REG(&regs->macintstatus, -1);
3399         brcms_b_mctrl(wlc_hw, ~0,
3400                        (MCTL_IHR_EN | MCTL_INFRA | MCTL_PSM_RUN | MCTL_WAKE));
3401
3402         /* wait for ucode to self-suspend after auto-init */
3403         SPINWAIT(((R_REG(&regs->macintstatus) & MI_MACSSPNDD) == 0),
3404                  1000 * 1000);
3405         if ((R_REG(&regs->macintstatus) & MI_MACSSPNDD) == 0)
3406                 wiphy_err(wiphy, "wl%d: wlc_coreinit: ucode did not self-"
3407                           "suspend!\n", wlc_hw->unit);
3408
3409         brcms_c_gpio_init(wlc);
3410
3411         sflags = ai_core_sflags(wlc_hw->sih, 0, 0);
3412
3413         if (D11REV_IS(wlc_hw->corerev, 23)) {
3414                 if (BRCMS_ISNPHY(wlc_hw->band))
3415                         brcms_c_write_inits(wlc_hw, ucode->d11n0initvals16);
3416                 else
3417                         wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev"
3418                                   " %d\n", __func__, wlc_hw->unit,
3419                                   wlc_hw->corerev);
3420         } else if (D11REV_IS(wlc_hw->corerev, 24)) {
3421                 if (BRCMS_ISLCNPHY(wlc_hw->band))
3422                         brcms_c_write_inits(wlc_hw, ucode->d11lcn0initvals24);
3423                 else
3424                         wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev"
3425                                   " %d\n", __func__, wlc_hw->unit,
3426                                   wlc_hw->corerev);
3427         } else {
3428                 wiphy_err(wiphy, "%s: wl%d: unsupported corerev %d\n",
3429                           __func__, wlc_hw->unit, wlc_hw->corerev);
3430         }
3431
3432         /* For old ucode, txfifo sizes needs to be modified(increased) */
3433         if (fifosz_fixup == true)
3434                 brcms_b_corerev_fifofixup(wlc_hw);
3435
3436         /* check txfifo allocations match between ucode and driver */
3437         buf[TX_AC_BE_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE0);
3438         if (buf[TX_AC_BE_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_BE_FIFO]) {
3439                 i = TX_AC_BE_FIFO;
3440                 err = -1;
3441         }
3442         buf[TX_AC_VI_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE1);
3443         if (buf[TX_AC_VI_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_VI_FIFO]) {
3444                 i = TX_AC_VI_FIFO;
3445                 err = -1;
3446         }
3447         buf[TX_AC_BK_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE2);
3448         buf[TX_AC_VO_FIFO] = (buf[TX_AC_BK_FIFO] >> 8) & 0xff;
3449         buf[TX_AC_BK_FIFO] &= 0xff;
3450         if (buf[TX_AC_BK_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_BK_FIFO]) {
3451                 i = TX_AC_BK_FIFO;
3452                 err = -1;
3453         }
3454         if (buf[TX_AC_VO_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_VO_FIFO]) {
3455                 i = TX_AC_VO_FIFO;
3456                 err = -1;
3457         }
3458         buf[TX_BCMC_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE3);
3459         buf[TX_ATIM_FIFO] = (buf[TX_BCMC_FIFO] >> 8) & 0xff;
3460         buf[TX_BCMC_FIFO] &= 0xff;
3461         if (buf[TX_BCMC_FIFO] != wlc_hw->xmtfifo_sz[TX_BCMC_FIFO]) {
3462                 i = TX_BCMC_FIFO;
3463                 err = -1;
3464         }
3465         if (buf[TX_ATIM_FIFO] != wlc_hw->xmtfifo_sz[TX_ATIM_FIFO]) {
3466                 i = TX_ATIM_FIFO;
3467                 err = -1;
3468         }
3469         if (err != 0)
3470                 wiphy_err(wiphy, "wlc_coreinit: txfifo mismatch: ucode size %d"
3471                           " driver size %d index %d\n", buf[i],
3472                           wlc_hw->xmtfifo_sz[i], i);
3473
3474         /* make sure we can still talk to the mac */
3475         WARN_ON(R_REG(&regs->maccontrol) == 0xffffffff);
3476
3477         /* band-specific inits done by wlc_bsinit() */
3478
3479         /* Set up frame burst size and antenna swap threshold init values */
3480         brcms_b_write_shm(wlc_hw, M_MBURST_SIZE, MAXTXFRAMEBURST);
3481         brcms_b_write_shm(wlc_hw, M_MAX_ANTCNT, ANTCNT);
3482
3483         /* enable one rx interrupt per received frame */
3484         W_REG(&regs->intrcvlazy[0], (1 << IRL_FC_SHIFT));
3485
3486         /* set the station mode (BSS STA) */
3487         brcms_b_mctrl(wlc_hw,
3488                        (MCTL_INFRA | MCTL_DISCARD_PMQ | MCTL_AP),
3489                        (MCTL_INFRA | MCTL_DISCARD_PMQ));
3490
3491         /* set up Beacon interval */
3492         bcnint_us = 0x8000 << 10;
3493         W_REG(&regs->tsf_cfprep, (bcnint_us << CFPREP_CBI_SHIFT));
3494         W_REG(&regs->tsf_cfpstart, bcnint_us);
3495         W_REG(&regs->macintstatus, MI_GP1);
3496
3497         /* write interrupt mask */
3498         W_REG(&regs->intctrlregs[RX_FIFO].intmask, DEF_RXINTMASK);
3499
3500         /* allow the MAC to control the PHY clock (dynamic on/off) */
3501         brcms_b_macphyclk_set(wlc_hw, ON);
3502
3503         /* program dynamic clock control fast powerup delay register */
3504         wlc->fastpwrup_dly = ai_clkctl_fast_pwrup_delay(wlc_hw->sih);
3505         W_REG(&regs->scc_fastpwrup_dly, wlc->fastpwrup_dly);
3506
3507         /* tell the ucode the corerev */
3508         brcms_b_write_shm(wlc_hw, M_MACHW_VER, (u16) wlc_hw->corerev);
3509
3510         /* tell the ucode MAC capabilities */
3511         brcms_b_write_shm(wlc_hw, M_MACHW_CAP_L,
3512                            (u16) (wlc_hw->machwcap & 0xffff));
3513         brcms_b_write_shm(wlc_hw, M_MACHW_CAP_H,
3514                            (u16) ((wlc_hw->
3515                                       machwcap >> 16) & 0xffff));
3516
3517         /* write retry limits to SCR, this done after PSM init */
3518         W_REG(&regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_SRC_LMT);
3519         (void)R_REG(&regs->objaddr);
3520         W_REG(&regs->objdata, wlc_hw->SRL);
3521         W_REG(&regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_LRC_LMT);
3522         (void)R_REG(&regs->objaddr);
3523         W_REG(&regs->objdata, wlc_hw->LRL);
3524
3525         /* write rate fallback retry limits */
3526         brcms_b_write_shm(wlc_hw, M_SFRMTXCNTFBRTHSD, wlc_hw->SFBL);
3527         brcms_b_write_shm(wlc_hw, M_LFRMTXCNTFBRTHSD, wlc_hw->LFBL);
3528
3529         AND_REG(&regs->ifs_ctl, 0x0FFF);
3530         W_REG(&regs->ifs_aifsn, EDCF_AIFSN_MIN);
3531
3532         /* init the tx dma engines */
3533         for (i = 0; i < NFIFO; i++) {
3534                 if (wlc_hw->di[i])
3535                         dma_txinit(wlc_hw->di[i]);
3536         }
3537
3538         /* init the rx dma engine(s) and post receive buffers */
3539         dma_rxinit(wlc_hw->di[RX_FIFO]);
3540         dma_rxfill(wlc_hw->di[RX_FIFO]);
3541 }
3542
3543 void
3544 static brcms_b_init(struct brcms_hardware *wlc_hw, u16 chanspec,
3545                           bool mute) {
3546         u32 macintmask;
3547         bool fastclk;
3548         struct brcms_c_info *wlc = wlc_hw->wlc;
3549
3550         BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
3551
3552         /* request FAST clock if not on */
3553         fastclk = wlc_hw->forcefastclk;
3554         if (!fastclk)
3555                 brcms_b_clkctl_clk(wlc_hw, CLK_FAST);
3556
3557         /* disable interrupts */
3558         macintmask = brcms_intrsoff(wlc->wl);
3559
3560         /* set up the specified band and chanspec */
3561         brcms_c_setxband(wlc_hw, chspec_bandunit(chanspec));
3562         wlc_phy_chanspec_radio_set(wlc_hw->band->pi, chanspec);
3563
3564         /* do one-time phy inits and calibration */
3565         wlc_phy_cal_init(wlc_hw->band->pi);
3566
3567         /* core-specific initialization */
3568         brcms_b_coreinit(wlc);
3569
3570         /* suspend the tx fifos and mute the phy for preism cac time */
3571         if (mute)
3572                 brcms_b_mute(wlc_hw, ON, PHY_MUTE_FOR_PREISM);
3573
3574         /* band-specific inits */
3575         brcms_b_bsinit(wlc, chanspec);
3576
3577         /* restore macintmask */
3578         brcms_intrsrestore(wlc->wl, macintmask);
3579
3580         /* seed wake_override with BRCMS_WAKE_OVERRIDE_MACSUSPEND since the mac
3581          * is suspended and brcms_c_enable_mac() will clear this override bit.
3582          */
3583         mboolset(wlc_hw->wake_override, BRCMS_WAKE_OVERRIDE_MACSUSPEND);
3584
3585         /*
3586          * initialize mac_suspend_depth to 1 to match ucode
3587          * initial suspended state
3588          */
3589         wlc_hw->mac_suspend_depth = 1;
3590
3591         /* restore the clk */
3592         if (!fastclk)
3593                 brcms_b_clkctl_clk(wlc_hw, CLK_DYNAMIC);
3594 }
3595
3596 static void brcms_c_set_phy_chanspec(struct brcms_c_info *wlc,
3597                                      u16 chanspec)
3598 {
3599         /* Save our copy of the chanspec */
3600         wlc->chanspec = chanspec;
3601
3602         /* Set the chanspec and power limits for this locale */
3603         brcms_c_channel_set_chanspec(wlc->cmi, chanspec, BRCMS_TXPWR_MAX);
3604
3605         if (wlc->stf->ss_algosel_auto)
3606                 brcms_c_stf_ss_algo_channel_get(wlc, &wlc->stf->ss_algo_channel,
3607                                             chanspec);
3608
3609         brcms_c_stf_ss_update(wlc, wlc->band);
3610
3611 }
3612
3613 static void brcms_c_bandinit_ordered(struct brcms_c_info *wlc,
3614                                      u16 chanspec)
3615 {
3616         struct brcms_c_rateset default_rateset;
3617         uint parkband;
3618         uint i, band_order[2];
3619
3620         BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
3621         /*
3622          * We might have been bandlocked during down and the chip
3623          * power-cycled (hibernate). Figure out the right band to park on
3624          */
3625         if (wlc->bandlocked || wlc->pub->_nbands == 1) {
3626                 /* updated in brcms_c_bandlock() */
3627                 parkband = wlc->band->bandunit;
3628                 band_order[0] = band_order[1] = parkband;
3629         } else {
3630                 /* park on the band of the specified chanspec */
3631                 parkband = chspec_bandunit(chanspec);
3632
3633                 /* order so that parkband initialize last */
3634                 band_order[0] = parkband ^ 1;
3635                 band_order[1] = parkband;
3636         }
3637
3638         /* make each band operational, software state init */
3639         for (i = 0; i < wlc->pub->_nbands; i++) {
3640                 uint j = band_order[i];
3641
3642                 wlc->band = wlc->bandstate[j];
3643
3644                 brcms_default_rateset(wlc, &default_rateset);
3645
3646                 /* fill in hw_rate */
3647                 brcms_c_rateset_filter(&default_rateset, &wlc->band->hw_rateset,
3648                                    false, BRCMS_RATES_CCK_OFDM, BRCMS_RATE_MASK,
3649                                    (bool) (wlc->pub->_n_enab & SUPPORT_11N));
3650
3651                 /* init basic rate lookup */
3652                 brcms_c_rate_lookup_init(wlc, &default_rateset);
3653         }
3654
3655         /* sync up phy/radio chanspec */
3656         brcms_c_set_phy_chanspec(wlc, chanspec);
3657 }
3658
3659 /*
3660  * ucode, hwmac update
3661  *    Channel dependent updates for ucode and hw
3662  */
3663 static void brcms_c_ucode_mac_upd(struct brcms_c_info *wlc)
3664 {
3665         /* enable or disable any active IBSSs depending on whether or not
3666          * we are on the home channel
3667          */
3668         if (wlc->home_chanspec == wlc_phy_chanspec_get(wlc->band->pi)) {
3669                 if (wlc->pub->associated) {
3670                         /*
3671                          * BMAC_NOTE: This is something that should be fixed
3672                          * in ucode inits. I think that the ucode inits set
3673                          * up the bcn templates and shm values with a bogus
3674                          * beacon. This should not be done in the inits. If
3675                          * ucode needs to set up a beacon for testing, the
3676                          * test routines should write it down, not expect the
3677                          * inits to populate a bogus beacon.
3678                          */
3679                         if (BRCMS_PHY_11N_CAP(wlc->band))
3680                                 brcms_c_write_shm(wlc, M_BCN_TXTSF_OFFSET, 0);
3681                 }
3682         } else {
3683                 /* disable an active IBSS if we are not on the home channel */
3684         }
3685
3686         /* update the various promisc bits */
3687         brcms_c_mac_bcn_promisc(wlc);
3688         brcms_c_mac_promisc(wlc);
3689 }
3690
3691 /* band-specific init */
3692 static void brcms_c_bsinit(struct brcms_c_info *wlc)
3693 {
3694         BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n",
3695                  wlc->pub->unit, wlc->band->bandunit);
3696
3697         /* write ucode ACK/CTS rate table */
3698         brcms_c_set_ratetable(wlc);
3699
3700         /* update some band specific mac configuration */
3701         brcms_c_ucode_mac_upd(wlc);
3702
3703         /* init antenna selection */
3704         brcms_c_antsel_init(wlc->asi);
3705
3706 }
3707
3708 /* formula:  IDLE_BUSY_RATIO_X_16 = (100-duty_cycle)/duty_cycle*16 */
3709 static int
3710 brcms_c_duty_cycle_set(struct brcms_c_info *wlc, int duty_cycle, bool isOFDM,
3711                    bool writeToShm)
3712 {
3713         int idle_busy_ratio_x_16 = 0;
3714         uint offset =
3715             isOFDM ? M_TX_IDLE_BUSY_RATIO_X_16_OFDM :
3716             M_TX_IDLE_BUSY_RATIO_X_16_CCK;
3717         if (duty_cycle > 100 || duty_cycle < 0) {
3718                 wiphy_err(wlc->wiphy, "wl%d:  duty cycle value off limit\n",
3719                           wlc->pub->unit);
3720                 return -EINVAL;
3721         }
3722         if (duty_cycle)
3723                 idle_busy_ratio_x_16 = (100 - duty_cycle) * 16 / duty_cycle;
3724         /* Only write to shared memory  when wl is up */
3725         if (writeToShm)
3726                 brcms_c_write_shm(wlc, offset, (u16) idle_busy_ratio_x_16);
3727
3728         if (isOFDM)
3729                 wlc->tx_duty_cycle_ofdm = (u16) duty_cycle;
3730         else
3731                 wlc->tx_duty_cycle_cck = (u16) duty_cycle;
3732
3733         return 0;
3734 }
3735
3736 /*
3737  * Initialize the base precedence map for dequeueing
3738  * from txq based on WME settings
3739  */
3740 static void brcms_c_tx_prec_map_init(struct brcms_c_info *wlc)
3741 {
3742         wlc->tx_prec_map = BRCMS_PREC_BMP_ALL;
3743         memset(wlc->fifo2prec_map, 0, NFIFO * sizeof(u16));
3744
3745         wlc->fifo2prec_map[TX_AC_BK_FIFO] = BRCMS_PREC_BMP_AC_BK;
3746         wlc->fifo2prec_map[TX_AC_BE_FIFO] = BRCMS_PREC_BMP_AC_BE;
3747         wlc->fifo2prec_map[TX_AC_VI_FIFO] = BRCMS_PREC_BMP_AC_VI;
3748         wlc->fifo2prec_map[TX_AC_VO_FIFO] = BRCMS_PREC_BMP_AC_VO;
3749 }
3750
3751 static void
3752 brcms_c_txflowcontrol_signal(struct brcms_c_info *wlc,
3753                              struct brcms_txq_info *qi, bool on, int prio)
3754 {
3755         /* transmit flowcontrol is not yet implemented */
3756 }
3757
3758 static void brcms_c_txflowcontrol_reset(struct brcms_c_info *wlc)
3759 {
3760         struct brcms_txq_info *qi;
3761
3762         for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) {
3763                 if (qi->stopped) {
3764                         brcms_c_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO);
3765                         qi->stopped = 0;
3766                 }
3767         }
3768 }
3769
3770 void brcms_c_init(struct brcms_c_info *wlc)
3771 {
3772         struct d11regs *regs;
3773         u16 chanspec;
3774         bool mute = false;
3775
3776         BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
3777
3778         regs = wlc->regs;
3779
3780         /*
3781          * This will happen if a big-hammer was executed. In
3782          * that case, we want to go back to the channel that
3783          * we were on and not new channel
3784          */
3785         if (wlc->pub->associated)
3786                 chanspec = wlc->home_chanspec;
3787         else
3788                 chanspec = brcms_c_init_chanspec(wlc);
3789
3790         brcms_b_init(wlc->hw, chanspec, mute);
3791
3792         /* update beacon listen interval */
3793         brcms_c_bcn_li_upd(wlc);
3794
3795         /* the world is new again, so is our reported rate */
3796         brcms_c_reprate_init(wlc);
3797
3798         /* write ethernet address to core */
3799         brcms_c_set_mac(wlc->bsscfg);
3800         brcms_c_set_bssid(wlc->bsscfg);
3801
3802         /* Update tsf_cfprep if associated and up */
3803         if (wlc->pub->associated && wlc->bsscfg->up) {
3804                 u32 bi;
3805
3806                 /* get beacon period and convert to uS */
3807                 bi = wlc->bsscfg->current_bss->beacon_period << 10;
3808                 /*
3809                  * update since init path would reset
3810                  * to default value
3811                  */
3812                 W_REG(&regs->tsf_cfprep,
3813                       (bi << CFPREP_CBI_SHIFT));
3814
3815                 /* Update maccontrol PM related bits */
3816                 brcms_c_set_ps_ctrl(wlc);
3817         }
3818
3819         brcms_c_bandinit_ordered(wlc, chanspec);
3820
3821         /* init probe response timeout */
3822         brcms_c_write_shm(wlc, M_PRS_MAXTIME, wlc->prb_resp_timeout);
3823
3824         /* init max burst txop (framebursting) */
3825         brcms_c_write_shm(wlc, M_MBURST_TXOP,
3826                       (wlc->
3827                        _rifs ? (EDCF_AC_VO_TXOP_AP << 5) : MAXFRAMEBURST_TXOP));
3828
3829         /* initialize maximum allowed duty cycle */
3830         brcms_c_duty_cycle_set(wlc, wlc->tx_duty_cycle_ofdm, true, true);
3831         brcms_c_duty_cycle_set(wlc, wlc->tx_duty_cycle_cck, false, true);
3832
3833         /*
3834          * Update some shared memory locations related to
3835          * max AMPDU size allowed to received
3836          */
3837         brcms_c_ampdu_shm_upd(wlc->ampdu);
3838
3839         /* band-specific inits */
3840         brcms_c_bsinit(wlc);
3841
3842         /* Enable EDCF mode (while the MAC is suspended) */
3843         OR_REG(&regs->ifs_ctl, IFS_USEEDCF);
3844         brcms_c_edcf_setparams(wlc, false);
3845
3846         /* Init precedence maps for empty FIFOs */
3847         brcms_c_tx_prec_map_init(wlc);
3848
3849         /* read the ucode version if we have not yet done so */
3850         if (wlc->ucode_rev == 0) {
3851                 wlc->ucode_rev =
3852                     brcms_c_read_shm(wlc, M_BOM_REV_MAJOR) << NBITS(u16);
3853                 wlc->ucode_rev |= brcms_c_read_shm(wlc, M_BOM_REV_MINOR);
3854         }
3855
3856         /* ..now really unleash hell (allow the MAC out of suspend) */
3857         brcms_c_enable_mac(wlc);
3858
3859         /* clear tx flow control */
3860         brcms_c_txflowcontrol_reset(wlc);
3861
3862         /* enable the RF Disable Delay timer */
3863         W_REG(&wlc->regs->rfdisabledly, RFDISABLE_DEFAULT);
3864
3865         /* initialize mpc delay */
3866         wlc->mpc_delay_off = wlc->mpc_dlycnt = BRCMS_MPC_MIN_DELAYCNT;
3867
3868         /*
3869          * Initialize WME parameters; if they haven't been set by some other
3870          * mechanism (IOVar, etc) then read them from the hardware.
3871          */
3872         if (GFIELD(wlc->wme_retries[0], EDCF_SHORT) == 0) {
3873                 /* Uninitialized; read from HW */
3874                 int ac;
3875
3876                 for (ac = 0; ac < AC_COUNT; ac++)
3877                         wlc->wme_retries[ac] =
3878                             brcms_c_read_shm(wlc, M_AC_TXLMT_ADDR(ac));
3879         }
3880 }
3881
3882 void brcms_c_mac_bcn_promisc_change(struct brcms_c_info *wlc, bool promisc)
3883 {
3884         wlc->bcnmisc_monitor = promisc;
3885         brcms_c_mac_bcn_promisc(wlc);
3886 }
3887
3888 void brcms_c_mac_bcn_promisc(struct brcms_c_info *wlc)
3889 {
3890         if (wlc->bcnmisc_monitor)
3891                 brcms_c_mctrl(wlc, MCTL_BCNS_PROMISC, MCTL_BCNS_PROMISC);
3892         else
3893                 brcms_c_mctrl(wlc, MCTL_BCNS_PROMISC, 0);
3894 }
3895
3896 /* set or clear maccontrol bits MCTL_PROMISC and MCTL_KEEPCONTROL */
3897 void brcms_c_mac_promisc(struct brcms_c_info *wlc)
3898 {
3899         u32 promisc_bits = 0;
3900
3901         /*
3902          * promiscuous mode just sets MCTL_PROMISC
3903          * Note: APs get all BSS traffic without the need to set
3904          * the MCTL_PROMISC bit since all BSS data traffic is
3905          * directed at the AP
3906          */
3907         if (wlc->pub->promisc)
3908                 promisc_bits |= MCTL_PROMISC;
3909
3910         /* monitor mode needs both MCTL_PROMISC and MCTL_KEEPCONTROL
3911          * Note: monitor mode also needs MCTL_BCNS_PROMISC, but that is
3912          * handled in brcms_c_mac_bcn_promisc()
3913          */
3914         if (wlc->monitor)
3915                 promisc_bits |= MCTL_PROMISC | MCTL_KEEPCONTROL;
3916
3917         brcms_c_mctrl(wlc, MCTL_PROMISC | MCTL_KEEPCONTROL, promisc_bits);
3918 }
3919
3920 /* push sw hps and wake state through hardware */
3921 void brcms_c_set_ps_ctrl(struct brcms_c_info *wlc)
3922 {
3923         u32 v1, v2;
3924         bool hps;
3925         bool awake_before;
3926
3927         hps = brcms_c_ps_allowed(wlc);
3928
3929         BCMMSG(wlc->wiphy, "wl%d: hps %d\n", wlc->pub->unit, hps);
3930
3931         v1 = R_REG(&wlc->regs->maccontrol);
3932         v2 = MCTL_WAKE;
3933         if (hps)
3934                 v2 |= MCTL_HPS;
3935
3936         brcms_c_mctrl(wlc, MCTL_WAKE | MCTL_HPS, v2);
3937
3938         awake_before = ((v1 & MCTL_WAKE) || ((v1 & MCTL_HPS) == 0));
3939
3940         if (!awake_before)
3941                 brcms_b_wait_for_wake(wlc->hw);
3942
3943 }
3944
3945 /*
3946  * Write this BSS config's MAC address to core.
3947  * Updates RXE match engine.
3948  */
3949 int brcms_c_set_mac(struct brcms_bss_cfg *bsscfg)
3950 {
3951         int err = 0;
3952         struct brcms_c_info *wlc = bsscfg->wlc;
3953
3954         /* enter the MAC addr into the RXE match registers */
3955         brcms_c_set_addrmatch(wlc, RCM_MAC_OFFSET, bsscfg->cur_etheraddr);
3956
3957         brcms_c_ampdu_macaddr_upd(wlc);
3958
3959         return err;
3960 }
3961
3962 /* Write the BSS config's BSSID address to core (set_bssid in d11procs.tcl).
3963  * Updates RXE match engine.
3964  */
3965 void brcms_c_set_bssid(struct brcms_bss_cfg *bsscfg)
3966 {
3967         /* we need to update BSSID in RXE match registers */
3968         brcms_c_set_addrmatch(bsscfg->wlc, RCM_BSSID_OFFSET, bsscfg->BSSID);
3969 }
3970
3971 static void brcms_b_set_shortslot(struct brcms_hardware *wlc_hw, bool shortslot)
3972 {
3973         wlc_hw->shortslot = shortslot;
3974
3975         if (brcms_b_bandtype(wlc_hw) == BRCM_BAND_2G && wlc_hw->up) {
3976                 brcms_c_suspend_mac_and_wait(wlc_hw->wlc);
3977                 brcms_b_update_slot_timing(wlc_hw, shortslot);
3978                 brcms_c_enable_mac(wlc_hw->wlc);
3979         }
3980 }
3981
3982 /*
3983  * Suspend the the MAC and update the slot timing
3984  * for standard 11b/g (20us slots) or shortslot 11g (9us slots).
3985  */
3986 void brcms_c_switch_shortslot(struct brcms_c_info *wlc, bool shortslot)
3987 {
3988         /* use the override if it is set */
3989         if (wlc->shortslot_override != BRCMS_SHORTSLOT_AUTO)
3990                 shortslot = (wlc->shortslot_override == BRCMS_SHORTSLOT_ON);
3991
3992         if (wlc->shortslot == shortslot)
3993                 return;
3994
3995         wlc->shortslot = shortslot;
3996
3997         brcms_b_set_shortslot(wlc->hw, shortslot);
3998 }
3999
4000 void brcms_c_set_home_chanspec(struct brcms_c_info *wlc, u16 chanspec)
4001 {
4002         if (wlc->home_chanspec != chanspec) {
4003                 wlc->home_chanspec = chanspec;
4004
4005                 if (wlc->bsscfg->associated)
4006                         wlc->bsscfg->current_bss->chanspec = chanspec;
4007         }
4008 }
4009
4010 void
4011 brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, u16 chanspec,
4012                       bool mute, struct txpwr_limits *txpwr)
4013 {
4014         uint bandunit;
4015
4016         BCMMSG(wlc_hw->wlc->wiphy, "wl%d: 0x%x\n", wlc_hw->unit, chanspec);
4017
4018         wlc_hw->chanspec = chanspec;
4019
4020         /* Switch bands if necessary */
4021         if (wlc_hw->_nbands > 1) {
4022                 bandunit = chspec_bandunit(chanspec);
4023                 if (wlc_hw->band->bandunit != bandunit) {
4024                         /* brcms_b_setband disables other bandunit,
4025                          *  use light band switch if not up yet
4026                          */
4027                         if (wlc_hw->up) {
4028                                 wlc_phy_chanspec_radio_set(wlc_hw->
4029                                                            bandstate[bandunit]->
4030                                                            pi, chanspec);
4031                                 brcms_b_setband(wlc_hw, bandunit, chanspec);
4032                         } else {
4033                                 brcms_c_setxband(wlc_hw, bandunit);
4034                         }
4035                 }
4036         }
4037
4038         wlc_phy_initcal_enable(wlc_hw->band->pi, !mute);
4039
4040         if (!wlc_hw->up) {
4041                 if (wlc_hw->clk)
4042                         wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr,
4043                                                   chanspec);
4044                 wlc_phy_chanspec_radio_set(wlc_hw->band->pi, chanspec);
4045         } else {
4046                 wlc_phy_chanspec_set(wlc_hw->band->pi, chanspec);
4047                 wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr, chanspec);
4048
4049                 /* Update muting of the channel */
4050                 brcms_b_mute(wlc_hw, mute, 0);
4051         }
4052 }
4053
4054 /* switch to and initialize new band */
4055 static void brcms_c_setband(struct brcms_c_info *wlc,
4056                                            uint bandunit)
4057 {
4058         struct brcms_bss_cfg *cfg = wlc->bsscfg;
4059
4060         wlc->band = wlc->bandstate[bandunit];
4061
4062         if (!wlc->pub->up)
4063                 return;
4064
4065         /* wait for at least one beacon before entering sleeping state */
4066         if (cfg->associated)
4067                 cfg->PMawakebcn = true;
4068
4069         brcms_c_set_ps_ctrl(wlc);
4070
4071         /* band-specific initializations */
4072         brcms_c_bsinit(wlc);
4073 }
4074
4075 void brcms_c_set_chanspec(struct brcms_c_info *wlc, u16 chanspec)
4076 {
4077         uint bandunit;
4078         bool switchband = false;
4079         u16 old_chanspec = wlc->chanspec;
4080
4081         if (!brcms_c_valid_chanspec_db(wlc->cmi, chanspec)) {
4082                 wiphy_err(wlc->wiphy, "wl%d: %s: Bad channel %d\n",
4083                           wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec));
4084                 return;
4085         }
4086
4087         /* Switch bands if necessary */
4088         if (wlc->pub->_nbands > 1) {
4089                 bandunit = chspec_bandunit(chanspec);
4090                 if (wlc->band->bandunit != bandunit || wlc->bandinit_pending) {
4091                         switchband = true;
4092                         if (wlc->bandlocked) {
4093                                 wiphy_err(wlc->wiphy, "wl%d: %s: chspec %d "
4094                                           "band is locked!\n",
4095                                           wlc->pub->unit, __func__,
4096                                           CHSPEC_CHANNEL(chanspec));
4097                                 return;
4098                         }
4099                         /*
4100                          * should the setband call come after the
4101                          * brcms_b_chanspec() ? if the setband updates
4102                          * (brcms_c_bsinit) use low level calls to inspect and
4103                          * set state, the state inspected may be from the wrong
4104                          * band, or the following brcms_b_set_chanspec() may
4105                          * undo the work.
4106                          */
4107                         brcms_c_setband(wlc, bandunit);
4108                 }
4109         }
4110
4111         /* sync up phy/radio chanspec */
4112         brcms_c_set_phy_chanspec(wlc, chanspec);
4113
4114         /* init antenna selection */
4115         if (brcms_chspec_bw(old_chanspec) != brcms_chspec_bw(chanspec)) {
4116                 brcms_c_antsel_init(wlc->asi);
4117
4118                 /* Fix the hardware rateset based on bw.
4119                  * Mainly add MCS32 for 40Mhz, remove MCS 32 for 20Mhz
4120                  */
4121                 brcms_c_rateset_bw_mcs_filter(&wlc->band->hw_rateset,
4122                         wlc->band->mimo_cap_40 ? brcms_chspec_bw(chanspec) : 0);
4123         }
4124
4125         /* update some mac configuration since chanspec changed */
4126         brcms_c_ucode_mac_upd(wlc);
4127 }
4128
4129 u32 brcms_c_lowest_basic_rspec(struct brcms_c_info *wlc,
4130                                       struct brcms_c_rateset *rs)
4131 {
4132         u32 lowest_basic_rspec;
4133         uint i;
4134
4135         /* Use the lowest basic rate */
4136         lowest_basic_rspec = rs->rates[0] & BRCMS_RATE_MASK;
4137         for (i = 0; i < rs->count; i++) {
4138                 if (rs->rates[i] & BRCMS_RATE_FLAG) {
4139                         lowest_basic_rspec = rs->rates[i] & BRCMS_RATE_MASK;
4140                         break;
4141                 }
4142         }
4143
4144         /*
4145          * pick siso/cdd as default for OFDM (note no basic
4146          * rate MCSs are supported yet)
4147          */
4148         if (is_ofdm_rate(lowest_basic_rspec))
4149                 lowest_basic_rspec |= (wlc->stf->ss_opmode << RSPEC_STF_SHIFT);
4150
4151         return lowest_basic_rspec;
4152 }
4153
4154 /*
4155  * This function changes the phytxctl for beacon based on current
4156  * beacon ratespec AND txant setting as per this table:
4157  *  ratespec     CCK            ant = wlc->stf->txant
4158  *              OFDM            ant = 3
4159  */
4160 void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc,
4161                                        u32 bcn_rspec)
4162 {
4163         u16 phyctl;
4164         u16 phytxant = wlc->stf->phytxant;
4165         u16 mask = PHY_TXC_ANT_MASK;
4166
4167         /* for non-siso rates or default setting, use the available chains */
4168         if (BRCMS_PHY_11N_CAP(wlc->band))
4169                 phytxant = brcms_c_stf_phytxchain_sel(wlc, bcn_rspec);
4170
4171         phyctl = brcms_c_read_shm(wlc, M_BCN_PCTLWD);
4172         phyctl = (phyctl & ~mask) | phytxant;
4173         brcms_c_write_shm(wlc, M_BCN_PCTLWD, phyctl);
4174 }
4175
4176 /*
4177  * centralized protection config change function to simplify debugging, no
4178  * consistency checking this should be called only on changes to avoid overhead
4179  * in periodic function
4180  */
4181 void brcms_c_protection_upd(struct brcms_c_info *wlc, uint idx, int val)
4182 {
4183         BCMMSG(wlc->wiphy, "idx %d, val %d\n", idx, val);
4184
4185         switch (idx) {
4186         case BRCMS_PROT_G_SPEC:
4187                 wlc->protection->_g = (bool) val;
4188                 break;
4189         case BRCMS_PROT_G_OVR:
4190                 wlc->protection->g_override = (s8) val;
4191                 break;
4192         case BRCMS_PROT_G_USER:
4193                 wlc->protection->gmode_user = (u8) val;
4194                 break;
4195         case BRCMS_PROT_OVERLAP:
4196                 wlc->protection->overlap = (s8) val;
4197                 break;
4198         case BRCMS_PROT_N_USER:
4199                 wlc->protection->nmode_user = (s8) val;
4200                 break;
4201         case BRCMS_PROT_N_CFG:
4202                 wlc->protection->n_cfg = (s8) val;
4203                 break;
4204         case BRCMS_PROT_N_CFG_OVR:
4205                 wlc->protection->n_cfg_override = (s8) val;
4206                 break;
4207         case BRCMS_PROT_N_NONGF:
4208                 wlc->protection->nongf = (bool) val;
4209                 break;
4210         case BRCMS_PROT_N_NONGF_OVR:
4211                 wlc->protection->nongf_override = (s8) val;
4212                 break;
4213         case BRCMS_PROT_N_PAM_OVR:
4214                 wlc->protection->n_pam_override = (s8) val;
4215                 break;
4216         case BRCMS_PROT_N_OBSS:
4217                 wlc->protection->n_obss = (bool) val;
4218                 break;
4219
4220         default:
4221                 break;
4222         }
4223
4224 }
4225
4226 static void brcms_c_ht_update_sgi_rx(struct brcms_c_info *wlc, int val)
4227 {
4228         if (wlc->pub->up) {
4229                 brcms_c_update_beacon(wlc);
4230                 brcms_c_update_probe_resp(wlc, true);
4231         }
4232 }
4233
4234 static void brcms_c_ht_update_ldpc(struct brcms_c_info *wlc, s8 val)
4235 {
4236         wlc->stf->ldpc = val;
4237
4238         if (wlc->pub->up) {
4239                 brcms_c_update_beacon(wlc);
4240                 brcms_c_update_probe_resp(wlc, true);
4241                 wlc_phy_ldpc_override_set(wlc->band->pi, (val ? true : false));
4242         }
4243 }
4244
4245 void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci,
4246                        const struct ieee80211_tx_queue_params *params,
4247                        bool suspend)
4248 {
4249         int i;
4250         struct shm_acparams acp_shm;
4251         u16 *shm_entry;
4252
4253         /* Only apply params if the core is out of reset and has clocks */
4254         if (!wlc->clk) {
4255                 wiphy_err(wlc->wiphy, "wl%d: %s : no-clock\n", wlc->pub->unit,
4256                           __func__);
4257                 return;
4258         }
4259
4260         do {
4261                 memset((char *)&acp_shm, 0, sizeof(struct shm_acparams));
4262                 /* fill in shm ac params struct */
4263                 acp_shm.txop = params->txop;
4264                 /* convert from units of 32us to us for ucode */
4265                 wlc->edcf_txop[aci & 0x3] = acp_shm.txop =
4266                     EDCF_TXOP2USEC(acp_shm.txop);
4267                 acp_shm.aifs = (params->aifs & EDCF_AIFSN_MASK);
4268
4269                 if (aci == AC_VI && acp_shm.txop == 0
4270                     && acp_shm.aifs < EDCF_AIFSN_MAX)
4271                         acp_shm.aifs++;
4272
4273                 if (acp_shm.aifs < EDCF_AIFSN_MIN
4274                     || acp_shm.aifs > EDCF_AIFSN_MAX) {
4275                         wiphy_err(wlc->wiphy, "wl%d: edcf_setparams: bad "
4276                                   "aifs %d\n", wlc->pub->unit, acp_shm.aifs);
4277                         continue;
4278                 }
4279
4280                 acp_shm.cwmin = params->cw_min;
4281                 acp_shm.cwmax = params->cw_max;
4282                 acp_shm.cwcur = acp_shm.cwmin;
4283                 acp_shm.bslots =
4284                     R_REG(&wlc->regs->tsf_random) & acp_shm.cwcur;
4285                 acp_shm.reggap = acp_shm.bslots + acp_shm.aifs;
4286                 /* Indicate the new params to the ucode */
4287                 acp_shm.status = brcms_c_read_shm(wlc, (M_EDCF_QINFO +
4288                                                   wme_ac2fifo[aci] *
4289                                                   M_EDCF_QLEN +
4290                                                   M_EDCF_STATUS_OFF));
4291                 acp_shm.status |= WME_STATUS_NEWAC;
4292
4293                 /* Fill in shm acparam table */
4294                 shm_entry = (u16 *) &acp_shm;
4295                 for (i = 0; i < (int)sizeof(struct shm_acparams); i += 2)
4296                         brcms_c_write_shm(wlc,
4297                                           M_EDCF_QINFO +
4298                                           wme_ac2fifo[aci] * M_EDCF_QLEN + i,
4299                                           *shm_entry++);
4300
4301         } while (0);
4302
4303         if (suspend)
4304                 brcms_c_suspend_mac_and_wait(wlc);
4305
4306         if (suspend)
4307                 brcms_c_enable_mac(wlc);
4308
4309 }
4310
4311 void brcms_c_edcf_setparams(struct brcms_c_info *wlc, bool suspend)
4312 {
4313         u16 aci;
4314         int i_ac;
4315         struct ieee80211_tx_queue_params txq_pars;
4316         static const struct edcf_acparam default_edcf_acparams[] = {
4317                  {EDCF_AC_BE_ACI_STA, EDCF_AC_BE_ECW_STA, EDCF_AC_BE_TXOP_STA},
4318                  {EDCF_AC_BK_ACI_STA, EDCF_AC_BK_ECW_STA, EDCF_AC_BK_TXOP_STA},
4319                  {EDCF_AC_VI_ACI_STA, EDCF_AC_VI_ECW_STA, EDCF_AC_VI_TXOP_STA},
4320                  {EDCF_AC_VO_ACI_STA, EDCF_AC_VO_ECW_STA, EDCF_AC_VO_TXOP_STA}
4321         }; /* ucode needs these parameters during its initialization */
4322         const struct edcf_acparam *edcf_acp = &default_edcf_acparams[0];
4323
4324         for (i_ac = 0; i_ac < AC_COUNT; i_ac++, edcf_acp++) {
4325                 /* find out which ac this set of params applies to */
4326                 aci = (edcf_acp->ACI & EDCF_ACI_MASK) >> EDCF_ACI_SHIFT;
4327
4328                 /* fill in shm ac params struct */
4329                 txq_pars.txop = edcf_acp->TXOP;
4330                 txq_pars.aifs = edcf_acp->ACI;
4331
4332                 /* CWmin = 2^(ECWmin) - 1 */
4333                 txq_pars.cw_min = EDCF_ECW2CW(edcf_acp->ECW & EDCF_ECWMIN_MASK);
4334                 /* CWmax = 2^(ECWmax) - 1 */
4335                 txq_pars.cw_max = EDCF_ECW2CW((edcf_acp->ECW & EDCF_ECWMAX_MASK)
4336                                             >> EDCF_ECWMAX_SHIFT);
4337                 brcms_c_wme_setparams(wlc, aci, &txq_pars, suspend);
4338         }
4339
4340         if (suspend)
4341                 brcms_c_suspend_mac_and_wait(wlc);
4342
4343         if (suspend)
4344                 brcms_c_enable_mac(wlc);
4345
4346 }
4347
4348 /* maintain LED behavior in down state */
4349 static void brcms_c_down_led_upd(struct brcms_c_info *wlc)
4350 {
4351         /*
4352          * maintain LEDs while in down state, turn on sbclk if
4353          * not available yet. Turn on sbclk if necessary
4354          */
4355         brcms_c_pllreq(wlc, true, BRCMS_PLLREQ_FLIP);
4356         brcms_c_pllreq(wlc, false, BRCMS_PLLREQ_FLIP);
4357 }
4358
4359 static bool brcms_c_radio_monitor_start(struct brcms_c_info *wlc)
4360 {
4361         /* Don't start the timer if HWRADIO feature is disabled */
4362         if (wlc->radio_monitor)
4363                 return true;
4364
4365         wlc->radio_monitor = true;
4366         brcms_c_pllreq(wlc, true, BRCMS_PLLREQ_RADIO_MON);
4367         brcms_add_timer(wlc->wl, wlc->radio_timer, TIMER_INTERVAL_RADIOCHK,
4368                         true);
4369         return true;
4370 }
4371
4372 void brcms_c_radio_disable(struct brcms_c_info *wlc)
4373 {
4374         if (!wlc->pub->up) {
4375                 brcms_c_down_led_upd(wlc);
4376                 return;
4377         }
4378
4379         brcms_c_radio_monitor_start(wlc);
4380         brcms_down(wlc->wl);
4381 }
4382
4383 static void brcms_c_radio_enable(struct brcms_c_info *wlc)
4384 {
4385         if (wlc->pub->up)
4386                 return;
4387
4388         if (brcms_deviceremoved(wlc))
4389                 return;
4390
4391         brcms_up(wlc->wl);
4392 }
4393
4394 bool brcms_c_radio_monitor_stop(struct brcms_c_info *wlc)
4395 {
4396         if (!wlc->radio_monitor)
4397                 return true;
4398
4399         wlc->radio_monitor = false;
4400         brcms_c_pllreq(wlc, false, BRCMS_PLLREQ_RADIO_MON);
4401         return brcms_del_timer(wlc->wl, wlc->radio_timer);
4402 }
4403
4404 /* read hwdisable state and propagate to wlc flag */
4405 static void brcms_c_radio_hwdisable_upd(struct brcms_c_info *wlc)
4406 {
4407         if (wlc->pub->hw_off)
4408                 return;
4409
4410         if (brcms_b_radio_read_hwdisabled(wlc->hw))
4411                 mboolset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE);
4412         else
4413                 mboolclr(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE);
4414 }
4415
4416 /*
4417  * centralized radio disable/enable function,
4418  * invoke radio enable/disable after updating hwradio status
4419  */
4420 static void brcms_c_radio_upd(struct brcms_c_info *wlc)
4421 {
4422         if (wlc->pub->radio_disabled)
4423                 brcms_c_radio_disable(wlc);
4424         else
4425                 brcms_c_radio_enable(wlc);
4426 }
4427
4428 /* update hwradio status and return it */
4429 bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc)
4430 {
4431         brcms_c_radio_hwdisable_upd(wlc);
4432
4433         return mboolisset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE) ?
4434                         true : false;
4435 }
4436
4437 /* periodical query hw radio button while driver is "down" */
4438 static void brcms_c_radio_timer(void *arg)
4439 {
4440         struct brcms_c_info *wlc = (struct brcms_c_info *) arg;
4441
4442         if (brcms_deviceremoved(wlc)) {
4443                 wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit,
4444                         __func__);
4445                 brcms_down(wlc->wl);
4446                 return;
4447         }
4448
4449         /* cap mpc off count */
4450         if (wlc->mpc_offcnt < BRCMS_MPC_MAX_DELAYCNT)
4451                 wlc->mpc_offcnt++;
4452
4453         brcms_c_radio_hwdisable_upd(wlc);
4454         brcms_c_radio_upd(wlc);
4455 }
4456
4457 /* common low-level watchdog code */
4458 static void brcms_b_watchdog(void *arg)
4459 {
4460         struct brcms_c_info *wlc = (struct brcms_c_info *) arg;
4461         struct brcms_hardware *wlc_hw = wlc->hw;
4462
4463         BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
4464
4465         if (!wlc_hw->up)
4466                 return;
4467
4468         /* increment second count */
4469         wlc_hw->now++;
4470
4471         /* Check for FIFO error interrupts */
4472         brcms_b_fifoerrors(wlc_hw);
4473
4474         /* make sure RX dma has buffers */
4475         dma_rxfill(wlc->hw->di[RX_FIFO]);
4476
4477         wlc_phy_watchdog(wlc_hw->band->pi);
4478 }
4479
4480 /* common watchdog code */
4481 static void brcms_c_watchdog(void *arg)
4482 {
4483         struct brcms_c_info *wlc = (struct brcms_c_info *) arg;
4484
4485         BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
4486
4487         if (!wlc->pub->up)
4488                 return;
4489
4490         if (brcms_deviceremoved(wlc)) {
4491                 wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit,
4492                           __func__);
4493                 brcms_down(wlc->wl);
4494                 return;
4495         }
4496
4497         /* increment second count */
4498         wlc->pub->now++;
4499
4500         /* delay radio disable */
4501         if (wlc->mpc_delay_off) {
4502                 if (--wlc->mpc_delay_off == 0) {
4503                         mboolset(wlc->pub->radio_disabled,
4504                                  WL_RADIO_MPC_DISABLE);
4505                         if (wlc->mpc && brcms_c_ismpc(wlc))
4506                                 wlc->mpc_offcnt = 0;
4507                 }
4508         }
4509
4510         /* mpc sync */
4511         brcms_c_radio_mpc_upd(wlc);
4512         /* radio sync: sw/hw/mpc --> radio_disable/radio_enable */
4513         brcms_c_radio_hwdisable_upd(wlc);
4514         brcms_c_radio_upd(wlc);
4515         /* if radio is disable, driver may be down, quit here */
4516         if (wlc->pub->radio_disabled)
4517                 return;
4518
4519         brcms_b_watchdog(wlc);
4520
4521         /*
4522          * occasionally sample mac stat counters to
4523          * detect 16-bit counter wrap
4524          */
4525         if ((wlc->pub->now % SW_TIMER_MAC_STAT_UPD) == 0)
4526                 brcms_c_statsupd(wlc);
4527
4528         if (BRCMS_ISNPHY(wlc->band) &&
4529             ((wlc->pub->now - wlc->tempsense_lasttime) >=
4530              BRCMS_TEMPSENSE_PERIOD)) {
4531                 wlc->tempsense_lasttime = wlc->pub->now;
4532                 brcms_c_tempsense_upd(wlc);
4533         }
4534 }
4535
4536 static void brcms_c_watchdog_by_timer(void *arg)
4537 {
4538         brcms_c_watchdog(arg);
4539 }
4540
4541 bool brcms_c_timers_init(struct brcms_c_info *wlc, int unit)
4542 {
4543         wlc->wdtimer = brcms_init_timer(wlc->wl, brcms_c_watchdog_by_timer,
4544                 wlc, "watchdog");
4545         if (!wlc->wdtimer) {
4546                 wiphy_err(wlc->wiphy, "wl%d:  wl_init_timer for wdtimer "
4547                           "failed\n", unit);
4548                 goto fail;
4549         }
4550
4551         wlc->radio_timer = brcms_init_timer(wlc->wl, brcms_c_radio_timer,
4552                 wlc, "radio");
4553         if (!wlc->radio_timer) {
4554                 wiphy_err(wlc->wiphy, "wl%d:  wl_init_timer for radio_timer "
4555                           "failed\n", unit);
4556                 goto fail;
4557         }
4558
4559         return true;
4560
4561  fail:
4562         return false;
4563 }
4564
4565 /*
4566  * Initialize brcms_c_info default values ...
4567  * may get overrides later in this function
4568  */
4569 void brcms_c_info_init(struct brcms_c_info *wlc, int unit)
4570 {
4571         int i;
4572
4573         /* Save our copy of the chanspec */
4574         wlc->chanspec = ch20mhz_chspec(1);
4575
4576         /* various 802.11g modes */
4577         wlc->shortslot = false;
4578         wlc->shortslot_override = BRCMS_SHORTSLOT_AUTO;
4579
4580         brcms_c_protection_upd(wlc, BRCMS_PROT_G_OVR, BRCMS_PROTECTION_AUTO);
4581         brcms_c_protection_upd(wlc, BRCMS_PROT_G_SPEC, false);
4582
4583         brcms_c_protection_upd(wlc, BRCMS_PROT_N_CFG_OVR,
4584                                BRCMS_PROTECTION_AUTO);
4585         brcms_c_protection_upd(wlc, BRCMS_PROT_N_CFG, BRCMS_N_PROTECTION_OFF);
4586         brcms_c_protection_upd(wlc, BRCMS_PROT_N_NONGF_OVR,
4587                                BRCMS_PROTECTION_AUTO);
4588         brcms_c_protection_upd(wlc, BRCMS_PROT_N_NONGF, false);
4589         brcms_c_protection_upd(wlc, BRCMS_PROT_N_PAM_OVR, AUTO);
4590
4591         brcms_c_protection_upd(wlc, BRCMS_PROT_OVERLAP,
4592                                BRCMS_PROTECTION_CTL_OVERLAP);
4593
4594         /* 802.11g draft 4.0 NonERP elt advertisement */
4595         wlc->include_legacy_erp = true;
4596
4597         wlc->stf->ant_rx_ovr = ANT_RX_DIV_DEF;
4598         wlc->stf->txant = ANT_TX_DEF;
4599
4600         wlc->prb_resp_timeout = BRCMS_PRB_RESP_TIMEOUT;
4601
4602         wlc->usr_fragthresh = DOT11_DEFAULT_FRAG_LEN;
4603         for (i = 0; i < NFIFO; i++)
4604                 wlc->fragthresh[i] = DOT11_DEFAULT_FRAG_LEN;
4605         wlc->RTSThresh = DOT11_DEFAULT_RTS_LEN;
4606
4607         /* default rate fallback retry limits */
4608         wlc->SFBL = RETRY_SHORT_FB;
4609         wlc->LFBL = RETRY_LONG_FB;
4610
4611         /* default mac retry limits */
4612         wlc->SRL = RETRY_SHORT_DEF;
4613         wlc->LRL = RETRY_LONG_DEF;
4614
4615         /* WME QoS mode is Auto by default */
4616         wlc->pub->_ampdu = AMPDU_AGG_HOST;
4617         wlc->pub->bcmerror = 0;
4618
4619         /* initialize mpc delay */
4620         wlc->mpc_delay_off = wlc->mpc_dlycnt = BRCMS_MPC_MIN_DELAYCNT;
4621 }
4622
4623 static bool brcms_c_state_bmac_sync(struct brcms_c_info *wlc)
4624 {
4625         struct brcms_b_state state_bmac = {0};
4626
4627         if (brcms_b_state_get(wlc->hw, &state_bmac) != 0)
4628                 return false;
4629
4630         wlc->machwcap = state_bmac.machwcap;
4631         brcms_c_protection_upd(wlc, BRCMS_PROT_N_PAM_OVR,
4632                            (s8) state_bmac.preamble_ovr);
4633
4634         return true;
4635 }
4636
4637 static uint brcms_c_attach_module(struct brcms_c_info *wlc)
4638 {
4639         uint err = 0;
4640         uint unit;
4641         unit = wlc->pub->unit;
4642
4643         wlc->asi = brcms_c_antsel_attach(wlc);
4644         if (wlc->asi == NULL) {
4645                 wiphy_err(wlc->wiphy, "wl%d: attach: antsel_attach "
4646                           "failed\n", unit);
4647                 err = 44;
4648                 goto fail;
4649         }
4650
4651         wlc->ampdu = brcms_c_ampdu_attach(wlc);
4652         if (wlc->ampdu == NULL) {
4653                 wiphy_err(wlc->wiphy, "wl%d: attach: ampdu_attach "
4654                           "failed\n", unit);
4655                 err = 50;
4656                 goto fail;
4657         }
4658
4659         if ((brcms_c_stf_attach(wlc) != 0)) {
4660                 wiphy_err(wlc->wiphy, "wl%d: attach: stf_attach "
4661                           "failed\n", unit);
4662                 err = 68;
4663                 goto fail;
4664         }
4665  fail:
4666         return err;
4667 }
4668
4669 struct brcms_pub *brcms_c_pub(struct brcms_c_info *wlc)
4670 {
4671         return wlc->pub;
4672 }
4673
4674 /* low level attach
4675  *    run backplane attach, init nvram
4676  *    run phy attach
4677  *    initialize software state for each core and band
4678  *    put the whole chip in reset(driver down state), no clock
4679  */
4680 static int brcms_b_attach(struct brcms_c_info *wlc, u16 vendor, u16 device,
4681                           uint unit, bool piomode, void __iomem *regsva,
4682                           struct pci_dev *btparam)
4683 {
4684         struct brcms_hardware *wlc_hw;
4685         struct d11regs *regs;
4686         char *macaddr = NULL;
4687         char *vars;
4688         uint err = 0;
4689         uint j;
4690         bool wme = false;
4691         struct shared_phy_params sha_params;
4692         struct wiphy *wiphy = wlc->wiphy;
4693         char *var;
4694         unsigned long res;
4695
4696         BCMMSG(wlc->wiphy, "wl%d: vendor 0x%x device 0x%x\n", unit, vendor,
4697                 device);
4698
4699         wme = true;
4700
4701         wlc_hw = wlc->hw;
4702         wlc_hw->wlc = wlc;
4703         wlc_hw->unit = unit;
4704         wlc_hw->band = wlc_hw->bandstate[0];
4705         wlc_hw->_piomode = piomode;
4706
4707         /* populate struct brcms_hardware with default values  */
4708         brcms_b_info_init(wlc_hw);
4709
4710         /*
4711          * Do the hardware portion of the attach. Also initialize software
4712          * state that depends on the particular hardware we are running.
4713          */
4714         wlc_hw->sih = ai_attach(regsva, btparam,
4715                                 &wlc_hw->vars, &wlc_hw->vars_size);
4716         if (wlc_hw->sih == NULL) {
4717                 wiphy_err(wiphy, "wl%d: brcms_b_attach: si_attach failed\n",
4718                           unit);
4719                 err = 11;
4720                 goto fail;
4721         }
4722         vars = wlc_hw->vars;
4723
4724         /*
4725          * Get vendid/devid nvram overwrites, which could be different
4726          * than those the BIOS recognizes for devices on PCMCIA_BUS,
4727          * SDIO_BUS, and SROMless devices on PCI_BUS.
4728          */
4729         var = getvar(vars, "vendid");
4730         if (var && !kstrtoul(var, 0, &res)) {
4731                 vendor = (u16)res;
4732                 wiphy_err(wiphy, "Overriding vendor id = 0x%x\n",
4733                           vendor);
4734         }
4735         var = getvar(vars, "devid");
4736         if (var && !kstrtoul(var, 0, &res)) {
4737                 u16 devid = (u16)res;
4738                 if (devid != 0xffff) {
4739                         device = devid;
4740                         wiphy_err(wiphy, "Overriding device id = 0x%x"
4741                                   "\n", device);
4742                 }
4743         }
4744
4745         /* verify again the device is supported */
4746         if (!brcms_c_chipmatch(vendor, device)) {
4747                 wiphy_err(wiphy, "wl%d: brcms_b_attach: Unsupported "
4748                         "vendor/device (0x%x/0x%x)\n",
4749                          unit, vendor, device);
4750                 err = 12;
4751                 goto fail;
4752         }
4753
4754         wlc_hw->vendorid = vendor;
4755         wlc_hw->deviceid = device;
4756
4757         /* set bar0 window to point at D11 core */
4758         wlc_hw->regs = (struct d11regs *) ai_setcore(wlc_hw->sih, D11_CORE_ID,
4759                                                      0);
4760         wlc_hw->corerev = ai_corerev(wlc_hw->sih);
4761
4762         regs = wlc_hw->regs;
4763
4764         wlc->regs = wlc_hw->regs;
4765
4766         /* validate chip, chiprev and corerev */
4767         if (!brcms_c_isgoodchip(wlc_hw)) {
4768                 err = 13;
4769                 goto fail;
4770         }
4771
4772         /* initialize power control registers */
4773         ai_clkctl_init(wlc_hw->sih);
4774
4775         /* request fastclock and force fastclock for the rest of attach
4776          * bring the d11 core out of reset.
4777          *   For PMU chips, the first wlc_clkctl_clk is no-op since core-clk
4778          *   is still false; But it will be called again inside wlc_corereset,
4779          *   after d11 is out of reset.
4780          */
4781         brcms_b_clkctl_clk(wlc_hw, CLK_FAST);
4782         brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS);
4783
4784         if (!brcms_b_validate_chip_access(wlc_hw)) {
4785                 wiphy_err(wiphy, "wl%d: brcms_b_attach: validate_chip_access "
4786                         "failed\n", unit);
4787                 err = 14;
4788                 goto fail;
4789         }
4790
4791         /* get the board rev, used just below */
4792         j = getintvar(vars, "boardrev");
4793         /* promote srom boardrev of 0xFF to 1 */
4794         if (j == BOARDREV_PROMOTABLE)
4795                 j = BOARDREV_PROMOTED;
4796         wlc_hw->boardrev = (u16) j;
4797         if (!brcms_c_validboardtype(wlc_hw)) {
4798                 wiphy_err(wiphy, "wl%d: brcms_b_attach: Unsupported Broadcom "
4799                         "board type (0x%x)" " or revision level (0x%x)\n",
4800                          unit, wlc_hw->sih->boardtype, wlc_hw->boardrev);
4801                 err = 15;
4802                 goto fail;
4803         }
4804         wlc_hw->sromrev = (u8) getintvar(vars, "sromrev");
4805         wlc_hw->boardflags = (u32) getintvar(vars, "boardflags");
4806         wlc_hw->boardflags2 = (u32) getintvar(vars, "boardflags2");
4807
4808         if (wlc_hw->boardflags & BFL_NOPLLDOWN)
4809                 brcms_b_pllreq(wlc_hw, true, BRCMS_PLLREQ_SHARED);
4810
4811         /* check device id(srom, nvram etc.) to set bands */
4812         if (wlc_hw->deviceid == BCM43224_D11N_ID ||
4813             wlc_hw->deviceid == BCM43224_D11N_ID_VEN1)
4814                 /* Dualband boards */
4815                 wlc_hw->_nbands = 2;
4816         else
4817                 wlc_hw->_nbands = 1;
4818
4819         if ((wlc_hw->sih->chip == BCM43225_CHIP_ID))
4820                 wlc_hw->_nbands = 1;
4821
4822         /* BMAC_NOTE: remove init of pub values when brcms_c_attach()
4823          * unconditionally does the init of these values
4824          */
4825         wlc->vendorid = wlc_hw->vendorid;
4826         wlc->deviceid = wlc_hw->deviceid;
4827         wlc->pub->sih = wlc_hw->sih;
4828         wlc->pub->corerev = wlc_hw->corerev;
4829         wlc->pub->sromrev = wlc_hw->sromrev;
4830         wlc->pub->boardrev = wlc_hw->boardrev;
4831         wlc->pub->boardflags = wlc_hw->boardflags;
4832         wlc->pub->boardflags2 = wlc_hw->boardflags2;
4833         wlc->pub->_nbands = wlc_hw->_nbands;
4834
4835         wlc_hw->physhim = wlc_phy_shim_attach(wlc_hw, wlc->wl, wlc);
4836
4837         if (wlc_hw->physhim == NULL) {
4838                 wiphy_err(wiphy, "wl%d: brcms_b_attach: wlc_phy_shim_attach "
4839                         "failed\n", unit);
4840                 err = 25;
4841                 goto fail;
4842         }
4843
4844         /* pass all the parameters to wlc_phy_shared_attach in one struct */
4845         sha_params.sih = wlc_hw->sih;
4846         sha_params.physhim = wlc_hw->physhim;
4847         sha_params.unit = unit;
4848         sha_params.corerev = wlc_hw->corerev;
4849         sha_params.vars = vars;
4850         sha_params.vid = wlc_hw->vendorid;
4851         sha_params.did = wlc_hw->deviceid;
4852         sha_params.chip = wlc_hw->sih->chip;
4853         sha_params.chiprev = wlc_hw->sih->chiprev;
4854         sha_params.chippkg = wlc_hw->sih->chippkg;
4855         sha_params.sromrev = wlc_hw->sromrev;
4856         sha_params.boardtype = wlc_hw->sih->boardtype;
4857         sha_params.boardrev = wlc_hw->boardrev;
4858         sha_params.boardvendor = wlc_hw->sih->boardvendor;
4859         sha_params.boardflags = wlc_hw->boardflags;
4860         sha_params.boardflags2 = wlc_hw->boardflags2;
4861         sha_params.buscorerev = wlc_hw->sih->buscorerev;
4862
4863         /* alloc and save pointer to shared phy state area */
4864         wlc_hw->phy_sh = wlc_phy_shared_attach(&sha_params);
4865         if (!wlc_hw->phy_sh) {
4866                 err = 16;
4867                 goto fail;
4868         }
4869
4870         /* initialize software state for each core and band */
4871         for (j = 0; j < wlc_hw->_nbands; j++) {
4872                 /*
4873                  * band0 is always 2.4Ghz
4874                  * band1, if present, is 5Ghz
4875                  */
4876
4877                 brcms_c_setxband(wlc_hw, j);
4878
4879                 wlc_hw->band->bandunit = j;
4880                 wlc_hw->band->bandtype = j ? BRCM_BAND_5G : BRCM_BAND_2G;
4881                 wlc->band->bandunit = j;
4882                 wlc->band->bandtype = j ? BRCM_BAND_5G : BRCM_BAND_2G;
4883                 wlc->core->coreidx = ai_coreidx(wlc_hw->sih);
4884
4885                 wlc_hw->machwcap = R_REG(&regs->machwcap);
4886                 wlc_hw->machwcap_backup = wlc_hw->machwcap;
4887
4888                 /* init tx fifo size */
4889                 wlc_hw->xmtfifo_sz =
4890                     xmtfifo_sz[(wlc_hw->corerev - XMTFIFOTBL_STARTREV)];
4891
4892                 /* Get a phy for this band */
4893                 wlc_hw->band->pi =
4894                         wlc_phy_attach(wlc_hw->phy_sh, regs,
4895                                        brcms_b_bandtype(wlc_hw), vars,
4896                                        wlc->wiphy);
4897                 if (wlc_hw->band->pi == NULL) {
4898                         wiphy_err(wiphy, "wl%d: brcms_b_attach: wlc_phy_"
4899                                   "attach failed\n", unit);
4900                         err = 17;
4901                         goto fail;
4902                 }
4903
4904                 wlc_phy_machwcap_set(wlc_hw->band->pi, wlc_hw->machwcap);
4905
4906                 wlc_phy_get_phyversion(wlc_hw->band->pi, &wlc_hw->band->phytype,
4907                                        &wlc_hw->band->phyrev,
4908                                        &wlc_hw->band->radioid,
4909                                        &wlc_hw->band->radiorev);
4910                 wlc_hw->band->abgphy_encore =
4911                     wlc_phy_get_encore(wlc_hw->band->pi);
4912                 wlc->band->abgphy_encore = wlc_phy_get_encore(wlc_hw->band->pi);
4913                 wlc_hw->band->core_flags =
4914                     wlc_phy_get_coreflags(wlc_hw->band->pi);
4915
4916                 /* verify good phy_type & supported phy revision */
4917                 if (BRCMS_ISNPHY(wlc_hw->band)) {
4918                         if (NCONF_HAS(wlc_hw->band->phyrev))
4919                                 goto good_phy;
4920                         else
4921                                 goto bad_phy;
4922                 } else if (BRCMS_ISLCNPHY(wlc_hw->band)) {
4923                         if (LCNCONF_HAS(wlc_hw->band->phyrev))
4924                                 goto good_phy;
4925                         else
4926                                 goto bad_phy;
4927                 } else {
4928  bad_phy:
4929                         wiphy_err(wiphy, "wl%d: brcms_b_attach: unsupported "
4930                                   "phy type/rev (%d/%d)\n", unit,
4931                                   wlc_hw->band->phytype, wlc_hw->band->phyrev);
4932                         err = 18;
4933                         goto fail;
4934                 }
4935
4936  good_phy:
4937                 /*
4938                  * BMAC_NOTE: wlc->band->pi should not be set below and should
4939                  * be done in the high level attach. However we can not make
4940                  * that change until all low level access is changed to
4941                  * wlc_hw->band->pi. Instead do the wlc->band->pi init below,
4942                  * keeping wlc_hw->band->pi as well for incremental update of
4943                  * low level fns, and cut over low only init when all fns
4944                  * updated.
4945                  */
4946                 wlc->band->pi = wlc_hw->band->pi;
4947                 wlc->band->phytype = wlc_hw->band->phytype;
4948                 wlc->band->phyrev = wlc_hw->band->phyrev;
4949                 wlc->band->radioid = wlc_hw->band->radioid;
4950                 wlc->band->radiorev = wlc_hw->band->radiorev;
4951
4952                 /* default contention windows size limits */
4953                 wlc_hw->band->CWmin = APHY_CWMIN;
4954                 wlc_hw->band->CWmax = PHY_CWMAX;
4955
4956                 if (!brcms_b_attach_dmapio(wlc, j, wme)) {
4957                         err = 19;
4958                         goto fail;
4959                 }
4960         }
4961
4962         /* disable core to match driver "down" state */
4963         brcms_c_coredisable(wlc_hw);
4964
4965         /* Match driver "down" state */
4966         ai_pci_down(wlc_hw->sih);
4967
4968         /* register sb interrupt callback functions */
4969         ai_register_intr_callback(wlc_hw->sih, (void *)brcms_c_wlintrsoff,
4970                                   (void *)brcms_c_wlintrsrestore, NULL, wlc);
4971
4972         /* turn off pll and xtal to match driver "down" state */
4973         brcms_b_xtal(wlc_hw, OFF);
4974
4975         /* *******************************************************************
4976          * The hardware is in the DOWN state at this point. D11 core
4977          * or cores are in reset with clocks off, and the board PLLs
4978          * are off if possible.
4979          *
4980          * Beyond this point, wlc->sbclk == false and chip registers
4981          * should not be touched.
4982          *********************************************************************
4983          */
4984
4985         /* init etheraddr state variables */
4986         macaddr = brcms_c_get_macaddr(wlc_hw);
4987         if (macaddr == NULL) {
4988                 wiphy_err(wiphy, "wl%d: brcms_b_attach: macaddr not found\n",
4989                           unit);
4990                 err = 21;
4991                 goto fail;
4992         }
4993         if (!mac_pton(macaddr, wlc_hw->etheraddr) ||
4994             is_broadcast_ether_addr(wlc_hw->etheraddr) ||
4995             is_zero_ether_addr(wlc_hw->etheraddr)) {
4996                 wiphy_err(wiphy, "wl%d: brcms_b_attach: bad macaddr %s\n",
4997                           unit, macaddr);
4998                 err = 22;
4999                 goto fail;
5000         }
5001
5002         BCMMSG(wlc->wiphy,
5003                  "deviceid 0x%x nbands %d board 0x%x macaddr: %s\n",
5004                  wlc_hw->deviceid, wlc_hw->_nbands,
5005                  wlc_hw->sih->boardtype, macaddr);
5006
5007         return err;
5008
5009  fail:
5010         wiphy_err(wiphy, "wl%d: brcms_b_attach: failed with err %d\n", unit,
5011                   err);
5012         return err;
5013 }
5014
5015 static void brcms_c_attach_antgain_init(struct brcms_c_info *wlc)
5016 {
5017         uint unit;
5018         unit = wlc->pub->unit;
5019
5020         if ((wlc->band->antgain == -1) && (wlc->pub->sromrev == 1)) {
5021                 /* default antenna gain for srom rev 1 is 2 dBm (8 qdbm) */
5022                 wlc->band->antgain = 8;
5023         } else if (wlc->band->antgain == -1) {
5024                 wiphy_err(wlc->wiphy, "wl%d: %s: Invalid antennas available in"
5025                           " srom, using 2dB\n", unit, __func__);
5026                 wlc->band->antgain = 8;
5027         } else {
5028                 s8 gain, fract;
5029                 /* Older sroms specified gain in whole dbm only.  In order
5030                  * be able to specify qdbm granularity and remain backward
5031                  * compatible the whole dbms are now encoded in only
5032                  * low 6 bits and remaining qdbms are encoded in the hi 2 bits.
5033                  * 6 bit signed number ranges from -32 - 31.
5034                  *
5035                  * Examples:
5036                  * 0x1 = 1 db,
5037                  * 0xc1 = 1.75 db (1 + 3 quarters),
5038                  * 0x3f = -1 (-1 + 0 quarters),
5039                  * 0x7f = -.75 (-1 + 1 quarters) = -3 qdbm.
5040                  * 0xbf = -.50 (-1 + 2 quarters) = -2 qdbm.
5041                  */
5042                 gain = wlc->band->antgain & 0x3f;
5043                 gain <<= 2;     /* Sign extend */
5044                 gain >>= 2;
5045                 fract = (wlc->band->antgain & 0xc0) >> 6;
5046                 wlc->band->antgain = 4 * gain + fract;
5047         }
5048 }
5049
5050 static bool brcms_c_attach_stf_ant_init(struct brcms_c_info *wlc)
5051 {
5052         int aa;
5053         uint unit;
5054         char *vars;
5055         int bandtype;
5056
5057         unit = wlc->pub->unit;
5058         vars = wlc->pub->vars;
5059         bandtype = wlc->band->bandtype;
5060
5061         /* get antennas available */
5062         aa = (s8) getintvar(vars, bandtype == BRCM_BAND_5G ? "aa5g" : "aa2g");
5063         if (aa == 0)
5064                 aa = (s8) getintvar(vars,
5065                                     bandtype == BRCM_BAND_5G ? "aa1" : "aa0");
5066         if ((aa < 1) || (aa > 15)) {
5067                 wiphy_err(wlc->wiphy, "wl%d: %s: Invalid antennas available in"
5068                           " srom (0x%x), using 3\n", unit, __func__, aa);
5069                 aa = 3;
5070         }
5071
5072         /* reset the defaults if we have a single antenna */
5073         if (aa == 1) {
5074                 wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_0;
5075                 wlc->stf->txant = ANT_TX_FORCE_0;
5076         } else if (aa == 2) {
5077                 wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_1;
5078                 wlc->stf->txant = ANT_TX_FORCE_1;
5079         } else {
5080         }
5081
5082         /* Compute Antenna Gain */
5083         wlc->band->antgain =
5084             (s8) getintvar(vars, bandtype == BRCM_BAND_5G ? "ag1" : "ag0");
5085         brcms_c_attach_antgain_init(wlc);
5086
5087         return true;
5088 }
5089
5090 static void brcms_c_bss_default_init(struct brcms_c_info *wlc)
5091 {
5092         u16 chanspec;
5093         struct brcms_band *band;
5094         struct brcms_bss_info *bi = wlc->default_bss;
5095
5096         /* init default and target BSS with some sane initial values */
5097         memset((char *)(bi), 0, sizeof(struct brcms_bss_info));
5098         bi->beacon_period = BEACON_INTERVAL_DEFAULT;
5099
5100         /* fill the default channel as the first valid channel
5101          * starting from the 2G channels
5102          */
5103         chanspec = ch20mhz_chspec(1);
5104         wlc->home_chanspec = bi->chanspec = chanspec;
5105
5106         /* find the band of our default channel */
5107         band = wlc->band;
5108         if (wlc->pub->_nbands > 1 &&
5109             band->bandunit != chspec_bandunit(chanspec))
5110                 band = wlc->bandstate[OTHERBANDUNIT(wlc)];
5111
5112         /* init bss rates to the band specific default rate set */
5113         brcms_c_rateset_default(&bi->rateset, NULL, band->phytype,
5114                 band->bandtype, false, BRCMS_RATE_MASK_FULL,
5115                 (bool) (wlc->pub->_n_enab & SUPPORT_11N),
5116                 brcms_chspec_bw(chanspec), wlc->stf->txstreams);
5117
5118         if (wlc->pub->_n_enab & SUPPORT_11N)
5119                 bi->flags |= BRCMS_BSS_HT;
5120 }
5121
5122 static struct brcms_txq_info *brcms_c_txq_alloc(struct brcms_c_info *wlc)
5123 {
5124         struct brcms_txq_info *qi, *p;
5125
5126         qi = kzalloc(sizeof(struct brcms_txq_info), GFP_ATOMIC);
5127         if (qi != NULL) {
5128                 /*
5129                  * Have enough room for control packets along with HI watermark
5130                  * Also, add room to txq for total psq packets if all the SCBs
5131                  * leave PS mode. The watermark for flowcontrol to OS packets
5132                  * will remain the same
5133                  */
5134                 brcmu_pktq_init(&qi->q, BRCMS_PREC_COUNT,
5135                           2 * BRCMS_DATAHIWAT + PKTQ_LEN_DEFAULT);
5136
5137                 /* add this queue to the the global list */
5138                 p = wlc->tx_queues;
5139                 if (p == NULL) {
5140                         wlc->tx_queues = qi;
5141                 } else {
5142                         while (p->next != NULL)
5143                                 p = p->next;
5144                         p->next = qi;
5145                 }
5146         }
5147         return qi;
5148 }
5149
5150 static void brcms_c_txq_free(struct brcms_c_info *wlc,
5151                              struct brcms_txq_info *qi)
5152 {
5153         struct brcms_txq_info *p;
5154
5155         if (qi == NULL)
5156                 return;
5157
5158         /* remove the queue from the linked list */
5159         p = wlc->tx_queues;
5160         if (p == qi)
5161                 wlc->tx_queues = p->next;
5162         else {
5163                 while (p != NULL && p->next != qi)
5164                         p = p->next;
5165                 if (p != NULL)
5166                         p->next = p->next->next;
5167         }
5168
5169         kfree(qi);
5170 }
5171
5172 static void brcms_c_update_mimo_band_bwcap(struct brcms_c_info *wlc, u8 bwcap)
5173 {
5174         uint i;
5175         struct brcms_band *band;
5176
5177         for (i = 0; i < wlc->pub->_nbands; i++) {
5178                 band = wlc->bandstate[i];
5179                 if (band->bandtype == BRCM_BAND_5G) {
5180                         if ((bwcap == BRCMS_N_BW_40ALL)
5181                             || (bwcap == BRCMS_N_BW_20IN2G_40IN5G))
5182                                 band->mimo_cap_40 = true;
5183                         else
5184                                 band->mimo_cap_40 = false;
5185                 } else {
5186                         if (bwcap == BRCMS_N_BW_40ALL)
5187                                 band->mimo_cap_40 = true;
5188                         else
5189                                 band->mimo_cap_40 = false;
5190                 }
5191         }
5192 }
5193
5194 /*
5195  * The common driver entry routine. Error codes should be unique
5196  */
5197 struct brcms_c_info *
5198 brcms_c_attach(struct brcms_info *wl, u16 vendor, u16 device, uint unit,
5199                bool piomode, void __iomem *regsva, struct pci_dev *btparam,
5200                uint *perr)
5201 {
5202         struct brcms_c_info *wlc;
5203         uint err = 0;
5204         uint i, j;
5205         struct brcms_pub *pub;
5206         uint n_disabled;
5207
5208         /* allocate struct brcms_c_info state and its substructures */
5209         wlc = (struct brcms_c_info *) brcms_c_attach_malloc(unit, &err, device);
5210         if (wlc == NULL)
5211                 goto fail;
5212         wlc->wiphy = wl->wiphy;
5213         pub = wlc->pub;
5214
5215 #if defined(BCMDBG)
5216         wlc_info_dbg = wlc;
5217 #endif
5218
5219         wlc->band = wlc->bandstate[0];
5220         wlc->core = wlc->corestate;
5221         wlc->wl = wl;
5222         pub->unit = unit;
5223         pub->_piomode = piomode;
5224         wlc->bandinit_pending = false;
5225
5226         /* populate struct brcms_c_info with default values  */
5227         brcms_c_info_init(wlc, unit);
5228
5229         /* update sta/ap related parameters */
5230         brcms_c_ap_upd(wlc);
5231
5232         /* 11n_disable nvram */
5233         n_disabled = getintvar(pub->vars, "11n_disable");
5234
5235         /*
5236          * low level attach steps(all hw accesses go
5237          * inside, no more in rest of the attach)
5238          */
5239         err = brcms_b_attach(wlc, vendor, device, unit, piomode, regsva,
5240                              btparam);
5241         if (err)
5242                 goto fail;
5243
5244         /*
5245          * for some states, due to different info pointer(e,g, wlc, wlc_hw) or
5246          * master/slave split, HIGH driver(both monolithic and HIGH_ONLY) needs
5247          * to sync states FROM BMAC portion driver
5248          */
5249         if (!brcms_c_state_bmac_sync(wlc)) {
5250                 err = 20;
5251                 goto fail;
5252         }
5253
5254         pub->phy_11ncapable = BRCMS_PHY_11N_CAP(wlc->band);
5255
5256         /* propagate *vars* from BMAC driver to high driver */
5257         brcms_b_copyfrom_vars(wlc->hw, &pub->vars, &wlc->vars_size);
5258
5259
5260         /* set maximum allowed duty cycle */
5261         wlc->tx_duty_cycle_ofdm =
5262             (u16) getintvar(pub->vars, "tx_duty_cycle_ofdm");
5263         wlc->tx_duty_cycle_cck =
5264             (u16) getintvar(pub->vars, "tx_duty_cycle_cck");
5265
5266         brcms_c_stf_phy_chain_calc(wlc);
5267
5268         /* txchain 1: txant 0, txchain 2: txant 1 */
5269         if (BRCMS_ISNPHY(wlc->band) && (wlc->stf->txstreams == 1))
5270                 wlc->stf->txant = wlc->stf->hw_txchain - 1;
5271
5272         /* push to BMAC driver */
5273         wlc_phy_stf_chain_init(wlc->band->pi, wlc->stf->hw_txchain,
5274                                wlc->stf->hw_rxchain);
5275
5276         /* pull up some info resulting from the low attach */
5277         for (i = 0; i < NFIFO; i++)
5278                 wlc->core->txavail[i] = wlc->hw->txavail[i];
5279
5280         brcms_b_hw_etheraddr(wlc->hw, wlc->perm_etheraddr);
5281
5282         memcpy(&pub->cur_etheraddr, &wlc->perm_etheraddr, ETH_ALEN);
5283
5284         for (j = 0; j < wlc->pub->_nbands; j++) {
5285                 wlc->band = wlc->bandstate[j];
5286
5287                 if (!brcms_c_attach_stf_ant_init(wlc)) {
5288                         err = 24;
5289                         goto fail;
5290                 }
5291
5292                 /* default contention windows size limits */
5293                 wlc->band->CWmin = APHY_CWMIN;
5294                 wlc->band->CWmax = PHY_CWMAX;
5295
5296                 /* init gmode value */
5297                 if (wlc->band->bandtype == BRCM_BAND_2G) {
5298                         wlc->band->gmode = GMODE_AUTO;
5299                         brcms_c_protection_upd(wlc, BRCMS_PROT_G_USER,
5300                                            wlc->band->gmode);
5301                 }
5302
5303                 /* init _n_enab supported mode */
5304                 if (BRCMS_PHY_11N_CAP(wlc->band)) {
5305                         if (n_disabled & WLFEATURE_DISABLE_11N) {
5306                                 pub->_n_enab = OFF;
5307                                 brcms_c_protection_upd(wlc, BRCMS_PROT_N_USER,
5308                                                        OFF);
5309                         } else {
5310                                 pub->_n_enab = SUPPORT_11N;
5311                                 brcms_c_protection_upd(wlc, BRCMS_PROT_N_USER,
5312                                                    ((pub->_n_enab ==
5313                                                      SUPPORT_11N) ? WL_11N_2x2 :
5314                                                     WL_11N_3x3));
5315                         }
5316                 }
5317
5318                 /* init per-band default rateset, depend on band->gmode */
5319                 brcms_default_rateset(wlc, &wlc->band->defrateset);
5320
5321                 /* fill in hw_rateset */
5322                 brcms_c_rateset_filter(&wlc->band->defrateset,
5323                                    &wlc->band->hw_rateset, false,
5324                                    BRCMS_RATES_CCK_OFDM, BRCMS_RATE_MASK,
5325                                    (bool) (wlc->pub->_n_enab & SUPPORT_11N));
5326         }
5327
5328         /*
5329          * update antenna config due to
5330          * wlc->stf->txant/txchain/ant_rx_ovr change
5331          */
5332         brcms_c_stf_phy_txant_upd(wlc);
5333
5334         /* attach each modules */
5335         err = brcms_c_attach_module(wlc);
5336         if (err != 0)
5337                 goto fail;
5338
5339         if (!brcms_c_timers_init(wlc, unit)) {
5340                 wiphy_err(wl->wiphy, "wl%d: %s: init_timer failed\n", unit,
5341                           __func__);
5342                 err = 32;
5343                 goto fail;
5344         }
5345
5346         /* depend on rateset, gmode */
5347         wlc->cmi = brcms_c_channel_mgr_attach(wlc);
5348         if (!wlc->cmi) {
5349                 wiphy_err(wl->wiphy, "wl%d: %s: channel_mgr_attach failed"
5350                           "\n", unit, __func__);
5351                 err = 33;
5352                 goto fail;
5353         }
5354
5355         /* init default when all parameters are ready, i.e. ->rateset */
5356         brcms_c_bss_default_init(wlc);
5357
5358         /*
5359          * Complete the wlc default state initializations..
5360          */
5361
5362         /* allocate our initial queue */
5363         wlc->pkt_queue = brcms_c_txq_alloc(wlc);
5364         if (wlc->pkt_queue == NULL) {
5365                 wiphy_err(wl->wiphy, "wl%d: %s: failed to malloc tx queue\n",
5366                           unit, __func__);
5367                 err = 100;
5368                 goto fail;
5369         }
5370
5371         wlc->bsscfg->_idx = 0;
5372         wlc->bsscfg->wlc = wlc;
5373
5374         wlc->mimoft = FT_HT;
5375         wlc->mimo_40txbw = AUTO;
5376         wlc->ofdm_40txbw = AUTO;
5377         wlc->cck_40txbw = AUTO;
5378         brcms_c_update_mimo_band_bwcap(wlc, BRCMS_N_BW_20IN2G_40IN5G);
5379
5380         /* Set default values of SGI */
5381         if (BRCMS_SGI_CAP_PHY(wlc)) {
5382                 brcms_c_ht_update_sgi_rx(wlc, (BRCMS_N_SGI_20 |
5383                                                BRCMS_N_SGI_40));
5384         } else if (BRCMS_ISSSLPNPHY(wlc->band)) {
5385                 brcms_c_ht_update_sgi_rx(wlc, (BRCMS_N_SGI_20 |
5386                                                BRCMS_N_SGI_40));
5387         } else {
5388                 brcms_c_ht_update_sgi_rx(wlc, 0);
5389         }
5390
5391         /* *******nvram 11n config overrides Start ********* */
5392
5393         if (n_disabled & WLFEATURE_DISABLE_11N_SGI_RX)
5394                 brcms_c_ht_update_sgi_rx(wlc, 0);
5395
5396         /* apply the stbc override from nvram conf */
5397         if (n_disabled & WLFEATURE_DISABLE_11N_STBC_TX) {
5398                 wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = OFF;
5399                 wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = OFF;
5400         }
5401         if (n_disabled & WLFEATURE_DISABLE_11N_STBC_RX)
5402                 brcms_c_stf_stbc_rx_set(wlc, HT_CAP_RX_STBC_NO);
5403
5404         /* initialize radio_mpc_disable according to wlc->mpc */
5405         brcms_c_radio_mpc_upd(wlc);
5406         brcms_b_antsel_set(wlc->hw, wlc->asi->antsel_avail);
5407
5408         if (perr)
5409                 *perr = 0;
5410
5411         return wlc;
5412
5413  fail:
5414         wiphy_err(wl->wiphy, "wl%d: %s: failed with err %d\n",
5415                   unit, __func__, err);
5416         if (wlc)
5417                 brcms_c_detach(wlc);
5418
5419         if (perr)
5420                 *perr = err;
5421         return NULL;
5422 }
5423
5424 static void brcms_c_timers_deinit(struct brcms_c_info *wlc)
5425 {
5426         /* free timer state */
5427         if (wlc->wdtimer) {
5428                 brcms_free_timer(wlc->wl, wlc->wdtimer);
5429                 wlc->wdtimer = NULL;
5430         }
5431         if (wlc->radio_timer) {
5432                 brcms_free_timer(wlc->wl, wlc->radio_timer);
5433                 wlc->radio_timer = NULL;
5434         }
5435 }
5436
5437 static void brcms_c_detach_module(struct brcms_c_info *wlc)
5438 {
5439         if (wlc->asi) {
5440                 brcms_c_antsel_detach(wlc->asi);
5441                 wlc->asi = NULL;
5442         }
5443
5444         if (wlc->ampdu) {
5445                 brcms_c_ampdu_detach(wlc->ampdu);
5446                 wlc->ampdu = NULL;
5447         }
5448
5449         brcms_c_stf_detach(wlc);
5450 }
5451
5452 /*
5453  * low level detach
5454  */
5455 static int brcms_b_detach(struct brcms_c_info *wlc)
5456 {
5457         uint i;
5458         struct brcms_hw_band *band;
5459         struct brcms_hardware *wlc_hw = wlc->hw;
5460         int callbacks;
5461
5462         callbacks = 0;
5463
5464         if (wlc_hw->sih) {
5465                 /*
5466                  * detach interrupt sync mechanism since interrupt is disabled
5467                  * and per-port interrupt object may has been freed. this must
5468                  * be done before sb core switch
5469                  */
5470                 ai_deregister_intr_callback(wlc_hw->sih);
5471                 ai_pci_sleep(wlc_hw->sih);
5472         }
5473
5474         brcms_b_detach_dmapio(wlc_hw);
5475
5476         band = wlc_hw->band;
5477         for (i = 0; i < wlc_hw->_nbands; i++) {
5478                 if (band->pi) {
5479                         /* Detach this band's phy */
5480                         wlc_phy_detach(band->pi);
5481                         band->pi = NULL;
5482                 }
5483                 band = wlc_hw->bandstate[OTHERBANDUNIT(wlc)];
5484         }
5485
5486         /* Free shared phy state */
5487         kfree(wlc_hw->phy_sh);
5488
5489         wlc_phy_shim_detach(wlc_hw->physhim);
5490
5491         /* free vars */
5492         kfree(wlc_hw->vars);
5493         wlc_hw->vars = NULL;
5494
5495         if (wlc_hw->sih) {
5496                 ai_detach(wlc_hw->sih);
5497                 wlc_hw->sih = NULL;
5498         }
5499
5500         return callbacks;
5501
5502 }
5503
5504 /*
5505  * Return a count of the number of driver callbacks still pending.
5506  *
5507  * General policy is that brcms_c_detach can only dealloc/free software states.
5508  * It can NOT touch hardware registers since the d11core may be in reset and
5509  * clock may not be available.
5510  * One exception is sb register access, which is possible if crystal is turned
5511  * on after "down" state, driver should avoid software timer with the exception
5512  * of radio_monitor.
5513  */
5514 uint brcms_c_detach(struct brcms_c_info *wlc)
5515 {
5516         uint callbacks = 0;
5517
5518         if (wlc == NULL)
5519                 return 0;
5520
5521         BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
5522
5523         callbacks += brcms_b_detach(wlc);
5524
5525         /* delete software timers */
5526         if (!brcms_c_radio_monitor_stop(wlc))
5527                 callbacks++;
5528
5529         brcms_c_channel_mgr_detach(wlc->cmi);
5530
5531         brcms_c_timers_deinit(wlc);
5532
5533         brcms_c_detach_module(wlc);
5534
5535
5536         while (wlc->tx_queues != NULL)
5537                 brcms_c_txq_free(wlc, wlc->tx_queues);
5538
5539         brcms_c_detach_mfree(wlc);
5540         return callbacks;
5541 }
5542
5543 /* update state that depends on the current value of "ap" */
5544 void brcms_c_ap_upd(struct brcms_c_info *wlc)
5545 {
5546         /* STA-BSS; short capable */
5547         wlc->PLCPHdr_override = BRCMS_PLCP_SHORT;
5548
5549         /* fixup mpc */
5550         wlc->mpc = true;
5551 }
5552
5553 /*
5554  * return true if Minimum Power Consumption should
5555  * be entered, false otherwise
5556  */
5557 bool brcms_c_is_non_delay_mpc(struct brcms_c_info *wlc)
5558 {
5559         return false;
5560 }
5561
5562 bool brcms_c_ismpc(struct brcms_c_info *wlc)
5563 {
5564         return (wlc->mpc_delay_off == 0) && (brcms_c_is_non_delay_mpc(wlc));
5565 }
5566
5567 void brcms_c_radio_mpc_upd(struct brcms_c_info *wlc)
5568 {
5569         bool mpc_radio, radio_state;
5570
5571         /*
5572          * Clear the WL_RADIO_MPC_DISABLE bit when mpc feature is disabled
5573          * in case the WL_RADIO_MPC_DISABLE bit was set. Stop the radio
5574          * monitor also when WL_RADIO_MPC_DISABLE is the only reason that
5575          * the radio is going down.
5576          */
5577         if (!wlc->mpc) {
5578                 if (!wlc->pub->radio_disabled)
5579                         return;
5580                 mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE);
5581                 brcms_c_radio_upd(wlc);
5582                 if (!wlc->pub->radio_disabled)
5583                         brcms_c_radio_monitor_stop(wlc);
5584                 return;
5585         }
5586
5587         /*
5588          * sync ismpc logic with WL_RADIO_MPC_DISABLE bit in
5589          * wlc->pub->radio_disabled to go ON, always call radio_upd
5590          * synchronously to go OFF, postpone radio_upd to later when
5591          * context is safe(e.g. watchdog)
5592          */
5593         radio_state =
5594             (mboolisset(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE) ? OFF :
5595              ON);
5596         mpc_radio = (brcms_c_ismpc(wlc) == true) ? OFF : ON;
5597
5598         if (radio_state == ON && mpc_radio == OFF)
5599                 wlc->mpc_delay_off = wlc->mpc_dlycnt;
5600         else if (radio_state == OFF && mpc_radio == ON) {
5601                 mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE);
5602                 brcms_c_radio_upd(wlc);
5603                 if (wlc->mpc_offcnt < BRCMS_MPC_THRESHOLD)
5604                         wlc->mpc_dlycnt = BRCMS_MPC_MAX_DELAYCNT;
5605                 else
5606                         wlc->mpc_dlycnt = BRCMS_MPC_MIN_DELAYCNT;
5607         }
5608         /*
5609          * Below logic is meant to capture the transition from mpc off
5610          * to mpc on for reasons other than wlc->mpc_delay_off keeping
5611          * the mpc off. In that case reset wlc->mpc_delay_off to
5612          * wlc->mpc_dlycnt, so that we restart the countdown of mpc_delay_off
5613          */
5614         if ((wlc->prev_non_delay_mpc == false) &&
5615             (brcms_c_is_non_delay_mpc(wlc) == true) && wlc->mpc_delay_off)
5616                 wlc->mpc_delay_off = wlc->mpc_dlycnt;
5617
5618         wlc->prev_non_delay_mpc = brcms_c_is_non_delay_mpc(wlc);
5619 }
5620 /* Initialize just the hardware when coming out of POR or S3/S5 system states */
5621 static void brcms_b_hw_up(struct brcms_hardware *wlc_hw)
5622 {
5623         if (wlc_hw->wlc->pub->hw_up)
5624                 return;
5625
5626         BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
5627
5628         /*
5629          * Enable pll and xtal, initialize the power control registers,
5630          * and force fastclock for the remainder of brcms_c_up().
5631          */
5632         brcms_b_xtal(wlc_hw, ON);
5633         ai_clkctl_init(wlc_hw->sih);
5634         brcms_b_clkctl_clk(wlc_hw, CLK_FAST);
5635
5636         ai_pci_fixcfg(wlc_hw->sih);
5637
5638         /*
5639          * AI chip doesn't restore bar0win2 on
5640          * hibernation/resume, need sw fixup
5641          */
5642         if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) ||
5643             (wlc_hw->sih->chip == BCM43225_CHIP_ID))
5644                 wlc_hw->regs = (struct d11regs *)
5645                                 ai_setcore(wlc_hw->sih, D11_CORE_ID, 0);
5646
5647         /*
5648          * Inform phy that a POR reset has occurred so
5649          * it does a complete phy init
5650          */
5651         wlc_phy_por_inform(wlc_hw->band->pi);
5652
5653         wlc_hw->ucode_loaded = false;
5654         wlc_hw->wlc->pub->hw_up = true;
5655
5656         if ((wlc_hw->boardflags & BFL_FEM)
5657             && (wlc_hw->sih->chip == BCM4313_CHIP_ID)) {
5658                 if (!
5659                     (wlc_hw->boardrev >= 0x1250
5660                      && (wlc_hw->boardflags & BFL_FEM_BT)))
5661                         ai_epa_4313war(wlc_hw->sih);
5662         }
5663 }
5664
5665 static int brcms_b_up_prep(struct brcms_hardware *wlc_hw)
5666 {
5667         uint coremask;
5668
5669         BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
5670
5671         /*
5672          * Enable pll and xtal, initialize the power control registers,
5673          * and force fastclock for the remainder of brcms_c_up().
5674          */
5675         brcms_b_xtal(wlc_hw, ON);
5676         ai_clkctl_init(wlc_hw->sih);
5677         brcms_b_clkctl_clk(wlc_hw, CLK_FAST);
5678
5679         /*
5680          * Configure pci/pcmcia here instead of in brcms_c_attach()
5681          * to allow mfg hotswap:  down, hotswap (chip power cycle), up.
5682          */
5683         coremask = (1 << wlc_hw->wlc->core->coreidx);
5684
5685         ai_pci_setup(wlc_hw->sih, coremask);
5686
5687         /*
5688          * Need to read the hwradio status here to cover the case where the
5689          * system is loaded with the hw radio disabled. We do not want to
5690          * bring the driver up in this case.
5691          */
5692         if (brcms_b_radio_read_hwdisabled(wlc_hw)) {
5693                 /* put SB PCI in down state again */
5694                 ai_pci_down(wlc_hw->sih);
5695                 brcms_b_xtal(wlc_hw, OFF);
5696                 return -ENOMEDIUM;
5697         }
5698
5699         ai_pci_up(wlc_hw->sih);
5700
5701         /* reset the d11 core */
5702         brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS);
5703
5704         return 0;
5705 }
5706
5707 static int brcms_b_up_finish(struct brcms_hardware *wlc_hw)
5708 {
5709         BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
5710
5711         wlc_hw->up = true;
5712         wlc_phy_hw_state_upd(wlc_hw->band->pi, true);
5713
5714         /* FULLY enable dynamic power control and d11 core interrupt */
5715         brcms_b_clkctl_clk(wlc_hw, CLK_DYNAMIC);
5716         brcms_intrson(wlc_hw->wlc->wl);
5717         return 0;
5718 }
5719
5720 /*
5721  * Write WME tunable parameters for retransmit/max rate
5722  * from wlc struct to ucode
5723  */
5724 static void brcms_c_wme_retries_write(struct brcms_c_info *wlc)
5725 {
5726         int ac;
5727
5728         /* Need clock to do this */
5729         if (!wlc->clk)
5730                 return;
5731
5732         for (ac = 0; ac < AC_COUNT; ac++)
5733                 brcms_c_write_shm(wlc, M_AC_TXLMT_ADDR(ac),
5734                                   wlc->wme_retries[ac]);
5735 }
5736
5737 /* make interface operational */
5738 int brcms_c_up(struct brcms_c_info *wlc)
5739 {
5740         BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
5741
5742         /* HW is turned off so don't try to access it */
5743         if (wlc->pub->hw_off || brcms_deviceremoved(wlc))
5744                 return -ENOMEDIUM;
5745
5746         if (!wlc->pub->hw_up) {
5747                 brcms_b_hw_up(wlc->hw);
5748                 wlc->pub->hw_up = true;
5749         }
5750
5751         if ((wlc->pub->boardflags & BFL_FEM)
5752             && (wlc->pub->sih->chip == BCM4313_CHIP_ID)) {
5753                 if (wlc->pub->boardrev >= 0x1250
5754                     && (wlc->pub->boardflags & BFL_FEM_BT))
5755                         brcms_c_mhf(wlc, MHF5, MHF5_4313_GPIOCTRL,
5756                                 MHF5_4313_GPIOCTRL, BRCM_BAND_ALL);
5757                 else
5758                         brcms_c_mhf(wlc, MHF4, MHF4_EXTPA_ENABLE,
5759                                     MHF4_EXTPA_ENABLE, BRCM_BAND_ALL);
5760         }
5761
5762         /*
5763          * Need to read the hwradio status here to cover the case where the
5764          * system is loaded with the hw radio disabled. We do not want to bring
5765          * the driver up in this case. If radio is disabled, abort up, lower
5766          * power, start radio timer and return 0(for NDIS) don't call
5767          * radio_update to avoid looping brcms_c_up.
5768          *
5769          * brcms_b_up_prep() returns either 0 or -BCME_RADIOOFF only
5770          */
5771         if (!wlc->pub->radio_disabled) {
5772                 int status = brcms_b_up_prep(wlc->hw);
5773                 if (status == -ENOMEDIUM) {
5774                         if (!mboolisset
5775                             (wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE)) {
5776                                 struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
5777                                 mboolset(wlc->pub->radio_disabled,
5778                                          WL_RADIO_HW_DISABLE);
5779
5780                                 if (bsscfg->enable && bsscfg->BSS)
5781                                         wiphy_err(wlc->wiphy, "wl%d: up"
5782                                                   ": rfdisable -> "
5783                                                   "bsscfg_disable()\n",
5784                                                    wlc->pub->unit);
5785                         }
5786                 }
5787         }
5788
5789         if (wlc->pub->radio_disabled) {
5790                 brcms_c_radio_monitor_start(wlc);
5791                 return 0;
5792         }
5793
5794         /* brcms_b_up_prep has done brcms_c_corereset(). so clk is on, set it */
5795         wlc->clk = true;
5796
5797         brcms_c_radio_monitor_stop(wlc);
5798
5799         /* Set EDCF hostflags */
5800         brcms_c_mhf(wlc, MHF1, MHF1_EDCF, MHF1_EDCF, BRCM_BAND_ALL);
5801
5802         brcms_init(wlc->wl);
5803         wlc->pub->up = true;
5804
5805         if (wlc->bandinit_pending) {
5806                 brcms_c_suspend_mac_and_wait(wlc);
5807                 brcms_c_set_chanspec(wlc, wlc->default_bss->chanspec);
5808                 wlc->bandinit_pending = false;
5809                 brcms_c_enable_mac(wlc);
5810         }
5811
5812         brcms_b_up_finish(wlc->hw);
5813
5814         /* Program the TX wme params with the current settings */
5815         brcms_c_wme_retries_write(wlc);
5816
5817         /* start one second watchdog timer */
5818         brcms_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, true);
5819         wlc->WDarmed = true;
5820
5821         /* ensure antenna config is up to date */
5822         brcms_c_stf_phy_txant_upd(wlc);
5823         /* ensure LDPC config is in sync */
5824         brcms_c_ht_update_ldpc(wlc, wlc->stf->ldpc);
5825
5826         return 0;
5827 }
5828
5829 static uint brcms_c_down_del_timer(struct brcms_c_info *wlc)
5830 {
5831         uint callbacks = 0;
5832
5833         return callbacks;
5834 }
5835
5836 static int brcms_b_bmac_down_prep(struct brcms_hardware *wlc_hw)
5837 {
5838         bool dev_gone;
5839         uint callbacks = 0;
5840
5841         BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
5842
5843         if (!wlc_hw->up)
5844                 return callbacks;
5845
5846         dev_gone = brcms_deviceremoved(wlc_hw->wlc);
5847
5848         /* disable interrupts */
5849         if (dev_gone)
5850                 wlc_hw->wlc->macintmask = 0;
5851         else {
5852                 /* now disable interrupts */
5853                 brcms_intrsoff(wlc_hw->wlc->wl);
5854
5855                 /* ensure we're running on the pll clock again */
5856                 brcms_b_clkctl_clk(wlc_hw, CLK_FAST);
5857         }
5858         /* down phy at the last of this stage */
5859         callbacks += wlc_phy_down(wlc_hw->band->pi);
5860
5861         return callbacks;
5862 }
5863
5864 static int brcms_b_down_finish(struct brcms_hardware *wlc_hw)
5865 {
5866         uint callbacks = 0;
5867         bool dev_gone;
5868
5869         BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
5870
5871         if (!wlc_hw->up)
5872                 return callbacks;
5873
5874         wlc_hw->up = false;
5875         wlc_phy_hw_state_upd(wlc_hw->band->pi, false);
5876
5877         dev_gone = brcms_deviceremoved(wlc_hw->wlc);
5878
5879         if (dev_gone) {
5880                 wlc_hw->sbclk = false;
5881                 wlc_hw->clk = false;
5882                 wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false);
5883
5884                 /* reclaim any posted packets */
5885                 brcms_c_flushqueues(wlc_hw->wlc);
5886         } else {
5887
5888                 /* Reset and disable the core */
5889                 if (ai_iscoreup(wlc_hw->sih)) {
5890                         if (R_REG(&wlc_hw->regs->maccontrol) &
5891                             MCTL_EN_MAC)
5892                                 brcms_c_suspend_mac_and_wait(wlc_hw->wlc);
5893                         callbacks += brcms_reset(wlc_hw->wlc->wl);
5894                         brcms_c_coredisable(wlc_hw);
5895                 }
5896
5897                 /* turn off primary xtal and pll */
5898                 if (!wlc_hw->noreset) {
5899                         ai_pci_down(wlc_hw->sih);
5900                         brcms_b_xtal(wlc_hw, OFF);
5901                 }
5902         }
5903
5904         return callbacks;
5905 }
5906
5907 /*
5908  * Mark the interface nonoperational, stop the software mechanisms,
5909  * disable the hardware, free any transient buffer state.
5910  * Return a count of the number of driver callbacks still pending.
5911  */
5912 uint brcms_c_down(struct brcms_c_info *wlc)
5913 {
5914
5915         uint callbacks = 0;
5916         int i;
5917         bool dev_gone = false;
5918         struct brcms_txq_info *qi;
5919
5920         BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
5921
5922         /* check if we are already in the going down path */
5923         if (wlc->going_down) {
5924                 wiphy_err(wlc->wiphy, "wl%d: %s: Driver going down so return"
5925                           "\n", wlc->pub->unit, __func__);
5926                 return 0;
5927         }
5928         if (!wlc->pub->up)
5929                 return callbacks;
5930
5931         /* in between, mpc could try to bring down again.. */
5932         wlc->going_down = true;
5933
5934         callbacks += brcms_b_bmac_down_prep(wlc->hw);
5935
5936         dev_gone = brcms_deviceremoved(wlc);
5937
5938         /* Call any registered down handlers */
5939         for (i = 0; i < BRCMS_MAXMODULES; i++) {
5940                 if (wlc->modulecb[i].down_fn)
5941                         callbacks +=
5942                             wlc->modulecb[i].down_fn(wlc->modulecb[i].hdl);
5943         }
5944
5945         /* cancel the watchdog timer */
5946         if (wlc->WDarmed) {
5947                 if (!brcms_del_timer(wlc->wl, wlc->wdtimer))
5948                         callbacks++;
5949                 wlc->WDarmed = false;
5950         }
5951         /* cancel all other timers */
5952         callbacks += brcms_c_down_del_timer(wlc);
5953
5954         wlc->pub->up = false;
5955
5956         wlc_phy_mute_upd(wlc->band->pi, false, PHY_MUTE_ALL);
5957
5958         /* clear txq flow control */
5959         brcms_c_txflowcontrol_reset(wlc);
5960
5961         /* flush tx queues */
5962         for (qi = wlc->tx_queues; qi != NULL; qi = qi->next)
5963                 brcmu_pktq_flush(&qi->q, true, NULL, NULL);
5964
5965         callbacks += brcms_b_down_finish(wlc->hw);
5966
5967         /* brcms_b_down_finish has done brcms_c_coredisable(). so clk is off */
5968         wlc->clk = false;
5969
5970         wlc->going_down = false;
5971         return callbacks;
5972 }
5973
5974 /* Set the current gmode configuration */
5975 int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config)
5976 {
5977         int ret = 0;
5978         uint i;
5979         struct brcms_c_rateset rs;
5980         /* Default to 54g Auto */
5981         /* Advertise and use shortslot (-1/0/1 Auto/Off/On) */
5982         s8 shortslot = BRCMS_SHORTSLOT_AUTO;
5983         bool shortslot_restrict = false; /* Restrict association to stations
5984                                           * that support shortslot
5985                                           */
5986         bool ofdm_basic = false;        /* Make 6, 12, and 24 basic rates */
5987         /* Advertise and use short preambles (-1/0/1 Auto/Off/On) */
5988         int preamble = BRCMS_PLCP_LONG;
5989         bool preamble_restrict = false; /* Restrict association to stations
5990                                          * that support short preambles
5991                                          */
5992         struct brcms_band *band;
5993
5994         /* if N-support is enabled, allow Gmode set as long as requested
5995          * Gmode is not GMODE_LEGACY_B
5996          */
5997         if ((wlc->pub->_n_enab & SUPPORT_11N) && gmode == GMODE_LEGACY_B)
5998                 return -ENOTSUPP;
5999
6000         /* verify that we are dealing with 2G band and grab the band pointer */
6001         if (wlc->band->bandtype == BRCM_BAND_2G)
6002                 band = wlc->band;
6003         else if ((wlc->pub->_nbands > 1) &&
6004                  (wlc->bandstate[OTHERBANDUNIT(wlc)]->bandtype == BRCM_BAND_2G))
6005                 band = wlc->bandstate[OTHERBANDUNIT(wlc)];
6006         else
6007                 return -EINVAL;
6008
6009         /* Legacy or bust when no OFDM is supported by regulatory */
6010         if ((brcms_c_channel_locale_flags_in_band(wlc->cmi, band->bandunit) &
6011              BRCMS_NO_OFDM) && (gmode != GMODE_LEGACY_B))
6012                 return -EINVAL;
6013
6014         /* update configuration value */
6015         if (config == true)
6016                 brcms_c_protection_upd(wlc, BRCMS_PROT_G_USER, gmode);
6017
6018         /* Clear rateset override */
6019         memset(&rs, 0, sizeof(struct brcms_c_rateset));
6020
6021         switch (gmode) {
6022         case GMODE_LEGACY_B:
6023                 shortslot = BRCMS_SHORTSLOT_OFF;
6024                 brcms_c_rateset_copy(&gphy_legacy_rates, &rs);
6025
6026                 break;
6027
6028         case GMODE_LRS:
6029                 break;
6030
6031         case GMODE_AUTO:
6032                 /* Accept defaults */
6033                 break;
6034
6035         case GMODE_ONLY:
6036                 ofdm_basic = true;
6037                 preamble = BRCMS_PLCP_SHORT;
6038                 preamble_restrict = true;
6039                 break;
6040
6041         case GMODE_PERFORMANCE:
6042                 shortslot = BRCMS_SHORTSLOT_ON;
6043                 shortslot_restrict = true;
6044                 ofdm_basic = true;
6045                 preamble = BRCMS_PLCP_SHORT;
6046                 preamble_restrict = true;
6047                 break;
6048
6049         default:
6050                 /* Error */
6051                 wiphy_err(wlc->wiphy, "wl%d: %s: invalid gmode %d\n",
6052                           wlc->pub->unit, __func__, gmode);
6053                 return -ENOTSUPP;
6054         }
6055
6056         /*
6057          * If we are switching to gmode == GMODE_LEGACY_B,
6058          * clean up rate info that may refer to OFDM rates.
6059          */
6060         if ((gmode == GMODE_LEGACY_B) && (band->gmode != GMODE_LEGACY_B)) {
6061                 band->gmode = gmode;
6062         }
6063
6064         band->gmode = gmode;
6065
6066         wlc->shortslot_override = shortslot;
6067
6068         /* Use the default 11g rateset */
6069         if (!rs.count)
6070                 brcms_c_rateset_copy(&cck_ofdm_rates, &rs);
6071
6072         if (ofdm_basic) {
6073                 for (i = 0; i < rs.count; i++) {
6074                         if (rs.rates[i] == BRCM_RATE_6M
6075                             || rs.rates[i] == BRCM_RATE_12M
6076                             || rs.rates[i] == BRCM_RATE_24M)
6077                                 rs.rates[i] |= BRCMS_RATE_FLAG;
6078                 }
6079         }
6080
6081         /* Set default bss rateset */
6082         wlc->default_bss->rateset.count = rs.count;
6083         memcpy(wlc->default_bss->rateset.rates, rs.rates,
6084                sizeof(wlc->default_bss->rateset.rates));
6085
6086         return ret;
6087 }
6088
6089 static int brcms_c_nmode_validate(struct brcms_c_info *wlc, s32 nmode)
6090 {
6091         int err = 0;
6092
6093         switch (nmode) {
6094
6095         case OFF:
6096                 break;
6097
6098         case AUTO:
6099         case WL_11N_2x2:
6100         case WL_11N_3x3:
6101                 if (!(BRCMS_PHY_11N_CAP(wlc->band)))
6102                         err = -EINVAL;
6103                 break;
6104
6105         default:
6106                 err = -EINVAL;
6107                 break;
6108         }
6109
6110         return err;
6111 }
6112
6113 int brcms_c_set_nmode(struct brcms_c_info *wlc, s32 nmode)
6114 {
6115         uint i;
6116         int err;
6117
6118         err = brcms_c_nmode_validate(wlc, nmode);
6119         if (err)
6120                 return err;
6121
6122         switch (nmode) {
6123         case OFF:
6124                 wlc->pub->_n_enab = OFF;
6125                 wlc->default_bss->flags &= ~BRCMS_BSS_HT;
6126                 /* delete the mcs rates from the default and hw ratesets */
6127                 brcms_c_rateset_mcs_clear(&wlc->default_bss->rateset);
6128                 for (i = 0; i < wlc->pub->_nbands; i++) {
6129                         memset(wlc->bandstate[i]->hw_rateset.mcs, 0,
6130                                MCSSET_LEN);
6131                 }
6132                 break;
6133
6134         case AUTO:
6135                 if (wlc->stf->txstreams == WL_11N_3x3)
6136                         nmode = WL_11N_3x3;
6137                 else
6138                         nmode = WL_11N_2x2;
6139         case WL_11N_2x2:
6140         case WL_11N_3x3:
6141                 /* force GMODE_AUTO if NMODE is ON */
6142                 brcms_c_set_gmode(wlc, GMODE_AUTO, true);
6143                 if (nmode == WL_11N_3x3)
6144                         wlc->pub->_n_enab = SUPPORT_HT;
6145                 else
6146                         wlc->pub->_n_enab = SUPPORT_11N;
6147                 wlc->default_bss->flags |= BRCMS_BSS_HT;
6148                 /* add the mcs rates to the default and hw ratesets */
6149                 brcms_c_rateset_mcs_build(&wlc->default_bss->rateset,
6150                                       wlc->stf->txstreams);
6151                 for (i = 0; i < wlc->pub->_nbands; i++)
6152                         memcpy(wlc->bandstate[i]->hw_rateset.mcs,
6153                                wlc->default_bss->rateset.mcs, MCSSET_LEN);
6154                 break;
6155
6156         default:
6157                 break;
6158         }
6159
6160         return err;
6161 }
6162
6163 static int
6164 brcms_c_set_internal_rateset(struct brcms_c_info *wlc,
6165                              struct brcms_c_rateset *rs_arg)
6166 {
6167         struct brcms_c_rateset rs, new;
6168         uint bandunit;
6169
6170         memcpy(&rs, rs_arg, sizeof(struct brcms_c_rateset));
6171
6172         /* check for bad count value */
6173         if ((rs.count == 0) || (rs.count > BRCMS_NUMRATES))
6174                 return -EINVAL;
6175
6176         /* try the current band */
6177         bandunit = wlc->band->bandunit;
6178         memcpy(&new, &rs, sizeof(struct brcms_c_rateset));
6179         if (brcms_c_rate_hwrs_filter_sort_validate
6180             (&new, &wlc->bandstate[bandunit]->hw_rateset, true,
6181              wlc->stf->txstreams))
6182                 goto good;
6183
6184         /* try the other band */
6185         if (brcms_is_mband_unlocked(wlc)) {
6186                 bandunit = OTHERBANDUNIT(wlc);
6187                 memcpy(&new, &rs, sizeof(struct brcms_c_rateset));
6188                 if (brcms_c_rate_hwrs_filter_sort_validate(&new,
6189                                                        &wlc->
6190                                                        bandstate[bandunit]->
6191                                                        hw_rateset, true,
6192                                                        wlc->stf->txstreams))
6193                         goto good;
6194         }
6195
6196         return -EBADE;
6197
6198  good:
6199         /* apply new rateset */
6200         memcpy(&wlc->default_bss->rateset, &new,
6201                sizeof(struct brcms_c_rateset));
6202         memcpy(&wlc->bandstate[bandunit]->defrateset, &new,
6203                sizeof(struct brcms_c_rateset));
6204         return 0;
6205 }
6206
6207 static void brcms_c_ofdm_rateset_war(struct brcms_c_info *wlc)
6208 {
6209         u8 r;
6210         bool war = false;
6211
6212         if (wlc->bsscfg->associated)
6213                 r = wlc->bsscfg->current_bss->rateset.rates[0];
6214         else
6215                 r = wlc->default_bss->rateset.rates[0];
6216
6217         wlc_phy_ofdm_rateset_war(wlc->band->pi, war);
6218
6219         return;
6220 }
6221
6222 int brcms_c_set_channel(struct brcms_c_info *wlc, u16 channel)
6223 {
6224         u16 chspec = ch20mhz_chspec(channel);
6225
6226         if (channel < 0 || channel > MAXCHANNEL)
6227                 return -EINVAL;
6228
6229         if (!brcms_c_valid_chanspec_db(wlc->cmi, chspec))
6230                 return -EINVAL;
6231
6232
6233         if (!wlc->pub->up && brcms_is_mband_unlocked(wlc)) {
6234                 if (wlc->band->bandunit != chspec_bandunit(chspec))
6235                         wlc->bandinit_pending = true;
6236                 else
6237                         wlc->bandinit_pending = false;
6238         }
6239
6240         wlc->default_bss->chanspec = chspec;
6241         /* brcms_c_BSSinit() will sanitize the rateset before
6242          * using it.. */
6243         if (wlc->pub->up && (wlc_phy_chanspec_get(wlc->band->pi) != chspec)) {
6244                 brcms_c_set_home_chanspec(wlc, chspec);
6245                 brcms_c_suspend_mac_and_wait(wlc);
6246                 brcms_c_set_chanspec(wlc, chspec);
6247                 brcms_c_enable_mac(wlc);
6248         }
6249         return 0;
6250 }
6251
6252 int brcms_c_set_rate_limit(struct brcms_c_info *wlc, u16 srl, u16 lrl)
6253 {
6254         int ac;
6255
6256         if (srl < 1 || srl > RETRY_SHORT_MAX ||
6257             lrl < 1 || lrl > RETRY_SHORT_MAX)
6258                 return -EINVAL;
6259
6260         wlc->SRL = srl;
6261         wlc->LRL = lrl;
6262
6263         brcms_b_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL);
6264
6265         for (ac = 0; ac < AC_COUNT; ac++) {
6266                 wlc->wme_retries[ac] =  SFIELD(wlc->wme_retries[ac],
6267                                                EDCF_SHORT,  wlc->SRL);
6268                 wlc->wme_retries[ac] =  SFIELD(wlc->wme_retries[ac],
6269                                                EDCF_LONG, wlc->LRL);
6270         }
6271         brcms_c_wme_retries_write(wlc);
6272
6273         return 0;
6274 }
6275
6276 void brcms_c_get_current_rateset(struct brcms_c_info *wlc,
6277                                  struct brcm_rateset *currs)
6278 {
6279         struct brcms_c_rateset *rs;
6280
6281         if (wlc->pub->associated)
6282                 rs = &wlc->bsscfg->current_bss->rateset;
6283         else
6284                 rs = &wlc->default_bss->rateset;
6285
6286         /* Copy only legacy rateset section */
6287         currs->count = rs->count;
6288         memcpy(&currs->rates, &rs->rates, rs->count);
6289 }
6290
6291 int brcms_c_set_rateset(struct brcms_c_info *wlc, struct brcm_rateset *rs)
6292 {
6293         struct brcms_c_rateset internal_rs;
6294         int bcmerror;
6295
6296         if (rs->count > BRCMS_NUMRATES)
6297                 return -ENOBUFS;
6298
6299         memset(&internal_rs, 0, sizeof(struct brcms_c_rateset));
6300
6301         /* Copy only legacy rateset section */
6302         internal_rs.count = rs->count;
6303         memcpy(&internal_rs.rates, &rs->rates, internal_rs.count);
6304
6305         /* merge rateset coming in with the current mcsset */
6306         if (wlc->pub->_n_enab & SUPPORT_11N) {
6307                 struct brcms_bss_info *mcsset_bss;
6308                 if (wlc->bsscfg->associated)
6309                         mcsset_bss = wlc->bsscfg->current_bss;
6310                 else
6311                         mcsset_bss = wlc->default_bss;
6312                 memcpy(internal_rs.mcs, &mcsset_bss->rateset.mcs[0],
6313                        MCSSET_LEN);
6314         }
6315
6316         bcmerror = brcms_c_set_internal_rateset(wlc, &internal_rs);
6317         if (!bcmerror)
6318                 brcms_c_ofdm_rateset_war(wlc);
6319
6320         return bcmerror;
6321 }
6322
6323 int brcms_c_set_beacon_period(struct brcms_c_info *wlc, u16 period)
6324 {
6325         if (period < DOT11_MIN_BEACON_PERIOD ||
6326             period > DOT11_MAX_BEACON_PERIOD)
6327                 return -EINVAL;
6328
6329         wlc->default_bss->beacon_period = period;
6330         return 0;
6331 }
6332
6333 u16 brcms_c_get_phy_type(struct brcms_c_info *wlc, int phyidx)
6334 {
6335         return wlc->band->phytype;
6336 }
6337
6338 void brcms_c_set_shortslot_override(struct brcms_c_info *wlc, s8 sslot_override)
6339 {
6340         wlc->shortslot_override = sslot_override;
6341
6342         /*
6343          * shortslot is an 11g feature, so no more work if we are
6344          * currently on the 5G band
6345          */
6346         if (wlc->band->bandtype == BRCM_BAND_5G)
6347                 return;
6348
6349         if (wlc->pub->up && wlc->pub->associated) {
6350                 /* let watchdog or beacon processing update shortslot */
6351         } else if (wlc->pub->up) {
6352                 /* unassociated shortslot is off */
6353                 brcms_c_switch_shortslot(wlc, false);
6354         } else {
6355                 /* driver is down, so just update the brcms_c_info
6356                  * value */
6357                 if (wlc->shortslot_override == BRCMS_SHORTSLOT_AUTO)
6358                         wlc->shortslot = false;
6359                 else
6360                         wlc->shortslot =
6361                             (wlc->shortslot_override ==
6362                              BRCMS_SHORTSLOT_ON);
6363         }
6364 }
6365
6366 /*
6367  * register watchdog and down handlers.
6368  */
6369 int brcms_c_module_register(struct brcms_pub *pub,
6370                             const char *name, struct brcms_info *hdl,
6371                             int (*d_fn)(void *handle))
6372 {
6373         struct brcms_c_info *wlc = (struct brcms_c_info *) pub->wlc;
6374         int i;
6375
6376         /* find an empty entry and just add, no duplication check! */
6377         for (i = 0; i < BRCMS_MAXMODULES; i++) {
6378                 if (wlc->modulecb[i].name[0] == '\0') {
6379                         strncpy(wlc->modulecb[i].name, name,
6380                                 sizeof(wlc->modulecb[i].name) - 1);
6381                         wlc->modulecb[i].hdl = hdl;
6382                         wlc->modulecb[i].down_fn = d_fn;
6383                         return 0;
6384                 }
6385         }
6386
6387         return -ENOSR;
6388 }
6389
6390 /* unregister module callbacks */
6391 int brcms_c_module_unregister(struct brcms_pub *pub, const char *name,
6392                               struct brcms_info *hdl)
6393 {
6394         struct brcms_c_info *wlc = (struct brcms_c_info *) pub->wlc;
6395         int i;
6396
6397         if (wlc == NULL)
6398                 return -ENODATA;
6399
6400         for (i = 0; i < BRCMS_MAXMODULES; i++) {
6401                 if (!strcmp(wlc->modulecb[i].name, name) &&
6402                     (wlc->modulecb[i].hdl == hdl)) {
6403                         memset(&wlc->modulecb[i], 0, sizeof(struct modulecb));
6404                         return 0;
6405                 }
6406         }
6407
6408         /* table not found! */
6409         return -ENODATA;
6410 }
6411
6412 #ifdef BCMDBG
6413 static const char * const supr_reason[] = {
6414         "None", "PMQ Entry", "Flush request",
6415         "Previous frag failure", "Channel mismatch",
6416         "Lifetime Expiry", "Underflow"
6417 };
6418
6419 static void brcms_c_print_txs_status(u16 s)
6420 {
6421         printk(KERN_DEBUG "[15:12]  %d  frame attempts\n",
6422                (s & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT);
6423         printk(KERN_DEBUG " [11:8]  %d  rts attempts\n",
6424                (s & TX_STATUS_RTS_RTX_MASK) >> TX_STATUS_RTS_RTX_SHIFT);
6425         printk(KERN_DEBUG "    [7]  %d  PM mode indicated\n",
6426                ((s & TX_STATUS_PMINDCTD) ? 1 : 0));
6427         printk(KERN_DEBUG "    [6]  %d  intermediate status\n",
6428                ((s & TX_STATUS_INTERMEDIATE) ? 1 : 0));
6429         printk(KERN_DEBUG "    [5]  %d  AMPDU\n",
6430                (s & TX_STATUS_AMPDU) ? 1 : 0);
6431         printk(KERN_DEBUG "  [4:2]  %d  Frame Suppressed Reason (%s)\n",
6432                ((s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT),
6433                supr_reason[(s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT]);
6434         printk(KERN_DEBUG "    [1]  %d  acked\n",
6435                ((s & TX_STATUS_ACK_RCV) ? 1 : 0));
6436 }
6437 #endif                          /* BCMDBG */
6438
6439 void brcms_c_print_txstatus(struct tx_status *txs)
6440 {
6441 #if defined(BCMDBG)
6442         u16 s = txs->status;
6443         u16 ackphyrxsh = txs->ackphyrxsh;
6444
6445         printk(KERN_DEBUG "\ntxpkt (MPDU) Complete\n");
6446
6447         printk(KERN_DEBUG "FrameID: %04x   ", txs->frameid);
6448         printk(KERN_DEBUG "TxStatus: %04x", s);
6449         printk(KERN_DEBUG "\n");
6450
6451         brcms_c_print_txs_status(s);
6452
6453         printk(KERN_DEBUG "LastTxTime: %04x ", txs->lasttxtime);
6454         printk(KERN_DEBUG "Seq: %04x ", txs->sequence);
6455         printk(KERN_DEBUG "PHYTxStatus: %04x ", txs->phyerr);
6456         printk(KERN_DEBUG "RxAckRSSI: %04x ",
6457                (ackphyrxsh & PRXS1_JSSI_MASK) >> PRXS1_JSSI_SHIFT);
6458         printk(KERN_DEBUG "RxAckSQ: %04x",
6459                (ackphyrxsh & PRXS1_SQ_MASK) >> PRXS1_SQ_SHIFT);
6460         printk(KERN_DEBUG "\n");
6461 #endif                          /* defined(BCMDBG) */
6462 }
6463
6464 void brcms_c_statsupd(struct brcms_c_info *wlc)
6465 {
6466         int i;
6467         struct macstat macstats;
6468 #ifdef BCMDBG
6469         u16 delta;
6470         u16 rxf0ovfl;
6471         u16 txfunfl[NFIFO];
6472 #endif                          /* BCMDBG */
6473
6474         /* if driver down, make no sense to update stats */
6475         if (!wlc->pub->up)
6476                 return;
6477
6478 #ifdef BCMDBG
6479         /* save last rx fifo 0 overflow count */
6480         rxf0ovfl = wlc->core->macstat_snapshot->rxf0ovfl;
6481
6482         /* save last tx fifo  underflow count */
6483         for (i = 0; i < NFIFO; i++)
6484                 txfunfl[i] = wlc->core->macstat_snapshot->txfunfl[i];
6485 #endif                          /* BCMDBG */
6486
6487         /* Read mac stats from contiguous shared memory */
6488         brcms_b_copyfrom_objmem(wlc->hw, M_UCODE_MACSTAT, &macstats,
6489                                 sizeof(struct macstat), OBJADDR_SHM_SEL);
6490
6491 #ifdef BCMDBG
6492         /* check for rx fifo 0 overflow */
6493         delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl);
6494         if (delta)
6495                 wiphy_err(wlc->wiphy, "wl%d: %u rx fifo 0 overflows!\n",
6496                           wlc->pub->unit, delta);
6497
6498         /* check for tx fifo underflows */
6499         for (i = 0; i < NFIFO; i++) {
6500                 delta =
6501                     (u16) (wlc->core->macstat_snapshot->txfunfl[i] -
6502                               txfunfl[i]);
6503                 if (delta)
6504                         wiphy_err(wlc->wiphy, "wl%d: %u tx fifo %d underflows!"
6505                                   "\n", wlc->pub->unit, delta, i);
6506         }
6507 #endif                          /* BCMDBG */
6508
6509         /* merge counters from dma module */
6510         for (i = 0; i < NFIFO; i++) {
6511                 if (wlc->hw->di[i])
6512                         dma_counterreset(wlc->hw->di[i]);
6513         }
6514 }
6515
6516 bool brcms_c_chipmatch(u16 vendor, u16 device)
6517 {
6518         if (vendor != PCI_VENDOR_ID_BROADCOM) {
6519                 pr_err("chipmatch: unknown vendor id %04x\n", vendor);
6520                 return false;
6521         }
6522
6523         if (device == BCM43224_D11N_ID_VEN1)
6524                 return true;
6525         if ((device == BCM43224_D11N_ID) || (device == BCM43225_D11N2G_ID))
6526                 return true;
6527         if (device == BCM4313_D11N2G_ID)
6528                 return true;
6529         if ((device == BCM43236_D11N_ID) || (device == BCM43236_D11N2G_ID))
6530                 return true;
6531
6532         pr_err("chipmatch: unknown device id %04x\n", device);
6533         return false;
6534 }
6535
6536 #if defined(BCMDBG)
6537 void brcms_c_print_txdesc(struct d11txh *txh)
6538 {
6539         u16 mtcl = le16_to_cpu(txh->MacTxControlLow);
6540         u16 mtch = le16_to_cpu(txh->MacTxControlHigh);
6541         u16 mfc = le16_to_cpu(txh->MacFrameControl);
6542         u16 tfest = le16_to_cpu(txh->TxFesTimeNormal);
6543         u16 ptcw = le16_to_cpu(txh->PhyTxControlWord);
6544         u16 ptcw_1 = le16_to_cpu(txh->PhyTxControlWord_1);
6545         u16 ptcw_1_Fbr = le16_to_cpu(txh->PhyTxControlWord_1_Fbr);
6546         u16 ptcw_1_Rts = le16_to_cpu(txh->PhyTxControlWord_1_Rts);
6547         u16 ptcw_1_FbrRts = le16_to_cpu(txh->PhyTxControlWord_1_FbrRts);
6548         u16 mainrates = le16_to_cpu(txh->MainRates);
6549         u16 xtraft = le16_to_cpu(txh->XtraFrameTypes);
6550         u8 *iv = txh->IV;
6551         u8 *ra = txh->TxFrameRA;
6552         u16 tfestfb = le16_to_cpu(txh->TxFesTimeFallback);
6553         u8 *rtspfb = txh->RTSPLCPFallback;
6554         u16 rtsdfb = le16_to_cpu(txh->RTSDurFallback);
6555         u8 *fragpfb = txh->FragPLCPFallback;
6556         u16 fragdfb = le16_to_cpu(txh->FragDurFallback);
6557         u16 mmodelen = le16_to_cpu(txh->MModeLen);
6558         u16 mmodefbrlen = le16_to_cpu(txh->MModeFbrLen);
6559         u16 tfid = le16_to_cpu(txh->TxFrameID);
6560         u16 txs = le16_to_cpu(txh->TxStatus);
6561         u16 mnmpdu = le16_to_cpu(txh->MaxNMpdus);
6562         u16 mabyte = le16_to_cpu(txh->MaxABytes_MRT);
6563         u16 mabyte_f = le16_to_cpu(txh->MaxABytes_FBR);
6564         u16 mmbyte = le16_to_cpu(txh->MinMBytes);
6565
6566         u8 *rtsph = txh->RTSPhyHeader;
6567         struct ieee80211_rts rts = txh->rts_frame;
6568         char hexbuf[256];
6569
6570         /* add plcp header along with txh descriptor */
6571         printk(KERN_DEBUG "Raw TxDesc + plcp header:\n");
6572         print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
6573                              txh, sizeof(struct d11txh) + 48);
6574
6575         printk(KERN_DEBUG "TxCtlLow: %04x ", mtcl);
6576         printk(KERN_DEBUG "TxCtlHigh: %04x ", mtch);
6577         printk(KERN_DEBUG "FC: %04x ", mfc);
6578         printk(KERN_DEBUG "FES Time: %04x\n", tfest);
6579         printk(KERN_DEBUG "PhyCtl: %04x%s ", ptcw,
6580                (ptcw & PHY_TXC_SHORT_HDR) ? " short" : "");
6581         printk(KERN_DEBUG "PhyCtl_1: %04x ", ptcw_1);
6582         printk(KERN_DEBUG "PhyCtl_1_Fbr: %04x\n", ptcw_1_Fbr);
6583         printk(KERN_DEBUG "PhyCtl_1_Rts: %04x ", ptcw_1_Rts);
6584         printk(KERN_DEBUG "PhyCtl_1_Fbr_Rts: %04x\n", ptcw_1_FbrRts);
6585         printk(KERN_DEBUG "MainRates: %04x ", mainrates);
6586         printk(KERN_DEBUG "XtraFrameTypes: %04x ", xtraft);
6587         printk(KERN_DEBUG "\n");
6588
6589         brcmu_format_hex(hexbuf, iv, sizeof(txh->IV));
6590         printk(KERN_DEBUG "SecIV:       %s\n", hexbuf);
6591         brcmu_format_hex(hexbuf, ra, sizeof(txh->TxFrameRA));
6592         printk(KERN_DEBUG "RA:          %s\n", hexbuf);
6593
6594         printk(KERN_DEBUG "Fb FES Time: %04x ", tfestfb);
6595         brcmu_format_hex(hexbuf, rtspfb, sizeof(txh->RTSPLCPFallback));
6596         printk(KERN_DEBUG "RTS PLCP: %s ", hexbuf);
6597         printk(KERN_DEBUG "RTS DUR: %04x ", rtsdfb);
6598         brcmu_format_hex(hexbuf, fragpfb, sizeof(txh->FragPLCPFallback));
6599         printk(KERN_DEBUG "PLCP: %s ", hexbuf);
6600         printk(KERN_DEBUG "DUR: %04x", fragdfb);
6601         printk(KERN_DEBUG "\n");
6602
6603         printk(KERN_DEBUG "MModeLen: %04x ", mmodelen);
6604         printk(KERN_DEBUG "MModeFbrLen: %04x\n", mmodefbrlen);
6605
6606         printk(KERN_DEBUG "FrameID:     %04x\n", tfid);
6607         printk(KERN_DEBUG "TxStatus:    %04x\n", txs);
6608
6609         printk(KERN_DEBUG "MaxNumMpdu:  %04x\n", mnmpdu);
6610         printk(KERN_DEBUG "MaxAggbyte:  %04x\n", mabyte);
6611         printk(KERN_DEBUG "MaxAggbyte_fb:  %04x\n", mabyte_f);
6612         printk(KERN_DEBUG "MinByte:     %04x\n", mmbyte);
6613
6614         brcmu_format_hex(hexbuf, rtsph, sizeof(txh->RTSPhyHeader));
6615         printk(KERN_DEBUG "RTS PLCP: %s ", hexbuf);
6616         brcmu_format_hex(hexbuf, (u8 *) &rts, sizeof(txh->rts_frame));
6617         printk(KERN_DEBUG "RTS Frame: %s", hexbuf);
6618         printk(KERN_DEBUG "\n");
6619 }
6620 #endif                          /* defined(BCMDBG) */
6621
6622 #if defined(BCMDBG)
6623 void brcms_c_print_rxh(struct d11rxhdr *rxh)
6624 {
6625         u16 len = rxh->RxFrameSize;
6626         u16 phystatus_0 = rxh->PhyRxStatus_0;
6627         u16 phystatus_1 = rxh->PhyRxStatus_1;
6628         u16 phystatus_2 = rxh->PhyRxStatus_2;
6629         u16 phystatus_3 = rxh->PhyRxStatus_3;
6630         u16 macstatus1 = rxh->RxStatus1;
6631         u16 macstatus2 = rxh->RxStatus2;
6632         char flagstr[64];
6633         char lenbuf[20];
6634         static const struct brcmu_bit_desc macstat_flags[] = {
6635                 {RXS_FCSERR, "FCSErr"},
6636                 {RXS_RESPFRAMETX, "Reply"},
6637                 {RXS_PBPRES, "PADDING"},
6638                 {RXS_DECATMPT, "DeCr"},
6639                 {RXS_DECERR, "DeCrErr"},
6640                 {RXS_BCNSENT, "Bcn"},
6641                 {0, NULL}
6642         };
6643
6644         printk(KERN_DEBUG "Raw RxDesc:\n");
6645         print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, rxh,
6646                              sizeof(struct d11rxhdr));
6647
6648         brcmu_format_flags(macstat_flags, macstatus1, flagstr, 64);
6649
6650         snprintf(lenbuf, sizeof(lenbuf), "0x%x", len);
6651
6652         printk(KERN_DEBUG "RxFrameSize:     %6s (%d)%s\n", lenbuf, len,
6653                (rxh->PhyRxStatus_0 & PRXS0_SHORTH) ? " short preamble" : "");
6654         printk(KERN_DEBUG "RxPHYStatus:     %04x %04x %04x %04x\n",
6655                phystatus_0, phystatus_1, phystatus_2, phystatus_3);
6656         printk(KERN_DEBUG "RxMACStatus:     %x %s\n", macstatus1, flagstr);
6657         printk(KERN_DEBUG "RXMACaggtype:    %x\n",
6658                (macstatus2 & RXS_AGGTYPE_MASK));
6659         printk(KERN_DEBUG "RxTSFTime:       %04x\n", rxh->RxTSFTime);
6660 }
6661 #endif                          /* defined(BCMDBG) */
6662
6663 u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate)
6664 {
6665         u16 table_ptr;
6666         u8 phy_rate, index;
6667
6668         /* get the phy specific rate encoding for the PLCP SIGNAL field */
6669         if (is_ofdm_rate(rate))
6670                 table_ptr = M_RT_DIRMAP_A;
6671         else
6672                 table_ptr = M_RT_DIRMAP_B;
6673
6674         /* for a given rate, the LS-nibble of the PLCP SIGNAL field is
6675          * the index into the rate table.
6676          */
6677         phy_rate = rate_info[rate] & BRCMS_RATE_MASK;
6678         index = phy_rate & 0xf;
6679
6680         /* Find the SHM pointer to the rate table entry by looking in the
6681          * Direct-map Table
6682          */
6683         return 2 * brcms_b_read_shm(wlc_hw, table_ptr + (index * 2));
6684 }
6685
6686 static u16 brcms_c_rate_shm_offset(struct brcms_c_info *wlc, u8 rate)
6687 {
6688         return brcms_b_rate_shm_offset(wlc->hw, rate);
6689 }
6690
6691 /* Callback for device removed */
6692
6693 /*
6694  * Attempts to queue a packet onto a multiple-precedence queue,
6695  * if necessary evicting a lower precedence packet from the queue.
6696  *
6697  * 'prec' is the precedence number that has already been mapped
6698  * from the packet priority.
6699  *
6700  * Returns true if packet consumed (queued), false if not.
6701  */
6702 static bool brcms_c_prec_enq(struct brcms_c_info *wlc, struct pktq *q,
6703                       struct sk_buff *pkt, int prec)
6704 {
6705         return brcms_c_prec_enq_head(wlc, q, pkt, prec, false);
6706 }
6707
6708 bool
6709 brcms_c_prec_enq_head(struct brcms_c_info *wlc, struct pktq *q,
6710                       struct sk_buff *pkt, int prec, bool head)
6711 {
6712         struct sk_buff *p;
6713         int eprec = -1;         /* precedence to evict from */
6714
6715         /* Determine precedence from which to evict packet, if any */
6716         if (pktq_pfull(q, prec))
6717                 eprec = prec;
6718         else if (pktq_full(q)) {
6719                 p = brcmu_pktq_peek_tail(q, &eprec);
6720                 if (eprec > prec) {
6721                         wiphy_err(wlc->wiphy, "%s: Failing: eprec %d > prec %d"
6722                                   "\n", __func__, eprec, prec);
6723                         return false;
6724                 }
6725         }
6726
6727         /* Evict if needed */
6728         if (eprec >= 0) {
6729                 bool discard_oldest;
6730
6731                 discard_oldest = ac_bitmap_tst(0, eprec);
6732
6733                 /* Refuse newer packet unless configured to discard oldest */
6734                 if (eprec == prec && !discard_oldest) {
6735                         wiphy_err(wlc->wiphy, "%s: No where to go, prec == %d"
6736                                   "\n", __func__, prec);
6737                         return false;
6738                 }
6739
6740                 /* Evict packet according to discard policy */
6741                 p = discard_oldest ? brcmu_pktq_pdeq(q, eprec) :
6742                         brcmu_pktq_pdeq_tail(q, eprec);
6743                 brcmu_pkt_buf_free_skb(p);
6744         }
6745
6746         /* Enqueue */
6747         if (head)
6748                 p = brcmu_pktq_penq_head(q, prec, pkt);
6749         else
6750                 p = brcmu_pktq_penq(q, prec, pkt);
6751
6752         return true;
6753 }
6754
6755 void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb,
6756                      struct sk_buff *sdu, uint prec)
6757 {
6758         struct brcms_txq_info *qi = wlc->pkt_queue;     /* Check me */
6759         struct pktq *q = &qi->q;
6760         int prio;
6761
6762         prio = sdu->priority;
6763
6764         if (!brcms_c_prec_enq(wlc, q, sdu, prec)) {
6765                 /*
6766                  * we might hit this condtion in case
6767                  * packet flooding from mac80211 stack
6768                  */
6769                 brcmu_pkt_buf_free_skb(sdu);
6770         }
6771 }
6772
6773 /*
6774  * bcmc_fid_generate:
6775  * Generate frame ID for a BCMC packet.  The frag field is not used
6776  * for MC frames so is used as part of the sequence number.
6777  */
6778 static inline u16
6779 bcmc_fid_generate(struct brcms_c_info *wlc, struct brcms_bss_cfg *bsscfg,
6780                   struct d11txh *txh)
6781 {
6782         u16 frameid;
6783
6784         frameid = le16_to_cpu(txh->TxFrameID) & ~(TXFID_SEQ_MASK |
6785                                                   TXFID_QUEUE_MASK);
6786         frameid |=
6787             (((wlc->
6788                mc_fid_counter++) << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) |
6789             TX_BCMC_FIFO;
6790
6791         return frameid;
6792 }
6793
6794 static uint
6795 brcms_c_calc_ack_time(struct brcms_c_info *wlc, u32 rspec,
6796                       u8 preamble_type)
6797 {
6798         uint dur = 0;
6799
6800         BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d\n",
6801                 wlc->pub->unit, rspec, preamble_type);
6802         /*
6803          * Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that
6804          * is less than or equal to the rate of the immediately previous
6805          * frame in the FES
6806          */
6807         rspec = brcms_basic_rate(wlc, rspec);
6808         /* ACK frame len == 14 == 2(fc) + 2(dur) + 6(ra) + 4(fcs) */
6809         dur =
6810             brcms_c_calc_frame_time(wlc, rspec, preamble_type,
6811                                 (DOT11_ACK_LEN + FCS_LEN));
6812         return dur;
6813 }
6814
6815 static uint
6816 brcms_c_calc_cts_time(struct brcms_c_info *wlc, u32 rspec,
6817                       u8 preamble_type)
6818 {
6819         BCMMSG(wlc->wiphy, "wl%d: ratespec 0x%x, preamble_type %d\n",
6820                 wlc->pub->unit, rspec, preamble_type);
6821         return brcms_c_calc_ack_time(wlc, rspec, preamble_type);
6822 }
6823
6824 static uint
6825 brcms_c_calc_ba_time(struct brcms_c_info *wlc, u32 rspec,
6826                      u8 preamble_type)
6827 {
6828         BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, "
6829                  "preamble_type %d\n", wlc->pub->unit, rspec, preamble_type);
6830         /*
6831          * Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that
6832          * is less than or equal to the rate of the immediately previous
6833          * frame in the FES
6834          */
6835         rspec = brcms_basic_rate(wlc, rspec);
6836         /* BA len == 32 == 16(ctl hdr) + 4(ba len) + 8(bitmap) + 4(fcs) */
6837         return brcms_c_calc_frame_time(wlc, rspec, preamble_type,
6838                                    (DOT11_BA_LEN + DOT11_BA_BITMAP_LEN +
6839                                     FCS_LEN));
6840 }
6841
6842 /* brcms_c_compute_frame_dur()
6843  *
6844  * Calculate the 802.11 MAC header DUR field for MPDU
6845  * DUR for a single frame = 1 SIFS + 1 ACK
6846  * DUR for a frame with following frags = 3 SIFS + 2 ACK + next frag time
6847  *
6848  * rate                 MPDU rate in unit of 500kbps
6849  * next_frag_len        next MPDU length in bytes
6850  * preamble_type        use short/GF or long/MM PLCP header
6851  */
6852 static u16
6853 brcms_c_compute_frame_dur(struct brcms_c_info *wlc, u32 rate,
6854                       u8 preamble_type, uint next_frag_len)
6855 {
6856         u16 dur, sifs;
6857
6858         sifs = get_sifs(wlc->band);
6859
6860         dur = sifs;
6861         dur += (u16) brcms_c_calc_ack_time(wlc, rate, preamble_type);
6862
6863         if (next_frag_len) {
6864                 /* Double the current DUR to get 2 SIFS + 2 ACKs */
6865                 dur *= 2;
6866                 /* add another SIFS and the frag time */
6867                 dur += sifs;
6868                 dur +=
6869                     (u16) brcms_c_calc_frame_time(wlc, rate, preamble_type,
6870                                                  next_frag_len);
6871         }
6872         return dur;
6873 }
6874
6875 /* The opposite of brcms_c_calc_frame_time */
6876 static uint
6877 brcms_c_calc_frame_len(struct brcms_c_info *wlc, u32 ratespec,
6878                    u8 preamble_type, uint dur)
6879 {
6880         uint nsyms, mac_len, Ndps, kNdps;
6881         uint rate = rspec2rate(ratespec);
6882
6883         BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d, dur %d\n",
6884                  wlc->pub->unit, ratespec, preamble_type, dur);
6885
6886         if (is_mcs_rate(ratespec)) {
6887                 uint mcs = ratespec & RSPEC_RATE_MASK;
6888                 int tot_streams = mcs_2_txstreams(mcs) + rspec_stc(ratespec);
6889                 dur -= PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT);
6890                 /* payload calculation matches that of regular ofdm */
6891                 if (wlc->band->bandtype == BRCM_BAND_2G)
6892                         dur -= DOT11_OFDM_SIGNAL_EXTENSION;
6893                 /* kNdbps = kbps * 4 */
6894                 kNdps = mcs_2_rate(mcs, rspec_is40mhz(ratespec),
6895                                    rspec_issgi(ratespec)) * 4;
6896                 nsyms = dur / APHY_SYMBOL_TIME;
6897                 mac_len =
6898                     ((nsyms * kNdps) -
6899                      ((APHY_SERVICE_NBITS + APHY_TAIL_NBITS) * 1000)) / 8000;
6900         } else if (is_ofdm_rate(ratespec)) {
6901                 dur -= APHY_PREAMBLE_TIME;
6902                 dur -= APHY_SIGNAL_TIME;
6903                 /* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */
6904                 Ndps = rate * 2;
6905                 nsyms = dur / APHY_SYMBOL_TIME;
6906                 mac_len =
6907                     ((nsyms * Ndps) -
6908                      (APHY_SERVICE_NBITS + APHY_TAIL_NBITS)) / 8;
6909         } else {
6910                 if (preamble_type & BRCMS_SHORT_PREAMBLE)
6911                         dur -= BPHY_PLCP_SHORT_TIME;
6912                 else
6913                         dur -= BPHY_PLCP_TIME;
6914                 mac_len = dur * rate;
6915                 /* divide out factor of 2 in rate (1/2 mbps) */
6916                 mac_len = mac_len / 8 / 2;
6917         }
6918         return mac_len;
6919 }
6920
6921 static u32
6922 mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band,
6923                        u32 int_val)
6924 {
6925         u8 stf = (int_val & NRATE_STF_MASK) >> NRATE_STF_SHIFT;
6926         u8 rate = int_val & NRATE_RATE_MASK;
6927         u32 rspec;
6928         bool ismcs = ((int_val & NRATE_MCS_INUSE) == NRATE_MCS_INUSE);
6929         bool issgi = ((int_val & NRATE_SGI_MASK) >> NRATE_SGI_SHIFT);
6930         bool override_mcs_only = ((int_val & NRATE_OVERRIDE_MCS_ONLY)
6931                                   == NRATE_OVERRIDE_MCS_ONLY);
6932         int bcmerror = 0;
6933
6934         if (!ismcs)
6935                 return (u32) rate;
6936
6937         /* validate the combination of rate/mcs/stf is allowed */
6938         if ((wlc->pub->_n_enab & SUPPORT_11N) && ismcs) {
6939                 /* mcs only allowed when nmode */
6940                 if (stf > PHY_TXC1_MODE_SDM) {
6941                         wiphy_err(wlc->wiphy, "wl%d: %s: Invalid stf\n",
6942                                   wlc->pub->unit, __func__);
6943                         bcmerror = -EINVAL;
6944                         goto done;
6945                 }
6946
6947                 /* mcs 32 is a special case, DUP mode 40 only */
6948                 if (rate == 32) {
6949                         if (!CHSPEC_IS40(wlc->home_chanspec) ||
6950                             ((stf != PHY_TXC1_MODE_SISO)
6951                              && (stf != PHY_TXC1_MODE_CDD))) {
6952                                 wiphy_err(wlc->wiphy, "wl%d: %s: Invalid mcs "
6953                                           "32\n", wlc->pub->unit, __func__);
6954                                 bcmerror = -EINVAL;
6955                                 goto done;
6956                         }
6957                         /* mcs > 7 must use stf SDM */
6958                 } else if (rate > HIGHEST_SINGLE_STREAM_MCS) {
6959                         /* mcs > 7 must use stf SDM */
6960                         if (stf != PHY_TXC1_MODE_SDM) {
6961                                 BCMMSG(wlc->wiphy, "wl%d: enabling "
6962                                        "SDM mode for mcs %d\n",
6963                                        wlc->pub->unit, rate);
6964                                 stf = PHY_TXC1_MODE_SDM;
6965                         }
6966                 } else {
6967                         /*
6968                          * MCS 0-7 may use SISO, CDD, and for
6969                          * phy_rev >= 3 STBC
6970                          */
6971                         if ((stf > PHY_TXC1_MODE_STBC) ||
6972                             (!BRCMS_STBC_CAP_PHY(wlc)
6973                              && (stf == PHY_TXC1_MODE_STBC))) {
6974                                 wiphy_err(wlc->wiphy, "wl%d: %s: Invalid STBC"
6975                                           "\n", wlc->pub->unit, __func__);
6976                                 bcmerror = -EINVAL;
6977                                 goto done;
6978                         }
6979                 }
6980         } else if (is_ofdm_rate(rate)) {
6981                 if ((stf != PHY_TXC1_MODE_CDD) && (stf != PHY_TXC1_MODE_SISO)) {
6982                         wiphy_err(wlc->wiphy, "wl%d: %s: Invalid OFDM\n",
6983                                   wlc->pub->unit, __func__);
6984                         bcmerror = -EINVAL;
6985                         goto done;
6986                 }
6987         } else if (is_cck_rate(rate)) {
6988                 if ((cur_band->bandtype != BRCM_BAND_2G)
6989                     || (stf != PHY_TXC1_MODE_SISO)) {
6990                         wiphy_err(wlc->wiphy, "wl%d: %s: Invalid CCK\n",
6991                                   wlc->pub->unit, __func__);
6992                         bcmerror = -EINVAL;
6993                         goto done;
6994                 }
6995         } else {
6996                 wiphy_err(wlc->wiphy, "wl%d: %s: Unknown rate type\n",
6997                           wlc->pub->unit, __func__);
6998                 bcmerror = -EINVAL;
6999                 goto done;
7000         }
7001         /* make sure multiple antennae are available for non-siso rates */
7002         if ((stf != PHY_TXC1_MODE_SISO) && (wlc->stf->txstreams == 1)) {
7003                 wiphy_err(wlc->wiphy, "wl%d: %s: SISO antenna but !SISO "
7004                           "request\n", wlc->pub->unit, __func__);
7005                 bcmerror = -EINVAL;
7006                 goto done;
7007         }
7008
7009         rspec = rate;
7010         if (ismcs) {
7011                 rspec |= RSPEC_MIMORATE;
7012                 /* For STBC populate the STC field of the ratespec */
7013                 if (stf == PHY_TXC1_MODE_STBC) {
7014                         u8 stc;
7015                         stc = 1;        /* Nss for single stream is always 1 */
7016                         rspec |= (stc << RSPEC_STC_SHIFT);
7017                 }
7018         }
7019
7020         rspec |= (stf << RSPEC_STF_SHIFT);
7021
7022         if (override_mcs_only)
7023                 rspec |= RSPEC_OVERRIDE_MCS_ONLY;
7024
7025         if (issgi)
7026                 rspec |= RSPEC_SHORT_GI;
7027
7028         if ((rate != 0)
7029             && !brcms_c_valid_rate(wlc, rspec, cur_band->bandtype, true))
7030                 return rate;
7031
7032         return rspec;
7033 done:
7034         return rate;
7035 }
7036
7037 /*
7038  * Add struct d11txh, struct cck_phy_hdr.
7039  *
7040  * 'p' data must start with 802.11 MAC header
7041  * 'p' must allow enough bytes of local headers to be "pushed" onto the packet
7042  *
7043  * headroom == D11_PHY_HDR_LEN + D11_TXH_LEN (D11_TXH_LEN is now 104 bytes)
7044  *
7045  */
7046 static u16
7047 brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw,
7048                      struct sk_buff *p, struct scb *scb, uint frag,
7049                      uint nfrags, uint queue, uint next_frag_len)
7050 {
7051         struct ieee80211_hdr *h;
7052         struct d11txh *txh;
7053         u8 *plcp, plcp_fallback[D11_PHY_HDR_LEN];
7054         int len, phylen, rts_phylen;
7055         u16 mch, phyctl, xfts, mainrates;
7056         u16 seq = 0, mcl = 0, status = 0, frameid = 0;
7057         u32 rspec[2] = { BRCM_RATE_1M, BRCM_RATE_1M };
7058         u32 rts_rspec[2] = { BRCM_RATE_1M, BRCM_RATE_1M };
7059         bool use_rts = false;
7060         bool use_cts = false;
7061         bool use_rifs = false;
7062         bool short_preamble[2] = { false, false };
7063         u8 preamble_type[2] = { BRCMS_LONG_PREAMBLE, BRCMS_LONG_PREAMBLE };
7064         u8 rts_preamble_type[2] = { BRCMS_LONG_PREAMBLE, BRCMS_LONG_PREAMBLE };
7065         u8 *rts_plcp, rts_plcp_fallback[D11_PHY_HDR_LEN];
7066         struct ieee80211_rts *rts = NULL;
7067         bool qos;
7068         uint ac;
7069         bool hwtkmic = false;
7070         u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ;
7071 #define ANTCFG_NONE 0xFF
7072         u8 antcfg = ANTCFG_NONE;
7073         u8 fbantcfg = ANTCFG_NONE;
7074         uint phyctl1_stf = 0;
7075         u16 durid = 0;
7076         struct ieee80211_tx_rate *txrate[2];
7077         int k;
7078         struct ieee80211_tx_info *tx_info;
7079         bool is_mcs;
7080         u16 mimo_txbw;
7081         u8 mimo_preamble_type;
7082
7083         /* locate 802.11 MAC header */
7084         h = (struct ieee80211_hdr *)(p->data);
7085         qos = ieee80211_is_data_qos(h->frame_control);
7086
7087         /* compute length of frame in bytes for use in PLCP computations */
7088         len = brcmu_pkttotlen(p);
7089         phylen = len + FCS_LEN;
7090
7091         /* Get tx_info */
7092         tx_info = IEEE80211_SKB_CB(p);
7093
7094         /* add PLCP */
7095         plcp = skb_push(p, D11_PHY_HDR_LEN);
7096
7097         /* add Broadcom tx descriptor header */
7098         txh = (struct d11txh *) skb_push(p, D11_TXH_LEN);
7099         memset(txh, 0, D11_TXH_LEN);
7100
7101         /* setup frameid */
7102         if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
7103                 /* non-AP STA should never use BCMC queue */
7104                 if (queue == TX_BCMC_FIFO) {
7105                         wiphy_err(wlc->wiphy, "wl%d: %s: ASSERT queue == "
7106                                   "TX_BCMC!\n", wlc->pub->unit, __func__);
7107                         frameid = bcmc_fid_generate(wlc, NULL, txh);
7108                 } else {
7109                         /* Increment the counter for first fragment */
7110                         if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
7111                                 scb->seqnum[p->priority]++;
7112
7113                         /* extract fragment number from frame first */
7114                         seq = le16_to_cpu(h->seq_ctrl) & FRAGNUM_MASK;
7115                         seq |= (scb->seqnum[p->priority] << SEQNUM_SHIFT);
7116                         h->seq_ctrl = cpu_to_le16(seq);
7117
7118                         frameid = ((seq << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) |
7119                             (queue & TXFID_QUEUE_MASK);
7120                 }
7121         }
7122         frameid |= queue & TXFID_QUEUE_MASK;
7123
7124         /* set the ignpmq bit for all pkts tx'd in PS mode and for beacons */
7125         if (ieee80211_is_beacon(h->frame_control))
7126                 mcl |= TXC_IGNOREPMQ;
7127
7128         txrate[0] = tx_info->control.rates;
7129         txrate[1] = txrate[0] + 1;
7130
7131         /*
7132          * if rate control algorithm didn't give us a fallback
7133          * rate, use the primary rate
7134          */
7135         if (txrate[1]->idx < 0)
7136                 txrate[1] = txrate[0];
7137
7138         for (k = 0; k < hw->max_rates; k++) {
7139                 is_mcs = txrate[k]->flags & IEEE80211_TX_RC_MCS ? true : false;
7140                 if (!is_mcs) {
7141                         if ((txrate[k]->idx >= 0)
7142                             && (txrate[k]->idx <
7143                                 hw->wiphy->bands[tx_info->band]->n_bitrates)) {
7144                                 rspec[k] =
7145                                     hw->wiphy->bands[tx_info->band]->
7146                                     bitrates[txrate[k]->idx].hw_value;
7147                                 short_preamble[k] =
7148                                     txrate[k]->
7149                                     flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE ?
7150                                     true : false;
7151                         } else {
7152                                 rspec[k] = BRCM_RATE_1M;
7153                         }
7154                 } else {
7155                         rspec[k] = mac80211_wlc_set_nrate(wlc, wlc->band,
7156                                         NRATE_MCS_INUSE | txrate[k]->idx);
7157                 }
7158
7159                 /*
7160                  * Currently only support same setting for primay and
7161                  * fallback rates. Unify flags for each rate into a
7162                  * single value for the frame
7163                  */
7164                 use_rts |=
7165                     txrate[k]->
7166                     flags & IEEE80211_TX_RC_USE_RTS_CTS ? true : false;
7167                 use_cts |=
7168                     txrate[k]->
7169                     flags & IEEE80211_TX_RC_USE_CTS_PROTECT ? true : false;
7170
7171
7172                 /*
7173                  * (1) RATE:
7174                  *   determine and validate primary rate
7175                  *   and fallback rates
7176                  */
7177                 if (!rspec_active(rspec[k])) {
7178                         rspec[k] = BRCM_RATE_1M;
7179                 } else {
7180                         if (!is_multicast_ether_addr(h->addr1)) {
7181                                 /* set tx antenna config */
7182                                 brcms_c_antsel_antcfg_get(wlc->asi, false,
7183                                         false, 0, 0, &antcfg, &fbantcfg);
7184                         }
7185                 }
7186         }
7187
7188         phyctl1_stf = wlc->stf->ss_opmode;
7189
7190         if (wlc->pub->_n_enab & SUPPORT_11N) {
7191                 for (k = 0; k < hw->max_rates; k++) {
7192                         /*
7193                          * apply siso/cdd to single stream mcs's or ofdm
7194                          * if rspec is auto selected
7195                          */
7196                         if (((is_mcs_rate(rspec[k]) &&
7197                               is_single_stream(rspec[k] & RSPEC_RATE_MASK)) ||
7198                              is_ofdm_rate(rspec[k]))
7199                             && ((rspec[k] & RSPEC_OVERRIDE_MCS_ONLY)
7200                                 || !(rspec[k] & RSPEC_OVERRIDE))) {
7201                                 rspec[k] &= ~(RSPEC_STF_MASK | RSPEC_STC_MASK);
7202
7203                                 /* For SISO MCS use STBC if possible */
7204                                 if (is_mcs_rate(rspec[k])
7205                                     && BRCMS_STF_SS_STBC_TX(wlc, scb)) {
7206                                         u8 stc;
7207
7208                                         /* Nss for single stream is always 1 */
7209                                         stc = 1;
7210                                         rspec[k] |= (PHY_TXC1_MODE_STBC <<
7211                                                         RSPEC_STF_SHIFT) |
7212                                                     (stc << RSPEC_STC_SHIFT);
7213                                 } else
7214                                         rspec[k] |=
7215                                             (phyctl1_stf << RSPEC_STF_SHIFT);
7216                         }
7217
7218                         /*
7219                          * Is the phy configured to use 40MHZ frames? If
7220                          * so then pick the desired txbw
7221                          */
7222                         if (brcms_chspec_bw(wlc->chanspec) == BRCMS_40_MHZ) {
7223                                 /* default txbw is 20in40 SB */
7224                                 mimo_ctlchbw = mimo_txbw =
7225                                    CHSPEC_SB_UPPER(wlc_phy_chanspec_get(
7226                                                                  wlc->band->pi))
7227                                    ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ;
7228
7229                                 if (is_mcs_rate(rspec[k])) {
7230                                         /* mcs 32 must be 40b/w DUP */
7231                                         if ((rspec[k] & RSPEC_RATE_MASK)
7232                                             == 32) {
7233                                                 mimo_txbw =
7234                                                     PHY_TXC1_BW_40MHZ_DUP;
7235                                                 /* use override */
7236                                         } else if (wlc->mimo_40txbw != AUTO)
7237                                                 mimo_txbw = wlc->mimo_40txbw;
7238                                         /* else check if dst is using 40 Mhz */
7239                                         else if (scb->flags & SCB_IS40)
7240                                                 mimo_txbw = PHY_TXC1_BW_40MHZ;
7241                                 } else if (is_ofdm_rate(rspec[k])) {
7242                                         if (wlc->ofdm_40txbw != AUTO)
7243                                                 mimo_txbw = wlc->ofdm_40txbw;
7244                                 } else if (wlc->cck_40txbw != AUTO) {
7245                                         mimo_txbw = wlc->cck_40txbw;
7246                                 }
7247                         } else {
7248                                 /*
7249                                  * mcs32 is 40 b/w only.
7250                                  * This is possible for probe packets on
7251                                  * a STA during SCAN
7252                                  */
7253                                 if ((rspec[k] & RSPEC_RATE_MASK) == 32)
7254                                         /* mcs 0 */
7255                                         rspec[k] = RSPEC_MIMORATE;
7256
7257                                 mimo_txbw = PHY_TXC1_BW_20MHZ;
7258                         }
7259
7260                         /* Set channel width */
7261                         rspec[k] &= ~RSPEC_BW_MASK;
7262                         if ((k == 0) || ((k > 0) && is_mcs_rate(rspec[k])))
7263                                 rspec[k] |= (mimo_txbw << RSPEC_BW_SHIFT);
7264                         else
7265                                 rspec[k] |= (mimo_ctlchbw << RSPEC_BW_SHIFT);
7266
7267                         /* Disable short GI, not supported yet */
7268                         rspec[k] &= ~RSPEC_SHORT_GI;
7269
7270                         mimo_preamble_type = BRCMS_MM_PREAMBLE;
7271                         if (txrate[k]->flags & IEEE80211_TX_RC_GREEN_FIELD)
7272                                 mimo_preamble_type = BRCMS_GF_PREAMBLE;
7273
7274                         if ((txrate[k]->flags & IEEE80211_TX_RC_MCS)
7275                             && (!is_mcs_rate(rspec[k]))) {
7276                                 wiphy_err(wlc->wiphy, "wl%d: %s: IEEE80211_TX_"
7277                                           "RC_MCS != is_mcs_rate(rspec)\n",
7278                                           wlc->pub->unit, __func__);
7279                         }
7280
7281                         if (is_mcs_rate(rspec[k])) {
7282                                 preamble_type[k] = mimo_preamble_type;
7283
7284                                 /*
7285                                  * if SGI is selected, then forced mm
7286                                  * for single stream
7287                                  */
7288                                 if ((rspec[k] & RSPEC_SHORT_GI)
7289                                     && is_single_stream(rspec[k] &
7290                                                         RSPEC_RATE_MASK))
7291                                         preamble_type[k] = BRCMS_MM_PREAMBLE;
7292                         }
7293
7294                         /* should be better conditionalized */
7295                         if (!is_mcs_rate(rspec[0])
7296                             && (tx_info->control.rates[0].
7297                                 flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE))
7298                                 preamble_type[k] = BRCMS_SHORT_PREAMBLE;
7299                 }
7300         } else {
7301                 for (k = 0; k < hw->max_rates; k++) {
7302                         /* Set ctrlchbw as 20Mhz */
7303                         rspec[k] &= ~RSPEC_BW_MASK;
7304                         rspec[k] |= (PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT);
7305
7306                         /* for nphy, stf of ofdm frames must follow policies */
7307                         if (BRCMS_ISNPHY(wlc->band) && is_ofdm_rate(rspec[k])) {
7308                                 rspec[k] &= ~RSPEC_STF_MASK;
7309                                 rspec[k] |= phyctl1_stf << RSPEC_STF_SHIFT;
7310                         }
7311                 }
7312         }
7313
7314         /* Reset these for use with AMPDU's */
7315         txrate[0]->count = 0;
7316         txrate[1]->count = 0;
7317
7318         /* (2) PROTECTION, may change rspec */
7319         if ((ieee80211_is_data(h->frame_control) ||
7320             ieee80211_is_mgmt(h->frame_control)) &&
7321             (phylen > wlc->RTSThresh) && !is_multicast_ether_addr(h->addr1))
7322                 use_rts = true;
7323
7324         /* (3) PLCP: determine PLCP header and MAC duration,
7325          * fill struct d11txh */
7326         brcms_c_compute_plcp(wlc, rspec[0], phylen, plcp);
7327         brcms_c_compute_plcp(wlc, rspec[1], phylen, plcp_fallback);
7328         memcpy(&txh->FragPLCPFallback,
7329                plcp_fallback, sizeof(txh->FragPLCPFallback));
7330
7331         /* Length field now put in CCK FBR CRC field */
7332         if (is_cck_rate(rspec[1])) {
7333                 txh->FragPLCPFallback[4] = phylen & 0xff;
7334                 txh->FragPLCPFallback[5] = (phylen & 0xff00) >> 8;
7335         }
7336
7337         /* MIMO-RATE: need validation ?? */
7338         mainrates = is_ofdm_rate(rspec[0]) ?
7339                         D11A_PHY_HDR_GRATE((struct ofdm_phy_hdr *) plcp) :
7340                         plcp[0];
7341
7342         /* DUR field for main rate */
7343         if (!ieee80211_is_pspoll(h->frame_control) &&
7344             !is_multicast_ether_addr(h->addr1) && !use_rifs) {
7345                 durid =
7346                     brcms_c_compute_frame_dur(wlc, rspec[0], preamble_type[0],
7347                                           next_frag_len);
7348                 h->duration_id = cpu_to_le16(durid);
7349         } else if (use_rifs) {
7350                 /* NAV protect to end of next max packet size */
7351                 durid =
7352                     (u16) brcms_c_calc_frame_time(wlc, rspec[0],
7353                                                  preamble_type[0],
7354                                                  DOT11_MAX_FRAG_LEN);
7355                 durid += RIFS_11N_TIME;
7356                 h->duration_id = cpu_to_le16(durid);
7357         }
7358
7359         /* DUR field for fallback rate */
7360         if (ieee80211_is_pspoll(h->frame_control))
7361                 txh->FragDurFallback = h->duration_id;
7362         else if (is_multicast_ether_addr(h->addr1) || use_rifs)
7363                 txh->FragDurFallback = 0;
7364         else {
7365                 durid = brcms_c_compute_frame_dur(wlc, rspec[1],
7366                                               preamble_type[1], next_frag_len);
7367                 txh->FragDurFallback = cpu_to_le16(durid);
7368         }
7369
7370         /* (4) MAC-HDR: MacTxControlLow */
7371         if (frag == 0)
7372                 mcl |= TXC_STARTMSDU;
7373
7374         if (!is_multicast_ether_addr(h->addr1))
7375                 mcl |= TXC_IMMEDACK;
7376
7377         if (wlc->band->bandtype == BRCM_BAND_5G)
7378                 mcl |= TXC_FREQBAND_5G;
7379
7380         if (CHSPEC_IS40(wlc_phy_chanspec_get(wlc->band->pi)))
7381                 mcl |= TXC_BW_40;
7382
7383         /* set AMIC bit if using hardware TKIP MIC */
7384         if (hwtkmic)
7385                 mcl |= TXC_AMIC;
7386
7387         txh->MacTxControlLow = cpu_to_le16(mcl);
7388
7389         /* MacTxControlHigh */
7390         mch = 0;
7391
7392         /* Set fallback rate preamble type */
7393         if ((preamble_type[1] == BRCMS_SHORT_PREAMBLE) ||
7394             (preamble_type[1] == BRCMS_GF_PREAMBLE)) {
7395                 if (rspec2rate(rspec[1]) != BRCM_RATE_1M)
7396                         mch |= TXC_PREAMBLE_DATA_FB_SHORT;
7397         }
7398
7399         /* MacFrameControl */
7400         memcpy(&txh->MacFrameControl, &h->frame_control, sizeof(u16));
7401         txh->TxFesTimeNormal = cpu_to_le16(0);
7402
7403         txh->TxFesTimeFallback = cpu_to_le16(0);
7404
7405         /* TxFrameRA */
7406         memcpy(&txh->TxFrameRA, &h->addr1, ETH_ALEN);
7407
7408         /* TxFrameID */
7409         txh->TxFrameID = cpu_to_le16(frameid);
7410
7411         /*
7412          * TxStatus, Note the case of recreating the first frag of a suppressed
7413          * frame then we may need to reset the retry cnt's via the status reg
7414          */
7415         txh->TxStatus = cpu_to_le16(status);
7416
7417         /*
7418          * extra fields for ucode AMPDU aggregation, the new fields are added to
7419          * the END of previous structure so that it's compatible in driver.
7420          */
7421         txh->MaxNMpdus = cpu_to_le16(0);
7422         txh->MaxABytes_MRT = cpu_to_le16(0);
7423         txh->MaxABytes_FBR = cpu_to_le16(0);
7424         txh->MinMBytes = cpu_to_le16(0);
7425
7426         /* (5) RTS/CTS: determine RTS/CTS PLCP header and MAC duration,
7427          * furnish struct d11txh */
7428         /* RTS PLCP header and RTS frame */
7429         if (use_rts || use_cts) {
7430                 if (use_rts && use_cts)
7431                         use_cts = false;
7432
7433                 for (k = 0; k < 2; k++) {
7434                         rts_rspec[k] = brcms_c_rspec_to_rts_rspec(wlc, rspec[k],
7435                                                               false,
7436                                                               mimo_ctlchbw);
7437                 }
7438
7439                 if (!is_ofdm_rate(rts_rspec[0]) &&
7440                     !((rspec2rate(rts_rspec[0]) == BRCM_RATE_1M) ||
7441                       (wlc->PLCPHdr_override == BRCMS_PLCP_LONG))) {
7442                         rts_preamble_type[0] = BRCMS_SHORT_PREAMBLE;
7443                         mch |= TXC_PREAMBLE_RTS_MAIN_SHORT;
7444                 }
7445
7446                 if (!is_ofdm_rate(rts_rspec[1]) &&
7447                     !((rspec2rate(rts_rspec[1]) == BRCM_RATE_1M) ||
7448                       (wlc->PLCPHdr_override == BRCMS_PLCP_LONG))) {
7449                         rts_preamble_type[1] = BRCMS_SHORT_PREAMBLE;
7450                         mch |= TXC_PREAMBLE_RTS_FB_SHORT;
7451                 }
7452
7453                 /* RTS/CTS additions to MacTxControlLow */
7454                 if (use_cts) {
7455                         txh->MacTxControlLow |= cpu_to_le16(TXC_SENDCTS);
7456                 } else {
7457                         txh->MacTxControlLow |= cpu_to_le16(TXC_SENDRTS);
7458                         txh->MacTxControlLow |= cpu_to_le16(TXC_LONGFRAME);
7459                 }
7460
7461                 /* RTS PLCP header */
7462                 rts_plcp = txh->RTSPhyHeader;
7463                 if (use_cts)
7464                         rts_phylen = DOT11_CTS_LEN + FCS_LEN;
7465                 else
7466                         rts_phylen = DOT11_RTS_LEN + FCS_LEN;
7467
7468                 brcms_c_compute_plcp(wlc, rts_rspec[0], rts_phylen, rts_plcp);
7469
7470                 /* fallback rate version of RTS PLCP header */
7471                 brcms_c_compute_plcp(wlc, rts_rspec[1], rts_phylen,
7472                                  rts_plcp_fallback);
7473                 memcpy(&txh->RTSPLCPFallback, rts_plcp_fallback,
7474                        sizeof(txh->RTSPLCPFallback));
7475
7476                 /* RTS frame fields... */
7477                 rts = (struct ieee80211_rts *)&txh->rts_frame;
7478
7479                 durid = brcms_c_compute_rtscts_dur(wlc, use_cts, rts_rspec[0],
7480                                                rspec[0], rts_preamble_type[0],
7481                                                preamble_type[0], phylen, false);
7482                 rts->duration = cpu_to_le16(durid);
7483                 /* fallback rate version of RTS DUR field */
7484                 durid = brcms_c_compute_rtscts_dur(wlc, use_cts,
7485                                                rts_rspec[1], rspec[1],
7486                                                rts_preamble_type[1],
7487                                                preamble_type[1], phylen, false);
7488                 txh->RTSDurFallback = cpu_to_le16(durid);
7489
7490                 if (use_cts) {
7491                         rts->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
7492                                                          IEEE80211_STYPE_CTS);
7493
7494                         memcpy(&rts->ra, &h->addr2, ETH_ALEN);
7495                 } else {
7496                         rts->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
7497                                                          IEEE80211_STYPE_RTS);
7498
7499                         memcpy(&rts->ra, &h->addr1, 2 * ETH_ALEN);
7500                 }
7501
7502                 /* mainrate
7503                  *    low 8 bits: main frag rate/mcs,
7504                  *    high 8 bits: rts/cts rate/mcs
7505                  */
7506                 mainrates |= (is_ofdm_rate(rts_rspec[0]) ?
7507                                 D11A_PHY_HDR_GRATE(
7508                                         (struct ofdm_phy_hdr *) rts_plcp) :
7509                                 rts_plcp[0]) << 8;
7510         } else {
7511                 memset((char *)txh->RTSPhyHeader, 0, D11_PHY_HDR_LEN);
7512                 memset((char *)&txh->rts_frame, 0,
7513                         sizeof(struct ieee80211_rts));
7514                 memset((char *)txh->RTSPLCPFallback, 0,
7515                       sizeof(txh->RTSPLCPFallback));
7516                 txh->RTSDurFallback = 0;
7517         }
7518
7519 #ifdef SUPPORT_40MHZ
7520         /* add null delimiter count */
7521         if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && is_mcs_rate(rspec))
7522                 txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] =
7523                    brcm_c_ampdu_null_delim_cnt(wlc->ampdu, scb, rspec, phylen);
7524
7525 #endif
7526
7527         /*
7528          * Now that RTS/RTS FB preamble types are updated, write
7529          * the final value
7530          */
7531         txh->MacTxControlHigh = cpu_to_le16(mch);
7532
7533         /*
7534          * MainRates (both the rts and frag plcp rates have
7535          * been calculated now)
7536          */
7537         txh->MainRates = cpu_to_le16(mainrates);
7538
7539         /* XtraFrameTypes */
7540         xfts = frametype(rspec[1], wlc->mimoft);
7541         xfts |= (frametype(rts_rspec[0], wlc->mimoft) << XFTS_RTS_FT_SHIFT);
7542         xfts |= (frametype(rts_rspec[1], wlc->mimoft) << XFTS_FBRRTS_FT_SHIFT);
7543         xfts |= CHSPEC_CHANNEL(wlc_phy_chanspec_get(wlc->band->pi)) <<
7544                                                              XFTS_CHANNEL_SHIFT;
7545         txh->XtraFrameTypes = cpu_to_le16(xfts);
7546
7547         /* PhyTxControlWord */
7548         phyctl = frametype(rspec[0], wlc->mimoft);
7549         if ((preamble_type[0] == BRCMS_SHORT_PREAMBLE) ||
7550             (preamble_type[0] == BRCMS_GF_PREAMBLE)) {
7551                 if (rspec2rate(rspec[0]) != BRCM_RATE_1M)
7552                         phyctl |= PHY_TXC_SHORT_HDR;
7553         }
7554
7555         /* phytxant is properly bit shifted */
7556         phyctl |= brcms_c_stf_d11hdrs_phyctl_txant(wlc, rspec[0]);
7557         txh->PhyTxControlWord = cpu_to_le16(phyctl);
7558
7559         /* PhyTxControlWord_1 */
7560         if (BRCMS_PHY_11N_CAP(wlc->band)) {
7561                 u16 phyctl1 = 0;
7562
7563                 phyctl1 = brcms_c_phytxctl1_calc(wlc, rspec[0]);
7564                 txh->PhyTxControlWord_1 = cpu_to_le16(phyctl1);
7565                 phyctl1 = brcms_c_phytxctl1_calc(wlc, rspec[1]);
7566                 txh->PhyTxControlWord_1_Fbr = cpu_to_le16(phyctl1);
7567
7568                 if (use_rts || use_cts) {
7569                         phyctl1 = brcms_c_phytxctl1_calc(wlc, rts_rspec[0]);
7570                         txh->PhyTxControlWord_1_Rts = cpu_to_le16(phyctl1);
7571                         phyctl1 = brcms_c_phytxctl1_calc(wlc, rts_rspec[1]);
7572                         txh->PhyTxControlWord_1_FbrRts = cpu_to_le16(phyctl1);
7573                 }
7574
7575                 /*
7576                  * For mcs frames, if mixedmode(overloaded with long preamble)
7577                  * is going to be set, fill in non-zero MModeLen and/or
7578                  * MModeFbrLen it will be unnecessary if they are separated
7579                  */
7580                 if (is_mcs_rate(rspec[0]) &&
7581                     (preamble_type[0] == BRCMS_MM_PREAMBLE)) {
7582                         u16 mmodelen =
7583                             brcms_c_calc_lsig_len(wlc, rspec[0], phylen);
7584                         txh->MModeLen = cpu_to_le16(mmodelen);
7585                 }
7586
7587                 if (is_mcs_rate(rspec[1]) &&
7588                     (preamble_type[1] == BRCMS_MM_PREAMBLE)) {
7589                         u16 mmodefbrlen =
7590                             brcms_c_calc_lsig_len(wlc, rspec[1], phylen);
7591                         txh->MModeFbrLen = cpu_to_le16(mmodefbrlen);
7592                 }
7593         }
7594
7595         ac = skb_get_queue_mapping(p);
7596         if ((scb->flags & SCB_WMECAP) && qos && wlc->edcf_txop[ac]) {
7597                 uint frag_dur, dur, dur_fallback;
7598
7599                 /* WME: Update TXOP threshold */
7600                 if (!(tx_info->flags & IEEE80211_TX_CTL_AMPDU) && frag == 0) {
7601                         frag_dur =
7602                             brcms_c_calc_frame_time(wlc, rspec[0],
7603                                         preamble_type[0], phylen);
7604
7605                         if (rts) {
7606                                 /* 1 RTS or CTS-to-self frame */
7607                                 dur =
7608                                     brcms_c_calc_cts_time(wlc, rts_rspec[0],
7609                                                       rts_preamble_type[0]);
7610                                 dur_fallback =
7611                                     brcms_c_calc_cts_time(wlc, rts_rspec[1],
7612                                                       rts_preamble_type[1]);
7613                                 /* (SIFS + CTS) + SIFS + frame + SIFS + ACK */
7614                                 dur += le16_to_cpu(rts->duration);
7615                                 dur_fallback +=
7616                                         le16_to_cpu(txh->RTSDurFallback);
7617                         } else if (use_rifs) {
7618                                 dur = frag_dur;
7619                                 dur_fallback = 0;
7620                         } else {
7621                                 /* frame + SIFS + ACK */
7622                                 dur = frag_dur;
7623                                 dur +=
7624                                     brcms_c_compute_frame_dur(wlc, rspec[0],
7625                                                           preamble_type[0], 0);
7626
7627                                 dur_fallback =
7628                                     brcms_c_calc_frame_time(wlc, rspec[1],
7629                                                         preamble_type[1],
7630                                                         phylen);
7631                                 dur_fallback +=
7632                                     brcms_c_compute_frame_dur(wlc, rspec[1],
7633                                                           preamble_type[1], 0);
7634                         }
7635                         /* NEED to set TxFesTimeNormal (hard) */
7636                         txh->TxFesTimeNormal = cpu_to_le16((u16) dur);
7637                         /*
7638                          * NEED to set fallback rate version of
7639                          * TxFesTimeNormal (hard)
7640                          */
7641                         txh->TxFesTimeFallback =
7642                                 cpu_to_le16((u16) dur_fallback);
7643
7644                         /*
7645                          * update txop byte threshold (txop minus intraframe
7646                          * overhead)
7647                          */
7648                         if (wlc->edcf_txop[ac] >= (dur - frag_dur)) {
7649                                 uint newfragthresh;
7650
7651                                 newfragthresh =
7652                                     brcms_c_calc_frame_len(wlc,
7653                                         rspec[0], preamble_type[0],
7654                                         (wlc->edcf_txop[ac] -
7655                                                 (dur - frag_dur)));
7656                                 /* range bound the fragthreshold */
7657                                 if (newfragthresh < DOT11_MIN_FRAG_LEN)
7658                                         newfragthresh =
7659                                             DOT11_MIN_FRAG_LEN;
7660                                 else if (newfragthresh >
7661                                          wlc->usr_fragthresh)
7662                                         newfragthresh =
7663                                             wlc->usr_fragthresh;
7664                                 /* update the fragthresh and do txc update */
7665                                 if (wlc->fragthresh[queue] !=
7666                                     (u16) newfragthresh)
7667                                         wlc->fragthresh[queue] =
7668                                             (u16) newfragthresh;
7669                         } else {
7670                                 wiphy_err(wlc->wiphy, "wl%d: %s txop invalid "
7671                                           "for rate %d\n",
7672                                           wlc->pub->unit, fifo_names[queue],
7673                                           rspec2rate(rspec[0]));
7674                         }
7675
7676                         if (dur > wlc->edcf_txop[ac])
7677                                 wiphy_err(wlc->wiphy, "wl%d: %s: %s txop "
7678                                           "exceeded phylen %d/%d dur %d/%d\n",
7679                                           wlc->pub->unit, __func__,
7680                                           fifo_names[queue],
7681                                           phylen, wlc->fragthresh[queue],
7682                                           dur, wlc->edcf_txop[ac]);
7683                 }
7684         }
7685
7686         return 0;
7687 }
7688
7689 void brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu,
7690                               struct ieee80211_hw *hw)
7691 {
7692         u8 prio;
7693         uint fifo;
7694         struct scb *scb = &wlc->pri_scb;
7695         struct ieee80211_hdr *d11_header = (struct ieee80211_hdr *)(sdu->data);
7696
7697         /*
7698          * 802.11 standard requires management traffic
7699          * to go at highest priority
7700          */
7701         prio = ieee80211_is_data(d11_header->frame_control) ? sdu->priority :
7702                 MAXPRIO;
7703         fifo = prio2fifo[prio];
7704         if (brcms_c_d11hdrs_mac80211(wlc, hw, sdu, scb, 0, 1, fifo, 0))
7705                 return;
7706         brcms_c_txq_enq(wlc, scb, sdu, BRCMS_PRIO_TO_PREC(prio));
7707         brcms_c_send_q(wlc);
7708 }
7709
7710 void brcms_c_send_q(struct brcms_c_info *wlc)
7711 {
7712         struct sk_buff *pkt[DOT11_MAXNUMFRAGS];
7713         int prec;
7714         u16 prec_map;
7715         int err = 0, i, count;
7716         uint fifo;
7717         struct brcms_txq_info *qi = wlc->pkt_queue;
7718         struct pktq *q = &qi->q;
7719         struct ieee80211_tx_info *tx_info;
7720
7721         prec_map = wlc->tx_prec_map;
7722
7723         /* Send all the enq'd pkts that we can.
7724          * Dequeue packets with precedence with empty HW fifo only
7725          */
7726         while (prec_map && (pkt[0] = brcmu_pktq_mdeq(q, prec_map, &prec))) {
7727                 tx_info = IEEE80211_SKB_CB(pkt[0]);
7728                 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
7729                         err = brcms_c_sendampdu(wlc->ampdu, qi, pkt, prec);
7730                 } else {
7731                         count = 1;
7732                         err = brcms_c_prep_pdu(wlc, pkt[0], &fifo);
7733                         if (!err) {
7734                                 for (i = 0; i < count; i++)
7735                                         brcms_c_txfifo(wlc, fifo, pkt[i], true,
7736                                                        1);
7737                         }
7738                 }
7739
7740                 if (err == -EBUSY) {
7741                         brcmu_pktq_penq_head(q, prec, pkt[0]);
7742                         /*
7743                          * If send failed due to any other reason than a
7744                          * change in HW FIFO condition, quit. Otherwise,
7745                          * read the new prec_map!
7746                          */
7747                         if (prec_map == wlc->tx_prec_map)
7748                                 break;
7749                         prec_map = wlc->tx_prec_map;
7750                 }
7751         }
7752 }
7753
7754 void
7755 brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p,
7756                bool commit, s8 txpktpend)
7757 {
7758         u16 frameid = INVALIDFID;
7759         struct d11txh *txh;
7760
7761         txh = (struct d11txh *) (p->data);
7762
7763         /* When a BC/MC frame is being committed to the BCMC fifo
7764          * via DMA (NOT PIO), update ucode or BSS info as appropriate.
7765          */
7766         if (fifo == TX_BCMC_FIFO)
7767                 frameid = le16_to_cpu(txh->TxFrameID);
7768
7769         /*
7770          * Bump up pending count for if not using rpc. If rpc is
7771          * used, this will be handled in brcms_b_txfifo()
7772          */
7773         if (commit) {
7774                 wlc->core->txpktpend[fifo] += txpktpend;
7775                 BCMMSG(wlc->wiphy, "pktpend inc %d to %d\n",
7776                          txpktpend, wlc->core->txpktpend[fifo]);
7777         }
7778
7779         /* Commit BCMC sequence number in the SHM frame ID location */
7780         if (frameid != INVALIDFID) {
7781                 /*
7782                  * To inform the ucode of the last mcast frame posted
7783                  * so that it can clear moredata bit
7784                  */
7785                 brcms_b_write_shm(wlc->hw, M_BCMC_FID, frameid);
7786         }
7787
7788         if (dma_txfast(wlc->hw->di[fifo], p, commit) < 0)
7789                 wiphy_err(wlc->wiphy, "txfifo: fatal, toss frames !!!\n");
7790 }
7791
7792 /*
7793  * Compute PLCP, but only requires actual rate and length of pkt.
7794  * Rate is given in the driver standard multiple of 500 kbps.
7795  * le is set for 11 Mbps rate if necessary.
7796  * Broken out for PRQ.
7797  */
7798
7799 static void brcms_c_cck_plcp_set(struct brcms_c_info *wlc, int rate_500,
7800                              uint length, u8 *plcp)
7801 {
7802         u16 usec = 0;
7803         u8 le = 0;
7804
7805         switch (rate_500) {
7806         case BRCM_RATE_1M:
7807                 usec = length << 3;
7808                 break;
7809         case BRCM_RATE_2M:
7810                 usec = length << 2;
7811                 break;
7812         case BRCM_RATE_5M5:
7813                 usec = (length << 4) / 11;
7814                 if ((length << 4) - (usec * 11) > 0)
7815                         usec++;
7816                 break;
7817         case BRCM_RATE_11M:
7818                 usec = (length << 3) / 11;
7819                 if ((length << 3) - (usec * 11) > 0) {
7820                         usec++;
7821                         if ((usec * 11) - (length << 3) >= 8)
7822                                 le = D11B_PLCP_SIGNAL_LE;
7823                 }
7824                 break;
7825
7826         default:
7827                 wiphy_err(wlc->wiphy,
7828                           "brcms_c_cck_plcp_set: unsupported rate %d\n",
7829                           rate_500);
7830                 rate_500 = BRCM_RATE_1M;
7831                 usec = length << 3;
7832                 break;
7833         }
7834         /* PLCP signal byte */
7835         plcp[0] = rate_500 * 5; /* r (500kbps) * 5 == r (100kbps) */
7836         /* PLCP service byte */
7837         plcp[1] = (u8) (le | D11B_PLCP_SIGNAL_LOCKED);
7838         /* PLCP length u16, little endian */
7839         plcp[2] = usec & 0xff;
7840         plcp[3] = (usec >> 8) & 0xff;
7841         /* PLCP CRC16 */
7842         plcp[4] = 0;
7843         plcp[5] = 0;
7844 }
7845
7846 /* Rate: 802.11 rate code, length: PSDU length in octets */
7847 static void brcms_c_compute_mimo_plcp(u32 rspec, uint length, u8 *plcp)
7848 {
7849         u8 mcs = (u8) (rspec & RSPEC_RATE_MASK);
7850         plcp[0] = mcs;
7851         if (rspec_is40mhz(rspec) || (mcs == 32))
7852                 plcp[0] |= MIMO_PLCP_40MHZ;
7853         BRCMS_SET_MIMO_PLCP_LEN(plcp, length);
7854         plcp[3] = rspec_mimoplcp3(rspec); /* rspec already holds this byte */
7855         plcp[3] |= 0x7; /* set smoothing, not sounding ppdu & reserved */
7856         plcp[4] = 0; /* number of extension spatial streams bit 0 & 1 */
7857         plcp[5] = 0;
7858 }
7859
7860 /* Rate: 802.11 rate code, length: PSDU length in octets */
7861 static void
7862 brcms_c_compute_ofdm_plcp(u32 rspec, u32 length, u8 *plcp)
7863 {
7864         u8 rate_signal;
7865         u32 tmp = 0;
7866         int rate = rspec2rate(rspec);
7867
7868         /*
7869          * encode rate per 802.11a-1999 sec 17.3.4.1, with lsb
7870          * transmitted first
7871          */
7872         rate_signal = rate_info[rate] & BRCMS_RATE_MASK;
7873         memset(plcp, 0, D11_PHY_HDR_LEN);
7874         D11A_PHY_HDR_SRATE((struct ofdm_phy_hdr *) plcp, rate_signal);
7875
7876         tmp = (length & 0xfff) << 5;
7877         plcp[2] |= (tmp >> 16) & 0xff;
7878         plcp[1] |= (tmp >> 8) & 0xff;
7879         plcp[0] |= tmp & 0xff;
7880
7881         return;
7882 }
7883
7884 /* Rate: 802.11 rate code, length: PSDU length in octets */
7885 static void brcms_c_compute_cck_plcp(struct brcms_c_info *wlc, u32 rspec,
7886                                  uint length, u8 *plcp)
7887 {
7888         int rate = rspec2rate(rspec);
7889
7890         brcms_c_cck_plcp_set(wlc, rate, length, plcp);
7891 }
7892
7893 void
7894 brcms_c_compute_plcp(struct brcms_c_info *wlc, u32 rspec,
7895                      uint length, u8 *plcp)
7896 {
7897         if (is_mcs_rate(rspec))
7898                 brcms_c_compute_mimo_plcp(rspec, length, plcp);
7899         else if (is_ofdm_rate(rspec))
7900                 brcms_c_compute_ofdm_plcp(rspec, length, plcp);
7901         else
7902                 brcms_c_compute_cck_plcp(wlc, rspec, length, plcp);
7903         return;
7904 }
7905
7906 /* brcms_c_compute_rtscts_dur()
7907  *
7908  * Calculate the 802.11 MAC header DUR field for an RTS or CTS frame
7909  * DUR for normal RTS/CTS w/ frame = 3 SIFS + 1 CTS + next frame time + 1 ACK
7910  * DUR for CTS-TO-SELF w/ frame    = 2 SIFS         + next frame time + 1 ACK
7911  *
7912  * cts                  cts-to-self or rts/cts
7913  * rts_rate             rts or cts rate in unit of 500kbps
7914  * rate                 next MPDU rate in unit of 500kbps
7915  * frame_len            next MPDU frame length in bytes
7916  */
7917 u16
7918 brcms_c_compute_rtscts_dur(struct brcms_c_info *wlc, bool cts_only,
7919                            u32 rts_rate,
7920                            u32 frame_rate, u8 rts_preamble_type,
7921                            u8 frame_preamble_type, uint frame_len, bool ba)
7922 {
7923         u16 dur, sifs;
7924
7925         sifs = get_sifs(wlc->band);
7926
7927         if (!cts_only) {
7928                 /* RTS/CTS */
7929                 dur = 3 * sifs;
7930                 dur +=
7931                     (u16) brcms_c_calc_cts_time(wlc, rts_rate,
7932                                                rts_preamble_type);
7933         } else {
7934                 /* CTS-TO-SELF */
7935                 dur = 2 * sifs;
7936         }
7937
7938         dur +=
7939             (u16) brcms_c_calc_frame_time(wlc, frame_rate, frame_preamble_type,
7940                                          frame_len);
7941         if (ba)
7942                 dur +=
7943                     (u16) brcms_c_calc_ba_time(wlc, frame_rate,
7944                                               BRCMS_SHORT_PREAMBLE);
7945         else
7946                 dur +=
7947                     (u16) brcms_c_calc_ack_time(wlc, frame_rate,
7948                                                frame_preamble_type);
7949         return dur;
7950 }
7951
7952 u16 brcms_c_phytxctl1_calc(struct brcms_c_info *wlc, u32 rspec)
7953 {
7954         u16 phyctl1 = 0;
7955         u16 bw;
7956
7957         if (BRCMS_ISLCNPHY(wlc->band)) {
7958                 bw = PHY_TXC1_BW_20MHZ;
7959         } else {
7960                 bw = rspec_get_bw(rspec);
7961                 /* 10Mhz is not supported yet */
7962                 if (bw < PHY_TXC1_BW_20MHZ) {
7963                         wiphy_err(wlc->wiphy, "phytxctl1_calc: bw %d is "
7964                                   "not supported yet, set to 20L\n", bw);
7965                         bw = PHY_TXC1_BW_20MHZ;
7966                 }
7967         }
7968
7969         if (is_mcs_rate(rspec)) {
7970                 uint mcs = rspec & RSPEC_RATE_MASK;
7971
7972                 /* bw, stf, coding-type is part of rspec_phytxbyte2 returns */
7973                 phyctl1 = rspec_phytxbyte2(rspec);
7974                 /* set the upper byte of phyctl1 */
7975                 phyctl1 |= (mcs_table[mcs].tx_phy_ctl3 << 8);
7976         } else if (is_cck_rate(rspec) && !BRCMS_ISLCNPHY(wlc->band)
7977                    && !BRCMS_ISSSLPNPHY(wlc->band)) {
7978                 /*
7979                  * In CCK mode LPPHY overloads OFDM Modulation bits with CCK
7980                  * Data Rate. Eventually MIMOPHY would also be converted to
7981                  * this format
7982                  */
7983                 /* 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps */
7984                 phyctl1 = (bw | (rspec_stf(rspec) << PHY_TXC1_MODE_SHIFT));
7985         } else {                /* legacy OFDM/CCK */
7986                 s16 phycfg;
7987                 /* get the phyctl byte from rate phycfg table */
7988                 phycfg = brcms_c_rate_legacy_phyctl(rspec2rate(rspec));
7989                 if (phycfg == -1) {
7990                         wiphy_err(wlc->wiphy, "phytxctl1_calc: wrong "
7991                                   "legacy OFDM/CCK rate\n");
7992                         phycfg = 0;
7993                 }
7994                 /* set the upper byte of phyctl1 */
7995                 phyctl1 =
7996                     (bw | (phycfg << 8) |
7997                      (rspec_stf(rspec) << PHY_TXC1_MODE_SHIFT));
7998         }
7999         return phyctl1;
8000 }
8001
8002 u32
8003 brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, u32 rspec,
8004                            bool use_rspec, u16 mimo_ctlchbw)
8005 {
8006         u32 rts_rspec = 0;
8007
8008         if (use_rspec)
8009                 /* use frame rate as rts rate */
8010                 rts_rspec = rspec;
8011         else if (wlc->band->gmode && wlc->protection->_g && !is_cck_rate(rspec))
8012                 /* Use 11Mbps as the g protection RTS target rate and fallback.
8013                  * Use the brcms_basic_rate() lookup to find the best basic rate
8014                  * under the target in case 11 Mbps is not Basic.
8015                  * 6 and 9 Mbps are not usually selected by rate selection, but
8016                  * even if the OFDM rate we are protecting is 6 or 9 Mbps, 11
8017                  * is more robust.
8018                  */
8019                 rts_rspec = brcms_basic_rate(wlc, BRCM_RATE_11M);
8020         else
8021                 /* calculate RTS rate and fallback rate based on the frame rate
8022                  * RTS must be sent at a basic rate since it is a
8023                  * control frame, sec 9.6 of 802.11 spec
8024                  */
8025                 rts_rspec = brcms_basic_rate(wlc, rspec);
8026
8027         if (BRCMS_PHY_11N_CAP(wlc->band)) {
8028                 /* set rts txbw to correct side band */
8029                 rts_rspec &= ~RSPEC_BW_MASK;
8030
8031                 /*
8032                  * if rspec/rspec_fallback is 40MHz, then send RTS on both
8033                  * 20MHz channel (DUP), otherwise send RTS on control channel
8034                  */
8035                 if (rspec_is40mhz(rspec) && !is_cck_rate(rts_rspec))
8036                         rts_rspec |= (PHY_TXC1_BW_40MHZ_DUP << RSPEC_BW_SHIFT);
8037                 else
8038                         rts_rspec |= (mimo_ctlchbw << RSPEC_BW_SHIFT);
8039
8040                 /* pick siso/cdd as default for ofdm */
8041                 if (is_ofdm_rate(rts_rspec)) {
8042                         rts_rspec &= ~RSPEC_STF_MASK;
8043                         rts_rspec |= (wlc->stf->ss_opmode << RSPEC_STF_SHIFT);
8044                 }
8045         }
8046         return rts_rspec;
8047 }
8048
8049 void brcms_c_tbtt(struct brcms_c_info *wlc)
8050 {
8051         if (!wlc->bsscfg->BSS)
8052                 /*
8053                  * DirFrmQ is now valid...defer setting until end
8054                  * of ATIM window
8055                  */
8056                 wlc->qvalid |= MCMD_DIRFRMQVAL;
8057 }
8058
8059 void
8060 brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo, s8 txpktpend)
8061 {
8062         wlc->core->txpktpend[fifo] -= txpktpend;
8063         BCMMSG(wlc->wiphy, "pktpend dec %d to %d\n", txpktpend,
8064                wlc->core->txpktpend[fifo]);
8065
8066         /* There is more room; mark precedences related to this FIFO sendable */
8067         wlc->tx_prec_map |= wlc->fifo2prec_map[fifo];
8068
8069         /* figure out which bsscfg is being worked on... */
8070 }
8071
8072 /* Update beacon listen interval in shared memory */
8073 void brcms_c_bcn_li_upd(struct brcms_c_info *wlc)
8074 {
8075         /* wake up every DTIM is the default */
8076         if (wlc->bcn_li_dtim == 1)
8077                 brcms_c_write_shm(wlc, M_BCN_LI, 0);
8078         else
8079                 brcms_c_write_shm(wlc, M_BCN_LI,
8080                               (wlc->bcn_li_dtim << 8) | wlc->bcn_li_bcn);
8081 }
8082
8083 static void
8084 brcms_b_read_tsf(struct brcms_hardware *wlc_hw, u32 *tsf_l_ptr,
8085                   u32 *tsf_h_ptr)
8086 {
8087         struct d11regs *regs = wlc_hw->regs;
8088
8089         /* read the tsf timer low, then high to get an atomic read */
8090         *tsf_l_ptr = R_REG(&regs->tsf_timerlow);
8091         *tsf_h_ptr = R_REG(&regs->tsf_timerhigh);
8092
8093         return;
8094 }
8095
8096 /*
8097  * recover 64bit TSF value from the 16bit TSF value in the rx header
8098  * given the assumption that the TSF passed in header is within 65ms
8099  * of the current tsf.
8100  *
8101  * 6       5       4       4       3       2       1
8102  * 3.......6.......8.......0.......2.......4.......6.......8......0
8103  * |<---------- tsf_h ----------->||<--- tsf_l -->||<-RxTSFTime ->|
8104  *
8105  * The RxTSFTime are the lowest 16 bits and provided by the ucode. The
8106  * tsf_l is filled in by brcms_b_recv, which is done earlier in the
8107  * receive call sequence after rx interrupt. Only the higher 16 bits
8108  * are used. Finally, the tsf_h is read from the tsf register.
8109  */
8110 static u64 brcms_c_recover_tsf64(struct brcms_c_info *wlc,
8111                                  struct d11rxhdr *rxh)
8112 {
8113         u32 tsf_h, tsf_l;
8114         u16 rx_tsf_0_15, rx_tsf_16_31;
8115
8116         brcms_b_read_tsf(wlc->hw, &tsf_l, &tsf_h);
8117
8118         rx_tsf_16_31 = (u16)(tsf_l >> 16);
8119         rx_tsf_0_15 = rxh->RxTSFTime;
8120
8121         /*
8122          * a greater tsf time indicates the low 16 bits of
8123          * tsf_l wrapped, so decrement the high 16 bits.
8124          */
8125         if ((u16)tsf_l < rx_tsf_0_15) {
8126                 rx_tsf_16_31 -= 1;
8127                 if (rx_tsf_16_31 == 0xffff)
8128                         tsf_h -= 1;
8129         }
8130
8131         return ((u64)tsf_h << 32) | (((u32)rx_tsf_16_31 << 16) + rx_tsf_0_15);
8132 }
8133
8134 static void
8135 prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
8136                      struct sk_buff *p,
8137                      struct ieee80211_rx_status *rx_status)
8138 {
8139         int preamble;
8140         int channel;
8141         u32 rspec;
8142         unsigned char *plcp;
8143
8144         /* fill in TSF and flag its presence */
8145         rx_status->mactime = brcms_c_recover_tsf64(wlc, rxh);
8146         rx_status->flag |= RX_FLAG_MACTIME_MPDU;
8147
8148         channel = BRCMS_CHAN_CHANNEL(rxh->RxChan);
8149
8150         if (channel > 14) {
8151                 rx_status->band = IEEE80211_BAND_5GHZ;
8152                 rx_status->freq = ieee80211_ofdm_chan_to_freq(
8153                                         WF_CHAN_FACTOR_5_G/2, channel);
8154
8155         } else {
8156                 rx_status->band = IEEE80211_BAND_2GHZ;
8157                 rx_status->freq = ieee80211_dsss_chan_to_freq(channel);
8158         }
8159
8160         rx_status->signal = wlc_phy_rssi_compute(wlc->hw->band->pi, rxh);
8161
8162         /* noise */
8163         /* qual */
8164         rx_status->antenna =
8165                 (rxh->PhyRxStatus_0 & PRXS0_RXANT_UPSUBBAND) ? 1 : 0;
8166
8167         plcp = p->data;
8168
8169         rspec = brcms_c_compute_rspec(rxh, plcp);
8170         if (is_mcs_rate(rspec)) {
8171                 rx_status->rate_idx = rspec & RSPEC_RATE_MASK;
8172                 rx_status->flag |= RX_FLAG_HT;
8173                 if (rspec_is40mhz(rspec))
8174                         rx_status->flag |= RX_FLAG_40MHZ;
8175         } else {
8176                 switch (rspec2rate(rspec)) {
8177                 case BRCM_RATE_1M:
8178                         rx_status->rate_idx = 0;
8179                         break;
8180                 case BRCM_RATE_2M:
8181                         rx_status->rate_idx = 1;
8182                         break;
8183                 case BRCM_RATE_5M5:
8184                         rx_status->rate_idx = 2;
8185                         break;
8186                 case BRCM_RATE_11M:
8187                         rx_status->rate_idx = 3;
8188                         break;
8189                 case BRCM_RATE_6M:
8190                         rx_status->rate_idx = 4;
8191                         break;
8192                 case BRCM_RATE_9M:
8193                         rx_status->rate_idx = 5;
8194                         break;
8195                 case BRCM_RATE_12M:
8196                         rx_status->rate_idx = 6;
8197                         break;
8198                 case BRCM_RATE_18M:
8199                         rx_status->rate_idx = 7;
8200                         break;
8201                 case BRCM_RATE_24M:
8202                         rx_status->rate_idx = 8;
8203                         break;
8204                 case BRCM_RATE_36M:
8205                         rx_status->rate_idx = 9;
8206                         break;
8207                 case BRCM_RATE_48M:
8208                         rx_status->rate_idx = 10;
8209                         break;
8210                 case BRCM_RATE_54M:
8211                         rx_status->rate_idx = 11;
8212                         break;
8213                 default:
8214                         wiphy_err(wlc->wiphy, "%s: Unknown rate\n", __func__);
8215                 }
8216
8217                 /*
8218                  * For 5GHz, we should decrease the index as it is
8219                  * a subset of the 2.4G rates. See bitrates field
8220                  * of brcms_band_5GHz_nphy (in mac80211_if.c).
8221                  */
8222                 if (rx_status->band == IEEE80211_BAND_5GHZ)
8223                         rx_status->rate_idx -= BRCMS_LEGACY_5G_RATE_OFFSET;
8224
8225                 /* Determine short preamble and rate_idx */
8226                 preamble = 0;
8227                 if (is_cck_rate(rspec)) {
8228                         if (rxh->PhyRxStatus_0 & PRXS0_SHORTH)
8229                                 rx_status->flag |= RX_FLAG_SHORTPRE;
8230                 } else if (is_ofdm_rate(rspec)) {
8231                         rx_status->flag |= RX_FLAG_SHORTPRE;
8232                 } else {
8233                         wiphy_err(wlc->wiphy, "%s: Unknown modulation\n",
8234                                   __func__);
8235                 }
8236         }
8237
8238         if (plcp3_issgi(plcp[3]))
8239                 rx_status->flag |= RX_FLAG_SHORT_GI;
8240
8241         if (rxh->RxStatus1 & RXS_DECERR) {
8242                 rx_status->flag |= RX_FLAG_FAILED_PLCP_CRC;
8243                 wiphy_err(wlc->wiphy, "%s:  RX_FLAG_FAILED_PLCP_CRC\n",
8244                           __func__);
8245         }
8246         if (rxh->RxStatus1 & RXS_FCSERR) {
8247                 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
8248                 wiphy_err(wlc->wiphy, "%s:  RX_FLAG_FAILED_FCS_CRC\n",
8249                           __func__);
8250         }
8251 }
8252
8253 static void
8254 brcms_c_recvctl(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
8255                 struct sk_buff *p)
8256 {
8257         int len_mpdu;
8258         struct ieee80211_rx_status rx_status;
8259
8260         memset(&rx_status, 0, sizeof(rx_status));
8261         prep_mac80211_status(wlc, rxh, p, &rx_status);
8262
8263         /* mac header+body length, exclude CRC and plcp header */
8264         len_mpdu = p->len - D11_PHY_HDR_LEN - FCS_LEN;
8265         skb_pull(p, D11_PHY_HDR_LEN);
8266         __skb_trim(p, len_mpdu);
8267
8268         memcpy(IEEE80211_SKB_RXCB(p), &rx_status, sizeof(rx_status));
8269         ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p);
8270         return;
8271 }
8272
8273 /* Process received frames */
8274 /*
8275  * Return true if more frames need to be processed. false otherwise.
8276  * Param 'bound' indicates max. # frames to process before break out.
8277  */
8278 void brcms_c_recv(struct brcms_c_info *wlc, struct sk_buff *p)
8279 {
8280         struct d11rxhdr *rxh;
8281         struct ieee80211_hdr *h;
8282         uint len;
8283         bool is_amsdu;
8284
8285         BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
8286
8287         /* frame starts with rxhdr */
8288         rxh = (struct d11rxhdr *) (p->data);
8289
8290         /* strip off rxhdr */
8291         skb_pull(p, BRCMS_HWRXOFF);
8292
8293         /* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */
8294         if (rxh->RxStatus1 & RXS_PBPRES) {
8295                 if (p->len < 2) {
8296                         wiphy_err(wlc->wiphy, "wl%d: recv: rcvd runt of "
8297                                   "len %d\n", wlc->pub->unit, p->len);
8298                         goto toss;
8299                 }
8300                 skb_pull(p, 2);
8301         }
8302
8303         h = (struct ieee80211_hdr *)(p->data + D11_PHY_HDR_LEN);
8304         len = p->len;
8305
8306         if (rxh->RxStatus1 & RXS_FCSERR) {
8307                 if (wlc->pub->mac80211_state & MAC80211_PROMISC_BCNS) {
8308                         wiphy_err(wlc->wiphy, "FCSERR while scanning******* -"
8309                                   " tossing\n");
8310                         goto toss;
8311                 } else {
8312                         wiphy_err(wlc->wiphy, "RCSERR!!!\n");
8313                         goto toss;
8314                 }
8315         }
8316
8317         /* check received pkt has at least frame control field */
8318         if (len < D11_PHY_HDR_LEN + sizeof(h->frame_control))
8319                 goto toss;
8320
8321         is_amsdu = rxh->RxStatus2 & RXS_AMSDU_MASK;
8322
8323         /* explicitly test bad src address to avoid sending bad deauth */
8324         if (!is_amsdu) {
8325                 /* CTS and ACK CTL frames are w/o a2 */
8326
8327                 if (ieee80211_is_data(h->frame_control) ||
8328                     ieee80211_is_mgmt(h->frame_control)) {
8329                         if ((is_zero_ether_addr(h->addr2) ||
8330                              is_multicast_ether_addr(h->addr2))) {
8331                                 wiphy_err(wlc->wiphy, "wl%d: %s: dropping a "
8332                                           "frame with invalid src mac address,"
8333                                           " a2: %pM\n",
8334                                          wlc->pub->unit, __func__, h->addr2);
8335                                 goto toss;
8336                         }
8337                 }
8338         }
8339
8340         /* due to sheer numbers, toss out probe reqs for now */
8341         if (ieee80211_is_probe_req(h->frame_control))
8342                 goto toss;
8343
8344         if (is_amsdu)
8345                 goto toss;
8346
8347         brcms_c_recvctl(wlc, rxh, p);
8348         return;
8349
8350  toss:
8351         brcmu_pkt_buf_free_skb(p);
8352 }
8353
8354 /* calculate frame duration for Mixed-mode L-SIG spoofing, return
8355  * number of bytes goes in the length field
8356  *
8357  * Formula given by HT PHY Spec v 1.13
8358  *   len = 3(nsyms + nstream + 3) - 3
8359  */
8360 u16
8361 brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec,
8362                       uint mac_len)
8363 {
8364         uint nsyms, len = 0, kNdps;
8365
8366         BCMMSG(wlc->wiphy, "wl%d: rate %d, len%d\n",
8367                  wlc->pub->unit, rspec2rate(ratespec), mac_len);
8368
8369         if (is_mcs_rate(ratespec)) {
8370                 uint mcs = ratespec & RSPEC_RATE_MASK;
8371                 int tot_streams = (mcs_2_txstreams(mcs) + 1) +
8372                                   rspec_stc(ratespec);
8373
8374                 /*
8375                  * the payload duration calculation matches that
8376                  * of regular ofdm
8377                  */
8378                 /* 1000Ndbps = kbps * 4 */
8379                 kNdps = mcs_2_rate(mcs, rspec_is40mhz(ratespec),
8380                                    rspec_issgi(ratespec)) * 4;
8381
8382                 if (rspec_stc(ratespec) == 0)
8383                         nsyms =
8384                             CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
8385                                   APHY_TAIL_NBITS) * 1000, kNdps);
8386                 else
8387                         /* STBC needs to have even number of symbols */
8388                         nsyms =
8389                             2 *
8390                             CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
8391                                   APHY_TAIL_NBITS) * 1000, 2 * kNdps);
8392
8393                 /* (+3) account for HT-SIG(2) and HT-STF(1) */
8394                 nsyms += (tot_streams + 3);
8395                 /*
8396                  * 3 bytes/symbol @ legacy 6Mbps rate
8397                  * (-3) excluding service bits and tail bits
8398                  */
8399                 len = (3 * nsyms) - 3;
8400         }
8401
8402         return (u16) len;
8403 }
8404
8405 /*
8406  * calculate frame duration of a given rate and length, return
8407  * time in usec unit
8408  */
8409 uint
8410 brcms_c_calc_frame_time(struct brcms_c_info *wlc, u32 ratespec,
8411                         u8 preamble_type, uint mac_len)
8412 {
8413         uint nsyms, dur = 0, Ndps, kNdps;
8414         uint rate = rspec2rate(ratespec);
8415
8416         if (rate == 0) {
8417                 wiphy_err(wlc->wiphy, "wl%d: WAR: using rate of 1 mbps\n",
8418                           wlc->pub->unit);
8419                 rate = BRCM_RATE_1M;
8420         }
8421
8422         BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d, len%d\n",
8423                  wlc->pub->unit, ratespec, preamble_type, mac_len);
8424
8425         if (is_mcs_rate(ratespec)) {
8426                 uint mcs = ratespec & RSPEC_RATE_MASK;
8427                 int tot_streams = mcs_2_txstreams(mcs) + rspec_stc(ratespec);
8428
8429                 dur = PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT);
8430                 if (preamble_type == BRCMS_MM_PREAMBLE)
8431                         dur += PREN_MM_EXT;
8432                 /* 1000Ndbps = kbps * 4 */
8433                 kNdps = mcs_2_rate(mcs, rspec_is40mhz(ratespec),
8434                                    rspec_issgi(ratespec)) * 4;
8435
8436                 if (rspec_stc(ratespec) == 0)
8437                         nsyms =
8438                             CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
8439                                   APHY_TAIL_NBITS) * 1000, kNdps);
8440                 else
8441                         /* STBC needs to have even number of symbols */
8442                         nsyms =
8443                             2 *
8444                             CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
8445                                   APHY_TAIL_NBITS) * 1000, 2 * kNdps);
8446
8447                 dur += APHY_SYMBOL_TIME * nsyms;
8448                 if (wlc->band->bandtype == BRCM_BAND_2G)
8449                         dur += DOT11_OFDM_SIGNAL_EXTENSION;
8450         } else if (is_ofdm_rate(rate)) {
8451                 dur = APHY_PREAMBLE_TIME;
8452                 dur += APHY_SIGNAL_TIME;
8453                 /* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */
8454                 Ndps = rate * 2;
8455                 /* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */
8456                 nsyms =
8457                     CEIL((APHY_SERVICE_NBITS + 8 * mac_len + APHY_TAIL_NBITS),
8458                          Ndps);
8459                 dur += APHY_SYMBOL_TIME * nsyms;
8460                 if (wlc->band->bandtype == BRCM_BAND_2G)
8461                         dur += DOT11_OFDM_SIGNAL_EXTENSION;
8462         } else {
8463                 /*
8464                  * calc # bits * 2 so factor of 2 in rate (1/2 mbps)
8465                  * will divide out
8466                  */
8467                 mac_len = mac_len * 8 * 2;
8468                 /* calc ceiling of bits/rate = microseconds of air time */
8469                 dur = (mac_len + rate - 1) / rate;
8470                 if (preamble_type & BRCMS_SHORT_PREAMBLE)
8471                         dur += BPHY_PLCP_SHORT_TIME;
8472                 else
8473                         dur += BPHY_PLCP_TIME;
8474         }
8475         return dur;
8476 }
8477
8478 /* derive wlc->band->basic_rate[] table from 'rateset' */
8479 void brcms_c_rate_lookup_init(struct brcms_c_info *wlc,
8480                               struct brcms_c_rateset *rateset)
8481 {
8482         u8 rate;
8483         u8 mandatory;
8484         u8 cck_basic = 0;
8485         u8 ofdm_basic = 0;
8486         u8 *br = wlc->band->basic_rate;
8487         uint i;
8488
8489         /* incoming rates are in 500kbps units as in 802.11 Supported Rates */
8490         memset(br, 0, BRCM_MAXRATE + 1);
8491
8492         /* For each basic rate in the rates list, make an entry in the
8493          * best basic lookup.
8494          */
8495         for (i = 0; i < rateset->count; i++) {
8496                 /* only make an entry for a basic rate */
8497                 if (!(rateset->rates[i] & BRCMS_RATE_FLAG))
8498                         continue;
8499
8500                 /* mask off basic bit */
8501                 rate = (rateset->rates[i] & BRCMS_RATE_MASK);
8502
8503                 if (rate > BRCM_MAXRATE) {
8504                         wiphy_err(wlc->wiphy, "brcms_c_rate_lookup_init: "
8505                                   "invalid rate 0x%X in rate set\n",
8506                                   rateset->rates[i]);
8507                         continue;
8508                 }
8509
8510                 br[rate] = rate;
8511         }
8512
8513         /* The rate lookup table now has non-zero entries for each
8514          * basic rate, equal to the basic rate: br[basicN] = basicN
8515          *
8516          * To look up the best basic rate corresponding to any
8517          * particular rate, code can use the basic_rate table
8518          * like this
8519          *
8520          * basic_rate = wlc->band->basic_rate[tx_rate]
8521          *
8522          * Make sure there is a best basic rate entry for
8523          * every rate by walking up the table from low rates
8524          * to high, filling in holes in the lookup table
8525          */
8526
8527         for (i = 0; i < wlc->band->hw_rateset.count; i++) {
8528                 rate = wlc->band->hw_rateset.rates[i];
8529
8530                 if (br[rate] != 0) {
8531                         /* This rate is a basic rate.
8532                          * Keep track of the best basic rate so far by
8533                          * modulation type.
8534                          */
8535                         if (is_ofdm_rate(rate))
8536                                 ofdm_basic = rate;
8537                         else
8538                                 cck_basic = rate;
8539
8540                         continue;
8541                 }
8542
8543                 /* This rate is not a basic rate so figure out the
8544                  * best basic rate less than this rate and fill in
8545                  * the hole in the table
8546                  */
8547
8548                 br[rate] = is_ofdm_rate(rate) ? ofdm_basic : cck_basic;
8549
8550                 if (br[rate] != 0)
8551                         continue;
8552
8553                 if (is_ofdm_rate(rate)) {
8554                         /*
8555                          * In 11g and 11a, the OFDM mandatory rates
8556                          * are 6, 12, and 24 Mbps
8557                          */
8558                         if (rate >= BRCM_RATE_24M)
8559                                 mandatory = BRCM_RATE_24M;
8560                         else if (rate >= BRCM_RATE_12M)
8561                                 mandatory = BRCM_RATE_12M;
8562                         else
8563                                 mandatory = BRCM_RATE_6M;
8564                 } else {
8565                         /* In 11b, all CCK rates are mandatory 1 - 11 Mbps */
8566                         mandatory = rate;
8567                 }
8568
8569                 br[rate] = mandatory;
8570         }
8571 }
8572
8573 static void brcms_c_write_rate_shm(struct brcms_c_info *wlc, u8 rate,
8574                                    u8 basic_rate)
8575 {
8576         u8 phy_rate, index;
8577         u8 basic_phy_rate, basic_index;
8578         u16 dir_table, basic_table;
8579         u16 basic_ptr;
8580
8581         /* Shared memory address for the table we are reading */
8582         dir_table = is_ofdm_rate(basic_rate) ? M_RT_DIRMAP_A : M_RT_DIRMAP_B;
8583
8584         /* Shared memory address for the table we are writing */
8585         basic_table = is_ofdm_rate(rate) ? M_RT_BBRSMAP_A : M_RT_BBRSMAP_B;
8586
8587         /*
8588          * for a given rate, the LS-nibble of the PLCP SIGNAL field is
8589          * the index into the rate table.
8590          */
8591         phy_rate = rate_info[rate] & BRCMS_RATE_MASK;
8592         basic_phy_rate = rate_info[basic_rate] & BRCMS_RATE_MASK;
8593         index = phy_rate & 0xf;
8594         basic_index = basic_phy_rate & 0xf;
8595
8596         /* Find the SHM pointer to the ACK rate entry by looking in the
8597          * Direct-map Table
8598          */
8599         basic_ptr = brcms_c_read_shm(wlc, (dir_table + basic_index * 2));
8600
8601         /* Update the SHM BSS-basic-rate-set mapping table with the pointer
8602          * to the correct basic rate for the given incoming rate
8603          */
8604         brcms_c_write_shm(wlc, (basic_table + index * 2), basic_ptr);
8605 }
8606
8607 static const struct brcms_c_rateset *
8608 brcms_c_rateset_get_hwrs(struct brcms_c_info *wlc)
8609 {
8610         const struct brcms_c_rateset *rs_dflt;
8611
8612         if (BRCMS_PHY_11N_CAP(wlc->band)) {
8613                 if (wlc->band->bandtype == BRCM_BAND_5G)
8614                         rs_dflt = &ofdm_mimo_rates;
8615                 else
8616                         rs_dflt = &cck_ofdm_mimo_rates;
8617         } else if (wlc->band->gmode)
8618                 rs_dflt = &cck_ofdm_rates;
8619         else
8620                 rs_dflt = &cck_rates;
8621
8622         return rs_dflt;
8623 }
8624
8625 void brcms_c_set_ratetable(struct brcms_c_info *wlc)
8626 {
8627         const struct brcms_c_rateset *rs_dflt;
8628         struct brcms_c_rateset rs;
8629         u8 rate, basic_rate;
8630         uint i;
8631
8632         rs_dflt = brcms_c_rateset_get_hwrs(wlc);
8633
8634         brcms_c_rateset_copy(rs_dflt, &rs);
8635         brcms_c_rateset_mcs_upd(&rs, wlc->stf->txstreams);
8636
8637         /* walk the phy rate table and update SHM basic rate lookup table */
8638         for (i = 0; i < rs.count; i++) {
8639                 rate = rs.rates[i] & BRCMS_RATE_MASK;
8640
8641                 /* for a given rate brcms_basic_rate returns the rate at
8642                  * which a response ACK/CTS should be sent.
8643                  */
8644                 basic_rate = brcms_basic_rate(wlc, rate);
8645                 if (basic_rate == 0)
8646                         /* This should only happen if we are using a
8647                          * restricted rateset.
8648                          */
8649                         basic_rate = rs.rates[0] & BRCMS_RATE_MASK;
8650
8651                 brcms_c_write_rate_shm(wlc, rate, basic_rate);
8652         }
8653 }
8654
8655 /*
8656  * Return true if the specified rate is supported by the specified band.
8657  * BRCM_BAND_AUTO indicates the current band.
8658  */
8659 bool brcms_c_valid_rate(struct brcms_c_info *wlc, u32 rspec, int band,
8660                     bool verbose)
8661 {
8662         struct brcms_c_rateset *hw_rateset;
8663         uint i;
8664
8665         if ((band == BRCM_BAND_AUTO) || (band == wlc->band->bandtype))
8666                 hw_rateset = &wlc->band->hw_rateset;
8667         else if (wlc->pub->_nbands > 1)
8668                 hw_rateset = &wlc->bandstate[OTHERBANDUNIT(wlc)]->hw_rateset;
8669         else
8670                 /* other band specified and we are a single band device */
8671                 return false;
8672
8673         /* check if this is a mimo rate */
8674         if (is_mcs_rate(rspec)) {
8675                 if ((rspec & RSPEC_RATE_MASK) >= MCS_TABLE_SIZE)
8676                         goto error;
8677
8678                 return isset(hw_rateset->mcs, (rspec & RSPEC_RATE_MASK));
8679         }
8680
8681         for (i = 0; i < hw_rateset->count; i++)
8682                 if (hw_rateset->rates[i] == rspec2rate(rspec))
8683                         return true;
8684  error:
8685         if (verbose)
8686                 wiphy_err(wlc->wiphy, "wl%d: valid_rate: rate spec 0x%x "
8687                           "not in hw_rateset\n", wlc->pub->unit, rspec);
8688
8689         return false;
8690 }
8691
8692 void brcms_c_mod_prb_rsp_rate_table(struct brcms_c_info *wlc, uint frame_len)
8693 {
8694         const struct brcms_c_rateset *rs_dflt;
8695         struct brcms_c_rateset rs;
8696         u8 rate;
8697         u16 entry_ptr;
8698         u8 plcp[D11_PHY_HDR_LEN];
8699         u16 dur, sifs;
8700         uint i;
8701
8702         sifs = get_sifs(wlc->band);
8703
8704         rs_dflt = brcms_c_rateset_get_hwrs(wlc);
8705
8706         brcms_c_rateset_copy(rs_dflt, &rs);
8707         brcms_c_rateset_mcs_upd(&rs, wlc->stf->txstreams);
8708
8709         /*
8710          * walk the phy rate table and update MAC core SHM
8711          * basic rate table entries
8712          */
8713         for (i = 0; i < rs.count; i++) {
8714                 rate = rs.rates[i] & BRCMS_RATE_MASK;
8715
8716                 entry_ptr = brcms_c_rate_shm_offset(wlc, rate);
8717
8718                 /* Calculate the Probe Response PLCP for the given rate */
8719                 brcms_c_compute_plcp(wlc, rate, frame_len, plcp);
8720
8721                 /*
8722                  * Calculate the duration of the Probe Response
8723                  * frame plus SIFS for the MAC
8724                  */
8725                 dur = (u16) brcms_c_calc_frame_time(wlc, rate,
8726                                                 BRCMS_LONG_PREAMBLE, frame_len);
8727                 dur += sifs;
8728
8729                 /* Update the SHM Rate Table entry Probe Response values */
8730                 brcms_c_write_shm(wlc, entry_ptr + M_RT_PRS_PLCP_POS,
8731                               (u16) (plcp[0] + (plcp[1] << 8)));
8732                 brcms_c_write_shm(wlc, entry_ptr + M_RT_PRS_PLCP_POS + 2,
8733                               (u16) (plcp[2] + (plcp[3] << 8)));
8734                 brcms_c_write_shm(wlc, entry_ptr + M_RT_PRS_DUR_POS, dur);
8735         }
8736 }
8737
8738 /*      Max buffering needed for beacon template/prb resp template is 142 bytes.
8739  *
8740  *      PLCP header is 6 bytes.
8741  *      802.11 A3 header is 24 bytes.
8742  *      Max beacon frame body template length is 112 bytes.
8743  *      Max probe resp frame body template length is 110 bytes.
8744  *
8745  *      *len on input contains the max length of the packet available.
8746  *
8747  *      The *len value is set to the number of bytes in buf used, and starts
8748  *      with the PLCP and included up to, but not including, the 4 byte FCS.
8749  */
8750 static void
8751 brcms_c_bcn_prb_template(struct brcms_c_info *wlc, u16 type,
8752                          u32 bcn_rspec,
8753                          struct brcms_bss_cfg *cfg, u16 *buf, int *len)
8754 {
8755         static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
8756         struct cck_phy_hdr *plcp;
8757         struct ieee80211_mgmt *h;
8758         int hdr_len, body_len;
8759
8760         hdr_len = D11_PHY_HDR_LEN + DOT11_MAC_HDR_LEN;
8761
8762         /* calc buffer size provided for frame body */
8763         body_len = *len - hdr_len;
8764         /* return actual size */
8765         *len = hdr_len + body_len;
8766
8767         /* format PHY and MAC headers */
8768         memset((char *)buf, 0, hdr_len);
8769
8770         plcp = (struct cck_phy_hdr *) buf;
8771
8772         /*
8773          * PLCP for Probe Response frames are filled in from
8774          * core's rate table
8775          */
8776         if (type == IEEE80211_STYPE_BEACON)
8777                 /* fill in PLCP */
8778                 brcms_c_compute_plcp(wlc, bcn_rspec,
8779                                  (DOT11_MAC_HDR_LEN + body_len + FCS_LEN),
8780                                  (u8 *) plcp);
8781
8782         /* "Regular" and 16 MBSS but not for 4 MBSS */
8783         /* Update the phytxctl for the beacon based on the rspec */
8784         brcms_c_beacon_phytxctl_txant_upd(wlc, bcn_rspec);
8785
8786         h = (struct ieee80211_mgmt *)&plcp[1];
8787
8788         /* fill in 802.11 header */
8789         h->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | type);
8790
8791         /* DUR is 0 for multicast bcn, or filled in by MAC for prb resp */
8792         /* A1 filled in by MAC for prb resp, broadcast for bcn */
8793         if (type == IEEE80211_STYPE_BEACON)
8794                 memcpy(&h->da, &ether_bcast, ETH_ALEN);
8795         memcpy(&h->sa, &cfg->cur_etheraddr, ETH_ALEN);
8796         memcpy(&h->bssid, &cfg->BSSID, ETH_ALEN);
8797
8798         /* SEQ filled in by MAC */
8799
8800         return;
8801 }
8802
8803 int brcms_c_get_header_len(void)
8804 {
8805         return TXOFF;
8806 }
8807
8808 /* mac is assumed to be suspended at this point */
8809 static void
8810 brcms_b_write_hw_bcntemplates(struct brcms_hardware *wlc_hw, u16 bcn[],
8811                               int len, bool both)
8812 {
8813         struct d11regs *regs = wlc_hw->regs;
8814
8815         if (both) {
8816                 brcms_c_write_hw_bcntemplate0(wlc_hw, bcn, len);
8817                 brcms_c_write_hw_bcntemplate1(wlc_hw, bcn, len);
8818         } else {
8819                 /* bcn 0 */
8820                 if (!(R_REG(&regs->maccommand) & MCMD_BCN0VLD))
8821                         brcms_c_write_hw_bcntemplate0(wlc_hw, bcn, len);
8822                 /* bcn 1 */
8823                 else if (!
8824                          (R_REG(&regs->maccommand) & MCMD_BCN1VLD))
8825                         brcms_c_write_hw_bcntemplate1(wlc_hw, bcn, len);
8826         }
8827 }
8828
8829 static void brcms_c_write_hw_bcntemplates(struct brcms_c_info *wlc, u16 bcn[],
8830                                           int len, bool both)
8831 {
8832         brcms_b_write_hw_bcntemplates(wlc->hw, bcn, len, both);
8833 }
8834
8835 /*
8836  * Update a beacon for a particular BSS
8837  * For MBSS, this updates the software template and sets "latest" to
8838  * the index of the template updated. Otherwise, it updates the hardware
8839  * template.
8840  */
8841 void brcms_c_bss_update_beacon(struct brcms_c_info *wlc,
8842                                struct brcms_bss_cfg *cfg)
8843 {
8844         int len = BCN_TMPL_LEN;
8845
8846         /* Clear the soft intmask */
8847         wlc->defmacintmask &= ~MI_BCNTPL;
8848
8849         if (!cfg->up)
8850                 /* Only allow updates on an UP bss */
8851                 return;
8852
8853         /* Optimize:  Some of if/else could be combined */
8854         if ((cfg->flags & BRCMS_BSSCFG_HW_BCN) != 0) {
8855                 /* Hardware beaconing for this config */
8856                 u16 bcn[BCN_TMPL_LEN / 2];
8857                 u32 both_valid = MCMD_BCN0VLD | MCMD_BCN1VLD;
8858                 struct d11regs *regs = wlc->regs;
8859
8860                 /* Check if both templates are in use, if so sched. an interrupt
8861                  *      that will call back into this routine
8862                  */
8863                 if ((R_REG(&regs->maccommand) & both_valid) == both_valid)
8864                         /* clear any previous status */
8865                         W_REG(&regs->macintstatus, MI_BCNTPL);
8866
8867                 /* Check that after scheduling the interrupt both of the
8868                  *      templates are still busy. if not clear the int. & remask
8869                  */
8870                 if ((R_REG(&regs->maccommand) & both_valid) == both_valid) {
8871                         wlc->defmacintmask |= MI_BCNTPL;
8872                         return;
8873                 }
8874
8875                 wlc->bcn_rspec =
8876                     brcms_c_lowest_basic_rspec(wlc, &cfg->current_bss->rateset);
8877                 /* update the template and ucode shm */
8878                 brcms_c_bcn_prb_template(wlc, IEEE80211_STYPE_BEACON,
8879                                      wlc->bcn_rspec, cfg, bcn, &len);
8880                 brcms_c_write_hw_bcntemplates(wlc, bcn, len, false);
8881         }
8882 }
8883
8884 /*
8885  * Update all beacons for the system.
8886  */
8887 void brcms_c_update_beacon(struct brcms_c_info *wlc)
8888 {
8889         struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
8890
8891         if (bsscfg->up && !bsscfg->BSS)
8892                 brcms_c_bss_update_beacon(wlc, bsscfg);
8893 }
8894
8895 /* Write ssid into shared memory */
8896 void brcms_c_shm_ssid_upd(struct brcms_c_info *wlc, struct brcms_bss_cfg *cfg)
8897 {
8898         u8 *ssidptr = cfg->SSID;
8899         u16 base = M_SSID;
8900         u8 ssidbuf[IEEE80211_MAX_SSID_LEN];
8901
8902         /* padding the ssid with zero and copy it into shm */
8903         memset(ssidbuf, 0, IEEE80211_MAX_SSID_LEN);
8904         memcpy(ssidbuf, ssidptr, cfg->SSID_len);
8905
8906         brcms_c_copyto_shm(wlc, base, ssidbuf, IEEE80211_MAX_SSID_LEN);
8907         brcms_c_write_shm(wlc, M_SSIDLEN, (u16) cfg->SSID_len);
8908 }
8909
8910 void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend)
8911 {
8912         struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
8913
8914         /* update AP or IBSS probe responses */
8915         if (bsscfg->up && !bsscfg->BSS)
8916                 brcms_c_bss_update_probe_resp(wlc, bsscfg, suspend);
8917 }
8918
8919 void
8920 brcms_c_bss_update_probe_resp(struct brcms_c_info *wlc,
8921                               struct brcms_bss_cfg *cfg,
8922                               bool suspend)
8923 {
8924         u16 prb_resp[BCN_TMPL_LEN / 2];
8925         int len = BCN_TMPL_LEN;
8926
8927         /*
8928          * write the probe response to hardware, or save in
8929          * the config structure
8930          */
8931
8932         /* create the probe response template */
8933         brcms_c_bcn_prb_template(wlc, IEEE80211_STYPE_PROBE_RESP, 0,
8934                                  cfg, prb_resp, &len);
8935
8936         if (suspend)
8937                 brcms_c_suspend_mac_and_wait(wlc);
8938
8939         /* write the probe response into the template region */
8940         brcms_b_write_template_ram(wlc->hw, T_PRS_TPL_BASE,
8941                                     (len + 3) & ~3, prb_resp);
8942
8943         /* write the length of the probe response frame (+PLCP/-FCS) */
8944         brcms_c_write_shm(wlc, M_PRB_RESP_FRM_LEN, (u16) len);
8945
8946         /* write the SSID and SSID length */
8947         brcms_c_shm_ssid_upd(wlc, cfg);
8948
8949         /*
8950          * Write PLCP headers and durations for probe response frames
8951          * at all rates. Use the actual frame length covered by the
8952          * PLCP header for the call to brcms_c_mod_prb_rsp_rate_table()
8953          * by subtracting the PLCP len and adding the FCS.
8954          */
8955         len += (-D11_PHY_HDR_LEN + FCS_LEN);
8956         brcms_c_mod_prb_rsp_rate_table(wlc, (u16) len);
8957
8958         if (suspend)
8959                 brcms_c_enable_mac(wlc);
8960 }
8961
8962 /* prepares pdu for transmission. returns BCM error codes */
8963 int brcms_c_prep_pdu(struct brcms_c_info *wlc, struct sk_buff *pdu, uint *fifop)
8964 {
8965         uint fifo;
8966         struct d11txh *txh;
8967         struct ieee80211_hdr *h;
8968         struct scb *scb;
8969
8970         txh = (struct d11txh *) (pdu->data);
8971         h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN);
8972
8973         /* get the pkt queue info. This was put at brcms_c_sendctl or
8974          * brcms_c_send for PDU */
8975         fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK;
8976
8977         scb = NULL;
8978
8979         *fifop = fifo;
8980
8981         /* return if insufficient dma resources */
8982         if (*wlc->core->txavail[fifo] < MAX_DMA_SEGS) {
8983                 /* Mark precedences related to this FIFO, unsendable */
8984                 /* A fifo is full. Clear precedences related to that FIFO */
8985                 wlc->tx_prec_map &= ~(wlc->fifo2prec_map[fifo]);
8986                 return -EBUSY;
8987         }
8988         return 0;
8989 }
8990
8991 /* init tx reported rate mechanism */
8992 void brcms_c_reprate_init(struct brcms_c_info *wlc)
8993 {
8994         brcms_c_bsscfg_reprate_init(wlc->bsscfg);
8995 }
8996
8997 /* per bsscfg init tx reported rate mechanism */
8998 void brcms_c_bsscfg_reprate_init(struct brcms_bss_cfg *bsscfg)
8999 {
9000         bsscfg->txrspecidx = 0;
9001         memset((char *)bsscfg->txrspec, 0, sizeof(bsscfg->txrspec));
9002 }
9003
9004 void brcms_default_rateset(struct brcms_c_info *wlc, struct brcms_c_rateset *rs)
9005 {
9006         brcms_c_rateset_default(rs, NULL, wlc->band->phytype,
9007                 wlc->band->bandtype, false, BRCMS_RATE_MASK_FULL,
9008                 (bool) (wlc->pub->_n_enab & SUPPORT_11N),
9009                 brcms_chspec_bw(wlc->default_bss->chanspec),
9010                 wlc->stf->txstreams);
9011 }
9012
9013 /* Read a single u16 from shared memory.
9014  * SHM 'offset' needs to be an even address
9015  */
9016 u16 brcms_c_read_shm(struct brcms_c_info *wlc, uint offset)
9017 {
9018         return brcms_b_read_shm(wlc->hw, offset);
9019 }
9020
9021 /* Write a single u16 to shared memory.
9022  * SHM 'offset' needs to be an even address
9023  */
9024 void brcms_c_write_shm(struct brcms_c_info *wlc, uint offset, u16 v)
9025 {
9026         brcms_b_write_shm(wlc->hw, offset, v);
9027 }
9028
9029 /* Copy a buffer to shared memory.
9030  * SHM 'offset' needs to be an even address and
9031  * Buffer length 'len' must be an even number of bytes
9032  */
9033 void brcms_c_copyto_shm(struct brcms_c_info *wlc, uint offset, const void *buf,
9034                         int len)
9035 {
9036         /* offset and len need to be even */
9037         if (len <= 0 || (offset & 1) || (len & 1))
9038                 return;
9039
9040         brcms_b_copyto_objmem(wlc->hw, offset, buf, len, OBJADDR_SHM_SEL);
9041
9042 }
9043
9044 /* wrapper BMAC functions to for HIGH driver access */
9045 void brcms_c_mctrl(struct brcms_c_info *wlc, u32 mask, u32 val)
9046 {
9047         brcms_b_mctrl(wlc->hw, mask, val);
9048 }
9049
9050 void brcms_c_mhf(struct brcms_c_info *wlc, u8 idx, u16 mask, u16 val, int bands)
9051 {
9052         brcms_b_mhf(wlc->hw, idx, mask, val, bands);
9053 }
9054
9055 static int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo,
9056                            uint *blocks)
9057 {
9058         if (fifo >= NFIFO)
9059                 return -EINVAL;
9060
9061         *blocks = wlc_hw->xmtfifo_sz[fifo];
9062
9063         return 0;
9064 }
9065
9066 int brcms_c_xmtfifo_sz_get(struct brcms_c_info *wlc, uint fifo, uint *blocks)
9067 {
9068         return brcms_b_xmtfifo_sz_get(wlc->hw, fifo, blocks);
9069 }
9070
9071 void brcms_c_write_template_ram(struct brcms_c_info *wlc, int offset, int len,
9072                             void *buf)
9073 {
9074         brcms_b_write_template_ram(wlc->hw, offset, len, buf);
9075 }
9076
9077 void
9078 brcms_c_set_addrmatch(struct brcms_c_info *wlc, int match_reg_offset,
9079                   const u8 *addr)
9080 {
9081         brcms_b_set_addrmatch(wlc->hw, match_reg_offset, addr);
9082         if (match_reg_offset == RCM_BSSID_OFFSET)
9083                 memcpy(wlc->bsscfg->BSSID, addr, ETH_ALEN);
9084 }
9085
9086 void brcms_c_pllreq(struct brcms_c_info *wlc, bool set, u32 req_bit)
9087 {
9088         brcms_b_pllreq(wlc->hw, set, req_bit);
9089 }
9090
9091 void brcms_c_reset_bmac_done(struct brcms_c_info *wlc)
9092 {
9093 }
9094
9095 /* check for the particular priority flow control bit being set */
9096 bool
9097 brcms_c_txflowcontrol_prio_isset(struct brcms_c_info *wlc,
9098                                  struct brcms_txq_info *q,
9099                                  int prio)
9100 {
9101         uint prio_mask;
9102
9103         if (prio == ALLPRIO)
9104                 prio_mask = TXQ_STOP_FOR_PRIOFC_MASK;
9105         else
9106                 prio_mask = NBITVAL(prio);
9107
9108         return (q->stopped & prio_mask) == prio_mask;
9109 }
9110
9111 /* propagate the flow control to all interfaces using the given tx queue */
9112 void brcms_c_txflowcontrol(struct brcms_c_info *wlc,
9113                            struct brcms_txq_info *qi,
9114                            bool on, int prio)
9115 {
9116         uint prio_bits;
9117         uint cur_bits;
9118
9119         BCMMSG(wlc->wiphy, "flow control kicks in\n");
9120
9121         if (prio == ALLPRIO)
9122                 prio_bits = TXQ_STOP_FOR_PRIOFC_MASK;
9123         else
9124                 prio_bits = NBITVAL(prio);
9125
9126         cur_bits = qi->stopped & prio_bits;
9127
9128         /* Check for the case of no change and return early
9129          * Otherwise update the bit and continue
9130          */
9131         if (on) {
9132                 if (cur_bits == prio_bits)
9133                         return;
9134
9135                 mboolset(qi->stopped, prio_bits);
9136         } else {
9137                 if (cur_bits == 0)
9138                         return;
9139
9140                 mboolclr(qi->stopped, prio_bits);
9141         }
9142
9143         /* If there is a flow control override we will not change the external
9144          * flow control state.
9145          */
9146         if (qi->stopped & ~TXQ_STOP_FOR_PRIOFC_MASK)
9147                 return;
9148
9149         brcms_c_txflowcontrol_signal(wlc, qi, on, prio);
9150 }
9151
9152 void
9153 brcms_c_txflowcontrol_override(struct brcms_c_info *wlc,
9154                                struct brcms_txq_info *qi,
9155                                bool on, uint override)
9156 {
9157         uint prev_override;
9158
9159         prev_override = (qi->stopped & ~TXQ_STOP_FOR_PRIOFC_MASK);
9160
9161         /* Update the flow control bits and do an early return if there is
9162          * no change in the external flow control state.
9163          */
9164         if (on) {
9165                 mboolset(qi->stopped, override);
9166                 /* if there was a previous override bit on, then setting this
9167                  * makes no difference.
9168                  */
9169                 if (prev_override)
9170                         return;
9171
9172                 brcms_c_txflowcontrol_signal(wlc, qi, ON, ALLPRIO);
9173         } else {
9174                 mboolclr(qi->stopped, override);
9175                 /* clearing an override bit will only make a difference for
9176                  * flow control if it was the only bit set. For any other
9177                  * override setting, just return
9178                  */
9179                 if (prev_override != override)
9180                         return;
9181
9182                 if (qi->stopped == 0) {
9183                         brcms_c_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO);
9184                 } else {
9185                         int prio;
9186
9187                         for (prio = MAXPRIO; prio >= 0; prio--) {
9188                                 if (!mboolisset(qi->stopped, NBITVAL(prio)))
9189                                         brcms_c_txflowcontrol_signal(
9190                                                 wlc, qi, OFF, prio);
9191                         }
9192                 }
9193         }
9194 }
9195
9196 /*
9197  * Flag 'scan in progress' to withhold dynamic phy calibration
9198  */
9199 void brcms_c_scan_start(struct brcms_c_info *wlc)
9200 {
9201         wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, true);
9202 }
9203
9204 void brcms_c_scan_stop(struct brcms_c_info *wlc)
9205 {
9206         wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, false);
9207 }
9208
9209 void brcms_c_associate_upd(struct brcms_c_info *wlc, bool state)
9210 {
9211         wlc->pub->associated = state;
9212         wlc->bsscfg->associated = state;
9213 }
9214
9215 /*
9216  * When a remote STA/AP is removed by Mac80211, or when it can no longer accept
9217  * AMPDU traffic, packets pending in hardware have to be invalidated so that
9218  * when later on hardware releases them, they can be handled appropriately.
9219  */
9220 void brcms_c_inval_dma_pkts(struct brcms_hardware *hw,
9221                                struct ieee80211_sta *sta,
9222                                void (*dma_callback_fn))
9223 {
9224         struct dma_pub *dmah;
9225         int i;
9226         for (i = 0; i < NFIFO; i++) {
9227                 dmah = hw->di[i];
9228                 if (dmah != NULL)
9229                         dma_walk_packets(dmah, dma_callback_fn, sta);
9230         }
9231 }
9232
9233 int brcms_c_get_curband(struct brcms_c_info *wlc)
9234 {
9235         return wlc->band->bandunit;
9236 }
9237
9238 void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, bool drop)
9239 {
9240         /* flush packet queue when requested */
9241         if (drop)
9242                 brcmu_pktq_flush(&wlc->pkt_queue->q, false, NULL, NULL);
9243
9244         /* wait for queue and DMA fifos to run dry */
9245         while (!pktq_empty(&wlc->pkt_queue->q) || brcms_txpktpendtot(wlc) > 0)
9246                 brcms_msleep(wlc->wl, 1);
9247 }
9248
9249 void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, u8 interval)
9250 {
9251         wlc->bcn_li_bcn = interval;
9252         if (wlc->pub->up)
9253                 brcms_c_bcn_li_upd(wlc);
9254 }
9255
9256 int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr)
9257 {
9258         uint qdbm;
9259
9260         /* Remove override bit and clip to max qdbm value */
9261         qdbm = min_t(uint, txpwr * BRCMS_TXPWR_DB_FACTOR, 0xff);
9262         return wlc_phy_txpower_set(wlc->band->pi, qdbm, false);
9263 }
9264
9265 int brcms_c_get_tx_power(struct brcms_c_info *wlc)
9266 {
9267         uint qdbm;
9268         bool override;
9269
9270         wlc_phy_txpower_get(wlc->band->pi, &qdbm, &override);
9271
9272         /* Return qdbm units */
9273         return (int)(qdbm / BRCMS_TXPWR_DB_FACTOR);
9274 }
9275
9276 void brcms_c_set_radio_mpc(struct brcms_c_info *wlc, bool mpc)
9277 {
9278         wlc->mpc = mpc;
9279         brcms_c_radio_mpc_upd(wlc);
9280 }
9281
9282 /*
9283  * Search the name=value vars for a specific one and return its value.
9284  * Returns NULL if not found.
9285  */
9286 char *getvar(char *vars, const char *name)
9287 {
9288         char *s;
9289         int len;
9290
9291         if (!name)
9292                 return NULL;
9293
9294         len = strlen(name);
9295         if (len == 0)
9296                 return NULL;
9297
9298         /* first look in vars[] */
9299         for (s = vars; s && *s;) {
9300                 if ((memcmp(s, name, len) == 0) && (s[len] == '='))
9301                         return &s[len + 1];
9302
9303                 while (*s++)
9304                         ;
9305         }
9306         /* nothing found */
9307         return NULL;
9308 }
9309
9310 /*
9311  * Search the vars for a specific one and return its value as
9312  * an integer. Returns 0 if not found.
9313  */
9314 int getintvar(char *vars, const char *name)
9315 {
9316         char *val;
9317         unsigned long res;
9318
9319         val = getvar(vars, name);
9320         if (val && !kstrtoul(val, 0, &res))
9321                 return res;
9322
9323         return 0;
9324 }