1 /* 2 * Copyright 2002-2005, Instant802 Networks, Inc. 3 * Copyright 2005-2006, Devicescape Software, Inc. 4 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> 5 * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 * 11 * utilities for mac80211 12 */ 13 14 #include <net/mac80211.h> 15 #include <linux/netdevice.h> 16 #include <linux/types.h> 17 #include <linux/slab.h> 18 #include <linux/skbuff.h> 19 #include <linux/etherdevice.h> 20 #include <linux/if_arp.h> 21 #include <linux/bitmap.h> 22 #include <linux/crc32.h> 23 #include <net/net_namespace.h> 24 #include <net/cfg80211.h> 25 #include <net/rtnetlink.h> 26 27 #include "ieee80211_i.h" 28 #include "driver-ops.h" 29 #include "rate.h" 30 #include "mesh.h" 31 #include "wme.h" 32 #include "led.h" 33 #include "wep.h" 34 35 /* privid for wiphys to determine whether they belong to us or not */ 36 void *mac80211_wiphy_privid = &mac80211_wiphy_privid; 37 38 struct ieee80211_hw *wiphy_to_ieee80211_hw(struct wiphy *wiphy) 39 { 40 struct ieee80211_local *local; 41 BUG_ON(!wiphy); 42 43 local = wiphy_priv(wiphy); 44 return &local->hw; 45 } 46 EXPORT_SYMBOL(wiphy_to_ieee80211_hw); 47 48 u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len, 49 enum nl80211_iftype type) 50 { 51 __le16 fc = hdr->frame_control; 52 53 /* drop ACK/CTS frames and incorrect hdr len (ctrl) */ 54 if (len < 16) 55 return NULL; 56 57 if (ieee80211_is_data(fc)) { 58 if (len < 24) /* drop incorrect hdr len (data) */ 59 return NULL; 60 61 if (ieee80211_has_a4(fc)) 62 return NULL; 63 if (ieee80211_has_tods(fc)) 64 return hdr->addr1; 65 if (ieee80211_has_fromds(fc)) 66 return hdr->addr2; 67 68 return hdr->addr3; 69 } 70 71 if (ieee80211_is_mgmt(fc)) { 72 if (len < 24) /* drop incorrect hdr len (mgmt) */ 73 return NULL; 74 return hdr->addr3; 75 } 76 77 if (ieee80211_is_ctl(fc)) { 78 if(ieee80211_is_pspoll(fc)) 79 return hdr->addr1; 80 81 if (ieee80211_is_back_req(fc)) { 82 switch (type) { 83 case NL80211_IFTYPE_STATION: 84 return hdr->addr2; 85 case NL80211_IFTYPE_AP: 86 case NL80211_IFTYPE_AP_VLAN: 87 return hdr->addr1; 88 default: 89 break; /* fall through to the return */ 90 } 91 } 92 } 93 94 return NULL; 95 } 96 97 void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx) 98 { 99 struct sk_buff *skb = tx->skb; 100 struct ieee80211_hdr *hdr; 101 102 do { 103 hdr = (struct ieee80211_hdr *) skb->data; 104 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); 105 } while ((skb = skb->next)); 106 } 107 108 int ieee80211_frame_duration(struct ieee80211_local *local, size_t len, 109 int rate, int erp, int short_preamble) 110 { 111 int dur; 112 113 /* calculate duration (in microseconds, rounded up to next higher 114 * integer if it includes a fractional microsecond) to send frame of 115 * len bytes (does not include FCS) at the given rate. Duration will 116 * also include SIFS. 117 * 118 * rate is in 100 kbps, so divident is multiplied by 10 in the 119 * DIV_ROUND_UP() operations. 120 */ 121 122 if (local->hw.conf.channel->band == IEEE80211_BAND_5GHZ || erp) { 123 /* 124 * OFDM: 125 * 126 * N_DBPS = DATARATE x 4 127 * N_SYM = Ceiling((16+8xLENGTH+6) / N_DBPS) 128 * (16 = SIGNAL time, 6 = tail bits) 129 * TXTIME = T_PREAMBLE + T_SIGNAL + T_SYM x N_SYM + Signal Ext 130 * 131 * T_SYM = 4 usec 132 * 802.11a - 17.5.2: aSIFSTime = 16 usec 133 * 802.11g - 19.8.4: aSIFSTime = 10 usec + 134 * signal ext = 6 usec 135 */ 136 dur = 16; /* SIFS + signal ext */ 137 dur += 16; /* 17.3.2.3: T_PREAMBLE = 16 usec */ 138 dur += 4; /* 17.3.2.3: T_SIGNAL = 4 usec */ 139 dur += 4 * DIV_ROUND_UP((16 + 8 * (len + 4) + 6) * 10, 140 4 * rate); /* T_SYM x N_SYM */ 141 } else { 142 /* 143 * 802.11b or 802.11g with 802.11b compatibility: 144 * 18.3.4: TXTIME = PreambleLength + PLCPHeaderTime + 145 * Ceiling(((LENGTH+PBCC)x8)/DATARATE). PBCC=0. 146 * 147 * 802.11 (DS): 15.3.3, 802.11b: 18.3.4 148 * aSIFSTime = 10 usec 149 * aPreambleLength = 144 usec or 72 usec with short preamble 150 * aPLCPHeaderLength = 48 usec or 24 usec with short preamble 151 */ 152 dur = 10; /* aSIFSTime = 10 usec */ 153 dur += short_preamble ? (72 + 24) : (144 + 48); 154 155 dur += DIV_ROUND_UP(8 * (len + 4) * 10, rate); 156 } 157 158 return dur; 159 } 160 161 /* Exported duration function for driver use */ 162 __le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw, 163 struct ieee80211_vif *vif, 164 size_t frame_len, 165 struct ieee80211_rate *rate) 166 { 167 struct ieee80211_local *local = hw_to_local(hw); 168 struct ieee80211_sub_if_data *sdata; 169 u16 dur; 170 int erp; 171 bool short_preamble = false; 172 173 erp = 0; 174 if (vif) { 175 sdata = vif_to_sdata(vif); 176 short_preamble = sdata->vif.bss_conf.use_short_preamble; 177 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) 178 erp = rate->flags & IEEE80211_RATE_ERP_G; 179 } 180 181 dur = ieee80211_frame_duration(local, frame_len, rate->bitrate, erp, 182 short_preamble); 183 184 return cpu_to_le16(dur); 185 } 186 EXPORT_SYMBOL(ieee80211_generic_frame_duration); 187 188 __le16 ieee80211_rts_duration(struct ieee80211_hw *hw, 189 struct ieee80211_vif *vif, size_t frame_len, 190 const struct ieee80211_tx_info *frame_txctl) 191 { 192 struct ieee80211_local *local = hw_to_local(hw); 193 struct ieee80211_rate *rate; 194 struct ieee80211_sub_if_data *sdata; 195 bool short_preamble; 196 int erp; 197 u16 dur; 198 struct ieee80211_supported_band *sband; 199 200 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 201 202 short_preamble = false; 203 204 rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx]; 205 206 erp = 0; 207 if (vif) { 208 sdata = vif_to_sdata(vif); 209 short_preamble = sdata->vif.bss_conf.use_short_preamble; 210 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) 211 erp = rate->flags & IEEE80211_RATE_ERP_G; 212 } 213 214 /* CTS duration */ 215 dur = ieee80211_frame_duration(local, 10, rate->bitrate, 216 erp, short_preamble); 217 /* Data frame duration */ 218 dur += ieee80211_frame_duration(local, frame_len, rate->bitrate, 219 erp, short_preamble); 220 /* ACK duration */ 221 dur += ieee80211_frame_duration(local, 10, rate->bitrate, 222 erp, short_preamble); 223 224 return cpu_to_le16(dur); 225 } 226 EXPORT_SYMBOL(ieee80211_rts_duration); 227 228 __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, 229 struct ieee80211_vif *vif, 230 size_t frame_len, 231 const struct ieee80211_tx_info *frame_txctl) 232 { 233 struct ieee80211_local *local = hw_to_local(hw); 234 struct ieee80211_rate *rate; 235 struct ieee80211_sub_if_data *sdata; 236 bool short_preamble; 237 int erp; 238 u16 dur; 239 struct ieee80211_supported_band *sband; 240 241 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 242 243 short_preamble = false; 244 245 rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx]; 246 erp = 0; 247 if (vif) { 248 sdata = vif_to_sdata(vif); 249 short_preamble = sdata->vif.bss_conf.use_short_preamble; 250 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) 251 erp = rate->flags & IEEE80211_RATE_ERP_G; 252 } 253 254 /* Data frame duration */ 255 dur = ieee80211_frame_duration(local, frame_len, rate->bitrate, 256 erp, short_preamble); 257 if (!(frame_txctl->flags & IEEE80211_TX_CTL_NO_ACK)) { 258 /* ACK duration */ 259 dur += ieee80211_frame_duration(local, 10, rate->bitrate, 260 erp, short_preamble); 261 } 262 263 return cpu_to_le16(dur); 264 } 265 EXPORT_SYMBOL(ieee80211_ctstoself_duration); 266 267 static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue, 268 enum queue_stop_reason reason) 269 { 270 struct ieee80211_local *local = hw_to_local(hw); 271 struct ieee80211_sub_if_data *sdata; 272 273 trace_wake_queue(local, queue, reason); 274 275 if (WARN_ON(queue >= hw->queues)) 276 return; 277 278 __clear_bit(reason, &local->queue_stop_reasons[queue]); 279 280 if (local->queue_stop_reasons[queue] != 0) 281 /* someone still has this queue stopped */ 282 return; 283 284 if (skb_queue_empty(&local->pending[queue])) { 285 rcu_read_lock(); 286 list_for_each_entry_rcu(sdata, &local->interfaces, list) 287 netif_tx_wake_queue(netdev_get_tx_queue(sdata->dev, queue)); 288 rcu_read_unlock(); 289 } else 290 tasklet_schedule(&local->tx_pending_tasklet); 291 } 292 293 void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, 294 enum queue_stop_reason reason) 295 { 296 struct ieee80211_local *local = hw_to_local(hw); 297 unsigned long flags; 298 299 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 300 __ieee80211_wake_queue(hw, queue, reason); 301 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 302 } 303 304 void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue) 305 { 306 ieee80211_wake_queue_by_reason(hw, queue, 307 IEEE80211_QUEUE_STOP_REASON_DRIVER); 308 } 309 EXPORT_SYMBOL(ieee80211_wake_queue); 310 311 static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue, 312 enum queue_stop_reason reason) 313 { 314 struct ieee80211_local *local = hw_to_local(hw); 315 struct ieee80211_sub_if_data *sdata; 316 317 trace_stop_queue(local, queue, reason); 318 319 if (WARN_ON(queue >= hw->queues)) 320 return; 321 322 __set_bit(reason, &local->queue_stop_reasons[queue]); 323 324 rcu_read_lock(); 325 list_for_each_entry_rcu(sdata, &local->interfaces, list) 326 netif_tx_stop_queue(netdev_get_tx_queue(sdata->dev, queue)); 327 rcu_read_unlock(); 328 } 329 330 void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, 331 enum queue_stop_reason reason) 332 { 333 struct ieee80211_local *local = hw_to_local(hw); 334 unsigned long flags; 335 336 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 337 __ieee80211_stop_queue(hw, queue, reason); 338 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 339 } 340 341 void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue) 342 { 343 ieee80211_stop_queue_by_reason(hw, queue, 344 IEEE80211_QUEUE_STOP_REASON_DRIVER); 345 } 346 EXPORT_SYMBOL(ieee80211_stop_queue); 347 348 void ieee80211_add_pending_skb(struct ieee80211_local *local, 349 struct sk_buff *skb) 350 { 351 struct ieee80211_hw *hw = &local->hw; 352 unsigned long flags; 353 int queue = skb_get_queue_mapping(skb); 354 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 355 356 if (WARN_ON(!info->control.vif)) { 357 kfree_skb(skb); 358 return; 359 } 360 361 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 362 __ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD); 363 __skb_queue_tail(&local->pending[queue], skb); 364 __ieee80211_wake_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD); 365 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 366 } 367 368 int ieee80211_add_pending_skbs(struct ieee80211_local *local, 369 struct sk_buff_head *skbs) 370 { 371 struct ieee80211_hw *hw = &local->hw; 372 struct sk_buff *skb; 373 unsigned long flags; 374 int queue, ret = 0, i; 375 376 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 377 for (i = 0; i < hw->queues; i++) 378 __ieee80211_stop_queue(hw, i, 379 IEEE80211_QUEUE_STOP_REASON_SKB_ADD); 380 381 while ((skb = skb_dequeue(skbs))) { 382 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 383 384 if (WARN_ON(!info->control.vif)) { 385 kfree_skb(skb); 386 continue; 387 } 388 389 ret++; 390 queue = skb_get_queue_mapping(skb); 391 __skb_queue_tail(&local->pending[queue], skb); 392 } 393 394 for (i = 0; i < hw->queues; i++) 395 __ieee80211_wake_queue(hw, i, 396 IEEE80211_QUEUE_STOP_REASON_SKB_ADD); 397 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 398 399 return ret; 400 } 401 402 void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, 403 enum queue_stop_reason reason) 404 { 405 struct ieee80211_local *local = hw_to_local(hw); 406 unsigned long flags; 407 int i; 408 409 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 410 411 for (i = 0; i < hw->queues; i++) 412 __ieee80211_stop_queue(hw, i, reason); 413 414 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 415 } 416 417 void ieee80211_stop_queues(struct ieee80211_hw *hw) 418 { 419 ieee80211_stop_queues_by_reason(hw, 420 IEEE80211_QUEUE_STOP_REASON_DRIVER); 421 } 422 EXPORT_SYMBOL(ieee80211_stop_queues); 423 424 int ieee80211_queue_stopped(struct ieee80211_hw *hw, int queue) 425 { 426 struct ieee80211_local *local = hw_to_local(hw); 427 unsigned long flags; 428 int ret; 429 430 if (WARN_ON(queue >= hw->queues)) 431 return true; 432 433 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 434 ret = !!local->queue_stop_reasons[queue]; 435 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 436 return ret; 437 } 438 EXPORT_SYMBOL(ieee80211_queue_stopped); 439 440 void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, 441 enum queue_stop_reason reason) 442 { 443 struct ieee80211_local *local = hw_to_local(hw); 444 unsigned long flags; 445 int i; 446 447 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 448 449 for (i = 0; i < hw->queues; i++) 450 __ieee80211_wake_queue(hw, i, reason); 451 452 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 453 } 454 455 void ieee80211_wake_queues(struct ieee80211_hw *hw) 456 { 457 ieee80211_wake_queues_by_reason(hw, IEEE80211_QUEUE_STOP_REASON_DRIVER); 458 } 459 EXPORT_SYMBOL(ieee80211_wake_queues); 460 461 void ieee80211_iterate_active_interfaces( 462 struct ieee80211_hw *hw, 463 void (*iterator)(void *data, u8 *mac, 464 struct ieee80211_vif *vif), 465 void *data) 466 { 467 struct ieee80211_local *local = hw_to_local(hw); 468 struct ieee80211_sub_if_data *sdata; 469 470 mutex_lock(&local->iflist_mtx); 471 472 list_for_each_entry(sdata, &local->interfaces, list) { 473 switch (sdata->vif.type) { 474 case __NL80211_IFTYPE_AFTER_LAST: 475 case NL80211_IFTYPE_UNSPECIFIED: 476 case NL80211_IFTYPE_MONITOR: 477 case NL80211_IFTYPE_AP_VLAN: 478 continue; 479 case NL80211_IFTYPE_AP: 480 case NL80211_IFTYPE_STATION: 481 case NL80211_IFTYPE_ADHOC: 482 case NL80211_IFTYPE_WDS: 483 case NL80211_IFTYPE_MESH_POINT: 484 break; 485 } 486 if (ieee80211_sdata_running(sdata)) 487 iterator(data, sdata->vif.addr, 488 &sdata->vif); 489 } 490 491 mutex_unlock(&local->iflist_mtx); 492 } 493 EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces); 494 495 void ieee80211_iterate_active_interfaces_atomic( 496 struct ieee80211_hw *hw, 497 void (*iterator)(void *data, u8 *mac, 498 struct ieee80211_vif *vif), 499 void *data) 500 { 501 struct ieee80211_local *local = hw_to_local(hw); 502 struct ieee80211_sub_if_data *sdata; 503 504 rcu_read_lock(); 505 506 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 507 switch (sdata->vif.type) { 508 case __NL80211_IFTYPE_AFTER_LAST: 509 case NL80211_IFTYPE_UNSPECIFIED: 510 case NL80211_IFTYPE_MONITOR: 511 case NL80211_IFTYPE_AP_VLAN: 512 continue; 513 case NL80211_IFTYPE_AP: 514 case NL80211_IFTYPE_STATION: 515 case NL80211_IFTYPE_ADHOC: 516 case NL80211_IFTYPE_WDS: 517 case NL80211_IFTYPE_MESH_POINT: 518 break; 519 } 520 if (ieee80211_sdata_running(sdata)) 521 iterator(data, sdata->vif.addr, 522 &sdata->vif); 523 } 524 525 rcu_read_unlock(); 526 } 527 EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic); 528 529 /* 530 * Nothing should have been stuffed into the workqueue during 531 * the suspend->resume cycle. If this WARN is seen then there 532 * is a bug with either the driver suspend or something in 533 * mac80211 stuffing into the workqueue which we haven't yet 534 * cleared during mac80211's suspend cycle. 535 */ 536 static bool ieee80211_can_queue_work(struct ieee80211_local *local) 537 { 538 if (WARN(local->suspended && !local->resuming, 539 "queueing ieee80211 work while going to suspend\n")) 540 return false; 541 542 return true; 543 } 544 545 void ieee80211_queue_work(struct ieee80211_hw *hw, struct work_struct *work) 546 { 547 struct ieee80211_local *local = hw_to_local(hw); 548 549 if (!ieee80211_can_queue_work(local)) 550 return; 551 552 queue_work(local->workqueue, work); 553 } 554 EXPORT_SYMBOL(ieee80211_queue_work); 555 556 void ieee80211_queue_delayed_work(struct ieee80211_hw *hw, 557 struct delayed_work *dwork, 558 unsigned long delay) 559 { 560 struct ieee80211_local *local = hw_to_local(hw); 561 562 if (!ieee80211_can_queue_work(local)) 563 return; 564 565 queue_delayed_work(local->workqueue, dwork, delay); 566 } 567 EXPORT_SYMBOL(ieee80211_queue_delayed_work); 568 569 void ieee802_11_parse_elems(u8 *start, size_t len, 570 struct ieee802_11_elems *elems) 571 { 572 ieee802_11_parse_elems_crc(start, len, elems, 0, 0); 573 } 574 575 u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, 576 struct ieee802_11_elems *elems, 577 u64 filter, u32 crc) 578 { 579 size_t left = len; 580 u8 *pos = start; 581 bool calc_crc = filter != 0; 582 583 memset(elems, 0, sizeof(*elems)); 584 elems->ie_start = start; 585 elems->total_len = len; 586 587 while (left >= 2) { 588 u8 id, elen; 589 590 id = *pos++; 591 elen = *pos++; 592 left -= 2; 593 594 if (elen > left) 595 break; 596 597 if (calc_crc && id < 64 && (filter & (1ULL << id))) 598 crc = crc32_be(crc, pos - 2, elen + 2); 599 600 switch (id) { 601 case WLAN_EID_SSID: 602 elems->ssid = pos; 603 elems->ssid_len = elen; 604 break; 605 case WLAN_EID_SUPP_RATES: 606 elems->supp_rates = pos; 607 elems->supp_rates_len = elen; 608 break; 609 case WLAN_EID_FH_PARAMS: 610 elems->fh_params = pos; 611 elems->fh_params_len = elen; 612 break; 613 case WLAN_EID_DS_PARAMS: 614 elems->ds_params = pos; 615 elems->ds_params_len = elen; 616 break; 617 case WLAN_EID_CF_PARAMS: 618 elems->cf_params = pos; 619 elems->cf_params_len = elen; 620 break; 621 case WLAN_EID_TIM: 622 if (elen >= sizeof(struct ieee80211_tim_ie)) { 623 elems->tim = (void *)pos; 624 elems->tim_len = elen; 625 } 626 break; 627 case WLAN_EID_IBSS_PARAMS: 628 elems->ibss_params = pos; 629 elems->ibss_params_len = elen; 630 break; 631 case WLAN_EID_CHALLENGE: 632 elems->challenge = pos; 633 elems->challenge_len = elen; 634 break; 635 case WLAN_EID_VENDOR_SPECIFIC: 636 if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 && 637 pos[2] == 0xf2) { 638 /* Microsoft OUI (00:50:F2) */ 639 640 if (calc_crc) 641 crc = crc32_be(crc, pos - 2, elen + 2); 642 643 if (pos[3] == 1) { 644 /* OUI Type 1 - WPA IE */ 645 elems->wpa = pos; 646 elems->wpa_len = elen; 647 } else if (elen >= 5 && pos[3] == 2) { 648 /* OUI Type 2 - WMM IE */ 649 if (pos[4] == 0) { 650 elems->wmm_info = pos; 651 elems->wmm_info_len = elen; 652 } else if (pos[4] == 1) { 653 elems->wmm_param = pos; 654 elems->wmm_param_len = elen; 655 } 656 } 657 } 658 break; 659 case WLAN_EID_RSN: 660 elems->rsn = pos; 661 elems->rsn_len = elen; 662 break; 663 case WLAN_EID_ERP_INFO: 664 elems->erp_info = pos; 665 elems->erp_info_len = elen; 666 break; 667 case WLAN_EID_EXT_SUPP_RATES: 668 elems->ext_supp_rates = pos; 669 elems->ext_supp_rates_len = elen; 670 break; 671 case WLAN_EID_HT_CAPABILITY: 672 if (elen >= sizeof(struct ieee80211_ht_cap)) 673 elems->ht_cap_elem = (void *)pos; 674 break; 675 case WLAN_EID_HT_INFORMATION: 676 if (elen >= sizeof(struct ieee80211_ht_info)) 677 elems->ht_info_elem = (void *)pos; 678 break; 679 case WLAN_EID_MESH_ID: 680 elems->mesh_id = pos; 681 elems->mesh_id_len = elen; 682 break; 683 case WLAN_EID_MESH_CONFIG: 684 if (elen >= sizeof(struct ieee80211_meshconf_ie)) 685 elems->mesh_config = (void *)pos; 686 break; 687 case WLAN_EID_PEER_LINK: 688 elems->peer_link = pos; 689 elems->peer_link_len = elen; 690 break; 691 case WLAN_EID_PREQ: 692 elems->preq = pos; 693 elems->preq_len = elen; 694 break; 695 case WLAN_EID_PREP: 696 elems->prep = pos; 697 elems->prep_len = elen; 698 break; 699 case WLAN_EID_PERR: 700 elems->perr = pos; 701 elems->perr_len = elen; 702 break; 703 case WLAN_EID_RANN: 704 if (elen >= sizeof(struct ieee80211_rann_ie)) 705 elems->rann = (void *)pos; 706 break; 707 case WLAN_EID_CHANNEL_SWITCH: 708 elems->ch_switch_elem = pos; 709 elems->ch_switch_elem_len = elen; 710 break; 711 case WLAN_EID_QUIET: 712 if (!elems->quiet_elem) { 713 elems->quiet_elem = pos; 714 elems->quiet_elem_len = elen; 715 } 716 elems->num_of_quiet_elem++; 717 break; 718 case WLAN_EID_COUNTRY: 719 elems->country_elem = pos; 720 elems->country_elem_len = elen; 721 break; 722 case WLAN_EID_PWR_CONSTRAINT: 723 elems->pwr_constr_elem = pos; 724 elems->pwr_constr_elem_len = elen; 725 break; 726 case WLAN_EID_TIMEOUT_INTERVAL: 727 elems->timeout_int = pos; 728 elems->timeout_int_len = elen; 729 break; 730 default: 731 break; 732 } 733 734 left -= elen; 735 pos += elen; 736 } 737 738 return crc; 739 } 740 741 void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata) 742 { 743 struct ieee80211_local *local = sdata->local; 744 struct ieee80211_tx_queue_params qparam; 745 int queue; 746 bool use_11b; 747 int aCWmin, aCWmax; 748 749 if (!local->ops->conf_tx) 750 return; 751 752 memset(&qparam, 0, sizeof(qparam)); 753 754 use_11b = (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ) && 755 !(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE); 756 757 for (queue = 0; queue < local_to_hw(local)->queues; queue++) { 758 /* Set defaults according to 802.11-2007 Table 7-37 */ 759 aCWmax = 1023; 760 if (use_11b) 761 aCWmin = 31; 762 else 763 aCWmin = 15; 764 765 switch (queue) { 766 case 3: /* AC_BK */ 767 qparam.cw_max = aCWmax; 768 qparam.cw_min = aCWmin; 769 qparam.txop = 0; 770 qparam.aifs = 7; 771 break; 772 default: /* never happens but let's not leave undefined */ 773 case 2: /* AC_BE */ 774 qparam.cw_max = aCWmax; 775 qparam.cw_min = aCWmin; 776 qparam.txop = 0; 777 qparam.aifs = 3; 778 break; 779 case 1: /* AC_VI */ 780 qparam.cw_max = aCWmin; 781 qparam.cw_min = (aCWmin + 1) / 2 - 1; 782 if (use_11b) 783 qparam.txop = 6016/32; 784 else 785 qparam.txop = 3008/32; 786 qparam.aifs = 2; 787 break; 788 case 0: /* AC_VO */ 789 qparam.cw_max = (aCWmin + 1) / 2 - 1; 790 qparam.cw_min = (aCWmin + 1) / 4 - 1; 791 if (use_11b) 792 qparam.txop = 3264/32; 793 else 794 qparam.txop = 1504/32; 795 qparam.aifs = 2; 796 break; 797 } 798 799 qparam.uapsd = false; 800 801 drv_conf_tx(local, queue, &qparam); 802 } 803 804 /* after reinitialize QoS TX queues setting to default, 805 * disable QoS at all */ 806 local->hw.conf.flags &= ~IEEE80211_CONF_QOS; 807 drv_config(local, IEEE80211_CONF_CHANGE_QOS); 808 } 809 810 void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, 811 const size_t supp_rates_len, 812 const u8 *supp_rates) 813 { 814 struct ieee80211_local *local = sdata->local; 815 int i, have_higher_than_11mbit = 0; 816 817 /* cf. IEEE 802.11 9.2.12 */ 818 for (i = 0; i < supp_rates_len; i++) 819 if ((supp_rates[i] & 0x7f) * 5 > 110) 820 have_higher_than_11mbit = 1; 821 822 if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ && 823 have_higher_than_11mbit) 824 sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE; 825 else 826 sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE; 827 828 ieee80211_set_wmm_default(sdata); 829 } 830 831 u32 ieee80211_mandatory_rates(struct ieee80211_local *local, 832 enum ieee80211_band band) 833 { 834 struct ieee80211_supported_band *sband; 835 struct ieee80211_rate *bitrates; 836 u32 mandatory_rates; 837 enum ieee80211_rate_flags mandatory_flag; 838 int i; 839 840 sband = local->hw.wiphy->bands[band]; 841 if (!sband) { 842 WARN_ON(1); 843 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 844 } 845 846 if (band == IEEE80211_BAND_2GHZ) 847 mandatory_flag = IEEE80211_RATE_MANDATORY_B; 848 else 849 mandatory_flag = IEEE80211_RATE_MANDATORY_A; 850 851 bitrates = sband->bitrates; 852 mandatory_rates = 0; 853 for (i = 0; i < sband->n_bitrates; i++) 854 if (bitrates[i].flags & mandatory_flag) 855 mandatory_rates |= BIT(i); 856 return mandatory_rates; 857 } 858 859 void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, 860 u16 transaction, u16 auth_alg, 861 u8 *extra, size_t extra_len, const u8 *bssid, 862 const u8 *key, u8 key_len, u8 key_idx) 863 { 864 struct ieee80211_local *local = sdata->local; 865 struct sk_buff *skb; 866 struct ieee80211_mgmt *mgmt; 867 int err; 868 869 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 870 sizeof(*mgmt) + 6 + extra_len); 871 if (!skb) { 872 printk(KERN_DEBUG "%s: failed to allocate buffer for auth " 873 "frame\n", sdata->name); 874 return; 875 } 876 skb_reserve(skb, local->hw.extra_tx_headroom); 877 878 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24 + 6); 879 memset(mgmt, 0, 24 + 6); 880 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 881 IEEE80211_STYPE_AUTH); 882 memcpy(mgmt->da, bssid, ETH_ALEN); 883 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); 884 memcpy(mgmt->bssid, bssid, ETH_ALEN); 885 mgmt->u.auth.auth_alg = cpu_to_le16(auth_alg); 886 mgmt->u.auth.auth_transaction = cpu_to_le16(transaction); 887 mgmt->u.auth.status_code = cpu_to_le16(0); 888 if (extra) 889 memcpy(skb_put(skb, extra_len), extra, extra_len); 890 891 if (auth_alg == WLAN_AUTH_SHARED_KEY && transaction == 3) { 892 mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); 893 err = ieee80211_wep_encrypt(local, skb, key, key_len, key_idx); 894 WARN_ON(err); 895 } 896 897 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 898 ieee80211_tx_skb(sdata, skb); 899 } 900 901 int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, 902 const u8 *ie, size_t ie_len, 903 enum ieee80211_band band) 904 { 905 struct ieee80211_supported_band *sband; 906 u8 *pos; 907 size_t offset = 0, noffset; 908 int supp_rates_len, i; 909 910 sband = local->hw.wiphy->bands[band]; 911 912 pos = buffer; 913 914 supp_rates_len = min_t(int, sband->n_bitrates, 8); 915 916 *pos++ = WLAN_EID_SUPP_RATES; 917 *pos++ = supp_rates_len; 918 919 for (i = 0; i < supp_rates_len; i++) { 920 int rate = sband->bitrates[i].bitrate; 921 *pos++ = (u8) (rate / 5); 922 } 923 924 /* insert "request information" if in custom IEs */ 925 if (ie && ie_len) { 926 static const u8 before_extrates[] = { 927 WLAN_EID_SSID, 928 WLAN_EID_SUPP_RATES, 929 WLAN_EID_REQUEST, 930 }; 931 noffset = ieee80211_ie_split(ie, ie_len, 932 before_extrates, 933 ARRAY_SIZE(before_extrates), 934 offset); 935 memcpy(pos, ie + offset, noffset - offset); 936 pos += noffset - offset; 937 offset = noffset; 938 } 939 940 if (sband->n_bitrates > i) { 941 *pos++ = WLAN_EID_EXT_SUPP_RATES; 942 *pos++ = sband->n_bitrates - i; 943 944 for (; i < sband->n_bitrates; i++) { 945 int rate = sband->bitrates[i].bitrate; 946 *pos++ = (u8) (rate / 5); 947 } 948 } 949 950 /* insert custom IEs that go before HT */ 951 if (ie && ie_len) { 952 static const u8 before_ht[] = { 953 WLAN_EID_SSID, 954 WLAN_EID_SUPP_RATES, 955 WLAN_EID_REQUEST, 956 WLAN_EID_EXT_SUPP_RATES, 957 WLAN_EID_DS_PARAMS, 958 WLAN_EID_SUPPORTED_REGULATORY_CLASSES, 959 }; 960 noffset = ieee80211_ie_split(ie, ie_len, 961 before_ht, ARRAY_SIZE(before_ht), 962 offset); 963 memcpy(pos, ie + offset, noffset - offset); 964 pos += noffset - offset; 965 offset = noffset; 966 } 967 968 if (sband->ht_cap.ht_supported) { 969 u16 cap = sband->ht_cap.cap; 970 __le16 tmp; 971 972 if (ieee80211_disable_40mhz_24ghz && 973 sband->band == IEEE80211_BAND_2GHZ) { 974 cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; 975 cap &= ~IEEE80211_HT_CAP_SGI_40; 976 } 977 978 *pos++ = WLAN_EID_HT_CAPABILITY; 979 *pos++ = sizeof(struct ieee80211_ht_cap); 980 memset(pos, 0, sizeof(struct ieee80211_ht_cap)); 981 tmp = cpu_to_le16(cap); 982 memcpy(pos, &tmp, sizeof(u16)); 983 pos += sizeof(u16); 984 *pos++ = sband->ht_cap.ampdu_factor | 985 (sband->ht_cap.ampdu_density << 986 IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT); 987 memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs)); 988 pos += sizeof(sband->ht_cap.mcs); 989 pos += 2 + 4 + 1; /* ext info, BF cap, antsel */ 990 } 991 992 /* 993 * If adding more here, adjust code in main.c 994 * that calculates local->scan_ies_len. 995 */ 996 997 /* add any remaining custom IEs */ 998 if (ie && ie_len) { 999 noffset = ie_len; 1000 memcpy(pos, ie + offset, noffset - offset); 1001 pos += noffset - offset; 1002 } 1003 1004 return pos - buffer; 1005 } 1006 1007 void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, 1008 const u8 *ssid, size_t ssid_len, 1009 const u8 *ie, size_t ie_len) 1010 { 1011 struct ieee80211_local *local = sdata->local; 1012 struct sk_buff *skb; 1013 struct ieee80211_mgmt *mgmt; 1014 size_t buf_len; 1015 u8 *buf; 1016 1017 /* FIXME: come up with a proper value */ 1018 buf = kmalloc(200 + ie_len, GFP_KERNEL); 1019 if (!buf) { 1020 printk(KERN_DEBUG "%s: failed to allocate temporary IE " 1021 "buffer\n", sdata->name); 1022 return; 1023 } 1024 1025 buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len, 1026 local->hw.conf.channel->band); 1027 1028 skb = ieee80211_probereq_get(&local->hw, &sdata->vif, 1029 ssid, ssid_len, 1030 buf, buf_len); 1031 1032 if (dst) { 1033 mgmt = (struct ieee80211_mgmt *) skb->data; 1034 memcpy(mgmt->da, dst, ETH_ALEN); 1035 memcpy(mgmt->bssid, dst, ETH_ALEN); 1036 } 1037 1038 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 1039 ieee80211_tx_skb(sdata, skb); 1040 kfree(buf); 1041 } 1042 1043 u32 ieee80211_sta_get_rates(struct ieee80211_local *local, 1044 struct ieee802_11_elems *elems, 1045 enum ieee80211_band band) 1046 { 1047 struct ieee80211_supported_band *sband; 1048 struct ieee80211_rate *bitrates; 1049 size_t num_rates; 1050 u32 supp_rates; 1051 int i, j; 1052 sband = local->hw.wiphy->bands[band]; 1053 1054 if (!sband) { 1055 WARN_ON(1); 1056 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 1057 } 1058 1059 bitrates = sband->bitrates; 1060 num_rates = sband->n_bitrates; 1061 supp_rates = 0; 1062 for (i = 0; i < elems->supp_rates_len + 1063 elems->ext_supp_rates_len; i++) { 1064 u8 rate = 0; 1065 int own_rate; 1066 if (i < elems->supp_rates_len) 1067 rate = elems->supp_rates[i]; 1068 else if (elems->ext_supp_rates) 1069 rate = elems->ext_supp_rates 1070 [i - elems->supp_rates_len]; 1071 own_rate = 5 * (rate & 0x7f); 1072 for (j = 0; j < num_rates; j++) 1073 if (bitrates[j].bitrate == own_rate) 1074 supp_rates |= BIT(j); 1075 } 1076 return supp_rates; 1077 } 1078 1079 void ieee80211_stop_device(struct ieee80211_local *local) 1080 { 1081 ieee80211_led_radio(local, false); 1082 1083 cancel_work_sync(&local->reconfig_filter); 1084 1085 flush_workqueue(local->workqueue); 1086 drv_stop(local); 1087 } 1088 1089 int ieee80211_reconfig(struct ieee80211_local *local) 1090 { 1091 struct ieee80211_hw *hw = &local->hw; 1092 struct ieee80211_sub_if_data *sdata; 1093 struct sta_info *sta; 1094 int res; 1095 1096 if (local->suspended) 1097 local->resuming = true; 1098 1099 /* restart hardware */ 1100 if (local->open_count) { 1101 /* 1102 * Upon resume hardware can sometimes be goofy due to 1103 * various platform / driver / bus issues, so restarting 1104 * the device may at times not work immediately. Propagate 1105 * the error. 1106 */ 1107 res = drv_start(local); 1108 if (res) { 1109 WARN(local->suspended, "Hardware became unavailable " 1110 "upon resume. This could be a software issue " 1111 "prior to suspend or a hardware issue.\n"); 1112 return res; 1113 } 1114 1115 ieee80211_led_radio(local, true); 1116 } 1117 1118 /* add interfaces */ 1119 list_for_each_entry(sdata, &local->interfaces, list) { 1120 if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && 1121 sdata->vif.type != NL80211_IFTYPE_MONITOR && 1122 ieee80211_sdata_running(sdata)) 1123 res = drv_add_interface(local, &sdata->vif); 1124 } 1125 1126 /* add STAs back */ 1127 mutex_lock(&local->sta_mtx); 1128 list_for_each_entry(sta, &local->sta_list, list) { 1129 if (sta->uploaded) { 1130 sdata = sta->sdata; 1131 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 1132 sdata = container_of(sdata->bss, 1133 struct ieee80211_sub_if_data, 1134 u.ap); 1135 1136 WARN_ON(drv_sta_add(local, sdata, &sta->sta)); 1137 } 1138 } 1139 mutex_unlock(&local->sta_mtx); 1140 1141 /* Clear Suspend state so that ADDBA requests can be processed */ 1142 1143 rcu_read_lock(); 1144 1145 if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) { 1146 list_for_each_entry_rcu(sta, &local->sta_list, list) { 1147 clear_sta_flags(sta, WLAN_STA_BLOCK_BA); 1148 } 1149 } 1150 1151 rcu_read_unlock(); 1152 1153 /* setup RTS threshold */ 1154 drv_set_rts_threshold(local, hw->wiphy->rts_threshold); 1155 1156 /* reconfigure hardware */ 1157 ieee80211_hw_config(local, ~0); 1158 1159 ieee80211_configure_filter(local); 1160 1161 /* Finally also reconfigure all the BSS information */ 1162 list_for_each_entry(sdata, &local->interfaces, list) { 1163 u32 changed; 1164 1165 if (!ieee80211_sdata_running(sdata)) 1166 continue; 1167 1168 /* common change flags for all interface types */ 1169 changed = BSS_CHANGED_ERP_CTS_PROT | 1170 BSS_CHANGED_ERP_PREAMBLE | 1171 BSS_CHANGED_ERP_SLOT | 1172 BSS_CHANGED_HT | 1173 BSS_CHANGED_BASIC_RATES | 1174 BSS_CHANGED_BEACON_INT | 1175 BSS_CHANGED_BSSID | 1176 BSS_CHANGED_CQM; 1177 1178 switch (sdata->vif.type) { 1179 case NL80211_IFTYPE_STATION: 1180 changed |= BSS_CHANGED_ASSOC; 1181 ieee80211_bss_info_change_notify(sdata, changed); 1182 break; 1183 case NL80211_IFTYPE_ADHOC: 1184 changed |= BSS_CHANGED_IBSS; 1185 /* fall through */ 1186 case NL80211_IFTYPE_AP: 1187 case NL80211_IFTYPE_MESH_POINT: 1188 changed |= BSS_CHANGED_BEACON | 1189 BSS_CHANGED_BEACON_ENABLED; 1190 ieee80211_bss_info_change_notify(sdata, changed); 1191 break; 1192 case NL80211_IFTYPE_WDS: 1193 break; 1194 case NL80211_IFTYPE_AP_VLAN: 1195 case NL80211_IFTYPE_MONITOR: 1196 /* ignore virtual */ 1197 break; 1198 case NL80211_IFTYPE_UNSPECIFIED: 1199 case __NL80211_IFTYPE_AFTER_LAST: 1200 WARN_ON(1); 1201 break; 1202 } 1203 } 1204 1205 rcu_read_lock(); 1206 if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) { 1207 list_for_each_entry_rcu(sta, &local->sta_list, list) { 1208 ieee80211_sta_tear_down_BA_sessions(sta); 1209 } 1210 } 1211 rcu_read_unlock(); 1212 1213 /* add back keys */ 1214 list_for_each_entry(sdata, &local->interfaces, list) 1215 if (ieee80211_sdata_running(sdata)) 1216 ieee80211_enable_keys(sdata); 1217 1218 ieee80211_wake_queues_by_reason(hw, 1219 IEEE80211_QUEUE_STOP_REASON_SUSPEND); 1220 1221 /* 1222 * If this is for hw restart things are still running. 1223 * We may want to change that later, however. 1224 */ 1225 if (!local->suspended) 1226 return 0; 1227 1228 #ifdef CONFIG_PM 1229 /* first set suspended false, then resuming */ 1230 local->suspended = false; 1231 mb(); 1232 local->resuming = false; 1233 1234 list_for_each_entry(sdata, &local->interfaces, list) { 1235 switch(sdata->vif.type) { 1236 case NL80211_IFTYPE_STATION: 1237 ieee80211_sta_restart(sdata); 1238 break; 1239 case NL80211_IFTYPE_ADHOC: 1240 ieee80211_ibss_restart(sdata); 1241 break; 1242 case NL80211_IFTYPE_MESH_POINT: 1243 ieee80211_mesh_restart(sdata); 1244 break; 1245 default: 1246 break; 1247 } 1248 } 1249 1250 add_timer(&local->sta_cleanup); 1251 1252 mutex_lock(&local->sta_mtx); 1253 list_for_each_entry(sta, &local->sta_list, list) 1254 mesh_plink_restart(sta); 1255 mutex_unlock(&local->sta_mtx); 1256 #else 1257 WARN_ON(1); 1258 #endif 1259 return 0; 1260 } 1261 1262 static int check_mgd_smps(struct ieee80211_if_managed *ifmgd, 1263 enum ieee80211_smps_mode *smps_mode) 1264 { 1265 if (ifmgd->associated) { 1266 *smps_mode = ifmgd->ap_smps; 1267 1268 if (*smps_mode == IEEE80211_SMPS_AUTOMATIC) { 1269 if (ifmgd->powersave) 1270 *smps_mode = IEEE80211_SMPS_DYNAMIC; 1271 else 1272 *smps_mode = IEEE80211_SMPS_OFF; 1273 } 1274 1275 return 1; 1276 } 1277 1278 return 0; 1279 } 1280 1281 /* must hold iflist_mtx */ 1282 void ieee80211_recalc_smps(struct ieee80211_local *local, 1283 struct ieee80211_sub_if_data *forsdata) 1284 { 1285 struct ieee80211_sub_if_data *sdata; 1286 enum ieee80211_smps_mode smps_mode = IEEE80211_SMPS_OFF; 1287 int count = 0; 1288 1289 if (forsdata) 1290 WARN_ON(!mutex_is_locked(&forsdata->u.mgd.mtx)); 1291 1292 WARN_ON(!mutex_is_locked(&local->iflist_mtx)); 1293 1294 /* 1295 * This function could be improved to handle multiple 1296 * interfaces better, but right now it makes any 1297 * non-station interfaces force SM PS to be turned 1298 * off. If there are multiple station interfaces it 1299 * could also use the best possible mode, e.g. if 1300 * one is in static and the other in dynamic then 1301 * dynamic is ok. 1302 */ 1303 1304 list_for_each_entry(sdata, &local->interfaces, list) { 1305 if (!netif_running(sdata->dev)) 1306 continue; 1307 if (sdata->vif.type != NL80211_IFTYPE_STATION) 1308 goto set; 1309 if (sdata != forsdata) { 1310 /* 1311 * This nested is ok -- we are holding the iflist_mtx 1312 * so can't get here twice or so. But it's required 1313 * since normally we acquire it first and then the 1314 * iflist_mtx. 1315 */ 1316 mutex_lock_nested(&sdata->u.mgd.mtx, SINGLE_DEPTH_NESTING); 1317 count += check_mgd_smps(&sdata->u.mgd, &smps_mode); 1318 mutex_unlock(&sdata->u.mgd.mtx); 1319 } else 1320 count += check_mgd_smps(&sdata->u.mgd, &smps_mode); 1321 1322 if (count > 1) { 1323 smps_mode = IEEE80211_SMPS_OFF; 1324 break; 1325 } 1326 } 1327 1328 if (smps_mode == local->smps_mode) 1329 return; 1330 1331 set: 1332 local->smps_mode = smps_mode; 1333 /* changed flag is auto-detected for this */ 1334 ieee80211_hw_config(local, 0); 1335 } 1336 1337 static bool ieee80211_id_in_list(const u8 *ids, int n_ids, u8 id) 1338 { 1339 int i; 1340 1341 for (i = 0; i < n_ids; i++) 1342 if (ids[i] == id) 1343 return true; 1344 return false; 1345 } 1346 1347 /** 1348 * ieee80211_ie_split - split an IE buffer according to ordering 1349 * 1350 * @ies: the IE buffer 1351 * @ielen: the length of the IE buffer 1352 * @ids: an array with element IDs that are allowed before 1353 * the split 1354 * @n_ids: the size of the element ID array 1355 * @offset: offset where to start splitting in the buffer 1356 * 1357 * This function splits an IE buffer by updating the @offset 1358 * variable to point to the location where the buffer should be 1359 * split. 1360 * 1361 * It assumes that the given IE buffer is well-formed, this 1362 * has to be guaranteed by the caller! 1363 * 1364 * It also assumes that the IEs in the buffer are ordered 1365 * correctly, if not the result of using this function will not 1366 * be ordered correctly either, i.e. it does no reordering. 1367 * 1368 * The function returns the offset where the next part of the 1369 * buffer starts, which may be @ielen if the entire (remainder) 1370 * of the buffer should be used. 1371 */ 1372 size_t ieee80211_ie_split(const u8 *ies, size_t ielen, 1373 const u8 *ids, int n_ids, size_t offset) 1374 { 1375 size_t pos = offset; 1376 1377 while (pos < ielen && ieee80211_id_in_list(ids, n_ids, ies[pos])) 1378 pos += 2 + ies[pos + 1]; 1379 1380 return pos; 1381 } 1382 1383 size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset) 1384 { 1385 size_t pos = offset; 1386 1387 while (pos < ielen && ies[pos] != WLAN_EID_VENDOR_SPECIFIC) 1388 pos += 2 + ies[pos + 1]; 1389 1390 return pos; 1391 } 1392