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