diff options
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/agg-rx.c | 7 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 9 | ||||
-rw-r--r-- | net/mac80211/iface.c | 12 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 40 | ||||
-rw-r--r-- | net/mac80211/offchannel.c | 16 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 4 | ||||
-rw-r--r-- | net/mac80211/sta_info.h | 5 | ||||
-rw-r--r-- | net/mac80211/tx.c | 9 | ||||
-rw-r--r-- | net/mac80211/util.c | 2 |
9 files changed, 83 insertions, 21 deletions
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index 26ddb699d693..c649188314cc 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c | |||
@@ -145,15 +145,20 @@ static void sta_rx_agg_session_timer_expired(unsigned long data) | |||
145 | struct tid_ampdu_rx *tid_rx; | 145 | struct tid_ampdu_rx *tid_rx; |
146 | unsigned long timeout; | 146 | unsigned long timeout; |
147 | 147 | ||
148 | rcu_read_lock(); | ||
148 | tid_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[*ptid]); | 149 | tid_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[*ptid]); |
149 | if (!tid_rx) | 150 | if (!tid_rx) { |
151 | rcu_read_unlock(); | ||
150 | return; | 152 | return; |
153 | } | ||
151 | 154 | ||
152 | timeout = tid_rx->last_rx + TU_TO_JIFFIES(tid_rx->timeout); | 155 | timeout = tid_rx->last_rx + TU_TO_JIFFIES(tid_rx->timeout); |
153 | if (time_is_after_jiffies(timeout)) { | 156 | if (time_is_after_jiffies(timeout)) { |
154 | mod_timer(&tid_rx->session_timer, timeout); | 157 | mod_timer(&tid_rx->session_timer, timeout); |
158 | rcu_read_unlock(); | ||
155 | return; | 159 | return; |
156 | } | 160 | } |
161 | rcu_read_unlock(); | ||
157 | 162 | ||
158 | #ifdef CONFIG_MAC80211_HT_DEBUG | 163 | #ifdef CONFIG_MAC80211_HT_DEBUG |
159 | printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid); | 164 | printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid); |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 495831ee48f1..7d5108a867ad 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -533,16 +533,16 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy, | |||
533 | sinfo.filled = 0; | 533 | sinfo.filled = 0; |
534 | sta_set_sinfo(sta, &sinfo); | 534 | sta_set_sinfo(sta, &sinfo); |
535 | 535 | ||
536 | if (sinfo.filled | STATION_INFO_TX_BITRATE) | 536 | if (sinfo.filled & STATION_INFO_TX_BITRATE) |
537 | data[i] = 100000 * | 537 | data[i] = 100000 * |
538 | cfg80211_calculate_bitrate(&sinfo.txrate); | 538 | cfg80211_calculate_bitrate(&sinfo.txrate); |
539 | i++; | 539 | i++; |
540 | if (sinfo.filled | STATION_INFO_RX_BITRATE) | 540 | if (sinfo.filled & STATION_INFO_RX_BITRATE) |
541 | data[i] = 100000 * | 541 | data[i] = 100000 * |
542 | cfg80211_calculate_bitrate(&sinfo.rxrate); | 542 | cfg80211_calculate_bitrate(&sinfo.rxrate); |
543 | i++; | 543 | i++; |
544 | 544 | ||
545 | if (sinfo.filled | STATION_INFO_SIGNAL_AVG) | 545 | if (sinfo.filled & STATION_INFO_SIGNAL_AVG) |
546 | data[i] = (u8)sinfo.signal_avg; | 546 | data[i] = (u8)sinfo.signal_avg; |
547 | i++; | 547 | i++; |
548 | } else { | 548 | } else { |
@@ -2093,6 +2093,9 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy, | |||
2093 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 2093 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
2094 | int i, ret; | 2094 | int i, ret; |
2095 | 2095 | ||
2096 | if (!ieee80211_sdata_running(sdata)) | ||
2097 | return -ENETDOWN; | ||
2098 | |||
2096 | if (local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) { | 2099 | if (local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) { |
2097 | ret = drv_set_bitrate_mask(local, sdata, mask); | 2100 | ret = drv_set_bitrate_mask(local, sdata, mask); |
2098 | if (ret) | 2101 | if (ret) |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index d4c19a7773db..8664111d0566 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -637,6 +637,18 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
637 | ieee80211_configure_filter(local); | 637 | ieee80211_configure_filter(local); |
638 | break; | 638 | break; |
639 | default: | 639 | 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 | |||
640 | flush_work(&sdata->work); | 652 | flush_work(&sdata->work); |
641 | /* | 653 | /* |
642 | * When we get here, the interface is marked down. | 654 | * When we get here, the interface is marked down. |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 04c306308987..66e4fcdd1c6b 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -1220,6 +1220,22 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, | |||
1220 | sdata->vif.bss_conf.qos = true; | 1220 | sdata->vif.bss_conf.qos = true; |
1221 | } | 1221 | } |
1222 | 1222 | ||
1223 | static void __ieee80211_stop_poll(struct ieee80211_sub_if_data *sdata) | ||
1224 | { | ||
1225 | lockdep_assert_held(&sdata->local->mtx); | ||
1226 | |||
1227 | sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL | | ||
1228 | IEEE80211_STA_BEACON_POLL); | ||
1229 | ieee80211_run_deferred_scan(sdata->local); | ||
1230 | } | ||
1231 | |||
1232 | static void ieee80211_stop_poll(struct ieee80211_sub_if_data *sdata) | ||
1233 | { | ||
1234 | mutex_lock(&sdata->local->mtx); | ||
1235 | __ieee80211_stop_poll(sdata); | ||
1236 | mutex_unlock(&sdata->local->mtx); | ||
1237 | } | ||
1238 | |||
1223 | static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata, | 1239 | static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata, |
1224 | u16 capab, bool erp_valid, u8 erp) | 1240 | u16 capab, bool erp_valid, u8 erp) |
1225 | { | 1241 | { |
@@ -1285,8 +1301,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
1285 | sdata->u.mgd.flags |= IEEE80211_STA_RESET_SIGNAL_AVE; | 1301 | sdata->u.mgd.flags |= IEEE80211_STA_RESET_SIGNAL_AVE; |
1286 | 1302 | ||
1287 | /* just to be sure */ | 1303 | /* just to be sure */ |
1288 | sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL | | 1304 | ieee80211_stop_poll(sdata); |
1289 | IEEE80211_STA_BEACON_POLL); | ||
1290 | 1305 | ||
1291 | ieee80211_led_assoc(local, 1); | 1306 | ieee80211_led_assoc(local, 1); |
1292 | 1307 | ||
@@ -1337,6 +1352,8 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1337 | if (WARN_ON(!ifmgd->associated)) | 1352 | if (WARN_ON(!ifmgd->associated)) |
1338 | return; | 1353 | return; |
1339 | 1354 | ||
1355 | ieee80211_stop_poll(sdata); | ||
1356 | |||
1340 | memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN); | 1357 | memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN); |
1341 | 1358 | ||
1342 | ifmgd->associated = NULL; | 1359 | ifmgd->associated = NULL; |
@@ -1456,8 +1473,7 @@ static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata) | |||
1456 | return; | 1473 | return; |
1457 | } | 1474 | } |
1458 | 1475 | ||
1459 | ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | | 1476 | __ieee80211_stop_poll(sdata); |
1460 | IEEE80211_STA_BEACON_POLL); | ||
1461 | 1477 | ||
1462 | mutex_lock(&local->iflist_mtx); | 1478 | mutex_lock(&local->iflist_mtx); |
1463 | ieee80211_recalc_ps(local, -1); | 1479 | ieee80211_recalc_ps(local, -1); |
@@ -1477,7 +1493,6 @@ static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata) | |||
1477 | round_jiffies_up(jiffies + | 1493 | round_jiffies_up(jiffies + |
1478 | IEEE80211_CONNECTION_IDLE_TIME)); | 1494 | IEEE80211_CONNECTION_IDLE_TIME)); |
1479 | out: | 1495 | out: |
1480 | ieee80211_run_deferred_scan(local); | ||
1481 | mutex_unlock(&local->mtx); | 1496 | mutex_unlock(&local->mtx); |
1482 | } | 1497 | } |
1483 | 1498 | ||
@@ -2408,7 +2423,11 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
2408 | net_dbg_ratelimited("%s: cancelling probereq poll due to a received beacon\n", | 2423 | net_dbg_ratelimited("%s: cancelling probereq poll due to a received beacon\n", |
2409 | sdata->name); | 2424 | sdata->name); |
2410 | #endif | 2425 | #endif |
2426 | mutex_lock(&local->mtx); | ||
2411 | ifmgd->flags &= ~IEEE80211_STA_BEACON_POLL; | 2427 | ifmgd->flags &= ~IEEE80211_STA_BEACON_POLL; |
2428 | ieee80211_run_deferred_scan(local); | ||
2429 | mutex_unlock(&local->mtx); | ||
2430 | |||
2412 | mutex_lock(&local->iflist_mtx); | 2431 | mutex_lock(&local->iflist_mtx); |
2413 | ieee80211_recalc_ps(local, -1); | 2432 | ieee80211_recalc_ps(local, -1); |
2414 | mutex_unlock(&local->iflist_mtx); | 2433 | mutex_unlock(&local->iflist_mtx); |
@@ -2595,9 +2614,6 @@ static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata, | |||
2595 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 2614 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
2596 | u8 frame_buf[DEAUTH_DISASSOC_LEN]; | 2615 | u8 frame_buf[DEAUTH_DISASSOC_LEN]; |
2597 | 2616 | ||
2598 | ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | | ||
2599 | IEEE80211_STA_BEACON_POLL); | ||
2600 | |||
2601 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, reason, | 2617 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, reason, |
2602 | false, frame_buf); | 2618 | false, frame_buf); |
2603 | mutex_unlock(&ifmgd->mtx); | 2619 | mutex_unlock(&ifmgd->mtx); |
@@ -2874,8 +2890,7 @@ static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata) | |||
2874 | u32 flags; | 2890 | u32 flags; |
2875 | 2891 | ||
2876 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { | 2892 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { |
2877 | sdata->u.mgd.flags &= ~(IEEE80211_STA_BEACON_POLL | | 2893 | __ieee80211_stop_poll(sdata); |
2878 | IEEE80211_STA_CONNECTION_POLL); | ||
2879 | 2894 | ||
2880 | /* let's probe the connection once */ | 2895 | /* let's probe the connection once */ |
2881 | flags = sdata->local->hw.flags; | 2896 | flags = sdata->local->hw.flags; |
@@ -2944,7 +2959,10 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata) | |||
2944 | if (test_and_clear_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running)) | 2959 | if (test_and_clear_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running)) |
2945 | add_timer(&ifmgd->chswitch_timer); | 2960 | add_timer(&ifmgd->chswitch_timer); |
2946 | ieee80211_sta_reset_beacon_monitor(sdata); | 2961 | ieee80211_sta_reset_beacon_monitor(sdata); |
2962 | |||
2963 | mutex_lock(&sdata->local->mtx); | ||
2947 | ieee80211_restart_sta_timer(sdata); | 2964 | ieee80211_restart_sta_timer(sdata); |
2965 | mutex_unlock(&sdata->local->mtx); | ||
2948 | } | 2966 | } |
2949 | #endif | 2967 | #endif |
2950 | 2968 | ||
@@ -3106,7 +3124,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, | |||
3106 | } | 3124 | } |
3107 | 3125 | ||
3108 | local->oper_channel = cbss->channel; | 3126 | local->oper_channel = cbss->channel; |
3109 | ieee80211_hw_config(local, 0); | 3127 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); |
3110 | 3128 | ||
3111 | if (!have_sta) { | 3129 | if (!have_sta) { |
3112 | u32 rates = 0, basic_rates = 0; | 3130 | u32 rates = 0, basic_rates = 0; |
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index f054e94901a2..935aa4b6deee 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c | |||
@@ -234,6 +234,22 @@ static void ieee80211_hw_roc_done(struct work_struct *work) | |||
234 | return; | 234 | return; |
235 | } | 235 | } |
236 | 236 | ||
237 | /* was never transmitted */ | ||
238 | if (local->hw_roc_skb) { | ||
239 | u64 cookie; | ||
240 | |||
241 | cookie = local->hw_roc_cookie ^ 2; | ||
242 | |||
243 | cfg80211_mgmt_tx_status(local->hw_roc_dev, cookie, | ||
244 | local->hw_roc_skb->data, | ||
245 | local->hw_roc_skb->len, false, | ||
246 | GFP_KERNEL); | ||
247 | |||
248 | kfree_skb(local->hw_roc_skb); | ||
249 | local->hw_roc_skb = NULL; | ||
250 | local->hw_roc_skb_for_status = NULL; | ||
251 | } | ||
252 | |||
237 | if (!local->hw_roc_for_tx) | 253 | if (!local->hw_roc_for_tx) |
238 | cfg80211_remain_on_channel_expired(local->hw_roc_dev, | 254 | cfg80211_remain_on_channel_expired(local->hw_roc_dev, |
239 | local->hw_roc_cookie, | 255 | local->hw_roc_cookie, |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index f5b1638fbf80..de455f8bbb91 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -378,7 +378,7 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU) | |||
378 | /* make the station visible */ | 378 | /* make the station visible */ |
379 | sta_info_hash_add(local, sta); | 379 | sta_info_hash_add(local, sta); |
380 | 380 | ||
381 | list_add(&sta->list, &local->sta_list); | 381 | list_add_rcu(&sta->list, &local->sta_list); |
382 | 382 | ||
383 | set_sta_flag(sta, WLAN_STA_INSERTED); | 383 | set_sta_flag(sta, WLAN_STA_INSERTED); |
384 | 384 | ||
@@ -688,7 +688,7 @@ int __must_check __sta_info_destroy(struct sta_info *sta) | |||
688 | if (ret) | 688 | if (ret) |
689 | return ret; | 689 | return ret; |
690 | 690 | ||
691 | list_del(&sta->list); | 691 | list_del_rcu(&sta->list); |
692 | 692 | ||
693 | mutex_lock(&local->key_mtx); | 693 | mutex_lock(&local->key_mtx); |
694 | for (i = 0; i < NUM_DEFAULT_KEYS; i++) | 694 | for (i = 0; i < NUM_DEFAULT_KEYS; i++) |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 3bb24a121c95..a470e1123a55 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -271,6 +271,9 @@ struct sta_ampdu_mlme { | |||
271 | * @plink_timer: peer link watch timer | 271 | * @plink_timer: peer link watch timer |
272 | * @plink_timer_was_running: used by suspend/resume to restore timers | 272 | * @plink_timer_was_running: used by suspend/resume to restore timers |
273 | * @t_offset: timing offset relative to this host | 273 | * @t_offset: timing offset relative to this host |
274 | * @t_offset_setpoint: reference timing offset of this sta to be used when | ||
275 | * calculating clockdrift | ||
276 | * @ch_type: peer's channel type | ||
274 | * @debugfs: debug filesystem info | 277 | * @debugfs: debug filesystem info |
275 | * @dead: set to true when sta is unlinked | 278 | * @dead: set to true when sta is unlinked |
276 | * @uploaded: set to true when sta is uploaded to the driver | 279 | * @uploaded: set to true when sta is uploaded to the driver |
@@ -278,6 +281,8 @@ struct sta_ampdu_mlme { | |||
278 | * @sta: station information we share with the driver | 281 | * @sta: station information we share with the driver |
279 | * @sta_state: duplicates information about station state (for debug) | 282 | * @sta_state: duplicates information about station state (for debug) |
280 | * @beacon_loss_count: number of times beacon loss has triggered | 283 | * @beacon_loss_count: number of times beacon loss has triggered |
284 | * @supports_40mhz: tracks whether the station advertised 40 MHz support | ||
285 | * as we overwrite its HT parameters with the currently used value | ||
281 | */ | 286 | */ |
282 | struct sta_info { | 287 | struct sta_info { |
283 | /* General information, mostly static */ | 288 | /* General information, mostly static */ |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 847215bb2a6f..e453212fa17f 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1737,7 +1737,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1737 | __le16 fc; | 1737 | __le16 fc; |
1738 | struct ieee80211_hdr hdr; | 1738 | struct ieee80211_hdr hdr; |
1739 | struct ieee80211s_hdr mesh_hdr __maybe_unused; | 1739 | struct ieee80211s_hdr mesh_hdr __maybe_unused; |
1740 | struct mesh_path __maybe_unused *mppath = NULL; | 1740 | struct mesh_path __maybe_unused *mppath = NULL, *mpath = NULL; |
1741 | const u8 *encaps_data; | 1741 | const u8 *encaps_data; |
1742 | int encaps_len, skip_header_bytes; | 1742 | int encaps_len, skip_header_bytes; |
1743 | int nh_pos, h_pos; | 1743 | int nh_pos, h_pos; |
@@ -1803,8 +1803,11 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1803 | goto fail; | 1803 | goto fail; |
1804 | } | 1804 | } |
1805 | rcu_read_lock(); | 1805 | rcu_read_lock(); |
1806 | if (!is_multicast_ether_addr(skb->data)) | 1806 | if (!is_multicast_ether_addr(skb->data)) { |
1807 | mppath = mpp_path_lookup(skb->data, sdata); | 1807 | mpath = mesh_path_lookup(skb->data, sdata); |
1808 | if (!mpath) | ||
1809 | mppath = mpp_path_lookup(skb->data, sdata); | ||
1810 | } | ||
1808 | 1811 | ||
1809 | /* | 1812 | /* |
1810 | * Use address extension if it is a packet from | 1813 | * Use address extension if it is a packet from |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index a44c6807df01..8dd4712620ff 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -1271,7 +1271,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1271 | enum ieee80211_sta_state state; | 1271 | enum ieee80211_sta_state state; |
1272 | 1272 | ||
1273 | for (state = IEEE80211_STA_NOTEXIST; | 1273 | for (state = IEEE80211_STA_NOTEXIST; |
1274 | state < sta->sta_state - 1; state++) | 1274 | state < sta->sta_state; state++) |
1275 | WARN_ON(drv_sta_state(local, sta->sdata, sta, | 1275 | WARN_ON(drv_sta_state(local, sta->sdata, sta, |
1276 | state, state + 1)); | 1276 | state, state + 1)); |
1277 | } | 1277 | } |