diff options
Diffstat (limited to 'net/mac80211')
| -rw-r--r-- | net/mac80211/agg-rx.c | 4 | ||||
| -rw-r--r-- | net/mac80211/agg-tx.c | 38 | ||||
| -rw-r--r-- | net/mac80211/cfg.c | 6 | ||||
| -rw-r--r-- | net/mac80211/ht.c | 10 | ||||
| -rw-r--r-- | net/mac80211/ibss.c | 12 | ||||
| -rw-r--r-- | net/mac80211/ieee80211_i.h | 10 | ||||
| -rw-r--r-- | net/mac80211/mesh_hwmp.c | 2 | ||||
| -rw-r--r-- | net/mac80211/mlme.c | 3 | ||||
| -rw-r--r-- | net/mac80211/tx.c | 2 | ||||
| -rw-r--r-- | net/mac80211/util.c | 19 |
10 files changed, 55 insertions, 51 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 bd765f30dba2..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) |
| @@ -668,24 +669,23 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, | |||
| 668 | 669 | ||
| 669 | spin_lock_bh(&sta->lock); | 670 | spin_lock_bh(&sta->lock); |
| 670 | 671 | ||
| 671 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { | 672 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) |
| 672 | spin_unlock_bh(&sta->lock); | 673 | goto out; |
| 673 | return; | ||
| 674 | } | ||
| 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 | spin_unlock_bh(&sta->lock); | ||
| 679 | #ifdef CONFIG_MAC80211_HT_DEBUG | 677 | #ifdef CONFIG_MAC80211_HT_DEBUG |
| 680 | printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); | 678 | printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); |
| 681 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 679 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
| 682 | return; | 680 | goto out; |
| 683 | } | 681 | } |
| 684 | 682 | ||
| 685 | del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); | 683 | del_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); |
| 684 | |||
| 686 | #ifdef CONFIG_MAC80211_HT_DEBUG | 685 | #ifdef CONFIG_MAC80211_HT_DEBUG |
| 687 | 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); |
| 688 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 687 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
| 688 | |||
| 689 | if (le16_to_cpu(mgmt->u.action.u.addba_resp.status) | 689 | if (le16_to_cpu(mgmt->u.action.u.addba_resp.status) |
| 690 | == WLAN_STATUS_SUCCESS) { | 690 | == WLAN_STATUS_SUCCESS) { |
| 691 | u8 curstate = *state; | 691 | u8 curstate = *state; |
| @@ -699,5 +699,7 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, | |||
| 699 | } else { | 699 | } else { |
| 700 | ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR); | 700 | ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR); |
| 701 | } | 701 | } |
| 702 | |||
| 703 | out: | ||
| 702 | spin_unlock_bh(&sta->lock); | 704 | spin_unlock_bh(&sta->lock); |
| 703 | } | 705 | } |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 5608f6c68413..7b5131bd6fa1 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
| @@ -72,6 +72,9 @@ static int ieee80211_change_iface(struct wiphy *wiphy, | |||
| 72 | struct ieee80211_sub_if_data *sdata; | 72 | struct ieee80211_sub_if_data *sdata; |
| 73 | int ret; | 73 | int ret; |
| 74 | 74 | ||
| 75 | if (netif_running(dev)) | ||
| 76 | return -EBUSY; | ||
| 77 | |||
| 75 | if (!nl80211_type_check(type)) | 78 | if (!nl80211_type_check(type)) |
| 76 | return -EINVAL; | 79 | return -EINVAL; |
| 77 | 80 | ||
| @@ -81,9 +84,6 @@ static int ieee80211_change_iface(struct wiphy *wiphy, | |||
| 81 | if (ret) | 84 | if (ret) |
| 82 | return ret; | 85 | return ret; |
| 83 | 86 | ||
| 84 | if (netif_running(sdata->dev)) | ||
| 85 | return -EBUSY; | ||
| 86 | |||
| 87 | if (ieee80211_vif_is_mesh(&sdata->vif) && params->mesh_id_len) | 87 | if (ieee80211_vif_is_mesh(&sdata->vif) && params->mesh_id_len) |
| 88 | ieee80211_sdata_set_mesh_id(sdata, | 88 | ieee80211_sdata_set_mesh_id(sdata, |
| 89 | params->mesh_id_len, | 89 | params->mesh_id_len, |
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 0891bfb06996..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 | ||
| @@ -153,7 +152,7 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, | |||
| 153 | if (net_ratelimit()) | 152 | if (net_ratelimit()) |
| 154 | printk(KERN_DEBUG "delba from %pM (%s) tid %d reason code %d\n", | 153 | printk(KERN_DEBUG "delba from %pM (%s) tid %d reason code %d\n", |
| 155 | mgmt->sa, initiator ? "initiator" : "recipient", tid, | 154 | mgmt->sa, initiator ? "initiator" : "recipient", tid, |
| 156 | mgmt->u.action.u.delba.reason_code); | 155 | le16_to_cpu(mgmt->u.action.u.delba.reason_code)); |
| 157 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 156 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
| 158 | 157 | ||
| 159 | if (initiator == WLAN_BACK_INITIATOR) | 158 | if (initiator == WLAN_BACK_INITIATOR) |
| @@ -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/ibss.c b/net/mac80211/ibss.c index 6eaf69823439..f1362f32c17d 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
| @@ -73,6 +73,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
| 73 | struct ieee80211_mgmt *mgmt; | 73 | struct ieee80211_mgmt *mgmt; |
| 74 | u8 *pos; | 74 | u8 *pos; |
| 75 | struct ieee80211_supported_band *sband; | 75 | struct ieee80211_supported_band *sband; |
| 76 | struct cfg80211_bss *bss; | ||
| 76 | u32 bss_change; | 77 | u32 bss_change; |
| 77 | u8 supp_rates[IEEE80211_MAX_SUPP_RATES]; | 78 | u8 supp_rates[IEEE80211_MAX_SUPP_RATES]; |
| 78 | 79 | ||
| @@ -177,8 +178,9 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
| 177 | mod_timer(&ifibss->timer, | 178 | mod_timer(&ifibss->timer, |
| 178 | round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL)); | 179 | round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL)); |
| 179 | 180 | ||
| 180 | cfg80211_inform_bss_frame(local->hw.wiphy, local->hw.conf.channel, | 181 | bss = cfg80211_inform_bss_frame(local->hw.wiphy, local->hw.conf.channel, |
| 181 | mgmt, skb->len, 0, GFP_KERNEL); | 182 | mgmt, skb->len, 0, GFP_KERNEL); |
| 183 | cfg80211_put_bss(bss); | ||
| 182 | cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL); | 184 | cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL); |
| 183 | } | 185 | } |
| 184 | 186 | ||
| @@ -538,13 +540,12 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) | |||
| 538 | WLAN_CAPABILITY_PRIVACY, | 540 | WLAN_CAPABILITY_PRIVACY, |
| 539 | capability); | 541 | capability); |
| 540 | 542 | ||
| 543 | if (bss) { | ||
| 541 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 544 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
| 542 | if (bss) | ||
| 543 | printk(KERN_DEBUG " sta_find_ibss: selected %pM current " | 545 | printk(KERN_DEBUG " sta_find_ibss: selected %pM current " |
| 544 | "%pM\n", bss->cbss.bssid, ifibss->bssid); | 546 | "%pM\n", bss->cbss.bssid, ifibss->bssid); |
| 545 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | 547 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ |
| 546 | 548 | ||
| 547 | if (bss && !memcmp(ifibss->bssid, bss->cbss.bssid, ETH_ALEN)) { | ||
| 548 | printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM" | 549 | printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM" |
| 549 | " based on configured SSID\n", | 550 | " based on configured SSID\n", |
| 550 | sdata->dev->name, bss->cbss.bssid); | 551 | sdata->dev->name, bss->cbss.bssid); |
| @@ -552,8 +553,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) | |||
| 552 | ieee80211_sta_join_ibss(sdata, bss); | 553 | ieee80211_sta_join_ibss(sdata, bss); |
| 553 | ieee80211_rx_bss_put(local, bss); | 554 | ieee80211_rx_bss_put(local, bss); |
| 554 | return; | 555 | return; |
| 555 | } else if (bss) | 556 | } |
| 556 | ieee80211_rx_bss_put(local, bss); | ||
| 557 | 557 | ||
| 558 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 558 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
| 559 | printk(KERN_DEBUG " did not try to join ibss\n"); | 559 | printk(KERN_DEBUG " did not try to join ibss\n"); |
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/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index e12a786e26b8..29b82e98effa 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c | |||
| @@ -259,7 +259,7 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local, | |||
| 259 | * @hwmp_ie: hwmp information element (PREP or PREQ) | 259 | * @hwmp_ie: hwmp information element (PREP or PREQ) |
| 260 | * | 260 | * |
| 261 | * This function updates the path routing information to the originator and the | 261 | * This function updates the path routing information to the originator and the |
| 262 | * transmitter of a HWMP PREQ or PREP fram. | 262 | * transmitter of a HWMP PREQ or PREP frame. |
| 263 | * | 263 | * |
| 264 | * Returns: metric to frame originator or 0 if the frame should not be further | 264 | * Returns: metric to frame originator or 0 if the frame should not be further |
| 265 | * processed | 265 | * processed |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 8d26e9bf8964..dc5049d58c51 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
| @@ -1457,8 +1457,7 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
| 1457 | if (status_code != WLAN_STATUS_SUCCESS) { | 1457 | if (status_code != WLAN_STATUS_SUCCESS) { |
| 1458 | printk(KERN_DEBUG "%s: AP denied association (code=%d)\n", | 1458 | printk(KERN_DEBUG "%s: AP denied association (code=%d)\n", |
| 1459 | sdata->dev->name, status_code); | 1459 | sdata->dev->name, status_code); |
| 1460 | list_del(&wk->list); | 1460 | wk->state = IEEE80211_MGD_STATE_IDLE; |
| 1461 | kfree(wk); | ||
| 1462 | return RX_MGMT_CFG80211_ASSOC; | 1461 | return RX_MGMT_CFG80211_ASSOC; |
| 1463 | } | 1462 | } |
| 1464 | 1463 | ||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index db4bda681ec9..eaa4118de988 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
| @@ -1445,7 +1445,7 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | |||
| 1445 | if (tmp_sdata->vif.type != NL80211_IFTYPE_AP) | 1445 | if (tmp_sdata->vif.type != NL80211_IFTYPE_AP) |
| 1446 | continue; | 1446 | continue; |
| 1447 | if (compare_ether_addr(tmp_sdata->dev->dev_addr, | 1447 | if (compare_ether_addr(tmp_sdata->dev->dev_addr, |
| 1448 | hdr->addr2)) { | 1448 | hdr->addr2) == 0) { |
| 1449 | dev_hold(tmp_sdata->dev); | 1449 | dev_hold(tmp_sdata->dev); |
| 1450 | dev_put(sdata->dev); | 1450 | dev_put(sdata->dev); |
| 1451 | sdata = tmp_sdata; | 1451 | sdata = tmp_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) { |
