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

📄 wlc.c

📁 wi-fi sources for asus wl138g v2 pci card
💻 C
📖 第 1 页 / 共 5 页
字号:
	}	/* Init precedence maps for empty FIFOs */	wlc_tx_prec_map_init(wlc);	/* ..now really unleash hell (allow the MAC out of suspend) */	wlc_enable_mac(wlc);	/* restore macintmask */	wl_intrsrestore(wlc->wl, macintmask);	/* clear tx flow control */	if (wlc->pub.txqstopped) {		wlc->pub.txqstopped = OFF;		wl_txflowcontrol(wlc->wl, OFF);	}	/* clear tx data fifo suspends */	wlc->tx_suspended = FALSE;	/* enable the RF Disable Delay timer */	if (wlc->pub.corerev >= 10) {		W_REG(&wlc->regs->rfdisabledly, RFDISABLE_DEFAULT);	}	/* Reinitialize the precedence map to syncup with FIFOs */	wlc_tx_prec_map_init(wlc);}/* return initial host flags value */static uint32BCMINITFN(wlc_mhfdef)(wlc_info_t *wlc){	uint32 mhf;	mhf = 0;	if (ISGPHY(wlc->band->pi))		mhf |= MHF_SYMWAR;	if (ISGPHY(wlc->band->pi) && GREV_IS(wlc->band->pi->phy_rev, 1))		mhf |= MHF_DCFILTWAR;	if (ISGPHY(wlc->band->pi) && (wlc->pub.boardflags & BFL_PACTRL) && !wlc->dbgsel)		mhf |= MHF_OFDMPWR;	/* enable CCK power boost in ucode but not for 4318/20 */	if (ISGPHY(wlc->band->pi) && (wlc->band->pi->phy_rev < 3)) {		if (mhf & MHF_OFDMPWR)			WL_ERROR(("wl%d: Cannot support simultaneous MHF_OFDMPWR & MHF_CCKPWR\n",				wlc->pub.unit));		else			mhf |= MHF_CCKPWR;	}	/* prohibit use of slowclock on multifunction boards */	if (wlc->pub.boardflags & BFL_NOPLLDOWN)		mhf |= MHF_FORCEFASTCLK;	if ((wlc->band->pi->radioid == BCM2050_ID) && (wlc->band->pi->radiorev < 6))		mhf |= MHF_SYNTHPUWAR;	if (WLC_WAR16165(wlc))		mhf |= MHF_PCISLOWCLKWAR;	return (mhf);}/* set or clear ucode host flag bits and return new value * 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 * * it change both bands' shadow variables if allbands is TRUE * return value is valid only if wlc->band has been initialized */uint32wlc_mhf(wlc_info_t *wlc, uint32 mask, uint32 val, bool allbands){	uint32 save;	ASSERT((val & ~mask) == 0);	if (wlc->band) {		save = wlc->band->mhf;		wlc->band->mhf = (wlc->band->mhf & ~mask) | val;		/* optimization: only write through if changed */		if (wlc->core->clk && (wlc->band->mhf != save)) {			wlc_write_shm(wlc, M_HOST_FLAGS, (uint16)wlc->band->mhf);			wlc_write_shm(wlc, M_HOST_FLAGS2, (uint16)(wlc->band->mhf >>				M_HOST_FLAGS_SZ));		}	}	if (allbands) {		wlc->bandstate[0].mhf = (wlc->bandstate[0].mhf & ~mask) | val;		wlc->bandstate[1].mhf = (wlc->bandstate[1].mhf & ~mask) | val;	}	return (wlc->band ? wlc->band->mhf : 0);}static voidwlc_write_mhf(wlc_info_t *wlc, uint32 val){	wlc_write_shm(wlc, M_HOST_FLAGS, (uint16)val);	wlc_write_shm(wlc, M_HOST_FLAGS2, (uint16)(val >> M_HOST_FLAGS_SZ));}/* set or clear maccontrol bits and return new value */void wlc_mctrl(wlc_info_t *wlc, uint32 mask, uint32 val){	ASSERT((val & ~mask) == 0);	wlc->maccontrol = (R_REG(&wlc->regs->maccontrol) & ~mask) | val;	W_REG(&wlc->regs->maccontrol, wlc->maccontrol);}voidwlc_mac_bcn_promisc(wlc_info_t *wlc){	/* default behavior: on for Gmode in BSS/IBSS) || (A/B mode in IBSS)	 *		     off for other cases	 */	if (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 */voidwlc_mac_promisc(wlc_info_t *wlc){	uint32 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 (wlc->pub.promisc)		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 (wlc->monitor)		promisc_bits |= MCTL_PROMISC | MCTL_KEEPCONTROL;	wlc_mctrl(wlc, MCTL_PROMISC | MCTL_KEEPCONTROL, promisc_bits);}/* push sw hps and wake state through hardware */voidwlc_set_ps_ctrl(wlc_info_t *wlc){	uint32 v1, v2;	bool hps, wake;	bool awake_before;	hps = PS_ALLOWED(wlc);	wake = STAY_AWAKE(wlc);	if (!hps)		wake = TRUE;	WL_TRACE(("wl%d: wlc_set_ps_ctrl: hps %d wake %d\n", wlc->pub.unit, hps, wake));	v1 = v2 = R_REG(&wlc->regs->maccontrol);	if (hps)		v2 |= MCTL_HPS;	else		v2 &= ~MCTL_HPS;	if (wake)		v2 |= MCTL_WAKE;	else		v2 &= ~MCTL_WAKE;	/* just return if no change */	if ((v1 & (MCTL_WAKE | MCTL_HPS)) == (v2 & ((MCTL_WAKE | MCTL_HPS))))		return;	if ((v1 & MCTL_HPS) && !hps)		WL_PS(("wl%d: PS mode disable \n", wlc->pub.unit));	if (!(v1 & MCTL_HPS) && hps)		WL_PS(("wl%d: PS mode enable \n", wlc->pub.unit));	if (hps) {		if ((v1 & MCTL_WAKE) && !wake)			WL_PS(("wl%d: PS-MODE: sleep\n", wlc->pub.unit));		if (!(v1 & MCTL_WAKE) && wake)			WL_PS(("wl%d: PS-MODE: wake\n", wlc->pub.unit));	}	wlc_mctrl(wlc, ~0, v2);	awake_before = ((v1 & MCTL_WAKE) || ((v1 & MCTL_HPS) == 0));	/* readback */	if (wake && !awake_before) {		if (D11REV_LT(wlc->pub.corerev, 5)) /* no slowclock */			OSL_DELAY(5);		else {			if ((ISGPHY(wlc->band->pi)) && (D11REV_IS(wlc->pub.corerev, 5)))				OSL_DELAY(2000);	/* delay before first read */			else				OSL_DELAY(40);	/* delay before first read */			SPINWAIT((wlc_read_shm(wlc, M_UCODE_DBGST) == DBGST_ASLEEP), (8 *				MIN_SLOW_CLK));		}		ASSERT(wlc_read_shm(wlc, M_UCODE_DBGST) != DBGST_ASLEEP);	}}/* * Write STA MAC address to core. * Updates RXE match engine and tx template addr fields. */static voidwlc_set_mac(wlc_info_t *wlc, struct ether_addr *addr){	d11regs_t *regs;	char template_buf[(T_RAM_ACCESS_SZ*2)];	WL_TRACE(("wl%d: wlc_set_mac\n", wlc->pub.unit));	regs = wlc->regs;	/* enter the MAC addr into the RXE match registers */	wlc_set_addrmatch(wlc, RCM_MAC_OFFSET, addr);	/* fill out a buffer with a multiple of 4 length, starting at	 * a 4 byte boundary offset for wlc_write_template_ram, 6 bytes	 * of MAC addr and the first 2 bytes of our beaconing BSSID.	 */	bcopy((char*)wlc->pub.cur_etheraddr.octet, template_buf, ETHER_ADDR_LEN);	bcopy((char*)wlc->announce_BSSID.octet, template_buf + ETHER_ADDR_LEN, 2);	/* The A2 (SA) MAC addr appears at bytes [16, 21] in the 802.11 frames	 * in the templates.	 * 6 bytes PLCP	 * 2 bytes FC	 * 2 bytes DUR/ID	 * 6 bytes A1	 * 6 bytes A2 (SA)	 * 6 bytes A3 (BSSID)	 */	/* update the BEACON templates */	wlc_write_template_ram(wlc, (T_BCN0_TPL_BASE + 16), (T_RAM_ACCESS_SZ*2), template_buf);	wlc_write_template_ram(wlc, (T_BCN1_TPL_BASE + 16), (T_RAM_ACCESS_SZ*2), template_buf);}static voidwlc_clear_bssid(wlc_info_t *wlc){	W_REG(&wlc->regs->rcm_ctl, RCM_BSSID_OFFSET | RCM_INC_DATA);	W_REG(&wlc->regs->rcm_mat_data, 0);	W_REG(&wlc->regs->rcm_mat_data, 0);	W_REG(&wlc->regs->rcm_mat_data, 0);}/* Write BSSID address to core (set_bssid in d11procs.tcl). * Updates RXE match engine and tx template addr fields. */static voidwlc_set_bssid(wlc_info_t *wlc){	d11regs_t *regs;	char template_buf[(T_RAM_ACCESS_SZ*2)];	WL_TRACE(("wl%d: wlc_set_bssid\n", wlc->pub.unit));	regs = wlc->regs;	/* enter the BSSID addr into the RXE match registers */	wlc_set_addrmatch(wlc, RCM_BSSID_OFFSET, &wlc->BSSID);	/* The A3 (BSSID) MAC addr appears at bytes [22, 27] in the 802.11 frames	 * in the templates.	 * 6 bytes PLCP	 * 2 bytes FC	 * 2 bytes DUR/ID	 * 6 bytes A1	 * 6 bytes A2 (SA)	 * 6 bytes A3 (BSSID)	 */	/* fill out a buffer with a multiple of 4 length, starting at	 * a 4 byte boundary offset for wlc_write_template_ram, last 2	 * bytes of MAC addr and the all 6 bytes our beaconing BSSID	 */	bcopy((char*)wlc->pub.cur_etheraddr.octet + 4, template_buf, 2);	bcopy((char*)wlc->announce_BSSID.octet, template_buf + 2, ETHER_ADDR_LEN);	/* update the BEACON templates */	wlc_write_template_ram(wlc, (T_BCN0_TPL_BASE + 20), (T_RAM_ACCESS_SZ*2), template_buf);	wlc_write_template_ram(wlc, (T_BCN1_TPL_BASE + 20), (T_RAM_ACCESS_SZ*2), template_buf);}/* * Write a MAC address to the rcmta structure */voidwlc_set_rcmta(wlc_info_t *wlc, int idx, const struct ether_addr *addr){	d11regs_t *regs = wlc->regs;	volatile uint16* objdata16 = (uint16*)&regs->objdata;	uint32 mac_hm;	uint16 mac_l;	WL_TRACE(("wl%d: %s\n", wlc->pub.unit, __FUNCTION__));	ASSERT(wlc->pub.corerev > 4);	ASSERT((idx >= 0) && (idx < (WSEC_MAX_RCMTA_KEYS - WSEC_MAX_DEFAULT_KEYS)));	mac_hm = (addr->octet[3] << 24) | (addr->octet[2] << 16) | (addr->octet[1] << 8) |		addr->octet[0];	mac_l = (addr->octet[5] << 8) | addr->octet[4];	W_REG(&regs->objaddr, (OBJADDR_RCMTA_SEL | (idx * 2)));	W_REG(&regs->objdata, mac_hm);	W_REG(&regs->objaddr, (OBJADDR_RCMTA_SEL | ((idx * 2) + 1)));	W_REG(objdata16, mac_l);}/* * Write a MAC address to the given match reg offset in the RXE match engine. */voidwlc_set_addrmatch(wlc_info_t *wlc, int match_reg_offset, const struct ether_addr *addr){	d11regs_t *regs;	uint16 mac_l;	uint16 mac_m;	uint16 mac_h;	WL_TRACE(("wl%d: wlc_set_addrmatch\n", wlc->pub.unit));	ASSERT((match_reg_offset < RCM_WEP_TA0_OFFSET) || (wlc->pub.corerev < 5));	regs = wlc->regs;	mac_l = addr->octet[0] | (addr->octet[1] << 8);	mac_m = addr->octet[2] | (addr->octet[3] << 8);	mac_h = addr->octet[4] | (addr->octet[5] << 8);	/* enter the MAC addr into the RXE match registers */	W_REG(&regs->rcm_ctl, RCM_INC_DATA | match_reg_offset);	W_REG(&regs->rcm_mat_data, mac_l);	W_REG(&regs->rcm_mat_data, mac_m);	W_REG(&regs->rcm_mat_data, mac_h);}voidwlc_write_template_ram(wlc_info_t *wlc, int offset, int len, void *buf){	d11regs_t *regs;	uint32 word;	bool be_bit;	WL_TRACE(("wl%d: wlc_write_template_ram\n", wlc->pub.unit));	regs = wlc->regs;	ASSERT(ISALIGNED(offset, sizeof(uint32)));	ASSERT(ISALIGNED(len, sizeof(uint32)));	ASSERT((offset & ~0xffff) == 0);	W_REG(&regs->tplatewrptr, offset);	/* if MCTL_BIGEND bit set in mac control register,	 * the chip swaps data in fifo, as well as data in	 * template ram	 */	be_bit = (R_REG(&regs->maccontrol) & MCTL_BIGEND) != 0;	while (len > 0) {		bcopy((uint8*)buf, &word, sizeof(uint32));		if (be_bit)			word = hton32(word);		else			word = htol32(word);		W_REG(&regs->tplatewrdata, word);		buf = (uint8*)buf + sizeof(uint32);		len -= sizeof(uint32);	}}/* * Suspend the the MAC and update the slot timing * for standard 11b/g (20us slots) or shortslot 11g (9us slots). */static voidwlc_switch_shortslot(wlc_info_t *wlc, bool shortslot){	ASSERT(wlc->band->gmode);

⌨️ 快捷键说明

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