diff options
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/agg-rx.c | 4 | ||||
-rw-r--r-- | net/mac80211/agg-tx.c | 35 | ||||
-rw-r--r-- | net/mac80211/ht.c | 8 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 10 | ||||
-rw-r--r-- | net/mac80211/util.c | 19 |
5 files changed, 38 insertions, 38 deletions
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index bc064d7933ff..ce8e0e772bab 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c | |||
@@ -85,10 +85,6 @@ void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *r | |||
85 | struct ieee80211_local *local = sdata->local; | 85 | struct ieee80211_local *local = sdata->local; |
86 | struct sta_info *sta; | 86 | struct sta_info *sta; |
87 | 87 | ||
88 | /* stop HW Rx aggregation. ampdu_action existence | ||
89 | * already verified in session init so we add the BUG_ON */ | ||
90 | BUG_ON(!local->ops->ampdu_action); | ||
91 | |||
92 | rcu_read_lock(); | 88 | rcu_read_lock(); |
93 | 89 | ||
94 | sta = sta_info_get(local, ra); | 90 | sta = sta_info_get(local, ra); |
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index b09948ceec4a..89e238b001de 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c | |||
@@ -123,13 +123,18 @@ void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u1 | |||
123 | ieee80211_tx_skb(sdata, skb, 0); | 123 | ieee80211_tx_skb(sdata, skb, 0); |
124 | } | 124 | } |
125 | 125 | ||
126 | static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | 126 | int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, |
127 | enum ieee80211_back_parties initiator) | 127 | enum ieee80211_back_parties initiator) |
128 | { | 128 | { |
129 | struct ieee80211_local *local = sta->local; | 129 | struct ieee80211_local *local = sta->local; |
130 | int ret; | 130 | int ret; |
131 | u8 *state; | 131 | u8 *state; |
132 | 132 | ||
133 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
134 | printk(KERN_DEBUG "Tx BA session stop requested for %pM tid %u\n", | ||
135 | sta->sta.addr, tid); | ||
136 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
137 | |||
133 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 138 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
134 | 139 | ||
135 | if (*state == HT_AGG_STATE_OPERATIONAL) | 140 | if (*state == HT_AGG_STATE_OPERATIONAL) |
@@ -143,7 +148,6 @@ static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | |||
143 | 148 | ||
144 | /* HW shall not deny going back to legacy */ | 149 | /* HW shall not deny going back to legacy */ |
145 | if (WARN_ON(ret)) { | 150 | if (WARN_ON(ret)) { |
146 | *state = HT_AGG_STATE_OPERATIONAL; | ||
147 | /* | 151 | /* |
148 | * We may have pending packets get stuck in this case... | 152 | * We may have pending packets get stuck in this case... |
149 | * Not bothering with a workaround for now. | 153 | * Not bothering with a workaround for now. |
@@ -173,12 +177,14 @@ static void sta_addba_resp_timer_expired(unsigned long data) | |||
173 | 177 | ||
174 | /* check if the TID waits for addBA response */ | 178 | /* check if the TID waits for addBA response */ |
175 | spin_lock_bh(&sta->lock); | 179 | spin_lock_bh(&sta->lock); |
176 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { | 180 | if ((*state & (HT_ADDBA_REQUESTED_MSK | HT_ADDBA_RECEIVED_MSK)) != |
181 | HT_ADDBA_REQUESTED_MSK) { | ||
177 | spin_unlock_bh(&sta->lock); | 182 | spin_unlock_bh(&sta->lock); |
178 | *state = HT_AGG_STATE_IDLE; | 183 | *state = HT_AGG_STATE_IDLE; |
179 | #ifdef CONFIG_MAC80211_HT_DEBUG | 184 | #ifdef CONFIG_MAC80211_HT_DEBUG |
180 | printk(KERN_DEBUG "timer expired on tid %d but we are not " | 185 | printk(KERN_DEBUG "timer expired on tid %d but we are not " |
181 | "expecting addBA response there", tid); | 186 | "(or no longer) expecting addBA response there", |
187 | tid); | ||
182 | #endif | 188 | #endif |
183 | return; | 189 | return; |
184 | } | 190 | } |
@@ -523,11 +529,6 @@ int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | |||
523 | goto unlock; | 529 | goto unlock; |
524 | } | 530 | } |
525 | 531 | ||
526 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
527 | printk(KERN_DEBUG "Tx BA session stop requested for %pM tid %u\n", | ||
528 | sta->sta.addr, tid); | ||
529 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
530 | |||
531 | ret = ___ieee80211_stop_tx_ba_session(sta, tid, initiator); | 532 | ret = ___ieee80211_stop_tx_ba_session(sta, tid, initiator); |
532 | 533 | ||
533 | unlock: | 534 | unlock: |
@@ -543,7 +544,7 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | |||
543 | struct sta_info *sta; | 544 | struct sta_info *sta; |
544 | int ret = 0; | 545 | int ret = 0; |
545 | 546 | ||
546 | if (WARN_ON(!local->ops->ampdu_action)) | 547 | if (!local->ops->ampdu_action) |
547 | return -EINVAL; | 548 | return -EINVAL; |
548 | 549 | ||
549 | if (tid >= STA_TID_NUM) | 550 | if (tid >= STA_TID_NUM) |
@@ -666,21 +667,21 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, | |||
666 | 667 | ||
667 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 668 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
668 | 669 | ||
669 | del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); | ||
670 | |||
671 | spin_lock_bh(&sta->lock); | 670 | spin_lock_bh(&sta->lock); |
672 | 671 | ||
673 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) | 672 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) |
674 | goto timer_still_needed; | 673 | goto out; |
675 | 674 | ||
676 | if (mgmt->u.action.u.addba_resp.dialog_token != | 675 | if (mgmt->u.action.u.addba_resp.dialog_token != |
677 | sta->ampdu_mlme.tid_tx[tid]->dialog_token) { | 676 | sta->ampdu_mlme.tid_tx[tid]->dialog_token) { |
678 | #ifdef CONFIG_MAC80211_HT_DEBUG | 677 | #ifdef CONFIG_MAC80211_HT_DEBUG |
679 | printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); | 678 | printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); |
680 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 679 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
681 | goto timer_still_needed; | 680 | goto out; |
682 | } | 681 | } |
683 | 682 | ||
683 | del_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); | ||
684 | |||
684 | #ifdef CONFIG_MAC80211_HT_DEBUG | 685 | #ifdef CONFIG_MAC80211_HT_DEBUG |
685 | printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid); | 686 | printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid); |
686 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 687 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
@@ -699,10 +700,6 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, | |||
699 | ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR); | 700 | ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR); |
700 | } | 701 | } |
701 | 702 | ||
702 | goto out; | ||
703 | |||
704 | timer_still_needed: | ||
705 | add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); | ||
706 | out: | 703 | out: |
707 | spin_unlock_bh(&sta->lock); | 704 | spin_unlock_bh(&sta->lock); |
708 | } | 705 | } |
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 48ef1a282b91..cdc58e61d921 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c | |||
@@ -141,7 +141,6 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, | |||
141 | struct sta_info *sta, | 141 | struct sta_info *sta, |
142 | struct ieee80211_mgmt *mgmt, size_t len) | 142 | struct ieee80211_mgmt *mgmt, size_t len) |
143 | { | 143 | { |
144 | struct ieee80211_local *local = sdata->local; | ||
145 | u16 tid, params; | 144 | u16 tid, params; |
146 | u16 initiator; | 145 | u16 initiator; |
147 | 146 | ||
@@ -161,10 +160,9 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, | |||
161 | WLAN_BACK_INITIATOR, 0); | 160 | WLAN_BACK_INITIATOR, 0); |
162 | else { /* WLAN_BACK_RECIPIENT */ | 161 | else { /* WLAN_BACK_RECIPIENT */ |
163 | spin_lock_bh(&sta->lock); | 162 | spin_lock_bh(&sta->lock); |
164 | sta->ampdu_mlme.tid_state_tx[tid] = | 163 | if (sta->ampdu_mlme.tid_state_tx[tid] & HT_ADDBA_REQUESTED_MSK) |
165 | HT_AGG_STATE_OPERATIONAL; | 164 | ___ieee80211_stop_tx_ba_session(sta, tid, |
165 | WLAN_BACK_RECIPIENT); | ||
166 | spin_unlock_bh(&sta->lock); | 166 | spin_unlock_bh(&sta->lock); |
167 | ieee80211_stop_tx_ba_session(&local->hw, sta->sta.addr, tid, | ||
168 | WLAN_BACK_RECIPIENT); | ||
169 | } | 167 | } |
170 | } | 168 | } |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 588005c84a6d..10d316e455de 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -662,6 +662,14 @@ struct ieee80211_local { | |||
662 | bool suspended; | 662 | bool suspended; |
663 | 663 | ||
664 | /* | 664 | /* |
665 | * Resuming is true while suspended, but when we're reprogramming the | ||
666 | * hardware -- at that time it's allowed to use ieee80211_queue_work() | ||
667 | * again even though some other parts of the stack are still suspended | ||
668 | * and we still drop received frames to avoid waking the stack. | ||
669 | */ | ||
670 | bool resuming; | ||
671 | |||
672 | /* | ||
665 | * quiescing is true during the suspend process _only_ to | 673 | * quiescing is true during the suspend process _only_ to |
666 | * ease timer cancelling etc. | 674 | * ease timer cancelling etc. |
667 | */ | 675 | */ |
@@ -1083,6 +1091,8 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, | |||
1083 | 1091 | ||
1084 | int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | 1092 | int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, |
1085 | enum ieee80211_back_parties initiator); | 1093 | enum ieee80211_back_parties initiator); |
1094 | int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | ||
1095 | enum ieee80211_back_parties initiator); | ||
1086 | 1096 | ||
1087 | /* Spectrum management */ | 1097 | /* Spectrum management */ |
1088 | void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata, | 1098 | void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata, |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index aeb65b3d2295..e6c08da8da26 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -520,9 +520,9 @@ EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic); | |||
520 | */ | 520 | */ |
521 | static bool ieee80211_can_queue_work(struct ieee80211_local *local) | 521 | static bool ieee80211_can_queue_work(struct ieee80211_local *local) |
522 | { | 522 | { |
523 | if (WARN(local->suspended, "queueing ieee80211 work while " | 523 | if (WARN(local->suspended && !local->resuming, |
524 | "going to suspend\n")) | 524 | "queueing ieee80211 work while going to suspend\n")) |
525 | return false; | 525 | return false; |
526 | 526 | ||
527 | return true; | 527 | return true; |
528 | } | 528 | } |
@@ -1025,13 +1025,9 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1025 | struct sta_info *sta; | 1025 | struct sta_info *sta; |
1026 | unsigned long flags; | 1026 | unsigned long flags; |
1027 | int res; | 1027 | int res; |
1028 | bool from_suspend = local->suspended; | ||
1029 | 1028 | ||
1030 | /* | 1029 | if (local->suspended) |
1031 | * We're going to start the hardware, at that point | 1030 | local->resuming = true; |
1032 | * we are no longer suspended and can RX frames. | ||
1033 | */ | ||
1034 | local->suspended = false; | ||
1035 | 1031 | ||
1036 | /* restart hardware */ | 1032 | /* restart hardware */ |
1037 | if (local->open_count) { | 1033 | if (local->open_count) { |
@@ -1129,11 +1125,14 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1129 | * If this is for hw restart things are still running. | 1125 | * If this is for hw restart things are still running. |
1130 | * We may want to change that later, however. | 1126 | * We may want to change that later, however. |
1131 | */ | 1127 | */ |
1132 | if (!from_suspend) | 1128 | if (!local->suspended) |
1133 | return 0; | 1129 | return 0; |
1134 | 1130 | ||
1135 | #ifdef CONFIG_PM | 1131 | #ifdef CONFIG_PM |
1132 | /* first set suspended false, then resuming */ | ||
1136 | local->suspended = false; | 1133 | local->suspended = false; |
1134 | mb(); | ||
1135 | local->resuming = false; | ||
1137 | 1136 | ||
1138 | list_for_each_entry(sdata, &local->interfaces, list) { | 1137 | list_for_each_entry(sdata, &local->interfaces, list) { |
1139 | switch(sdata->vif.type) { | 1138 | switch(sdata->vif.type) { |