diff options
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/debugfs_netdev.c | 10 | ||||
-rw-r--r-- | net/mac80211/main.c | 4 | ||||
-rw-r--r-- | net/mac80211/mesh.c | 3 | ||||
-rw-r--r-- | net/mac80211/mesh_hwmp.c | 4 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 13 | ||||
-rw-r--r-- | net/mac80211/rx.c | 5 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 21 | ||||
-rw-r--r-- | net/mac80211/tx.c | 6 | ||||
-rw-r--r-- | net/mac80211/util.c | 18 |
9 files changed, 56 insertions, 28 deletions
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index ee61a9f6fabc..623e6644b80c 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c | |||
@@ -48,20 +48,24 @@ static ssize_t ieee80211_if_write( | |||
48 | ssize_t (*write)(struct ieee80211_sub_if_data *, const char *, int)) | 48 | ssize_t (*write)(struct ieee80211_sub_if_data *, const char *, int)) |
49 | { | 49 | { |
50 | u8 *buf; | 50 | u8 *buf; |
51 | ssize_t ret = -ENODEV; | 51 | ssize_t ret; |
52 | 52 | ||
53 | buf = kzalloc(count, GFP_KERNEL); | 53 | buf = kmalloc(count, GFP_KERNEL); |
54 | if (!buf) | 54 | if (!buf) |
55 | return -ENOMEM; | 55 | return -ENOMEM; |
56 | 56 | ||
57 | ret = -EFAULT; | ||
57 | if (copy_from_user(buf, userbuf, count)) | 58 | if (copy_from_user(buf, userbuf, count)) |
58 | return -EFAULT; | 59 | goto freebuf; |
59 | 60 | ||
61 | ret = -ENODEV; | ||
60 | rtnl_lock(); | 62 | rtnl_lock(); |
61 | if (sdata->dev->reg_state == NETREG_REGISTERED) | 63 | if (sdata->dev->reg_state == NETREG_REGISTERED) |
62 | ret = (*write)(sdata, buf, count); | 64 | ret = (*write)(sdata, buf, count); |
63 | rtnl_unlock(); | 65 | rtnl_unlock(); |
64 | 66 | ||
67 | freebuf: | ||
68 | kfree(buf); | ||
65 | return ret; | 69 | return ret; |
66 | } | 70 | } |
67 | 71 | ||
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 06c33b68d8e5..b887e484ae04 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -225,11 +225,11 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | |||
225 | switch (sdata->vif.type) { | 225 | switch (sdata->vif.type) { |
226 | case NL80211_IFTYPE_AP: | 226 | case NL80211_IFTYPE_AP: |
227 | sdata->vif.bss_conf.enable_beacon = | 227 | sdata->vif.bss_conf.enable_beacon = |
228 | !!rcu_dereference(sdata->u.ap.beacon); | 228 | !!sdata->u.ap.beacon; |
229 | break; | 229 | break; |
230 | case NL80211_IFTYPE_ADHOC: | 230 | case NL80211_IFTYPE_ADHOC: |
231 | sdata->vif.bss_conf.enable_beacon = | 231 | sdata->vif.bss_conf.enable_beacon = |
232 | !!rcu_dereference(sdata->u.ibss.presp); | 232 | !!sdata->u.ibss.presp; |
233 | break; | 233 | break; |
234 | case NL80211_IFTYPE_MESH_POINT: | 234 | case NL80211_IFTYPE_MESH_POINT: |
235 | sdata->vif.bss_conf.enable_beacon = true; | 235 | sdata->vif.bss_conf.enable_beacon = true; |
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 61080c5fad50..7a6bebce7f2f 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -749,9 +749,6 @@ ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) | |||
749 | 749 | ||
750 | switch (fc & IEEE80211_FCTL_STYPE) { | 750 | switch (fc & IEEE80211_FCTL_STYPE) { |
751 | case IEEE80211_STYPE_ACTION: | 751 | case IEEE80211_STYPE_ACTION: |
752 | if (skb->len < IEEE80211_MIN_ACTION_SIZE) | ||
753 | return RX_DROP_MONITOR; | ||
754 | /* fall through */ | ||
755 | case IEEE80211_STYPE_PROBE_RESP: | 752 | case IEEE80211_STYPE_PROBE_RESP: |
756 | case IEEE80211_STYPE_BEACON: | 753 | case IEEE80211_STYPE_BEACON: |
757 | skb_queue_tail(&ifmsh->skb_queue, skb); | 754 | skb_queue_tail(&ifmsh->skb_queue, skb); |
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index ce84237ebad3..ccff6133e19a 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c | |||
@@ -391,7 +391,7 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata, | |||
391 | if (SN_GT(mpath->sn, orig_sn) || | 391 | if (SN_GT(mpath->sn, orig_sn) || |
392 | (mpath->sn == orig_sn && | 392 | (mpath->sn == orig_sn && |
393 | action == MPATH_PREQ && | 393 | action == MPATH_PREQ && |
394 | new_metric > mpath->metric)) { | 394 | new_metric >= mpath->metric)) { |
395 | process = false; | 395 | process = false; |
396 | fresh_info = false; | 396 | fresh_info = false; |
397 | } | 397 | } |
@@ -611,7 +611,7 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata, | |||
611 | 611 | ||
612 | mesh_path_sel_frame_tx(MPATH_PREP, flags, orig_addr, | 612 | mesh_path_sel_frame_tx(MPATH_PREP, flags, orig_addr, |
613 | cpu_to_le32(orig_sn), 0, target_addr, | 613 | cpu_to_le32(orig_sn), 0, target_addr, |
614 | cpu_to_le32(target_sn), mpath->next_hop->sta.addr, hopcount, | 614 | cpu_to_le32(target_sn), next_hop, hopcount, |
615 | ttl, cpu_to_le32(lifetime), cpu_to_le32(metric), | 615 | ttl, cpu_to_le32(lifetime), cpu_to_le32(metric), |
616 | 0, sdata); | 616 | 0, sdata); |
617 | rcu_read_unlock(); | 617 | rcu_read_unlock(); |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 4c189d0be4a3..461167dfa42c 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -447,10 +447,12 @@ static void ieee80211_enable_ps(struct ieee80211_local *local, | |||
447 | if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) | 447 | if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) |
448 | ieee80211_send_nullfunc(local, sdata, 1); | 448 | ieee80211_send_nullfunc(local, sdata, 1); |
449 | 449 | ||
450 | if (!(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) { | 450 | if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) && |
451 | conf->flags |= IEEE80211_CONF_PS; | 451 | (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) |
452 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); | 452 | return; |
453 | } | 453 | |
454 | conf->flags |= IEEE80211_CONF_PS; | ||
455 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); | ||
454 | } | 456 | } |
455 | } | 457 | } |
456 | 458 | ||
@@ -569,7 +571,8 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work) | |||
569 | (!(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED))) | 571 | (!(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED))) |
570 | ieee80211_send_nullfunc(local, sdata, 1); | 572 | ieee80211_send_nullfunc(local, sdata, 1); |
571 | 573 | ||
572 | if (!(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) || | 574 | if (!((local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) && |
575 | (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)) || | ||
573 | (ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED)) { | 576 | (ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED)) { |
574 | ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED; | 577 | ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED; |
575 | local->hw.conf.flags |= IEEE80211_CONF_PS; | 578 | local->hw.conf.flags |= IEEE80211_CONF_PS; |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index a33f865807f9..c0ad7e879a6e 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -1994,6 +1994,11 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
1994 | goto handled; | 1994 | goto handled; |
1995 | } | 1995 | } |
1996 | break; | 1996 | break; |
1997 | case MESH_PLINK_CATEGORY: | ||
1998 | case MESH_PATH_SEL_CATEGORY: | ||
1999 | if (ieee80211_vif_is_mesh(&sdata->vif)) | ||
2000 | return ieee80211_mesh_rx_mgmt(sdata, rx->skb); | ||
2001 | break; | ||
1997 | } | 2002 | } |
1998 | 2003 | ||
1999 | /* | 2004 | /* |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 5bf044b92dca..4de987cbda1c 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -93,12 +93,18 @@ struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata, | |||
93 | struct ieee80211_local *local = sdata->local; | 93 | struct ieee80211_local *local = sdata->local; |
94 | struct sta_info *sta; | 94 | struct sta_info *sta; |
95 | 95 | ||
96 | sta = rcu_dereference(local->sta_hash[STA_HASH(addr)]); | 96 | sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)], |
97 | rcu_read_lock_held() || | ||
98 | lockdep_is_held(&local->sta_lock) || | ||
99 | lockdep_is_held(&local->sta_mtx)); | ||
97 | while (sta) { | 100 | while (sta) { |
98 | if (sta->sdata == sdata && | 101 | if (sta->sdata == sdata && |
99 | memcmp(sta->sta.addr, addr, ETH_ALEN) == 0) | 102 | memcmp(sta->sta.addr, addr, ETH_ALEN) == 0) |
100 | break; | 103 | break; |
101 | sta = rcu_dereference(sta->hnext); | 104 | sta = rcu_dereference_check(sta->hnext, |
105 | rcu_read_lock_held() || | ||
106 | lockdep_is_held(&local->sta_lock) || | ||
107 | lockdep_is_held(&local->sta_mtx)); | ||
102 | } | 108 | } |
103 | return sta; | 109 | return sta; |
104 | } | 110 | } |
@@ -113,13 +119,19 @@ struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata, | |||
113 | struct ieee80211_local *local = sdata->local; | 119 | struct ieee80211_local *local = sdata->local; |
114 | struct sta_info *sta; | 120 | struct sta_info *sta; |
115 | 121 | ||
116 | sta = rcu_dereference(local->sta_hash[STA_HASH(addr)]); | 122 | sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)], |
123 | rcu_read_lock_held() || | ||
124 | lockdep_is_held(&local->sta_lock) || | ||
125 | lockdep_is_held(&local->sta_mtx)); | ||
117 | while (sta) { | 126 | while (sta) { |
118 | if ((sta->sdata == sdata || | 127 | if ((sta->sdata == sdata || |
119 | sta->sdata->bss == sdata->bss) && | 128 | sta->sdata->bss == sdata->bss) && |
120 | memcmp(sta->sta.addr, addr, ETH_ALEN) == 0) | 129 | memcmp(sta->sta.addr, addr, ETH_ALEN) == 0) |
121 | break; | 130 | break; |
122 | sta = rcu_dereference(sta->hnext); | 131 | sta = rcu_dereference_check(sta->hnext, |
132 | rcu_read_lock_held() || | ||
133 | lockdep_is_held(&local->sta_lock) || | ||
134 | lockdep_is_held(&local->sta_mtx)); | ||
123 | } | 135 | } |
124 | return sta; | 136 | return sta; |
125 | } | 137 | } |
@@ -431,6 +443,7 @@ int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU) | |||
431 | /* check if STA exists already */ | 443 | /* check if STA exists already */ |
432 | if (sta_info_get_bss(sdata, sta->sta.addr)) { | 444 | if (sta_info_get_bss(sdata, sta->sta.addr)) { |
433 | spin_unlock_irqrestore(&local->sta_lock, flags); | 445 | spin_unlock_irqrestore(&local->sta_lock, flags); |
446 | mutex_unlock(&local->sta_mtx); | ||
434 | rcu_read_lock(); | 447 | rcu_read_lock(); |
435 | err = -EEXIST; | 448 | err = -EEXIST; |
436 | goto out_free; | 449 | goto out_free; |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index f7209d691c35..2cb77267f733 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1992,6 +1992,7 @@ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local, | |||
1992 | void ieee80211_tx_pending(unsigned long data) | 1992 | void ieee80211_tx_pending(unsigned long data) |
1993 | { | 1993 | { |
1994 | struct ieee80211_local *local = (struct ieee80211_local *)data; | 1994 | struct ieee80211_local *local = (struct ieee80211_local *)data; |
1995 | struct ieee80211_sub_if_data *sdata; | ||
1995 | unsigned long flags; | 1996 | unsigned long flags; |
1996 | int i; | 1997 | int i; |
1997 | bool txok; | 1998 | bool txok; |
@@ -2028,6 +2029,11 @@ void ieee80211_tx_pending(unsigned long data) | |||
2028 | if (!txok) | 2029 | if (!txok) |
2029 | break; | 2030 | break; |
2030 | } | 2031 | } |
2032 | |||
2033 | if (skb_queue_empty(&local->pending[i])) | ||
2034 | list_for_each_entry_rcu(sdata, &local->interfaces, list) | ||
2035 | netif_tx_wake_queue( | ||
2036 | netdev_get_tx_queue(sdata->dev, i)); | ||
2031 | } | 2037 | } |
2032 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | 2038 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); |
2033 | 2039 | ||
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 7614821caed5..ad9009f717ed 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -279,13 +279,13 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue, | |||
279 | /* someone still has this queue stopped */ | 279 | /* someone still has this queue stopped */ |
280 | return; | 280 | return; |
281 | 281 | ||
282 | if (!skb_queue_empty(&local->pending[queue])) | 282 | if (skb_queue_empty(&local->pending[queue])) { |
283 | rcu_read_lock(); | ||
284 | list_for_each_entry_rcu(sdata, &local->interfaces, list) | ||
285 | netif_tx_wake_queue(netdev_get_tx_queue(sdata->dev, queue)); | ||
286 | rcu_read_unlock(); | ||
287 | } else | ||
283 | tasklet_schedule(&local->tx_pending_tasklet); | 288 | tasklet_schedule(&local->tx_pending_tasklet); |
284 | |||
285 | rcu_read_lock(); | ||
286 | list_for_each_entry_rcu(sdata, &local->interfaces, list) | ||
287 | netif_tx_wake_queue(netdev_get_tx_queue(sdata->dev, queue)); | ||
288 | rcu_read_unlock(); | ||
289 | } | 289 | } |
290 | 290 | ||
291 | void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, | 291 | void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, |
@@ -1102,9 +1102,9 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1102 | */ | 1102 | */ |
1103 | res = drv_start(local); | 1103 | res = drv_start(local); |
1104 | if (res) { | 1104 | if (res) { |
1105 | WARN(local->suspended, "Harware became unavailable " | 1105 | WARN(local->suspended, "Hardware became unavailable " |
1106 | "upon resume. This is could be a software issue" | 1106 | "upon resume. This could be a software issue " |
1107 | "prior to suspend or a hardware issue\n"); | 1107 | "prior to suspend or a hardware issue.\n"); |
1108 | return res; | 1108 | return res; |
1109 | } | 1109 | } |
1110 | 1110 | ||