1 /*- 2 * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #include <sys/cdefs.h> 27 __FBSDID("$FreeBSD$"); 28 29 /* 30 * IEEE 802.11 power save support. 31 */ 32 #include "opt_wlan.h" 33 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/kernel.h> 37 #include <sys/malloc.h> 38 39 #include <sys/socket.h> 40 41 #include <net/if.h> 42 #include <net/if_var.h> 43 #include <net/if_media.h> 44 #include <net/ethernet.h> 45 46 #include <netproto/802_11/ieee80211_var.h> 47 48 #include <net/bpf.h> 49 50 static void ieee80211_update_ps(struct ieee80211vap *, int); 51 static int ieee80211_set_tim(struct ieee80211_node *, int); 52 53 static MALLOC_DEFINE(M_80211_POWER, "80211power", "802.11 power save state"); 54 55 void 56 ieee80211_power_attach(struct ieee80211com *ic) 57 { 58 } 59 60 void 61 ieee80211_power_detach(struct ieee80211com *ic) 62 { 63 } 64 65 void 66 ieee80211_power_vattach(struct ieee80211vap *vap) 67 { 68 if (vap->iv_opmode == IEEE80211_M_HOSTAP || 69 vap->iv_opmode == IEEE80211_M_IBSS) { 70 /* NB: driver should override */ 71 vap->iv_update_ps = ieee80211_update_ps; 72 vap->iv_set_tim = ieee80211_set_tim; 73 } 74 vap->iv_node_ps = ieee80211_node_pwrsave; 75 vap->iv_sta_ps = ieee80211_sta_pwrsave; 76 } 77 78 void 79 ieee80211_power_latevattach(struct ieee80211vap *vap) 80 { 81 /* 82 * Allocate these only if needed. Beware that we 83 * know adhoc mode doesn't support ATIM yet... 84 */ 85 if (vap->iv_opmode == IEEE80211_M_HOSTAP) { 86 vap->iv_tim_len = howmany(vap->iv_max_aid,8) * sizeof(uint8_t); 87 #if defined(__DragonFly__) 88 vap->iv_tim_bitmap = (uint8_t *) kmalloc(vap->iv_tim_len, 89 M_80211_POWER, M_INTWAIT | M_ZERO); 90 #else 91 vap->iv_tim_bitmap = (uint8_t *) IEEE80211_MALLOC(vap->iv_tim_len, 92 M_80211_POWER, 93 IEEE80211_M_NOWAIT | IEEE80211_M_ZERO); 94 #endif 95 if (vap->iv_tim_bitmap == NULL) { 96 kprintf("%s: no memory for TIM bitmap!\n", __func__); 97 /* XXX good enough to keep from crashing? */ 98 vap->iv_tim_len = 0; 99 } 100 } 101 } 102 103 void 104 ieee80211_power_vdetach(struct ieee80211vap *vap) 105 { 106 if (vap->iv_tim_bitmap != NULL) { 107 IEEE80211_FREE(vap->iv_tim_bitmap, M_80211_POWER); 108 vap->iv_tim_bitmap = NULL; 109 } 110 } 111 112 void 113 ieee80211_psq_init(struct ieee80211_psq *psq, const char *name) 114 { 115 memset(psq, 0, sizeof(*psq)); 116 psq->psq_maxlen = IEEE80211_PS_MAX_QUEUE; 117 IEEE80211_PSQ_INIT(psq, name); /* OS-dependent setup */ 118 } 119 120 void 121 ieee80211_psq_cleanup(struct ieee80211_psq *psq) 122 { 123 #if 0 124 psq_drain(psq); /* XXX should not be needed? */ 125 #else 126 KASSERT(psq->psq_len == 0, ("%d frames on ps q", psq->psq_len)); 127 #endif 128 IEEE80211_PSQ_DESTROY(psq); /* OS-dependent cleanup */ 129 } 130 131 /* 132 * Return the highest priority frame in the ps queue. 133 */ 134 struct mbuf * 135 ieee80211_node_psq_dequeue(struct ieee80211_node *ni, int *qlen) 136 { 137 struct ieee80211_psq *psq = &ni->ni_psq; 138 struct ieee80211_psq_head *qhead; 139 struct mbuf *m; 140 141 IEEE80211_PSQ_LOCK(psq); 142 qhead = &psq->psq_head[0]; 143 again: 144 if ((m = qhead->head) != NULL) { 145 if ((qhead->head = m->m_nextpkt) == NULL) 146 qhead->tail = NULL; 147 KASSERT(qhead->len > 0, ("qhead len %d", qhead->len)); 148 qhead->len--; 149 KASSERT(psq->psq_len > 0, ("psq len %d", psq->psq_len)); 150 psq->psq_len--; 151 m->m_nextpkt = NULL; 152 } 153 if (m == NULL && qhead == &psq->psq_head[0]) { 154 /* Algol-68 style for loop */ 155 qhead = &psq->psq_head[1]; 156 goto again; 157 } 158 if (qlen != NULL) 159 *qlen = psq->psq_len; 160 IEEE80211_PSQ_UNLOCK(psq); 161 return m; 162 } 163 164 /* 165 * Reclaim an mbuf from the ps q. If marked with M_ENCAP 166 * we assume there is a node reference that must be relcaimed. 167 */ 168 static void 169 psq_mfree(struct mbuf *m) 170 { 171 if (m->m_flags & M_ENCAP) { 172 struct ieee80211_node *ni = (void *) m->m_pkthdr.rcvif; 173 ieee80211_free_node(ni); 174 } 175 m->m_nextpkt = NULL; 176 m_freem(m); 177 } 178 179 /* 180 * Clear any frames queued in the power save queue. 181 * The number of frames that were present is returned. 182 */ 183 static int 184 psq_drain(struct ieee80211_psq *psq) 185 { 186 struct ieee80211_psq_head *qhead; 187 struct mbuf *m; 188 int qlen; 189 190 IEEE80211_PSQ_LOCK(psq); 191 qlen = psq->psq_len; 192 qhead = &psq->psq_head[0]; 193 again: 194 while ((m = qhead->head) != NULL) { 195 qhead->head = m->m_nextpkt; 196 psq_mfree(m); 197 } 198 qhead->tail = NULL; 199 qhead->len = 0; 200 if (qhead == &psq->psq_head[0]) { /* Algol-68 style for loop */ 201 qhead = &psq->psq_head[1]; 202 goto again; 203 } 204 psq->psq_len = 0; 205 IEEE80211_PSQ_UNLOCK(psq); 206 207 return qlen; 208 } 209 210 /* 211 * Clear any frames queued in the power save queue. 212 * The number of frames that were present is returned. 213 */ 214 int 215 ieee80211_node_psq_drain(struct ieee80211_node *ni) 216 { 217 return psq_drain(&ni->ni_psq); 218 } 219 220 /* 221 * Age frames on the power save queue. The aging interval is 222 * 4 times the listen interval specified by the station. This 223 * number is factored into the age calculations when the frame 224 * is placed on the queue. We store ages as time differences 225 * so we can check and/or adjust only the head of the list. 226 * If a frame's age exceeds the threshold then discard it. 227 * The number of frames discarded is returned so the caller 228 * can check if it needs to adjust the tim. 229 */ 230 int 231 ieee80211_node_psq_age(struct ieee80211_node *ni) 232 { 233 struct ieee80211_psq *psq = &ni->ni_psq; 234 int discard = 0; 235 236 if (psq->psq_len != 0) { 237 #ifdef IEEE80211_DEBUG 238 struct ieee80211vap *vap = ni->ni_vap; 239 #endif 240 struct ieee80211_psq_head *qhead; 241 struct mbuf *m; 242 243 IEEE80211_PSQ_LOCK(psq); 244 qhead = &psq->psq_head[0]; 245 again: 246 while ((m = qhead->head) != NULL && 247 M_AGE_GET(m) < IEEE80211_INACT_WAIT) { 248 IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni, 249 "discard frame, age %u", M_AGE_GET(m)); 250 if ((qhead->head = m->m_nextpkt) == NULL) 251 qhead->tail = NULL; 252 KASSERT(qhead->len > 0, ("qhead len %d", qhead->len)); 253 qhead->len--; 254 KASSERT(psq->psq_len > 0, ("psq len %d", psq->psq_len)); 255 psq->psq_len--; 256 psq_mfree(m); 257 discard++; 258 } 259 if (qhead == &psq->psq_head[0]) { /* Algol-68 style for loop */ 260 qhead = &psq->psq_head[1]; 261 goto again; 262 } 263 if (m != NULL) 264 M_AGE_SUB(m, IEEE80211_INACT_WAIT); 265 IEEE80211_PSQ_UNLOCK(psq); 266 267 IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni, 268 "discard %u frames for age", discard); 269 IEEE80211_NODE_STAT_ADD(ni, ps_discard, discard); 270 } 271 return discard; 272 } 273 274 /* 275 * Handle a change in the PS station occupancy. 276 */ 277 static void 278 ieee80211_update_ps(struct ieee80211vap *vap, int nsta) 279 { 280 281 KASSERT(vap->iv_opmode == IEEE80211_M_HOSTAP || 282 vap->iv_opmode == IEEE80211_M_IBSS, 283 ("operating mode %u", vap->iv_opmode)); 284 } 285 286 /* 287 * Indicate whether there are frames queued for a station in power-save mode. 288 */ 289 static int 290 ieee80211_set_tim(struct ieee80211_node *ni, int set) 291 { 292 struct ieee80211vap *vap = ni->ni_vap; 293 struct ieee80211com *ic = ni->ni_ic; 294 uint16_t aid; 295 int changed; 296 297 KASSERT(vap->iv_opmode == IEEE80211_M_HOSTAP || 298 vap->iv_opmode == IEEE80211_M_IBSS, 299 ("operating mode %u", vap->iv_opmode)); 300 301 aid = IEEE80211_AID(ni->ni_associd); 302 KASSERT(aid < vap->iv_max_aid, 303 ("bogus aid %u, max %u", aid, vap->iv_max_aid)); 304 305 IEEE80211_LOCK(ic); 306 changed = (set != (isset(vap->iv_tim_bitmap, aid) != 0)); 307 if (changed) { 308 if (set) { 309 setbit(vap->iv_tim_bitmap, aid); 310 vap->iv_ps_pending++; 311 } else { 312 clrbit(vap->iv_tim_bitmap, aid); 313 vap->iv_ps_pending--; 314 } 315 /* NB: we know vap is in RUN state so no need to check */ 316 vap->iv_update_beacon(vap, IEEE80211_BEACON_TIM); 317 } 318 IEEE80211_UNLOCK(ic); 319 320 return changed; 321 } 322 323 /* 324 * Save an outbound packet for a node in power-save sleep state. 325 * The new packet is placed on the node's saved queue, and the TIM 326 * is changed, if necessary. 327 */ 328 int 329 ieee80211_pwrsave(struct ieee80211_node *ni, struct mbuf *m) 330 { 331 struct ieee80211_psq *psq = &ni->ni_psq; 332 struct ieee80211vap *vap = ni->ni_vap; 333 struct ieee80211com *ic = ni->ni_ic; 334 struct ieee80211_psq_head *qhead; 335 int qlen, age; 336 337 IEEE80211_PSQ_LOCK(psq); 338 if (psq->psq_len >= psq->psq_maxlen) { 339 psq->psq_drops++; 340 IEEE80211_PSQ_UNLOCK(psq); 341 IEEE80211_NOTE(vap, IEEE80211_MSG_ANY, ni, 342 "pwr save q overflow, drops %d (size %d)", 343 psq->psq_drops, psq->psq_len); 344 #ifdef IEEE80211_DEBUG 345 if (ieee80211_msg_dumppkts(vap)) 346 ieee80211_dump_pkt(ni->ni_ic, mtod(m, caddr_t), 347 m->m_len, -1, -1); 348 #endif 349 psq_mfree(m); 350 return ENOSPC; 351 } 352 /* 353 * Tag the frame with it's expiry time and insert it in 354 * the appropriate queue. The aging interval is 4 times 355 * the listen interval specified by the station. Frames 356 * that sit around too long are reclaimed using this 357 * information. 358 */ 359 /* TU -> secs. XXX handle overflow? */ 360 age = IEEE80211_TU_TO_MS((ni->ni_intval * ic->ic_bintval) << 2) / 1000; 361 /* 362 * Encapsulated frames go on the high priority queue, 363 * other stuff goes on the low priority queue. We use 364 * this to order frames returned out of the driver 365 * ahead of frames we collect in ieee80211_start. 366 */ 367 if (m->m_flags & M_ENCAP) 368 qhead = &psq->psq_head[0]; 369 else 370 qhead = &psq->psq_head[1]; 371 if (qhead->tail == NULL) { 372 struct mbuf *mh; 373 374 qhead->head = m; 375 /* 376 * Take care to adjust age when inserting the first 377 * frame of a queue and the other queue already has 378 * frames. We need to preserve the age difference 379 * relationship so ieee80211_node_psq_age works. 380 */ 381 if (qhead == &psq->psq_head[1]) { 382 mh = psq->psq_head[0].head; 383 if (mh != NULL) 384 age-= M_AGE_GET(mh); 385 } else { 386 mh = psq->psq_head[1].head; 387 if (mh != NULL) { 388 int nage = M_AGE_GET(mh) - age; 389 /* XXX is clamping to zero good 'nuf? */ 390 M_AGE_SET(mh, nage < 0 ? 0 : nage); 391 } 392 } 393 } else { 394 qhead->tail->m_nextpkt = m; 395 age -= M_AGE_GET(qhead->head); 396 } 397 KASSERT(age >= 0, ("age %d", age)); 398 M_AGE_SET(m, age); 399 m->m_nextpkt = NULL; 400 qhead->tail = m; 401 qhead->len++; 402 qlen = ++(psq->psq_len); 403 IEEE80211_PSQ_UNLOCK(psq); 404 405 IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni, 406 "save frame with age %d, %u now queued", age, qlen); 407 408 if (qlen == 1 && vap->iv_set_tim != NULL) 409 vap->iv_set_tim(ni, 1); 410 411 return 0; 412 } 413 414 /* 415 * Move frames from the ps q to the vap's send queue 416 * and/or the driver's send queue; and kick the start 417 * method for each, as appropriate. Note we're careful 418 * to preserve packet ordering here. 419 */ 420 static void 421 pwrsave_flushq(struct ieee80211_node *ni) 422 { 423 struct ieee80211_psq *psq = &ni->ni_psq; 424 struct ieee80211com *ic = ni->ni_ic; 425 struct ieee80211vap *vap = ni->ni_vap; 426 struct ieee80211_psq_head *qhead; 427 struct mbuf *parent_q = NULL, *ifp_q = NULL; 428 struct mbuf *m; 429 430 IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni, 431 "flush ps queue, %u packets queued", psq->psq_len); 432 433 IEEE80211_PSQ_LOCK(psq); 434 qhead = &psq->psq_head[0]; /* 802.11 frames */ 435 if (qhead->head != NULL) { 436 /* XXX could dispatch through vap and check M_ENCAP */ 437 /* XXX need different driver interface */ 438 /* XXX bypasses q max and OACTIVE */ 439 parent_q = qhead->head; 440 qhead->head = qhead->tail = NULL; 441 qhead->len = 0; 442 } 443 444 qhead = &psq->psq_head[1]; /* 802.3 frames */ 445 if (qhead->head != NULL) { 446 /* XXX need different driver interface */ 447 /* XXX bypasses q max and OACTIVE */ 448 ifp_q = qhead->head; 449 qhead->head = qhead->tail = NULL; 450 qhead->len = 0; 451 } 452 psq->psq_len = 0; 453 IEEE80211_PSQ_UNLOCK(psq); 454 455 /* NB: do this outside the psq lock */ 456 /* XXX packets might get reordered if parent is OACTIVE */ 457 /* parent frames, should be encapsulated */ 458 while (parent_q != NULL) { 459 m = parent_q; 460 parent_q = m->m_nextpkt; 461 m->m_nextpkt = NULL; 462 /* must be encapsulated */ 463 KASSERT((m->m_flags & M_ENCAP), 464 ("%s: parentq with non-M_ENCAP frame!\n", 465 __func__)); 466 (void) ieee80211_parent_xmitpkt(ic, m); 467 } 468 469 /* VAP frames, aren't encapsulated */ 470 while (ifp_q != NULL) { 471 m = ifp_q; 472 ifp_q = m->m_nextpkt; 473 m->m_nextpkt = NULL; 474 KASSERT((!(m->m_flags & M_ENCAP)), 475 ("%s: vapq with M_ENCAP frame!\n", __func__)); 476 (void) ieee80211_vap_xmitpkt(vap, m); 477 } 478 } 479 480 /* 481 * Handle station power-save state change. 482 */ 483 void 484 ieee80211_node_pwrsave(struct ieee80211_node *ni, int enable) 485 { 486 struct ieee80211vap *vap = ni->ni_vap; 487 int update; 488 489 update = 0; 490 if (enable) { 491 if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) == 0) { 492 vap->iv_ps_sta++; 493 update = 1; 494 } 495 ni->ni_flags |= IEEE80211_NODE_PWR_MGT; 496 IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni, 497 "power save mode on, %u sta's in ps mode", vap->iv_ps_sta); 498 499 if (update) 500 vap->iv_update_ps(vap, vap->iv_ps_sta); 501 } else { 502 if (ni->ni_flags & IEEE80211_NODE_PWR_MGT) { 503 vap->iv_ps_sta--; 504 update = 1; 505 } 506 ni->ni_flags &= ~IEEE80211_NODE_PWR_MGT; 507 IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni, 508 "power save mode off, %u sta's in ps mode", vap->iv_ps_sta); 509 510 /* NB: order here is intentional so TIM is clear before flush */ 511 if (vap->iv_set_tim != NULL) 512 vap->iv_set_tim(ni, 0); 513 if (update) { 514 /* NB if no sta's in ps, driver should flush mc q */ 515 vap->iv_update_ps(vap, vap->iv_ps_sta); 516 } 517 if (ni->ni_psq.psq_len != 0) 518 pwrsave_flushq(ni); 519 } 520 } 521 522 /* 523 * Handle power-save state change in station mode. 524 */ 525 void 526 ieee80211_sta_pwrsave(struct ieee80211vap *vap, int enable) 527 { 528 struct ieee80211_node *ni = vap->iv_bss; 529 530 if (!((enable != 0) ^ ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) != 0))) 531 return; 532 533 IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni, 534 "sta power save mode %s", enable ? "on" : "off"); 535 if (!enable) { 536 ni->ni_flags &= ~IEEE80211_NODE_PWR_MGT; 537 ieee80211_send_nulldata(ieee80211_ref_node(ni)); 538 /* 539 * Flush any queued frames; we can do this immediately 540 * because we know they'll be queued behind the null 541 * data frame we send the ap. 542 * XXX can we use a data frame to take us out of ps? 543 */ 544 if (ni->ni_psq.psq_len != 0) 545 pwrsave_flushq(ni); 546 } else { 547 ni->ni_flags |= IEEE80211_NODE_PWR_MGT; 548 ieee80211_send_nulldata(ieee80211_ref_node(ni)); 549 } 550 } 551 552 /* 553 * Handle being notified that we have data available for us in a TIM/ATIM. 554 * 555 * This may schedule a transition from _SLEEP -> _RUN if it's appropriate. 556 * 557 * In STA mode, we may have put to sleep during scan and need to be dragged 558 * back out of powersave mode. 559 */ 560 void 561 ieee80211_sta_tim_notify(struct ieee80211vap *vap, int set) 562 { 563 struct ieee80211com *ic = vap->iv_ic; 564 565 /* 566 * Schedule the driver state change. It'll happen at some point soon. 567 * Since the hardware shouldn't know that we're running just yet 568 * (and thus tell the peer that we're awake before we actually wake 569 * up said hardware), we leave the actual node state transition 570 * up to the transition to RUN. 571 * 572 * XXX TODO: verify that the transition to RUN will wake up the 573 * BSS node! 574 */ 575 IEEE80211_LOCK(vap->iv_ic); 576 if (set == 1 && vap->iv_state == IEEE80211_S_SLEEP) { 577 ieee80211_new_state_locked(vap, IEEE80211_S_RUN, 0); 578 IEEE80211_DPRINTF(vap, IEEE80211_MSG_POWER, 579 "%s: TIM=%d; wakeup\n", __func__, set); 580 } else if ((set == 1) && (ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN)) { 581 /* 582 * XXX only do this if we're in RUN state? 583 */ 584 IEEE80211_DPRINTF(vap, IEEE80211_MSG_POWER, 585 "%s: wake up from bgscan vap sleep\n", 586 __func__); 587 /* 588 * We may be in BGSCAN mode - this means the VAP is is in STA 589 * mode powersave. If it is, we need to wake it up so we 590 * can process outbound traffic. 591 */ 592 vap->iv_sta_ps(vap, 0); 593 } 594 IEEE80211_UNLOCK(vap->iv_ic); 595 } 596 597 /* 598 * Timer check on whether the VAP has had any transmit activity. 599 * 600 * This may schedule a transition from _RUN -> _SLEEP if it's appropriate. 601 */ 602 void 603 ieee80211_sta_ps_timer_check(struct ieee80211vap *vap) 604 { 605 struct ieee80211com *ic = vap->iv_ic; 606 607 /* XXX lock assert */ 608 609 /* For no, only do this in STA mode */ 610 if (! (vap->iv_caps & IEEE80211_C_SWSLEEP)) 611 goto out; 612 613 if (vap->iv_opmode != IEEE80211_M_STA) 614 goto out; 615 616 /* If we're not at run state, bail */ 617 if (vap->iv_state != IEEE80211_S_RUN) 618 goto out; 619 620 IEEE80211_DPRINTF(vap, IEEE80211_MSG_POWER, 621 "%s: lastdata=%llu, ticks=%llu\n", 622 __func__, (unsigned long long) ic->ic_lastdata, 623 (unsigned long long) ticks); 624 625 /* If powersave is disabled on the VAP, don't bother */ 626 if (! (vap->iv_flags & IEEE80211_F_PMGTON)) 627 goto out; 628 629 /* If we've done any data within our idle interval, bail */ 630 /* XXX hard-coded to one second for now, ew! */ 631 if (ieee80211_time_after(ic->ic_lastdata + 500, ticks)) 632 goto out; 633 634 /* 635 * Signify we're going into power save and transition the 636 * node to powersave. 637 */ 638 if ((vap->iv_bss->ni_flags & IEEE80211_NODE_PWR_MGT) == 0) 639 vap->iv_sta_ps(vap, 1); 640 641 /* 642 * XXX The driver has to handle the fact that we're going 643 * to sleep but frames may still be transmitted; 644 * hopefully it and/or us will do the right thing and mark any 645 * transmitted frames with PWRMGT set to 1. 646 */ 647 ieee80211_new_state_locked(vap, IEEE80211_S_SLEEP, 0); 648 649 IEEE80211_DPRINTF(vap, IEEE80211_MSG_POWER, 650 "%s: time delta=%d msec\n", __func__, 651 (int) ticks_to_msecs(ticks - ic->ic_lastdata)); 652 653 out: 654 return; 655 } 656