Lines Matching +full:mode +full:- +full:xxx
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
68 if (vap->iv_opmode == IEEE80211_M_HOSTAP || in ieee80211_power_vattach()
69 vap->iv_opmode == IEEE80211_M_IBSS) { in ieee80211_power_vattach()
71 vap->iv_update_ps = ieee80211_update_ps; in ieee80211_power_vattach()
72 vap->iv_set_tim = ieee80211_set_tim; in ieee80211_power_vattach()
74 vap->iv_node_ps = ieee80211_node_pwrsave; in ieee80211_power_vattach()
75 vap->iv_sta_ps = ieee80211_sta_pwrsave; in ieee80211_power_vattach()
83 * know adhoc mode doesn't support ATIM yet... in ieee80211_power_latevattach()
85 if (vap->iv_opmode == IEEE80211_M_HOSTAP) { in ieee80211_power_latevattach()
86 vap->iv_tim_len = howmany(vap->iv_max_aid,8) * sizeof(uint8_t); in ieee80211_power_latevattach()
87 vap->iv_tim_bitmap = (uint8_t *) IEEE80211_MALLOC(vap->iv_tim_len, in ieee80211_power_latevattach()
90 if (vap->iv_tim_bitmap == NULL) { in ieee80211_power_latevattach()
92 /* XXX good enough to keep from crashing? */ in ieee80211_power_latevattach()
93 vap->iv_tim_len = 0; in ieee80211_power_latevattach()
101 if (vap->iv_tim_bitmap != NULL) { in ieee80211_power_vdetach()
102 IEEE80211_FREE(vap->iv_tim_bitmap, M_80211_POWER); in ieee80211_power_vdetach()
103 vap->iv_tim_bitmap = NULL; in ieee80211_power_vdetach()
111 psq->psq_maxlen = IEEE80211_PS_MAX_QUEUE; in ieee80211_psq_init()
112 IEEE80211_PSQ_INIT(psq, name); /* OS-dependent setup */ in ieee80211_psq_init()
119 psq_drain(psq); /* XXX should not be needed? */ in ieee80211_psq_cleanup()
121 KASSERT(psq->psq_len == 0, ("%d frames on ps q", psq->psq_len)); in ieee80211_psq_cleanup()
123 IEEE80211_PSQ_DESTROY(psq); /* OS-dependent cleanup */ in ieee80211_psq_cleanup()
132 struct ieee80211_psq *psq = &ni->ni_psq; in ieee80211_node_psq_dequeue()
137 qhead = &psq->psq_head[0]; in ieee80211_node_psq_dequeue()
139 if ((m = qhead->head) != NULL) { in ieee80211_node_psq_dequeue()
140 if ((qhead->head = m->m_nextpkt) == NULL) in ieee80211_node_psq_dequeue()
141 qhead->tail = NULL; in ieee80211_node_psq_dequeue()
142 KASSERT(qhead->len > 0, ("qhead len %d", qhead->len)); in ieee80211_node_psq_dequeue()
143 qhead->len--; in ieee80211_node_psq_dequeue()
144 KASSERT(psq->psq_len > 0, ("psq len %d", psq->psq_len)); in ieee80211_node_psq_dequeue()
145 psq->psq_len--; in ieee80211_node_psq_dequeue()
146 m->m_nextpkt = NULL; in ieee80211_node_psq_dequeue()
148 if (m == NULL && qhead == &psq->psq_head[0]) { in ieee80211_node_psq_dequeue()
149 /* Algol-68 style for loop */ in ieee80211_node_psq_dequeue()
150 qhead = &psq->psq_head[1]; in ieee80211_node_psq_dequeue()
154 *qlen = psq->psq_len; in ieee80211_node_psq_dequeue()
166 if (m->m_flags & M_ENCAP) { in psq_mfree()
167 struct ieee80211_node *ni = (void *) m->m_pkthdr.rcvif; in psq_mfree()
170 m->m_nextpkt = NULL; in psq_mfree()
186 qlen = psq->psq_len; in psq_drain()
187 qhead = &psq->psq_head[0]; in psq_drain()
189 while ((m = qhead->head) != NULL) { in psq_drain()
190 qhead->head = m->m_nextpkt; in psq_drain()
193 qhead->tail = NULL; in psq_drain()
194 qhead->len = 0; in psq_drain()
195 if (qhead == &psq->psq_head[0]) { /* Algol-68 style for loop */ in psq_drain()
196 qhead = &psq->psq_head[1]; in psq_drain()
199 psq->psq_len = 0; in psq_drain()
212 return psq_drain(&ni->ni_psq); in ieee80211_node_psq_drain()
228 struct ieee80211_psq *psq = &ni->ni_psq; in ieee80211_node_psq_age()
231 if (psq->psq_len != 0) { in ieee80211_node_psq_age()
233 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_node_psq_age()
239 qhead = &psq->psq_head[0]; in ieee80211_node_psq_age()
241 while ((m = qhead->head) != NULL && in ieee80211_node_psq_age()
245 if ((qhead->head = m->m_nextpkt) == NULL) in ieee80211_node_psq_age()
246 qhead->tail = NULL; in ieee80211_node_psq_age()
247 KASSERT(qhead->len > 0, ("qhead len %d", qhead->len)); in ieee80211_node_psq_age()
248 qhead->len--; in ieee80211_node_psq_age()
249 KASSERT(psq->psq_len > 0, ("psq len %d", psq->psq_len)); in ieee80211_node_psq_age()
250 psq->psq_len--; in ieee80211_node_psq_age()
254 if (qhead == &psq->psq_head[0]) { /* Algol-68 style for loop */ in ieee80211_node_psq_age()
255 qhead = &psq->psq_head[1]; in ieee80211_node_psq_age()
276 KASSERT(vap->iv_opmode == IEEE80211_M_HOSTAP || in ieee80211_update_ps()
277 vap->iv_opmode == IEEE80211_M_IBSS, in ieee80211_update_ps()
278 ("operating mode %u", vap->iv_opmode)); in ieee80211_update_ps()
282 * Indicate whether there are frames queued for a station in power-save mode.
287 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_set_tim()
288 struct ieee80211com *ic = ni->ni_ic; in ieee80211_set_tim()
292 KASSERT(vap->iv_opmode == IEEE80211_M_HOSTAP || in ieee80211_set_tim()
293 vap->iv_opmode == IEEE80211_M_IBSS, in ieee80211_set_tim()
294 ("operating mode %u", vap->iv_opmode)); in ieee80211_set_tim()
296 aid = IEEE80211_AID(ni->ni_associd); in ieee80211_set_tim()
297 KASSERT(aid < vap->iv_max_aid, in ieee80211_set_tim()
298 ("bogus aid %u, max %u", aid, vap->iv_max_aid)); in ieee80211_set_tim()
301 changed = (set != (isset(vap->iv_tim_bitmap, aid) != 0)); in ieee80211_set_tim()
304 setbit(vap->iv_tim_bitmap, aid); in ieee80211_set_tim()
305 vap->iv_ps_pending++; in ieee80211_set_tim()
307 clrbit(vap->iv_tim_bitmap, aid); in ieee80211_set_tim()
308 vap->iv_ps_pending--; in ieee80211_set_tim()
311 vap->iv_update_beacon(vap, IEEE80211_BEACON_TIM); in ieee80211_set_tim()
319 * Save an outbound packet for a node in power-save sleep state.
326 struct ieee80211_psq *psq = &ni->ni_psq; in ieee80211_pwrsave()
327 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_pwrsave()
328 struct ieee80211com *ic = ni->ni_ic; in ieee80211_pwrsave()
333 if (psq->psq_len >= psq->psq_maxlen) { in ieee80211_pwrsave()
334 psq->psq_drops++; in ieee80211_pwrsave()
338 psq->psq_drops, psq->psq_len); in ieee80211_pwrsave()
341 ieee80211_dump_pkt(ni->ni_ic, mtod(m, caddr_t), in ieee80211_pwrsave()
342 m->m_len, -1, -1); in ieee80211_pwrsave()
354 /* TU -> secs. XXX handle overflow? */ in ieee80211_pwrsave()
355 age = IEEE80211_TU_TO_MS((ni->ni_intval * ic->ic_bintval) << 2) / 1000; in ieee80211_pwrsave()
362 if (m->m_flags & M_ENCAP) in ieee80211_pwrsave()
363 qhead = &psq->psq_head[0]; in ieee80211_pwrsave()
365 qhead = &psq->psq_head[1]; in ieee80211_pwrsave()
366 if (qhead->tail == NULL) { in ieee80211_pwrsave()
369 qhead->head = m; in ieee80211_pwrsave()
376 if (qhead == &psq->psq_head[1]) { in ieee80211_pwrsave()
377 mh = psq->psq_head[0].head; in ieee80211_pwrsave()
379 age-= M_AGE_GET(mh); in ieee80211_pwrsave()
381 mh = psq->psq_head[1].head; in ieee80211_pwrsave()
383 int nage = M_AGE_GET(mh) - age; in ieee80211_pwrsave()
384 /* XXX is clamping to zero good 'nuf? */ in ieee80211_pwrsave()
389 qhead->tail->m_nextpkt = m; in ieee80211_pwrsave()
390 age -= M_AGE_GET(qhead->head); in ieee80211_pwrsave()
394 m->m_nextpkt = NULL; in ieee80211_pwrsave()
395 qhead->tail = m; in ieee80211_pwrsave()
396 qhead->len++; in ieee80211_pwrsave()
397 qlen = ++(psq->psq_len); in ieee80211_pwrsave()
403 if (qlen == 1 && vap->iv_set_tim != NULL) in ieee80211_pwrsave()
404 vap->iv_set_tim(ni, 1); in ieee80211_pwrsave()
418 struct ieee80211_psq *psq = &ni->ni_psq; in pwrsave_flushq()
419 struct ieee80211com *ic = ni->ni_ic; in pwrsave_flushq()
420 struct ieee80211vap *vap = ni->ni_vap; in pwrsave_flushq()
426 "flush ps queue, %u packets queued", psq->psq_len); in pwrsave_flushq()
429 qhead = &psq->psq_head[0]; /* 802.11 frames */ in pwrsave_flushq()
430 if (qhead->head != NULL) { in pwrsave_flushq()
431 /* XXX could dispatch through vap and check M_ENCAP */ in pwrsave_flushq()
432 /* XXX need different driver interface */ in pwrsave_flushq()
433 /* XXX bypasses q max and OACTIVE */ in pwrsave_flushq()
434 parent_q = qhead->head; in pwrsave_flushq()
435 qhead->head = qhead->tail = NULL; in pwrsave_flushq()
436 qhead->len = 0; in pwrsave_flushq()
439 qhead = &psq->psq_head[1]; /* 802.3 frames */ in pwrsave_flushq()
440 if (qhead->head != NULL) { in pwrsave_flushq()
441 /* XXX need different driver interface */ in pwrsave_flushq()
442 /* XXX bypasses q max and OACTIVE */ in pwrsave_flushq()
443 ifp_q = qhead->head; in pwrsave_flushq()
444 qhead->head = qhead->tail = NULL; in pwrsave_flushq()
445 qhead->len = 0; in pwrsave_flushq()
447 psq->psq_len = 0; in pwrsave_flushq()
451 /* XXX packets might get reordered if parent is OACTIVE */ in pwrsave_flushq()
455 parent_q = m->m_nextpkt; in pwrsave_flushq()
456 m->m_nextpkt = NULL; in pwrsave_flushq()
458 KASSERT((m->m_flags & M_ENCAP), in pwrsave_flushq()
459 ("%s: parentq with non-M_ENCAP frame!\n", in pwrsave_flushq()
467 ifp_q = m->m_nextpkt; in pwrsave_flushq()
468 m->m_nextpkt = NULL; in pwrsave_flushq()
469 KASSERT((!(m->m_flags & M_ENCAP)), in pwrsave_flushq()
476 * Handle station power-save state change.
481 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_node_pwrsave()
486 if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) == 0) { in ieee80211_node_pwrsave()
487 vap->iv_ps_sta++; in ieee80211_node_pwrsave()
490 ni->ni_flags |= IEEE80211_NODE_PWR_MGT; in ieee80211_node_pwrsave()
492 "power save mode on, %u sta's in ps mode", vap->iv_ps_sta); in ieee80211_node_pwrsave()
495 vap->iv_update_ps(vap, vap->iv_ps_sta); in ieee80211_node_pwrsave()
497 if (ni->ni_flags & IEEE80211_NODE_PWR_MGT) { in ieee80211_node_pwrsave()
498 vap->iv_ps_sta--; in ieee80211_node_pwrsave()
501 ni->ni_flags &= ~IEEE80211_NODE_PWR_MGT; in ieee80211_node_pwrsave()
503 "power save mode off, %u sta's in ps mode", vap->iv_ps_sta); in ieee80211_node_pwrsave()
506 if (vap->iv_set_tim != NULL) in ieee80211_node_pwrsave()
507 vap->iv_set_tim(ni, 0); in ieee80211_node_pwrsave()
510 vap->iv_update_ps(vap, vap->iv_ps_sta); in ieee80211_node_pwrsave()
512 if (ni->ni_psq.psq_len != 0) in ieee80211_node_pwrsave()
518 * Handle power-save state change in station mode.
523 struct ieee80211_node *ni = vap->iv_bss; in ieee80211_sta_pwrsave()
525 if (!((enable != 0) ^ ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) != 0))) in ieee80211_sta_pwrsave()
529 "sta power save mode %s", enable ? "on" : "off"); in ieee80211_sta_pwrsave()
531 ni->ni_flags &= ~IEEE80211_NODE_PWR_MGT; in ieee80211_sta_pwrsave()
537 * XXX can we use a data frame to take us out of ps? in ieee80211_sta_pwrsave()
539 if (ni->ni_psq.psq_len != 0) in ieee80211_sta_pwrsave()
542 ni->ni_flags |= IEEE80211_NODE_PWR_MGT; in ieee80211_sta_pwrsave()
550 * This may schedule a transition from _SLEEP -> _RUN if it's appropriate.
552 * In STA mode, we may have put to sleep during scan and need to be dragged
553 * back out of powersave mode.
558 struct ieee80211com *ic = vap->iv_ic; in ieee80211_sta_tim_notify()
567 * XXX TODO: verify that the transition to RUN will wake up the in ieee80211_sta_tim_notify()
570 IEEE80211_LOCK(vap->iv_ic); in ieee80211_sta_tim_notify()
571 if (set == 1 && vap->iv_state == IEEE80211_S_SLEEP) { in ieee80211_sta_tim_notify()
575 } else if ((set == 1) && (ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN)) { in ieee80211_sta_tim_notify()
577 * XXX only do this if we're in RUN state? in ieee80211_sta_tim_notify()
583 * We may be in BGSCAN mode - this means the VAP is in STA in ieee80211_sta_tim_notify()
584 * mode powersave. If it is, we need to wake it up so we in ieee80211_sta_tim_notify()
587 vap->iv_sta_ps(vap, 0); in ieee80211_sta_tim_notify()
589 IEEE80211_UNLOCK(vap->iv_ic); in ieee80211_sta_tim_notify()
595 * This may schedule a transition from _RUN -> _SLEEP if it's appropriate.
600 struct ieee80211com *ic = vap->iv_ic; in ieee80211_sta_ps_timer_check()
602 /* XXX lock assert */ in ieee80211_sta_ps_timer_check()
604 /* For no, only do this in STA mode */ in ieee80211_sta_ps_timer_check()
605 if (! (vap->iv_caps & IEEE80211_C_SWSLEEP)) in ieee80211_sta_ps_timer_check()
608 if (vap->iv_opmode != IEEE80211_M_STA) in ieee80211_sta_ps_timer_check()
612 if (vap->iv_state != IEEE80211_S_RUN) in ieee80211_sta_ps_timer_check()
617 __func__, (unsigned long long) ic->ic_lastdata, in ieee80211_sta_ps_timer_check()
621 if (! (vap->iv_flags & IEEE80211_F_PMGTON)) in ieee80211_sta_ps_timer_check()
625 /* XXX hard-coded to one second for now, ew! */ in ieee80211_sta_ps_timer_check()
626 if (ieee80211_time_after(ic->ic_lastdata + 500, ticks)) in ieee80211_sta_ps_timer_check()
633 if ((vap->iv_bss->ni_flags & IEEE80211_NODE_PWR_MGT) == 0) in ieee80211_sta_ps_timer_check()
634 vap->iv_sta_ps(vap, 1); in ieee80211_sta_ps_timer_check()
637 * XXX The driver has to handle the fact that we're going in ieee80211_sta_ps_timer_check()
646 (int) ticks_to_msecs(ticks - ic->ic_lastdata)); in ieee80211_sta_ps_timer_check()