cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

main.c (217303B)


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