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 807 if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { 808 sdata->vif.bss_conf.qos = 809 sdata->vif.type != NL80211_IFTYPE_STATION; 810 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_QOS); 811 } 812 } 813 814 void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, 815 const size_t supp_rates_len, 816 const u8 *supp_rates) 817 { 818 struct ieee80211_local *local = sdata->local; 819 int i, have_higher_than_11mbit = 0; 820 821 /* cf. IEEE 802.11 9.2.12 */ 822 for (i = 0; i < supp_rates_len; i++) 823 if ((supp_rates[i] & 0x7f) * 5 > 110) 824 have_higher_than_11mbit = 1; 825 826 if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ && 827 have_higher_than_11mbit) 828 sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE; 829 else 830 sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE; 831 832 ieee80211_set_wmm_default(sdata); 833 } 834 835 u32 ieee80211_mandatory_rates(struct ieee80211_local *local, 836 enum ieee80211_band band) 837 { 838 struct ieee80211_supported_band *sband; 839 struct ieee80211_rate *bitrates; 840 u32 mandatory_rates; 841 enum ieee80211_rate_flags mandatory_flag; 842 int i; 843 844 sband = local->hw.wiphy->bands[band]; 845 if (!sband) { 846 WARN_ON(1); 847 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 848 } 849 850 if (band == IEEE80211_BAND_2GHZ) 851 mandatory_flag = IEEE80211_RATE_MANDATORY_B; 852 else 853 mandatory_flag = IEEE80211_RATE_MANDATORY_A; 854 855 bitrates = sband->bitrates; 856 mandatory_rates = 0; 857 for (i = 0; i < sband->n_bitrates; i++) 858 if (bitrates[i].flags & mandatory_flag) 859 mandatory_rates |= BIT(i); 860 return mandatory_rates; 861 } 862 863 void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, 864 u16 transaction, u16 auth_alg, 865 u8 *extra, size_t extra_len, const u8 *bssid, 866 const u8 *key, u8 key_len, u8 key_idx) 867 { 868 struct ieee80211_local *local = sdata->local; 869 struct sk_buff *skb; 870 struct ieee80211_mgmt *mgmt; 871 int err; 872 873 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 874 sizeof(*mgmt) + 6 + extra_len); 875 if (!skb) { 876 printk(KERN_DEBUG "%s: failed to allocate buffer for auth " 877 "frame\n", sdata->name); 878 return; 879 } 880 skb_reserve(skb, local->hw.extra_tx_headroom); 881 882 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24 + 6); 883 memset(mgmt, 0, 24 + 6); 884 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 885 IEEE80211_STYPE_AUTH); 886 memcpy(mgmt->da, bssid, ETH_ALEN); 887 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); 888 memcpy(mgmt->bssid, bssid, ETH_ALEN); 889 mgmt->u.auth.auth_alg = cpu_to_le16(auth_alg); 890 mgmt->u.auth.auth_transaction = cpu_to_le16(transaction); 891 mgmt->u.auth.status_code = cpu_to_le16(0); 892 if (extra) 893 memcpy(skb_put(skb, extra_len), extra, extra_len); 894 895 if (auth_alg == WLAN_AUTH_SHARED_KEY && transaction == 3) { 896 mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); 897 err = ieee80211_wep_encrypt(local, skb, key, key_len, key_idx); 898 WARN_ON(err); 899 } 900 901 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 902 ieee80211_tx_skb(sdata, skb); 903 } 904 905 int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, 906 const u8 *ie, size_t ie_len, 907 enum ieee80211_band band) 908 { 909 struct ieee80211_supported_band *sband; 910 u8 *pos; 911 size_t offset = 0, noffset; 912 int supp_rates_len, i; 913 914 sband = local->hw.wiphy->bands[band]; 915 916 pos = buffer; 917 918 supp_rates_len = min_t(int, sband->n_bitrates, 8); 919 920 *pos++ = WLAN_EID_SUPP_RATES; 921 *pos++ = supp_rates_len; 922 923 for (i = 0; i < supp_rates_len; i++) { 924 int rate = sband->bitrates[i].bitrate; 925 *pos++ = (u8) (rate / 5); 926 } 927 928 /* insert "request information" if in custom IEs */ 929 if (ie && ie_len) { 930 static const u8 before_extrates[] = { 931 WLAN_EID_SSID, 932 WLAN_EID_SUPP_RATES, 933 WLAN_EID_REQUEST, 934 }; 935 noffset = ieee80211_ie_split(ie, ie_len, 936 before_extrates, 937 ARRAY_SIZE(before_extrates), 938 offset); 939 memcpy(pos, ie + offset, noffset - offset); 940 pos += noffset - offset; 941 offset = noffset; 942 } 943 944 if (sband->n_bitrates > i) { 945 *pos++ = WLAN_EID_EXT_SUPP_RATES; 946 *pos++ = sband->n_bitrates - i; 947 948 for (; i < sband->n_bitrates; i++) { 949 int rate = sband->bitrates[i].bitrate; 950 *pos++ = (u8) (rate / 5); 951 } 952 } 953 954 /* insert custom IEs that go before HT */ 955 if (ie && ie_len) { 956 static const u8 before_ht[] = { 957 WLAN_EID_SSID, 958 WLAN_EID_SUPP_RATES, 959 WLAN_EID_REQUEST, 960 WLAN_EID_EXT_SUPP_RATES, 961 WLAN_EID_DS_PARAMS, 962 WLAN_EID_SUPPORTED_REGULATORY_CLASSES, 963 }; 964 noffset = ieee80211_ie_split(ie, ie_len, 965 before_ht, ARRAY_SIZE(before_ht), 966 offset); 967 memcpy(pos, ie + offset, noffset - offset); 968 pos += noffset - offset; 969 offset = noffset; 970 } 971 972 if (sband->ht_cap.ht_supported) { 973 u16 cap = sband->ht_cap.cap; 974 __le16 tmp; 975 976 if (ieee80211_disable_40mhz_24ghz && 977 sband->band == IEEE80211_BAND_2GHZ) { 978 cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; 979 cap &= ~IEEE80211_HT_CAP_SGI_40; 980 } 981 982 *pos++ = WLAN_EID_HT_CAPABILITY; 983 *pos++ = sizeof(struct ieee80211_ht_cap); 984 memset(pos, 0, sizeof(struct ieee80211_ht_cap)); 985 tmp = cpu_to_le16(cap); 986 memcpy(pos, &tmp, sizeof(u16)); 987 pos += sizeof(u16); 988 *pos++ = sband->ht_cap.ampdu_factor | 989 (sband->ht_cap.ampdu_density << 990 IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT); 991 memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs)); 992 pos += sizeof(sband->ht_cap.mcs); 993 pos += 2 + 4 + 1; /* ext info, BF cap, antsel */ 994 } 995 996 /* 997 * If adding more here, adjust code in main.c 998 * that calculates local->scan_ies_len. 999 */ 1000 1001 /* add any remaining custom IEs */ 1002 if (ie && ie_len) { 1003 noffset = ie_len; 1004 memcpy(pos, ie + offset, noffset - offset); 1005 pos += noffset - offset; 1006 } 1007 1008 return pos - buffer; 1009 } 1010 1011 void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, 1012 const u8 *ssid, size_t ssid_len, 1013 const u8 *ie, size_t ie_len) 1014 { 1015 struct ieee80211_local *local = sdata->local; 1016 struct sk_buff *skb; 1017 struct ieee80211_mgmt *mgmt; 1018 size_t buf_len; 1019 u8 *buf; 1020 1021 /* FIXME: come up with a proper value */ 1022 buf = kmalloc(200 + ie_len, GFP_KERNEL); 1023 if (!buf) { 1024 printk(KERN_DEBUG "%s: failed to allocate temporary IE " 1025 "buffer\n", sdata->name); 1026 return; 1027 } 1028 1029 buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len, 1030 local->hw.conf.channel->band); 1031 1032 skb = ieee80211_probereq_get(&local->hw, &sdata->vif, 1033 ssid, ssid_len, 1034 buf, buf_len); 1035 1036 if (dst) { 1037 mgmt = (struct ieee80211_mgmt *) skb->data; 1038 memcpy(mgmt->da, dst, ETH_ALEN); 1039 memcpy(mgmt->bssid, dst, ETH_ALEN); 1040 } 1041 1042 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 1043 ieee80211_tx_skb(sdata, skb); 1044 kfree(buf); 1045 } 1046 1047 u32 ieee80211_sta_get_rates(struct ieee80211_local *local, 1048 struct ieee802_11_elems *elems, 1049 enum ieee80211_band band) 1050 { 1051 struct ieee80211_supported_band *sband; 1052 struct ieee80211_rate *bitrates; 1053 size_t num_rates; 1054 u32 supp_rates; 1055 int i, j; 1056 sband = local->hw.wiphy->bands[band]; 1057 1058 if (!sband) { 1059 WARN_ON(1); 1060 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 1061 } 1062 1063 bitrates = sband->bitrates; 1064 num_rates = sband->n_bitrates; 1065 supp_rates = 0; 1066 for (i = 0; i < elems->supp_rates_len + 1067 elems->ext_supp_rates_len; i++) { 1068 u8 rate = 0; 1069 int own_rate; 1070 if (i < elems->supp_rates_len) 1071 rate = elems->supp_rates[i]; 1072 else if (elems->ext_supp_rates) 1073 rate = elems->ext_supp_rates 1074 [i - elems->supp_rates_len]; 1075 own_rate = 5 * (rate & 0x7f); 1076 for (j = 0; j < num_rates; j++) 1077 if (bitrates[j].bitrate == own_rate) 1078 supp_rates |= BIT(j); 1079 } 1080 return supp_rates; 1081 } 1082 1083 void ieee80211_stop_device(struct ieee80211_local *local) 1084 { 1085 ieee80211_led_radio(local, false); 1086 1087 cancel_work_sync(&local->reconfig_filter); 1088 1089 flush_workqueue(local->workqueue); 1090 drv_stop(local); 1091 } 1092 1093 int ieee80211_reconfig(struct ieee80211_local *local) 1094 { 1095 struct ieee80211_hw *hw = &local->hw; 1096 struct ieee80211_sub_if_data *sdata; 1097 struct sta_info *sta; 1098 int res; 1099 1100 if (local->suspended) 1101 local->resuming = true; 1102 1103 /* restart hardware */ 1104 if (local->open_count) { 1105 /* 1106 * Upon resume hardware can sometimes be goofy due to 1107 * various platform / driver / bus issues, so restarting 1108 * the device may at times not work immediately. Propagate 1109 * the error. 1110 */ 1111 res = drv_start(local); 1112 if (res) { 1113 WARN(local->suspended, "Hardware became unavailable " 1114 "upon resume. This could be a software issue " 1115 "prior to suspend or a hardware issue.\n"); 1116 return res; 1117 } 1118 1119 ieee80211_led_radio(local, true); 1120 } 1121 1122 /* add interfaces */ 1123 list_for_each_entry(sdata, &local->interfaces, list) { 1124 if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && 1125 sdata->vif.type != NL80211_IFTYPE_MONITOR && 1126 ieee80211_sdata_running(sdata)) 1127 res = drv_add_interface(local, &sdata->vif); 1128 } 1129 1130 /* add STAs back */ 1131 mutex_lock(&local->sta_mtx); 1132 list_for_each_entry(sta, &local->sta_list, list) { 1133 if (sta->uploaded) { 1134 sdata = sta->sdata; 1135 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 1136 sdata = container_of(sdata->bss, 1137 struct ieee80211_sub_if_data, 1138 u.ap); 1139 1140 WARN_ON(drv_sta_add(local, sdata, &sta->sta)); 1141 } 1142 } 1143 mutex_unlock(&local->sta_mtx); 1144 1145 /* setup RTS threshold */ 1146 drv_set_rts_threshold(local, hw->wiphy->rts_threshold); 1147 1148 /* reconfigure hardware */ 1149 ieee80211_hw_config(local, ~0); 1150 1151 ieee80211_configure_filter(local); 1152 1153 /* Finally also reconfigure all the BSS information */ 1154 list_for_each_entry(sdata, &local->interfaces, list) { 1155 u32 changed; 1156 1157 if (!ieee80211_sdata_running(sdata)) 1158 continue; 1159 1160 /* common change flags for all interface types */ 1161 changed = BSS_CHANGED_ERP_CTS_PROT | 1162 BSS_CHANGED_ERP_PREAMBLE | 1163 BSS_CHANGED_ERP_SLOT | 1164 BSS_CHANGED_HT | 1165 BSS_CHANGED_BASIC_RATES | 1166 BSS_CHANGED_BEACON_INT | 1167 BSS_CHANGED_BSSID | 1168 BSS_CHANGED_CQM | 1169 BSS_CHANGED_QOS; 1170 1171 switch (sdata->vif.type) { 1172 case NL80211_IFTYPE_STATION: 1173 changed |= BSS_CHANGED_ASSOC; 1174 ieee80211_bss_info_change_notify(sdata, changed); 1175 break; 1176 case NL80211_IFTYPE_ADHOC: 1177 changed |= BSS_CHANGED_IBSS; 1178 /* fall through */ 1179 case NL80211_IFTYPE_AP: 1180 case NL80211_IFTYPE_MESH_POINT: 1181 changed |= BSS_CHANGED_BEACON | 1182 BSS_CHANGED_BEACON_ENABLED; 1183 ieee80211_bss_info_change_notify(sdata, changed); 1184 break; 1185 case NL80211_IFTYPE_WDS: 1186 break; 1187 case NL80211_IFTYPE_AP_VLAN: 1188 case NL80211_IFTYPE_MONITOR: 1189 /* ignore virtual */ 1190 break; 1191 case NL80211_IFTYPE_UNSPECIFIED: 1192 case __NL80211_IFTYPE_AFTER_LAST: 1193 WARN_ON(1); 1194 break; 1195 } 1196 } 1197 1198 /* 1199 * Clear the WLAN_STA_BLOCK_BA flag so new aggregation 1200 * sessions can be established after a resume. 1201 * 1202 * Also tear down aggregation sessions since reconfiguring 1203 * them in a hardware restart scenario is not easily done 1204 * right now, and the hardware will have lost information 1205 * about the sessions, but we and the AP still think they 1206 * are active. This is really a workaround though. 1207 */ 1208 if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) { 1209 mutex_lock(&local->sta_mtx); 1210 1211 list_for_each_entry(sta, &local->sta_list, list) { 1212 ieee80211_sta_tear_down_BA_sessions(sta); 1213 clear_sta_flags(sta, WLAN_STA_BLOCK_BA); 1214 } 1215 1216 mutex_unlock(&local->sta_mtx); 1217 } 1218 1219 /* add back keys */ 1220 list_for_each_entry(sdata, &local->interfaces, list) 1221 if (ieee80211_sdata_running(sdata)) 1222 ieee80211_enable_keys(sdata); 1223 1224 ieee80211_wake_queues_by_reason(hw, 1225 IEEE80211_QUEUE_STOP_REASON_SUSPEND); 1226 1227 /* 1228 * If this is for hw restart things are still running. 1229 * We may want to change that later, however. 1230 */ 1231 if (!local->suspended) 1232 return 0; 1233 1234 #ifdef CONFIG_PM 1235 /* first set suspended false, then resuming */ 1236 local->suspended = false; 1237 mb(); 1238 local->resuming = false; 1239 1240 list_for_each_entry(sdata, &local->interfaces, list) { 1241 switch(sdata->vif.type) { 1242 case NL80211_IFTYPE_STATION: 1243 ieee80211_sta_restart(sdata); 1244 break; 1245 case NL80211_IFTYPE_ADHOC: 1246 ieee80211_ibss_restart(sdata); 1247 break; 1248 case NL80211_IFTYPE_MESH_POINT: 1249 ieee80211_mesh_restart(sdata); 1250 break; 1251 default: 1252 break; 1253 } 1254 } 1255 1256 add_timer(&local->sta_cleanup); 1257 1258 mutex_lock(&local->sta_mtx); 1259 list_for_each_entry(sta, &local->sta_list, list) 1260 mesh_plink_restart(sta); 1261 mutex_unlock(&local->sta_mtx); 1262 #else 1263 WARN_ON(1); 1264 #endif 1265 return 0; 1266 } 1267 1268 static int check_mgd_smps(struct ieee80211_if_managed *ifmgd, 1269 enum ieee80211_smps_mode *smps_mode) 1270 { 1271 if (ifmgd->associated) { 1272 *smps_mode = ifmgd->ap_smps; 1273 1274 if (*smps_mode == IEEE80211_SMPS_AUTOMATIC) { 1275 if (ifmgd->powersave) 1276 *smps_mode = IEEE80211_SMPS_DYNAMIC; 1277 else 1278 *smps_mode = IEEE80211_SMPS_OFF; 1279 } 1280 1281 return 1; 1282 } 1283 1284 return 0; 1285 } 1286 1287 /* must hold iflist_mtx */ 1288 void ieee80211_recalc_smps(struct ieee80211_local *local, 1289 struct ieee80211_sub_if_data *forsdata) 1290 { 1291 struct ieee80211_sub_if_data *sdata; 1292 enum ieee80211_smps_mode smps_mode = IEEE80211_SMPS_OFF; 1293 int count = 0; 1294 1295 if (forsdata) 1296 WARN_ON(!mutex_is_locked(&forsdata->u.mgd.mtx)); 1297 1298 WARN_ON(!mutex_is_locked(&local->iflist_mtx)); 1299 1300 /* 1301 * This function could be improved to handle multiple 1302 * interfaces better, but right now it makes any 1303 * non-station interfaces force SM PS to be turned 1304 * off. If there are multiple station interfaces it 1305 * could also use the best possible mode, e.g. if 1306 * one is in static and the other in dynamic then 1307 * dynamic is ok. 1308 */ 1309 1310 list_for_each_entry(sdata, &local->interfaces, list) { 1311 if (!netif_running(sdata->dev)) 1312 continue; 1313 if (sdata->vif.type != NL80211_IFTYPE_STATION) 1314 goto set; 1315 if (sdata != forsdata) { 1316 /* 1317 * This nested is ok -- we are holding the iflist_mtx 1318 * so can't get here twice or so. But it's required 1319 * since normally we acquire it first and then the 1320 * iflist_mtx. 1321 */ 1322 mutex_lock_nested(&sdata->u.mgd.mtx, SINGLE_DEPTH_NESTING); 1323 count += check_mgd_smps(&sdata->u.mgd, &smps_mode); 1324 mutex_unlock(&sdata->u.mgd.mtx); 1325 } else 1326 count += check_mgd_smps(&sdata->u.mgd, &smps_mode); 1327 1328 if (count > 1) { 1329 smps_mode = IEEE80211_SMPS_OFF; 1330 break; 1331 } 1332 } 1333 1334 if (smps_mode == local->smps_mode) 1335 return; 1336 1337 set: 1338 local->smps_mode = smps_mode; 1339 /* changed flag is auto-detected for this */ 1340 ieee80211_hw_config(local, 0); 1341 } 1342 1343 static bool ieee80211_id_in_list(const u8 *ids, int n_ids, u8 id) 1344 { 1345 int i; 1346 1347 for (i = 0; i < n_ids; i++) 1348 if (ids[i] == id) 1349 return true; 1350 return false; 1351 } 1352 1353 /** 1354 * ieee80211_ie_split - split an IE buffer according to ordering 1355 * 1356 * @ies: the IE buffer 1357 * @ielen: the length of the IE buffer 1358 * @ids: an array with element IDs that are allowed before 1359 * the split 1360 * @n_ids: the size of the element ID array 1361 * @offset: offset where to start splitting in the buffer 1362 * 1363 * This function splits an IE buffer by updating the @offset 1364 * variable to point to the location where the buffer should be 1365 * split. 1366 * 1367 * It assumes that the given IE buffer is well-formed, this 1368 * has to be guaranteed by the caller! 1369 * 1370 * It also assumes that the IEs in the buffer are ordered 1371 * correctly, if not the result of using this function will not 1372 * be ordered correctly either, i.e. it does no reordering. 1373 * 1374 * The function returns the offset where the next part of the 1375 * buffer starts, which may be @ielen if the entire (remainder) 1376 * of the buffer should be used. 1377 */ 1378 size_t ieee80211_ie_split(const u8 *ies, size_t ielen, 1379 const u8 *ids, int n_ids, size_t offset) 1380 { 1381 size_t pos = offset; 1382 1383 while (pos < ielen && ieee80211_id_in_list(ids, n_ids, ies[pos])) 1384 pos += 2 + ies[pos + 1]; 1385 1386 return pos; 1387 } 1388 1389 size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset) 1390 { 1391 size_t pos = offset; 1392 1393 while (pos < ielen && ies[pos] != WLAN_EID_VENDOR_SPECIFIC) 1394 pos += 2 + ies[pos + 1]; 1395 1396 return pos; 1397 } 1398