diff options
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/Makefile | 1 | ||||
-rw-r--r-- | net/mac80211/agg-rx.c | 30 | ||||
-rw-r--r-- | net/mac80211/agg-tx.c | 109 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 579 | ||||
-rw-r--r-- | net/mac80211/chan.c | 4 | ||||
-rw-r--r-- | net/mac80211/debugfs_netdev.c | 3 | ||||
-rw-r--r-- | net/mac80211/ibss.c | 114 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 92 | ||||
-rw-r--r-- | net/mac80211/iface.c | 42 | ||||
-rw-r--r-- | net/mac80211/main.c | 17 | ||||
-rw-r--r-- | net/mac80211/mesh.c | 3 | ||||
-rw-r--r-- | net/mac80211/mesh_hwmp.c | 2 | ||||
-rw-r--r-- | net/mac80211/mesh_pathtbl.c | 2 | ||||
-rw-r--r-- | net/mac80211/mesh_plink.c | 2 | ||||
-rw-r--r-- | net/mac80211/mesh_sync.c | 2 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 189 | ||||
-rw-r--r-- | net/mac80211/offchannel.c | 280 | ||||
-rw-r--r-- | net/mac80211/pm.c | 1 | ||||
-rw-r--r-- | net/mac80211/rx.c | 22 | ||||
-rw-r--r-- | net/mac80211/scan.c | 4 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 23 | ||||
-rw-r--r-- | net/mac80211/status.c | 30 | ||||
-rw-r--r-- | net/mac80211/tkip.c | 21 | ||||
-rw-r--r-- | net/mac80211/tx.c | 14 | ||||
-rw-r--r-- | net/mac80211/util.c | 117 | ||||
-rw-r--r-- | net/mac80211/work.c | 370 |
26 files changed, 885 insertions, 1188 deletions
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile index 3e9d931bba35..2b1470bac178 100644 --- a/net/mac80211/Makefile +++ b/net/mac80211/Makefile | |||
@@ -9,7 +9,6 @@ mac80211-y := \ | |||
9 | scan.o offchannel.o \ | 9 | scan.o offchannel.o \ |
10 | ht.o agg-tx.o agg-rx.o \ | 10 | ht.o agg-tx.o agg-rx.o \ |
11 | ibss.o \ | 11 | ibss.o \ |
12 | work.o \ | ||
13 | iface.o \ | 12 | iface.o \ |
14 | rate.o \ | 13 | rate.o \ |
15 | michael.o \ | 14 | michael.o \ |
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index c649188314cc..32ef11d69798 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c | |||
@@ -74,18 +74,15 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, | |||
74 | 74 | ||
75 | RCU_INIT_POINTER(sta->ampdu_mlme.tid_rx[tid], NULL); | 75 | RCU_INIT_POINTER(sta->ampdu_mlme.tid_rx[tid], NULL); |
76 | 76 | ||
77 | #ifdef CONFIG_MAC80211_HT_DEBUG | 77 | ht_vdbg("Rx BA session stop requested for %pM tid %u %s reason: %d\n", |
78 | printk(KERN_DEBUG | 78 | sta->sta.addr, tid, |
79 | "Rx BA session stop requested for %pM tid %u %s reason: %d\n", | 79 | initiator == WLAN_BACK_RECIPIENT ? "recipient" : "inititator", |
80 | sta->sta.addr, tid, | 80 | (int)reason); |
81 | initiator == WLAN_BACK_RECIPIENT ? "recipient" : "inititator", | ||
82 | (int)reason); | ||
83 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
84 | 81 | ||
85 | if (drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_RX_STOP, | 82 | if (drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_RX_STOP, |
86 | &sta->sta, tid, NULL, 0)) | 83 | &sta->sta, tid, NULL, 0)) |
87 | printk(KERN_DEBUG "HW problem - can not stop rx " | 84 | pr_debug("HW problem - can not stop rx aggregation for tid %d\n", |
88 | "aggregation for tid %d\n", tid); | 85 | tid); |
89 | 86 | ||
90 | /* check if this is a self generated aggregation halt */ | 87 | /* check if this is a self generated aggregation halt */ |
91 | if (initiator == WLAN_BACK_RECIPIENT && tx) | 88 | if (initiator == WLAN_BACK_RECIPIENT && tx) |
@@ -160,9 +157,8 @@ static void sta_rx_agg_session_timer_expired(unsigned long data) | |||
160 | } | 157 | } |
161 | rcu_read_unlock(); | 158 | rcu_read_unlock(); |
162 | 159 | ||
163 | #ifdef CONFIG_MAC80211_HT_DEBUG | 160 | ht_vdbg("rx session timer expired on tid %d\n", (u16)*ptid); |
164 | printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid); | 161 | |
165 | #endif | ||
166 | set_bit(*ptid, sta->ampdu_mlme.tid_rx_timer_expired); | 162 | set_bit(*ptid, sta->ampdu_mlme.tid_rx_timer_expired); |
167 | ieee80211_queue_work(&sta->local->hw, &sta->ampdu_mlme.work); | 163 | ieee80211_queue_work(&sta->local->hw, &sta->ampdu_mlme.work); |
168 | } | 164 | } |
@@ -249,10 +245,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, | |||
249 | status = WLAN_STATUS_REQUEST_DECLINED; | 245 | status = WLAN_STATUS_REQUEST_DECLINED; |
250 | 246 | ||
251 | if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) { | 247 | if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) { |
252 | #ifdef CONFIG_MAC80211_HT_DEBUG | 248 | ht_vdbg("Suspend in progress - Denying ADDBA request\n"); |
253 | printk(KERN_DEBUG "Suspend in progress. " | ||
254 | "Denying ADDBA request\n"); | ||
255 | #endif | ||
256 | goto end_no_lock; | 249 | goto end_no_lock; |
257 | } | 250 | } |
258 | 251 | ||
@@ -324,10 +317,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, | |||
324 | 317 | ||
325 | ret = drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_RX_START, | 318 | ret = drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_RX_START, |
326 | &sta->sta, tid, &start_seq_num, 0); | 319 | &sta->sta, tid, &start_seq_num, 0); |
327 | #ifdef CONFIG_MAC80211_HT_DEBUG | 320 | ht_vdbg("Rx A-MPDU request on tid %d result %d\n", tid, ret); |
328 | printk(KERN_DEBUG "Rx A-MPDU request on tid %d result %d\n", tid, ret); | ||
329 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
330 | |||
331 | if (ret) { | 321 | if (ret) { |
332 | kfree(tid_agg_rx->reorder_buf); | 322 | kfree(tid_agg_rx->reorder_buf); |
333 | kfree(tid_agg_rx->reorder_time); | 323 | kfree(tid_agg_rx->reorder_time); |
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index 7cf07158805c..da07f01cfe4d 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c | |||
@@ -184,10 +184,8 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | |||
184 | 184 | ||
185 | spin_unlock_bh(&sta->lock); | 185 | spin_unlock_bh(&sta->lock); |
186 | 186 | ||
187 | #ifdef CONFIG_MAC80211_HT_DEBUG | 187 | ht_vdbg("Tx BA session stop requested for %pM tid %u\n", |
188 | printk(KERN_DEBUG "Tx BA session stop requested for %pM tid %u\n", | 188 | sta->sta.addr, tid); |
189 | sta->sta.addr, tid); | ||
190 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
191 | 189 | ||
192 | del_timer_sync(&tid_tx->addba_resp_timer); | 190 | del_timer_sync(&tid_tx->addba_resp_timer); |
193 | del_timer_sync(&tid_tx->session_timer); | 191 | del_timer_sync(&tid_tx->session_timer); |
@@ -253,17 +251,12 @@ static void sta_addba_resp_timer_expired(unsigned long data) | |||
253 | if (!tid_tx || | 251 | if (!tid_tx || |
254 | test_bit(HT_AGG_STATE_RESPONSE_RECEIVED, &tid_tx->state)) { | 252 | test_bit(HT_AGG_STATE_RESPONSE_RECEIVED, &tid_tx->state)) { |
255 | rcu_read_unlock(); | 253 | rcu_read_unlock(); |
256 | #ifdef CONFIG_MAC80211_HT_DEBUG | 254 | ht_vdbg("timer expired on tid %d but we are not (or no longer) expecting addBA response there\n", |
257 | printk(KERN_DEBUG "timer expired on tid %d but we are not " | ||
258 | "(or no longer) expecting addBA response there\n", | ||
259 | tid); | 255 | tid); |
260 | #endif | ||
261 | return; | 256 | return; |
262 | } | 257 | } |
263 | 258 | ||
264 | #ifdef CONFIG_MAC80211_HT_DEBUG | 259 | ht_vdbg("addBA response timer expired on tid %d\n", tid); |
265 | printk(KERN_DEBUG "addBA response timer expired on tid %d\n", tid); | ||
266 | #endif | ||
267 | 260 | ||
268 | ieee80211_stop_tx_ba_session(&sta->sta, tid); | 261 | ieee80211_stop_tx_ba_session(&sta->sta, tid); |
269 | rcu_read_unlock(); | 262 | rcu_read_unlock(); |
@@ -372,10 +365,7 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) | |||
372 | ret = drv_ampdu_action(local, sdata, IEEE80211_AMPDU_TX_START, | 365 | ret = drv_ampdu_action(local, sdata, IEEE80211_AMPDU_TX_START, |
373 | &sta->sta, tid, &start_seq_num, 0); | 366 | &sta->sta, tid, &start_seq_num, 0); |
374 | if (ret) { | 367 | if (ret) { |
375 | #ifdef CONFIG_MAC80211_HT_DEBUG | 368 | ht_vdbg("BA request denied - HW unavailable for tid %d\n", tid); |
376 | printk(KERN_DEBUG "BA request denied - HW unavailable for" | ||
377 | " tid %d\n", tid); | ||
378 | #endif | ||
379 | spin_lock_bh(&sta->lock); | 369 | spin_lock_bh(&sta->lock); |
380 | ieee80211_agg_splice_packets(sdata, tid_tx, tid); | 370 | ieee80211_agg_splice_packets(sdata, tid_tx, tid); |
381 | ieee80211_assign_tid_tx(sta, tid, NULL); | 371 | ieee80211_assign_tid_tx(sta, tid, NULL); |
@@ -388,9 +378,7 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) | |||
388 | 378 | ||
389 | /* activate the timer for the recipient's addBA response */ | 379 | /* activate the timer for the recipient's addBA response */ |
390 | mod_timer(&tid_tx->addba_resp_timer, jiffies + ADDBA_RESP_INTERVAL); | 380 | mod_timer(&tid_tx->addba_resp_timer, jiffies + ADDBA_RESP_INTERVAL); |
391 | #ifdef CONFIG_MAC80211_HT_DEBUG | 381 | ht_vdbg("activated addBA response timer on tid %d\n", tid); |
392 | printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid); | ||
393 | #endif | ||
394 | 382 | ||
395 | spin_lock_bh(&sta->lock); | 383 | spin_lock_bh(&sta->lock); |
396 | sta->ampdu_mlme.last_addba_req_time[tid] = jiffies; | 384 | sta->ampdu_mlme.last_addba_req_time[tid] = jiffies; |
@@ -437,9 +425,7 @@ static void sta_tx_agg_session_timer_expired(unsigned long data) | |||
437 | 425 | ||
438 | rcu_read_unlock(); | 426 | rcu_read_unlock(); |
439 | 427 | ||
440 | #ifdef CONFIG_MAC80211_HT_DEBUG | 428 | ht_vdbg("tx session timer expired on tid %d\n", (u16)*ptid); |
441 | printk(KERN_DEBUG "tx session timer expired on tid %d\n", (u16)*ptid); | ||
442 | #endif | ||
443 | 429 | ||
444 | ieee80211_stop_tx_ba_session(&sta->sta, *ptid); | 430 | ieee80211_stop_tx_ba_session(&sta->sta, *ptid); |
445 | } | 431 | } |
@@ -463,10 +449,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, | |||
463 | (local->hw.flags & IEEE80211_HW_TX_AMPDU_SETUP_IN_HW)) | 449 | (local->hw.flags & IEEE80211_HW_TX_AMPDU_SETUP_IN_HW)) |
464 | return -EINVAL; | 450 | return -EINVAL; |
465 | 451 | ||
466 | #ifdef CONFIG_MAC80211_HT_DEBUG | 452 | ht_vdbg("Open BA session requested for %pM tid %u\n", |
467 | printk(KERN_DEBUG "Open BA session requested for %pM tid %u\n", | 453 | pubsta->addr, tid); |
468 | pubsta->addr, tid); | ||
469 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
470 | 454 | ||
471 | if (sdata->vif.type != NL80211_IFTYPE_STATION && | 455 | if (sdata->vif.type != NL80211_IFTYPE_STATION && |
472 | sdata->vif.type != NL80211_IFTYPE_MESH_POINT && | 456 | sdata->vif.type != NL80211_IFTYPE_MESH_POINT && |
@@ -476,10 +460,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, | |||
476 | return -EINVAL; | 460 | return -EINVAL; |
477 | 461 | ||
478 | if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) { | 462 | if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) { |
479 | #ifdef CONFIG_MAC80211_HT_DEBUG | 463 | ht_vdbg("BA sessions blocked - Denying BA session request\n"); |
480 | printk(KERN_DEBUG "BA sessions blocked. " | ||
481 | "Denying BA session request\n"); | ||
482 | #endif | ||
483 | return -EINVAL; | 464 | return -EINVAL; |
484 | } | 465 | } |
485 | 466 | ||
@@ -497,10 +478,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, | |||
497 | */ | 478 | */ |
498 | if (sta->sdata->vif.type == NL80211_IFTYPE_ADHOC && | 479 | if (sta->sdata->vif.type == NL80211_IFTYPE_ADHOC && |
499 | !sta->sta.ht_cap.ht_supported) { | 480 | !sta->sta.ht_cap.ht_supported) { |
500 | #ifdef CONFIG_MAC80211_HT_DEBUG | 481 | ht_vdbg("BA request denied - IBSS STA %pM does not advertise HT support\n", |
501 | printk(KERN_DEBUG "BA request denied - IBSS STA %pM" | 482 | pubsta->addr); |
502 | "does not advertise HT support\n", pubsta->addr); | ||
503 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
504 | return -EINVAL; | 483 | return -EINVAL; |
505 | } | 484 | } |
506 | 485 | ||
@@ -520,12 +499,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, | |||
520 | if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_BURST_RETRIES && | 499 | if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_BURST_RETRIES && |
521 | time_before(jiffies, sta->ampdu_mlme.last_addba_req_time[tid] + | 500 | time_before(jiffies, sta->ampdu_mlme.last_addba_req_time[tid] + |
522 | HT_AGG_RETRIES_PERIOD)) { | 501 | HT_AGG_RETRIES_PERIOD)) { |
523 | #ifdef CONFIG_MAC80211_HT_DEBUG | 502 | ht_vdbg("BA request denied - waiting a grace period after %d failed requests on tid %u\n", |
524 | printk(KERN_DEBUG "BA request denied - " | 503 | sta->ampdu_mlme.addba_req_num[tid], tid); |
525 | "waiting a grace period after %d failed requests " | ||
526 | "on tid %u\n", | ||
527 | sta->ampdu_mlme.addba_req_num[tid], tid); | ||
528 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
529 | ret = -EBUSY; | 504 | ret = -EBUSY; |
530 | goto err_unlock_sta; | 505 | goto err_unlock_sta; |
531 | } | 506 | } |
@@ -533,10 +508,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, | |||
533 | tid_tx = rcu_dereference_protected_tid_tx(sta, tid); | 508 | tid_tx = rcu_dereference_protected_tid_tx(sta, tid); |
534 | /* check if the TID is not in aggregation flow already */ | 509 | /* check if the TID is not in aggregation flow already */ |
535 | if (tid_tx || sta->ampdu_mlme.tid_start_tx[tid]) { | 510 | if (tid_tx || sta->ampdu_mlme.tid_start_tx[tid]) { |
536 | #ifdef CONFIG_MAC80211_HT_DEBUG | 511 | ht_vdbg("BA request denied - session is not idle on tid %u\n", |
537 | printk(KERN_DEBUG "BA request denied - session is not " | 512 | tid); |
538 | "idle on tid %u\n", tid); | ||
539 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
540 | ret = -EAGAIN; | 513 | ret = -EAGAIN; |
541 | goto err_unlock_sta; | 514 | goto err_unlock_sta; |
542 | } | 515 | } |
@@ -591,9 +564,7 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local, | |||
591 | 564 | ||
592 | tid_tx = rcu_dereference_protected_tid_tx(sta, tid); | 565 | tid_tx = rcu_dereference_protected_tid_tx(sta, tid); |
593 | 566 | ||
594 | #ifdef CONFIG_MAC80211_HT_DEBUG | 567 | ht_vdbg("Aggregation is on for tid %d\n", tid); |
595 | printk(KERN_DEBUG "Aggregation is on for tid %d\n", tid); | ||
596 | #endif | ||
597 | 568 | ||
598 | drv_ampdu_action(local, sta->sdata, | 569 | drv_ampdu_action(local, sta->sdata, |
599 | IEEE80211_AMPDU_TX_OPERATIONAL, | 570 | IEEE80211_AMPDU_TX_OPERATIONAL, |
@@ -627,10 +598,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid) | |||
627 | trace_api_start_tx_ba_cb(sdata, ra, tid); | 598 | trace_api_start_tx_ba_cb(sdata, ra, tid); |
628 | 599 | ||
629 | if (tid >= STA_TID_NUM) { | 600 | if (tid >= STA_TID_NUM) { |
630 | #ifdef CONFIG_MAC80211_HT_DEBUG | 601 | ht_vdbg("Bad TID value: tid = %d (>= %d)\n", tid, STA_TID_NUM); |
631 | printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n", | ||
632 | tid, STA_TID_NUM); | ||
633 | #endif | ||
634 | return; | 602 | return; |
635 | } | 603 | } |
636 | 604 | ||
@@ -638,9 +606,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid) | |||
638 | sta = sta_info_get_bss(sdata, ra); | 606 | sta = sta_info_get_bss(sdata, ra); |
639 | if (!sta) { | 607 | if (!sta) { |
640 | mutex_unlock(&local->sta_mtx); | 608 | mutex_unlock(&local->sta_mtx); |
641 | #ifdef CONFIG_MAC80211_HT_DEBUG | 609 | ht_vdbg("Could not find station: %pM\n", ra); |
642 | printk(KERN_DEBUG "Could not find station: %pM\n", ra); | ||
643 | #endif | ||
644 | return; | 610 | return; |
645 | } | 611 | } |
646 | 612 | ||
@@ -648,9 +614,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid) | |||
648 | tid_tx = rcu_dereference_protected_tid_tx(sta, tid); | 614 | tid_tx = rcu_dereference_protected_tid_tx(sta, tid); |
649 | 615 | ||
650 | if (WARN_ON(!tid_tx)) { | 616 | if (WARN_ON(!tid_tx)) { |
651 | #ifdef CONFIG_MAC80211_HT_DEBUG | 617 | ht_vdbg("addBA was not requested!\n"); |
652 | printk(KERN_DEBUG "addBA was not requested!\n"); | ||
653 | #endif | ||
654 | goto unlock; | 618 | goto unlock; |
655 | } | 619 | } |
656 | 620 | ||
@@ -750,25 +714,17 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid) | |||
750 | trace_api_stop_tx_ba_cb(sdata, ra, tid); | 714 | trace_api_stop_tx_ba_cb(sdata, ra, tid); |
751 | 715 | ||
752 | if (tid >= STA_TID_NUM) { | 716 | if (tid >= STA_TID_NUM) { |
753 | #ifdef CONFIG_MAC80211_HT_DEBUG | 717 | ht_vdbg("Bad TID value: tid = %d (>= %d)\n", tid, STA_TID_NUM); |
754 | printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n", | ||
755 | tid, STA_TID_NUM); | ||
756 | #endif | ||
757 | return; | 718 | return; |
758 | } | 719 | } |
759 | 720 | ||
760 | #ifdef CONFIG_MAC80211_HT_DEBUG | 721 | ht_vdbg("Stopping Tx BA session for %pM tid %d\n", ra, tid); |
761 | printk(KERN_DEBUG "Stopping Tx BA session for %pM tid %d\n", | ||
762 | ra, tid); | ||
763 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
764 | 722 | ||
765 | mutex_lock(&local->sta_mtx); | 723 | mutex_lock(&local->sta_mtx); |
766 | 724 | ||
767 | sta = sta_info_get_bss(sdata, ra); | 725 | sta = sta_info_get_bss(sdata, ra); |
768 | if (!sta) { | 726 | if (!sta) { |
769 | #ifdef CONFIG_MAC80211_HT_DEBUG | 727 | ht_vdbg("Could not find station: %pM\n", ra); |
770 | printk(KERN_DEBUG "Could not find station: %pM\n", ra); | ||
771 | #endif | ||
772 | goto unlock; | 728 | goto unlock; |
773 | } | 729 | } |
774 | 730 | ||
@@ -777,9 +733,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid) | |||
777 | tid_tx = rcu_dereference_protected_tid_tx(sta, tid); | 733 | tid_tx = rcu_dereference_protected_tid_tx(sta, tid); |
778 | 734 | ||
779 | if (!tid_tx || !test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { | 735 | if (!tid_tx || !test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { |
780 | #ifdef CONFIG_MAC80211_HT_DEBUG | 736 | ht_vdbg("unexpected callback to A-MPDU stop\n"); |
781 | printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n"); | ||
782 | #endif | ||
783 | goto unlock_sta; | 737 | goto unlock_sta; |
784 | } | 738 | } |
785 | 739 | ||
@@ -855,17 +809,13 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, | |||
855 | goto out; | 809 | goto out; |
856 | 810 | ||
857 | if (mgmt->u.action.u.addba_resp.dialog_token != tid_tx->dialog_token) { | 811 | if (mgmt->u.action.u.addba_resp.dialog_token != tid_tx->dialog_token) { |
858 | #ifdef CONFIG_MAC80211_HT_DEBUG | 812 | ht_vdbg("wrong addBA response token, tid %d\n", tid); |
859 | printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); | ||
860 | #endif | ||
861 | goto out; | 813 | goto out; |
862 | } | 814 | } |
863 | 815 | ||
864 | del_timer_sync(&tid_tx->addba_resp_timer); | 816 | del_timer_sync(&tid_tx->addba_resp_timer); |
865 | 817 | ||
866 | #ifdef CONFIG_MAC80211_HT_DEBUG | 818 | ht_vdbg("switched off addBA timer for tid %d\n", tid); |
867 | printk(KERN_DEBUG "switched off addBA timer for tid %d\n", tid); | ||
868 | #endif | ||
869 | 819 | ||
870 | /* | 820 | /* |
871 | * addba_resp_timer may have fired before we got here, and | 821 | * addba_resp_timer may have fired before we got here, and |
@@ -874,11 +824,8 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, | |||
874 | */ | 824 | */ |
875 | if (test_bit(HT_AGG_STATE_WANT_STOP, &tid_tx->state) || | 825 | if (test_bit(HT_AGG_STATE_WANT_STOP, &tid_tx->state) || |
876 | test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { | 826 | test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { |
877 | #ifdef CONFIG_MAC80211_HT_DEBUG | 827 | ht_vdbg("got addBA resp for tid %d but we already gave up\n", |
878 | printk(KERN_DEBUG | 828 | tid); |
879 | "got addBA resp for tid %d but we already gave up\n", | ||
880 | tid); | ||
881 | #endif | ||
882 | goto out; | 829 | goto out; |
883 | } | 830 | } |
884 | 831 | ||
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index e9cecca5c44d..498c94e34427 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -674,6 +674,48 @@ static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev, | |||
674 | return ret; | 674 | return ret; |
675 | } | 675 | } |
676 | 676 | ||
677 | static int ieee80211_set_channel(struct wiphy *wiphy, | ||
678 | struct net_device *netdev, | ||
679 | struct ieee80211_channel *chan, | ||
680 | enum nl80211_channel_type channel_type) | ||
681 | { | ||
682 | struct ieee80211_local *local = wiphy_priv(wiphy); | ||
683 | struct ieee80211_sub_if_data *sdata = NULL; | ||
684 | |||
685 | if (netdev) | ||
686 | sdata = IEEE80211_DEV_TO_SUB_IF(netdev); | ||
687 | |||
688 | switch (ieee80211_get_channel_mode(local, NULL)) { | ||
689 | case CHAN_MODE_HOPPING: | ||
690 | return -EBUSY; | ||
691 | case CHAN_MODE_FIXED: | ||
692 | if (local->oper_channel != chan) | ||
693 | return -EBUSY; | ||
694 | if (!sdata && local->_oper_channel_type == channel_type) | ||
695 | return 0; | ||
696 | break; | ||
697 | case CHAN_MODE_UNDEFINED: | ||
698 | break; | ||
699 | } | ||
700 | |||
701 | if (!ieee80211_set_channel_type(local, sdata, channel_type)) | ||
702 | return -EBUSY; | ||
703 | |||
704 | local->oper_channel = chan; | ||
705 | |||
706 | /* auto-detects changes */ | ||
707 | ieee80211_hw_config(local, 0); | ||
708 | |||
709 | return 0; | ||
710 | } | ||
711 | |||
712 | static int ieee80211_set_monitor_channel(struct wiphy *wiphy, | ||
713 | struct ieee80211_channel *chan, | ||
714 | enum nl80211_channel_type channel_type) | ||
715 | { | ||
716 | return ieee80211_set_channel(wiphy, NULL, chan, channel_type); | ||
717 | } | ||
718 | |||
677 | static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata, | 719 | static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata, |
678 | const u8 *resp, size_t resp_len) | 720 | const u8 *resp, size_t resp_len) |
679 | { | 721 | { |
@@ -788,6 +830,11 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev, | |||
788 | if (old) | 830 | if (old) |
789 | return -EALREADY; | 831 | return -EALREADY; |
790 | 832 | ||
833 | err = ieee80211_set_channel(wiphy, dev, params->channel, | ||
834 | params->channel_type); | ||
835 | if (err) | ||
836 | return err; | ||
837 | |||
791 | /* | 838 | /* |
792 | * Apply control port protocol, this allows us to | 839 | * Apply control port protocol, this allows us to |
793 | * not encrypt dynamic WEP control frames. | 840 | * not encrypt dynamic WEP control frames. |
@@ -1558,6 +1605,12 @@ static int ieee80211_join_mesh(struct wiphy *wiphy, struct net_device *dev, | |||
1558 | err = copy_mesh_setup(ifmsh, setup); | 1605 | err = copy_mesh_setup(ifmsh, setup); |
1559 | if (err) | 1606 | if (err) |
1560 | return err; | 1607 | return err; |
1608 | |||
1609 | err = ieee80211_set_channel(wiphy, dev, setup->channel, | ||
1610 | setup->channel_type); | ||
1611 | if (err) | ||
1612 | return err; | ||
1613 | |||
1561 | ieee80211_start_mesh(sdata); | 1614 | ieee80211_start_mesh(sdata); |
1562 | 1615 | ||
1563 | return 0; | 1616 | return 0; |
@@ -1677,55 +1730,6 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy, | |||
1677 | return 0; | 1730 | return 0; |
1678 | } | 1731 | } |
1679 | 1732 | ||
1680 | static int ieee80211_set_channel(struct wiphy *wiphy, | ||
1681 | struct net_device *netdev, | ||
1682 | struct ieee80211_channel *chan, | ||
1683 | enum nl80211_channel_type channel_type) | ||
1684 | { | ||
1685 | struct ieee80211_local *local = wiphy_priv(wiphy); | ||
1686 | struct ieee80211_sub_if_data *sdata = NULL; | ||
1687 | struct ieee80211_channel *old_oper; | ||
1688 | enum nl80211_channel_type old_oper_type; | ||
1689 | enum nl80211_channel_type old_vif_oper_type= NL80211_CHAN_NO_HT; | ||
1690 | |||
1691 | if (netdev) | ||
1692 | sdata = IEEE80211_DEV_TO_SUB_IF(netdev); | ||
1693 | |||
1694 | switch (ieee80211_get_channel_mode(local, NULL)) { | ||
1695 | case CHAN_MODE_HOPPING: | ||
1696 | return -EBUSY; | ||
1697 | case CHAN_MODE_FIXED: | ||
1698 | if (local->oper_channel != chan) | ||
1699 | return -EBUSY; | ||
1700 | if (!sdata && local->_oper_channel_type == channel_type) | ||
1701 | return 0; | ||
1702 | break; | ||
1703 | case CHAN_MODE_UNDEFINED: | ||
1704 | break; | ||
1705 | } | ||
1706 | |||
1707 | if (sdata) | ||
1708 | old_vif_oper_type = sdata->vif.bss_conf.channel_type; | ||
1709 | old_oper_type = local->_oper_channel_type; | ||
1710 | |||
1711 | if (!ieee80211_set_channel_type(local, sdata, channel_type)) | ||
1712 | return -EBUSY; | ||
1713 | |||
1714 | old_oper = local->oper_channel; | ||
1715 | local->oper_channel = chan; | ||
1716 | |||
1717 | /* Update driver if changes were actually made. */ | ||
1718 | if ((old_oper != local->oper_channel) || | ||
1719 | (old_oper_type != local->_oper_channel_type)) | ||
1720 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | ||
1721 | |||
1722 | if (sdata && sdata->vif.type != NL80211_IFTYPE_MONITOR && | ||
1723 | old_vif_oper_type != sdata->vif.bss_conf.channel_type) | ||
1724 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_HT); | ||
1725 | |||
1726 | return 0; | ||
1727 | } | ||
1728 | |||
1729 | #ifdef CONFIG_PM | 1733 | #ifdef CONFIG_PM |
1730 | static int ieee80211_suspend(struct wiphy *wiphy, | 1734 | static int ieee80211_suspend(struct wiphy *wiphy, |
1731 | struct cfg80211_wowlan *wowlan) | 1735 | struct cfg80211_wowlan *wowlan) |
@@ -2108,35 +2112,171 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy, | |||
2108 | return 0; | 2112 | return 0; |
2109 | } | 2113 | } |
2110 | 2114 | ||
2111 | static int ieee80211_remain_on_channel_hw(struct ieee80211_local *local, | 2115 | static int ieee80211_start_roc_work(struct ieee80211_local *local, |
2112 | struct net_device *dev, | 2116 | struct ieee80211_sub_if_data *sdata, |
2113 | struct ieee80211_channel *chan, | 2117 | struct ieee80211_channel *channel, |
2114 | enum nl80211_channel_type chantype, | 2118 | enum nl80211_channel_type channel_type, |
2115 | unsigned int duration, u64 *cookie) | 2119 | unsigned int duration, u64 *cookie, |
2120 | struct sk_buff *txskb) | ||
2116 | { | 2121 | { |
2122 | struct ieee80211_roc_work *roc, *tmp; | ||
2123 | bool queued = false; | ||
2117 | int ret; | 2124 | int ret; |
2118 | u32 random_cookie; | ||
2119 | 2125 | ||
2120 | lockdep_assert_held(&local->mtx); | 2126 | lockdep_assert_held(&local->mtx); |
2121 | 2127 | ||
2122 | if (local->hw_roc_cookie) | 2128 | roc = kzalloc(sizeof(*roc), GFP_KERNEL); |
2123 | return -EBUSY; | 2129 | if (!roc) |
2124 | /* must be nonzero */ | 2130 | return -ENOMEM; |
2125 | random_cookie = random32() | 1; | 2131 | |
2126 | 2132 | roc->chan = channel; | |
2127 | *cookie = random_cookie; | 2133 | roc->chan_type = channel_type; |
2128 | local->hw_roc_dev = dev; | 2134 | roc->duration = duration; |
2129 | local->hw_roc_cookie = random_cookie; | 2135 | roc->req_duration = duration; |
2130 | local->hw_roc_channel = chan; | 2136 | roc->frame = txskb; |
2131 | local->hw_roc_channel_type = chantype; | 2137 | roc->mgmt_tx_cookie = (unsigned long)txskb; |
2132 | local->hw_roc_duration = duration; | 2138 | roc->sdata = sdata; |
2133 | ret = drv_remain_on_channel(local, chan, chantype, duration); | 2139 | INIT_DELAYED_WORK(&roc->work, ieee80211_sw_roc_work); |
2140 | INIT_LIST_HEAD(&roc->dependents); | ||
2141 | |||
2142 | /* if there's one pending or we're scanning, queue this one */ | ||
2143 | if (!list_empty(&local->roc_list) || local->scanning) | ||
2144 | goto out_check_combine; | ||
2145 | |||
2146 | /* if not HW assist, just queue & schedule work */ | ||
2147 | if (!local->ops->remain_on_channel) { | ||
2148 | ieee80211_queue_delayed_work(&local->hw, &roc->work, 0); | ||
2149 | goto out_queue; | ||
2150 | } | ||
2151 | |||
2152 | /* otherwise actually kick it off here (for error handling) */ | ||
2153 | |||
2154 | /* | ||
2155 | * If the duration is zero, then the driver | ||
2156 | * wouldn't actually do anything. Set it to | ||
2157 | * 10 for now. | ||
2158 | * | ||
2159 | * TODO: cancel the off-channel operation | ||
2160 | * when we get the SKB's TX status and | ||
2161 | * the wait time was zero before. | ||
2162 | */ | ||
2163 | if (!duration) | ||
2164 | duration = 10; | ||
2165 | |||
2166 | ret = drv_remain_on_channel(local, channel, channel_type, duration); | ||
2134 | if (ret) { | 2167 | if (ret) { |
2135 | local->hw_roc_channel = NULL; | 2168 | kfree(roc); |
2136 | local->hw_roc_cookie = 0; | 2169 | return ret; |
2137 | } | 2170 | } |
2138 | 2171 | ||
2139 | return ret; | 2172 | roc->started = true; |
2173 | goto out_queue; | ||
2174 | |||
2175 | out_check_combine: | ||
2176 | list_for_each_entry(tmp, &local->roc_list, list) { | ||
2177 | if (tmp->chan != channel || tmp->chan_type != channel_type) | ||
2178 | continue; | ||
2179 | |||
2180 | /* | ||
2181 | * Extend this ROC if possible: | ||
2182 | * | ||
2183 | * If it hasn't started yet, just increase the duration | ||
2184 | * and add the new one to the list of dependents. | ||
2185 | */ | ||
2186 | if (!tmp->started) { | ||
2187 | list_add_tail(&roc->list, &tmp->dependents); | ||
2188 | tmp->duration = max(tmp->duration, roc->duration); | ||
2189 | queued = true; | ||
2190 | break; | ||
2191 | } | ||
2192 | |||
2193 | /* If it has already started, it's more difficult ... */ | ||
2194 | if (local->ops->remain_on_channel) { | ||
2195 | unsigned long j = jiffies; | ||
2196 | |||
2197 | /* | ||
2198 | * In the offloaded ROC case, if it hasn't begun, add | ||
2199 | * this new one to the dependent list to be handled | ||
2200 | * when the the master one begins. If it has begun, | ||
2201 | * check that there's still a minimum time left and | ||
2202 | * if so, start this one, transmitting the frame, but | ||
2203 | * add it to the list directly after this one with a | ||
2204 | * a reduced time so we'll ask the driver to execute | ||
2205 | * it right after finishing the previous one, in the | ||
2206 | * hope that it'll also be executed right afterwards, | ||
2207 | * effectively extending the old one. | ||
2208 | * If there's no minimum time left, just add it to the | ||
2209 | * normal list. | ||
2210 | */ | ||
2211 | if (!tmp->hw_begun) { | ||
2212 | list_add_tail(&roc->list, &tmp->dependents); | ||
2213 | queued = true; | ||
2214 | break; | ||
2215 | } | ||
2216 | |||
2217 | if (time_before(j + IEEE80211_ROC_MIN_LEFT, | ||
2218 | tmp->hw_start_time + | ||
2219 | msecs_to_jiffies(tmp->duration))) { | ||
2220 | int new_dur; | ||
2221 | |||
2222 | ieee80211_handle_roc_started(roc); | ||
2223 | |||
2224 | new_dur = roc->duration - | ||
2225 | jiffies_to_msecs(tmp->hw_start_time + | ||
2226 | msecs_to_jiffies( | ||
2227 | tmp->duration) - | ||
2228 | j); | ||
2229 | |||
2230 | if (new_dur > 0) { | ||
2231 | /* add right after tmp */ | ||
2232 | list_add(&roc->list, &tmp->list); | ||
2233 | } else { | ||
2234 | list_add_tail(&roc->list, | ||
2235 | &tmp->dependents); | ||
2236 | } | ||
2237 | queued = true; | ||
2238 | } | ||
2239 | } else if (del_timer_sync(&tmp->work.timer)) { | ||
2240 | unsigned long new_end; | ||
2241 | |||
2242 | /* | ||
2243 | * In the software ROC case, cancel the timer, if | ||
2244 | * that fails then the finish work is already | ||
2245 | * queued/pending and thus we queue the new ROC | ||
2246 | * normally, if that succeeds then we can extend | ||
2247 | * the timer duration and TX the frame (if any.) | ||
2248 | */ | ||
2249 | |||
2250 | list_add_tail(&roc->list, &tmp->dependents); | ||
2251 | queued = true; | ||
2252 | |||
2253 | new_end = jiffies + msecs_to_jiffies(roc->duration); | ||
2254 | |||
2255 | /* ok, it was started & we canceled timer */ | ||
2256 | if (time_after(new_end, tmp->work.timer.expires)) | ||
2257 | mod_timer(&tmp->work.timer, new_end); | ||
2258 | else | ||
2259 | add_timer(&tmp->work.timer); | ||
2260 | |||
2261 | ieee80211_handle_roc_started(roc); | ||
2262 | } | ||
2263 | break; | ||
2264 | } | ||
2265 | |||
2266 | out_queue: | ||
2267 | if (!queued) | ||
2268 | list_add_tail(&roc->list, &local->roc_list); | ||
2269 | |||
2270 | /* | ||
2271 | * cookie is either the roc (for normal roc) | ||
2272 | * or the SKB (for mgmt TX) | ||
2273 | */ | ||
2274 | if (txskb) | ||
2275 | *cookie = (unsigned long)txskb; | ||
2276 | else | ||
2277 | *cookie = (unsigned long)roc; | ||
2278 | |||
2279 | return 0; | ||
2140 | } | 2280 | } |
2141 | 2281 | ||
2142 | static int ieee80211_remain_on_channel(struct wiphy *wiphy, | 2282 | static int ieee80211_remain_on_channel(struct wiphy *wiphy, |
@@ -2148,42 +2288,64 @@ static int ieee80211_remain_on_channel(struct wiphy *wiphy, | |||
2148 | { | 2288 | { |
2149 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 2289 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
2150 | struct ieee80211_local *local = sdata->local; | 2290 | struct ieee80211_local *local = sdata->local; |
2291 | int ret; | ||
2151 | 2292 | ||
2152 | if (local->ops->remain_on_channel) { | 2293 | mutex_lock(&local->mtx); |
2153 | int ret; | 2294 | ret = ieee80211_start_roc_work(local, sdata, chan, channel_type, |
2154 | 2295 | duration, cookie, NULL); | |
2155 | mutex_lock(&local->mtx); | 2296 | mutex_unlock(&local->mtx); |
2156 | ret = ieee80211_remain_on_channel_hw(local, dev, | ||
2157 | chan, channel_type, | ||
2158 | duration, cookie); | ||
2159 | local->hw_roc_for_tx = false; | ||
2160 | mutex_unlock(&local->mtx); | ||
2161 | |||
2162 | return ret; | ||
2163 | } | ||
2164 | 2297 | ||
2165 | return ieee80211_wk_remain_on_channel(sdata, chan, channel_type, | 2298 | return ret; |
2166 | duration, cookie); | ||
2167 | } | 2299 | } |
2168 | 2300 | ||
2169 | static int ieee80211_cancel_remain_on_channel_hw(struct ieee80211_local *local, | 2301 | static int ieee80211_cancel_roc(struct ieee80211_local *local, |
2170 | u64 cookie) | 2302 | u64 cookie, bool mgmt_tx) |
2171 | { | 2303 | { |
2304 | struct ieee80211_roc_work *roc, *tmp, *found = NULL; | ||
2172 | int ret; | 2305 | int ret; |
2173 | 2306 | ||
2174 | lockdep_assert_held(&local->mtx); | 2307 | mutex_lock(&local->mtx); |
2308 | list_for_each_entry_safe(roc, tmp, &local->roc_list, list) { | ||
2309 | if (!mgmt_tx && (unsigned long)roc != cookie) | ||
2310 | continue; | ||
2311 | else if (mgmt_tx && roc->mgmt_tx_cookie != cookie) | ||
2312 | continue; | ||
2313 | |||
2314 | found = roc; | ||
2315 | break; | ||
2316 | } | ||
2175 | 2317 | ||
2176 | if (local->hw_roc_cookie != cookie) | 2318 | if (!found) { |
2319 | mutex_unlock(&local->mtx); | ||
2177 | return -ENOENT; | 2320 | return -ENOENT; |
2321 | } | ||
2178 | 2322 | ||
2179 | ret = drv_cancel_remain_on_channel(local); | 2323 | if (local->ops->remain_on_channel) { |
2180 | if (ret) | 2324 | if (found->started) { |
2181 | return ret; | 2325 | ret = drv_cancel_remain_on_channel(local); |
2326 | if (WARN_ON_ONCE(ret)) { | ||
2327 | mutex_unlock(&local->mtx); | ||
2328 | return ret; | ||
2329 | } | ||
2330 | } | ||
2182 | 2331 | ||
2183 | local->hw_roc_cookie = 0; | 2332 | list_del(&found->list); |
2184 | local->hw_roc_channel = NULL; | ||
2185 | 2333 | ||
2186 | ieee80211_recalc_idle(local); | 2334 | ieee80211_run_deferred_scan(local); |
2335 | ieee80211_start_next_roc(local); | ||
2336 | mutex_unlock(&local->mtx); | ||
2337 | |||
2338 | ieee80211_roc_notify_destroy(found); | ||
2339 | } else { | ||
2340 | /* work may be pending so use it all the time */ | ||
2341 | found->abort = true; | ||
2342 | ieee80211_queue_delayed_work(&local->hw, &found->work, 0); | ||
2343 | |||
2344 | mutex_unlock(&local->mtx); | ||
2345 | |||
2346 | /* work will clean up etc */ | ||
2347 | flush_delayed_work(&found->work); | ||
2348 | } | ||
2187 | 2349 | ||
2188 | return 0; | 2350 | return 0; |
2189 | } | 2351 | } |
@@ -2195,39 +2357,7 @@ static int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy, | |||
2195 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 2357 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
2196 | struct ieee80211_local *local = sdata->local; | 2358 | struct ieee80211_local *local = sdata->local; |
2197 | 2359 | ||
2198 | if (local->ops->cancel_remain_on_channel) { | 2360 | return ieee80211_cancel_roc(local, cookie, false); |
2199 | int ret; | ||
2200 | |||
2201 | mutex_lock(&local->mtx); | ||
2202 | ret = ieee80211_cancel_remain_on_channel_hw(local, cookie); | ||
2203 | mutex_unlock(&local->mtx); | ||
2204 | |||
2205 | return ret; | ||
2206 | } | ||
2207 | |||
2208 | return ieee80211_wk_cancel_remain_on_channel(sdata, cookie); | ||
2209 | } | ||
2210 | |||
2211 | static enum work_done_result | ||
2212 | ieee80211_offchan_tx_done(struct ieee80211_work *wk, struct sk_buff *skb) | ||
2213 | { | ||
2214 | /* | ||
2215 | * Use the data embedded in the work struct for reporting | ||
2216 | * here so if the driver mangled the SKB before dropping | ||
2217 | * it (which is the only way we really should get here) | ||
2218 | * then we don't report mangled data. | ||
2219 | * | ||
2220 | * If there was no wait time, then by the time we get here | ||
2221 | * the driver will likely not have reported the status yet, | ||
2222 | * so in that case userspace will have to deal with it. | ||
2223 | */ | ||
2224 | |||
2225 | if (wk->offchan_tx.wait && !wk->offchan_tx.status) | ||
2226 | cfg80211_mgmt_tx_status(wk->sdata->dev, | ||
2227 | (unsigned long) wk->offchan_tx.frame, | ||
2228 | wk->data, wk->data_len, false, GFP_KERNEL); | ||
2229 | |||
2230 | return WORK_DONE_DESTROY; | ||
2231 | } | 2361 | } |
2232 | 2362 | ||
2233 | static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, | 2363 | static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, |
@@ -2241,10 +2371,10 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, | |||
2241 | struct ieee80211_local *local = sdata->local; | 2371 | struct ieee80211_local *local = sdata->local; |
2242 | struct sk_buff *skb; | 2372 | struct sk_buff *skb; |
2243 | struct sta_info *sta; | 2373 | struct sta_info *sta; |
2244 | struct ieee80211_work *wk; | ||
2245 | const struct ieee80211_mgmt *mgmt = (void *)buf; | 2374 | const struct ieee80211_mgmt *mgmt = (void *)buf; |
2375 | bool need_offchan = false; | ||
2246 | u32 flags; | 2376 | u32 flags; |
2247 | bool is_offchan = false; | 2377 | int ret; |
2248 | 2378 | ||
2249 | if (dont_wait_for_ack) | 2379 | if (dont_wait_for_ack) |
2250 | flags = IEEE80211_TX_CTL_NO_ACK; | 2380 | flags = IEEE80211_TX_CTL_NO_ACK; |
@@ -2252,33 +2382,28 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, | |||
2252 | flags = IEEE80211_TX_INTFL_NL80211_FRAME_TX | | 2382 | flags = IEEE80211_TX_INTFL_NL80211_FRAME_TX | |
2253 | IEEE80211_TX_CTL_REQ_TX_STATUS; | 2383 | IEEE80211_TX_CTL_REQ_TX_STATUS; |
2254 | 2384 | ||
2255 | /* Check that we are on the requested channel for transmission */ | ||
2256 | if (chan != local->tmp_channel && | ||
2257 | chan != local->oper_channel) | ||
2258 | is_offchan = true; | ||
2259 | if (channel_type_valid && | ||
2260 | (channel_type != local->tmp_channel_type && | ||
2261 | channel_type != local->_oper_channel_type)) | ||
2262 | is_offchan = true; | ||
2263 | |||
2264 | if (chan == local->hw_roc_channel) { | ||
2265 | /* TODO: check channel type? */ | ||
2266 | is_offchan = false; | ||
2267 | flags |= IEEE80211_TX_CTL_TX_OFFCHAN; | ||
2268 | } | ||
2269 | |||
2270 | if (no_cck) | 2385 | if (no_cck) |
2271 | flags |= IEEE80211_TX_CTL_NO_CCK_RATE; | 2386 | flags |= IEEE80211_TX_CTL_NO_CCK_RATE; |
2272 | 2387 | ||
2273 | if (is_offchan && !offchan) | ||
2274 | return -EBUSY; | ||
2275 | |||
2276 | switch (sdata->vif.type) { | 2388 | switch (sdata->vif.type) { |
2277 | case NL80211_IFTYPE_ADHOC: | 2389 | case NL80211_IFTYPE_ADHOC: |
2390 | if (!sdata->vif.bss_conf.ibss_joined) | ||
2391 | need_offchan = true; | ||
2392 | /* fall through */ | ||
2393 | #ifdef CONFIG_MAC80211_MESH | ||
2394 | case NL80211_IFTYPE_MESH_POINT: | ||
2395 | if (ieee80211_vif_is_mesh(&sdata->vif) && | ||
2396 | !sdata->u.mesh.mesh_id_len) | ||
2397 | need_offchan = true; | ||
2398 | /* fall through */ | ||
2399 | #endif | ||
2278 | case NL80211_IFTYPE_AP: | 2400 | case NL80211_IFTYPE_AP: |
2279 | case NL80211_IFTYPE_AP_VLAN: | 2401 | case NL80211_IFTYPE_AP_VLAN: |
2280 | case NL80211_IFTYPE_P2P_GO: | 2402 | case NL80211_IFTYPE_P2P_GO: |
2281 | case NL80211_IFTYPE_MESH_POINT: | 2403 | if (sdata->vif.type != NL80211_IFTYPE_ADHOC && |
2404 | !ieee80211_vif_is_mesh(&sdata->vif) && | ||
2405 | !rcu_access_pointer(sdata->bss->beacon)) | ||
2406 | need_offchan = true; | ||
2282 | if (!ieee80211_is_action(mgmt->frame_control) || | 2407 | if (!ieee80211_is_action(mgmt->frame_control) || |
2283 | mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) | 2408 | mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) |
2284 | break; | 2409 | break; |
@@ -2290,103 +2415,60 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, | |||
2290 | break; | 2415 | break; |
2291 | case NL80211_IFTYPE_STATION: | 2416 | case NL80211_IFTYPE_STATION: |
2292 | case NL80211_IFTYPE_P2P_CLIENT: | 2417 | case NL80211_IFTYPE_P2P_CLIENT: |
2418 | if (!sdata->u.mgd.associated) | ||
2419 | need_offchan = true; | ||
2293 | break; | 2420 | break; |
2294 | default: | 2421 | default: |
2295 | return -EOPNOTSUPP; | 2422 | return -EOPNOTSUPP; |
2296 | } | 2423 | } |
2297 | 2424 | ||
2425 | mutex_lock(&local->mtx); | ||
2426 | |||
2427 | /* Check if the operating channel is the requested channel */ | ||
2428 | if (!need_offchan) { | ||
2429 | need_offchan = chan != local->oper_channel; | ||
2430 | if (channel_type_valid && | ||
2431 | channel_type != local->_oper_channel_type) | ||
2432 | need_offchan = true; | ||
2433 | } | ||
2434 | |||
2435 | if (need_offchan && !offchan) { | ||
2436 | ret = -EBUSY; | ||
2437 | goto out_unlock; | ||
2438 | } | ||
2439 | |||
2298 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + len); | 2440 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + len); |
2299 | if (!skb) | 2441 | if (!skb) { |
2300 | return -ENOMEM; | 2442 | ret = -ENOMEM; |
2443 | goto out_unlock; | ||
2444 | } | ||
2301 | skb_reserve(skb, local->hw.extra_tx_headroom); | 2445 | skb_reserve(skb, local->hw.extra_tx_headroom); |
2302 | 2446 | ||
2303 | memcpy(skb_put(skb, len), buf, len); | 2447 | memcpy(skb_put(skb, len), buf, len); |
2304 | 2448 | ||
2305 | IEEE80211_SKB_CB(skb)->flags = flags; | 2449 | IEEE80211_SKB_CB(skb)->flags = flags; |
2306 | 2450 | ||
2307 | if (flags & IEEE80211_TX_CTL_TX_OFFCHAN) | ||
2308 | IEEE80211_SKB_CB(skb)->hw_queue = | ||
2309 | local->hw.offchannel_tx_hw_queue; | ||
2310 | |||
2311 | skb->dev = sdata->dev; | 2451 | skb->dev = sdata->dev; |
2312 | 2452 | ||
2313 | *cookie = (unsigned long) skb; | 2453 | if (!need_offchan) { |
2314 | 2454 | ieee80211_tx_skb(sdata, skb); | |
2315 | if (is_offchan && local->ops->remain_on_channel) { | 2455 | ret = 0; |
2316 | unsigned int duration; | 2456 | goto out_unlock; |
2317 | int ret; | 2457 | } |
2318 | |||
2319 | mutex_lock(&local->mtx); | ||
2320 | /* | ||
2321 | * If the duration is zero, then the driver | ||
2322 | * wouldn't actually do anything. Set it to | ||
2323 | * 100 for now. | ||
2324 | * | ||
2325 | * TODO: cancel the off-channel operation | ||
2326 | * when we get the SKB's TX status and | ||
2327 | * the wait time was zero before. | ||
2328 | */ | ||
2329 | duration = 100; | ||
2330 | if (wait) | ||
2331 | duration = wait; | ||
2332 | ret = ieee80211_remain_on_channel_hw(local, dev, chan, | ||
2333 | channel_type, | ||
2334 | duration, cookie); | ||
2335 | if (ret) { | ||
2336 | kfree_skb(skb); | ||
2337 | mutex_unlock(&local->mtx); | ||
2338 | return ret; | ||
2339 | } | ||
2340 | |||
2341 | local->hw_roc_for_tx = true; | ||
2342 | local->hw_roc_duration = wait; | ||
2343 | |||
2344 | /* | ||
2345 | * queue up frame for transmission after | ||
2346 | * ieee80211_ready_on_channel call | ||
2347 | */ | ||
2348 | 2458 | ||
2349 | /* modify cookie to prevent API mismatches */ | 2459 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_TX_OFFCHAN; |
2350 | *cookie ^= 2; | 2460 | if (local->hw.flags & IEEE80211_HW_QUEUE_CONTROL) |
2351 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_TX_OFFCHAN; | ||
2352 | IEEE80211_SKB_CB(skb)->hw_queue = | 2461 | IEEE80211_SKB_CB(skb)->hw_queue = |
2353 | local->hw.offchannel_tx_hw_queue; | 2462 | local->hw.offchannel_tx_hw_queue; |
2354 | local->hw_roc_skb = skb; | ||
2355 | local->hw_roc_skb_for_status = skb; | ||
2356 | mutex_unlock(&local->mtx); | ||
2357 | |||
2358 | return 0; | ||
2359 | } | ||
2360 | |||
2361 | /* | ||
2362 | * Can transmit right away if the channel was the | ||
2363 | * right one and there's no wait involved... If a | ||
2364 | * wait is involved, we might otherwise not be on | ||
2365 | * the right channel for long enough! | ||
2366 | */ | ||
2367 | if (!is_offchan && !wait && !sdata->vif.bss_conf.idle) { | ||
2368 | ieee80211_tx_skb(sdata, skb); | ||
2369 | return 0; | ||
2370 | } | ||
2371 | 2463 | ||
2372 | wk = kzalloc(sizeof(*wk) + len, GFP_KERNEL); | 2464 | /* This will handle all kinds of coalescing and immediate TX */ |
2373 | if (!wk) { | 2465 | ret = ieee80211_start_roc_work(local, sdata, chan, channel_type, |
2466 | wait, cookie, skb); | ||
2467 | if (ret) | ||
2374 | kfree_skb(skb); | 2468 | kfree_skb(skb); |
2375 | return -ENOMEM; | 2469 | out_unlock: |
2376 | } | 2470 | mutex_unlock(&local->mtx); |
2377 | 2471 | return ret; | |
2378 | wk->type = IEEE80211_WORK_OFFCHANNEL_TX; | ||
2379 | wk->chan = chan; | ||
2380 | wk->chan_type = channel_type; | ||
2381 | wk->sdata = sdata; | ||
2382 | wk->done = ieee80211_offchan_tx_done; | ||
2383 | wk->offchan_tx.frame = skb; | ||
2384 | wk->offchan_tx.wait = wait; | ||
2385 | wk->data_len = len; | ||
2386 | memcpy(wk->data, buf, len); | ||
2387 | |||
2388 | ieee80211_add_work(wk); | ||
2389 | return 0; | ||
2390 | } | 2472 | } |
2391 | 2473 | ||
2392 | static int ieee80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, | 2474 | static int ieee80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, |
@@ -2395,45 +2477,8 @@ static int ieee80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, | |||
2395 | { | 2477 | { |
2396 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 2478 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
2397 | struct ieee80211_local *local = sdata->local; | 2479 | struct ieee80211_local *local = sdata->local; |
2398 | struct ieee80211_work *wk; | ||
2399 | int ret = -ENOENT; | ||
2400 | |||
2401 | mutex_lock(&local->mtx); | ||
2402 | |||
2403 | if (local->ops->cancel_remain_on_channel) { | ||
2404 | cookie ^= 2; | ||
2405 | ret = ieee80211_cancel_remain_on_channel_hw(local, cookie); | ||
2406 | |||
2407 | if (ret == 0) { | ||
2408 | kfree_skb(local->hw_roc_skb); | ||
2409 | local->hw_roc_skb = NULL; | ||
2410 | local->hw_roc_skb_for_status = NULL; | ||
2411 | } | ||
2412 | |||
2413 | mutex_unlock(&local->mtx); | ||
2414 | 2480 | ||
2415 | return ret; | 2481 | return ieee80211_cancel_roc(local, cookie, true); |
2416 | } | ||
2417 | |||
2418 | list_for_each_entry(wk, &local->work_list, list) { | ||
2419 | if (wk->sdata != sdata) | ||
2420 | continue; | ||
2421 | |||
2422 | if (wk->type != IEEE80211_WORK_OFFCHANNEL_TX) | ||
2423 | continue; | ||
2424 | |||
2425 | if (cookie != (unsigned long) wk->offchan_tx.frame) | ||
2426 | continue; | ||
2427 | |||
2428 | wk->timeout = jiffies; | ||
2429 | |||
2430 | ieee80211_queue_work(&local->hw, &local->work_work); | ||
2431 | ret = 0; | ||
2432 | break; | ||
2433 | } | ||
2434 | mutex_unlock(&local->mtx); | ||
2435 | |||
2436 | return ret; | ||
2437 | } | 2482 | } |
2438 | 2483 | ||
2439 | static void ieee80211_mgmt_frame_register(struct wiphy *wiphy, | 2484 | static void ieee80211_mgmt_frame_register(struct wiphy *wiphy, |
@@ -2677,7 +2722,7 @@ static int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, | |||
2677 | return -EINVAL; | 2722 | return -EINVAL; |
2678 | 2723 | ||
2679 | #ifdef CONFIG_MAC80211_VERBOSE_TDLS_DEBUG | 2724 | #ifdef CONFIG_MAC80211_VERBOSE_TDLS_DEBUG |
2680 | printk(KERN_DEBUG "TDLS mgmt action %d peer %pM\n", action_code, peer); | 2725 | pr_debug("TDLS mgmt action %d peer %pM\n", action_code, peer); |
2681 | #endif | 2726 | #endif |
2682 | 2727 | ||
2683 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + | 2728 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + |
@@ -2788,7 +2833,7 @@ static int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, | |||
2788 | return -EINVAL; | 2833 | return -EINVAL; |
2789 | 2834 | ||
2790 | #ifdef CONFIG_MAC80211_VERBOSE_TDLS_DEBUG | 2835 | #ifdef CONFIG_MAC80211_VERBOSE_TDLS_DEBUG |
2791 | printk(KERN_DEBUG "TDLS oper %d peer %pM\n", oper, peer); | 2836 | pr_debug("TDLS oper %d peer %pM\n", oper, peer); |
2792 | #endif | 2837 | #endif |
2793 | 2838 | ||
2794 | switch (oper) { | 2839 | switch (oper) { |
@@ -2933,7 +2978,7 @@ struct cfg80211_ops mac80211_config_ops = { | |||
2933 | #endif | 2978 | #endif |
2934 | .change_bss = ieee80211_change_bss, | 2979 | .change_bss = ieee80211_change_bss, |
2935 | .set_txq_params = ieee80211_set_txq_params, | 2980 | .set_txq_params = ieee80211_set_txq_params, |
2936 | .set_channel = ieee80211_set_channel, | 2981 | .set_monitor_channel = ieee80211_set_monitor_channel, |
2937 | .suspend = ieee80211_suspend, | 2982 | .suspend = ieee80211_suspend, |
2938 | .resume = ieee80211_resume, | 2983 | .resume = ieee80211_resume, |
2939 | .scan = ieee80211_scan, | 2984 | .scan = ieee80211_scan, |
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index c76cf7230c7d..f0f87e5a1d35 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c | |||
@@ -41,6 +41,10 @@ __ieee80211_get_channel_mode(struct ieee80211_local *local, | |||
41 | if (!sdata->u.ap.beacon) | 41 | if (!sdata->u.ap.beacon) |
42 | continue; | 42 | continue; |
43 | break; | 43 | break; |
44 | case NL80211_IFTYPE_MESH_POINT: | ||
45 | if (!sdata->wdev.mesh_id_len) | ||
46 | continue; | ||
47 | break; | ||
44 | default: | 48 | default: |
45 | break; | 49 | break; |
46 | } | 50 | } |
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index 7ed433c66d68..d4272ff43f71 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c | |||
@@ -607,6 +607,7 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata) | |||
607 | MESHPARAMS_ADD(min_discovery_timeout); | 607 | MESHPARAMS_ADD(min_discovery_timeout); |
608 | MESHPARAMS_ADD(dot11MeshHWMPRootMode); | 608 | MESHPARAMS_ADD(dot11MeshHWMPRootMode); |
609 | MESHPARAMS_ADD(dot11MeshHWMPRannInterval); | 609 | MESHPARAMS_ADD(dot11MeshHWMPRannInterval); |
610 | MESHPARAMS_ADD(dot11MeshForwarding); | ||
610 | MESHPARAMS_ADD(dot11MeshGateAnnouncementProtocol); | 611 | MESHPARAMS_ADD(dot11MeshGateAnnouncementProtocol); |
611 | MESHPARAMS_ADD(rssi_threshold); | 612 | MESHPARAMS_ADD(rssi_threshold); |
612 | MESHPARAMS_ADD(ht_opmode); | 613 | MESHPARAMS_ADD(ht_opmode); |
@@ -685,6 +686,6 @@ void ieee80211_debugfs_rename_netdev(struct ieee80211_sub_if_data *sdata) | |||
685 | 686 | ||
686 | sprintf(buf, "netdev:%s", sdata->name); | 687 | sprintf(buf, "netdev:%s", sdata->name); |
687 | if (!debugfs_rename(dir->d_parent, dir, dir->d_parent, buf)) | 688 | if (!debugfs_rename(dir->d_parent, dir, dir->d_parent, buf)) |
688 | printk(KERN_ERR "mac80211: debugfs: failed to rename debugfs " | 689 | pr_err("mac80211: debugfs: failed to rename debugfs " |
689 | "dir to %s\n", buf); | 690 | "dir to %s\n", buf); |
690 | } | 691 | } |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 33d9d0c3e3d0..725cb4be229d 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -82,8 +82,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
82 | 82 | ||
83 | local->oper_channel = chan; | 83 | local->oper_channel = chan; |
84 | channel_type = ifibss->channel_type; | 84 | channel_type = ifibss->channel_type; |
85 | if (channel_type > NL80211_CHAN_HT20 && | 85 | if (!cfg80211_can_beacon_sec_chan(local->hw.wiphy, chan, channel_type)) |
86 | !cfg80211_can_beacon_sec_chan(local->hw.wiphy, chan, channel_type)) | ||
87 | channel_type = NL80211_CHAN_HT20; | 86 | channel_type = NL80211_CHAN_HT20; |
88 | if (!ieee80211_set_channel_type(local, sdata, channel_type)) { | 87 | if (!ieee80211_set_channel_type(local, sdata, channel_type)) { |
89 | /* can only fail due to HT40+/- mismatch */ | 88 | /* can only fail due to HT40+/- mismatch */ |
@@ -281,11 +280,8 @@ static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta, | |||
281 | if (sta_info_insert_rcu(sta)) | 280 | if (sta_info_insert_rcu(sta)) |
282 | return sta_info_get(sdata, addr); | 281 | return sta_info_get(sdata, addr); |
283 | if (auth) { | 282 | if (auth) { |
284 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 283 | ibss_vdbg("TX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=1)\n", |
285 | printk(KERN_DEBUG "TX Auth SA=%pM DA=%pM BSSID=%pM" | 284 | sdata->vif.addr, sdata->u.ibss.bssid, addr); |
286 | "(auth_transaction=1)\n", sdata->vif.addr, | ||
287 | sdata->u.ibss.bssid, addr); | ||
288 | #endif | ||
289 | ieee80211_send_auth(sdata, 1, WLAN_AUTH_OPEN, NULL, 0, | 285 | ieee80211_send_auth(sdata, 1, WLAN_AUTH_OPEN, NULL, 0, |
290 | addr, sdata->u.ibss.bssid, NULL, 0, 0); | 286 | addr, sdata->u.ibss.bssid, NULL, 0, 0); |
291 | } | 287 | } |
@@ -355,11 +351,9 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata, | |||
355 | 351 | ||
356 | if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1) | 352 | if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1) |
357 | return; | 353 | return; |
358 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 354 | ibss_vdbg("%s: RX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=%d)\n", |
359 | printk(KERN_DEBUG "%s: RX Auth SA=%pM DA=%pM BSSID=%pM." | 355 | sdata->name, mgmt->sa, mgmt->da, mgmt->bssid, |
360 | "(auth_transaction=%d)\n", | 356 | auth_transaction); |
361 | sdata->name, mgmt->sa, mgmt->da, mgmt->bssid, auth_transaction); | ||
362 | #endif | ||
363 | sta_info_destroy_addr(sdata, mgmt->sa); | 357 | sta_info_destroy_addr(sdata, mgmt->sa); |
364 | ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 0, false); | 358 | ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 0, false); |
365 | rcu_read_unlock(); | 359 | rcu_read_unlock(); |
@@ -422,15 +416,10 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
422 | ieee80211_mandatory_rates(local, band); | 416 | ieee80211_mandatory_rates(local, band); |
423 | 417 | ||
424 | if (sta->sta.supp_rates[band] != prev_rates) { | 418 | if (sta->sta.supp_rates[band] != prev_rates) { |
425 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 419 | ibss_vdbg("%s: updated supp_rates set for %pM based on beacon/probe_resp (0x%x -> 0x%x)\n", |
426 | printk(KERN_DEBUG | 420 | sdata->name, sta->sta.addr, |
427 | "%s: updated supp_rates set " | 421 | prev_rates, |
428 | "for %pM based on beacon" | 422 | sta->sta.supp_rates[band]); |
429 | "/probe_resp (0x%x -> 0x%x)\n", | ||
430 | sdata->name, sta->sta.addr, | ||
431 | prev_rates, | ||
432 | sta->sta.supp_rates[band]); | ||
433 | #endif | ||
434 | rates_updated = true; | 423 | rates_updated = true; |
435 | } | 424 | } |
436 | } else { | 425 | } else { |
@@ -545,22 +534,16 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
545 | rx_timestamp = drv_get_tsf(local, sdata); | 534 | rx_timestamp = drv_get_tsf(local, sdata); |
546 | } | 535 | } |
547 | 536 | ||
548 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 537 | ibss_vdbg("RX beacon SA=%pM BSSID=%pM TSF=0x%llx BCN=0x%llx diff=%lld @%lu\n", |
549 | printk(KERN_DEBUG "RX beacon SA=%pM BSSID=" | 538 | mgmt->sa, mgmt->bssid, |
550 | "%pM TSF=0x%llx BCN=0x%llx diff=%lld @%lu\n", | 539 | (unsigned long long)rx_timestamp, |
551 | mgmt->sa, mgmt->bssid, | 540 | (unsigned long long)beacon_timestamp, |
552 | (unsigned long long)rx_timestamp, | 541 | (unsigned long long)(rx_timestamp - beacon_timestamp), |
553 | (unsigned long long)beacon_timestamp, | 542 | jiffies); |
554 | (unsigned long long)(rx_timestamp - beacon_timestamp), | ||
555 | jiffies); | ||
556 | #endif | ||
557 | 543 | ||
558 | if (beacon_timestamp > rx_timestamp) { | 544 | if (beacon_timestamp > rx_timestamp) { |
559 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 545 | ibss_vdbg("%s: beacon TSF higher than local TSF - IBSS merge with BSSID %pM\n", |
560 | printk(KERN_DEBUG "%s: beacon TSF higher than " | 546 | sdata->name, mgmt->bssid); |
561 | "local TSF - IBSS merge with BSSID %pM\n", | ||
562 | sdata->name, mgmt->bssid); | ||
563 | #endif | ||
564 | ieee80211_sta_join_ibss(sdata, bss); | 547 | ieee80211_sta_join_ibss(sdata, bss); |
565 | supp_rates = ieee80211_sta_get_rates(local, elems, band, NULL); | 548 | supp_rates = ieee80211_sta_get_rates(local, elems, band, NULL); |
566 | ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, | 549 | ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, |
@@ -662,8 +645,8 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata) | |||
662 | if (ifibss->fixed_channel) | 645 | if (ifibss->fixed_channel) |
663 | return; | 646 | return; |
664 | 647 | ||
665 | printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other " | 648 | pr_debug("%s: No active IBSS STAs - trying to scan for other IBSS networks with same SSID (merge)\n", |
666 | "IBSS networks with same SSID (merge)\n", sdata->name); | 649 | sdata->name); |
667 | 650 | ||
668 | ieee80211_request_internal_scan(sdata, | 651 | ieee80211_request_internal_scan(sdata, |
669 | ifibss->ssid, ifibss->ssid_len, NULL); | 652 | ifibss->ssid, ifibss->ssid_len, NULL); |
@@ -691,8 +674,8 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) | |||
691 | bssid[0] |= 0x02; | 674 | bssid[0] |= 0x02; |
692 | } | 675 | } |
693 | 676 | ||
694 | printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %pM\n", | 677 | pr_debug("%s: Creating new IBSS network, BSSID %pM\n", |
695 | sdata->name, bssid); | 678 | sdata->name, bssid); |
696 | 679 | ||
697 | capability = WLAN_CAPABILITY_IBSS; | 680 | capability = WLAN_CAPABILITY_IBSS; |
698 | 681 | ||
@@ -723,10 +706,8 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) | |||
723 | lockdep_assert_held(&ifibss->mtx); | 706 | lockdep_assert_held(&ifibss->mtx); |
724 | 707 | ||
725 | active_ibss = ieee80211_sta_active_ibss(sdata); | 708 | active_ibss = ieee80211_sta_active_ibss(sdata); |
726 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 709 | ibss_vdbg("%s: sta_find_ibss (active_ibss=%d)\n", |
727 | printk(KERN_DEBUG "%s: sta_find_ibss (active_ibss=%d)\n", | 710 | sdata->name, active_ibss); |
728 | sdata->name, active_ibss); | ||
729 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | ||
730 | 711 | ||
731 | if (active_ibss) | 712 | if (active_ibss) |
732 | return; | 713 | return; |
@@ -749,29 +730,23 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) | |||
749 | struct ieee80211_bss *bss; | 730 | struct ieee80211_bss *bss; |
750 | 731 | ||
751 | bss = (void *)cbss->priv; | 732 | bss = (void *)cbss->priv; |
752 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 733 | ibss_vdbg(" sta_find_ibss: selected %pM current %pM\n", |
753 | printk(KERN_DEBUG " sta_find_ibss: selected %pM current " | 734 | cbss->bssid, ifibss->bssid); |
754 | "%pM\n", cbss->bssid, ifibss->bssid); | 735 | pr_debug("%s: Selected IBSS BSSID %pM based on configured SSID\n", |
755 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | 736 | sdata->name, cbss->bssid); |
756 | |||
757 | printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM" | ||
758 | " based on configured SSID\n", | ||
759 | sdata->name, cbss->bssid); | ||
760 | 737 | ||
761 | ieee80211_sta_join_ibss(sdata, bss); | 738 | ieee80211_sta_join_ibss(sdata, bss); |
762 | ieee80211_rx_bss_put(local, bss); | 739 | ieee80211_rx_bss_put(local, bss); |
763 | return; | 740 | return; |
764 | } | 741 | } |
765 | 742 | ||
766 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 743 | ibss_vdbg(" did not try to join ibss\n"); |
767 | printk(KERN_DEBUG " did not try to join ibss\n"); | ||
768 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | ||
769 | 744 | ||
770 | /* Selected IBSS not found in current scan results - try to scan */ | 745 | /* Selected IBSS not found in current scan results - try to scan */ |
771 | if (time_after(jiffies, ifibss->last_scan_completed + | 746 | if (time_after(jiffies, ifibss->last_scan_completed + |
772 | IEEE80211_SCAN_INTERVAL)) { | 747 | IEEE80211_SCAN_INTERVAL)) { |
773 | printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to " | 748 | pr_debug("%s: Trigger new scan to find an IBSS to join\n", |
774 | "join\n", sdata->name); | 749 | sdata->name); |
775 | 750 | ||
776 | ieee80211_request_internal_scan(sdata, | 751 | ieee80211_request_internal_scan(sdata, |
777 | ifibss->ssid, ifibss->ssid_len, | 752 | ifibss->ssid, ifibss->ssid_len, |
@@ -785,9 +760,9 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) | |||
785 | ieee80211_sta_create_ibss(sdata); | 760 | ieee80211_sta_create_ibss(sdata); |
786 | return; | 761 | return; |
787 | } | 762 | } |
788 | printk(KERN_DEBUG "%s: IBSS not allowed on" | 763 | pr_debug("%s: IBSS not allowed on %d MHz\n", |
789 | " %d MHz\n", sdata->name, | 764 | sdata->name, |
790 | local->hw.conf.channel->center_freq); | 765 | local->hw.conf.channel->center_freq); |
791 | 766 | ||
792 | /* No IBSS found - decrease scan interval and continue | 767 | /* No IBSS found - decrease scan interval and continue |
793 | * scanning. */ | 768 | * scanning. */ |
@@ -822,12 +797,9 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, | |||
822 | 797 | ||
823 | tx_last_beacon = drv_tx_last_beacon(local); | 798 | tx_last_beacon = drv_tx_last_beacon(local); |
824 | 799 | ||
825 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 800 | ibss_vdbg("%s: RX ProbeReq SA=%pM DA=%pM BSSID=%pM (tx_last_beacon=%d)\n", |
826 | printk(KERN_DEBUG "%s: RX ProbeReq SA=%pM DA=%pM BSSID=%pM" | 801 | sdata->name, mgmt->sa, mgmt->da, |
827 | " (tx_last_beacon=%d)\n", | 802 | mgmt->bssid, tx_last_beacon); |
828 | sdata->name, mgmt->sa, mgmt->da, | ||
829 | mgmt->bssid, tx_last_beacon); | ||
830 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | ||
831 | 803 | ||
832 | if (!tx_last_beacon && is_multicast_ether_addr(mgmt->da)) | 804 | if (!tx_last_beacon && is_multicast_ether_addr(mgmt->da)) |
833 | return; | 805 | return; |
@@ -840,11 +812,8 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, | |||
840 | pos = mgmt->u.probe_req.variable; | 812 | pos = mgmt->u.probe_req.variable; |
841 | if (pos[0] != WLAN_EID_SSID || | 813 | if (pos[0] != WLAN_EID_SSID || |
842 | pos + 2 + pos[1] > end) { | 814 | pos + 2 + pos[1] > end) { |
843 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 815 | ibss_vdbg("%s: Invalid SSID IE in ProbeReq from %pM\n", |
844 | printk(KERN_DEBUG "%s: Invalid SSID IE in ProbeReq " | 816 | sdata->name, mgmt->sa); |
845 | "from %pM\n", | ||
846 | sdata->name, mgmt->sa); | ||
847 | #endif | ||
848 | return; | 817 | return; |
849 | } | 818 | } |
850 | if (pos[1] != 0 && | 819 | if (pos[1] != 0 && |
@@ -861,10 +830,7 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, | |||
861 | 830 | ||
862 | resp = (struct ieee80211_mgmt *) skb->data; | 831 | resp = (struct ieee80211_mgmt *) skb->data; |
863 | memcpy(resp->da, mgmt->sa, ETH_ALEN); | 832 | memcpy(resp->da, mgmt->sa, ETH_ALEN); |
864 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 833 | ibss_vdbg("%s: Sending ProbeResp to %pM\n", sdata->name, resp->da); |
865 | printk(KERN_DEBUG "%s: Sending ProbeResp to %pM\n", | ||
866 | sdata->name, resp->da); | ||
867 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | ||
868 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; | 834 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; |
869 | ieee80211_tx_skb(sdata, skb); | 835 | ieee80211_tx_skb(sdata, skb); |
870 | } | 836 | } |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 3f3cd50fff16..e6cbf5b68c89 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -317,55 +317,30 @@ struct mesh_preq_queue { | |||
317 | u8 flags; | 317 | u8 flags; |
318 | }; | 318 | }; |
319 | 319 | ||
320 | enum ieee80211_work_type { | 320 | #if HZ/100 == 0 |
321 | IEEE80211_WORK_ABORT, | 321 | #define IEEE80211_ROC_MIN_LEFT 1 |
322 | IEEE80211_WORK_REMAIN_ON_CHANNEL, | 322 | #else |
323 | IEEE80211_WORK_OFFCHANNEL_TX, | 323 | #define IEEE80211_ROC_MIN_LEFT (HZ/100) |
324 | }; | 324 | #endif |
325 | |||
326 | /** | ||
327 | * enum work_done_result - indicates what to do after work was done | ||
328 | * | ||
329 | * @WORK_DONE_DESTROY: This work item is no longer needed, destroy. | ||
330 | * @WORK_DONE_REQUEUE: This work item was reset to be reused, and | ||
331 | * should be requeued. | ||
332 | */ | ||
333 | enum work_done_result { | ||
334 | WORK_DONE_DESTROY, | ||
335 | WORK_DONE_REQUEUE, | ||
336 | }; | ||
337 | 325 | ||
338 | struct ieee80211_work { | 326 | struct ieee80211_roc_work { |
339 | struct list_head list; | 327 | struct list_head list; |
328 | struct list_head dependents; | ||
340 | 329 | ||
341 | struct rcu_head rcu_head; | 330 | struct delayed_work work; |
342 | 331 | ||
343 | struct ieee80211_sub_if_data *sdata; | 332 | struct ieee80211_sub_if_data *sdata; |
344 | 333 | ||
345 | enum work_done_result (*done)(struct ieee80211_work *wk, | ||
346 | struct sk_buff *skb); | ||
347 | |||
348 | struct ieee80211_channel *chan; | 334 | struct ieee80211_channel *chan; |
349 | enum nl80211_channel_type chan_type; | 335 | enum nl80211_channel_type chan_type; |
350 | 336 | ||
351 | unsigned long timeout; | 337 | bool started, abort, hw_begun, notified; |
352 | enum ieee80211_work_type type; | ||
353 | 338 | ||
354 | bool started; | 339 | unsigned long hw_start_time; |
355 | 340 | ||
356 | union { | 341 | u32 duration, req_duration; |
357 | struct { | 342 | struct sk_buff *frame; |
358 | u32 duration; | 343 | u64 mgmt_tx_cookie; |
359 | } remain; | ||
360 | struct { | ||
361 | struct sk_buff *frame; | ||
362 | u32 wait; | ||
363 | bool status; | ||
364 | } offchan_tx; | ||
365 | }; | ||
366 | |||
367 | size_t data_len; | ||
368 | u8 data[]; | ||
369 | }; | 344 | }; |
370 | 345 | ||
371 | /* flags used in struct ieee80211_if_managed.flags */ | 346 | /* flags used in struct ieee80211_if_managed.flags */ |
@@ -399,7 +374,6 @@ struct ieee80211_mgd_auth_data { | |||
399 | struct ieee80211_mgd_assoc_data { | 374 | struct ieee80211_mgd_assoc_data { |
400 | struct cfg80211_bss *bss; | 375 | struct cfg80211_bss *bss; |
401 | const u8 *supp_rates; | 376 | const u8 *supp_rates; |
402 | const u8 *ht_operation_ie; | ||
403 | 377 | ||
404 | unsigned long timeout; | 378 | unsigned long timeout; |
405 | int tries; | 379 | int tries; |
@@ -414,6 +388,8 @@ struct ieee80211_mgd_assoc_data { | |||
414 | bool sent_assoc; | 388 | bool sent_assoc; |
415 | bool synced; | 389 | bool synced; |
416 | 390 | ||
391 | u8 ap_ht_param; | ||
392 | |||
417 | size_t ie_len; | 393 | size_t ie_len; |
418 | u8 ie[]; | 394 | u8 ie[]; |
419 | }; | 395 | }; |
@@ -847,13 +823,6 @@ struct ieee80211_local { | |||
847 | const struct ieee80211_ops *ops; | 823 | const struct ieee80211_ops *ops; |
848 | 824 | ||
849 | /* | 825 | /* |
850 | * work stuff, potentially off-channel (in the future) | ||
851 | */ | ||
852 | struct list_head work_list; | ||
853 | struct timer_list work_timer; | ||
854 | struct work_struct work_work; | ||
855 | |||
856 | /* | ||
857 | * private workqueue to mac80211. mac80211 makes this accessible | 826 | * private workqueue to mac80211. mac80211 makes this accessible |
858 | * via ieee80211_queue_work() | 827 | * via ieee80211_queue_work() |
859 | */ | 828 | */ |
@@ -1087,14 +1056,12 @@ struct ieee80211_local { | |||
1087 | } debugfs; | 1056 | } debugfs; |
1088 | #endif | 1057 | #endif |
1089 | 1058 | ||
1090 | struct ieee80211_channel *hw_roc_channel; | 1059 | /* |
1091 | struct net_device *hw_roc_dev; | 1060 | * Remain-on-channel support |
1092 | struct sk_buff *hw_roc_skb, *hw_roc_skb_for_status; | 1061 | */ |
1062 | struct list_head roc_list; | ||
1093 | struct work_struct hw_roc_start, hw_roc_done; | 1063 | struct work_struct hw_roc_start, hw_roc_done; |
1094 | enum nl80211_channel_type hw_roc_channel_type; | 1064 | unsigned long hw_roc_start_time; |
1095 | unsigned int hw_roc_duration; | ||
1096 | u32 hw_roc_cookie; | ||
1097 | bool hw_roc_for_tx; | ||
1098 | 1065 | ||
1099 | struct idr ack_status_frames; | 1066 | struct idr ack_status_frames; |
1100 | spinlock_t ack_status_lock; | 1067 | spinlock_t ack_status_lock; |
@@ -1290,7 +1257,12 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local, | |||
1290 | bool offchannel_ps_enable); | 1257 | bool offchannel_ps_enable); |
1291 | void ieee80211_offchannel_return(struct ieee80211_local *local, | 1258 | void ieee80211_offchannel_return(struct ieee80211_local *local, |
1292 | bool offchannel_ps_disable); | 1259 | bool offchannel_ps_disable); |
1293 | void ieee80211_hw_roc_setup(struct ieee80211_local *local); | 1260 | void ieee80211_roc_setup(struct ieee80211_local *local); |
1261 | void ieee80211_start_next_roc(struct ieee80211_local *local); | ||
1262 | void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata); | ||
1263 | void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc); | ||
1264 | void ieee80211_sw_roc_work(struct work_struct *work); | ||
1265 | void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc); | ||
1294 | 1266 | ||
1295 | /* interface handling */ | 1267 | /* interface handling */ |
1296 | int ieee80211_iface_init(void); | 1268 | int ieee80211_iface_init(void); |
@@ -1500,18 +1472,6 @@ u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, | |||
1500 | enum nl80211_channel_type channel_type, | 1472 | enum nl80211_channel_type channel_type, |
1501 | u16 prot_mode); | 1473 | u16 prot_mode); |
1502 | 1474 | ||
1503 | /* internal work items */ | ||
1504 | void ieee80211_work_init(struct ieee80211_local *local); | ||
1505 | void ieee80211_add_work(struct ieee80211_work *wk); | ||
1506 | void free_work(struct ieee80211_work *wk); | ||
1507 | void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata); | ||
1508 | int ieee80211_wk_remain_on_channel(struct ieee80211_sub_if_data *sdata, | ||
1509 | struct ieee80211_channel *chan, | ||
1510 | enum nl80211_channel_type channel_type, | ||
1511 | unsigned int duration, u64 *cookie); | ||
1512 | int ieee80211_wk_cancel_remain_on_channel( | ||
1513 | struct ieee80211_sub_if_data *sdata, u64 cookie); | ||
1514 | |||
1515 | /* channel management */ | 1475 | /* channel management */ |
1516 | enum ieee80211_chan_mode { | 1476 | enum ieee80211_chan_mode { |
1517 | CHAN_MODE_UNDEFINED, | 1477 | CHAN_MODE_UNDEFINED, |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 8664111d0566..87aeb4f21ffd 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -58,7 +58,7 @@ static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) | |||
58 | } | 58 | } |
59 | 59 | ||
60 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 60 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
61 | printk(KERN_DEBUG "%s: setting MTU %d\n", dev->name, new_mtu); | 61 | pr_debug("%s: setting MTU %d\n", dev->name, new_mtu); |
62 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | 62 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ |
63 | dev->mtu = new_mtu; | 63 | dev->mtu = new_mtu; |
64 | return 0; | 64 | return 0; |
@@ -528,10 +528,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
528 | */ | 528 | */ |
529 | netif_tx_stop_all_queues(sdata->dev); | 529 | netif_tx_stop_all_queues(sdata->dev); |
530 | 530 | ||
531 | /* | 531 | ieee80211_roc_purge(sdata); |
532 | * Purge work for this interface. | ||
533 | */ | ||
534 | ieee80211_work_purge(sdata); | ||
535 | 532 | ||
536 | /* | 533 | /* |
537 | * Remove all stations associated with this interface. | 534 | * Remove all stations associated with this interface. |
@@ -637,18 +634,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
637 | ieee80211_configure_filter(local); | 634 | ieee80211_configure_filter(local); |
638 | break; | 635 | break; |
639 | default: | 636 | default: |
640 | mutex_lock(&local->mtx); | ||
641 | if (local->hw_roc_dev == sdata->dev && | ||
642 | local->hw_roc_channel) { | ||
643 | /* ignore return value since this is racy */ | ||
644 | drv_cancel_remain_on_channel(local); | ||
645 | ieee80211_queue_work(&local->hw, &local->hw_roc_done); | ||
646 | } | ||
647 | mutex_unlock(&local->mtx); | ||
648 | |||
649 | flush_work(&local->hw_roc_start); | ||
650 | flush_work(&local->hw_roc_done); | ||
651 | |||
652 | flush_work(&sdata->work); | 637 | flush_work(&sdata->work); |
653 | /* | 638 | /* |
654 | * When we get here, the interface is marked down. | 639 | * When we get here, the interface is marked down. |
@@ -1238,7 +1223,7 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local, | |||
1238 | 1223 | ||
1239 | if (__ffs64(mask) + hweight64(mask) != fls64(mask)) { | 1224 | if (__ffs64(mask) + hweight64(mask) != fls64(mask)) { |
1240 | /* not a contiguous mask ... not handled now! */ | 1225 | /* not a contiguous mask ... not handled now! */ |
1241 | printk(KERN_DEBUG "not contiguous\n"); | 1226 | pr_debug("not contiguous\n"); |
1242 | break; | 1227 | break; |
1243 | } | 1228 | } |
1244 | 1229 | ||
@@ -1364,6 +1349,8 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, | |||
1364 | sdata->u.mgd.use_4addr = params->use_4addr; | 1349 | sdata->u.mgd.use_4addr = params->use_4addr; |
1365 | } | 1350 | } |
1366 | 1351 | ||
1352 | ndev->features |= local->hw.netdev_features; | ||
1353 | |||
1367 | ret = register_netdevice(ndev); | 1354 | ret = register_netdevice(ndev); |
1368 | if (ret) | 1355 | if (ret) |
1369 | goto fail; | 1356 | goto fail; |
@@ -1454,9 +1441,9 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local) | |||
1454 | { | 1441 | { |
1455 | struct ieee80211_sub_if_data *sdata; | 1442 | struct ieee80211_sub_if_data *sdata; |
1456 | int count = 0; | 1443 | int count = 0; |
1457 | bool working = false, scanning = false, hw_roc = false; | 1444 | bool working = false, scanning = false; |
1458 | struct ieee80211_work *wk; | ||
1459 | unsigned int led_trig_start = 0, led_trig_stop = 0; | 1445 | unsigned int led_trig_start = 0, led_trig_stop = 0; |
1446 | struct ieee80211_roc_work *roc; | ||
1460 | 1447 | ||
1461 | #ifdef CONFIG_PROVE_LOCKING | 1448 | #ifdef CONFIG_PROVE_LOCKING |
1462 | WARN_ON(debug_locks && !lockdep_rtnl_is_held() && | 1449 | WARN_ON(debug_locks && !lockdep_rtnl_is_held() && |
@@ -1491,9 +1478,11 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local) | |||
1491 | count++; | 1478 | count++; |
1492 | } | 1479 | } |
1493 | 1480 | ||
1494 | list_for_each_entry(wk, &local->work_list, list) { | 1481 | if (!local->ops->remain_on_channel) { |
1495 | working = true; | 1482 | list_for_each_entry(roc, &local->roc_list, list) { |
1496 | wk->sdata->vif.bss_conf.idle = false; | 1483 | working = true; |
1484 | roc->sdata->vif.bss_conf.idle = false; | ||
1485 | } | ||
1497 | } | 1486 | } |
1498 | 1487 | ||
1499 | if (local->scan_sdata && | 1488 | if (local->scan_sdata && |
@@ -1502,9 +1491,6 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local) | |||
1502 | local->scan_sdata->vif.bss_conf.idle = false; | 1491 | local->scan_sdata->vif.bss_conf.idle = false; |
1503 | } | 1492 | } |
1504 | 1493 | ||
1505 | if (local->hw_roc_channel) | ||
1506 | hw_roc = true; | ||
1507 | |||
1508 | list_for_each_entry(sdata, &local->interfaces, list) { | 1494 | list_for_each_entry(sdata, &local->interfaces, list) { |
1509 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR || | 1495 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR || |
1510 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | 1496 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) |
@@ -1516,7 +1502,7 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local) | |||
1516 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE); | 1502 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE); |
1517 | } | 1503 | } |
1518 | 1504 | ||
1519 | if (working || scanning || hw_roc) | 1505 | if (working || scanning) |
1520 | led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_WORK; | 1506 | led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_WORK; |
1521 | else | 1507 | else |
1522 | led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_WORK; | 1508 | led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_WORK; |
@@ -1528,8 +1514,6 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local) | |||
1528 | 1514 | ||
1529 | ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop); | 1515 | ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop); |
1530 | 1516 | ||
1531 | if (hw_roc) | ||
1532 | return ieee80211_idle_off(local, "hw remain-on-channel"); | ||
1533 | if (working) | 1517 | if (working) |
1534 | return ieee80211_idle_off(local, "working"); | 1518 | return ieee80211_idle_off(local, "working"); |
1535 | if (scanning) | 1519 | if (scanning) |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index f5548e953259..d81c178c7712 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -625,8 +625,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
625 | 625 | ||
626 | INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work); | 626 | INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work); |
627 | 627 | ||
628 | ieee80211_work_init(local); | ||
629 | |||
630 | INIT_WORK(&local->restart_work, ieee80211_restart_work); | 628 | INIT_WORK(&local->restart_work, ieee80211_restart_work); |
631 | 629 | ||
632 | INIT_WORK(&local->reconfig_filter, ieee80211_reconfig_filter); | 630 | INIT_WORK(&local->reconfig_filter, ieee80211_reconfig_filter); |
@@ -669,7 +667,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
669 | 667 | ||
670 | ieee80211_led_names(local); | 668 | ieee80211_led_names(local); |
671 | 669 | ||
672 | ieee80211_hw_roc_setup(local); | 670 | ieee80211_roc_setup(local); |
673 | 671 | ||
674 | return &local->hw; | 672 | return &local->hw; |
675 | } | 673 | } |
@@ -682,6 +680,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
682 | enum ieee80211_band band; | 680 | enum ieee80211_band band; |
683 | int channels, max_bitrates; | 681 | int channels, max_bitrates; |
684 | bool supp_ht; | 682 | bool supp_ht; |
683 | netdev_features_t feature_whitelist; | ||
685 | static const u32 cipher_suites[] = { | 684 | static const u32 cipher_suites[] = { |
686 | /* keep WEP first, it may be removed below */ | 685 | /* keep WEP first, it may be removed below */ |
687 | WLAN_CIPHER_SUITE_WEP40, | 686 | WLAN_CIPHER_SUITE_WEP40, |
@@ -708,6 +707,12 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
708 | if ((hw->flags & IEEE80211_HW_SCAN_WHILE_IDLE) && !local->ops->hw_scan) | 707 | if ((hw->flags & IEEE80211_HW_SCAN_WHILE_IDLE) && !local->ops->hw_scan) |
709 | return -EINVAL; | 708 | return -EINVAL; |
710 | 709 | ||
710 | /* Only HW csum features are currently compatible with mac80211 */ | ||
711 | feature_whitelist = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | | ||
712 | NETIF_F_HW_CSUM; | ||
713 | if (WARN_ON(hw->netdev_features & ~feature_whitelist)) | ||
714 | return -EINVAL; | ||
715 | |||
711 | if (hw->max_report_rates == 0) | 716 | if (hw->max_report_rates == 0) |
712 | hw->max_report_rates = hw->max_rates; | 717 | hw->max_report_rates = hw->max_rates; |
713 | 718 | ||
@@ -1009,12 +1014,6 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
1009 | 1014 | ||
1010 | rtnl_unlock(); | 1015 | rtnl_unlock(); |
1011 | 1016 | ||
1012 | /* | ||
1013 | * Now all work items will be gone, but the | ||
1014 | * timer might still be armed, so delete it | ||
1015 | */ | ||
1016 | del_timer_sync(&local->work_timer); | ||
1017 | |||
1018 | cancel_work_sync(&local->restart_work); | 1017 | cancel_work_sync(&local->restart_work); |
1019 | cancel_work_sync(&local->reconfig_filter); | 1018 | cancel_work_sync(&local->reconfig_filter); |
1020 | 1019 | ||
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 2913113c5833..7cf19509fb68 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -524,8 +524,7 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata, | |||
524 | bool free_plinks; | 524 | bool free_plinks; |
525 | 525 | ||
526 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 526 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
527 | printk(KERN_DEBUG "%s: running mesh housekeeping\n", | 527 | pr_debug("%s: running mesh housekeeping\n", sdata->name); |
528 | sdata->name); | ||
529 | #endif | 528 | #endif |
530 | 529 | ||
531 | ieee80211_sta_expire(sdata, IEEE80211_MESH_PEER_INACTIVITY_LIMIT); | 530 | ieee80211_sta_expire(sdata, IEEE80211_MESH_PEER_INACTIVITY_LIMIT); |
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 9b59658e8650..fa7c58035246 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c | |||
@@ -15,7 +15,7 @@ | |||
15 | 15 | ||
16 | #ifdef CONFIG_MAC80211_VERBOSE_MHWMP_DEBUG | 16 | #ifdef CONFIG_MAC80211_VERBOSE_MHWMP_DEBUG |
17 | #define mhwmp_dbg(fmt, args...) \ | 17 | #define mhwmp_dbg(fmt, args...) \ |
18 | printk(KERN_DEBUG "Mesh HWMP (%s): " fmt "\n", sdata->name, ##args) | 18 | pr_debug("Mesh HWMP (%s): " fmt "\n", sdata->name, ##args) |
19 | #else | 19 | #else |
20 | #define mhwmp_dbg(fmt, args...) do { (void)(0); } while (0) | 20 | #define mhwmp_dbg(fmt, args...) do { (void)(0); } while (0) |
21 | #endif | 21 | #endif |
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index b39224d8255c..572f706fd65b 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c | |||
@@ -19,7 +19,7 @@ | |||
19 | #include "mesh.h" | 19 | #include "mesh.h" |
20 | 20 | ||
21 | #ifdef CONFIG_MAC80211_VERBOSE_MPATH_DEBUG | 21 | #ifdef CONFIG_MAC80211_VERBOSE_MPATH_DEBUG |
22 | #define mpath_dbg(fmt, args...) printk(KERN_DEBUG fmt, ##args) | 22 | #define mpath_dbg(fmt, args...) pr_debug(fmt, ##args) |
23 | #else | 23 | #else |
24 | #define mpath_dbg(fmt, args...) do { (void)(0); } while (0) | 24 | #define mpath_dbg(fmt, args...) do { (void)(0); } while (0) |
25 | #endif | 25 | #endif |
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 60ef235c9d9b..be4fad128c34 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c | |||
@@ -14,7 +14,7 @@ | |||
14 | #include "mesh.h" | 14 | #include "mesh.h" |
15 | 15 | ||
16 | #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG | 16 | #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG |
17 | #define mpl_dbg(fmt, args...) printk(KERN_DEBUG fmt, ##args) | 17 | #define mpl_dbg(fmt, args...) pr_debug(fmt, ##args) |
18 | #else | 18 | #else |
19 | #define mpl_dbg(fmt, args...) do { (void)(0); } while (0) | 19 | #define mpl_dbg(fmt, args...) do { (void)(0); } while (0) |
20 | #endif | 20 | #endif |
diff --git a/net/mac80211/mesh_sync.c b/net/mac80211/mesh_sync.c index 38d30e8ce6dc..0ccdad49f987 100644 --- a/net/mac80211/mesh_sync.c +++ b/net/mac80211/mesh_sync.c | |||
@@ -14,7 +14,7 @@ | |||
14 | 14 | ||
15 | #ifdef CONFIG_MAC80211_VERBOSE_MESH_SYNC_DEBUG | 15 | #ifdef CONFIG_MAC80211_VERBOSE_MESH_SYNC_DEBUG |
16 | #define msync_dbg(fmt, args...) \ | 16 | #define msync_dbg(fmt, args...) \ |
17 | printk(KERN_DEBUG "Mesh sync (%s): " fmt "\n", sdata->name, ##args) | 17 | pr_debug("Mesh sync (%s): " fmt "\n", sdata->name, ##args) |
18 | #else | 18 | #else |
19 | #define msync_dbg(fmt, args...) do { (void)(0); } while (0) | 19 | #define msync_dbg(fmt, args...) do { (void)(0); } while (0) |
20 | #endif | 20 | #endif |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index d94627c2929c..0f45d02e0ba7 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -258,12 +258,11 @@ static int ieee80211_compatible_rates(const u8 *supp_rates, int supp_rates_len, | |||
258 | } | 258 | } |
259 | 259 | ||
260 | static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata, | 260 | static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata, |
261 | struct sk_buff *skb, const u8 *ht_oper_ie, | 261 | struct sk_buff *skb, u8 ap_ht_param, |
262 | struct ieee80211_supported_band *sband, | 262 | struct ieee80211_supported_band *sband, |
263 | struct ieee80211_channel *channel, | 263 | struct ieee80211_channel *channel, |
264 | enum ieee80211_smps_mode smps) | 264 | enum ieee80211_smps_mode smps) |
265 | { | 265 | { |
266 | struct ieee80211_ht_operation *ht_oper; | ||
267 | u8 *pos; | 266 | u8 *pos; |
268 | u32 flags = channel->flags; | 267 | u32 flags = channel->flags; |
269 | u16 cap; | 268 | u16 cap; |
@@ -271,21 +270,13 @@ static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata, | |||
271 | 270 | ||
272 | BUILD_BUG_ON(sizeof(ht_cap) != sizeof(sband->ht_cap)); | 271 | BUILD_BUG_ON(sizeof(ht_cap) != sizeof(sband->ht_cap)); |
273 | 272 | ||
274 | if (!ht_oper_ie) | ||
275 | return; | ||
276 | |||
277 | if (ht_oper_ie[1] < sizeof(struct ieee80211_ht_operation)) | ||
278 | return; | ||
279 | |||
280 | memcpy(&ht_cap, &sband->ht_cap, sizeof(ht_cap)); | 273 | memcpy(&ht_cap, &sband->ht_cap, sizeof(ht_cap)); |
281 | ieee80211_apply_htcap_overrides(sdata, &ht_cap); | 274 | ieee80211_apply_htcap_overrides(sdata, &ht_cap); |
282 | 275 | ||
283 | ht_oper = (struct ieee80211_ht_operation *)(ht_oper_ie + 2); | ||
284 | |||
285 | /* determine capability flags */ | 276 | /* determine capability flags */ |
286 | cap = ht_cap.cap; | 277 | cap = ht_cap.cap; |
287 | 278 | ||
288 | switch (ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { | 279 | switch (ap_ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { |
289 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: | 280 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: |
290 | if (flags & IEEE80211_CHAN_NO_HT40PLUS) { | 281 | if (flags & IEEE80211_CHAN_NO_HT40PLUS) { |
291 | cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; | 282 | cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; |
@@ -509,7 +500,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) | |||
509 | } | 500 | } |
510 | 501 | ||
511 | if (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) | 502 | if (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) |
512 | ieee80211_add_ht_ie(sdata, skb, assoc_data->ht_operation_ie, | 503 | ieee80211_add_ht_ie(sdata, skb, assoc_data->ap_ht_param, |
513 | sband, local->oper_channel, ifmgd->ap_smps); | 504 | sband, local->oper_channel, ifmgd->ap_smps); |
514 | 505 | ||
515 | /* if present, add any custom non-vendor IEs that go after HT */ | 506 | /* if present, add any custom non-vendor IEs that go after HT */ |
@@ -939,11 +930,6 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency) | |||
939 | return; | 930 | return; |
940 | } | 931 | } |
941 | 932 | ||
942 | if (!list_empty(&local->work_list)) { | ||
943 | local->ps_sdata = NULL; | ||
944 | goto change; | ||
945 | } | ||
946 | |||
947 | list_for_each_entry(sdata, &local->interfaces, list) { | 933 | list_for_each_entry(sdata, &local->interfaces, list) { |
948 | if (!ieee80211_sdata_running(sdata)) | 934 | if (!ieee80211_sdata_running(sdata)) |
949 | continue; | 935 | continue; |
@@ -1016,7 +1002,6 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency) | |||
1016 | local->ps_sdata = NULL; | 1002 | local->ps_sdata = NULL; |
1017 | } | 1003 | } |
1018 | 1004 | ||
1019 | change: | ||
1020 | ieee80211_change_ps(local); | 1005 | ieee80211_change_ps(local); |
1021 | } | 1006 | } |
1022 | 1007 | ||
@@ -1585,6 +1570,8 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, | |||
1585 | net_dbg_ratelimited("%s: detected beacon loss from AP - sending probe request\n", | 1570 | net_dbg_ratelimited("%s: detected beacon loss from AP - sending probe request\n", |
1586 | sdata->name); | 1571 | sdata->name); |
1587 | #endif | 1572 | #endif |
1573 | ieee80211_cqm_rssi_notify(&sdata->vif, | ||
1574 | NL80211_CQM_RSSI_BEACON_LOSS_EVENT, GFP_KERNEL); | ||
1588 | 1575 | ||
1589 | /* | 1576 | /* |
1590 | * The driver/our work has already reported this event or the | 1577 | * The driver/our work has already reported this event or the |
@@ -1667,8 +1654,7 @@ static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata) | |||
1667 | 1654 | ||
1668 | memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN); | 1655 | memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN); |
1669 | 1656 | ||
1670 | printk(KERN_DEBUG "%s: Connection to AP %pM lost.\n", | 1657 | pr_debug("%s: Connection to AP %pM lost\n", sdata->name, bssid); |
1671 | sdata->name, bssid); | ||
1672 | 1658 | ||
1673 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, | 1659 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, |
1674 | WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, | 1660 | WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, |
@@ -1802,9 +1788,10 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, | |||
1802 | return RX_MGMT_NONE; | 1788 | return RX_MGMT_NONE; |
1803 | 1789 | ||
1804 | if (status_code != WLAN_STATUS_SUCCESS) { | 1790 | if (status_code != WLAN_STATUS_SUCCESS) { |
1805 | printk(KERN_DEBUG "%s: %pM denied authentication (status %d)\n", | 1791 | pr_debug("%s: %pM denied authentication (status %d)\n", |
1806 | sdata->name, mgmt->sa, status_code); | 1792 | sdata->name, mgmt->sa, status_code); |
1807 | goto out; | 1793 | ieee80211_destroy_auth_data(sdata, false); |
1794 | return RX_MGMT_CFG80211_RX_AUTH; | ||
1808 | } | 1795 | } |
1809 | 1796 | ||
1810 | switch (ifmgd->auth_data->algorithm) { | 1797 | switch (ifmgd->auth_data->algorithm) { |
@@ -1825,8 +1812,7 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, | |||
1825 | return RX_MGMT_NONE; | 1812 | return RX_MGMT_NONE; |
1826 | } | 1813 | } |
1827 | 1814 | ||
1828 | printk(KERN_DEBUG "%s: authenticated\n", sdata->name); | 1815 | pr_debug("%s: authenticated\n", sdata->name); |
1829 | out: | ||
1830 | ifmgd->auth_data->done = true; | 1816 | ifmgd->auth_data->done = true; |
1831 | ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC; | 1817 | ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC; |
1832 | run_again(ifmgd, ifmgd->auth_data->timeout); | 1818 | run_again(ifmgd, ifmgd->auth_data->timeout); |
@@ -1839,8 +1825,7 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, | |||
1839 | goto out_err; | 1825 | goto out_err; |
1840 | } | 1826 | } |
1841 | if (sta_info_move_state(sta, IEEE80211_STA_AUTH)) { | 1827 | if (sta_info_move_state(sta, IEEE80211_STA_AUTH)) { |
1842 | printk(KERN_DEBUG "%s: failed moving %pM to auth\n", | 1828 | pr_debug("%s: failed moving %pM to auth\n", sdata->name, bssid); |
1843 | sdata->name, bssid); | ||
1844 | goto out_err; | 1829 | goto out_err; |
1845 | } | 1830 | } |
1846 | mutex_unlock(&sdata->local->sta_mtx); | 1831 | mutex_unlock(&sdata->local->sta_mtx); |
@@ -1874,8 +1859,8 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, | |||
1874 | 1859 | ||
1875 | reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); | 1860 | reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); |
1876 | 1861 | ||
1877 | printk(KERN_DEBUG "%s: deauthenticated from %pM (Reason: %u)\n", | 1862 | pr_debug("%s: deauthenticated from %pM (Reason: %u)\n", |
1878 | sdata->name, bssid, reason_code); | 1863 | sdata->name, bssid, reason_code); |
1879 | 1864 | ||
1880 | ieee80211_set_disassoc(sdata, 0, 0, false, NULL); | 1865 | ieee80211_set_disassoc(sdata, 0, 0, false, NULL); |
1881 | 1866 | ||
@@ -1905,8 +1890,8 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1905 | 1890 | ||
1906 | reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); | 1891 | reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); |
1907 | 1892 | ||
1908 | printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n", | 1893 | pr_debug("%s: disassociated from %pM (Reason: %u)\n", |
1909 | sdata->name, mgmt->sa, reason_code); | 1894 | sdata->name, mgmt->sa, reason_code); |
1910 | 1895 | ||
1911 | ieee80211_set_disassoc(sdata, 0, 0, false, NULL); | 1896 | ieee80211_set_disassoc(sdata, 0, 0, false, NULL); |
1912 | 1897 | ||
@@ -1998,17 +1983,15 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, | |||
1998 | capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info); | 1983 | capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info); |
1999 | 1984 | ||
2000 | if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14))) | 1985 | if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14))) |
2001 | printk(KERN_DEBUG | 1986 | pr_debug("%s: invalid AID value 0x%x; bits 15:14 not set\n", |
2002 | "%s: invalid AID value 0x%x; bits 15:14 not set\n", | 1987 | sdata->name, aid); |
2003 | sdata->name, aid); | ||
2004 | aid &= ~(BIT(15) | BIT(14)); | 1988 | aid &= ~(BIT(15) | BIT(14)); |
2005 | 1989 | ||
2006 | ifmgd->broken_ap = false; | 1990 | ifmgd->broken_ap = false; |
2007 | 1991 | ||
2008 | if (aid == 0 || aid > IEEE80211_MAX_AID) { | 1992 | if (aid == 0 || aid > IEEE80211_MAX_AID) { |
2009 | printk(KERN_DEBUG | 1993 | pr_debug("%s: invalid AID value %d (out of range), turn off PS\n", |
2010 | "%s: invalid AID value %d (out of range), turn off PS\n", | 1994 | sdata->name, aid); |
2011 | sdata->name, aid); | ||
2012 | aid = 0; | 1995 | aid = 0; |
2013 | ifmgd->broken_ap = true; | 1996 | ifmgd->broken_ap = true; |
2014 | } | 1997 | } |
@@ -2017,8 +2000,8 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, | |||
2017 | ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); | 2000 | ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); |
2018 | 2001 | ||
2019 | if (!elems.supp_rates) { | 2002 | if (!elems.supp_rates) { |
2020 | printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n", | 2003 | pr_debug("%s: no SuppRates element in AssocResp\n", |
2021 | sdata->name); | 2004 | sdata->name); |
2022 | return false; | 2005 | return false; |
2023 | } | 2006 | } |
2024 | 2007 | ||
@@ -2058,9 +2041,8 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, | |||
2058 | if (!err && !(ifmgd->flags & IEEE80211_STA_CONTROL_PORT)) | 2041 | if (!err && !(ifmgd->flags & IEEE80211_STA_CONTROL_PORT)) |
2059 | err = sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED); | 2042 | err = sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED); |
2060 | if (err) { | 2043 | if (err) { |
2061 | printk(KERN_DEBUG | 2044 | pr_debug("%s: failed to move station %pM to desired state\n", |
2062 | "%s: failed to move station %pM to desired state\n", | 2045 | sdata->name, sta->sta.addr); |
2063 | sdata->name, sta->sta.addr); | ||
2064 | WARN_ON(__sta_info_destroy(sta)); | 2046 | WARN_ON(__sta_info_destroy(sta)); |
2065 | mutex_unlock(&sdata->local->sta_mtx); | 2047 | mutex_unlock(&sdata->local->sta_mtx); |
2066 | return false; | 2048 | return false; |
@@ -2143,10 +2125,9 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2143 | status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code); | 2125 | status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code); |
2144 | aid = le16_to_cpu(mgmt->u.assoc_resp.aid); | 2126 | aid = le16_to_cpu(mgmt->u.assoc_resp.aid); |
2145 | 2127 | ||
2146 | printk(KERN_DEBUG "%s: RX %sssocResp from %pM (capab=0x%x " | 2128 | pr_debug("%s: RX %sssocResp from %pM (capab=0x%x status=%d aid=%d)\n", |
2147 | "status=%d aid=%d)\n", | 2129 | sdata->name, reassoc ? "Rea" : "A", mgmt->sa, |
2148 | sdata->name, reassoc ? "Rea" : "A", mgmt->sa, | 2130 | capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14)))); |
2149 | capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14)))); | ||
2150 | 2131 | ||
2151 | pos = mgmt->u.assoc_resp.variable; | 2132 | pos = mgmt->u.assoc_resp.variable; |
2152 | ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); | 2133 | ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); |
@@ -2157,9 +2138,8 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2157 | u32 tu, ms; | 2138 | u32 tu, ms; |
2158 | tu = get_unaligned_le32(elems.timeout_int + 1); | 2139 | tu = get_unaligned_le32(elems.timeout_int + 1); |
2159 | ms = tu * 1024 / 1000; | 2140 | ms = tu * 1024 / 1000; |
2160 | printk(KERN_DEBUG "%s: %pM rejected association temporarily; " | 2141 | pr_debug("%s: %pM rejected association temporarily; comeback duration %u TU (%u ms)\n", |
2161 | "comeback duration %u TU (%u ms)\n", | 2142 | sdata->name, mgmt->sa, tu, ms); |
2162 | sdata->name, mgmt->sa, tu, ms); | ||
2163 | assoc_data->timeout = jiffies + msecs_to_jiffies(ms); | 2143 | assoc_data->timeout = jiffies + msecs_to_jiffies(ms); |
2164 | if (ms > IEEE80211_ASSOC_TIMEOUT) | 2144 | if (ms > IEEE80211_ASSOC_TIMEOUT) |
2165 | run_again(ifmgd, assoc_data->timeout); | 2145 | run_again(ifmgd, assoc_data->timeout); |
@@ -2169,11 +2149,11 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2169 | *bss = assoc_data->bss; | 2149 | *bss = assoc_data->bss; |
2170 | 2150 | ||
2171 | if (status_code != WLAN_STATUS_SUCCESS) { | 2151 | if (status_code != WLAN_STATUS_SUCCESS) { |
2172 | printk(KERN_DEBUG "%s: %pM denied association (code=%d)\n", | 2152 | pr_debug("%s: %pM denied association (code=%d)\n", |
2173 | sdata->name, mgmt->sa, status_code); | 2153 | sdata->name, mgmt->sa, status_code); |
2174 | ieee80211_destroy_assoc_data(sdata, false); | 2154 | ieee80211_destroy_assoc_data(sdata, false); |
2175 | } else { | 2155 | } else { |
2176 | printk(KERN_DEBUG "%s: associated\n", sdata->name); | 2156 | pr_debug("%s: associated\n", sdata->name); |
2177 | 2157 | ||
2178 | if (!ieee80211_assoc_success(sdata, *bss, mgmt, len)) { | 2158 | if (!ieee80211_assoc_success(sdata, *bss, mgmt, len)) { |
2179 | /* oops -- internal error -- send timeout for now */ | 2159 | /* oops -- internal error -- send timeout for now */ |
@@ -2281,7 +2261,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, | |||
2281 | if (ifmgd->auth_data && !ifmgd->auth_data->bss->proberesp_ies && | 2261 | if (ifmgd->auth_data && !ifmgd->auth_data->bss->proberesp_ies && |
2282 | ether_addr_equal(mgmt->bssid, ifmgd->auth_data->bss->bssid)) { | 2262 | ether_addr_equal(mgmt->bssid, ifmgd->auth_data->bss->bssid)) { |
2283 | /* got probe response, continue with auth */ | 2263 | /* got probe response, continue with auth */ |
2284 | printk(KERN_DEBUG "%s: direct probe responded\n", sdata->name); | 2264 | pr_debug("%s: direct probe responded\n", sdata->name); |
2285 | ifmgd->auth_data->tries = 0; | 2265 | ifmgd->auth_data->tries = 0; |
2286 | ifmgd->auth_data->timeout = jiffies; | 2266 | ifmgd->auth_data->timeout = jiffies; |
2287 | run_again(ifmgd, ifmgd->auth_data->timeout); | 2267 | run_again(ifmgd, ifmgd->auth_data->timeout); |
@@ -2645,8 +2625,8 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) | |||
2645 | auth_data->tries++; | 2625 | auth_data->tries++; |
2646 | 2626 | ||
2647 | if (auth_data->tries > IEEE80211_AUTH_MAX_TRIES) { | 2627 | if (auth_data->tries > IEEE80211_AUTH_MAX_TRIES) { |
2648 | printk(KERN_DEBUG "%s: authentication with %pM timed out\n", | 2628 | pr_debug("%s: authentication with %pM timed out\n", |
2649 | sdata->name, auth_data->bss->bssid); | 2629 | sdata->name, auth_data->bss->bssid); |
2650 | 2630 | ||
2651 | /* | 2631 | /* |
2652 | * Most likely AP is not in the range so remove the | 2632 | * Most likely AP is not in the range so remove the |
@@ -2658,9 +2638,9 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) | |||
2658 | } | 2638 | } |
2659 | 2639 | ||
2660 | if (auth_data->bss->proberesp_ies) { | 2640 | if (auth_data->bss->proberesp_ies) { |
2661 | printk(KERN_DEBUG "%s: send auth to %pM (try %d/%d)\n", | 2641 | pr_debug("%s: send auth to %pM (try %d/%d)\n", |
2662 | sdata->name, auth_data->bss->bssid, auth_data->tries, | 2642 | sdata->name, auth_data->bss->bssid, auth_data->tries, |
2663 | IEEE80211_AUTH_MAX_TRIES); | 2643 | IEEE80211_AUTH_MAX_TRIES); |
2664 | 2644 | ||
2665 | auth_data->expected_transaction = 2; | 2645 | auth_data->expected_transaction = 2; |
2666 | ieee80211_send_auth(sdata, 1, auth_data->algorithm, | 2646 | ieee80211_send_auth(sdata, 1, auth_data->algorithm, |
@@ -2670,9 +2650,9 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) | |||
2670 | } else { | 2650 | } else { |
2671 | const u8 *ssidie; | 2651 | const u8 *ssidie; |
2672 | 2652 | ||
2673 | printk(KERN_DEBUG "%s: direct probe to %pM (try %d/%i)\n", | 2653 | pr_debug("%s: direct probe to %pM (try %d/%i)\n", |
2674 | sdata->name, auth_data->bss->bssid, auth_data->tries, | 2654 | sdata->name, auth_data->bss->bssid, auth_data->tries, |
2675 | IEEE80211_AUTH_MAX_TRIES); | 2655 | IEEE80211_AUTH_MAX_TRIES); |
2676 | 2656 | ||
2677 | ssidie = ieee80211_bss_get_ie(auth_data->bss, WLAN_EID_SSID); | 2657 | ssidie = ieee80211_bss_get_ie(auth_data->bss, WLAN_EID_SSID); |
2678 | if (!ssidie) | 2658 | if (!ssidie) |
@@ -2700,8 +2680,8 @@ static int ieee80211_do_assoc(struct ieee80211_sub_if_data *sdata) | |||
2700 | 2680 | ||
2701 | assoc_data->tries++; | 2681 | assoc_data->tries++; |
2702 | if (assoc_data->tries > IEEE80211_ASSOC_MAX_TRIES) { | 2682 | if (assoc_data->tries > IEEE80211_ASSOC_MAX_TRIES) { |
2703 | printk(KERN_DEBUG "%s: association with %pM timed out\n", | 2683 | pr_debug("%s: association with %pM timed out\n", |
2704 | sdata->name, assoc_data->bss->bssid); | 2684 | sdata->name, assoc_data->bss->bssid); |
2705 | 2685 | ||
2706 | /* | 2686 | /* |
2707 | * Most likely AP is not in the range so remove the | 2687 | * Most likely AP is not in the range so remove the |
@@ -2712,9 +2692,9 @@ static int ieee80211_do_assoc(struct ieee80211_sub_if_data *sdata) | |||
2712 | return -ETIMEDOUT; | 2692 | return -ETIMEDOUT; |
2713 | } | 2693 | } |
2714 | 2694 | ||
2715 | printk(KERN_DEBUG "%s: associate with %pM (try %d/%d)\n", | 2695 | pr_debug("%s: associate with %pM (try %d/%d)\n", |
2716 | sdata->name, assoc_data->bss->bssid, assoc_data->tries, | 2696 | sdata->name, assoc_data->bss->bssid, assoc_data->tries, |
2717 | IEEE80211_ASSOC_MAX_TRIES); | 2697 | IEEE80211_ASSOC_MAX_TRIES); |
2718 | ieee80211_send_assoc(sdata); | 2698 | ieee80211_send_assoc(sdata); |
2719 | 2699 | ||
2720 | assoc_data->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT; | 2700 | assoc_data->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT; |
@@ -3085,13 +3065,10 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, | |||
3085 | * since we look at probe response/beacon data here | 3065 | * since we look at probe response/beacon data here |
3086 | * it should be OK. | 3066 | * it should be OK. |
3087 | */ | 3067 | */ |
3088 | printk(KERN_DEBUG | 3068 | pr_debug("%s: Wrong control channel: center-freq: %d ht-cfreq: %d ht->primary_chan: %d band: %d - Disabling HT\n", |
3089 | "%s: Wrong control channel: center-freq: %d" | 3069 | sdata->name, cbss->channel->center_freq, |
3090 | " ht-cfreq: %d ht->primary_chan: %d" | 3070 | ht_cfreq, ht_oper->primary_chan, |
3091 | " band: %d. Disabling HT.\n", | 3071 | cbss->channel->band); |
3092 | sdata->name, cbss->channel->center_freq, | ||
3093 | ht_cfreq, ht_oper->primary_chan, | ||
3094 | cbss->channel->band); | ||
3095 | ht_oper = NULL; | 3072 | ht_oper = NULL; |
3096 | } | 3073 | } |
3097 | } | 3074 | } |
@@ -3115,9 +3092,8 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, | |||
3115 | if (!ieee80211_set_channel_type(local, sdata, channel_type)) { | 3092 | if (!ieee80211_set_channel_type(local, sdata, channel_type)) { |
3116 | /* can only fail due to HT40+/- mismatch */ | 3093 | /* can only fail due to HT40+/- mismatch */ |
3117 | channel_type = NL80211_CHAN_HT20; | 3094 | channel_type = NL80211_CHAN_HT20; |
3118 | printk(KERN_DEBUG | 3095 | pr_debug("%s: disabling 40 MHz due to multi-vif mismatch\n", |
3119 | "%s: disabling 40 MHz due to multi-vif mismatch\n", | 3096 | sdata->name); |
3120 | sdata->name); | ||
3121 | ifmgd->flags |= IEEE80211_STA_DISABLE_40MHZ; | 3097 | ifmgd->flags |= IEEE80211_STA_DISABLE_40MHZ; |
3122 | WARN_ON(!ieee80211_set_channel_type(local, sdata, | 3098 | WARN_ON(!ieee80211_set_channel_type(local, sdata, |
3123 | channel_type)); | 3099 | channel_type)); |
@@ -3146,9 +3122,8 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, | |||
3146 | * we can connect -- with a warning. | 3122 | * we can connect -- with a warning. |
3147 | */ | 3123 | */ |
3148 | if (!basic_rates && min_rate_index >= 0) { | 3124 | if (!basic_rates && min_rate_index >= 0) { |
3149 | printk(KERN_DEBUG | 3125 | pr_debug("%s: No basic rates, using min rate instead\n", |
3150 | "%s: No basic rates, using min rate instead.\n", | 3126 | sdata->name); |
3151 | sdata->name); | ||
3152 | basic_rates = BIT(min_rate_index); | 3127 | basic_rates = BIT(min_rate_index); |
3153 | } | 3128 | } |
3154 | 3129 | ||
@@ -3174,9 +3149,8 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, | |||
3174 | err = sta_info_insert(sta); | 3149 | err = sta_info_insert(sta); |
3175 | sta = NULL; | 3150 | sta = NULL; |
3176 | if (err) { | 3151 | if (err) { |
3177 | printk(KERN_DEBUG | 3152 | pr_debug("%s: failed to insert STA entry for the AP (error %d)\n", |
3178 | "%s: failed to insert STA entry for the AP (error %d)\n", | 3153 | sdata->name, err); |
3179 | sdata->name, err); | ||
3180 | return err; | 3154 | return err; |
3181 | } | 3155 | } |
3182 | } else | 3156 | } else |
@@ -3254,8 +3228,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | |||
3254 | if (ifmgd->associated) | 3228 | if (ifmgd->associated) |
3255 | ieee80211_set_disassoc(sdata, 0, 0, false, NULL); | 3229 | ieee80211_set_disassoc(sdata, 0, 0, false, NULL); |
3256 | 3230 | ||
3257 | printk(KERN_DEBUG "%s: authenticate with %pM\n", | 3231 | pr_debug("%s: authenticate with %pM\n", sdata->name, req->bss->bssid); |
3258 | sdata->name, req->bss->bssid); | ||
3259 | 3232 | ||
3260 | err = ieee80211_prep_connection(sdata, req->bss, false); | 3233 | err = ieee80211_prep_connection(sdata, req->bss, false); |
3261 | if (err) | 3234 | if (err) |
@@ -3290,7 +3263,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
3290 | struct ieee80211_bss *bss = (void *)req->bss->priv; | 3263 | struct ieee80211_bss *bss = (void *)req->bss->priv; |
3291 | struct ieee80211_mgd_assoc_data *assoc_data; | 3264 | struct ieee80211_mgd_assoc_data *assoc_data; |
3292 | struct ieee80211_supported_band *sband; | 3265 | struct ieee80211_supported_band *sband; |
3293 | const u8 *ssidie; | 3266 | const u8 *ssidie, *ht_ie; |
3294 | int i, err; | 3267 | int i, err; |
3295 | 3268 | ||
3296 | ssidie = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID); | 3269 | ssidie = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID); |
@@ -3338,11 +3311,15 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
3338 | * We can set this to true for non-11n hardware, that'll be checked | 3311 | * We can set this to true for non-11n hardware, that'll be checked |
3339 | * separately along with the peer capabilities. | 3312 | * separately along with the peer capabilities. |
3340 | */ | 3313 | */ |
3341 | for (i = 0; i < req->crypto.n_ciphers_pairwise; i++) | 3314 | for (i = 0; i < req->crypto.n_ciphers_pairwise; i++) { |
3342 | if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 || | 3315 | if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 || |
3343 | req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP || | 3316 | req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP || |
3344 | req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104) | 3317 | req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104) { |
3345 | ifmgd->flags |= IEEE80211_STA_DISABLE_11N; | 3318 | ifmgd->flags |= IEEE80211_STA_DISABLE_11N; |
3319 | netdev_info(sdata->dev, | ||
3320 | "disabling HT due to WEP/TKIP use\n"); | ||
3321 | } | ||
3322 | } | ||
3346 | 3323 | ||
3347 | if (req->flags & ASSOC_REQ_DISABLE_HT) | 3324 | if (req->flags & ASSOC_REQ_DISABLE_HT) |
3348 | ifmgd->flags |= IEEE80211_STA_DISABLE_11N; | 3325 | ifmgd->flags |= IEEE80211_STA_DISABLE_11N; |
@@ -3350,8 +3327,11 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
3350 | /* Also disable HT if we don't support it or the AP doesn't use WMM */ | 3327 | /* Also disable HT if we don't support it or the AP doesn't use WMM */ |
3351 | sband = local->hw.wiphy->bands[req->bss->channel->band]; | 3328 | sband = local->hw.wiphy->bands[req->bss->channel->band]; |
3352 | if (!sband->ht_cap.ht_supported || | 3329 | if (!sband->ht_cap.ht_supported || |
3353 | local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used) | 3330 | local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used) { |
3354 | ifmgd->flags |= IEEE80211_STA_DISABLE_11N; | 3331 | ifmgd->flags |= IEEE80211_STA_DISABLE_11N; |
3332 | netdev_info(sdata->dev, | ||
3333 | "disabling HT as WMM/QoS is not supported\n"); | ||
3334 | } | ||
3355 | 3335 | ||
3356 | memcpy(&ifmgd->ht_capa, &req->ht_capa, sizeof(ifmgd->ht_capa)); | 3336 | memcpy(&ifmgd->ht_capa, &req->ht_capa, sizeof(ifmgd->ht_capa)); |
3357 | memcpy(&ifmgd->ht_capa_mask, &req->ht_capa_mask, | 3337 | memcpy(&ifmgd->ht_capa_mask, &req->ht_capa_mask, |
@@ -3377,8 +3357,13 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
3377 | (local->hw.queues >= IEEE80211_NUM_ACS); | 3357 | (local->hw.queues >= IEEE80211_NUM_ACS); |
3378 | assoc_data->supp_rates = bss->supp_rates; | 3358 | assoc_data->supp_rates = bss->supp_rates; |
3379 | assoc_data->supp_rates_len = bss->supp_rates_len; | 3359 | assoc_data->supp_rates_len = bss->supp_rates_len; |
3380 | assoc_data->ht_operation_ie = | 3360 | |
3381 | ieee80211_bss_get_ie(req->bss, WLAN_EID_HT_OPERATION); | 3361 | ht_ie = ieee80211_bss_get_ie(req->bss, WLAN_EID_HT_OPERATION); |
3362 | if (ht_ie && ht_ie[1] >= sizeof(struct ieee80211_ht_operation)) | ||
3363 | assoc_data->ap_ht_param = | ||
3364 | ((struct ieee80211_ht_operation *)(ht_ie + 2))->ht_param; | ||
3365 | else | ||
3366 | ifmgd->flags |= IEEE80211_STA_DISABLE_11N; | ||
3382 | 3367 | ||
3383 | if (bss->wmm_used && bss->uapsd_supported && | 3368 | if (bss->wmm_used && bss->uapsd_supported && |
3384 | (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) { | 3369 | (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) { |
@@ -3425,8 +3410,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
3425 | * Wait up to one beacon interval ... | 3410 | * Wait up to one beacon interval ... |
3426 | * should this be more if we miss one? | 3411 | * should this be more if we miss one? |
3427 | */ | 3412 | */ |
3428 | printk(KERN_DEBUG "%s: waiting for beacon from %pM\n", | 3413 | pr_debug("%s: waiting for beacon from %pM\n", |
3429 | sdata->name, ifmgd->bssid); | 3414 | sdata->name, ifmgd->bssid); |
3430 | assoc_data->timeout = TU_TO_EXP_TIME(req->bss->beacon_interval); | 3415 | assoc_data->timeout = TU_TO_EXP_TIME(req->bss->beacon_interval); |
3431 | } else { | 3416 | } else { |
3432 | assoc_data->have_beacon = true; | 3417 | assoc_data->have_beacon = true; |
@@ -3445,8 +3430,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
3445 | corrupt_type = "beacon"; | 3430 | corrupt_type = "beacon"; |
3446 | } else if (bss->corrupt_data & IEEE80211_BSS_CORRUPT_PROBE_RESP) | 3431 | } else if (bss->corrupt_data & IEEE80211_BSS_CORRUPT_PROBE_RESP) |
3447 | corrupt_type = "probe response"; | 3432 | corrupt_type = "probe response"; |
3448 | printk(KERN_DEBUG "%s: associating with AP with corrupt %s\n", | 3433 | pr_debug("%s: associating with AP with corrupt %s\n", |
3449 | sdata->name, corrupt_type); | 3434 | sdata->name, corrupt_type); |
3450 | } | 3435 | } |
3451 | 3436 | ||
3452 | err = 0; | 3437 | err = 0; |
@@ -3475,9 +3460,8 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
3475 | return 0; | 3460 | return 0; |
3476 | } | 3461 | } |
3477 | 3462 | ||
3478 | printk(KERN_DEBUG | 3463 | pr_debug("%s: deauthenticating from %pM by local choice (reason=%d)\n", |
3479 | "%s: deauthenticating from %pM by local choice (reason=%d)\n", | 3464 | sdata->name, req->bssid, req->reason_code); |
3480 | sdata->name, req->bssid, req->reason_code); | ||
3481 | 3465 | ||
3482 | if (ifmgd->associated && | 3466 | if (ifmgd->associated && |
3483 | ether_addr_equal(ifmgd->associated->bssid, req->bssid)) | 3467 | ether_addr_equal(ifmgd->associated->bssid, req->bssid)) |
@@ -3519,8 +3503,8 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, | |||
3519 | return -ENOLINK; | 3503 | return -ENOLINK; |
3520 | } | 3504 | } |
3521 | 3505 | ||
3522 | printk(KERN_DEBUG "%s: disassociating from %pM by local choice (reason=%d)\n", | 3506 | pr_debug("%s: disassociating from %pM by local choice (reason=%d)\n", |
3523 | sdata->name, req->bss->bssid, req->reason_code); | 3507 | sdata->name, req->bss->bssid, req->reason_code); |
3524 | 3508 | ||
3525 | memcpy(bssid, req->bss->bssid, ETH_ALEN); | 3509 | memcpy(bssid, req->bss->bssid, ETH_ALEN); |
3526 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DISASSOC, | 3510 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DISASSOC, |
@@ -3561,10 +3545,3 @@ void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif, | |||
3561 | cfg80211_cqm_rssi_notify(sdata->dev, rssi_event, gfp); | 3545 | cfg80211_cqm_rssi_notify(sdata->dev, rssi_event, gfp); |
3562 | } | 3546 | } |
3563 | EXPORT_SYMBOL(ieee80211_cqm_rssi_notify); | 3547 | EXPORT_SYMBOL(ieee80211_cqm_rssi_notify); |
3564 | |||
3565 | unsigned char ieee80211_get_operstate(struct ieee80211_vif *vif) | ||
3566 | { | ||
3567 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | ||
3568 | return sdata->dev->operstate; | ||
3569 | } | ||
3570 | EXPORT_SYMBOL(ieee80211_get_operstate); | ||
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index 935aa4b6deee..abb226dc4753 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <net/mac80211.h> | 16 | #include <net/mac80211.h> |
17 | #include "ieee80211_i.h" | 17 | #include "ieee80211_i.h" |
18 | #include "driver-trace.h" | 18 | #include "driver-trace.h" |
19 | #include "driver-ops.h" | ||
19 | 20 | ||
20 | /* | 21 | /* |
21 | * Tell our hardware to disable PS. | 22 | * Tell our hardware to disable PS. |
@@ -181,34 +182,58 @@ void ieee80211_offchannel_return(struct ieee80211_local *local, | |||
181 | mutex_unlock(&local->iflist_mtx); | 182 | mutex_unlock(&local->iflist_mtx); |
182 | } | 183 | } |
183 | 184 | ||
185 | void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc) | ||
186 | { | ||
187 | if (roc->notified) | ||
188 | return; | ||
189 | |||
190 | if (roc->mgmt_tx_cookie) { | ||
191 | if (!WARN_ON(!roc->frame)) { | ||
192 | ieee80211_tx_skb(roc->sdata, roc->frame); | ||
193 | roc->frame = NULL; | ||
194 | } | ||
195 | } else { | ||
196 | cfg80211_ready_on_channel(roc->sdata->dev, (unsigned long)roc, | ||
197 | roc->chan, roc->chan_type, | ||
198 | roc->req_duration, GFP_KERNEL); | ||
199 | } | ||
200 | |||
201 | roc->notified = true; | ||
202 | } | ||
203 | |||
184 | static void ieee80211_hw_roc_start(struct work_struct *work) | 204 | static void ieee80211_hw_roc_start(struct work_struct *work) |
185 | { | 205 | { |
186 | struct ieee80211_local *local = | 206 | struct ieee80211_local *local = |
187 | container_of(work, struct ieee80211_local, hw_roc_start); | 207 | container_of(work, struct ieee80211_local, hw_roc_start); |
188 | struct ieee80211_sub_if_data *sdata; | 208 | struct ieee80211_roc_work *roc, *dep, *tmp; |
189 | 209 | ||
190 | mutex_lock(&local->mtx); | 210 | mutex_lock(&local->mtx); |
191 | 211 | ||
192 | if (!local->hw_roc_channel) { | 212 | if (list_empty(&local->roc_list)) |
193 | mutex_unlock(&local->mtx); | 213 | goto out_unlock; |
194 | return; | ||
195 | } | ||
196 | 214 | ||
197 | if (local->hw_roc_skb) { | 215 | roc = list_first_entry(&local->roc_list, struct ieee80211_roc_work, |
198 | sdata = IEEE80211_DEV_TO_SUB_IF(local->hw_roc_dev); | 216 | list); |
199 | ieee80211_tx_skb(sdata, local->hw_roc_skb); | 217 | |
200 | local->hw_roc_skb = NULL; | 218 | if (!roc->started) |
201 | } else { | 219 | goto out_unlock; |
202 | cfg80211_ready_on_channel(local->hw_roc_dev, | ||
203 | local->hw_roc_cookie, | ||
204 | local->hw_roc_channel, | ||
205 | local->hw_roc_channel_type, | ||
206 | local->hw_roc_duration, | ||
207 | GFP_KERNEL); | ||
208 | } | ||
209 | 220 | ||
210 | ieee80211_recalc_idle(local); | 221 | roc->hw_begun = true; |
222 | roc->hw_start_time = local->hw_roc_start_time; | ||
211 | 223 | ||
224 | ieee80211_handle_roc_started(roc); | ||
225 | list_for_each_entry_safe(dep, tmp, &roc->dependents, list) { | ||
226 | ieee80211_handle_roc_started(dep); | ||
227 | |||
228 | if (dep->duration > roc->duration) { | ||
229 | u32 dur = dep->duration; | ||
230 | dep->duration = dur - roc->duration; | ||
231 | roc->duration = dur; | ||
232 | list_del(&dep->list); | ||
233 | list_add(&dep->list, &roc->list); | ||
234 | } | ||
235 | } | ||
236 | out_unlock: | ||
212 | mutex_unlock(&local->mtx); | 237 | mutex_unlock(&local->mtx); |
213 | } | 238 | } |
214 | 239 | ||
@@ -216,52 +241,179 @@ void ieee80211_ready_on_channel(struct ieee80211_hw *hw) | |||
216 | { | 241 | { |
217 | struct ieee80211_local *local = hw_to_local(hw); | 242 | struct ieee80211_local *local = hw_to_local(hw); |
218 | 243 | ||
244 | local->hw_roc_start_time = jiffies; | ||
245 | |||
219 | trace_api_ready_on_channel(local); | 246 | trace_api_ready_on_channel(local); |
220 | 247 | ||
221 | ieee80211_queue_work(hw, &local->hw_roc_start); | 248 | ieee80211_queue_work(hw, &local->hw_roc_start); |
222 | } | 249 | } |
223 | EXPORT_SYMBOL_GPL(ieee80211_ready_on_channel); | 250 | EXPORT_SYMBOL_GPL(ieee80211_ready_on_channel); |
224 | 251 | ||
225 | static void ieee80211_hw_roc_done(struct work_struct *work) | 252 | void ieee80211_start_next_roc(struct ieee80211_local *local) |
226 | { | 253 | { |
227 | struct ieee80211_local *local = | 254 | struct ieee80211_roc_work *roc; |
228 | container_of(work, struct ieee80211_local, hw_roc_done); | ||
229 | 255 | ||
230 | mutex_lock(&local->mtx); | 256 | lockdep_assert_held(&local->mtx); |
231 | 257 | ||
232 | if (!local->hw_roc_channel) { | 258 | if (list_empty(&local->roc_list)) { |
233 | mutex_unlock(&local->mtx); | 259 | ieee80211_run_deferred_scan(local); |
234 | return; | 260 | return; |
235 | } | 261 | } |
236 | 262 | ||
237 | /* was never transmitted */ | 263 | roc = list_first_entry(&local->roc_list, struct ieee80211_roc_work, |
238 | if (local->hw_roc_skb) { | 264 | list); |
239 | u64 cookie; | ||
240 | 265 | ||
241 | cookie = local->hw_roc_cookie ^ 2; | 266 | if (local->ops->remain_on_channel) { |
267 | int ret, duration = roc->duration; | ||
242 | 268 | ||
243 | cfg80211_mgmt_tx_status(local->hw_roc_dev, cookie, | 269 | /* XXX: duplicated, see ieee80211_start_roc_work() */ |
244 | local->hw_roc_skb->data, | 270 | if (!duration) |
245 | local->hw_roc_skb->len, false, | 271 | duration = 10; |
246 | GFP_KERNEL); | ||
247 | 272 | ||
248 | kfree_skb(local->hw_roc_skb); | 273 | ret = drv_remain_on_channel(local, roc->chan, |
249 | local->hw_roc_skb = NULL; | 274 | roc->chan_type, |
250 | local->hw_roc_skb_for_status = NULL; | 275 | duration); |
276 | |||
277 | roc->started = true; | ||
278 | |||
279 | if (ret) { | ||
280 | wiphy_warn(local->hw.wiphy, | ||
281 | "failed to start next HW ROC (%d)\n", ret); | ||
282 | /* | ||
283 | * queue the work struct again to avoid recursion | ||
284 | * when multiple failures occur | ||
285 | */ | ||
286 | ieee80211_remain_on_channel_expired(&local->hw); | ||
287 | } | ||
288 | } else { | ||
289 | /* delay it a bit */ | ||
290 | ieee80211_queue_delayed_work(&local->hw, &roc->work, | ||
291 | round_jiffies_relative(HZ/2)); | ||
292 | } | ||
293 | } | ||
294 | |||
295 | void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc) | ||
296 | { | ||
297 | struct ieee80211_roc_work *dep, *tmp; | ||
298 | |||
299 | /* was never transmitted */ | ||
300 | if (roc->frame) { | ||
301 | cfg80211_mgmt_tx_status(roc->sdata->dev, | ||
302 | (unsigned long)roc->frame, | ||
303 | roc->frame->data, roc->frame->len, | ||
304 | false, GFP_KERNEL); | ||
305 | kfree_skb(roc->frame); | ||
251 | } | 306 | } |
252 | 307 | ||
253 | if (!local->hw_roc_for_tx) | 308 | if (!roc->mgmt_tx_cookie) |
254 | cfg80211_remain_on_channel_expired(local->hw_roc_dev, | 309 | cfg80211_remain_on_channel_expired(roc->sdata->dev, |
255 | local->hw_roc_cookie, | 310 | (unsigned long)roc, |
256 | local->hw_roc_channel, | 311 | roc->chan, roc->chan_type, |
257 | local->hw_roc_channel_type, | ||
258 | GFP_KERNEL); | 312 | GFP_KERNEL); |
259 | 313 | ||
260 | local->hw_roc_channel = NULL; | 314 | list_for_each_entry_safe(dep, tmp, &roc->dependents, list) |
261 | local->hw_roc_cookie = 0; | 315 | ieee80211_roc_notify_destroy(dep); |
316 | |||
317 | kfree(roc); | ||
318 | } | ||
319 | |||
320 | void ieee80211_sw_roc_work(struct work_struct *work) | ||
321 | { | ||
322 | struct ieee80211_roc_work *roc = | ||
323 | container_of(work, struct ieee80211_roc_work, work.work); | ||
324 | struct ieee80211_sub_if_data *sdata = roc->sdata; | ||
325 | struct ieee80211_local *local = sdata->local; | ||
326 | |||
327 | mutex_lock(&local->mtx); | ||
328 | |||
329 | if (roc->abort) | ||
330 | goto finish; | ||
331 | |||
332 | if (WARN_ON(list_empty(&local->roc_list))) | ||
333 | goto out_unlock; | ||
334 | |||
335 | if (WARN_ON(roc != list_first_entry(&local->roc_list, | ||
336 | struct ieee80211_roc_work, | ||
337 | list))) | ||
338 | goto out_unlock; | ||
339 | |||
340 | if (!roc->started) { | ||
341 | struct ieee80211_roc_work *dep; | ||
342 | |||
343 | /* start this ROC */ | ||
262 | 344 | ||
263 | ieee80211_recalc_idle(local); | 345 | /* switch channel etc */ |
346 | ieee80211_recalc_idle(local); | ||
264 | 347 | ||
348 | local->tmp_channel = roc->chan; | ||
349 | local->tmp_channel_type = roc->chan_type; | ||
350 | ieee80211_hw_config(local, 0); | ||
351 | |||
352 | /* tell userspace or send frame */ | ||
353 | ieee80211_handle_roc_started(roc); | ||
354 | list_for_each_entry(dep, &roc->dependents, list) | ||
355 | ieee80211_handle_roc_started(dep); | ||
356 | |||
357 | /* if it was pure TX, just finish right away */ | ||
358 | if (!roc->duration) | ||
359 | goto finish; | ||
360 | |||
361 | roc->started = true; | ||
362 | ieee80211_queue_delayed_work(&local->hw, &roc->work, | ||
363 | msecs_to_jiffies(roc->duration)); | ||
364 | } else { | ||
365 | /* finish this ROC */ | ||
366 | finish: | ||
367 | list_del(&roc->list); | ||
368 | ieee80211_roc_notify_destroy(roc); | ||
369 | |||
370 | if (roc->started) { | ||
371 | drv_flush(local, false); | ||
372 | |||
373 | local->tmp_channel = NULL; | ||
374 | ieee80211_hw_config(local, 0); | ||
375 | |||
376 | ieee80211_offchannel_return(local, true); | ||
377 | } | ||
378 | |||
379 | ieee80211_recalc_idle(local); | ||
380 | |||
381 | ieee80211_start_next_roc(local); | ||
382 | ieee80211_run_deferred_scan(local); | ||
383 | } | ||
384 | |||
385 | out_unlock: | ||
386 | mutex_unlock(&local->mtx); | ||
387 | } | ||
388 | |||
389 | static void ieee80211_hw_roc_done(struct work_struct *work) | ||
390 | { | ||
391 | struct ieee80211_local *local = | ||
392 | container_of(work, struct ieee80211_local, hw_roc_done); | ||
393 | struct ieee80211_roc_work *roc; | ||
394 | |||
395 | mutex_lock(&local->mtx); | ||
396 | |||
397 | if (list_empty(&local->roc_list)) | ||
398 | goto out_unlock; | ||
399 | |||
400 | roc = list_first_entry(&local->roc_list, struct ieee80211_roc_work, | ||
401 | list); | ||
402 | |||
403 | if (!roc->started) | ||
404 | goto out_unlock; | ||
405 | |||
406 | list_del(&roc->list); | ||
407 | |||
408 | ieee80211_roc_notify_destroy(roc); | ||
409 | |||
410 | /* if there's another roc, start it now */ | ||
411 | ieee80211_start_next_roc(local); | ||
412 | |||
413 | /* or scan maybe */ | ||
414 | ieee80211_run_deferred_scan(local); | ||
415 | |||
416 | out_unlock: | ||
265 | mutex_unlock(&local->mtx); | 417 | mutex_unlock(&local->mtx); |
266 | } | 418 | } |
267 | 419 | ||
@@ -275,8 +427,48 @@ void ieee80211_remain_on_channel_expired(struct ieee80211_hw *hw) | |||
275 | } | 427 | } |
276 | EXPORT_SYMBOL_GPL(ieee80211_remain_on_channel_expired); | 428 | EXPORT_SYMBOL_GPL(ieee80211_remain_on_channel_expired); |
277 | 429 | ||
278 | void ieee80211_hw_roc_setup(struct ieee80211_local *local) | 430 | void ieee80211_roc_setup(struct ieee80211_local *local) |
279 | { | 431 | { |
280 | INIT_WORK(&local->hw_roc_start, ieee80211_hw_roc_start); | 432 | INIT_WORK(&local->hw_roc_start, ieee80211_hw_roc_start); |
281 | INIT_WORK(&local->hw_roc_done, ieee80211_hw_roc_done); | 433 | INIT_WORK(&local->hw_roc_done, ieee80211_hw_roc_done); |
434 | INIT_LIST_HEAD(&local->roc_list); | ||
435 | } | ||
436 | |||
437 | void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata) | ||
438 | { | ||
439 | struct ieee80211_local *local = sdata->local; | ||
440 | struct ieee80211_roc_work *roc, *tmp; | ||
441 | LIST_HEAD(tmp_list); | ||
442 | |||
443 | mutex_lock(&local->mtx); | ||
444 | list_for_each_entry_safe(roc, tmp, &local->roc_list, list) { | ||
445 | if (roc->sdata != sdata) | ||
446 | continue; | ||
447 | |||
448 | if (roc->started && local->ops->remain_on_channel) { | ||
449 | /* can race, so ignore return value */ | ||
450 | drv_cancel_remain_on_channel(local); | ||
451 | } | ||
452 | |||
453 | list_move_tail(&roc->list, &tmp_list); | ||
454 | roc->abort = true; | ||
455 | } | ||
456 | |||
457 | ieee80211_start_next_roc(local); | ||
458 | ieee80211_run_deferred_scan(local); | ||
459 | mutex_unlock(&local->mtx); | ||
460 | |||
461 | list_for_each_entry_safe(roc, tmp, &tmp_list, list) { | ||
462 | if (local->ops->remain_on_channel) { | ||
463 | list_del(&roc->list); | ||
464 | ieee80211_roc_notify_destroy(roc); | ||
465 | } else { | ||
466 | ieee80211_queue_delayed_work(&local->hw, &roc->work, 0); | ||
467 | |||
468 | /* work will clean up etc */ | ||
469 | flush_delayed_work(&roc->work); | ||
470 | } | ||
471 | } | ||
472 | |||
473 | WARN_ON_ONCE(!list_empty(&tmp_list)); | ||
282 | } | 474 | } |
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index af1c4e26e965..98c128be3827 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c | |||
@@ -77,6 +77,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | |||
77 | int err = drv_suspend(local, wowlan); | 77 | int err = drv_suspend(local, wowlan); |
78 | if (err < 0) { | 78 | if (err < 0) { |
79 | local->quiescing = false; | 79 | local->quiescing = false; |
80 | local->wowlan = false; | ||
80 | return err; | 81 | return err; |
81 | } else if (err > 0) { | 82 | } else if (err > 0) { |
82 | WARN_ON(err != 1); | 83 | WARN_ON(err != 1); |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 7bcecf73aafb..6fd2cb0838c4 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -1137,22 +1137,22 @@ static void ap_sta_ps_start(struct sta_info *sta) | |||
1137 | if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS)) | 1137 | if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS)) |
1138 | drv_sta_notify(local, sdata, STA_NOTIFY_SLEEP, &sta->sta); | 1138 | drv_sta_notify(local, sdata, STA_NOTIFY_SLEEP, &sta->sta); |
1139 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 1139 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
1140 | printk(KERN_DEBUG "%s: STA %pM aid %d enters power save mode\n", | 1140 | pr_debug("%s: STA %pM aid %d enters power save mode\n", |
1141 | sdata->name, sta->sta.addr, sta->sta.aid); | 1141 | sdata->name, sta->sta.addr, sta->sta.aid); |
1142 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 1142 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
1143 | } | 1143 | } |
1144 | 1144 | ||
1145 | static void ap_sta_ps_end(struct sta_info *sta) | 1145 | static void ap_sta_ps_end(struct sta_info *sta) |
1146 | { | 1146 | { |
1147 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 1147 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
1148 | printk(KERN_DEBUG "%s: STA %pM aid %d exits power save mode\n", | 1148 | pr_debug("%s: STA %pM aid %d exits power save mode\n", |
1149 | sta->sdata->name, sta->sta.addr, sta->sta.aid); | 1149 | sta->sdata->name, sta->sta.addr, sta->sta.aid); |
1150 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 1150 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
1151 | 1151 | ||
1152 | if (test_sta_flag(sta, WLAN_STA_PS_DRIVER)) { | 1152 | if (test_sta_flag(sta, WLAN_STA_PS_DRIVER)) { |
1153 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 1153 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
1154 | printk(KERN_DEBUG "%s: STA %pM aid %d driver-ps-blocked\n", | 1154 | pr_debug("%s: STA %pM aid %d driver-ps-blocked\n", |
1155 | sta->sdata->name, sta->sta.addr, sta->sta.aid); | 1155 | sta->sdata->name, sta->sta.addr, sta->sta.aid); |
1156 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 1156 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
1157 | return; | 1157 | return; |
1158 | } | 1158 | } |
@@ -1387,12 +1387,10 @@ ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata, | |||
1387 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 1387 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
1388 | struct ieee80211_hdr *hdr = | 1388 | struct ieee80211_hdr *hdr = |
1389 | (struct ieee80211_hdr *) entry->skb_list.next->data; | 1389 | (struct ieee80211_hdr *) entry->skb_list.next->data; |
1390 | printk(KERN_DEBUG "%s: RX reassembly removed oldest " | 1390 | pr_debug("%s: RX reassembly removed oldest fragment entry (idx=%d age=%lu seq=%d last_frag=%d addr1=%pM addr2=%pM\n", |
1391 | "fragment entry (idx=%d age=%lu seq=%d last_frag=%d " | 1391 | sdata->name, idx, |
1392 | "addr1=%pM addr2=%pM\n", | 1392 | jiffies - entry->first_frag_time, entry->seq, |
1393 | sdata->name, idx, | 1393 | entry->last_frag, hdr->addr1, hdr->addr2); |
1394 | jiffies - entry->first_frag_time, entry->seq, | ||
1395 | entry->last_frag, hdr->addr1, hdr->addr2); | ||
1396 | #endif | 1394 | #endif |
1397 | __skb_queue_purge(&entry->skb_list); | 1395 | __skb_queue_purge(&entry->skb_list); |
1398 | } | 1396 | } |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 6d90a562669f..267b2940fadd 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -322,7 +322,7 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted, | |||
322 | ieee80211_mlme_notify_scan_completed(local); | 322 | ieee80211_mlme_notify_scan_completed(local); |
323 | ieee80211_ibss_notify_scan_completed(local); | 323 | ieee80211_ibss_notify_scan_completed(local); |
324 | ieee80211_mesh_notify_scan_completed(local); | 324 | ieee80211_mesh_notify_scan_completed(local); |
325 | ieee80211_queue_work(&local->hw, &local->work_work); | 325 | ieee80211_start_next_roc(local); |
326 | } | 326 | } |
327 | 327 | ||
328 | void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) | 328 | void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) |
@@ -375,7 +375,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local) | |||
375 | static bool ieee80211_can_scan(struct ieee80211_local *local, | 375 | static bool ieee80211_can_scan(struct ieee80211_local *local, |
376 | struct ieee80211_sub_if_data *sdata) | 376 | struct ieee80211_sub_if_data *sdata) |
377 | { | 377 | { |
378 | if (!list_empty(&local->work_list)) | 378 | if (!list_empty(&local->roc_list)) |
379 | return false; | 379 | return false; |
380 | 380 | ||
381 | if (sdata->vif.type == NL80211_IFTYPE_STATION && | 381 | if (sdata->vif.type == NL80211_IFTYPE_STATION && |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index de455f8bbb91..77dcf2f89d42 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -333,9 +333,8 @@ static int sta_info_insert_drv_state(struct ieee80211_local *local, | |||
333 | } | 333 | } |
334 | 334 | ||
335 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { | 335 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { |
336 | printk(KERN_DEBUG | 336 | pr_debug("%s: failed to move IBSS STA %pM to state %d (%d) - keeping it anyway\n", |
337 | "%s: failed to move IBSS STA %pM to state %d (%d) - keeping it anyway.\n", | 337 | sdata->name, sta->sta.addr, state + 1, err); |
338 | sdata->name, sta->sta.addr, state + 1, err); | ||
339 | err = 0; | 338 | err = 0; |
340 | } | 339 | } |
341 | 340 | ||
@@ -619,8 +618,7 @@ static bool sta_info_cleanup_expire_buffered_ac(struct ieee80211_local *local, | |||
619 | 618 | ||
620 | local->total_ps_buffered--; | 619 | local->total_ps_buffered--; |
621 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 620 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
622 | printk(KERN_DEBUG "Buffered frame expired (STA %pM)\n", | 621 | pr_debug("Buffered frame expired (STA %pM)\n", sta->sta.addr); |
623 | sta->sta.addr); | ||
624 | #endif | 622 | #endif |
625 | dev_kfree_skb(skb); | 623 | dev_kfree_skb(skb); |
626 | } | 624 | } |
@@ -889,10 +887,8 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, | |||
889 | continue; | 887 | continue; |
890 | 888 | ||
891 | if (time_after(jiffies, sta->last_rx + exp_time)) { | 889 | if (time_after(jiffies, sta->last_rx + exp_time)) { |
892 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 890 | ibss_vdbg("%s: expiring inactive STA %pM\n", |
893 | printk(KERN_DEBUG "%s: expiring inactive STA %pM\n", | 891 | sdata->name, sta->sta.addr); |
894 | sdata->name, sta->sta.addr); | ||
895 | #endif | ||
896 | WARN_ON(__sta_info_destroy(sta)); | 892 | WARN_ON(__sta_info_destroy(sta)); |
897 | } | 893 | } |
898 | } | 894 | } |
@@ -991,9 +987,8 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) | |||
991 | sta_info_recalc_tim(sta); | 987 | sta_info_recalc_tim(sta); |
992 | 988 | ||
993 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 989 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
994 | printk(KERN_DEBUG "%s: STA %pM aid %d sending %d filtered/%d PS frames " | 990 | pr_debug("%s: STA %pM aid %d sending %d filtered/%d PS frames since STA not sleeping anymore\n", |
995 | "since STA not sleeping anymore\n", sdata->name, | 991 | sdata->name, sta->sta.addr, sta->sta.aid, filtered, buffered); |
996 | sta->sta.addr, sta->sta.aid, filtered, buffered); | ||
997 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 992 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
998 | } | 993 | } |
999 | 994 | ||
@@ -1385,8 +1380,8 @@ int sta_info_move_state(struct sta_info *sta, | |||
1385 | } | 1380 | } |
1386 | 1381 | ||
1387 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 1382 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
1388 | printk(KERN_DEBUG "%s: moving STA %pM to state %d\n", | 1383 | pr_debug("%s: moving STA %pM to state %d\n", |
1389 | sta->sdata->name, sta->sta.addr, new_state); | 1384 | sta->sdata->name, sta->sta.addr, new_state); |
1390 | #endif | 1385 | #endif |
1391 | 1386 | ||
1392 | /* | 1387 | /* |
diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 28cfa981cfb1..6b4f42527887 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c | |||
@@ -520,36 +520,16 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
520 | 520 | ||
521 | if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX) { | 521 | if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX) { |
522 | u64 cookie = (unsigned long)skb; | 522 | u64 cookie = (unsigned long)skb; |
523 | acked = info->flags & IEEE80211_TX_STAT_ACK; | ||
523 | 524 | ||
524 | if (ieee80211_is_nullfunc(hdr->frame_control) || | 525 | if (ieee80211_is_nullfunc(hdr->frame_control) || |
525 | ieee80211_is_qos_nullfunc(hdr->frame_control)) { | 526 | ieee80211_is_qos_nullfunc(hdr->frame_control)) |
526 | acked = info->flags & IEEE80211_TX_STAT_ACK; | ||
527 | |||
528 | cfg80211_probe_status(skb->dev, hdr->addr1, | 527 | cfg80211_probe_status(skb->dev, hdr->addr1, |
529 | cookie, acked, GFP_ATOMIC); | 528 | cookie, acked, GFP_ATOMIC); |
530 | } else { | 529 | else |
531 | struct ieee80211_work *wk; | ||
532 | |||
533 | rcu_read_lock(); | ||
534 | list_for_each_entry_rcu(wk, &local->work_list, list) { | ||
535 | if (wk->type != IEEE80211_WORK_OFFCHANNEL_TX) | ||
536 | continue; | ||
537 | if (wk->offchan_tx.frame != skb) | ||
538 | continue; | ||
539 | wk->offchan_tx.status = true; | ||
540 | break; | ||
541 | } | ||
542 | rcu_read_unlock(); | ||
543 | if (local->hw_roc_skb_for_status == skb) { | ||
544 | cookie = local->hw_roc_cookie ^ 2; | ||
545 | local->hw_roc_skb_for_status = NULL; | ||
546 | } | ||
547 | |||
548 | cfg80211_mgmt_tx_status( | 530 | cfg80211_mgmt_tx_status( |
549 | skb->dev, cookie, skb->data, skb->len, | 531 | skb->dev, cookie, skb->data, skb->len, |
550 | !!(info->flags & IEEE80211_TX_STAT_ACK), | 532 | acked, GFP_ATOMIC); |
551 | GFP_ATOMIC); | ||
552 | } | ||
553 | } | 533 | } |
554 | 534 | ||
555 | if (unlikely(info->ack_frame_id)) { | 535 | if (unlikely(info->ack_frame_id)) { |
@@ -589,7 +569,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
589 | /* send frame to monitor interfaces now */ | 569 | /* send frame to monitor interfaces now */ |
590 | rtap_len = ieee80211_tx_radiotap_len(info); | 570 | rtap_len = ieee80211_tx_radiotap_len(info); |
591 | if (WARN_ON_ONCE(skb_headroom(skb) < rtap_len)) { | 571 | if (WARN_ON_ONCE(skb_headroom(skb) < rtap_len)) { |
592 | printk(KERN_ERR "ieee80211_tx_status: headroom too small\n"); | 572 | pr_err("ieee80211_tx_status: headroom too small\n"); |
593 | dev_kfree_skb(skb); | 573 | dev_kfree_skb(skb); |
594 | return; | 574 | return; |
595 | } | 575 | } |
diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c index 51077a956a83..68be47ca208f 100644 --- a/net/mac80211/tkip.c +++ b/net/mac80211/tkip.c | |||
@@ -263,12 +263,11 @@ int ieee80211_tkip_decrypt_data(struct crypto_cipher *tfm, | |||
263 | #ifdef CONFIG_MAC80211_TKIP_DEBUG | 263 | #ifdef CONFIG_MAC80211_TKIP_DEBUG |
264 | { | 264 | { |
265 | int i; | 265 | int i; |
266 | printk(KERN_DEBUG "TKIP decrypt: data(len=%zd)", payload_len); | 266 | pr_debug("TKIP decrypt: data(len=%zd)", payload_len); |
267 | for (i = 0; i < payload_len; i++) | 267 | for (i = 0; i < payload_len; i++) |
268 | printk(" %02x", payload[i]); | 268 | printk(" %02x", payload[i]); |
269 | printk("\n"); | 269 | printk("\n"); |
270 | printk(KERN_DEBUG "TKIP decrypt: iv16=%04x iv32=%08x\n", | 270 | pr_debug("TKIP decrypt: iv16=%04x iv32=%08x\n", iv16, iv32); |
271 | iv16, iv32); | ||
272 | } | 271 | } |
273 | #endif | 272 | #endif |
274 | 273 | ||
@@ -283,11 +282,10 @@ int ieee80211_tkip_decrypt_data(struct crypto_cipher *tfm, | |||
283 | (iv32 == key->u.tkip.rx[queue].iv32 && | 282 | (iv32 == key->u.tkip.rx[queue].iv32 && |
284 | iv16 <= key->u.tkip.rx[queue].iv16))) { | 283 | iv16 <= key->u.tkip.rx[queue].iv16))) { |
285 | #ifdef CONFIG_MAC80211_TKIP_DEBUG | 284 | #ifdef CONFIG_MAC80211_TKIP_DEBUG |
286 | printk(KERN_DEBUG "TKIP replay detected for RX frame from " | 285 | pr_debug("TKIP replay detected for RX frame from %pM (RX IV (%04x,%02x) <= prev. IV (%04x,%02x)\n", |
287 | "%pM (RX IV (%04x,%02x) <= prev. IV (%04x,%02x)\n", | 286 | ta, iv32, iv16, |
288 | ta, | 287 | key->u.tkip.rx[queue].iv32, |
289 | iv32, iv16, key->u.tkip.rx[queue].iv32, | 288 | key->u.tkip.rx[queue].iv16); |
290 | key->u.tkip.rx[queue].iv16); | ||
291 | #endif | 289 | #endif |
292 | return TKIP_DECRYPT_REPLAY; | 290 | return TKIP_DECRYPT_REPLAY; |
293 | } | 291 | } |
@@ -306,13 +304,12 @@ int ieee80211_tkip_decrypt_data(struct crypto_cipher *tfm, | |||
306 | { | 304 | { |
307 | int i; | 305 | int i; |
308 | u8 key_offset = NL80211_TKIP_DATA_OFFSET_ENCR_KEY; | 306 | u8 key_offset = NL80211_TKIP_DATA_OFFSET_ENCR_KEY; |
309 | printk(KERN_DEBUG "TKIP decrypt: Phase1 TA=%pM" | 307 | pr_debug("TKIP decrypt: Phase1 TA=%pM TK=", ta); |
310 | " TK=", ta); | ||
311 | for (i = 0; i < 16; i++) | 308 | for (i = 0; i < 16; i++) |
312 | printk("%02x ", | 309 | printk("%02x ", |
313 | key->conf.key[key_offset + i]); | 310 | key->conf.key[key_offset + i]); |
314 | printk("\n"); | 311 | printk("\n"); |
315 | printk(KERN_DEBUG "TKIP decrypt: P1K="); | 312 | pr_debug("TKIP decrypt: P1K="); |
316 | for (i = 0; i < 5; i++) | 313 | for (i = 0; i < 5; i++) |
317 | printk("%04x ", key->u.tkip.rx[queue].p1k[i]); | 314 | printk("%04x ", key->u.tkip.rx[queue].p1k[i]); |
318 | printk("\n"); | 315 | printk("\n"); |
@@ -336,7 +333,7 @@ int ieee80211_tkip_decrypt_data(struct crypto_cipher *tfm, | |||
336 | #ifdef CONFIG_MAC80211_TKIP_DEBUG | 333 | #ifdef CONFIG_MAC80211_TKIP_DEBUG |
337 | { | 334 | { |
338 | int i; | 335 | int i; |
339 | printk(KERN_DEBUG "TKIP decrypt: Phase2 rc4key="); | 336 | pr_debug("TKIP decrypt: Phase2 rc4key="); |
340 | for (i = 0; i < 16; i++) | 337 | for (i = 0; i < 16; i++) |
341 | printk("%02x ", rc4key[i]); | 338 | printk("%02x ", rc4key[i]); |
342 | printk("\n"); | 339 | printk("\n"); |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index e453212fa17f..af25c4e7ec5c 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -297,9 +297,8 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) | |||
297 | if (unlikely(!assoc && | 297 | if (unlikely(!assoc && |
298 | ieee80211_is_data(hdr->frame_control))) { | 298 | ieee80211_is_data(hdr->frame_control))) { |
299 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 299 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
300 | printk(KERN_DEBUG "%s: dropped data frame to not " | 300 | pr_debug("%s: dropped data frame to not associated station %pM\n", |
301 | "associated station %pM\n", | 301 | tx->sdata->name, hdr->addr1); |
302 | tx->sdata->name, hdr->addr1); | ||
303 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | 302 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ |
304 | I802_DEBUG_INC(tx->local->tx_handlers_drop_not_assoc); | 303 | I802_DEBUG_INC(tx->local->tx_handlers_drop_not_assoc); |
305 | return TX_DROP; | 304 | return TX_DROP; |
@@ -467,8 +466,8 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
467 | } | 466 | } |
468 | 467 | ||
469 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 468 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
470 | printk(KERN_DEBUG "STA %pM aid %d: PS buffer for AC %d\n", | 469 | pr_debug("STA %pM aid %d: PS buffer for AC %d\n", |
471 | sta->sta.addr, sta->sta.aid, ac); | 470 | sta->sta.addr, sta->sta.aid, ac); |
472 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 471 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
473 | if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER) | 472 | if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER) |
474 | purge_old_ps_buffers(tx->local); | 473 | purge_old_ps_buffers(tx->local); |
@@ -502,9 +501,8 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
502 | } | 501 | } |
503 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 502 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
504 | else if (unlikely(test_sta_flag(sta, WLAN_STA_PS_STA))) { | 503 | else if (unlikely(test_sta_flag(sta, WLAN_STA_PS_STA))) { |
505 | printk(KERN_DEBUG | 504 | pr_debug("%s: STA %pM in PS mode, but polling/in SP -> send frame\n", |
506 | "%s: STA %pM in PS mode, but polling/in SP -> send frame\n", | 505 | tx->sdata->name, sta->sta.addr); |
507 | tx->sdata->name, sta->sta.addr); | ||
508 | } | 506 | } |
509 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 507 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
510 | 508 | ||
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 8dd4712620ff..1df4019f294b 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -804,7 +804,7 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, | |||
804 | struct ieee80211_local *local = sdata->local; | 804 | struct ieee80211_local *local = sdata->local; |
805 | struct ieee80211_tx_queue_params qparam; | 805 | struct ieee80211_tx_queue_params qparam; |
806 | int ac; | 806 | int ac; |
807 | bool use_11b; | 807 | bool use_11b, enable_qos; |
808 | int aCWmin, aCWmax; | 808 | int aCWmin, aCWmax; |
809 | 809 | ||
810 | if (!local->ops->conf_tx) | 810 | if (!local->ops->conf_tx) |
@@ -818,6 +818,13 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, | |||
818 | use_11b = (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ) && | 818 | use_11b = (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ) && |
819 | !(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE); | 819 | !(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE); |
820 | 820 | ||
821 | /* | ||
822 | * By default disable QoS in STA mode for old access points, which do | ||
823 | * not support 802.11e. New APs will provide proper queue parameters, | ||
824 | * that we will configure later. | ||
825 | */ | ||
826 | enable_qos = (sdata->vif.type != NL80211_IFTYPE_STATION); | ||
827 | |||
821 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { | 828 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { |
822 | /* Set defaults according to 802.11-2007 Table 7-37 */ | 829 | /* Set defaults according to 802.11-2007 Table 7-37 */ |
823 | aCWmax = 1023; | 830 | aCWmax = 1023; |
@@ -826,38 +833,47 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, | |||
826 | else | 833 | else |
827 | aCWmin = 15; | 834 | aCWmin = 15; |
828 | 835 | ||
829 | switch (ac) { | 836 | if (enable_qos) { |
830 | case IEEE80211_AC_BK: | 837 | switch (ac) { |
831 | qparam.cw_max = aCWmax; | 838 | case IEEE80211_AC_BK: |
832 | qparam.cw_min = aCWmin; | 839 | qparam.cw_max = aCWmax; |
833 | qparam.txop = 0; | 840 | qparam.cw_min = aCWmin; |
834 | qparam.aifs = 7; | 841 | qparam.txop = 0; |
835 | break; | 842 | qparam.aifs = 7; |
836 | default: /* never happens but let's not leave undefined */ | 843 | break; |
837 | case IEEE80211_AC_BE: | 844 | /* never happens but let's not leave undefined */ |
845 | default: | ||
846 | case IEEE80211_AC_BE: | ||
847 | qparam.cw_max = aCWmax; | ||
848 | qparam.cw_min = aCWmin; | ||
849 | qparam.txop = 0; | ||
850 | qparam.aifs = 3; | ||
851 | break; | ||
852 | case IEEE80211_AC_VI: | ||
853 | qparam.cw_max = aCWmin; | ||
854 | qparam.cw_min = (aCWmin + 1) / 2 - 1; | ||
855 | if (use_11b) | ||
856 | qparam.txop = 6016/32; | ||
857 | else | ||
858 | qparam.txop = 3008/32; | ||
859 | qparam.aifs = 2; | ||
860 | break; | ||
861 | case IEEE80211_AC_VO: | ||
862 | qparam.cw_max = (aCWmin + 1) / 2 - 1; | ||
863 | qparam.cw_min = (aCWmin + 1) / 4 - 1; | ||
864 | if (use_11b) | ||
865 | qparam.txop = 3264/32; | ||
866 | else | ||
867 | qparam.txop = 1504/32; | ||
868 | qparam.aifs = 2; | ||
869 | break; | ||
870 | } | ||
871 | } else { | ||
872 | /* Confiure old 802.11b/g medium access rules. */ | ||
838 | qparam.cw_max = aCWmax; | 873 | qparam.cw_max = aCWmax; |
839 | qparam.cw_min = aCWmin; | 874 | qparam.cw_min = aCWmin; |
840 | qparam.txop = 0; | 875 | qparam.txop = 0; |
841 | qparam.aifs = 3; | ||
842 | break; | ||
843 | case IEEE80211_AC_VI: | ||
844 | qparam.cw_max = aCWmin; | ||
845 | qparam.cw_min = (aCWmin + 1) / 2 - 1; | ||
846 | if (use_11b) | ||
847 | qparam.txop = 6016/32; | ||
848 | else | ||
849 | qparam.txop = 3008/32; | ||
850 | qparam.aifs = 2; | ||
851 | break; | ||
852 | case IEEE80211_AC_VO: | ||
853 | qparam.cw_max = (aCWmin + 1) / 2 - 1; | ||
854 | qparam.cw_min = (aCWmin + 1) / 4 - 1; | ||
855 | if (use_11b) | ||
856 | qparam.txop = 3264/32; | ||
857 | else | ||
858 | qparam.txop = 1504/32; | ||
859 | qparam.aifs = 2; | 876 | qparam.aifs = 2; |
860 | break; | ||
861 | } | 877 | } |
862 | 878 | ||
863 | qparam.uapsd = false; | 879 | qparam.uapsd = false; |
@@ -866,12 +882,8 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, | |||
866 | drv_conf_tx(local, sdata, ac, &qparam); | 882 | drv_conf_tx(local, sdata, ac, &qparam); |
867 | } | 883 | } |
868 | 884 | ||
869 | /* after reinitialize QoS TX queues setting to default, | ||
870 | * disable QoS at all */ | ||
871 | |||
872 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { | 885 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { |
873 | sdata->vif.bss_conf.qos = | 886 | sdata->vif.bss_conf.qos = enable_qos; |
874 | sdata->vif.type != NL80211_IFTYPE_STATION; | ||
875 | if (bss_notify) | 887 | if (bss_notify) |
876 | ieee80211_bss_info_change_notify(sdata, | 888 | ieee80211_bss_info_change_notify(sdata, |
877 | BSS_CHANGED_QOS); | 889 | BSS_CHANGED_QOS); |
@@ -1267,14 +1279,19 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1267 | /* add STAs back */ | 1279 | /* add STAs back */ |
1268 | mutex_lock(&local->sta_mtx); | 1280 | mutex_lock(&local->sta_mtx); |
1269 | list_for_each_entry(sta, &local->sta_list, list) { | 1281 | list_for_each_entry(sta, &local->sta_list, list) { |
1270 | if (sta->uploaded) { | 1282 | enum ieee80211_sta_state state; |
1271 | enum ieee80211_sta_state state; | ||
1272 | 1283 | ||
1273 | for (state = IEEE80211_STA_NOTEXIST; | 1284 | if (!sta->uploaded) |
1274 | state < sta->sta_state; state++) | 1285 | continue; |
1275 | WARN_ON(drv_sta_state(local, sta->sdata, sta, | 1286 | |
1276 | state, state + 1)); | 1287 | /* AP-mode stations will be added later */ |
1277 | } | 1288 | if (sta->sdata->vif.type == NL80211_IFTYPE_AP) |
1289 | continue; | ||
1290 | |||
1291 | for (state = IEEE80211_STA_NOTEXIST; | ||
1292 | state < sta->sta_state; state++) | ||
1293 | WARN_ON(drv_sta_state(local, sta->sdata, sta, state, | ||
1294 | state + 1)); | ||
1278 | } | 1295 | } |
1279 | mutex_unlock(&local->sta_mtx); | 1296 | mutex_unlock(&local->sta_mtx); |
1280 | 1297 | ||
@@ -1371,6 +1388,24 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1371 | } | 1388 | } |
1372 | } | 1389 | } |
1373 | 1390 | ||
1391 | /* APs are now beaconing, add back stations */ | ||
1392 | mutex_lock(&local->sta_mtx); | ||
1393 | list_for_each_entry(sta, &local->sta_list, list) { | ||
1394 | enum ieee80211_sta_state state; | ||
1395 | |||
1396 | if (!sta->uploaded) | ||
1397 | continue; | ||
1398 | |||
1399 | if (sta->sdata->vif.type != NL80211_IFTYPE_AP) | ||
1400 | continue; | ||
1401 | |||
1402 | for (state = IEEE80211_STA_NOTEXIST; | ||
1403 | state < sta->sta_state; state++) | ||
1404 | WARN_ON(drv_sta_state(local, sta->sdata, sta, state, | ||
1405 | state + 1)); | ||
1406 | } | ||
1407 | mutex_unlock(&local->sta_mtx); | ||
1408 | |||
1374 | /* add back keys */ | 1409 | /* add back keys */ |
1375 | list_for_each_entry(sdata, &local->interfaces, list) | 1410 | list_for_each_entry(sdata, &local->interfaces, list) |
1376 | if (ieee80211_sdata_running(sdata)) | 1411 | if (ieee80211_sdata_running(sdata)) |
diff --git a/net/mac80211/work.c b/net/mac80211/work.c deleted file mode 100644 index b2650a9d45ff..000000000000 --- a/net/mac80211/work.c +++ /dev/null | |||
@@ -1,370 +0,0 @@ | |||
1 | /* | ||
2 | * mac80211 work implementation | ||
3 | * | ||
4 | * Copyright 2003-2008, Jouni Malinen <j@w1.fi> | ||
5 | * Copyright 2004, Instant802 Networks, Inc. | ||
6 | * Copyright 2005, Devicescape Software, Inc. | ||
7 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> | ||
8 | * Copyright 2007, Michael Wu <flamingice@sourmilk.net> | ||
9 | * Copyright 2009, Johannes Berg <johannes@sipsolutions.net> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2 as | ||
13 | * published by the Free Software Foundation. | ||
14 | */ | ||
15 | |||
16 | #include <linux/delay.h> | ||
17 | #include <linux/if_ether.h> | ||
18 | #include <linux/skbuff.h> | ||
19 | #include <linux/if_arp.h> | ||
20 | #include <linux/etherdevice.h> | ||
21 | #include <linux/crc32.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <net/mac80211.h> | ||
24 | #include <asm/unaligned.h> | ||
25 | |||
26 | #include "ieee80211_i.h" | ||
27 | #include "rate.h" | ||
28 | #include "driver-ops.h" | ||
29 | |||
30 | enum work_action { | ||
31 | WORK_ACT_NONE, | ||
32 | WORK_ACT_TIMEOUT, | ||
33 | }; | ||
34 | |||
35 | |||
36 | /* utils */ | ||
37 | static inline void ASSERT_WORK_MTX(struct ieee80211_local *local) | ||
38 | { | ||
39 | lockdep_assert_held(&local->mtx); | ||
40 | } | ||
41 | |||
42 | /* | ||
43 | * We can have multiple work items (and connection probing) | ||
44 | * scheduling this timer, but we need to take care to only | ||
45 | * reschedule it when it should fire _earlier_ than it was | ||
46 | * asked for before, or if it's not pending right now. This | ||
47 | * function ensures that. Note that it then is required to | ||
48 | * run this function for all timeouts after the first one | ||
49 | * has happened -- the work that runs from this timer will | ||
50 | * do that. | ||
51 | */ | ||
52 | static void run_again(struct ieee80211_local *local, | ||
53 | unsigned long timeout) | ||
54 | { | ||
55 | ASSERT_WORK_MTX(local); | ||
56 | |||
57 | if (!timer_pending(&local->work_timer) || | ||
58 | time_before(timeout, local->work_timer.expires)) | ||
59 | mod_timer(&local->work_timer, timeout); | ||
60 | } | ||
61 | |||
62 | void free_work(struct ieee80211_work *wk) | ||
63 | { | ||
64 | kfree_rcu(wk, rcu_head); | ||
65 | } | ||
66 | |||
67 | static enum work_action __must_check | ||
68 | ieee80211_remain_on_channel_timeout(struct ieee80211_work *wk) | ||
69 | { | ||
70 | /* | ||
71 | * First time we run, do nothing -- the generic code will | ||
72 | * have switched to the right channel etc. | ||
73 | */ | ||
74 | if (!wk->started) { | ||
75 | wk->timeout = jiffies + msecs_to_jiffies(wk->remain.duration); | ||
76 | |||
77 | cfg80211_ready_on_channel(wk->sdata->dev, (unsigned long) wk, | ||
78 | wk->chan, wk->chan_type, | ||
79 | wk->remain.duration, GFP_KERNEL); | ||
80 | |||
81 | return WORK_ACT_NONE; | ||
82 | } | ||
83 | |||
84 | return WORK_ACT_TIMEOUT; | ||
85 | } | ||
86 | |||
87 | static enum work_action __must_check | ||
88 | ieee80211_offchannel_tx(struct ieee80211_work *wk) | ||
89 | { | ||
90 | if (!wk->started) { | ||
91 | wk->timeout = jiffies + msecs_to_jiffies(wk->offchan_tx.wait); | ||
92 | |||
93 | /* | ||
94 | * After this, offchan_tx.frame remains but now is no | ||
95 | * longer a valid pointer -- we still need it as the | ||
96 | * cookie for canceling this work/status matching. | ||
97 | */ | ||
98 | ieee80211_tx_skb(wk->sdata, wk->offchan_tx.frame); | ||
99 | |||
100 | return WORK_ACT_NONE; | ||
101 | } | ||
102 | |||
103 | return WORK_ACT_TIMEOUT; | ||
104 | } | ||
105 | |||
106 | static void ieee80211_work_timer(unsigned long data) | ||
107 | { | ||
108 | struct ieee80211_local *local = (void *) data; | ||
109 | |||
110 | if (local->quiescing) | ||
111 | return; | ||
112 | |||
113 | ieee80211_queue_work(&local->hw, &local->work_work); | ||
114 | } | ||
115 | |||
116 | static void ieee80211_work_work(struct work_struct *work) | ||
117 | { | ||
118 | struct ieee80211_local *local = | ||
119 | container_of(work, struct ieee80211_local, work_work); | ||
120 | struct ieee80211_work *wk, *tmp; | ||
121 | LIST_HEAD(free_work); | ||
122 | enum work_action rma; | ||
123 | bool remain_off_channel = false; | ||
124 | |||
125 | /* | ||
126 | * ieee80211_queue_work() should have picked up most cases, | ||
127 | * here we'll pick the rest. | ||
128 | */ | ||
129 | if (WARN(local->suspended, "work scheduled while going to suspend\n")) | ||
130 | return; | ||
131 | |||
132 | mutex_lock(&local->mtx); | ||
133 | |||
134 | if (local->scanning) { | ||
135 | mutex_unlock(&local->mtx); | ||
136 | return; | ||
137 | } | ||
138 | |||
139 | ieee80211_recalc_idle(local); | ||
140 | |||
141 | list_for_each_entry_safe(wk, tmp, &local->work_list, list) { | ||
142 | bool started = wk->started; | ||
143 | |||
144 | /* mark work as started if it's on the current off-channel */ | ||
145 | if (!started && local->tmp_channel && | ||
146 | wk->chan == local->tmp_channel && | ||
147 | wk->chan_type == local->tmp_channel_type) { | ||
148 | started = true; | ||
149 | wk->timeout = jiffies; | ||
150 | } | ||
151 | |||
152 | if (!started && !local->tmp_channel) { | ||
153 | ieee80211_offchannel_stop_vifs(local, true); | ||
154 | |||
155 | local->tmp_channel = wk->chan; | ||
156 | local->tmp_channel_type = wk->chan_type; | ||
157 | |||
158 | ieee80211_hw_config(local, 0); | ||
159 | |||
160 | started = true; | ||
161 | wk->timeout = jiffies; | ||
162 | } | ||
163 | |||
164 | /* don't try to work with items that aren't started */ | ||
165 | if (!started) | ||
166 | continue; | ||
167 | |||
168 | if (time_is_after_jiffies(wk->timeout)) { | ||
169 | /* | ||
170 | * This work item isn't supposed to be worked on | ||
171 | * right now, but take care to adjust the timer | ||
172 | * properly. | ||
173 | */ | ||
174 | run_again(local, wk->timeout); | ||
175 | continue; | ||
176 | } | ||
177 | |||
178 | switch (wk->type) { | ||
179 | default: | ||
180 | WARN_ON(1); | ||
181 | /* nothing */ | ||
182 | rma = WORK_ACT_NONE; | ||
183 | break; | ||
184 | case IEEE80211_WORK_ABORT: | ||
185 | rma = WORK_ACT_TIMEOUT; | ||
186 | break; | ||
187 | case IEEE80211_WORK_REMAIN_ON_CHANNEL: | ||
188 | rma = ieee80211_remain_on_channel_timeout(wk); | ||
189 | break; | ||
190 | case IEEE80211_WORK_OFFCHANNEL_TX: | ||
191 | rma = ieee80211_offchannel_tx(wk); | ||
192 | break; | ||
193 | } | ||
194 | |||
195 | wk->started = started; | ||
196 | |||
197 | switch (rma) { | ||
198 | case WORK_ACT_NONE: | ||
199 | /* might have changed the timeout */ | ||
200 | run_again(local, wk->timeout); | ||
201 | break; | ||
202 | case WORK_ACT_TIMEOUT: | ||
203 | list_del_rcu(&wk->list); | ||
204 | synchronize_rcu(); | ||
205 | list_add(&wk->list, &free_work); | ||
206 | break; | ||
207 | default: | ||
208 | WARN(1, "unexpected: %d", rma); | ||
209 | } | ||
210 | } | ||
211 | |||
212 | list_for_each_entry(wk, &local->work_list, list) { | ||
213 | if (!wk->started) | ||
214 | continue; | ||
215 | if (wk->chan != local->tmp_channel || | ||
216 | wk->chan_type != local->tmp_channel_type) | ||
217 | continue; | ||
218 | remain_off_channel = true; | ||
219 | } | ||
220 | |||
221 | if (!remain_off_channel && local->tmp_channel) { | ||
222 | local->tmp_channel = NULL; | ||
223 | ieee80211_hw_config(local, 0); | ||
224 | |||
225 | ieee80211_offchannel_return(local, true); | ||
226 | |||
227 | /* give connection some time to breathe */ | ||
228 | run_again(local, jiffies + HZ/2); | ||
229 | } | ||
230 | |||
231 | ieee80211_recalc_idle(local); | ||
232 | ieee80211_run_deferred_scan(local); | ||
233 | |||
234 | mutex_unlock(&local->mtx); | ||
235 | |||
236 | list_for_each_entry_safe(wk, tmp, &free_work, list) { | ||
237 | wk->done(wk, NULL); | ||
238 | list_del(&wk->list); | ||
239 | kfree(wk); | ||
240 | } | ||
241 | } | ||
242 | |||
243 | void ieee80211_add_work(struct ieee80211_work *wk) | ||
244 | { | ||
245 | struct ieee80211_local *local; | ||
246 | |||
247 | if (WARN_ON(!wk->chan)) | ||
248 | return; | ||
249 | |||
250 | if (WARN_ON(!wk->sdata)) | ||
251 | return; | ||
252 | |||
253 | if (WARN_ON(!wk->done)) | ||
254 | return; | ||
255 | |||
256 | if (WARN_ON(!ieee80211_sdata_running(wk->sdata))) | ||
257 | return; | ||
258 | |||
259 | wk->started = false; | ||
260 | |||
261 | local = wk->sdata->local; | ||
262 | mutex_lock(&local->mtx); | ||
263 | list_add_tail(&wk->list, &local->work_list); | ||
264 | mutex_unlock(&local->mtx); | ||
265 | |||
266 | ieee80211_queue_work(&local->hw, &local->work_work); | ||
267 | } | ||
268 | |||
269 | void ieee80211_work_init(struct ieee80211_local *local) | ||
270 | { | ||
271 | INIT_LIST_HEAD(&local->work_list); | ||
272 | setup_timer(&local->work_timer, ieee80211_work_timer, | ||
273 | (unsigned long)local); | ||
274 | INIT_WORK(&local->work_work, ieee80211_work_work); | ||
275 | } | ||
276 | |||
277 | void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata) | ||
278 | { | ||
279 | struct ieee80211_local *local = sdata->local; | ||
280 | struct ieee80211_work *wk; | ||
281 | bool cleanup = false; | ||
282 | |||
283 | mutex_lock(&local->mtx); | ||
284 | list_for_each_entry(wk, &local->work_list, list) { | ||
285 | if (wk->sdata != sdata) | ||
286 | continue; | ||
287 | cleanup = true; | ||
288 | wk->type = IEEE80211_WORK_ABORT; | ||
289 | wk->started = true; | ||
290 | wk->timeout = jiffies; | ||
291 | } | ||
292 | mutex_unlock(&local->mtx); | ||
293 | |||
294 | /* run cleanups etc. */ | ||
295 | if (cleanup) | ||
296 | ieee80211_work_work(&local->work_work); | ||
297 | |||
298 | mutex_lock(&local->mtx); | ||
299 | list_for_each_entry(wk, &local->work_list, list) { | ||
300 | if (wk->sdata != sdata) | ||
301 | continue; | ||
302 | WARN_ON(1); | ||
303 | break; | ||
304 | } | ||
305 | mutex_unlock(&local->mtx); | ||
306 | } | ||
307 | |||
308 | static enum work_done_result ieee80211_remain_done(struct ieee80211_work *wk, | ||
309 | struct sk_buff *skb) | ||
310 | { | ||
311 | /* | ||
312 | * We are done serving the remain-on-channel command. | ||
313 | */ | ||
314 | cfg80211_remain_on_channel_expired(wk->sdata->dev, (unsigned long) wk, | ||
315 | wk->chan, wk->chan_type, | ||
316 | GFP_KERNEL); | ||
317 | |||
318 | return WORK_DONE_DESTROY; | ||
319 | } | ||
320 | |||
321 | int ieee80211_wk_remain_on_channel(struct ieee80211_sub_if_data *sdata, | ||
322 | struct ieee80211_channel *chan, | ||
323 | enum nl80211_channel_type channel_type, | ||
324 | unsigned int duration, u64 *cookie) | ||
325 | { | ||
326 | struct ieee80211_work *wk; | ||
327 | |||
328 | wk = kzalloc(sizeof(*wk), GFP_KERNEL); | ||
329 | if (!wk) | ||
330 | return -ENOMEM; | ||
331 | |||
332 | wk->type = IEEE80211_WORK_REMAIN_ON_CHANNEL; | ||
333 | wk->chan = chan; | ||
334 | wk->chan_type = channel_type; | ||
335 | wk->sdata = sdata; | ||
336 | wk->done = ieee80211_remain_done; | ||
337 | |||
338 | wk->remain.duration = duration; | ||
339 | |||
340 | *cookie = (unsigned long) wk; | ||
341 | |||
342 | ieee80211_add_work(wk); | ||
343 | |||
344 | return 0; | ||
345 | } | ||
346 | |||
347 | int ieee80211_wk_cancel_remain_on_channel(struct ieee80211_sub_if_data *sdata, | ||
348 | u64 cookie) | ||
349 | { | ||
350 | struct ieee80211_local *local = sdata->local; | ||
351 | struct ieee80211_work *wk, *tmp; | ||
352 | bool found = false; | ||
353 | |||
354 | mutex_lock(&local->mtx); | ||
355 | list_for_each_entry_safe(wk, tmp, &local->work_list, list) { | ||
356 | if ((unsigned long) wk == cookie) { | ||
357 | wk->timeout = jiffies; | ||
358 | found = true; | ||
359 | break; | ||
360 | } | ||
361 | } | ||
362 | mutex_unlock(&local->mtx); | ||
363 | |||
364 | if (!found) | ||
365 | return -ENOENT; | ||
366 | |||
367 | ieee80211_queue_work(&local->hw, &local->work_work); | ||
368 | |||
369 | return 0; | ||
370 | } | ||