diff options
Diffstat (limited to 'net/mac80211')
| -rw-r--r-- | net/mac80211/Kconfig | 1 | ||||
| -rw-r--r-- | net/mac80211/mesh_pathtbl.c | 11 | ||||
| -rw-r--r-- | net/mac80211/mlme.c | 2 | ||||
| -rw-r--r-- | net/mac80211/pm.c | 24 | ||||
| -rw-r--r-- | net/mac80211/rx.c | 12 | ||||
| -rw-r--r-- | net/mac80211/tx.c | 2 |
6 files changed, 38 insertions, 14 deletions
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig index ba2643a43c73..7836ee928983 100644 --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig | |||
| @@ -83,6 +83,7 @@ endmenu | |||
| 83 | config MAC80211_MESH | 83 | config MAC80211_MESH |
| 84 | bool "Enable mac80211 mesh networking (pre-802.11s) support" | 84 | bool "Enable mac80211 mesh networking (pre-802.11s) support" |
| 85 | depends on MAC80211 && EXPERIMENTAL | 85 | depends on MAC80211 && EXPERIMENTAL |
| 86 | depends on BROKEN | ||
| 86 | ---help--- | 87 | ---help--- |
| 87 | This options enables support of Draft 802.11s mesh networking. | 88 | This options enables support of Draft 802.11s mesh networking. |
| 88 | The implementation is based on Draft 1.08 of the Mesh Networking | 89 | The implementation is based on Draft 1.08 of the Mesh Networking |
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 3c72557df45a..479597e88583 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c | |||
| @@ -175,6 +175,8 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata) | |||
| 175 | int err = 0; | 175 | int err = 0; |
| 176 | u32 hash_idx; | 176 | u32 hash_idx; |
| 177 | 177 | ||
| 178 | might_sleep(); | ||
| 179 | |||
| 178 | if (memcmp(dst, sdata->dev->dev_addr, ETH_ALEN) == 0) | 180 | if (memcmp(dst, sdata->dev->dev_addr, ETH_ALEN) == 0) |
| 179 | /* never add ourselves as neighbours */ | 181 | /* never add ourselves as neighbours */ |
| 180 | return -ENOTSUPP; | 182 | return -ENOTSUPP; |
| @@ -265,6 +267,7 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata) | |||
| 265 | int err = 0; | 267 | int err = 0; |
| 266 | u32 hash_idx; | 268 | u32 hash_idx; |
| 267 | 269 | ||
| 270 | might_sleep(); | ||
| 268 | 271 | ||
| 269 | if (memcmp(dst, sdata->dev->dev_addr, ETH_ALEN) == 0) | 272 | if (memcmp(dst, sdata->dev->dev_addr, ETH_ALEN) == 0) |
| 270 | /* never add ourselves as neighbours */ | 273 | /* never add ourselves as neighbours */ |
| @@ -491,8 +494,10 @@ void mesh_path_tx_pending(struct mesh_path *mpath) | |||
| 491 | * @skb: frame to discard | 494 | * @skb: frame to discard |
| 492 | * @sdata: network subif the frame was to be sent through | 495 | * @sdata: network subif the frame was to be sent through |
| 493 | * | 496 | * |
| 494 | * If the frame was beign forwarded from another MP, a PERR frame will be sent | 497 | * If the frame was being forwarded from another MP, a PERR frame will be sent |
| 495 | * to the precursor. | 498 | * to the precursor. The precursor's address (i.e. the previous hop) was saved |
| 499 | * in addr1 of the frame-to-be-forwarded, and would only be overwritten once | ||
| 500 | * the destination is successfully resolved. | ||
| 496 | * | 501 | * |
| 497 | * Locking: the function must me called within a rcu_read_lock region | 502 | * Locking: the function must me called within a rcu_read_lock region |
| 498 | */ | 503 | */ |
| @@ -507,7 +512,7 @@ void mesh_path_discard_frame(struct sk_buff *skb, | |||
| 507 | u8 *ra, *da; | 512 | u8 *ra, *da; |
| 508 | 513 | ||
| 509 | da = hdr->addr3; | 514 | da = hdr->addr3; |
| 510 | ra = hdr->addr2; | 515 | ra = hdr->addr1; |
| 511 | mpath = mesh_path_lookup(da, sdata); | 516 | mpath = mesh_path_lookup(da, sdata); |
| 512 | if (mpath) | 517 | if (mpath) |
| 513 | dsn = ++mpath->dsn; | 518 | dsn = ++mpath->dsn; |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index aca22b00b6a3..07e7e41816be 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
| @@ -721,7 +721,7 @@ void ieee80211_dynamic_ps_timer(unsigned long data) | |||
| 721 | { | 721 | { |
| 722 | struct ieee80211_local *local = (void *) data; | 722 | struct ieee80211_local *local = (void *) data; |
| 723 | 723 | ||
| 724 | if (local->quiescing) | 724 | if (local->quiescing || local->suspended) |
| 725 | return; | 725 | return; |
| 726 | 726 | ||
| 727 | queue_work(local->hw.workqueue, &local->dynamic_ps_enable_work); | 727 | queue_work(local->hw.workqueue, &local->dynamic_ps_enable_work); |
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index 7a549f9deb96..5e3d476972f9 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c | |||
| @@ -55,15 +55,6 @@ int __ieee80211_suspend(struct ieee80211_hw *hw) | |||
| 55 | 55 | ||
| 56 | rcu_read_unlock(); | 56 | rcu_read_unlock(); |
| 57 | 57 | ||
| 58 | /* flush again, in case driver queued work */ | ||
| 59 | flush_workqueue(local->hw.workqueue); | ||
| 60 | |||
| 61 | /* stop hardware - this must stop RX */ | ||
| 62 | if (local->open_count) { | ||
| 63 | ieee80211_led_radio(local, false); | ||
| 64 | drv_stop(local); | ||
| 65 | } | ||
| 66 | |||
| 67 | /* remove STAs */ | 58 | /* remove STAs */ |
| 68 | spin_lock_irqsave(&local->sta_lock, flags); | 59 | spin_lock_irqsave(&local->sta_lock, flags); |
| 69 | list_for_each_entry(sta, &local->sta_list, list) { | 60 | list_for_each_entry(sta, &local->sta_list, list) { |
| @@ -111,7 +102,22 @@ int __ieee80211_suspend(struct ieee80211_hw *hw) | |||
| 111 | drv_remove_interface(local, &conf); | 102 | drv_remove_interface(local, &conf); |
| 112 | } | 103 | } |
| 113 | 104 | ||
| 105 | /* stop hardware - this must stop RX */ | ||
| 106 | if (local->open_count) { | ||
| 107 | ieee80211_led_radio(local, false); | ||
| 108 | drv_stop(local); | ||
| 109 | } | ||
| 110 | |||
| 111 | /* | ||
| 112 | * flush again, in case driver queued work -- it | ||
| 113 | * shouldn't be doing (or cancel everything in the | ||
| 114 | * stop callback) that but better safe than sorry. | ||
| 115 | */ | ||
| 116 | flush_workqueue(local->hw.workqueue); | ||
| 117 | |||
| 114 | local->suspended = true; | 118 | local->suspended = true; |
| 119 | /* need suspended to be visible before quiescing is false */ | ||
| 120 | barrier(); | ||
| 115 | local->quiescing = false; | 121 | local->quiescing = false; |
| 116 | 122 | ||
| 117 | return 0; | 123 | return 0; |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index de5bba7f910a..0936fc24942d 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
| @@ -2453,6 +2453,18 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
| 2453 | return; | 2453 | return; |
| 2454 | } | 2454 | } |
| 2455 | 2455 | ||
| 2456 | /* | ||
| 2457 | * If we're suspending, it is possible although not too likely | ||
| 2458 | * that we'd be receiving frames after having already partially | ||
| 2459 | * quiesced the stack. We can't process such frames then since | ||
| 2460 | * that might, for example, cause stations to be added or other | ||
| 2461 | * driver callbacks be invoked. | ||
| 2462 | */ | ||
| 2463 | if (unlikely(local->quiescing || local->suspended)) { | ||
| 2464 | kfree_skb(skb); | ||
| 2465 | return; | ||
| 2466 | } | ||
| 2467 | |||
| 2456 | if (status->flag & RX_FLAG_HT) { | 2468 | if (status->flag & RX_FLAG_HT) { |
| 2457 | /* rate_idx is MCS index */ | 2469 | /* rate_idx is MCS index */ |
| 2458 | if (WARN_ON(status->rate_idx < 0 || | 2470 | if (WARN_ON(status->rate_idx < 0 || |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index d238a8939a09..3a8922cd1038 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
| @@ -1455,7 +1455,7 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 1455 | monitor_iface = UNKNOWN_ADDRESS; | 1455 | monitor_iface = UNKNOWN_ADDRESS; |
| 1456 | 1456 | ||
| 1457 | len_rthdr = ieee80211_get_radiotap_len(skb->data); | 1457 | len_rthdr = ieee80211_get_radiotap_len(skb->data); |
| 1458 | hdr = (struct ieee80211_hdr *)skb->data + len_rthdr; | 1458 | hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr); |
| 1459 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 1459 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
| 1460 | 1460 | ||
| 1461 | /* check the header is complete in the frame */ | 1461 | /* check the header is complete in the frame */ |
