2 * Copyright (c) 2010 Broadcom Corporation
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.
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.
17 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
19 #include <linux/pci_ids.h>
20 #include <linux/if_ether.h>
21 #include <net/cfg80211.h>
22 #include <net/mac80211.h>
23 #include <brcm_hw_ids.h>
25 #include <chipcommon.h>
28 #include "phy/phy_hal.h"
33 #include "mac80211_if.h"
34 #include "ucode_loader.h"
39 #include "brcms_trace_events.h"
41 /* watchdog timer, in unit of ms */
42 #define TIMER_INTERVAL_WATCHDOG 1000
43 /* radio monitor timer, in unit of ms */
44 #define TIMER_INTERVAL_RADIOCHK 800
46 /* beacon interval, in unit of 1024TU */
47 #define BEACON_INTERVAL_DEFAULT 100
49 /* n-mode support capability */
50 /* 2x2 includes both 1x1 & 2x2 devices
51 * reserved #define 2 for future when we want to separate 1x1 & 2x2 and
52 * control it independently
58 #define EDCF_ACI_MASK 0x60
59 #define EDCF_ACI_SHIFT 5
60 #define EDCF_ECWMIN_MASK 0x0f
61 #define EDCF_ECWMAX_SHIFT 4
62 #define EDCF_AIFSN_MASK 0x0f
63 #define EDCF_AIFSN_MAX 15
64 #define EDCF_ECWMAX_MASK 0xf0
66 #define EDCF_AC_BE_TXOP_STA 0x0000
67 #define EDCF_AC_BK_TXOP_STA 0x0000
68 #define EDCF_AC_VO_ACI_STA 0x62
69 #define EDCF_AC_VO_ECW_STA 0x32
70 #define EDCF_AC_VI_ACI_STA 0x42
71 #define EDCF_AC_VI_ECW_STA 0x43
72 #define EDCF_AC_BK_ECW_STA 0xA4
73 #define EDCF_AC_VI_TXOP_STA 0x005e
74 #define EDCF_AC_VO_TXOP_STA 0x002f
75 #define EDCF_AC_BE_ACI_STA 0x03
76 #define EDCF_AC_BE_ECW_STA 0xA4
77 #define EDCF_AC_BK_ACI_STA 0x27
78 #define EDCF_AC_VO_TXOP_AP 0x002f
80 #define EDCF_TXOP2USEC(txop) ((txop) << 5)
81 #define EDCF_ECW2CW(exp) ((1 << (exp)) - 1)
83 #define APHY_SYMBOL_TIME 4
84 #define APHY_PREAMBLE_TIME 16
85 #define APHY_SIGNAL_TIME 4
86 #define APHY_SIFS_TIME 16
87 #define APHY_SERVICE_NBITS 16
88 #define APHY_TAIL_NBITS 6
89 #define BPHY_SIFS_TIME 10
90 #define BPHY_PLCP_SHORT_TIME 96
92 #define PREN_PREAMBLE 24
93 #define PREN_MM_EXT 12
94 #define PREN_PREAMBLE_EXT 4
96 #define DOT11_MAC_HDR_LEN 24
97 #define DOT11_ACK_LEN 10
98 #define DOT11_BA_LEN 4
99 #define DOT11_OFDM_SIGNAL_EXTENSION 6
100 #define DOT11_MIN_FRAG_LEN 256
101 #define DOT11_RTS_LEN 16
102 #define DOT11_CTS_LEN 10
103 #define DOT11_BA_BITMAP_LEN 128
104 #define DOT11_MAXNUMFRAGS 16
105 #define DOT11_MAX_FRAG_LEN 2346
107 #define BPHY_PLCP_TIME 192
108 #define RIFS_11N_TIME 2
110 /* length of the BCN template area */
111 #define BCN_TMPL_LEN 512
113 /* brcms_bss_info flag bit values */
114 #define BRCMS_BSS_HT 0x0020 /* BSS is HT (MIMO) capable */
116 /* chip rx buffer offset */
117 #define BRCMS_HWRXOFF 38
119 /* rfdisable delay timer 500 ms, runs of ALP clock */
120 #define RFDISABLE_DEFAULT 10000000
122 #define BRCMS_TEMPSENSE_PERIOD 10 /* 10 second timeout */
124 /* synthpu_dly times in us */
125 #define SYNTHPU_DLY_APHY_US 3700
126 #define SYNTHPU_DLY_BPHY_US 1050
127 #define SYNTHPU_DLY_NPHY_US 2048
128 #define SYNTHPU_DLY_LPPHY_US 300
130 #define ANTCNT 10 /* vanilla M_MAX_ANTCNT val */
132 /* Per-AC retry limit register definitions; uses defs.h bitfield macros */
133 #define EDCF_SHORT_S 0
135 #define EDCF_LONG_S 8
136 #define EDCF_LFB_S 12
137 #define EDCF_SHORT_M BITFIELD_MASK(4)
138 #define EDCF_SFB_M BITFIELD_MASK(4)
139 #define EDCF_LONG_M BITFIELD_MASK(4)
140 #define EDCF_LFB_M BITFIELD_MASK(4)
142 #define RETRY_SHORT_DEF 7 /* Default Short retry Limit */
143 #define RETRY_SHORT_MAX 255 /* Maximum Short retry Limit */
144 #define RETRY_LONG_DEF 4 /* Default Long retry count */
145 #define RETRY_SHORT_FB 3 /* Short count for fb rate */
146 #define RETRY_LONG_FB 2 /* Long count for fb rate */
148 #define APHY_CWMIN 15
149 #define PHY_CWMAX 1023
151 #define EDCF_AIFSN_MIN 1
153 #define FRAGNUM_MASK 0xF
155 #define APHY_SLOT_TIME 9
156 #define BPHY_SLOT_TIME 20
158 #define WL_SPURAVOID_OFF 0
159 #define WL_SPURAVOID_ON1 1
160 #define WL_SPURAVOID_ON2 2
162 /* invalid core flags, use the saved coreflags */
163 #define BRCMS_USE_COREFLAGS 0xffffffff
165 /* values for PLCPHdr_override */
166 #define BRCMS_PLCP_AUTO -1
167 #define BRCMS_PLCP_SHORT 0
168 #define BRCMS_PLCP_LONG 1
170 /* values for g_protection_override and n_protection_override */
171 #define BRCMS_PROTECTION_AUTO -1
172 #define BRCMS_PROTECTION_OFF 0
173 #define BRCMS_PROTECTION_ON 1
174 #define BRCMS_PROTECTION_MMHDR_ONLY 2
175 #define BRCMS_PROTECTION_CTS_ONLY 3
177 /* values for g_protection_control and n_protection_control */
178 #define BRCMS_PROTECTION_CTL_OFF 0
179 #define BRCMS_PROTECTION_CTL_LOCAL 1
180 #define BRCMS_PROTECTION_CTL_OVERLAP 2
182 /* values for n_protection */
183 #define BRCMS_N_PROTECTION_OFF 0
184 #define BRCMS_N_PROTECTION_OPTIONAL 1
185 #define BRCMS_N_PROTECTION_20IN40 2
186 #define BRCMS_N_PROTECTION_MIXEDMODE 3
188 /* values for band specific 40MHz capabilities */
189 #define BRCMS_N_BW_20ALL 0
190 #define BRCMS_N_BW_40ALL 1
191 #define BRCMS_N_BW_20IN2G_40IN5G 2
193 /* bitflags for SGI support (sgi_rx iovar) */
194 #define BRCMS_N_SGI_20 0x01
195 #define BRCMS_N_SGI_40 0x02
197 /* defines used by the nrate iovar */
198 /* MSC in use,indicates b0-6 holds an mcs */
199 #define NRATE_MCS_INUSE 0x00000080
201 #define NRATE_RATE_MASK 0x0000007f
202 /* stf mode mask: siso, cdd, stbc, sdm */
203 #define NRATE_STF_MASK 0x0000ff00
205 #define NRATE_STF_SHIFT 8
206 /* bit indicate to override mcs only */
207 #define NRATE_OVERRIDE_MCS_ONLY 0x40000000
208 #define NRATE_SGI_MASK 0x00800000 /* sgi mode */
209 #define NRATE_SGI_SHIFT 23 /* sgi mode */
210 #define NRATE_LDPC_CODING 0x00400000 /* adv coding in use */
211 #define NRATE_LDPC_SHIFT 22 /* ldpc shift */
213 #define NRATE_STF_SISO 0 /* stf mode SISO */
214 #define NRATE_STF_CDD 1 /* stf mode CDD */
215 #define NRATE_STF_STBC 2 /* stf mode STBC */
216 #define NRATE_STF_SDM 3 /* stf mode SDM */
218 #define MAX_DMA_SEGS 4
220 /* # of entries in Tx FIFO */
222 /* Max # of entries in Rx FIFO based on 4kb page size */
225 /* Amount of headroom to leave in Tx FIFO */
226 #define TX_HEADROOM 4
228 /* try to keep this # rbufs posted to the chip */
229 #define NRXBUFPOST 32
231 /* max # frames to process in brcms_c_recv() */
233 /* max # tx status to process in wlc_txstatus() */
236 /* brcmu_format_flags() bit description structure */
237 struct brcms_c_bit_desc
{
243 * The following table lists the buffer memory allocated to xmt fifos in HW.
244 * the size is in units of 256bytes(one block), total size is HW dependent
245 * ucode has default fifo partition, sw can overwrite if necessary
247 * This is documented in twiki under the topic UcodeTxFifo. Please ensure
248 * the twiki is updated before making changes.
251 /* Starting corerev for the fifo size table */
252 #define XMTFIFOTBL_STARTREV 17
260 struct edcf_acparam
{
269 /* TX FIFO number to WME/802.1E Access Category */
270 static const u8 wme_fifo2ac
[] = {
279 /* ieee80211 Access Category to TX FIFO number */
280 static const u8 wme_ac2fifo
[] = {
287 static const u16 xmtfifo_sz
[][NFIFO
] = {
288 /* corerev 17: 5120, 49152, 49152, 5376, 4352, 1280 */
289 {20, 192, 192, 21, 17, 5},
294 /* corerev 20: 5120, 49152, 49152, 5376, 4352, 1280 */
295 {20, 192, 192, 21, 17, 5},
296 /* corerev 21: 2304, 14848, 5632, 3584, 3584, 1280 */
297 {9, 58, 22, 14, 14, 5},
298 /* corerev 22: 5120, 49152, 49152, 5376, 4352, 1280 */
299 {20, 192, 192, 21, 17, 5},
300 /* corerev 23: 5120, 49152, 49152, 5376, 4352, 1280 */
301 {20, 192, 192, 21, 17, 5},
302 /* corerev 24: 2304, 14848, 5632, 3584, 3584, 1280 */
303 {9, 58, 22, 14, 14, 5},
310 /* corerev 28: 2304, 14848, 5632, 3584, 3584, 1280 */
311 {9, 58, 22, 14, 14, 5},
315 static const char * const fifo_names
[] = {
316 "AC_BK", "AC_BE", "AC_VI", "AC_VO", "BCMC", "ATIM" };
318 static const char fifo_names
[6][0];
322 /* pointer to most recently allocated wl/wlc */
323 static struct brcms_c_info
*wlc_info_dbg
= (struct brcms_c_info
*) (NULL
);
326 /* Mapping of ieee80211 AC numbers to tx fifos */
327 static const u8 ac_to_fifo_mapping
[IEEE80211_NUM_ACS
] = {
328 [IEEE80211_AC_VO
] = TX_AC_VO_FIFO
,
329 [IEEE80211_AC_VI
] = TX_AC_VI_FIFO
,
330 [IEEE80211_AC_BE
] = TX_AC_BE_FIFO
,
331 [IEEE80211_AC_BK
] = TX_AC_BK_FIFO
,
334 /* Mapping of tx fifos to ieee80211 AC numbers */
335 static const u8 fifo_to_ac_mapping
[IEEE80211_NUM_ACS
] = {
336 [TX_AC_BK_FIFO
] = IEEE80211_AC_BK
,
337 [TX_AC_BE_FIFO
] = IEEE80211_AC_BE
,
338 [TX_AC_VI_FIFO
] = IEEE80211_AC_VI
,
339 [TX_AC_VO_FIFO
] = IEEE80211_AC_VO
,
342 static u8
brcms_ac_to_fifo(u8 ac
)
344 if (ac
>= ARRAY_SIZE(ac_to_fifo_mapping
))
345 return TX_AC_BE_FIFO
;
346 return ac_to_fifo_mapping
[ac
];
349 static u8
brcms_fifo_to_ac(u8 fifo
)
351 if (fifo
>= ARRAY_SIZE(fifo_to_ac_mapping
))
352 return IEEE80211_AC_BE
;
353 return fifo_to_ac_mapping
[fifo
];
356 /* Find basic rate for a given rate */
357 static u8
brcms_basic_rate(struct brcms_c_info
*wlc
, u32 rspec
)
359 if (is_mcs_rate(rspec
))
360 return wlc
->band
->basic_rate
[mcs_table
[rspec
& RSPEC_RATE_MASK
]
362 return wlc
->band
->basic_rate
[rspec
& RSPEC_RATE_MASK
];
365 static u16
frametype(u32 rspec
, u8 mimoframe
)
367 if (is_mcs_rate(rspec
))
369 return is_cck_rate(rspec
) ? FT_CCK
: FT_OFDM
;
372 /* currently the best mechanism for determining SIFS is the band in use */
373 static u16
get_sifs(struct brcms_band
*band
)
375 return band
->bandtype
== BRCM_BAND_5G
? APHY_SIFS_TIME
:
380 * Detect Card removed.
381 * Even checking an sbconfig register read will not false trigger when the core
382 * is in reset it breaks CF address mechanism. Accessing gphy phyversion will
383 * cause SB error if aphy is in reset on 4306B0-DB. Need a simple accessible
384 * reg with fixed 0/1 pattern (some platforms return all 0).
385 * If clocks are present, call the sb routine which will figure out if the
388 static bool brcms_deviceremoved(struct brcms_c_info
*wlc
)
393 return ai_deviceremoved(wlc
->hw
->sih
);
394 macctrl
= bcma_read32(wlc
->hw
->d11core
,
395 D11REGOFFS(maccontrol
));
396 return (macctrl
& (MCTL_PSM_JMP_0
| MCTL_IHR_EN
)) != MCTL_IHR_EN
;
399 /* sum the individual fifo tx pending packet counts */
400 static int brcms_txpktpendtot(struct brcms_c_info
*wlc
)
405 for (i
= 0; i
< ARRAY_SIZE(wlc
->hw
->di
); i
++)
407 pending
+= dma_txpending(wlc
->hw
->di
[i
]);
411 static bool brcms_is_mband_unlocked(struct brcms_c_info
*wlc
)
413 return wlc
->pub
->_nbands
> 1 && !wlc
->bandlocked
;
416 static int brcms_chspec_bw(u16 chanspec
)
418 if (CHSPEC_IS40(chanspec
))
420 if (CHSPEC_IS20(chanspec
))
426 static void brcms_c_bsscfg_mfree(struct brcms_bss_cfg
*cfg
)
431 kfree(cfg
->current_bss
);
435 static void brcms_c_detach_mfree(struct brcms_c_info
*wlc
)
440 brcms_c_bsscfg_mfree(wlc
->bsscfg
);
442 kfree(wlc
->modulecb
);
443 kfree(wlc
->default_bss
);
444 kfree(wlc
->protection
);
446 kfree(wlc
->bandstate
[0]);
447 kfree(wlc
->corestate
->macstat_snapshot
);
448 kfree(wlc
->corestate
);
449 kfree(wlc
->hw
->bandstate
[0]);
457 static struct brcms_bss_cfg
*brcms_c_bsscfg_malloc(uint unit
)
459 struct brcms_bss_cfg
*cfg
;
461 cfg
= kzalloc(sizeof(struct brcms_bss_cfg
), GFP_ATOMIC
);
465 cfg
->current_bss
= kzalloc(sizeof(struct brcms_bss_info
), GFP_ATOMIC
);
466 if (cfg
->current_bss
== NULL
)
472 brcms_c_bsscfg_mfree(cfg
);
476 static struct brcms_c_info
*
477 brcms_c_attach_malloc(uint unit
, uint
*err
, uint devid
)
479 struct brcms_c_info
*wlc
;
481 wlc
= kzalloc(sizeof(struct brcms_c_info
), GFP_ATOMIC
);
487 /* allocate struct brcms_c_pub state structure */
488 wlc
->pub
= kzalloc(sizeof(struct brcms_pub
), GFP_ATOMIC
);
489 if (wlc
->pub
== NULL
) {
495 /* allocate struct brcms_hardware state structure */
497 wlc
->hw
= kzalloc(sizeof(struct brcms_hardware
), GFP_ATOMIC
);
498 if (wlc
->hw
== NULL
) {
504 wlc
->hw
->bandstate
[0] =
505 kzalloc(sizeof(struct brcms_hw_band
) * MAXBANDS
, GFP_ATOMIC
);
506 if (wlc
->hw
->bandstate
[0] == NULL
) {
512 for (i
= 1; i
< MAXBANDS
; i
++)
513 wlc
->hw
->bandstate
[i
] = (struct brcms_hw_band
*)
514 ((unsigned long)wlc
->hw
->bandstate
[0] +
515 (sizeof(struct brcms_hw_band
) * i
));
519 kzalloc(sizeof(struct modulecb
) * BRCMS_MAXMODULES
, GFP_ATOMIC
);
520 if (wlc
->modulecb
== NULL
) {
525 wlc
->default_bss
= kzalloc(sizeof(struct brcms_bss_info
), GFP_ATOMIC
);
526 if (wlc
->default_bss
== NULL
) {
531 wlc
->bsscfg
= brcms_c_bsscfg_malloc(unit
);
532 if (wlc
->bsscfg
== NULL
) {
537 wlc
->protection
= kzalloc(sizeof(struct brcms_protection
),
539 if (wlc
->protection
== NULL
) {
544 wlc
->stf
= kzalloc(sizeof(struct brcms_stf
), GFP_ATOMIC
);
545 if (wlc
->stf
== NULL
) {
551 kzalloc(sizeof(struct brcms_band
)*MAXBANDS
, GFP_ATOMIC
);
552 if (wlc
->bandstate
[0] == NULL
) {
558 for (i
= 1; i
< MAXBANDS
; i
++)
559 wlc
->bandstate
[i
] = (struct brcms_band
*)
560 ((unsigned long)wlc
->bandstate
[0]
561 + (sizeof(struct brcms_band
)*i
));
564 wlc
->corestate
= kzalloc(sizeof(struct brcms_core
), GFP_ATOMIC
);
565 if (wlc
->corestate
== NULL
) {
570 wlc
->corestate
->macstat_snapshot
=
571 kzalloc(sizeof(struct macstat
), GFP_ATOMIC
);
572 if (wlc
->corestate
->macstat_snapshot
== NULL
) {
580 brcms_c_detach_mfree(wlc
);
585 * Update the slot timing for standard 11b/g (20us slots)
586 * or shortslot 11g (9us slots)
587 * The PSM needs to be suspended for this call.
589 static void brcms_b_update_slot_timing(struct brcms_hardware
*wlc_hw
,
592 struct bcma_device
*core
= wlc_hw
->d11core
;
595 /* 11g short slot: 11a timing */
596 bcma_write16(core
, D11REGOFFS(ifs_slot
), 0x0207);
597 brcms_b_write_shm(wlc_hw
, M_DOT11_SLOT
, APHY_SLOT_TIME
);
599 /* 11g long slot: 11b timing */
600 bcma_write16(core
, D11REGOFFS(ifs_slot
), 0x0212);
601 brcms_b_write_shm(wlc_hw
, M_DOT11_SLOT
, BPHY_SLOT_TIME
);
606 * calculate frame duration of a given rate and length, return
609 static uint
brcms_c_calc_frame_time(struct brcms_c_info
*wlc
, u32 ratespec
,
610 u8 preamble_type
, uint mac_len
)
612 uint nsyms
, dur
= 0, Ndps
, kNdps
;
613 uint rate
= rspec2rate(ratespec
);
616 brcms_err(wlc
->hw
->d11core
, "wl%d: WAR: using rate of 1 mbps\n",
621 if (is_mcs_rate(ratespec
)) {
622 uint mcs
= ratespec
& RSPEC_RATE_MASK
;
623 int tot_streams
= mcs_2_txstreams(mcs
) + rspec_stc(ratespec
);
625 dur
= PREN_PREAMBLE
+ (tot_streams
* PREN_PREAMBLE_EXT
);
626 if (preamble_type
== BRCMS_MM_PREAMBLE
)
628 /* 1000Ndbps = kbps * 4 */
629 kNdps
= mcs_2_rate(mcs
, rspec_is40mhz(ratespec
),
630 rspec_issgi(ratespec
)) * 4;
632 if (rspec_stc(ratespec
) == 0)
634 CEIL((APHY_SERVICE_NBITS
+ 8 * mac_len
+
635 APHY_TAIL_NBITS
) * 1000, kNdps
);
637 /* STBC needs to have even number of symbols */
640 CEIL((APHY_SERVICE_NBITS
+ 8 * mac_len
+
641 APHY_TAIL_NBITS
) * 1000, 2 * kNdps
);
643 dur
+= APHY_SYMBOL_TIME
* nsyms
;
644 if (wlc
->band
->bandtype
== BRCM_BAND_2G
)
645 dur
+= DOT11_OFDM_SIGNAL_EXTENSION
;
646 } else if (is_ofdm_rate(rate
)) {
647 dur
= APHY_PREAMBLE_TIME
;
648 dur
+= APHY_SIGNAL_TIME
;
649 /* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */
651 /* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */
653 CEIL((APHY_SERVICE_NBITS
+ 8 * mac_len
+ APHY_TAIL_NBITS
),
655 dur
+= APHY_SYMBOL_TIME
* nsyms
;
656 if (wlc
->band
->bandtype
== BRCM_BAND_2G
)
657 dur
+= DOT11_OFDM_SIGNAL_EXTENSION
;
660 * calc # bits * 2 so factor of 2 in rate (1/2 mbps)
663 mac_len
= mac_len
* 8 * 2;
664 /* calc ceiling of bits/rate = microseconds of air time */
665 dur
= (mac_len
+ rate
- 1) / rate
;
666 if (preamble_type
& BRCMS_SHORT_PREAMBLE
)
667 dur
+= BPHY_PLCP_SHORT_TIME
;
669 dur
+= BPHY_PLCP_TIME
;
674 static void brcms_c_write_inits(struct brcms_hardware
*wlc_hw
,
675 const struct d11init
*inits
)
677 struct bcma_device
*core
= wlc_hw
->d11core
;
683 brcms_dbg_info(wlc_hw
->d11core
, "wl%d\n", wlc_hw
->unit
);
685 for (i
= 0; inits
[i
].addr
!= cpu_to_le16(0xffff); i
++) {
686 size
= le16_to_cpu(inits
[i
].size
);
687 offset
= le16_to_cpu(inits
[i
].addr
);
688 value
= le32_to_cpu(inits
[i
].value
);
690 bcma_write16(core
, offset
, value
);
692 bcma_write32(core
, offset
, value
);
698 static void brcms_c_write_mhf(struct brcms_hardware
*wlc_hw
, u16
*mhfs
)
702 M_HOST_FLAGS1
, M_HOST_FLAGS2
, M_HOST_FLAGS3
, M_HOST_FLAGS4
,
706 for (idx
= 0; idx
< MHFMAX
; idx
++)
707 brcms_b_write_shm(wlc_hw
, addr
[idx
], mhfs
[idx
]);
710 static void brcms_c_ucode_bsinit(struct brcms_hardware
*wlc_hw
)
712 struct brcms_ucode
*ucode
= &wlc_hw
->wlc
->wl
->ucode
;
714 /* init microcode host flags */
715 brcms_c_write_mhf(wlc_hw
, wlc_hw
->band
->mhfs
);
717 /* do band-specific ucode IHR, SHM, and SCR inits */
718 if (D11REV_IS(wlc_hw
->corerev
, 17) || D11REV_IS(wlc_hw
->corerev
, 23)) {
719 if (BRCMS_ISNPHY(wlc_hw
->band
))
720 brcms_c_write_inits(wlc_hw
, ucode
->d11n0bsinitvals16
);
722 brcms_err(wlc_hw
->d11core
,
723 "%s: wl%d: unsupported phy in corerev %d\n",
724 __func__
, wlc_hw
->unit
,
727 if (D11REV_IS(wlc_hw
->corerev
, 24)) {
728 if (BRCMS_ISLCNPHY(wlc_hw
->band
))
729 brcms_c_write_inits(wlc_hw
,
730 ucode
->d11lcn0bsinitvals24
);
732 brcms_err(wlc_hw
->d11core
,
733 "%s: wl%d: unsupported phy in core rev %d\n",
734 __func__
, wlc_hw
->unit
,
737 brcms_err(wlc_hw
->d11core
,
738 "%s: wl%d: unsupported corerev %d\n",
739 __func__
, wlc_hw
->unit
, wlc_hw
->corerev
);
744 static void brcms_b_core_ioctl(struct brcms_hardware
*wlc_hw
, u32 m
, u32 v
)
746 struct bcma_device
*core
= wlc_hw
->d11core
;
747 u32 ioctl
= bcma_aread32(core
, BCMA_IOCTL
) & ~m
;
749 bcma_awrite32(core
, BCMA_IOCTL
, ioctl
| v
);
752 static void brcms_b_core_phy_clk(struct brcms_hardware
*wlc_hw
, bool clk
)
754 brcms_dbg_info(wlc_hw
->d11core
, "wl%d: clk %d\n", wlc_hw
->unit
, clk
);
756 wlc_hw
->phyclk
= clk
;
758 if (OFF
== clk
) { /* clear gmode bit, put phy into reset */
760 brcms_b_core_ioctl(wlc_hw
, (SICF_PRST
| SICF_FGC
| SICF_GMODE
),
761 (SICF_PRST
| SICF_FGC
));
763 brcms_b_core_ioctl(wlc_hw
, (SICF_PRST
| SICF_FGC
), SICF_PRST
);
766 } else { /* take phy out of reset */
768 brcms_b_core_ioctl(wlc_hw
, (SICF_PRST
| SICF_FGC
), SICF_FGC
);
770 brcms_b_core_ioctl(wlc_hw
, SICF_FGC
, 0);
776 /* low-level band switch utility routine */
777 static void brcms_c_setxband(struct brcms_hardware
*wlc_hw
, uint bandunit
)
779 brcms_dbg_mac80211(wlc_hw
->d11core
, "wl%d: bandunit %d\n", wlc_hw
->unit
,
782 wlc_hw
->band
= wlc_hw
->bandstate
[bandunit
];
786 * until we eliminate need for wlc->band refs in low level code
788 wlc_hw
->wlc
->band
= wlc_hw
->wlc
->bandstate
[bandunit
];
790 /* set gmode core flag */
791 if (wlc_hw
->sbclk
&& !wlc_hw
->noreset
) {
797 brcms_b_core_ioctl(wlc_hw
, SICF_GMODE
, gmode
);
801 /* switch to new band but leave it inactive */
802 static u32
brcms_c_setband_inact(struct brcms_c_info
*wlc
, uint bandunit
)
804 struct brcms_hardware
*wlc_hw
= wlc
->hw
;
808 brcms_dbg_mac80211(wlc_hw
->d11core
, "wl%d\n", wlc_hw
->unit
);
809 macctrl
= bcma_read32(wlc_hw
->d11core
,
810 D11REGOFFS(maccontrol
));
811 WARN_ON((macctrl
& MCTL_EN_MAC
) != 0);
813 /* disable interrupts */
814 macintmask
= brcms_intrsoff(wlc
->wl
);
817 wlc_phy_switch_radio(wlc_hw
->band
->pi
, OFF
);
819 brcms_b_core_phy_clk(wlc_hw
, OFF
);
821 brcms_c_setxband(wlc_hw
, bandunit
);
826 /* process an individual struct tx_status */
828 brcms_c_dotxstatus(struct brcms_c_info
*wlc
, struct tx_status
*txs
)
830 struct sk_buff
*p
= NULL
;
832 struct dma_pub
*dma
= NULL
;
833 struct d11txh
*txh
= NULL
;
834 struct scb
*scb
= NULL
;
836 int tx_rts
, tx_frame_count
, tx_rts_count
;
837 uint totlen
, supr_status
;
839 struct ieee80211_hdr
*h
;
841 struct ieee80211_tx_info
*tx_info
;
842 struct ieee80211_tx_rate
*txrate
;
846 trace_brcms_txstatus(&wlc
->hw
->d11core
->dev
, txs
->framelen
,
847 txs
->frameid
, txs
->status
, txs
->lasttxtime
,
848 txs
->sequence
, txs
->phyerr
, txs
->ackphyrxsh
);
850 /* discard intermediate indications for ucode with one legitimate case:
851 * e.g. if "useRTS" is set. ucode did a successful rts/cts exchange,
852 * but the subsequent tx of DATA failed. so it will start rts/cts
853 * from the beginning (resetting the rts transmission count)
855 if (!(txs
->status
& TX_STATUS_AMPDU
)
856 && (txs
->status
& TX_STATUS_INTERMEDIATE
)) {
857 brcms_dbg_tx(wlc
->hw
->d11core
, "INTERMEDIATE but not AMPDU\n");
862 queue
= txs
->frameid
& TXFID_QUEUE_MASK
;
863 if (queue
>= NFIFO
) {
864 brcms_err(wlc
->hw
->d11core
, "queue %u >= NFIFO\n", queue
);
868 dma
= wlc
->hw
->di
[queue
];
870 p
= dma_getnexttxp(wlc
->hw
->di
[queue
], DMA_RANGE_TRANSMITTED
);
872 brcms_err(wlc
->hw
->d11core
, "dma_getnexttxp returned null!\n");
876 txh
= (struct d11txh
*) (p
->data
);
877 mcl
= le16_to_cpu(txh
->MacTxControlLow
);
880 brcms_err(wlc
->hw
->d11core
, "phyerr 0x%x, rate 0x%x\n",
881 txs
->phyerr
, txh
->MainRates
);
883 if (txs
->frameid
!= le16_to_cpu(txh
->TxFrameID
)) {
884 brcms_err(wlc
->hw
->d11core
, "frameid != txh->TxFrameID\n");
887 tx_info
= IEEE80211_SKB_CB(p
);
888 h
= (struct ieee80211_hdr
*)((u8
*) (txh
+ 1) + D11_PHY_HDR_LEN
);
890 if (tx_info
->rate_driver_data
[0])
893 if (tx_info
->flags
& IEEE80211_TX_CTL_AMPDU
) {
894 brcms_c_ampdu_dotxstatus(wlc
->ampdu
, scb
, p
, txs
);
900 * brcms_c_ampdu_dotxstatus() will trace tx descriptors for AMPDU
901 * frames; this traces them for the rest.
903 trace_brcms_txdesc(&wlc
->hw
->d11core
->dev
, txh
, sizeof(*txh
));
905 supr_status
= txs
->status
& TX_STATUS_SUPR_MASK
;
906 if (supr_status
== TX_STATUS_SUPR_BADCH
) {
907 unsigned xfts
= le16_to_cpu(txh
->XtraFrameTypes
);
908 brcms_dbg_tx(wlc
->hw
->d11core
,
909 "Pkt tx suppressed, dest chan %u, current %d\n",
910 (xfts
>> XFTS_CHANNEL_SHIFT
) & 0xff,
911 CHSPEC_CHANNEL(wlc
->default_bss
->chanspec
));
914 tx_rts
= le16_to_cpu(txh
->MacTxControlLow
) & TXC_SENDRTS
;
916 (txs
->status
& TX_STATUS_FRM_RTX_MASK
) >> TX_STATUS_FRM_RTX_SHIFT
;
918 (txs
->status
& TX_STATUS_RTS_RTX_MASK
) >> TX_STATUS_RTS_RTX_SHIFT
;
920 lastframe
= !ieee80211_has_morefrags(h
->frame_control
);
923 brcms_err(wlc
->hw
->d11core
, "Not last frame!\n");
926 * Set information to be consumed by Minstrel ht.
928 * The "fallback limit" is the number of tx attempts a given
929 * MPDU is sent at the "primary" rate. Tx attempts beyond that
930 * limit are sent at the "secondary" rate.
931 * A 'short frame' does not exceed RTS treshold.
933 u16 sfbl
, /* Short Frame Rate Fallback Limit */
934 lfbl
, /* Long Frame Rate Fallback Limit */
937 if (queue
< IEEE80211_NUM_ACS
) {
938 sfbl
= GFIELD(wlc
->wme_retries
[wme_fifo2ac
[queue
]],
940 lfbl
= GFIELD(wlc
->wme_retries
[wme_fifo2ac
[queue
]],
947 txrate
= tx_info
->status
.rates
;
948 if (txrate
[0].flags
& IEEE80211_TX_RC_USE_RTS_CTS
)
953 ieee80211_tx_info_clear_status(tx_info
);
955 if ((tx_frame_count
> fbl
) && (txrate
[1].idx
>= 0)) {
957 * rate selection requested a fallback rate
960 txrate
[0].count
= fbl
;
961 txrate
[1].count
= tx_frame_count
- fbl
;
964 * rate selection did not request fallback rate, or
967 txrate
[0].count
= tx_frame_count
;
969 * rc80211_minstrel.c:minstrel_tx_status() expects
970 * unused rates to be marked with idx = -1
976 /* clear the rest of the rates */
977 for (i
= 2; i
< IEEE80211_TX_MAX_RATES
; i
++) {
982 if (txs
->status
& TX_STATUS_ACK_RCV
)
983 tx_info
->flags
|= IEEE80211_TX_STAT_ACK
;
990 /* remove PLCP & Broadcom tx descriptor header */
991 skb_pull(p
, D11_PHY_HDR_LEN
);
992 skb_pull(p
, D11_TXH_LEN
);
993 ieee80211_tx_status_irqsafe(wlc
->pub
->ieee_hw
, p
);
995 brcms_err(wlc
->hw
->d11core
,
996 "%s: Not last frame => not calling tx_status\n",
1005 trace_brcms_txdesc(&wlc
->hw
->d11core
->dev
, txh
,
1008 brcmu_pkt_buf_free_skb(p
);
1011 if (dma
&& queue
< NFIFO
) {
1012 u16 ac_queue
= brcms_fifo_to_ac(queue
);
1013 if (dma
->txavail
> TX_HEADROOM
&& queue
< TX_BCMC_FIFO
&&
1014 ieee80211_queue_stopped(wlc
->pub
->ieee_hw
, ac_queue
))
1015 ieee80211_wake_queue(wlc
->pub
->ieee_hw
, ac_queue
);
1022 /* process tx completion events in BMAC
1023 * Return true if more tx status need to be processed. false otherwise.
1026 brcms_b_txstatus(struct brcms_hardware
*wlc_hw
, bool bound
, bool *fatal
)
1028 struct bcma_device
*core
;
1029 struct tx_status txstatus
, *txs
;
1033 * Param 'max_tx_num' indicates max. # tx status to process before
1036 uint max_tx_num
= bound
? TXSBND
: -1;
1039 core
= wlc_hw
->d11core
;
1042 while (n
< max_tx_num
) {
1043 s1
= bcma_read32(core
, D11REGOFFS(frmtxstatus
));
1044 if (s1
== 0xffffffff) {
1045 brcms_err(core
, "wl%d: %s: dead chip\n", wlc_hw
->unit
,
1050 /* only process when valid */
1054 s2
= bcma_read32(core
, D11REGOFFS(frmtxstatus2
));
1055 txs
->status
= s1
& TXS_STATUS_MASK
;
1056 txs
->frameid
= (s1
& TXS_FID_MASK
) >> TXS_FID_SHIFT
;
1057 txs
->sequence
= s2
& TXS_SEQ_MASK
;
1058 txs
->phyerr
= (s2
& TXS_PTX_MASK
) >> TXS_PTX_SHIFT
;
1059 txs
->lasttxtime
= 0;
1061 *fatal
= brcms_c_dotxstatus(wlc_hw
->wlc
, txs
);
1067 return n
>= max_tx_num
;
1070 static void brcms_c_tbtt(struct brcms_c_info
*wlc
)
1072 if (!wlc
->bsscfg
->BSS
)
1074 * DirFrmQ is now valid...defer setting until end
1077 wlc
->qvalid
|= MCMD_DIRFRMQVAL
;
1080 /* set initial host flags value */
1082 brcms_c_mhfdef(struct brcms_c_info
*wlc
, u16
*mhfs
, u16 mhf2_init
)
1084 struct brcms_hardware
*wlc_hw
= wlc
->hw
;
1086 memset(mhfs
, 0, MHFMAX
* sizeof(u16
));
1088 mhfs
[MHF2
] |= mhf2_init
;
1090 /* prohibit use of slowclock on multifunction boards */
1091 if (wlc_hw
->boardflags
& BFL_NOPLLDOWN
)
1092 mhfs
[MHF1
] |= MHF1_FORCEFASTCLK
;
1094 if (BRCMS_ISNPHY(wlc_hw
->band
) && NREV_LT(wlc_hw
->band
->phyrev
, 2)) {
1095 mhfs
[MHF2
] |= MHF2_NPHY40MHZ_WAR
;
1096 mhfs
[MHF1
] |= MHF1_IQSWAP_WAR
;
1101 dmareg(uint direction
, uint fifonum
)
1103 if (direction
== DMA_TX
)
1104 return offsetof(struct d11regs
, fifo64regs
[fifonum
].dmaxmt
);
1105 return offsetof(struct d11regs
, fifo64regs
[fifonum
].dmarcv
);
1108 static bool brcms_b_attach_dmapio(struct brcms_c_info
*wlc
, uint j
, bool wme
)
1113 * ucode host flag 2 needed for pio mode, independent of band and fifo
1116 struct brcms_hardware
*wlc_hw
= wlc
->hw
;
1117 uint unit
= wlc_hw
->unit
;
1119 /* name and offsets for dma_attach */
1120 snprintf(name
, sizeof(name
), "wl%d", unit
);
1122 if (wlc_hw
->di
[0] == NULL
) { /* Init FIFOs */
1123 int dma_attach_err
= 0;
1127 * TX: TX_AC_BK_FIFO (TX AC Background data packets)
1128 * RX: RX_FIFO (RX data packets)
1130 wlc_hw
->di
[0] = dma_attach(name
, wlc
,
1131 (wme
? dmareg(DMA_TX
, 0) : 0),
1133 (wme
? NTXD
: 0), NRXD
,
1134 RXBUFSZ
, -1, NRXBUFPOST
,
1136 dma_attach_err
|= (NULL
== wlc_hw
->di
[0]);
1140 * TX: TX_AC_BE_FIFO (TX AC Best-Effort data packets)
1141 * (legacy) TX_DATA_FIFO (TX data packets)
1144 wlc_hw
->di
[1] = dma_attach(name
, wlc
,
1145 dmareg(DMA_TX
, 1), 0,
1146 NTXD
, 0, 0, -1, 0, 0);
1147 dma_attach_err
|= (NULL
== wlc_hw
->di
[1]);
1151 * TX: TX_AC_VI_FIFO (TX AC Video data packets)
1154 wlc_hw
->di
[2] = dma_attach(name
, wlc
,
1155 dmareg(DMA_TX
, 2), 0,
1156 NTXD
, 0, 0, -1, 0, 0);
1157 dma_attach_err
|= (NULL
== wlc_hw
->di
[2]);
1160 * TX: TX_AC_VO_FIFO (TX AC Voice data packets)
1161 * (legacy) TX_CTL_FIFO (TX control & mgmt packets)
1163 wlc_hw
->di
[3] = dma_attach(name
, wlc
,
1167 dma_attach_err
|= (NULL
== wlc_hw
->di
[3]);
1168 /* Cleaner to leave this as if with AP defined */
1170 if (dma_attach_err
) {
1171 brcms_err(wlc_hw
->d11core
,
1172 "wl%d: wlc_attach: dma_attach failed\n",
1177 /* get pointer to dma engine tx flow control variable */
1178 for (i
= 0; i
< NFIFO
; i
++)
1180 wlc_hw
->txavail
[i
] =
1181 (uint
*) dma_getvar(wlc_hw
->di
[i
],
1185 /* initial ucode host flags */
1186 brcms_c_mhfdef(wlc
, wlc_hw
->band
->mhfs
, pio_mhf2
);
1191 static void brcms_b_detach_dmapio(struct brcms_hardware
*wlc_hw
)
1195 for (j
= 0; j
< NFIFO
; j
++) {
1196 if (wlc_hw
->di
[j
]) {
1197 dma_detach(wlc_hw
->di
[j
]);
1198 wlc_hw
->di
[j
] = NULL
;
1204 * Initialize brcms_c_info default values ...
1205 * may get overrides later in this function
1206 * BMAC_NOTES, move low out and resolve the dangling ones
1208 static void brcms_b_info_init(struct brcms_hardware
*wlc_hw
)
1210 struct brcms_c_info
*wlc
= wlc_hw
->wlc
;
1212 /* set default sw macintmask value */
1213 wlc
->defmacintmask
= DEF_MACINTMASK
;
1215 /* various 802.11g modes */
1216 wlc_hw
->shortslot
= false;
1218 wlc_hw
->SFBL
= RETRY_SHORT_FB
;
1219 wlc_hw
->LFBL
= RETRY_LONG_FB
;
1221 /* default mac retry limits */
1222 wlc_hw
->SRL
= RETRY_SHORT_DEF
;
1223 wlc_hw
->LRL
= RETRY_LONG_DEF
;
1224 wlc_hw
->chanspec
= ch20mhz_chspec(1);
1227 static void brcms_b_wait_for_wake(struct brcms_hardware
*wlc_hw
)
1229 /* delay before first read of ucode state */
1232 /* wait until ucode is no longer asleep */
1233 SPINWAIT((brcms_b_read_shm(wlc_hw
, M_UCODE_DBGST
) ==
1234 DBGST_ASLEEP
), wlc_hw
->wlc
->fastpwrup_dly
);
1237 /* control chip clock to save power, enable dynamic clock or force fast clock */
1238 static void brcms_b_clkctl_clk(struct brcms_hardware
*wlc_hw
, enum bcma_clkmode mode
)
1240 if (ai_get_cccaps(wlc_hw
->sih
) & CC_CAP_PMU
) {
1241 /* new chips with PMU, CCS_FORCEHT will distribute the HT clock
1242 * on backplane, but mac core will still run on ALP(not HT) when
1243 * it enters powersave mode, which means the FCA bit may not be
1244 * set. Should wakeup mac if driver wants it to run on HT.
1248 if (mode
== BCMA_CLKMODE_FAST
) {
1249 bcma_set32(wlc_hw
->d11core
,
1250 D11REGOFFS(clk_ctl_st
),
1256 ((bcma_read32(wlc_hw
->d11core
,
1257 D11REGOFFS(clk_ctl_st
)) &
1259 PMU_MAX_TRANSITION_DLY
);
1260 WARN_ON(!(bcma_read32(wlc_hw
->d11core
,
1261 D11REGOFFS(clk_ctl_st
)) &
1264 if ((ai_get_pmurev(wlc_hw
->sih
) == 0) &&
1265 (bcma_read32(wlc_hw
->d11core
,
1266 D11REGOFFS(clk_ctl_st
)) &
1267 (CCS_FORCEHT
| CCS_HTAREQ
)))
1269 ((bcma_read32(wlc_hw
->d11core
,
1270 offsetof(struct d11regs
,
1273 PMU_MAX_TRANSITION_DLY
);
1274 bcma_mask32(wlc_hw
->d11core
,
1275 D11REGOFFS(clk_ctl_st
),
1279 wlc_hw
->forcefastclk
= (mode
== BCMA_CLKMODE_FAST
);
1282 /* old chips w/o PMU, force HT through cc,
1283 * then use FCA to verify mac is running fast clock
1286 wlc_hw
->forcefastclk
= ai_clkctl_cc(wlc_hw
->sih
, mode
);
1288 /* check fast clock is available (if core is not in reset) */
1289 if (wlc_hw
->forcefastclk
&& wlc_hw
->clk
)
1290 WARN_ON(!(bcma_aread32(wlc_hw
->d11core
, BCMA_IOST
) &
1294 * keep the ucode wake bit on if forcefastclk is on since we
1295 * do not want ucode to put us back to slow clock when it dozes
1296 * for PM mode. Code below matches the wake override bit with
1297 * current forcefastclk state. Only setting bit in wake_override
1298 * instead of waking ucode immediately since old code had this
1299 * behavior. Older code set wlc->forcefastclk but only had the
1300 * wake happen if the wakup_ucode work (protected by an up
1301 * check) was executed just below.
1303 if (wlc_hw
->forcefastclk
)
1304 mboolset(wlc_hw
->wake_override
,
1305 BRCMS_WAKE_OVERRIDE_FORCEFAST
);
1307 mboolclr(wlc_hw
->wake_override
,
1308 BRCMS_WAKE_OVERRIDE_FORCEFAST
);
1312 /* set or clear ucode host flag bits
1313 * it has an optimization for no-change write
1314 * it only writes through shared memory when the core has clock;
1315 * pre-CLK changes should use wlc_write_mhf to get around the optimization
1318 * bands values are: BRCM_BAND_AUTO <--- Current band only
1319 * BRCM_BAND_5G <--- 5G band only
1320 * BRCM_BAND_2G <--- 2G band only
1321 * BRCM_BAND_ALL <--- All bands
1324 brcms_b_mhf(struct brcms_hardware
*wlc_hw
, u8 idx
, u16 mask
, u16 val
,
1328 u16 addr
[MHFMAX
] = {
1329 M_HOST_FLAGS1
, M_HOST_FLAGS2
, M_HOST_FLAGS3
, M_HOST_FLAGS4
,
1332 struct brcms_hw_band
*band
;
1334 if ((val
& ~mask
) || idx
>= MHFMAX
)
1335 return; /* error condition */
1338 /* Current band only or all bands,
1339 * then set the band to current band
1341 case BRCM_BAND_AUTO
:
1343 band
= wlc_hw
->band
;
1346 band
= wlc_hw
->bandstate
[BAND_5G_INDEX
];
1349 band
= wlc_hw
->bandstate
[BAND_2G_INDEX
];
1352 band
= NULL
; /* error condition */
1356 save
= band
->mhfs
[idx
];
1357 band
->mhfs
[idx
] = (band
->mhfs
[idx
] & ~mask
) | val
;
1359 /* optimization: only write through if changed, and
1360 * changed band is the current band
1362 if (wlc_hw
->clk
&& (band
->mhfs
[idx
] != save
)
1363 && (band
== wlc_hw
->band
))
1364 brcms_b_write_shm(wlc_hw
, addr
[idx
],
1365 (u16
) band
->mhfs
[idx
]);
1368 if (bands
== BRCM_BAND_ALL
) {
1369 wlc_hw
->bandstate
[0]->mhfs
[idx
] =
1370 (wlc_hw
->bandstate
[0]->mhfs
[idx
] & ~mask
) | val
;
1371 wlc_hw
->bandstate
[1]->mhfs
[idx
] =
1372 (wlc_hw
->bandstate
[1]->mhfs
[idx
] & ~mask
) | val
;
1376 /* set the maccontrol register to desired reset state and
1377 * initialize the sw cache of the register
1379 static void brcms_c_mctrl_reset(struct brcms_hardware
*wlc_hw
)
1381 /* IHR accesses are always enabled, PSM disabled, HPS off and WAKE on */
1382 wlc_hw
->maccontrol
= 0;
1383 wlc_hw
->suspended_fifos
= 0;
1384 wlc_hw
->wake_override
= 0;
1385 wlc_hw
->mute_override
= 0;
1386 brcms_b_mctrl(wlc_hw
, ~0, MCTL_IHR_EN
| MCTL_WAKE
);
1390 * write the software state of maccontrol and
1391 * overrides to the maccontrol register
1393 static void brcms_c_mctrl_write(struct brcms_hardware
*wlc_hw
)
1395 u32 maccontrol
= wlc_hw
->maccontrol
;
1397 /* OR in the wake bit if overridden */
1398 if (wlc_hw
->wake_override
)
1399 maccontrol
|= MCTL_WAKE
;
1401 /* set AP and INFRA bits for mute if needed */
1402 if (wlc_hw
->mute_override
) {
1403 maccontrol
&= ~(MCTL_AP
);
1404 maccontrol
|= MCTL_INFRA
;
1407 bcma_write32(wlc_hw
->d11core
, D11REGOFFS(maccontrol
),
1411 /* set or clear maccontrol bits */
1412 void brcms_b_mctrl(struct brcms_hardware
*wlc_hw
, u32 mask
, u32 val
)
1418 return; /* error condition */
1419 maccontrol
= wlc_hw
->maccontrol
;
1420 new_maccontrol
= (maccontrol
& ~mask
) | val
;
1422 /* if the new maccontrol value is the same as the old, nothing to do */
1423 if (new_maccontrol
== maccontrol
)
1426 /* something changed, cache the new value */
1427 wlc_hw
->maccontrol
= new_maccontrol
;
1429 /* write the new values with overrides applied */
1430 brcms_c_mctrl_write(wlc_hw
);
1433 void brcms_c_ucode_wake_override_set(struct brcms_hardware
*wlc_hw
,
1436 if (wlc_hw
->wake_override
|| (wlc_hw
->maccontrol
& MCTL_WAKE
)) {
1437 mboolset(wlc_hw
->wake_override
, override_bit
);
1441 mboolset(wlc_hw
->wake_override
, override_bit
);
1443 brcms_c_mctrl_write(wlc_hw
);
1444 brcms_b_wait_for_wake(wlc_hw
);
1447 void brcms_c_ucode_wake_override_clear(struct brcms_hardware
*wlc_hw
,
1450 mboolclr(wlc_hw
->wake_override
, override_bit
);
1452 if (wlc_hw
->wake_override
|| (wlc_hw
->maccontrol
& MCTL_WAKE
))
1455 brcms_c_mctrl_write(wlc_hw
);
1458 /* When driver needs ucode to stop beaconing, it has to make sure that
1459 * MCTL_AP is clear and MCTL_INFRA is set
1460 * Mode MCTL_AP MCTL_INFRA
1462 * STA 0 1 <--- This will ensure no beacons
1465 static void brcms_c_ucode_mute_override_set(struct brcms_hardware
*wlc_hw
)
1467 wlc_hw
->mute_override
= 1;
1469 /* if maccontrol already has AP == 0 and INFRA == 1 without this
1470 * override, then there is no change to write
1472 if ((wlc_hw
->maccontrol
& (MCTL_AP
| MCTL_INFRA
)) == MCTL_INFRA
)
1475 brcms_c_mctrl_write(wlc_hw
);
1478 /* Clear the override on AP and INFRA bits */
1479 static void brcms_c_ucode_mute_override_clear(struct brcms_hardware
*wlc_hw
)
1481 if (wlc_hw
->mute_override
== 0)
1484 wlc_hw
->mute_override
= 0;
1486 /* if maccontrol already has AP == 0 and INFRA == 1 without this
1487 * override, then there is no change to write
1489 if ((wlc_hw
->maccontrol
& (MCTL_AP
| MCTL_INFRA
)) == MCTL_INFRA
)
1492 brcms_c_mctrl_write(wlc_hw
);
1496 * Write a MAC address to the given match reg offset in the RXE match engine.
1499 brcms_b_set_addrmatch(struct brcms_hardware
*wlc_hw
, int match_reg_offset
,
1502 struct bcma_device
*core
= wlc_hw
->d11core
;
1507 brcms_dbg_rx(core
, "wl%d: brcms_b_set_addrmatch\n", wlc_hw
->unit
);
1509 mac_l
= addr
[0] | (addr
[1] << 8);
1510 mac_m
= addr
[2] | (addr
[3] << 8);
1511 mac_h
= addr
[4] | (addr
[5] << 8);
1513 /* enter the MAC addr into the RXE match registers */
1514 bcma_write16(core
, D11REGOFFS(rcm_ctl
),
1515 RCM_INC_DATA
| match_reg_offset
);
1516 bcma_write16(core
, D11REGOFFS(rcm_mat_data
), mac_l
);
1517 bcma_write16(core
, D11REGOFFS(rcm_mat_data
), mac_m
);
1518 bcma_write16(core
, D11REGOFFS(rcm_mat_data
), mac_h
);
1522 brcms_b_write_template_ram(struct brcms_hardware
*wlc_hw
, int offset
, int len
,
1525 struct bcma_device
*core
= wlc_hw
->d11core
;
1530 brcms_dbg_info(core
, "wl%d\n", wlc_hw
->unit
);
1532 bcma_write32(core
, D11REGOFFS(tplatewrptr
), offset
);
1534 /* if MCTL_BIGEND bit set in mac control register,
1535 * the chip swaps data in fifo, as well as data in
1538 be_bit
= (bcma_read32(core
, D11REGOFFS(maccontrol
)) & MCTL_BIGEND
) != 0;
1541 memcpy(&word
, buf
, sizeof(u32
));
1544 word_be
= cpu_to_be32(word
);
1545 word
= *(u32
*)&word_be
;
1547 word_le
= cpu_to_le32(word
);
1548 word
= *(u32
*)&word_le
;
1551 bcma_write32(core
, D11REGOFFS(tplatewrdata
), word
);
1553 buf
= (u8
*) buf
+ sizeof(u32
);
1558 static void brcms_b_set_cwmin(struct brcms_hardware
*wlc_hw
, u16 newmin
)
1560 wlc_hw
->band
->CWmin
= newmin
;
1562 bcma_write32(wlc_hw
->d11core
, D11REGOFFS(objaddr
),
1563 OBJADDR_SCR_SEL
| S_DOT11_CWMIN
);
1564 (void)bcma_read32(wlc_hw
->d11core
, D11REGOFFS(objaddr
));
1565 bcma_write32(wlc_hw
->d11core
, D11REGOFFS(objdata
), newmin
);
1568 static void brcms_b_set_cwmax(struct brcms_hardware
*wlc_hw
, u16 newmax
)
1570 wlc_hw
->band
->CWmax
= newmax
;
1572 bcma_write32(wlc_hw
->d11core
, D11REGOFFS(objaddr
),
1573 OBJADDR_SCR_SEL
| S_DOT11_CWMAX
);
1574 (void)bcma_read32(wlc_hw
->d11core
, D11REGOFFS(objaddr
));
1575 bcma_write32(wlc_hw
->d11core
, D11REGOFFS(objdata
), newmax
);
1578 void brcms_b_bw_set(struct brcms_hardware
*wlc_hw
, u16 bw
)
1582 /* request FAST clock if not on */
1583 fastclk
= wlc_hw
->forcefastclk
;
1585 brcms_b_clkctl_clk(wlc_hw
, BCMA_CLKMODE_FAST
);
1587 wlc_phy_bw_state_set(wlc_hw
->band
->pi
, bw
);
1589 brcms_b_phy_reset(wlc_hw
);
1590 wlc_phy_init(wlc_hw
->band
->pi
, wlc_phy_chanspec_get(wlc_hw
->band
->pi
));
1592 /* restore the clk */
1594 brcms_b_clkctl_clk(wlc_hw
, BCMA_CLKMODE_DYNAMIC
);
1597 static void brcms_b_upd_synthpu(struct brcms_hardware
*wlc_hw
)
1600 struct brcms_c_info
*wlc
= wlc_hw
->wlc
;
1601 /* update SYNTHPU_DLY */
1603 if (BRCMS_ISLCNPHY(wlc
->band
))
1604 v
= SYNTHPU_DLY_LPPHY_US
;
1605 else if (BRCMS_ISNPHY(wlc
->band
) && (NREV_GE(wlc
->band
->phyrev
, 3)))
1606 v
= SYNTHPU_DLY_NPHY_US
;
1608 v
= SYNTHPU_DLY_BPHY_US
;
1610 brcms_b_write_shm(wlc_hw
, M_SYNTHPU_DLY
, v
);
1613 static void brcms_c_ucode_txant_set(struct brcms_hardware
*wlc_hw
)
1616 u16 phytxant
= wlc_hw
->bmac_phytxant
;
1617 u16 mask
= PHY_TXC_ANT_MASK
;
1619 /* set the Probe Response frame phy control word */
1620 phyctl
= brcms_b_read_shm(wlc_hw
, M_CTXPRS_BLK
+ C_CTX_PCTLWD_POS
);
1621 phyctl
= (phyctl
& ~mask
) | phytxant
;
1622 brcms_b_write_shm(wlc_hw
, M_CTXPRS_BLK
+ C_CTX_PCTLWD_POS
, phyctl
);
1624 /* set the Response (ACK/CTS) frame phy control word */
1625 phyctl
= brcms_b_read_shm(wlc_hw
, M_RSP_PCTLWD
);
1626 phyctl
= (phyctl
& ~mask
) | phytxant
;
1627 brcms_b_write_shm(wlc_hw
, M_RSP_PCTLWD
, phyctl
);
1630 static u16
brcms_b_ofdm_ratetable_offset(struct brcms_hardware
*wlc_hw
,
1635 struct plcp_signal_rate_lookup
{
1639 /* OFDM RATE sub-field of PLCP SIGNAL field, per 802.11 sec 17.3.4.1 */
1640 const struct plcp_signal_rate_lookup rate_lookup
[] = {
1641 {BRCM_RATE_6M
, 0xB},
1642 {BRCM_RATE_9M
, 0xF},
1643 {BRCM_RATE_12M
, 0xA},
1644 {BRCM_RATE_18M
, 0xE},
1645 {BRCM_RATE_24M
, 0x9},
1646 {BRCM_RATE_36M
, 0xD},
1647 {BRCM_RATE_48M
, 0x8},
1648 {BRCM_RATE_54M
, 0xC}
1651 for (i
= 0; i
< ARRAY_SIZE(rate_lookup
); i
++) {
1652 if (rate
== rate_lookup
[i
].rate
) {
1653 plcp_rate
= rate_lookup
[i
].signal_rate
;
1658 /* Find the SHM pointer to the rate table entry by looking in the
1661 return 2 * brcms_b_read_shm(wlc_hw
, M_RT_DIRMAP_A
+ (plcp_rate
* 2));
1664 static void brcms_upd_ofdm_pctl1_table(struct brcms_hardware
*wlc_hw
)
1668 BRCM_RATE_6M
, BRCM_RATE_9M
, BRCM_RATE_12M
, BRCM_RATE_18M
,
1669 BRCM_RATE_24M
, BRCM_RATE_36M
, BRCM_RATE_48M
, BRCM_RATE_54M
1675 if (!BRCMS_PHY_11N_CAP(wlc_hw
->band
))
1678 /* walk the phy rate table and update the entries */
1679 for (i
= 0; i
< ARRAY_SIZE(rates
); i
++) {
1682 entry_ptr
= brcms_b_ofdm_ratetable_offset(wlc_hw
, rate
);
1684 /* read the SHM Rate Table entry OFDM PCTL1 values */
1686 brcms_b_read_shm(wlc_hw
, entry_ptr
+ M_RT_OFDM_PCTL1_POS
);
1688 /* modify the value */
1689 pctl1
&= ~PHY_TXC1_MODE_MASK
;
1690 pctl1
|= (wlc_hw
->hw_stf_ss_opmode
<< PHY_TXC1_MODE_SHIFT
);
1692 /* Update the SHM Rate Table entry OFDM PCTL1 values */
1693 brcms_b_write_shm(wlc_hw
, entry_ptr
+ M_RT_OFDM_PCTL1_POS
,
1698 /* band-specific init */
1699 static void brcms_b_bsinit(struct brcms_c_info
*wlc
, u16 chanspec
)
1701 struct brcms_hardware
*wlc_hw
= wlc
->hw
;
1703 brcms_dbg_mac80211(wlc_hw
->d11core
, "wl%d: bandunit %d\n", wlc_hw
->unit
,
1704 wlc_hw
->band
->bandunit
);
1706 brcms_c_ucode_bsinit(wlc_hw
);
1708 wlc_phy_init(wlc_hw
->band
->pi
, chanspec
);
1710 brcms_c_ucode_txant_set(wlc_hw
);
1713 * cwmin is band-specific, update hardware
1714 * with value for current band
1716 brcms_b_set_cwmin(wlc_hw
, wlc_hw
->band
->CWmin
);
1717 brcms_b_set_cwmax(wlc_hw
, wlc_hw
->band
->CWmax
);
1719 brcms_b_update_slot_timing(wlc_hw
,
1720 wlc_hw
->band
->bandtype
== BRCM_BAND_5G
?
1721 true : wlc_hw
->shortslot
);
1723 /* write phytype and phyvers */
1724 brcms_b_write_shm(wlc_hw
, M_PHYTYPE
, (u16
) wlc_hw
->band
->phytype
);
1725 brcms_b_write_shm(wlc_hw
, M_PHYVER
, (u16
) wlc_hw
->band
->phyrev
);
1728 * initialize the txphyctl1 rate table since
1729 * shmem is shared between bands
1731 brcms_upd_ofdm_pctl1_table(wlc_hw
);
1733 brcms_b_upd_synthpu(wlc_hw
);
1736 /* Perform a soft reset of the PHY PLL */
1737 void brcms_b_core_phypll_reset(struct brcms_hardware
*wlc_hw
)
1739 ai_cc_reg(wlc_hw
->sih
, offsetof(struct chipcregs
, chipcontrol_addr
),
1742 ai_cc_reg(wlc_hw
->sih
, offsetof(struct chipcregs
, chipcontrol_data
),
1745 ai_cc_reg(wlc_hw
->sih
, offsetof(struct chipcregs
, chipcontrol_data
),
1748 ai_cc_reg(wlc_hw
->sih
, offsetof(struct chipcregs
, chipcontrol_data
),
1753 /* light way to turn on phy clock without reset for NPHY only
1754 * refer to brcms_b_core_phy_clk for full version
1756 void brcms_b_phyclk_fgc(struct brcms_hardware
*wlc_hw
, bool clk
)
1758 /* support(necessary for NPHY and HYPHY) only */
1759 if (!BRCMS_ISNPHY(wlc_hw
->band
))
1763 brcms_b_core_ioctl(wlc_hw
, SICF_FGC
, SICF_FGC
);
1765 brcms_b_core_ioctl(wlc_hw
, SICF_FGC
, 0);
1769 void brcms_b_macphyclk_set(struct brcms_hardware
*wlc_hw
, bool clk
)
1772 brcms_b_core_ioctl(wlc_hw
, SICF_MPCLKE
, SICF_MPCLKE
);
1774 brcms_b_core_ioctl(wlc_hw
, SICF_MPCLKE
, 0);
1777 void brcms_b_phy_reset(struct brcms_hardware
*wlc_hw
)
1779 struct brcms_phy_pub
*pih
= wlc_hw
->band
->pi
;
1781 bool phy_in_reset
= false;
1783 brcms_dbg_info(wlc_hw
->d11core
, "wl%d: reset phy\n", wlc_hw
->unit
);
1788 phy_bw_clkbits
= wlc_phy_clk_bwbits(wlc_hw
->band
->pi
);
1790 /* Specific reset sequence required for NPHY rev 3 and 4 */
1791 if (BRCMS_ISNPHY(wlc_hw
->band
) && NREV_GE(wlc_hw
->band
->phyrev
, 3) &&
1792 NREV_LE(wlc_hw
->band
->phyrev
, 4)) {
1793 /* Set the PHY bandwidth */
1794 brcms_b_core_ioctl(wlc_hw
, SICF_BWMASK
, phy_bw_clkbits
);
1798 /* Perform a soft reset of the PHY PLL */
1799 brcms_b_core_phypll_reset(wlc_hw
);
1802 brcms_b_core_ioctl(wlc_hw
, (SICF_PRST
| SICF_PCLKE
),
1803 (SICF_PRST
| SICF_PCLKE
));
1804 phy_in_reset
= true;
1806 brcms_b_core_ioctl(wlc_hw
,
1807 (SICF_PRST
| SICF_PCLKE
| SICF_BWMASK
),
1808 (SICF_PRST
| SICF_PCLKE
| phy_bw_clkbits
));
1812 brcms_b_core_phy_clk(wlc_hw
, ON
);
1815 wlc_phy_anacore(pih
, ON
);
1818 /* switch to and initialize new band */
1819 static void brcms_b_setband(struct brcms_hardware
*wlc_hw
, uint bandunit
,
1821 struct brcms_c_info
*wlc
= wlc_hw
->wlc
;
1824 /* Enable the d11 core before accessing it */
1825 if (!bcma_core_is_enabled(wlc_hw
->d11core
)) {
1826 bcma_core_enable(wlc_hw
->d11core
, 0);
1827 brcms_c_mctrl_reset(wlc_hw
);
1830 macintmask
= brcms_c_setband_inact(wlc
, bandunit
);
1835 brcms_b_core_phy_clk(wlc_hw
, ON
);
1837 /* band-specific initializations */
1838 brcms_b_bsinit(wlc
, chanspec
);
1841 * If there are any pending software interrupt bits,
1842 * then replace these with a harmless nonzero value
1843 * so brcms_c_dpc() will re-enable interrupts when done.
1845 if (wlc
->macintstatus
)
1846 wlc
->macintstatus
= MI_DMAINT
;
1848 /* restore macintmask */
1849 brcms_intrsrestore(wlc
->wl
, macintmask
);
1851 /* ucode should still be suspended.. */
1852 WARN_ON((bcma_read32(wlc_hw
->d11core
, D11REGOFFS(maccontrol
)) &
1856 static bool brcms_c_isgoodchip(struct brcms_hardware
*wlc_hw
)
1859 /* reject unsupported corerev */
1860 if (!CONF_HAS(D11CONF
, wlc_hw
->corerev
)) {
1861 wiphy_err(wlc_hw
->wlc
->wiphy
, "unsupported core rev %d\n",
1869 /* Validate some board info parameters */
1870 static bool brcms_c_validboardtype(struct brcms_hardware
*wlc_hw
)
1872 uint boardrev
= wlc_hw
->boardrev
;
1874 /* 4 bits each for board type, major, minor, and tiny version */
1875 uint brt
= (boardrev
& 0xf000) >> 12;
1876 uint b0
= (boardrev
& 0xf00) >> 8;
1877 uint b1
= (boardrev
& 0xf0) >> 4;
1878 uint b2
= boardrev
& 0xf;
1880 /* voards from other vendors are always considered valid */
1881 if (ai_get_boardvendor(wlc_hw
->sih
) != PCI_VENDOR_ID_BROADCOM
)
1884 /* do some boardrev sanity checks when boardvendor is Broadcom */
1888 if (boardrev
<= 0xff)
1891 if ((brt
> 2) || (brt
== 0) || (b0
> 9) || (b0
== 0) || (b1
> 9)
1898 static void brcms_c_get_macaddr(struct brcms_hardware
*wlc_hw
, u8 etheraddr
[ETH_ALEN
])
1900 struct ssb_sprom
*sprom
= &wlc_hw
->d11core
->bus
->sprom
;
1902 /* If macaddr exists, use it (Sromrev4, CIS, ...). */
1903 if (!is_zero_ether_addr(sprom
->il0mac
)) {
1904 memcpy(etheraddr
, sprom
->il0mac
, 6);
1908 if (wlc_hw
->_nbands
> 1)
1909 memcpy(etheraddr
, sprom
->et1mac
, 6);
1911 memcpy(etheraddr
, sprom
->il0mac
, 6);
1914 /* power both the pll and external oscillator on/off */
1915 static void brcms_b_xtal(struct brcms_hardware
*wlc_hw
, bool want
)
1917 brcms_dbg_info(wlc_hw
->d11core
, "wl%d: want %d\n", wlc_hw
->unit
, want
);
1920 * dont power down if plldown is false or
1921 * we must poll hw radio disable
1923 if (!want
&& wlc_hw
->pllreq
)
1926 wlc_hw
->sbclk
= want
;
1927 if (!wlc_hw
->sbclk
) {
1928 wlc_hw
->clk
= false;
1929 if (wlc_hw
->band
&& wlc_hw
->band
->pi
)
1930 wlc_phy_hw_clk_state_upd(wlc_hw
->band
->pi
, false);
1935 * Return true if radio is disabled, otherwise false.
1936 * hw radio disable signal is an external pin, users activate it asynchronously
1937 * this function could be called when driver is down and w/o clock
1938 * it operates on different registers depending on corerev and boardflag.
1940 static bool brcms_b_radio_read_hwdisabled(struct brcms_hardware
*wlc_hw
)
1945 xtal
= wlc_hw
->sbclk
;
1947 brcms_b_xtal(wlc_hw
, ON
);
1949 /* may need to take core out of reset first */
1953 * mac no longer enables phyclk automatically when driver
1954 * accesses phyreg throughput mac. This can be skipped since
1955 * only mac reg is accessed below
1957 if (D11REV_GE(wlc_hw
->corerev
, 18))
1958 flags
|= SICF_PCLKE
;
1961 * TODO: test suspend/resume
1963 * AI chip doesn't restore bar0win2 on
1964 * hibernation/resume, need sw fixup
1967 bcma_core_enable(wlc_hw
->d11core
, flags
);
1968 brcms_c_mctrl_reset(wlc_hw
);
1971 v
= ((bcma_read32(wlc_hw
->d11core
,
1972 D11REGOFFS(phydebug
)) & PDBG_RFD
) != 0);
1974 /* put core back into reset */
1976 bcma_core_disable(wlc_hw
->d11core
, 0);
1979 brcms_b_xtal(wlc_hw
, OFF
);
1984 static bool wlc_dma_rxreset(struct brcms_hardware
*wlc_hw
, uint fifo
)
1986 struct dma_pub
*di
= wlc_hw
->di
[fifo
];
1987 return dma_rxreset(di
);
1991 * ensure fask clock during reset
1993 * reset d11(out of reset)
1994 * reset phy(out of reset)
1995 * clear software macintstatus for fresh new start
1996 * one testing hack wlc_hw->noreset will bypass the d11/phy reset
1998 void brcms_b_corereset(struct brcms_hardware
*wlc_hw
, u32 flags
)
2003 if (flags
== BRCMS_USE_COREFLAGS
)
2004 flags
= (wlc_hw
->band
->pi
? wlc_hw
->band
->core_flags
: 0);
2006 brcms_dbg_info(wlc_hw
->d11core
, "wl%d: core reset\n", wlc_hw
->unit
);
2008 /* request FAST clock if not on */
2009 fastclk
= wlc_hw
->forcefastclk
;
2011 brcms_b_clkctl_clk(wlc_hw
, BCMA_CLKMODE_FAST
);
2013 /* reset the dma engines except first time thru */
2014 if (bcma_core_is_enabled(wlc_hw
->d11core
)) {
2015 for (i
= 0; i
< NFIFO
; i
++)
2016 if ((wlc_hw
->di
[i
]) && (!dma_txreset(wlc_hw
->di
[i
])))
2017 brcms_err(wlc_hw
->d11core
, "wl%d: %s: "
2018 "dma_txreset[%d]: cannot stop dma\n",
2019 wlc_hw
->unit
, __func__
, i
);
2021 if ((wlc_hw
->di
[RX_FIFO
])
2022 && (!wlc_dma_rxreset(wlc_hw
, RX_FIFO
)))
2023 brcms_err(wlc_hw
->d11core
, "wl%d: %s: dma_rxreset"
2024 "[%d]: cannot stop dma\n",
2025 wlc_hw
->unit
, __func__
, RX_FIFO
);
2027 /* if noreset, just stop the psm and return */
2028 if (wlc_hw
->noreset
) {
2029 wlc_hw
->wlc
->macintstatus
= 0; /* skip wl_dpc after down */
2030 brcms_b_mctrl(wlc_hw
, MCTL_PSM_RUN
| MCTL_EN_MAC
, 0);
2035 * mac no longer enables phyclk automatically when driver accesses
2036 * phyreg throughput mac, AND phy_reset is skipped at early stage when
2037 * band->pi is invalid. need to enable PHY CLK
2039 if (D11REV_GE(wlc_hw
->corerev
, 18))
2040 flags
|= SICF_PCLKE
;
2044 * In chips with PMU, the fastclk request goes through d11 core
2045 * reg 0x1e0, which is cleared by the core_reset. have to re-request it.
2047 * This adds some delay and we can optimize it by also requesting
2048 * fastclk through chipcommon during this period if necessary. But
2049 * that has to work coordinate with other driver like mips/arm since
2050 * they may touch chipcommon as well.
2052 wlc_hw
->clk
= false;
2053 bcma_core_enable(wlc_hw
->d11core
, flags
);
2055 if (wlc_hw
->band
&& wlc_hw
->band
->pi
)
2056 wlc_phy_hw_clk_state_upd(wlc_hw
->band
->pi
, true);
2058 brcms_c_mctrl_reset(wlc_hw
);
2060 if (ai_get_cccaps(wlc_hw
->sih
) & CC_CAP_PMU
)
2061 brcms_b_clkctl_clk(wlc_hw
, BCMA_CLKMODE_FAST
);
2063 brcms_b_phy_reset(wlc_hw
);
2065 /* turn on PHY_PLL */
2066 brcms_b_core_phypll_ctl(wlc_hw
, true);
2068 /* clear sw intstatus */
2069 wlc_hw
->wlc
->macintstatus
= 0;
2071 /* restore the clk setting */
2073 brcms_b_clkctl_clk(wlc_hw
, BCMA_CLKMODE_DYNAMIC
);
2076 /* txfifo sizes needs to be modified(increased) since the newer cores
2079 static void brcms_b_corerev_fifofixup(struct brcms_hardware
*wlc_hw
)
2081 struct bcma_device
*core
= wlc_hw
->d11core
;
2083 u16 txfifo_startblk
= TXFIFO_START_BLK
, txfifo_endblk
;
2084 u16 txfifo_def
, txfifo_def1
;
2087 /* tx fifos start at TXFIFO_START_BLK from the Base address */
2088 txfifo_startblk
= TXFIFO_START_BLK
;
2090 /* sequence of operations: reset fifo, set fifo size, reset fifo */
2091 for (fifo_nu
= 0; fifo_nu
< NFIFO
; fifo_nu
++) {
2093 txfifo_endblk
= txfifo_startblk
+ wlc_hw
->xmtfifo_sz
[fifo_nu
];
2094 txfifo_def
= (txfifo_startblk
& 0xff) |
2095 (((txfifo_endblk
- 1) & 0xff) << TXFIFO_FIFOTOP_SHIFT
);
2096 txfifo_def1
= ((txfifo_startblk
>> 8) & 0x1) |
2098 1) >> 8) & 0x1) << TXFIFO_FIFOTOP_SHIFT
);
2100 TXFIFOCMD_RESET_MASK
| (fifo_nu
<< TXFIFOCMD_FIFOSEL_SHIFT
);
2102 bcma_write16(core
, D11REGOFFS(xmtfifocmd
), txfifo_cmd
);
2103 bcma_write16(core
, D11REGOFFS(xmtfifodef
), txfifo_def
);
2104 bcma_write16(core
, D11REGOFFS(xmtfifodef1
), txfifo_def1
);
2106 bcma_write16(core
, D11REGOFFS(xmtfifocmd
), txfifo_cmd
);
2108 txfifo_startblk
+= wlc_hw
->xmtfifo_sz
[fifo_nu
];
2111 * need to propagate to shm location to be in sync since ucode/hw won't
2114 brcms_b_write_shm(wlc_hw
, M_FIFOSIZE0
,
2115 wlc_hw
->xmtfifo_sz
[TX_AC_BE_FIFO
]);
2116 brcms_b_write_shm(wlc_hw
, M_FIFOSIZE1
,
2117 wlc_hw
->xmtfifo_sz
[TX_AC_VI_FIFO
]);
2118 brcms_b_write_shm(wlc_hw
, M_FIFOSIZE2
,
2119 ((wlc_hw
->xmtfifo_sz
[TX_AC_VO_FIFO
] << 8) | wlc_hw
->
2120 xmtfifo_sz
[TX_AC_BK_FIFO
]));
2121 brcms_b_write_shm(wlc_hw
, M_FIFOSIZE3
,
2122 ((wlc_hw
->xmtfifo_sz
[TX_ATIM_FIFO
] << 8) | wlc_hw
->
2123 xmtfifo_sz
[TX_BCMC_FIFO
]));
2126 /* This function is used for changing the tsf frac register
2127 * If spur avoidance mode is off, the mac freq will be 80/120/160Mhz
2128 * If spur avoidance mode is on1, the mac freq will be 82/123/164Mhz
2129 * If spur avoidance mode is on2, the mac freq will be 84/126/168Mhz
2130 * HTPHY Formula is 2^26/freq(MHz) e.g.
2131 * For spuron2 - 126MHz -> 2^26/126 = 532610.0
2132 * - 532610 = 0x82082 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x2082
2133 * For spuron: 123MHz -> 2^26/123 = 545600.5
2134 * - 545601 = 0x85341 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x5341
2135 * For spur off: 120MHz -> 2^26/120 = 559240.5
2136 * - 559241 = 0x88889 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x8889
2139 void brcms_b_switch_macfreq(struct brcms_hardware
*wlc_hw
, u8 spurmode
)
2141 struct bcma_device
*core
= wlc_hw
->d11core
;
2143 if ((ai_get_chip_id(wlc_hw
->sih
) == BCMA_CHIP_ID_BCM43224
) ||
2144 (ai_get_chip_id(wlc_hw
->sih
) == BCMA_CHIP_ID_BCM43225
)) {
2145 if (spurmode
== WL_SPURAVOID_ON2
) { /* 126Mhz */
2146 bcma_write16(core
, D11REGOFFS(tsf_clk_frac_l
), 0x2082);
2147 bcma_write16(core
, D11REGOFFS(tsf_clk_frac_h
), 0x8);
2148 } else if (spurmode
== WL_SPURAVOID_ON1
) { /* 123Mhz */
2149 bcma_write16(core
, D11REGOFFS(tsf_clk_frac_l
), 0x5341);
2150 bcma_write16(core
, D11REGOFFS(tsf_clk_frac_h
), 0x8);
2151 } else { /* 120Mhz */
2152 bcma_write16(core
, D11REGOFFS(tsf_clk_frac_l
), 0x8889);
2153 bcma_write16(core
, D11REGOFFS(tsf_clk_frac_h
), 0x8);
2155 } else if (BRCMS_ISLCNPHY(wlc_hw
->band
)) {
2156 if (spurmode
== WL_SPURAVOID_ON1
) { /* 82Mhz */
2157 bcma_write16(core
, D11REGOFFS(tsf_clk_frac_l
), 0x7CE0);
2158 bcma_write16(core
, D11REGOFFS(tsf_clk_frac_h
), 0xC);
2159 } else { /* 80Mhz */
2160 bcma_write16(core
, D11REGOFFS(tsf_clk_frac_l
), 0xCCCD);
2161 bcma_write16(core
, D11REGOFFS(tsf_clk_frac_h
), 0xC);
2166 /* Initialize GPIOs that are controlled by D11 core */
2167 static void brcms_c_gpio_init(struct brcms_c_info
*wlc
)
2169 struct brcms_hardware
*wlc_hw
= wlc
->hw
;
2172 /* use GPIO select 0 to get all gpio signals from the gpio out reg */
2173 brcms_b_mctrl(wlc_hw
, MCTL_GPOUT_SEL_MASK
, 0);
2176 * Common GPIO setup:
2177 * G0 = LED 0 = WLAN Activity
2178 * G1 = LED 1 = WLAN 2.4 GHz Radio State
2179 * G2 = LED 2 = WLAN 5 GHz Radio State
2180 * G4 = radio disable input (HI enabled, LO disabled)
2185 /* Allocate GPIOs for mimo antenna diversity feature */
2186 if (wlc_hw
->antsel_type
== ANTSEL_2x3
) {
2187 /* Enable antenna diversity, use 2x3 mode */
2188 brcms_b_mhf(wlc_hw
, MHF3
, MHF3_ANTSEL_EN
,
2189 MHF3_ANTSEL_EN
, BRCM_BAND_ALL
);
2190 brcms_b_mhf(wlc_hw
, MHF3
, MHF3_ANTSEL_MODE
,
2191 MHF3_ANTSEL_MODE
, BRCM_BAND_ALL
);
2193 /* init superswitch control */
2194 wlc_phy_antsel_init(wlc_hw
->band
->pi
, false);
2196 } else if (wlc_hw
->antsel_type
== ANTSEL_2x4
) {
2197 gm
|= gc
|= (BOARD_GPIO_12
| BOARD_GPIO_13
);
2199 * The board itself is powered by these GPIOs
2200 * (when not sending pattern) so set them high
2202 bcma_set16(wlc_hw
->d11core
, D11REGOFFS(psm_gpio_oe
),
2203 (BOARD_GPIO_12
| BOARD_GPIO_13
));
2204 bcma_set16(wlc_hw
->d11core
, D11REGOFFS(psm_gpio_out
),
2205 (BOARD_GPIO_12
| BOARD_GPIO_13
));
2207 /* Enable antenna diversity, use 2x4 mode */
2208 brcms_b_mhf(wlc_hw
, MHF3
, MHF3_ANTSEL_EN
,
2209 MHF3_ANTSEL_EN
, BRCM_BAND_ALL
);
2210 brcms_b_mhf(wlc_hw
, MHF3
, MHF3_ANTSEL_MODE
, 0,
2213 /* Configure the desired clock to be 4Mhz */
2214 brcms_b_write_shm(wlc_hw
, M_ANTSEL_CLKDIV
,
2215 ANTSEL_CLKDIV_4MHZ
);
2219 * gpio 9 controls the PA. ucode is responsible
2220 * for wiggling out and oe
2222 if (wlc_hw
->boardflags
& BFL_PACTRL
)
2223 gm
|= gc
|= BOARD_GPIO_PACTRL
;
2225 /* apply to gpiocontrol register */
2226 bcma_chipco_gpio_control(&wlc_hw
->d11core
->bus
->drv_cc
, gm
, gc
);
2229 static void brcms_ucode_write(struct brcms_hardware
*wlc_hw
,
2230 const __le32 ucode
[], const size_t nbytes
)
2232 struct bcma_device
*core
= wlc_hw
->d11core
;
2236 brcms_dbg_info(wlc_hw
->d11core
, "wl%d\n", wlc_hw
->unit
);
2238 count
= (nbytes
/ sizeof(u32
));
2240 bcma_write32(core
, D11REGOFFS(objaddr
),
2241 OBJADDR_AUTO_INC
| OBJADDR_UCM_SEL
);
2242 (void)bcma_read32(core
, D11REGOFFS(objaddr
));
2243 for (i
= 0; i
< count
; i
++)
2244 bcma_write32(core
, D11REGOFFS(objdata
), le32_to_cpu(ucode
[i
]));
2248 static void brcms_ucode_download(struct brcms_hardware
*wlc_hw
)
2250 struct brcms_c_info
*wlc
;
2251 struct brcms_ucode
*ucode
= &wlc_hw
->wlc
->wl
->ucode
;
2255 if (wlc_hw
->ucode_loaded
)
2258 if (D11REV_IS(wlc_hw
->corerev
, 17) || D11REV_IS(wlc_hw
->corerev
, 23)) {
2259 if (BRCMS_ISNPHY(wlc_hw
->band
)) {
2260 brcms_ucode_write(wlc_hw
, ucode
->bcm43xx_16_mimo
,
2261 ucode
->bcm43xx_16_mimosz
);
2262 wlc_hw
->ucode_loaded
= true;
2264 brcms_err(wlc_hw
->d11core
,
2265 "%s: wl%d: unsupported phy in corerev %d\n",
2266 __func__
, wlc_hw
->unit
, wlc_hw
->corerev
);
2267 } else if (D11REV_IS(wlc_hw
->corerev
, 24)) {
2268 if (BRCMS_ISLCNPHY(wlc_hw
->band
)) {
2269 brcms_ucode_write(wlc_hw
, ucode
->bcm43xx_24_lcn
,
2270 ucode
->bcm43xx_24_lcnsz
);
2271 wlc_hw
->ucode_loaded
= true;
2273 brcms_err(wlc_hw
->d11core
,
2274 "%s: wl%d: unsupported phy in corerev %d\n",
2275 __func__
, wlc_hw
->unit
, wlc_hw
->corerev
);
2280 void brcms_b_txant_set(struct brcms_hardware
*wlc_hw
, u16 phytxant
)
2282 /* update sw state */
2283 wlc_hw
->bmac_phytxant
= phytxant
;
2285 /* push to ucode if up */
2288 brcms_c_ucode_txant_set(wlc_hw
);
2292 u16
brcms_b_get_txant(struct brcms_hardware
*wlc_hw
)
2294 return (u16
) wlc_hw
->wlc
->stf
->txant
;
2297 void brcms_b_antsel_type_set(struct brcms_hardware
*wlc_hw
, u8 antsel_type
)
2299 wlc_hw
->antsel_type
= antsel_type
;
2301 /* Update the antsel type for phy module to use */
2302 wlc_phy_antsel_type_set(wlc_hw
->band
->pi
, antsel_type
);
2305 static void brcms_b_fifoerrors(struct brcms_hardware
*wlc_hw
)
2309 uint intstatus
, idx
;
2310 struct bcma_device
*core
= wlc_hw
->d11core
;
2312 unit
= wlc_hw
->unit
;
2314 for (idx
= 0; idx
< NFIFO
; idx
++) {
2315 /* read intstatus register and ignore any non-error bits */
2318 D11REGOFFS(intctrlregs
[idx
].intstatus
)) &
2323 brcms_dbg_int(core
, "wl%d: intstatus%d 0x%x\n",
2324 unit
, idx
, intstatus
);
2326 if (intstatus
& I_RO
) {
2327 brcms_err(core
, "wl%d: fifo %d: receive fifo "
2328 "overflow\n", unit
, idx
);
2332 if (intstatus
& I_PC
) {
2333 brcms_err(core
, "wl%d: fifo %d: descriptor error\n",
2338 if (intstatus
& I_PD
) {
2339 brcms_err(core
, "wl%d: fifo %d: data error\n", unit
,
2344 if (intstatus
& I_DE
) {
2345 brcms_err(core
, "wl%d: fifo %d: descriptor protocol "
2346 "error\n", unit
, idx
);
2350 if (intstatus
& I_RU
)
2351 brcms_err(core
, "wl%d: fifo %d: receive descriptor "
2352 "underflow\n", idx
, unit
);
2354 if (intstatus
& I_XU
) {
2355 brcms_err(core
, "wl%d: fifo %d: transmit fifo "
2356 "underflow\n", idx
, unit
);
2361 brcms_fatal_error(wlc_hw
->wlc
->wl
); /* big hammer */
2365 D11REGOFFS(intctrlregs
[idx
].intstatus
),
2370 void brcms_c_intrson(struct brcms_c_info
*wlc
)
2372 struct brcms_hardware
*wlc_hw
= wlc
->hw
;
2373 wlc
->macintmask
= wlc
->defmacintmask
;
2374 bcma_write32(wlc_hw
->d11core
, D11REGOFFS(macintmask
), wlc
->macintmask
);
2377 u32
brcms_c_intrsoff(struct brcms_c_info
*wlc
)
2379 struct brcms_hardware
*wlc_hw
= wlc
->hw
;
2385 macintmask
= wlc
->macintmask
; /* isr can still happen */
2387 bcma_write32(wlc_hw
->d11core
, D11REGOFFS(macintmask
), 0);
2388 (void)bcma_read32(wlc_hw
->d11core
, D11REGOFFS(macintmask
));
2389 udelay(1); /* ensure int line is no longer driven */
2390 wlc
->macintmask
= 0;
2392 /* return previous macintmask; resolve race between us and our isr */
2393 return wlc
->macintstatus
? 0 : macintmask
;
2396 void brcms_c_intrsrestore(struct brcms_c_info
*wlc
, u32 macintmask
)
2398 struct brcms_hardware
*wlc_hw
= wlc
->hw
;
2402 wlc
->macintmask
= macintmask
;
2403 bcma_write32(wlc_hw
->d11core
, D11REGOFFS(macintmask
), wlc
->macintmask
);
2406 /* assumes that the d11 MAC is enabled */
2407 static void brcms_b_tx_fifo_suspend(struct brcms_hardware
*wlc_hw
,
2410 u8 fifo
= 1 << tx_fifo
;
2412 /* Two clients of this code, 11h Quiet period and scanning. */
2414 /* only suspend if not already suspended */
2415 if ((wlc_hw
->suspended_fifos
& fifo
) == fifo
)
2418 /* force the core awake only if not already */
2419 if (wlc_hw
->suspended_fifos
== 0)
2420 brcms_c_ucode_wake_override_set(wlc_hw
,
2421 BRCMS_WAKE_OVERRIDE_TXFIFO
);
2423 wlc_hw
->suspended_fifos
|= fifo
;
2425 if (wlc_hw
->di
[tx_fifo
]) {
2427 * Suspending AMPDU transmissions in the middle can cause
2428 * underflow which may result in mismatch between ucode and
2429 * driver so suspend the mac before suspending the FIFO
2431 if (BRCMS_PHY_11N_CAP(wlc_hw
->band
))
2432 brcms_c_suspend_mac_and_wait(wlc_hw
->wlc
);
2434 dma_txsuspend(wlc_hw
->di
[tx_fifo
]);
2436 if (BRCMS_PHY_11N_CAP(wlc_hw
->band
))
2437 brcms_c_enable_mac(wlc_hw
->wlc
);
2441 static void brcms_b_tx_fifo_resume(struct brcms_hardware
*wlc_hw
,
2444 /* BMAC_NOTE: BRCMS_TX_FIFO_ENAB is done in brcms_c_dpc() for DMA case
2445 * but need to be done here for PIO otherwise the watchdog will catch
2446 * the inconsistency and fire
2448 /* Two clients of this code, 11h Quiet period and scanning. */
2449 if (wlc_hw
->di
[tx_fifo
])
2450 dma_txresume(wlc_hw
->di
[tx_fifo
]);
2452 /* allow core to sleep again */
2453 if (wlc_hw
->suspended_fifos
== 0)
2456 wlc_hw
->suspended_fifos
&= ~(1 << tx_fifo
);
2457 if (wlc_hw
->suspended_fifos
== 0)
2458 brcms_c_ucode_wake_override_clear(wlc_hw
,
2459 BRCMS_WAKE_OVERRIDE_TXFIFO
);
2463 /* precondition: requires the mac core to be enabled */
2464 static void brcms_b_mute(struct brcms_hardware
*wlc_hw
, bool mute_tx
)
2466 static const u8 null_ether_addr
[ETH_ALEN
] = {0, 0, 0, 0, 0, 0};
2467 u8
*ethaddr
= wlc_hw
->wlc
->pub
->cur_etheraddr
;
2470 /* suspend tx fifos */
2471 brcms_b_tx_fifo_suspend(wlc_hw
, TX_DATA_FIFO
);
2472 brcms_b_tx_fifo_suspend(wlc_hw
, TX_CTL_FIFO
);
2473 brcms_b_tx_fifo_suspend(wlc_hw
, TX_AC_BK_FIFO
);
2474 brcms_b_tx_fifo_suspend(wlc_hw
, TX_AC_VI_FIFO
);
2476 /* zero the address match register so we do not send ACKs */
2477 brcms_b_set_addrmatch(wlc_hw
, RCM_MAC_OFFSET
, null_ether_addr
);
2479 /* resume tx fifos */
2480 brcms_b_tx_fifo_resume(wlc_hw
, TX_DATA_FIFO
);
2481 brcms_b_tx_fifo_resume(wlc_hw
, TX_CTL_FIFO
);
2482 brcms_b_tx_fifo_resume(wlc_hw
, TX_AC_BK_FIFO
);
2483 brcms_b_tx_fifo_resume(wlc_hw
, TX_AC_VI_FIFO
);
2485 /* Restore address */
2486 brcms_b_set_addrmatch(wlc_hw
, RCM_MAC_OFFSET
, ethaddr
);
2489 wlc_phy_mute_upd(wlc_hw
->band
->pi
, mute_tx
, 0);
2492 brcms_c_ucode_mute_override_set(wlc_hw
);
2494 brcms_c_ucode_mute_override_clear(wlc_hw
);
2498 brcms_c_mute(struct brcms_c_info
*wlc
, bool mute_tx
)
2500 brcms_b_mute(wlc
->hw
, mute_tx
);
2504 * Read and clear macintmask and macintstatus and intstatus registers.
2505 * This routine should be called with interrupts off
2507 * -1 if brcms_deviceremoved(wlc) evaluates to true;
2508 * 0 if the interrupt is not for us, or we are in some special cases;
2509 * device interrupt status bits otherwise.
2511 static inline u32
wlc_intstatus(struct brcms_c_info
*wlc
, bool in_isr
)
2513 struct brcms_hardware
*wlc_hw
= wlc
->hw
;
2514 struct bcma_device
*core
= wlc_hw
->d11core
;
2515 u32 macintstatus
, mask
;
2517 /* macintstatus includes a DMA interrupt summary bit */
2518 macintstatus
= bcma_read32(core
, D11REGOFFS(macintstatus
));
2519 mask
= in_isr
? wlc
->macintmask
: wlc
->defmacintmask
;
2521 trace_brcms_macintstatus(&core
->dev
, in_isr
, macintstatus
, mask
);
2523 /* detect cardbus removed, in power down(suspend) and in reset */
2524 if (brcms_deviceremoved(wlc
))
2527 /* brcms_deviceremoved() succeeds even when the core is still resetting,
2528 * handle that case here.
2530 if (macintstatus
== 0xffffffff)
2533 /* defer unsolicited interrupts */
2534 macintstatus
&= mask
;
2537 if (macintstatus
== 0)
2540 /* turn off the interrupts */
2541 bcma_write32(core
, D11REGOFFS(macintmask
), 0);
2542 (void)bcma_read32(core
, D11REGOFFS(macintmask
));
2543 wlc
->macintmask
= 0;
2545 /* clear device interrupts */
2546 bcma_write32(core
, D11REGOFFS(macintstatus
), macintstatus
);
2548 /* MI_DMAINT is indication of non-zero intstatus */
2549 if (macintstatus
& MI_DMAINT
)
2551 * only fifo interrupt enabled is I_RI in
2552 * RX_FIFO. If MI_DMAINT is set, assume it
2553 * is set and clear the interrupt.
2555 bcma_write32(core
, D11REGOFFS(intctrlregs
[RX_FIFO
].intstatus
),
2558 return macintstatus
;
2561 /* Update wlc->macintstatus and wlc->intstatus[]. */
2562 /* Return true if they are updated successfully. false otherwise */
2563 bool brcms_c_intrsupd(struct brcms_c_info
*wlc
)
2567 /* read and clear macintstatus and intstatus registers */
2568 macintstatus
= wlc_intstatus(wlc
, false);
2570 /* device is removed */
2571 if (macintstatus
== 0xffffffff)
2574 /* update interrupt status in software */
2575 wlc
->macintstatus
|= macintstatus
;
2581 * First-level interrupt processing.
2582 * Return true if this was our interrupt
2583 * and if further brcms_c_dpc() processing is required,
2586 bool brcms_c_isr(struct brcms_c_info
*wlc
)
2588 struct brcms_hardware
*wlc_hw
= wlc
->hw
;
2591 if (!wlc_hw
->up
|| !wlc
->macintmask
)
2594 /* read and clear macintstatus and intstatus registers */
2595 macintstatus
= wlc_intstatus(wlc
, true);
2597 if (macintstatus
== 0xffffffff) {
2598 brcms_err(wlc_hw
->d11core
,
2599 "DEVICEREMOVED detected in the ISR code path\n");
2603 /* it is not for us */
2604 if (macintstatus
== 0)
2607 /* save interrupt status bits */
2608 wlc
->macintstatus
= macintstatus
;
2614 void brcms_c_suspend_mac_and_wait(struct brcms_c_info
*wlc
)
2616 struct brcms_hardware
*wlc_hw
= wlc
->hw
;
2617 struct bcma_device
*core
= wlc_hw
->d11core
;
2620 brcms_dbg_mac80211(core
, "wl%d: bandunit %d\n", wlc_hw
->unit
,
2621 wlc_hw
->band
->bandunit
);
2624 * Track overlapping suspend requests
2626 wlc_hw
->mac_suspend_depth
++;
2627 if (wlc_hw
->mac_suspend_depth
> 1)
2630 /* force the core awake */
2631 brcms_c_ucode_wake_override_set(wlc_hw
, BRCMS_WAKE_OVERRIDE_MACSUSPEND
);
2633 mc
= bcma_read32(core
, D11REGOFFS(maccontrol
));
2635 if (mc
== 0xffffffff) {
2636 brcms_err(core
, "wl%d: %s: dead chip\n", wlc_hw
->unit
,
2638 brcms_down(wlc
->wl
);
2641 WARN_ON(mc
& MCTL_PSM_JMP_0
);
2642 WARN_ON(!(mc
& MCTL_PSM_RUN
));
2643 WARN_ON(!(mc
& MCTL_EN_MAC
));
2645 mi
= bcma_read32(core
, D11REGOFFS(macintstatus
));
2646 if (mi
== 0xffffffff) {
2647 brcms_err(core
, "wl%d: %s: dead chip\n", wlc_hw
->unit
,
2649 brcms_down(wlc
->wl
);
2652 WARN_ON(mi
& MI_MACSSPNDD
);
2654 brcms_b_mctrl(wlc_hw
, MCTL_EN_MAC
, 0);
2656 SPINWAIT(!(bcma_read32(core
, D11REGOFFS(macintstatus
)) & MI_MACSSPNDD
),
2657 BRCMS_MAX_MAC_SUSPEND
);
2659 if (!(bcma_read32(core
, D11REGOFFS(macintstatus
)) & MI_MACSSPNDD
)) {
2660 brcms_err(core
, "wl%d: wlc_suspend_mac_and_wait: waited %d uS"
2661 " and MI_MACSSPNDD is still not on.\n",
2662 wlc_hw
->unit
, BRCMS_MAX_MAC_SUSPEND
);
2663 brcms_err(core
, "wl%d: psmdebug 0x%08x, phydebug 0x%08x, "
2664 "psm_brc 0x%04x\n", wlc_hw
->unit
,
2665 bcma_read32(core
, D11REGOFFS(psmdebug
)),
2666 bcma_read32(core
, D11REGOFFS(phydebug
)),
2667 bcma_read16(core
, D11REGOFFS(psm_brc
)));
2670 mc
= bcma_read32(core
, D11REGOFFS(maccontrol
));
2671 if (mc
== 0xffffffff) {
2672 brcms_err(core
, "wl%d: %s: dead chip\n", wlc_hw
->unit
,
2674 brcms_down(wlc
->wl
);
2677 WARN_ON(mc
& MCTL_PSM_JMP_0
);
2678 WARN_ON(!(mc
& MCTL_PSM_RUN
));
2679 WARN_ON(mc
& MCTL_EN_MAC
);
2682 void brcms_c_enable_mac(struct brcms_c_info
*wlc
)
2684 struct brcms_hardware
*wlc_hw
= wlc
->hw
;
2685 struct bcma_device
*core
= wlc_hw
->d11core
;
2688 brcms_dbg_mac80211(core
, "wl%d: bandunit %d\n", wlc_hw
->unit
,
2689 wlc
->band
->bandunit
);
2692 * Track overlapping suspend requests
2694 wlc_hw
->mac_suspend_depth
--;
2695 if (wlc_hw
->mac_suspend_depth
> 0)
2698 mc
= bcma_read32(core
, D11REGOFFS(maccontrol
));
2699 WARN_ON(mc
& MCTL_PSM_JMP_0
);
2700 WARN_ON(mc
& MCTL_EN_MAC
);
2701 WARN_ON(!(mc
& MCTL_PSM_RUN
));
2703 brcms_b_mctrl(wlc_hw
, MCTL_EN_MAC
, MCTL_EN_MAC
);
2704 bcma_write32(core
, D11REGOFFS(macintstatus
), MI_MACSSPNDD
);
2706 mc
= bcma_read32(core
, D11REGOFFS(maccontrol
));
2707 WARN_ON(mc
& MCTL_PSM_JMP_0
);
2708 WARN_ON(!(mc
& MCTL_EN_MAC
));
2709 WARN_ON(!(mc
& MCTL_PSM_RUN
));
2711 mi
= bcma_read32(core
, D11REGOFFS(macintstatus
));
2712 WARN_ON(mi
& MI_MACSSPNDD
);
2714 brcms_c_ucode_wake_override_clear(wlc_hw
,
2715 BRCMS_WAKE_OVERRIDE_MACSUSPEND
);
2718 void brcms_b_band_stf_ss_set(struct brcms_hardware
*wlc_hw
, u8 stf_mode
)
2720 wlc_hw
->hw_stf_ss_opmode
= stf_mode
;
2723 brcms_upd_ofdm_pctl1_table(wlc_hw
);
2726 static bool brcms_b_validate_chip_access(struct brcms_hardware
*wlc_hw
)
2728 struct bcma_device
*core
= wlc_hw
->d11core
;
2730 struct wiphy
*wiphy
= wlc_hw
->wlc
->wiphy
;
2732 /* Validate dchip register access */
2734 bcma_write32(core
, D11REGOFFS(objaddr
), OBJADDR_SHM_SEL
| 0);
2735 (void)bcma_read32(core
, D11REGOFFS(objaddr
));
2736 w
= bcma_read32(core
, D11REGOFFS(objdata
));
2738 /* Can we write and read back a 32bit register? */
2739 bcma_write32(core
, D11REGOFFS(objaddr
), OBJADDR_SHM_SEL
| 0);
2740 (void)bcma_read32(core
, D11REGOFFS(objaddr
));
2741 bcma_write32(core
, D11REGOFFS(objdata
), (u32
) 0xaa5555aa);
2743 bcma_write32(core
, D11REGOFFS(objaddr
), OBJADDR_SHM_SEL
| 0);
2744 (void)bcma_read32(core
, D11REGOFFS(objaddr
));
2745 val
= bcma_read32(core
, D11REGOFFS(objdata
));
2746 if (val
!= (u32
) 0xaa5555aa) {
2747 wiphy_err(wiphy
, "wl%d: validate_chip_access: SHM = 0x%x, "
2748 "expected 0xaa5555aa\n", wlc_hw
->unit
, val
);
2752 bcma_write32(core
, D11REGOFFS(objaddr
), OBJADDR_SHM_SEL
| 0);
2753 (void)bcma_read32(core
, D11REGOFFS(objaddr
));
2754 bcma_write32(core
, D11REGOFFS(objdata
), (u32
) 0x55aaaa55);
2756 bcma_write32(core
, D11REGOFFS(objaddr
), OBJADDR_SHM_SEL
| 0);
2757 (void)bcma_read32(core
, D11REGOFFS(objaddr
));
2758 val
= bcma_read32(core
, D11REGOFFS(objdata
));
2759 if (val
!= (u32
) 0x55aaaa55) {
2760 wiphy_err(wiphy
, "wl%d: validate_chip_access: SHM = 0x%x, "
2761 "expected 0x55aaaa55\n", wlc_hw
->unit
, val
);
2765 bcma_write32(core
, D11REGOFFS(objaddr
), OBJADDR_SHM_SEL
| 0);
2766 (void)bcma_read32(core
, D11REGOFFS(objaddr
));
2767 bcma_write32(core
, D11REGOFFS(objdata
), w
);
2769 /* clear CFPStart */
2770 bcma_write32(core
, D11REGOFFS(tsf_cfpstart
), 0);
2772 w
= bcma_read32(core
, D11REGOFFS(maccontrol
));
2773 if ((w
!= (MCTL_IHR_EN
| MCTL_WAKE
)) &&
2774 (w
!= (MCTL_IHR_EN
| MCTL_GMODE
| MCTL_WAKE
))) {
2775 wiphy_err(wiphy
, "wl%d: validate_chip_access: maccontrol = "
2776 "0x%x, expected 0x%x or 0x%x\n", wlc_hw
->unit
, w
,
2777 (MCTL_IHR_EN
| MCTL_WAKE
),
2778 (MCTL_IHR_EN
| MCTL_GMODE
| MCTL_WAKE
));
2785 #define PHYPLL_WAIT_US 100000
2787 void brcms_b_core_phypll_ctl(struct brcms_hardware
*wlc_hw
, bool on
)
2789 struct bcma_device
*core
= wlc_hw
->d11core
;
2792 brcms_dbg_info(core
, "wl%d\n", wlc_hw
->unit
);
2797 if ((ai_get_chip_id(wlc_hw
->sih
) == BCMA_CHIP_ID_BCM4313
)) {
2798 bcma_set32(core
, D11REGOFFS(clk_ctl_st
),
2800 CCS_ERSRC_REQ_D11PLL
|
2801 CCS_ERSRC_REQ_PHYPLL
);
2802 SPINWAIT((bcma_read32(core
, D11REGOFFS(clk_ctl_st
)) &
2803 CCS_ERSRC_AVAIL_HT
) != CCS_ERSRC_AVAIL_HT
,
2806 tmp
= bcma_read32(core
, D11REGOFFS(clk_ctl_st
));
2807 if ((tmp
& CCS_ERSRC_AVAIL_HT
) != CCS_ERSRC_AVAIL_HT
)
2808 brcms_err(core
, "%s: turn on PHY PLL failed\n",
2811 bcma_set32(core
, D11REGOFFS(clk_ctl_st
),
2812 tmp
| CCS_ERSRC_REQ_D11PLL
|
2813 CCS_ERSRC_REQ_PHYPLL
);
2814 SPINWAIT((bcma_read32(core
, D11REGOFFS(clk_ctl_st
)) &
2815 (CCS_ERSRC_AVAIL_D11PLL
|
2816 CCS_ERSRC_AVAIL_PHYPLL
)) !=
2817 (CCS_ERSRC_AVAIL_D11PLL
|
2818 CCS_ERSRC_AVAIL_PHYPLL
), PHYPLL_WAIT_US
);
2820 tmp
= bcma_read32(core
, D11REGOFFS(clk_ctl_st
));
2822 (CCS_ERSRC_AVAIL_D11PLL
| CCS_ERSRC_AVAIL_PHYPLL
))
2824 (CCS_ERSRC_AVAIL_D11PLL
| CCS_ERSRC_AVAIL_PHYPLL
))
2825 brcms_err(core
, "%s: turn on PHY PLL failed\n",
2830 * Since the PLL may be shared, other cores can still
2831 * be requesting it; so we'll deassert the request but
2832 * not wait for status to comply.
2834 bcma_mask32(core
, D11REGOFFS(clk_ctl_st
),
2835 ~CCS_ERSRC_REQ_PHYPLL
);
2836 (void)bcma_read32(core
, D11REGOFFS(clk_ctl_st
));
2840 static void brcms_c_coredisable(struct brcms_hardware
*wlc_hw
)
2844 brcms_dbg_info(wlc_hw
->d11core
, "wl%d: disable core\n", wlc_hw
->unit
);
2846 dev_gone
= brcms_deviceremoved(wlc_hw
->wlc
);
2851 if (wlc_hw
->noreset
)
2855 wlc_phy_switch_radio(wlc_hw
->band
->pi
, OFF
);
2857 /* turn off analog core */
2858 wlc_phy_anacore(wlc_hw
->band
->pi
, OFF
);
2860 /* turn off PHYPLL to save power */
2861 brcms_b_core_phypll_ctl(wlc_hw
, false);
2863 wlc_hw
->clk
= false;
2864 bcma_core_disable(wlc_hw
->d11core
, 0);
2865 wlc_phy_hw_clk_state_upd(wlc_hw
->band
->pi
, false);
2868 static void brcms_c_flushqueues(struct brcms_c_info
*wlc
)
2870 struct brcms_hardware
*wlc_hw
= wlc
->hw
;
2873 /* free any posted tx packets */
2874 for (i
= 0; i
< NFIFO
; i
++) {
2875 if (wlc_hw
->di
[i
]) {
2876 dma_txreclaim(wlc_hw
->di
[i
], DMA_RANGE_ALL
);
2877 if (i
< TX_BCMC_FIFO
)
2878 ieee80211_wake_queue(wlc
->pub
->ieee_hw
,
2879 brcms_fifo_to_ac(i
));
2883 /* free any posted rx packets */
2884 dma_rxreclaim(wlc_hw
->di
[RX_FIFO
]);
2888 brcms_b_read_objmem(struct brcms_hardware
*wlc_hw
, uint offset
, u32 sel
)
2890 struct bcma_device
*core
= wlc_hw
->d11core
;
2891 u16 objoff
= D11REGOFFS(objdata
);
2893 bcma_write32(core
, D11REGOFFS(objaddr
), sel
| (offset
>> 2));
2894 (void)bcma_read32(core
, D11REGOFFS(objaddr
));
2898 return bcma_read16(core
, objoff
);
2902 brcms_b_write_objmem(struct brcms_hardware
*wlc_hw
, uint offset
, u16 v
,
2905 struct bcma_device
*core
= wlc_hw
->d11core
;
2906 u16 objoff
= D11REGOFFS(objdata
);
2908 bcma_write32(core
, D11REGOFFS(objaddr
), sel
| (offset
>> 2));
2909 (void)bcma_read32(core
, D11REGOFFS(objaddr
));
2913 bcma_wflush16(core
, objoff
, v
);
2917 * Read a single u16 from shared memory.
2918 * SHM 'offset' needs to be an even address
2920 u16
brcms_b_read_shm(struct brcms_hardware
*wlc_hw
, uint offset
)
2922 return brcms_b_read_objmem(wlc_hw
, offset
, OBJADDR_SHM_SEL
);
2926 * Write a single u16 to shared memory.
2927 * SHM 'offset' needs to be an even address
2929 void brcms_b_write_shm(struct brcms_hardware
*wlc_hw
, uint offset
, u16 v
)
2931 brcms_b_write_objmem(wlc_hw
, offset
, v
, OBJADDR_SHM_SEL
);
2935 * Copy a buffer to shared memory of specified type .
2936 * SHM 'offset' needs to be an even address and
2937 * Buffer length 'len' must be an even number of bytes
2938 * 'sel' selects the type of memory
2941 brcms_b_copyto_objmem(struct brcms_hardware
*wlc_hw
, uint offset
,
2942 const void *buf
, int len
, u32 sel
)
2945 const u8
*p
= (const u8
*)buf
;
2948 if (len
<= 0 || (offset
& 1) || (len
& 1))
2951 for (i
= 0; i
< len
; i
+= 2) {
2952 v
= p
[i
] | (p
[i
+ 1] << 8);
2953 brcms_b_write_objmem(wlc_hw
, offset
+ i
, v
, sel
);
2958 * Copy a piece of shared memory of specified type to a buffer .
2959 * SHM 'offset' needs to be an even address and
2960 * Buffer length 'len' must be an even number of bytes
2961 * 'sel' selects the type of memory
2964 brcms_b_copyfrom_objmem(struct brcms_hardware
*wlc_hw
, uint offset
, void *buf
,
2971 if (len
<= 0 || (offset
& 1) || (len
& 1))
2974 for (i
= 0; i
< len
; i
+= 2) {
2975 v
= brcms_b_read_objmem(wlc_hw
, offset
+ i
, sel
);
2977 p
[i
+ 1] = (v
>> 8) & 0xFF;
2981 /* Copy a buffer to shared memory.
2982 * SHM 'offset' needs to be an even address and
2983 * Buffer length 'len' must be an even number of bytes
2985 static void brcms_c_copyto_shm(struct brcms_c_info
*wlc
, uint offset
,
2986 const void *buf
, int len
)
2988 brcms_b_copyto_objmem(wlc
->hw
, offset
, buf
, len
, OBJADDR_SHM_SEL
);
2991 static void brcms_b_retrylimit_upd(struct brcms_hardware
*wlc_hw
,
2997 /* write retry limit to SCR, shouldn't need to suspend */
2999 bcma_write32(wlc_hw
->d11core
, D11REGOFFS(objaddr
),
3000 OBJADDR_SCR_SEL
| S_DOT11_SRC_LMT
);
3001 (void)bcma_read32(wlc_hw
->d11core
, D11REGOFFS(objaddr
));
3002 bcma_write32(wlc_hw
->d11core
, D11REGOFFS(objdata
), wlc_hw
->SRL
);
3003 bcma_write32(wlc_hw
->d11core
, D11REGOFFS(objaddr
),
3004 OBJADDR_SCR_SEL
| S_DOT11_LRC_LMT
);
3005 (void)bcma_read32(wlc_hw
->d11core
, D11REGOFFS(objaddr
));
3006 bcma_write32(wlc_hw
->d11core
, D11REGOFFS(objdata
), wlc_hw
->LRL
);
3010 static void brcms_b_pllreq(struct brcms_hardware
*wlc_hw
, bool set
, u32 req_bit
)
3013 if (mboolisset(wlc_hw
->pllreq
, req_bit
))
3016 mboolset(wlc_hw
->pllreq
, req_bit
);
3018 if (mboolisset(wlc_hw
->pllreq
, BRCMS_PLLREQ_FLIP
)) {
3020 brcms_b_xtal(wlc_hw
, ON
);
3023 if (!mboolisset(wlc_hw
->pllreq
, req_bit
))
3026 mboolclr(wlc_hw
->pllreq
, req_bit
);
3028 if (mboolisset(wlc_hw
->pllreq
, BRCMS_PLLREQ_FLIP
)) {
3030 brcms_b_xtal(wlc_hw
, OFF
);
3035 static void brcms_b_antsel_set(struct brcms_hardware
*wlc_hw
, u32 antsel_avail
)
3037 wlc_hw
->antsel_avail
= antsel_avail
;
3041 * conditions under which the PM bit should be set in outgoing frames
3042 * and STAY_AWAKE is meaningful
3044 static bool brcms_c_ps_allowed(struct brcms_c_info
*wlc
)
3046 struct brcms_bss_cfg
*cfg
= wlc
->bsscfg
;
3048 /* disallow PS when one of the following global conditions meets */
3049 if (!wlc
->pub
->associated
)
3052 /* disallow PS when one of these meets when not scanning */
3053 if (wlc
->filter_flags
& FIF_PROMISC_IN_BSS
)
3056 if (cfg
->associated
) {
3058 * disallow PS when one of the following
3059 * bsscfg specific conditions meets
3070 static void brcms_c_statsupd(struct brcms_c_info
*wlc
)
3073 struct macstat macstats
;
3080 /* if driver down, make no sense to update stats */
3085 /* save last rx fifo 0 overflow count */
3086 rxf0ovfl
= wlc
->core
->macstat_snapshot
->rxf0ovfl
;
3088 /* save last tx fifo underflow count */
3089 for (i
= 0; i
< NFIFO
; i
++)
3090 txfunfl
[i
] = wlc
->core
->macstat_snapshot
->txfunfl
[i
];
3093 /* Read mac stats from contiguous shared memory */
3094 brcms_b_copyfrom_objmem(wlc
->hw
, M_UCODE_MACSTAT
, &macstats
,
3095 sizeof(struct macstat
), OBJADDR_SHM_SEL
);
3098 /* check for rx fifo 0 overflow */
3099 delta
= (u16
) (wlc
->core
->macstat_snapshot
->rxf0ovfl
- rxf0ovfl
);
3101 brcms_err(wlc
->hw
->d11core
, "wl%d: %u rx fifo 0 overflows!\n",
3102 wlc
->pub
->unit
, delta
);
3104 /* check for tx fifo underflows */
3105 for (i
= 0; i
< NFIFO
; i
++) {
3107 (u16
) (wlc
->core
->macstat_snapshot
->txfunfl
[i
] -
3110 brcms_err(wlc
->hw
->d11core
,
3111 "wl%d: %u tx fifo %d underflows!\n",
3112 wlc
->pub
->unit
, delta
, i
);
3116 /* merge counters from dma module */
3117 for (i
= 0; i
< NFIFO
; i
++) {
3119 dma_counterreset(wlc
->hw
->di
[i
]);
3123 static void brcms_b_reset(struct brcms_hardware
*wlc_hw
)
3125 /* reset the core */
3126 if (!brcms_deviceremoved(wlc_hw
->wlc
))
3127 brcms_b_corereset(wlc_hw
, BRCMS_USE_COREFLAGS
);
3129 /* purge the dma rings */
3130 brcms_c_flushqueues(wlc_hw
->wlc
);
3133 void brcms_c_reset(struct brcms_c_info
*wlc
)
3135 brcms_dbg_info(wlc
->hw
->d11core
, "wl%d\n", wlc
->pub
->unit
);
3137 /* slurp up hw mac counters before core reset */
3138 brcms_c_statsupd(wlc
);
3140 /* reset our snapshot of macstat counters */
3141 memset((char *)wlc
->core
->macstat_snapshot
, 0,
3142 sizeof(struct macstat
));
3144 brcms_b_reset(wlc
->hw
);
3147 void brcms_c_init_scb(struct scb
*scb
)
3151 memset(scb
, 0, sizeof(struct scb
));
3152 scb
->flags
= SCB_WMECAP
| SCB_HTCAP
;
3153 for (i
= 0; i
< NUMPRIO
; i
++) {
3155 scb
->seqctl
[i
] = 0xFFFF;
3158 scb
->seqctl_nonqos
= 0xFFFF;
3159 scb
->magic
= SCB_MAGIC
;
3164 * download ucode/PCM
3165 * let ucode run to suspended
3166 * download ucode inits
3167 * config other core registers
3170 static void brcms_b_coreinit(struct brcms_c_info
*wlc
)
3172 struct brcms_hardware
*wlc_hw
= wlc
->hw
;
3173 struct bcma_device
*core
= wlc_hw
->d11core
;
3177 bool fifosz_fixup
= false;
3180 struct brcms_ucode
*ucode
= &wlc_hw
->wlc
->wl
->ucode
;
3182 brcms_dbg_info(core
, "wl%d: core init\n", wlc_hw
->unit
);
3185 brcms_b_mctrl(wlc_hw
, ~0, (MCTL_IHR_EN
| MCTL_PSM_JMP_0
| MCTL_WAKE
));
3187 brcms_ucode_download(wlc_hw
);
3189 * FIFOSZ fixup. driver wants to controls the fifo allocation.
3191 fifosz_fixup
= true;
3193 /* let the PSM run to the suspended state, set mode to BSS STA */
3194 bcma_write32(core
, D11REGOFFS(macintstatus
), -1);
3195 brcms_b_mctrl(wlc_hw
, ~0,
3196 (MCTL_IHR_EN
| MCTL_INFRA
| MCTL_PSM_RUN
| MCTL_WAKE
));
3198 /* wait for ucode to self-suspend after auto-init */
3199 SPINWAIT(((bcma_read32(core
, D11REGOFFS(macintstatus
)) &
3200 MI_MACSSPNDD
) == 0), 1000 * 1000);
3201 if ((bcma_read32(core
, D11REGOFFS(macintstatus
)) & MI_MACSSPNDD
) == 0)
3202 brcms_err(core
, "wl%d: wlc_coreinit: ucode did not self-"
3203 "suspend!\n", wlc_hw
->unit
);
3205 brcms_c_gpio_init(wlc
);
3207 sflags
= bcma_aread32(core
, BCMA_IOST
);
3209 if (D11REV_IS(wlc_hw
->corerev
, 17) || D11REV_IS(wlc_hw
->corerev
, 23)) {
3210 if (BRCMS_ISNPHY(wlc_hw
->band
))
3211 brcms_c_write_inits(wlc_hw
, ucode
->d11n0initvals16
);
3213 brcms_err(core
, "%s: wl%d: unsupported phy in corerev"
3214 " %d\n", __func__
, wlc_hw
->unit
,
3216 } else if (D11REV_IS(wlc_hw
->corerev
, 24)) {
3217 if (BRCMS_ISLCNPHY(wlc_hw
->band
))
3218 brcms_c_write_inits(wlc_hw
, ucode
->d11lcn0initvals24
);
3220 brcms_err(core
, "%s: wl%d: unsupported phy in corerev"
3221 " %d\n", __func__
, wlc_hw
->unit
,
3224 brcms_err(core
, "%s: wl%d: unsupported corerev %d\n",
3225 __func__
, wlc_hw
->unit
, wlc_hw
->corerev
);
3228 /* For old ucode, txfifo sizes needs to be modified(increased) */
3230 brcms_b_corerev_fifofixup(wlc_hw
);
3232 /* check txfifo allocations match between ucode and driver */
3233 buf
[TX_AC_BE_FIFO
] = brcms_b_read_shm(wlc_hw
, M_FIFOSIZE0
);
3234 if (buf
[TX_AC_BE_FIFO
] != wlc_hw
->xmtfifo_sz
[TX_AC_BE_FIFO
]) {
3238 buf
[TX_AC_VI_FIFO
] = brcms_b_read_shm(wlc_hw
, M_FIFOSIZE1
);
3239 if (buf
[TX_AC_VI_FIFO
] != wlc_hw
->xmtfifo_sz
[TX_AC_VI_FIFO
]) {
3243 buf
[TX_AC_BK_FIFO
] = brcms_b_read_shm(wlc_hw
, M_FIFOSIZE2
);
3244 buf
[TX_AC_VO_FIFO
] = (buf
[TX_AC_BK_FIFO
] >> 8) & 0xff;
3245 buf
[TX_AC_BK_FIFO
] &= 0xff;
3246 if (buf
[TX_AC_BK_FIFO
] != wlc_hw
->xmtfifo_sz
[TX_AC_BK_FIFO
]) {
3250 if (buf
[TX_AC_VO_FIFO
] != wlc_hw
->xmtfifo_sz
[TX_AC_VO_FIFO
]) {
3254 buf
[TX_BCMC_FIFO
] = brcms_b_read_shm(wlc_hw
, M_FIFOSIZE3
);
3255 buf
[TX_ATIM_FIFO
] = (buf
[TX_BCMC_FIFO
] >> 8) & 0xff;
3256 buf
[TX_BCMC_FIFO
] &= 0xff;
3257 if (buf
[TX_BCMC_FIFO
] != wlc_hw
->xmtfifo_sz
[TX_BCMC_FIFO
]) {
3261 if (buf
[TX_ATIM_FIFO
] != wlc_hw
->xmtfifo_sz
[TX_ATIM_FIFO
]) {
3266 brcms_err(core
, "wlc_coreinit: txfifo mismatch: ucode size %d"
3267 " driver size %d index %d\n", buf
[i
],
3268 wlc_hw
->xmtfifo_sz
[i
], i
);
3270 /* make sure we can still talk to the mac */
3271 WARN_ON(bcma_read32(core
, D11REGOFFS(maccontrol
)) == 0xffffffff);
3273 /* band-specific inits done by wlc_bsinit() */
3275 /* Set up frame burst size and antenna swap threshold init values */
3276 brcms_b_write_shm(wlc_hw
, M_MBURST_SIZE
, MAXTXFRAMEBURST
);
3277 brcms_b_write_shm(wlc_hw
, M_MAX_ANTCNT
, ANTCNT
);
3279 /* enable one rx interrupt per received frame */
3280 bcma_write32(core
, D11REGOFFS(intrcvlazy
[0]), (1 << IRL_FC_SHIFT
));
3282 /* set the station mode (BSS STA) */
3283 brcms_b_mctrl(wlc_hw
,
3284 (MCTL_INFRA
| MCTL_DISCARD_PMQ
| MCTL_AP
),
3285 (MCTL_INFRA
| MCTL_DISCARD_PMQ
));
3287 /* set up Beacon interval */
3288 bcnint_us
= 0x8000 << 10;
3289 bcma_write32(core
, D11REGOFFS(tsf_cfprep
),
3290 (bcnint_us
<< CFPREP_CBI_SHIFT
));
3291 bcma_write32(core
, D11REGOFFS(tsf_cfpstart
), bcnint_us
);
3292 bcma_write32(core
, D11REGOFFS(macintstatus
), MI_GP1
);
3294 /* write interrupt mask */
3295 bcma_write32(core
, D11REGOFFS(intctrlregs
[RX_FIFO
].intmask
),
3298 /* allow the MAC to control the PHY clock (dynamic on/off) */
3299 brcms_b_macphyclk_set(wlc_hw
, ON
);
3301 /* program dynamic clock control fast powerup delay register */
3302 wlc
->fastpwrup_dly
= ai_clkctl_fast_pwrup_delay(wlc_hw
->sih
);
3303 bcma_write16(core
, D11REGOFFS(scc_fastpwrup_dly
), wlc
->fastpwrup_dly
);
3305 /* tell the ucode the corerev */
3306 brcms_b_write_shm(wlc_hw
, M_MACHW_VER
, (u16
) wlc_hw
->corerev
);
3308 /* tell the ucode MAC capabilities */
3309 brcms_b_write_shm(wlc_hw
, M_MACHW_CAP_L
,
3310 (u16
) (wlc_hw
->machwcap
& 0xffff));
3311 brcms_b_write_shm(wlc_hw
, M_MACHW_CAP_H
,
3313 machwcap
>> 16) & 0xffff));
3315 /* write retry limits to SCR, this done after PSM init */
3316 bcma_write32(core
, D11REGOFFS(objaddr
),
3317 OBJADDR_SCR_SEL
| S_DOT11_SRC_LMT
);
3318 (void)bcma_read32(core
, D11REGOFFS(objaddr
));
3319 bcma_write32(core
, D11REGOFFS(objdata
), wlc_hw
->SRL
);
3320 bcma_write32(core
, D11REGOFFS(objaddr
),
3321 OBJADDR_SCR_SEL
| S_DOT11_LRC_LMT
);
3322 (void)bcma_read32(core
, D11REGOFFS(objaddr
));
3323 bcma_write32(core
, D11REGOFFS(objdata
), wlc_hw
->LRL
);
3325 /* write rate fallback retry limits */
3326 brcms_b_write_shm(wlc_hw
, M_SFRMTXCNTFBRTHSD
, wlc_hw
->SFBL
);
3327 brcms_b_write_shm(wlc_hw
, M_LFRMTXCNTFBRTHSD
, wlc_hw
->LFBL
);
3329 bcma_mask16(core
, D11REGOFFS(ifs_ctl
), 0x0FFF);
3330 bcma_write16(core
, D11REGOFFS(ifs_aifsn
), EDCF_AIFSN_MIN
);
3332 /* init the tx dma engines */
3333 for (i
= 0; i
< NFIFO
; i
++) {
3335 dma_txinit(wlc_hw
->di
[i
]);
3338 /* init the rx dma engine(s) and post receive buffers */
3339 dma_rxinit(wlc_hw
->di
[RX_FIFO
]);
3340 dma_rxfill(wlc_hw
->di
[RX_FIFO
]);
3344 static brcms_b_init(struct brcms_hardware
*wlc_hw
, u16 chanspec
) {
3347 struct brcms_c_info
*wlc
= wlc_hw
->wlc
;
3349 /* request FAST clock if not on */
3350 fastclk
= wlc_hw
->forcefastclk
;
3352 brcms_b_clkctl_clk(wlc_hw
, BCMA_CLKMODE_FAST
);
3354 /* disable interrupts */
3355 macintmask
= brcms_intrsoff(wlc
->wl
);
3357 /* set up the specified band and chanspec */
3358 brcms_c_setxband(wlc_hw
, chspec_bandunit(chanspec
));
3359 wlc_phy_chanspec_radio_set(wlc_hw
->band
->pi
, chanspec
);
3361 /* do one-time phy inits and calibration */
3362 wlc_phy_cal_init(wlc_hw
->band
->pi
);
3364 /* core-specific initialization */
3365 brcms_b_coreinit(wlc
);
3367 /* band-specific inits */
3368 brcms_b_bsinit(wlc
, chanspec
);
3370 /* restore macintmask */
3371 brcms_intrsrestore(wlc
->wl
, macintmask
);
3373 /* seed wake_override with BRCMS_WAKE_OVERRIDE_MACSUSPEND since the mac
3374 * is suspended and brcms_c_enable_mac() will clear this override bit.
3376 mboolset(wlc_hw
->wake_override
, BRCMS_WAKE_OVERRIDE_MACSUSPEND
);
3379 * initialize mac_suspend_depth to 1 to match ucode
3380 * initial suspended state
3382 wlc_hw
->mac_suspend_depth
= 1;
3384 /* restore the clk */
3386 brcms_b_clkctl_clk(wlc_hw
, BCMA_CLKMODE_DYNAMIC
);
3389 static void brcms_c_set_phy_chanspec(struct brcms_c_info
*wlc
,
3392 /* Save our copy of the chanspec */
3393 wlc
->chanspec
= chanspec
;
3395 /* Set the chanspec and power limits for this locale */
3396 brcms_c_channel_set_chanspec(wlc
->cmi
, chanspec
, BRCMS_TXPWR_MAX
);
3398 if (wlc
->stf
->ss_algosel_auto
)
3399 brcms_c_stf_ss_algo_channel_get(wlc
, &wlc
->stf
->ss_algo_channel
,
3402 brcms_c_stf_ss_update(wlc
, wlc
->band
);
3406 brcms_default_rateset(struct brcms_c_info
*wlc
, struct brcms_c_rateset
*rs
)
3408 brcms_c_rateset_default(rs
, NULL
, wlc
->band
->phytype
,
3409 wlc
->band
->bandtype
, false, BRCMS_RATE_MASK_FULL
,
3410 (bool) (wlc
->pub
->_n_enab
& SUPPORT_11N
),
3411 brcms_chspec_bw(wlc
->default_bss
->chanspec
),
3412 wlc
->stf
->txstreams
);
3415 /* derive wlc->band->basic_rate[] table from 'rateset' */
3416 static void brcms_c_rate_lookup_init(struct brcms_c_info
*wlc
,
3417 struct brcms_c_rateset
*rateset
)
3423 u8
*br
= wlc
->band
->basic_rate
;
3426 /* incoming rates are in 500kbps units as in 802.11 Supported Rates */
3427 memset(br
, 0, BRCM_MAXRATE
+ 1);
3429 /* For each basic rate in the rates list, make an entry in the
3430 * best basic lookup.
3432 for (i
= 0; i
< rateset
->count
; i
++) {
3433 /* only make an entry for a basic rate */
3434 if (!(rateset
->rates
[i
] & BRCMS_RATE_FLAG
))
3437 /* mask off basic bit */
3438 rate
= (rateset
->rates
[i
] & BRCMS_RATE_MASK
);
3440 if (rate
> BRCM_MAXRATE
) {
3441 brcms_err(wlc
->hw
->d11core
, "brcms_c_rate_lookup_init: "
3442 "invalid rate 0x%X in rate set\n",
3450 /* The rate lookup table now has non-zero entries for each
3451 * basic rate, equal to the basic rate: br[basicN] = basicN
3453 * To look up the best basic rate corresponding to any
3454 * particular rate, code can use the basic_rate table
3457 * basic_rate = wlc->band->basic_rate[tx_rate]
3459 * Make sure there is a best basic rate entry for
3460 * every rate by walking up the table from low rates
3461 * to high, filling in holes in the lookup table
3464 for (i
= 0; i
< wlc
->band
->hw_rateset
.count
; i
++) {
3465 rate
= wlc
->band
->hw_rateset
.rates
[i
];
3467 if (br
[rate
] != 0) {
3468 /* This rate is a basic rate.
3469 * Keep track of the best basic rate so far by
3472 if (is_ofdm_rate(rate
))
3480 /* This rate is not a basic rate so figure out the
3481 * best basic rate less than this rate and fill in
3482 * the hole in the table
3485 br
[rate
] = is_ofdm_rate(rate
) ? ofdm_basic
: cck_basic
;
3490 if (is_ofdm_rate(rate
)) {
3492 * In 11g and 11a, the OFDM mandatory rates
3493 * are 6, 12, and 24 Mbps
3495 if (rate
>= BRCM_RATE_24M
)
3496 mandatory
= BRCM_RATE_24M
;
3497 else if (rate
>= BRCM_RATE_12M
)
3498 mandatory
= BRCM_RATE_12M
;
3500 mandatory
= BRCM_RATE_6M
;
3502 /* In 11b, all CCK rates are mandatory 1 - 11 Mbps */
3506 br
[rate
] = mandatory
;
3510 static void brcms_c_bandinit_ordered(struct brcms_c_info
*wlc
,
3513 struct brcms_c_rateset default_rateset
;
3515 uint i
, band_order
[2];
3518 * We might have been bandlocked during down and the chip
3519 * power-cycled (hibernate). Figure out the right band to park on
3521 if (wlc
->bandlocked
|| wlc
->pub
->_nbands
== 1) {
3522 /* updated in brcms_c_bandlock() */
3523 parkband
= wlc
->band
->bandunit
;
3524 band_order
[0] = band_order
[1] = parkband
;
3526 /* park on the band of the specified chanspec */
3527 parkband
= chspec_bandunit(chanspec
);
3529 /* order so that parkband initialize last */
3530 band_order
[0] = parkband
^ 1;
3531 band_order
[1] = parkband
;
3534 /* make each band operational, software state init */
3535 for (i
= 0; i
< wlc
->pub
->_nbands
; i
++) {
3536 uint j
= band_order
[i
];
3538 wlc
->band
= wlc
->bandstate
[j
];
3540 brcms_default_rateset(wlc
, &default_rateset
);
3542 /* fill in hw_rate */
3543 brcms_c_rateset_filter(&default_rateset
, &wlc
->band
->hw_rateset
,
3544 false, BRCMS_RATES_CCK_OFDM
, BRCMS_RATE_MASK
,
3545 (bool) (wlc
->pub
->_n_enab
& SUPPORT_11N
));
3547 /* init basic rate lookup */
3548 brcms_c_rate_lookup_init(wlc
, &default_rateset
);
3551 /* sync up phy/radio chanspec */
3552 brcms_c_set_phy_chanspec(wlc
, chanspec
);
3556 * Set or clear filtering related maccontrol bits based on
3557 * specified filter flags
3559 void brcms_c_mac_promisc(struct brcms_c_info
*wlc
, uint filter_flags
)
3561 u32 promisc_bits
= 0;
3563 wlc
->filter_flags
= filter_flags
;
3565 if (filter_flags
& (FIF_PROMISC_IN_BSS
| FIF_OTHER_BSS
))
3566 promisc_bits
|= MCTL_PROMISC
;
3568 if (filter_flags
& FIF_BCN_PRBRESP_PROMISC
)
3569 promisc_bits
|= MCTL_BCNS_PROMISC
;
3571 if (filter_flags
& FIF_FCSFAIL
)
3572 promisc_bits
|= MCTL_KEEPBADFCS
;
3574 if (filter_flags
& (FIF_CONTROL
| FIF_PSPOLL
))
3575 promisc_bits
|= MCTL_KEEPCONTROL
;
3577 brcms_b_mctrl(wlc
->hw
,
3578 MCTL_PROMISC
| MCTL_BCNS_PROMISC
|
3579 MCTL_KEEPCONTROL
| MCTL_KEEPBADFCS
,
3584 * ucode, hwmac update
3585 * Channel dependent updates for ucode and hw
3587 static void brcms_c_ucode_mac_upd(struct brcms_c_info
*wlc
)
3589 /* enable or disable any active IBSSs depending on whether or not
3590 * we are on the home channel
3592 if (wlc
->home_chanspec
== wlc_phy_chanspec_get(wlc
->band
->pi
)) {
3593 if (wlc
->pub
->associated
) {
3595 * BMAC_NOTE: This is something that should be fixed
3596 * in ucode inits. I think that the ucode inits set
3597 * up the bcn templates and shm values with a bogus
3598 * beacon. This should not be done in the inits. If
3599 * ucode needs to set up a beacon for testing, the
3600 * test routines should write it down, not expect the
3601 * inits to populate a bogus beacon.
3603 if (BRCMS_PHY_11N_CAP(wlc
->band
))
3604 brcms_b_write_shm(wlc
->hw
,
3605 M_BCN_TXTSF_OFFSET
, 0);
3608 /* disable an active IBSS if we are not on the home channel */
3612 static void brcms_c_write_rate_shm(struct brcms_c_info
*wlc
, u8 rate
,
3616 u8 basic_phy_rate
, basic_index
;
3617 u16 dir_table
, basic_table
;
3620 /* Shared memory address for the table we are reading */
3621 dir_table
= is_ofdm_rate(basic_rate
) ? M_RT_DIRMAP_A
: M_RT_DIRMAP_B
;
3623 /* Shared memory address for the table we are writing */
3624 basic_table
= is_ofdm_rate(rate
) ? M_RT_BBRSMAP_A
: M_RT_BBRSMAP_B
;
3627 * for a given rate, the LS-nibble of the PLCP SIGNAL field is
3628 * the index into the rate table.
3630 phy_rate
= rate_info
[rate
] & BRCMS_RATE_MASK
;
3631 basic_phy_rate
= rate_info
[basic_rate
] & BRCMS_RATE_MASK
;
3632 index
= phy_rate
& 0xf;
3633 basic_index
= basic_phy_rate
& 0xf;
3635 /* Find the SHM pointer to the ACK rate entry by looking in the
3638 basic_ptr
= brcms_b_read_shm(wlc
->hw
, (dir_table
+ basic_index
* 2));
3640 /* Update the SHM BSS-basic-rate-set mapping table with the pointer
3641 * to the correct basic rate for the given incoming rate
3643 brcms_b_write_shm(wlc
->hw
, (basic_table
+ index
* 2), basic_ptr
);
3646 static const struct brcms_c_rateset
*
3647 brcms_c_rateset_get_hwrs(struct brcms_c_info
*wlc
)
3649 const struct brcms_c_rateset
*rs_dflt
;
3651 if (BRCMS_PHY_11N_CAP(wlc
->band
)) {
3652 if (wlc
->band
->bandtype
== BRCM_BAND_5G
)
3653 rs_dflt
= &ofdm_mimo_rates
;
3655 rs_dflt
= &cck_ofdm_mimo_rates
;
3656 } else if (wlc
->band
->gmode
)
3657 rs_dflt
= &cck_ofdm_rates
;
3659 rs_dflt
= &cck_rates
;
3664 static void brcms_c_set_ratetable(struct brcms_c_info
*wlc
)
3666 const struct brcms_c_rateset
*rs_dflt
;
3667 struct brcms_c_rateset rs
;
3668 u8 rate
, basic_rate
;
3671 rs_dflt
= brcms_c_rateset_get_hwrs(wlc
);
3673 brcms_c_rateset_copy(rs_dflt
, &rs
);
3674 brcms_c_rateset_mcs_upd(&rs
, wlc
->stf
->txstreams
);
3676 /* walk the phy rate table and update SHM basic rate lookup table */
3677 for (i
= 0; i
< rs
.count
; i
++) {
3678 rate
= rs
.rates
[i
] & BRCMS_RATE_MASK
;
3680 /* for a given rate brcms_basic_rate returns the rate at
3681 * which a response ACK/CTS should be sent.
3683 basic_rate
= brcms_basic_rate(wlc
, rate
);
3684 if (basic_rate
== 0)
3685 /* This should only happen if we are using a
3686 * restricted rateset.
3688 basic_rate
= rs
.rates
[0] & BRCMS_RATE_MASK
;
3690 brcms_c_write_rate_shm(wlc
, rate
, basic_rate
);
3694 /* band-specific init */
3695 static void brcms_c_bsinit(struct brcms_c_info
*wlc
)
3697 brcms_dbg_info(wlc
->hw
->d11core
, "wl%d: bandunit %d\n",
3698 wlc
->pub
->unit
, wlc
->band
->bandunit
);
3700 /* write ucode ACK/CTS rate table */
3701 brcms_c_set_ratetable(wlc
);
3703 /* update some band specific mac configuration */
3704 brcms_c_ucode_mac_upd(wlc
);
3706 /* init antenna selection */
3707 brcms_c_antsel_init(wlc
->asi
);
3711 /* formula: IDLE_BUSY_RATIO_X_16 = (100-duty_cycle)/duty_cycle*16 */
3713 brcms_c_duty_cycle_set(struct brcms_c_info
*wlc
, int duty_cycle
, bool isOFDM
,
3716 int idle_busy_ratio_x_16
= 0;
3718 isOFDM
? M_TX_IDLE_BUSY_RATIO_X_16_OFDM
:
3719 M_TX_IDLE_BUSY_RATIO_X_16_CCK
;
3720 if (duty_cycle
> 100 || duty_cycle
< 0) {
3721 brcms_err(wlc
->hw
->d11core
,
3722 "wl%d: duty cycle value off limit\n",
3727 idle_busy_ratio_x_16
= (100 - duty_cycle
) * 16 / duty_cycle
;
3728 /* Only write to shared memory when wl is up */
3730 brcms_b_write_shm(wlc
->hw
, offset
, (u16
) idle_busy_ratio_x_16
);
3733 wlc
->tx_duty_cycle_ofdm
= (u16
) duty_cycle
;
3735 wlc
->tx_duty_cycle_cck
= (u16
) duty_cycle
;
3740 /* push sw hps and wake state through hardware */
3741 static void brcms_c_set_ps_ctrl(struct brcms_c_info
*wlc
)
3747 hps
= brcms_c_ps_allowed(wlc
);
3749 brcms_dbg_mac80211(wlc
->hw
->d11core
, "wl%d: hps %d\n", wlc
->pub
->unit
,
3752 v1
= bcma_read32(wlc
->hw
->d11core
, D11REGOFFS(maccontrol
));
3757 brcms_b_mctrl(wlc
->hw
, MCTL_WAKE
| MCTL_HPS
, v2
);
3759 awake_before
= ((v1
& MCTL_WAKE
) || ((v1
& MCTL_HPS
) == 0));
3762 brcms_b_wait_for_wake(wlc
->hw
);
3766 * Write this BSS config's MAC address to core.
3767 * Updates RXE match engine.
3769 static int brcms_c_set_mac(struct brcms_bss_cfg
*bsscfg
)
3772 struct brcms_c_info
*wlc
= bsscfg
->wlc
;
3774 /* enter the MAC addr into the RXE match registers */
3775 brcms_c_set_addrmatch(wlc
, RCM_MAC_OFFSET
, bsscfg
->cur_etheraddr
);
3777 brcms_c_ampdu_macaddr_upd(wlc
);
3782 /* Write the BSS config's BSSID address to core (set_bssid in d11procs.tcl).
3783 * Updates RXE match engine.
3785 static void brcms_c_set_bssid(struct brcms_bss_cfg
*bsscfg
)
3787 /* we need to update BSSID in RXE match registers */
3788 brcms_c_set_addrmatch(bsscfg
->wlc
, RCM_BSSID_OFFSET
, bsscfg
->BSSID
);
3791 static void brcms_b_set_shortslot(struct brcms_hardware
*wlc_hw
, bool shortslot
)
3793 wlc_hw
->shortslot
= shortslot
;
3795 if (wlc_hw
->band
->bandtype
== BRCM_BAND_2G
&& wlc_hw
->up
) {
3796 brcms_c_suspend_mac_and_wait(wlc_hw
->wlc
);
3797 brcms_b_update_slot_timing(wlc_hw
, shortslot
);
3798 brcms_c_enable_mac(wlc_hw
->wlc
);
3803 * Suspend the the MAC and update the slot timing
3804 * for standard 11b/g (20us slots) or shortslot 11g (9us slots).
3806 static void brcms_c_switch_shortslot(struct brcms_c_info
*wlc
, bool shortslot
)
3808 /* use the override if it is set */
3809 if (wlc
->shortslot_override
!= BRCMS_SHORTSLOT_AUTO
)
3810 shortslot
= (wlc
->shortslot_override
== BRCMS_SHORTSLOT_ON
);
3812 if (wlc
->shortslot
== shortslot
)
3815 wlc
->shortslot
= shortslot
;
3817 brcms_b_set_shortslot(wlc
->hw
, shortslot
);
3820 static void brcms_c_set_home_chanspec(struct brcms_c_info
*wlc
, u16 chanspec
)
3822 if (wlc
->home_chanspec
!= chanspec
) {
3823 wlc
->home_chanspec
= chanspec
;
3825 if (wlc
->bsscfg
->associated
)
3826 wlc
->bsscfg
->current_bss
->chanspec
= chanspec
;
3831 brcms_b_set_chanspec(struct brcms_hardware
*wlc_hw
, u16 chanspec
,
3832 bool mute_tx
, struct txpwr_limits
*txpwr
)
3836 brcms_dbg_mac80211(wlc_hw
->d11core
, "wl%d: 0x%x\n", wlc_hw
->unit
,
3839 wlc_hw
->chanspec
= chanspec
;
3841 /* Switch bands if necessary */
3842 if (wlc_hw
->_nbands
> 1) {
3843 bandunit
= chspec_bandunit(chanspec
);
3844 if (wlc_hw
->band
->bandunit
!= bandunit
) {
3845 /* brcms_b_setband disables other bandunit,
3846 * use light band switch if not up yet
3849 wlc_phy_chanspec_radio_set(wlc_hw
->
3850 bandstate
[bandunit
]->
3852 brcms_b_setband(wlc_hw
, bandunit
, chanspec
);
3854 brcms_c_setxband(wlc_hw
, bandunit
);
3859 wlc_phy_initcal_enable(wlc_hw
->band
->pi
, !mute_tx
);
3863 wlc_phy_txpower_limit_set(wlc_hw
->band
->pi
, txpwr
,
3865 wlc_phy_chanspec_radio_set(wlc_hw
->band
->pi
, chanspec
);
3867 wlc_phy_chanspec_set(wlc_hw
->band
->pi
, chanspec
);
3868 wlc_phy_txpower_limit_set(wlc_hw
->band
->pi
, txpwr
, chanspec
);
3870 /* Update muting of the channel */
3871 brcms_b_mute(wlc_hw
, mute_tx
);
3875 /* switch to and initialize new band */
3876 static void brcms_c_setband(struct brcms_c_info
*wlc
,
3879 wlc
->band
= wlc
->bandstate
[bandunit
];
3884 /* wait for at least one beacon before entering sleeping state */
3885 brcms_c_set_ps_ctrl(wlc
);
3887 /* band-specific initializations */
3888 brcms_c_bsinit(wlc
);
3891 static void brcms_c_set_chanspec(struct brcms_c_info
*wlc
, u16 chanspec
)
3894 bool switchband
= false;
3895 u16 old_chanspec
= wlc
->chanspec
;
3897 if (!brcms_c_valid_chanspec_db(wlc
->cmi
, chanspec
)) {
3898 brcms_err(wlc
->hw
->d11core
, "wl%d: %s: Bad channel %d\n",
3899 wlc
->pub
->unit
, __func__
, CHSPEC_CHANNEL(chanspec
));
3903 /* Switch bands if necessary */
3904 if (wlc
->pub
->_nbands
> 1) {
3905 bandunit
= chspec_bandunit(chanspec
);
3906 if (wlc
->band
->bandunit
!= bandunit
|| wlc
->bandinit_pending
) {
3908 if (wlc
->bandlocked
) {
3909 brcms_err(wlc
->hw
->d11core
,
3910 "wl%d: %s: chspec %d band is locked!\n",
3911 wlc
->pub
->unit
, __func__
,
3912 CHSPEC_CHANNEL(chanspec
));
3916 * should the setband call come after the
3917 * brcms_b_chanspec() ? if the setband updates
3918 * (brcms_c_bsinit) use low level calls to inspect and
3919 * set state, the state inspected may be from the wrong
3920 * band, or the following brcms_b_set_chanspec() may
3923 brcms_c_setband(wlc
, bandunit
);
3927 /* sync up phy/radio chanspec */
3928 brcms_c_set_phy_chanspec(wlc
, chanspec
);
3930 /* init antenna selection */
3931 if (brcms_chspec_bw(old_chanspec
) != brcms_chspec_bw(chanspec
)) {
3932 brcms_c_antsel_init(wlc
->asi
);
3934 /* Fix the hardware rateset based on bw.
3935 * Mainly add MCS32 for 40Mhz, remove MCS 32 for 20Mhz
3937 brcms_c_rateset_bw_mcs_filter(&wlc
->band
->hw_rateset
,
3938 wlc
->band
->mimo_cap_40
? brcms_chspec_bw(chanspec
) : 0);
3941 /* update some mac configuration since chanspec changed */
3942 brcms_c_ucode_mac_upd(wlc
);
3946 * This function changes the phytxctl for beacon based on current
3947 * beacon ratespec AND txant setting as per this table:
3948 * ratespec CCK ant = wlc->stf->txant
3951 void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info
*wlc
,
3955 u16 phytxant
= wlc
->stf
->phytxant
;
3956 u16 mask
= PHY_TXC_ANT_MASK
;
3958 /* for non-siso rates or default setting, use the available chains */
3959 if (BRCMS_PHY_11N_CAP(wlc
->band
))
3960 phytxant
= brcms_c_stf_phytxchain_sel(wlc
, bcn_rspec
);
3962 phyctl
= brcms_b_read_shm(wlc
->hw
, M_BCN_PCTLWD
);
3963 phyctl
= (phyctl
& ~mask
) | phytxant
;
3964 brcms_b_write_shm(wlc
->hw
, M_BCN_PCTLWD
, phyctl
);
3968 * centralized protection config change function to simplify debugging, no
3969 * consistency checking this should be called only on changes to avoid overhead
3970 * in periodic function
3972 void brcms_c_protection_upd(struct brcms_c_info
*wlc
, uint idx
, int val
)
3975 * Cannot use brcms_dbg_* here because this function is called
3976 * before wlc is sufficiently initialized.
3978 BCMMSG(wlc
->wiphy
, "idx %d, val %d\n", idx
, val
);
3981 case BRCMS_PROT_G_SPEC
:
3982 wlc
->protection
->_g
= (bool) val
;
3984 case BRCMS_PROT_G_OVR
:
3985 wlc
->protection
->g_override
= (s8
) val
;
3987 case BRCMS_PROT_G_USER
:
3988 wlc
->protection
->gmode_user
= (u8
) val
;
3990 case BRCMS_PROT_OVERLAP
:
3991 wlc
->protection
->overlap
= (s8
) val
;
3993 case BRCMS_PROT_N_USER
:
3994 wlc
->protection
->nmode_user
= (s8
) val
;
3996 case BRCMS_PROT_N_CFG
:
3997 wlc
->protection
->n_cfg
= (s8
) val
;
3999 case BRCMS_PROT_N_CFG_OVR
:
4000 wlc
->protection
->n_cfg_override
= (s8
) val
;
4002 case BRCMS_PROT_N_NONGF
:
4003 wlc
->protection
->nongf
= (bool) val
;
4005 case BRCMS_PROT_N_NONGF_OVR
:
4006 wlc
->protection
->nongf_override
= (s8
) val
;
4008 case BRCMS_PROT_N_PAM_OVR
:
4009 wlc
->protection
->n_pam_override
= (s8
) val
;
4011 case BRCMS_PROT_N_OBSS
:
4012 wlc
->protection
->n_obss
= (bool) val
;
4021 static void brcms_c_ht_update_sgi_rx(struct brcms_c_info
*wlc
, int val
)
4024 brcms_c_update_beacon(wlc
);
4025 brcms_c_update_probe_resp(wlc
, true);
4029 static void brcms_c_ht_update_ldpc(struct brcms_c_info
*wlc
, s8 val
)
4031 wlc
->stf
->ldpc
= val
;
4034 brcms_c_update_beacon(wlc
);
4035 brcms_c_update_probe_resp(wlc
, true);
4036 wlc_phy_ldpc_override_set(wlc
->band
->pi
, (val
? true : false));
4040 void brcms_c_wme_setparams(struct brcms_c_info
*wlc
, u16 aci
,
4041 const struct ieee80211_tx_queue_params
*params
,
4045 struct shm_acparams acp_shm
;
4048 /* Only apply params if the core is out of reset and has clocks */
4050 brcms_err(wlc
->hw
->d11core
, "wl%d: %s : no-clock\n",
4051 wlc
->pub
->unit
, __func__
);
4055 memset((char *)&acp_shm
, 0, sizeof(struct shm_acparams
));
4056 /* fill in shm ac params struct */
4057 acp_shm
.txop
= params
->txop
;
4058 /* convert from units of 32us to us for ucode */
4059 wlc
->edcf_txop
[aci
& 0x3] = acp_shm
.txop
=
4060 EDCF_TXOP2USEC(acp_shm
.txop
);
4061 acp_shm
.aifs
= (params
->aifs
& EDCF_AIFSN_MASK
);
4063 if (aci
== IEEE80211_AC_VI
&& acp_shm
.txop
== 0
4064 && acp_shm
.aifs
< EDCF_AIFSN_MAX
)
4067 if (acp_shm
.aifs
< EDCF_AIFSN_MIN
4068 || acp_shm
.aifs
> EDCF_AIFSN_MAX
) {
4069 brcms_err(wlc
->hw
->d11core
, "wl%d: edcf_setparams: bad "
4070 "aifs %d\n", wlc
->pub
->unit
, acp_shm
.aifs
);
4072 acp_shm
.cwmin
= params
->cw_min
;
4073 acp_shm
.cwmax
= params
->cw_max
;
4074 acp_shm
.cwcur
= acp_shm
.cwmin
;
4076 bcma_read16(wlc
->hw
->d11core
, D11REGOFFS(tsf_random
)) &
4078 acp_shm
.reggap
= acp_shm
.bslots
+ acp_shm
.aifs
;
4079 /* Indicate the new params to the ucode */
4080 acp_shm
.status
= brcms_b_read_shm(wlc
->hw
, (M_EDCF_QINFO
+
4083 M_EDCF_STATUS_OFF
));
4084 acp_shm
.status
|= WME_STATUS_NEWAC
;
4086 /* Fill in shm acparam table */
4087 shm_entry
= (u16
*) &acp_shm
;
4088 for (i
= 0; i
< (int)sizeof(struct shm_acparams
); i
+= 2)
4089 brcms_b_write_shm(wlc
->hw
,
4091 wme_ac2fifo
[aci
] * M_EDCF_QLEN
+ i
,
4096 brcms_c_suspend_mac_and_wait(wlc
);
4097 brcms_c_enable_mac(wlc
);
4101 static void brcms_c_edcf_setparams(struct brcms_c_info
*wlc
, bool suspend
)
4105 struct ieee80211_tx_queue_params txq_pars
;
4106 static const struct edcf_acparam default_edcf_acparams
[] = {
4107 {EDCF_AC_BE_ACI_STA
, EDCF_AC_BE_ECW_STA
, EDCF_AC_BE_TXOP_STA
},
4108 {EDCF_AC_BK_ACI_STA
, EDCF_AC_BK_ECW_STA
, EDCF_AC_BK_TXOP_STA
},
4109 {EDCF_AC_VI_ACI_STA
, EDCF_AC_VI_ECW_STA
, EDCF_AC_VI_TXOP_STA
},
4110 {EDCF_AC_VO_ACI_STA
, EDCF_AC_VO_ECW_STA
, EDCF_AC_VO_TXOP_STA
}
4111 }; /* ucode needs these parameters during its initialization */
4112 const struct edcf_acparam
*edcf_acp
= &default_edcf_acparams
[0];
4114 for (i_ac
= 0; i_ac
< IEEE80211_NUM_ACS
; i_ac
++, edcf_acp
++) {
4115 /* find out which ac this set of params applies to */
4116 aci
= (edcf_acp
->ACI
& EDCF_ACI_MASK
) >> EDCF_ACI_SHIFT
;
4118 /* fill in shm ac params struct */
4119 txq_pars
.txop
= edcf_acp
->TXOP
;
4120 txq_pars
.aifs
= edcf_acp
->ACI
;
4122 /* CWmin = 2^(ECWmin) - 1 */
4123 txq_pars
.cw_min
= EDCF_ECW2CW(edcf_acp
->ECW
& EDCF_ECWMIN_MASK
);
4124 /* CWmax = 2^(ECWmax) - 1 */
4125 txq_pars
.cw_max
= EDCF_ECW2CW((edcf_acp
->ECW
& EDCF_ECWMAX_MASK
)
4126 >> EDCF_ECWMAX_SHIFT
);
4127 brcms_c_wme_setparams(wlc
, aci
, &txq_pars
, suspend
);
4131 brcms_c_suspend_mac_and_wait(wlc
);
4132 brcms_c_enable_mac(wlc
);
4136 static void brcms_c_radio_monitor_start(struct brcms_c_info
*wlc
)
4138 /* Don't start the timer if HWRADIO feature is disabled */
4139 if (wlc
->radio_monitor
)
4142 wlc
->radio_monitor
= true;
4143 brcms_b_pllreq(wlc
->hw
, true, BRCMS_PLLREQ_RADIO_MON
);
4144 brcms_add_timer(wlc
->radio_timer
, TIMER_INTERVAL_RADIOCHK
, true);
4147 static bool brcms_c_radio_monitor_stop(struct brcms_c_info
*wlc
)
4149 if (!wlc
->radio_monitor
)
4152 wlc
->radio_monitor
= false;
4153 brcms_b_pllreq(wlc
->hw
, false, BRCMS_PLLREQ_RADIO_MON
);
4154 return brcms_del_timer(wlc
->radio_timer
);
4157 /* read hwdisable state and propagate to wlc flag */
4158 static void brcms_c_radio_hwdisable_upd(struct brcms_c_info
*wlc
)
4160 if (wlc
->pub
->hw_off
)
4163 if (brcms_b_radio_read_hwdisabled(wlc
->hw
))
4164 mboolset(wlc
->pub
->radio_disabled
, WL_RADIO_HW_DISABLE
);
4166 mboolclr(wlc
->pub
->radio_disabled
, WL_RADIO_HW_DISABLE
);
4169 /* update hwradio status and return it */
4170 bool brcms_c_check_radio_disabled(struct brcms_c_info
*wlc
)
4172 brcms_c_radio_hwdisable_upd(wlc
);
4174 return mboolisset(wlc
->pub
->radio_disabled
, WL_RADIO_HW_DISABLE
) ?
4178 /* periodical query hw radio button while driver is "down" */
4179 static void brcms_c_radio_timer(void *arg
)
4181 struct brcms_c_info
*wlc
= (struct brcms_c_info
*) arg
;
4183 if (brcms_deviceremoved(wlc
)) {
4184 brcms_err(wlc
->hw
->d11core
, "wl%d: %s: dead chip\n",
4185 wlc
->pub
->unit
, __func__
);
4186 brcms_down(wlc
->wl
);
4190 brcms_c_radio_hwdisable_upd(wlc
);
4193 /* common low-level watchdog code */
4194 static void brcms_b_watchdog(struct brcms_c_info
*wlc
)
4196 struct brcms_hardware
*wlc_hw
= wlc
->hw
;
4201 /* increment second count */
4204 /* Check for FIFO error interrupts */
4205 brcms_b_fifoerrors(wlc_hw
);
4207 /* make sure RX dma has buffers */
4208 dma_rxfill(wlc
->hw
->di
[RX_FIFO
]);
4210 wlc_phy_watchdog(wlc_hw
->band
->pi
);
4213 /* common watchdog code */
4214 static void brcms_c_watchdog(struct brcms_c_info
*wlc
)
4216 brcms_dbg_info(wlc
->hw
->d11core
, "wl%d\n", wlc
->pub
->unit
);
4221 if (brcms_deviceremoved(wlc
)) {
4222 brcms_err(wlc
->hw
->d11core
, "wl%d: %s: dead chip\n",
4223 wlc
->pub
->unit
, __func__
);
4224 brcms_down(wlc
->wl
);
4228 /* increment second count */
4231 brcms_c_radio_hwdisable_upd(wlc
);
4232 /* if radio is disable, driver may be down, quit here */
4233 if (wlc
->pub
->radio_disabled
)
4236 brcms_b_watchdog(wlc
);
4239 * occasionally sample mac stat counters to
4240 * detect 16-bit counter wrap
4242 if ((wlc
->pub
->now
% SW_TIMER_MAC_STAT_UPD
) == 0)
4243 brcms_c_statsupd(wlc
);
4245 if (BRCMS_ISNPHY(wlc
->band
) &&
4246 ((wlc
->pub
->now
- wlc
->tempsense_lasttime
) >=
4247 BRCMS_TEMPSENSE_PERIOD
)) {
4248 wlc
->tempsense_lasttime
= wlc
->pub
->now
;
4249 brcms_c_tempsense_upd(wlc
);
4253 static void brcms_c_watchdog_by_timer(void *arg
)
4255 struct brcms_c_info
*wlc
= (struct brcms_c_info
*) arg
;
4257 brcms_c_watchdog(wlc
);
4260 static bool brcms_c_timers_init(struct brcms_c_info
*wlc
, int unit
)
4262 wlc
->wdtimer
= brcms_init_timer(wlc
->wl
, brcms_c_watchdog_by_timer
,
4264 if (!wlc
->wdtimer
) {
4265 wiphy_err(wlc
->wiphy
, "wl%d: wl_init_timer for wdtimer "
4270 wlc
->radio_timer
= brcms_init_timer(wlc
->wl
, brcms_c_radio_timer
,
4272 if (!wlc
->radio_timer
) {
4273 wiphy_err(wlc
->wiphy
, "wl%d: wl_init_timer for radio_timer "
4285 * Initialize brcms_c_info default values ...
4286 * may get overrides later in this function
4288 static void brcms_c_info_init(struct brcms_c_info
*wlc
, int unit
)
4292 /* Save our copy of the chanspec */
4293 wlc
->chanspec
= ch20mhz_chspec(1);
4295 /* various 802.11g modes */
4296 wlc
->shortslot
= false;
4297 wlc
->shortslot_override
= BRCMS_SHORTSLOT_AUTO
;
4299 brcms_c_protection_upd(wlc
, BRCMS_PROT_G_OVR
, BRCMS_PROTECTION_AUTO
);
4300 brcms_c_protection_upd(wlc
, BRCMS_PROT_G_SPEC
, false);
4302 brcms_c_protection_upd(wlc
, BRCMS_PROT_N_CFG_OVR
,
4303 BRCMS_PROTECTION_AUTO
);
4304 brcms_c_protection_upd(wlc
, BRCMS_PROT_N_CFG
, BRCMS_N_PROTECTION_OFF
);
4305 brcms_c_protection_upd(wlc
, BRCMS_PROT_N_NONGF_OVR
,
4306 BRCMS_PROTECTION_AUTO
);
4307 brcms_c_protection_upd(wlc
, BRCMS_PROT_N_NONGF
, false);
4308 brcms_c_protection_upd(wlc
, BRCMS_PROT_N_PAM_OVR
, AUTO
);
4310 brcms_c_protection_upd(wlc
, BRCMS_PROT_OVERLAP
,
4311 BRCMS_PROTECTION_CTL_OVERLAP
);
4313 /* 802.11g draft 4.0 NonERP elt advertisement */
4314 wlc
->include_legacy_erp
= true;
4316 wlc
->stf
->ant_rx_ovr
= ANT_RX_DIV_DEF
;
4317 wlc
->stf
->txant
= ANT_TX_DEF
;
4319 wlc
->prb_resp_timeout
= BRCMS_PRB_RESP_TIMEOUT
;
4321 wlc
->usr_fragthresh
= DOT11_DEFAULT_FRAG_LEN
;
4322 for (i
= 0; i
< NFIFO
; i
++)
4323 wlc
->fragthresh
[i
] = DOT11_DEFAULT_FRAG_LEN
;
4324 wlc
->RTSThresh
= DOT11_DEFAULT_RTS_LEN
;
4326 /* default rate fallback retry limits */
4327 wlc
->SFBL
= RETRY_SHORT_FB
;
4328 wlc
->LFBL
= RETRY_LONG_FB
;
4330 /* default mac retry limits */
4331 wlc
->SRL
= RETRY_SHORT_DEF
;
4332 wlc
->LRL
= RETRY_LONG_DEF
;
4334 /* WME QoS mode is Auto by default */
4335 wlc
->pub
->_ampdu
= AMPDU_AGG_HOST
;
4336 wlc
->pub
->bcmerror
= 0;
4339 static uint
brcms_c_attach_module(struct brcms_c_info
*wlc
)
4343 unit
= wlc
->pub
->unit
;
4345 wlc
->asi
= brcms_c_antsel_attach(wlc
);
4346 if (wlc
->asi
== NULL
) {
4347 wiphy_err(wlc
->wiphy
, "wl%d: attach: antsel_attach "
4353 wlc
->ampdu
= brcms_c_ampdu_attach(wlc
);
4354 if (wlc
->ampdu
== NULL
) {
4355 wiphy_err(wlc
->wiphy
, "wl%d: attach: ampdu_attach "
4361 if ((brcms_c_stf_attach(wlc
) != 0)) {
4362 wiphy_err(wlc
->wiphy
, "wl%d: attach: stf_attach "
4371 struct brcms_pub
*brcms_c_pub(struct brcms_c_info
*wlc
)
4377 * run backplane attach, init nvram
4379 * initialize software state for each core and band
4380 * put the whole chip in reset(driver down state), no clock
4382 static int brcms_b_attach(struct brcms_c_info
*wlc
, struct bcma_device
*core
,
4383 uint unit
, bool piomode
)
4385 struct brcms_hardware
*wlc_hw
;
4389 struct shared_phy_params sha_params
;
4390 struct wiphy
*wiphy
= wlc
->wiphy
;
4391 struct pci_dev
*pcidev
= core
->bus
->host_pci
;
4392 struct ssb_sprom
*sprom
= &core
->bus
->sprom
;
4394 if (core
->bus
->hosttype
== BCMA_HOSTTYPE_PCI
)
4395 brcms_dbg_info(core
, "wl%d: vendor 0x%x device 0x%x\n", unit
,
4399 brcms_dbg_info(core
, "wl%d: vendor 0x%x device 0x%x\n", unit
,
4400 core
->bus
->boardinfo
.vendor
,
4401 core
->bus
->boardinfo
.type
);
4407 wlc_hw
->unit
= unit
;
4408 wlc_hw
->band
= wlc_hw
->bandstate
[0];
4409 wlc_hw
->_piomode
= piomode
;
4411 /* populate struct brcms_hardware with default values */
4412 brcms_b_info_init(wlc_hw
);
4415 * Do the hardware portion of the attach. Also initialize software
4416 * state that depends on the particular hardware we are running.
4418 wlc_hw
->sih
= ai_attach(core
->bus
);
4419 if (wlc_hw
->sih
== NULL
) {
4420 wiphy_err(wiphy
, "wl%d: brcms_b_attach: si_attach failed\n",
4426 /* verify again the device is supported */
4427 if (!brcms_c_chipmatch(core
)) {
4428 wiphy_err(wiphy
, "wl%d: brcms_b_attach: Unsupported device\n",
4434 if (core
->bus
->hosttype
== BCMA_HOSTTYPE_PCI
) {
4435 wlc_hw
->vendorid
= pcidev
->vendor
;
4436 wlc_hw
->deviceid
= pcidev
->device
;
4438 wlc_hw
->vendorid
= core
->bus
->boardinfo
.vendor
;
4439 wlc_hw
->deviceid
= core
->bus
->boardinfo
.type
;
4442 wlc_hw
->d11core
= core
;
4443 wlc_hw
->corerev
= core
->id
.rev
;
4445 /* validate chip, chiprev and corerev */
4446 if (!brcms_c_isgoodchip(wlc_hw
)) {
4451 /* initialize power control registers */
4452 ai_clkctl_init(wlc_hw
->sih
);
4454 /* request fastclock and force fastclock for the rest of attach
4455 * bring the d11 core out of reset.
4456 * For PMU chips, the first wlc_clkctl_clk is no-op since core-clk
4457 * is still false; But it will be called again inside wlc_corereset,
4458 * after d11 is out of reset.
4460 brcms_b_clkctl_clk(wlc_hw
, BCMA_CLKMODE_FAST
);
4461 brcms_b_corereset(wlc_hw
, BRCMS_USE_COREFLAGS
);
4463 if (!brcms_b_validate_chip_access(wlc_hw
)) {
4464 wiphy_err(wiphy
, "wl%d: brcms_b_attach: validate_chip_access "
4470 /* get the board rev, used just below */
4471 j
= sprom
->board_rev
;
4472 /* promote srom boardrev of 0xFF to 1 */
4473 if (j
== BOARDREV_PROMOTABLE
)
4474 j
= BOARDREV_PROMOTED
;
4475 wlc_hw
->boardrev
= (u16
) j
;
4476 if (!brcms_c_validboardtype(wlc_hw
)) {
4477 wiphy_err(wiphy
, "wl%d: brcms_b_attach: Unsupported Broadcom "
4478 "board type (0x%x)" " or revision level (0x%x)\n",
4479 unit
, ai_get_boardtype(wlc_hw
->sih
),
4484 wlc_hw
->sromrev
= sprom
->revision
;
4485 wlc_hw
->boardflags
= sprom
->boardflags_lo
+ (sprom
->boardflags_hi
<< 16);
4486 wlc_hw
->boardflags2
= sprom
->boardflags2_lo
+ (sprom
->boardflags2_hi
<< 16);
4488 if (wlc_hw
->boardflags
& BFL_NOPLLDOWN
)
4489 brcms_b_pllreq(wlc_hw
, true, BRCMS_PLLREQ_SHARED
);
4491 /* check device id(srom, nvram etc.) to set bands */
4492 if (wlc_hw
->deviceid
== BCM43224_D11N_ID
||
4493 wlc_hw
->deviceid
== BCM43224_D11N_ID_VEN1
||
4494 wlc_hw
->deviceid
== BCM43224_CHIP_ID
)
4495 /* Dualband boards */
4496 wlc_hw
->_nbands
= 2;
4498 wlc_hw
->_nbands
= 1;
4500 if ((ai_get_chip_id(wlc_hw
->sih
) == BCMA_CHIP_ID_BCM43225
))
4501 wlc_hw
->_nbands
= 1;
4503 /* BMAC_NOTE: remove init of pub values when brcms_c_attach()
4504 * unconditionally does the init of these values
4506 wlc
->vendorid
= wlc_hw
->vendorid
;
4507 wlc
->deviceid
= wlc_hw
->deviceid
;
4508 wlc
->pub
->sih
= wlc_hw
->sih
;
4509 wlc
->pub
->corerev
= wlc_hw
->corerev
;
4510 wlc
->pub
->sromrev
= wlc_hw
->sromrev
;
4511 wlc
->pub
->boardrev
= wlc_hw
->boardrev
;
4512 wlc
->pub
->boardflags
= wlc_hw
->boardflags
;
4513 wlc
->pub
->boardflags2
= wlc_hw
->boardflags2
;
4514 wlc
->pub
->_nbands
= wlc_hw
->_nbands
;
4516 wlc_hw
->physhim
= wlc_phy_shim_attach(wlc_hw
, wlc
->wl
, wlc
);
4518 if (wlc_hw
->physhim
== NULL
) {
4519 wiphy_err(wiphy
, "wl%d: brcms_b_attach: wlc_phy_shim_attach "
4525 /* pass all the parameters to wlc_phy_shared_attach in one struct */
4526 sha_params
.sih
= wlc_hw
->sih
;
4527 sha_params
.physhim
= wlc_hw
->physhim
;
4528 sha_params
.unit
= unit
;
4529 sha_params
.corerev
= wlc_hw
->corerev
;
4530 sha_params
.vid
= wlc_hw
->vendorid
;
4531 sha_params
.did
= wlc_hw
->deviceid
;
4532 sha_params
.chip
= ai_get_chip_id(wlc_hw
->sih
);
4533 sha_params
.chiprev
= ai_get_chiprev(wlc_hw
->sih
);
4534 sha_params
.chippkg
= ai_get_chippkg(wlc_hw
->sih
);
4535 sha_params
.sromrev
= wlc_hw
->sromrev
;
4536 sha_params
.boardtype
= ai_get_boardtype(wlc_hw
->sih
);
4537 sha_params
.boardrev
= wlc_hw
->boardrev
;
4538 sha_params
.boardflags
= wlc_hw
->boardflags
;
4539 sha_params
.boardflags2
= wlc_hw
->boardflags2
;
4541 /* alloc and save pointer to shared phy state area */
4542 wlc_hw
->phy_sh
= wlc_phy_shared_attach(&sha_params
);
4543 if (!wlc_hw
->phy_sh
) {
4548 /* initialize software state for each core and band */
4549 for (j
= 0; j
< wlc_hw
->_nbands
; j
++) {
4551 * band0 is always 2.4Ghz
4552 * band1, if present, is 5Ghz
4555 brcms_c_setxband(wlc_hw
, j
);
4557 wlc_hw
->band
->bandunit
= j
;
4558 wlc_hw
->band
->bandtype
= j
? BRCM_BAND_5G
: BRCM_BAND_2G
;
4559 wlc
->band
->bandunit
= j
;
4560 wlc
->band
->bandtype
= j
? BRCM_BAND_5G
: BRCM_BAND_2G
;
4561 wlc
->core
->coreidx
= core
->core_index
;
4563 wlc_hw
->machwcap
= bcma_read32(core
, D11REGOFFS(machwcap
));
4564 wlc_hw
->machwcap_backup
= wlc_hw
->machwcap
;
4566 /* init tx fifo size */
4567 WARN_ON((wlc_hw
->corerev
- XMTFIFOTBL_STARTREV
) < 0 ||
4568 (wlc_hw
->corerev
- XMTFIFOTBL_STARTREV
) >
4569 ARRAY_SIZE(xmtfifo_sz
));
4570 wlc_hw
->xmtfifo_sz
=
4571 xmtfifo_sz
[(wlc_hw
->corerev
- XMTFIFOTBL_STARTREV
)];
4572 WARN_ON(!wlc_hw
->xmtfifo_sz
[0]);
4574 /* Get a phy for this band */
4576 wlc_phy_attach(wlc_hw
->phy_sh
, core
,
4577 wlc_hw
->band
->bandtype
,
4579 if (wlc_hw
->band
->pi
== NULL
) {
4580 wiphy_err(wiphy
, "wl%d: brcms_b_attach: wlc_phy_"
4581 "attach failed\n", unit
);
4586 wlc_phy_machwcap_set(wlc_hw
->band
->pi
, wlc_hw
->machwcap
);
4588 wlc_phy_get_phyversion(wlc_hw
->band
->pi
, &wlc_hw
->band
->phytype
,
4589 &wlc_hw
->band
->phyrev
,
4590 &wlc_hw
->band
->radioid
,
4591 &wlc_hw
->band
->radiorev
);
4592 wlc_hw
->band
->abgphy_encore
=
4593 wlc_phy_get_encore(wlc_hw
->band
->pi
);
4594 wlc
->band
->abgphy_encore
= wlc_phy_get_encore(wlc_hw
->band
->pi
);
4595 wlc_hw
->band
->core_flags
=
4596 wlc_phy_get_coreflags(wlc_hw
->band
->pi
);
4598 /* verify good phy_type & supported phy revision */
4599 if (BRCMS_ISNPHY(wlc_hw
->band
)) {
4600 if (NCONF_HAS(wlc_hw
->band
->phyrev
))
4604 } else if (BRCMS_ISLCNPHY(wlc_hw
->band
)) {
4605 if (LCNCONF_HAS(wlc_hw
->band
->phyrev
))
4611 wiphy_err(wiphy
, "wl%d: brcms_b_attach: unsupported "
4612 "phy type/rev (%d/%d)\n", unit
,
4613 wlc_hw
->band
->phytype
, wlc_hw
->band
->phyrev
);
4620 * BMAC_NOTE: wlc->band->pi should not be set below and should
4621 * be done in the high level attach. However we can not make
4622 * that change until all low level access is changed to
4623 * wlc_hw->band->pi. Instead do the wlc->band->pi init below,
4624 * keeping wlc_hw->band->pi as well for incremental update of
4625 * low level fns, and cut over low only init when all fns
4628 wlc
->band
->pi
= wlc_hw
->band
->pi
;
4629 wlc
->band
->phytype
= wlc_hw
->band
->phytype
;
4630 wlc
->band
->phyrev
= wlc_hw
->band
->phyrev
;
4631 wlc
->band
->radioid
= wlc_hw
->band
->radioid
;
4632 wlc
->band
->radiorev
= wlc_hw
->band
->radiorev
;
4634 /* default contention windows size limits */
4635 wlc_hw
->band
->CWmin
= APHY_CWMIN
;
4636 wlc_hw
->band
->CWmax
= PHY_CWMAX
;
4638 if (!brcms_b_attach_dmapio(wlc
, j
, wme
)) {
4644 /* disable core to match driver "down" state */
4645 brcms_c_coredisable(wlc_hw
);
4647 /* Match driver "down" state */
4648 ai_pci_down(wlc_hw
->sih
);
4650 /* turn off pll and xtal to match driver "down" state */
4651 brcms_b_xtal(wlc_hw
, OFF
);
4653 /* *******************************************************************
4654 * The hardware is in the DOWN state at this point. D11 core
4655 * or cores are in reset with clocks off, and the board PLLs
4656 * are off if possible.
4658 * Beyond this point, wlc->sbclk == false and chip registers
4659 * should not be touched.
4660 *********************************************************************
4663 /* init etheraddr state variables */
4664 brcms_c_get_macaddr(wlc_hw
, wlc_hw
->etheraddr
);
4666 if (is_broadcast_ether_addr(wlc_hw
->etheraddr
) ||
4667 is_zero_ether_addr(wlc_hw
->etheraddr
)) {
4668 wiphy_err(wiphy
, "wl%d: brcms_b_attach: bad macaddr\n",
4674 brcms_dbg_info(wlc_hw
->d11core
, "deviceid 0x%x nbands %d board 0x%x\n",
4675 wlc_hw
->deviceid
, wlc_hw
->_nbands
,
4676 ai_get_boardtype(wlc_hw
->sih
));
4681 wiphy_err(wiphy
, "wl%d: brcms_b_attach: failed with err %d\n", unit
,
4686 static void brcms_c_attach_antgain_init(struct brcms_c_info
*wlc
)
4689 unit
= wlc
->pub
->unit
;
4691 if ((wlc
->band
->antgain
== -1) && (wlc
->pub
->sromrev
== 1)) {
4692 /* default antenna gain for srom rev 1 is 2 dBm (8 qdbm) */
4693 wlc
->band
->antgain
= 8;
4694 } else if (wlc
->band
->antgain
== -1) {
4695 wiphy_err(wlc
->wiphy
, "wl%d: %s: Invalid antennas available in"
4696 " srom, using 2dB\n", unit
, __func__
);
4697 wlc
->band
->antgain
= 8;
4700 /* Older sroms specified gain in whole dbm only. In order
4701 * be able to specify qdbm granularity and remain backward
4702 * compatible the whole dbms are now encoded in only
4703 * low 6 bits and remaining qdbms are encoded in the hi 2 bits.
4704 * 6 bit signed number ranges from -32 - 31.
4708 * 0xc1 = 1.75 db (1 + 3 quarters),
4709 * 0x3f = -1 (-1 + 0 quarters),
4710 * 0x7f = -.75 (-1 + 1 quarters) = -3 qdbm.
4711 * 0xbf = -.50 (-1 + 2 quarters) = -2 qdbm.
4713 gain
= wlc
->band
->antgain
& 0x3f;
4714 gain
<<= 2; /* Sign extend */
4716 fract
= (wlc
->band
->antgain
& 0xc0) >> 6;
4717 wlc
->band
->antgain
= 4 * gain
+ fract
;
4721 static bool brcms_c_attach_stf_ant_init(struct brcms_c_info
*wlc
)
4726 struct ssb_sprom
*sprom
= &wlc
->hw
->d11core
->bus
->sprom
;
4728 unit
= wlc
->pub
->unit
;
4729 bandtype
= wlc
->band
->bandtype
;
4731 /* get antennas available */
4732 if (bandtype
== BRCM_BAND_5G
)
4733 aa
= sprom
->ant_available_a
;
4735 aa
= sprom
->ant_available_bg
;
4737 if ((aa
< 1) || (aa
> 15)) {
4738 wiphy_err(wlc
->wiphy
, "wl%d: %s: Invalid antennas available in"
4739 " srom (0x%x), using 3\n", unit
, __func__
, aa
);
4743 /* reset the defaults if we have a single antenna */
4745 wlc
->stf
->ant_rx_ovr
= ANT_RX_DIV_FORCE_0
;
4746 wlc
->stf
->txant
= ANT_TX_FORCE_0
;
4747 } else if (aa
== 2) {
4748 wlc
->stf
->ant_rx_ovr
= ANT_RX_DIV_FORCE_1
;
4749 wlc
->stf
->txant
= ANT_TX_FORCE_1
;
4753 /* Compute Antenna Gain */
4754 if (bandtype
== BRCM_BAND_5G
)
4755 wlc
->band
->antgain
= sprom
->antenna_gain
.a1
;
4757 wlc
->band
->antgain
= sprom
->antenna_gain
.a0
;
4759 brcms_c_attach_antgain_init(wlc
);
4764 static void brcms_c_bss_default_init(struct brcms_c_info
*wlc
)
4767 struct brcms_band
*band
;
4768 struct brcms_bss_info
*bi
= wlc
->default_bss
;
4770 /* init default and target BSS with some sane initial values */
4771 memset((char *)(bi
), 0, sizeof(struct brcms_bss_info
));
4772 bi
->beacon_period
= BEACON_INTERVAL_DEFAULT
;
4774 /* fill the default channel as the first valid channel
4775 * starting from the 2G channels
4777 chanspec
= ch20mhz_chspec(1);
4778 wlc
->home_chanspec
= bi
->chanspec
= chanspec
;
4780 /* find the band of our default channel */
4782 if (wlc
->pub
->_nbands
> 1 &&
4783 band
->bandunit
!= chspec_bandunit(chanspec
))
4784 band
= wlc
->bandstate
[OTHERBANDUNIT(wlc
)];
4786 /* init bss rates to the band specific default rate set */
4787 brcms_c_rateset_default(&bi
->rateset
, NULL
, band
->phytype
,
4788 band
->bandtype
, false, BRCMS_RATE_MASK_FULL
,
4789 (bool) (wlc
->pub
->_n_enab
& SUPPORT_11N
),
4790 brcms_chspec_bw(chanspec
), wlc
->stf
->txstreams
);
4792 if (wlc
->pub
->_n_enab
& SUPPORT_11N
)
4793 bi
->flags
|= BRCMS_BSS_HT
;
4796 static void brcms_c_update_mimo_band_bwcap(struct brcms_c_info
*wlc
, u8 bwcap
)
4799 struct brcms_band
*band
;
4801 for (i
= 0; i
< wlc
->pub
->_nbands
; i
++) {
4802 band
= wlc
->bandstate
[i
];
4803 if (band
->bandtype
== BRCM_BAND_5G
) {
4804 if ((bwcap
== BRCMS_N_BW_40ALL
)
4805 || (bwcap
== BRCMS_N_BW_20IN2G_40IN5G
))
4806 band
->mimo_cap_40
= true;
4808 band
->mimo_cap_40
= false;
4810 if (bwcap
== BRCMS_N_BW_40ALL
)
4811 band
->mimo_cap_40
= true;
4813 band
->mimo_cap_40
= false;
4818 static void brcms_c_timers_deinit(struct brcms_c_info
*wlc
)
4820 /* free timer state */
4822 brcms_free_timer(wlc
->wdtimer
);
4823 wlc
->wdtimer
= NULL
;
4825 if (wlc
->radio_timer
) {
4826 brcms_free_timer(wlc
->radio_timer
);
4827 wlc
->radio_timer
= NULL
;
4831 static void brcms_c_detach_module(struct brcms_c_info
*wlc
)
4834 brcms_c_antsel_detach(wlc
->asi
);
4839 brcms_c_ampdu_detach(wlc
->ampdu
);
4843 brcms_c_stf_detach(wlc
);
4849 static int brcms_b_detach(struct brcms_c_info
*wlc
)
4852 struct brcms_hw_band
*band
;
4853 struct brcms_hardware
*wlc_hw
= wlc
->hw
;
4858 brcms_b_detach_dmapio(wlc_hw
);
4860 band
= wlc_hw
->band
;
4861 for (i
= 0; i
< wlc_hw
->_nbands
; i
++) {
4863 /* Detach this band's phy */
4864 wlc_phy_detach(band
->pi
);
4867 band
= wlc_hw
->bandstate
[OTHERBANDUNIT(wlc
)];
4870 /* Free shared phy state */
4871 kfree(wlc_hw
->phy_sh
);
4873 wlc_phy_shim_detach(wlc_hw
->physhim
);
4876 ai_detach(wlc_hw
->sih
);
4885 * Return a count of the number of driver callbacks still pending.
4887 * General policy is that brcms_c_detach can only dealloc/free software states.
4888 * It can NOT touch hardware registers since the d11core may be in reset and
4889 * clock may not be available.
4890 * One exception is sb register access, which is possible if crystal is turned
4891 * on after "down" state, driver should avoid software timer with the exception
4894 uint
brcms_c_detach(struct brcms_c_info
*wlc
)
4901 callbacks
+= brcms_b_detach(wlc
);
4903 /* delete software timers */
4904 if (!brcms_c_radio_monitor_stop(wlc
))
4907 brcms_c_channel_mgr_detach(wlc
->cmi
);
4909 brcms_c_timers_deinit(wlc
);
4911 brcms_c_detach_module(wlc
);
4913 brcms_c_detach_mfree(wlc
);
4917 /* update state that depends on the current value of "ap" */
4918 static void brcms_c_ap_upd(struct brcms_c_info
*wlc
)
4920 /* STA-BSS; short capable */
4921 wlc
->PLCPHdr_override
= BRCMS_PLCP_SHORT
;
4924 /* Initialize just the hardware when coming out of POR or S3/S5 system states */
4925 static void brcms_b_hw_up(struct brcms_hardware
*wlc_hw
)
4927 if (wlc_hw
->wlc
->pub
->hw_up
)
4930 brcms_dbg_info(wlc_hw
->d11core
, "wl%d\n", wlc_hw
->unit
);
4933 * Enable pll and xtal, initialize the power control registers,
4934 * and force fastclock for the remainder of brcms_c_up().
4936 brcms_b_xtal(wlc_hw
, ON
);
4937 ai_clkctl_init(wlc_hw
->sih
);
4938 brcms_b_clkctl_clk(wlc_hw
, BCMA_CLKMODE_FAST
);
4941 * TODO: test suspend/resume
4943 * AI chip doesn't restore bar0win2 on
4944 * hibernation/resume, need sw fixup
4948 * Inform phy that a POR reset has occurred so
4949 * it does a complete phy init
4951 wlc_phy_por_inform(wlc_hw
->band
->pi
);
4953 wlc_hw
->ucode_loaded
= false;
4954 wlc_hw
->wlc
->pub
->hw_up
= true;
4956 if ((wlc_hw
->boardflags
& BFL_FEM
)
4957 && (ai_get_chip_id(wlc_hw
->sih
) == BCMA_CHIP_ID_BCM4313
)) {
4959 (wlc_hw
->boardrev
>= 0x1250
4960 && (wlc_hw
->boardflags
& BFL_FEM_BT
)))
4961 ai_epa_4313war(wlc_hw
->sih
);
4965 static int brcms_b_up_prep(struct brcms_hardware
*wlc_hw
)
4967 brcms_dbg_info(wlc_hw
->d11core
, "wl%d\n", wlc_hw
->unit
);
4970 * Enable pll and xtal, initialize the power control registers,
4971 * and force fastclock for the remainder of brcms_c_up().
4973 brcms_b_xtal(wlc_hw
, ON
);
4974 ai_clkctl_init(wlc_hw
->sih
);
4975 brcms_b_clkctl_clk(wlc_hw
, BCMA_CLKMODE_FAST
);
4978 * Configure pci/pcmcia here instead of in brcms_c_attach()
4979 * to allow mfg hotswap: down, hotswap (chip power cycle), up.
4981 bcma_core_pci_irq_ctl(&wlc_hw
->d11core
->bus
->drv_pci
[0], wlc_hw
->d11core
,
4985 * Need to read the hwradio status here to cover the case where the
4986 * system is loaded with the hw radio disabled. We do not want to
4987 * bring the driver up in this case.
4989 if (brcms_b_radio_read_hwdisabled(wlc_hw
)) {
4990 /* put SB PCI in down state again */
4991 ai_pci_down(wlc_hw
->sih
);
4992 brcms_b_xtal(wlc_hw
, OFF
);
4996 ai_pci_up(wlc_hw
->sih
);
4998 /* reset the d11 core */
4999 brcms_b_corereset(wlc_hw
, BRCMS_USE_COREFLAGS
);
5004 static int brcms_b_up_finish(struct brcms_hardware
*wlc_hw
)
5007 wlc_phy_hw_state_upd(wlc_hw
->band
->pi
, true);
5009 /* FULLY enable dynamic power control and d11 core interrupt */
5010 brcms_b_clkctl_clk(wlc_hw
, BCMA_CLKMODE_DYNAMIC
);
5011 brcms_intrson(wlc_hw
->wlc
->wl
);
5016 * Write WME tunable parameters for retransmit/max rate
5017 * from wlc struct to ucode
5019 static void brcms_c_wme_retries_write(struct brcms_c_info
*wlc
)
5023 /* Need clock to do this */
5027 for (ac
= 0; ac
< IEEE80211_NUM_ACS
; ac
++)
5028 brcms_b_write_shm(wlc
->hw
, M_AC_TXLMT_ADDR(ac
),
5029 wlc
->wme_retries
[ac
]);
5032 /* make interface operational */
5033 int brcms_c_up(struct brcms_c_info
*wlc
)
5035 struct ieee80211_channel
*ch
;
5037 brcms_dbg_info(wlc
->hw
->d11core
, "wl%d\n", wlc
->pub
->unit
);
5039 /* HW is turned off so don't try to access it */
5040 if (wlc
->pub
->hw_off
|| brcms_deviceremoved(wlc
))
5043 if (!wlc
->pub
->hw_up
) {
5044 brcms_b_hw_up(wlc
->hw
);
5045 wlc
->pub
->hw_up
= true;
5048 if ((wlc
->pub
->boardflags
& BFL_FEM
)
5049 && (ai_get_chip_id(wlc
->hw
->sih
) == BCMA_CHIP_ID_BCM4313
)) {
5050 if (wlc
->pub
->boardrev
>= 0x1250
5051 && (wlc
->pub
->boardflags
& BFL_FEM_BT
))
5052 brcms_b_mhf(wlc
->hw
, MHF5
, MHF5_4313_GPIOCTRL
,
5053 MHF5_4313_GPIOCTRL
, BRCM_BAND_ALL
);
5055 brcms_b_mhf(wlc
->hw
, MHF4
, MHF4_EXTPA_ENABLE
,
5056 MHF4_EXTPA_ENABLE
, BRCM_BAND_ALL
);
5060 * Need to read the hwradio status here to cover the case where the
5061 * system is loaded with the hw radio disabled. We do not want to bring
5062 * the driver up in this case. If radio is disabled, abort up, lower
5063 * power, start radio timer and return 0(for NDIS) don't call
5064 * radio_update to avoid looping brcms_c_up.
5066 * brcms_b_up_prep() returns either 0 or -BCME_RADIOOFF only
5068 if (!wlc
->pub
->radio_disabled
) {
5069 int status
= brcms_b_up_prep(wlc
->hw
);
5070 if (status
== -ENOMEDIUM
) {
5072 (wlc
->pub
->radio_disabled
, WL_RADIO_HW_DISABLE
)) {
5073 struct brcms_bss_cfg
*bsscfg
= wlc
->bsscfg
;
5074 mboolset(wlc
->pub
->radio_disabled
,
5075 WL_RADIO_HW_DISABLE
);
5077 if (bsscfg
->enable
&& bsscfg
->BSS
)
5078 brcms_err(wlc
->hw
->d11core
,
5079 "wl%d: up: rfdisable -> "
5080 "bsscfg_disable()\n",
5086 if (wlc
->pub
->radio_disabled
) {
5087 brcms_c_radio_monitor_start(wlc
);
5091 /* brcms_b_up_prep has done brcms_c_corereset(). so clk is on, set it */
5094 brcms_c_radio_monitor_stop(wlc
);
5096 /* Set EDCF hostflags */
5097 brcms_b_mhf(wlc
->hw
, MHF1
, MHF1_EDCF
, MHF1_EDCF
, BRCM_BAND_ALL
);
5099 brcms_init(wlc
->wl
);
5100 wlc
->pub
->up
= true;
5102 if (wlc
->bandinit_pending
) {
5103 ch
= wlc
->pub
->ieee_hw
->conf
.channel
;
5104 brcms_c_suspend_mac_and_wait(wlc
);
5105 brcms_c_set_chanspec(wlc
, ch20mhz_chspec(ch
->hw_value
));
5106 wlc
->bandinit_pending
= false;
5107 brcms_c_enable_mac(wlc
);
5110 brcms_b_up_finish(wlc
->hw
);
5112 /* Program the TX wme params with the current settings */
5113 brcms_c_wme_retries_write(wlc
);
5115 /* start one second watchdog timer */
5116 brcms_add_timer(wlc
->wdtimer
, TIMER_INTERVAL_WATCHDOG
, true);
5117 wlc
->WDarmed
= true;
5119 /* ensure antenna config is up to date */
5120 brcms_c_stf_phy_txant_upd(wlc
);
5121 /* ensure LDPC config is in sync */
5122 brcms_c_ht_update_ldpc(wlc
, wlc
->stf
->ldpc
);
5127 static uint
brcms_c_down_del_timer(struct brcms_c_info
*wlc
)
5134 static int brcms_b_bmac_down_prep(struct brcms_hardware
*wlc_hw
)
5142 dev_gone
= brcms_deviceremoved(wlc_hw
->wlc
);
5144 /* disable interrupts */
5146 wlc_hw
->wlc
->macintmask
= 0;
5148 /* now disable interrupts */
5149 brcms_intrsoff(wlc_hw
->wlc
->wl
);
5151 /* ensure we're running on the pll clock again */
5152 brcms_b_clkctl_clk(wlc_hw
, BCMA_CLKMODE_FAST
);
5154 /* down phy at the last of this stage */
5155 callbacks
+= wlc_phy_down(wlc_hw
->band
->pi
);
5160 static int brcms_b_down_finish(struct brcms_hardware
*wlc_hw
)
5169 wlc_phy_hw_state_upd(wlc_hw
->band
->pi
, false);
5171 dev_gone
= brcms_deviceremoved(wlc_hw
->wlc
);
5174 wlc_hw
->sbclk
= false;
5175 wlc_hw
->clk
= false;
5176 wlc_phy_hw_clk_state_upd(wlc_hw
->band
->pi
, false);
5178 /* reclaim any posted packets */
5179 brcms_c_flushqueues(wlc_hw
->wlc
);
5182 /* Reset and disable the core */
5183 if (bcma_core_is_enabled(wlc_hw
->d11core
)) {
5184 if (bcma_read32(wlc_hw
->d11core
,
5185 D11REGOFFS(maccontrol
)) & MCTL_EN_MAC
)
5186 brcms_c_suspend_mac_and_wait(wlc_hw
->wlc
);
5187 callbacks
+= brcms_reset(wlc_hw
->wlc
->wl
);
5188 brcms_c_coredisable(wlc_hw
);
5191 /* turn off primary xtal and pll */
5192 if (!wlc_hw
->noreset
) {
5193 ai_pci_down(wlc_hw
->sih
);
5194 brcms_b_xtal(wlc_hw
, OFF
);
5202 * Mark the interface nonoperational, stop the software mechanisms,
5203 * disable the hardware, free any transient buffer state.
5204 * Return a count of the number of driver callbacks still pending.
5206 uint
brcms_c_down(struct brcms_c_info
*wlc
)
5211 bool dev_gone
= false;
5213 brcms_dbg_info(wlc
->hw
->d11core
, "wl%d\n", wlc
->pub
->unit
);
5215 /* check if we are already in the going down path */
5216 if (wlc
->going_down
) {
5217 brcms_err(wlc
->hw
->d11core
,
5218 "wl%d: %s: Driver going down so return\n",
5219 wlc
->pub
->unit
, __func__
);
5225 wlc
->going_down
= true;
5227 callbacks
+= brcms_b_bmac_down_prep(wlc
->hw
);
5229 dev_gone
= brcms_deviceremoved(wlc
);
5231 /* Call any registered down handlers */
5232 for (i
= 0; i
< BRCMS_MAXMODULES
; i
++) {
5233 if (wlc
->modulecb
[i
].down_fn
)
5235 wlc
->modulecb
[i
].down_fn(wlc
->modulecb
[i
].hdl
);
5238 /* cancel the watchdog timer */
5240 if (!brcms_del_timer(wlc
->wdtimer
))
5242 wlc
->WDarmed
= false;
5244 /* cancel all other timers */
5245 callbacks
+= brcms_c_down_del_timer(wlc
);
5247 wlc
->pub
->up
= false;
5249 wlc_phy_mute_upd(wlc
->band
->pi
, false, PHY_MUTE_ALL
);
5251 callbacks
+= brcms_b_down_finish(wlc
->hw
);
5253 /* brcms_b_down_finish has done brcms_c_coredisable(). so clk is off */
5256 wlc
->going_down
= false;
5260 /* Set the current gmode configuration */
5261 int brcms_c_set_gmode(struct brcms_c_info
*wlc
, u8 gmode
, bool config
)
5265 struct brcms_c_rateset rs
;
5266 /* Default to 54g Auto */
5267 /* Advertise and use shortslot (-1/0/1 Auto/Off/On) */
5268 s8 shortslot
= BRCMS_SHORTSLOT_AUTO
;
5269 bool shortslot_restrict
= false; /* Restrict association to stations
5270 * that support shortslot
5272 bool ofdm_basic
= false; /* Make 6, 12, and 24 basic rates */
5273 /* Advertise and use short preambles (-1/0/1 Auto/Off/On) */
5274 int preamble
= BRCMS_PLCP_LONG
;
5275 bool preamble_restrict
= false; /* Restrict association to stations
5276 * that support short preambles
5278 struct brcms_band
*band
;
5280 /* if N-support is enabled, allow Gmode set as long as requested
5281 * Gmode is not GMODE_LEGACY_B
5283 if ((wlc
->pub
->_n_enab
& SUPPORT_11N
) && gmode
== GMODE_LEGACY_B
)
5286 /* verify that we are dealing with 2G band and grab the band pointer */
5287 if (wlc
->band
->bandtype
== BRCM_BAND_2G
)
5289 else if ((wlc
->pub
->_nbands
> 1) &&
5290 (wlc
->bandstate
[OTHERBANDUNIT(wlc
)]->bandtype
== BRCM_BAND_2G
))
5291 band
= wlc
->bandstate
[OTHERBANDUNIT(wlc
)];
5295 /* update configuration value */
5297 brcms_c_protection_upd(wlc
, BRCMS_PROT_G_USER
, gmode
);
5299 /* Clear rateset override */
5300 memset(&rs
, 0, sizeof(struct brcms_c_rateset
));
5303 case GMODE_LEGACY_B
:
5304 shortslot
= BRCMS_SHORTSLOT_OFF
;
5305 brcms_c_rateset_copy(&gphy_legacy_rates
, &rs
);
5313 /* Accept defaults */
5318 preamble
= BRCMS_PLCP_SHORT
;
5319 preamble_restrict
= true;
5322 case GMODE_PERFORMANCE
:
5323 shortslot
= BRCMS_SHORTSLOT_ON
;
5324 shortslot_restrict
= true;
5326 preamble
= BRCMS_PLCP_SHORT
;
5327 preamble_restrict
= true;
5332 brcms_err(wlc
->hw
->d11core
, "wl%d: %s: invalid gmode %d\n",
5333 wlc
->pub
->unit
, __func__
, gmode
);
5337 band
->gmode
= gmode
;
5339 wlc
->shortslot_override
= shortslot
;
5341 /* Use the default 11g rateset */
5343 brcms_c_rateset_copy(&cck_ofdm_rates
, &rs
);
5346 for (i
= 0; i
< rs
.count
; i
++) {
5347 if (rs
.rates
[i
] == BRCM_RATE_6M
5348 || rs
.rates
[i
] == BRCM_RATE_12M
5349 || rs
.rates
[i
] == BRCM_RATE_24M
)
5350 rs
.rates
[i
] |= BRCMS_RATE_FLAG
;
5354 /* Set default bss rateset */
5355 wlc
->default_bss
->rateset
.count
= rs
.count
;
5356 memcpy(wlc
->default_bss
->rateset
.rates
, rs
.rates
,
5357 sizeof(wlc
->default_bss
->rateset
.rates
));
5362 int brcms_c_set_nmode(struct brcms_c_info
*wlc
)
5367 if (wlc
->stf
->txstreams
== WL_11N_3x3
)
5372 /* force GMODE_AUTO if NMODE is ON */
5373 brcms_c_set_gmode(wlc
, GMODE_AUTO
, true);
5374 if (nmode
== WL_11N_3x3
)
5375 wlc
->pub
->_n_enab
= SUPPORT_HT
;
5377 wlc
->pub
->_n_enab
= SUPPORT_11N
;
5378 wlc
->default_bss
->flags
|= BRCMS_BSS_HT
;
5379 /* add the mcs rates to the default and hw ratesets */
5380 brcms_c_rateset_mcs_build(&wlc
->default_bss
->rateset
,
5381 wlc
->stf
->txstreams
);
5382 for (i
= 0; i
< wlc
->pub
->_nbands
; i
++)
5383 memcpy(wlc
->bandstate
[i
]->hw_rateset
.mcs
,
5384 wlc
->default_bss
->rateset
.mcs
, MCSSET_LEN
);
5390 brcms_c_set_internal_rateset(struct brcms_c_info
*wlc
,
5391 struct brcms_c_rateset
*rs_arg
)
5393 struct brcms_c_rateset rs
, new;
5396 memcpy(&rs
, rs_arg
, sizeof(struct brcms_c_rateset
));
5398 /* check for bad count value */
5399 if ((rs
.count
== 0) || (rs
.count
> BRCMS_NUMRATES
))
5402 /* try the current band */
5403 bandunit
= wlc
->band
->bandunit
;
5404 memcpy(&new, &rs
, sizeof(struct brcms_c_rateset
));
5405 if (brcms_c_rate_hwrs_filter_sort_validate
5406 (&new, &wlc
->bandstate
[bandunit
]->hw_rateset
, true,
5407 wlc
->stf
->txstreams
))
5410 /* try the other band */
5411 if (brcms_is_mband_unlocked(wlc
)) {
5412 bandunit
= OTHERBANDUNIT(wlc
);
5413 memcpy(&new, &rs
, sizeof(struct brcms_c_rateset
));
5414 if (brcms_c_rate_hwrs_filter_sort_validate(&new,
5416 bandstate
[bandunit
]->
5418 wlc
->stf
->txstreams
))
5425 /* apply new rateset */
5426 memcpy(&wlc
->default_bss
->rateset
, &new,
5427 sizeof(struct brcms_c_rateset
));
5428 memcpy(&wlc
->bandstate
[bandunit
]->defrateset
, &new,
5429 sizeof(struct brcms_c_rateset
));
5433 static void brcms_c_ofdm_rateset_war(struct brcms_c_info
*wlc
)
5438 if (wlc
->bsscfg
->associated
)
5439 r
= wlc
->bsscfg
->current_bss
->rateset
.rates
[0];
5441 r
= wlc
->default_bss
->rateset
.rates
[0];
5443 wlc_phy_ofdm_rateset_war(wlc
->band
->pi
, war
);
5446 int brcms_c_set_channel(struct brcms_c_info
*wlc
, u16 channel
)
5448 u16 chspec
= ch20mhz_chspec(channel
);
5450 if (channel
< 0 || channel
> MAXCHANNEL
)
5453 if (!brcms_c_valid_chanspec_db(wlc
->cmi
, chspec
))
5457 if (!wlc
->pub
->up
&& brcms_is_mband_unlocked(wlc
)) {
5458 if (wlc
->band
->bandunit
!= chspec_bandunit(chspec
))
5459 wlc
->bandinit_pending
= true;
5461 wlc
->bandinit_pending
= false;
5464 wlc
->default_bss
->chanspec
= chspec
;
5465 /* brcms_c_BSSinit() will sanitize the rateset before
5467 if (wlc
->pub
->up
&& (wlc_phy_chanspec_get(wlc
->band
->pi
) != chspec
)) {
5468 brcms_c_set_home_chanspec(wlc
, chspec
);
5469 brcms_c_suspend_mac_and_wait(wlc
);
5470 brcms_c_set_chanspec(wlc
, chspec
);
5471 brcms_c_enable_mac(wlc
);
5476 int brcms_c_set_rate_limit(struct brcms_c_info
*wlc
, u16 srl
, u16 lrl
)
5480 if (srl
< 1 || srl
> RETRY_SHORT_MAX
||
5481 lrl
< 1 || lrl
> RETRY_SHORT_MAX
)
5487 brcms_b_retrylimit_upd(wlc
->hw
, wlc
->SRL
, wlc
->LRL
);
5489 for (ac
= 0; ac
< IEEE80211_NUM_ACS
; ac
++) {
5490 wlc
->wme_retries
[ac
] = SFIELD(wlc
->wme_retries
[ac
],
5491 EDCF_SHORT
, wlc
->SRL
);
5492 wlc
->wme_retries
[ac
] = SFIELD(wlc
->wme_retries
[ac
],
5493 EDCF_LONG
, wlc
->LRL
);
5495 brcms_c_wme_retries_write(wlc
);
5500 void brcms_c_get_current_rateset(struct brcms_c_info
*wlc
,
5501 struct brcm_rateset
*currs
)
5503 struct brcms_c_rateset
*rs
;
5505 if (wlc
->pub
->associated
)
5506 rs
= &wlc
->bsscfg
->current_bss
->rateset
;
5508 rs
= &wlc
->default_bss
->rateset
;
5510 /* Copy only legacy rateset section */
5511 currs
->count
= rs
->count
;
5512 memcpy(&currs
->rates
, &rs
->rates
, rs
->count
);
5515 int brcms_c_set_rateset(struct brcms_c_info
*wlc
, struct brcm_rateset
*rs
)
5517 struct brcms_c_rateset internal_rs
;
5520 if (rs
->count
> BRCMS_NUMRATES
)
5523 memset(&internal_rs
, 0, sizeof(struct brcms_c_rateset
));
5525 /* Copy only legacy rateset section */
5526 internal_rs
.count
= rs
->count
;
5527 memcpy(&internal_rs
.rates
, &rs
->rates
, internal_rs
.count
);
5529 /* merge rateset coming in with the current mcsset */
5530 if (wlc
->pub
->_n_enab
& SUPPORT_11N
) {
5531 struct brcms_bss_info
*mcsset_bss
;
5532 if (wlc
->bsscfg
->associated
)
5533 mcsset_bss
= wlc
->bsscfg
->current_bss
;
5535 mcsset_bss
= wlc
->default_bss
;
5536 memcpy(internal_rs
.mcs
, &mcsset_bss
->rateset
.mcs
[0],
5540 bcmerror
= brcms_c_set_internal_rateset(wlc
, &internal_rs
);
5542 brcms_c_ofdm_rateset_war(wlc
);
5547 int brcms_c_set_beacon_period(struct brcms_c_info
*wlc
, u16 period
)
5552 wlc
->default_bss
->beacon_period
= period
;
5556 u16
brcms_c_get_phy_type(struct brcms_c_info
*wlc
, int phyidx
)
5558 return wlc
->band
->phytype
;
5561 void brcms_c_set_shortslot_override(struct brcms_c_info
*wlc
, s8 sslot_override
)
5563 wlc
->shortslot_override
= sslot_override
;
5566 * shortslot is an 11g feature, so no more work if we are
5567 * currently on the 5G band
5569 if (wlc
->band
->bandtype
== BRCM_BAND_5G
)
5572 if (wlc
->pub
->up
&& wlc
->pub
->associated
) {
5573 /* let watchdog or beacon processing update shortslot */
5574 } else if (wlc
->pub
->up
) {
5575 /* unassociated shortslot is off */
5576 brcms_c_switch_shortslot(wlc
, false);
5578 /* driver is down, so just update the brcms_c_info
5580 if (wlc
->shortslot_override
== BRCMS_SHORTSLOT_AUTO
)
5581 wlc
->shortslot
= false;
5584 (wlc
->shortslot_override
==
5585 BRCMS_SHORTSLOT_ON
);
5590 * register watchdog and down handlers.
5592 int brcms_c_module_register(struct brcms_pub
*pub
,
5593 const char *name
, struct brcms_info
*hdl
,
5594 int (*d_fn
)(void *handle
))
5596 struct brcms_c_info
*wlc
= (struct brcms_c_info
*) pub
->wlc
;
5599 /* find an empty entry and just add, no duplication check! */
5600 for (i
= 0; i
< BRCMS_MAXMODULES
; i
++) {
5601 if (wlc
->modulecb
[i
].name
[0] == '\0') {
5602 strncpy(wlc
->modulecb
[i
].name
, name
,
5603 sizeof(wlc
->modulecb
[i
].name
) - 1);
5604 wlc
->modulecb
[i
].hdl
= hdl
;
5605 wlc
->modulecb
[i
].down_fn
= d_fn
;
5613 /* unregister module callbacks */
5614 int brcms_c_module_unregister(struct brcms_pub
*pub
, const char *name
,
5615 struct brcms_info
*hdl
)
5617 struct brcms_c_info
*wlc
= (struct brcms_c_info
*) pub
->wlc
;
5623 for (i
= 0; i
< BRCMS_MAXMODULES
; i
++) {
5624 if (!strcmp(wlc
->modulecb
[i
].name
, name
) &&
5625 (wlc
->modulecb
[i
].hdl
== hdl
)) {
5626 memset(&wlc
->modulecb
[i
], 0, sizeof(struct modulecb
));
5631 /* table not found! */
5635 static bool brcms_c_chipmatch_pci(struct bcma_device
*core
)
5637 struct pci_dev
*pcidev
= core
->bus
->host_pci
;
5638 u16 vendor
= pcidev
->vendor
;
5639 u16 device
= pcidev
->device
;
5641 if (vendor
!= PCI_VENDOR_ID_BROADCOM
) {
5642 pr_err("unknown vendor id %04x\n", vendor
);
5646 if (device
== BCM43224_D11N_ID_VEN1
|| device
== BCM43224_CHIP_ID
)
5648 if ((device
== BCM43224_D11N_ID
) || (device
== BCM43225_D11N2G_ID
))
5650 if (device
== BCM4313_D11N2G_ID
)
5652 if ((device
== BCM43236_D11N_ID
) || (device
== BCM43236_D11N2G_ID
))
5655 pr_err("unknown device id %04x\n", device
);
5659 static bool brcms_c_chipmatch_soc(struct bcma_device
*core
)
5661 struct bcma_chipinfo
*chipinfo
= &core
->bus
->chipinfo
;
5663 if (chipinfo
->id
== BCMA_CHIP_ID_BCM4716
)
5666 pr_err("unknown chip id %04x\n", chipinfo
->id
);
5670 bool brcms_c_chipmatch(struct bcma_device
*core
)
5672 switch (core
->bus
->hosttype
) {
5673 case BCMA_HOSTTYPE_PCI
:
5674 return brcms_c_chipmatch_pci(core
);
5675 case BCMA_HOSTTYPE_SOC
:
5676 return brcms_c_chipmatch_soc(core
);
5678 pr_err("unknown host type: %i\n", core
->bus
->hosttype
);
5683 u16
brcms_b_rate_shm_offset(struct brcms_hardware
*wlc_hw
, u8 rate
)
5688 /* get the phy specific rate encoding for the PLCP SIGNAL field */
5689 if (is_ofdm_rate(rate
))
5690 table_ptr
= M_RT_DIRMAP_A
;
5692 table_ptr
= M_RT_DIRMAP_B
;
5694 /* for a given rate, the LS-nibble of the PLCP SIGNAL field is
5695 * the index into the rate table.
5697 phy_rate
= rate_info
[rate
] & BRCMS_RATE_MASK
;
5698 index
= phy_rate
& 0xf;
5700 /* Find the SHM pointer to the rate table entry by looking in the
5703 return 2 * brcms_b_read_shm(wlc_hw
, table_ptr
+ (index
* 2));
5707 * bcmc_fid_generate:
5708 * Generate frame ID for a BCMC packet. The frag field is not used
5709 * for MC frames so is used as part of the sequence number.
5712 bcmc_fid_generate(struct brcms_c_info
*wlc
, struct brcms_bss_cfg
*bsscfg
,
5717 frameid
= le16_to_cpu(txh
->TxFrameID
) & ~(TXFID_SEQ_MASK
|
5721 mc_fid_counter
++) << TXFID_SEQ_SHIFT
) & TXFID_SEQ_MASK
) |
5728 brcms_c_calc_ack_time(struct brcms_c_info
*wlc
, u32 rspec
,
5734 * Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that
5735 * is less than or equal to the rate of the immediately previous
5738 rspec
= brcms_basic_rate(wlc
, rspec
);
5739 /* ACK frame len == 14 == 2(fc) + 2(dur) + 6(ra) + 4(fcs) */
5741 brcms_c_calc_frame_time(wlc
, rspec
, preamble_type
,
5742 (DOT11_ACK_LEN
+ FCS_LEN
));
5747 brcms_c_calc_cts_time(struct brcms_c_info
*wlc
, u32 rspec
,
5750 return brcms_c_calc_ack_time(wlc
, rspec
, preamble_type
);
5754 brcms_c_calc_ba_time(struct brcms_c_info
*wlc
, u32 rspec
,
5758 * Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that
5759 * is less than or equal to the rate of the immediately previous
5762 rspec
= brcms_basic_rate(wlc
, rspec
);
5763 /* BA len == 32 == 16(ctl hdr) + 4(ba len) + 8(bitmap) + 4(fcs) */
5764 return brcms_c_calc_frame_time(wlc
, rspec
, preamble_type
,
5765 (DOT11_BA_LEN
+ DOT11_BA_BITMAP_LEN
+
5769 /* brcms_c_compute_frame_dur()
5771 * Calculate the 802.11 MAC header DUR field for MPDU
5772 * DUR for a single frame = 1 SIFS + 1 ACK
5773 * DUR for a frame with following frags = 3 SIFS + 2 ACK + next frag time
5775 * rate MPDU rate in unit of 500kbps
5776 * next_frag_len next MPDU length in bytes
5777 * preamble_type use short/GF or long/MM PLCP header
5780 brcms_c_compute_frame_dur(struct brcms_c_info
*wlc
, u32 rate
,
5781 u8 preamble_type
, uint next_frag_len
)
5785 sifs
= get_sifs(wlc
->band
);
5788 dur
+= (u16
) brcms_c_calc_ack_time(wlc
, rate
, preamble_type
);
5790 if (next_frag_len
) {
5791 /* Double the current DUR to get 2 SIFS + 2 ACKs */
5793 /* add another SIFS and the frag time */
5796 (u16
) brcms_c_calc_frame_time(wlc
, rate
, preamble_type
,
5802 /* The opposite of brcms_c_calc_frame_time */
5804 brcms_c_calc_frame_len(struct brcms_c_info
*wlc
, u32 ratespec
,
5805 u8 preamble_type
, uint dur
)
5807 uint nsyms
, mac_len
, Ndps
, kNdps
;
5808 uint rate
= rspec2rate(ratespec
);
5810 if (is_mcs_rate(ratespec
)) {
5811 uint mcs
= ratespec
& RSPEC_RATE_MASK
;
5812 int tot_streams
= mcs_2_txstreams(mcs
) + rspec_stc(ratespec
);
5813 dur
-= PREN_PREAMBLE
+ (tot_streams
* PREN_PREAMBLE_EXT
);
5814 /* payload calculation matches that of regular ofdm */
5815 if (wlc
->band
->bandtype
== BRCM_BAND_2G
)
5816 dur
-= DOT11_OFDM_SIGNAL_EXTENSION
;
5817 /* kNdbps = kbps * 4 */
5818 kNdps
= mcs_2_rate(mcs
, rspec_is40mhz(ratespec
),
5819 rspec_issgi(ratespec
)) * 4;
5820 nsyms
= dur
/ APHY_SYMBOL_TIME
;
5823 ((APHY_SERVICE_NBITS
+ APHY_TAIL_NBITS
) * 1000)) / 8000;
5824 } else if (is_ofdm_rate(ratespec
)) {
5825 dur
-= APHY_PREAMBLE_TIME
;
5826 dur
-= APHY_SIGNAL_TIME
;
5827 /* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */
5829 nsyms
= dur
/ APHY_SYMBOL_TIME
;
5832 (APHY_SERVICE_NBITS
+ APHY_TAIL_NBITS
)) / 8;
5834 if (preamble_type
& BRCMS_SHORT_PREAMBLE
)
5835 dur
-= BPHY_PLCP_SHORT_TIME
;
5837 dur
-= BPHY_PLCP_TIME
;
5838 mac_len
= dur
* rate
;
5839 /* divide out factor of 2 in rate (1/2 mbps) */
5840 mac_len
= mac_len
/ 8 / 2;
5846 * Return true if the specified rate is supported by the specified band.
5847 * BRCM_BAND_AUTO indicates the current band.
5849 static bool brcms_c_valid_rate(struct brcms_c_info
*wlc
, u32 rspec
, int band
,
5852 struct brcms_c_rateset
*hw_rateset
;
5855 if ((band
== BRCM_BAND_AUTO
) || (band
== wlc
->band
->bandtype
))
5856 hw_rateset
= &wlc
->band
->hw_rateset
;
5857 else if (wlc
->pub
->_nbands
> 1)
5858 hw_rateset
= &wlc
->bandstate
[OTHERBANDUNIT(wlc
)]->hw_rateset
;
5860 /* other band specified and we are a single band device */
5863 /* check if this is a mimo rate */
5864 if (is_mcs_rate(rspec
)) {
5865 if ((rspec
& RSPEC_RATE_MASK
) >= MCS_TABLE_SIZE
)
5868 return isset(hw_rateset
->mcs
, (rspec
& RSPEC_RATE_MASK
));
5871 for (i
= 0; i
< hw_rateset
->count
; i
++)
5872 if (hw_rateset
->rates
[i
] == rspec2rate(rspec
))
5876 brcms_err(wlc
->hw
->d11core
, "wl%d: valid_rate: rate spec 0x%x "
5877 "not in hw_rateset\n", wlc
->pub
->unit
, rspec
);
5883 mac80211_wlc_set_nrate(struct brcms_c_info
*wlc
, struct brcms_band
*cur_band
,
5886 struct bcma_device
*core
= wlc
->hw
->d11core
;
5887 u8 stf
= (int_val
& NRATE_STF_MASK
) >> NRATE_STF_SHIFT
;
5888 u8 rate
= int_val
& NRATE_RATE_MASK
;
5890 bool ismcs
= ((int_val
& NRATE_MCS_INUSE
) == NRATE_MCS_INUSE
);
5891 bool issgi
= ((int_val
& NRATE_SGI_MASK
) >> NRATE_SGI_SHIFT
);
5892 bool override_mcs_only
= ((int_val
& NRATE_OVERRIDE_MCS_ONLY
)
5893 == NRATE_OVERRIDE_MCS_ONLY
);
5899 /* validate the combination of rate/mcs/stf is allowed */
5900 if ((wlc
->pub
->_n_enab
& SUPPORT_11N
) && ismcs
) {
5901 /* mcs only allowed when nmode */
5902 if (stf
> PHY_TXC1_MODE_SDM
) {
5903 brcms_err(core
, "wl%d: %s: Invalid stf\n",
5904 wlc
->pub
->unit
, __func__
);
5909 /* mcs 32 is a special case, DUP mode 40 only */
5911 if (!CHSPEC_IS40(wlc
->home_chanspec
) ||
5912 ((stf
!= PHY_TXC1_MODE_SISO
)
5913 && (stf
!= PHY_TXC1_MODE_CDD
))) {
5914 brcms_err(core
, "wl%d: %s: Invalid mcs 32\n",
5915 wlc
->pub
->unit
, __func__
);
5919 /* mcs > 7 must use stf SDM */
5920 } else if (rate
> HIGHEST_SINGLE_STREAM_MCS
) {
5921 /* mcs > 7 must use stf SDM */
5922 if (stf
!= PHY_TXC1_MODE_SDM
) {
5923 brcms_dbg_mac80211(core
, "wl%d: enabling "
5924 "SDM mode for mcs %d\n",
5925 wlc
->pub
->unit
, rate
);
5926 stf
= PHY_TXC1_MODE_SDM
;
5930 * MCS 0-7 may use SISO, CDD, and for
5933 if ((stf
> PHY_TXC1_MODE_STBC
) ||
5934 (!BRCMS_STBC_CAP_PHY(wlc
)
5935 && (stf
== PHY_TXC1_MODE_STBC
))) {
5936 brcms_err(core
, "wl%d: %s: Invalid STBC\n",
5937 wlc
->pub
->unit
, __func__
);
5942 } else if (is_ofdm_rate(rate
)) {
5943 if ((stf
!= PHY_TXC1_MODE_CDD
) && (stf
!= PHY_TXC1_MODE_SISO
)) {
5944 brcms_err(core
, "wl%d: %s: Invalid OFDM\n",
5945 wlc
->pub
->unit
, __func__
);
5949 } else if (is_cck_rate(rate
)) {
5950 if ((cur_band
->bandtype
!= BRCM_BAND_2G
)
5951 || (stf
!= PHY_TXC1_MODE_SISO
)) {
5952 brcms_err(core
, "wl%d: %s: Invalid CCK\n",
5953 wlc
->pub
->unit
, __func__
);
5958 brcms_err(core
, "wl%d: %s: Unknown rate type\n",
5959 wlc
->pub
->unit
, __func__
);
5963 /* make sure multiple antennae are available for non-siso rates */
5964 if ((stf
!= PHY_TXC1_MODE_SISO
) && (wlc
->stf
->txstreams
== 1)) {
5965 brcms_err(core
, "wl%d: %s: SISO antenna but !SISO "
5966 "request\n", wlc
->pub
->unit
, __func__
);
5973 rspec
|= RSPEC_MIMORATE
;
5974 /* For STBC populate the STC field of the ratespec */
5975 if (stf
== PHY_TXC1_MODE_STBC
) {
5977 stc
= 1; /* Nss for single stream is always 1 */
5978 rspec
|= (stc
<< RSPEC_STC_SHIFT
);
5982 rspec
|= (stf
<< RSPEC_STF_SHIFT
);
5984 if (override_mcs_only
)
5985 rspec
|= RSPEC_OVERRIDE_MCS_ONLY
;
5988 rspec
|= RSPEC_SHORT_GI
;
5991 && !brcms_c_valid_rate(wlc
, rspec
, cur_band
->bandtype
, true))
6000 * Compute PLCP, but only requires actual rate and length of pkt.
6001 * Rate is given in the driver standard multiple of 500 kbps.
6002 * le is set for 11 Mbps rate if necessary.
6003 * Broken out for PRQ.
6006 static void brcms_c_cck_plcp_set(struct brcms_c_info
*wlc
, int rate_500
,
6007 uint length
, u8
*plcp
)
6020 usec
= (length
<< 4) / 11;
6021 if ((length
<< 4) - (usec
* 11) > 0)
6025 usec
= (length
<< 3) / 11;
6026 if ((length
<< 3) - (usec
* 11) > 0) {
6028 if ((usec
* 11) - (length
<< 3) >= 8)
6029 le
= D11B_PLCP_SIGNAL_LE
;
6034 brcms_err(wlc
->hw
->d11core
,
6035 "brcms_c_cck_plcp_set: unsupported rate %d\n",
6037 rate_500
= BRCM_RATE_1M
;
6041 /* PLCP signal byte */
6042 plcp
[0] = rate_500
* 5; /* r (500kbps) * 5 == r (100kbps) */
6043 /* PLCP service byte */
6044 plcp
[1] = (u8
) (le
| D11B_PLCP_SIGNAL_LOCKED
);
6045 /* PLCP length u16, little endian */
6046 plcp
[2] = usec
& 0xff;
6047 plcp
[3] = (usec
>> 8) & 0xff;
6053 /* Rate: 802.11 rate code, length: PSDU length in octets */
6054 static void brcms_c_compute_mimo_plcp(u32 rspec
, uint length
, u8
*plcp
)
6056 u8 mcs
= (u8
) (rspec
& RSPEC_RATE_MASK
);
6058 if (rspec_is40mhz(rspec
) || (mcs
== 32))
6059 plcp
[0] |= MIMO_PLCP_40MHZ
;
6060 BRCMS_SET_MIMO_PLCP_LEN(plcp
, length
);
6061 plcp
[3] = rspec_mimoplcp3(rspec
); /* rspec already holds this byte */
6062 plcp
[3] |= 0x7; /* set smoothing, not sounding ppdu & reserved */
6063 plcp
[4] = 0; /* number of extension spatial streams bit 0 & 1 */
6067 /* Rate: 802.11 rate code, length: PSDU length in octets */
6069 brcms_c_compute_ofdm_plcp(u32 rspec
, u32 length
, u8
*plcp
)
6073 int rate
= rspec2rate(rspec
);
6076 * encode rate per 802.11a-1999 sec 17.3.4.1, with lsb
6079 rate_signal
= rate_info
[rate
] & BRCMS_RATE_MASK
;
6080 memset(plcp
, 0, D11_PHY_HDR_LEN
);
6081 D11A_PHY_HDR_SRATE((struct ofdm_phy_hdr
*) plcp
, rate_signal
);
6083 tmp
= (length
& 0xfff) << 5;
6084 plcp
[2] |= (tmp
>> 16) & 0xff;
6085 plcp
[1] |= (tmp
>> 8) & 0xff;
6086 plcp
[0] |= tmp
& 0xff;
6089 /* Rate: 802.11 rate code, length: PSDU length in octets */
6090 static void brcms_c_compute_cck_plcp(struct brcms_c_info
*wlc
, u32 rspec
,
6091 uint length
, u8
*plcp
)
6093 int rate
= rspec2rate(rspec
);
6095 brcms_c_cck_plcp_set(wlc
, rate
, length
, plcp
);
6099 brcms_c_compute_plcp(struct brcms_c_info
*wlc
, u32 rspec
,
6100 uint length
, u8
*plcp
)
6102 if (is_mcs_rate(rspec
))
6103 brcms_c_compute_mimo_plcp(rspec
, length
, plcp
);
6104 else if (is_ofdm_rate(rspec
))
6105 brcms_c_compute_ofdm_plcp(rspec
, length
, plcp
);
6107 brcms_c_compute_cck_plcp(wlc
, rspec
, length
, plcp
);
6110 /* brcms_c_compute_rtscts_dur()
6112 * Calculate the 802.11 MAC header DUR field for an RTS or CTS frame
6113 * DUR for normal RTS/CTS w/ frame = 3 SIFS + 1 CTS + next frame time + 1 ACK
6114 * DUR for CTS-TO-SELF w/ frame = 2 SIFS + next frame time + 1 ACK
6116 * cts cts-to-self or rts/cts
6117 * rts_rate rts or cts rate in unit of 500kbps
6118 * rate next MPDU rate in unit of 500kbps
6119 * frame_len next MPDU frame length in bytes
6122 brcms_c_compute_rtscts_dur(struct brcms_c_info
*wlc
, bool cts_only
,
6124 u32 frame_rate
, u8 rts_preamble_type
,
6125 u8 frame_preamble_type
, uint frame_len
, bool ba
)
6129 sifs
= get_sifs(wlc
->band
);
6135 (u16
) brcms_c_calc_cts_time(wlc
, rts_rate
,
6143 (u16
) brcms_c_calc_frame_time(wlc
, frame_rate
, frame_preamble_type
,
6147 (u16
) brcms_c_calc_ba_time(wlc
, frame_rate
,
6148 BRCMS_SHORT_PREAMBLE
);
6151 (u16
) brcms_c_calc_ack_time(wlc
, frame_rate
,
6152 frame_preamble_type
);
6156 static u16
brcms_c_phytxctl1_calc(struct brcms_c_info
*wlc
, u32 rspec
)
6161 if (BRCMS_ISLCNPHY(wlc
->band
)) {
6162 bw
= PHY_TXC1_BW_20MHZ
;
6164 bw
= rspec_get_bw(rspec
);
6165 /* 10Mhz is not supported yet */
6166 if (bw
< PHY_TXC1_BW_20MHZ
) {
6167 brcms_err(wlc
->hw
->d11core
, "phytxctl1_calc: bw %d is "
6168 "not supported yet, set to 20L\n", bw
);
6169 bw
= PHY_TXC1_BW_20MHZ
;
6173 if (is_mcs_rate(rspec
)) {
6174 uint mcs
= rspec
& RSPEC_RATE_MASK
;
6176 /* bw, stf, coding-type is part of rspec_phytxbyte2 returns */
6177 phyctl1
= rspec_phytxbyte2(rspec
);
6178 /* set the upper byte of phyctl1 */
6179 phyctl1
|= (mcs_table
[mcs
].tx_phy_ctl3
<< 8);
6180 } else if (is_cck_rate(rspec
) && !BRCMS_ISLCNPHY(wlc
->band
)
6181 && !BRCMS_ISSSLPNPHY(wlc
->band
)) {
6183 * In CCK mode LPPHY overloads OFDM Modulation bits with CCK
6184 * Data Rate. Eventually MIMOPHY would also be converted to
6187 /* 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps */
6188 phyctl1
= (bw
| (rspec_stf(rspec
) << PHY_TXC1_MODE_SHIFT
));
6189 } else { /* legacy OFDM/CCK */
6191 /* get the phyctl byte from rate phycfg table */
6192 phycfg
= brcms_c_rate_legacy_phyctl(rspec2rate(rspec
));
6194 brcms_err(wlc
->hw
->d11core
, "phytxctl1_calc: wrong "
6195 "legacy OFDM/CCK rate\n");
6198 /* set the upper byte of phyctl1 */
6200 (bw
| (phycfg
<< 8) |
6201 (rspec_stf(rspec
) << PHY_TXC1_MODE_SHIFT
));
6207 * Add struct d11txh, struct cck_phy_hdr.
6209 * 'p' data must start with 802.11 MAC header
6210 * 'p' must allow enough bytes of local headers to be "pushed" onto the packet
6212 * headroom == D11_PHY_HDR_LEN + D11_TXH_LEN (D11_TXH_LEN is now 104 bytes)
6216 brcms_c_d11hdrs_mac80211(struct brcms_c_info
*wlc
, struct ieee80211_hw
*hw
,
6217 struct sk_buff
*p
, struct scb
*scb
, uint frag
,
6218 uint nfrags
, uint queue
, uint next_frag_len
)
6220 struct ieee80211_hdr
*h
;
6222 u8
*plcp
, plcp_fallback
[D11_PHY_HDR_LEN
];
6223 int len
, phylen
, rts_phylen
;
6224 u16 mch
, phyctl
, xfts
, mainrates
;
6225 u16 seq
= 0, mcl
= 0, status
= 0, frameid
= 0;
6226 u32 rspec
[2] = { BRCM_RATE_1M
, BRCM_RATE_1M
};
6227 u32 rts_rspec
[2] = { BRCM_RATE_1M
, BRCM_RATE_1M
};
6228 bool use_rts
= false;
6229 bool use_cts
= false;
6230 bool use_rifs
= false;
6231 bool short_preamble
[2] = { false, false };
6232 u8 preamble_type
[2] = { BRCMS_LONG_PREAMBLE
, BRCMS_LONG_PREAMBLE
};
6233 u8 rts_preamble_type
[2] = { BRCMS_LONG_PREAMBLE
, BRCMS_LONG_PREAMBLE
};
6234 u8
*rts_plcp
, rts_plcp_fallback
[D11_PHY_HDR_LEN
];
6235 struct ieee80211_rts
*rts
= NULL
;
6238 bool hwtkmic
= false;
6239 u16 mimo_ctlchbw
= PHY_TXC1_BW_20MHZ
;
6240 #define ANTCFG_NONE 0xFF
6241 u8 antcfg
= ANTCFG_NONE
;
6242 u8 fbantcfg
= ANTCFG_NONE
;
6243 uint phyctl1_stf
= 0;
6245 struct ieee80211_tx_rate
*txrate
[2];
6247 struct ieee80211_tx_info
*tx_info
;
6250 u8 mimo_preamble_type
;
6252 /* locate 802.11 MAC header */
6253 h
= (struct ieee80211_hdr
*)(p
->data
);
6254 qos
= ieee80211_is_data_qos(h
->frame_control
);
6256 /* compute length of frame in bytes for use in PLCP computations */
6258 phylen
= len
+ FCS_LEN
;
6261 tx_info
= IEEE80211_SKB_CB(p
);
6264 plcp
= skb_push(p
, D11_PHY_HDR_LEN
);
6266 /* add Broadcom tx descriptor header */
6267 txh
= (struct d11txh
*) skb_push(p
, D11_TXH_LEN
);
6268 memset(txh
, 0, D11_TXH_LEN
);
6271 if (tx_info
->flags
& IEEE80211_TX_CTL_ASSIGN_SEQ
) {
6272 /* non-AP STA should never use BCMC queue */
6273 if (queue
== TX_BCMC_FIFO
) {
6274 brcms_err(wlc
->hw
->d11core
,
6275 "wl%d: %s: ASSERT queue == TX_BCMC!\n",
6276 wlc
->pub
->unit
, __func__
);
6277 frameid
= bcmc_fid_generate(wlc
, NULL
, txh
);
6279 /* Increment the counter for first fragment */
6280 if (tx_info
->flags
& IEEE80211_TX_CTL_FIRST_FRAGMENT
)
6281 scb
->seqnum
[p
->priority
]++;
6283 /* extract fragment number from frame first */
6284 seq
= le16_to_cpu(h
->seq_ctrl
) & FRAGNUM_MASK
;
6285 seq
|= (scb
->seqnum
[p
->priority
] << SEQNUM_SHIFT
);
6286 h
->seq_ctrl
= cpu_to_le16(seq
);
6288 frameid
= ((seq
<< TXFID_SEQ_SHIFT
) & TXFID_SEQ_MASK
) |
6289 (queue
& TXFID_QUEUE_MASK
);
6292 frameid
|= queue
& TXFID_QUEUE_MASK
;
6294 /* set the ignpmq bit for all pkts tx'd in PS mode and for beacons */
6295 if (ieee80211_is_beacon(h
->frame_control
))
6296 mcl
|= TXC_IGNOREPMQ
;
6298 txrate
[0] = tx_info
->control
.rates
;
6299 txrate
[1] = txrate
[0] + 1;
6302 * if rate control algorithm didn't give us a fallback
6303 * rate, use the primary rate
6305 if (txrate
[1]->idx
< 0)
6306 txrate
[1] = txrate
[0];
6308 for (k
= 0; k
< hw
->max_rates
; k
++) {
6309 is_mcs
= txrate
[k
]->flags
& IEEE80211_TX_RC_MCS
? true : false;
6311 if ((txrate
[k
]->idx
>= 0)
6312 && (txrate
[k
]->idx
<
6313 hw
->wiphy
->bands
[tx_info
->band
]->n_bitrates
)) {
6315 hw
->wiphy
->bands
[tx_info
->band
]->
6316 bitrates
[txrate
[k
]->idx
].hw_value
;
6319 flags
& IEEE80211_TX_RC_USE_SHORT_PREAMBLE
?
6322 rspec
[k
] = BRCM_RATE_1M
;
6325 rspec
[k
] = mac80211_wlc_set_nrate(wlc
, wlc
->band
,
6326 NRATE_MCS_INUSE
| txrate
[k
]->idx
);
6330 * Currently only support same setting for primay and
6331 * fallback rates. Unify flags for each rate into a
6332 * single value for the frame
6336 flags
& IEEE80211_TX_RC_USE_RTS_CTS
? true : false;
6339 flags
& IEEE80211_TX_RC_USE_CTS_PROTECT
? true : false;
6344 * determine and validate primary rate
6345 * and fallback rates
6347 if (!rspec_active(rspec
[k
])) {
6348 rspec
[k
] = BRCM_RATE_1M
;
6350 if (!is_multicast_ether_addr(h
->addr1
)) {
6351 /* set tx antenna config */
6352 brcms_c_antsel_antcfg_get(wlc
->asi
, false,
6353 false, 0, 0, &antcfg
, &fbantcfg
);
6358 phyctl1_stf
= wlc
->stf
->ss_opmode
;
6360 if (wlc
->pub
->_n_enab
& SUPPORT_11N
) {
6361 for (k
= 0; k
< hw
->max_rates
; k
++) {
6363 * apply siso/cdd to single stream mcs's or ofdm
6364 * if rspec is auto selected
6366 if (((is_mcs_rate(rspec
[k
]) &&
6367 is_single_stream(rspec
[k
] & RSPEC_RATE_MASK
)) ||
6368 is_ofdm_rate(rspec
[k
]))
6369 && ((rspec
[k
] & RSPEC_OVERRIDE_MCS_ONLY
)
6370 || !(rspec
[k
] & RSPEC_OVERRIDE
))) {
6371 rspec
[k
] &= ~(RSPEC_STF_MASK
| RSPEC_STC_MASK
);
6373 /* For SISO MCS use STBC if possible */
6374 if (is_mcs_rate(rspec
[k
])
6375 && BRCMS_STF_SS_STBC_TX(wlc
, scb
)) {
6378 /* Nss for single stream is always 1 */
6380 rspec
[k
] |= (PHY_TXC1_MODE_STBC
<<
6382 (stc
<< RSPEC_STC_SHIFT
);
6385 (phyctl1_stf
<< RSPEC_STF_SHIFT
);
6389 * Is the phy configured to use 40MHZ frames? If
6390 * so then pick the desired txbw
6392 if (brcms_chspec_bw(wlc
->chanspec
) == BRCMS_40_MHZ
) {
6393 /* default txbw is 20in40 SB */
6394 mimo_ctlchbw
= mimo_txbw
=
6395 CHSPEC_SB_UPPER(wlc_phy_chanspec_get(
6397 ? PHY_TXC1_BW_20MHZ_UP
: PHY_TXC1_BW_20MHZ
;
6399 if (is_mcs_rate(rspec
[k
])) {
6400 /* mcs 32 must be 40b/w DUP */
6401 if ((rspec
[k
] & RSPEC_RATE_MASK
)
6404 PHY_TXC1_BW_40MHZ_DUP
;
6406 } else if (wlc
->mimo_40txbw
!= AUTO
)
6407 mimo_txbw
= wlc
->mimo_40txbw
;
6408 /* else check if dst is using 40 Mhz */
6409 else if (scb
->flags
& SCB_IS40
)
6410 mimo_txbw
= PHY_TXC1_BW_40MHZ
;
6411 } else if (is_ofdm_rate(rspec
[k
])) {
6412 if (wlc
->ofdm_40txbw
!= AUTO
)
6413 mimo_txbw
= wlc
->ofdm_40txbw
;
6414 } else if (wlc
->cck_40txbw
!= AUTO
) {
6415 mimo_txbw
= wlc
->cck_40txbw
;
6419 * mcs32 is 40 b/w only.
6420 * This is possible for probe packets on
6423 if ((rspec
[k
] & RSPEC_RATE_MASK
) == 32)
6425 rspec
[k
] = RSPEC_MIMORATE
;
6427 mimo_txbw
= PHY_TXC1_BW_20MHZ
;
6430 /* Set channel width */
6431 rspec
[k
] &= ~RSPEC_BW_MASK
;
6432 if ((k
== 0) || ((k
> 0) && is_mcs_rate(rspec
[k
])))
6433 rspec
[k
] |= (mimo_txbw
<< RSPEC_BW_SHIFT
);
6435 rspec
[k
] |= (mimo_ctlchbw
<< RSPEC_BW_SHIFT
);
6437 /* Disable short GI, not supported yet */
6438 rspec
[k
] &= ~RSPEC_SHORT_GI
;
6440 mimo_preamble_type
= BRCMS_MM_PREAMBLE
;
6441 if (txrate
[k
]->flags
& IEEE80211_TX_RC_GREEN_FIELD
)
6442 mimo_preamble_type
= BRCMS_GF_PREAMBLE
;
6444 if ((txrate
[k
]->flags
& IEEE80211_TX_RC_MCS
)
6445 && (!is_mcs_rate(rspec
[k
]))) {
6446 brcms_err(wlc
->hw
->d11core
,
6447 "wl%d: %s: IEEE80211_TX_"
6448 "RC_MCS != is_mcs_rate(rspec)\n",
6449 wlc
->pub
->unit
, __func__
);
6452 if (is_mcs_rate(rspec
[k
])) {
6453 preamble_type
[k
] = mimo_preamble_type
;
6456 * if SGI is selected, then forced mm
6459 if ((rspec
[k
] & RSPEC_SHORT_GI
)
6460 && is_single_stream(rspec
[k
] &
6462 preamble_type
[k
] = BRCMS_MM_PREAMBLE
;
6465 /* should be better conditionalized */
6466 if (!is_mcs_rate(rspec
[0])
6467 && (tx_info
->control
.rates
[0].
6468 flags
& IEEE80211_TX_RC_USE_SHORT_PREAMBLE
))
6469 preamble_type
[k
] = BRCMS_SHORT_PREAMBLE
;
6472 for (k
= 0; k
< hw
->max_rates
; k
++) {
6473 /* Set ctrlchbw as 20Mhz */
6474 rspec
[k
] &= ~RSPEC_BW_MASK
;
6475 rspec
[k
] |= (PHY_TXC1_BW_20MHZ
<< RSPEC_BW_SHIFT
);
6477 /* for nphy, stf of ofdm frames must follow policies */
6478 if (BRCMS_ISNPHY(wlc
->band
) && is_ofdm_rate(rspec
[k
])) {
6479 rspec
[k
] &= ~RSPEC_STF_MASK
;
6480 rspec
[k
] |= phyctl1_stf
<< RSPEC_STF_SHIFT
;
6485 /* Reset these for use with AMPDU's */
6486 txrate
[0]->count
= 0;
6487 txrate
[1]->count
= 0;
6489 /* (2) PROTECTION, may change rspec */
6490 if ((ieee80211_is_data(h
->frame_control
) ||
6491 ieee80211_is_mgmt(h
->frame_control
)) &&
6492 (phylen
> wlc
->RTSThresh
) && !is_multicast_ether_addr(h
->addr1
))
6495 /* (3) PLCP: determine PLCP header and MAC duration,
6496 * fill struct d11txh */
6497 brcms_c_compute_plcp(wlc
, rspec
[0], phylen
, plcp
);
6498 brcms_c_compute_plcp(wlc
, rspec
[1], phylen
, plcp_fallback
);
6499 memcpy(&txh
->FragPLCPFallback
,
6500 plcp_fallback
, sizeof(txh
->FragPLCPFallback
));
6502 /* Length field now put in CCK FBR CRC field */
6503 if (is_cck_rate(rspec
[1])) {
6504 txh
->FragPLCPFallback
[4] = phylen
& 0xff;
6505 txh
->FragPLCPFallback
[5] = (phylen
& 0xff00) >> 8;
6508 /* MIMO-RATE: need validation ?? */
6509 mainrates
= is_ofdm_rate(rspec
[0]) ?
6510 D11A_PHY_HDR_GRATE((struct ofdm_phy_hdr
*) plcp
) :
6513 /* DUR field for main rate */
6514 if (!ieee80211_is_pspoll(h
->frame_control
) &&
6515 !is_multicast_ether_addr(h
->addr1
) && !use_rifs
) {
6517 brcms_c_compute_frame_dur(wlc
, rspec
[0], preamble_type
[0],
6519 h
->duration_id
= cpu_to_le16(durid
);
6520 } else if (use_rifs
) {
6521 /* NAV protect to end of next max packet size */
6523 (u16
) brcms_c_calc_frame_time(wlc
, rspec
[0],
6525 DOT11_MAX_FRAG_LEN
);
6526 durid
+= RIFS_11N_TIME
;
6527 h
->duration_id
= cpu_to_le16(durid
);
6530 /* DUR field for fallback rate */
6531 if (ieee80211_is_pspoll(h
->frame_control
))
6532 txh
->FragDurFallback
= h
->duration_id
;
6533 else if (is_multicast_ether_addr(h
->addr1
) || use_rifs
)
6534 txh
->FragDurFallback
= 0;
6536 durid
= brcms_c_compute_frame_dur(wlc
, rspec
[1],
6537 preamble_type
[1], next_frag_len
);
6538 txh
->FragDurFallback
= cpu_to_le16(durid
);
6541 /* (4) MAC-HDR: MacTxControlLow */
6543 mcl
|= TXC_STARTMSDU
;
6545 if (!is_multicast_ether_addr(h
->addr1
))
6546 mcl
|= TXC_IMMEDACK
;
6548 if (wlc
->band
->bandtype
== BRCM_BAND_5G
)
6549 mcl
|= TXC_FREQBAND_5G
;
6551 if (CHSPEC_IS40(wlc_phy_chanspec_get(wlc
->band
->pi
)))
6554 /* set AMIC bit if using hardware TKIP MIC */
6558 txh
->MacTxControlLow
= cpu_to_le16(mcl
);
6560 /* MacTxControlHigh */
6563 /* Set fallback rate preamble type */
6564 if ((preamble_type
[1] == BRCMS_SHORT_PREAMBLE
) ||
6565 (preamble_type
[1] == BRCMS_GF_PREAMBLE
)) {
6566 if (rspec2rate(rspec
[1]) != BRCM_RATE_1M
)
6567 mch
|= TXC_PREAMBLE_DATA_FB_SHORT
;
6570 /* MacFrameControl */
6571 memcpy(&txh
->MacFrameControl
, &h
->frame_control
, sizeof(u16
));
6572 txh
->TxFesTimeNormal
= cpu_to_le16(0);
6574 txh
->TxFesTimeFallback
= cpu_to_le16(0);
6577 memcpy(&txh
->TxFrameRA
, &h
->addr1
, ETH_ALEN
);
6580 txh
->TxFrameID
= cpu_to_le16(frameid
);
6583 * TxStatus, Note the case of recreating the first frag of a suppressed
6584 * frame then we may need to reset the retry cnt's via the status reg
6586 txh
->TxStatus
= cpu_to_le16(status
);
6589 * extra fields for ucode AMPDU aggregation, the new fields are added to
6590 * the END of previous structure so that it's compatible in driver.
6592 txh
->MaxNMpdus
= cpu_to_le16(0);
6593 txh
->MaxABytes_MRT
= cpu_to_le16(0);
6594 txh
->MaxABytes_FBR
= cpu_to_le16(0);
6595 txh
->MinMBytes
= cpu_to_le16(0);
6597 /* (5) RTS/CTS: determine RTS/CTS PLCP header and MAC duration,
6598 * furnish struct d11txh */
6599 /* RTS PLCP header and RTS frame */
6600 if (use_rts
|| use_cts
) {
6601 if (use_rts
&& use_cts
)
6604 for (k
= 0; k
< 2; k
++) {
6605 rts_rspec
[k
] = brcms_c_rspec_to_rts_rspec(wlc
, rspec
[k
],
6610 if (!is_ofdm_rate(rts_rspec
[0]) &&
6611 !((rspec2rate(rts_rspec
[0]) == BRCM_RATE_1M
) ||
6612 (wlc
->PLCPHdr_override
== BRCMS_PLCP_LONG
))) {
6613 rts_preamble_type
[0] = BRCMS_SHORT_PREAMBLE
;
6614 mch
|= TXC_PREAMBLE_RTS_MAIN_SHORT
;
6617 if (!is_ofdm_rate(rts_rspec
[1]) &&
6618 !((rspec2rate(rts_rspec
[1]) == BRCM_RATE_1M
) ||
6619 (wlc
->PLCPHdr_override
== BRCMS_PLCP_LONG
))) {
6620 rts_preamble_type
[1] = BRCMS_SHORT_PREAMBLE
;
6621 mch
|= TXC_PREAMBLE_RTS_FB_SHORT
;
6624 /* RTS/CTS additions to MacTxControlLow */
6626 txh
->MacTxControlLow
|= cpu_to_le16(TXC_SENDCTS
);
6628 txh
->MacTxControlLow
|= cpu_to_le16(TXC_SENDRTS
);
6629 txh
->MacTxControlLow
|= cpu_to_le16(TXC_LONGFRAME
);
6632 /* RTS PLCP header */
6633 rts_plcp
= txh
->RTSPhyHeader
;
6635 rts_phylen
= DOT11_CTS_LEN
+ FCS_LEN
;
6637 rts_phylen
= DOT11_RTS_LEN
+ FCS_LEN
;
6639 brcms_c_compute_plcp(wlc
, rts_rspec
[0], rts_phylen
, rts_plcp
);
6641 /* fallback rate version of RTS PLCP header */
6642 brcms_c_compute_plcp(wlc
, rts_rspec
[1], rts_phylen
,
6644 memcpy(&txh
->RTSPLCPFallback
, rts_plcp_fallback
,
6645 sizeof(txh
->RTSPLCPFallback
));
6647 /* RTS frame fields... */
6648 rts
= (struct ieee80211_rts
*)&txh
->rts_frame
;
6650 durid
= brcms_c_compute_rtscts_dur(wlc
, use_cts
, rts_rspec
[0],
6651 rspec
[0], rts_preamble_type
[0],
6652 preamble_type
[0], phylen
, false);
6653 rts
->duration
= cpu_to_le16(durid
);
6654 /* fallback rate version of RTS DUR field */
6655 durid
= brcms_c_compute_rtscts_dur(wlc
, use_cts
,
6656 rts_rspec
[1], rspec
[1],
6657 rts_preamble_type
[1],
6658 preamble_type
[1], phylen
, false);
6659 txh
->RTSDurFallback
= cpu_to_le16(durid
);
6662 rts
->frame_control
= cpu_to_le16(IEEE80211_FTYPE_CTL
|
6663 IEEE80211_STYPE_CTS
);
6665 memcpy(&rts
->ra
, &h
->addr2
, ETH_ALEN
);
6667 rts
->frame_control
= cpu_to_le16(IEEE80211_FTYPE_CTL
|
6668 IEEE80211_STYPE_RTS
);
6670 memcpy(&rts
->ra
, &h
->addr1
, 2 * ETH_ALEN
);
6674 * low 8 bits: main frag rate/mcs,
6675 * high 8 bits: rts/cts rate/mcs
6677 mainrates
|= (is_ofdm_rate(rts_rspec
[0]) ?
6679 (struct ofdm_phy_hdr
*) rts_plcp
) :
6682 memset((char *)txh
->RTSPhyHeader
, 0, D11_PHY_HDR_LEN
);
6683 memset((char *)&txh
->rts_frame
, 0,
6684 sizeof(struct ieee80211_rts
));
6685 memset((char *)txh
->RTSPLCPFallback
, 0,
6686 sizeof(txh
->RTSPLCPFallback
));
6687 txh
->RTSDurFallback
= 0;
6690 #ifdef SUPPORT_40MHZ
6691 /* add null delimiter count */
6692 if ((tx_info
->flags
& IEEE80211_TX_CTL_AMPDU
) && is_mcs_rate(rspec
))
6693 txh
->RTSPLCPFallback
[AMPDU_FBR_NULL_DELIM
] =
6694 brcm_c_ampdu_null_delim_cnt(wlc
->ampdu
, scb
, rspec
, phylen
);
6699 * Now that RTS/RTS FB preamble types are updated, write
6702 txh
->MacTxControlHigh
= cpu_to_le16(mch
);
6705 * MainRates (both the rts and frag plcp rates have
6706 * been calculated now)
6708 txh
->MainRates
= cpu_to_le16(mainrates
);
6710 /* XtraFrameTypes */
6711 xfts
= frametype(rspec
[1], wlc
->mimoft
);
6712 xfts
|= (frametype(rts_rspec
[0], wlc
->mimoft
) << XFTS_RTS_FT_SHIFT
);
6713 xfts
|= (frametype(rts_rspec
[1], wlc
->mimoft
) << XFTS_FBRRTS_FT_SHIFT
);
6714 xfts
|= CHSPEC_CHANNEL(wlc_phy_chanspec_get(wlc
->band
->pi
)) <<
6716 txh
->XtraFrameTypes
= cpu_to_le16(xfts
);
6718 /* PhyTxControlWord */
6719 phyctl
= frametype(rspec
[0], wlc
->mimoft
);
6720 if ((preamble_type
[0] == BRCMS_SHORT_PREAMBLE
) ||
6721 (preamble_type
[0] == BRCMS_GF_PREAMBLE
)) {
6722 if (rspec2rate(rspec
[0]) != BRCM_RATE_1M
)
6723 phyctl
|= PHY_TXC_SHORT_HDR
;
6726 /* phytxant is properly bit shifted */
6727 phyctl
|= brcms_c_stf_d11hdrs_phyctl_txant(wlc
, rspec
[0]);
6728 txh
->PhyTxControlWord
= cpu_to_le16(phyctl
);
6730 /* PhyTxControlWord_1 */
6731 if (BRCMS_PHY_11N_CAP(wlc
->band
)) {
6734 phyctl1
= brcms_c_phytxctl1_calc(wlc
, rspec
[0]);
6735 txh
->PhyTxControlWord_1
= cpu_to_le16(phyctl1
);
6736 phyctl1
= brcms_c_phytxctl1_calc(wlc
, rspec
[1]);
6737 txh
->PhyTxControlWord_1_Fbr
= cpu_to_le16(phyctl1
);
6739 if (use_rts
|| use_cts
) {
6740 phyctl1
= brcms_c_phytxctl1_calc(wlc
, rts_rspec
[0]);
6741 txh
->PhyTxControlWord_1_Rts
= cpu_to_le16(phyctl1
);
6742 phyctl1
= brcms_c_phytxctl1_calc(wlc
, rts_rspec
[1]);
6743 txh
->PhyTxControlWord_1_FbrRts
= cpu_to_le16(phyctl1
);
6747 * For mcs frames, if mixedmode(overloaded with long preamble)
6748 * is going to be set, fill in non-zero MModeLen and/or
6749 * MModeFbrLen it will be unnecessary if they are separated
6751 if (is_mcs_rate(rspec
[0]) &&
6752 (preamble_type
[0] == BRCMS_MM_PREAMBLE
)) {
6754 brcms_c_calc_lsig_len(wlc
, rspec
[0], phylen
);
6755 txh
->MModeLen
= cpu_to_le16(mmodelen
);
6758 if (is_mcs_rate(rspec
[1]) &&
6759 (preamble_type
[1] == BRCMS_MM_PREAMBLE
)) {
6761 brcms_c_calc_lsig_len(wlc
, rspec
[1], phylen
);
6762 txh
->MModeFbrLen
= cpu_to_le16(mmodefbrlen
);
6766 ac
= skb_get_queue_mapping(p
);
6767 if ((scb
->flags
& SCB_WMECAP
) && qos
&& wlc
->edcf_txop
[ac
]) {
6768 uint frag_dur
, dur
, dur_fallback
;
6770 /* WME: Update TXOP threshold */
6771 if (!(tx_info
->flags
& IEEE80211_TX_CTL_AMPDU
) && frag
== 0) {
6773 brcms_c_calc_frame_time(wlc
, rspec
[0],
6774 preamble_type
[0], phylen
);
6777 /* 1 RTS or CTS-to-self frame */
6779 brcms_c_calc_cts_time(wlc
, rts_rspec
[0],
6780 rts_preamble_type
[0]);
6782 brcms_c_calc_cts_time(wlc
, rts_rspec
[1],
6783 rts_preamble_type
[1]);
6784 /* (SIFS + CTS) + SIFS + frame + SIFS + ACK */
6785 dur
+= le16_to_cpu(rts
->duration
);
6787 le16_to_cpu(txh
->RTSDurFallback
);
6788 } else if (use_rifs
) {
6792 /* frame + SIFS + ACK */
6795 brcms_c_compute_frame_dur(wlc
, rspec
[0],
6796 preamble_type
[0], 0);
6799 brcms_c_calc_frame_time(wlc
, rspec
[1],
6803 brcms_c_compute_frame_dur(wlc
, rspec
[1],
6804 preamble_type
[1], 0);
6806 /* NEED to set TxFesTimeNormal (hard) */
6807 txh
->TxFesTimeNormal
= cpu_to_le16((u16
) dur
);
6809 * NEED to set fallback rate version of
6810 * TxFesTimeNormal (hard)
6812 txh
->TxFesTimeFallback
=
6813 cpu_to_le16((u16
) dur_fallback
);
6816 * update txop byte threshold (txop minus intraframe
6819 if (wlc
->edcf_txop
[ac
] >= (dur
- frag_dur
)) {
6823 brcms_c_calc_frame_len(wlc
,
6824 rspec
[0], preamble_type
[0],
6825 (wlc
->edcf_txop
[ac
] -
6827 /* range bound the fragthreshold */
6828 if (newfragthresh
< DOT11_MIN_FRAG_LEN
)
6831 else if (newfragthresh
>
6832 wlc
->usr_fragthresh
)
6834 wlc
->usr_fragthresh
;
6835 /* update the fragthresh and do txc update */
6836 if (wlc
->fragthresh
[queue
] !=
6837 (u16
) newfragthresh
)
6838 wlc
->fragthresh
[queue
] =
6839 (u16
) newfragthresh
;
6841 brcms_err(wlc
->hw
->d11core
,
6842 "wl%d: %s txop invalid "
6844 wlc
->pub
->unit
, fifo_names
[queue
],
6845 rspec2rate(rspec
[0]));
6848 if (dur
> wlc
->edcf_txop
[ac
])
6849 brcms_err(wlc
->hw
->d11core
,
6850 "wl%d: %s: %s txop "
6851 "exceeded phylen %d/%d dur %d/%d\n",
6852 wlc
->pub
->unit
, __func__
,
6854 phylen
, wlc
->fragthresh
[queue
],
6855 dur
, wlc
->edcf_txop
[ac
]);
6862 static int brcms_c_tx(struct brcms_c_info
*wlc
, struct sk_buff
*skb
)
6864 struct dma_pub
*dma
;
6865 int fifo
, ret
= -ENOSPC
;
6867 u16 frameid
= INVALIDFID
;
6869 fifo
= brcms_ac_to_fifo(skb_get_queue_mapping(skb
));
6870 dma
= wlc
->hw
->di
[fifo
];
6871 txh
= (struct d11txh
*)(skb
->data
);
6873 if (dma
->txavail
== 0) {
6875 * We sometimes get a frame from mac80211 after stopping
6876 * the queues. This only ever seems to be a single frame
6877 * and is seems likely to be a race. TX_HEADROOM should
6878 * ensure that we have enough space to handle these stray
6879 * packets, so warn if there isn't. If we're out of space
6880 * in the tx ring and the tx queue isn't stopped then
6881 * we've really got a bug; warn loudly if that happens.
6883 brcms_warn(wlc
->hw
->d11core
,
6884 "Received frame for tx with no space in DMA ring\n");
6885 WARN_ON(!ieee80211_queue_stopped(wlc
->pub
->ieee_hw
,
6886 skb_get_queue_mapping(skb
)));
6890 /* When a BC/MC frame is being committed to the BCMC fifo
6891 * via DMA (NOT PIO), update ucode or BSS info as appropriate.
6893 if (fifo
== TX_BCMC_FIFO
)
6894 frameid
= le16_to_cpu(txh
->TxFrameID
);
6896 /* Commit BCMC sequence number in the SHM frame ID location */
6897 if (frameid
!= INVALIDFID
) {
6899 * To inform the ucode of the last mcast frame posted
6900 * so that it can clear moredata bit
6902 brcms_b_write_shm(wlc
->hw
, M_BCMC_FID
, frameid
);
6905 ret
= brcms_c_txfifo(wlc
, fifo
, skb
);
6907 * The only reason for brcms_c_txfifo to fail is because
6908 * there weren't any DMA descriptors, but we've already
6909 * checked for that. So if it does fail yell loudly.
6916 bool brcms_c_sendpkt_mac80211(struct brcms_c_info
*wlc
, struct sk_buff
*sdu
,
6917 struct ieee80211_hw
*hw
)
6920 struct scb
*scb
= &wlc
->pri_scb
;
6922 fifo
= brcms_ac_to_fifo(skb_get_queue_mapping(sdu
));
6923 brcms_c_d11hdrs_mac80211(wlc
, hw
, sdu
, scb
, 0, 1, fifo
, 0);
6924 if (!brcms_c_tx(wlc
, sdu
))
6927 /* packet discarded */
6928 dev_kfree_skb_any(sdu
);
6933 brcms_c_txfifo(struct brcms_c_info
*wlc
, uint fifo
, struct sk_buff
*p
)
6935 struct dma_pub
*dma
= wlc
->hw
->di
[fifo
];
6939 ret
= dma_txfast(wlc
, dma
, p
);
6941 wiphy_err(wlc
->wiphy
, "txfifo: fatal, toss frames !!!\n");
6944 * Stop queue if DMA ring is full. Reserve some free descriptors,
6945 * as we sometimes receive a frame from mac80211 after the queues
6948 queue
= skb_get_queue_mapping(p
);
6949 if (dma
->txavail
<= TX_HEADROOM
&& fifo
< TX_BCMC_FIFO
&&
6950 !ieee80211_queue_stopped(wlc
->pub
->ieee_hw
, queue
))
6951 ieee80211_stop_queue(wlc
->pub
->ieee_hw
, queue
);
6957 brcms_c_rspec_to_rts_rspec(struct brcms_c_info
*wlc
, u32 rspec
,
6958 bool use_rspec
, u16 mimo_ctlchbw
)
6963 /* use frame rate as rts rate */
6965 else if (wlc
->band
->gmode
&& wlc
->protection
->_g
&& !is_cck_rate(rspec
))
6966 /* Use 11Mbps as the g protection RTS target rate and fallback.
6967 * Use the brcms_basic_rate() lookup to find the best basic rate
6968 * under the target in case 11 Mbps is not Basic.
6969 * 6 and 9 Mbps are not usually selected by rate selection, but
6970 * even if the OFDM rate we are protecting is 6 or 9 Mbps, 11
6973 rts_rspec
= brcms_basic_rate(wlc
, BRCM_RATE_11M
);
6975 /* calculate RTS rate and fallback rate based on the frame rate
6976 * RTS must be sent at a basic rate since it is a
6977 * control frame, sec 9.6 of 802.11 spec
6979 rts_rspec
= brcms_basic_rate(wlc
, rspec
);
6981 if (BRCMS_PHY_11N_CAP(wlc
->band
)) {
6982 /* set rts txbw to correct side band */
6983 rts_rspec
&= ~RSPEC_BW_MASK
;
6986 * if rspec/rspec_fallback is 40MHz, then send RTS on both
6987 * 20MHz channel (DUP), otherwise send RTS on control channel
6989 if (rspec_is40mhz(rspec
) && !is_cck_rate(rts_rspec
))
6990 rts_rspec
|= (PHY_TXC1_BW_40MHZ_DUP
<< RSPEC_BW_SHIFT
);
6992 rts_rspec
|= (mimo_ctlchbw
<< RSPEC_BW_SHIFT
);
6994 /* pick siso/cdd as default for ofdm */
6995 if (is_ofdm_rate(rts_rspec
)) {
6996 rts_rspec
&= ~RSPEC_STF_MASK
;
6997 rts_rspec
|= (wlc
->stf
->ss_opmode
<< RSPEC_STF_SHIFT
);
7003 /* Update beacon listen interval in shared memory */
7004 static void brcms_c_bcn_li_upd(struct brcms_c_info
*wlc
)
7006 /* wake up every DTIM is the default */
7007 if (wlc
->bcn_li_dtim
== 1)
7008 brcms_b_write_shm(wlc
->hw
, M_BCN_LI
, 0);
7010 brcms_b_write_shm(wlc
->hw
, M_BCN_LI
,
7011 (wlc
->bcn_li_dtim
<< 8) | wlc
->bcn_li_bcn
);
7015 brcms_b_read_tsf(struct brcms_hardware
*wlc_hw
, u32
*tsf_l_ptr
,
7018 struct bcma_device
*core
= wlc_hw
->d11core
;
7020 /* read the tsf timer low, then high to get an atomic read */
7021 *tsf_l_ptr
= bcma_read32(core
, D11REGOFFS(tsf_timerlow
));
7022 *tsf_h_ptr
= bcma_read32(core
, D11REGOFFS(tsf_timerhigh
));
7026 * recover 64bit TSF value from the 16bit TSF value in the rx header
7027 * given the assumption that the TSF passed in header is within 65ms
7028 * of the current tsf.
7031 * 3.......6.......8.......0.......2.......4.......6.......8......0
7032 * |<---------- tsf_h ----------->||<--- tsf_l -->||<-RxTSFTime ->|
7034 * The RxTSFTime are the lowest 16 bits and provided by the ucode. The
7035 * tsf_l is filled in by brcms_b_recv, which is done earlier in the
7036 * receive call sequence after rx interrupt. Only the higher 16 bits
7037 * are used. Finally, the tsf_h is read from the tsf register.
7039 static u64
brcms_c_recover_tsf64(struct brcms_c_info
*wlc
,
7040 struct d11rxhdr
*rxh
)
7043 u16 rx_tsf_0_15
, rx_tsf_16_31
;
7045 brcms_b_read_tsf(wlc
->hw
, &tsf_l
, &tsf_h
);
7047 rx_tsf_16_31
= (u16
)(tsf_l
>> 16);
7048 rx_tsf_0_15
= rxh
->RxTSFTime
;
7051 * a greater tsf time indicates the low 16 bits of
7052 * tsf_l wrapped, so decrement the high 16 bits.
7054 if ((u16
)tsf_l
< rx_tsf_0_15
) {
7056 if (rx_tsf_16_31
== 0xffff)
7060 return ((u64
)tsf_h
<< 32) | (((u32
)rx_tsf_16_31
<< 16) + rx_tsf_0_15
);
7064 prep_mac80211_status(struct brcms_c_info
*wlc
, struct d11rxhdr
*rxh
,
7066 struct ieee80211_rx_status
*rx_status
)
7071 unsigned char *plcp
;
7073 /* fill in TSF and flag its presence */
7074 rx_status
->mactime
= brcms_c_recover_tsf64(wlc
, rxh
);
7075 rx_status
->flag
|= RX_FLAG_MACTIME_START
;
7077 channel
= BRCMS_CHAN_CHANNEL(rxh
->RxChan
);
7080 channel
> 14 ? IEEE80211_BAND_5GHZ
: IEEE80211_BAND_2GHZ
;
7082 ieee80211_channel_to_frequency(channel
, rx_status
->band
);
7084 rx_status
->signal
= wlc_phy_rssi_compute(wlc
->hw
->band
->pi
, rxh
);
7088 rx_status
->antenna
=
7089 (rxh
->PhyRxStatus_0
& PRXS0_RXANT_UPSUBBAND
) ? 1 : 0;
7093 rspec
= brcms_c_compute_rspec(rxh
, plcp
);
7094 if (is_mcs_rate(rspec
)) {
7095 rx_status
->rate_idx
= rspec
& RSPEC_RATE_MASK
;
7096 rx_status
->flag
|= RX_FLAG_HT
;
7097 if (rspec_is40mhz(rspec
))
7098 rx_status
->flag
|= RX_FLAG_40MHZ
;
7100 switch (rspec2rate(rspec
)) {
7102 rx_status
->rate_idx
= 0;
7105 rx_status
->rate_idx
= 1;
7108 rx_status
->rate_idx
= 2;
7111 rx_status
->rate_idx
= 3;
7114 rx_status
->rate_idx
= 4;
7117 rx_status
->rate_idx
= 5;
7120 rx_status
->rate_idx
= 6;
7123 rx_status
->rate_idx
= 7;
7126 rx_status
->rate_idx
= 8;
7129 rx_status
->rate_idx
= 9;
7132 rx_status
->rate_idx
= 10;
7135 rx_status
->rate_idx
= 11;
7138 brcms_err(wlc
->hw
->d11core
,
7139 "%s: Unknown rate\n", __func__
);
7143 * For 5GHz, we should decrease the index as it is
7144 * a subset of the 2.4G rates. See bitrates field
7145 * of brcms_band_5GHz_nphy (in mac80211_if.c).
7147 if (rx_status
->band
== IEEE80211_BAND_5GHZ
)
7148 rx_status
->rate_idx
-= BRCMS_LEGACY_5G_RATE_OFFSET
;
7150 /* Determine short preamble and rate_idx */
7152 if (is_cck_rate(rspec
)) {
7153 if (rxh
->PhyRxStatus_0
& PRXS0_SHORTH
)
7154 rx_status
->flag
|= RX_FLAG_SHORTPRE
;
7155 } else if (is_ofdm_rate(rspec
)) {
7156 rx_status
->flag
|= RX_FLAG_SHORTPRE
;
7158 brcms_err(wlc
->hw
->d11core
, "%s: Unknown modulation\n",
7163 if (plcp3_issgi(plcp
[3]))
7164 rx_status
->flag
|= RX_FLAG_SHORT_GI
;
7166 if (rxh
->RxStatus1
& RXS_DECERR
) {
7167 rx_status
->flag
|= RX_FLAG_FAILED_PLCP_CRC
;
7168 brcms_err(wlc
->hw
->d11core
, "%s: RX_FLAG_FAILED_PLCP_CRC\n",
7171 if (rxh
->RxStatus1
& RXS_FCSERR
) {
7172 rx_status
->flag
|= RX_FLAG_FAILED_FCS_CRC
;
7173 brcms_err(wlc
->hw
->d11core
, "%s: RX_FLAG_FAILED_FCS_CRC\n",
7179 brcms_c_recvctl(struct brcms_c_info
*wlc
, struct d11rxhdr
*rxh
,
7183 struct ieee80211_rx_status rx_status
;
7184 struct ieee80211_hdr
*hdr
;
7186 memset(&rx_status
, 0, sizeof(rx_status
));
7187 prep_mac80211_status(wlc
, rxh
, p
, &rx_status
);
7189 /* mac header+body length, exclude CRC and plcp header */
7190 len_mpdu
= p
->len
- D11_PHY_HDR_LEN
- FCS_LEN
;
7191 skb_pull(p
, D11_PHY_HDR_LEN
);
7192 __skb_trim(p
, len_mpdu
);
7194 /* unmute transmit */
7195 if (wlc
->hw
->suspended_fifos
) {
7196 hdr
= (struct ieee80211_hdr
*)p
->data
;
7197 if (ieee80211_is_beacon(hdr
->frame_control
))
7198 brcms_b_mute(wlc
->hw
, false);
7201 memcpy(IEEE80211_SKB_RXCB(p
), &rx_status
, sizeof(rx_status
));
7202 ieee80211_rx_irqsafe(wlc
->pub
->ieee_hw
, p
);
7205 /* calculate frame duration for Mixed-mode L-SIG spoofing, return
7206 * number of bytes goes in the length field
7208 * Formula given by HT PHY Spec v 1.13
7209 * len = 3(nsyms + nstream + 3) - 3
7212 brcms_c_calc_lsig_len(struct brcms_c_info
*wlc
, u32 ratespec
,
7215 uint nsyms
, len
= 0, kNdps
;
7217 if (is_mcs_rate(ratespec
)) {
7218 uint mcs
= ratespec
& RSPEC_RATE_MASK
;
7219 int tot_streams
= (mcs_2_txstreams(mcs
) + 1) +
7220 rspec_stc(ratespec
);
7223 * the payload duration calculation matches that
7226 /* 1000Ndbps = kbps * 4 */
7227 kNdps
= mcs_2_rate(mcs
, rspec_is40mhz(ratespec
),
7228 rspec_issgi(ratespec
)) * 4;
7230 if (rspec_stc(ratespec
) == 0)
7232 CEIL((APHY_SERVICE_NBITS
+ 8 * mac_len
+
7233 APHY_TAIL_NBITS
) * 1000, kNdps
);
7235 /* STBC needs to have even number of symbols */
7238 CEIL((APHY_SERVICE_NBITS
+ 8 * mac_len
+
7239 APHY_TAIL_NBITS
) * 1000, 2 * kNdps
);
7241 /* (+3) account for HT-SIG(2) and HT-STF(1) */
7242 nsyms
+= (tot_streams
+ 3);
7244 * 3 bytes/symbol @ legacy 6Mbps rate
7245 * (-3) excluding service bits and tail bits
7247 len
= (3 * nsyms
) - 3;
7254 brcms_c_mod_prb_rsp_rate_table(struct brcms_c_info
*wlc
, uint frame_len
)
7256 const struct brcms_c_rateset
*rs_dflt
;
7257 struct brcms_c_rateset rs
;
7260 u8 plcp
[D11_PHY_HDR_LEN
];
7264 sifs
= get_sifs(wlc
->band
);
7266 rs_dflt
= brcms_c_rateset_get_hwrs(wlc
);
7268 brcms_c_rateset_copy(rs_dflt
, &rs
);
7269 brcms_c_rateset_mcs_upd(&rs
, wlc
->stf
->txstreams
);
7272 * walk the phy rate table and update MAC core SHM
7273 * basic rate table entries
7275 for (i
= 0; i
< rs
.count
; i
++) {
7276 rate
= rs
.rates
[i
] & BRCMS_RATE_MASK
;
7278 entry_ptr
= brcms_b_rate_shm_offset(wlc
->hw
, rate
);
7280 /* Calculate the Probe Response PLCP for the given rate */
7281 brcms_c_compute_plcp(wlc
, rate
, frame_len
, plcp
);
7284 * Calculate the duration of the Probe Response
7285 * frame plus SIFS for the MAC
7287 dur
= (u16
) brcms_c_calc_frame_time(wlc
, rate
,
7288 BRCMS_LONG_PREAMBLE
, frame_len
);
7291 /* Update the SHM Rate Table entry Probe Response values */
7292 brcms_b_write_shm(wlc
->hw
, entry_ptr
+ M_RT_PRS_PLCP_POS
,
7293 (u16
) (plcp
[0] + (plcp
[1] << 8)));
7294 brcms_b_write_shm(wlc
->hw
, entry_ptr
+ M_RT_PRS_PLCP_POS
+ 2,
7295 (u16
) (plcp
[2] + (plcp
[3] << 8)));
7296 brcms_b_write_shm(wlc
->hw
, entry_ptr
+ M_RT_PRS_DUR_POS
, dur
);
7300 /* Max buffering needed for beacon template/prb resp template is 142 bytes.
7302 * PLCP header is 6 bytes.
7303 * 802.11 A3 header is 24 bytes.
7304 * Max beacon frame body template length is 112 bytes.
7305 * Max probe resp frame body template length is 110 bytes.
7307 * *len on input contains the max length of the packet available.
7309 * The *len value is set to the number of bytes in buf used, and starts
7310 * with the PLCP and included up to, but not including, the 4 byte FCS.
7313 brcms_c_bcn_prb_template(struct brcms_c_info
*wlc
, u16 type
,
7315 struct brcms_bss_cfg
*cfg
, u16
*buf
, int *len
)
7317 static const u8 ether_bcast
[ETH_ALEN
] = {255, 255, 255, 255, 255, 255};
7318 struct cck_phy_hdr
*plcp
;
7319 struct ieee80211_mgmt
*h
;
7320 int hdr_len
, body_len
;
7322 hdr_len
= D11_PHY_HDR_LEN
+ DOT11_MAC_HDR_LEN
;
7324 /* calc buffer size provided for frame body */
7325 body_len
= *len
- hdr_len
;
7326 /* return actual size */
7327 *len
= hdr_len
+ body_len
;
7329 /* format PHY and MAC headers */
7330 memset((char *)buf
, 0, hdr_len
);
7332 plcp
= (struct cck_phy_hdr
*) buf
;
7335 * PLCP for Probe Response frames are filled in from
7338 if (type
== IEEE80211_STYPE_BEACON
)
7340 brcms_c_compute_plcp(wlc
, bcn_rspec
,
7341 (DOT11_MAC_HDR_LEN
+ body_len
+ FCS_LEN
),
7344 /* "Regular" and 16 MBSS but not for 4 MBSS */
7345 /* Update the phytxctl for the beacon based on the rspec */
7346 brcms_c_beacon_phytxctl_txant_upd(wlc
, bcn_rspec
);
7348 h
= (struct ieee80211_mgmt
*)&plcp
[1];
7350 /* fill in 802.11 header */
7351 h
->frame_control
= cpu_to_le16(IEEE80211_FTYPE_MGMT
| type
);
7353 /* DUR is 0 for multicast bcn, or filled in by MAC for prb resp */
7354 /* A1 filled in by MAC for prb resp, broadcast for bcn */
7355 if (type
== IEEE80211_STYPE_BEACON
)
7356 memcpy(&h
->da
, ðer_bcast
, ETH_ALEN
);
7357 memcpy(&h
->sa
, &cfg
->cur_etheraddr
, ETH_ALEN
);
7358 memcpy(&h
->bssid
, &cfg
->BSSID
, ETH_ALEN
);
7360 /* SEQ filled in by MAC */
7363 int brcms_c_get_header_len(void)
7369 * Update all beacons for the system.
7371 void brcms_c_update_beacon(struct brcms_c_info
*wlc
)
7373 struct brcms_bss_cfg
*bsscfg
= wlc
->bsscfg
;
7375 if (bsscfg
->up
&& !bsscfg
->BSS
)
7376 /* Clear the soft intmask */
7377 wlc
->defmacintmask
&= ~MI_BCNTPL
;
7380 /* Write ssid into shared memory */
7382 brcms_c_shm_ssid_upd(struct brcms_c_info
*wlc
, struct brcms_bss_cfg
*cfg
)
7384 u8
*ssidptr
= cfg
->SSID
;
7386 u8 ssidbuf
[IEEE80211_MAX_SSID_LEN
];
7388 /* padding the ssid with zero and copy it into shm */
7389 memset(ssidbuf
, 0, IEEE80211_MAX_SSID_LEN
);
7390 memcpy(ssidbuf
, ssidptr
, cfg
->SSID_len
);
7392 brcms_c_copyto_shm(wlc
, base
, ssidbuf
, IEEE80211_MAX_SSID_LEN
);
7393 brcms_b_write_shm(wlc
->hw
, M_SSIDLEN
, (u16
) cfg
->SSID_len
);
7397 brcms_c_bss_update_probe_resp(struct brcms_c_info
*wlc
,
7398 struct brcms_bss_cfg
*cfg
,
7402 int len
= BCN_TMPL_LEN
;
7404 prb_resp
= kmalloc(BCN_TMPL_LEN
, GFP_ATOMIC
);
7409 * write the probe response to hardware, or save in
7410 * the config structure
7413 /* create the probe response template */
7414 brcms_c_bcn_prb_template(wlc
, IEEE80211_STYPE_PROBE_RESP
, 0,
7415 cfg
, prb_resp
, &len
);
7418 brcms_c_suspend_mac_and_wait(wlc
);
7420 /* write the probe response into the template region */
7421 brcms_b_write_template_ram(wlc
->hw
, T_PRS_TPL_BASE
,
7422 (len
+ 3) & ~3, prb_resp
);
7424 /* write the length of the probe response frame (+PLCP/-FCS) */
7425 brcms_b_write_shm(wlc
->hw
, M_PRB_RESP_FRM_LEN
, (u16
) len
);
7427 /* write the SSID and SSID length */
7428 brcms_c_shm_ssid_upd(wlc
, cfg
);
7431 * Write PLCP headers and durations for probe response frames
7432 * at all rates. Use the actual frame length covered by the
7433 * PLCP header for the call to brcms_c_mod_prb_rsp_rate_table()
7434 * by subtracting the PLCP len and adding the FCS.
7436 len
+= (-D11_PHY_HDR_LEN
+ FCS_LEN
);
7437 brcms_c_mod_prb_rsp_rate_table(wlc
, (u16
) len
);
7440 brcms_c_enable_mac(wlc
);
7445 void brcms_c_update_probe_resp(struct brcms_c_info
*wlc
, bool suspend
)
7447 struct brcms_bss_cfg
*bsscfg
= wlc
->bsscfg
;
7449 /* update AP or IBSS probe responses */
7450 if (bsscfg
->up
&& !bsscfg
->BSS
)
7451 brcms_c_bss_update_probe_resp(wlc
, bsscfg
, suspend
);
7454 int brcms_b_xmtfifo_sz_get(struct brcms_hardware
*wlc_hw
, uint fifo
,
7460 *blocks
= wlc_hw
->xmtfifo_sz
[fifo
];
7466 brcms_c_set_addrmatch(struct brcms_c_info
*wlc
, int match_reg_offset
,
7469 brcms_b_set_addrmatch(wlc
->hw
, match_reg_offset
, addr
);
7470 if (match_reg_offset
== RCM_BSSID_OFFSET
)
7471 memcpy(wlc
->bsscfg
->BSSID
, addr
, ETH_ALEN
);
7475 * Flag 'scan in progress' to withhold dynamic phy calibration
7477 void brcms_c_scan_start(struct brcms_c_info
*wlc
)
7479 wlc_phy_hold_upd(wlc
->band
->pi
, PHY_HOLD_FOR_SCAN
, true);
7482 void brcms_c_scan_stop(struct brcms_c_info
*wlc
)
7484 wlc_phy_hold_upd(wlc
->band
->pi
, PHY_HOLD_FOR_SCAN
, false);
7487 void brcms_c_associate_upd(struct brcms_c_info
*wlc
, bool state
)
7489 wlc
->pub
->associated
= state
;
7490 wlc
->bsscfg
->associated
= state
;
7494 * When a remote STA/AP is removed by Mac80211, or when it can no longer accept
7495 * AMPDU traffic, packets pending in hardware have to be invalidated so that
7496 * when later on hardware releases them, they can be handled appropriately.
7498 void brcms_c_inval_dma_pkts(struct brcms_hardware
*hw
,
7499 struct ieee80211_sta
*sta
,
7500 void (*dma_callback_fn
))
7502 struct dma_pub
*dmah
;
7504 for (i
= 0; i
< NFIFO
; i
++) {
7507 dma_walk_packets(dmah
, dma_callback_fn
, sta
);
7511 int brcms_c_get_curband(struct brcms_c_info
*wlc
)
7513 return wlc
->band
->bandunit
;
7516 bool brcms_c_tx_flush_completed(struct brcms_c_info
*wlc
)
7520 /* Kick DMA to send any pending AMPDU */
7521 for (i
= 0; i
< ARRAY_SIZE(wlc
->hw
->di
); i
++)
7523 dma_kick_tx(wlc
->hw
->di
[i
]);
7525 return !brcms_txpktpendtot(wlc
);
7528 void brcms_c_set_beacon_listen_interval(struct brcms_c_info
*wlc
, u8 interval
)
7530 wlc
->bcn_li_bcn
= interval
;
7532 brcms_c_bcn_li_upd(wlc
);
7535 int brcms_c_set_tx_power(struct brcms_c_info
*wlc
, int txpwr
)
7539 /* Remove override bit and clip to max qdbm value */
7540 qdbm
= min_t(uint
, txpwr
* BRCMS_TXPWR_DB_FACTOR
, 0xff);
7541 return wlc_phy_txpower_set(wlc
->band
->pi
, qdbm
, false);
7544 int brcms_c_get_tx_power(struct brcms_c_info
*wlc
)
7549 wlc_phy_txpower_get(wlc
->band
->pi
, &qdbm
, &override
);
7551 /* Return qdbm units */
7552 return (int)(qdbm
/ BRCMS_TXPWR_DB_FACTOR
);
7555 /* Process received frames */
7557 * Return true if more frames need to be processed. false otherwise.
7558 * Param 'bound' indicates max. # frames to process before break out.
7560 static void brcms_c_recv(struct brcms_c_info
*wlc
, struct sk_buff
*p
)
7562 struct d11rxhdr
*rxh
;
7563 struct ieee80211_hdr
*h
;
7567 /* frame starts with rxhdr */
7568 rxh
= (struct d11rxhdr
*) (p
->data
);
7570 /* strip off rxhdr */
7571 skb_pull(p
, BRCMS_HWRXOFF
);
7573 /* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */
7574 if (rxh
->RxStatus1
& RXS_PBPRES
) {
7576 brcms_err(wlc
->hw
->d11core
,
7577 "wl%d: recv: rcvd runt of len %d\n",
7578 wlc
->pub
->unit
, p
->len
);
7584 h
= (struct ieee80211_hdr
*)(p
->data
+ D11_PHY_HDR_LEN
);
7587 if (rxh
->RxStatus1
& RXS_FCSERR
) {
7588 if (!(wlc
->filter_flags
& FIF_FCSFAIL
))
7592 /* check received pkt has at least frame control field */
7593 if (len
< D11_PHY_HDR_LEN
+ sizeof(h
->frame_control
))
7596 /* not supporting A-MSDU */
7597 is_amsdu
= rxh
->RxStatus2
& RXS_AMSDU_MASK
;
7601 brcms_c_recvctl(wlc
, rxh
, p
);
7605 brcmu_pkt_buf_free_skb(p
);
7608 /* Process received frames */
7610 * Return true if more frames need to be processed. false otherwise.
7611 * Param 'bound' indicates max. # frames to process before break out.
7614 brcms_b_recv(struct brcms_hardware
*wlc_hw
, uint fifo
, bool bound
)
7617 struct sk_buff
*next
= NULL
;
7618 struct sk_buff_head recv_frames
;
7621 uint bound_limit
= bound
? RXBND
: -1;
7622 bool morepending
= false;
7624 skb_queue_head_init(&recv_frames
);
7626 /* gather received frames */
7628 /* !give others some time to run! */
7629 if (n
>= bound_limit
)
7632 morepending
= dma_rx(wlc_hw
->di
[fifo
], &recv_frames
);
7634 } while (morepending
);
7636 /* post more rbufs */
7637 dma_rxfill(wlc_hw
->di
[fifo
]);
7639 /* process each frame */
7640 skb_queue_walk_safe(&recv_frames
, p
, next
) {
7641 struct d11rxhdr_le
*rxh_le
;
7642 struct d11rxhdr
*rxh
;
7644 skb_unlink(p
, &recv_frames
);
7645 rxh_le
= (struct d11rxhdr_le
*)p
->data
;
7646 rxh
= (struct d11rxhdr
*)p
->data
;
7648 /* fixup rx header endianness */
7649 rxh
->RxFrameSize
= le16_to_cpu(rxh_le
->RxFrameSize
);
7650 rxh
->PhyRxStatus_0
= le16_to_cpu(rxh_le
->PhyRxStatus_0
);
7651 rxh
->PhyRxStatus_1
= le16_to_cpu(rxh_le
->PhyRxStatus_1
);
7652 rxh
->PhyRxStatus_2
= le16_to_cpu(rxh_le
->PhyRxStatus_2
);
7653 rxh
->PhyRxStatus_3
= le16_to_cpu(rxh_le
->PhyRxStatus_3
);
7654 rxh
->PhyRxStatus_4
= le16_to_cpu(rxh_le
->PhyRxStatus_4
);
7655 rxh
->PhyRxStatus_5
= le16_to_cpu(rxh_le
->PhyRxStatus_5
);
7656 rxh
->RxStatus1
= le16_to_cpu(rxh_le
->RxStatus1
);
7657 rxh
->RxStatus2
= le16_to_cpu(rxh_le
->RxStatus2
);
7658 rxh
->RxTSFTime
= le16_to_cpu(rxh_le
->RxTSFTime
);
7659 rxh
->RxChan
= le16_to_cpu(rxh_le
->RxChan
);
7661 brcms_c_recv(wlc_hw
->wlc
, p
);
7667 /* second-level interrupt processing
7668 * Return true if another dpc needs to be re-scheduled. false otherwise.
7669 * Param 'bounded' indicates if applicable loops should be bounded.
7671 bool brcms_c_dpc(struct brcms_c_info
*wlc
, bool bounded
)
7674 struct brcms_hardware
*wlc_hw
= wlc
->hw
;
7675 struct bcma_device
*core
= wlc_hw
->d11core
;
7677 if (brcms_deviceremoved(wlc
)) {
7678 brcms_err(core
, "wl%d: %s: dead chip\n", wlc_hw
->unit
,
7680 brcms_down(wlc
->wl
);
7684 /* grab and clear the saved software intstatus bits */
7685 macintstatus
= wlc
->macintstatus
;
7686 wlc
->macintstatus
= 0;
7688 brcms_dbg_int(core
, "wl%d: macintstatus 0x%x\n",
7689 wlc_hw
->unit
, macintstatus
);
7691 WARN_ON(macintstatus
& MI_PRQ
); /* PRQ Interrupt in non-MBSS */
7694 if (macintstatus
& MI_TFS
) {
7696 if (brcms_b_txstatus(wlc
->hw
, bounded
, &fatal
))
7697 wlc
->macintstatus
|= MI_TFS
;
7699 brcms_err(core
, "MI_TFS: fatal\n");
7704 if (macintstatus
& (MI_TBTT
| MI_DTIM_TBTT
))
7707 /* ATIM window end */
7708 if (macintstatus
& MI_ATIMWINEND
) {
7709 brcms_dbg_info(core
, "end of ATIM window\n");
7710 bcma_set32(core
, D11REGOFFS(maccommand
), wlc
->qvalid
);
7715 * received data or control frame, MI_DMAINT is
7716 * indication of RX_FIFO interrupt
7718 if (macintstatus
& MI_DMAINT
)
7719 if (brcms_b_recv(wlc_hw
, RX_FIFO
, bounded
))
7720 wlc
->macintstatus
|= MI_DMAINT
;
7722 /* noise sample collected */
7723 if (macintstatus
& MI_BG_NOISE
)
7724 wlc_phy_noise_sample_intr(wlc_hw
->band
->pi
);
7726 if (macintstatus
& MI_GP0
) {
7727 brcms_err(core
, "wl%d: PSM microcode watchdog fired at %d "
7728 "(seconds). Resetting.\n", wlc_hw
->unit
, wlc_hw
->now
);
7730 printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n",
7731 __func__
, ai_get_chip_id(wlc_hw
->sih
),
7732 ai_get_chiprev(wlc_hw
->sih
));
7733 brcms_fatal_error(wlc_hw
->wlc
->wl
);
7736 /* gptimer timeout */
7737 if (macintstatus
& MI_TO
)
7738 bcma_write32(core
, D11REGOFFS(gptimer
), 0);
7740 if (macintstatus
& MI_RFDISABLE
) {
7741 brcms_dbg_info(core
, "wl%d: BMAC Detected a change on the"
7742 " RF Disable Input\n", wlc_hw
->unit
);
7743 brcms_rfkill_set_hw_state(wlc
->wl
);
7746 /* it isn't done and needs to be resched if macintstatus is non-zero */
7747 return wlc
->macintstatus
!= 0;
7750 brcms_fatal_error(wlc_hw
->wlc
->wl
);
7751 return wlc
->macintstatus
!= 0;
7754 void brcms_c_init(struct brcms_c_info
*wlc
, bool mute_tx
)
7756 struct bcma_device
*core
= wlc
->hw
->d11core
;
7757 struct ieee80211_channel
*ch
= wlc
->pub
->ieee_hw
->conf
.channel
;
7760 brcms_dbg_info(core
, "wl%d\n", wlc
->pub
->unit
);
7762 chanspec
= ch20mhz_chspec(ch
->hw_value
);
7764 brcms_b_init(wlc
->hw
, chanspec
);
7766 /* update beacon listen interval */
7767 brcms_c_bcn_li_upd(wlc
);
7769 /* write ethernet address to core */
7770 brcms_c_set_mac(wlc
->bsscfg
);
7771 brcms_c_set_bssid(wlc
->bsscfg
);
7773 /* Update tsf_cfprep if associated and up */
7774 if (wlc
->pub
->associated
&& wlc
->bsscfg
->up
) {
7777 /* get beacon period and convert to uS */
7778 bi
= wlc
->bsscfg
->current_bss
->beacon_period
<< 10;
7780 * update since init path would reset
7783 bcma_write32(core
, D11REGOFFS(tsf_cfprep
),
7784 bi
<< CFPREP_CBI_SHIFT
);
7786 /* Update maccontrol PM related bits */
7787 brcms_c_set_ps_ctrl(wlc
);
7790 brcms_c_bandinit_ordered(wlc
, chanspec
);
7792 /* init probe response timeout */
7793 brcms_b_write_shm(wlc
->hw
, M_PRS_MAXTIME
, wlc
->prb_resp_timeout
);
7795 /* init max burst txop (framebursting) */
7796 brcms_b_write_shm(wlc
->hw
, M_MBURST_TXOP
,
7798 _rifs
? (EDCF_AC_VO_TXOP_AP
<< 5) : MAXFRAMEBURST_TXOP
));
7800 /* initialize maximum allowed duty cycle */
7801 brcms_c_duty_cycle_set(wlc
, wlc
->tx_duty_cycle_ofdm
, true, true);
7802 brcms_c_duty_cycle_set(wlc
, wlc
->tx_duty_cycle_cck
, false, true);
7805 * Update some shared memory locations related to
7806 * max AMPDU size allowed to received
7808 brcms_c_ampdu_shm_upd(wlc
->ampdu
);
7810 /* band-specific inits */
7811 brcms_c_bsinit(wlc
);
7813 /* Enable EDCF mode (while the MAC is suspended) */
7814 bcma_set16(core
, D11REGOFFS(ifs_ctl
), IFS_USEEDCF
);
7815 brcms_c_edcf_setparams(wlc
, false);
7817 /* read the ucode version if we have not yet done so */
7818 if (wlc
->ucode_rev
== 0) {
7820 brcms_b_read_shm(wlc
->hw
, M_BOM_REV_MAJOR
) << NBITS(u16
);
7821 wlc
->ucode_rev
|= brcms_b_read_shm(wlc
->hw
, M_BOM_REV_MINOR
);
7824 /* ..now really unleash hell (allow the MAC out of suspend) */
7825 brcms_c_enable_mac(wlc
);
7827 /* suspend the tx fifos and mute the phy for preism cac time */
7829 brcms_b_mute(wlc
->hw
, true);
7831 /* enable the RF Disable Delay timer */
7832 bcma_write32(core
, D11REGOFFS(rfdisabledly
), RFDISABLE_DEFAULT
);
7835 * Initialize WME parameters; if they haven't been set by some other
7836 * mechanism (IOVar, etc) then read them from the hardware.
7838 if (GFIELD(wlc
->wme_retries
[0], EDCF_SHORT
) == 0) {
7839 /* Uninitialized; read from HW */
7842 for (ac
= 0; ac
< IEEE80211_NUM_ACS
; ac
++)
7843 wlc
->wme_retries
[ac
] =
7844 brcms_b_read_shm(wlc
->hw
, M_AC_TXLMT_ADDR(ac
));
7849 * The common driver entry routine. Error codes should be unique
7851 struct brcms_c_info
*
7852 brcms_c_attach(struct brcms_info
*wl
, struct bcma_device
*core
, uint unit
,
7853 bool piomode
, uint
*perr
)
7855 struct brcms_c_info
*wlc
;
7858 struct brcms_pub
*pub
;
7860 /* allocate struct brcms_c_info state and its substructures */
7861 wlc
= brcms_c_attach_malloc(unit
, &err
, 0);
7864 wlc
->wiphy
= wl
->wiphy
;
7871 wlc
->band
= wlc
->bandstate
[0];
7872 wlc
->core
= wlc
->corestate
;
7875 pub
->_piomode
= piomode
;
7876 wlc
->bandinit_pending
= false;
7878 /* populate struct brcms_c_info with default values */
7879 brcms_c_info_init(wlc
, unit
);
7881 /* update sta/ap related parameters */
7882 brcms_c_ap_upd(wlc
);
7885 * low level attach steps(all hw accesses go
7886 * inside, no more in rest of the attach)
7888 err
= brcms_b_attach(wlc
, core
, unit
, piomode
);
7892 brcms_c_protection_upd(wlc
, BRCMS_PROT_N_PAM_OVR
, OFF
);
7894 pub
->phy_11ncapable
= BRCMS_PHY_11N_CAP(wlc
->band
);
7896 /* disable allowed duty cycle */
7897 wlc
->tx_duty_cycle_ofdm
= 0;
7898 wlc
->tx_duty_cycle_cck
= 0;
7900 brcms_c_stf_phy_chain_calc(wlc
);
7902 /* txchain 1: txant 0, txchain 2: txant 1 */
7903 if (BRCMS_ISNPHY(wlc
->band
) && (wlc
->stf
->txstreams
== 1))
7904 wlc
->stf
->txant
= wlc
->stf
->hw_txchain
- 1;
7906 /* push to BMAC driver */
7907 wlc_phy_stf_chain_init(wlc
->band
->pi
, wlc
->stf
->hw_txchain
,
7908 wlc
->stf
->hw_rxchain
);
7910 /* pull up some info resulting from the low attach */
7911 for (i
= 0; i
< NFIFO
; i
++)
7912 wlc
->core
->txavail
[i
] = wlc
->hw
->txavail
[i
];
7914 memcpy(&wlc
->perm_etheraddr
, &wlc
->hw
->etheraddr
, ETH_ALEN
);
7915 memcpy(&pub
->cur_etheraddr
, &wlc
->hw
->etheraddr
, ETH_ALEN
);
7917 for (j
= 0; j
< wlc
->pub
->_nbands
; j
++) {
7918 wlc
->band
= wlc
->bandstate
[j
];
7920 if (!brcms_c_attach_stf_ant_init(wlc
)) {
7925 /* default contention windows size limits */
7926 wlc
->band
->CWmin
= APHY_CWMIN
;
7927 wlc
->band
->CWmax
= PHY_CWMAX
;
7929 /* init gmode value */
7930 if (wlc
->band
->bandtype
== BRCM_BAND_2G
) {
7931 wlc
->band
->gmode
= GMODE_AUTO
;
7932 brcms_c_protection_upd(wlc
, BRCMS_PROT_G_USER
,
7936 /* init _n_enab supported mode */
7937 if (BRCMS_PHY_11N_CAP(wlc
->band
)) {
7938 pub
->_n_enab
= SUPPORT_11N
;
7939 brcms_c_protection_upd(wlc
, BRCMS_PROT_N_USER
,
7941 SUPPORT_11N
) ? WL_11N_2x2
:
7945 /* init per-band default rateset, depend on band->gmode */
7946 brcms_default_rateset(wlc
, &wlc
->band
->defrateset
);
7948 /* fill in hw_rateset */
7949 brcms_c_rateset_filter(&wlc
->band
->defrateset
,
7950 &wlc
->band
->hw_rateset
, false,
7951 BRCMS_RATES_CCK_OFDM
, BRCMS_RATE_MASK
,
7952 (bool) (wlc
->pub
->_n_enab
& SUPPORT_11N
));
7956 * update antenna config due to
7957 * wlc->stf->txant/txchain/ant_rx_ovr change
7959 brcms_c_stf_phy_txant_upd(wlc
);
7961 /* attach each modules */
7962 err
= brcms_c_attach_module(wlc
);
7966 if (!brcms_c_timers_init(wlc
, unit
)) {
7967 wiphy_err(wl
->wiphy
, "wl%d: %s: init_timer failed\n", unit
,
7973 /* depend on rateset, gmode */
7974 wlc
->cmi
= brcms_c_channel_mgr_attach(wlc
);
7976 wiphy_err(wl
->wiphy
, "wl%d: %s: channel_mgr_attach failed"
7977 "\n", unit
, __func__
);
7982 /* init default when all parameters are ready, i.e. ->rateset */
7983 brcms_c_bss_default_init(wlc
);
7986 * Complete the wlc default state initializations..
7989 wlc
->bsscfg
->wlc
= wlc
;
7991 wlc
->mimoft
= FT_HT
;
7992 wlc
->mimo_40txbw
= AUTO
;
7993 wlc
->ofdm_40txbw
= AUTO
;
7994 wlc
->cck_40txbw
= AUTO
;
7995 brcms_c_update_mimo_band_bwcap(wlc
, BRCMS_N_BW_20IN2G_40IN5G
);
7997 /* Set default values of SGI */
7998 if (BRCMS_SGI_CAP_PHY(wlc
)) {
7999 brcms_c_ht_update_sgi_rx(wlc
, (BRCMS_N_SGI_20
|
8001 } else if (BRCMS_ISSSLPNPHY(wlc
->band
)) {
8002 brcms_c_ht_update_sgi_rx(wlc
, (BRCMS_N_SGI_20
|
8005 brcms_c_ht_update_sgi_rx(wlc
, 0);
8008 brcms_b_antsel_set(wlc
->hw
, wlc
->asi
->antsel_avail
);
8016 wiphy_err(wl
->wiphy
, "wl%d: %s: failed with err %d\n",
8017 unit
, __func__
, err
);
8019 brcms_c_detach(wlc
);