Esempio n. 1
0
/*
 * Reset the rate control state for each 802.11 state transition.
 */
static void
ath_rate_newstate(struct ieee80211vap *vap, enum ieee80211_state state)
{
	struct ieee80211com *ic = vap->iv_ic;
	struct ath_softc *sc = ic->ic_dev->priv;
	struct ieee80211_node *ni;

	if (state == IEEE80211_S_INIT)
		return;
	if (vap->iv_opmode == IEEE80211_M_STA) {
		/*
		 * Reset local xmit state; this is really only
		 * meaningful when operating in station mode.
		 */
		ni = vap->iv_bss;
		if (state == IEEE80211_S_RUN) {
			ath_rate_ctl_start(sc, ni);
		} else {
			ath_rate_update(sc, ni, 0);
		}
	} else {
		/*
		 * When operating as a station the node table holds
		 * the AP's that were discovered during scanning.
		 * For any other operating mode we want to reset the
		 * tx rate state of each node.
		 */
		ieee80211_iterate_nodes(&ic->ic_sta, ath_rate_cb, NULL);
		ath_rate_update(sc, vap->iv_bss, 0);
	}
}
/*
 * Reset the rate control state for each 802.11 state transition.
 */
void
ath_rate_newstate(struct ath_softc *sc, enum ieee80211_state state)
{
	struct ieee80211com *ic = &sc->sc_ic;

	if (state == IEEE80211_S_RUN) {
		if (ic->ic_opmode != IEEE80211_M_STA) {
			/*
			 * Sync rates for associated stations and neighbors.
			 */
			ieee80211_iterate_nodes(&ic->ic_sta, rate_cb, sc);
		}
		ath_rate_newassoc(sc, ATH_NODE(ic->ic_bss), 1);
	}
}
Esempio n. 3
0
/*
 * Reset the rate control state for each 802.11 state transition.
 */
void
ath_rate_newstate(struct ath_softc *sc, enum ieee80211_state state)
{
	struct onoe_softc *osc = (struct onoe_softc *) sc->sc_rc;
	struct ieee80211com *ic = &sc->sc_ic;
	struct ieee80211_node *ni;

	if (state == IEEE80211_S_INIT) {
		callout_stop(&osc->timer);
		return;
	}
	if (ic->ic_opmode == IEEE80211_M_STA) {
		/*
		 * Reset local xmit state; this is really only
		 * meaningful when operating in station mode.
		 */
		ni = ic->ic_bss;
		if (state == IEEE80211_S_RUN) {
			ath_rate_ctl_start(sc, ni);
		} else {
			ath_rate_update(sc, ni, 0);
		}
	} else {
		/*
		 * When operating as a station the node table holds
		 * the AP's that were discovered during scanning.
		 * For any other operating mode we want to reset the
		 * tx rate state of each node.
		 */
		ieee80211_iterate_nodes(&ic->ic_sta, ath_rate_cb, sc);
		ath_rate_update(sc, ic->ic_bss, 0);
	}
	if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE &&
	    state == IEEE80211_S_RUN) {
		int interval;
		/*
		 * Start the background rate control thread if we
		 * are not configured to use a fixed xmit rate.
		 */
		interval = ath_rateinterval;
		if (ic->ic_opmode == IEEE80211_M_STA)
			interval /= 2;
		callout_reset(&osc->timer, (interval * hz) / 1000,
			ath_ratectl, &sc->sc_if);
	}
}
Esempio n. 4
0
static void
ath_ratectl(void *arg)
{
	struct ifnet *ifp = arg;
	struct ath_softc *sc = ifp->if_softc;
	struct onoe_softc *osc = (struct onoe_softc *) sc->sc_rc;
	struct ieee80211com *ic = &sc->sc_ic;
	int interval;

	if (ifp->if_flags & IFF_RUNNING) {
		sc->sc_stats.ast_rate_calls++;

		if (ic->ic_opmode == IEEE80211_M_STA)
			ath_rate_ctl(sc, ic->ic_bss);	/* NB: no reference */
		else
			ieee80211_iterate_nodes(&ic->ic_sta, ath_rate_ctl, sc);
	}
	interval = ath_rateinterval;
	if (ic->ic_opmode == IEEE80211_M_STA)
		interval /= 2;
	callout_reset(&osc->timer, (interval * hz) / 1000,
		ath_ratectl, &sc->sc_if);
}
Esempio n. 5
0
static void
ath_ratectl(unsigned long data)
{
	struct net_device *dev = (struct net_device *)data;
	struct ath_softc *sc = dev->priv;
	struct amrr_softc *asc = (struct amrr_softc *) sc->sc_rc;
	struct ieee80211com *ic = &sc->sc_ic;
	int interval;

	if (dev->flags & IFF_RUNNING) {
		sc->sc_stats.ast_rate_calls++;

		if (ic->ic_opmode == IEEE80211_M_STA)
			ath_rate_ctl(sc, ic->ic_bss);	/* NB: no reference */
		else
			ieee80211_iterate_nodes(ic, ath_rate_ctl, sc);
	}
	interval = ath_rateinterval;
	if (ic->ic_opmode == IEEE80211_M_STA)
		interval /= 2;
	asc->timer.expires = jiffies + ((HZ * interval) / 1000);
	add_timer(&asc->timer);
}
Esempio n. 6
0
/*
 * TDMA state machine handler.
 */
static int
tdma_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
	struct ieee80211_tdma_state *ts = vap->iv_tdma;
	struct ieee80211com *ic = vap->iv_ic;
	enum ieee80211_state ostate;
	int status;

	IEEE80211_LOCK_ASSERT(ic);

	ostate = vap->iv_state;
	IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, "%s: %s -> %s (%d)\n",
	    __func__, ieee80211_state_name[ostate],
	    ieee80211_state_name[nstate], arg);

	if (vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS)
		callout_stop(&vap->iv_swbmiss);
	if (nstate == IEEE80211_S_SCAN &&
	    (ostate == IEEE80211_S_INIT || ostate == IEEE80211_S_RUN) &&
	    ts->tdma_slot != 0) {
		/*
		 * Override adhoc behaviour when operating as a slave;
		 * we need to scan even if the channel is locked.
		 */
		vap->iv_state = nstate;			/* state transition */
		ieee80211_cancel_scan(vap);		/* background scan */
		if (ostate == IEEE80211_S_RUN) {
			/* purge station table; entries are stale */
			ieee80211_iterate_nodes(&ic->ic_sta, sta_leave, vap);
		}
		if (vap->iv_flags_ext & IEEE80211_FEXT_SCANREQ) {
			ieee80211_check_scan(vap,
			    vap->iv_scanreq_flags,
			    vap->iv_scanreq_duration,
			    vap->iv_scanreq_mindwell,
			    vap->iv_scanreq_maxdwell,
			    vap->iv_scanreq_nssid, vap->iv_scanreq_ssid);
			vap->iv_flags_ext &= ~IEEE80211_FEXT_SCANREQ;
		} else
			ieee80211_check_scan_current(vap);
		status = 0;
	} else {
		status = ts->tdma_newstate(vap, nstate, arg);
	}
	if (status == 0 && 
	    nstate == IEEE80211_S_RUN && ostate != IEEE80211_S_RUN &&
	    (vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS) &&
	    ts->tdma_slot != 0 &&
	    vap->iv_des_chan == IEEE80211_CHAN_ANYC) {
		/*
		 * Start s/w beacon miss timer for slave devices w/o
		 * hardware support.  Note we do this only if we're
		 * not locked to a channel (i.e. roam to follow the
		 * master). The 2x is a fudge for our doing this in
		 * software.
		 */
		vap->iv_swbmiss_period = IEEE80211_TU_TO_TICKS(
		    2 * vap->iv_bmissthreshold * ts->tdma_bintval *
		    ((ts->tdma_slotcnt * ts->tdma_slotlen) / 1024));
		vap->iv_swbmiss_count = 0;
		callout_reset(&vap->iv_swbmiss, vap->iv_swbmiss_period,
			ieee80211_swbmiss, vap);
	}
	return status;
}
Esempio n. 7
0
/*
 * IEEE80211_M_IBSS+IEEE80211_M_AHDEMO vap state machine handler.
 */
static int
adhoc_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
	struct ieee80211com *ic = vap->iv_ic;
	struct ieee80211_node *ni;
	enum ieee80211_state ostate;

	IEEE80211_LOCK_ASSERT(vap->iv_ic);

	ostate = vap->iv_state;
	IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, "%s: %s -> %s (%d)\n",
	    __func__, ieee80211_state_name[ostate],
	    ieee80211_state_name[nstate], arg);
	vap->iv_state = nstate;			/* state transition */
	if (ostate != IEEE80211_S_SCAN)
		ieee80211_cancel_scan(vap);	/* background scan */
	ni = vap->iv_bss;			/* NB: no reference held */
	switch (nstate) {
	case IEEE80211_S_INIT:
		switch (ostate) {
		case IEEE80211_S_SCAN:
			ieee80211_cancel_scan(vap);
			break;
		default:
			break;
		}
		if (ostate != IEEE80211_S_INIT) {
			/* NB: optimize INIT -> INIT case */
			ieee80211_reset_bss(vap);
		}
		break;
	case IEEE80211_S_SCAN:
		switch (ostate) {
		case IEEE80211_S_RUN:		/* beacon miss */
			/* purge station table; entries are stale */
			ieee80211_iterate_nodes(&ic->ic_sta, sta_leave, vap);
			/* fall thru... */
		case IEEE80211_S_INIT:
			if (vap->iv_des_chan != IEEE80211_CHAN_ANYC &&
			    !IEEE80211_IS_CHAN_RADAR(vap->iv_des_chan)) {
				/*
				 * Already have a channel; bypass the
				 * scan and startup immediately.
				 */
				ieee80211_create_ibss(vap,
				    ieee80211_ht_adjust_channel(ic,
				    vap->iv_des_chan, vap->iv_flags_ht));
				break;
			}
			/*
			 * Initiate a scan.  We can come here as a result
			 * of an IEEE80211_IOC_SCAN_REQ too in which case
			 * the vap will be marked with IEEE80211_FEXT_SCANREQ
			 * and the scan request parameters will be present
			 * in iv_scanreq.  Otherwise we do the default.
			 */
			if (vap->iv_flags_ext & IEEE80211_FEXT_SCANREQ) {
				ieee80211_check_scan(vap,
				    vap->iv_scanreq_flags,
				    vap->iv_scanreq_duration,
				    vap->iv_scanreq_mindwell,
				    vap->iv_scanreq_maxdwell,
				    vap->iv_scanreq_nssid, vap->iv_scanreq_ssid);
				vap->iv_flags_ext &= ~IEEE80211_FEXT_SCANREQ;
			} else
				ieee80211_check_scan_current(vap);
			break;
		case IEEE80211_S_SCAN:
			/*
			 * This can happen because of a change in state
			 * that requires a reset.  Trigger a new scan
			 * unless we're in manual roaming mode in which
			 * case an application must issue an explicit request.
			 */
			if (vap->iv_roaming == IEEE80211_ROAMING_AUTO)
				ieee80211_check_scan_current(vap);
			break;
		default:
			goto invalid;
		}
		break;
	case IEEE80211_S_RUN:
		if (vap->iv_flags & IEEE80211_F_WPA) {
			/* XXX validate prerequisites */
		}
		switch (ostate) {
		case IEEE80211_S_SCAN:
#ifdef IEEE80211_DEBUG
			if (ieee80211_msg_debug(vap)) {
				ieee80211_note(vap,
				    "synchronized with %s ssid ",
				    ether_sprintf(ni->ni_bssid));
				ieee80211_print_essid(vap->iv_bss->ni_essid,
				    ni->ni_esslen);
				/* XXX MCS/HT */
				printf(" channel %d start %uMb\n",
				    ieee80211_chan2ieee(ic, ic->ic_curchan),
				    IEEE80211_RATE2MBS(ni->ni_txrate));
			}
#endif
			break;
		case IEEE80211_S_RUN:	/* IBSS merge */
			break;
		default:
			goto invalid;
		}
		/*
		 * When 802.1x is not in use mark the port authorized
		 * at this point so traffic can flow.
		 */
		if (ni->ni_authmode != IEEE80211_AUTH_8021X)
			ieee80211_node_authorize(ni);
		/*
		 * Fake association when joining an existing bss.
		 */
		if (!IEEE80211_ADDR_EQ(ni->ni_macaddr, vap->iv_myaddr) &&
		    ic->ic_newassoc != NULL)
			ic->ic_newassoc(ni, ostate != IEEE80211_S_RUN);
		break;
	case IEEE80211_S_SLEEP:
		vap->iv_sta_ps(vap, 0);
		break;
	default:
	invalid:
		IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE,
		    "%s: unexpected state transition %s -> %s\n", __func__,
		    ieee80211_state_name[ostate], ieee80211_state_name[nstate]);
		break;
	}
	return 0;
}