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