Ejemplo n.º 1
0
/*
 * Timer check on whether the VAP has had any transmit activity.
 *
 * This may schedule a transition from _RUN -> _SLEEP if it's appropriate.
 */
void
ieee80211_sta_ps_timer_check(struct ieee80211vap *vap)
{
	struct ieee80211com *ic = vap->iv_ic;

	/* XXX lock assert */

	/* For no, only do this in STA mode */
	if (! (vap->iv_caps & IEEE80211_C_SWSLEEP))
		goto out;

	if (vap->iv_opmode != IEEE80211_M_STA)
		goto out;

	/* If we're not at run state, bail */
	if (vap->iv_state != IEEE80211_S_RUN)
		goto out;

	IEEE80211_DPRINTF(vap, IEEE80211_MSG_POWER,
	    "%s: lastdata=%llu, ticks=%llu\n",
	    __func__, (unsigned long long) ic->ic_lastdata,
	    (unsigned long long) ticks);

	/* If powersave is disabled on the VAP, don't bother */
	if (! (vap->iv_flags & IEEE80211_F_PMGTON))
		goto out;

	/* If we've done any data within our idle interval, bail */
	/* XXX hard-coded to one second for now, ew! */
	if (ieee80211_time_after(ic->ic_lastdata + 500, ticks))
		goto out;

	/*
	 * Signify we're going into power save and transition the
	 * node to powersave.
	 */
	if ((vap->iv_bss->ni_flags & IEEE80211_NODE_PWR_MGT) == 0)
		vap->iv_sta_ps(vap, 1);

	/*
	 * XXX The driver has to handle the fact that we're going
	 * to sleep but frames may still be transmitted;
	 * hopefully it and/or us will do the right thing and mark any
	 * transmitted frames with PWRMGT set to 1.
	 */
	ieee80211_new_state_locked(vap, IEEE80211_S_SLEEP, 0);

	IEEE80211_DPRINTF(vap, IEEE80211_MSG_POWER,
	    "%s: time delta=%d msec\n", __func__,
	    (int) ticks_to_msecs(ticks - ic->ic_lastdata));

out:
	return;
}
/*
 * Handle being notified that we have data available for us in a TIM/ATIM.
 *
 * This may schedule a transition from _SLEEP -> _RUN if it's appropriate.
 */
void
ieee80211_sta_tim_notify(struct ieee80211vap *vap, int set)
{
	/*
	 * Schedule the driver state change.  It'll happen at some point soon.
	 * Since the hardware shouldn't know that we're running just yet
	 * (and thus tell the peer that we're awake before we actually wake
	 * up said hardware), we leave the actual node state transition
	 * up to the transition to RUN.
	 *
	 * XXX TODO: verify that the transition to RUN will wake up the
	 * BSS node!
	 */
	IEEE80211_DPRINTF(vap, IEEE80211_MSG_POWER, "%s: TIM=%d\n", __func__, set);
	if (set == 1 && vap->iv_state == IEEE80211_S_SLEEP) {
		ieee80211_new_state_locked(vap, IEEE80211_S_RUN, 0);
	}
}
Ejemplo n.º 3
0
/*
 * Handle being notified that we have data available for us in a TIM/ATIM.
 *
 * This may schedule a transition from _SLEEP -> _RUN if it's appropriate.
 *
 * In STA mode, we may have put to sleep during scan and need to be dragged
 * back out of powersave mode.
 */
void
ieee80211_sta_tim_notify(struct ieee80211vap *vap, int set)
{
	struct ieee80211com *ic = vap->iv_ic;

	/*
	 * Schedule the driver state change.  It'll happen at some point soon.
	 * Since the hardware shouldn't know that we're running just yet
	 * (and thus tell the peer that we're awake before we actually wake
	 * up said hardware), we leave the actual node state transition
	 * up to the transition to RUN.
	 *
	 * XXX TODO: verify that the transition to RUN will wake up the
	 * BSS node!
	 */
	IEEE80211_LOCK(vap->iv_ic);
	if (set == 1 && vap->iv_state == IEEE80211_S_SLEEP) {
		ieee80211_new_state_locked(vap, IEEE80211_S_RUN, 0);
		IEEE80211_DPRINTF(vap, IEEE80211_MSG_POWER,
		    "%s: TIM=%d; wakeup\n", __func__, set);
	} else if ((set == 1) && (ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN)) {
		/*
		 * XXX only do this if we're in RUN state?
		 */
		IEEE80211_DPRINTF(vap, IEEE80211_MSG_POWER,
		    "%s: wake up from bgscan vap sleep\n",
		    __func__);
		/*
		 * We may be in BGSCAN mode - this means the VAP is is in STA
		 * mode powersave.  If it is, we need to wake it up so we
		 * can process outbound traffic.
		 */
		vap->iv_sta_ps(vap, 0);
	}
	IEEE80211_UNLOCK(vap->iv_ic);
}