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

📄 wlc.c

📁 wi-fi sources for asus wl138g v2 pci card
💻 C
📖 第 1 页 / 共 5 页
字号:
	/* 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 */	wlc->pub.current_bss.capability &= ~DOT11_CAP_SHORTSLOT;	if (wlc->shortslot)		wlc->pub.current_bss.capability |= DOT11_CAP_SHORTSLOT;	wlc_suspend_mac_and_wait(wlc);	wlc_update_slot_timing(wlc, shortslot);	wlc_enable_mac(wlc);}/* * 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 voidwlc_update_slot_timing(wlc_info_t *wlc, bool shortslot){	d11regs_t *regs;	regs = wlc->regs;	if (shortslot) {		/* 11g short slot: 11a timing */		W_REG(&regs->ifs_slot, 0x0207);	/* APHY_SLOT_TIME */		wlc_write_shm(wlc, M_DOT11_SLOT, APHY_SLOT_TIME);	} else {		/* 11g long slot: 11b timing */		W_REG(&regs->ifs_slot, 0x0212);	/* BPHY_SLOT_TIME */		wlc_write_shm(wlc, M_DOT11_SLOT, BPHY_SLOT_TIME);	}}voidwlc_set_cwmin(wlc_info_t *wlc, uint16 newmin){	wlc->band->CWmin = newmin;	W_REG(&wlc->regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_CWMIN);	W_REG(&wlc->regs->objdata, newmin);}voidwlc_set_cwmax(wlc_info_t *wlc, uint16 newmax){	wlc->band->CWmax = newmax;	W_REG(&wlc->regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_CWMAX);	W_REG(&wlc->regs->objdata, newmax);}voidwlc_update_txpwr_shmem(wlc_pub_t *pub){	wlc_info_t *wlc = (wlc_info_t *)pub;	uint8	r;	bool	war = FALSE;	WL_TRACE(("wl%d: %s\n", pub->unit, __FUNCTION__));	if (wlc->core->clk) {		if (wlc->pub.associated)			r = wlc->pub.current_bss.rateset.rates[0];		else			r = wlc->default_bss.rateset.rates[0];		if (ISGPHY(wlc->band->pi) &&		    ((r != 0x82) && (r != 0x84) && (r != 0x8b) && (r != 0x96)))			war = TRUE;		wlc_phy_update_txpwr_shmem(wlc->band->pi, war);	}}static voidwlc_scan(	wlc_info_t *wlc,	int bss_type,	const struct ether_addr* bssid,	const uchar ssid[],	int ssid_len,	int scan_type,	int nprobes,	int active_time,	int passive_time,	int home_time,	const uint16* channel_list,	int channel_num,	bool save_prb,	cb_fn_t fn, void* arg){	bool scan_in_progress;	bool scan_timer_set;	int i;	ASSERT(ssid_len >= 0);	ASSERT(ssid_len <= DOT11_MAX_SSID_LEN);	ASSERT(bss_type == DOT11_BSSTYPE_INFRASTRUCTURE || bss_type == DOT11_BSSTYPE_INDEPENDENT ||		bss_type == DOT11_BSSTYPE_ANY);	WL_INFORM(("wl%d: %s: for SSID \"%s\"\n",		wlc->pub.unit, __FUNCTION__, (wlc_format_ssid(ssidbuf, ssid, ssid_len), ssidbuf)));	scan_in_progress = SCAN_IN_PROGRESS(wlc);	scan_timer_set = (scan_in_progress &&		0 == (wlc->scan.state & (SCAN_STATE_WSUSPEND | SCAN_STATE_PSPEND)));	/* clear or set optional params to default */	wlc->scan.state &= SCAN_STATE_SUPPRESS;	/* keep persistent scan suppress flag */	wlc->scan.nprobes = wlc->scan.defaults.nprobes;	if (wlc->pub.associated) {		wlc->scan.active_time = wlc->scan.defaults.assoc_time;		wlc->scan.home_time = wlc->scan.defaults.home_time;	} else {		wlc->scan.active_time = wlc->scan.defaults.unassoc_time;		wlc->scan.home_time = 0;	}	wlc->scan.passive_time = wlc->scan.defaults.passive_time;	if (wlc->scan.defaults.passive)		wlc->scan.state |= SCAN_STATE_PASSIVE;	wlc_scan_default_channels(wlc, wlc->scan.channel_list, &wlc->scan.channel_num);	/* set required and optional params */	/* If IBSS Lock Out feature is turned on, set the scan type to BSS only */	wlc->scan.bss_type = (wlc->ibss_allowed == FALSE)?DOT11_BSSTYPE_INFRASTRUCTURE:bss_type;	bcopy((char*)bssid, (char*)&wlc->scan.bssid, ETHER_ADDR_LEN);	wlc->scan.ssid_len = ssid_len;	bzero(wlc->scan.ssid, DOT11_MAX_SSID_LEN);	if (ssid_len > 0)		bcopy(ssid, wlc->scan.ssid, ssid_len);	if (scan_type == DOT11_SCANTYPE_ACTIVE) {		wlc->scan.state &= ~SCAN_STATE_PASSIVE;	} else if (scan_type == DOT11_SCANTYPE_PASSIVE) {		wlc->scan.state |= SCAN_STATE_PASSIVE;	}	/* passive scan always has nprobes to 1 */	if (wlc->scan.state & SCAN_STATE_PASSIVE) {		wlc->scan.nprobes = 1;	}	if (active_time > 0)		wlc->scan.active_time = (uint16)active_time;	if (passive_time > 0)		wlc->scan.passive_time = (uint16)passive_time;	if (home_time >= 0 && wlc->pub.associated)		wlc->scan.home_time = (uint16)home_time;	if (nprobes > 0 && (wlc->scan.state & SCAN_STATE_PASSIVE) == 0)		wlc->scan.nprobes = (uint8)nprobes;	if (save_prb)		wlc->scan.state |= SCAN_STATE_SAVE_PRB;	wlc->scan.cb = fn;	wlc->scan.cb_arg = arg;	WL_INFORM(("wl%d: %s: wlc_scan params: nprobes %d dwell active/passive %dms/%dms home %dms"		" flags %d\n",		wlc->pub.unit, __FUNCTION__, wlc->scan.nprobes, wlc->scan.active_time,		wlc->scan.passive_time,		wlc->scan.home_time, wlc->scan.state));	/* channel list validation */	if (channel_num > MAXCHANNEL) {		WL_ERROR(("wl%d: %s: wlc_scan bad param channel_num %d greater than max %d\n",			wlc->pub.unit, __FUNCTION__, channel_num, MAXCHANNEL));		channel_num = 0;	}	if (channel_num > 0 && channel_list == NULL) {		WL_ERROR(("wl%d: %s: wlc_scan bad param channel_list was NULL with channel_num ="			" %d\n",			wlc->pub.unit, __FUNCTION__, channel_num));		channel_num = 0;	}	for (i = 0; i < channel_num; i++) {		if (!VALID_CHANNEL_DB(wlc, channel_list[i] & WL_CHANSPEC_CHAN_MASK)) {			channel_num = 0;		}	}	if (channel_num > 0) {		for (i = 0; i < channel_num; i++)			wlc->scan.channel_list[i] = channel_list[i] & WL_CHANSPEC_CHAN_MASK;		wlc->scan.channel_num = channel_num;	}	if ((wlc->scan.state & SCAN_STATE_SUPPRESS) || (!wlc->scan.channel_num)) {		WL_INFORM(("wl%d: %s: scan.state %d scan.channel_num %d\n",			wlc->pub.unit, __FUNCTION__, wlc->scan.state, wlc->scan.channel_num));		if (scan_in_progress)			wlc_scan_abort(wlc);		/* no scan now, but free any earlier leftovers */		wlc_bss_list_free(wlc, &wlc->scan_results);		if (fn)			(fn)(arg);		return;	}	if (scan_in_progress && wlc->assoc_state == AS_IDLE)		wlc_mac_event(wlc, WLC_E_SCAN_COMPLETE, NULL, WLC_E_STATUS_ABORT, 0, 0, 0, 0);	/* start the scan with the results cleared */	wlc->scan.away_count = 0;	wlc->scan.away_limit = MAX(1, WLC_SCAN_AWAY_LIMIT / wlc->scan.active_time);	wlc->scan.channel_idx = 0;	wlc->scan.pass = WLC_SCAN_START;	/* ...and free any leftover responses from before */	wlc_bss_list_free(wlc, &wlc->scan_results);	/* keep core awake to receive solicited probe responses, SCAN_IN_PROGRESS is TRUE */	ASSERT(STAY_AWAKE(wlc));	wlc_set_ps_ctrl(wlc);	if (wlc->pub.associated) {		/* return to the current BSS channel if associated */		wlc->scan.channel_return = wlc->pub.current_bss.channel;	} else if (!scan_in_progress) {		/* not associated and no scan in progress, so just return to the current channel */		if (VALID_CHANNEL_DB(wlc, wlc->band->pi->radio_channel)) {			wlc->scan.channel_return = (uint8)wlc->band->pi->radio_channel;		} else {			wlc->scan.channel_return = wlc_next_channel(wlc,				(uint8)wlc->band->pi->radio_channel, CHAN_TYPE_ANY, 1);		}	}	/* else, we are interrupting a scan, but not associated, so use the original return channel	 */	if (!scan_timer_set) {		/* call wlc_scantimer to get the scan state machine going */		/* DUALBAND - Don't call wlc_scantimer() directly from DPC... */		wl_add_timer(wlc->wl, wlc->scan.timer, 0, 0);	}	/* if a scan is in progress, allow the next callback to restart the scan state machine */}static voidwlc_scan_abort(wlc_info_t *wlc){	if (!SCAN_IN_PROGRESS(wlc))		return;	/* abort the current scan, and return to home channel */	WL_INFORM(("wl%d: %s: aborting scan in progress\n", wlc->pub.unit, __FUNCTION__));	if (wlc->assoc_state == AS_IDLE)		wlc_mac_event(wlc, WLC_E_SCAN_COMPLETE, NULL, WLC_E_STATUS_ABORT, 0, 0, 0, 0);	wlc_bss_list_free(wlc, &wlc->scan_results);	/* Move to abort state for wlc_scantimer to clean up */	wlc->scan.pass = WLC_SCAN_ABORT;	/* Change the radio channel to the return channel */	if (wlc->band->pi->radio_channel != wlc->scan.channel_return) {		wlc_suspend_mac_and_wait(wlc);		wlc_set_channel(wlc, wlc->scan.channel_return);		wlc_enable_mac(wlc);	}	/* un-block PSPoll operations and restore PS state */	if (wlc->PMblocked) {		wlc->PMblocked = FALSE;		/* come out of PS mode if appropriate */		if (wlc->PM != PM_MAX || wlc->WME_PM_blocked)			wlc_set_pmstate(wlc, FALSE);	}	/* Clear the tssi values since we may have collected	 * info from other channels during the scan	 */	wlc_clear_tssi(wlc->band->pi);	/* un-suspend the data fifos now that we are back on the home channel */	wlc_tx_resume(wlc);	wlc->block_datafifo &= ~DATA_BLOCK_SCAN;	/* enable CFP update */	wlc_mhf(wlc, MHF_SKIP_CFP_UPDATE, 0, TRUE);	/* check for states that indicate the scan timer is not scheduled */	if (wlc->scan.state & (SCAN_STATE_WSUSPEND | SCAN_STATE_PSPEND)) {		/* wlc_scantimer would have been scheduled by either a tx fifo		 * suspend or PS indication, both of which we are canceling.		 * Call wlc_scantimer directly to abort.		 */		wlc->scan.state &= ~(SCAN_STATE_WSUSPEND | SCAN_STATE_PSPEND);		wlc_scantimer(wlc);	}}static voidwlc_scantimer(void *arg){	wlc_info_t *wlc = (wlc_info_t*)arg;	uint channel;	int next_channel;	int8 passes;	if (!wlc->pub.up)		return;	if (DEVICEREMOVED(wlc)) {		WL_ERROR(("wl%d: %s: dead chip\n", wlc->pub.unit, __FUNCTION__));		wl_down(wlc->wl);		return;	}	if (wlc->scan.pass == WLC_SCAN_ABORT) {		WL_ASSOC(("SCAN: wlc_scantimer: aborted scan for SSID \"%s\"\n", ssidbuf));		wlc->scan.channel_idx = -1;		wlc_set_ps_ctrl(wlc);		return;	}	/* check if we are still waiting on an event to continue */	if (wlc->scan.state & SCAN_STATE_SUSPEND_REQ) {		wlc->scan.state &= ~SCAN_STATE_SUSPEND_REQ;		if (!wlc_tx_suspended(wlc)) {			wlc_tx_suspend(wlc);			wlc->scan.state |= SCAN_STATE_WSUSPEND;			return;		}	}	/* still waiting for tx data fifo suspended indication */	if (wlc->scan.state & SCAN_STATE_WSUSPEND)		return;	wlc->scan.pass++;	channel = wlc->scan.channel_list[wlc->scan.channel_idx];	passes = QUIET_CHANNEL(wlc, channel) ? 1 : wlc->scan.nprobes;	if (wlc->scan.pass > passes) {		if (wlc->scan.pass == passes + 1) {			/* scan passes complete for the current channel */			WL_INFORM(("wl%d: %s: %sscanned channel %d, %d total responses for SSID"				" \"%s\"\n",				wlc->pub.unit, __FUNCTION__,				((QUIET_CHANNEL(wlc, channel) && !(wlc->scan.state &				SCAN_STATE_RADAR_CLEAR)) ? "passively ":""),				channel, wlc->scan_results.count, ssidbuf));			/* reset the radar clear flag since we will be leaving the channel */			wlc->scan.state &= ~SCAN_STATE_RADAR_CLEAR;		}		if (wlc->scan.channel_idx < wlc->scan.channel_num - 1)			next_channel = wlc->scan.channel_list[wlc->scan.channel_idx + 1];		else			next_channel = -1;		/* keep track of the number of channels scanned since the last		 * time we returned to the home channel		 */		if (wlc->band->pi->radio_channel != wlc->scan.channel_return)			wlc->scan.away_count++;		else			wlc->scan.away_count = 0;		/* If the home_time is non-zero,		 * and there are more channels to scan,		 * and we reached the away channel limit or the channel		 *	we just scanned or are about to scan is a passive scan channel,		 * return to the home channel before scanning the next channel		 */		if (wlc->scan.pass == (passes + 1) &&		    wlc->scan.home_time > 0 &&		    next_channel != -1 &&		    (wlc->scan.away_count >= wlc->scan.away_limit ||		     QUIET_CHANNEL(wlc, channel) || QUIET_CHANNEL(wlc, next_channel))) {			/* Change the radio channel to associated BSS */			wlc_suspend_mac_and_wait(wlc);			wlc_set_channel(wlc, wlc->scan.channel_return);			if (!wlc->pub.BSS)				wlc_ibss_resume(wlc);			/* Restore promisc behavior for beacons and probes */			wlc->bcnmisc_scan = FALSE;			wlc_mac_bcn_promisc(wlc);			wlc_enable_mac(wlc);			/* Clear the tssi values */			wlc_clear_tssi(wlc->band->pi);			/* un-block PSPoll operations and restore PS state */			if (wlc->PMblocked) {				wlc->PMblocked = FALSE;				/* come out of PS mode if appropriate */				if (wlc->PM != PM_MAX || wlc->WME_PM_blocked)					wlc_set_pmstate(wlc, FALSE);			}			/* un-suspend the DATA fifo now that we are back on the home channel */			wlc_tx_resume(wlc);			/* re-enable txq processing now that we are back on the home channel */			wlc->block_datafifo &= ~DATA_BLOCK_SCAN;			/* enable CFP update */			wlc_mhf(wlc, MHF_SKIP_CFP_UPDATE, 0, TRUE);			/* Allow normal traffic before next channel scan */			wl_add_timer(wlc->wl, wlc->scan.timer, wlc->scan.home_time, 0);			/* wlc_scantimer called back when wlc->scan.timer fires */			return;		}

⌨️ 快捷键说明

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