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

📄 wlc_scb.c

📁 wi-fi sources for asus wl138g v2 pci card
💻 C
📖 第 1 页 / 共 2 页
字号:
	WL_ASSOC(("wlc_scb : state = %x\n", scb->state));}/* * "& ~" operation . * idx = position of the bsscfg in the wlc array of multi ssids. */voidwlc_scb_clearstatebit_bsscfg(struct scb *scb, uint8 state, int idx){	int i;	ASSERT(scb);	WL_ASSOC(("clear state : %x   bsscfg idx : %d\n", state, idx));	/*	   any clear of a stable state should lead to clear a bit	   Warning though : this implies that, if we want to switch from	   associated to authenticated, the clear happens before the set	   otherwise this bit will be clear in authenticated state.	*/	if ((state & AUTHENTICATED) || (state & ASSOCIATED) || (state & AUTHORIZED))	{		clrbit(&scb->auth_bsscfg, idx);	}	/* quik hack .. clear first ... */	scb->state &= ~state;	for (i = 0; i < SCB_BSSCFG_BITSIZE; i++)	{		/* reset if needed */		if (scb->auth_bsscfg[i])		{			scb->state |= state;			break;		}	}}/* reset all state. */voidwlc_scb_resetstate(struct scb *scb){	WL_ASSOC(("reset state\n"));	ASSERT(scb);	memset(&scb->auth_bsscfg, 0, SCB_BSSCFG_BITSIZE);	scb->state = 0;	WL_ASSOC(("wlc_scb : state = %x\n", scb->state));}/* initialize per-scb state utilized by rate selection */voidwlc_scb_rate_init(wlc_info_t *wlc, struct scb *scb){	wlc_rate_init(scb->ratestate, scb->rateset.rates, scb->rateset.count,		scb->select_rateset.rates, &scb->select_rateset.count,		0, &scb->txc.txhlen);}voidwlc_scb_reinit(wlc_info_t *wlc){	uint prev_count;	const rateset_t *rs;	wlcband_t *band;	struct scb *scb;	struct scb_iter scbiter;	/* sanitize any existing scb rates against the current hardware rates */	FOREACHSCB(&scbiter, wlc->scbstate->scb, scb) {		prev_count = scb->rateset.count;		/* Keep only CCK if gmode == GMODE_LEGACY_B */		band = ((struct scb_info*)scb)->band;		if (ISGPHY(band->pi) && (band->gmode == GMODE_LEGACY_B)) {			rs = cck_rates;		} else {			rs = &band->hw_rateset;		}		wlc_sort_rates(&scb->rateset, rs);		/* if the count of rates is different, then the rate state		 * needs to be reinitialized		 */		if (scb->rateset.count != prev_count)			wlc_scb_rate_init(wlc, scb);	}}static INLINE struct scb*_wlc_scbfind(wlc_info_t *wlc, const struct ether_addr *ea, int bandunit){	int index;	struct scb_info *scbinfo;	/* map any multicast address into the single broadcast scb */	if (ETHER_ISMULTI(ea))		ea = &ether_bcast;	index = SCBHASHINDEX(ea->octet);	/* search for the scb which corresponds to the remote station ea */	scbinfo = (struct scb_info *)(SCBSTATE_PRIV(wlc->scbstate)->scbhash[bandunit][index]);	for (; scbinfo; scbinfo = scbinfo->hashnext) {		if (bcmp((char*)ea, (char*)&(scbinfo->scbpub.ea), ETHER_ADDR_LEN) == 0)			break;	}	return (struct scb *)scbinfo;}/* Find station control block corresponding to the remote id */struct scb *wlc_scbfind(wlc_info_t *wlc, const struct ether_addr *ea){	return _wlc_scbfind(wlc, ea, wlc->band->bandunit);}/* * Lookup station control block corresponding to the remote id. * If not found, create a new entry. */static INLINE struct scb *_wlc_scblookup(wlc_info_t *wlc, const struct ether_addr *ea, int bandunit){	int index;	struct scb *scb;	scb_module_priv_t *scbstate;	if ((scb = _wlc_scbfind(wlc, ea, bandunit))) {		return (scb);	}	/* no scb match, allocate one */	if (!(scb = wlc_scballoc(wlc))) {		WL_ERROR(("wl%d: wlc_scblookup: out of memory, malloced %d bytes\n",		          wlc->pub.unit, MALLOCED(wlc->pub.osh)));		return (NULL);	}	/* map any multicast address into the single broadcast scb */	if (ETHER_ISMULTI(ea))		ea = &ether_bcast;	scb->ea = *((struct ether_addr*)ea);	/* install it in the cache */	scbstate = SCBSTATE_PRIV(wlc->scbstate);	scb->bandunit = bandunit;	index = SCBHASHINDEX(ea->octet);	((struct scb_info *)scb)->hashnext =		(struct scb_info *)scbstate->scbhash[bandunit][index];	scbstate->scbhash[bandunit][index] = scb;	/* send ofdm rate probe */	if (!wlc->pub.BSS && wlc->band->gmode && wlc->pub.up)		wlc_rateprobe(wlc, (struct ether_addr*)ea, scb, WLC_RATEPROBE_RATE);	return (scb);}struct scb *wlc_scblookup(wlc_info_t *wlc, const struct ether_addr *ea){	return (_wlc_scblookup(wlc, ea, wlc->band->bandunit));}struct scb *wlc_scblookupband(wlc_info_t *wlc, const struct ether_addr *ea, int bandunit){	/* assert that the band is the current band, or we are dual band and it is the other band */	ASSERT((bandunit == (int)wlc->band->bandunit) ||	       (NBANDS(wlc) > 1 && bandunit == (int)OTHERBANDUNIT(wlc)));	return (_wlc_scblookup(wlc, ea, bandunit));}/* Get scb from band */struct scb *wlc_scbfindband(wlc_info_t *wlc, const struct ether_addr *ea, int bandunit){	/* assert that the band is the current band, or we are dual band and it is the other band */	ASSERT((bandunit == (int)wlc->band->bandunit) ||	       (NBANDS(wlc) > 1 && bandunit == (int)OTHERBANDUNIT(wlc)));	return (_wlc_scbfind(wlc, ea, bandunit));}static voidwlc_scb_deauth_sendcomplete(wlc_info_t *wlc, uint txstatus, void *ea_arg){	struct scb *scb;	/* Is this scb still around */	if ((scb = wlc_scbfind(wlc, (struct ether_addr*)ea_arg)) == NULL)	    return;	/* As long as it made it, complete the state transition */	wlc_scb_resetstate(scb);	/* delete pairwise key on deauthentication */	if (scb->key) {		WL_WSEC(("wl%d: %s: deauthenticating sta, deleting pairwise"		         " key for %s\n",		         wlc->pub.unit, __FUNCTION__,		         bcm_ether_ntoa(&scb->ea, eabuf)));		wlc_scb_key_delete(wlc, scb);	}}/* (de)authorize/(de)authenticate single station * 'enable' TRUE means authorize, FLASE means deauthorize/deauthenticate * 'flag' is AUTHORIZED or AUTHENICATED for the type of operation * 'rc' is the reason code for a deauthenticate packet */voidwlc_scb_set_auth(wlc_info_t *wlc, struct scb *scb, bool enable, uint32 flag, int rc){	void *pkt = NULL;	if (enable) {		if (flag == AUTHORIZED) {			wlc_scb_setstatebit(scb, AUTHORIZED);			scb->flags &= ~SCB_DEAUTH;		} else {			wlc_scb_setstatebit(scb, AUTHENTICATED);		}	} else {		if (flag == AUTHORIZED) {			wlc_scb_clearstatebit(scb, AUTHORIZED);		} else {			if (wlc->pub.up && (SCB_AUTHENTICATED(scb))) {				struct ether_addr *bssid;				bssid = (scb->flags & SCB_MYAP) ? &wlc->BSSID :					&wlc->announce_BSSID;				pkt = wlc_senddeauth(wlc, &scb->ea, bssid, scb, (uint16)rc);			}			if (pkt == NULL ||			    wlc_pkt_callback_register(wlc, wlc_scb_deauth_sendcomplete,			                              (void *)&scb->ea, pkt))				WL_ERROR(("wl%d: wlc_scb_set_auth: could not register callback\n",				          wlc->pub.unit));		}	}	WL_ASSOC(("wl%d: %s %s%s\n", wlc->pub.unit,		bcm_ether_ntoa(&scb->ea, eabuf),		(enable ? "" : "de"),		((flag == AUTHORIZED) ? "authorized" : "authenticated")));}voidwlc_scb_sortrates(struct scb *scb){	struct scb_info *scbinfo = (struct scb_info *)scb;	wlc_sort_rates(&scb->rateset, &scbinfo->band->hw_rateset);}voidBCMINITFN(wlc_scblist_validaterates)(wlc_info_t *wlc){	struct scb *scb;	struct scb_iter scbiter;	FOREACHSCB(&scbiter, wlc->scbstate->scb, scb) {		wlc_scb_sortrates(scb);		if (scb->rateset.count == 0) {			wlc_scbfree(wlc, scb);		}	}}/* Give then tx_fn, return the feature id from txmod_fns array. * If tx_fn is NULL, 0 will be returned * If entry is not found, it's an ERROR! */static INLINE scb_txmod_twlc_txmod_fid(wlc_info_t *wlc, txmod_tx_fn_t tx_fn){	scb_txmod_t txmod;	for (txmod = SCB_START; txmod < SCB_LAST; txmod++)		if (tx_fn == wlc->txmod_fns[txmod].tx_fn)			return txmod;	/* Should not reach here */	ASSERT(txmod < SCB_LAST);	return txmod;}/* Add a feature to the path. It should not be already on the path and should be configured * Does not take care of evicting anybody */static voidwlc_txmod_activate(wlc_info_t *wlc, struct scb *scb, scb_txmod_t fid){	/* Numeric value designating this feature's position in tx_path */	static const uint txmod_position[SCB_LAST] = {		0, /* SCB_START */		1, /* SCB_CRAM */		1, /* SCB_APPS */		1, /* SCB_AMSDU */		2, /* SCB_BA */		2, /* SCB_AMPDU */		3, /* SCB_TRANSMIT */	};	uint curr_mod_position;	scb_txmod_t prev, next;	txmod_info_t curr_mod_info = wlc->txmod_fns[fid];	ASSERT(SCB_TXMOD_CONFIGURED(scb, fid) &&	       !SCB_TXMOD_ACTIVE(scb, fid));	curr_mod_position = txmod_position[fid];	prev = SCB_START;	while ((next = wlc_txmod_fid(wlc, scb->tx_path[prev].next_tx_fn)) != 0 &&	       txmod_position[next] < curr_mod_position)		prev = next;	/* next == 0 indicate this is the first addition to the path	 * it HAS to be SCB_TRANSMIT as it's the one that puts the packet in	 * txq. If this changes, then assert will need to be removed.	 */	ASSERT(next != 0 || fid == SCB_TRANSMIT);	ASSERT(txmod_position[next] != curr_mod_position);	SCB_TXMOD_SET(scb, prev, fid);	SCB_TXMOD_SET(scb, fid, next);	/* invoke any activate notify functions now that it's in the path */	if (curr_mod_info.activate_notify_fn)		curr_mod_info.activate_notify_fn(curr_mod_info.ctx, scb);}/* Remove a fid from the path. It should be already on the path * Does not take care of replacing it with any other feature. */static voidwlc_txmod_deactivate(wlc_info_t *wlc, struct scb *scb, scb_txmod_t fid){	scb_txmod_t prev, next;	txmod_info_t curr_mod_info = wlc->txmod_fns[fid];	/* If not active, do nothing */	if (!SCB_TXMOD_ACTIVE(scb, fid))		return;	/* if deactivate notify function is present, call it */	if (curr_mod_info.deactivate_notify_fn)		curr_mod_info.deactivate_notify_fn(curr_mod_info.ctx, scb);	prev = SCB_START;	while ((next = wlc_txmod_fid(wlc, scb->tx_path[prev].next_tx_fn))	       != fid)		prev = next;	SCB_TXMOD_SET(scb, prev, wlc_txmod_fid(wlc, scb->tx_path[fid].next_tx_fn));	scb->tx_path[fid].next_tx_fn = NULL;}/* Add the fid to handle packets for this SCB, if allowed */voidwlc_txmod_config(wlc_info_t *wlc, struct scb *scb, scb_txmod_t fid){	ASSERT(fid < SCB_LAST);	/* Don't do anything if not yet registered or	 * already configured	 */	if ((wlc->txmod_fns[fid].tx_fn == NULL) ||	    (SCB_TXMOD_CONFIGURED(scb, fid)))		return;	/* Indicate that the feature is configured */	scb->tx_path[fid].configured = TRUE;	ASSERT(!SCB_TXMOD_ACTIVE(scb, fid));	/* Try to activate this feature by adding it to the path	 * If conflicting features exist in the path, then	 *     - If this feature is of higher precedence, deactivate other features	 *     - Else, mark this feature deactivated	 * Note: When evicting other features, they remain 'configured'	 */	switch (fid) {	case SCB_APPS:		/* Deactivate CRAM/AMSDU/BA/AMPDU */		wlc_txmod_deactivate(wlc, scb, SCB_CRAM);		wlc_txmod_deactivate(wlc, scb, SCB_AMSDU);		wlc_txmod_deactivate(wlc, scb, SCB_BA);		wlc_txmod_deactivate(wlc, scb, SCB_AMPDU);		break;	case SCB_CRAM:		/* Don't activate if AMSDU or APPS are active */		if (SCB_TXMOD_ACTIVE(scb, SCB_AMSDU) ||		    SCB_TXMOD_ACTIVE(scb, SCB_APPS))			return;		break;	case SCB_AMSDU:		/* Don't activate if APPS is active */		if (SCB_TXMOD_ACTIVE(scb, SCB_APPS))			return;		/* Deactivate CRAM if on path */		wlc_txmod_deactivate(wlc, scb, SCB_CRAM);		break;	case SCB_BA:		/* Don't activate if AMPDU is active */		if (SCB_TXMOD_ACTIVE(scb, SCB_AMPDU))			return;		/* Don't activate if APPS is active */		if (SCB_TXMOD_ACTIVE(scb, SCB_APPS))			return;		break;	case SCB_AMPDU:		/* Don't activate if APPS is active */		if (SCB_TXMOD_ACTIVE(scb, SCB_APPS))			return;		/* Deactivate BA if on path */		wlc_txmod_deactivate(wlc, scb, SCB_BA);		break;	case SCB_TRANSMIT:		break;	case SCB_START:	case SCB_LAST:		ASSERT(0);	};	wlc_txmod_activate(wlc, scb, fid);}/* Remove the feature to handle packets for this SCB. * If just configured but not in path, just marked unconfigured * If in path, feature is removed and, if applicable, replaced by any other feature */voidwlc_txmod_unconfig(wlc_info_t *wlc, struct scb *scb, scb_txmod_t fid){	ASSERT(fid < SCB_LAST && fid != SCB_TRANSMIT);	if (!SCB_TXMOD_CONFIGURED(scb, fid))		return;	scb->tx_path[fid].configured = FALSE;	/* Nothing to do if not active */	if (!SCB_TXMOD_ACTIVE(scb, fid))		return;	wlc_txmod_deactivate(wlc, scb, fid);	/* Restore any other features to the path */	/* APPS unconfigured  => CRAM/AMSDU/BA can be active	 * AMSDU unconfigured => CRAM can be active	 */	switch (fid) {	case SCB_APPS:		/* Activate AMSDU/BA/CRAM if configured		 * Order below helps reduce redundant operations		 * if both CRAM/AMSDU are configured		 */		if (SCB_TXMOD_CONFIGURED(scb, SCB_AMSDU))			wlc_txmod_activate(wlc, scb, SCB_AMSDU);		else if (SCB_TXMOD_CONFIGURED(scb, SCB_CRAM))			wlc_txmod_activate(wlc, scb, SCB_CRAM);		if (SCB_TXMOD_CONFIGURED(scb, SCB_BA))			wlc_txmod_activate(wlc, scb, SCB_BA);		if (SCB_TXMOD_CONFIGURED(scb, SCB_AMPDU))			wlc_txmod_activate(wlc, scb, SCB_AMPDU);		break;	case SCB_AMSDU:		/* Activate CRAM if configured and APPS is not active */		if (SCB_TXMOD_CONFIGURED(scb, SCB_CRAM) &&		    !SCB_TXMOD_ACTIVE(scb, SCB_APPS))			wlc_txmod_activate(wlc, scb, SCB_CRAM);		break;	case SCB_CRAM:	case SCB_BA:	case SCB_AMPDU:	case SCB_TRANSMIT:	case SCB_START:	case SCB_LAST:		break;	}}

⌨️ 快捷键说明

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