⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wlc.c

📁 wi-fi sources for asus wl138g v2 pci card
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Common (OS-independent) portion of * Broadcom 802.11abg Networking Device Driver * * Copyright 2005-2006, Broadcom Corporation * All Rights Reserved.                 *  * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. * * $Id$ */#include <wlc_cfg.h>#include <typedefs.h>#include <bcmdefs.h>#include <osl.h>#include <sbutils.h>#include <bcmendian.h>#include <bcmutils.h>#include <proto/802.1d.h>#include <proto/802.11.h>#include <proto/802.11e.h>#include <proto/wpa.h>#include <proto/vlan.h>#include <sbconfig.h>#include <pcicfg.h>#include <bcmsrom.h>#include <wlioctl.h>#include <epivers.h>#include <proto/eapol.h>#include <bcmwpa.h>#include <sbhndpio.h>#include <sbhnddma.h>#include <hnddma.h>#include <d11.h>#include <wlc_rate.h>#include <wlc_pub.h>#include <wlc_rate_sel.h>#include <wlc_key.h>#include <wlc_bsscfg.h>#include <wlc_channel.h>#include <wlc_bsscfg.h>#include <wlc_pio.h>#include <wlc.h>#include <wlc_scb.h>#include <wlc_phy.h>#include <wlc_led.h>#include <wlc_frmutil.h>#include <wlc_security.h>#include <wl_export.h>#include "d11ucode.h"/* * 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 * DOT11_MAX_SSID_LEN) + 1)/* antenna swap threshold */#define	ANTCNT			10		/* vanilla M_MAX_ANTCNT value */#define SCAN_IN_PROGRESS(wlc)	((wlc)->scan.channel_idx != -1)#define	WLC_ACTION_ASSOC	1 /* Association request for MAC */#define	WLC_ACTION_ROAM		2 /* Roaming request for MAC */#define	WLC_ACTION_SCAN		3 /* Scan request for MAC */#define	WLC_ACTION_QUIET	4 /* Quiet request for MAC */#define	WLC_ACTION_RM		5 /* Radio Measure request for MAC */#define	TIMER_INTERVAL_WATCHDOG	1000	/* watchdog timer, in unit of ms */#define	TIMER_INTERVAL_RADIOCHK	800	/* radio monitor timer, in unit of ms */#define	BEACON_INTERVAL_DEFAULT	100	/* beacon interval, in unit of ms */#define	DTIM_INTERVAL_DEFAULT	3	/* DTIM interval, in unit of beacon interval */#define	SYNTHPU_DLY_APHY_US	3700	/* a phy synthpu_dly time in us */#define	PRETBTT_APHY_US		120	/* a phy pretbtt time in us */#define	SYNTHPU_DLY_BPHY_US	1050	/* b/g phy synthpu_dly time in us, default */#define	PRETBTT_BPHY_US		250	/* b/g phy pretbtt time 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 */#define	SW_TIMER_IBSS_GMODE_RATEPROBE	60	/* periodic IBSS gmode rate probing */#define	SW_TIMER_MAC_STAT_UPD		30	/* periodic MAC stats update */#define	LED_TIME			200	/* 200ms wlc_led_timer() period *//* Find basic rate for a given rate : pren simply returns the same rspec */#define WLC_BASIC_RATE(wlc, rspec) ((wlc)->band->basic_rate[rspec & RSPC_RATE_MASK])/* Do we support this rate? */#define VALID_RATE(wlc, rspec) wlc_valid_rate(wlc, rspec, WLC_BAND_AUTO, FALSE)#define VALID_RATE_DBG(wlc, rspec) wlc_valid_rate(wlc, rspec, WLC_BAND_AUTO, TRUE)#define PLCP_PHYRATE(plcp, is_ofdm) (is_ofdm ? (((ofdm_phy_hdr_t *)plcp)->rlpt[0] & 0xf) : \	(((cck_phy_hdr_t *)plcp)->signal))/* To inform the ucode of the last mcast frame posted so that it can clear moredata bit */#define BCMCFID(wlc, fid) wlc_write_shm((wlc), M_BCMC_FID, (fid))#define WLC_IS_CURRENT_BSSID(wlc, bssid) \	(!bcmp((char*)(bssid), (char*)&((wlc)->BSSID), ETHER_ADDR_LEN))#define WLC_IS_TARGET_BSSID(wlc, bssid) \	(!bcmp((char*)(bssid), (char*)&((wlc)->target_bss.BSSID), ETHER_ADDR_LEN))#define WLC_IS_CURRENT_SSID(wlc, ssid, len) \	(((len) == (wlc)->pub.current_bss.SSID_len) && \	 !bcmp((char*)(ssid), (char*)&((wlc)->pub.current_bss.SSID), (len)))#define WLC_IS_TARGET_SSID(wlc, ssid, len) \	(((len) == (wlc)->target_bss.SSID_len) && \	 !bcmp((char*)(ssid), (char*)&((wlc)->target_bss.SSID), (len)))#define WLC_BSS_CONNECTED(wlc) \	((wlc)->pub.associated && (!(wlc)->pub.BSS || !ETHER_ISNULLADDR(&(wlc)->BSSID)))#define IS_SINGLEBAND_5G(device) \	((device == BCM4306_D11A_ID) || \	 (device == BCM4311_D11A_ID) || \	 (device == BCM4318_D11A_ID))#define START_CORE_INDEX(device, ncores) \	((unsigned)((IS_SINGLEBAND_5G(device)) && ((ncores) == 2) ? 1 : 0))#define END_CORE_INDEX(device, ncores, nbands) \	((unsigned)((((ncores) == 2) && (((nbands) == 2) || (IS_SINGLEBAND_5G(device)))) ? 2 : 1))#define FOR_ACTIVE_D11_CORES(loopindex, device, ncores, nbands) \	for (loopindex = START_CORE_INDEX(device, ncores); \		loopindex < END_CORE_INDEX(device, ncores, nbands); \			loopindex++)#define DMAREG(wlc, direction, fifonum)	(D11REV_LT(wlc->pub.corerev, 11) ? \	((direction == DMA_TX) ? (void*)&(wlc->regs->fifo.f32regs.dmaregs[fifonum].xmt) : \				 (void*)&(wlc->regs->fifo.f32regs.dmaregs[fifonum].rcv)) : \	((direction == DMA_TX) ? (void*)&(wlc->regs->fifo.f64regs[fifonum].dmaxmt) : \				 (void*)&(wlc->regs->fifo.f64regs[fifonum].dmarcv)))#define DATA_BLOCK_SCAN		(1 << 0)#define DATA_BLOCK_QUIET	(1 << 1)#define DATA_BLOCK_JOIN		(1 << 2)#define DATA_BLOCK_PS		(1 << 3)#define WL_DUMP_BUF_SIZE	(32 * 1024)#define FRAMETYPE(r, frame)	((IS_CCK(r) ? FT_CCK : FT_OFDM))/* join pref width in bits */#define WLC_JOIN_PREF_BITS_RSSI		8 /* # of bits for TLV in Join Pref for RSSI *//* join pref formats */#define WLC_JOIN_PREF_OFF_COUNT		1 /* Offset for Count for Join Pref TLV */#define WLC_JOIN_PREF_OFF_BAND		1 /* Offset for Band for Join Pref TLV */#define WLC_JOIN_PREF_LEN_FIXED		2 /* Fixed length for Join PREF TLV *//* handy macros */#define WLCWLUNIT(wlc)		((wlc)->pub.unit)#define WLCTYPEBMP(type)	(1 << (type))#define WLCMAXCNT(type)		(1 << (type))#define WLCMAXVAL(bits)		((1 << (bits)) - 1)#define WLCBITMASK(bits)	((1 << (bits)) - 1)#define WLC_BCMC_PSMODE(wlc) (TRUE)#define WLC_WAR16165(wlc) (wlc->war16165)#define RFDISABLE_DEFAULT	10000000 /* rfdisable delay timer 500 ms, runs of ALP clock  *//* debug/trace */uint wl_msg_level =	0;/* 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_RTSTHRESH = 1,	IOV_5G_RATE,	IOV_2G_RATE,	IOV_FRAGTHRESH,	IOV_WSEC,	IOV_PWSEC,	IOV_GWSEC,	IOV_WSEC_KEY,	IOV_WPA_AUTH,	IOV_D11_AUTH,	IOV_WPAIE,		/* set/get the wpaie to/from the driver */	IOV_WSEC_RESTRICT,	IOV_TKIP_CMS,		/* TKIP counter measures */	IOV_URXEAPOL_RESTRICT,	IOV_LAST 		/* In case of a need to check max ID number */};static uint8 WPA_info_element[] = {	DOT11_MNG_WPA_ID, 0x18,	0x00, 0x50, 0xf2, 0x01, 0x01, 0x00,	0x00, 0x50, 0xf2, 0xff,	0x01, 0x00, 0x00, 0x50, 0xf2, 0xff,	0x01, 0x00, 0x00, 0x50, 0xf2, 0xff,	0x00, 0x00};#ifdef BCMWPA2static uint8 WPA2_info_element[] = {	DOT11_MNG_RSN_ID, 0x14, 0x01, 0x00,	0x00, 0x0F, 0xAC, 0xff,	0x01, 0x00, 0x00, 0x0F, 0xAC, 0xff,	0x01, 0x00, 0x00, 0x0F, 0xAC, 0xff,	0x00, 0x00};#endif /* BCMWPA2 */const wlc_iovar_t wlc_iovars[] = {	{"rtsthresh", IOV_RTSTHRESH,	(IOVF_WHL), IOVT_UINT16, 0	},	{"a_rate", IOV_5G_RATE,	(0), IOVT_UINT32, 0	},	{"bg_rate", IOV_2G_RATE,	(0), IOVT_UINT32, 0	},	{"fragthresh", IOV_FRAGTHRESH,	(0), IOVT_UINT16, 0	},	{"wsec", IOV_WSEC,	(0), IOVT_UINT32, 0	},	{"pwsec", IOV_PWSEC,	(0), IOVT_UINT32, 0	},	{"gwsec", IOV_GWSEC,	(0), IOVT_UINT32, 0	},	{"wsec_key", IOV_WSEC_KEY,	(0), IOVT_BUFFER, sizeof(wl_wsec_key_t)	},	{"wpa_auth", IOV_WPA_AUTH,	(0), IOVT_INT32, 0	}, 	{"auth", IOV_D11_AUTH,	0, IOVT_INT32, 0	},	{"wpaie", IOV_WPAIE,	0, IOVT_BUFFER, 16,	},	{"wsec_restrict", IOV_WSEC_RESTRICT,	(0), IOVT_BOOL, 0	},	{"tkip_countermeasures", IOV_TKIP_CMS,	(0), IOVT_BOOL, 0	},	{"rx_unecrypted_restrict", IOV_URXEAPOL_RESTRICT,	(0), IOVT_BOOL, 0	},	{NULL, 0, 0, 0, 0 }};uint8 wme_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 uint8 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 */};/* Define a bitmap of precedences comprised by each AC */#define WLC_PREC_BMP_AC_BE	(NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_BE)) |	\				 NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_BE)) |	\				 NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_EE)) |	\				 NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_EE)))#define WLC_PREC_BMP_AC_BK	(NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_BK)) |	\				 NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_BK)) |	\				 NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_NONE)) |	\				 NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_NONE)))#define WLC_PREC_BMP_AC_VI	(NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_CL)) |	\				 NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_CL)) |	\				 NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_VI)) |	\				 NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_VI)))#define WLC_PREC_BMP_AC_VO	(NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_VO)) |	\				 NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_VO)) |	\				 NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_NC)) |	\				 NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_NC)))/* AC bitmap to precedence bitmap mapping (constructed in wlc_attach) */uint wlc_acbitmap2precbitmap[16];/* 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) ((wlc)->core->txpktpend[(fifo)] || \	((wlc)->core->txpktpend[(fifo)] == 0 && \	((wlc)->tx_prec_map & (wlc)->fifo2prec_map[(fifo)]) == \	(wlc)->fifo2prec_map[(fifo)]) || \	(PIO_ENAB((wlc)) && (wlc->tx_suspended || \		 !wlc_pio_txavailable((wlc)->core->pio[fifo], 1, 1))))/* TX FIFO number to WME/802.1E Access Category */const uint8 wme_fifo2ac[] = { AC_BK, AC_BE, AC_VI, AC_VO, AC_BE, AC_BE };/* Shared memory location index for various AC params */static uint8 wme_shmemacindex[] = {	1,	/* AC_BE index */	0, 	/* AC_BK index */	2, 	/* AC_VI index */	3	/* AC_VO index */};/* conditions under which we want to keep the core awake */#define STAY_AWAKE(wlc) (wlc->wake || SCAN_IN_PROGRESS(wlc) || \	wlc->PMpending || wlc->assoc_state || wlc->check_for_unaligned_tbtt || \	wlc->PSpoll || wlc->apsd_sta_usp || wlc->forcefastclk || \	wlc->wakeforclkctl || wlc->pub.wakeforphyreg || wlc->wakefortxfifo || \	wlc->wakeformacsuspend || wlc->txpend16165war || wlc->PMawakebcn)#define WLC_CHAN_ID(x)		(((x) & RXS_CHAN_ID_MASK) >> RXS_CHAN_ID_SHIFT)#define WLC_CHAN_PHYTYPE(x)	(((x) & RXS_CHAN_PHYTYPE_MASK) >> RXS_CHAN_PHYTYPE_SHIFT)/* 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/* priority to replay counter (Rx IV) entry index mapping. *//** It is one-to-one mapping when there are 16 replay counters.* Otherwise it is many-to-one mapping when there are only 4* counters which are one-to-one mapped to 4 ACs.*/#if WLC_REPLAY_CNTRS_VALUE == WPA_CAP_16_REPLAY_CNTRS#define PRIO2IVIDX(prio)	(prio)#elif WLC_REPLAY_CNTRS_VALUE == WPA_CAP_4_REPLAY_CNTRS#define PRIO2IVIDX(prio)	WME_PRIO2AC(prio)#else#error "Neither WPA_CAP_4_REPLAY_CNTRS nor WPA_CAP_16_REPLAY_CNTRS is used"#endif /* WLC_REPLAY_CNTRS_VALUE == WPA_CAP_16_REPLAY_CNTRS *//* local prototypes */static void wlc_monitor(wlc_info_t *wlc, d11rxhdr_t *rxh, void *p);static void wlc_write_inits(wlc_info_t *wlc, const d11init_t *inits);static void wlc_wme_setparams(wlc_info_t *wlc, bool suspend);static bool wlc_is_wme_ie(wlc_info_t *wlc, uint8 *ie, uint8 **tlvs, uint *tlvs_len);static void wlc_write_ucode(wlc_info_t *wlc, const uint32 ucode[], const uint nbytes);static void wlc_write_pcm(wlc_info_t *wlc, const uint32 pcm[], const uint nbytes);static void wlc_set_txant(wlc_info_t *wlc, int txant);static void wlc_fifoerrors(wlc_info_t *wlc);static bool wlc_validboardtype(wlc_info_t *wlc);static bool wlc_isgoodchip(wlc_info_t* wlc);static void wlc_txq_enq(void *ctx, struct scb *scb, void *sdu, uint prec);static void wlc_pkt_callback(wlc_info_t *wlc, void *pkt, uint16 tx_status);static void wlc_tx_prec_map_init(wlc_info_t *wlc);static void wlc_switch_shortslot(wlc_info_t *wlc, bool shortslot);static void wlc_update_slot_timing(wlc_info_t *wlc, bool shortslot);static void wlc_watchdog(void *arg);static bool wlc_update_gbss_modes(wlc_info_t *wlc);static int wlc_set_rateset(wlc_info_t *wlc, struct rateset *rs_arg);static int wlc_iovar_rangecheck(wlc_info_t *wlc, uint32 val, const wlc_iovar_t *vi);int wlc_doiovar(void *hdl, const wlc_iovar_t *vi, uint32 actionid, const char *name,	void *params, uint p_len, void *arg, int len, int val_size, struct wlc_if *wlcif);static const wlc_iovar_t* wlc_iovar_lookup(const wlc_iovar_t *table, const char *name);static void wlc_ap_upd(wlc_info_t* wlc);static char* wlc_dump_bsscfg(wlc_info_t *wlc, wlc_bsscfg_t *cfg, int bsscfg_idx, char *buf);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -