/*
 * Copyright (c) 2010 Broadcom Corporation
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */
#include <linux/kernel.h>
#include <linux/ctype.h>
#include <linux/etherdevice.h>
#include <net/mac80211.h>

#include <bcmdefs.h>
#include <bcmdevs.h>
#include <bcmutils.h>
#include <bcmwifi.h>
#include <siutils.h>
#include <pcicfg.h>
#include <bcmsrom.h>
#include <wlioctl.h>
#include <sbhnddma.h>
#include <hnddma.h>
#include <hndpmu.h>

#include "d11.h"
#include "wlc_types.h"
#include "wlc_cfg.h"
#include "wlc_rate.h"
#include "wlc_scb.h"
#include "wlc_pub.h"
#include "wlc_key.h"
#include "wlc_bsscfg.h"
#include "phy/wlc_phy_hal.h"
#include "wlc_channel.h"
#include "wlc_main.h"
#include "wlc_bmac.h"
#include "wlc_phy_hal.h"
#include "wlc_phy_shim.h"
#include "wlc_antsel.h"
#include "wlc_stf.h"
#include "wlc_ampdu.h"
#include "wl_export.h"
#include "wlc_alloc.h"
#include "wl_dbg.h"

/*
 *	Disable statistics counting for WME
 */
#define WLCNTSET(a, b)
#define WLCNTINCR(a)
#define WLCNTADD(a, b)

/*
 * WPA(2) definitions
 */
#define RSN_CAP_4_REPLAY_CNTRS		2
#define RSN_CAP_16_REPLAY_CNTRS		3

#define WPA_CAP_4_REPLAY_CNTRS		RSN_CAP_4_REPLAY_CNTRS
#define WPA_CAP_16_REPLAY_CNTRS		RSN_CAP_16_REPLAY_CNTRS

/*
 * Indication for txflowcontrol that all priority bits in
 * TXQ_STOP_FOR_PRIOFC_MASK are to be considered.
 */
#define ALLPRIO		-1

/*
 * buffer length needed for wlc_format_ssid
 * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL.
 */
#define SSID_FMT_BUF_LEN	((4 * IEEE80211_MAX_SSID_LEN) + 1)

#define	TIMER_INTERVAL_WATCHDOG	1000	/* watchdog timer, in unit of ms */
#define	TIMER_INTERVAL_RADIOCHK	800	/* radio monitor timer, in unit of ms */

#ifndef WLC_MPC_MAX_DELAYCNT
#define	WLC_MPC_MAX_DELAYCNT	10	/* Max MPC timeout, in unit of watchdog */
#endif
#define	WLC_MPC_MIN_DELAYCNT	1	/* Min MPC timeout, in unit of watchdog */
#define	WLC_MPC_THRESHOLD	3	/* MPC count threshold level */

#define	BEACON_INTERVAL_DEFAULT	100	/* beacon interval, in unit of 1024TU */
#define	DTIM_INTERVAL_DEFAULT	3	/* DTIM interval, in unit of beacon interval */

/* Scale down delays to accommodate QT slow speed */
#define	BEACON_INTERVAL_DEF_QT	20	/* beacon interval, in unit of 1024TU */
#define	DTIM_INTERVAL_DEF_QT	1	/* DTIM interval, in unit of beacon interval */

#define	TBTT_ALIGN_LEEWAY_US	100	/* min leeway before first TBTT in us */

/*
 * driver maintains internal 'tick'(wlc->pub->now) which increments in 1s OS timer(soft
 * watchdog) it is not a wall clock and won't increment when driver is in "down" state
 * this low resolution driver tick can be used for maintenance tasks such as phy
 * calibration and scb update
 */

/* watchdog trigger mode: OSL timer or TBTT */
#define WLC_WATCHDOG_TBTT(wlc) \
	(wlc->stas_associated > 0 && wlc->PM != PM_OFF && wlc->pub->align_wd_tbtt)

/* To inform the ucode of the last mcast frame posted so that it can clear moredata bit */
#define BCMCFID(wlc, fid) wlc_bmac_write_shm((wlc)->hw, M_BCMC_FID, (fid))

#define WLC_WAR16165(wlc) (wlc->pub->sih->bustype == PCI_BUS && \
				(!AP_ENAB(wlc->pub)) && (wlc->war16165))

/* debug/trace */
uint wl_msg_level =
#if defined(BCMDBG)
    WL_ERROR_VAL;
#else
    0;
#endif				/* BCMDBG */

/* Find basic rate for a given rate */
#define WLC_BASIC_RATE(wlc, rspec)	(IS_MCS(rspec) ? \
			(wlc)->band->basic_rate[mcs_table[rspec & RSPEC_RATE_MASK].leg_ofdm] : \
			(wlc)->band->basic_rate[rspec & RSPEC_RATE_MASK])

#define FRAMETYPE(r, mimoframe)	(IS_MCS(r) ? mimoframe	: (IS_CCK(r) ? FT_CCK : FT_OFDM))

#define RFDISABLE_DEFAULT	10000000	/* rfdisable delay timer 500 ms, runs of ALP clock */

#define WLC_TEMPSENSE_PERIOD		10	/* 10 second timeout */

#define SCAN_IN_PROGRESS(x)	0

#define EPI_VERSION_NUM		0x054b0b00

#ifdef BCMDBG
/* pointer to most recently allocated wl/wlc */
static struct wlc_info *wlc_info_dbg = (struct wlc_info *) (NULL);
#endif

/* IOVar table */

/* Parameter IDs, for use only internally to wlc -- in the wlc_iovars
 * table and by the wlc_doiovar() function.  No ordering is imposed:
 * the table is keyed by name, and the function uses a switch.
 */
enum {
	IOV_MPC = 1,
	IOV_RTSTHRESH,
	IOV_QTXPOWER,
	IOV_BCN_LI_BCN,		/* Beacon listen interval in # of beacons */
	IOV_LAST		/* In case of a need to check max ID number */
};

const bcm_iovar_t wlc_iovars[] = {
	{"mpc", IOV_MPC, (0), IOVT_BOOL, 0},
	{"rtsthresh", IOV_RTSTHRESH, (IOVF_WHL), IOVT_UINT16, 0},
	{"qtxpower", IOV_QTXPOWER, (IOVF_WHL), IOVT_UINT32, 0},
	{"bcn_li_bcn", IOV_BCN_LI_BCN, (0), IOVT_UINT8, 0},
	{NULL, 0, 0, 0, 0}
};

const u8 prio2fifo[NUMPRIO] = {
	TX_AC_BE_FIFO,		/* 0    BE      AC_BE   Best Effort */
	TX_AC_BK_FIFO,		/* 1    BK      AC_BK   Background */
	TX_AC_BK_FIFO,		/* 2    --      AC_BK   Background */
	TX_AC_BE_FIFO,		/* 3    EE      AC_BE   Best Effort */
	TX_AC_VI_FIFO,		/* 4    CL      AC_VI   Video */
	TX_AC_VI_FIFO,		/* 5    VI      AC_VI   Video */
	TX_AC_VO_FIFO,		/* 6    VO      AC_VO   Voice */
	TX_AC_VO_FIFO		/* 7    NC      AC_VO   Voice */
};

/* precedences numbers for wlc queues. These are twice as may levels as
 * 802.1D priorities.
 * Odd numbers are used for HI priority traffic at same precedence levels
 * These constants are used ONLY by wlc_prio2prec_map.  Do not use them elsewhere.
 */
#define	_WLC_PREC_NONE		0	/* None = - */
#define	_WLC_PREC_BK		2	/* BK - Background */
#define	_WLC_PREC_BE		4	/* BE - Best-effort */
#define	_WLC_PREC_EE		6	/* EE - Excellent-effort */
#define	_WLC_PREC_CL		8	/* CL - Controlled Load */
#define	_WLC_PREC_VI		10	/* Vi - Video */
#define	_WLC_PREC_VO		12	/* Vo - Voice */
#define	_WLC_PREC_NC		14	/* NC - Network Control */

/* 802.1D Priority to precedence queue mapping */
const u8 wlc_prio2prec_map[] = {
	_WLC_PREC_BE,		/* 0 BE - Best-effort */
	_WLC_PREC_BK,		/* 1 BK - Background */
	_WLC_PREC_NONE,		/* 2 None = - */
	_WLC_PREC_EE,		/* 3 EE - Excellent-effort */
	_WLC_PREC_CL,		/* 4 CL - Controlled Load */
	_WLC_PREC_VI,		/* 5 Vi - Video */
	_WLC_PREC_VO,		/* 6 Vo - Voice */
	_WLC_PREC_NC,		/* 7 NC - Network Control */
};

/* Sanity check for tx_prec_map and fifo synchup
 * Either there are some packets pending for the fifo, else if fifo is empty then
 * all the corresponding precmap bits should be set
 */
#define WLC_TX_FIFO_CHECK(wlc, fifo) (TXPKTPENDGET((wlc), (fifo)) ||	\
	(TXPKTPENDGET((wlc), (fifo)) == 0 && \
	((wlc)->tx_prec_map & (wlc)->fifo2prec_map[(fifo)]) == \
	(wlc)->fifo2prec_map[(fifo)]))

/* TX FIFO number to WME/802.1E Access Category */
const u8 wme_fifo2ac[] = { AC_BK, AC_BE, AC_VI, AC_VO, AC_BE, AC_BE };

/* WME/802.1E Access Category to TX FIFO number */
static const u8 wme_ac2fifo[] = { 1, 0, 2, 3 };

static bool in_send_q = false;

/* Shared memory location index for various AC params */
#define wme_shmemacindex(ac)	wme_ac2fifo[ac]

#ifdef BCMDBG
static const char *fifo_names[] = {
	"AC_BK", "AC_BE", "AC_VI", "AC_VO", "BCMC", "ATIM" };
#else
static const char fifo_names[6][0];
#endif

static const u8 acbitmap2maxprio[] = {
	PRIO_8021D_BE, PRIO_8021D_BE, PRIO_8021D_BK, PRIO_8021D_BK,
	PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI,
	PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO,
	PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO
};

/* currently the best mechanism for determining SIFS is the band in use */
#define SIFS(band) ((band)->bandtype == WLC_BAND_5G ? APHY_SIFS_TIME : BPHY_SIFS_TIME);

/* value for # replay counters currently supported */
#define WLC_REPLAY_CNTRS_VALUE	WPA_CAP_16_REPLAY_CNTRS

/* local prototypes */
static u16 BCMFASTPATH wlc_d11hdrs_mac80211(struct wlc_info *wlc,
					       struct ieee80211_hw *hw,
					       struct sk_buff *p,
					       struct scb *scb, uint frag,
					       uint nfrags, uint queue,
					       uint next_frag_len,
					       wsec_key_t *key,
					       ratespec_t rspec_override);

static void wlc_ctrupd_cache(u16 cur_stat, u16 *macstat_snapshot, u32 *macstat);
static void wlc_bss_default_init(struct wlc_info *wlc);
static void wlc_ucode_mac_upd(struct wlc_info *wlc);
static ratespec_t mac80211_wlc_set_nrate(struct wlc_info *wlc,
					 struct wlcband *cur_band, u32 int_val);
static void wlc_tx_prec_map_init(struct wlc_info *wlc);
static void wlc_watchdog(void *arg);
static void wlc_watchdog_by_timer(void *arg);
static u16 wlc_rate_shm_offset(struct wlc_info *wlc, u8 rate);
static int wlc_set_rateset(struct wlc_info *wlc, wlc_rateset_t *rs_arg);
static int wlc_iovar_rangecheck(struct wlc_info *wlc, u32 val,
				const bcm_iovar_t *vi);
static u8 wlc_local_constraint_qdbm(struct wlc_info *wlc);

/* send and receive */
static struct wlc_txq_info *wlc_txq_alloc(struct wlc_info *wlc);
static void wlc_txq_free(struct wlc_info *wlc,
			 struct wlc_txq_info *qi);
static void wlc_txflowcontrol_signal(struct wlc_info *wlc,
				     struct wlc_txq_info *qi,
				     bool on, int prio);
static void wlc_txflowcontrol_reset(struct wlc_info *wlc);
static u16 wlc_compute_airtime(struct wlc_info *wlc, ratespec_t rspec,
				  uint length);
static void wlc_compute_cck_plcp(ratespec_t rate, uint length, u8 *plcp);
static void wlc_compute_ofdm_plcp(ratespec_t rate, uint length, u8 *plcp);
static void wlc_compute_mimo_plcp(ratespec_t rate, uint length, u8 *plcp);
static u16 wlc_compute_frame_dur(struct wlc_info *wlc, ratespec_t rate,
				    u8 preamble_type, uint next_frag_len);
static void wlc_recvctl(struct wlc_info *wlc,
			d11rxhdr_t *rxh, struct sk_buff *p);
static uint wlc_calc_frame_len(struct wlc_info *wlc, ratespec_t rate,
			       u8 preamble_type, uint dur);
static uint wlc_calc_ack_time(struct wlc_info *wlc, ratespec_t rate,
			      u8 preamble_type);
static uint wlc_calc_cts_time(struct wlc_info *wlc, ratespec_t rate,
			      u8 preamble_type);
/* interrupt, up/down, band */
static void wlc_setband(struct wlc_info *wlc, uint bandunit);
static chanspec_t wlc_init_chanspec(struct wlc_info *wlc);
static void wlc_bandinit_ordered(struct wlc_info *wlc, chanspec_t chanspec);
static void wlc_bsinit(struct wlc_info *wlc);
static int wlc_duty_cycle_set(struct wlc_info *wlc, int duty_cycle, bool isOFDM,
			      bool writeToShm);
static void wlc_radio_hwdisable_upd(struct wlc_info *wlc);
static bool wlc_radio_monitor_start(struct wlc_info *wlc);
static void wlc_radio_timer(void *arg);
static void wlc_radio_enable(struct wlc_info *wlc);
static void wlc_radio_upd(struct wlc_info *wlc);

/* scan, association, BSS */
static uint wlc_calc_ba_time(struct wlc_info *wlc, ratespec_t rate,
			     u8 preamble_type);
static void wlc_update_mimo_band_bwcap(struct wlc_info *wlc, u8 bwcap);
static void wlc_ht_update_sgi_rx(struct wlc_info *wlc, int val);
static void wlc_ht_update_ldpc(struct wlc_info *wlc, s8 val);
static void wlc_war16165(struct wlc_info *wlc, bool tx);

static void wlc_wme_retries_write(struct wlc_info *wlc);
static bool wlc_attach_stf_ant_init(struct wlc_info *wlc);
static uint wlc_attach_module(struct wlc_info *wlc);
static void wlc_detach_module(struct wlc_info *wlc);
static void wlc_timers_deinit(struct wlc_info *wlc);
static void wlc_down_led_upd(struct wlc_info *wlc);
static uint wlc_down_del_timer(struct wlc_info *wlc);
static void wlc_ofdm_rateset_war(struct wlc_info *wlc);
static int _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len,
		      struct wlc_if *wlcif);

#if defined(BCMDBG)
void wlc_get_rcmta(struct wlc_info *wlc, int idx, u8 *addr)
{
	d11regs_t *regs = wlc->regs;
	u32 v32;

	WL_TRACE("wl%d: %s\n", WLCWLUNIT(wlc), __func__);

	W_REG(&regs->objaddr, (OBJADDR_RCMTA_SEL | (idx * 2)));
	(void)R_REG(&regs->objaddr);
	v32 = R_REG(&regs->objdata);
	addr[0] = (u8) v32;
	addr[1] = (u8) (v32 >> 8);
	addr[2] = (u8) (v32 >> 16);
	addr[3] = (u8) (v32 >> 24);
	W_REG(&regs->objaddr, (OBJADDR_RCMTA_SEL | ((idx * 2) + 1)));
	(void)R_REG(&regs->objaddr);
	v32 = R_REG(&regs->objdata);
	addr[4] = (u8) v32;
	addr[5] = (u8) (v32 >> 8);
}
#endif				/* defined(BCMDBG) */

/* keep the chip awake if needed */
bool wlc_stay_awake(struct wlc_info *wlc)
{
	return true;
}

/* conditions under which the PM bit should be set in outgoing frames and STAY_AWAKE is meaningful
 */
bool wlc_ps_allowed(struct wlc_info *wlc)
{
	int idx;
	struct wlc_bsscfg *cfg;

	/* disallow PS when one of the following global conditions meets */
	if (!wlc->pub->associated || !wlc->PMenabled || wlc->PM_override)
		return false;

	/* disallow PS when one of these meets when not scanning */
	if (!wlc->PMblocked) {
		if (AP_ACTIVE(wlc) || wlc->monitor)
			return false;
	}

	FOREACH_AS_STA(wlc, idx, cfg) {
		/* disallow PS when one of the following bsscfg specific conditions meets */
		if (!cfg->BSS || !WLC_PORTOPEN(cfg))
			return false;

		if (!cfg->dtim_programmed)
			return false;
	}

	return true;
}

void wlc_reset(struct wlc_info *wlc)
{
	WL_TRACE("wl%d: wlc_reset\n", wlc->pub->unit);

	wlc->check_for_unaligned_tbtt = false;

	/* slurp up hw mac counters before core reset */
	wlc_statsupd(wlc);

	/* reset our snapshot of macstat counters */
	memset((char *)wlc->core->macstat_snapshot, 0,
		sizeof(macstat_t));

	wlc_bmac_reset(wlc->hw);
	wlc_ampdu_reset(wlc->ampdu);
	wlc->txretried = 0;

}

void wlc_fatal_error(struct wlc_info *wlc)
{
	WL_ERROR("wl%d: fatal error, reinitializing\n", wlc->pub->unit);
	wl_init(wlc->wl);
}

/* Return the channel the driver should initialize during wlc_init.
 * the channel may have to be changed from the currently configured channel
 * if other configurations are in conflict (bandlocked, 11n mode disabled,
 * invalid channel for current country, etc.)
 */
static chanspec_t wlc_init_chanspec(struct wlc_info *wlc)
{
	chanspec_t chanspec =
	    1 | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE |
	    WL_CHANSPEC_BAND_2G;

	/* make sure the channel is on the supported band if we are band-restricted */
	if (wlc->bandlocked || NBANDS(wlc) == 1) {
		ASSERT(CHSPEC_WLCBANDUNIT(chanspec) == wlc->band->bandunit);
	}
	ASSERT(wlc_valid_chanspec_db(wlc->cmi, chanspec));
	return chanspec;
}

struct scb global_scb;

static void wlc_init_scb(struct wlc_info *wlc, struct scb *scb)
{
	int i;
	scb->flags = SCB_WMECAP | SCB_HTCAP;
	for (i = 0; i < NUMPRIO; i++)
		scb->seqnum[i] = 0;
}

void wlc_init(struct wlc_info *wlc)
{
	d11regs_t *regs;
	chanspec_t chanspec;
	int i;
	struct wlc_bsscfg *bsscfg;
	bool mute = false;

	WL_TRACE("wl%d: wlc_init\n", wlc->pub->unit);

	regs = wlc->regs;

	/* This will happen if a big-hammer was executed. In that case, we want to go back
	 * to the channel that we were on and not new channel
	 */
	if (wlc->pub->associated)
		chanspec = wlc->home_chanspec;
	else
		chanspec = wlc_init_chanspec(wlc);

	wlc_bmac_init(wlc->hw, chanspec, mute);

	wlc->seckeys = wlc_bmac_read_shm(wlc->hw, M_SECRXKEYS_PTR) * 2;
	if (wlc->machwcap & MCAP_TKIPMIC)
		wlc->tkmickeys =
		    wlc_bmac_read_shm(wlc->hw, M_TKMICKEYS_PTR) * 2;

	/* update beacon listen interval */
	wlc_bcn_li_upd(wlc);
	wlc->bcn_wait_prd =
	    (u8) (wlc_bmac_read_shm(wlc->hw, M_NOSLPZNATDTIM) >> 10);
	ASSERT(wlc->bcn_wait_prd > 0);

	/* the world is new again, so is our reported rate */
	wlc_reprate_init(wlc);

	/* write ethernet address to core */
	FOREACH_BSS(wlc, i, bsscfg) {
		wlc_set_mac(bsscfg);
		wlc_set_bssid(bsscfg);
	}

	/* Update tsf_cfprep if associated and up */
	if (wlc->pub->associated) {
		FOREACH_BSS(wlc, i, bsscfg) {
			if (bsscfg->up) {
				u32 bi;

				/* get beacon period and convert to uS */
				bi = bsscfg->current_bss->beacon_period << 10;
				/*
				 * update since init path would reset
				 * to default value
				 */
				W_REG(&regs->tsf_cfprep,
				      (bi << CFPREP_CBI_SHIFT));

				/* Update maccontrol PM related bits */
				wlc_set_ps_ctrl(wlc);

				break;
			}
		}
	}

	wlc_key_hw_init_all(wlc);

	wlc_bandinit_ordered(wlc, chanspec);

	wlc_init_scb(wlc, &global_scb);

	/* init probe response timeout */
	wlc_write_shm(wlc, M_PRS_MAXTIME, wlc->prb_resp_timeout);

	/* init max burst txop (framebursting) */
	wlc_write_shm(wlc, M_MBURST_TXOP,
		      (wlc->
		       _rifs ? (EDCF_AC_VO_TXOP_AP << 5) : MAXFRAMEBURST_TXOP));

	/* initialize maximum allowed duty cycle */
	wlc_duty_cycle_set(wlc, wlc->tx_duty_cycle_ofdm, true, true);
	wlc_duty_cycle_set(wlc, wlc->tx_duty_cycle_cck, false, true);

	/* Update some shared memory locations related to max AMPDU size allowed to received */
	wlc_ampdu_shm_upd(wlc->ampdu);

	/* band-specific inits */
	wlc_bsinit(wlc);

	/* Enable EDCF mode (while the MAC is suspended) */
	if (EDCF_ENAB(wlc->pub)) {
		OR_REG(&regs->ifs_ctl, IFS_USEEDCF);
		wlc_edcf_setparams(wlc->cfg, false);
	}

	/* Init precedence maps for empty FIFOs */
	wlc_tx_prec_map_init(wlc);

	/* read the ucode version if we have not yet done so */
	if (wlc->ucode_rev == 0) {
		wlc->ucode_rev =
		    wlc_read_shm(wlc, M_BOM_REV_MAJOR) << NBITS(u16);
		wlc->ucode_rev |= wlc_read_shm(wlc, M_BOM_REV_MINOR);
	}

	/* ..now really unleash hell (allow the MAC out of suspend) */
	wlc_enable_mac(wlc);

	/* clear tx flow control */
	wlc_txflowcontrol_reset(wlc);

	/* clear tx data fifo suspends */
	wlc->tx_suspended = false;

	/* enable the RF Disable Delay timer */
	W_REG(&wlc->regs->rfdisabledly, RFDISABLE_DEFAULT);

	/* initialize mpc delay */
	wlc->mpc_delay_off = wlc->mpc_dlycnt = WLC_MPC_MIN_DELAYCNT;

	/*
	 * Initialize WME parameters; if they haven't been set by some other
	 * mechanism (IOVar, etc) then read them from the hardware.
	 */
	if (WLC_WME_RETRY_SHORT_GET(wlc, 0) == 0) {	/* Uninitialized; read from HW */
		int ac;

		ASSERT(wlc->clk);
		for (ac = 0; ac < AC_COUNT; ac++) {
			wlc->wme_retries[ac] =
			    wlc_read_shm(wlc, M_AC_TXLMT_ADDR(ac));
		}
	}
}

void wlc_mac_bcn_promisc_change(struct wlc_info *wlc, bool promisc)
{
	wlc->bcnmisc_monitor = promisc;
	wlc_mac_bcn_promisc(wlc);
}

void wlc_mac_bcn_promisc(struct wlc_info *wlc)
{
	if ((AP_ENAB(wlc->pub) && (N_ENAB(wlc->pub) || wlc->band->gmode)) ||
	    wlc->bcnmisc_ibss || wlc->bcnmisc_scan || wlc->bcnmisc_monitor)
		wlc_mctrl(wlc, MCTL_BCNS_PROMISC, MCTL_BCNS_PROMISC);
	else
		wlc_mctrl(wlc, MCTL_BCNS_PROMISC, 0);
}

/* set or clear maccontrol bits MCTL_PROMISC and MCTL_KEEPCONTROL */
void wlc_mac_promisc(struct wlc_info *wlc)
{
	u32 promisc_bits = 0;

	/* promiscuous mode just sets MCTL_PROMISC
	 * Note: APs get all BSS traffic without the need to set the MCTL_PROMISC bit
	 * since all BSS data traffic is directed at the AP
	 */
	if (PROMISC_ENAB(wlc->pub) && !AP_ENAB(wlc->pub) && !wlc->wet)
		promisc_bits |= MCTL_PROMISC;

	/* monitor mode needs both MCTL_PROMISC and MCTL_KEEPCONTROL
	 * Note: monitor mode also needs MCTL_BCNS_PROMISC, but that is
	 * handled in wlc_mac_bcn_promisc()
	 */
	if (MONITOR_ENAB(wlc))
		promisc_bits |= MCTL_PROMISC | MCTL_KEEPCONTROL;

	wlc_mctrl(wlc, MCTL_PROMISC | MCTL_KEEPCONTROL, promisc_bits);
}

/* check if hps and wake states of sw and hw are in sync */
bool wlc_ps_check(struct wlc_info *wlc)
{
	bool res = true;
	bool hps, wake;
	bool wake_ok;

	if (!AP_ACTIVE(wlc)) {
		u32 tmp;
		tmp = R_REG(&wlc->regs->maccontrol);

		/*
		 * If deviceremoved is detected, then don't take any action as
		 * this can be called in any context. Assume that caller will
		 * take care of the condition. This is just to avoid assert
		 */
		if (tmp == 0xffffffff) {
			WL_ERROR("wl%d: %s: dead chip\n",
				 wlc->pub->unit, __func__);
			return DEVICEREMOVED(wlc);
		}

		hps = PS_ALLOWED(wlc);

		if (hps != ((tmp & MCTL_HPS) != 0)) {
			int idx;
			struct wlc_bsscfg *cfg;
			WL_ERROR("wl%d: hps not sync, sw %d, maccontrol 0x%x\n",
				 wlc->pub->unit, hps, tmp);
			FOREACH_BSS(wlc, idx, cfg) {
				if (!BSSCFG_STA(cfg))
					continue;
			}

			res = false;
		}
		/* For a monolithic build the wake check can be exact since it looks at wake
		 * override bits. The MCTL_WAKE bit should match the 'wake' value.
		 */
		wake = STAY_AWAKE(wlc) || wlc->hw->wake_override;
		wake_ok = (wake == ((tmp & MCTL_WAKE) != 0));
		if (hps && !wake_ok) {
			WL_ERROR("wl%d: wake not sync, sw %d maccontrol 0x%x\n",
				 wlc->pub->unit, wake, tmp);
			res = false;
		}
	}
	ASSERT(res);
	return res;
}

/* push sw hps and wake state through hardware */
void wlc_set_ps_ctrl(struct wlc_info *wlc)
{
	u32 v1, v2;
	bool hps, wake;
	bool awake_before;

	hps = PS_ALLOWED(wlc);
	wake = hps ? (STAY_AWAKE(wlc)) : true;

	WL_TRACE("wl%d: wlc_set_ps_ctrl: hps %d wake %d\n",
		 wlc->pub->unit, hps, wake);

	v1 = R_REG(&wlc->regs->maccontrol);
	v2 = 0;
	if (hps)
		v2 |= MCTL_HPS;
	if (wake)
		v2 |= MCTL_WAKE;

	wlc_mctrl(wlc, MCTL_WAKE | MCTL_HPS, v2);

	awake_before = ((v1 & MCTL_WAKE) || ((v1 & MCTL_HPS) == 0));

	if (wake && !awake_before)
		wlc_bmac_wait_for_wake(wlc->hw);

}

/*
 * Write this BSS config's MAC address to core.
 * Updates RXE match engine.
 */
int wlc_set_mac(struct wlc_bsscfg *cfg)
{
	int err = 0;
	struct wlc_info *wlc = cfg->wlc;

	if (cfg == wlc->cfg) {
		/* enter the MAC addr into the RXE match registers */
		wlc_set_addrmatch(wlc, RCM_MAC_OFFSET, cfg->cur_etheraddr);
	}

	wlc_ampdu_macaddr_upd(wlc);

	return err;
}

/* Write the BSS config's BSSID address to core (set_bssid in d11procs.tcl).
 * Updates RXE match engine.
 */
void wlc_set_bssid(struct wlc_bsscfg *cfg)
{
	struct wlc_info *wlc = cfg->wlc;

	/* if primary config, we need to update BSSID in RXE match registers */
	if (cfg == wlc->cfg) {
		wlc_set_addrmatch(wlc, RCM_BSSID_OFFSET, cfg->BSSID);
	}
#ifdef SUPPORT_HWKEYS
	else if (BSSCFG_STA(cfg) && cfg->BSS) {
		wlc_rcmta_add_bssid(wlc, cfg);
	}
#endif
}

/*
 * Suspend the the MAC and update the slot timing
 * for standard 11b/g (20us slots) or shortslot 11g (9us slots).
 */
void wlc_switch_shortslot(struct wlc_info *wlc, bool shortslot)
{
	int idx;
	struct wlc_bsscfg *cfg;

	ASSERT(wlc->band->gmode);

	/* use the override if it is set */
	if (wlc->shortslot_override != WLC_SHORTSLOT_AUTO)
		shortslot = (wlc->shortslot_override == WLC_SHORTSLOT_ON);

	if (wlc->shortslot == shortslot)
		return;

	wlc->shortslot = shortslot;

	/* update the capability based on current shortslot mode */
	FOREACH_BSS(wlc, idx, cfg) {
		if (!cfg->associated)
			continue;
		cfg->current_bss->capability &=
					~WLAN_CAPABILITY_SHORT_SLOT_TIME;
		if (wlc->shortslot)
			cfg->current_bss->capability |=
					WLAN_CAPABILITY_SHORT_SLOT_TIME;
	}

	wlc_bmac_set_shortslot(wlc->hw, shortslot);
}

static u8 wlc_local_constraint_qdbm(struct wlc_info *wlc)
{
	u8 local;
	s16 local_max;

	local = WLC_TXPWR_MAX;
	if (wlc->pub->associated &&
	    (wf_chspec_ctlchan(wlc->chanspec) ==
	     wf_chspec_ctlchan(wlc->home_chanspec))) {

		/* get the local power constraint if we are on the AP's
		 * channel [802.11h, 7.3.2.13]
		 */
		/* Clamp the value between 0 and WLC_TXPWR_MAX w/o overflowing the target */
		local_max =
		    (wlc->txpwr_local_max -
		     wlc->txpwr_local_constraint) * WLC_TXPWR_DB_FACTOR;
		if (local_max > 0 && local_max < WLC_TXPWR_MAX)
			return (u8) local_max;
		if (local_max < 0)
			return 0;
	}

	return local;
}

/* propagate home chanspec to all bsscfgs in case bsscfg->current_bss->chanspec is referenced */
void wlc_set_home_chanspec(struct wlc_info *wlc, chanspec_t chanspec)
{
	if (wlc->home_chanspec != chanspec) {
		int idx;
		struct wlc_bsscfg *cfg;

		wlc->home_chanspec = chanspec;

		FOREACH_BSS(wlc, idx, cfg) {
			if (!cfg->associated)
				continue;

			cfg->current_bss->chanspec = chanspec;
		}

	}
}

static void wlc_set_phy_chanspec(struct wlc_info *wlc, chanspec_t chanspec)
{
	/* Save our copy of the chanspec */
	wlc->chanspec = chanspec;

	/* Set the chanspec and power limits for this locale after computing
	 * any 11h local tx power constraints.
	 */
	wlc_channel_set_chanspec(wlc->cmi, chanspec,
				 wlc_local_constraint_qdbm(wlc));

	if (wlc->stf->ss_algosel_auto)
		wlc_stf_ss_algo_channel_get(wlc, &wlc->stf->ss_algo_channel,
					    chanspec);

	wlc_stf_ss_update(wlc, wlc->band);

}

void wlc_set_chanspec(struct wlc_info *wlc, chanspec_t chanspec)
{
	uint bandunit;
	bool switchband = false;
	chanspec_t old_chanspec = wlc->chanspec;

	if (!wlc_valid_chanspec_db(wlc->cmi, chanspec)) {
		WL_ERROR("wl%d: %s: Bad channel %d\n",
			 wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec));
		ASSERT(wlc_valid_chanspec_db(wlc->cmi, chanspec));
		return;
	}

	/* Switch bands if necessary */
	if (NBANDS(wlc) > 1) {
		bandunit = CHSPEC_WLCBANDUNIT(chanspec);
		if (wlc->band->bandunit != bandunit || wlc->bandinit_pending) {
			switchband = true;
			if (wlc->bandlocked) {
				WL_ERROR("wl%d: %s: chspec %d band is locked!\n",
					 wlc->pub->unit, __func__,
					 CHSPEC_CHANNEL(chanspec));
				return;
			}
			/* BMAC_NOTE: should the setband call come after the wlc_bmac_chanspec() ?
			 * if the setband updates (wlc_bsinit) use low level calls to inspect and
			 * set state, the state inspected may be from the wrong band, or the
			 * following wlc_bmac_set_chanspec() may undo the work.
			 */
			wlc_setband(wlc, bandunit);
		}
	}

	ASSERT(N_ENAB(wlc->pub) || !CHSPEC_IS40(chanspec));

	/* sync up phy/radio chanspec */
	wlc_set_phy_chanspec(wlc, chanspec);

	/* init antenna selection */
	if (CHSPEC_WLC_BW(old_chanspec) != CHSPEC_WLC_BW(chanspec)) {
		wlc_antsel_init(wlc->asi);

		/* Fix the hardware rateset based on bw.
		 * Mainly add MCS32 for 40Mhz, remove MCS 32 for 20Mhz
		 */
		wlc_rateset_bw_mcs_filter(&wlc->band->hw_rateset,
					  wlc->band->
					  mimo_cap_40 ? CHSPEC_WLC_BW(chanspec)
					  : 0);
	}

	/* update some mac configuration since chanspec changed */
	wlc_ucode_mac_upd(wlc);
}

#if defined(BCMDBG)
static int wlc_get_current_txpwr(struct wlc_info *wlc, void *pwr, uint len)
{
	txpwr_limits_t txpwr;
	tx_power_t power;
	tx_power_legacy_t *old_power = NULL;
	int r, c;
	uint qdbm;
	bool override;

	if (len == sizeof(tx_power_legacy_t))
		old_power = (tx_power_legacy_t *) pwr;
	else if (len < sizeof(tx_power_t))
		return BCME_BUFTOOSHORT;

	memset(&power, 0, sizeof(tx_power_t));

	power.chanspec = WLC_BAND_PI_RADIO_CHANSPEC;
	if (wlc->pub->associated)
		power.local_chanspec = wlc->home_chanspec;

	/* Return the user target tx power limits for the various rates.  Note  wlc_phy.c's
	 * public interface only implements getting and setting a single value for all of
	 * rates, so we need to fill the array ourselves.
	 */
	wlc_phy_txpower_get(wlc->band->pi, &qdbm, &override);
	for (r = 0; r < WL_TX_POWER_RATES; r++) {
		power.user_limit[r] = (u8) qdbm;
	}

	power.local_max = wlc->txpwr_local_max * WLC_TXPWR_DB_FACTOR;
	power.local_constraint =
	    wlc->txpwr_local_constraint * WLC_TXPWR_DB_FACTOR;

	power.antgain[0] = wlc->bandstate[BAND_2G_INDEX]->antgain;
	power.antgain[1] = wlc->bandstate[BAND_5G_INDEX]->antgain;

	wlc_channel_reg_limits(wlc->cmi, power.chanspec, &txpwr);

#if WL_TX_POWER_CCK_NUM != WLC_NUM_RATES_CCK
#error "WL_TX_POWER_CCK_NUM != WLC_NUM_RATES_CCK"
#endif

	/* CCK tx power limits */
	for (c = 0, r = WL_TX_POWER_CCK_FIRST; c < WL_TX_POWER_CCK_NUM;
	     c++, r++)
		power.reg_limit[r] = txpwr.cck[c];

#if WL_TX_POWER_OFDM_NUM != WLC_NUM_RATES_OFDM
#error "WL_TX_POWER_OFDM_NUM != WLC_NUM_RATES_OFDM"
#endif

	/* 20 MHz OFDM SISO tx power limits */
	for (c = 0, r = WL_TX_POWER_OFDM_FIRST; c < WL_TX_POWER_OFDM_NUM;
	     c++, r++)
		power.reg_limit[r] = txpwr.ofdm[c];

	if (WLC_PHY_11N_CAP(wlc->band)) {

		/* 20 MHz OFDM CDD tx power limits */
		for (c = 0, r = WL_TX_POWER_OFDM20_CDD_FIRST;
		     c < WL_TX_POWER_OFDM_NUM; c++, r++)
			power.reg_limit[r] = txpwr.ofdm_cdd[c];

		/* 40 MHz OFDM SISO tx power limits */
		for (c = 0, r = WL_TX_POWER_OFDM40_SISO_FIRST;
		     c < WL_TX_POWER_OFDM_NUM; c++, r++)
			power.reg_limit[r] = txpwr.ofdm_40_siso[c];

		/* 40 MHz OFDM CDD tx power limits */
		for (c = 0, r = WL_TX_POWER_OFDM40_CDD_FIRST;
		     c < WL_TX_POWER_OFDM_NUM; c++, r++)
			power.reg_limit[r] = txpwr.ofdm_40_cdd[c];

#if WL_TX_POWER_MCS_1_STREAM_NUM != WLC_NUM_RATES_MCS_1_STREAM
#error "WL_TX_POWER_MCS_1_STREAM_NUM != WLC_NUM_RATES_MCS_1_STREAM"
#endif

		/* 20MHz MCS0-7 SISO tx power limits */
		for (c = 0, r = WL_TX_POWER_MCS20_SISO_FIRST;
		     c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++)
			power.reg_limit[r] = txpwr.mcs_20_siso[c];

		/* 20MHz MCS0-7 CDD tx power limits */
		for (c = 0, r = WL_TX_POWER_MCS20_CDD_FIRST;
		     c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++)
			power.reg_limit[r] = txpwr.mcs_20_cdd[c];

		/* 20MHz MCS0-7 STBC tx power limits */
		for (c = 0, r = WL_TX_POWER_MCS20_STBC_FIRST;
		     c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++)
			power.reg_limit[r] = txpwr.mcs_20_stbc[c];

		/* 40MHz MCS0-7 SISO tx power limits */
		for (c = 0, r = WL_TX_POWER_MCS40_SISO_FIRST;
		     c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++)
			power.reg_limit[r] = txpwr.mcs_40_siso[c];

		/* 40MHz MCS0-7 CDD tx power limits */
		for (c = 0, r = WL_TX_POWER_MCS40_CDD_FIRST;
		     c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++)
			power.reg_limit[r] = txpwr.mcs_40_cdd[c];

		/* 40MHz MCS0-7 STBC tx power limits */
		for (c = 0, r = WL_TX_POWER_MCS40_STBC_FIRST;
		     c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++)
			power.reg_limit[r] = txpwr.mcs_40_stbc[c];

#if WL_TX_POWER_MCS_2_STREAM_NUM != WLC_NUM_RATES_MCS_2_STREAM
#error "WL_TX_POWER_MCS_2_STREAM_NUM != WLC_NUM_RATES_MCS_2_STREAM"
#endif

		/* 20MHz MCS8-15 SDM tx power limits */
		for (c = 0, r = WL_TX_POWER_MCS20_SDM_FIRST;
		     c < WLC_NUM_RATES_MCS_2_STREAM; c++, r++)
			power.reg_limit[r] = txpwr.mcs_20_mimo[c];

		/* 40MHz MCS8-15 SDM tx power limits */
		for (c = 0, r = WL_TX_POWER_MCS40_SDM_FIRST;
		     c < WLC_NUM_RATES_MCS_2_STREAM; c++, r++)
			power.reg_limit[r] = txpwr.mcs_40_mimo[c];

		/* MCS 32 */
		power.reg_limit[WL_TX_POWER_MCS_32] = txpwr.mcs32;
	}

	wlc_phy_txpower_get_current(wlc->band->pi, &power,
				    CHSPEC_CHANNEL(power.chanspec));

	/* copy the tx_power_t struct to the return buffer,
	 * or convert to a tx_power_legacy_t struct
	 */
	if (!old_power) {
		memcpy(pwr, &power, sizeof(tx_power_t));
	} else {
		int band_idx = CHSPEC_IS2G(power.chanspec) ? 0 : 1;

		memset(old_power, 0, sizeof(tx_power_legacy_t));

		old_power->txpwr_local_max = power.local_max;
		old_power->txpwr_local_constraint = power.local_constraint;
		if (CHSPEC_IS2G(power.chanspec)) {
			old_power->txpwr_chan_reg_max = txpwr.cck[0];
			old_power->txpwr_est_Pout[band_idx] =
			    power.est_Pout_cck;
			old_power->txpwr_est_Pout_gofdm = power.est_Pout[0];
		} else {
			old_power->txpwr_chan_reg_max = txpwr.ofdm[0];
			old_power->txpwr_est_Pout[band_idx] = power.est_Pout[0];
		}
		old_power->txpwr_antgain[0] = power.antgain[0];
		old_power->txpwr_antgain[1] = power.antgain[1];

		for (r = 0; r < NUM_PWRCTRL_RATES; r++) {
			old_power->txpwr_band_max[r] = power.user_limit[r];
			old_power->txpwr_limit[r] = power.reg_limit[r];
			old_power->txpwr_target[band_idx][r] = power.target[r];
			if (CHSPEC_IS2G(power.chanspec))
				old_power->txpwr_bphy_cck_max[r] =
				    power.board_limit[r];
			else
				old_power->txpwr_aphy_max[r] =
				    power.board_limit[r];
		}
	}

	return 0;
}
#endif				/* defined(BCMDBG) */

static u32 wlc_watchdog_backup_bi(struct wlc_info *wlc)
{
	u32 bi;
	bi = 2 * wlc->cfg->current_bss->dtim_period *
	    wlc->cfg->current_bss->beacon_period;
	if (wlc->bcn_li_dtim)
		bi *= wlc->bcn_li_dtim;
	else if (wlc->bcn_li_bcn)
		/* recalculate bi based on bcn_li_bcn */
		bi = 2 * wlc->bcn_li_bcn * wlc->cfg->current_bss->beacon_period;

	if (bi < 2 * TIMER_INTERVAL_WATCHDOG)
		bi = 2 * TIMER_INTERVAL_WATCHDOG;
	return bi;
}

/* Change to run the watchdog either from a periodic timer or from tbtt handler.
 * Call watchdog from tbtt handler if tbtt is true, watchdog timer otherwise.
 */
void wlc_watchdog_upd(struct wlc_info *wlc, bool tbtt)
{
	/* make sure changing watchdog driver is allowed */
	if (!wlc->pub->up || !wlc->pub->align_wd_tbtt)
		return;
	if (!tbtt && wlc->WDarmed) {
		wl_del_timer(wlc->wl, wlc->wdtimer);
		wlc->WDarmed = false;
	}

	/* stop watchdog timer and use tbtt interrupt to drive watchdog */
	if (tbtt && wlc->WDarmed) {
		wl_del_timer(wlc->wl, wlc->wdtimer);
		wlc->WDarmed = false;
		wlc->WDlast = OSL_SYSUPTIME();
	}
	/* arm watchdog timer and drive the watchdog there */
	else if (!tbtt && !wlc->WDarmed) {
		wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG,
			     true);
		wlc->WDarmed = true;
	}
	if (tbtt && !wlc->WDarmed) {
		wl_add_timer(wlc->wl, wlc->wdtimer, wlc_watchdog_backup_bi(wlc),
			     true);
		wlc->WDarmed = true;
	}
}

ratespec_t wlc_lowest_basic_rspec(struct wlc_info *wlc, wlc_rateset_t *rs)
{
	ratespec_t lowest_basic_rspec;
	uint i;

	/* Use the lowest basic rate */
	lowest_basic_rspec = rs->rates[0] & RATE_MASK;
	for (i = 0; i < rs->count; i++) {
		if (rs->rates[i] & WLC_RATE_FLAG) {
			lowest_basic_rspec = rs->rates[i] & RATE_MASK;
			break;
		}
	}
#if NCONF
	/* pick siso/cdd as default for OFDM (note no basic rate MCSs are supported yet) */
	if (IS_OFDM(lowest_basic_rspec)) {
		lowest_basic_rspec |= (wlc->stf->ss_opmode << RSPEC_STF_SHIFT);
	}
#endif

	return lowest_basic_rspec;
}

/* This function changes the phytxctl for beacon based on current beacon ratespec AND txant
 * setting as per this table:
 *  ratespec     CCK		ant = wlc->stf->txant
 *  		OFDM		ant = 3
 */
void wlc_beacon_phytxctl_txant_upd(struct wlc_info *wlc, ratespec_t bcn_rspec)
{
	u16 phyctl;
	u16 phytxant = wlc->stf->phytxant;
	u16 mask = PHY_TXC_ANT_MASK;

	/* for non-siso rates or default setting, use the available chains */
	if (WLC_PHY_11N_CAP(wlc->band)) {
		phytxant = wlc_stf_phytxchain_sel(wlc, bcn_rspec);
	}

	phyctl = wlc_read_shm(wlc, M_BCN_PCTLWD);
	phyctl = (phyctl & ~mask) | phytxant;
	wlc_write_shm(wlc, M_BCN_PCTLWD, phyctl);
}

/* centralized protection config change function to simplify debugging, no consistency checking
 * this should be called only on changes to avoid overhead in periodic function
*/
void wlc_protection_upd(struct wlc_info *wlc, uint idx, int val)
{
	WL_TRACE("wlc_protection_upd: idx %d, val %d\n", idx, val);

	switch (idx) {
	case WLC_PROT_G_SPEC:
		wlc->protection->_g = (bool) val;
		break;
	case WLC_PROT_G_OVR:
		wlc->protection->g_override = (s8) val;
		break;
	case WLC_PROT_G_USER:
		wlc->protection->gmode_user = (u8) val;
		break;
	case WLC_PROT_OVERLAP:
		wlc->protection->overlap = (s8) val;
		break;
	case WLC_PROT_N_USER:
		wlc->protection->nmode_user = (s8) val;
		break;
	case WLC_PROT_N_CFG:
		wlc->protection->n_cfg = (s8) val;
		break;
	case WLC_PROT_N_CFG_OVR:
		wlc->protection->n_cfg_override = (s8) val;
		break;
	case WLC_PROT_N_NONGF:
		wlc->protection->nongf = (bool) val;
		break;
	case WLC_PROT_N_NONGF_OVR:
		wlc->protection->nongf_override = (s8) val;
		break;
	case WLC_PROT_N_PAM_OVR:
		wlc->protection->n_pam_override = (s8) val;
		break;
	case WLC_PROT_N_OBSS:
		wlc->protection->n_obss = (bool) val;
		break;

	default:
		ASSERT(0);
		break;
	}

}

static void wlc_ht_update_sgi_rx(struct wlc_info *wlc, int val)
{
	wlc->ht_cap.cap_info &= ~(IEEE80211_HT_CAP_SGI_20 |
					IEEE80211_HT_CAP_SGI_40);
	wlc->ht_cap.cap_info |= (val & WLC_N_SGI_20) ?
					IEEE80211_HT_CAP_SGI_20 : 0;
	wlc->ht_cap.cap_info |= (val & WLC_N_SGI_40) ?
					IEEE80211_HT_CAP_SGI_40 : 0;

	if (wlc->pub->up) {
		wlc_update_beacon(wlc);
		wlc_update_probe_resp(wlc, true);
	}
}

static void wlc_ht_update_ldpc(struct wlc_info *wlc, s8 val)
{
	wlc->stf->ldpc = val;

	wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_LDPC_CODING;
	if (wlc->stf->ldpc != OFF)
		wlc->ht_cap.cap_info |= IEEE80211_HT_CAP_LDPC_CODING;

	if (wlc->pub->up) {
		wlc_update_beacon(wlc);
		wlc_update_probe_resp(wlc, true);
		wlc_phy_ldpc_override_set(wlc->band->pi, (val ? true : false));
	}
}

/*
 * ucode, hwmac update
 *    Channel dependent updates for ucode and hw
 */
static void wlc_ucode_mac_upd(struct wlc_info *wlc)
{
	/* enable or disable any active IBSSs depending on whether or not
	 * we are on the home channel
	 */
	if (wlc->home_chanspec == WLC_BAND_PI_RADIO_CHANSPEC) {
		if (wlc->pub->associated) {
			/* BMAC_NOTE: This is something that should be fixed in ucode inits.
			 * I think that the ucode inits set up the bcn templates and shm values
			 * with a bogus beacon. This should not be done in the inits. If ucode needs
			 * to set up a beacon for testing, the test routines should write it down,
			 * not expect the inits to populate a bogus beacon.
			 */
			if (WLC_PHY_11N_CAP(wlc->band)) {
				wlc_write_shm(wlc, M_BCN_TXTSF_OFFSET,
					      wlc->band->bcntsfoff);
			}
		}
	} else {
		/* disable an active IBSS if we are not on the home channel */
	}

	/* update the various promisc bits */
	wlc_mac_bcn_promisc(wlc);
	wlc_mac_promisc(wlc);
}

static void wlc_bandinit_ordered(struct wlc_info *wlc, chanspec_t chanspec)
{
	wlc_rateset_t default_rateset;
	uint parkband;
	uint i, band_order[2];

	WL_TRACE("wl%d: wlc_bandinit_ordered\n", wlc->pub->unit);
	/*
	 * We might have been bandlocked during down and the chip power-cycled (hibernate).
	 * figure out the right band to park on
	 */
	if (wlc->bandlocked || NBANDS(wlc) == 1) {
		ASSERT(CHSPEC_WLCBANDUNIT(chanspec) == wlc->band->bandunit);

		parkband = wlc->band->bandunit;	/* updated in wlc_bandlock() */
		band_order[0] = band_order[1] = parkband;
	} else {
		/* park on the band of the specified chanspec */
		parkband = CHSPEC_WLCBANDUNIT(chanspec);

		/* order so that parkband initialize last */
		band_order[0] = parkband ^ 1;
		band_order[1] = parkband;
	}

	/* make each band operational, software state init */
	for (i = 0; i < NBANDS(wlc); i++) {
		uint j = band_order[i];

		wlc->band = wlc->bandstate[j];

		wlc_default_rateset(wlc, &default_rateset);

		/* fill in hw_rate */
		wlc_rateset_filter(&default_rateset, &wlc->band->hw_rateset,
				   false, WLC_RATES_CCK_OFDM, RATE_MASK,
				   (bool) N_ENAB(wlc->pub));

		/* init basic rate lookup */
		wlc_rate_lookup_init(wlc, &default_rateset);
	}

	/* sync up phy/radio chanspec */
	wlc_set_phy_chanspec(wlc, chanspec);
}

/* band-specific init */
static void WLBANDINITFN(wlc_bsinit) (struct wlc_info *wlc)
{
	WL_TRACE("wl%d: wlc_bsinit: bandunit %d\n",
		 wlc->pub->unit, wlc->band->bandunit);

	/* write ucode ACK/CTS rate table */
	wlc_set_ratetable(wlc);

	/* update some band specific mac configuration */
	wlc_ucode_mac_upd(wlc);

	/* init antenna selection */
	wlc_antsel_init(wlc->asi);

}

/* switch to and initialize new band */
static void WLBANDINITFN(wlc_setband) (struct wlc_info *wlc, uint bandunit)
{
	int idx;
	struct wlc_bsscfg *cfg;

	ASSERT(NBANDS(wlc) > 1);
	ASSERT(!wlc->bandlocked);
	ASSERT(bandunit != wlc->band->bandunit || wlc->bandinit_pending);

	wlc->band = wlc->bandstate[bandunit];

	if (!wlc->pub->up)
		return;

	/* wait for at least one beacon before entering sleeping state */
	wlc->PMawakebcn = true;
	FOREACH_AS_STA(wlc, idx, cfg)
	    cfg->PMawakebcn = true;
	wlc_set_ps_ctrl(wlc);

	/* band-specific initializations */
	wlc_bsinit(wlc);
}

/* Initialize a WME Parameter Info Element with default STA parameters from WMM Spec, Table 12 */
void wlc_wme_initparams_sta(struct wlc_info *wlc, wme_param_ie_t *pe)
{
	static const wme_param_ie_t stadef = {
		WME_OUI,
		WME_TYPE,
		WME_SUBTYPE_PARAM_IE,
		WME_VER,
		0,
		0,
		{
		 {EDCF_AC_BE_ACI_STA, EDCF_AC_BE_ECW_STA,
		  cpu_to_le16(EDCF_AC_BE_TXOP_STA)},
		 {EDCF_AC_BK_ACI_STA, EDCF_AC_BK_ECW_STA,
		  cpu_to_le16(EDCF_AC_BK_TXOP_STA)},
		 {EDCF_AC_VI_ACI_STA, EDCF_AC_VI_ECW_STA,
		  cpu_to_le16(EDCF_AC_VI_TXOP_STA)},
		 {EDCF_AC_VO_ACI_STA, EDCF_AC_VO_ECW_STA,
		  cpu_to_le16(EDCF_AC_VO_TXOP_STA)}
		 }
	};

	ASSERT(sizeof(*pe) == WME_PARAM_IE_LEN);
	memcpy(pe, &stadef, sizeof(*pe));
}

void wlc_wme_setparams(struct wlc_info *wlc, u16 aci, void *arg, bool suspend)
{
	int i;
	shm_acparams_t acp_shm;
	u16 *shm_entry;
	struct ieee80211_tx_queue_params *params = arg;

	ASSERT(wlc);

	/* Only apply params if the core is out of reset and has clocks */
	if (!wlc->clk) {
		WL_ERROR("wl%d: %s : no-clock\n", wlc->pub->unit, __func__);
		return;
	}

	/*
	 * AP uses AC params from wme_param_ie_ap.
	 * AP advertises AC params from wme_param_ie.
	 * STA uses AC params from wme_param_ie.
	 */

	wlc->wme_admctl = 0;

	do {
		memset((char *)&acp_shm, 0, sizeof(shm_acparams_t));
		/* find out which ac this set of params applies to */
		ASSERT(aci < AC_COUNT);
		/* set the admission control policy for this AC */
		/* wlc->wme_admctl |= 1 << aci; *//* should be set ??  seems like off by default */

		/* fill in shm ac params struct */
		acp_shm.txop = le16_to_cpu(params->txop);
		/* convert from units of 32us to us for ucode */
		wlc->edcf_txop[aci & 0x3] = acp_shm.txop =
		    EDCF_TXOP2USEC(acp_shm.txop);
		acp_shm.aifs = (params->aifs & EDCF_AIFSN_MASK);

		if (aci == AC_VI && acp_shm.txop == 0
		    && acp_shm.aifs < EDCF_AIFSN_MAX)
			acp_shm.aifs++;

		if (acp_shm.aifs < EDCF_AIFSN_MIN
		    || acp_shm.aifs > EDCF_AIFSN_MAX) {
			WL_ERROR("wl%d: wlc_edcf_setparams: bad aifs %d\n",
				 wlc->pub->unit, acp_shm.aifs);
			continue;
		}

		acp_shm.cwmin = params->cw_min;
		acp_shm.cwmax = params->cw_max;
		acp_shm.cwcur = acp_shm.cwmin;
		acp_shm.bslots =
		    R_REG(&wlc->regs->tsf_random) & acp_shm.cwcur;
		acp_shm.reggap = acp_shm.bslots + acp_shm.aifs;
		/* Indicate the new params to the ucode */
		acp_shm.status = wlc_read_shm(wlc, (M_EDCF_QINFO +
						    wme_shmemacindex(aci) *
						    M_EDCF_QLEN +
						    M_EDCF_STATUS_OFF));
		acp_shm.status |= WME_STATUS_NEWAC;

		/* Fill in shm acparam table */
		shm_entry = (u16 *) &acp_shm;
		for (i = 0; i < (int)sizeof(shm_acparams_t); i += 2)
			wlc_write_shm(wlc,
				      M_EDCF_QINFO +
				      wme_shmemacindex(aci) * M_EDCF_QLEN + i,
				      *shm_entry++);

	} while (0);

	if (suspend)
		wlc_suspend_mac_and_wait(wlc);

	if (suspend)
		wlc_enable_mac(wlc);

}

void wlc_edcf_setparams(struct wlc_bsscfg *cfg, bool suspend)
{
	struct wlc_info *wlc = cfg->wlc;
	uint aci, i, j;
	edcf_acparam_t *edcf_acp;
	shm_acparams_t acp_shm;
	u16 *shm_entry;

	ASSERT(cfg);
	ASSERT(wlc);

	/* Only apply params if the core is out of reset and has clocks */
	if (!wlc->clk)
		return;

	/*
	 * AP uses AC params from wme_param_ie_ap.
	 * AP advertises AC params from wme_param_ie.
	 * STA uses AC params from wme_param_ie.
	 */

	edcf_acp = (edcf_acparam_t *) &wlc->wme_param_ie.acparam[0];

	wlc->wme_admctl = 0;

	for (i = 0; i < AC_COUNT; i++, edcf_acp++) {
		memset((char *)&acp_shm, 0, sizeof(shm_acparams_t));
		/* find out which ac this set of params applies to */
		aci = (edcf_acp->ACI & EDCF_ACI_MASK) >> EDCF_ACI_SHIFT;
		ASSERT(aci < AC_COUNT);
		/* set the admission control policy for this AC */
		if (edcf_acp->ACI & EDCF_ACM_MASK) {
			wlc->wme_admctl |= 1 << aci;
		}

		/* fill in shm ac params struct */
		acp_shm.txop = le16_to_cpu(edcf_acp->TXOP);
		/* convert from units of 32us to us for ucode */
		wlc->edcf_txop[aci] = acp_shm.txop =
		    EDCF_TXOP2USEC(acp_shm.txop);
		acp_shm.aifs = (edcf_acp->ACI & EDCF_AIFSN_MASK);

		if (aci == AC_VI && acp_shm.txop == 0
		    && acp_shm.aifs < EDCF_AIFSN_MAX)
			acp_shm.aifs++;

		if (acp_shm.aifs < EDCF_AIFSN_MIN
		    || acp_shm.aifs > EDCF_AIFSN_MAX) {
			WL_ERROR("wl%d: wlc_edcf_setparams: bad aifs %d\n",
				 wlc->pub->unit, acp_shm.aifs);
			continue;
		}

		/* CWmin = 2^(ECWmin) - 1 */
		acp_shm.cwmin = EDCF_ECW2CW(edcf_acp->ECW & EDCF_ECWMIN_MASK);
		/* CWmax = 2^(ECWmax) - 1 */
		acp_shm.cwmax = EDCF_ECW2CW((edcf_acp->ECW & EDCF_ECWMAX_MASK)
					    >> EDCF_ECWMAX_SHIFT);
		acp_shm.cwcur = acp_shm.cwmin;
		acp_shm.bslots =
		    R_REG(&wlc->regs->tsf_random) & acp_shm.cwcur;
		acp_shm.reggap = acp_shm.bslots + acp_shm.aifs;
		/* Indicate the new params to the ucode */
		acp_shm.status = wlc_read_shm(wlc, (M_EDCF_QINFO +
						    wme_shmemacindex(aci) *
						    M_EDCF_QLEN +
						    M_EDCF_STATUS_OFF));
		acp_shm.status |= WME_STATUS_NEWAC;

		/* Fill in shm acparam table */
		shm_entry = (u16 *) &acp_shm;
		for (j = 0; j < (int)sizeof(shm_acparams_t); j += 2)
			wlc_write_shm(wlc,
				      M_EDCF_QINFO +
				      wme_shmemacindex(aci) * M_EDCF_QLEN + j,
				      *shm_entry++);
	}

	if (suspend)
		wlc_suspend_mac_and_wait(wlc);

	if (AP_ENAB(wlc->pub) && WME_ENAB(wlc->pub)) {
		wlc_update_beacon(wlc);
		wlc_update_probe_resp(wlc, false);
	}

	if (suspend)
		wlc_enable_mac(wlc);

}

bool wlc_timers_init(struct wlc_info *wlc, int unit)
{
	wlc->wdtimer = wl_init_timer(wlc->wl, wlc_watchdog_by_timer,
		wlc, "watchdog");
	if (!wlc->wdtimer) {
		WL_ERROR("wl%d:  wl_init_timer for wdtimer failed\n", unit);
		goto fail;
	}

	wlc->radio_timer = wl_init_timer(wlc->wl, wlc_radio_timer,
		wlc, "radio");
	if (!wlc->radio_timer) {
		WL_ERROR("wl%d:  wl_init_timer for radio_timer failed\n", unit);
		goto fail;
	}

	return true;

 fail:
	return false;
}

/*
 * Initialize wlc_info default values ...
 * may get overrides later in this function
 */
void wlc_info_init(struct wlc_info *wlc, int unit)
{
	int i;
	/* Assume the device is there until proven otherwise */
	wlc->device_present = true;

	/* set default power output percentage to 100 percent */
	wlc->txpwr_percent = 100;

	/* Save our copy of the chanspec */
	wlc->chanspec = CH20MHZ_CHSPEC(1);

	/* initialize CCK preamble mode to unassociated state */
	wlc->shortpreamble = false;

	wlc->legacy_probe = true;

	/* various 802.11g modes */
	wlc->shortslot = false;
	wlc->shortslot_override = WLC_SHORTSLOT_AUTO;

	wlc->barker_overlap_control = true;
	wlc->barker_preamble = WLC_BARKER_SHORT_ALLOWED;
	wlc->txburst_limit_override = AUTO;

	wlc_protection_upd(wlc, WLC_PROT_G_OVR, WLC_PROTECTION_AUTO);
	wlc_protection_upd(wlc, WLC_PROT_G_SPEC, false);

	wlc_protection_upd(wlc, WLC_PROT_N_CFG_OVR, WLC_PROTECTION_AUTO);
	wlc_protection_upd(wlc, WLC_PROT_N_CFG, WLC_N_PROTECTION_OFF);
	wlc_protection_upd(wlc, WLC_PROT_N_NONGF_OVR, WLC_PROTECTION_AUTO);
	wlc_protection_upd(wlc, WLC_PROT_N_NONGF, false);
	wlc_protection_upd(wlc, WLC_PROT_N_PAM_OVR, AUTO);

	wlc_protection_upd(wlc, WLC_PROT_OVERLAP, WLC_PROTECTION_CTL_OVERLAP);

	/* 802.11g draft 4.0 NonERP elt advertisement */
	wlc->include_legacy_erp = true;

	wlc->stf->ant_rx_ovr = ANT_RX_DIV_DEF;
	wlc->stf->txant = ANT_TX_DEF;

	wlc->prb_resp_timeout = WLC_PRB_RESP_TIMEOUT;

	wlc->usr_fragthresh = DOT11_DEFAULT_FRAG_LEN;
	for (i = 0; i < NFIFO; i++)
		wlc->fragthresh[i] = DOT11_DEFAULT_FRAG_LEN;
	wlc->RTSThresh = DOT11_DEFAULT_RTS_LEN;

	/* default rate fallback retry limits */
	wlc->SFBL = RETRY_SHORT_FB;
	wlc->LFBL = RETRY_LONG_FB;

	/* default mac retry limits */
	wlc->SRL = RETRY_SHORT_DEF;
	wlc->LRL = RETRY_LONG_DEF;

	/* init PM state */
	wlc->PM = PM_OFF;	/* User's setting of PM mode through IOCTL */
	wlc->PM_override = false;	/* Prevents from going to PM if our AP is 'ill' */
	wlc->PMenabled = false;	/* Current PM state */
	wlc->PMpending = false;	/* Tracks whether STA indicated PM in the last attempt */
	wlc->PMblocked = false;	/* To allow blocking going into PM during RM and scans */

	/* In WMM Auto mode, PM is allowed if association is a UAPSD association */
	wlc->WME_PM_blocked = false;

	/* Init wme queuing method */
	wlc->wme_prec_queuing = false;

	/* Overrides for the core to stay awake under zillion conditions Look for STAY_AWAKE */
	wlc->wake = false;
	/* Are we waiting for a response to PS-Poll that we sent */
	wlc->PSpoll = false;

	/* APSD defaults */
	wlc->wme_apsd = true;
	wlc->apsd_sta_usp = false;
	wlc->apsd_trigger_timeout = 0;	/* disable the trigger timer */
	wlc->apsd_trigger_ac = AC_BITMAP_ALL;

	/* Set flag to indicate that hw keys should be used when available. */
	wlc->wsec_swkeys = false;

	/* init the 4 static WEP default keys */
	for (i = 0; i < WSEC_MAX_DEFAULT_KEYS; i++) {
		wlc->wsec_keys[i] = wlc->wsec_def_keys[i];
		wlc->wsec_keys[i]->idx = (u8) i;
	}

	wlc->_regulatory_domain = false;	/* 802.11d */

	/* WME QoS mode is Auto by default */
	wlc->pub->_wme = AUTO;

#ifdef BCMSDIODEV_ENABLED
	wlc->pub->_priofc = true;	/* enable priority flow control for sdio dongle */
#endif

	wlc->pub->_ampdu = AMPDU_AGG_HOST;
	wlc->pub->bcmerror = 0;
	wlc->ibss_allowed = true;
	wlc->ibss_coalesce_allowed = true;
	wlc->pub->_coex = ON;

	/* initialize mpc delay */
	wlc->mpc_delay_off = wlc->mpc_dlycnt = WLC_MPC_MIN_DELAYCNT;

	wlc->pr80838_war = true;
}

static bool wlc_state_bmac_sync(struct wlc_info *wlc)
{
	wlc_bmac_state_t state_bmac;

	if (wlc_bmac_state_get(wlc->hw, &state_bmac) != 0)
		return false;

	wlc->machwcap = state_bmac.machwcap;
	wlc_protection_upd(wlc, WLC_PROT_N_PAM_OVR,
			   (s8) state_bmac.preamble_ovr);

	return true;
}

static uint wlc_attach_module(struct wlc_info *wlc)
{
	uint err = 0;
	uint unit;
	unit = wlc->pub->unit;

	wlc->asi = wlc_antsel_attach(wlc);
	if (wlc->asi == NULL) {
		WL_ERROR("wl%d: wlc_attach: wlc_antsel_attach failed\n", unit);
		err = 44;
		goto fail;
	}

	wlc->ampdu = wlc_ampdu_attach(wlc);
	if (wlc->ampdu == NULL) {
		WL_ERROR("wl%d: wlc_attach: wlc_ampdu_attach failed\n", unit);
		err = 50;
		goto fail;
	}

	if ((wlc_stf_attach(wlc) != 0)) {
		WL_ERROR("wl%d: wlc_attach: wlc_stf_attach failed\n", unit);
		err = 68;
		goto fail;
	}
 fail:
	return err;
}

struct wlc_pub *wlc_pub(void *wlc)
{
	return ((struct wlc_info *) wlc)->pub;
}

#define CHIP_SUPPORTS_11N(wlc) 	1

/*
 * The common driver entry routine. Error codes should be unique
 */
void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode,
		 void *regsva, uint bustype, void *btparam, uint *perr)
{
	struct wlc_info *wlc;
	uint err = 0;
	uint j;
	struct wlc_pub *pub;
	struct wlc_txq_info *qi;
	uint n_disabled;

	WL_NONE("wl%d: %s: vendor 0x%x device 0x%x\n",
		unit, __func__, vendor, device);

	ASSERT(WSEC_MAX_RCMTA_KEYS <= WSEC_MAX_KEYS);
	ASSERT(WSEC_MAX_DEFAULT_KEYS == WLC_DEFAULT_KEYS);

	/* some code depends on packed structures */
	ASSERT(sizeof(struct ethhdr) == ETH_HLEN);
	ASSERT(sizeof(d11regs_t) == SI_CORE_SIZE);
	ASSERT(sizeof(ofdm_phy_hdr_t) == D11_PHY_HDR_LEN);
	ASSERT(sizeof(cck_phy_hdr_t) == D11_PHY_HDR_LEN);
	ASSERT(sizeof(d11txh_t) == D11_TXH_LEN);
	ASSERT(sizeof(d11rxhdr_t) == RXHDR_LEN);
	ASSERT(sizeof(struct ieee80211_hdr) == DOT11_A4_HDR_LEN);
	ASSERT(sizeof(struct ieee80211_rts) == DOT11_RTS_LEN);
	ASSERT(sizeof(tx_status_t) == TXSTATUS_LEN);
	ASSERT(sizeof(struct ieee80211_ht_cap) == HT_CAP_IE_LEN);
#ifdef BRCM_FULLMAC
	ASSERT(offsetof(wl_scan_params_t, channel_list) ==
	       WL_SCAN_PARAMS_FIXED_SIZE);
#endif
	ASSERT(IS_ALIGNED(offsetof(wsec_key_t, data), sizeof(u32)));
	ASSERT(ISPOWEROF2(MA_WINDOW_SZ));

	ASSERT(sizeof(wlc_d11rxhdr_t) <= WL_HWRXOFF);

	/*
	 * Number of replay counters value used in WPA IE must match # rxivs
	 * supported in wsec_key_t struct. See 802.11i/D3.0 sect. 7.3.2.17
	 * 'RSN Information Element' figure 8 for this mapping.
	 */
	ASSERT((WPA_CAP_16_REPLAY_CNTRS == WLC_REPLAY_CNTRS_VALUE
		&& 16 == WLC_NUMRXIVS)
	       || (WPA_CAP_4_REPLAY_CNTRS == WLC_REPLAY_CNTRS_VALUE
		   && 4 == WLC_NUMRXIVS));

	/* allocate struct wlc_info state and its substructures */
	wlc = (struct wlc_info *) wlc_attach_malloc(unit, &err, device);
	if (wlc == NULL)
		goto fail;
	pub = wlc->pub;

#if defined(BCMDBG)
	wlc_info_dbg = wlc;
#endif

	wlc->band = wlc->bandstate[0];
	wlc->core = wlc->corestate;
	wlc->wl = wl;
	pub->unit = unit;
	wlc->btparam = btparam;
	pub->_piomode = piomode;
	wlc->bandinit_pending = false;
	/* By default restrict TKIP associations from 11n STA's */
	wlc->ht_wsec_restriction = WLC_HT_TKIP_RESTRICT;

	/* populate struct wlc_info with default values  */
	wlc_info_init(wlc, unit);

	/* update sta/ap related parameters */
	wlc_ap_upd(wlc);

	/* 11n_disable nvram */
	n_disabled = getintvar(pub->vars, "11n_disable");

	/* register a module (to handle iovars) */
	wlc_module_register(wlc->pub, wlc_iovars, "wlc_iovars", wlc,
			    wlc_doiovar, NULL, NULL);

	/*
	 * low level attach steps(all hw accesses go
	 * inside, no more in rest of the attach)
	 */
	err = wlc_bmac_attach(wlc, vendor, device, unit, piomode, regsva,
			      bustype, btparam);
	if (err)
		goto fail;

	/* for some states, due to different info pointer(e,g, wlc, wlc_hw) or master/slave split,
	 * HIGH driver(both monolithic and HIGH_ONLY) needs to sync states FROM BMAC portion driver
	 */
	if (!wlc_state_bmac_sync(wlc)) {
		err = 20;
		goto fail;
	}

	pub->phy_11ncapable = WLC_PHY_11N_CAP(wlc->band);

	/* propagate *vars* from BMAC driver to high driver */
	wlc_bmac_copyfrom_vars(wlc->hw, &pub->vars, &wlc->vars_size);


	/* set maximum allowed duty cycle */
	wlc->tx_duty_cycle_ofdm =
	    (u16) getintvar(pub->vars, "tx_duty_cycle_ofdm");
	wlc->tx_duty_cycle_cck =
	    (u16) getintvar(pub->vars, "tx_duty_cycle_cck");

	wlc_stf_phy_chain_calc(wlc);

	/* txchain 1: txant 0, txchain 2: txant 1 */
	if (WLCISNPHY(wlc->band) && (wlc->stf->txstreams == 1))
		wlc->stf->txant = wlc->stf->hw_txchain - 1;

	/* push to BMAC driver */
	wlc_phy_stf_chain_init(wlc->band->pi, wlc->stf->hw_txchain,
			       wlc->stf->hw_rxchain);

	/* pull up some info resulting from the low attach */
	{
		int i;
		for (i = 0; i < NFIFO; i++)
			wlc->core->txavail[i] = wlc->hw->txavail[i];
	}

	wlc_bmac_hw_etheraddr(wlc->hw, wlc->perm_etheraddr);

	memcpy(&pub->cur_etheraddr, &wlc->perm_etheraddr, ETH_ALEN);

	for (j = 0; j < NBANDS(wlc); j++) {
		/* Use band 1 for single band 11a */
		if (IS_SINGLEBAND_5G(wlc->deviceid))
			j = BAND_5G_INDEX;

		wlc->band = wlc->bandstate[j];

		if (!wlc_attach_stf_ant_init(wlc)) {
			err = 24;
			goto fail;
		}

		/* default contention windows size limits */
		wlc->band->CWmin = APHY_CWMIN;
		wlc->band->CWmax = PHY_CWMAX;

		/* init gmode value */
		if (BAND_2G(wlc->band->bandtype)) {
			wlc->band->gmode = GMODE_AUTO;
			wlc_protection_upd(wlc, WLC_PROT_G_USER,
					   wlc->band->gmode);
		}

		/* init _n_enab supported mode */
		if (WLC_PHY_11N_CAP(wlc->band) && CHIP_SUPPORTS_11N(wlc)) {
			if (n_disabled & WLFEATURE_DISABLE_11N) {
				pub->_n_enab = OFF;
				wlc_protection_upd(wlc, WLC_PROT_N_USER, OFF);
			} else {
				pub->_n_enab = SUPPORT_11N;
				wlc_protection_upd(wlc, WLC_PROT_N_USER,
						   ((pub->_n_enab ==
						     SUPPORT_11N) ? WL_11N_2x2 :
						    WL_11N_3x3));
			}
		}

		/* init per-band default rateset, depend on band->gmode */
		wlc_default_rateset(wlc, &wlc->band->defrateset);

		/* fill in hw_rateset (used early by WLC_SET_RATESET) */
		wlc_rateset_filter(&wlc->band->defrateset,
				   &wlc->band->hw_rateset, false,
				   WLC_RATES_CCK_OFDM, RATE_MASK,
				   (bool) N_ENAB(wlc->pub));
	}

	/* update antenna config due to wlc->stf->txant/txchain/ant_rx_ovr change */
	wlc_stf_phy_txant_upd(wlc);

	/* attach each modules */
	err = wlc_attach_module(wlc);
	if (err != 0)
		goto fail;

	if (!wlc_timers_init(wlc, unit)) {
		WL_ERROR("wl%d: %s: wlc_init_timer failed\n", unit, __func__);
		err = 32;
		goto fail;
	}

	/* depend on rateset, gmode */
	wlc->cmi = wlc_channel_mgr_attach(wlc);
	if (!wlc->cmi) {
		WL_ERROR("wl%d: %s: wlc_channel_mgr_attach failed\n",
			 unit, __func__);
		err = 33;
		goto fail;
	}

	/* init default when all parameters are ready, i.e. ->rateset */
	wlc_bss_default_init(wlc);

	/*
	 * Complete the wlc default state initializations..
	 */

	/* allocate our initial queue */
	qi = wlc_txq_alloc(wlc);
	if (qi == NULL) {
		WL_ERROR("wl%d: %s: failed to malloc tx queue\n",
			 unit, __func__);
		err = 100;
		goto fail;
	}
	wlc->active_queue = qi;

	wlc->bsscfg[0] = wlc->cfg;
	wlc->cfg->_idx = 0;
	wlc->cfg->wlc = wlc;
	pub->txmaxpkts = MAXTXPKTS;

	pub->_cnt->version = WL_CNT_T_VERSION;
	pub->_cnt->length = sizeof(struct wl_cnt);

	WLCNTSET(pub->_wme_cnt->version, WL_WME_CNT_VERSION);
	WLCNTSET(pub->_wme_cnt->length, sizeof(wl_wme_cnt_t));

	wlc_wme_initparams_sta(wlc, &wlc->wme_param_ie);

	wlc->mimoft = FT_HT;
	wlc->ht_cap.cap_info = HT_CAP;
	if (HT_ENAB(wlc->pub))
		wlc->stf->ldpc = AUTO;

	wlc->mimo_40txbw = AUTO;
	wlc->ofdm_40txbw = AUTO;
	wlc->cck_40txbw = AUTO;
	wlc_update_mimo_band_bwcap(wlc, WLC_N_BW_20IN2G_40IN5G);

	/* Enable setting the RIFS Mode bit by default in HT Info IE */
	wlc->rifs_advert = AUTO;

	/* Set default values of SGI */
	if (WLC_SGI_CAP_PHY(wlc)) {
		wlc_ht_update_sgi_rx(wlc, (WLC_N_SGI_20 | WLC_N_SGI_40));
		wlc->sgi_tx = AUTO;
	} else if (WLCISSSLPNPHY(wlc->band)) {
		wlc_ht_update_sgi_rx(wlc, (WLC_N_SGI_20 | WLC_N_SGI_40));
		wlc->sgi_tx = AUTO;
	} else {
		wlc_ht_update_sgi_rx(wlc, 0);
		wlc->sgi_tx = OFF;
	}

	/* *******nvram 11n config overrides Start ********* */

	/* apply the sgi override from nvram conf */
	if (n_disabled & WLFEATURE_DISABLE_11N_SGI_TX)
		wlc->sgi_tx = OFF;

	if (n_disabled & WLFEATURE_DISABLE_11N_SGI_RX)
		wlc_ht_update_sgi_rx(wlc, 0);

	/* apply the stbc override from nvram conf */
	if (n_disabled & WLFEATURE_DISABLE_11N_STBC_TX) {
		wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = OFF;
		wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = OFF;
		wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_TX_STBC;
	}
	if (n_disabled & WLFEATURE_DISABLE_11N_STBC_RX)
		wlc_stf_stbc_rx_set(wlc, HT_CAP_RX_STBC_NO);

	/* apply the GF override from nvram conf */
	if (n_disabled & WLFEATURE_DISABLE_11N_GF)
		wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_GRN_FLD;

	/* initialize radio_mpc_disable according to wlc->mpc */
	wlc_radio_mpc_upd(wlc);

	if ((wlc->pub->sih->chip) == BCM43235_CHIP_ID) {
		if ((getintvar(wlc->pub->vars, "aa2g") == 7) ||
		    (getintvar(wlc->pub->vars, "aa5g") == 7)) {
			wlc_bmac_antsel_set(wlc->hw, 1);
		}
	} else {
		wlc_bmac_antsel_set(wlc->hw, wlc->asi->antsel_avail);
	}

	if (perr)
		*perr = 0;

	return (void *)wlc;

 fail:
	WL_ERROR("wl%d: %s: failed with err %d\n", unit, __func__, err);
	if (wlc)
		wlc_detach(wlc);

	if (perr)
		*perr = err;
	return NULL;
}

static void wlc_attach_antgain_init(struct wlc_info *wlc)
{
	uint unit;
	unit = wlc->pub->unit;

	if ((wlc->band->antgain == -1) && (wlc->pub->sromrev == 1)) {
		/* default antenna gain for srom rev 1 is 2 dBm (8 qdbm) */
		wlc->band->antgain = 8;
	} else if (wlc->band->antgain == -1) {
		WL_ERROR("wl%d: %s: Invalid antennas available in srom, using 2dB\n",
			 unit, __func__);
		wlc->band->antgain = 8;
	} else {
		s8 gain, fract;
		/* Older sroms specified gain in whole dbm only.  In order
		 * be able to specify qdbm granularity and remain backward compatible
		 * the whole dbms are now encoded in only low 6 bits and remaining qdbms
		 * are encoded in the hi 2 bits. 6 bit signed number ranges from
		 * -32 - 31. Examples: 0x1 = 1 db,
		 * 0xc1 = 1.75 db (1 + 3 quarters),
		 * 0x3f = -1 (-1 + 0 quarters),
		 * 0x7f = -.75 (-1 in low 6 bits + 1 quarters in hi 2 bits) = -3 qdbm.
		 * 0xbf = -.50 (-1 in low 6 bits + 2 quarters in hi 2 bits) = -2 qdbm.
		 */
		gain = wlc->band->antgain & 0x3f;
		gain <<= 2;	/* Sign extend */
		gain >>= 2;
		fract = (wlc->band->antgain & 0xc0) >> 6;
		wlc->band->antgain = 4 * gain + fract;
	}
}

static bool wlc_attach_stf_ant_init(struct wlc_info *wlc)
{
	int aa;
	uint unit;
	char *vars;
	int bandtype;

	unit = wlc->pub->unit;
	vars = wlc->pub->vars;
	bandtype = wlc->band->bandtype;

	/* get antennas available */
	aa = (s8) getintvar(vars, (BAND_5G(bandtype) ? "aa5g" : "aa2g"));
	if (aa == 0)
		aa = (s8) getintvar(vars,
				      (BAND_5G(bandtype) ? "aa1" : "aa0"));
	if ((aa < 1) || (aa > 15)) {
		WL_ERROR("wl%d: %s: Invalid antennas available in srom (0x%x), using 3\n",
			 unit, __func__, aa);
		aa = 3;
	}

	/* reset the defaults if we have a single antenna */
	if (aa == 1) {
		wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_0;
		wlc->stf->txant = ANT_TX_FORCE_0;
	} else if (aa == 2) {
		wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_1;
		wlc->stf->txant = ANT_TX_FORCE_1;
	} else {
	}

	/* Compute Antenna Gain */
	wlc->band->antgain =
	    (s8) getintvar(vars, (BAND_5G(bandtype) ? "ag1" : "ag0"));
	wlc_attach_antgain_init(wlc);

	return true;
}


static void wlc_timers_deinit(struct wlc_info *wlc)
{
	/* free timer state */
	if (wlc->wdtimer) {
		wl_free_timer(wlc->wl, wlc->wdtimer);
		wlc->wdtimer = NULL;
	}
	if (wlc->radio_timer) {
		wl_free_timer(wlc->wl, wlc->radio_timer);
		wlc->radio_timer = NULL;
	}
}

static void wlc_detach_module(struct wlc_info *wlc)
{
	if (wlc->asi) {
		wlc_antsel_detach(wlc->asi);
		wlc->asi = NULL;
	}

	if (wlc->ampdu) {
		wlc_ampdu_detach(wlc->ampdu);
		wlc->ampdu = NULL;
	}

	wlc_stf_detach(wlc);
}

/*
 * Return a count of the number of driver callbacks still pending.
 *
 * General policy is that wlc_detach can only dealloc/free software states. It can NOT
 *  touch hardware registers since the d11core may be in reset and clock may not be available.
 *    One exception is sb register access, which is possible if crystal is turned on
 * After "down" state, driver should avoid software timer with the exception of radio_monitor.
 */
uint wlc_detach(struct wlc_info *wlc)
{
	uint i;
	uint callbacks = 0;

	if (wlc == NULL)
		return 0;

	WL_TRACE("wl%d: %s\n", wlc->pub->unit, __func__);

	ASSERT(!wlc->pub->up);

	callbacks += wlc_bmac_detach(wlc);

	/* delete software timers */
	if (!wlc_radio_monitor_stop(wlc))
		callbacks++;

	wlc_channel_mgr_detach(wlc->cmi);

	wlc_timers_deinit(wlc);

	wlc_detach_module(wlc);

	/* free other state */


#ifdef BCMDBG
	kfree(wlc->country_ie_override);
	wlc->country_ie_override = NULL;
#endif				/* BCMDBG */

	{
		/* free dumpcb list */
		struct dumpcb_s *prev, *ptr;
		prev = ptr = wlc->dumpcb_head;
		while (ptr) {
			ptr = prev->next;
			kfree(prev);
			prev = ptr;
		}
		wlc->dumpcb_head = NULL;
	}

	/* Detach from iovar manager */
	wlc_module_unregister(wlc->pub, "wlc_iovars", wlc);

	while (wlc->tx_queues != NULL)
		wlc_txq_free(wlc, wlc->tx_queues);

	/*
	 * consistency check: wlc_module_register/wlc_module_unregister calls
	 * should match therefore nothing should be left here.
	 */
	for (i = 0; i < WLC_MAXMODULES; i++)
		ASSERT(wlc->modulecb[i].name[0] == '\0');

	wlc_detach_mfree(wlc);
	return callbacks;
}

/* update state that depends on the current value of "ap" */
void wlc_ap_upd(struct wlc_info *wlc)
{
	if (AP_ENAB(wlc->pub))
		wlc->PLCPHdr_override = WLC_PLCP_AUTO;	/* AP: short not allowed, but not enforced */
	else
		wlc->PLCPHdr_override = WLC_PLCP_SHORT;	/* STA-BSS; short capable */

	/* disable vlan_mode on AP since some legacy STAs cannot rx tagged pkts */
	wlc->vlan_mode = AP_ENAB(wlc->pub) ? OFF : AUTO;

	/* fixup mpc */
	wlc->mpc = true;
}

/* read hwdisable state and propagate to wlc flag */
static void wlc_radio_hwdisable_upd(struct wlc_info *wlc)
{
	if (wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO || wlc->pub->hw_off)
		return;

	if (wlc_bmac_radio_read_hwdisabled(wlc->hw)) {
		mboolset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE);
	} else {
		mboolclr(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE);
	}
}

/* return true if Minimum Power Consumption should be entered, false otherwise */
bool wlc_is_non_delay_mpc(struct wlc_info *wlc)
{
	return false;
}

bool wlc_ismpc(struct wlc_info *wlc)
{
	return (wlc->mpc_delay_off == 0) && (wlc_is_non_delay_mpc(wlc));
}

void wlc_radio_mpc_upd(struct wlc_info *wlc)
{
	bool mpc_radio, radio_state;

	/*
	 * Clear the WL_RADIO_MPC_DISABLE bit when mpc feature is disabled
	 * in case the WL_RADIO_MPC_DISABLE bit was set. Stop the radio
	 * monitor also when WL_RADIO_MPC_DISABLE is the only reason that
	 * the radio is going down.
	 */
	if (!wlc->mpc) {
		if (!wlc->pub->radio_disabled)
			return;
		mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE);
		wlc_radio_upd(wlc);
		if (!wlc->pub->radio_disabled)
			wlc_radio_monitor_stop(wlc);
		return;
	}

	/*
	 * sync ismpc logic with WL_RADIO_MPC_DISABLE bit in wlc->pub->radio_disabled
	 * to go ON, always call radio_upd synchronously
	 * to go OFF, postpone radio_upd to later when context is safe(e.g. watchdog)
	 */
	radio_state =
	    (mboolisset(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE) ? OFF :
	     ON);
	mpc_radio = (wlc_ismpc(wlc) == true) ? OFF : ON;

	if (radio_state == ON && mpc_radio == OFF)
		wlc->mpc_delay_off = wlc->mpc_dlycnt;
	else if (radio_state == OFF && mpc_radio == ON) {
		mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE);
		wlc_radio_upd(wlc);
		if (wlc->mpc_offcnt < WLC_MPC_THRESHOLD) {
			wlc->mpc_dlycnt = WLC_MPC_MAX_DELAYCNT;
		} else
			wlc->mpc_dlycnt = WLC_MPC_MIN_DELAYCNT;
		wlc->mpc_dur += OSL_SYSUPTIME() - wlc->mpc_laston_ts;
	}
	/* Below logic is meant to capture the transition from mpc off to mpc on for reasons
	 * other than wlc->mpc_delay_off keeping the mpc off. In that case reset
	 * wlc->mpc_delay_off to wlc->mpc_dlycnt, so that we restart the countdown of mpc_delay_off
	 */
	if ((wlc->prev_non_delay_mpc == false) &&
	    (wlc_is_non_delay_mpc(wlc) == true) && wlc->mpc_delay_off) {
		wlc->mpc_delay_off = wlc->mpc_dlycnt;
	}
	wlc->prev_non_delay_mpc = wlc_is_non_delay_mpc(wlc);
}

/*
 * centralized radio disable/enable function,
 * invoke radio enable/disable after updating hwradio status
 */
static void wlc_radio_upd(struct wlc_info *wlc)
{
	if (wlc->pub->radio_disabled) {
		wlc_radio_disable(wlc);
	} else {
		wlc_radio_enable(wlc);
	}
}

/* maintain LED behavior in down state */
static void wlc_down_led_upd(struct wlc_info *wlc)
{
	ASSERT(!wlc->pub->up);

	/* maintain LEDs while in down state, turn on sbclk if not available yet */
	/* turn on sbclk if necessary */
	if (!AP_ENAB(wlc->pub)) {
		wlc_pllreq(wlc, true, WLC_PLLREQ_FLIP);

		wlc_pllreq(wlc, false, WLC_PLLREQ_FLIP);
	}
}

/* update hwradio status and return it */
bool wlc_check_radio_disabled(struct wlc_info *wlc)
{
	wlc_radio_hwdisable_upd(wlc);

	return mboolisset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE) ? true : false;
}

void wlc_radio_disable(struct wlc_info *wlc)
{
	if (!wlc->pub->up) {
		wlc_down_led_upd(wlc);
		return;
	}

	wlc_radio_monitor_start(wlc);
	wl_down(wlc->wl);
}

static void wlc_radio_enable(struct wlc_info *wlc)
{
	if (wlc->pub->up)
		return;

	if (DEVICEREMOVED(wlc))
		return;

	if (!wlc->down_override) {	/* imposed by wl down/out ioctl */
		wl_up(wlc->wl);
	}
}

/* periodical query hw radio button while driver is "down" */
static void wlc_radio_timer(void *arg)
{
	struct wlc_info *wlc = (struct wlc_info *) arg;

	if (DEVICEREMOVED(wlc)) {
		WL_ERROR("wl%d: %s: dead chip\n", wlc->pub->unit, __func__);
		wl_down(wlc->wl);
		return;
	}

	/* cap mpc off count */
	if (wlc->mpc_offcnt < WLC_MPC_MAX_DELAYCNT)
		wlc->mpc_offcnt++;

	/* validate all the reasons driver could be down and running this radio_timer */
	ASSERT(wlc->pub->radio_disabled || wlc->down_override);
	wlc_radio_hwdisable_upd(wlc);
	wlc_radio_upd(wlc);
}

static bool wlc_radio_monitor_start(struct wlc_info *wlc)
{
	/* Don't start the timer if HWRADIO feature is disabled */
	if (wlc->radio_monitor || (wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO))
		return true;

	wlc->radio_monitor = true;
	wlc_pllreq(wlc, true, WLC_PLLREQ_RADIO_MON);
	wl_add_timer(wlc->wl, wlc->radio_timer, TIMER_INTERVAL_RADIOCHK, true);
	return true;
}

bool wlc_radio_monitor_stop(struct wlc_info *wlc)
{
	if (!wlc->radio_monitor)
		return true;

	ASSERT((wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO) !=
	       WL_SWFL_NOHWRADIO);

	wlc->radio_monitor = false;
	wlc_pllreq(wlc, false, WLC_PLLREQ_RADIO_MON);
	return wl_del_timer(wlc->wl, wlc->radio_timer);
}

/* bring the driver down, but don't reset hardware */
void wlc_out(struct wlc_info *wlc)
{
	wlc_bmac_set_noreset(wlc->hw, true);
	wlc_radio_upd(wlc);
	wl_down(wlc->wl);
	wlc_bmac_set_noreset(wlc->hw, false);

	/* core clk is true in BMAC driver due to noreset, need to mirror it in HIGH */
	wlc->clk = true;

	/* This will make sure that when 'up' is done
	 * after 'out' it'll restore hardware (especially gpios)
	 */
	wlc->pub->hw_up = false;
}

#if defined(BCMDBG)
/* Verify the sanity of wlc->tx_prec_map. This can be done only by making sure that
 * if there is no packet pending for the FIFO, then the corresponding prec bits should be set
 * in prec_map. Of course, ignore this rule when block_datafifo is set
 */
static bool wlc_tx_prec_map_verify(struct wlc_info *wlc)
{
	/* For non-WME, both fifos have overlapping prec_map. So it's an error only if both
	 * fail the check.
	 */
	if (!EDCF_ENAB(wlc->pub)) {
		if (!(WLC_TX_FIFO_CHECK(wlc, TX_DATA_FIFO) ||
		      WLC_TX_FIFO_CHECK(wlc, TX_CTL_FIFO)))
			return false;
		else
			return true;
	}

	return WLC_TX_FIFO_CHECK(wlc, TX_AC_BK_FIFO)
		&& WLC_TX_FIFO_CHECK(wlc, TX_AC_BE_FIFO)
		&& WLC_TX_FIFO_CHECK(wlc, TX_AC_VI_FIFO)
		&& WLC_TX_FIFO_CHECK(wlc, TX_AC_VO_FIFO);
}
#endif				/* BCMDBG */

static void wlc_watchdog_by_timer(void *arg)
{
	struct wlc_info *wlc = (struct wlc_info *) arg;
	wlc_watchdog(arg);
	if (WLC_WATCHDOG_TBTT(wlc)) {
		/* set to normal osl watchdog period */
		wl_del_timer(wlc->wl, wlc->wdtimer);
		wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG,
			     true);
	}
}

/* common watchdog code */
static void wlc_watchdog(void *arg)
{
	struct wlc_info *wlc = (struct wlc_info *) arg;
	int i;
	struct wlc_bsscfg *cfg;

	WL_TRACE("wl%d: wlc_watchdog\n", wlc->pub->unit);

	if (!wlc->pub->up)
		return;

	if (DEVICEREMOVED(wlc)) {
		WL_ERROR("wl%d: %s: dead chip\n", wlc->pub->unit, __func__);
		wl_down(wlc->wl);
		return;
	}

	/* increment second count */
	wlc->pub->now++;

	/* delay radio disable */
	if (wlc->mpc_delay_off) {
		if (--wlc->mpc_delay_off == 0) {
			mboolset(wlc->pub->radio_disabled,
				 WL_RADIO_MPC_DISABLE);
			if (wlc->mpc && wlc_ismpc(wlc))
				wlc->mpc_offcnt = 0;
			wlc->mpc_laston_ts = OSL_SYSUPTIME();
		}
	}

	/* mpc sync */
	wlc_radio_mpc_upd(wlc);
	/* radio sync: sw/hw/mpc --> radio_disable/radio_enable */
	wlc_radio_hwdisable_upd(wlc);
	wlc_radio_upd(wlc);
	/* if ismpc, driver should be in down state if up/down is allowed */
	if (wlc->mpc && wlc_ismpc(wlc))
		ASSERT(!wlc->pub->up);
	/* if radio is disable, driver may be down, quit here */
	if (wlc->pub->radio_disabled)
		return;

	wlc_bmac_watchdog(wlc);

	/* occasionally sample mac stat counters to detect 16-bit counter wrap */
	if ((wlc->pub->now % SW_TIMER_MAC_STAT_UPD) == 0)
		wlc_statsupd(wlc);

	/* Manage TKIP countermeasures timers */
	FOREACH_BSS(wlc, i, cfg) {
		if (cfg->tk_cm_dt) {
			cfg->tk_cm_dt--;
		}
		if (cfg->tk_cm_bt) {
			cfg->tk_cm_bt--;
		}
	}

	/* Call any registered watchdog handlers */
	for (i = 0; i < WLC_MAXMODULES; i++) {
		if (wlc->modulecb[i].watchdog_fn)
			wlc->modulecb[i].watchdog_fn(wlc->modulecb[i].hdl);
	}

	if (WLCISNPHY(wlc->band) && !wlc->pub->tempsense_disable &&
	    ((wlc->pub->now - wlc->tempsense_lasttime) >=
	     WLC_TEMPSENSE_PERIOD)) {
		wlc->tempsense_lasttime = wlc->pub->now;
		wlc_tempsense_upd(wlc);
	}
	/* BMAC_NOTE: for HIGH_ONLY driver, this seems being called after RPC bus failed */
	ASSERT(wlc_bmac_taclear(wlc->hw, true));

	/* Verify that tx_prec_map and fifos are in sync to avoid lock ups */
	ASSERT(wlc_tx_prec_map_verify(wlc));

	ASSERT(wlc_ps_check(wlc));
}

/* make interface operational */
int wlc_up(struct wlc_info *wlc)
{
	WL_TRACE("wl%d: %s:\n", wlc->pub->unit, __func__);

	/* HW is turned off so don't try to access it */
	if (wlc->pub->hw_off || DEVICEREMOVED(wlc))
		return BCME_RADIOOFF;

	if (!wlc->pub->hw_up) {
		wlc_bmac_hw_up(wlc->hw);
		wlc->pub->hw_up = true;
	}

	if ((wlc->pub->boardflags & BFL_FEM)
	    && (wlc->pub->sih->chip == BCM4313_CHIP_ID)) {
		if (wlc->pub->boardrev >= 0x1250
		    && (wlc->pub->boardflags & BFL_FEM_BT)) {
			wlc_mhf(wlc, MHF5, MHF5_4313_GPIOCTRL,
				MHF5_4313_GPIOCTRL, WLC_BAND_ALL);
		} else {
			wlc_mhf(wlc, MHF4, MHF4_EXTPA_ENABLE, MHF4_EXTPA_ENABLE,
				WLC_BAND_ALL);
		}
	}

	/*
	 * Need to read the hwradio status here to cover the case where the system
	 * is loaded with the hw radio disabled. We do not want to bring the driver up in this case.
	 * if radio is disabled, abort up, lower power, start radio timer and return 0(for NDIS)
	 * don't call radio_update to avoid looping wlc_up.
	 *
	 * wlc_bmac_up_prep() returns either 0 or BCME_RADIOOFF only
	 */
	if (!wlc->pub->radio_disabled) {
		int status = wlc_bmac_up_prep(wlc->hw);
		if (status == BCME_RADIOOFF) {
			if (!mboolisset
			    (wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE)) {
				int idx;
				struct wlc_bsscfg *bsscfg;
				mboolset(wlc->pub->radio_disabled,
					 WL_RADIO_HW_DISABLE);

				FOREACH_BSS(wlc, idx, bsscfg) {
					if (!BSSCFG_STA(bsscfg)
					    || !bsscfg->enable || !bsscfg->BSS)
						continue;
					WL_ERROR("wl%d.%d: wlc_up: rfdisable -> " "wlc_bsscfg_disable()\n",
						 wlc->pub->unit, idx);
				}
			}
		} else
			ASSERT(!status);
	}

	if (wlc->pub->radio_disabled) {
		wlc_radio_monitor_start(wlc);
		return 0;
	}

	/* wlc_bmac_up_prep has done wlc_corereset(). so clk is on, set it */
	wlc->clk = true;

	wlc_radio_monitor_stop(wlc);

	/* Set EDCF hostflags */
	if (EDCF_ENAB(wlc->pub)) {
		wlc_mhf(wlc, MHF1, MHF1_EDCF, MHF1_EDCF, WLC_BAND_ALL);
	} else {
		wlc_mhf(wlc, MHF1, MHF1_EDCF, 0, WLC_BAND_ALL);
	}

	if (WLC_WAR16165(wlc))
		wlc_mhf(wlc, MHF2, MHF2_PCISLOWCLKWAR, MHF2_PCISLOWCLKWAR,
			WLC_BAND_ALL);

	wl_init(wlc->wl);
	wlc->pub->up = true;

	if (wlc->bandinit_pending) {
		wlc_suspend_mac_and_wait(wlc);
		wlc_set_chanspec(wlc, wlc->default_bss->chanspec);
		wlc->bandinit_pending = false;
		wlc_enable_mac(wlc);
	}

	wlc_bmac_up_finish(wlc->hw);

	/* other software states up after ISR is running */
	/* start APs that were to be brought up but are not up  yet */
	/* if (AP_ENAB(wlc->pub)) wlc_restart_ap(wlc->ap); */

	/* Program the TX wme params with the current settings */
	wlc_wme_retries_write(wlc);

	/* start one second watchdog timer */
	ASSERT(!wlc->WDarmed);
	wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, true);
	wlc->WDarmed = true;

	/* ensure antenna config is up to date */
	wlc_stf_phy_txant_upd(wlc);
	/* ensure LDPC config is in sync */
	wlc_ht_update_ldpc(wlc, wlc->stf->ldpc);

	return 0;
}

/* Initialize the base precedence map for dequeueing from txq based on WME settings */
static void wlc_tx_prec_map_init(struct wlc_info *wlc)
{
	wlc->tx_prec_map = WLC_PREC_BMP_ALL;
	memset(wlc->fifo2prec_map, 0, NFIFO * sizeof(u16));

	/* For non-WME, both fifos have overlapping MAXPRIO. So just disable all precedences
	 * if either is full.
	 */
	if (!EDCF_ENAB(wlc->pub)) {
		wlc->fifo2prec_map[TX_DATA_FIFO] = WLC_PREC_BMP_ALL;
		wlc->fifo2prec_map[TX_CTL_FIFO] = WLC_PREC_BMP_ALL;
	} else {
		wlc->fifo2prec_map[TX_AC_BK_FIFO] = WLC_PREC_BMP_AC_BK;
		wlc->fifo2prec_map[TX_AC_BE_FIFO] = WLC_PREC_BMP_AC_BE;
		wlc->fifo2prec_map[TX_AC_VI_FIFO] = WLC_PREC_BMP_AC_VI;
		wlc->fifo2prec_map[TX_AC_VO_FIFO] = WLC_PREC_BMP_AC_VO;
	}
}

static uint wlc_down_del_timer(struct wlc_info *wlc)
{
	uint callbacks = 0;

	return callbacks;
}

/*
 * Mark the interface nonoperational, stop the software mechanisms,
 * disable the hardware, free any transient buffer state.
 * Return a count of the number of driver callbacks still pending.
 */
uint wlc_down(struct wlc_info *wlc)
{

	uint callbacks = 0;
	int i;
	bool dev_gone = false;
	struct wlc_txq_info *qi;

	WL_TRACE("wl%d: %s:\n", wlc->pub->unit, __func__);

	/* check if we are already in the going down path */
	if (wlc->going_down) {
		WL_ERROR("wl%d: %s: Driver going down so return\n",
			 wlc->pub->unit, __func__);
		return 0;
	}
	if (!wlc->pub->up)
		return callbacks;

	/* in between, mpc could try to bring down again.. */
	wlc->going_down = true;

	callbacks += wlc_bmac_down_prep(wlc->hw);

	dev_gone = DEVICEREMOVED(wlc);

	/* Call any registered down handlers */
	for (i = 0; i < WLC_MAXMODULES; i++) {
		if (wlc->modulecb[i].down_fn)
			callbacks +=
			    wlc->modulecb[i].down_fn(wlc->modulecb[i].hdl);
	}

	/* cancel the watchdog timer */
	if (wlc->WDarmed) {
		if (!wl_del_timer(wlc->wl, wlc->wdtimer))
			callbacks++;
		wlc->WDarmed = false;
	}
	/* cancel all other timers */
	callbacks += wlc_down_del_timer(wlc);

	/* interrupt must have been blocked */
	ASSERT((wlc->macintmask == 0) || !wlc->pub->up);

	wlc->pub->up = false;

	wlc_phy_mute_upd(wlc->band->pi, false, PHY_MUTE_ALL);

	/* clear txq flow control */
	wlc_txflowcontrol_reset(wlc);

	/* flush tx queues */
	for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) {
		pktq_flush(&qi->q, true, NULL, 0);
		ASSERT(pktq_empty(&qi->q));
	}

	callbacks += wlc_bmac_down_finish(wlc->hw);

	/* wlc_bmac_down_finish has done wlc_coredisable(). so clk is off */
	wlc->clk = false;

#ifdef BCMDBG
	/* Since all the packets should have been freed,
	 * all callbacks should have been called
	 */
	for (i = 1; i <= wlc->pub->tunables->maxpktcb; i++)
		ASSERT(wlc->pkt_callback[i].fn == NULL);
#endif
	wlc->going_down = false;
	return callbacks;
}

/* Set the current gmode configuration */
int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config)
{
	int ret = 0;
	uint i;
	wlc_rateset_t rs;
	/* Default to 54g Auto */
	s8 shortslot = WLC_SHORTSLOT_AUTO;	/* Advertise and use shortslot (-1/0/1 Auto/Off/On) */
	bool shortslot_restrict = false;	/* Restrict association to stations that support shortslot
						 */
	bool ignore_bcns = true;	/* Ignore legacy beacons on the same channel */
	bool ofdm_basic = false;	/* Make 6, 12, and 24 basic rates */
	int preamble = WLC_PLCP_LONG;	/* Advertise and use short preambles (-1/0/1 Auto/Off/On) */
	bool preamble_restrict = false;	/* Restrict association to stations that support short
					 * preambles
					 */
	struct wlcband *band;

	/* if N-support is enabled, allow Gmode set as long as requested
	 * Gmode is not GMODE_LEGACY_B
	 */
	if (N_ENAB(wlc->pub) && gmode == GMODE_LEGACY_B)
		return BCME_UNSUPPORTED;

	/* verify that we are dealing with 2G band and grab the band pointer */
	if (wlc->band->bandtype == WLC_BAND_2G)
		band = wlc->band;
	else if ((NBANDS(wlc) > 1) &&
		 (wlc->bandstate[OTHERBANDUNIT(wlc)]->bandtype == WLC_BAND_2G))
		band = wlc->bandstate[OTHERBANDUNIT(wlc)];
	else
		return BCME_BADBAND;

	/* Legacy or bust when no OFDM is supported by regulatory */
	if ((wlc_channel_locale_flags_in_band(wlc->cmi, band->bandunit) &
	     WLC_NO_OFDM) && (gmode != GMODE_LEGACY_B))
		return BCME_RANGE;

	/* update configuration value */
	if (config == true)
		wlc_protection_upd(wlc, WLC_PROT_G_USER, gmode);

	/* Clear supported rates filter */
	memset(&wlc->sup_rates_override, 0, sizeof(wlc_rateset_t));

	/* Clear rateset override */
	memset(&rs, 0, sizeof(wlc_rateset_t));

	switch (gmode) {
	case GMODE_LEGACY_B:
		shortslot = WLC_SHORTSLOT_OFF;
		wlc_rateset_copy(&gphy_legacy_rates, &rs);

		break;

	case GMODE_LRS:
		if (AP_ENAB(wlc->pub))
			wlc_rateset_copy(&cck_rates, &wlc->sup_rates_override);
		break;

	case GMODE_AUTO:
		/* Accept defaults */
		break;

	case GMODE_ONLY:
		ofdm_basic = true;
		preamble = WLC_PLCP_SHORT;
		preamble_restrict = true;
		break;

	case GMODE_PERFORMANCE:
		if (AP_ENAB(wlc->pub))	/* Put all rates into the Supported Rates element */
			wlc_rateset_copy(&cck_ofdm_rates,
					 &wlc->sup_rates_override);

		shortslot = WLC_SHORTSLOT_ON;
		shortslot_restrict = true;
		ofdm_basic = true;
		preamble = WLC_PLCP_SHORT;
		preamble_restrict = true;
		break;

	default:
		/* Error */
		WL_ERROR("wl%d: %s: invalid gmode %d\n",
			 wlc->pub->unit, __func__, gmode);
		return BCME_UNSUPPORTED;
	}

	/*
	 * If we are switching to gmode == GMODE_LEGACY_B,
	 * clean up rate info that may refer to OFDM rates.
	 */
	if ((gmode == GMODE_LEGACY_B) && (band->gmode != GMODE_LEGACY_B)) {
		band->gmode = gmode;
		if (band->rspec_override && !IS_CCK(band->rspec_override)) {
			band->rspec_override = 0;
			wlc_reprate_init(wlc);
		}
		if (band->mrspec_override && !IS_CCK(band->mrspec_override)) {
			band->mrspec_override = 0;
		}
	}

	band->gmode = gmode;

	wlc->ignore_bcns = ignore_bcns;

	wlc->shortslot_override = shortslot;

	if (AP_ENAB(wlc->pub)) {
		/* wlc->ap->shortslot_restrict = shortslot_restrict; */
		wlc->PLCPHdr_override =
		    (preamble !=
		     WLC_PLCP_LONG) ? WLC_PLCP_SHORT : WLC_PLCP_AUTO;
	}

	if ((AP_ENAB(wlc->pub) && preamble != WLC_PLCP_LONG)
	    || preamble == WLC_PLCP_SHORT)
		wlc->default_bss->capability |= WLAN_CAPABILITY_SHORT_PREAMBLE;
	else
		wlc->default_bss->capability &= ~WLAN_CAPABILITY_SHORT_PREAMBLE;

	/* Update shortslot capability bit for AP and IBSS */
	if ((AP_ENAB(wlc->pub) && shortslot == WLC_SHORTSLOT_AUTO) ||
	    shortslot == WLC_SHORTSLOT_ON)
		wlc->default_bss->capability |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
	else
		wlc->default_bss->capability &=
					~WLAN_CAPABILITY_SHORT_SLOT_TIME;

	/* Use the default 11g rateset */
	if (!rs.count)
		wlc_rateset_copy(&cck_ofdm_rates, &rs);

	if (ofdm_basic) {
		for (i = 0; i < rs.count; i++) {
			if (rs.rates[i] == WLC_RATE_6M
			    || rs.rates[i] == WLC_RATE_12M
			    || rs.rates[i] == WLC_RATE_24M)
				rs.rates[i] |= WLC_RATE_FLAG;
		}
	}

	/* Set default bss rateset */
	wlc->default_bss->rateset.count = rs.count;
	memcpy(wlc->default_bss->rateset.rates, rs.rates, 
	       sizeof(wlc->default_bss->rateset.rates));

	return ret;
}

static int wlc_nmode_validate(struct wlc_info *wlc, s32 nmode)
{
	int err = 0;

	switch (nmode) {

	case OFF:
		break;

	case AUTO:
	case WL_11N_2x2:
	case WL_11N_3x3:
		if (!(WLC_PHY_11N_CAP(wlc->band)))
			err = BCME_BADBAND;
		break;

	default:
		err = BCME_RANGE;
		break;
	}

	return err;
}

int wlc_set_nmode(struct wlc_info *wlc, s32 nmode)
{
	uint i;
	int err;

	err = wlc_nmode_validate(wlc, nmode);
	ASSERT(err == 0);
	if (err)
		return err;

	switch (nmode) {
	case OFF:
		wlc->pub->_n_enab = OFF;
		wlc->default_bss->flags &= ~WLC_BSS_HT;
		/* delete the mcs rates from the default and hw ratesets */
		wlc_rateset_mcs_clear(&wlc->default_bss->rateset);
		for (i = 0; i < NBANDS(wlc); i++) {
			memset(wlc->bandstate[i]->hw_rateset.mcs, 0,
			       MCSSET_LEN);
			if (IS_MCS(wlc->band->rspec_override)) {
				wlc->bandstate[i]->rspec_override = 0;
				wlc_reprate_init(wlc);
			}
			if (IS_MCS(wlc->band->mrspec_override))
				wlc->bandstate[i]->mrspec_override = 0;
		}
		break;

	case AUTO:
		if (wlc->stf->txstreams == WL_11N_3x3)
			nmode = WL_11N_3x3;
		else
			nmode = WL_11N_2x2;
	case WL_11N_2x2:
	case WL_11N_3x3:
		ASSERT(WLC_PHY_11N_CAP(wlc->band));
		/* force GMODE_AUTO if NMODE is ON */
		wlc_set_gmode(wlc, GMODE_AUTO, true);
		if (nmode == WL_11N_3x3)
			wlc->pub->_n_enab = SUPPORT_HT;
		else
			wlc->pub->_n_enab = SUPPORT_11N;
		wlc->default_bss->flags |= WLC_BSS_HT;
		/* add the mcs rates to the default and hw ratesets */
		wlc_rateset_mcs_build(&wlc->default_bss->rateset,
				      wlc->stf->txstreams);
		for (i = 0; i < NBANDS(wlc); i++)
			memcpy(wlc->bandstate[i]->hw_rateset.mcs,
			       wlc->default_bss->rateset.mcs, MCSSET_LEN);
		break;

	default:
		ASSERT(0);
		break;
	}

	return err;
}

static int wlc_set_rateset(struct wlc_info *wlc, wlc_rateset_t *rs_arg)
{
	wlc_rateset_t rs, new;
	uint bandunit;

	memcpy(&rs, rs_arg, sizeof(wlc_rateset_t));

	/* check for bad count value */
	if ((rs.count == 0) || (rs.count > WLC_NUMRATES))
		return BCME_BADRATESET;

	/* try the current band */
	bandunit = wlc->band->bandunit;
	memcpy(&new, &rs, sizeof(wlc_rateset_t));
	if (wlc_rate_hwrs_filter_sort_validate
	    (&new, &wlc->bandstate[bandunit]->hw_rateset, true,
	     wlc->stf->txstreams))
		goto good;

	/* try the other band */
	if (IS_MBAND_UNLOCKED(wlc)) {
		bandunit = OTHERBANDUNIT(wlc);
		memcpy(&new, &rs, sizeof(wlc_rateset_t));
		if (wlc_rate_hwrs_filter_sort_validate(&new,
						       &wlc->
						       bandstate[bandunit]->
						       hw_rateset, true,
						       wlc->stf->txstreams))
			goto good;
	}

	return BCME_ERROR;

 good:
	/* apply new rateset */
	memcpy(&wlc->default_bss->rateset, &new, sizeof(wlc_rateset_t));
	memcpy(&wlc->bandstate[bandunit]->defrateset, &new,
	       sizeof(wlc_rateset_t));
	return 0;
}

/* simplified integer set interface for common ioctl handler */
int wlc_set(struct wlc_info *wlc, int cmd, int arg)
{
	return wlc_ioctl(wlc, cmd, (void *)&arg, sizeof(arg), NULL);
}

/* simplified integer get interface for common ioctl handler */
int wlc_get(struct wlc_info *wlc, int cmd, int *arg)
{
	return wlc_ioctl(wlc, cmd, arg, sizeof(int), NULL);
}

static void wlc_ofdm_rateset_war(struct wlc_info *wlc)
{
	u8 r;
	bool war = false;

	if (wlc->cfg->associated)
		r = wlc->cfg->current_bss->rateset.rates[0];
	else
		r = wlc->default_bss->rateset.rates[0];

	wlc_phy_ofdm_rateset_war(wlc->band->pi, war);

	return;
}

int
wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len,
	  struct wlc_if *wlcif)
{
	return _wlc_ioctl(wlc, cmd, arg, len, wlcif);
}

/* common ioctl handler. return: 0=ok, -1=error, positive=particular error */
static int
_wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len,
	   struct wlc_if *wlcif)
{
	int val, *pval;
	bool bool_val;
	int bcmerror;
	d11regs_t *regs;
	uint i;
	struct scb *nextscb;
	bool ta_ok;
	uint band;
	rw_reg_t *r;
	struct wlc_bsscfg *bsscfg;
	wlc_bss_info_t *current_bss;

	/* update bsscfg pointer */
	bsscfg = NULL;		/* XXX: Hack bsscfg to be size one and use this globally */
	current_bss = NULL;

	/* initialize the following to get rid of compiler warning */
	nextscb = NULL;
	ta_ok = false;
	band = 0;
	r = NULL;

	/* If the device is turned off, then it's not "removed" */
	if (!wlc->pub->hw_off && DEVICEREMOVED(wlc)) {
		WL_ERROR("wl%d: %s: dead chip\n", wlc->pub->unit, __func__);
		wl_down(wlc->wl);
		return BCME_ERROR;
	}

	ASSERT(!(wlc->pub->hw_off && wlc->pub->up));

	/* default argument is generic integer */
	pval = arg ? (int *)arg:NULL;

	/* This will prevent the misaligned access */
	if (pval && (u32) len >= sizeof(val))
		memcpy(&val, pval, sizeof(val));
	else
		val = 0;

	/* bool conversion to avoid duplication below */
	bool_val = val != 0;

	if (cmd != WLC_SET_CHANNEL)
		WL_NONE("WLC_IOCTL: cmd %d val 0x%x (%d) len %d\n",
			cmd, (uint)val, val, len);

	bcmerror = 0;
	regs = wlc->regs;

	/* A few commands don't need any arguments; all the others do. */
	switch (cmd) {
	case WLC_UP:
	case WLC_OUT:
	case WLC_DOWN:
	case WLC_DISASSOC:
	case WLC_RESTART:
	case WLC_REBOOT:
	case WLC_START_CHANNEL_QA:
	case WLC_INIT:
		break;

	default:
		if ((arg == NULL) || (len <= 0)) {
			WL_ERROR("wl%d: %s: Command %d needs arguments\n",
				 wlc->pub->unit, __func__, cmd);
			bcmerror = BCME_BADARG;
			goto done;
		}
	}

	switch (cmd) {

#if defined(BCMDBG)
	case WLC_GET_MSGLEVEL:
		*pval = wl_msg_level;
		break;

	case WLC_SET_MSGLEVEL:
		wl_msg_level = val;
		break;
#endif

	case WLC_GET_INSTANCE:
		*pval = wlc->pub->unit;
		break;

	case WLC_GET_CHANNEL:{
			channel_info_t *ci = (channel_info_t *) arg;

			ASSERT(len > (int)sizeof(ci));

			ci->hw_channel =
			    CHSPEC_CHANNEL(WLC_BAND_PI_RADIO_CHANSPEC);
			ci->target_channel =
			    CHSPEC_CHANNEL(wlc->default_bss->chanspec);
			ci->scan_channel = 0;

			break;
		}

	case WLC_SET_CHANNEL:{
			chanspec_t chspec = CH20MHZ_CHSPEC(val);

			if (val < 0 || val > MAXCHANNEL) {
				bcmerror = BCME_OUTOFRANGECHAN;
				break;
			}

			if (!wlc_valid_chanspec_db(wlc->cmi, chspec)) {
				bcmerror = BCME_BADCHAN;
				break;
			}

			if (!wlc->pub->up && IS_MBAND_UNLOCKED(wlc)) {
				if (wlc->band->bandunit !=
				    CHSPEC_WLCBANDUNIT(chspec))
					wlc->bandinit_pending = true;
				else
					wlc->bandinit_pending = false;
			}

			wlc->default_bss->chanspec = chspec;
			/* wlc_BSSinit() will sanitize the rateset before using it.. */
			if (wlc->pub->up &&
			    (WLC_BAND_PI_RADIO_CHANSPEC != chspec)) {
				wlc_set_home_chanspec(wlc, chspec);
				wlc_suspend_mac_and_wait(wlc);
				wlc_set_chanspec(wlc, chspec);
				wlc_enable_mac(wlc);
			}
			break;
		}

#if defined(BCMDBG)
	case WLC_GET_UCFLAGS:
		if (!wlc->pub->up) {
			bcmerror = BCME_NOTUP;
			break;
		}

		/* optional band is stored in the second integer of incoming buffer */
		band =
		    (len <
		     (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1];

		/* bcmerror checking */
		bcmerror = wlc_iocregchk(wlc, band);
		if (bcmerror)
			break;

		if (val >= MHFMAX) {
			bcmerror = BCME_RANGE;
			break;
		}

		*pval = wlc_bmac_mhf_get(wlc->hw, (u8) val, WLC_BAND_AUTO);
		break;

	case WLC_SET_UCFLAGS:
		if (!wlc->pub->up) {
			bcmerror = BCME_NOTUP;
			break;
		}

		/* optional band is stored in the second integer of incoming buffer */
		band =
		    (len <
		     (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1];

		/* bcmerror checking */
		bcmerror = wlc_iocregchk(wlc, band);
		if (bcmerror)
			break;

		i = (u16) val;
		if (i >= MHFMAX) {
			bcmerror = BCME_RANGE;
			break;
		}

		wlc_mhf(wlc, (u8) i, 0xffff, (u16) (val >> NBITS(u16)),
			WLC_BAND_AUTO);
		break;

	case WLC_GET_SHMEM:
		ta_ok = true;

		/* optional band is stored in the second integer of incoming buffer */
		band =
		    (len <
		     (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1];

		/* bcmerror checking */
		bcmerror = wlc_iocregchk(wlc, band);
		if (bcmerror)
			break;

		if (val & 1) {
			bcmerror = BCME_BADADDR;
			break;
		}

		*pval = wlc_read_shm(wlc, (u16) val);
		break;

	case WLC_SET_SHMEM:
		ta_ok = true;

		/* optional band is stored in the second integer of incoming buffer */
		band =
		    (len <
		     (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1];

		/* bcmerror checking */
		bcmerror = wlc_iocregchk(wlc, band);
		if (bcmerror)
			break;

		if (val & 1) {
			bcmerror = BCME_BADADDR;
			break;
		}

		wlc_write_shm(wlc, (u16) val,
			      (u16) (val >> NBITS(u16)));
		break;

	case WLC_R_REG:	/* MAC registers */
		ta_ok = true;
		r = (rw_reg_t *) arg;
		band = WLC_BAND_AUTO;

		if (len < (int)(sizeof(rw_reg_t) - sizeof(uint))) {
			bcmerror = BCME_BUFTOOSHORT;
			break;
		}

		if (len >= (int)sizeof(rw_reg_t))
			band = r->band;

		/* bcmerror checking */
		bcmerror = wlc_iocregchk(wlc, band);
		if (bcmerror)
			break;

		if ((r->byteoff + r->size) > sizeof(d11regs_t)) {
			bcmerror = BCME_BADADDR;
			break;
		}
		if (r->size == sizeof(u32))
			r->val =
			    R_REG((u32 *)((unsigned char *)(unsigned long)regs +
					      r->byteoff));
		else if (r->size == sizeof(u16))
			r->val =
			    R_REG((u16 *)((unsigned char *)(unsigned long)regs +
					      r->byteoff));
		else
			bcmerror = BCME_BADADDR;
		break;

	case WLC_W_REG:
		ta_ok = true;
		r = (rw_reg_t *) arg;
		band = WLC_BAND_AUTO;

		if (len < (int)(sizeof(rw_reg_t) - sizeof(uint))) {
			bcmerror = BCME_BUFTOOSHORT;
			break;
		}

		if (len >= (int)sizeof(rw_reg_t))
			band = r->band;

		/* bcmerror checking */
		bcmerror = wlc_iocregchk(wlc, band);
		if (bcmerror)
			break;

		if (r->byteoff + r->size > sizeof(d11regs_t)) {
			bcmerror = BCME_BADADDR;
			break;
		}
		if (r->size == sizeof(u32))
			W_REG((u32 *)((unsigned char *)(unsigned long) regs +
					  r->byteoff), r->val);
		else if (r->size == sizeof(u16))
			W_REG((u16 *)((unsigned char *)(unsigned long) regs +
					  r->byteoff), r->val);
		else
			bcmerror = BCME_BADADDR;
		break;
#endif				/* BCMDBG */

	case WLC_GET_TXANT:
		*pval = wlc->stf->txant;
		break;

	case WLC_SET_TXANT:
		bcmerror = wlc_stf_ant_txant_validate(wlc, (s8) val);
		if (bcmerror < 0)
			break;

		wlc->stf->txant = (s8) val;

		/* if down, we are done */
		if (!wlc->pub->up)
			break;

		wlc_suspend_mac_and_wait(wlc);

		wlc_stf_phy_txant_upd(wlc);
		wlc_beacon_phytxctl_txant_upd(wlc, wlc->bcn_rspec);

		wlc_enable_mac(wlc);

		break;

	case WLC_GET_ANTDIV:{
			u8 phy_antdiv;

			/* return configured value if core is down */
			if (!wlc->pub->up) {
				*pval = wlc->stf->ant_rx_ovr;

			} else {
				if (wlc_phy_ant_rxdiv_get
				    (wlc->band->pi, &phy_antdiv))
					*pval = (int)phy_antdiv;
				else
					*pval = (int)wlc->stf->ant_rx_ovr;
			}

			break;
		}
	case WLC_SET_ANTDIV:
		/* values are -1=driver default, 0=force0, 1=force1, 2=start1, 3=start0 */
		if ((val < -1) || (val > 3)) {
			bcmerror = BCME_RANGE;
			break;
		}

		if (val == -1)
			val = ANT_RX_DIV_DEF;

		wlc->stf->ant_rx_ovr = (u8) val;
		wlc_phy_ant_rxdiv_set(wlc->band->pi, (u8) val);
		break;

	case WLC_GET_RX_ANT:{	/* get latest used rx antenna */
			u16 rxstatus;

			if (!wlc->pub->up) {
				bcmerror = BCME_NOTUP;
				break;
			}

			rxstatus = R_REG(&wlc->regs->phyrxstatus0);
			if (rxstatus == 0xdead || rxstatus == (u16) -1) {
				bcmerror = BCME_ERROR;
				break;
			}
			*pval = (rxstatus & PRXS0_RXANT_UPSUBBAND) ? 1 : 0;
			break;
		}

#if defined(BCMDBG)
	case WLC_GET_UCANTDIV:
		if (!wlc->clk) {
			bcmerror = BCME_NOCLK;
			break;
		}

		*pval =
		    (wlc_bmac_mhf_get(wlc->hw, MHF1, WLC_BAND_AUTO) &
		     MHF1_ANTDIV);
		break;

	case WLC_SET_UCANTDIV:{
			if (!wlc->pub->up) {
				bcmerror = BCME_NOTUP;
				break;
			}

			/* if multiband, band must be locked */
			if (IS_MBAND_UNLOCKED(wlc)) {
				bcmerror = BCME_NOTBANDLOCKED;
				break;
			}

			wlc_mhf(wlc, MHF1, MHF1_ANTDIV,
				(val ? MHF1_ANTDIV : 0), WLC_BAND_AUTO);
			break;
		}
#endif				/* defined(BCMDBG) */

	case WLC_GET_SRL:
		*pval = wlc->SRL;
		break;

	case WLC_SET_SRL:
		if (val >= 1 && val <= RETRY_SHORT_MAX) {
			int ac;
			wlc->SRL = (u16) val;

			wlc_bmac_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL);

			for (ac = 0; ac < AC_COUNT; ac++) {
				WLC_WME_RETRY_SHORT_SET(wlc, ac, wlc->SRL);
			}
			wlc_wme_retries_write(wlc);
		} else
			bcmerror = BCME_RANGE;
		break;

	case WLC_GET_LRL:
		*pval = wlc->LRL;
		break;

	case WLC_SET_LRL:
		if (val >= 1 && val <= 255) {
			int ac;
			wlc->LRL = (u16) val;

			wlc_bmac_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL);

			for (ac = 0; ac < AC_COUNT; ac++) {
				WLC_WME_RETRY_LONG_SET(wlc, ac, wlc->LRL);
			}
			wlc_wme_retries_write(wlc);
		} else
			bcmerror = BCME_RANGE;
		break;

	case WLC_GET_CWMIN:
		*pval = wlc->band->CWmin;
		break;

	case WLC_SET_CWMIN:
		if (!wlc->clk) {
			bcmerror = BCME_NOCLK;
			break;
		}

		if (val >= 1 && val <= 255) {
			wlc_set_cwmin(wlc, (u16) val);
		} else
			bcmerror = BCME_RANGE;
		break;

	case WLC_GET_CWMAX:
		*pval = wlc->band->CWmax;
		break;

	case WLC_SET_CWMAX:
		if (!wlc->clk) {
			bcmerror = BCME_NOCLK;
			break;
		}

		if (val >= 255 && val <= 2047) {
			wlc_set_cwmax(wlc, (u16) val);
		} else
			bcmerror = BCME_RANGE;
		break;

	case WLC_GET_RADIO:	/* use mask if don't want to expose some internal bits */
		*pval = wlc->pub->radio_disabled;
		break;

	case WLC_SET_RADIO:{	/* 32 bits input, higher 16 bits are mask, lower 16 bits are value to
				 * set
				 */
			u16 radiomask, radioval;
			uint validbits =
			    WL_RADIO_SW_DISABLE | WL_RADIO_HW_DISABLE;
			mbool new = 0;

			radiomask = (val & 0xffff0000) >> 16;
			radioval = val & 0x0000ffff;

			if ((radiomask == 0) || (radiomask & ~validbits)
			    || (radioval & ~validbits)
			    || ((radioval & ~radiomask) != 0)) {
				WL_ERROR("SET_RADIO with wrong bits 0x%x\n",
					 val);
				bcmerror = BCME_RANGE;
				break;
			}

			new =
			    (wlc->pub->radio_disabled & ~radiomask) | radioval;
			wlc->pub->radio_disabled = new;

			wlc_radio_hwdisable_upd(wlc);
			wlc_radio_upd(wlc);
			break;
		}

	case WLC_GET_PHYTYPE:
		*pval = WLC_PHYTYPE(wlc->band->phytype);
		break;

#if defined(BCMDBG)
	case WLC_GET_KEY:
		if ((val >= 0) && (val < WLC_MAX_WSEC_KEYS(wlc))) {
			wl_wsec_key_t key;

			wsec_key_t *src_key = wlc->wsec_keys[val];

			if (len < (int)sizeof(key)) {
				bcmerror = BCME_BUFTOOSHORT;
				break;
			}

			memset((char *)&key, 0, sizeof(key));
			if (src_key) {
				key.index = src_key->id;
				key.len = src_key->len;
				memcpy(key.data, src_key->data, key.len);
				key.algo = src_key->algo;
				if (WSEC_SOFTKEY(wlc, src_key, bsscfg))
					key.flags |= WL_SOFT_KEY;
				if (src_key->flags & WSEC_PRIMARY_KEY)
					key.flags |= WL_PRIMARY_KEY;

				memcpy(key.ea, src_key->ea, ETH_ALEN);
			}

			memcpy(arg, &key, sizeof(key));
		} else
			bcmerror = BCME_BADKEYIDX;
		break;
#endif				/* defined(BCMDBG) */

	case WLC_SET_KEY:
		bcmerror =
		    wlc_iovar_op(wlc, "wsec_key", NULL, 0, arg, len, IOV_SET,
				 wlcif);
		break;

	case WLC_GET_KEY_SEQ:{
			wsec_key_t *key;

			if (len < DOT11_WPA_KEY_RSC_LEN) {
				bcmerror = BCME_BUFTOOSHORT;
				break;
			}

			/* Return the key's tx iv as an EAPOL sequence counter.
			 * This will be used to supply the RSC value to a supplicant.
			 * The format is 8 bytes, with least significant in seq[0].
			 */

			key = WSEC_KEY(wlc, val);
			if ((val >= 0) && (val < WLC_MAX_WSEC_KEYS(wlc)) &&
				(key != NULL)) {
				u8 seq[DOT11_WPA_KEY_RSC_LEN];
				u16 lo;
				u32 hi;
				/* group keys in WPA-NONE (IBSS only, AES and TKIP) use a global TXIV */
				if ((bsscfg->WPA_auth & WPA_AUTH_NONE) &&
				    is_zero_ether_addr(key->ea)) {
					lo = bsscfg->wpa_none_txiv.lo;
					hi = bsscfg->wpa_none_txiv.hi;
				} else {
					lo = key->txiv.lo;
					hi = key->txiv.hi;
				}

				/* format the buffer, low to high */
				seq[0] = lo & 0xff;
				seq[1] = (lo >> 8) & 0xff;
				seq[2] = hi & 0xff;
				seq[3] = (hi >> 8) & 0xff;
				seq[4] = (hi >> 16) & 0xff;
				seq[5] = (hi >> 24) & 0xff;
				seq[6] = 0;
				seq[7] = 0;

				memcpy(arg, seq, sizeof(seq));
			} else {
				bcmerror = BCME_BADKEYIDX;
			}
			break;
		}

	case WLC_GET_CURR_RATESET:{
			wl_rateset_t *ret_rs = (wl_rateset_t *) arg;
			wlc_rateset_t *rs;

			if (bsscfg->associated)
				rs = &current_bss->rateset;
			else
				rs = &wlc->default_bss->rateset;

			if (len < (int)(rs->count + sizeof(rs->count))) {
				bcmerror = BCME_BUFTOOSHORT;
				break;
			}

			/* Copy only legacy rateset section */
			ret_rs->count = rs->count;
			memcpy(&ret_rs->rates, &rs->rates, rs->count);
			break;
		}

	case WLC_GET_RATESET:{
			wlc_rateset_t rs;
			wl_rateset_t *ret_rs = (wl_rateset_t *) arg;

			memset(&rs, 0, sizeof(wlc_rateset_t));
			wlc_default_rateset(wlc, (wlc_rateset_t *) &rs);

			if (len < (int)(rs.count + sizeof(rs.count))) {
				bcmerror = BCME_BUFTOOSHORT;
				break;
			}

			/* Copy only legacy rateset section */
			ret_rs->count = rs.count;
			memcpy(&ret_rs->rates, &rs.rates, rs.count);
			break;
		}

	case WLC_SET_RATESET:{
			wlc_rateset_t rs;
			wl_rateset_t *in_rs = (wl_rateset_t *) arg;

			if (len < (int)(in_rs->count + sizeof(in_rs->count))) {
				bcmerror = BCME_BUFTOOSHORT;
				break;
			}

			if (in_rs->count > WLC_NUMRATES) {
				bcmerror = BCME_BUFTOOLONG;
				break;
			}

			memset(&rs, 0, sizeof(wlc_rateset_t));

			/* Copy only legacy rateset section */
			rs.count = in_rs->count;
			memcpy(&rs.rates, &in_rs->rates, rs.count);

			/* merge rateset coming in with the current mcsset */
			if (N_ENAB(wlc->pub)) {
				if (bsscfg->associated)
					memcpy(rs.mcs,
					       &current_bss->rateset.mcs[0],
					       MCSSET_LEN);
				else
					memcpy(rs.mcs,
					       &wlc->default_bss->rateset.mcs[0],
					       MCSSET_LEN);
			}

			bcmerror = wlc_set_rateset(wlc, &rs);

			if (!bcmerror)
				wlc_ofdm_rateset_war(wlc);

			break;
		}

	case WLC_GET_BCNPRD:
		if (BSSCFG_STA(bsscfg) && bsscfg->BSS && bsscfg->associated)
			*pval = current_bss->beacon_period;
		else
			*pval = wlc->default_bss->beacon_period;
		break;

	case WLC_SET_BCNPRD:
		/* range [1, 0xffff] */
		if (val >= DOT11_MIN_BEACON_PERIOD
		    && val <= DOT11_MAX_BEACON_PERIOD) {
			wlc->default_bss->beacon_period = (u16) val;
		} else
			bcmerror = BCME_RANGE;
		break;

	case WLC_GET_DTIMPRD:
		if (BSSCFG_STA(bsscfg) && bsscfg->BSS && bsscfg->associated)
			*pval = current_bss->dtim_period;
		else
			*pval = wlc->default_bss->dtim_period;
		break;

	case WLC_SET_DTIMPRD:
		/* range [1, 0xff] */
		if (val >= DOT11_MIN_DTIM_PERIOD
		    && val <= DOT11_MAX_DTIM_PERIOD) {
			wlc->default_bss->dtim_period = (u8) val;
		} else
			bcmerror = BCME_RANGE;
		break;

#ifdef SUPPORT_PS
	case WLC_GET_PM:
		*pval = wlc->PM;
		break;

	case WLC_SET_PM:
		if ((val >= PM_OFF) && (val <= PM_MAX)) {
			wlc->PM = (u8) val;
			if (wlc->pub->up) {
			}
			/* Change watchdog driver to align watchdog with tbtt if possible */
			wlc_watchdog_upd(wlc, PS_ALLOWED(wlc));
		} else
			bcmerror = BCME_ERROR;
		break;
#endif				/* SUPPORT_PS */

#ifdef SUPPORT_PS
#ifdef BCMDBG
	case WLC_GET_WAKE:
		if (AP_ENAB(wlc->pub)) {
			bcmerror = BCME_NOTSTA;
			break;
		}
		*pval = wlc->wake;
		break;

	case WLC_SET_WAKE:
		if (AP_ENAB(wlc->pub)) {
			bcmerror = BCME_NOTSTA;
			break;
		}

		wlc->wake = val ? true : false;

		/* if down, we're done */
		if (!wlc->pub->up)
			break;

		/* apply to the mac */
		wlc_set_ps_ctrl(wlc);
		break;
#endif				/* BCMDBG */
#endif				/* SUPPORT_PS */

	case WLC_GET_REVINFO:
		bcmerror = wlc_get_revision_info(wlc, arg, (uint) len);
		break;

	case WLC_GET_AP:
		*pval = (int)AP_ENAB(wlc->pub);
		break;

	case WLC_GET_ATIM:
		if (bsscfg->associated)
			*pval = (int)current_bss->atim_window;
		else
			*pval = (int)wlc->default_bss->atim_window;
		break;

	case WLC_SET_ATIM:
		wlc->default_bss->atim_window = (u32) val;
		break;

	case WLC_GET_PKTCNTS:{
			get_pktcnt_t *pktcnt = (get_pktcnt_t *) pval;
			wlc_statsupd(wlc);
			pktcnt->rx_good_pkt = wlc->pub->_cnt->rxframe;
			pktcnt->rx_bad_pkt = wlc->pub->_cnt->rxerror;
			pktcnt->tx_good_pkt =
			    wlc->pub->_cnt->txfrmsnt;
			pktcnt->tx_bad_pkt =
			    wlc->pub->_cnt->txerror +
			    wlc->pub->_cnt->txfail;
			if (len >= (int)sizeof(get_pktcnt_t)) {
				/* Be backward compatible - only if buffer is large enough  */
				pktcnt->rx_ocast_good_pkt =
				    wlc->pub->_cnt->rxmfrmocast;
			}
			break;
		}

#ifdef SUPPORT_HWKEY
	case WLC_GET_WSEC:
		bcmerror =
		    wlc_iovar_op(wlc, "wsec", NULL, 0, arg, len, IOV_GET,
				 wlcif);
		break;

	case WLC_SET_WSEC:
		bcmerror =
		    wlc_iovar_op(wlc, "wsec", NULL, 0, arg, len, IOV_SET,
				 wlcif);
		break;

	case WLC_GET_WPA_AUTH:
		*pval = (int)bsscfg->WPA_auth;
		break;

	case WLC_SET_WPA_AUTH:
		/* change of WPA_Auth modifies the PS_ALLOWED state */
		if (BSSCFG_STA(bsscfg)) {
			bsscfg->WPA_auth = (u16) val;
		} else
			bsscfg->WPA_auth = (u16) val;
		break;
#endif				/* SUPPORT_HWKEY */

	case WLC_GET_BANDLIST:
		/* count of number of bands, followed by each band type */
		*pval++ = NBANDS(wlc);
		*pval++ = wlc->band->bandtype;
		if (NBANDS(wlc) > 1)
			*pval++ = wlc->bandstate[OTHERBANDUNIT(wlc)]->bandtype;
		break;

	case WLC_GET_BAND:
		*pval = wlc->bandlocked ? wlc->band->bandtype : WLC_BAND_AUTO;
		break;

	case WLC_GET_PHYLIST:
		{
			unsigned char *cp = arg;
			if (len < 3) {
				bcmerror = BCME_BUFTOOSHORT;
				break;
			}

			if (WLCISNPHY(wlc->band)) {
				*cp++ = 'n';
			} else if (WLCISLCNPHY(wlc->band)) {
				*cp++ = 'c';
			} else if (WLCISSSLPNPHY(wlc->band)) {
				*cp++ = 's';
			}
			*cp = '\0';
			break;
		}

	case WLC_GET_SHORTSLOT:
		*pval = wlc->shortslot;
		break;

	case WLC_GET_SHORTSLOT_OVERRIDE:
		*pval = wlc->shortslot_override;
		break;

	case WLC_SET_SHORTSLOT_OVERRIDE:
		if ((val != WLC_SHORTSLOT_AUTO) &&
		    (val != WLC_SHORTSLOT_OFF) && (val != WLC_SHORTSLOT_ON)) {
			bcmerror = BCME_RANGE;
			break;
		}

		wlc->shortslot_override = (s8) val;

		/* shortslot is an 11g feature, so no more work if we are
		 * currently on the 5G band
		 */
		if (BAND_5G(wlc->band->bandtype))
			break;

		if (wlc->pub->up && wlc->pub->associated) {
			/* let watchdog or beacon processing update shortslot */
		} else if (wlc->pub->up) {
			/* unassociated shortslot is off */
			wlc_switch_shortslot(wlc, false);
		} else {
			/* driver is down, so just update the wlc_info value */
			if (wlc->shortslot_override == WLC_SHORTSLOT_AUTO) {
				wlc->shortslot = false;
			} else {
				wlc->shortslot =
				    (wlc->shortslot_override ==
				     WLC_SHORTSLOT_ON);
			}
		}

		break;

	case WLC_GET_LEGACY_ERP:
		*pval = wlc->include_legacy_erp;
		break;

	case WLC_SET_LEGACY_ERP:
		if (wlc->include_legacy_erp == bool_val)
			break;

		wlc->include_legacy_erp = bool_val;

		if (AP_ENAB(wlc->pub) && wlc->clk) {
			wlc_update_beacon(wlc);
			wlc_update_probe_resp(wlc, true);
		}
		break;

	case WLC_GET_GMODE:
		if (wlc->band->bandtype == WLC_BAND_2G)
			*pval = wlc->band->gmode;
		else if (NBANDS(wlc) > 1)
			*pval = wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode;
		break;

	case WLC_SET_GMODE:
		if (!wlc->pub->associated)
			bcmerror = wlc_set_gmode(wlc, (u8) val, true);
		else {
			bcmerror = BCME_ASSOCIATED;
			break;
		}
		break;

	case WLC_GET_GMODE_PROTECTION:
		*pval = wlc->protection->_g;
		break;

	case WLC_GET_PROTECTION_CONTROL:
		*pval = wlc->protection->overlap;
		break;

	case WLC_SET_PROTECTION_CONTROL:
		if ((val != WLC_PROTECTION_CTL_OFF) &&
		    (val != WLC_PROTECTION_CTL_LOCAL) &&
		    (val != WLC_PROTECTION_CTL_OVERLAP)) {
			bcmerror = BCME_RANGE;
			break;
		}

		wlc_protection_upd(wlc, WLC_PROT_OVERLAP, (s8) val);

		/* Current g_protection will sync up to the specified control alg in watchdog
		 * if the driver is up and associated.
		 * If the driver is down or not associated, the control setting has no effect.
		 */
		break;

	case WLC_GET_GMODE_PROTECTION_OVERRIDE:
		*pval = wlc->protection->g_override;
		break;

	case WLC_SET_GMODE_PROTECTION_OVERRIDE:
		if ((val != WLC_PROTECTION_AUTO) &&
		    (val != WLC_PROTECTION_OFF) && (val != WLC_PROTECTION_ON)) {
			bcmerror = BCME_RANGE;
			break;
		}

		wlc_protection_upd(wlc, WLC_PROT_G_OVR, (s8) val);

		break;

	case WLC_SET_SUP_RATESET_OVERRIDE:{
			wlc_rateset_t rs, new;

			/* copyin */
			if (len < (int)sizeof(wlc_rateset_t)) {
				bcmerror = BCME_BUFTOOSHORT;
				break;
			}
			memcpy(&rs, arg, sizeof(wlc_rateset_t));

			/* check for bad count value */
			if (rs.count > WLC_NUMRATES) {
				bcmerror = BCME_BADRATESET;	/* invalid rateset */
				break;
			}

			/* this command is only appropriate for gmode operation */
			if (!(wlc->band->gmode ||
			      ((NBANDS(wlc) > 1)
			       && wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode))) {
				bcmerror = BCME_BADBAND;	/* gmode only command when not in gmode */
				break;
			}

			/* check for an empty rateset to clear the override */
			if (rs.count == 0) {
				memset(&wlc->sup_rates_override, 0,
				      sizeof(wlc_rateset_t));
				break;
			}

			/* validate rateset by comparing pre and post sorted against 11g hw rates */
			wlc_rateset_filter(&rs, &new, false, WLC_RATES_CCK_OFDM,
					   RATE_MASK, BSS_N_ENAB(wlc, bsscfg));
			wlc_rate_hwrs_filter_sort_validate(&new,
							   &cck_ofdm_rates,
							   false,
							   wlc->stf->txstreams);
			if (rs.count != new.count) {
				bcmerror = BCME_BADRATESET;	/* invalid rateset */
				break;
			}

			/* apply new rateset to the override */
			memcpy(&wlc->sup_rates_override, &new,
			      sizeof(wlc_rateset_t));

			/* update bcn and probe resp if needed */
			if (wlc->pub->up && AP_ENAB(wlc->pub)
			    && wlc->pub->associated) {
				wlc_update_beacon(wlc);
				wlc_update_probe_resp(wlc, true);
			}
			break;
		}

	case WLC_GET_SUP_RATESET_OVERRIDE:
		/* this command is only appropriate for gmode operation */
		if (!(wlc->band->gmode ||
		      ((NBANDS(wlc) > 1)
		       && wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode))) {
			bcmerror = BCME_BADBAND;	/* gmode only command when not in gmode */
			break;
		}
		if (len < (int)sizeof(wlc_rateset_t)) {
			bcmerror = BCME_BUFTOOSHORT;
			break;
		}
		memcpy(arg, &wlc->sup_rates_override, sizeof(wlc_rateset_t));

		break;

	case WLC_GET_PRB_RESP_TIMEOUT:
		*pval = wlc->prb_resp_timeout;
		break;

	case WLC_SET_PRB_RESP_TIMEOUT:
		if (wlc->pub->up) {
			bcmerror = BCME_NOTDOWN;
			break;
		}
		if (val < 0 || val >= 0xFFFF) {
			bcmerror = BCME_RANGE;	/* bad value */
			break;
		}
		wlc->prb_resp_timeout = (u16) val;
		break;

	case WLC_GET_KEY_PRIMARY:{
			wsec_key_t *key;

			/* treat the 'val' parm as the key id */
			key = WSEC_BSS_DEFAULT_KEY(bsscfg);
			if (key != NULL) {
				*pval = key->id == val ? true : false;
			} else {
				bcmerror = BCME_BADKEYIDX;
			}
			break;
		}

	case WLC_SET_KEY_PRIMARY:{
			wsec_key_t *key, *old_key;

			bcmerror = BCME_BADKEYIDX;

			/* treat the 'val' parm as the key id */
			for (i = 0; i < WSEC_MAX_DEFAULT_KEYS; i++) {
				key = bsscfg->bss_def_keys[i];
				if (key != NULL && key->id == val) {
					old_key = WSEC_BSS_DEFAULT_KEY(bsscfg);
					if (old_key != NULL)
						old_key->flags &=
						    ~WSEC_PRIMARY_KEY;
					key->flags |= WSEC_PRIMARY_KEY;
					bsscfg->wsec_index = i;
					bcmerror = BCME_OK;
				}
			}
			break;
		}

#ifdef BCMDBG
	case WLC_INIT:
		wl_init(wlc->wl);
		break;
#endif

	case WLC_SET_VAR:
	case WLC_GET_VAR:{
			char *name;
			/* validate the name value */
			name = (char *)arg;
			for (i = 0; i < (uint) len && *name != '\0';
			     i++, name++)
				;

			if (i == (uint) len) {
				bcmerror = BCME_BUFTOOSHORT;
				break;
			}
			i++;	/* include the null in the string length */

			if (cmd == WLC_GET_VAR) {
				bcmerror =
				    wlc_iovar_op(wlc, arg,
						 (void *)((s8 *) arg + i),
						 len - i, arg, len, IOV_GET,
						 wlcif);
			} else
				bcmerror =
				    wlc_iovar_op(wlc, arg, NULL, 0,
						 (void *)((s8 *) arg + i),
						 len - i, IOV_SET, wlcif);

			break;
		}

	case WLC_SET_WSEC_PMK:
		bcmerror = BCME_UNSUPPORTED;
		break;

#if defined(BCMDBG)
	case WLC_CURRENT_PWR:
		if (!wlc->pub->up)
			bcmerror = BCME_NOTUP;
		else
			bcmerror = wlc_get_current_txpwr(wlc, arg, len);
		break;
#endif

	case WLC_LAST:
		WL_ERROR("%s: WLC_LAST\n", __func__);
	}
 done:

	if (bcmerror) {
		if (VALID_BCMERROR(bcmerror))
			wlc->pub->bcmerror = bcmerror;
		else {
			bcmerror = 0;
		}

	}
	/* BMAC_NOTE: for HIGH_ONLY driver, this seems being called after RPC bus failed */
	/* In hw_off condition, IOCTLs that reach here are deemed safe but taclear would
	 * certainly result in getting -1 for register reads. So skip ta_clear altogether
	 */
	if (!(wlc->pub->hw_off))
		ASSERT(wlc_bmac_taclear(wlc->hw, ta_ok) || !ta_ok);

	return bcmerror;
}

#if defined(BCMDBG)
/* consolidated register access ioctl error checking */
int wlc_iocregchk(struct wlc_info *wlc, uint band)
{
	/* if band is specified, it must be the current band */
	if ((band != WLC_BAND_AUTO) && (band != (uint) wlc->band->bandtype))
		return BCME_BADBAND;

	/* if multiband and band is not specified, band must be locked */
	if ((band == WLC_BAND_AUTO) && IS_MBAND_UNLOCKED(wlc))
		return BCME_NOTBANDLOCKED;

	/* must have core clocks */
	if (!wlc->clk)
		return BCME_NOCLK;

	return 0;
}
#endif				/* defined(BCMDBG) */

#if defined(BCMDBG)
/* For some ioctls, make sure that the pi pointer matches the current phy */
int wlc_iocpichk(struct wlc_info *wlc, uint phytype)
{
	if (wlc->band->phytype != phytype)
		return BCME_BADBAND;
	return 0;
}
#endif

/* Look up the given var name in the given table */
static const bcm_iovar_t *wlc_iovar_lookup(const bcm_iovar_t *table,
					   const char *name)
{
	const bcm_iovar_t *vi;
	const char *lookup_name;

	/* skip any ':' delimited option prefixes */
	lookup_name = strrchr(name, ':');
	if (lookup_name != NULL)
		lookup_name++;
	else
		lookup_name = name;

	ASSERT(table != NULL);

	for (vi = table; vi->name; vi++) {
		if (!strcmp(vi->name, lookup_name))
			return vi;
	}
	/* ran to end of table */

	return NULL;		/* var name not found */
}

/* simplified integer get interface for common WLC_GET_VAR ioctl handler */
int wlc_iovar_getint(struct wlc_info *wlc, const char *name, int *arg)
{
	return wlc_iovar_op(wlc, name, NULL, 0, arg, sizeof(s32), IOV_GET,
			    NULL);
}

/* simplified integer set interface for common WLC_SET_VAR ioctl handler */
int wlc_iovar_setint(struct wlc_info *wlc, const char *name, int arg)
{
	return wlc_iovar_op(wlc, name, NULL, 0, (void *)&arg, sizeof(arg),
			    IOV_SET, NULL);
}

/* simplified s8 get interface for common WLC_GET_VAR ioctl handler */
int wlc_iovar_gets8(struct wlc_info *wlc, const char *name, s8 *arg)
{
	int iovar_int;
	int err;

	err =
	    wlc_iovar_op(wlc, name, NULL, 0, &iovar_int, sizeof(iovar_int),
			 IOV_GET, NULL);
	if (!err)
		*arg = (s8) iovar_int;

	return err;
}

/*
 * register iovar table, watchdog and down handlers.
 * calling function must keep 'iovars' until wlc_module_unregister is called.
 * 'iovar' must have the last entry's name field being NULL as terminator.
 */
int wlc_module_register(struct wlc_pub *pub, const bcm_iovar_t *iovars,
			const char *name, void *hdl, iovar_fn_t i_fn,
			watchdog_fn_t w_fn, down_fn_t d_fn)
{
	struct wlc_info *wlc = (struct wlc_info *) pub->wlc;
	int i;

	ASSERT(name != NULL);
	ASSERT(i_fn != NULL || w_fn != NULL || d_fn != NULL);

	/* find an empty entry and just add, no duplication check! */
	for (i = 0; i < WLC_MAXMODULES; i++) {
		if (wlc->modulecb[i].name[0] == '\0') {
			strncpy(wlc->modulecb[i].name, name,
				sizeof(wlc->modulecb[i].name) - 1);
			wlc->modulecb[i].iovars = iovars;
			wlc->modulecb[i].hdl = hdl;
			wlc->modulecb[i].iovar_fn = i_fn;
			wlc->modulecb[i].watchdog_fn = w_fn;
			wlc->modulecb[i].down_fn = d_fn;
			return 0;
		}
	}

	/* it is time to increase the capacity */
	ASSERT(i < WLC_MAXMODULES);
	return BCME_NORESOURCE;
}

/* unregister module callbacks */
int wlc_module_unregister(struct wlc_pub *pub, const char *name, void *hdl)
{
	struct wlc_info *wlc = (struct wlc_info *) pub->wlc;
	int i;

	if (wlc == NULL)
		return BCME_NOTFOUND;

	ASSERT(name != NULL);

	for (i = 0; i < WLC_MAXMODULES; i++) {
		if (!strcmp(wlc->modulecb[i].name, name) &&
		    (wlc->modulecb[i].hdl == hdl)) {
			memset(&wlc->modulecb[i], 0, sizeof(struct modulecb));
			return 0;
		}
	}

	/* table not found! */
	return BCME_NOTFOUND;
}

/* Write WME tunable parameters for retransmit/max rate from wlc struct to ucode */
static void wlc_wme_retries_write(struct wlc_info *wlc)
{
	int ac;

	/* Need clock to do this */
	if (!wlc->clk)
		return;

	for (ac = 0; ac < AC_COUNT; ac++) {
		wlc_write_shm(wlc, M_AC_TXLMT_ADDR(ac), wlc->wme_retries[ac]);
	}
}

/* Get or set an iovar.  The params/p_len pair specifies any additional
 * qualifying parameters (e.g. an "element index") for a get, while the
 * arg/len pair is the buffer for the value to be set or retrieved.
 * Operation (get/set) is specified by the last argument.
 * interface context provided by wlcif
 *
 * All pointers may point into the same buffer.
 */
int
wlc_iovar_op(struct wlc_info *wlc, const char *name,
	     void *params, int p_len, void *arg, int len,
	     bool set, struct wlc_if *wlcif)
{
	int err = 0;
	int val_size;
	const bcm_iovar_t *vi = NULL;
	u32 actionid;
	int i;

	ASSERT(name != NULL);

	ASSERT(len >= 0);

	/* Get MUST have return space */
	ASSERT(set || (arg && len));

	ASSERT(!(wlc->pub->hw_off && wlc->pub->up));

	/* Set does NOT take qualifiers */
	ASSERT(!set || (!params && !p_len));

	if (!set && (len == sizeof(int)) &&
	    !(IS_ALIGNED((unsigned long)(arg), (uint) sizeof(int)))) {
		WL_ERROR("wl%d: %s unaligned get ptr for %s\n",
			 wlc->pub->unit, __func__, name);
		ASSERT(0);
	}

	/* find the given iovar name */
	for (i = 0; i < WLC_MAXMODULES; i++) {
		if (!wlc->modulecb[i].iovars)
			continue;
		vi = wlc_iovar_lookup(wlc->modulecb[i].iovars, name);
		if (vi)
			break;
	}
	/* iovar name not found */
	if (i >= WLC_MAXMODULES) {
		err = BCME_UNSUPPORTED;
		goto exit;
	}

	/* set up 'params' pointer in case this is a set command so that
	 * the convenience int and bool code can be common to set and get
	 */
	if (params == NULL) {
		params = arg;
		p_len = len;
	}

	if (vi->type == IOVT_VOID)
		val_size = 0;
	else if (vi->type == IOVT_BUFFER)
		val_size = len;
	else
		/* all other types are integer sized */
		val_size = sizeof(int);

	actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid);

	/* Do the actual parameter implementation */
	err = wlc->modulecb[i].iovar_fn(wlc->modulecb[i].hdl, vi, actionid,
					name, params, p_len, arg, len, val_size,
					wlcif);

 exit:
	return err;
}

int
wlc_iovar_check(struct wlc_pub *pub, const bcm_iovar_t *vi, void *arg, int len,
		bool set)
{
	struct wlc_info *wlc = (struct wlc_info *) pub->wlc;
	int err = 0;
	s32 int_val = 0;

	/* check generic condition flags */
	if (set) {
		if (((vi->flags & IOVF_SET_DOWN) && wlc->pub->up) ||
		    ((vi->flags & IOVF_SET_UP) && !wlc->pub->up)) {
			err = (wlc->pub->up ? BCME_NOTDOWN : BCME_NOTUP);
		} else if ((vi->flags & IOVF_SET_BAND)
			   && IS_MBAND_UNLOCKED(wlc)) {
			err = BCME_NOTBANDLOCKED;
		} else if ((vi->flags & IOVF_SET_CLK) && !wlc->clk) {
			err = BCME_NOCLK;
		}
	} else {
		if (((vi->flags & IOVF_GET_DOWN) && wlc->pub->up) ||
		    ((vi->flags & IOVF_GET_UP) && !wlc->pub->up)) {
			err = (wlc->pub->up ? BCME_NOTDOWN : BCME_NOTUP);
		} else if ((vi->flags & IOVF_GET_BAND)
			   && IS_MBAND_UNLOCKED(wlc)) {
			err = BCME_NOTBANDLOCKED;
		} else if ((vi->flags & IOVF_GET_CLK) && !wlc->clk) {
			err = BCME_NOCLK;
		}
	}

	if (err)
		goto exit;

	/* length check on io buf */
	err = bcm_iovar_lencheck(vi, arg, len, set);
	if (err)
		goto exit;

	/* On set, check value ranges for integer types */
	if (set) {
		switch (vi->type) {
		case IOVT_BOOL:
		case IOVT_INT8:
		case IOVT_INT16:
		case IOVT_INT32:
		case IOVT_UINT8:
		case IOVT_UINT16:
		case IOVT_UINT32:
			memcpy(&int_val, arg, sizeof(int));
			err = wlc_iovar_rangecheck(wlc, int_val, vi);
			break;
		}
	}
 exit:
	return err;
}

/* handler for iovar table wlc_iovars */
/*
 * IMPLEMENTATION NOTE: In order to avoid checking for get/set in each
 * iovar case, the switch statement maps the iovar id into separate get
 * and set values.  If you add a new iovar to the switch you MUST use
 * IOV_GVAL and/or IOV_SVAL in the case labels to avoid conflict with
 * another case.
 * Please use params for additional qualifying parameters.
 */
int
wlc_doiovar(void *hdl, const bcm_iovar_t *vi, u32 actionid,
	    const char *name, void *params, uint p_len, void *arg, int len,
	    int val_size, struct wlc_if *wlcif)
{
	struct wlc_info *wlc = hdl;
	struct wlc_bsscfg *bsscfg;
	int err = 0;
	s32 int_val = 0;
	s32 int_val2 = 0;
	s32 *ret_int_ptr;
	bool bool_val;
	bool bool_val2;
	wlc_bss_info_t *current_bss;

	WL_TRACE("wl%d: %s\n", wlc->pub->unit, __func__);

	bsscfg = NULL;
	current_bss = NULL;

	err = wlc_iovar_check(wlc->pub, vi, arg, len, IOV_ISSET(actionid));
	if (err != 0)
		return err;

	/* convenience int and bool vals for first 8 bytes of buffer */
	if (p_len >= (int)sizeof(int_val))
		memcpy(&int_val, params, sizeof(int_val));

	if (p_len >= (int)sizeof(int_val) * 2)
		memcpy(&int_val2,
		       (void *)((unsigned long)params + sizeof(int_val)),
		       sizeof(int_val));

	/* convenience int ptr for 4-byte gets (requires int aligned arg) */
	ret_int_ptr = (s32 *) arg;

	bool_val = (int_val != 0) ? true : false;
	bool_val2 = (int_val2 != 0) ? true : false;

	WL_TRACE("wl%d: %s: id %d\n",
		 wlc->pub->unit, __func__, IOV_ID(actionid));
	/* Do the actual parameter implementation */
	switch (actionid) {
	case IOV_SVAL(IOV_RTSTHRESH):
		wlc->RTSThresh = int_val;
		break;

	case IOV_GVAL(IOV_QTXPOWER):{
			uint qdbm;
			bool override;

			err = wlc_phy_txpower_get(wlc->band->pi, &qdbm,
				&override);
			if (err != BCME_OK)
				return err;

			/* Return qdbm units */
			*ret_int_ptr =
			    qdbm | (override ? WL_TXPWR_OVERRIDE : 0);
			break;
		}

		/* As long as override is false, this only sets the *user* targets.
		   User can twiddle this all he wants with no harm.
		   wlc_phy_txpower_set() explicitly sets override to false if
		   not internal or test.
		 */
	case IOV_SVAL(IOV_QTXPOWER):{
			u8 qdbm;
			bool override;

			/* Remove override bit and clip to max qdbm value */
			qdbm = (u8)min_t(u32, (int_val & ~WL_TXPWR_OVERRIDE), 0xff);
			/* Extract override setting */
			override = (int_val & WL_TXPWR_OVERRIDE) ? true : false;
			err =
			    wlc_phy_txpower_set(wlc->band->pi, qdbm, override);
			break;
		}

	case IOV_GVAL(IOV_MPC):
		*ret_int_ptr = (s32) wlc->mpc;
		break;

	case IOV_SVAL(IOV_MPC):
		wlc->mpc = bool_val;
		wlc_radio_mpc_upd(wlc);

		break;

	case IOV_GVAL(IOV_BCN_LI_BCN):
		*ret_int_ptr = wlc->bcn_li_bcn;
		break;

	case IOV_SVAL(IOV_BCN_LI_BCN):
		wlc->bcn_li_bcn = (u8) int_val;
		if (wlc->pub->up)
			wlc_bcn_li_upd(wlc);
		break;

	default:
		WL_ERROR("wl%d: %s: unsupported\n", wlc->pub->unit, __func__);
		err = BCME_UNSUPPORTED;
		break;
	}

	goto exit;		/* avoid unused label warning */

 exit:
	return err;
}

static int
wlc_iovar_rangecheck(struct wlc_info *wlc, u32 val, const bcm_iovar_t *vi)
{
	int err = 0;
	u32 min_val = 0;
	u32 max_val = 0;

	/* Only ranged integers are checked */
	switch (vi->type) {
	case IOVT_INT32:
		max_val |= 0x7fffffff;
		/* fall through */
	case IOVT_INT16:
		max_val |= 0x00007fff;
		/* fall through */
	case IOVT_INT8:
		max_val |= 0x0000007f;
		min_val = ~max_val;
		if (vi->flags & IOVF_NTRL)
			min_val = 1;
		else if (vi->flags & IOVF_WHL)
			min_val = 0;
		/* Signed values are checked against max_val and min_val */
		if ((s32) val < (s32) min_val
		    || (s32) val > (s32) max_val)
			err = BCME_RANGE;
		break;

	case IOVT_UINT32:
		max_val |= 0xffffffff;
		/* fall through */
	case IOVT_UINT16:
		max_val |= 0x0000ffff;
		/* fall through */
	case IOVT_UINT8:
		max_val |= 0x000000ff;
		if (vi->flags & IOVF_NTRL)
			min_val = 1;
		if ((val < min_val) || (val > max_val))
			err = BCME_RANGE;
		break;
	}

	return err;
}

#ifdef BCMDBG
static const char *supr_reason[] = {
	"None", "PMQ Entry", "Flush request",
	"Previous frag failure", "Channel mismatch",
	"Lifetime Expiry", "Underflow"
};

static void wlc_print_txs_status(u16 s)
{
	printk(KERN_DEBUG "[15:12]  %d  frame attempts\n",
	       (s & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT);
	printk(KERN_DEBUG " [11:8]  %d  rts attempts\n",
	       (s & TX_STATUS_RTS_RTX_MASK) >> TX_STATUS_RTS_RTX_SHIFT);
	printk(KERN_DEBUG "    [7]  %d  PM mode indicated\n",
	       ((s & TX_STATUS_PMINDCTD) ? 1 : 0));
	printk(KERN_DEBUG "    [6]  %d  intermediate status\n",
	       ((s & TX_STATUS_INTERMEDIATE) ? 1 : 0));
	printk(KERN_DEBUG "    [5]  %d  AMPDU\n",
	       (s & TX_STATUS_AMPDU) ? 1 : 0);
	printk(KERN_DEBUG "  [4:2]  %d  Frame Suppressed Reason (%s)\n",
	       ((s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT),
	       supr_reason[(s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT]);
	printk(KERN_DEBUG "    [1]  %d  acked\n",
	       ((s & TX_STATUS_ACK_RCV) ? 1 : 0));
}
#endif				/* BCMDBG */

void wlc_print_txstatus(tx_status_t *txs)
{
#if defined(BCMDBG)
	u16 s = txs->status;
	u16 ackphyrxsh = txs->ackphyrxsh;

	printk(KERN_DEBUG "\ntxpkt (MPDU) Complete\n");

	printk(KERN_DEBUG "FrameID: %04x   ", txs->frameid);
	printk(KERN_DEBUG "TxStatus: %04x", s);
	printk(KERN_DEBUG "\n");

	wlc_print_txs_status(s);

	printk(KERN_DEBUG "LastTxTime: %04x ", txs->lasttxtime);
	printk(KERN_DEBUG "Seq: %04x ", txs->sequence);
	printk(KERN_DEBUG "PHYTxStatus: %04x ", txs->phyerr);
	printk(KERN_DEBUG "RxAckRSSI: %04x ",
	       (ackphyrxsh & PRXS1_JSSI_MASK) >> PRXS1_JSSI_SHIFT);
	printk(KERN_DEBUG "RxAckSQ: %04x",
	       (ackphyrxsh & PRXS1_SQ_MASK) >> PRXS1_SQ_SHIFT);
	printk(KERN_DEBUG "\n");
#endif				/* defined(BCMDBG) */
}

static void
wlc_ctrupd_cache(u16 cur_stat, u16 *macstat_snapshot, u32 *macstat)
{
	u16 v;
	u16 delta;

	v = le16_to_cpu(cur_stat);
	delta = (u16)(v - *macstat_snapshot);

	if (delta != 0) {
		*macstat += delta;
		*macstat_snapshot = v;
	}
}

#define MACSTATUPD(name) \
	wlc_ctrupd_cache(macstats.name, &wlc->core->macstat_snapshot->name, &wlc->pub->_cnt->name)

void wlc_statsupd(struct wlc_info *wlc)
{
	int i;
	macstat_t macstats;
#ifdef BCMDBG
	u16 delta;
	u16 rxf0ovfl;
	u16 txfunfl[NFIFO];
#endif				/* BCMDBG */

	/* if driver down, make no sense to update stats */
	if (!wlc->pub->up)
		return;

#ifdef BCMDBG
	/* save last rx fifo 0 overflow count */
	rxf0ovfl = wlc->core->macstat_snapshot->rxf0ovfl;

	/* save last tx fifo  underflow count */
	for (i = 0; i < NFIFO; i++)
		txfunfl[i] = wlc->core->macstat_snapshot->txfunfl[i];
#endif				/* BCMDBG */

	/* Read mac stats from contiguous shared memory */
	wlc_bmac_copyfrom_shm(wlc->hw, M_UCODE_MACSTAT,
			      &macstats, sizeof(macstat_t));

	/* update mac stats */
	MACSTATUPD(txallfrm);
	MACSTATUPD(txrtsfrm);
	MACSTATUPD(txctsfrm);
	MACSTATUPD(txackfrm);
	MACSTATUPD(txdnlfrm);
	MACSTATUPD(txbcnfrm);
	for (i = 0; i < NFIFO; i++)
		MACSTATUPD(txfunfl[i]);
	MACSTATUPD(txtplunfl);
	MACSTATUPD(txphyerr);
	MACSTATUPD(rxfrmtoolong);
	MACSTATUPD(rxfrmtooshrt);
	MACSTATUPD(rxinvmachdr);
	MACSTATUPD(rxbadfcs);
	MACSTATUPD(rxbadplcp);
	MACSTATUPD(rxcrsglitch);
	MACSTATUPD(rxstrt);
	MACSTATUPD(rxdfrmucastmbss);
	MACSTATUPD(rxmfrmucastmbss);
	MACSTATUPD(rxcfrmucast);
	MACSTATUPD(rxrtsucast);
	MACSTATUPD(rxctsucast);
	MACSTATUPD(rxackucast);
	MACSTATUPD(rxdfrmocast);
	MACSTATUPD(rxmfrmocast);
	MACSTATUPD(rxcfrmocast);
	MACSTATUPD(rxrtsocast);
	MACSTATUPD(rxctsocast);
	MACSTATUPD(rxdfrmmcast);
	MACSTATUPD(rxmfrmmcast);
	MACSTATUPD(rxcfrmmcast);
	MACSTATUPD(rxbeaconmbss);
	MACSTATUPD(rxdfrmucastobss);
	MACSTATUPD(rxbeaconobss);
	MACSTATUPD(rxrsptmout);
	MACSTATUPD(bcntxcancl);
	MACSTATUPD(rxf0ovfl);
	MACSTATUPD(rxf1ovfl);
	MACSTATUPD(rxf2ovfl);
	MACSTATUPD(txsfovfl);
	MACSTATUPD(pmqovfl);
	MACSTATUPD(rxcgprqfrm);
	MACSTATUPD(rxcgprsqovfl);
	MACSTATUPD(txcgprsfail);
	MACSTATUPD(txcgprssuc);
	MACSTATUPD(prs_timeout);
	MACSTATUPD(rxnack);
	MACSTATUPD(frmscons);
	MACSTATUPD(txnack);
	MACSTATUPD(txglitch_nack);
	MACSTATUPD(txburst);
	MACSTATUPD(phywatchdog);
	MACSTATUPD(pktengrxducast);
	MACSTATUPD(pktengrxdmcast);

#ifdef BCMDBG
	/* check for rx fifo 0 overflow */
	delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl);
	if (delta)
		WL_ERROR("wl%d: %u rx fifo 0 overflows!\n",
			 wlc->pub->unit, delta);

	/* check for tx fifo underflows */
	for (i = 0; i < NFIFO; i++) {
		delta =
		    (u16) (wlc->core->macstat_snapshot->txfunfl[i] -
			      txfunfl[i]);
		if (delta)
			WL_ERROR("wl%d: %u tx fifo %d underflows!\n",
				 wlc->pub->unit, delta, i);
	}
#endif				/* BCMDBG */

	/* dot11 counter update */

	WLCNTSET(wlc->pub->_cnt->txrts,
		 (wlc->pub->_cnt->rxctsucast -
		  wlc->pub->_cnt->d11cnt_txrts_off));
	WLCNTSET(wlc->pub->_cnt->rxcrc,
		 (wlc->pub->_cnt->rxbadfcs - wlc->pub->_cnt->d11cnt_rxcrc_off));
	WLCNTSET(wlc->pub->_cnt->txnocts,
		 ((wlc->pub->_cnt->txrtsfrm - wlc->pub->_cnt->rxctsucast) -
		  wlc->pub->_cnt->d11cnt_txnocts_off));

	/* merge counters from dma module */
	for (i = 0; i < NFIFO; i++) {
		if (wlc->hw->di[i]) {
			WLCNTADD(wlc->pub->_cnt->txnobuf,
				 (wlc->hw->di[i])->txnobuf);
			WLCNTADD(wlc->pub->_cnt->rxnobuf,
				 (wlc->hw->di[i])->rxnobuf);
			WLCNTADD(wlc->pub->_cnt->rxgiant,
				 (wlc->hw->di[i])->rxgiants);
			dma_counterreset(wlc->hw->di[i]);
		}
	}

	/*
	 * Aggregate transmit and receive errors that probably resulted
	 * in the loss of a frame are computed on the fly.
	 */
	WLCNTSET(wlc->pub->_cnt->txerror,
		 wlc->pub->_cnt->txnobuf + wlc->pub->_cnt->txnoassoc +
		 wlc->pub->_cnt->txuflo + wlc->pub->_cnt->txrunt +
		 wlc->pub->_cnt->dmade + wlc->pub->_cnt->dmada +
		 wlc->pub->_cnt->dmape);
	WLCNTSET(wlc->pub->_cnt->rxerror,
		 wlc->pub->_cnt->rxoflo + wlc->pub->_cnt->rxnobuf +
		 wlc->pub->_cnt->rxfragerr + wlc->pub->_cnt->rxrunt +
		 wlc->pub->_cnt->rxgiant + wlc->pub->_cnt->rxnoscb +
		 wlc->pub->_cnt->rxbadsrcmac);
	for (i = 0; i < NFIFO; i++)
		wlc->pub->_cnt->rxerror += wlc->pub->_cnt->rxuflo[i];
}

bool wlc_chipmatch(u16 vendor, u16 device)
{
	if (vendor != VENDOR_BROADCOM) {
		WL_ERROR("wlc_chipmatch: unknown vendor id %04x\n", vendor);
		return false;
	}

	if ((device == BCM43224_D11N_ID) || (device == BCM43225_D11N2G_ID))
		return true;

	if (device == BCM4313_D11N2G_ID)
		return true;
	if ((device == BCM43236_D11N_ID) || (device == BCM43236_D11N2G_ID))
		return true;

	WL_ERROR("wlc_chipmatch: unknown device id %04x\n", device);
	return false;
}

#if defined(BCMDBG)
void wlc_print_txdesc(d11txh_t *txh)
{
	u16 mtcl = le16_to_cpu(txh->MacTxControlLow);
	u16 mtch = le16_to_cpu(txh->MacTxControlHigh);
	u16 mfc = le16_to_cpu(txh->MacFrameControl);
	u16 tfest = le16_to_cpu(txh->TxFesTimeNormal);
	u16 ptcw = le16_to_cpu(txh->PhyTxControlWord);
	u16 ptcw_1 = le16_to_cpu(txh->PhyTxControlWord_1);
	u16 ptcw_1_Fbr = le16_to_cpu(txh->PhyTxControlWord_1_Fbr);
	u16 ptcw_1_Rts = le16_to_cpu(txh->PhyTxControlWord_1_Rts);
	u16 ptcw_1_FbrRts = le16_to_cpu(txh->PhyTxControlWord_1_FbrRts);
	u16 mainrates = le16_to_cpu(txh->MainRates);
	u16 xtraft = le16_to_cpu(txh->XtraFrameTypes);
	u8 *iv = txh->IV;
	u8 *ra = txh->TxFrameRA;
	u16 tfestfb = le16_to_cpu(txh->TxFesTimeFallback);
	u8 *rtspfb = txh->RTSPLCPFallback;
	u16 rtsdfb = le16_to_cpu(txh->RTSDurFallback);
	u8 *fragpfb = txh->FragPLCPFallback;
	u16 fragdfb = le16_to_cpu(txh->FragDurFallback);
	u16 mmodelen = le16_to_cpu(txh->MModeLen);
	u16 mmodefbrlen = le16_to_cpu(txh->MModeFbrLen);
	u16 tfid = le16_to_cpu(txh->TxFrameID);
	u16 txs = le16_to_cpu(txh->TxStatus);
	u16 mnmpdu = le16_to_cpu(txh->MaxNMpdus);
	u16 mabyte = le16_to_cpu(txh->MaxABytes_MRT);
	u16 mabyte_f = le16_to_cpu(txh->MaxABytes_FBR);
	u16 mmbyte = le16_to_cpu(txh->MinMBytes);

	u8 *rtsph = txh->RTSPhyHeader;
	struct ieee80211_rts rts = txh->rts_frame;
	char hexbuf[256];

	/* add plcp header along with txh descriptor */
	prhex("Raw TxDesc + plcp header", (unsigned char *) txh, sizeof(d11txh_t) + 48);

	printk(KERN_DEBUG "TxCtlLow: %04x ", mtcl);
	printk(KERN_DEBUG "TxCtlHigh: %04x ", mtch);
	printk(KERN_DEBUG "FC: %04x ", mfc);
	printk(KERN_DEBUG "FES Time: %04x\n", tfest);
	printk(KERN_DEBUG "PhyCtl: %04x%s ", ptcw,
	       (ptcw & PHY_TXC_SHORT_HDR) ? " short" : "");
	printk(KERN_DEBUG "PhyCtl_1: %04x ", ptcw_1);
	printk(KERN_DEBUG "PhyCtl_1_Fbr: %04x\n", ptcw_1_Fbr);
	printk(KERN_DEBUG "PhyCtl_1_Rts: %04x ", ptcw_1_Rts);
	printk(KERN_DEBUG "PhyCtl_1_Fbr_Rts: %04x\n", ptcw_1_FbrRts);
	printk(KERN_DEBUG "MainRates: %04x ", mainrates);
	printk(KERN_DEBUG "XtraFrameTypes: %04x ", xtraft);
	printk(KERN_DEBUG "\n");

	bcm_format_hex(hexbuf, iv, sizeof(txh->IV));
	printk(KERN_DEBUG "SecIV:       %s\n", hexbuf);
	bcm_format_hex(hexbuf, ra, sizeof(txh->TxFrameRA));
	printk(KERN_DEBUG "RA:          %s\n", hexbuf);

	printk(KERN_DEBUG "Fb FES Time: %04x ", tfestfb);
	bcm_format_hex(hexbuf, rtspfb, sizeof(txh->RTSPLCPFallback));
	printk(KERN_DEBUG "RTS PLCP: %s ", hexbuf);
	printk(KERN_DEBUG "RTS DUR: %04x ", rtsdfb);
	bcm_format_hex(hexbuf, fragpfb, sizeof(txh->FragPLCPFallback));
	printk(KERN_DEBUG "PLCP: %s ", hexbuf);
	printk(KERN_DEBUG "DUR: %04x", fragdfb);
	printk(KERN_DEBUG "\n");

	printk(KERN_DEBUG "MModeLen: %04x ", mmodelen);
	printk(KERN_DEBUG "MModeFbrLen: %04x\n", mmodefbrlen);

	printk(KERN_DEBUG "FrameID:     %04x\n", tfid);
	printk(KERN_DEBUG "TxStatus:    %04x\n", txs);

	printk(KERN_DEBUG "MaxNumMpdu:  %04x\n", mnmpdu);
	printk(KERN_DEBUG "MaxAggbyte:  %04x\n", mabyte);
	printk(KERN_DEBUG "MaxAggbyte_fb:  %04x\n", mabyte_f);
	printk(KERN_DEBUG "MinByte:     %04x\n", mmbyte);

	bcm_format_hex(hexbuf, rtsph, sizeof(txh->RTSPhyHeader));
	printk(KERN_DEBUG "RTS PLCP: %s ", hexbuf);
	bcm_format_hex(hexbuf, (u8 *) &rts, sizeof(txh->rts_frame));
	printk(KERN_DEBUG "RTS Frame: %s", hexbuf);
	printk(KERN_DEBUG "\n");
}
#endif				/* defined(BCMDBG) */

#if defined(BCMDBG)
void wlc_print_rxh(d11rxhdr_t *rxh)
{
	u16 len = rxh->RxFrameSize;
	u16 phystatus_0 = rxh->PhyRxStatus_0;
	u16 phystatus_1 = rxh->PhyRxStatus_1;
	u16 phystatus_2 = rxh->PhyRxStatus_2;
	u16 phystatus_3 = rxh->PhyRxStatus_3;
	u16 macstatus1 = rxh->RxStatus1;
	u16 macstatus2 = rxh->RxStatus2;
	char flagstr[64];
	char lenbuf[20];
	static const bcm_bit_desc_t macstat_flags[] = {
		{RXS_FCSERR, "FCSErr"},
		{RXS_RESPFRAMETX, "Reply"},
		{RXS_PBPRES, "PADDING"},
		{RXS_DECATMPT, "DeCr"},
		{RXS_DECERR, "DeCrErr"},
		{RXS_BCNSENT, "Bcn"},
		{0, NULL}
	};

	prhex("Raw RxDesc", (unsigned char *) rxh, sizeof(d11rxhdr_t));

	bcm_format_flags(macstat_flags, macstatus1, flagstr, 64);

	snprintf(lenbuf, sizeof(lenbuf), "0x%x", len);

	printk(KERN_DEBUG "RxFrameSize:     %6s (%d)%s\n", lenbuf, len,
	       (rxh->PhyRxStatus_0 & PRXS0_SHORTH) ? " short preamble" : "");
	printk(KERN_DEBUG "RxPHYStatus:     %04x %04x %04x %04x\n",
	       phystatus_0, phystatus_1, phystatus_2, phystatus_3);
	printk(KERN_DEBUG "RxMACStatus:     %x %s\n", macstatus1, flagstr);
	printk(KERN_DEBUG "RXMACaggtype:    %x\n",
	       (macstatus2 & RXS_AGGTYPE_MASK));
	printk(KERN_DEBUG "RxTSFTime:       %04x\n", rxh->RxTSFTime);
}
#endif				/* defined(BCMDBG) */

#if defined(BCMDBG)
int wlc_format_ssid(char *buf, const unsigned char ssid[], uint ssid_len)
{
	uint i, c;
	char *p = buf;
	char *endp = buf + SSID_FMT_BUF_LEN;

	if (ssid_len > IEEE80211_MAX_SSID_LEN)
		ssid_len = IEEE80211_MAX_SSID_LEN;

	for (i = 0; i < ssid_len; i++) {
		c = (uint) ssid[i];
		if (c == '\\') {
			*p++ = '\\';
			*p++ = '\\';
		} else if (isprint((unsigned char) c)) {
			*p++ = (char)c;
		} else {
			p += snprintf(p, (endp - p), "\\x%02X", c);
		}
	}
	*p = '\0';
	ASSERT(p < endp);

	return (int)(p - buf);
}
#endif				/* defined(BCMDBG) */

static u16 wlc_rate_shm_offset(struct wlc_info *wlc, u8 rate)
{
	return wlc_bmac_rate_shm_offset(wlc->hw, rate);
}

/* Callback for device removed */

/*
 * Attempts to queue a packet onto a multiple-precedence queue,
 * if necessary evicting a lower precedence packet from the queue.
 *
 * 'prec' is the precedence number that has already been mapped
 * from the packet priority.
 *
 * Returns true if packet consumed (queued), false if not.
 */
bool BCMFASTPATH
wlc_prec_enq(struct wlc_info *wlc, struct pktq *q, void *pkt, int prec)
{
	return wlc_prec_enq_head(wlc, q, pkt, prec, false);
}

bool BCMFASTPATH
wlc_prec_enq_head(struct wlc_info *wlc, struct pktq *q, struct sk_buff *pkt,
		  int prec, bool head)
{
	struct sk_buff *p;
	int eprec = -1;		/* precedence to evict from */

	/* Determine precedence from which to evict packet, if any */
	if (pktq_pfull(q, prec))
		eprec = prec;
	else if (pktq_full(q)) {
		p = pktq_peek_tail(q, &eprec);
		ASSERT(p != NULL);
		if (eprec > prec) {
			WL_ERROR("%s: Failing: eprec %d > prec %d\n",
				 __func__, eprec, prec);
			return false;
		}
	}

	/* Evict if needed */
	if (eprec >= 0) {
		bool discard_oldest;

		/* Detect queueing to unconfigured precedence */
		ASSERT(!pktq_pempty(q, eprec));

		discard_oldest = AC_BITMAP_TST(wlc->wme_dp, eprec);

		/* Refuse newer packet unless configured to discard oldest */
		if (eprec == prec && !discard_oldest) {
			WL_ERROR("%s: No where to go, prec == %d\n",
				 __func__, prec);
			return false;
		}

		/* Evict packet according to discard policy */
		p = discard_oldest ? pktq_pdeq(q, eprec) : pktq_pdeq_tail(q,
									  eprec);
		ASSERT(p != NULL);

		/* Increment wme stats */
		if (WME_ENAB(wlc->pub)) {
			WLCNTINCR(wlc->pub->_wme_cnt->
				  tx_failed[WME_PRIO2AC(p->priority)].packets);
			WLCNTADD(wlc->pub->_wme_cnt->
				 tx_failed[WME_PRIO2AC(p->priority)].bytes,
				 pkttotlen(p));
		}
		pkt_buf_free_skb(p);
		wlc->pub->_cnt->txnobuf++;
	}

	/* Enqueue */
	if (head)
		p = pktq_penq_head(q, prec, pkt);
	else
		p = pktq_penq(q, prec, pkt);
	ASSERT(p != NULL);

	return true;
}

void BCMFASTPATH wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu,
			     uint prec)
{
	struct wlc_info *wlc = (struct wlc_info *) ctx;
	struct wlc_txq_info *qi = wlc->active_queue;	/* Check me */
	struct pktq *q = &qi->q;
	int prio;

	prio = sdu->priority;

	ASSERT(pktq_max(q) >= wlc->pub->tunables->datahiwat);

	if (!wlc_prec_enq(wlc, q, sdu, prec)) {
		if (!EDCF_ENAB(wlc->pub)
		    || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL))
			WL_ERROR("wl%d: wlc_txq_enq: txq overflow\n",
				 wlc->pub->unit);

		/*
		 * XXX we might hit this condtion in case
		 * packet flooding from mac80211 stack
		 */
		pkt_buf_free_skb(sdu);
		wlc->pub->_cnt->txnobuf++;
	}

	/* Check if flow control needs to be turned on after enqueuing the packet
	 *   Don't turn on flow control if EDCF is enabled. Driver would make the decision on what
	 *   to drop instead of relying on stack to make the right decision
	 */
	if (!EDCF_ENAB(wlc->pub)
	    || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL)) {
		if (pktq_len(q) >= wlc->pub->tunables->datahiwat) {
			wlc_txflowcontrol(wlc, qi, ON, ALLPRIO);
		}
	} else if (wlc->pub->_priofc) {
		if (pktq_plen(q, wlc_prio2prec_map[prio]) >=
		    wlc->pub->tunables->datahiwat) {
			wlc_txflowcontrol(wlc, qi, ON, prio);
		}
	}
}

bool BCMFASTPATH
wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu,
		     struct ieee80211_hw *hw)
{
	u8 prio;
	uint fifo;
	void *pkt;
	struct scb *scb = &global_scb;
	struct ieee80211_hdr *d11_header = (struct ieee80211_hdr *)(sdu->data);

	ASSERT(sdu);

	/* 802.11 standard requires management traffic to go at highest priority */
	prio = ieee80211_is_data(d11_header->frame_control) ? sdu->priority :
		MAXPRIO;
	fifo = prio2fifo[prio];

	ASSERT((uint) skb_headroom(sdu) >= TXOFF);
	ASSERT(!(sdu->next));
	ASSERT(!(sdu->prev));
	ASSERT(fifo < NFIFO);

	pkt = sdu;
	if (unlikely
	    (wlc_d11hdrs_mac80211(wlc, hw, pkt, scb, 0, 1, fifo, 0, NULL, 0)))
		return -EINVAL;
	wlc_txq_enq(wlc, scb, pkt, WLC_PRIO_TO_PREC(prio));
	wlc_send_q(wlc, wlc->active_queue);

	wlc->pub->_cnt->ieee_tx++;
	return 0;
}

void BCMFASTPATH wlc_send_q(struct wlc_info *wlc, struct wlc_txq_info *qi)
{
	struct sk_buff *pkt[DOT11_MAXNUMFRAGS];
	int prec;
	u16 prec_map;
	int err = 0, i, count;
	uint fifo;
	struct pktq *q = &qi->q;
	struct ieee80211_tx_info *tx_info;

	/* only do work for the active queue */
	if (qi != wlc->active_queue)
		return;

	if (in_send_q)
		return;
	else
		in_send_q = true;

	prec_map = wlc->tx_prec_map;

	/* Send all the enq'd pkts that we can.
	 * Dequeue packets with precedence with empty HW fifo only
	 */
	while (prec_map && (pkt[0] = pktq_mdeq(q, prec_map, &prec))) {
		tx_info = IEEE80211_SKB_CB(pkt[0]);
		if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
			err = wlc_sendampdu(wlc->ampdu, qi, pkt, prec);
		} else {
			count = 1;
			err = wlc_prep_pdu(wlc, pkt[0], &fifo);
			if (!err) {
				for (i = 0; i < count; i++) {
					wlc_txfifo(wlc, fifo, pkt[i], true, 1);
				}
			}
		}

		if (err == BCME_BUSY) {
			pktq_penq_head(q, prec, pkt[0]);
			/* If send failed due to any other reason than a change in
			 * HW FIFO condition, quit. Otherwise, read the new prec_map!
			 */
			if (prec_map == wlc->tx_prec_map)
				break;
			prec_map = wlc->tx_prec_map;
		}
	}

	/* Check if flow control needs to be turned off after sending the packet */
	if (!EDCF_ENAB(wlc->pub)
	    || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL)) {
		if (wlc_txflowcontrol_prio_isset(wlc, qi, ALLPRIO)
		    && (pktq_len(q) < wlc->pub->tunables->datahiwat / 2)) {
			wlc_txflowcontrol(wlc, qi, OFF, ALLPRIO);
		}
	} else if (wlc->pub->_priofc) {
		int prio;
		for (prio = MAXPRIO; prio >= 0; prio--) {
			if (wlc_txflowcontrol_prio_isset(wlc, qi, prio) &&
			    (pktq_plen(q, wlc_prio2prec_map[prio]) <
			     wlc->pub->tunables->datahiwat / 2)) {
				wlc_txflowcontrol(wlc, qi, OFF, prio);
			}
		}
	}
	in_send_q = false;
}

/*
 * bcmc_fid_generate:
 * Generate frame ID for a BCMC packet.  The frag field is not used
 * for MC frames so is used as part of the sequence number.
 */
static inline u16
bcmc_fid_generate(struct wlc_info *wlc, struct wlc_bsscfg *bsscfg,
		  d11txh_t *txh)
{
	u16 frameid;

	frameid = le16_to_cpu(txh->TxFrameID) & ~(TXFID_SEQ_MASK |
						  TXFID_QUEUE_MASK);
	frameid |=
	    (((wlc->
	       mc_fid_counter++) << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) |
	    TX_BCMC_FIFO;

	return frameid;
}

void BCMFASTPATH
wlc_txfifo(struct wlc_info *wlc, uint fifo, struct sk_buff *p, bool commit,
	   s8 txpktpend)
{
	u16 frameid = INVALIDFID;
	d11txh_t *txh;

	ASSERT(fifo < NFIFO);
	txh = (d11txh_t *) (p->data);

	/* When a BC/MC frame is being committed to the BCMC fifo via DMA (NOT PIO), update
	 * ucode or BSS info as appropriate.
	 */
	if (fifo == TX_BCMC_FIFO) {
		frameid = le16_to_cpu(txh->TxFrameID);

	}

	if (WLC_WAR16165(wlc))
		wlc_war16165(wlc, true);


	/* Bump up pending count for if not using rpc. If rpc is used, this will be handled
	 * in wlc_bmac_txfifo()
	 */
	if (commit) {
		TXPKTPENDINC(wlc, fifo, txpktpend);
		WL_TRACE("wlc_txfifo, pktpend inc %d to %d\n",
			 txpktpend, TXPKTPENDGET(wlc, fifo));
	}

	/* Commit BCMC sequence number in the SHM frame ID location */
	if (frameid != INVALIDFID)
		BCMCFID(wlc, frameid);

	if (dma_txfast(wlc->hw->di[fifo], p, commit) < 0) {
		WL_ERROR("wlc_txfifo: fatal, toss frames !!!\n");
	}
}

static u16
wlc_compute_airtime(struct wlc_info *wlc, ratespec_t rspec, uint length)
{
	u16 usec = 0;
	uint mac_rate = RSPEC2RATE(rspec);
	uint nsyms;

	if (IS_MCS(rspec)) {
		/* not supported yet */
		ASSERT(0);
	} else if (IS_OFDM(rspec)) {
		/* nsyms = Ceiling(Nbits / (Nbits/sym))
		 *
		 * Nbits = length * 8
		 * Nbits/sym = Mbps * 4 = mac_rate * 2
		 */
		nsyms = CEIL((length * 8), (mac_rate * 2));

		/* usec = symbols * usec/symbol */
		usec = (u16) (nsyms * APHY_SYMBOL_TIME);
		return usec;
	} else {
		switch (mac_rate) {
		case WLC_RATE_1M:
			usec = length << 3;
			break;
		case WLC_RATE_2M:
			usec = length << 2;
			break;
		case WLC_RATE_5M5:
			usec = (length << 4) / 11;
			break;
		case WLC_RATE_11M:
			usec = (length << 3) / 11;
			break;
		default:
			WL_ERROR("wl%d: wlc_compute_airtime: unsupported rspec 0x%x\n",
				 wlc->pub->unit, rspec);
			ASSERT((const char *)"Bad phy_rate" == NULL);
			break;
		}
	}

	return usec;
}

void BCMFASTPATH
wlc_compute_plcp(struct wlc_info *wlc, ratespec_t rspec, uint length, u8 *plcp)
{
	if (IS_MCS(rspec)) {
		wlc_compute_mimo_plcp(rspec, length, plcp);
	} else if (IS_OFDM(rspec)) {
		wlc_compute_ofdm_plcp(rspec, length, plcp);
	} else {
		wlc_compute_cck_plcp(rspec, length, plcp);
	}
	return;
}

/* Rate: 802.11 rate code, length: PSDU length in octets */
static void wlc_compute_mimo_plcp(ratespec_t rspec, uint length, u8 *plcp)
{
	u8 mcs = (u8) (rspec & RSPEC_RATE_MASK);
	ASSERT(IS_MCS(rspec));
	plcp[0] = mcs;
	if (RSPEC_IS40MHZ(rspec) || (mcs == 32))
		plcp[0] |= MIMO_PLCP_40MHZ;
	WLC_SET_MIMO_PLCP_LEN(plcp, length);
	plcp[3] = RSPEC_MIMOPLCP3(rspec);	/* rspec already holds this byte */
	plcp[3] |= 0x7;		/* set smoothing, not sounding ppdu & reserved */
	plcp[4] = 0;		/* number of extension spatial streams bit 0 & 1 */
	plcp[5] = 0;
}

/* Rate: 802.11 rate code, length: PSDU length in octets */
static void BCMFASTPATH
wlc_compute_ofdm_plcp(ratespec_t rspec, u32 length, u8 *plcp)
{
	u8 rate_signal;
	u32 tmp = 0;
	int rate = RSPEC2RATE(rspec);

	ASSERT(IS_OFDM(rspec));

	/* encode rate per 802.11a-1999 sec 17.3.4.1, with lsb transmitted first */
	rate_signal = rate_info[rate] & RATE_MASK;
	ASSERT(rate_signal != 0);

	memset(plcp, 0, D11_PHY_HDR_LEN);
	D11A_PHY_HDR_SRATE((ofdm_phy_hdr_t *) plcp, rate_signal);

	tmp = (length & 0xfff) << 5;
	plcp[2] |= (tmp >> 16) & 0xff;
	plcp[1] |= (tmp >> 8) & 0xff;
	plcp[0] |= tmp & 0xff;

	return;
}

/*
 * Compute PLCP, but only requires actual rate and length of pkt.
 * Rate is given in the driver standard multiple of 500 kbps.
 * le is set for 11 Mbps rate if necessary.
 * Broken out for PRQ.
 */

static void wlc_cck_plcp_set(int rate_500, uint length, u8 *plcp)
{
	u16 usec = 0;
	u8 le = 0;

	switch (rate_500) {
	case WLC_RATE_1M:
		usec = length << 3;
		break;
	case WLC_RATE_2M:
		usec = length << 2;
		break;
	case WLC_RATE_5M5:
		usec = (length << 4) / 11;
		if ((length << 4) - (usec * 11) > 0)
			usec++;
		break;
	case WLC_RATE_11M:
		usec = (length << 3) / 11;
		if ((length << 3) - (usec * 11) > 0) {
			usec++;
			if ((usec * 11) - (length << 3) >= 8)
				le = D11B_PLCP_SIGNAL_LE;
		}
		break;

	default:
		WL_ERROR("wlc_cck_plcp_set: unsupported rate %d\n", rate_500);
		rate_500 = WLC_RATE_1M;
		usec = length << 3;
		break;
	}
	/* PLCP signal byte */
	plcp[0] = rate_500 * 5;	/* r (500kbps) * 5 == r (100kbps) */
	/* PLCP service byte */
	plcp[1] = (u8) (le | D11B_PLCP_SIGNAL_LOCKED);
	/* PLCP length u16, little endian */
	plcp[2] = usec & 0xff;
	plcp[3] = (usec >> 8) & 0xff;
	/* PLCP CRC16 */
	plcp[4] = 0;
	plcp[5] = 0;
}

/* Rate: 802.11 rate code, length: PSDU length in octets */
static void wlc_compute_cck_plcp(ratespec_t rspec, uint length, u8 *plcp)
{
	int rate = RSPEC2RATE(rspec);

	ASSERT(IS_CCK(rspec));

	wlc_cck_plcp_set(rate, length, plcp);
}

/* wlc_compute_frame_dur()
 *
 * Calculate the 802.11 MAC header DUR field for MPDU
 * DUR for a single frame = 1 SIFS + 1 ACK
 * DUR for a frame with following frags = 3 SIFS + 2 ACK + next frag time
 *
 * rate			MPDU rate in unit of 500kbps
 * next_frag_len	next MPDU length in bytes
 * preamble_type	use short/GF or long/MM PLCP header
 */
static u16 BCMFASTPATH
wlc_compute_frame_dur(struct wlc_info *wlc, ratespec_t rate, u8 preamble_type,
		      uint next_frag_len)
{
	u16 dur, sifs;

	sifs = SIFS(wlc->band);

	dur = sifs;
	dur += (u16) wlc_calc_ack_time(wlc, rate, preamble_type);

	if (next_frag_len) {
		/* Double the current DUR to get 2 SIFS + 2 ACKs */
		dur *= 2;
		/* add another SIFS and the frag time */
		dur += sifs;
		dur +=
		    (u16) wlc_calc_frame_time(wlc, rate, preamble_type,
						 next_frag_len);
	}
	return dur;
}

/* wlc_compute_rtscts_dur()
 *
 * Calculate the 802.11 MAC header DUR field for an RTS or CTS frame
 * DUR for normal RTS/CTS w/ frame = 3 SIFS + 1 CTS + next frame time + 1 ACK
 * DUR for CTS-TO-SELF w/ frame    = 2 SIFS         + next frame time + 1 ACK
 *
 * cts			cts-to-self or rts/cts
 * rts_rate		rts or cts rate in unit of 500kbps
 * rate			next MPDU rate in unit of 500kbps
 * frame_len		next MPDU frame length in bytes
 */
u16 BCMFASTPATH
wlc_compute_rtscts_dur(struct wlc_info *wlc, bool cts_only, ratespec_t rts_rate,
		       ratespec_t frame_rate, u8 rts_preamble_type,
		       u8 frame_preamble_type, uint frame_len, bool ba)
{
	u16 dur, sifs;

	sifs = SIFS(wlc->band);

	if (!cts_only) {	/* RTS/CTS */
		dur = 3 * sifs;
		dur +=
		    (u16) wlc_calc_cts_time(wlc, rts_rate,
					       rts_preamble_type);
	} else {		/* CTS-TO-SELF */
		dur = 2 * sifs;
	}

	dur +=
	    (u16) wlc_calc_frame_time(wlc, frame_rate, frame_preamble_type,
					 frame_len);
	if (ba)
		dur +=
		    (u16) wlc_calc_ba_time(wlc, frame_rate,
					      WLC_SHORT_PREAMBLE);
	else
		dur +=
		    (u16) wlc_calc_ack_time(wlc, frame_rate,
					       frame_preamble_type);
	return dur;
}

static bool wlc_phy_rspec_check(struct wlc_info *wlc, u16 bw, ratespec_t rspec)
{
	if (IS_MCS(rspec)) {
		uint mcs = rspec & RSPEC_RATE_MASK;

		if (mcs < 8) {
			ASSERT(RSPEC_STF(rspec) < PHY_TXC1_MODE_SDM);
		} else if ((mcs >= 8) && (mcs <= 23)) {
			ASSERT(RSPEC_STF(rspec) == PHY_TXC1_MODE_SDM);
		} else if (mcs == 32) {
			ASSERT(RSPEC_STF(rspec) < PHY_TXC1_MODE_SDM);
			ASSERT(bw == PHY_TXC1_BW_40MHZ_DUP);
		}
	} else if (IS_OFDM(rspec)) {
		ASSERT(RSPEC_STF(rspec) < PHY_TXC1_MODE_STBC);
	} else {
		ASSERT(IS_CCK(rspec));

		ASSERT((bw == PHY_TXC1_BW_20MHZ)
		       || (bw == PHY_TXC1_BW_20MHZ_UP));
		ASSERT(RSPEC_STF(rspec) == PHY_TXC1_MODE_SISO);
	}

	return true;
}

u16 BCMFASTPATH wlc_phytxctl1_calc(struct wlc_info *wlc, ratespec_t rspec)
{
	u16 phyctl1 = 0;
	u16 bw;

	if (WLCISLCNPHY(wlc->band)) {
		bw = PHY_TXC1_BW_20MHZ;
	} else {
		bw = RSPEC_GET_BW(rspec);
		/* 10Mhz is not supported yet */
		if (bw < PHY_TXC1_BW_20MHZ) {
			WL_ERROR("wlc_phytxctl1_calc: bw %d is not supported yet, set to 20L\n",
				 bw);
			bw = PHY_TXC1_BW_20MHZ;
		}

		wlc_phy_rspec_check(wlc, bw, rspec);
	}

	if (IS_MCS(rspec)) {
		uint mcs = rspec & RSPEC_RATE_MASK;

		/* bw, stf, coding-type is part of RSPEC_PHYTXBYTE2 returns */
		phyctl1 = RSPEC_PHYTXBYTE2(rspec);
		/* set the upper byte of phyctl1 */
		phyctl1 |= (mcs_table[mcs].tx_phy_ctl3 << 8);
	} else if (IS_CCK(rspec) && !WLCISLCNPHY(wlc->band)
		   && !WLCISSSLPNPHY(wlc->band)) {
		/* In CCK mode LPPHY overloads OFDM Modulation bits with CCK Data Rate */
		/* Eventually MIMOPHY would also be converted to this format */
		/* 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps */
		phyctl1 = (bw | (RSPEC_STF(rspec) << PHY_TXC1_MODE_SHIFT));
	} else {		/* legacy OFDM/CCK */
		s16 phycfg;
		/* get the phyctl byte from rate phycfg table */
		phycfg = wlc_rate_legacy_phyctl(RSPEC2RATE(rspec));
		if (phycfg == -1) {
			WL_ERROR("wlc_phytxctl1_calc: wrong legacy OFDM/CCK rate\n");
			ASSERT(0);
			phycfg = 0;
		}
		/* set the upper byte of phyctl1 */
		phyctl1 =
		    (bw | (phycfg << 8) |
		     (RSPEC_STF(rspec) << PHY_TXC1_MODE_SHIFT));
	}

#ifdef BCMDBG
	/* phy clock must support 40Mhz if tx descriptor uses it */
	if ((phyctl1 & PHY_TXC1_BW_MASK) >= PHY_TXC1_BW_40MHZ) {
		ASSERT(CHSPEC_WLC_BW(wlc->chanspec) == WLC_40_MHZ);
		ASSERT(wlc->chanspec == wlc_phy_chanspec_get(wlc->band->pi));
	}
#endif				/* BCMDBG */
	return phyctl1;
}

ratespec_t BCMFASTPATH
wlc_rspec_to_rts_rspec(struct wlc_info *wlc, ratespec_t rspec, bool use_rspec,
		       u16 mimo_ctlchbw)
{
	ratespec_t rts_rspec = 0;

	if (use_rspec) {
		/* use frame rate as rts rate */
		rts_rspec = rspec;

	} else if (wlc->band->gmode && wlc->protection->_g && !IS_CCK(rspec)) {
		/* Use 11Mbps as the g protection RTS target rate and fallback.
		 * Use the WLC_BASIC_RATE() lookup to find the best basic rate under the
		 * target in case 11 Mbps is not Basic.
		 * 6 and 9 Mbps are not usually selected by rate selection, but even
		 * if the OFDM rate we are protecting is 6 or 9 Mbps, 11 is more robust.
		 */
		rts_rspec = WLC_BASIC_RATE(wlc, WLC_RATE_11M);
	} else {
		/* calculate RTS rate and fallback rate based on the frame rate
		 * RTS must be sent at a basic rate since it is a
		 * control frame, sec 9.6 of 802.11 spec
		 */
		rts_rspec = WLC_BASIC_RATE(wlc, rspec);
	}

	if (WLC_PHY_11N_CAP(wlc->band)) {
		/* set rts txbw to correct side band */
		rts_rspec &= ~RSPEC_BW_MASK;

		/* if rspec/rspec_fallback is 40MHz, then send RTS on both 20MHz channel
		 * (DUP), otherwise send RTS on control channel
		 */
		if (RSPEC_IS40MHZ(rspec) && !IS_CCK(rts_rspec))
			rts_rspec |= (PHY_TXC1_BW_40MHZ_DUP << RSPEC_BW_SHIFT);
		else
			rts_rspec |= (mimo_ctlchbw << RSPEC_BW_SHIFT);

		/* pick siso/cdd as default for ofdm */
		if (IS_OFDM(rts_rspec)) {
			rts_rspec &= ~RSPEC_STF_MASK;
			rts_rspec |= (wlc->stf->ss_opmode << RSPEC_STF_SHIFT);
		}
	}
	return rts_rspec;
}

/*
 * Add d11txh_t, cck_phy_hdr_t.
 *
 * 'p' data must start with 802.11 MAC header
 * 'p' must allow enough bytes of local headers to be "pushed" onto the packet
 *
 * headroom == D11_PHY_HDR_LEN + D11_TXH_LEN (D11_TXH_LEN is now 104 bytes)
 *
 */
static u16 BCMFASTPATH
wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw,
		     struct sk_buff *p, struct scb *scb, uint frag,
		     uint nfrags, uint queue, uint next_frag_len,
		     wsec_key_t *key, ratespec_t rspec_override)
{
	struct ieee80211_hdr *h;
	d11txh_t *txh;
	u8 *plcp, plcp_fallback[D11_PHY_HDR_LEN];
	int len, phylen, rts_phylen;
	u16 mch, phyctl, xfts, mainrates;
	u16 seq = 0, mcl = 0, status = 0, frameid = 0;
	ratespec_t rspec[2] = { WLC_RATE_1M, WLC_RATE_1M }, rts_rspec[2] = {
	WLC_RATE_1M, WLC_RATE_1M};
	bool use_rts = false;
	bool use_cts = false;
	bool use_rifs = false;
	bool short_preamble[2] = { false, false };
	u8 preamble_type[2] = { WLC_LONG_PREAMBLE, WLC_LONG_PREAMBLE };
	u8 rts_preamble_type[2] = { WLC_LONG_PREAMBLE, WLC_LONG_PREAMBLE };
	u8 *rts_plcp, rts_plcp_fallback[D11_PHY_HDR_LEN];
	struct ieee80211_rts *rts = NULL;
	bool qos;
	uint ac;
	u32 rate_val[2];
	bool hwtkmic = false;
	u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ;
#define ANTCFG_NONE 0xFF
	u8 antcfg = ANTCFG_NONE;
	u8 fbantcfg = ANTCFG_NONE;
	uint phyctl1_stf = 0;
	u16 durid = 0;
	struct ieee80211_tx_rate *txrate[2];
	int k;
	struct ieee80211_tx_info *tx_info;
	bool is_mcs[2];
	u16 mimo_txbw;
	u8 mimo_preamble_type;

	ASSERT(queue < NFIFO);

	/* locate 802.11 MAC header */
	h = (struct ieee80211_hdr *)(p->data);
	qos = ieee80211_is_data_qos(h->frame_control);

	/* compute length of frame in bytes for use in PLCP computations */
	len = pkttotlen(p);
	phylen = len + FCS_LEN;

	/* If WEP enabled, add room in phylen for the additional bytes of
	 * ICV which MAC generates.  We do NOT add the additional bytes to
	 * the packet itself, thus phylen = packet length + ICV_LEN + FCS_LEN
	 * in this case
	 */
	if (key) {
		phylen += key->icv_len;
	}

	/* Get tx_info */
	tx_info = IEEE80211_SKB_CB(p);
	ASSERT(tx_info);

	/* add PLCP */
	plcp = skb_push(p, D11_PHY_HDR_LEN);

	/* add Broadcom tx descriptor header */
	txh = (d11txh_t *) skb_push(p, D11_TXH_LEN);
	memset(txh, 0, D11_TXH_LEN);

	/* setup frameid */
	if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
		/* non-AP STA should never use BCMC queue */
		ASSERT(queue != TX_BCMC_FIFO);
		if (queue == TX_BCMC_FIFO) {
			WL_ERROR("wl%d: %s: ASSERT queue == TX_BCMC!\n",
				 WLCWLUNIT(wlc), __func__);
			frameid = bcmc_fid_generate(wlc, NULL, txh);
		} else {
			/* Increment the counter for first fragment */
			if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) {
				SCB_SEQNUM(scb, p->priority)++;
			}

			/* extract fragment number from frame first */
			seq = le16_to_cpu(seq) & FRAGNUM_MASK;
			seq |= (SCB_SEQNUM(scb, p->priority) << SEQNUM_SHIFT);
			h->seq_ctrl = cpu_to_le16(seq);

			frameid = ((seq << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) |
			    (queue & TXFID_QUEUE_MASK);
		}
	}
	frameid |= queue & TXFID_QUEUE_MASK;

	/* set the ignpmq bit for all pkts tx'd in PS mode and for beacons */
	if (SCB_PS(scb) || ieee80211_is_beacon(h->frame_control))
		mcl |= TXC_IGNOREPMQ;

	ASSERT(hw->max_rates <= IEEE80211_TX_MAX_RATES);
	ASSERT(hw->max_rates == 2);

	txrate[0] = tx_info->control.rates;
	txrate[1] = txrate[0] + 1;

	ASSERT(txrate[0]->idx >= 0);
	/* if rate control algorithm didn't give us a fallback rate, use the primary rate */
	if (txrate[1]->idx < 0) {
		txrate[1] = txrate[0];
	}

	for (k = 0; k < hw->max_rates; k++) {
		is_mcs[k] =
		    txrate[k]->flags & IEEE80211_TX_RC_MCS ? true : false;
		if (!is_mcs[k]) {
			ASSERT(!(tx_info->flags & IEEE80211_TX_CTL_AMPDU));
			if ((txrate[k]->idx >= 0)
			    && (txrate[k]->idx <
				hw->wiphy->bands[tx_info->band]->n_bitrates)) {
				rate_val[k] =
				    hw->wiphy->bands[tx_info->band]->
				    bitrates[txrate[k]->idx].hw_value;
				short_preamble[k] =
				    txrate[k]->
				    flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE ?
				    true : false;
			} else {
				ASSERT((txrate[k]->idx >= 0) &&
				       (txrate[k]->idx <
					hw->wiphy->bands[tx_info->band]->
					n_bitrates));
				rate_val[k] = WLC_RATE_1M;
			}
		} else {
			rate_val[k] = txrate[k]->idx;
		}
		/* Currently only support same setting for primay and fallback rates.
		 * Unify flags for each rate into a single value for the frame
		 */
		use_rts |=
		    txrate[k]->
		    flags & IEEE80211_TX_RC_USE_RTS_CTS ? true : false;
		use_cts |=
		    txrate[k]->
		    flags & IEEE80211_TX_RC_USE_CTS_PROTECT ? true : false;

		if (is_mcs[k])
			rate_val[k] |= NRATE_MCS_INUSE;

		rspec[k] = mac80211_wlc_set_nrate(wlc, wlc->band, rate_val[k]);

		/* (1) RATE: determine and validate primary rate and fallback rates */
		if (!RSPEC_ACTIVE(rspec[k])) {
			ASSERT(RSPEC_ACTIVE(rspec[k]));
			rspec[k] = WLC_RATE_1M;
		} else {
			if (!is_multicast_ether_addr(h->addr1)) {
				/* set tx antenna config */
				wlc_antsel_antcfg_get(wlc->asi, false, false, 0,
						      0, &antcfg, &fbantcfg);
			}
		}
	}

	phyctl1_stf = wlc->stf->ss_opmode;

	if (N_ENAB(wlc->pub)) {
		for (k = 0; k < hw->max_rates; k++) {
			/* apply siso/cdd to single stream mcs's or ofdm if rspec is auto selected */
			if (((IS_MCS(rspec[k]) &&
			      IS_SINGLE_STREAM(rspec[k] & RSPEC_RATE_MASK)) ||
			     IS_OFDM(rspec[k]))
			    && ((rspec[k] & RSPEC_OVERRIDE_MCS_ONLY)
				|| !(rspec[k] & RSPEC_OVERRIDE))) {
				rspec[k] &= ~(RSPEC_STF_MASK | RSPEC_STC_MASK);

				/* For SISO MCS use STBC if possible */
				if (IS_MCS(rspec[k])
				    && WLC_STF_SS_STBC_TX(wlc, scb)) {
					u8 stc;

					ASSERT(WLC_STBC_CAP_PHY(wlc));
					stc = 1;	/* Nss for single stream is always 1 */
					rspec[k] |=
					    (PHY_TXC1_MODE_STBC <<
					     RSPEC_STF_SHIFT) | (stc <<
								 RSPEC_STC_SHIFT);
				} else
					rspec[k] |=
					    (phyctl1_stf << RSPEC_STF_SHIFT);
			}

			/* Is the phy configured to use 40MHZ frames? If so then pick the desired txbw */
			if (CHSPEC_WLC_BW(wlc->chanspec) == WLC_40_MHZ) {
				/* default txbw is 20in40 SB */
				mimo_ctlchbw = mimo_txbw =
				    CHSPEC_SB_UPPER(WLC_BAND_PI_RADIO_CHANSPEC)
				    ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ;

				if (IS_MCS(rspec[k])) {
					/* mcs 32 must be 40b/w DUP */
					if ((rspec[k] & RSPEC_RATE_MASK) == 32) {
						mimo_txbw =
						    PHY_TXC1_BW_40MHZ_DUP;
						/* use override */
					} else if (wlc->mimo_40txbw != AUTO)
						mimo_txbw = wlc->mimo_40txbw;
					/* else check if dst is using 40 Mhz */
					else if (scb->flags & SCB_IS40)
						mimo_txbw = PHY_TXC1_BW_40MHZ;
				} else if (IS_OFDM(rspec[k])) {
					if (wlc->ofdm_40txbw != AUTO)
						mimo_txbw = wlc->ofdm_40txbw;
				} else {
					ASSERT(IS_CCK(rspec[k]));
					if (wlc->cck_40txbw != AUTO)
						mimo_txbw = wlc->cck_40txbw;
				}
			} else {
				/* mcs32 is 40 b/w only.
				 * This is possible for probe packets on a STA during SCAN
				 */
				if ((rspec[k] & RSPEC_RATE_MASK) == 32) {
					/* mcs 0 */
					rspec[k] = RSPEC_MIMORATE;
				}
				mimo_txbw = PHY_TXC1_BW_20MHZ;
			}

			/* Set channel width */
			rspec[k] &= ~RSPEC_BW_MASK;
			if ((k == 0) || ((k > 0) && IS_MCS(rspec[k])))
				rspec[k] |= (mimo_txbw << RSPEC_BW_SHIFT);
			else
				rspec[k] |= (mimo_ctlchbw << RSPEC_BW_SHIFT);

			/* Set Short GI */
#ifdef NOSGIYET
			if (IS_MCS(rspec[k])
			    && (txrate[k]->flags & IEEE80211_TX_RC_SHORT_GI))
				rspec[k] |= RSPEC_SHORT_GI;
			else if (!(txrate[k]->flags & IEEE80211_TX_RC_SHORT_GI))
				rspec[k] &= ~RSPEC_SHORT_GI;
#else
			rspec[k] &= ~RSPEC_SHORT_GI;
#endif

			mimo_preamble_type = WLC_MM_PREAMBLE;
			if (txrate[k]->flags & IEEE80211_TX_RC_GREEN_FIELD)
				mimo_preamble_type = WLC_GF_PREAMBLE;

			if ((txrate[k]->flags & IEEE80211_TX_RC_MCS)
			    && (!IS_MCS(rspec[k]))) {
				WL_ERROR("wl%d: %s: IEEE80211_TX_RC_MCS != IS_MCS(rspec)\n",
					 WLCWLUNIT(wlc), __func__);
				ASSERT(0 && "Rate mismatch");
			}

			if (IS_MCS(rspec[k])) {
				preamble_type[k] = mimo_preamble_type;

				/* if SGI is selected, then forced mm for single stream */
				if ((rspec[k] & RSPEC_SHORT_GI)
				    && IS_SINGLE_STREAM(rspec[k] &
							RSPEC_RATE_MASK)) {
					preamble_type[k] = WLC_MM_PREAMBLE;
				}
			}

			/* mimo bw field MUST now be valid in the rspec (it affects duration calculations) */
			ASSERT(VALID_RATE_DBG(wlc, rspec[0]));

			/* should be better conditionalized */
			if (!IS_MCS(rspec[0])
			    && (tx_info->control.rates[0].
				flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE))
				preamble_type[k] = WLC_SHORT_PREAMBLE;

			ASSERT(!IS_MCS(rspec[0])
			       || WLC_IS_MIMO_PREAMBLE(preamble_type[k]));
		}
	} else {
		for (k = 0; k < hw->max_rates; k++) {
			/* Set ctrlchbw as 20Mhz */
			ASSERT(!IS_MCS(rspec[k]));
			rspec[k] &= ~RSPEC_BW_MASK;
			rspec[k] |= (PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT);

			/* for nphy, stf of ofdm frames must follow policies */
			if (WLCISNPHY(wlc->band) && IS_OFDM(rspec[k])) {
				rspec[k] &= ~RSPEC_STF_MASK;
				rspec[k] |= phyctl1_stf << RSPEC_STF_SHIFT;
			}
		}
	}

	/* Reset these for use with AMPDU's */
	txrate[0]->count = 0;
	txrate[1]->count = 0;

	/* (2) PROTECTION, may change rspec */
	if ((ieee80211_is_data(h->frame_control) ||
	    ieee80211_is_mgmt(h->frame_control)) &&
	    (phylen > wlc->RTSThresh) && !is_multicast_ether_addr(h->addr1))
		use_rts = true;

	/* (3) PLCP: determine PLCP header and MAC duration, fill d11txh_t */
	wlc_compute_plcp(wlc, rspec[0], phylen, plcp);
	wlc_compute_plcp(wlc, rspec[1], phylen, plcp_fallback);
	memcpy(&txh->FragPLCPFallback,
	       plcp_fallback, sizeof(txh->FragPLCPFallback));

	/* Length field now put in CCK FBR CRC field */
	if (IS_CCK(rspec[1])) {
		txh->FragPLCPFallback[4] = phylen & 0xff;
		txh->FragPLCPFallback[5] = (phylen & 0xff00) >> 8;
	}

	/* MIMO-RATE: need validation ?? */
	mainrates =
	    IS_OFDM(rspec[0]) ? D11A_PHY_HDR_GRATE((ofdm_phy_hdr_t *) plcp) :
	    plcp[0];

	/* DUR field for main rate */
	if (!ieee80211_is_pspoll(h->frame_control) &&
	    !is_multicast_ether_addr(h->addr1) && !use_rifs) {
		durid =
		    wlc_compute_frame_dur(wlc, rspec[0], preamble_type[0],
					  next_frag_len);
		h->duration_id = cpu_to_le16(durid);
	} else if (use_rifs) {
		/* NAV protect to end of next max packet size */
		durid =
		    (u16) wlc_calc_frame_time(wlc, rspec[0],
						 preamble_type[0],
						 DOT11_MAX_FRAG_LEN);
		durid += RIFS_11N_TIME;
		h->duration_id = cpu_to_le16(durid);
	}

	/* DUR field for fallback rate */
	if (ieee80211_is_pspoll(h->frame_control))
		txh->FragDurFallback = h->duration_id;
	else if (is_multicast_ether_addr(h->addr1) || use_rifs)
		txh->FragDurFallback = 0;
	else {
		durid = wlc_compute_frame_dur(wlc, rspec[1],
					      preamble_type[1], next_frag_len);
		txh->FragDurFallback = cpu_to_le16(durid);
	}

	/* (4) MAC-HDR: MacTxControlLow */
	if (frag == 0)
		mcl |= TXC_STARTMSDU;

	if (!is_multicast_ether_addr(h->addr1))
		mcl |= TXC_IMMEDACK;

	if (BAND_5G(wlc->band->bandtype))
		mcl |= TXC_FREQBAND_5G;

	if (CHSPEC_IS40(WLC_BAND_PI_RADIO_CHANSPEC))
		mcl |= TXC_BW_40;

	/* set AMIC bit if using hardware TKIP MIC */
	if (hwtkmic)
		mcl |= TXC_AMIC;

	txh->MacTxControlLow = cpu_to_le16(mcl);

	/* MacTxControlHigh */
	mch = 0;

	/* Set fallback rate preamble type */
	if ((preamble_type[1] == WLC_SHORT_PREAMBLE) ||
	    (preamble_type[1] == WLC_GF_PREAMBLE)) {
		ASSERT((preamble_type[1] == WLC_GF_PREAMBLE) ||
		       (!IS_MCS(rspec[1])));
		if (RSPEC2RATE(rspec[1]) != WLC_RATE_1M)
			mch |= TXC_PREAMBLE_DATA_FB_SHORT;
	}

	/* MacFrameControl */
	memcpy(&txh->MacFrameControl, &h->frame_control, sizeof(u16));
	txh->TxFesTimeNormal = cpu_to_le16(0);

	txh->TxFesTimeFallback = cpu_to_le16(0);

	/* TxFrameRA */
	memcpy(&txh->TxFrameRA, &h->addr1, ETH_ALEN);

	/* TxFrameID */
	txh->TxFrameID = cpu_to_le16(frameid);

	/* TxStatus, Note the case of recreating the first frag of a suppressed frame
	 * then we may need to reset the retry cnt's via the status reg
	 */
	txh->TxStatus = cpu_to_le16(status);

	/* extra fields for ucode AMPDU aggregation, the new fields are added to
	 * the END of previous structure so that it's compatible in driver.
	 */
	txh->MaxNMpdus = cpu_to_le16(0);
	txh->MaxABytes_MRT = cpu_to_le16(0);
	txh->MaxABytes_FBR = cpu_to_le16(0);
	txh->MinMBytes = cpu_to_le16(0);

	/* (5) RTS/CTS: determine RTS/CTS PLCP header and MAC duration, furnish d11txh_t */
	/* RTS PLCP header and RTS frame */
	if (use_rts || use_cts) {
		if (use_rts && use_cts)
			use_cts = false;

		for (k = 0; k < 2; k++) {
			rts_rspec[k] = wlc_rspec_to_rts_rspec(wlc, rspec[k],
							      false,
							      mimo_ctlchbw);
		}

		if (!IS_OFDM(rts_rspec[0]) &&
		    !((RSPEC2RATE(rts_rspec[0]) == WLC_RATE_1M) ||
		      (wlc->PLCPHdr_override == WLC_PLCP_LONG))) {
			rts_preamble_type[0] = WLC_SHORT_PREAMBLE;
			mch |= TXC_PREAMBLE_RTS_MAIN_SHORT;
		}

		if (!IS_OFDM(rts_rspec[1]) &&
		    !((RSPEC2RATE(rts_rspec[1]) == WLC_RATE_1M) ||
		      (wlc->PLCPHdr_override == WLC_PLCP_LONG))) {
			rts_preamble_type[1] = WLC_SHORT_PREAMBLE;
			mch |= TXC_PREAMBLE_RTS_FB_SHORT;
		}

		/* RTS/CTS additions to MacTxControlLow */
		if (use_cts) {
			txh->MacTxControlLow |= cpu_to_le16(TXC_SENDCTS);
		} else {
			txh->MacTxControlLow |= cpu_to_le16(TXC_SENDRTS);
			txh->MacTxControlLow |= cpu_to_le16(TXC_LONGFRAME);
		}

		/* RTS PLCP header */
		ASSERT(IS_ALIGNED((unsigned long)txh->RTSPhyHeader, sizeof(u16)));
		rts_plcp = txh->RTSPhyHeader;
		if (use_cts)
			rts_phylen = DOT11_CTS_LEN + FCS_LEN;
		else
			rts_phylen = DOT11_RTS_LEN + FCS_LEN;

		wlc_compute_plcp(wlc, rts_rspec[0], rts_phylen, rts_plcp);

		/* fallback rate version of RTS PLCP header */
		wlc_compute_plcp(wlc, rts_rspec[1], rts_phylen,
				 rts_plcp_fallback);
		memcpy(&txh->RTSPLCPFallback, rts_plcp_fallback,
		       sizeof(txh->RTSPLCPFallback));

		/* RTS frame fields... */
		rts = (struct ieee80211_rts *)&txh->rts_frame;

		durid = wlc_compute_rtscts_dur(wlc, use_cts, rts_rspec[0],
					       rspec[0], rts_preamble_type[0],
					       preamble_type[0], phylen, false);
		rts->duration = cpu_to_le16(durid);
		/* fallback rate version of RTS DUR field */
		durid = wlc_compute_rtscts_dur(wlc, use_cts,
					       rts_rspec[1], rspec[1],
					       rts_preamble_type[1],
					       preamble_type[1], phylen, false);
		txh->RTSDurFallback = cpu_to_le16(durid);

		if (use_cts) {
			rts->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
							 IEEE80211_STYPE_CTS);

			memcpy(&rts->ra, &h->addr2, ETH_ALEN);
		} else {
			rts->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
							 IEEE80211_STYPE_RTS);

			memcpy(&rts->ra, &h->addr1, 2 * ETH_ALEN);
		}

		/* mainrate
		 *    low 8 bits: main frag rate/mcs,
		 *    high 8 bits: rts/cts rate/mcs
		 */
		mainrates |= (IS_OFDM(rts_rspec[0]) ?
			      D11A_PHY_HDR_GRATE((ofdm_phy_hdr_t *) rts_plcp) :
			      rts_plcp[0]) << 8;
	} else {
		memset((char *)txh->RTSPhyHeader, 0, D11_PHY_HDR_LEN);
		memset((char *)&txh->rts_frame, 0,
			sizeof(struct ieee80211_rts));
		memset((char *)txh->RTSPLCPFallback, 0,
		      sizeof(txh->RTSPLCPFallback));
		txh->RTSDurFallback = 0;
	}

#ifdef SUPPORT_40MHZ
	/* add null delimiter count */
	if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && IS_MCS(rspec)) {
		txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] =
		    wlc_ampdu_null_delim_cnt(wlc->ampdu, scb, rspec, phylen);
	}
#endif

	/* Now that RTS/RTS FB preamble types are updated, write the final value */
	txh->MacTxControlHigh = cpu_to_le16(mch);

	/* MainRates (both the rts and frag plcp rates have been calculated now) */
	txh->MainRates = cpu_to_le16(mainrates);

	/* XtraFrameTypes */
	xfts = FRAMETYPE(rspec[1], wlc->mimoft);
	xfts |= (FRAMETYPE(rts_rspec[0], wlc->mimoft) << XFTS_RTS_FT_SHIFT);
	xfts |= (FRAMETYPE(rts_rspec[1], wlc->mimoft) << XFTS_FBRRTS_FT_SHIFT);
	xfts |=
	    CHSPEC_CHANNEL(WLC_BAND_PI_RADIO_CHANSPEC) << XFTS_CHANNEL_SHIFT;
	txh->XtraFrameTypes = cpu_to_le16(xfts);

	/* PhyTxControlWord */
	phyctl = FRAMETYPE(rspec[0], wlc->mimoft);
	if ((preamble_type[0] == WLC_SHORT_PREAMBLE) ||
	    (preamble_type[0] == WLC_GF_PREAMBLE)) {
		ASSERT((preamble_type[0] == WLC_GF_PREAMBLE)
		       || !IS_MCS(rspec[0]));
		if (RSPEC2RATE(rspec[0]) != WLC_RATE_1M)
			phyctl |= PHY_TXC_SHORT_HDR;
		wlc->pub->_cnt->txprshort++;
	}

	/* phytxant is properly bit shifted */
	phyctl |= wlc_stf_d11hdrs_phyctl_txant(wlc, rspec[0]);
	txh->PhyTxControlWord = cpu_to_le16(phyctl);

	/* PhyTxControlWord_1 */
	if (WLC_PHY_11N_CAP(wlc->band)) {
		u16 phyctl1 = 0;

		phyctl1 = wlc_phytxctl1_calc(wlc, rspec[0]);
		txh->PhyTxControlWord_1 = cpu_to_le16(phyctl1);
		phyctl1 = wlc_phytxctl1_calc(wlc, rspec[1]);
		txh->PhyTxControlWord_1_Fbr = cpu_to_le16(phyctl1);

		if (use_rts || use_cts) {
			phyctl1 = wlc_phytxctl1_calc(wlc, rts_rspec[0]);
			txh->PhyTxControlWord_1_Rts = cpu_to_le16(phyctl1);
			phyctl1 = wlc_phytxctl1_calc(wlc, rts_rspec[1]);
			txh->PhyTxControlWord_1_FbrRts = cpu_to_le16(phyctl1);
		}

		/*
		 * For mcs frames, if mixedmode(overloaded with long preamble) is going to be set,
		 * fill in non-zero MModeLen and/or MModeFbrLen
		 *  it will be unnecessary if they are separated
		 */
		if (IS_MCS(rspec[0]) && (preamble_type[0] == WLC_MM_PREAMBLE)) {
			u16 mmodelen =
			    wlc_calc_lsig_len(wlc, rspec[0], phylen);
			txh->MModeLen = cpu_to_le16(mmodelen);
		}

		if (IS_MCS(rspec[1]) && (preamble_type[1] == WLC_MM_PREAMBLE)) {
			u16 mmodefbrlen =
			    wlc_calc_lsig_len(wlc, rspec[1], phylen);
			txh->MModeFbrLen = cpu_to_le16(mmodefbrlen);
		}
	}

	if (IS_MCS(rspec[0]))
		ASSERT(IS_MCS(rspec[1]));

	ASSERT(!IS_MCS(rspec[0]) ||
	       ((preamble_type[0] == WLC_MM_PREAMBLE) == (txh->MModeLen != 0)));
	ASSERT(!IS_MCS(rspec[1]) ||
	       ((preamble_type[1] == WLC_MM_PREAMBLE) ==
		(txh->MModeFbrLen != 0)));

	ac = skb_get_queue_mapping(p);
	if (SCB_WME(scb) && qos && wlc->edcf_txop[ac]) {
		uint frag_dur, dur, dur_fallback;

		ASSERT(!is_multicast_ether_addr(h->addr1));

		/* WME: Update TXOP threshold */
		if ((!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) && (frag == 0)) {
			frag_dur =
			    wlc_calc_frame_time(wlc, rspec[0], preamble_type[0],
						phylen);

			if (rts) {
				/* 1 RTS or CTS-to-self frame */
				dur =
				    wlc_calc_cts_time(wlc, rts_rspec[0],
						      rts_preamble_type[0]);
				dur_fallback =
				    wlc_calc_cts_time(wlc, rts_rspec[1],
						      rts_preamble_type[1]);
				/* (SIFS + CTS) + SIFS + frame + SIFS + ACK */
				dur += le16_to_cpu(rts->duration);
				dur_fallback +=
					le16_to_cpu(txh->RTSDurFallback);
			} else if (use_rifs) {
				dur = frag_dur;
				dur_fallback = 0;
			} else {
				/* frame + SIFS + ACK */
				dur = frag_dur;
				dur +=
				    wlc_compute_frame_dur(wlc, rspec[0],
							  preamble_type[0], 0);

				dur_fallback =
				    wlc_calc_frame_time(wlc, rspec[1],
							preamble_type[1],
							phylen);
				dur_fallback +=
				    wlc_compute_frame_dur(wlc, rspec[1],
							  preamble_type[1], 0);
			}
			/* NEED to set TxFesTimeNormal (hard) */
			txh->TxFesTimeNormal = cpu_to_le16((u16) dur);
			/* NEED to set fallback rate version of TxFesTimeNormal (hard) */
			txh->TxFesTimeFallback =
				cpu_to_le16((u16) dur_fallback);

			/* update txop byte threshold (txop minus intraframe overhead) */
			if (wlc->edcf_txop[ac] >= (dur - frag_dur)) {
				{
					uint newfragthresh;

					newfragthresh =
					    wlc_calc_frame_len(wlc, rspec[0],
							       preamble_type[0],
							       (wlc->
								edcf_txop[ac] -
								(dur -
								 frag_dur)));
					/* range bound the fragthreshold */
					if (newfragthresh < DOT11_MIN_FRAG_LEN)
						newfragthresh =
						    DOT11_MIN_FRAG_LEN;
					else if (newfragthresh >
						 wlc->usr_fragthresh)
						newfragthresh =
						    wlc->usr_fragthresh;
					/* update the fragthresh and do txc update */
					if (wlc->fragthresh[queue] !=
					    (u16) newfragthresh) {
						wlc->fragthresh[queue] =
						    (u16) newfragthresh;
					}
				}
			} else
				WL_ERROR("wl%d: %s txop invalid for rate %d\n",
					 wlc->pub->unit, fifo_names[queue],
					 RSPEC2RATE(rspec[0]));

			if (dur > wlc->edcf_txop[ac])
				WL_ERROR("wl%d: %s: %s txop exceeded phylen %d/%d dur %d/%d\n",
					 wlc->pub->unit, __func__,
					 fifo_names[queue],
					 phylen, wlc->fragthresh[queue],
					 dur, wlc->edcf_txop[ac]);
		}
	}

	return 0;
}

void wlc_tbtt(struct wlc_info *wlc, d11regs_t *regs)
{
	struct wlc_bsscfg *cfg = wlc->cfg;

	wlc->pub->_cnt->tbtt++;

	if (BSSCFG_STA(cfg)) {
		/* run watchdog here if the watchdog timer is not armed */
		if (WLC_WATCHDOG_TBTT(wlc)) {
			u32 cur, delta;
			if (wlc->WDarmed) {
				wl_del_timer(wlc->wl, wlc->wdtimer);
				wlc->WDarmed = false;
			}

			cur = OSL_SYSUPTIME();
			delta = cur > wlc->WDlast ? cur - wlc->WDlast :
			    (u32) ~0 - wlc->WDlast + cur + 1;
			if (delta >= TIMER_INTERVAL_WATCHDOG) {
				wlc_watchdog((void *)wlc);
				wlc->WDlast = cur;
			}

			wl_add_timer(wlc->wl, wlc->wdtimer,
				     wlc_watchdog_backup_bi(wlc), true);
			wlc->WDarmed = true;
		}
	}

	if (!cfg->BSS) {
		/* DirFrmQ is now valid...defer setting until end of ATIM window */
		wlc->qvalid |= MCMD_DIRFRMQVAL;
	}
}

/* GP timer is a freerunning 32 bit counter, decrements at 1 us rate */
void wlc_hwtimer_gptimer_set(struct wlc_info *wlc, uint us)
{
	W_REG(&wlc->regs->gptimer, us);
}

void wlc_hwtimer_gptimer_abort(struct wlc_info *wlc)
{
	W_REG(&wlc->regs->gptimer, 0);
}

static void wlc_hwtimer_gptimer_cb(struct wlc_info *wlc)
{
	/* when interrupt is generated, the counter is loaded with last value
	 * written and continue to decrement. So it has to be cleaned first
	 */
	W_REG(&wlc->regs->gptimer, 0);
}

/*
 * This fn has all the high level dpc processing from wlc_dpc.
 * POLICY: no macinstatus change, no bounding loop.
 *         All dpc bounding should be handled in BMAC dpc, like txstatus and rxint
 */
void wlc_high_dpc(struct wlc_info *wlc, u32 macintstatus)
{
	d11regs_t *regs = wlc->regs;
#ifdef BCMDBG
	char flagstr[128];
	static const bcm_bit_desc_t int_flags[] = {
		{MI_MACSSPNDD, "MACSSPNDD"},
		{MI_BCNTPL, "BCNTPL"},
		{MI_TBTT, "TBTT"},
		{MI_BCNSUCCESS, "BCNSUCCESS"},
		{MI_BCNCANCLD, "BCNCANCLD"},
		{MI_ATIMWINEND, "ATIMWINEND"},
		{MI_PMQ, "PMQ"},
		{MI_NSPECGEN_0, "NSPECGEN_0"},
		{MI_NSPECGEN_1, "NSPECGEN_1"},
		{MI_MACTXERR, "MACTXERR"},
		{MI_NSPECGEN_3, "NSPECGEN_3"},
		{MI_PHYTXERR, "PHYTXERR"},
		{MI_PME, "PME"},
		{MI_GP0, "GP0"},
		{MI_GP1, "GP1"},
		{MI_DMAINT, "DMAINT"},
		{MI_TXSTOP, "TXSTOP"},
		{MI_CCA, "CCA"},
		{MI_BG_NOISE, "BG_NOISE"},
		{MI_DTIM_TBTT, "DTIM_TBTT"},
		{MI_PRQ, "PRQ"},
		{MI_PWRUP, "PWRUP"},
		{MI_RFDISABLE, "RFDISABLE"},
		{MI_TFS, "TFS"},
		{MI_PHYCHANGED, "PHYCHANGED"},
		{MI_TO, "TO"},
		{0, NULL}
	};

	if (macintstatus & ~(MI_TBTT | MI_TXSTOP)) {
		bcm_format_flags(int_flags, macintstatus, flagstr,
				 sizeof(flagstr));
		WL_TRACE("wl%d: macintstatus 0x%x %s\n",
			 wlc->pub->unit, macintstatus, flagstr);
	}
#endif				/* BCMDBG */

	if (macintstatus & MI_PRQ) {
		/* Process probe request FIFO */
		ASSERT(0 && "PRQ Interrupt in non-MBSS");
	}

	/* TBTT indication */
	/* ucode only gives either TBTT or DTIM_TBTT, not both */
	if (macintstatus & (MI_TBTT | MI_DTIM_TBTT))
		wlc_tbtt(wlc, regs);

	if (macintstatus & MI_GP0) {
		WL_ERROR("wl%d: PSM microcode watchdog fired at %d (seconds). Resetting.\n",
			 wlc->pub->unit, wlc->pub->now);

		printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n",
					__func__, wlc->pub->sih->chip,
					wlc->pub->sih->chiprev);

		wlc->pub->_cnt->psmwds++;

		/* big hammer */
		wl_init(wlc->wl);
	}

	/* gptimer timeout */
	if (macintstatus & MI_TO) {
		wlc_hwtimer_gptimer_cb(wlc);
	}

	if (macintstatus & MI_RFDISABLE) {
		WL_ERROR("wl%d: MAC Detected a change on the RF Disable Input 0x%x\n",
			 wlc->pub->unit,
			 R_REG(&regs->phydebug) & PDBG_RFD);
		/* delay the cleanup to wl_down in IBSS case */
		if ((R_REG(&regs->phydebug) & PDBG_RFD)) {
			int idx;
			struct wlc_bsscfg *bsscfg;
			FOREACH_BSS(wlc, idx, bsscfg) {
				if (!BSSCFG_STA(bsscfg) || !bsscfg->enable
				    || !bsscfg->BSS)
					continue;
				WL_ERROR("wl%d: wlc_dpc: rfdisable -> wlc_bsscfg_disable()\n",
					 wlc->pub->unit);
			}
		}
	}

	/* send any enq'd tx packets. Just makes sure to jump start tx */
	if (!pktq_empty(&wlc->active_queue->q))
		wlc_send_q(wlc, wlc->active_queue);

	ASSERT(wlc_ps_check(wlc));
}

static void wlc_war16165(struct wlc_info *wlc, bool tx)
{
	if (tx) {
		/* the post-increment is used in STAY_AWAKE macro */
		if (wlc->txpend16165war++ == 0)
			wlc_set_ps_ctrl(wlc);
	} else {
		wlc->txpend16165war--;
		if (wlc->txpend16165war == 0)
			wlc_set_ps_ctrl(wlc);
	}
}

/* process an individual tx_status_t */
/* WLC_HIGH_API */
bool BCMFASTPATH
wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2)
{
	struct sk_buff *p;
	uint queue;
	d11txh_t *txh;
	struct scb *scb = NULL;
	bool free_pdu;
	int tx_rts, tx_frame_count, tx_rts_count;
	uint totlen, supr_status;
	bool lastframe;
	struct ieee80211_hdr *h;
	u16 mcl;
	struct ieee80211_tx_info *tx_info;
	struct ieee80211_tx_rate *txrate;
	int i;

	(void)(frm_tx2);	/* Compiler reference to avoid unused variable warning */

	/* discard intermediate indications for ucode with one legitimate case:
	 *   e.g. if "useRTS" is set. ucode did a successful rts/cts exchange, but the subsequent
	 *   tx of DATA failed. so it will start rts/cts from the beginning (resetting the rts
	 *   transmission count)
	 */
	if (!(txs->status & TX_STATUS_AMPDU)
	    && (txs->status & TX_STATUS_INTERMEDIATE)) {
		WLCNTADD(wlc->pub->_cnt->txnoack,
			 ((txs->
			   status & TX_STATUS_FRM_RTX_MASK) >>
			  TX_STATUS_FRM_RTX_SHIFT));
		WL_ERROR("%s: INTERMEDIATE but not AMPDU\n", __func__);
		return false;
	}

	queue = txs->frameid & TXFID_QUEUE_MASK;
	ASSERT(queue < NFIFO);
	if (queue >= NFIFO) {
		p = NULL;
		goto fatal;
	}

	p = GETNEXTTXP(wlc, queue);
	if (WLC_WAR16165(wlc))
		wlc_war16165(wlc, false);
	if (p == NULL)
		goto fatal;

	txh = (d11txh_t *) (p->data);
	mcl = le16_to_cpu(txh->MacTxControlLow);

	if (txs->phyerr) {
		if (WL_ERROR_ON()) {
			WL_ERROR("phyerr 0x%x, rate 0x%x\n",
				 txs->phyerr, txh->MainRates);
			wlc_print_txdesc(txh);
		}
		wlc_print_txstatus(txs);
	}

	ASSERT(txs->frameid == cpu_to_le16(txh->TxFrameID));
	if (txs->frameid != cpu_to_le16(txh->TxFrameID))
		goto fatal;

	tx_info = IEEE80211_SKB_CB(p);
	h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN);

	if (tx_info->control.sta)
		scb = (struct scb *)tx_info->control.sta->drv_priv;

	if (N_ENAB(wlc->pub)) {
		u8 *plcp = (u8 *) (txh + 1);
		if (PLCP3_ISSGI(plcp[3]))
			wlc->pub->_cnt->txmpdu_sgi++;
		if (PLCP3_ISSTBC(plcp[3]))
			wlc->pub->_cnt->txmpdu_stbc++;
	}

	if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
		ASSERT((mcl & TXC_AMPDU_MASK) != TXC_AMPDU_NONE);
		wlc_ampdu_dotxstatus(wlc->ampdu, scb, p, txs);
		return false;
	}

	supr_status = txs->status & TX_STATUS_SUPR_MASK;
	if (supr_status == TX_STATUS_SUPR_BADCH)
		WL_NONE("%s: Pkt tx suppressed, possibly channel %d\n",
			__func__, CHSPEC_CHANNEL(wlc->default_bss->chanspec));

	tx_rts = cpu_to_le16(txh->MacTxControlLow) & TXC_SENDRTS;
	tx_frame_count =
	    (txs->status & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT;
	tx_rts_count =
	    (txs->status & TX_STATUS_RTS_RTX_MASK) >> TX_STATUS_RTS_RTX_SHIFT;

	lastframe = !ieee80211_has_morefrags(h->frame_control);

	if (!lastframe) {
		WL_ERROR("Not last frame!\n");
	} else {
		u16 sfbl, lfbl;
		ieee80211_tx_info_clear_status(tx_info);
		if (queue < AC_COUNT) {
			sfbl = WLC_WME_RETRY_SFB_GET(wlc, wme_fifo2ac[queue]);
			lfbl = WLC_WME_RETRY_LFB_GET(wlc, wme_fifo2ac[queue]);
		} else {
			sfbl = wlc->SFBL;
			lfbl = wlc->LFBL;
		}

		txrate = tx_info->status.rates;
		/* FIXME: this should use a combination of sfbl, lfbl depending on frame length and RTS setting */
		if ((tx_frame_count > sfbl) && (txrate[1].idx >= 0)) {
			/* rate selection requested a fallback rate and we used it */
			txrate->count = lfbl;
			txrate[1].count = tx_frame_count - lfbl;
		} else {
			/* rate selection did not request fallback rate, or we didn't need it */
			txrate->count = tx_frame_count;
			/* rc80211_minstrel.c:minstrel_tx_status() expects unused rates to be marked with idx = -1 */
			txrate[1].idx = -1;
			txrate[1].count = 0;
		}

		/* clear the rest of the rates */
		for (i = 2; i < IEEE80211_TX_MAX_RATES; i++) {
			txrate[i].idx = -1;
			txrate[i].count = 0;
		}

		if (txs->status & TX_STATUS_ACK_RCV)
			tx_info->flags |= IEEE80211_TX_STAT_ACK;
	}

	totlen = pkttotlen(p);
	free_pdu = true;

	wlc_txfifo_complete(wlc, queue, 1);

	if (lastframe) {
		p->next = NULL;
		p->prev = NULL;
		wlc->txretried = 0;
		/* remove PLCP & Broadcom tx descriptor header */
		skb_pull(p, D11_PHY_HDR_LEN);
		skb_pull(p, D11_TXH_LEN);
		ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p);
		wlc->pub->_cnt->ieee_tx_status++;
	} else {
		WL_ERROR("%s: Not last frame => not calling tx_status\n",
			 __func__);
	}

	return false;

 fatal:
	ASSERT(0);
	if (p)
		pkt_buf_free_skb(p);

	return true;

}

void BCMFASTPATH
wlc_txfifo_complete(struct wlc_info *wlc, uint fifo, s8 txpktpend)
{
	TXPKTPENDDEC(wlc, fifo, txpktpend);
	WL_TRACE("wlc_txfifo_complete, pktpend dec %d to %d\n",
		 txpktpend, TXPKTPENDGET(wlc, fifo));

	/* There is more room; mark precedences related to this FIFO sendable */
	WLC_TX_FIFO_ENAB(wlc, fifo);
	ASSERT(TXPKTPENDGET(wlc, fifo) >= 0);

	if (!TXPKTPENDTOT(wlc)) {
		if (wlc->block_datafifo & DATA_BLOCK_TX_SUPR)
			wlc_bsscfg_tx_check(wlc);
	}

	/* Clear MHF2_TXBCMC_NOW flag if BCMC fifo has drained */
	if (AP_ENAB(wlc->pub) &&
	    wlc->bcmcfifo_drain && !TXPKTPENDGET(wlc, TX_BCMC_FIFO)) {
		wlc->bcmcfifo_drain = false;
		wlc_mhf(wlc, MHF2, MHF2_TXBCMC_NOW, 0, WLC_BAND_AUTO);
	}

	/* figure out which bsscfg is being worked on... */
}

/* Given the beacon interval in kus, and a 64 bit TSF in us,
 * return the offset (in us) of the TSF from the last TBTT
 */
u32 wlc_calc_tbtt_offset(u32 bp, u32 tsf_h, u32 tsf_l)
{
	u32 k, btklo, btkhi, offset;

	/* TBTT is always an even multiple of the beacon_interval,
	 * so the TBTT less than or equal to the beacon timestamp is
	 * the beacon timestamp minus the beacon timestamp modulo
	 * the beacon interval.
	 *
	 * TBTT = BT - (BT % BIu)
	 *      = (BTk - (BTk % BP)) * 2^10
	 *
	 * BT = beacon timestamp (usec, 64bits)
	 * BTk = beacon timestamp (Kusec, 54bits)
	 * BP = beacon interval (Kusec, 16bits)
	 * BIu = BP * 2^10 = beacon interval (usec, 26bits)
	 *
	 * To keep the calculations in u32s, the modulo operation
	 * on the high part of BT needs to be done in parts using the
	 * relations:
	 * X*Y mod Z = ((X mod Z) * (Y mod Z)) mod Z
	 * and
	 * (X + Y) mod Z = ((X mod Z) + (Y mod Z)) mod Z
	 *
	 * So, if BTk[n] = u16 n [0,3] of BTk.
	 * BTk % BP = SUM((BTk[n] * 2^16n) % BP , 0<=n<4) % BP
	 * and the SUM term can be broken down:
	 * (BTk[n] *     2^16n)    % BP
	 * (BTk[n] * (2^16n % BP)) % BP
	 *
	 * Create a set of power of 2 mod BP constants:
	 * K[n] = 2^(16n) % BP
	 *      = (K[n-1] * 2^16) % BP
	 * K[2] = 2^32 % BP = ((2^16 % BP) * 2^16) % BP
	 *
	 * BTk % BP = BTk[0-1] % BP +
	 *            (BTk[2] * K[2]) % BP +
	 *            (BTk[3] * K[3]) % BP
	 *
	 * Since K[n] < 2^16 and BTk[n] is < 2^16, then BTk[n] * K[n] < 2^32
	 */

	/* BTk = BT >> 10, btklo = BTk[0-3], bkthi = BTk[4-6] */
	btklo = (tsf_h << 22) | (tsf_l >> 10);
	btkhi = tsf_h >> 10;

	/* offset = BTk % BP */
	offset = btklo % bp;

	/* K[2] = ((2^16 % BP) * 2^16) % BP */
	k = (u32) (1 << 16) % bp;
	k = (u32) (k * 1 << 16) % (u32) bp;

	/* offset += (BTk[2] * K[2]) % BP */
	offset += ((btkhi & 0xffff) * k) % bp;

	/* BTk[3] */
	btkhi = btkhi >> 16;

	/* k[3] = (K[2] * 2^16) % BP */
	k = (k << 16) % bp;

	/* offset += (BTk[3] * K[3]) % BP */
	offset += ((btkhi & 0xffff) * k) % bp;

	offset = offset % bp;

	/* convert offset from kus to us by shifting up 10 bits and
	 * add in the low 10 bits of tsf that we ignored
	 */
	offset = (offset << 10) + (tsf_l & 0x3FF);

	return offset;
}

/* Update beacon listen interval in shared memory */
void wlc_bcn_li_upd(struct wlc_info *wlc)
{
	if (AP_ENAB(wlc->pub))
		return;

	/* wake up every DTIM is the default */
	if (wlc->bcn_li_dtim == 1)
		wlc_write_shm(wlc, M_BCN_LI, 0);
	else
		wlc_write_shm(wlc, M_BCN_LI,
			      (wlc->bcn_li_dtim << 8) | wlc->bcn_li_bcn);
}

static void
prep_mac80211_status(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p,
		     struct ieee80211_rx_status *rx_status)
{
	u32 tsf_l, tsf_h;
	wlc_d11rxhdr_t *wlc_rxh = (wlc_d11rxhdr_t *) rxh;
	int preamble;
	int channel;
	ratespec_t rspec;
	unsigned char *plcp;

#if 0
	/* Clearly, this is bogus -- reading the TSF now is wrong */
	wlc_read_tsf(wlc, &tsf_l, &tsf_h);	/* mactime */
	rx_status->mactime = tsf_h;
	rx_status->mactime <<= 32;
	rx_status->mactime |= tsf_l;
	rx_status->flag |= RX_FLAG_MACTIME_MPDU; /* clearly wrong */
#endif

	channel = WLC_CHAN_CHANNEL(rxh->RxChan);

	if (channel > 14) {
		rx_status->band = IEEE80211_BAND_5GHZ;
		rx_status->freq = ieee80211_ofdm_chan_to_freq(
					WF_CHAN_FACTOR_5_G/2, channel);

	} else {
		rx_status->band = IEEE80211_BAND_2GHZ;
		rx_status->freq = ieee80211_dsss_chan_to_freq(channel);
	}

	rx_status->signal = wlc_rxh->rssi;	/* signal */

	/* noise */
	/* qual */
	rx_status->antenna = (rxh->PhyRxStatus_0 & PRXS0_RXANT_UPSUBBAND) ? 1 : 0;	/* ant */

	plcp = p->data;

	rspec = wlc_compute_rspec(rxh, plcp);
	if (IS_MCS(rspec)) {
		rx_status->rate_idx = rspec & RSPEC_RATE_MASK;
		rx_status->flag |= RX_FLAG_HT;
		if (RSPEC_IS40MHZ(rspec))
			rx_status->flag |= RX_FLAG_40MHZ;
	} else {
		switch (RSPEC2RATE(rspec)) {
		case WLC_RATE_1M:
			rx_status->rate_idx = 0;
			break;
		case WLC_RATE_2M:
			rx_status->rate_idx = 1;
			break;
		case WLC_RATE_5M5:
			rx_status->rate_idx = 2;
			break;
		case WLC_RATE_11M:
			rx_status->rate_idx = 3;
			break;
		case WLC_RATE_6M:
			rx_status->rate_idx = 4;
			break;
		case WLC_RATE_9M:
			rx_status->rate_idx = 5;
			break;
		case WLC_RATE_12M:
			rx_status->rate_idx = 6;
			break;
		case WLC_RATE_18M:
			rx_status->rate_idx = 7;
			break;
		case WLC_RATE_24M:
			rx_status->rate_idx = 8;
			break;
		case WLC_RATE_36M:
			rx_status->rate_idx = 9;
			break;
		case WLC_RATE_48M:
			rx_status->rate_idx = 10;
			break;
		case WLC_RATE_54M:
			rx_status->rate_idx = 11;
			break;
		default:
			WL_ERROR("%s: Unknown rate\n", __func__);
		}

		/* Determine short preamble and rate_idx */
		preamble = 0;
		if (IS_CCK(rspec)) {
			if (rxh->PhyRxStatus_0 & PRXS0_SHORTH)
				rx_status->flag |= RX_FLAG_SHORTPRE;
		} else if (IS_OFDM(rspec)) {
			rx_status->flag |= RX_FLAG_SHORTPRE;
		} else {
			WL_ERROR("%s: Unknown modulation\n", __func__);
		}
	}

	if (PLCP3_ISSGI(plcp[3]))
		rx_status->flag |= RX_FLAG_SHORT_GI;

	if (rxh->RxStatus1 & RXS_DECERR) {
		rx_status->flag |= RX_FLAG_FAILED_PLCP_CRC;
		WL_ERROR("%s:  RX_FLAG_FAILED_PLCP_CRC\n", __func__);
	}
	if (rxh->RxStatus1 & RXS_FCSERR) {
		rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
		WL_ERROR("%s:  RX_FLAG_FAILED_FCS_CRC\n", __func__);
	}
}

static void
wlc_recvctl(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p)
{
	int len_mpdu;
	struct ieee80211_rx_status rx_status;
#if defined(BCMDBG)
	struct sk_buff *skb = p;
#endif				/* BCMDBG */
	/* Todo:
	 * Cache plcp for first MPDU of AMPD and use chacched version for INTERMEDIATE.
	 * Test for INTERMEDIATE  like so:
	 * if (!(plcp[0] | plcp[1] | plcp[2]))
	 */

	memset(&rx_status, 0, sizeof(rx_status));
	prep_mac80211_status(wlc, rxh, p, &rx_status);

	/* mac header+body length, exclude CRC and plcp header */
	len_mpdu = p->len - D11_PHY_HDR_LEN - FCS_LEN;
	skb_pull(p, D11_PHY_HDR_LEN);
	__skb_trim(p, len_mpdu);

	ASSERT(!(p->next));
	ASSERT(!(p->prev));

	ASSERT(IS_ALIGNED((unsigned long)skb->data, 2));

	memcpy(IEEE80211_SKB_RXCB(p), &rx_status, sizeof(rx_status));
	ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p);

	wlc->pub->_cnt->ieee_rx++;
	return;
}

void wlc_bss_list_free(struct wlc_info *wlc, struct wlc_bss_list *bss_list)
{
	uint index;

	if (!bss_list) {
		WL_ERROR("%s: Attempting to free NULL list\n", __func__);
		return;
	}
	/* inspect all BSS descriptor */
	for (index = 0; index < bss_list->count; index++) {
		kfree(bss_list->ptrs[index]);
		bss_list->ptrs[index] = NULL;
	}
	bss_list->count = 0;
}

/* Process received frames */
/*
 * Return true if more frames need to be processed. false otherwise.
 * Param 'bound' indicates max. # frames to process before break out.
 */
/* WLC_HIGH_API */
void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p)
{
	d11rxhdr_t *rxh;
	struct ieee80211_hdr *h;
	uint len;
	bool is_amsdu;

	WL_TRACE("wl%d: wlc_recv\n", wlc->pub->unit);

	/* frame starts with rxhdr */
	rxh = (d11rxhdr_t *) (p->data);

	/* strip off rxhdr */
	skb_pull(p, wlc->hwrxoff);

	/* fixup rx header endianness */
	rxh->RxFrameSize = le16_to_cpu(rxh->RxFrameSize);
	rxh->PhyRxStatus_0 = le16_to_cpu(rxh->PhyRxStatus_0);
	rxh->PhyRxStatus_1 = le16_to_cpu(rxh->PhyRxStatus_1);
	rxh->PhyRxStatus_2 = le16_to_cpu(rxh->PhyRxStatus_2);
	rxh->PhyRxStatus_3 = le16_to_cpu(rxh->PhyRxStatus_3);
	rxh->PhyRxStatus_4 = le16_to_cpu(rxh->PhyRxStatus_4);
	rxh->PhyRxStatus_5 = le16_to_cpu(rxh->PhyRxStatus_5);
	rxh->RxStatus1 = le16_to_cpu(rxh->RxStatus1);
	rxh->RxStatus2 = le16_to_cpu(rxh->RxStatus2);
	rxh->RxTSFTime = le16_to_cpu(rxh->RxTSFTime);
	rxh->RxChan = le16_to_cpu(rxh->RxChan);

	/* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */
	if (rxh->RxStatus1 & RXS_PBPRES) {
		if (p->len < 2) {
			wlc->pub->_cnt->rxrunt++;
			WL_ERROR("wl%d: wlc_recv: rcvd runt of len %d\n",
				 wlc->pub->unit, p->len);
			goto toss;
		}
		skb_pull(p, 2);
	}

	h = (struct ieee80211_hdr *)(p->data + D11_PHY_HDR_LEN);
	len = p->len;

	if (rxh->RxStatus1 & RXS_FCSERR) {
		if (wlc->pub->mac80211_state & MAC80211_PROMISC_BCNS) {
			WL_ERROR("FCSERR while scanning******* - tossing\n");
			goto toss;
		} else {
			WL_ERROR("RCSERR!!!\n");
			goto toss;
		}
	}

	/* check received pkt has at least frame control field */
	if (len < D11_PHY_HDR_LEN + sizeof(h->frame_control)) {
		wlc->pub->_cnt->rxrunt++;
		goto toss;
	}

	is_amsdu = rxh->RxStatus2 & RXS_AMSDU_MASK;

	/* explicitly test bad src address to avoid sending bad deauth */
	if (!is_amsdu) {
		/* CTS and ACK CTL frames are w/o a2 */

		if (ieee80211_is_data(h->frame_control) ||
		    ieee80211_is_mgmt(h->frame_control)) {
			if ((is_zero_ether_addr(h->addr2) ||
			     is_multicast_ether_addr(h->addr2))) {
				WL_ERROR("wl%d: %s: dropping a frame with "
					 "invalid src mac address, a2: %pM\n",
					 wlc->pub->unit, __func__, h->addr2);
				wlc->pub->_cnt->rxbadsrcmac++;
				goto toss;
			}
			wlc->pub->_cnt->rxfrag++;
		}
	}

	/* due to sheer numbers, toss out probe reqs for now */
	if (ieee80211_is_probe_req(h->frame_control))
		goto toss;

	if (is_amsdu)
		goto toss;

	wlc_recvctl(wlc, rxh, p);
	return;

 toss:
	pkt_buf_free_skb(p);
}

/* calculate frame duration for Mixed-mode L-SIG spoofing, return
 * number of bytes goes in the length field
 *
 * Formula given by HT PHY Spec v 1.13
 *   len = 3(nsyms + nstream + 3) - 3
 */
u16 BCMFASTPATH
wlc_calc_lsig_len(struct wlc_info *wlc, ratespec_t ratespec, uint mac_len)
{
	uint nsyms, len = 0, kNdps;

	WL_TRACE("wl%d: wlc_calc_lsig_len: rate %d, len%d\n",
		 wlc->pub->unit, RSPEC2RATE(ratespec), mac_len);

	if (IS_MCS(ratespec)) {
		uint mcs = ratespec & RSPEC_RATE_MASK;
		/* MCS_TXS(mcs) returns num tx streams - 1 */
		int tot_streams = (MCS_TXS(mcs) + 1) + RSPEC_STC(ratespec);

		ASSERT(WLC_PHY_11N_CAP(wlc->band));
		/* the payload duration calculation matches that of regular ofdm */
		/* 1000Ndbps = kbps * 4 */
		kNdps =
		    MCS_RATE(mcs, RSPEC_IS40MHZ(ratespec),
			     RSPEC_ISSGI(ratespec)) * 4;

		if (RSPEC_STC(ratespec) == 0)
			/* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */
			nsyms =
			    CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
				  APHY_TAIL_NBITS) * 1000, kNdps);
		else
			/* STBC needs to have even number of symbols */
			nsyms =
			    2 *
			    CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
				  APHY_TAIL_NBITS) * 1000, 2 * kNdps);

		nsyms += (tot_streams + 3);	/* (+3) account for HT-SIG(2) and HT-STF(1) */
		/* 3 bytes/symbol @ legacy 6Mbps rate */
		len = (3 * nsyms) - 3;	/* (-3) excluding service bits and tail bits */
	}

	return (u16) len;
}

/* calculate frame duration of a given rate and length, return time in usec unit */
uint BCMFASTPATH
wlc_calc_frame_time(struct wlc_info *wlc, ratespec_t ratespec, u8 preamble_type,
		    uint mac_len)
{
	uint nsyms, dur = 0, Ndps, kNdps;
	uint rate = RSPEC2RATE(ratespec);

	if (rate == 0) {
		ASSERT(0);
		WL_ERROR("wl%d: WAR: using rate of 1 mbps\n", wlc->pub->unit);
		rate = WLC_RATE_1M;
	}

	WL_TRACE("wl%d: wlc_calc_frame_time: rspec 0x%x, preamble_type %d, len%d\n",
		 wlc->pub->unit, ratespec, preamble_type, mac_len);

	if (IS_MCS(ratespec)) {
		uint mcs = ratespec & RSPEC_RATE_MASK;
		int tot_streams = MCS_TXS(mcs) + RSPEC_STC(ratespec);
		ASSERT(WLC_PHY_11N_CAP(wlc->band));
		ASSERT(WLC_IS_MIMO_PREAMBLE(preamble_type));

		dur = PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT);
		if (preamble_type == WLC_MM_PREAMBLE)
			dur += PREN_MM_EXT;
		/* 1000Ndbps = kbps * 4 */
		kNdps =
		    MCS_RATE(mcs, RSPEC_IS40MHZ(ratespec),
			     RSPEC_ISSGI(ratespec)) * 4;

		if (RSPEC_STC(ratespec) == 0)
			/* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */
			nsyms =
			    CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
				  APHY_TAIL_NBITS) * 1000, kNdps);
		else
			/* STBC needs to have even number of symbols */
			nsyms =
			    2 *
			    CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
				  APHY_TAIL_NBITS) * 1000, 2 * kNdps);

		dur += APHY_SYMBOL_TIME * nsyms;
		if (BAND_2G(wlc->band->bandtype))
			dur += DOT11_OFDM_SIGNAL_EXTENSION;
	} else if (IS_OFDM(rate)) {
		dur = APHY_PREAMBLE_TIME;
		dur += APHY_SIGNAL_TIME;
		/* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */
		Ndps = rate * 2;
		/* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */
		nsyms =
		    CEIL((APHY_SERVICE_NBITS + 8 * mac_len + APHY_TAIL_NBITS),
			 Ndps);
		dur += APHY_SYMBOL_TIME * nsyms;
		if (BAND_2G(wlc->band->bandtype))
			dur += DOT11_OFDM_SIGNAL_EXTENSION;
	} else {
		/* calc # bits * 2 so factor of 2 in rate (1/2 mbps) will divide out */
		mac_len = mac_len * 8 * 2;
		/* calc ceiling of bits/rate = microseconds of air time */
		dur = (mac_len + rate - 1) / rate;
		if (preamble_type & WLC_SHORT_PREAMBLE)
			dur += BPHY_PLCP_SHORT_TIME;
		else
			dur += BPHY_PLCP_TIME;
	}
	return dur;
}

/* The opposite of wlc_calc_frame_time */
static uint
wlc_calc_frame_len(struct wlc_info *wlc, ratespec_t ratespec, u8 preamble_type,
		   uint dur)
{
	uint nsyms, mac_len, Ndps, kNdps;
	uint rate = RSPEC2RATE(ratespec);

	WL_TRACE("wl%d: wlc_calc_frame_len: rspec 0x%x, preamble_type %d, dur %d\n",
		 wlc->pub->unit, ratespec, preamble_type, dur);

	if (IS_MCS(ratespec)) {
		uint mcs = ratespec & RSPEC_RATE_MASK;
		int tot_streams = MCS_TXS(mcs) + RSPEC_STC(ratespec);
		ASSERT(WLC_PHY_11N_CAP(wlc->band));
		dur -= PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT);
		/* payload calculation matches that of regular ofdm */
		if (BAND_2G(wlc->band->bandtype))
			dur -= DOT11_OFDM_SIGNAL_EXTENSION;
		/* kNdbps = kbps * 4 */
		kNdps =
		    MCS_RATE(mcs, RSPEC_IS40MHZ(ratespec),
			     RSPEC_ISSGI(ratespec)) * 4;
		nsyms = dur / APHY_SYMBOL_TIME;
		mac_len =
		    ((nsyms * kNdps) -
		     ((APHY_SERVICE_NBITS + APHY_TAIL_NBITS) * 1000)) / 8000;
	} else if (IS_OFDM(ratespec)) {
		dur -= APHY_PREAMBLE_TIME;
		dur -= APHY_SIGNAL_TIME;
		/* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */
		Ndps = rate * 2;
		nsyms = dur / APHY_SYMBOL_TIME;
		mac_len =
		    ((nsyms * Ndps) -
		     (APHY_SERVICE_NBITS + APHY_TAIL_NBITS)) / 8;
	} else {
		if (preamble_type & WLC_SHORT_PREAMBLE)
			dur -= BPHY_PLCP_SHORT_TIME;
		else
			dur -= BPHY_PLCP_TIME;
		mac_len = dur * rate;
		/* divide out factor of 2 in rate (1/2 mbps) */
		mac_len = mac_len / 8 / 2;
	}
	return mac_len;
}

static uint
wlc_calc_ba_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type)
{
	WL_TRACE("wl%d: wlc_calc_ba_time: rspec 0x%x, preamble_type %d\n",
		 wlc->pub->unit, rspec, preamble_type);
	/* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that is less than
	 * or equal to the rate of the immediately previous frame in the FES
	 */
	rspec = WLC_BASIC_RATE(wlc, rspec);
	ASSERT(VALID_RATE_DBG(wlc, rspec));

	/* BA len == 32 == 16(ctl hdr) + 4(ba len) + 8(bitmap) + 4(fcs) */
	return wlc_calc_frame_time(wlc, rspec, preamble_type,
				   (DOT11_BA_LEN + DOT11_BA_BITMAP_LEN +
				    FCS_LEN));
}

static uint BCMFASTPATH
wlc_calc_ack_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type)
{
	uint dur = 0;

	WL_TRACE("wl%d: wlc_calc_ack_time: rspec 0x%x, preamble_type %d\n",
		 wlc->pub->unit, rspec, preamble_type);
	/* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that is less than
	 * or equal to the rate of the immediately previous frame in the FES
	 */
	rspec = WLC_BASIC_RATE(wlc, rspec);
	ASSERT(VALID_RATE_DBG(wlc, rspec));

	/* ACK frame len == 14 == 2(fc) + 2(dur) + 6(ra) + 4(fcs) */
	dur =
	    wlc_calc_frame_time(wlc, rspec, preamble_type,
				(DOT11_ACK_LEN + FCS_LEN));
	return dur;
}

static uint
wlc_calc_cts_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type)
{
	WL_TRACE("wl%d: wlc_calc_cts_time: ratespec 0x%x, preamble_type %d\n",
		 wlc->pub->unit, rspec, preamble_type);
	return wlc_calc_ack_time(wlc, rspec, preamble_type);
}

/* derive wlc->band->basic_rate[] table from 'rateset' */
void wlc_rate_lookup_init(struct wlc_info *wlc, wlc_rateset_t *rateset)
{
	u8 rate;
	u8 mandatory;
	u8 cck_basic = 0;
	u8 ofdm_basic = 0;
	u8 *br = wlc->band->basic_rate;
	uint i;

	/* incoming rates are in 500kbps units as in 802.11 Supported Rates */
	memset(br, 0, WLC_MAXRATE + 1);

	/* For each basic rate in the rates list, make an entry in the
	 * best basic lookup.
	 */
	for (i = 0; i < rateset->count; i++) {
		/* only make an entry for a basic rate */
		if (!(rateset->rates[i] & WLC_RATE_FLAG))
			continue;

		/* mask off basic bit */
		rate = (rateset->rates[i] & RATE_MASK);

		if (rate > WLC_MAXRATE) {
			WL_ERROR("wlc_rate_lookup_init: invalid rate 0x%X in rate set\n",
				 rateset->rates[i]);
			continue;
		}

		br[rate] = rate;
	}

	/* The rate lookup table now has non-zero entries for each
	 * basic rate, equal to the basic rate: br[basicN] = basicN
	 *
	 * To look up the best basic rate corresponding to any
	 * particular rate, code can use the basic_rate table
	 * like this
	 *
	 * basic_rate = wlc->band->basic_rate[tx_rate]
	 *
	 * Make sure there is a best basic rate entry for
	 * every rate by walking up the table from low rates
	 * to high, filling in holes in the lookup table
	 */

	for (i = 0; i < wlc->band->hw_rateset.count; i++) {
		rate = wlc->band->hw_rateset.rates[i];
		ASSERT(rate <= WLC_MAXRATE);

		if (br[rate] != 0) {
			/* This rate is a basic rate.
			 * Keep track of the best basic rate so far by
			 * modulation type.
			 */
			if (IS_OFDM(rate))
				ofdm_basic = rate;
			else
				cck_basic = rate;

			continue;
		}

		/* This rate is not a basic rate so figure out the
		 * best basic rate less than this rate and fill in
		 * the hole in the table
		 */

		br[rate] = IS_OFDM(rate) ? ofdm_basic : cck_basic;

		if (br[rate] != 0)
			continue;

		if (IS_OFDM(rate)) {
			/* In 11g and 11a, the OFDM mandatory rates are 6, 12, and 24 Mbps */
			if (rate >= WLC_RATE_24M)
				mandatory = WLC_RATE_24M;
			else if (rate >= WLC_RATE_12M)
				mandatory = WLC_RATE_12M;
			else
				mandatory = WLC_RATE_6M;
		} else {
			/* In 11b, all the CCK rates are mandatory 1 - 11 Mbps */
			mandatory = rate;
		}

		br[rate] = mandatory;
	}
}

static void wlc_write_rate_shm(struct wlc_info *wlc, u8 rate, u8 basic_rate)
{
	u8 phy_rate, index;
	u8 basic_phy_rate, basic_index;
	u16 dir_table, basic_table;
	u16 basic_ptr;

	/* Shared memory address for the table we are reading */
	dir_table = IS_OFDM(basic_rate) ? M_RT_DIRMAP_A : M_RT_DIRMAP_B;

	/* Shared memory address for the table we are writing */
	basic_table = IS_OFDM(rate) ? M_RT_BBRSMAP_A : M_RT_BBRSMAP_B;

	/*
	 * for a given rate, the LS-nibble of the PLCP SIGNAL field is
	 * the index into the rate table.
	 */
	phy_rate = rate_info[rate] & RATE_MASK;
	basic_phy_rate = rate_info[basic_rate] & RATE_MASK;
	index = phy_rate & 0xf;
	basic_index = basic_phy_rate & 0xf;

	/* Find the SHM pointer to the ACK rate entry by looking in the
	 * Direct-map Table
	 */
	basic_ptr = wlc_read_shm(wlc, (dir_table + basic_index * 2));

	/* Update the SHM BSS-basic-rate-set mapping table with the pointer
	 * to the correct basic rate for the given incoming rate
	 */
	wlc_write_shm(wlc, (basic_table + index * 2), basic_ptr);
}

static const wlc_rateset_t *wlc_rateset_get_hwrs(struct wlc_info *wlc)
{
	const wlc_rateset_t *rs_dflt;

	if (WLC_PHY_11N_CAP(wlc->band)) {
		if (BAND_5G(wlc->band->bandtype))
			rs_dflt = &ofdm_mimo_rates;
		else
			rs_dflt = &cck_ofdm_mimo_rates;
	} else if (wlc->band->gmode)
		rs_dflt = &cck_ofdm_rates;
	else
		rs_dflt = &cck_rates;

	return rs_dflt;
}

void wlc_set_ratetable(struct wlc_info *wlc)
{
	const wlc_rateset_t *rs_dflt;
	wlc_rateset_t rs;
	u8 rate, basic_rate;
	uint i;

	rs_dflt = wlc_rateset_get_hwrs(wlc);
	ASSERT(rs_dflt != NULL);

	wlc_rateset_copy(rs_dflt, &rs);
	wlc_rateset_mcs_upd(&rs, wlc->stf->txstreams);

	/* walk the phy rate table and update SHM basic rate lookup table */
	for (i = 0; i < rs.count; i++) {
		rate = rs.rates[i] & RATE_MASK;

		/* for a given rate WLC_BASIC_RATE returns the rate at
		 * which a response ACK/CTS should be sent.
		 */
		basic_rate = WLC_BASIC_RATE(wlc, rate);
		if (basic_rate == 0) {
			/* This should only happen if we are using a
			 * restricted rateset.
			 */
			basic_rate = rs.rates[0] & RATE_MASK;
		}

		wlc_write_rate_shm(wlc, rate, basic_rate);
	}
}

/*
 * Return true if the specified rate is supported by the specified band.
 * WLC_BAND_AUTO indicates the current band.
 */
bool wlc_valid_rate(struct wlc_info *wlc, ratespec_t rspec, int band,
		    bool verbose)
{
	wlc_rateset_t *hw_rateset;
	uint i;

	if ((band == WLC_BAND_AUTO) || (band == wlc->band->bandtype)) {
		hw_rateset = &wlc->band->hw_rateset;
	} else if (NBANDS(wlc) > 1) {
		hw_rateset = &wlc->bandstate[OTHERBANDUNIT(wlc)]->hw_rateset;
	} else {
		/* other band specified and we are a single band device */
		return false;
	}

	/* check if this is a mimo rate */
	if (IS_MCS(rspec)) {
		if (!VALID_MCS((rspec & RSPEC_RATE_MASK)))
			goto error;

		return isset(hw_rateset->mcs, (rspec & RSPEC_RATE_MASK));
	}

	for (i = 0; i < hw_rateset->count; i++)
		if (hw_rateset->rates[i] == RSPEC2RATE(rspec))
			return true;
 error:
	if (verbose) {
		WL_ERROR("wl%d: wlc_valid_rate: rate spec 0x%x not in hw_rateset\n",
			 wlc->pub->unit, rspec);
	}

	return false;
}

static void wlc_update_mimo_band_bwcap(struct wlc_info *wlc, u8 bwcap)
{
	uint i;
	struct wlcband *band;

	for (i = 0; i < NBANDS(wlc); i++) {
		if (IS_SINGLEBAND_5G(wlc->deviceid))
			i = BAND_5G_INDEX;
		band = wlc->bandstate[i];
		if (band->bandtype == WLC_BAND_5G) {
			if ((bwcap == WLC_N_BW_40ALL)
			    || (bwcap == WLC_N_BW_20IN2G_40IN5G))
				band->mimo_cap_40 = true;
			else
				band->mimo_cap_40 = false;
		} else {
			ASSERT(band->bandtype == WLC_BAND_2G);
			if (bwcap == WLC_N_BW_40ALL)
				band->mimo_cap_40 = true;
			else
				band->mimo_cap_40 = false;
		}
	}

	wlc->mimo_band_bwcap = bwcap;
}

void wlc_mod_prb_rsp_rate_table(struct wlc_info *wlc, uint frame_len)
{
	const wlc_rateset_t *rs_dflt;
	wlc_rateset_t rs;
	u8 rate;
	u16 entry_ptr;
	u8 plcp[D11_PHY_HDR_LEN];
	u16 dur, sifs;
	uint i;

	sifs = SIFS(wlc->band);

	rs_dflt = wlc_rateset_get_hwrs(wlc);
	ASSERT(rs_dflt != NULL);

	wlc_rateset_copy(rs_dflt, &rs);
	wlc_rateset_mcs_upd(&rs, wlc->stf->txstreams);

	/* walk the phy rate table and update MAC core SHM basic rate table entries */
	for (i = 0; i < rs.count; i++) {
		rate = rs.rates[i] & RATE_MASK;

		entry_ptr = wlc_rate_shm_offset(wlc, rate);

		/* Calculate the Probe Response PLCP for the given rate */
		wlc_compute_plcp(wlc, rate, frame_len, plcp);

		/* Calculate the duration of the Probe Response frame plus SIFS for the MAC */
		dur =
		    (u16) wlc_calc_frame_time(wlc, rate, WLC_LONG_PREAMBLE,
						 frame_len);
		dur += sifs;

		/* Update the SHM Rate Table entry Probe Response values */
		wlc_write_shm(wlc, entry_ptr + M_RT_PRS_PLCP_POS,
			      (u16) (plcp[0] + (plcp[1] << 8)));
		wlc_write_shm(wlc, entry_ptr + M_RT_PRS_PLCP_POS + 2,
			      (u16) (plcp[2] + (plcp[3] << 8)));
		wlc_write_shm(wlc, entry_ptr + M_RT_PRS_DUR_POS, dur);
	}
}

u16
wlc_compute_bcntsfoff(struct wlc_info *wlc, ratespec_t rspec,
		      bool short_preamble, bool phydelay)
{
	uint bcntsfoff = 0;

	if (IS_MCS(rspec)) {
		WL_ERROR("wl%d: recd beacon with mcs rate; rspec 0x%x\n",
			 wlc->pub->unit, rspec);
	} else if (IS_OFDM(rspec)) {
		/* tx delay from MAC through phy to air (2.1 usec) +
		 * phy header time (preamble + PLCP SIGNAL == 20 usec) +
		 * PLCP SERVICE + MAC header time (SERVICE + FC + DUR + A1 + A2 + A3 + SEQ == 26
		 * bytes at beacon rate)
		 */
		bcntsfoff += phydelay ? D11A_PHY_TX_DELAY : 0;
		bcntsfoff += APHY_PREAMBLE_TIME + APHY_SIGNAL_TIME;
		bcntsfoff +=
		    wlc_compute_airtime(wlc, rspec,
					APHY_SERVICE_NBITS / 8 +
					DOT11_MAC_HDR_LEN);
	} else {
		/* tx delay from MAC through phy to air (3.4 usec) +
		 * phy header time (long preamble + PLCP == 192 usec) +
		 * MAC header time (FC + DUR + A1 + A2 + A3 + SEQ == 24 bytes at beacon rate)
		 */
		bcntsfoff += phydelay ? D11B_PHY_TX_DELAY : 0;
		bcntsfoff +=
		    short_preamble ? D11B_PHY_SPREHDR_TIME :
		    D11B_PHY_LPREHDR_TIME;
		bcntsfoff += wlc_compute_airtime(wlc, rspec, DOT11_MAC_HDR_LEN);
	}
	return (u16) (bcntsfoff);
}

/*	Max buffering needed for beacon template/prb resp template is 142 bytes.
 *
 *	PLCP header is 6 bytes.
 *	802.11 A3 header is 24 bytes.
 *	Max beacon frame body template length is 112 bytes.
 *	Max probe resp frame body template length is 110 bytes.
 *
 *      *len on input contains the max length of the packet available.
 *
 *	The *len value is set to the number of bytes in buf used, and starts with the PLCP
 *	and included up to, but not including, the 4 byte FCS.
 */
static void
wlc_bcn_prb_template(struct wlc_info *wlc, u16 type, ratespec_t bcn_rspec,
		     struct wlc_bsscfg *cfg, u16 *buf, int *len)
{
	static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
	cck_phy_hdr_t *plcp;
	struct ieee80211_mgmt *h;
	int hdr_len, body_len;

	ASSERT(*len >= 142);
	ASSERT(type == IEEE80211_STYPE_BEACON ||
	       type == IEEE80211_STYPE_PROBE_RESP);

	if (MBSS_BCN_ENAB(cfg) && type == IEEE80211_STYPE_BEACON)
		hdr_len = DOT11_MAC_HDR_LEN;
	else
		hdr_len = D11_PHY_HDR_LEN + DOT11_MAC_HDR_LEN;
	body_len = *len - hdr_len;	/* calc buffer size provided for frame body */

	*len = hdr_len + body_len;	/* return actual size */

	/* format PHY and MAC headers */
	memset((char *)buf, 0, hdr_len);

	plcp = (cck_phy_hdr_t *) buf;

	/* PLCP for Probe Response frames are filled in from core's rate table */
	if (type == IEEE80211_STYPE_BEACON && !MBSS_BCN_ENAB(cfg)) {
		/* fill in PLCP */
		wlc_compute_plcp(wlc, bcn_rspec,
				 (DOT11_MAC_HDR_LEN + body_len + FCS_LEN),
				 (u8 *) plcp);

	}
	/* "Regular" and 16 MBSS but not for 4 MBSS */
	/* Update the phytxctl for the beacon based on the rspec */
	if (!SOFTBCN_ENAB(cfg))
		wlc_beacon_phytxctl_txant_upd(wlc, bcn_rspec);

	if (MBSS_BCN_ENAB(cfg) && type == IEEE80211_STYPE_BEACON)
		h = (struct ieee80211_mgmt *)&plcp[0];
	else
		h = (struct ieee80211_mgmt *)&plcp[1];

	/* fill in 802.11 header */
	h->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | type);

	/* DUR is 0 for multicast bcn, or filled in by MAC for prb resp */
	/* A1 filled in by MAC for prb resp, broadcast for bcn */
	if (type == IEEE80211_STYPE_BEACON)
		memcpy(&h->da, &ether_bcast, ETH_ALEN);
	memcpy(&h->sa, &cfg->cur_etheraddr, ETH_ALEN);
	memcpy(&h->bssid, &cfg->BSSID, ETH_ALEN);

	/* SEQ filled in by MAC */

	return;
}

int wlc_get_header_len()
{
	return TXOFF;
}

/* Update a beacon for a particular BSS
 * For MBSS, this updates the software template and sets "latest" to the index of the
 * template updated.
 * Otherwise, it updates the hardware template.
 */
void wlc_bss_update_beacon(struct wlc_info *wlc, struct wlc_bsscfg *cfg)
{
	int len = BCN_TMPL_LEN;

	/* Clear the soft intmask */
	wlc->defmacintmask &= ~MI_BCNTPL;

	if (!cfg->up) {		/* Only allow updates on an UP bss */
		return;
	}

	/* Optimize:  Some of if/else could be combined */
	if (!MBSS_BCN_ENAB(cfg) && HWBCN_ENAB(cfg)) {
		/* Hardware beaconing for this config */
		u16 bcn[BCN_TMPL_LEN / 2];
		u32 both_valid = MCMD_BCN0VLD | MCMD_BCN1VLD;
		d11regs_t *regs = wlc->regs;

		/* Check if both templates are in use, if so sched. an interrupt
		 *      that will call back into this routine
		 */
		if ((R_REG(&regs->maccommand) & both_valid) == both_valid) {
			/* clear any previous status */
			W_REG(&regs->macintstatus, MI_BCNTPL);
		}
		/* Check that after scheduling the interrupt both of the
		 *      templates are still busy. if not clear the int. & remask
		 */
		if ((R_REG(&regs->maccommand) & both_valid) == both_valid) {
			wlc->defmacintmask |= MI_BCNTPL;
			return;
		}

		wlc->bcn_rspec =
		    wlc_lowest_basic_rspec(wlc, &cfg->current_bss->rateset);
		ASSERT(wlc_valid_rate
		       (wlc, wlc->bcn_rspec,
			CHSPEC_IS2G(cfg->current_bss->
				    chanspec) ? WLC_BAND_2G : WLC_BAND_5G,
			true));

		/* update the template and ucode shm */
		wlc_bcn_prb_template(wlc, IEEE80211_STYPE_BEACON,
				     wlc->bcn_rspec, cfg, bcn, &len);
		wlc_write_hw_bcntemplates(wlc, bcn, len, false);
	}
}

/*
 * Update all beacons for the system.
 */
void wlc_update_beacon(struct wlc_info *wlc)
{
	int idx;
	struct wlc_bsscfg *bsscfg;

	/* update AP or IBSS beacons */
	FOREACH_BSS(wlc, idx, bsscfg) {
		if (bsscfg->up && (BSSCFG_AP(bsscfg) || !bsscfg->BSS))
			wlc_bss_update_beacon(wlc, bsscfg);
	}
}

/* Write ssid into shared memory */
void wlc_shm_ssid_upd(struct wlc_info *wlc, struct wlc_bsscfg *cfg)
{
	u8 *ssidptr = cfg->SSID;
	u16 base = M_SSID;
	u8 ssidbuf[IEEE80211_MAX_SSID_LEN];

	/* padding the ssid with zero and copy it into shm */
	memset(ssidbuf, 0, IEEE80211_MAX_SSID_LEN);
	memcpy(ssidbuf, ssidptr, cfg->SSID_len);

	wlc_copyto_shm(wlc, base, ssidbuf, IEEE80211_MAX_SSID_LEN);

	if (!MBSS_BCN_ENAB(cfg))
		wlc_write_shm(wlc, M_SSIDLEN, (u16) cfg->SSID_len);
}

void wlc_update_probe_resp(struct wlc_info *wlc, bool suspend)
{
	int idx;
	struct wlc_bsscfg *bsscfg;

	/* update AP or IBSS probe responses */
	FOREACH_BSS(wlc, idx, bsscfg) {
		if (bsscfg->up && (BSSCFG_AP(bsscfg) || !bsscfg->BSS))
			wlc_bss_update_probe_resp(wlc, bsscfg, suspend);
	}
}

void
wlc_bss_update_probe_resp(struct wlc_info *wlc, struct wlc_bsscfg *cfg,
			  bool suspend)
{
	u16 prb_resp[BCN_TMPL_LEN / 2];
	int len = BCN_TMPL_LEN;

	/* write the probe response to hardware, or save in the config structure */
	if (!MBSS_PRB_ENAB(cfg)) {

		/* create the probe response template */
		wlc_bcn_prb_template(wlc, IEEE80211_STYPE_PROBE_RESP, 0, cfg,
				     prb_resp, &len);

		if (suspend)
			wlc_suspend_mac_and_wait(wlc);

		/* write the probe response into the template region */
		wlc_bmac_write_template_ram(wlc->hw, T_PRS_TPL_BASE,
					    (len + 3) & ~3, prb_resp);

		/* write the length of the probe response frame (+PLCP/-FCS) */
		wlc_write_shm(wlc, M_PRB_RESP_FRM_LEN, (u16) len);

		/* write the SSID and SSID length */
		wlc_shm_ssid_upd(wlc, cfg);

		/*
		 * Write PLCP headers and durations for probe response frames at all rates.
		 * Use the actual frame length covered by the PLCP header for the call to
		 * wlc_mod_prb_rsp_rate_table() by subtracting the PLCP len and adding the FCS.
		 */
		len += (-D11_PHY_HDR_LEN + FCS_LEN);
		wlc_mod_prb_rsp_rate_table(wlc, (u16) len);

		if (suspend)
			wlc_enable_mac(wlc);
	} else {		/* Generating probe resp in sw; update local template */
		ASSERT(0 && "No software probe response support without MBSS");
	}
}

/* prepares pdu for transmission. returns BCM error codes */
int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifop)
{
	uint fifo;
	d11txh_t *txh;
	struct ieee80211_hdr *h;
	struct scb *scb;

	ASSERT(pdu);
	txh = (d11txh_t *) (pdu->data);
	ASSERT(txh);
	h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN);
	ASSERT(h);

	/* get the pkt queue info. This was put at wlc_sendctl or wlc_send for PDU */
	fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK;

	scb = NULL;

	*fifop = fifo;

	/* return if insufficient dma resources */
	if (TXAVAIL(wlc, fifo) < MAX_DMA_SEGS) {
		/* Mark precedences related to this FIFO, unsendable */
		WLC_TX_FIFO_CLEAR(wlc, fifo);
		return BCME_BUSY;
	}

	if (!ieee80211_is_data(txh->MacFrameControl))
		wlc->pub->_cnt->txctl++;

	return 0;
}

/* init tx reported rate mechanism */
void wlc_reprate_init(struct wlc_info *wlc)
{
	int i;
	struct wlc_bsscfg *bsscfg;

	FOREACH_BSS(wlc, i, bsscfg) {
		wlc_bsscfg_reprate_init(bsscfg);
	}
}

/* per bsscfg init tx reported rate mechanism */
void wlc_bsscfg_reprate_init(struct wlc_bsscfg *bsscfg)
{
	bsscfg->txrspecidx = 0;
	memset((char *)bsscfg->txrspec, 0, sizeof(bsscfg->txrspec));
}

/* Retrieve a consolidated set of revision information,
 * typically for the WLC_GET_REVINFO ioctl
 */
int wlc_get_revision_info(struct wlc_info *wlc, void *buf, uint len)
{
	wlc_rev_info_t *rinfo = (wlc_rev_info_t *) buf;

	if (len < WL_REV_INFO_LEGACY_LENGTH)
		return BCME_BUFTOOSHORT;

	rinfo->vendorid = wlc->vendorid;
	rinfo->deviceid = wlc->deviceid;
	rinfo->radiorev = (wlc->band->radiorev << IDCODE_REV_SHIFT) |
	    (wlc->band->radioid << IDCODE_ID_SHIFT);
	rinfo->chiprev = wlc->pub->sih->chiprev;
	rinfo->corerev = wlc->pub->corerev;
	rinfo->boardid = wlc->pub->sih->boardtype;
	rinfo->boardvendor = wlc->pub->sih->boardvendor;
	rinfo->boardrev = wlc->pub->boardrev;
	rinfo->ucoderev = wlc->ucode_rev;
	rinfo->driverrev = EPI_VERSION_NUM;
	rinfo->bus = wlc->pub->sih->bustype;
	rinfo->chipnum = wlc->pub->sih->chip;

	if (len >= (offsetof(wlc_rev_info_t, chippkg))) {
		rinfo->phytype = wlc->band->phytype;
		rinfo->phyrev = wlc->band->phyrev;
		rinfo->anarev = 0;	/* obsolete stuff, suppress */
	}

	if (len >= sizeof(*rinfo)) {
		rinfo->chippkg = wlc->pub->sih->chippkg;
	}

	return BCME_OK;
}

void wlc_default_rateset(struct wlc_info *wlc, wlc_rateset_t *rs)
{
	wlc_rateset_default(rs, NULL, wlc->band->phytype, wlc->band->bandtype,
			    false, RATE_MASK_FULL, (bool) N_ENAB(wlc->pub),
			    CHSPEC_WLC_BW(wlc->default_bss->chanspec),
			    wlc->stf->txstreams);
}

static void wlc_bss_default_init(struct wlc_info *wlc)
{
	chanspec_t chanspec;
	struct wlcband *band;
	wlc_bss_info_t *bi = wlc->default_bss;

	/* init default and target BSS with some sane initial values */
	memset((char *)(bi), 0, sizeof(wlc_bss_info_t));
	bi->beacon_period = ISSIM_ENAB(wlc->pub->sih) ? BEACON_INTERVAL_DEF_QT :
	    BEACON_INTERVAL_DEFAULT;
	bi->dtim_period = ISSIM_ENAB(wlc->pub->sih) ? DTIM_INTERVAL_DEF_QT :
	    DTIM_INTERVAL_DEFAULT;

	/* fill the default channel as the first valid channel
	 * starting from the 2G channels
	 */
	chanspec = CH20MHZ_CHSPEC(1);
	ASSERT(chanspec != INVCHANSPEC);

	wlc->home_chanspec = bi->chanspec = chanspec;

	/* find the band of our default channel */
	band = wlc->band;
	if (NBANDS(wlc) > 1 && band->bandunit != CHSPEC_WLCBANDUNIT(chanspec))
		band = wlc->bandstate[OTHERBANDUNIT(wlc)];

	/* init bss rates to the band specific default rate set */
	wlc_rateset_default(&bi->rateset, NULL, band->phytype, band->bandtype,
			    false, RATE_MASK_FULL, (bool) N_ENAB(wlc->pub),
			    CHSPEC_WLC_BW(chanspec), wlc->stf->txstreams);

	if (N_ENAB(wlc->pub))
		bi->flags |= WLC_BSS_HT;
}

void
wlc_uint64_sub(u32 *a_high, u32 *a_low, u32 b_high, u32 b_low)
{
	if (b_low > *a_low) {
		/* low half needs a carry */
		b_high += 1;
	}
	*a_low -= b_low;
	*a_high -= b_high;
}

static ratespec_t
mac80211_wlc_set_nrate(struct wlc_info *wlc, struct wlcband *cur_band,
		       u32 int_val)
{
	u8 stf = (int_val & NRATE_STF_MASK) >> NRATE_STF_SHIFT;
	u8 rate = int_val & NRATE_RATE_MASK;
	ratespec_t rspec;
	bool ismcs = ((int_val & NRATE_MCS_INUSE) == NRATE_MCS_INUSE);
	bool issgi = ((int_val & NRATE_SGI_MASK) >> NRATE_SGI_SHIFT);
	bool override_mcs_only = ((int_val & NRATE_OVERRIDE_MCS_ONLY)
				  == NRATE_OVERRIDE_MCS_ONLY);
	int bcmerror = 0;

	if (!ismcs) {
		return (ratespec_t) rate;
	}

	/* validate the combination of rate/mcs/stf is allowed */
	if (N_ENAB(wlc->pub) && ismcs) {
		/* mcs only allowed when nmode */
		if (stf > PHY_TXC1_MODE_SDM) {
			WL_ERROR("wl%d: %s: Invalid stf\n",
				 WLCWLUNIT(wlc), __func__);
			bcmerror = BCME_RANGE;
			goto done;
		}

		/* mcs 32 is a special case, DUP mode 40 only */
		if (rate == 32) {
			if (!CHSPEC_IS40(wlc->home_chanspec) ||
			    ((stf != PHY_TXC1_MODE_SISO)
			     && (stf != PHY_TXC1_MODE_CDD))) {
				WL_ERROR("wl%d: %s: Invalid mcs 32\n",
					 WLCWLUNIT(wlc), __func__);
				bcmerror = BCME_RANGE;
				goto done;
			}
			/* mcs > 7 must use stf SDM */
		} else if (rate > HIGHEST_SINGLE_STREAM_MCS) {
			/* mcs > 7 must use stf SDM */
			if (stf != PHY_TXC1_MODE_SDM) {
				WL_TRACE("wl%d: %s: enabling SDM mode for mcs %d\n",
					 WLCWLUNIT(wlc), __func__, rate);
				stf = PHY_TXC1_MODE_SDM;
			}
		} else {
			/* MCS 0-7 may use SISO, CDD, and for phy_rev >= 3 STBC */
			if ((stf > PHY_TXC1_MODE_STBC) ||
			    (!WLC_STBC_CAP_PHY(wlc)
			     && (stf == PHY_TXC1_MODE_STBC))) {
				WL_ERROR("wl%d: %s: Invalid STBC\n",
					 WLCWLUNIT(wlc), __func__);
				bcmerror = BCME_RANGE;
				goto done;
			}
		}
	} else if (IS_OFDM(rate)) {
		if ((stf != PHY_TXC1_MODE_CDD) && (stf != PHY_TXC1_MODE_SISO)) {
			WL_ERROR("wl%d: %s: Invalid OFDM\n",
				 WLCWLUNIT(wlc), __func__);
			bcmerror = BCME_RANGE;
			goto done;
		}
	} else if (IS_CCK(rate)) {
		if ((cur_band->bandtype != WLC_BAND_2G)
		    || (stf != PHY_TXC1_MODE_SISO)) {
			WL_ERROR("wl%d: %s: Invalid CCK\n",
				 WLCWLUNIT(wlc), __func__);
			bcmerror = BCME_RANGE;
			goto done;
		}
	} else {
		WL_ERROR("wl%d: %s: Unknown rate type\n",
			 WLCWLUNIT(wlc), __func__);
		bcmerror = BCME_RANGE;
		goto done;
	}
	/* make sure multiple antennae are available for non-siso rates */
	if ((stf != PHY_TXC1_MODE_SISO) && (wlc->stf->txstreams == 1)) {
		WL_ERROR("wl%d: %s: SISO antenna but !SISO request\n",
			 WLCWLUNIT(wlc), __func__);
		bcmerror = BCME_RANGE;
		goto done;
	}

	rspec = rate;
	if (ismcs) {
		rspec |= RSPEC_MIMORATE;
		/* For STBC populate the STC field of the ratespec */
		if (stf == PHY_TXC1_MODE_STBC) {
			u8 stc;
			stc = 1;	/* Nss for single stream is always 1 */
			rspec |= (stc << RSPEC_STC_SHIFT);
		}
	}

	rspec |= (stf << RSPEC_STF_SHIFT);

	if (override_mcs_only)
		rspec |= RSPEC_OVERRIDE_MCS_ONLY;

	if (issgi)
		rspec |= RSPEC_SHORT_GI;

	if ((rate != 0)
	    && !wlc_valid_rate(wlc, rspec, cur_band->bandtype, true)) {
		return rate;
	}

	return rspec;
 done:
	WL_ERROR("Hoark\n");
	return rate;
}

/* formula:  IDLE_BUSY_RATIO_X_16 = (100-duty_cycle)/duty_cycle*16 */
static int
wlc_duty_cycle_set(struct wlc_info *wlc, int duty_cycle, bool isOFDM,
		   bool writeToShm)
{
	int idle_busy_ratio_x_16 = 0;
	uint offset =
	    isOFDM ? M_TX_IDLE_BUSY_RATIO_X_16_OFDM :
	    M_TX_IDLE_BUSY_RATIO_X_16_CCK;
	if (duty_cycle > 100 || duty_cycle < 0) {
		WL_ERROR("wl%d:  duty cycle value off limit\n", wlc->pub->unit);
		return BCME_RANGE;
	}
	if (duty_cycle)
		idle_busy_ratio_x_16 = (100 - duty_cycle) * 16 / duty_cycle;
	/* Only write to shared memory  when wl is up */
	if (writeToShm)
		wlc_write_shm(wlc, offset, (u16) idle_busy_ratio_x_16);

	if (isOFDM)
		wlc->tx_duty_cycle_ofdm = (u16) duty_cycle;
	else
		wlc->tx_duty_cycle_cck = (u16) duty_cycle;

	return BCME_OK;
}

/* Read a single u16 from shared memory.
 * SHM 'offset' needs to be an even address
 */
u16 wlc_read_shm(struct wlc_info *wlc, uint offset)
{
	return wlc_bmac_read_shm(wlc->hw, offset);
}

/* Write a single u16 to shared memory.
 * SHM 'offset' needs to be an even address
 */
void wlc_write_shm(struct wlc_info *wlc, uint offset, u16 v)
{
	wlc_bmac_write_shm(wlc->hw, offset, v);
}

/* Set a range of shared memory to a value.
 * SHM 'offset' needs to be an even address and
 * Range length 'len' must be an even number of bytes
 */
void wlc_set_shm(struct wlc_info *wlc, uint offset, u16 v, int len)
{
	/* offset and len need to be even */
	ASSERT((offset & 1) == 0);
	ASSERT((len & 1) == 0);

	if (len <= 0)
		return;

	wlc_bmac_set_shm(wlc->hw, offset, v, len);
}

/* Copy a buffer to shared memory.
 * SHM 'offset' needs to be an even address and
 * Buffer length 'len' must be an even number of bytes
 */
void wlc_copyto_shm(struct wlc_info *wlc, uint offset, const void *buf, int len)
{
	/* offset and len need to be even */
	ASSERT((offset & 1) == 0);
	ASSERT((len & 1) == 0);

	if (len <= 0)
		return;
	wlc_bmac_copyto_objmem(wlc->hw, offset, buf, len, OBJADDR_SHM_SEL);

}

/* Copy from shared memory to a buffer.
 * SHM 'offset' needs to be an even address and
 * Buffer length 'len' must be an even number of bytes
 */
void wlc_copyfrom_shm(struct wlc_info *wlc, uint offset, void *buf, int len)
{
	/* offset and len need to be even */
	ASSERT((offset & 1) == 0);
	ASSERT((len & 1) == 0);

	if (len <= 0)
		return;

	wlc_bmac_copyfrom_objmem(wlc->hw, offset, buf, len, OBJADDR_SHM_SEL);
}

/* wrapper BMAC functions to for HIGH driver access */
void wlc_mctrl(struct wlc_info *wlc, u32 mask, u32 val)
{
	wlc_bmac_mctrl(wlc->hw, mask, val);
}

void wlc_corereset(struct wlc_info *wlc, u32 flags)
{
	wlc_bmac_corereset(wlc->hw, flags);
}

void wlc_mhf(struct wlc_info *wlc, u8 idx, u16 mask, u16 val, int bands)
{
	wlc_bmac_mhf(wlc->hw, idx, mask, val, bands);
}

u16 wlc_mhf_get(struct wlc_info *wlc, u8 idx, int bands)
{
	return wlc_bmac_mhf_get(wlc->hw, idx, bands);
}

int wlc_xmtfifo_sz_get(struct wlc_info *wlc, uint fifo, uint *blocks)
{
	return wlc_bmac_xmtfifo_sz_get(wlc->hw, fifo, blocks);
}

void wlc_write_template_ram(struct wlc_info *wlc, int offset, int len,
			    void *buf)
{
	wlc_bmac_write_template_ram(wlc->hw, offset, len, buf);
}

void wlc_write_hw_bcntemplates(struct wlc_info *wlc, void *bcn, int len,
			       bool both)
{
	wlc_bmac_write_hw_bcntemplates(wlc->hw, bcn, len, both);
}

void
wlc_set_addrmatch(struct wlc_info *wlc, int match_reg_offset,
		  const u8 *addr)
{
	wlc_bmac_set_addrmatch(wlc->hw, match_reg_offset, addr);
	if (match_reg_offset == RCM_BSSID_OFFSET)
		memcpy(wlc->cfg->BSSID, addr, ETH_ALEN);
}

void wlc_set_rcmta(struct wlc_info *wlc, int idx, const u8 *addr)
{
	wlc_bmac_set_rcmta(wlc->hw, idx, addr);
}

void wlc_read_tsf(struct wlc_info *wlc, u32 *tsf_l_ptr, u32 *tsf_h_ptr)
{
	wlc_bmac_read_tsf(wlc->hw, tsf_l_ptr, tsf_h_ptr);
}

void wlc_set_cwmin(struct wlc_info *wlc, u16 newmin)
{
	wlc->band->CWmin = newmin;
	wlc_bmac_set_cwmin(wlc->hw, newmin);
}

void wlc_set_cwmax(struct wlc_info *wlc, u16 newmax)
{
	wlc->band->CWmax = newmax;
	wlc_bmac_set_cwmax(wlc->hw, newmax);
}

void wlc_fifoerrors(struct wlc_info *wlc)
{

	wlc_bmac_fifoerrors(wlc->hw);
}

/* Search mem rw utilities */

void wlc_pllreq(struct wlc_info *wlc, bool set, mbool req_bit)
{
	wlc_bmac_pllreq(wlc->hw, set, req_bit);
}

void wlc_reset_bmac_done(struct wlc_info *wlc)
{
}

void wlc_ht_mimops_cap_update(struct wlc_info *wlc, u8 mimops_mode)
{
	wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_SM_PS;
	wlc->ht_cap.cap_info |= (mimops_mode << IEEE80211_HT_CAP_SM_PS_SHIFT);

	if (AP_ENAB(wlc->pub) && wlc->clk) {
		wlc_update_beacon(wlc);
		wlc_update_probe_resp(wlc, true);
	}
}

/* check for the particular priority flow control bit being set */
bool
wlc_txflowcontrol_prio_isset(struct wlc_info *wlc, struct wlc_txq_info *q,
			     int prio)
{
	uint prio_mask;

	if (prio == ALLPRIO) {
		prio_mask = TXQ_STOP_FOR_PRIOFC_MASK;
	} else {
		ASSERT(prio >= 0 && prio <= MAXPRIO);
		prio_mask = NBITVAL(prio);
	}

	return (q->stopped & prio_mask) == prio_mask;
}

/* propagate the flow control to all interfaces using the given tx queue */
void wlc_txflowcontrol(struct wlc_info *wlc, struct wlc_txq_info *qi,
		       bool on, int prio)
{
	uint prio_bits;
	uint cur_bits;

	WL_TRACE("%s: flow control kicks in\n", __func__);

	if (prio == ALLPRIO) {
		prio_bits = TXQ_STOP_FOR_PRIOFC_MASK;
	} else {
		ASSERT(prio >= 0 && prio <= MAXPRIO);
		prio_bits = NBITVAL(prio);
	}

	cur_bits = qi->stopped & prio_bits;

	/* Check for the case of no change and return early
	 * Otherwise update the bit and continue
	 */
	if (on) {
		if (cur_bits == prio_bits) {
			return;
		}
		mboolset(qi->stopped, prio_bits);
	} else {
		if (cur_bits == 0) {
			return;
		}
		mboolclr(qi->stopped, prio_bits);
	}

	/* If there is a flow control override we will not change the external
	 * flow control state.
	 */
	if (qi->stopped & ~TXQ_STOP_FOR_PRIOFC_MASK) {
		return;
	}

	wlc_txflowcontrol_signal(wlc, qi, on, prio);
}

void
wlc_txflowcontrol_override(struct wlc_info *wlc, struct wlc_txq_info *qi,
			   bool on, uint override)
{
	uint prev_override;

	ASSERT(override != 0);
	ASSERT((override & TXQ_STOP_FOR_PRIOFC_MASK) == 0);

	prev_override = (qi->stopped & ~TXQ_STOP_FOR_PRIOFC_MASK);

	/* Update the flow control bits and do an early return if there is
	 * no change in the external flow control state.
	 */
	if (on) {
		mboolset(qi->stopped, override);
		/* if there was a previous override bit on, then setting this
		 * makes no difference.
		 */
		if (prev_override) {
			return;
		}

		wlc_txflowcontrol_signal(wlc, qi, ON, ALLPRIO);
	} else {
		mboolclr(qi->stopped, override);
		/* clearing an override bit will only make a difference for
		 * flow control if it was the only bit set. For any other
		 * override setting, just return
		 */
		if (prev_override != override) {
			return;
		}

		if (qi->stopped == 0) {
			wlc_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO);
		} else {
			int prio;

			for (prio = MAXPRIO; prio >= 0; prio--) {
				if (!mboolisset(qi->stopped, NBITVAL(prio)))
					wlc_txflowcontrol_signal(wlc, qi, OFF,
								 prio);
			}
		}
	}
}

static void wlc_txflowcontrol_reset(struct wlc_info *wlc)
{
	struct wlc_txq_info *qi;

	for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) {
		if (qi->stopped) {
			wlc_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO);
			qi->stopped = 0;
		}
	}
}

static void
wlc_txflowcontrol_signal(struct wlc_info *wlc, struct wlc_txq_info *qi, bool on,
			 int prio)
{
	struct wlc_if *wlcif;

	for (wlcif = wlc->wlcif_list; wlcif != NULL; wlcif = wlcif->next) {
		if (wlcif->qi == qi && wlcif->flags & WLC_IF_LINKED)
			wl_txflowcontrol(wlc->wl, wlcif->wlif, on, prio);
	}
}

static struct wlc_txq_info *wlc_txq_alloc(struct wlc_info *wlc)
{
	struct wlc_txq_info *qi, *p;

	qi = wlc_calloc(wlc->pub->unit, sizeof(struct wlc_txq_info));
	if (qi != NULL) {
		/*
		 * Have enough room for control packets along with HI watermark
		 * Also, add room to txq for total psq packets if all the SCBs
		 * leave PS mode. The watermark for flowcontrol to OS packets
		 * will remain the same
		 */
		pktq_init(&qi->q, WLC_PREC_COUNT,
			  (2 * wlc->pub->tunables->datahiwat) + PKTQ_LEN_DEFAULT
			  + wlc->pub->psq_pkts_total);

		/* add this queue to the the global list */
		p = wlc->tx_queues;
		if (p == NULL) {
			wlc->tx_queues = qi;
		} else {
			while (p->next != NULL)
				p = p->next;
			p->next = qi;
		}
	}
	return qi;
}

static void wlc_txq_free(struct wlc_info *wlc, struct wlc_txq_info *qi)
{
	struct wlc_txq_info *p;

	if (qi == NULL)
		return;

	/* remove the queue from the linked list */
	p = wlc->tx_queues;
	if (p == qi)
		wlc->tx_queues = p->next;
	else {
		while (p != NULL && p->next != qi)
			p = p->next;
		ASSERT(p->next == qi);
		if (p != NULL)
			p->next = p->next->next;
	}

	kfree(qi);
}

/*
 * Flag 'scan in progress' to withhold dynamic phy calibration
 */
void wlc_scan_start(struct wlc_info *wlc)
{
	wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, true);
}

void wlc_scan_stop(struct wlc_info *wlc)
{
	wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, false);
}

void wlc_associate_upd(struct wlc_info *wlc, bool state)
{
	wlc->pub->associated = state;
	wlc->cfg->associated = state;
}

/*
 * When a remote STA/AP is removed by Mac80211, or when it can no longer accept
 * AMPDU traffic, packets pending in hardware have to be invalidated so that
 * when later on hardware releases them, they can be handled appropriately.
 */
void wlc_inval_dma_pkts(struct wlc_hw_info *hw,
			       struct ieee80211_sta *sta,
			       void (*dma_callback_fn))
{
	struct hnddma_pub *dmah;
	int i;
	for (i = 0; i < NFIFO; i++) {
		dmah = hw->di[i];
		if (dmah != NULL)
			dma_walk_packets(dmah, dma_callback_fn, sta);
	}
}
