linux/drivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c

/*
 * Copyright (c) 2010 Broadcom Corporation
 * Copyright (c) 2013 Hauke Mehrtens <[email protected]>
 *
 * 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.
 */

#define pr_fmt(fmt)

#include <linux/pci_ids.h>
#include <linux/if_ether.h>
#include <net/cfg80211.h>
#include <net/mac80211.h>
#include <brcm_hw_ids.h>
#include <aiutils.h>
#include <chipcommon.h>
#include "rate.h"
#include "scb.h"
#include "phy/phy_hal.h"
#include "channel.h"
#include "antsel.h"
#include "stf.h"
#include "ampdu.h"
#include "mac80211_if.h"
#include "ucode_loader.h"
#include "main.h"
#include "soc.h"
#include "dma.h"
#include "debug.h"
#include "brcms_trace_events.h"

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

/* beacon interval, in unit of 1024TU */
#define BEACON_INTERVAL_DEFAULT

/* n-mode support capability */
/* 2x2 includes both 1x1 & 2x2 devices
 * reserved #define 2 for future when we want to separate 1x1 & 2x2 and
 * control it independently
 */
#define WL_11N_2x2
#define WL_11N_3x3
#define WL_11N_4x4

#define EDCF_ACI_MASK
#define EDCF_ACI_SHIFT
#define EDCF_ECWMIN_MASK
#define EDCF_ECWMAX_SHIFT
#define EDCF_AIFSN_MASK
#define EDCF_AIFSN_MAX
#define EDCF_ECWMAX_MASK

#define EDCF_AC_BE_TXOP_STA
#define EDCF_AC_BK_TXOP_STA
#define EDCF_AC_VO_ACI_STA
#define EDCF_AC_VO_ECW_STA
#define EDCF_AC_VI_ACI_STA
#define EDCF_AC_VI_ECW_STA
#define EDCF_AC_BK_ECW_STA
#define EDCF_AC_VI_TXOP_STA
#define EDCF_AC_VO_TXOP_STA
#define EDCF_AC_BE_ACI_STA
#define EDCF_AC_BE_ECW_STA
#define EDCF_AC_BK_ACI_STA
#define EDCF_AC_VO_TXOP_AP

#define EDCF_TXOP2USEC(txop)
#define EDCF_ECW2CW(exp)

#define APHY_SYMBOL_TIME
#define APHY_PREAMBLE_TIME
#define APHY_SIGNAL_TIME
#define APHY_SIFS_TIME
#define APHY_SERVICE_NBITS
#define APHY_TAIL_NBITS
#define BPHY_SIFS_TIME
#define BPHY_PLCP_SHORT_TIME

#define PREN_PREAMBLE
#define PREN_MM_EXT
#define PREN_PREAMBLE_EXT

#define DOT11_MAC_HDR_LEN
#define DOT11_ACK_LEN
#define DOT11_BA_LEN
#define DOT11_OFDM_SIGNAL_EXTENSION
#define DOT11_MIN_FRAG_LEN
#define DOT11_RTS_LEN
#define DOT11_CTS_LEN
#define DOT11_BA_BITMAP_LEN
#define DOT11_MAXNUMFRAGS
#define DOT11_MAX_FRAG_LEN

#define BPHY_PLCP_TIME
#define RIFS_11N_TIME

/* length of the BCN template area */
#define BCN_TMPL_LEN

/* brcms_bss_info flag bit values */
#define BRCMS_BSS_HT

/* chip rx buffer offset */
#define BRCMS_HWRXOFF

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

#define BRCMS_TEMPSENSE_PERIOD

/* synthpu_dly times in us */
#define SYNTHPU_DLY_APHY_US
#define SYNTHPU_DLY_BPHY_US
#define SYNTHPU_DLY_NPHY_US
#define SYNTHPU_DLY_LPPHY_US

#define ANTCNT

/* Per-AC retry limit register definitions; uses defs.h bitfield macros */
#define EDCF_SHORT_S
#define EDCF_SFB_S
#define EDCF_LONG_S
#define EDCF_LFB_S
#define EDCF_SHORT_M
#define EDCF_SFB_M
#define EDCF_LONG_M
#define EDCF_LFB_M

#define RETRY_SHORT_DEF
#define RETRY_SHORT_MAX
#define RETRY_LONG_DEF
#define RETRY_SHORT_FB
#define RETRY_LONG_FB

#define APHY_CWMIN
#define PHY_CWMAX

#define EDCF_AIFSN_MIN

#define FRAGNUM_MASK

#define APHY_SLOT_TIME
#define BPHY_SLOT_TIME

#define WL_SPURAVOID_OFF
#define WL_SPURAVOID_ON1
#define WL_SPURAVOID_ON2

/* invalid core flags, use the saved coreflags */
#define BRCMS_USE_COREFLAGS

/* values for PLCPHdr_override */
#define BRCMS_PLCP_AUTO
#define BRCMS_PLCP_SHORT
#define BRCMS_PLCP_LONG

/* values for g_protection_override and n_protection_override */
#define BRCMS_PROTECTION_AUTO
#define BRCMS_PROTECTION_OFF
#define BRCMS_PROTECTION_ON
#define BRCMS_PROTECTION_MMHDR_ONLY
#define BRCMS_PROTECTION_CTS_ONLY

/* values for g_protection_control and n_protection_control */
#define BRCMS_PROTECTION_CTL_OFF
#define BRCMS_PROTECTION_CTL_LOCAL
#define BRCMS_PROTECTION_CTL_OVERLAP

/* values for n_protection */
#define BRCMS_N_PROTECTION_OFF
#define BRCMS_N_PROTECTION_OPTIONAL
#define BRCMS_N_PROTECTION_20IN40
#define BRCMS_N_PROTECTION_MIXEDMODE

/* values for band specific 40MHz capabilities */
#define BRCMS_N_BW_20ALL
#define BRCMS_N_BW_40ALL
#define BRCMS_N_BW_20IN2G_40IN5G

/* bitflags for SGI support (sgi_rx iovar) */
#define BRCMS_N_SGI_20
#define BRCMS_N_SGI_40

/* defines used by the nrate iovar */
/* MSC in use,indicates b0-6 holds an mcs */
#define NRATE_MCS_INUSE
/* rate/mcs value */
#define NRATE_RATE_MASK
/* stf mode mask: siso, cdd, stbc, sdm */
#define NRATE_STF_MASK
/* stf mode shift */
#define NRATE_STF_SHIFT
/* bit indicate to override mcs only */
#define NRATE_OVERRIDE_MCS_ONLY
#define NRATE_SGI_MASK
#define NRATE_SGI_SHIFT
#define NRATE_LDPC_CODING
#define NRATE_LDPC_SHIFT

#define NRATE_STF_SISO
#define NRATE_STF_CDD
#define NRATE_STF_STBC
#define NRATE_STF_SDM

#define MAX_DMA_SEGS

/* # of entries in Tx FIFO */
#define NTXD
/* Max # of entries in Rx FIFO based on 4kb page size */
#define NRXD

/* Amount of headroom to leave in Tx FIFO */
#define TX_HEADROOM

/* try to keep this # rbufs posted to the chip */
#define NRXBUFPOST

/* max # frames to process in brcms_c_recv() */
#define RXBND
/* max # tx status to process in wlc_txstatus() */
#define TXSBND

/*
 * The following table lists the buffer memory allocated to xmt fifos in HW.
 * the size is in units of 256bytes(one block), total size is HW dependent
 * ucode has default fifo partition, sw can overwrite if necessary
 *
 * This is documented in twiki under the topic UcodeTxFifo. Please ensure
 * the twiki is updated before making changes.
 */

/* Starting corerev for the fifo size table */
#define XMTFIFOTBL_STARTREV

struct d11init {};

struct edcf_acparam {} __packed;

/* debug/trace */
uint brcm_msg_level;

/* TX FIFO number to WME/802.1E Access Category */
static const u8 wme_fifo2ac[] =;

/* ieee80211 Access Category to TX FIFO number */
static const u8 wme_ac2fifo[] =;

static const u16 xmtfifo_sz[][NFIFO] =;

#ifdef DEBUG
static const char * const fifo_names[] =;
#else
static const char fifo_names[6][1];
#endif

#ifdef DEBUG
/* pointer to most recently allocated wl/wlc */
static struct brcms_c_info *wlc_info_dbg =;
#endif

/* Mapping of ieee80211 AC numbers to tx fifos */
static const u8 ac_to_fifo_mapping[IEEE80211_NUM_ACS] =;

/* Mapping of tx fifos to ieee80211 AC numbers */
static const u8 fifo_to_ac_mapping[IEEE80211_NUM_ACS] =;

static u8 brcms_ac_to_fifo(u8 ac)
{}

static u8 brcms_fifo_to_ac(u8 fifo)
{}

/* Find basic rate for a given rate */
static u8 brcms_basic_rate(struct brcms_c_info *wlc, u32 rspec)
{}

static u16 frametype(u32 rspec, u8 mimoframe)
{}

/* currently the best mechanism for determining SIFS is the band in use */
static u16 get_sifs(struct brcms_band *band)
{}

/*
 * Detect Card removed.
 * Even checking an sbconfig register read will not false trigger when the core
 * is in reset it breaks CF address mechanism. Accessing gphy phyversion will
 * cause SB error if aphy is in reset on 4306B0-DB. Need a simple accessible
 * reg with fixed 0/1 pattern (some platforms return all 0).
 * If clocks are present, call the sb routine which will figure out if the
 * device is removed.
 */
static bool brcms_deviceremoved(struct brcms_c_info *wlc)
{}

/* sum the individual fifo tx pending packet counts */
static int brcms_txpktpendtot(struct brcms_c_info *wlc)
{}

static bool brcms_is_mband_unlocked(struct brcms_c_info *wlc)
{}

static int brcms_chspec_bw(u16 chanspec)
{}

static void brcms_c_bsscfg_mfree(struct brcms_bss_cfg *cfg)
{}

static void brcms_c_detach_mfree(struct brcms_c_info *wlc)
{}

static struct brcms_bss_cfg *brcms_c_bsscfg_malloc(uint unit)
{}

static struct brcms_c_info *
brcms_c_attach_malloc(uint unit, uint *err, uint devid)
{}

/*
 * Update the slot timing for standard 11b/g (20us slots)
 * or shortslot 11g (9us slots)
 * The PSM needs to be suspended for this call.
 */
static void brcms_b_update_slot_timing(struct brcms_hardware *wlc_hw,
					bool shortslot)
{}

/*
 * calculate frame duration of a given rate and length, return
 * time in usec unit
 */
static uint brcms_c_calc_frame_time(struct brcms_c_info *wlc, u32 ratespec,
				    u8 preamble_type, uint mac_len)
{}

static void brcms_c_write_inits(struct brcms_hardware *wlc_hw,
				const struct d11init *inits)
{}

static void brcms_c_write_mhf(struct brcms_hardware *wlc_hw, u16 *mhfs)
{}

static void brcms_c_ucode_bsinit(struct brcms_hardware *wlc_hw)
{}

static void brcms_b_core_ioctl(struct brcms_hardware *wlc_hw, u32 m, u32 v)
{}

static void brcms_b_core_phy_clk(struct brcms_hardware *wlc_hw, bool clk)
{}

/* low-level band switch utility routine */
static void brcms_c_setxband(struct brcms_hardware *wlc_hw, uint bandunit)
{}

/* switch to new band but leave it inactive */
static u32 brcms_c_setband_inact(struct brcms_c_info *wlc, uint bandunit)
{}

/* process an individual struct tx_status */
static bool
brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
{}

/* process tx completion events in BMAC
 * Return true if more tx status need to be processed. false otherwise.
 */
static bool
brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
{}

static void brcms_c_tbtt(struct brcms_c_info *wlc)
{}

/* set initial host flags value */
static void
brcms_c_mhfdef(struct brcms_c_info *wlc, u16 *mhfs, u16 mhf2_init)
{}

static uint
dmareg(uint direction, uint fifonum)
{}

static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme)
{}

static void brcms_b_detach_dmapio(struct brcms_hardware *wlc_hw)
{}

/*
 * Initialize brcms_c_info default values ...
 * may get overrides later in this function
 *  BMAC_NOTES, move low out and resolve the dangling ones
 */
static void brcms_b_info_init(struct brcms_hardware *wlc_hw)
{}

static void brcms_b_wait_for_wake(struct brcms_hardware *wlc_hw)
{}

/* control chip clock to save power, enable dynamic clock or force fast clock */
static void brcms_b_clkctl_clk(struct brcms_hardware *wlc_hw, enum bcma_clkmode mode)
{}

/* set or clear ucode host flag bits
 * it has an optimization for no-change write
 * it only writes through shared memory when the core has clock;
 * pre-CLK changes should use wlc_write_mhf to get around the optimization
 *
 *
 * bands values are: BRCM_BAND_AUTO <--- Current band only
 *                   BRCM_BAND_5G   <--- 5G band only
 *                   BRCM_BAND_2G   <--- 2G band only
 *                   BRCM_BAND_ALL  <--- All bands
 */
void
brcms_b_mhf(struct brcms_hardware *wlc_hw, u8 idx, u16 mask, u16 val,
	     int bands)
{}

/* set the maccontrol register to desired reset state and
 * initialize the sw cache of the register
 */
static void brcms_c_mctrl_reset(struct brcms_hardware *wlc_hw)
{}

/*
 * write the software state of maccontrol and
 * overrides to the maccontrol register
 */
static void brcms_c_mctrl_write(struct brcms_hardware *wlc_hw)
{}

/* set or clear maccontrol bits */
void brcms_b_mctrl(struct brcms_hardware *wlc_hw, u32 mask, u32 val)
{}

void brcms_c_ucode_wake_override_set(struct brcms_hardware *wlc_hw,
				 u32 override_bit)
{}

void brcms_c_ucode_wake_override_clear(struct brcms_hardware *wlc_hw,
				   u32 override_bit)
{}

/* When driver needs ucode to stop beaconing, it has to make sure that
 * MCTL_AP is clear and MCTL_INFRA is set
 * Mode           MCTL_AP        MCTL_INFRA
 * AP                1              1
 * STA               0              1 <--- This will ensure no beacons
 * IBSS              0              0
 */
static void brcms_c_ucode_mute_override_set(struct brcms_hardware *wlc_hw)
{}

/* Clear the override on AP and INFRA bits */
static void brcms_c_ucode_mute_override_clear(struct brcms_hardware *wlc_hw)
{}

/*
 * Write a MAC address to the given match reg offset in the RXE match engine.
 */
static void
brcms_b_set_addrmatch(struct brcms_hardware *wlc_hw, int match_reg_offset,
		       const u8 *addr)
{}

void
brcms_b_write_template_ram(struct brcms_hardware *wlc_hw, int offset, int len,
			    void *buf)
{}

static void brcms_b_set_cwmin(struct brcms_hardware *wlc_hw, u16 newmin)
{}

static void brcms_b_set_cwmax(struct brcms_hardware *wlc_hw, u16 newmax)
{}

void brcms_b_bw_set(struct brcms_hardware *wlc_hw, u16 bw)
{}

static void brcms_b_upd_synthpu(struct brcms_hardware *wlc_hw)
{}

static void brcms_c_ucode_txant_set(struct brcms_hardware *wlc_hw)
{}

static u16 brcms_b_ofdm_ratetable_offset(struct brcms_hardware *wlc_hw,
					 u8 rate)
{}

static void brcms_upd_ofdm_pctl1_table(struct brcms_hardware *wlc_hw)
{}

/* band-specific init */
static void brcms_b_bsinit(struct brcms_c_info *wlc, u16 chanspec)
{}

/* Perform a soft reset of the PHY PLL */
void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw)
{}

/* light way to turn on phy clock without reset for NPHY only
 *  refer to brcms_b_core_phy_clk for full version
 */
void brcms_b_phyclk_fgc(struct brcms_hardware *wlc_hw, bool clk)
{}

void brcms_b_macphyclk_set(struct brcms_hardware *wlc_hw, bool clk)
{}

void brcms_b_phy_reset(struct brcms_hardware *wlc_hw)
{}

/* switch to and initialize new band */
static void brcms_b_setband(struct brcms_hardware *wlc_hw, uint bandunit,
			    u16 chanspec) {}

static bool brcms_c_isgoodchip(struct brcms_hardware *wlc_hw)
{}

/* Validate some board info parameters */
static bool brcms_c_validboardtype(struct brcms_hardware *wlc_hw)
{}

static void brcms_c_get_macaddr(struct brcms_hardware *wlc_hw, u8 etheraddr[ETH_ALEN])
{}

/* power both the pll and external oscillator on/off */
static void brcms_b_xtal(struct brcms_hardware *wlc_hw, bool want)
{}

/*
 * Return true if radio is disabled, otherwise false.
 * hw radio disable signal is an external pin, users activate it asynchronously
 * this function could be called when driver is down and w/o clock
 * it operates on different registers depending on corerev and boardflag.
 */
static bool brcms_b_radio_read_hwdisabled(struct brcms_hardware *wlc_hw)
{}

static bool wlc_dma_rxreset(struct brcms_hardware *wlc_hw, uint fifo)
{}

/* d11 core reset
 *   ensure fask clock during reset
 *   reset dma
 *   reset d11(out of reset)
 *   reset phy(out of reset)
 *   clear software macintstatus for fresh new start
 * one testing hack wlc_hw->noreset will bypass the d11/phy reset
 */
void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags)
{}

/* txfifo sizes needs to be modified(increased) since the newer cores
 * have more memory.
 */
static void brcms_b_corerev_fifofixup(struct brcms_hardware *wlc_hw)
{}

/* This function is used for changing the tsf frac register
 * If spur avoidance mode is off, the mac freq will be 80/120/160Mhz
 * If spur avoidance mode is on1, the mac freq will be 82/123/164Mhz
 * If spur avoidance mode is on2, the mac freq will be 84/126/168Mhz
 * HTPHY Formula is 2^26/freq(MHz) e.g.
 * For spuron2 - 126MHz -> 2^26/126 = 532610.0
 *  - 532610 = 0x82082 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x2082
 * For spuron: 123MHz -> 2^26/123    = 545600.5
 *  - 545601 = 0x85341 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x5341
 * For spur off: 120MHz -> 2^26/120    = 559240.5
 *  - 559241 = 0x88889 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x8889
 */

void brcms_b_switch_macfreq(struct brcms_hardware *wlc_hw, u8 spurmode)
{}

void brcms_c_start_station(struct brcms_c_info *wlc, u8 *addr)
{}

void brcms_c_start_ap(struct brcms_c_info *wlc, u8 *addr, const u8 *bssid,
		      u8 *ssid, size_t ssid_len)
{}

void brcms_c_start_adhoc(struct brcms_c_info *wlc, u8 *addr)
{}

/* Initialize GPIOs that are controlled by D11 core */
static void brcms_c_gpio_init(struct brcms_c_info *wlc)
{}

static void brcms_ucode_write(struct brcms_hardware *wlc_hw,
			      const __le32 ucode[], const size_t nbytes)
{}

static void brcms_ucode_download(struct brcms_hardware *wlc_hw)
{}

void brcms_b_txant_set(struct brcms_hardware *wlc_hw, u16 phytxant)
{}

u16 brcms_b_get_txant(struct brcms_hardware *wlc_hw)
{}

void brcms_b_antsel_type_set(struct brcms_hardware *wlc_hw, u8 antsel_type)
{}

static void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw)
{}

void brcms_c_intrson(struct brcms_c_info *wlc)
{}

u32 brcms_c_intrsoff(struct brcms_c_info *wlc)
{}

void brcms_c_intrsrestore(struct brcms_c_info *wlc, u32 macintmask)
{}

/* assumes that the d11 MAC is enabled */
static void brcms_b_tx_fifo_suspend(struct brcms_hardware *wlc_hw,
				    uint tx_fifo)
{}

static void brcms_b_tx_fifo_resume(struct brcms_hardware *wlc_hw,
				   uint tx_fifo)
{}

/* precondition: requires the mac core to be enabled */
static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool mute_tx)
{}

void
brcms_c_mute(struct brcms_c_info *wlc, bool mute_tx)
{}

/*
 * Read and clear macintmask and macintstatus and intstatus registers.
 * This routine should be called with interrupts off
 * Return:
 *   -1 if brcms_deviceremoved(wlc) evaluates to true;
 *   0 if the interrupt is not for us, or we are in some special cases;
 *   device interrupt status bits otherwise.
 */
static inline u32 wlc_intstatus(struct brcms_c_info *wlc, bool in_isr)
{}

/* Update wlc->macintstatus and wlc->intstatus[]. */
/* Return true if they are updated successfully. false otherwise */
bool brcms_c_intrsupd(struct brcms_c_info *wlc)
{}

/*
 * First-level interrupt processing.
 * Return true if this was our interrupt
 * and if further brcms_c_dpc() processing is required,
 * false otherwise.
 */
bool brcms_c_isr(struct brcms_c_info *wlc)
{}

void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc)
{}

void brcms_c_enable_mac(struct brcms_c_info *wlc)
{}

void brcms_b_band_stf_ss_set(struct brcms_hardware *wlc_hw, u8 stf_mode)
{}

static bool brcms_b_validate_chip_access(struct brcms_hardware *wlc_hw)
{}

#define PHYPLL_WAIT_US

void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on)
{}

static void brcms_c_coredisable(struct brcms_hardware *wlc_hw)
{}

static void brcms_c_flushqueues(struct brcms_c_info *wlc)
{}

static u16
brcms_b_read_objmem(struct brcms_hardware *wlc_hw, uint offset, u32 sel)
{}

static void
brcms_b_write_objmem(struct brcms_hardware *wlc_hw, uint offset, u16 v,
		     u32 sel)
{}

/*
 * Read a single u16 from shared memory.
 * SHM 'offset' needs to be an even address
 */
u16 brcms_b_read_shm(struct brcms_hardware *wlc_hw, uint offset)
{}

/*
 * Write a single u16 to shared memory.
 * SHM 'offset' needs to be an even address
 */
void brcms_b_write_shm(struct brcms_hardware *wlc_hw, uint offset, u16 v)
{}

/*
 * Copy a buffer to shared memory of specified type .
 * SHM 'offset' needs to be an even address and
 * Buffer length 'len' must be an even number of bytes
 * 'sel' selects the type of memory
 */
void
brcms_b_copyto_objmem(struct brcms_hardware *wlc_hw, uint offset,
		      const void *buf, int len, u32 sel)
{}

/*
 * Copy a piece of shared memory of specified type to a buffer .
 * SHM 'offset' needs to be an even address and
 * Buffer length 'len' must be an even number of bytes
 * 'sel' selects the type of memory
 */
void
brcms_b_copyfrom_objmem(struct brcms_hardware *wlc_hw, uint offset, void *buf,
			 int len, u32 sel)
{}

/* 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
 */
static void brcms_c_copyto_shm(struct brcms_c_info *wlc, uint offset,
			const void *buf, int len)
{}

static void brcms_b_retrylimit_upd(struct brcms_hardware *wlc_hw,
				   u16 SRL, u16 LRL)
{}

static void brcms_b_pllreq(struct brcms_hardware *wlc_hw, bool set, u32 req_bit)
{}

static void brcms_b_antsel_set(struct brcms_hardware *wlc_hw, u32 antsel_avail)
{}

/*
 * conditions under which the PM bit should be set in outgoing frames
 * and STAY_AWAKE is meaningful
 */
static bool brcms_c_ps_allowed(struct brcms_c_info *wlc)
{}

static void brcms_c_statsupd(struct brcms_c_info *wlc)
{}

static void brcms_b_reset(struct brcms_hardware *wlc_hw)
{}

void brcms_c_reset(struct brcms_c_info *wlc)
{}

void brcms_c_init_scb(struct scb *scb)
{}

/* d11 core init
 *   reset PSM
 *   download ucode/PCM
 *   let ucode run to suspended
 *   download ucode inits
 *   config other core registers
 *   init dma
 */
static void brcms_b_coreinit(struct brcms_c_info *wlc)
{}

static void brcms_b_init(struct brcms_hardware *wlc_hw, u16 chanspec)
{}

static void brcms_c_set_phy_chanspec(struct brcms_c_info *wlc,
				     u16 chanspec)
{}

static void
brcms_default_rateset(struct brcms_c_info *wlc, struct brcms_c_rateset *rs)
{}

/* derive wlc->band->basic_rate[] table from 'rateset' */
static void brcms_c_rate_lookup_init(struct brcms_c_info *wlc,
			      struct brcms_c_rateset *rateset)
{}

static void brcms_c_bandinit_ordered(struct brcms_c_info *wlc,
				     u16 chanspec)
{}

/*
 * Set or clear filtering related maccontrol bits based on
 * specified filter flags
 */
void brcms_c_mac_promisc(struct brcms_c_info *wlc, uint filter_flags)
{}

/*
 * ucode, hwmac update
 *    Channel dependent updates for ucode and hw
 */
static void brcms_c_ucode_mac_upd(struct brcms_c_info *wlc)
{}

static void brcms_c_write_rate_shm(struct brcms_c_info *wlc, u8 rate,
				   u8 basic_rate)
{}

static const struct brcms_c_rateset *
brcms_c_rateset_get_hwrs(struct brcms_c_info *wlc)
{}

static void brcms_c_set_ratetable(struct brcms_c_info *wlc)
{}

/* band-specific init */
static void brcms_c_bsinit(struct brcms_c_info *wlc)
{}

/* formula:  IDLE_BUSY_RATIO_X_16 = (100-duty_cycle)/duty_cycle*16 */
static int
brcms_c_duty_cycle_set(struct brcms_c_info *wlc, int duty_cycle, bool isOFDM,
		   bool writeToShm)
{}

/* push sw hps and wake state through hardware */
static void brcms_c_set_ps_ctrl(struct brcms_c_info *wlc)
{}

/*
 * Write this BSS config's MAC address to core.
 * Updates RXE match engine.
 */
static void brcms_c_set_mac(struct brcms_bss_cfg *bsscfg)
{}

/* Write the BSS config's BSSID address to core (set_bssid in d11procs.tcl).
 * Updates RXE match engine.
 */
static void brcms_c_set_bssid(struct brcms_bss_cfg *bsscfg)
{}

void brcms_c_set_ssid(struct brcms_c_info *wlc, u8 *ssid, size_t ssid_len)
{}

static void brcms_b_set_shortslot(struct brcms_hardware *wlc_hw, bool shortslot)
{}

/*
 * Suspend the MAC and update the slot timing
 * for standard 11b/g (20us slots) or shortslot 11g (9us slots).
 */
static void brcms_c_switch_shortslot(struct brcms_c_info *wlc, bool shortslot)
{}

static void brcms_c_set_home_chanspec(struct brcms_c_info *wlc, u16 chanspec)
{}

void
brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, u16 chanspec,
		      bool mute_tx, struct txpwr_limits *txpwr)
{}

/* switch to and initialize new band */
static void brcms_c_setband(struct brcms_c_info *wlc,
					   uint bandunit)
{}

static void brcms_c_set_chanspec(struct brcms_c_info *wlc, u16 chanspec)
{}

/*
 * 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 brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc,
				       u32 bcn_rspec)
{}

/*
 * 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 brcms_c_protection_upd(struct brcms_c_info *wlc, uint idx, int val)
{}

static void brcms_c_ht_update_sgi_rx(struct brcms_c_info *wlc, int val)
{}

static void brcms_c_ht_update_ldpc(struct brcms_c_info *wlc, s8 val)
{}

void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci,
		       const struct ieee80211_tx_queue_params *params,
		       bool suspend)
{}

static void brcms_c_edcf_setparams(struct brcms_c_info *wlc, bool suspend)
{}

static void brcms_c_radio_monitor_start(struct brcms_c_info *wlc)
{}

static bool brcms_c_radio_monitor_stop(struct brcms_c_info *wlc)
{}

/* read hwdisable state and propagate to wlc flag */
static void brcms_c_radio_hwdisable_upd(struct brcms_c_info *wlc)
{}

/* update hwradio status and return it */
bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc)
{}

/* periodical query hw radio button while driver is "down" */
static void brcms_c_radio_timer(void *arg)
{}

/* common low-level watchdog code */
static void brcms_b_watchdog(struct brcms_c_info *wlc)
{}

/* common watchdog code */
static void brcms_c_watchdog(struct brcms_c_info *wlc)
{}

static void brcms_c_watchdog_by_timer(void *arg)
{}

static bool brcms_c_timers_init(struct brcms_c_info *wlc, int unit)
{}

/*
 * Initialize brcms_c_info default values ...
 * may get overrides later in this function
 */
static void brcms_c_info_init(struct brcms_c_info *wlc, int unit)
{}

static uint brcms_c_attach_module(struct brcms_c_info *wlc)
{}

struct brcms_pub *brcms_c_pub(struct brcms_c_info *wlc)
{}

/* low level attach
 *    run backplane attach, init nvram
 *    run phy attach
 *    initialize software state for each core and band
 *    put the whole chip in reset(driver down state), no clock
 */
static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core,
			  uint unit, bool piomode)
{}

static bool brcms_c_attach_stf_ant_init(struct brcms_c_info *wlc)
{}

static void brcms_c_bss_default_init(struct brcms_c_info *wlc)
{}

static void brcms_c_update_mimo_band_bwcap(struct brcms_c_info *wlc, u8 bwcap)
{}

static void brcms_c_timers_deinit(struct brcms_c_info *wlc)
{}

static void brcms_c_detach_module(struct brcms_c_info *wlc)
{}

/*
 * low level detach
 */
static void brcms_b_detach(struct brcms_c_info *wlc)
{}

/*
 * Return a count of the number of driver callbacks still pending.
 *
 * General policy is that brcms_c_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 brcms_c_detach(struct brcms_c_info *wlc)
{}

/* update state that depends on the current value of "ap" */
static void brcms_c_ap_upd(struct brcms_c_info *wlc)
{}

/* Initialize just the hardware when coming out of POR or S3/S5 system states */
static void brcms_b_hw_up(struct brcms_hardware *wlc_hw)
{}

static int brcms_b_up_prep(struct brcms_hardware *wlc_hw)
{}

static int brcms_b_up_finish(struct brcms_hardware *wlc_hw)
{}

/*
 * Write WME tunable parameters for retransmit/max rate
 * from wlc struct to ucode
 */
static void brcms_c_wme_retries_write(struct brcms_c_info *wlc)
{}

/* make interface operational */
int brcms_c_up(struct brcms_c_info *wlc)
{}

static int brcms_b_bmac_down_prep(struct brcms_hardware *wlc_hw)
{}

static int brcms_b_down_finish(struct brcms_hardware *wlc_hw)
{}

/*
 * 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 brcms_c_down(struct brcms_c_info *wlc)
{}

/* Set the current gmode configuration */
int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config)
{}

int brcms_c_set_nmode(struct brcms_c_info *wlc)
{}

static int
brcms_c_set_internal_rateset(struct brcms_c_info *wlc,
			     struct brcms_c_rateset *rs_arg)
{}

static void brcms_c_ofdm_rateset_war(struct brcms_c_info *wlc)
{}

int brcms_c_set_channel(struct brcms_c_info *wlc, u16 channel)
{}

int brcms_c_set_rate_limit(struct brcms_c_info *wlc, u16 srl, u16 lrl)
{}

void brcms_c_get_current_rateset(struct brcms_c_info *wlc,
				 struct brcm_rateset *currs)
{}

int brcms_c_set_rateset(struct brcms_c_info *wlc, struct brcm_rateset *rs)
{}

static void brcms_c_time_lock(struct brcms_c_info *wlc)
{}

static void brcms_c_time_unlock(struct brcms_c_info *wlc)
{}

int brcms_c_set_beacon_period(struct brcms_c_info *wlc, u16 period)
{}

u16 brcms_c_get_phy_type(struct brcms_c_info *wlc, int phyidx)
{}

void brcms_c_set_shortslot_override(struct brcms_c_info *wlc, s8 sslot_override)
{}

/*
 * register watchdog and down handlers.
 */
int brcms_c_module_register(struct brcms_pub *pub,
			    const char *name, struct brcms_info *hdl,
			    int (*d_fn)(void *handle))
{}

/* unregister module callbacks */
int brcms_c_module_unregister(struct brcms_pub *pub, const char *name,
			      struct brcms_info *hdl)
{}

static bool brcms_c_chipmatch_pci(struct bcma_device *core)
{}

static bool brcms_c_chipmatch_soc(struct bcma_device *core)
{}

bool brcms_c_chipmatch(struct bcma_device *core)
{}

u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate)
{}

/*
 * 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 brcms_c_info *wlc, struct brcms_bss_cfg *bsscfg,
		  struct d11txh *txh)
{}

static uint
brcms_c_calc_ack_time(struct brcms_c_info *wlc, u32 rspec,
		      u8 preamble_type)
{}

static uint
brcms_c_calc_cts_time(struct brcms_c_info *wlc, u32 rspec,
		      u8 preamble_type)
{}

static uint
brcms_c_calc_ba_time(struct brcms_c_info *wlc, u32 rspec,
		     u8 preamble_type)
{}

/* brcms_c_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
brcms_c_compute_frame_dur(struct brcms_c_info *wlc, u32 rate,
		      u8 preamble_type, uint next_frag_len)
{}

/* The opposite of brcms_c_calc_frame_time */
static uint
brcms_c_calc_frame_len(struct brcms_c_info *wlc, u32 ratespec,
		   u8 preamble_type, uint dur)
{}

/*
 * Return true if the specified rate is supported by the specified band.
 * BRCM_BAND_AUTO indicates the current band.
 */
static bool brcms_c_valid_rate(struct brcms_c_info *wlc, u32 rspec, int band,
		    bool verbose)
{}

static u32
mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band,
		       u32 int_val)
{}

/*
 * 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 brcms_c_cck_plcp_set(struct brcms_c_info *wlc, int rate_500,
			     uint length, u8 *plcp)
{}

/* Rate: 802.11 rate code, length: PSDU length in octets */
static void brcms_c_compute_mimo_plcp(u32 rspec, uint length, u8 *plcp)
{}

/* Rate: 802.11 rate code, length: PSDU length in octets */
static void
brcms_c_compute_ofdm_plcp(u32 rspec, u32 length, u8 *plcp)
{}

/* Rate: 802.11 rate code, length: PSDU length in octets */
static void brcms_c_compute_cck_plcp(struct brcms_c_info *wlc, u32 rspec,
				 uint length, u8 *plcp)
{}

static void
brcms_c_compute_plcp(struct brcms_c_info *wlc, u32 rspec,
		     uint length, u8 *plcp)
{}

/* brcms_c_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
brcms_c_compute_rtscts_dur(struct brcms_c_info *wlc, bool cts_only,
			   u32 rts_rate,
			   u32 frame_rate, u8 rts_preamble_type,
			   u8 frame_preamble_type, uint frame_len, bool ba)
{}

static u16 brcms_c_phytxctl1_calc(struct brcms_c_info *wlc, u32 rspec)
{}

/*
 * Add struct d11txh, struct cck_phy_hdr.
 *
 * '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
brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw,
		     struct sk_buff *p, struct scb *scb, uint frag,
		     uint nfrags, uint queue, uint next_frag_len)
{}

static int brcms_c_tx(struct brcms_c_info *wlc, struct sk_buff *skb)
{}

bool brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu,
			      struct ieee80211_hw *hw)
{}

int
brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p)
{}

u32
brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, u32 rspec,
			   bool use_rspec, u16 mimo_ctlchbw)
{}

/* Update beacon listen interval in shared memory */
static void brcms_c_bcn_li_upd(struct brcms_c_info *wlc)
{}

static void
brcms_b_read_tsf(struct brcms_hardware *wlc_hw, u32 *tsf_l_ptr,
		  u32 *tsf_h_ptr)
{}

/*
 * recover 64bit TSF value from the 16bit TSF value in the rx header
 * given the assumption that the TSF passed in header is within 65ms
 * of the current tsf.
 *
 * 6       5       4       4       3       2       1
 * 3.......6.......8.......0.......2.......4.......6.......8......0
 * |<---------- tsf_h ----------->||<--- tsf_l -->||<-RxTSFTime ->|
 *
 * The RxTSFTime are the lowest 16 bits and provided by the ucode. The
 * tsf_l is filled in by brcms_b_recv, which is done earlier in the
 * receive call sequence after rx interrupt. Only the higher 16 bits
 * are used. Finally, the tsf_h is read from the tsf register.
 */
static u64 brcms_c_recover_tsf64(struct brcms_c_info *wlc,
				 struct d11rxhdr *rxh)
{}

static void
prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
		     struct sk_buff *p,
		     struct ieee80211_rx_status *rx_status)
{}

static void
brcms_c_recvctl(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
		struct sk_buff *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
brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec,
		      uint mac_len)
{}

static void
brcms_c_mod_prb_rsp_rate_table(struct brcms_c_info *wlc, uint frame_len)
{}

int brcms_c_get_header_len(void)
{}

static void brcms_c_beacon_write(struct brcms_c_info *wlc,
				 struct sk_buff *beacon, u16 tim_offset,
				 u16 dtim_period, bool bcn0, bool bcn1)
{}

static void brcms_c_update_beacon_hw(struct brcms_c_info *wlc,
				     struct sk_buff *beacon, u16 tim_offset,
				     u16 dtim_period)
{}

/*
 * Update all beacons for the system.
 */
void brcms_c_update_beacon(struct brcms_c_info *wlc)
{}

void brcms_c_set_new_beacon(struct brcms_c_info *wlc, struct sk_buff *beacon,
			    u16 tim_offset, u16 dtim_period)
{}

void brcms_c_set_new_probe_resp(struct brcms_c_info *wlc,
				struct sk_buff *probe_resp)
{}

void brcms_c_enable_probe_resp(struct brcms_c_info *wlc, bool enable)
{}

/* Write ssid into shared memory */
static void
brcms_c_shm_ssid_upd(struct brcms_c_info *wlc, struct brcms_bss_cfg *cfg)
{}

static void
brcms_c_bss_update_probe_resp(struct brcms_c_info *wlc,
			      struct brcms_bss_cfg *cfg,
			      struct sk_buff *probe_resp,
			      bool suspend)
{}

void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend)
{}

int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo,
			   uint *blocks)
{}

void
brcms_c_set_addrmatch(struct brcms_c_info *wlc, int match_reg_offset,
		  const u8 *addr)
{}

/*
 * Flag 'scan in progress' to withhold dynamic phy calibration
 */
void brcms_c_scan_start(struct brcms_c_info *wlc)
{}

void brcms_c_scan_stop(struct brcms_c_info *wlc)
{}

void brcms_c_associate_upd(struct brcms_c_info *wlc, bool 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 brcms_c_inval_dma_pkts(struct brcms_hardware *hw,
			       struct ieee80211_sta *sta,
			       void (*dma_callback_fn))
{}

int brcms_c_get_curband(struct brcms_c_info *wlc)
{}

bool brcms_c_tx_flush_completed(struct brcms_c_info *wlc)
{}

void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, u8 interval)
{}

u64 brcms_c_tsf_get(struct brcms_c_info *wlc)
{}

void brcms_c_tsf_set(struct brcms_c_info *wlc, u64 tsf)
{}

int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr)
{}

int brcms_c_get_tx_power(struct brcms_c_info *wlc)
{}

/* Process received frames */
/*
 * Return true if more frames need to be processed. false otherwise.
 * Param 'bound' indicates max. # frames to process before break out.
 */
static void brcms_c_recv(struct brcms_c_info *wlc, struct sk_buff *p)
{}

/* Process received frames */
/*
 * Return true if more frames need to be processed. false otherwise.
 * Param 'bound' indicates max. # frames to process before break out.
 */
static bool
brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound)
{}

/* second-level interrupt processing
 *   Return true if another dpc needs to be re-scheduled. false otherwise.
 *   Param 'bounded' indicates if applicable loops should be bounded.
 */
bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded)
{}

void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx)
{}

/*
 * The common driver entry routine. Error codes should be unique
 */
struct brcms_c_info *
brcms_c_attach(struct brcms_info *wl, struct bcma_device *core, uint unit,
	       bool piomode, uint *perr)
{}