diff options
author | David S. Miller <davem@davemloft.net> | 2008-05-15 03:52:37 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-05-15 03:52:37 -0400 |
commit | f42a44494bcdf03fc851c03d438464d59c0ceaf5 (patch) | |
tree | 986ea7b54e9fc79a64863fd7e92eabd99ffd37a3 /net | |
parent | 63fe46da9c380b3f2bbdf3765044649517cc717c (diff) | |
parent | ef85ad541f9a6ccd3f89ec73f92b2d6f45a9d3e8 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'net')
-rw-r--r-- | net/ieee80211/ieee80211_rx.c | 2 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 2 | ||||
-rw-r--r-- | net/mac80211/debugfs_sta.c | 17 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 6 | ||||
-rw-r--r-- | net/mac80211/iface.c | 3 | ||||
-rw-r--r-- | net/mac80211/key.c | 4 | ||||
-rw-r--r-- | net/mac80211/main.c | 41 | ||||
-rw-r--r-- | net/mac80211/mesh_hwmp.c | 2 | ||||
-rw-r--r-- | net/mac80211/mesh_plink.c | 88 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 71 | ||||
-rw-r--r-- | net/mac80211/rx.c | 214 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 14 | ||||
-rw-r--r-- | net/mac80211/sta_info.h | 74 | ||||
-rw-r--r-- | net/mac80211/tkip.c | 145 | ||||
-rw-r--r-- | net/mac80211/tx.c | 30 | ||||
-rw-r--r-- | net/mac80211/wext.c | 28 | ||||
-rw-r--r-- | net/wireless/core.c | 33 | ||||
-rw-r--r-- | net/wireless/radiotap.c | 16 |
18 files changed, 455 insertions, 335 deletions
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c index 200ee1e63728..69dbc342a464 100644 --- a/net/ieee80211/ieee80211_rx.c +++ b/net/ieee80211/ieee80211_rx.c | |||
@@ -391,7 +391,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, | |||
391 | 391 | ||
392 | wstats.updated = 0; | 392 | wstats.updated = 0; |
393 | if (rx_stats->mask & IEEE80211_STATMASK_RSSI) { | 393 | if (rx_stats->mask & IEEE80211_STATMASK_RSSI) { |
394 | wstats.level = rx_stats->rssi; | 394 | wstats.level = rx_stats->signal; |
395 | wstats.updated |= IW_QUAL_LEVEL_UPDATED; | 395 | wstats.updated |= IW_QUAL_LEVEL_UPDATED; |
396 | } else | 396 | } else |
397 | wstats.updated |= IW_QUAL_LEVEL_INVALID; | 397 | wstats.updated |= IW_QUAL_LEVEL_INVALID; |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 699d97b8de5e..3cef80dcd0e5 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -602,6 +602,7 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
602 | */ | 602 | */ |
603 | 603 | ||
604 | if (params->station_flags & STATION_FLAG_CHANGED) { | 604 | if (params->station_flags & STATION_FLAG_CHANGED) { |
605 | spin_lock_bh(&sta->lock); | ||
605 | sta->flags &= ~WLAN_STA_AUTHORIZED; | 606 | sta->flags &= ~WLAN_STA_AUTHORIZED; |
606 | if (params->station_flags & STATION_FLAG_AUTHORIZED) | 607 | if (params->station_flags & STATION_FLAG_AUTHORIZED) |
607 | sta->flags |= WLAN_STA_AUTHORIZED; | 608 | sta->flags |= WLAN_STA_AUTHORIZED; |
@@ -613,6 +614,7 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
613 | sta->flags &= ~WLAN_STA_WME; | 614 | sta->flags &= ~WLAN_STA_WME; |
614 | if (params->station_flags & STATION_FLAG_WME) | 615 | if (params->station_flags & STATION_FLAG_WME) |
615 | sta->flags |= WLAN_STA_WME; | 616 | sta->flags |= WLAN_STA_WME; |
617 | spin_unlock_bh(&sta->lock); | ||
616 | } | 618 | } |
617 | 619 | ||
618 | /* | 620 | /* |
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 676a93202ff9..a2cc0284c9d0 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c | |||
@@ -63,8 +63,8 @@ STA_FILE(tx_fragments, tx_fragments, LU); | |||
63 | STA_FILE(tx_filtered, tx_filtered_count, LU); | 63 | STA_FILE(tx_filtered, tx_filtered_count, LU); |
64 | STA_FILE(tx_retry_failed, tx_retry_failed, LU); | 64 | STA_FILE(tx_retry_failed, tx_retry_failed, LU); |
65 | STA_FILE(tx_retry_count, tx_retry_count, LU); | 65 | STA_FILE(tx_retry_count, tx_retry_count, LU); |
66 | STA_FILE(last_rssi, last_rssi, D); | ||
67 | STA_FILE(last_signal, last_signal, D); | 66 | STA_FILE(last_signal, last_signal, D); |
67 | STA_FILE(last_qual, last_qual, D); | ||
68 | STA_FILE(last_noise, last_noise, D); | 68 | STA_FILE(last_noise, last_noise, D); |
69 | STA_FILE(channel_use, channel_use, D); | 69 | STA_FILE(channel_use, channel_use, D); |
70 | STA_FILE(wep_weak_iv_count, wep_weak_iv_count, LU); | 70 | STA_FILE(wep_weak_iv_count, wep_weak_iv_count, LU); |
@@ -74,14 +74,15 @@ static ssize_t sta_flags_read(struct file *file, char __user *userbuf, | |||
74 | { | 74 | { |
75 | char buf[100]; | 75 | char buf[100]; |
76 | struct sta_info *sta = file->private_data; | 76 | struct sta_info *sta = file->private_data; |
77 | u32 staflags = get_sta_flags(sta); | ||
77 | int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s", | 78 | int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s", |
78 | sta->flags & WLAN_STA_AUTH ? "AUTH\n" : "", | 79 | staflags & WLAN_STA_AUTH ? "AUTH\n" : "", |
79 | sta->flags & WLAN_STA_ASSOC ? "ASSOC\n" : "", | 80 | staflags & WLAN_STA_ASSOC ? "ASSOC\n" : "", |
80 | sta->flags & WLAN_STA_PS ? "PS\n" : "", | 81 | staflags & WLAN_STA_PS ? "PS\n" : "", |
81 | sta->flags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "", | 82 | staflags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "", |
82 | sta->flags & WLAN_STA_SHORT_PREAMBLE ? "SHORT PREAMBLE\n" : "", | 83 | staflags & WLAN_STA_SHORT_PREAMBLE ? "SHORT PREAMBLE\n" : "", |
83 | sta->flags & WLAN_STA_WME ? "WME\n" : "", | 84 | staflags & WLAN_STA_WME ? "WME\n" : "", |
84 | sta->flags & WLAN_STA_WDS ? "WDS\n" : ""); | 85 | staflags & WLAN_STA_WDS ? "WDS\n" : ""); |
85 | return simple_read_from_buffer(userbuf, count, ppos, buf, res); | 86 | return simple_read_from_buffer(userbuf, count, ppos, buf, res); |
86 | } | 87 | } |
87 | STA_OPS(flags); | 88 | STA_OPS(flags); |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index d82ed20a344c..ed0d9b35ae6f 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -82,7 +82,7 @@ struct ieee80211_sta_bss { | |||
82 | u16 capability; /* host byte order */ | 82 | u16 capability; /* host byte order */ |
83 | enum ieee80211_band band; | 83 | enum ieee80211_band band; |
84 | int freq; | 84 | int freq; |
85 | int rssi, signal, noise; | 85 | int signal, noise, qual; |
86 | u8 *wpa_ie; | 86 | u8 *wpa_ie; |
87 | size_t wpa_ie_len; | 87 | size_t wpa_ie_len; |
88 | u8 *rsn_ie; | 88 | u8 *rsn_ie; |
@@ -610,8 +610,8 @@ struct ieee80211_local { | |||
610 | struct sta_info *sta_hash[STA_HASH_SIZE]; | 610 | struct sta_info *sta_hash[STA_HASH_SIZE]; |
611 | struct timer_list sta_cleanup; | 611 | struct timer_list sta_cleanup; |
612 | 612 | ||
613 | unsigned long state[IEEE80211_MAX_AMPDU_QUEUES + IEEE80211_MAX_AMPDU_QUEUES]; | 613 | unsigned long state[IEEE80211_MAX_QUEUES + IEEE80211_MAX_AMPDU_QUEUES]; |
614 | struct ieee80211_tx_stored_packet pending_packet[IEEE80211_MAX_AMPDU_QUEUES + IEEE80211_MAX_AMPDU_QUEUES]; | 614 | struct ieee80211_tx_stored_packet pending_packet[IEEE80211_MAX_QUEUES + IEEE80211_MAX_AMPDU_QUEUES]; |
615 | struct tasklet_struct tx_pending_tasklet; | 615 | struct tasklet_struct tx_pending_tasklet; |
616 | 616 | ||
617 | /* number of interfaces with corresponding IFF_ flags */ | 617 | /* number of interfaces with corresponding IFF_ flags */ |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 4a8062f8b1cc..3c64e42eb12e 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -166,9 +166,10 @@ void ieee80211_if_set_type(struct net_device *dev, int type) | |||
166 | ifsta->auth_algs = IEEE80211_AUTH_ALG_OPEN | | 166 | ifsta->auth_algs = IEEE80211_AUTH_ALG_OPEN | |
167 | IEEE80211_AUTH_ALG_SHARED_KEY; | 167 | IEEE80211_AUTH_ALG_SHARED_KEY; |
168 | ifsta->flags |= IEEE80211_STA_CREATE_IBSS | | 168 | ifsta->flags |= IEEE80211_STA_CREATE_IBSS | |
169 | IEEE80211_STA_WMM_ENABLED | | ||
170 | IEEE80211_STA_AUTO_BSSID_SEL | | 169 | IEEE80211_STA_AUTO_BSSID_SEL | |
171 | IEEE80211_STA_AUTO_CHANNEL_SEL; | 170 | IEEE80211_STA_AUTO_CHANNEL_SEL; |
171 | if (sdata->local->hw.queues >= 4) | ||
172 | ifsta->flags |= IEEE80211_STA_WMM_ENABLED; | ||
172 | 173 | ||
173 | msdata = IEEE80211_DEV_TO_SUB_IF(sdata->local->mdev); | 174 | msdata = IEEE80211_DEV_TO_SUB_IF(sdata->local->mdev); |
174 | sdata->bss = &msdata->u.ap; | 175 | sdata->bss = &msdata->u.ap; |
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 88b211af7c1f..d4893bd17754 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -321,7 +321,7 @@ void ieee80211_key_link(struct ieee80211_key *key, | |||
321 | * some hardware cannot handle TKIP with QoS, so | 321 | * some hardware cannot handle TKIP with QoS, so |
322 | * we indicate whether QoS could be in use. | 322 | * we indicate whether QoS could be in use. |
323 | */ | 323 | */ |
324 | if (sta->flags & WLAN_STA_WME) | 324 | if (test_sta_flags(sta, WLAN_STA_WME)) |
325 | key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA; | 325 | key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA; |
326 | 326 | ||
327 | /* | 327 | /* |
@@ -342,7 +342,7 @@ void ieee80211_key_link(struct ieee80211_key *key, | |||
342 | /* same here, the AP could be using QoS */ | 342 | /* same here, the AP could be using QoS */ |
343 | ap = sta_info_get(key->local, key->sdata->u.sta.bssid); | 343 | ap = sta_info_get(key->local, key->sdata->u.sta.bssid); |
344 | if (ap) { | 344 | if (ap) { |
345 | if (ap->flags & WLAN_STA_WME) | 345 | if (test_sta_flags(ap, WLAN_STA_WME)) |
346 | key->conf.flags |= | 346 | key->conf.flags |= |
347 | IEEE80211_KEY_FLAG_WMM_STA; | 347 | IEEE80211_KEY_FLAG_WMM_STA; |
348 | } | 348 | } |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index eb347eca30b5..36016363d225 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -346,6 +346,7 @@ static int ieee80211_open(struct net_device *dev) | |||
346 | goto err_del_interface; | 346 | goto err_del_interface; |
347 | } | 347 | } |
348 | 348 | ||
349 | /* no locking required since STA is not live yet */ | ||
349 | sta->flags |= WLAN_STA_AUTHORIZED; | 350 | sta->flags |= WLAN_STA_AUTHORIZED; |
350 | 351 | ||
351 | res = sta_info_insert(sta); | 352 | res = sta_info_insert(sta); |
@@ -588,7 +589,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
588 | return -ENOENT; | 589 | return -ENOENT; |
589 | } | 590 | } |
590 | 591 | ||
591 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 592 | spin_lock_bh(&sta->lock); |
592 | 593 | ||
593 | /* we have tried too many times, receiver does not want A-MPDU */ | 594 | /* we have tried too many times, receiver does not want A-MPDU */ |
594 | if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) { | 595 | if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) { |
@@ -691,7 +692,7 @@ start_ba_err: | |||
691 | spin_unlock_bh(&local->mdev->queue_lock); | 692 | spin_unlock_bh(&local->mdev->queue_lock); |
692 | ret = -EBUSY; | 693 | ret = -EBUSY; |
693 | start_ba_exit: | 694 | start_ba_exit: |
694 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 695 | spin_unlock_bh(&sta->lock); |
695 | rcu_read_unlock(); | 696 | rcu_read_unlock(); |
696 | return ret; | 697 | return ret; |
697 | } | 698 | } |
@@ -719,7 +720,7 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | |||
719 | 720 | ||
720 | /* check if the TID is in aggregation */ | 721 | /* check if the TID is in aggregation */ |
721 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 722 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
722 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 723 | spin_lock_bh(&sta->lock); |
723 | 724 | ||
724 | if (*state != HT_AGG_STATE_OPERATIONAL) { | 725 | if (*state != HT_AGG_STATE_OPERATIONAL) { |
725 | ret = -ENOENT; | 726 | ret = -ENOENT; |
@@ -749,7 +750,7 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | |||
749 | } | 750 | } |
750 | 751 | ||
751 | stop_BA_exit: | 752 | stop_BA_exit: |
752 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 753 | spin_unlock_bh(&sta->lock); |
753 | rcu_read_unlock(); | 754 | rcu_read_unlock(); |
754 | return ret; | 755 | return ret; |
755 | } | 756 | } |
@@ -778,12 +779,12 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
778 | } | 779 | } |
779 | 780 | ||
780 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 781 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
781 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 782 | spin_lock_bh(&sta->lock); |
782 | 783 | ||
783 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { | 784 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { |
784 | printk(KERN_DEBUG "addBA was not requested yet, state is %d\n", | 785 | printk(KERN_DEBUG "addBA was not requested yet, state is %d\n", |
785 | *state); | 786 | *state); |
786 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 787 | spin_unlock_bh(&sta->lock); |
787 | rcu_read_unlock(); | 788 | rcu_read_unlock(); |
788 | return; | 789 | return; |
789 | } | 790 | } |
@@ -796,7 +797,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
796 | printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid); | 797 | printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid); |
797 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); | 798 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); |
798 | } | 799 | } |
799 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 800 | spin_unlock_bh(&sta->lock); |
800 | rcu_read_unlock(); | 801 | rcu_read_unlock(); |
801 | } | 802 | } |
802 | EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); | 803 | EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); |
@@ -830,10 +831,10 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | |||
830 | } | 831 | } |
831 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 832 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
832 | 833 | ||
833 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 834 | spin_lock_bh(&sta->lock); |
834 | if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) { | 835 | if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) { |
835 | printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n"); | 836 | printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n"); |
836 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 837 | spin_unlock_bh(&sta->lock); |
837 | rcu_read_unlock(); | 838 | rcu_read_unlock(); |
838 | return; | 839 | return; |
839 | } | 840 | } |
@@ -860,7 +861,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | |||
860 | sta->ampdu_mlme.addba_req_num[tid] = 0; | 861 | sta->ampdu_mlme.addba_req_num[tid] = 0; |
861 | kfree(sta->ampdu_mlme.tid_tx[tid]); | 862 | kfree(sta->ampdu_mlme.tid_tx[tid]); |
862 | sta->ampdu_mlme.tid_tx[tid] = NULL; | 863 | sta->ampdu_mlme.tid_tx[tid] = NULL; |
863 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 864 | spin_unlock_bh(&sta->lock); |
864 | 865 | ||
865 | rcu_read_unlock(); | 866 | rcu_read_unlock(); |
866 | } | 867 | } |
@@ -1315,7 +1316,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
1315 | * packet. If the STA went to power save mode, this will happen | 1316 | * packet. If the STA went to power save mode, this will happen |
1316 | * happen when it wakes up for the next time. | 1317 | * happen when it wakes up for the next time. |
1317 | */ | 1318 | */ |
1318 | sta->flags |= WLAN_STA_CLEAR_PS_FILT; | 1319 | set_sta_flags(sta, WLAN_STA_CLEAR_PS_FILT); |
1319 | 1320 | ||
1320 | /* | 1321 | /* |
1321 | * This code races in the following way: | 1322 | * This code races in the following way: |
@@ -1347,7 +1348,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
1347 | * can be unknown, for example with different interrupt status | 1348 | * can be unknown, for example with different interrupt status |
1348 | * bits. | 1349 | * bits. |
1349 | */ | 1350 | */ |
1350 | if (sta->flags & WLAN_STA_PS && | 1351 | if (test_sta_flags(sta, WLAN_STA_PS) && |
1351 | skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) { | 1352 | skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) { |
1352 | ieee80211_remove_tx_extra(local, sta->key, skb, | 1353 | ieee80211_remove_tx_extra(local, sta->key, skb, |
1353 | &status->control); | 1354 | &status->control); |
@@ -1355,7 +1356,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
1355 | return; | 1356 | return; |
1356 | } | 1357 | } |
1357 | 1358 | ||
1358 | if (!(sta->flags & WLAN_STA_PS) && | 1359 | if (!test_sta_flags(sta, WLAN_STA_PS) && |
1359 | !(status->control.flags & IEEE80211_TXCTL_REQUEUE)) { | 1360 | !(status->control.flags & IEEE80211_TXCTL_REQUEUE)) { |
1360 | /* Software retry the packet once */ | 1361 | /* Software retry the packet once */ |
1361 | status->control.flags |= IEEE80211_TXCTL_REQUEUE; | 1362 | status->control.flags |= IEEE80211_TXCTL_REQUEUE; |
@@ -1370,7 +1371,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
1370 | "queue_len=%d PS=%d @%lu\n", | 1371 | "queue_len=%d PS=%d @%lu\n", |
1371 | wiphy_name(local->hw.wiphy), | 1372 | wiphy_name(local->hw.wiphy), |
1372 | skb_queue_len(&sta->tx_filtered), | 1373 | skb_queue_len(&sta->tx_filtered), |
1373 | !!(sta->flags & WLAN_STA_PS), jiffies); | 1374 | !!test_sta_flags(sta, WLAN_STA_PS), jiffies); |
1374 | dev_kfree_skb(skb); | 1375 | dev_kfree_skb(skb); |
1375 | } | 1376 | } |
1376 | 1377 | ||
@@ -1399,7 +1400,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1399 | struct sta_info *sta; | 1400 | struct sta_info *sta; |
1400 | sta = sta_info_get(local, hdr->addr1); | 1401 | sta = sta_info_get(local, hdr->addr1); |
1401 | if (sta) { | 1402 | if (sta) { |
1402 | if (sta->flags & WLAN_STA_PS) { | 1403 | if (test_sta_flags(sta, WLAN_STA_PS)) { |
1403 | /* | 1404 | /* |
1404 | * The STA is in power save mode, so assume | 1405 | * The STA is in power save mode, so assume |
1405 | * that this TX packet failed because of that. | 1406 | * that this TX packet failed because of that. |
@@ -1701,13 +1702,13 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1701 | 1702 | ||
1702 | local->hw.conf.beacon_int = 1000; | 1703 | local->hw.conf.beacon_int = 1000; |
1703 | 1704 | ||
1704 | local->wstats_flags |= local->hw.max_rssi ? | 1705 | local->wstats_flags |= local->hw.flags & (IEEE80211_HW_SIGNAL_UNSPEC | |
1705 | IW_QUAL_LEVEL_UPDATED : IW_QUAL_LEVEL_INVALID; | 1706 | IEEE80211_HW_SIGNAL_DB | |
1706 | local->wstats_flags |= local->hw.max_signal ? | 1707 | IEEE80211_HW_SIGNAL_DBM) ? |
1707 | IW_QUAL_QUAL_UPDATED : IW_QUAL_QUAL_INVALID; | 1708 | IW_QUAL_QUAL_UPDATED : IW_QUAL_QUAL_INVALID; |
1708 | local->wstats_flags |= local->hw.max_noise ? | 1709 | local->wstats_flags |= local->hw.flags & IEEE80211_HW_NOISE_DBM ? |
1709 | IW_QUAL_NOISE_UPDATED : IW_QUAL_NOISE_INVALID; | 1710 | IW_QUAL_NOISE_UPDATED : IW_QUAL_NOISE_INVALID; |
1710 | if (local->hw.max_rssi < 0 || local->hw.max_noise < 0) | 1711 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) |
1711 | local->wstats_flags |= IW_QUAL_DBM; | 1712 | local->wstats_flags |= IW_QUAL_DBM; |
1712 | 1713 | ||
1713 | result = sta_info_start(local); | 1714 | result = sta_info_start(local); |
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index af0cd1e3e213..7fa149e230e6 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c | |||
@@ -26,7 +26,7 @@ static inline u32 u32_field_get(u8 *preq_elem, int offset, bool ae) | |||
26 | { | 26 | { |
27 | if (ae) | 27 | if (ae) |
28 | offset += 6; | 28 | offset += 6; |
29 | return le32_to_cpu(get_unaligned((__le32 *) (preq_elem + offset))); | 29 | return get_unaligned_le32(preq_elem + offset); |
30 | } | 30 | } |
31 | 31 | ||
32 | /* HWMP IE processing macros */ | 32 | /* HWMP IE processing macros */ |
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 37f0c2b94ae7..9efeb1f07025 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c | |||
@@ -79,7 +79,7 @@ void mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata) | |||
79 | * | 79 | * |
80 | * @sta: mes peer link to restart | 80 | * @sta: mes peer link to restart |
81 | * | 81 | * |
82 | * Locking: this function must be called holding sta->plink_lock | 82 | * Locking: this function must be called holding sta->lock |
83 | */ | 83 | */ |
84 | static inline void mesh_plink_fsm_restart(struct sta_info *sta) | 84 | static inline void mesh_plink_fsm_restart(struct sta_info *sta) |
85 | { | 85 | { |
@@ -105,7 +105,7 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata, | |||
105 | if (!sta) | 105 | if (!sta) |
106 | return NULL; | 106 | return NULL; |
107 | 107 | ||
108 | sta->flags |= WLAN_STA_AUTHORIZED; | 108 | sta->flags = WLAN_STA_AUTHORIZED; |
109 | sta->supp_rates[local->hw.conf.channel->band] = rates; | 109 | sta->supp_rates[local->hw.conf.channel->band] = rates; |
110 | 110 | ||
111 | return sta; | 111 | return sta; |
@@ -118,7 +118,7 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata, | |||
118 | * | 118 | * |
119 | * All mesh paths with this peer as next hop will be flushed | 119 | * All mesh paths with this peer as next hop will be flushed |
120 | * | 120 | * |
121 | * Locking: the caller must hold sta->plink_lock | 121 | * Locking: the caller must hold sta->lock |
122 | */ | 122 | */ |
123 | static void __mesh_plink_deactivate(struct sta_info *sta) | 123 | static void __mesh_plink_deactivate(struct sta_info *sta) |
124 | { | 124 | { |
@@ -139,9 +139,9 @@ static void __mesh_plink_deactivate(struct sta_info *sta) | |||
139 | */ | 139 | */ |
140 | void mesh_plink_deactivate(struct sta_info *sta) | 140 | void mesh_plink_deactivate(struct sta_info *sta) |
141 | { | 141 | { |
142 | spin_lock_bh(&sta->plink_lock); | 142 | spin_lock_bh(&sta->lock); |
143 | __mesh_plink_deactivate(sta); | 143 | __mesh_plink_deactivate(sta); |
144 | spin_unlock_bh(&sta->plink_lock); | 144 | spin_unlock_bh(&sta->lock); |
145 | } | 145 | } |
146 | 146 | ||
147 | static int mesh_plink_frame_tx(struct net_device *dev, | 147 | static int mesh_plink_frame_tx(struct net_device *dev, |
@@ -270,10 +270,10 @@ static void mesh_plink_timer(unsigned long data) | |||
270 | */ | 270 | */ |
271 | sta = (struct sta_info *) data; | 271 | sta = (struct sta_info *) data; |
272 | 272 | ||
273 | spin_lock_bh(&sta->plink_lock); | 273 | spin_lock_bh(&sta->lock); |
274 | if (sta->ignore_plink_timer) { | 274 | if (sta->ignore_plink_timer) { |
275 | sta->ignore_plink_timer = false; | 275 | sta->ignore_plink_timer = false; |
276 | spin_unlock_bh(&sta->plink_lock); | 276 | spin_unlock_bh(&sta->lock); |
277 | return; | 277 | return; |
278 | } | 278 | } |
279 | mpl_dbg("Mesh plink timer for %s fired on state %d\n", | 279 | mpl_dbg("Mesh plink timer for %s fired on state %d\n", |
@@ -298,7 +298,7 @@ static void mesh_plink_timer(unsigned long data) | |||
298 | rand % sta->plink_timeout; | 298 | rand % sta->plink_timeout; |
299 | ++sta->plink_retries; | 299 | ++sta->plink_retries; |
300 | mod_plink_timer(sta, sta->plink_timeout); | 300 | mod_plink_timer(sta, sta->plink_timeout); |
301 | spin_unlock_bh(&sta->plink_lock); | 301 | spin_unlock_bh(&sta->lock); |
302 | mesh_plink_frame_tx(dev, PLINK_OPEN, sta->addr, llid, | 302 | mesh_plink_frame_tx(dev, PLINK_OPEN, sta->addr, llid, |
303 | 0, 0); | 303 | 0, 0); |
304 | break; | 304 | break; |
@@ -311,7 +311,7 @@ static void mesh_plink_timer(unsigned long data) | |||
311 | reason = cpu_to_le16(MESH_CONFIRM_TIMEOUT); | 311 | reason = cpu_to_le16(MESH_CONFIRM_TIMEOUT); |
312 | sta->plink_state = PLINK_HOLDING; | 312 | sta->plink_state = PLINK_HOLDING; |
313 | mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); | 313 | mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); |
314 | spin_unlock_bh(&sta->plink_lock); | 314 | spin_unlock_bh(&sta->lock); |
315 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, plid, | 315 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, plid, |
316 | reason); | 316 | reason); |
317 | break; | 317 | break; |
@@ -319,10 +319,10 @@ static void mesh_plink_timer(unsigned long data) | |||
319 | /* holding timer */ | 319 | /* holding timer */ |
320 | del_timer(&sta->plink_timer); | 320 | del_timer(&sta->plink_timer); |
321 | mesh_plink_fsm_restart(sta); | 321 | mesh_plink_fsm_restart(sta); |
322 | spin_unlock_bh(&sta->plink_lock); | 322 | spin_unlock_bh(&sta->lock); |
323 | break; | 323 | break; |
324 | default: | 324 | default: |
325 | spin_unlock_bh(&sta->plink_lock); | 325 | spin_unlock_bh(&sta->lock); |
326 | break; | 326 | break; |
327 | } | 327 | } |
328 | } | 328 | } |
@@ -344,16 +344,16 @@ int mesh_plink_open(struct sta_info *sta) | |||
344 | DECLARE_MAC_BUF(mac); | 344 | DECLARE_MAC_BUF(mac); |
345 | #endif | 345 | #endif |
346 | 346 | ||
347 | spin_lock_bh(&sta->plink_lock); | 347 | spin_lock_bh(&sta->lock); |
348 | get_random_bytes(&llid, 2); | 348 | get_random_bytes(&llid, 2); |
349 | sta->llid = llid; | 349 | sta->llid = llid; |
350 | if (sta->plink_state != PLINK_LISTEN) { | 350 | if (sta->plink_state != PLINK_LISTEN) { |
351 | spin_unlock_bh(&sta->plink_lock); | 351 | spin_unlock_bh(&sta->lock); |
352 | return -EBUSY; | 352 | return -EBUSY; |
353 | } | 353 | } |
354 | sta->plink_state = PLINK_OPN_SNT; | 354 | sta->plink_state = PLINK_OPN_SNT; |
355 | mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); | 355 | mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); |
356 | spin_unlock_bh(&sta->plink_lock); | 356 | spin_unlock_bh(&sta->lock); |
357 | mpl_dbg("Mesh plink: starting establishment with %s\n", | 357 | mpl_dbg("Mesh plink: starting establishment with %s\n", |
358 | print_mac(mac, sta->addr)); | 358 | print_mac(mac, sta->addr)); |
359 | 359 | ||
@@ -367,10 +367,10 @@ void mesh_plink_block(struct sta_info *sta) | |||
367 | DECLARE_MAC_BUF(mac); | 367 | DECLARE_MAC_BUF(mac); |
368 | #endif | 368 | #endif |
369 | 369 | ||
370 | spin_lock_bh(&sta->plink_lock); | 370 | spin_lock_bh(&sta->lock); |
371 | __mesh_plink_deactivate(sta); | 371 | __mesh_plink_deactivate(sta); |
372 | sta->plink_state = PLINK_BLOCKED; | 372 | sta->plink_state = PLINK_BLOCKED; |
373 | spin_unlock_bh(&sta->plink_lock); | 373 | spin_unlock_bh(&sta->lock); |
374 | } | 374 | } |
375 | 375 | ||
376 | int mesh_plink_close(struct sta_info *sta) | 376 | int mesh_plink_close(struct sta_info *sta) |
@@ -383,14 +383,14 @@ int mesh_plink_close(struct sta_info *sta) | |||
383 | 383 | ||
384 | mpl_dbg("Mesh plink: closing link with %s\n", | 384 | mpl_dbg("Mesh plink: closing link with %s\n", |
385 | print_mac(mac, sta->addr)); | 385 | print_mac(mac, sta->addr)); |
386 | spin_lock_bh(&sta->plink_lock); | 386 | spin_lock_bh(&sta->lock); |
387 | sta->reason = cpu_to_le16(MESH_LINK_CANCELLED); | 387 | sta->reason = cpu_to_le16(MESH_LINK_CANCELLED); |
388 | reason = sta->reason; | 388 | reason = sta->reason; |
389 | 389 | ||
390 | if (sta->plink_state == PLINK_LISTEN || | 390 | if (sta->plink_state == PLINK_LISTEN || |
391 | sta->plink_state == PLINK_BLOCKED) { | 391 | sta->plink_state == PLINK_BLOCKED) { |
392 | mesh_plink_fsm_restart(sta); | 392 | mesh_plink_fsm_restart(sta); |
393 | spin_unlock_bh(&sta->plink_lock); | 393 | spin_unlock_bh(&sta->lock); |
394 | return 0; | 394 | return 0; |
395 | } else if (sta->plink_state == PLINK_ESTAB) { | 395 | } else if (sta->plink_state == PLINK_ESTAB) { |
396 | __mesh_plink_deactivate(sta); | 396 | __mesh_plink_deactivate(sta); |
@@ -402,7 +402,7 @@ int mesh_plink_close(struct sta_info *sta) | |||
402 | sta->plink_state = PLINK_HOLDING; | 402 | sta->plink_state = PLINK_HOLDING; |
403 | llid = sta->llid; | 403 | llid = sta->llid; |
404 | plid = sta->plid; | 404 | plid = sta->plid; |
405 | spin_unlock_bh(&sta->plink_lock); | 405 | spin_unlock_bh(&sta->lock); |
406 | mesh_plink_frame_tx(sta->sdata->dev, PLINK_CLOSE, sta->addr, llid, | 406 | mesh_plink_frame_tx(sta->sdata->dev, PLINK_CLOSE, sta->addr, llid, |
407 | plid, reason); | 407 | plid, reason); |
408 | return 0; | 408 | return 0; |
@@ -490,7 +490,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
490 | /* avoid warning */ | 490 | /* avoid warning */ |
491 | break; | 491 | break; |
492 | } | 492 | } |
493 | spin_lock_bh(&sta->plink_lock); | 493 | spin_lock_bh(&sta->lock); |
494 | } else if (!sta) { | 494 | } else if (!sta) { |
495 | /* ftype == PLINK_OPEN */ | 495 | /* ftype == PLINK_OPEN */ |
496 | u64 rates; | 496 | u64 rates; |
@@ -512,9 +512,9 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
512 | return; | 512 | return; |
513 | } | 513 | } |
514 | event = OPN_ACPT; | 514 | event = OPN_ACPT; |
515 | spin_lock_bh(&sta->plink_lock); | 515 | spin_lock_bh(&sta->lock); |
516 | } else { | 516 | } else { |
517 | spin_lock_bh(&sta->plink_lock); | 517 | spin_lock_bh(&sta->lock); |
518 | switch (ftype) { | 518 | switch (ftype) { |
519 | case PLINK_OPEN: | 519 | case PLINK_OPEN: |
520 | if (!mesh_plink_free_count(sdata) || | 520 | if (!mesh_plink_free_count(sdata) || |
@@ -551,7 +551,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
551 | break; | 551 | break; |
552 | default: | 552 | default: |
553 | mpl_dbg("Mesh plink: unknown frame subtype\n"); | 553 | mpl_dbg("Mesh plink: unknown frame subtype\n"); |
554 | spin_unlock_bh(&sta->plink_lock); | 554 | spin_unlock_bh(&sta->lock); |
555 | rcu_read_unlock(); | 555 | rcu_read_unlock(); |
556 | return; | 556 | return; |
557 | } | 557 | } |
@@ -568,7 +568,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
568 | switch (event) { | 568 | switch (event) { |
569 | case CLS_ACPT: | 569 | case CLS_ACPT: |
570 | mesh_plink_fsm_restart(sta); | 570 | mesh_plink_fsm_restart(sta); |
571 | spin_unlock_bh(&sta->plink_lock); | 571 | spin_unlock_bh(&sta->lock); |
572 | break; | 572 | break; |
573 | case OPN_ACPT: | 573 | case OPN_ACPT: |
574 | sta->plink_state = PLINK_OPN_RCVD; | 574 | sta->plink_state = PLINK_OPN_RCVD; |
@@ -576,14 +576,14 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
576 | get_random_bytes(&llid, 2); | 576 | get_random_bytes(&llid, 2); |
577 | sta->llid = llid; | 577 | sta->llid = llid; |
578 | mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); | 578 | mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); |
579 | spin_unlock_bh(&sta->plink_lock); | 579 | spin_unlock_bh(&sta->lock); |
580 | mesh_plink_frame_tx(dev, PLINK_OPEN, sta->addr, llid, | 580 | mesh_plink_frame_tx(dev, PLINK_OPEN, sta->addr, llid, |
581 | 0, 0); | 581 | 0, 0); |
582 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, | 582 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, |
583 | llid, plid, 0); | 583 | llid, plid, 0); |
584 | break; | 584 | break; |
585 | default: | 585 | default: |
586 | spin_unlock_bh(&sta->plink_lock); | 586 | spin_unlock_bh(&sta->lock); |
587 | break; | 587 | break; |
588 | } | 588 | } |
589 | break; | 589 | break; |
@@ -603,7 +603,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
603 | sta->ignore_plink_timer = true; | 603 | sta->ignore_plink_timer = true; |
604 | 604 | ||
605 | llid = sta->llid; | 605 | llid = sta->llid; |
606 | spin_unlock_bh(&sta->plink_lock); | 606 | spin_unlock_bh(&sta->lock); |
607 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, | 607 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, |
608 | plid, reason); | 608 | plid, reason); |
609 | break; | 609 | break; |
@@ -612,7 +612,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
612 | sta->plink_state = PLINK_OPN_RCVD; | 612 | sta->plink_state = PLINK_OPN_RCVD; |
613 | sta->plid = plid; | 613 | sta->plid = plid; |
614 | llid = sta->llid; | 614 | llid = sta->llid; |
615 | spin_unlock_bh(&sta->plink_lock); | 615 | spin_unlock_bh(&sta->lock); |
616 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, | 616 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, |
617 | plid, 0); | 617 | plid, 0); |
618 | break; | 618 | break; |
@@ -622,10 +622,10 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
622 | dot11MeshConfirmTimeout(sdata))) | 622 | dot11MeshConfirmTimeout(sdata))) |
623 | sta->ignore_plink_timer = true; | 623 | sta->ignore_plink_timer = true; |
624 | 624 | ||
625 | spin_unlock_bh(&sta->plink_lock); | 625 | spin_unlock_bh(&sta->lock); |
626 | break; | 626 | break; |
627 | default: | 627 | default: |
628 | spin_unlock_bh(&sta->plink_lock); | 628 | spin_unlock_bh(&sta->lock); |
629 | break; | 629 | break; |
630 | } | 630 | } |
631 | break; | 631 | break; |
@@ -645,13 +645,13 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
645 | sta->ignore_plink_timer = true; | 645 | sta->ignore_plink_timer = true; |
646 | 646 | ||
647 | llid = sta->llid; | 647 | llid = sta->llid; |
648 | spin_unlock_bh(&sta->plink_lock); | 648 | spin_unlock_bh(&sta->lock); |
649 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, | 649 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, |
650 | plid, reason); | 650 | plid, reason); |
651 | break; | 651 | break; |
652 | case OPN_ACPT: | 652 | case OPN_ACPT: |
653 | llid = sta->llid; | 653 | llid = sta->llid; |
654 | spin_unlock_bh(&sta->plink_lock); | 654 | spin_unlock_bh(&sta->lock); |
655 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, | 655 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, |
656 | plid, 0); | 656 | plid, 0); |
657 | break; | 657 | break; |
@@ -659,12 +659,12 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
659 | del_timer(&sta->plink_timer); | 659 | del_timer(&sta->plink_timer); |
660 | sta->plink_state = PLINK_ESTAB; | 660 | sta->plink_state = PLINK_ESTAB; |
661 | mesh_plink_inc_estab_count(sdata); | 661 | mesh_plink_inc_estab_count(sdata); |
662 | spin_unlock_bh(&sta->plink_lock); | 662 | spin_unlock_bh(&sta->lock); |
663 | mpl_dbg("Mesh plink with %s ESTABLISHED\n", | 663 | mpl_dbg("Mesh plink with %s ESTABLISHED\n", |
664 | print_mac(mac, sta->addr)); | 664 | print_mac(mac, sta->addr)); |
665 | break; | 665 | break; |
666 | default: | 666 | default: |
667 | spin_unlock_bh(&sta->plink_lock); | 667 | spin_unlock_bh(&sta->lock); |
668 | break; | 668 | break; |
669 | } | 669 | } |
670 | break; | 670 | break; |
@@ -684,7 +684,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
684 | sta->ignore_plink_timer = true; | 684 | sta->ignore_plink_timer = true; |
685 | 685 | ||
686 | llid = sta->llid; | 686 | llid = sta->llid; |
687 | spin_unlock_bh(&sta->plink_lock); | 687 | spin_unlock_bh(&sta->lock); |
688 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, | 688 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, |
689 | plid, reason); | 689 | plid, reason); |
690 | break; | 690 | break; |
@@ -692,14 +692,14 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
692 | del_timer(&sta->plink_timer); | 692 | del_timer(&sta->plink_timer); |
693 | sta->plink_state = PLINK_ESTAB; | 693 | sta->plink_state = PLINK_ESTAB; |
694 | mesh_plink_inc_estab_count(sdata); | 694 | mesh_plink_inc_estab_count(sdata); |
695 | spin_unlock_bh(&sta->plink_lock); | 695 | spin_unlock_bh(&sta->lock); |
696 | mpl_dbg("Mesh plink with %s ESTABLISHED\n", | 696 | mpl_dbg("Mesh plink with %s ESTABLISHED\n", |
697 | print_mac(mac, sta->addr)); | 697 | print_mac(mac, sta->addr)); |
698 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, | 698 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, |
699 | plid, 0); | 699 | plid, 0); |
700 | break; | 700 | break; |
701 | default: | 701 | default: |
702 | spin_unlock_bh(&sta->plink_lock); | 702 | spin_unlock_bh(&sta->lock); |
703 | break; | 703 | break; |
704 | } | 704 | } |
705 | break; | 705 | break; |
@@ -713,18 +713,18 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
713 | sta->plink_state = PLINK_HOLDING; | 713 | sta->plink_state = PLINK_HOLDING; |
714 | llid = sta->llid; | 714 | llid = sta->llid; |
715 | mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); | 715 | mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); |
716 | spin_unlock_bh(&sta->plink_lock); | 716 | spin_unlock_bh(&sta->lock); |
717 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, | 717 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, |
718 | plid, reason); | 718 | plid, reason); |
719 | break; | 719 | break; |
720 | case OPN_ACPT: | 720 | case OPN_ACPT: |
721 | llid = sta->llid; | 721 | llid = sta->llid; |
722 | spin_unlock_bh(&sta->plink_lock); | 722 | spin_unlock_bh(&sta->lock); |
723 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, | 723 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, |
724 | plid, 0); | 724 | plid, 0); |
725 | break; | 725 | break; |
726 | default: | 726 | default: |
727 | spin_unlock_bh(&sta->plink_lock); | 727 | spin_unlock_bh(&sta->lock); |
728 | break; | 728 | break; |
729 | } | 729 | } |
730 | break; | 730 | break; |
@@ -734,7 +734,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
734 | if (del_timer(&sta->plink_timer)) | 734 | if (del_timer(&sta->plink_timer)) |
735 | sta->ignore_plink_timer = 1; | 735 | sta->ignore_plink_timer = 1; |
736 | mesh_plink_fsm_restart(sta); | 736 | mesh_plink_fsm_restart(sta); |
737 | spin_unlock_bh(&sta->plink_lock); | 737 | spin_unlock_bh(&sta->lock); |
738 | break; | 738 | break; |
739 | case OPN_ACPT: | 739 | case OPN_ACPT: |
740 | case CNF_ACPT: | 740 | case CNF_ACPT: |
@@ -742,19 +742,19 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
742 | case CNF_RJCT: | 742 | case CNF_RJCT: |
743 | llid = sta->llid; | 743 | llid = sta->llid; |
744 | reason = sta->reason; | 744 | reason = sta->reason; |
745 | spin_unlock_bh(&sta->plink_lock); | 745 | spin_unlock_bh(&sta->lock); |
746 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, | 746 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, |
747 | plid, reason); | 747 | plid, reason); |
748 | break; | 748 | break; |
749 | default: | 749 | default: |
750 | spin_unlock_bh(&sta->plink_lock); | 750 | spin_unlock_bh(&sta->lock); |
751 | } | 751 | } |
752 | break; | 752 | break; |
753 | default: | 753 | default: |
754 | /* should not get here, PLINK_BLOCKED is dealt with at the | 754 | /* should not get here, PLINK_BLOCKED is dealt with at the |
755 | * beggining of the function | 755 | * beggining of the function |
756 | */ | 756 | */ |
757 | spin_unlock_bh(&sta->plink_lock); | 757 | spin_unlock_bh(&sta->lock); |
758 | break; | 758 | break; |
759 | } | 759 | } |
760 | 760 | ||
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 5d7719f44bea..7877d3b3f4cb 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -272,6 +272,12 @@ static void ieee80211_sta_wmm_params(struct net_device *dev, | |||
272 | int count; | 272 | int count; |
273 | u8 *pos; | 273 | u8 *pos; |
274 | 274 | ||
275 | if (!(ifsta->flags & IEEE80211_STA_WMM_ENABLED)) | ||
276 | return; | ||
277 | |||
278 | if (!wmm_param) | ||
279 | return; | ||
280 | |||
275 | if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1) | 281 | if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1) |
276 | return; | 282 | return; |
277 | count = wmm_param[6] & 0x0f; | 283 | count = wmm_param[6] & 0x0f; |
@@ -799,8 +805,10 @@ static void ieee80211_send_assoc(struct net_device *dev, | |||
799 | *pos++ = 1; /* WME ver */ | 805 | *pos++ = 1; /* WME ver */ |
800 | *pos++ = 0; | 806 | *pos++ = 0; |
801 | } | 807 | } |
808 | |||
802 | /* wmm support is a must to HT */ | 809 | /* wmm support is a must to HT */ |
803 | if (wmm && sband->ht_info.ht_supported) { | 810 | if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED) && |
811 | sband->ht_info.ht_supported) { | ||
804 | __le16 tmp = cpu_to_le16(sband->ht_info.cap); | 812 | __le16 tmp = cpu_to_le16(sband->ht_info.cap); |
805 | pos = skb_put(skb, sizeof(struct ieee80211_ht_cap)+2); | 813 | pos = skb_put(skb, sizeof(struct ieee80211_ht_cap)+2); |
806 | *pos++ = WLAN_EID_HT_CAPABILITY; | 814 | *pos++ = WLAN_EID_HT_CAPABILITY; |
@@ -1269,7 +1277,7 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev, | |||
1269 | 1277 | ||
1270 | 1278 | ||
1271 | /* examine state machine */ | 1279 | /* examine state machine */ |
1272 | spin_lock_bh(&sta->ampdu_mlme.ampdu_rx); | 1280 | spin_lock_bh(&sta->lock); |
1273 | 1281 | ||
1274 | if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_IDLE) { | 1282 | if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_IDLE) { |
1275 | #ifdef CONFIG_MAC80211_HT_DEBUG | 1283 | #ifdef CONFIG_MAC80211_HT_DEBUG |
@@ -1336,7 +1344,7 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev, | |||
1336 | tid_agg_rx->stored_mpdu_num = 0; | 1344 | tid_agg_rx->stored_mpdu_num = 0; |
1337 | status = WLAN_STATUS_SUCCESS; | 1345 | status = WLAN_STATUS_SUCCESS; |
1338 | end: | 1346 | end: |
1339 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx); | 1347 | spin_unlock_bh(&sta->lock); |
1340 | 1348 | ||
1341 | end_no_lock: | 1349 | end_no_lock: |
1342 | ieee80211_send_addba_resp(sta->sdata->dev, sta->addr, tid, | 1350 | ieee80211_send_addba_resp(sta->sdata->dev, sta->addr, tid, |
@@ -1368,10 +1376,10 @@ static void ieee80211_sta_process_addba_resp(struct net_device *dev, | |||
1368 | 1376 | ||
1369 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 1377 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
1370 | 1378 | ||
1371 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 1379 | spin_lock_bh(&sta->lock); |
1372 | 1380 | ||
1373 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { | 1381 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { |
1374 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 1382 | spin_unlock_bh(&sta->lock); |
1375 | printk(KERN_DEBUG "state not HT_ADDBA_REQUESTED_MSK:" | 1383 | printk(KERN_DEBUG "state not HT_ADDBA_REQUESTED_MSK:" |
1376 | "%d\n", *state); | 1384 | "%d\n", *state); |
1377 | goto addba_resp_exit; | 1385 | goto addba_resp_exit; |
@@ -1379,7 +1387,7 @@ static void ieee80211_sta_process_addba_resp(struct net_device *dev, | |||
1379 | 1387 | ||
1380 | if (mgmt->u.action.u.addba_resp.dialog_token != | 1388 | if (mgmt->u.action.u.addba_resp.dialog_token != |
1381 | sta->ampdu_mlme.tid_tx[tid]->dialog_token) { | 1389 | sta->ampdu_mlme.tid_tx[tid]->dialog_token) { |
1382 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 1390 | spin_unlock_bh(&sta->lock); |
1383 | #ifdef CONFIG_MAC80211_HT_DEBUG | 1391 | #ifdef CONFIG_MAC80211_HT_DEBUG |
1384 | printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); | 1392 | printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); |
1385 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 1393 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
@@ -1403,7 +1411,7 @@ static void ieee80211_sta_process_addba_resp(struct net_device *dev, | |||
1403 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); | 1411 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); |
1404 | } | 1412 | } |
1405 | 1413 | ||
1406 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 1414 | spin_unlock_bh(&sta->lock); |
1407 | printk(KERN_DEBUG "recipient accepted agg: tid %d \n", tid); | 1415 | printk(KERN_DEBUG "recipient accepted agg: tid %d \n", tid); |
1408 | } else { | 1416 | } else { |
1409 | printk(KERN_DEBUG "recipient rejected agg: tid %d \n", tid); | 1417 | printk(KERN_DEBUG "recipient rejected agg: tid %d \n", tid); |
@@ -1411,7 +1419,7 @@ static void ieee80211_sta_process_addba_resp(struct net_device *dev, | |||
1411 | sta->ampdu_mlme.addba_req_num[tid]++; | 1419 | sta->ampdu_mlme.addba_req_num[tid]++; |
1412 | /* this will allow the state check in stop_BA_session */ | 1420 | /* this will allow the state check in stop_BA_session */ |
1413 | *state = HT_AGG_STATE_OPERATIONAL; | 1421 | *state = HT_AGG_STATE_OPERATIONAL; |
1414 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 1422 | spin_unlock_bh(&sta->lock); |
1415 | ieee80211_stop_tx_ba_session(hw, sta->addr, tid, | 1423 | ieee80211_stop_tx_ba_session(hw, sta->addr, tid, |
1416 | WLAN_BACK_INITIATOR); | 1424 | WLAN_BACK_INITIATOR); |
1417 | } | 1425 | } |
@@ -1481,17 +1489,17 @@ void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *ra, u16 tid, | |||
1481 | } | 1489 | } |
1482 | 1490 | ||
1483 | /* check if TID is in operational state */ | 1491 | /* check if TID is in operational state */ |
1484 | spin_lock_bh(&sta->ampdu_mlme.ampdu_rx); | 1492 | spin_lock_bh(&sta->lock); |
1485 | if (sta->ampdu_mlme.tid_state_rx[tid] | 1493 | if (sta->ampdu_mlme.tid_state_rx[tid] |
1486 | != HT_AGG_STATE_OPERATIONAL) { | 1494 | != HT_AGG_STATE_OPERATIONAL) { |
1487 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx); | 1495 | spin_unlock_bh(&sta->lock); |
1488 | rcu_read_unlock(); | 1496 | rcu_read_unlock(); |
1489 | return; | 1497 | return; |
1490 | } | 1498 | } |
1491 | sta->ampdu_mlme.tid_state_rx[tid] = | 1499 | sta->ampdu_mlme.tid_state_rx[tid] = |
1492 | HT_AGG_STATE_REQ_STOP_BA_MSK | | 1500 | HT_AGG_STATE_REQ_STOP_BA_MSK | |
1493 | (initiator << HT_AGG_STATE_INITIATOR_SHIFT); | 1501 | (initiator << HT_AGG_STATE_INITIATOR_SHIFT); |
1494 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx); | 1502 | spin_unlock_bh(&sta->lock); |
1495 | 1503 | ||
1496 | /* stop HW Rx aggregation. ampdu_action existence | 1504 | /* stop HW Rx aggregation. ampdu_action existence |
1497 | * already verified in session init so we add the BUG_ON */ | 1505 | * already verified in session init so we add the BUG_ON */ |
@@ -1568,10 +1576,10 @@ static void ieee80211_sta_process_delba(struct net_device *dev, | |||
1568 | ieee80211_sta_stop_rx_ba_session(dev, sta->addr, tid, | 1576 | ieee80211_sta_stop_rx_ba_session(dev, sta->addr, tid, |
1569 | WLAN_BACK_INITIATOR, 0); | 1577 | WLAN_BACK_INITIATOR, 0); |
1570 | else { /* WLAN_BACK_RECIPIENT */ | 1578 | else { /* WLAN_BACK_RECIPIENT */ |
1571 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 1579 | spin_lock_bh(&sta->lock); |
1572 | sta->ampdu_mlme.tid_state_tx[tid] = | 1580 | sta->ampdu_mlme.tid_state_tx[tid] = |
1573 | HT_AGG_STATE_OPERATIONAL; | 1581 | HT_AGG_STATE_OPERATIONAL; |
1574 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 1582 | spin_unlock_bh(&sta->lock); |
1575 | ieee80211_stop_tx_ba_session(&local->hw, sta->addr, tid, | 1583 | ieee80211_stop_tx_ba_session(&local->hw, sta->addr, tid, |
1576 | WLAN_BACK_RECIPIENT); | 1584 | WLAN_BACK_RECIPIENT); |
1577 | } | 1585 | } |
@@ -1608,9 +1616,9 @@ void sta_addba_resp_timer_expired(unsigned long data) | |||
1608 | 1616 | ||
1609 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 1617 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
1610 | /* check if the TID waits for addBA response */ | 1618 | /* check if the TID waits for addBA response */ |
1611 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 1619 | spin_lock_bh(&sta->lock); |
1612 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { | 1620 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { |
1613 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 1621 | spin_unlock_bh(&sta->lock); |
1614 | *state = HT_AGG_STATE_IDLE; | 1622 | *state = HT_AGG_STATE_IDLE; |
1615 | printk(KERN_DEBUG "timer expired on tid %d but we are not " | 1623 | printk(KERN_DEBUG "timer expired on tid %d but we are not " |
1616 | "expecting addBA response there", tid); | 1624 | "expecting addBA response there", tid); |
@@ -1621,7 +1629,7 @@ void sta_addba_resp_timer_expired(unsigned long data) | |||
1621 | 1629 | ||
1622 | /* go through the state check in stop_BA_session */ | 1630 | /* go through the state check in stop_BA_session */ |
1623 | *state = HT_AGG_STATE_OPERATIONAL; | 1631 | *state = HT_AGG_STATE_OPERATIONAL; |
1624 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 1632 | spin_unlock_bh(&sta->lock); |
1625 | ieee80211_stop_tx_ba_session(hw, temp_sta->addr, tid, | 1633 | ieee80211_stop_tx_ba_session(hw, temp_sta->addr, tid, |
1626 | WLAN_BACK_INITIATOR); | 1634 | WLAN_BACK_INITIATOR); |
1627 | 1635 | ||
@@ -1987,8 +1995,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1987 | local->hw.conf.channel->center_freq, | 1995 | local->hw.conf.channel->center_freq, |
1988 | ifsta->ssid, ifsta->ssid_len); | 1996 | ifsta->ssid, ifsta->ssid_len); |
1989 | if (bss) { | 1997 | if (bss) { |
1990 | sta->last_rssi = bss->rssi; | ||
1991 | sta->last_signal = bss->signal; | 1998 | sta->last_signal = bss->signal; |
1999 | sta->last_qual = bss->qual; | ||
1992 | sta->last_noise = bss->noise; | 2000 | sta->last_noise = bss->noise; |
1993 | ieee80211_rx_bss_put(dev, bss); | 2001 | ieee80211_rx_bss_put(dev, bss); |
1994 | } | 2002 | } |
@@ -2012,8 +2020,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2012 | * to between the sta_info_alloc() and sta_info_insert() above. | 2020 | * to between the sta_info_alloc() and sta_info_insert() above. |
2013 | */ | 2021 | */ |
2014 | 2022 | ||
2015 | sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP | | 2023 | set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP | |
2016 | WLAN_STA_AUTHORIZED; | 2024 | WLAN_STA_AUTHORIZED); |
2017 | 2025 | ||
2018 | rates = 0; | 2026 | rates = 0; |
2019 | basic_rates = 0; | 2027 | basic_rates = 0; |
@@ -2057,7 +2065,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2057 | else | 2065 | else |
2058 | sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE; | 2066 | sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE; |
2059 | 2067 | ||
2060 | if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param) { | 2068 | if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param && |
2069 | (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) { | ||
2061 | struct ieee80211_ht_bss_info bss_info; | 2070 | struct ieee80211_ht_bss_info bss_info; |
2062 | ieee80211_ht_cap_ie_to_ht_info( | 2071 | ieee80211_ht_cap_ie_to_ht_info( |
2063 | (struct ieee80211_ht_cap *) | 2072 | (struct ieee80211_ht_cap *) |
@@ -2070,8 +2079,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2070 | 2079 | ||
2071 | rate_control_rate_init(sta, local); | 2080 | rate_control_rate_init(sta, local); |
2072 | 2081 | ||
2073 | if (elems.wmm_param && (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) { | 2082 | if (elems.wmm_param) { |
2074 | sta->flags |= WLAN_STA_WME; | 2083 | set_sta_flags(sta, WLAN_STA_WME); |
2075 | rcu_read_unlock(); | 2084 | rcu_read_unlock(); |
2076 | ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param, | 2085 | ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param, |
2077 | elems.wmm_param_len); | 2086 | elems.wmm_param_len); |
@@ -2656,9 +2665,9 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2656 | 2665 | ||
2657 | bss->timestamp = beacon_timestamp; | 2666 | bss->timestamp = beacon_timestamp; |
2658 | bss->last_update = jiffies; | 2667 | bss->last_update = jiffies; |
2659 | bss->rssi = rx_status->ssi; | ||
2660 | bss->signal = rx_status->signal; | 2668 | bss->signal = rx_status->signal; |
2661 | bss->noise = rx_status->noise; | 2669 | bss->noise = rx_status->noise; |
2670 | bss->qual = rx_status->qual; | ||
2662 | if (!beacon && !bss->probe_resp) | 2671 | if (!beacon && !bss->probe_resp) |
2663 | bss->probe_resp = true; | 2672 | bss->probe_resp = true; |
2664 | 2673 | ||
@@ -2853,10 +2862,8 @@ static void ieee80211_rx_mgmt_beacon(struct net_device *dev, | |||
2853 | 2862 | ||
2854 | ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); | 2863 | ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); |
2855 | 2864 | ||
2856 | if (elems.wmm_param && (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) { | 2865 | ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param, |
2857 | ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param, | 2866 | elems.wmm_param_len); |
2858 | elems.wmm_param_len); | ||
2859 | } | ||
2860 | 2867 | ||
2861 | /* Do not send changes to driver if we are scanning. This removes | 2868 | /* Do not send changes to driver if we are scanning. This removes |
2862 | * requirement that driver's bss_info_changed function needs to be | 2869 | * requirement that driver's bss_info_changed function needs to be |
@@ -3456,9 +3463,9 @@ static int ieee80211_sta_config_auth(struct net_device *dev, | |||
3456 | !ieee80211_sta_match_ssid(ifsta, bss->ssid, bss->ssid_len)) | 3463 | !ieee80211_sta_match_ssid(ifsta, bss->ssid, bss->ssid_len)) |
3457 | continue; | 3464 | continue; |
3458 | 3465 | ||
3459 | if (!selected || top_rssi < bss->rssi) { | 3466 | if (!selected || top_rssi < bss->signal) { |
3460 | selected = bss; | 3467 | selected = bss; |
3461 | top_rssi = bss->rssi; | 3468 | top_rssi = bss->signal; |
3462 | } | 3469 | } |
3463 | } | 3470 | } |
3464 | if (selected) | 3471 | if (selected) |
@@ -4089,8 +4096,8 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
4089 | 4096 | ||
4090 | memset(&iwe, 0, sizeof(iwe)); | 4097 | memset(&iwe, 0, sizeof(iwe)); |
4091 | iwe.cmd = IWEVQUAL; | 4098 | iwe.cmd = IWEVQUAL; |
4092 | iwe.u.qual.qual = bss->signal; | 4099 | iwe.u.qual.qual = bss->qual; |
4093 | iwe.u.qual.level = bss->rssi; | 4100 | iwe.u.qual.level = bss->signal; |
4094 | iwe.u.qual.noise = bss->noise; | 4101 | iwe.u.qual.noise = bss->noise; |
4095 | iwe.u.qual.updated = local->wstats_flags; | 4102 | iwe.u.qual.updated = local->wstats_flags; |
4096 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, | 4103 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, |
@@ -4266,7 +4273,7 @@ struct sta_info *ieee80211_ibss_add_sta(struct net_device *dev, | |||
4266 | if (!sta) | 4273 | if (!sta) |
4267 | return NULL; | 4274 | return NULL; |
4268 | 4275 | ||
4269 | sta->flags |= WLAN_STA_AUTHORIZED; | 4276 | set_sta_flags(sta, WLAN_STA_AUTHORIZED); |
4270 | 4277 | ||
4271 | sta->supp_rates[local->hw.conf.channel->band] = | 4278 | sta->supp_rates[local->hw.conf.channel->band] = |
4272 | sdata->u.sta.supp_rates_bits[local->hw.conf.channel->band]; | 4279 | sdata->u.sta.supp_rates_bits[local->hw.conf.channel->band]; |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 9b5a3cbec265..fa68305fd59e 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -77,6 +77,134 @@ static inline int should_drop_frame(struct ieee80211_rx_status *status, | |||
77 | return 0; | 77 | return 0; |
78 | } | 78 | } |
79 | 79 | ||
80 | static int | ||
81 | ieee80211_rx_radiotap_len(struct ieee80211_local *local, | ||
82 | struct ieee80211_rx_status *status) | ||
83 | { | ||
84 | int len; | ||
85 | |||
86 | /* always present fields */ | ||
87 | len = sizeof(struct ieee80211_radiotap_header) + 9; | ||
88 | |||
89 | if (status->flag & RX_FLAG_TSFT) | ||
90 | len += 8; | ||
91 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DB || | ||
92 | local->hw.flags & IEEE80211_HW_SIGNAL_DBM) | ||
93 | len += 1; | ||
94 | if (local->hw.flags & IEEE80211_HW_NOISE_DBM) | ||
95 | len += 1; | ||
96 | |||
97 | if (len & 1) /* padding for RX_FLAGS if necessary */ | ||
98 | len++; | ||
99 | |||
100 | /* make sure radiotap starts at a naturally aligned address */ | ||
101 | if (len % 8) | ||
102 | len = roundup(len, 8); | ||
103 | |||
104 | return len; | ||
105 | } | ||
106 | |||
107 | /** | ||
108 | * ieee80211_add_rx_radiotap_header - add radiotap header | ||
109 | * | ||
110 | * add a radiotap header containing all the fields which the hardware provided. | ||
111 | */ | ||
112 | static void | ||
113 | ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, | ||
114 | struct sk_buff *skb, | ||
115 | struct ieee80211_rx_status *status, | ||
116 | struct ieee80211_rate *rate, | ||
117 | int rtap_len) | ||
118 | { | ||
119 | struct ieee80211_radiotap_header *rthdr; | ||
120 | unsigned char *pos; | ||
121 | |||
122 | rthdr = (struct ieee80211_radiotap_header *)skb_push(skb, rtap_len); | ||
123 | memset(rthdr, 0, rtap_len); | ||
124 | |||
125 | /* radiotap header, set always present flags */ | ||
126 | rthdr->it_present = | ||
127 | cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | | ||
128 | (1 << IEEE80211_RADIOTAP_RATE) | | ||
129 | (1 << IEEE80211_RADIOTAP_CHANNEL) | | ||
130 | (1 << IEEE80211_RADIOTAP_ANTENNA) | | ||
131 | (1 << IEEE80211_RADIOTAP_RX_FLAGS)); | ||
132 | rthdr->it_len = cpu_to_le16(rtap_len); | ||
133 | |||
134 | pos = (unsigned char *)(rthdr+1); | ||
135 | |||
136 | /* the order of the following fields is important */ | ||
137 | |||
138 | /* IEEE80211_RADIOTAP_TSFT */ | ||
139 | if (status->flag & RX_FLAG_TSFT) { | ||
140 | *(__le64 *)pos = cpu_to_le64(status->mactime); | ||
141 | rthdr->it_present |= | ||
142 | cpu_to_le32(1 << IEEE80211_RADIOTAP_TSFT); | ||
143 | pos += 8; | ||
144 | } | ||
145 | |||
146 | /* IEEE80211_RADIOTAP_FLAGS */ | ||
147 | if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) | ||
148 | *pos |= IEEE80211_RADIOTAP_F_FCS; | ||
149 | pos++; | ||
150 | |||
151 | /* IEEE80211_RADIOTAP_RATE */ | ||
152 | *pos = rate->bitrate / 5; | ||
153 | pos++; | ||
154 | |||
155 | /* IEEE80211_RADIOTAP_CHANNEL */ | ||
156 | *(__le16 *)pos = cpu_to_le16(status->freq); | ||
157 | pos += 2; | ||
158 | if (status->band == IEEE80211_BAND_5GHZ) | ||
159 | *(__le16 *)pos = cpu_to_le16(IEEE80211_CHAN_OFDM | | ||
160 | IEEE80211_CHAN_5GHZ); | ||
161 | else | ||
162 | *(__le16 *)pos = cpu_to_le16(IEEE80211_CHAN_DYN | | ||
163 | IEEE80211_CHAN_2GHZ); | ||
164 | pos += 2; | ||
165 | |||
166 | /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */ | ||
167 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) { | ||
168 | *pos = status->signal; | ||
169 | rthdr->it_present |= | ||
170 | cpu_to_le32(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL); | ||
171 | pos++; | ||
172 | } | ||
173 | |||
174 | /* IEEE80211_RADIOTAP_DBM_ANTNOISE */ | ||
175 | if (local->hw.flags & IEEE80211_HW_NOISE_DBM) { | ||
176 | *pos = status->noise; | ||
177 | rthdr->it_present |= | ||
178 | cpu_to_le32(1 << IEEE80211_RADIOTAP_DBM_ANTNOISE); | ||
179 | pos++; | ||
180 | } | ||
181 | |||
182 | /* IEEE80211_RADIOTAP_LOCK_QUALITY is missing */ | ||
183 | |||
184 | /* IEEE80211_RADIOTAP_ANTENNA */ | ||
185 | *pos = status->antenna; | ||
186 | pos++; | ||
187 | |||
188 | /* IEEE80211_RADIOTAP_DB_ANTSIGNAL */ | ||
189 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DB) { | ||
190 | *pos = status->signal; | ||
191 | rthdr->it_present |= | ||
192 | cpu_to_le32(1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL); | ||
193 | pos++; | ||
194 | } | ||
195 | |||
196 | /* IEEE80211_RADIOTAP_DB_ANTNOISE is not used */ | ||
197 | |||
198 | /* IEEE80211_RADIOTAP_RX_FLAGS */ | ||
199 | /* ensure 2 byte alignment for the 2 byte field as required */ | ||
200 | if ((pos - (unsigned char *)rthdr) & 1) | ||
201 | pos++; | ||
202 | /* FIXME: when radiotap gets a 'bad PLCP' flag use it here */ | ||
203 | if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC)) | ||
204 | *(__le16 *)pos |= cpu_to_le16(IEEE80211_RADIOTAP_F_RX_BADFCS); | ||
205 | pos += 2; | ||
206 | } | ||
207 | |||
80 | /* | 208 | /* |
81 | * This function copies a received frame to all monitor interfaces and | 209 | * This function copies a received frame to all monitor interfaces and |
82 | * returns a cleaned-up SKB that no longer includes the FCS nor the | 210 | * returns a cleaned-up SKB that no longer includes the FCS nor the |
@@ -89,17 +217,6 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, | |||
89 | { | 217 | { |
90 | struct ieee80211_sub_if_data *sdata; | 218 | struct ieee80211_sub_if_data *sdata; |
91 | int needed_headroom = 0; | 219 | int needed_headroom = 0; |
92 | struct ieee80211_radiotap_header *rthdr; | ||
93 | __le64 *rttsft = NULL; | ||
94 | struct ieee80211_rtap_fixed_data { | ||
95 | u8 flags; | ||
96 | u8 rate; | ||
97 | __le16 chan_freq; | ||
98 | __le16 chan_flags; | ||
99 | u8 antsignal; | ||
100 | u8 padding_for_rxflags; | ||
101 | __le16 rx_flags; | ||
102 | } __attribute__ ((packed)) *rtfixed; | ||
103 | struct sk_buff *skb, *skb2; | 220 | struct sk_buff *skb, *skb2; |
104 | struct net_device *prev_dev = NULL; | 221 | struct net_device *prev_dev = NULL; |
105 | int present_fcs_len = 0; | 222 | int present_fcs_len = 0; |
@@ -116,8 +233,8 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, | |||
116 | if (status->flag & RX_FLAG_RADIOTAP) | 233 | if (status->flag & RX_FLAG_RADIOTAP) |
117 | rtap_len = ieee80211_get_radiotap_len(origskb->data); | 234 | rtap_len = ieee80211_get_radiotap_len(origskb->data); |
118 | else | 235 | else |
119 | /* room for radiotap header, always present fields and TSFT */ | 236 | /* room for the radiotap header based on driver features */ |
120 | needed_headroom = sizeof(*rthdr) + sizeof(*rtfixed) + 8; | 237 | needed_headroom = ieee80211_rx_radiotap_len(local, status); |
121 | 238 | ||
122 | if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) | 239 | if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) |
123 | present_fcs_len = FCS_LEN; | 240 | present_fcs_len = FCS_LEN; |
@@ -163,55 +280,9 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, | |||
163 | } | 280 | } |
164 | 281 | ||
165 | /* if necessary, prepend radiotap information */ | 282 | /* if necessary, prepend radiotap information */ |
166 | if (!(status->flag & RX_FLAG_RADIOTAP)) { | 283 | if (!(status->flag & RX_FLAG_RADIOTAP)) |
167 | rtfixed = (void *) skb_push(skb, sizeof(*rtfixed)); | 284 | ieee80211_add_rx_radiotap_header(local, skb, status, rate, |
168 | rtap_len = sizeof(*rthdr) + sizeof(*rtfixed); | 285 | needed_headroom); |
169 | if (status->flag & RX_FLAG_TSFT) { | ||
170 | rttsft = (void *) skb_push(skb, sizeof(*rttsft)); | ||
171 | rtap_len += 8; | ||
172 | } | ||
173 | rthdr = (void *) skb_push(skb, sizeof(*rthdr)); | ||
174 | memset(rthdr, 0, sizeof(*rthdr)); | ||
175 | memset(rtfixed, 0, sizeof(*rtfixed)); | ||
176 | rthdr->it_present = | ||
177 | cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | | ||
178 | (1 << IEEE80211_RADIOTAP_RATE) | | ||
179 | (1 << IEEE80211_RADIOTAP_CHANNEL) | | ||
180 | (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | | ||
181 | (1 << IEEE80211_RADIOTAP_RX_FLAGS)); | ||
182 | rtfixed->flags = 0; | ||
183 | if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) | ||
184 | rtfixed->flags |= IEEE80211_RADIOTAP_F_FCS; | ||
185 | |||
186 | if (rttsft) { | ||
187 | *rttsft = cpu_to_le64(status->mactime); | ||
188 | rthdr->it_present |= | ||
189 | cpu_to_le32(1 << IEEE80211_RADIOTAP_TSFT); | ||
190 | } | ||
191 | |||
192 | /* FIXME: when radiotap gets a 'bad PLCP' flag use it here */ | ||
193 | rtfixed->rx_flags = 0; | ||
194 | if (status->flag & | ||
195 | (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC)) | ||
196 | rtfixed->rx_flags |= | ||
197 | cpu_to_le16(IEEE80211_RADIOTAP_F_RX_BADFCS); | ||
198 | |||
199 | rtfixed->rate = rate->bitrate / 5; | ||
200 | |||
201 | rtfixed->chan_freq = cpu_to_le16(status->freq); | ||
202 | |||
203 | if (status->band == IEEE80211_BAND_5GHZ) | ||
204 | rtfixed->chan_flags = | ||
205 | cpu_to_le16(IEEE80211_CHAN_OFDM | | ||
206 | IEEE80211_CHAN_5GHZ); | ||
207 | else | ||
208 | rtfixed->chan_flags = | ||
209 | cpu_to_le16(IEEE80211_CHAN_DYN | | ||
210 | IEEE80211_CHAN_2GHZ); | ||
211 | |||
212 | rtfixed->antsignal = status->ssi; | ||
213 | rthdr->it_len = cpu_to_le16(rtap_len); | ||
214 | } | ||
215 | 286 | ||
216 | skb_reset_mac_header(skb); | 287 | skb_reset_mac_header(skb); |
217 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 288 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
@@ -479,7 +550,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) | |||
479 | ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL && | 550 | ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL && |
480 | (rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)) && | 551 | (rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)) && |
481 | rx->sdata->vif.type != IEEE80211_IF_TYPE_IBSS && | 552 | rx->sdata->vif.type != IEEE80211_IF_TYPE_IBSS && |
482 | (!rx->sta || !(rx->sta->flags & WLAN_STA_ASSOC)))) { | 553 | (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) { |
483 | if ((!(rx->fc & IEEE80211_FCTL_FROMDS) && | 554 | if ((!(rx->fc & IEEE80211_FCTL_FROMDS) && |
484 | !(rx->fc & IEEE80211_FCTL_TODS) && | 555 | !(rx->fc & IEEE80211_FCTL_TODS) && |
485 | (rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) | 556 | (rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) |
@@ -630,8 +701,7 @@ static void ap_sta_ps_start(struct net_device *dev, struct sta_info *sta) | |||
630 | 701 | ||
631 | if (sdata->bss) | 702 | if (sdata->bss) |
632 | atomic_inc(&sdata->bss->num_sta_ps); | 703 | atomic_inc(&sdata->bss->num_sta_ps); |
633 | sta->flags |= WLAN_STA_PS; | 704 | set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL); |
634 | sta->flags &= ~WLAN_STA_PSPOLL; | ||
635 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 705 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
636 | printk(KERN_DEBUG "%s: STA %s aid %d enters power save mode\n", | 706 | printk(KERN_DEBUG "%s: STA %s aid %d enters power save mode\n", |
637 | dev->name, print_mac(mac, sta->addr), sta->aid); | 707 | dev->name, print_mac(mac, sta->addr), sta->aid); |
@@ -652,7 +722,7 @@ static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta) | |||
652 | if (sdata->bss) | 722 | if (sdata->bss) |
653 | atomic_dec(&sdata->bss->num_sta_ps); | 723 | atomic_dec(&sdata->bss->num_sta_ps); |
654 | 724 | ||
655 | sta->flags &= ~(WLAN_STA_PS | WLAN_STA_PSPOLL); | 725 | clear_sta_flags(sta, WLAN_STA_PS | WLAN_STA_PSPOLL); |
656 | 726 | ||
657 | if (!skb_queue_empty(&sta->ps_tx_buf)) | 727 | if (!skb_queue_empty(&sta->ps_tx_buf)) |
658 | sta_info_clear_tim_bit(sta); | 728 | sta_info_clear_tim_bit(sta); |
@@ -720,16 +790,17 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | |||
720 | 790 | ||
721 | sta->rx_fragments++; | 791 | sta->rx_fragments++; |
722 | sta->rx_bytes += rx->skb->len; | 792 | sta->rx_bytes += rx->skb->len; |
723 | sta->last_rssi = rx->status->ssi; | ||
724 | sta->last_signal = rx->status->signal; | 793 | sta->last_signal = rx->status->signal; |
794 | sta->last_qual = rx->status->qual; | ||
725 | sta->last_noise = rx->status->noise; | 795 | sta->last_noise = rx->status->noise; |
726 | 796 | ||
727 | if (!(rx->fc & IEEE80211_FCTL_MOREFRAGS)) { | 797 | if (!(rx->fc & IEEE80211_FCTL_MOREFRAGS)) { |
728 | /* Change STA power saving mode only in the end of a frame | 798 | /* Change STA power saving mode only in the end of a frame |
729 | * exchange sequence */ | 799 | * exchange sequence */ |
730 | if ((sta->flags & WLAN_STA_PS) && !(rx->fc & IEEE80211_FCTL_PM)) | 800 | if (test_sta_flags(sta, WLAN_STA_PS) && |
801 | !(rx->fc & IEEE80211_FCTL_PM)) | ||
731 | rx->sent_ps_buffered += ap_sta_ps_end(dev, sta); | 802 | rx->sent_ps_buffered += ap_sta_ps_end(dev, sta); |
732 | else if (!(sta->flags & WLAN_STA_PS) && | 803 | else if (!test_sta_flags(sta, WLAN_STA_PS) && |
733 | (rx->fc & IEEE80211_FCTL_PM)) | 804 | (rx->fc & IEEE80211_FCTL_PM)) |
734 | ap_sta_ps_start(dev, sta); | 805 | ap_sta_ps_start(dev, sta); |
735 | } | 806 | } |
@@ -983,7 +1054,7 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) | |||
983 | * Tell TX path to send one frame even though the STA may | 1054 | * Tell TX path to send one frame even though the STA may |
984 | * still remain is PS mode after this frame exchange. | 1055 | * still remain is PS mode after this frame exchange. |
985 | */ | 1056 | */ |
986 | rx->sta->flags |= WLAN_STA_PSPOLL; | 1057 | set_sta_flags(rx->sta, WLAN_STA_PSPOLL); |
987 | 1058 | ||
988 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 1059 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
989 | printk(KERN_DEBUG "STA %s aid %d: PS Poll (entries after %d)\n", | 1060 | printk(KERN_DEBUG "STA %s aid %d: PS Poll (entries after %d)\n", |
@@ -1046,7 +1117,8 @@ ieee80211_rx_h_remove_qos_control(struct ieee80211_rx_data *rx) | |||
1046 | static int | 1117 | static int |
1047 | ieee80211_802_1x_port_control(struct ieee80211_rx_data *rx) | 1118 | ieee80211_802_1x_port_control(struct ieee80211_rx_data *rx) |
1048 | { | 1119 | { |
1049 | if (unlikely(!rx->sta || !(rx->sta->flags & WLAN_STA_AUTHORIZED))) { | 1120 | if (unlikely(!rx->sta || |
1121 | !test_sta_flags(rx->sta, WLAN_STA_AUTHORIZED))) { | ||
1050 | #ifdef CONFIG_MAC80211_DEBUG | 1122 | #ifdef CONFIG_MAC80211_DEBUG |
1051 | if (net_ratelimit()) | 1123 | if (net_ratelimit()) |
1052 | printk(KERN_DEBUG "%s: dropped frame " | 1124 | printk(KERN_DEBUG "%s: dropped frame " |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 631943e8af8b..baf5e4746884 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -202,14 +202,12 @@ void sta_info_destroy(struct sta_info *sta) | |||
202 | dev_kfree_skb_any(skb); | 202 | dev_kfree_skb_any(skb); |
203 | 203 | ||
204 | for (i = 0; i < STA_TID_NUM; i++) { | 204 | for (i = 0; i < STA_TID_NUM; i++) { |
205 | spin_lock_bh(&sta->ampdu_mlme.ampdu_rx); | 205 | spin_lock_bh(&sta->lock); |
206 | if (sta->ampdu_mlme.tid_rx[i]) | 206 | if (sta->ampdu_mlme.tid_rx[i]) |
207 | del_timer_sync(&sta->ampdu_mlme.tid_rx[i]->session_timer); | 207 | del_timer_sync(&sta->ampdu_mlme.tid_rx[i]->session_timer); |
208 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx); | ||
209 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
210 | if (sta->ampdu_mlme.tid_tx[i]) | 208 | if (sta->ampdu_mlme.tid_tx[i]) |
211 | del_timer_sync(&sta->ampdu_mlme.tid_tx[i]->addba_resp_timer); | 209 | del_timer_sync(&sta->ampdu_mlme.tid_tx[i]->addba_resp_timer); |
212 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 210 | spin_unlock_bh(&sta->lock); |
213 | } | 211 | } |
214 | 212 | ||
215 | __sta_info_free(local, sta); | 213 | __sta_info_free(local, sta); |
@@ -236,6 +234,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
236 | if (!sta) | 234 | if (!sta) |
237 | return NULL; | 235 | return NULL; |
238 | 236 | ||
237 | spin_lock_init(&sta->lock); | ||
238 | |||
239 | memcpy(sta->addr, addr, ETH_ALEN); | 239 | memcpy(sta->addr, addr, ETH_ALEN); |
240 | sta->local = local; | 240 | sta->local = local; |
241 | sta->sdata = sdata; | 241 | sta->sdata = sdata; |
@@ -249,8 +249,6 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
249 | return NULL; | 249 | return NULL; |
250 | } | 250 | } |
251 | 251 | ||
252 | spin_lock_init(&sta->ampdu_mlme.ampdu_rx); | ||
253 | spin_lock_init(&sta->ampdu_mlme.ampdu_tx); | ||
254 | for (i = 0; i < STA_TID_NUM; i++) { | 252 | for (i = 0; i < STA_TID_NUM; i++) { |
255 | /* timer_to_tid must be initialized with identity mapping to | 253 | /* timer_to_tid must be initialized with identity mapping to |
256 | * enable session_timer's data differentiation. refer to | 254 | * enable session_timer's data differentiation. refer to |
@@ -276,7 +274,6 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
276 | 274 | ||
277 | #ifdef CONFIG_MAC80211_MESH | 275 | #ifdef CONFIG_MAC80211_MESH |
278 | sta->plink_state = PLINK_LISTEN; | 276 | sta->plink_state = PLINK_LISTEN; |
279 | spin_lock_init(&sta->plink_lock); | ||
280 | init_timer(&sta->plink_timer); | 277 | init_timer(&sta->plink_timer); |
281 | #endif | 278 | #endif |
282 | 279 | ||
@@ -437,8 +434,7 @@ void __sta_info_unlink(struct sta_info **sta) | |||
437 | 434 | ||
438 | list_del(&(*sta)->list); | 435 | list_del(&(*sta)->list); |
439 | 436 | ||
440 | if ((*sta)->flags & WLAN_STA_PS) { | 437 | if (test_and_clear_sta_flags(*sta, WLAN_STA_PS)) { |
441 | (*sta)->flags &= ~WLAN_STA_PS; | ||
442 | if (sdata->bss) | 438 | if (sdata->bss) |
443 | atomic_dec(&sdata->bss->num_sta_ps); | 439 | atomic_dec(&sdata->bss->num_sta_ps); |
444 | __sta_info_clear_tim_bit(sdata->bss, *sta); | 440 | __sta_info_clear_tim_bit(sdata->bss, *sta); |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index f8c95bc9659c..e89cc1655547 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -129,23 +129,19 @@ enum plink_state { | |||
129 | * | 129 | * |
130 | * @tid_state_rx: TID's state in Rx session state machine. | 130 | * @tid_state_rx: TID's state in Rx session state machine. |
131 | * @tid_rx: aggregation info for Rx per TID | 131 | * @tid_rx: aggregation info for Rx per TID |
132 | * @ampdu_rx: for locking sections in aggregation Rx flow | ||
133 | * @tid_state_tx: TID's state in Tx session state machine. | 132 | * @tid_state_tx: TID's state in Tx session state machine. |
134 | * @tid_tx: aggregation info for Tx per TID | 133 | * @tid_tx: aggregation info for Tx per TID |
135 | * @addba_req_num: number of times addBA request has been sent. | 134 | * @addba_req_num: number of times addBA request has been sent. |
136 | * @ampdu_tx: for locking sectionsi in aggregation Tx flow | ||
137 | * @dialog_token_allocator: dialog token enumerator for each new session; | 135 | * @dialog_token_allocator: dialog token enumerator for each new session; |
138 | */ | 136 | */ |
139 | struct sta_ampdu_mlme { | 137 | struct sta_ampdu_mlme { |
140 | /* rx */ | 138 | /* rx */ |
141 | u8 tid_state_rx[STA_TID_NUM]; | 139 | u8 tid_state_rx[STA_TID_NUM]; |
142 | struct tid_ampdu_rx *tid_rx[STA_TID_NUM]; | 140 | struct tid_ampdu_rx *tid_rx[STA_TID_NUM]; |
143 | spinlock_t ampdu_rx; | ||
144 | /* tx */ | 141 | /* tx */ |
145 | u8 tid_state_tx[STA_TID_NUM]; | 142 | u8 tid_state_tx[STA_TID_NUM]; |
146 | struct tid_ampdu_tx *tid_tx[STA_TID_NUM]; | 143 | struct tid_ampdu_tx *tid_tx[STA_TID_NUM]; |
147 | u8 addba_req_num[STA_TID_NUM]; | 144 | u8 addba_req_num[STA_TID_NUM]; |
148 | spinlock_t ampdu_tx; | ||
149 | u8 dialog_token_allocator; | 145 | u8 dialog_token_allocator; |
150 | }; | 146 | }; |
151 | 147 | ||
@@ -177,6 +173,8 @@ struct sta_ampdu_mlme { | |||
177 | * @rx_bytes: Number of bytes received from this STA | 173 | * @rx_bytes: Number of bytes received from this STA |
178 | * @supp_rates: Bitmap of supported rates (per band) | 174 | * @supp_rates: Bitmap of supported rates (per band) |
179 | * @ht_info: HT capabilities of this STA | 175 | * @ht_info: HT capabilities of this STA |
176 | * @lock: used for locking all fields that require locking, see comments | ||
177 | * in the header file. | ||
180 | */ | 178 | */ |
181 | struct sta_info { | 179 | struct sta_info { |
182 | /* General information, mostly static */ | 180 | /* General information, mostly static */ |
@@ -187,6 +185,7 @@ struct sta_info { | |||
187 | struct ieee80211_key *key; | 185 | struct ieee80211_key *key; |
188 | struct rate_control_ref *rate_ctrl; | 186 | struct rate_control_ref *rate_ctrl; |
189 | void *rate_ctrl_priv; | 187 | void *rate_ctrl_priv; |
188 | spinlock_t lock; | ||
190 | struct ieee80211_ht_info ht_info; | 189 | struct ieee80211_ht_info ht_info; |
191 | u64 supp_rates[IEEE80211_NUM_BANDS]; | 190 | u64 supp_rates[IEEE80211_NUM_BANDS]; |
192 | u8 addr[ETH_ALEN]; | 191 | u8 addr[ETH_ALEN]; |
@@ -199,7 +198,7 @@ struct sta_info { | |||
199 | */ | 198 | */ |
200 | u8 pin_status; | 199 | u8 pin_status; |
201 | 200 | ||
202 | /* frequently updated information, needs locking? */ | 201 | /* frequently updated information, locked with lock spinlock */ |
203 | u32 flags; | 202 | u32 flags; |
204 | 203 | ||
205 | /* | 204 | /* |
@@ -217,8 +216,8 @@ struct sta_info { | |||
217 | * from this STA */ | 216 | * from this STA */ |
218 | unsigned long rx_fragments; /* number of received MPDUs */ | 217 | unsigned long rx_fragments; /* number of received MPDUs */ |
219 | unsigned long rx_dropped; /* number of dropped MPDUs from this STA */ | 218 | unsigned long rx_dropped; /* number of dropped MPDUs from this STA */ |
220 | int last_rssi; /* RSSI of last received frame from this STA */ | ||
221 | int last_signal; /* signal of last received frame from this STA */ | 219 | int last_signal; /* signal of last received frame from this STA */ |
220 | int last_qual; /* qual of last received frame from this STA */ | ||
222 | int last_noise; /* noise of last received frame from this STA */ | 221 | int last_noise; /* noise of last received frame from this STA */ |
223 | /* last received seq/frag number from this STA (per RX queue) */ | 222 | /* last received seq/frag number from this STA (per RX queue) */ |
224 | __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES]; | 223 | __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES]; |
@@ -251,7 +250,7 @@ struct sta_info { | |||
251 | int channel_use_raw; | 250 | int channel_use_raw; |
252 | 251 | ||
253 | /* | 252 | /* |
254 | * Aggregation information, comes with own locking. | 253 | * Aggregation information, locked with lock. |
255 | */ | 254 | */ |
256 | struct sta_ampdu_mlme ampdu_mlme; | 255 | struct sta_ampdu_mlme ampdu_mlme; |
257 | u8 timer_to_tid[STA_TID_NUM]; /* identity mapping to ID timers */ | 256 | u8 timer_to_tid[STA_TID_NUM]; /* identity mapping to ID timers */ |
@@ -270,9 +269,6 @@ struct sta_info { | |||
270 | enum plink_state plink_state; | 269 | enum plink_state plink_state; |
271 | u32 plink_timeout; | 270 | u32 plink_timeout; |
272 | struct timer_list plink_timer; | 271 | struct timer_list plink_timer; |
273 | spinlock_t plink_lock; /* For peer_state reads / updates and other | ||
274 | updates in the structure. Ensures robust | ||
275 | transitions for the peerlink FSM */ | ||
276 | #endif | 272 | #endif |
277 | 273 | ||
278 | #ifdef CONFIG_MAC80211_DEBUGFS | 274 | #ifdef CONFIG_MAC80211_DEBUGFS |
@@ -299,6 +295,64 @@ static inline enum plink_state sta_plink_state(struct sta_info *sta) | |||
299 | return PLINK_LISTEN; | 295 | return PLINK_LISTEN; |
300 | } | 296 | } |
301 | 297 | ||
298 | static inline void set_sta_flags(struct sta_info *sta, const u32 flags) | ||
299 | { | ||
300 | spin_lock_bh(&sta->lock); | ||
301 | sta->flags |= flags; | ||
302 | spin_unlock_bh(&sta->lock); | ||
303 | } | ||
304 | |||
305 | static inline void clear_sta_flags(struct sta_info *sta, const u32 flags) | ||
306 | { | ||
307 | spin_lock_bh(&sta->lock); | ||
308 | sta->flags &= ~flags; | ||
309 | spin_unlock_bh(&sta->lock); | ||
310 | } | ||
311 | |||
312 | static inline void set_and_clear_sta_flags(struct sta_info *sta, | ||
313 | const u32 set, const u32 clear) | ||
314 | { | ||
315 | spin_lock_bh(&sta->lock); | ||
316 | sta->flags |= set; | ||
317 | sta->flags &= ~clear; | ||
318 | spin_unlock_bh(&sta->lock); | ||
319 | } | ||
320 | |||
321 | static inline u32 test_sta_flags(struct sta_info *sta, const u32 flags) | ||
322 | { | ||
323 | u32 ret; | ||
324 | |||
325 | spin_lock_bh(&sta->lock); | ||
326 | ret = sta->flags & flags; | ||
327 | spin_unlock_bh(&sta->lock); | ||
328 | |||
329 | return ret; | ||
330 | } | ||
331 | |||
332 | static inline u32 test_and_clear_sta_flags(struct sta_info *sta, | ||
333 | const u32 flags) | ||
334 | { | ||
335 | u32 ret; | ||
336 | |||
337 | spin_lock_bh(&sta->lock); | ||
338 | ret = sta->flags & flags; | ||
339 | sta->flags &= ~flags; | ||
340 | spin_unlock_bh(&sta->lock); | ||
341 | |||
342 | return ret; | ||
343 | } | ||
344 | |||
345 | static inline u32 get_sta_flags(struct sta_info *sta) | ||
346 | { | ||
347 | u32 ret; | ||
348 | |||
349 | spin_lock_bh(&sta->lock); | ||
350 | ret = sta->flags; | ||
351 | spin_unlock_bh(&sta->lock); | ||
352 | |||
353 | return ret; | ||
354 | } | ||
355 | |||
302 | 356 | ||
303 | /* Maximum number of concurrently registered stations */ | 357 | /* Maximum number of concurrently registered stations */ |
304 | #define MAX_STA_COUNT 2007 | 358 | #define MAX_STA_COUNT 2007 |
diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c index 09093da24af6..a7c3febc5a45 100644 --- a/net/mac80211/tkip.c +++ b/net/mac80211/tkip.c | |||
@@ -8,23 +8,22 @@ | |||
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
11 | #include <linux/bitops.h> | ||
11 | #include <linux/types.h> | 12 | #include <linux/types.h> |
12 | #include <linux/netdevice.h> | 13 | #include <linux/netdevice.h> |
14 | #include <asm/unaligned.h> | ||
13 | 15 | ||
14 | #include <net/mac80211.h> | 16 | #include <net/mac80211.h> |
15 | #include "key.h" | 17 | #include "key.h" |
16 | #include "tkip.h" | 18 | #include "tkip.h" |
17 | #include "wep.h" | 19 | #include "wep.h" |
18 | 20 | ||
19 | |||
20 | /* TKIP key mixing functions */ | ||
21 | |||
22 | |||
23 | #define PHASE1_LOOP_COUNT 8 | 21 | #define PHASE1_LOOP_COUNT 8 |
24 | 22 | ||
25 | 23 | /* | |
26 | /* 2-byte by 2-byte subset of the full AES S-box table; second part of this | 24 | * 2-byte by 2-byte subset of the full AES S-box table; second part of this |
27 | * table is identical to first part but byte-swapped */ | 25 | * table is identical to first part but byte-swapped |
26 | */ | ||
28 | static const u16 tkip_sbox[256] = | 27 | static const u16 tkip_sbox[256] = |
29 | { | 28 | { |
30 | 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154, | 29 | 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154, |
@@ -61,53 +60,13 @@ static const u16 tkip_sbox[256] = | |||
61 | 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A, | 60 | 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A, |
62 | }; | 61 | }; |
63 | 62 | ||
64 | 63 | static u16 tkipS(u16 val) | |
65 | static inline u16 Mk16(u8 x, u8 y) | ||
66 | { | ||
67 | return ((u16) x << 8) | (u16) y; | ||
68 | } | ||
69 | |||
70 | |||
71 | static inline u8 Hi8(u16 v) | ||
72 | { | ||
73 | return v >> 8; | ||
74 | } | ||
75 | |||
76 | |||
77 | static inline u8 Lo8(u16 v) | ||
78 | { | ||
79 | return v & 0xff; | ||
80 | } | ||
81 | |||
82 | |||
83 | static inline u16 Hi16(u32 v) | ||
84 | { | ||
85 | return v >> 16; | ||
86 | } | ||
87 | |||
88 | |||
89 | static inline u16 Lo16(u32 v) | ||
90 | { | ||
91 | return v & 0xffff; | ||
92 | } | ||
93 | |||
94 | |||
95 | static inline u16 RotR1(u16 v) | ||
96 | { | 64 | { |
97 | return (v >> 1) | ((v & 0x0001) << 15); | 65 | return tkip_sbox[val & 0xff] ^ swab16(tkip_sbox[val >> 8]); |
98 | } | ||
99 | |||
100 | |||
101 | static inline u16 tkip_S(u16 val) | ||
102 | { | ||
103 | u16 a = tkip_sbox[Hi8(val)]; | ||
104 | |||
105 | return tkip_sbox[Lo8(val)] ^ Hi8(a) ^ (Lo8(a) << 8); | ||
106 | } | 66 | } |
107 | 67 | ||
108 | 68 | /* | |
109 | 69 | * P1K := Phase1(TA, TK, TSC) | |
110 | /* P1K := Phase1(TA, TK, TSC) | ||
111 | * TA = transmitter address (48 bits) | 70 | * TA = transmitter address (48 bits) |
112 | * TK = dot11DefaultKeyValue or dot11KeyMappingValue (128 bits) | 71 | * TK = dot11DefaultKeyValue or dot11KeyMappingValue (128 bits) |
113 | * TSC = TKIP sequence counter (48 bits, only 32 msb bits used) | 72 | * TSC = TKIP sequence counter (48 bits, only 32 msb bits used) |
@@ -118,23 +77,22 @@ static void tkip_mixing_phase1(const u8 *ta, const u8 *tk, u32 tsc_IV32, | |||
118 | { | 77 | { |
119 | int i, j; | 78 | int i, j; |
120 | 79 | ||
121 | p1k[0] = Lo16(tsc_IV32); | 80 | p1k[0] = tsc_IV32 & 0xFFFF; |
122 | p1k[1] = Hi16(tsc_IV32); | 81 | p1k[1] = tsc_IV32 >> 16; |
123 | p1k[2] = Mk16(ta[1], ta[0]); | 82 | p1k[2] = get_unaligned_le16(ta + 0); |
124 | p1k[3] = Mk16(ta[3], ta[2]); | 83 | p1k[3] = get_unaligned_le16(ta + 2); |
125 | p1k[4] = Mk16(ta[5], ta[4]); | 84 | p1k[4] = get_unaligned_le16(ta + 4); |
126 | 85 | ||
127 | for (i = 0; i < PHASE1_LOOP_COUNT; i++) { | 86 | for (i = 0; i < PHASE1_LOOP_COUNT; i++) { |
128 | j = 2 * (i & 1); | 87 | j = 2 * (i & 1); |
129 | p1k[0] += tkip_S(p1k[4] ^ Mk16(tk[ 1 + j], tk[ 0 + j])); | 88 | p1k[0] += tkipS(p1k[4] ^ get_unaligned_le16(tk + 0 + j)); |
130 | p1k[1] += tkip_S(p1k[0] ^ Mk16(tk[ 5 + j], tk[ 4 + j])); | 89 | p1k[1] += tkipS(p1k[0] ^ get_unaligned_le16(tk + 4 + j)); |
131 | p1k[2] += tkip_S(p1k[1] ^ Mk16(tk[ 9 + j], tk[ 8 + j])); | 90 | p1k[2] += tkipS(p1k[1] ^ get_unaligned_le16(tk + 8 + j)); |
132 | p1k[3] += tkip_S(p1k[2] ^ Mk16(tk[13 + j], tk[12 + j])); | 91 | p1k[3] += tkipS(p1k[2] ^ get_unaligned_le16(tk + 12 + j)); |
133 | p1k[4] += tkip_S(p1k[3] ^ Mk16(tk[ 1 + j], tk[ 0 + j])) + i; | 92 | p1k[4] += tkipS(p1k[3] ^ get_unaligned_le16(tk + 0 + j)) + i; |
134 | } | 93 | } |
135 | } | 94 | } |
136 | 95 | ||
137 | |||
138 | static void tkip_mixing_phase2(const u16 *p1k, const u8 *tk, u16 tsc_IV16, | 96 | static void tkip_mixing_phase2(const u16 *p1k, const u8 *tk, u16 tsc_IV16, |
139 | u8 *rc4key) | 97 | u8 *rc4key) |
140 | { | 98 | { |
@@ -148,31 +106,29 @@ static void tkip_mixing_phase2(const u16 *p1k, const u8 *tk, u16 tsc_IV16, | |||
148 | ppk[4] = p1k[4]; | 106 | ppk[4] = p1k[4]; |
149 | ppk[5] = p1k[4] + tsc_IV16; | 107 | ppk[5] = p1k[4] + tsc_IV16; |
150 | 108 | ||
151 | ppk[0] += tkip_S(ppk[5] ^ Mk16(tk[ 1], tk[ 0])); | 109 | ppk[0] += tkipS(ppk[5] ^ get_unaligned_le16(tk + 0)); |
152 | ppk[1] += tkip_S(ppk[0] ^ Mk16(tk[ 3], tk[ 2])); | 110 | ppk[1] += tkipS(ppk[0] ^ get_unaligned_le16(tk + 2)); |
153 | ppk[2] += tkip_S(ppk[1] ^ Mk16(tk[ 5], tk[ 4])); | 111 | ppk[2] += tkipS(ppk[1] ^ get_unaligned_le16(tk + 4)); |
154 | ppk[3] += tkip_S(ppk[2] ^ Mk16(tk[ 7], tk[ 6])); | 112 | ppk[3] += tkipS(ppk[2] ^ get_unaligned_le16(tk + 6)); |
155 | ppk[4] += tkip_S(ppk[3] ^ Mk16(tk[ 9], tk[ 8])); | 113 | ppk[4] += tkipS(ppk[3] ^ get_unaligned_le16(tk + 8)); |
156 | ppk[5] += tkip_S(ppk[4] ^ Mk16(tk[11], tk[10])); | 114 | ppk[5] += tkipS(ppk[4] ^ get_unaligned_le16(tk + 10)); |
157 | ppk[0] += RotR1(ppk[5] ^ Mk16(tk[13], tk[12])); | 115 | ppk[0] += ror16(ppk[5] ^ get_unaligned_le16(tk + 12), 1); |
158 | ppk[1] += RotR1(ppk[0] ^ Mk16(tk[15], tk[14])); | 116 | ppk[1] += ror16(ppk[0] ^ get_unaligned_le16(tk + 14), 1); |
159 | ppk[2] += RotR1(ppk[1]); | 117 | ppk[2] += ror16(ppk[1], 1); |
160 | ppk[3] += RotR1(ppk[2]); | 118 | ppk[3] += ror16(ppk[2], 1); |
161 | ppk[4] += RotR1(ppk[3]); | 119 | ppk[4] += ror16(ppk[3], 1); |
162 | ppk[5] += RotR1(ppk[4]); | 120 | ppk[5] += ror16(ppk[4], 1); |
163 | 121 | ||
164 | rc4key[0] = Hi8(tsc_IV16); | 122 | rc4key[0] = tsc_IV16 >> 8; |
165 | rc4key[1] = (Hi8(tsc_IV16) | 0x20) & 0x7f; | 123 | rc4key[1] = ((tsc_IV16 >> 8) | 0x20) & 0x7f; |
166 | rc4key[2] = Lo8(tsc_IV16); | 124 | rc4key[2] = tsc_IV16 & 0xFF; |
167 | rc4key[3] = Lo8((ppk[5] ^ Mk16(tk[1], tk[0])) >> 1); | 125 | rc4key[3] = ((ppk[5] ^ get_unaligned_le16(tk)) >> 1) & 0xFF; |
168 | 126 | ||
169 | for (i = 0; i < 6; i++) { | 127 | rc4key += 4; |
170 | rc4key[4 + 2 * i] = Lo8(ppk[i]); | 128 | for (i = 0; i < 6; i++) |
171 | rc4key[5 + 2 * i] = Hi8(ppk[i]); | 129 | put_unaligned_le16(ppk[i], rc4key + 2 * i); |
172 | } | ||
173 | } | 130 | } |
174 | 131 | ||
175 | |||
176 | /* Add TKIP IV and Ext. IV at @pos. @iv0, @iv1, and @iv2 are the first octets | 132 | /* Add TKIP IV and Ext. IV at @pos. @iv0, @iv1, and @iv2 are the first octets |
177 | * of the IV. Returns pointer to the octet following IVs (i.e., beginning of | 133 | * of the IV. Returns pointer to the octet following IVs (i.e., beginning of |
178 | * the packet payload). */ | 134 | * the packet payload). */ |
@@ -183,14 +139,10 @@ u8 * ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, | |||
183 | *pos++ = iv1; | 139 | *pos++ = iv1; |
184 | *pos++ = iv2; | 140 | *pos++ = iv2; |
185 | *pos++ = (key->conf.keyidx << 6) | (1 << 5) /* Ext IV */; | 141 | *pos++ = (key->conf.keyidx << 6) | (1 << 5) /* Ext IV */; |
186 | *pos++ = key->u.tkip.iv32 & 0xff; | 142 | put_unaligned_le32(key->u.tkip.iv32, pos); |
187 | *pos++ = (key->u.tkip.iv32 >> 8) & 0xff; | 143 | return pos + 4; |
188 | *pos++ = (key->u.tkip.iv32 >> 16) & 0xff; | ||
189 | *pos++ = (key->u.tkip.iv32 >> 24) & 0xff; | ||
190 | return pos; | ||
191 | } | 144 | } |
192 | 145 | ||
193 | |||
194 | void ieee80211_tkip_gen_phase1key(struct ieee80211_key *key, u8 *ta, | 146 | void ieee80211_tkip_gen_phase1key(struct ieee80211_key *key, u8 *ta, |
195 | u16 *phase1key) | 147 | u16 *phase1key) |
196 | { | 148 | { |
@@ -228,10 +180,8 @@ void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf, | |||
228 | u16 iv16; | 180 | u16 iv16; |
229 | u32 iv32; | 181 | u32 iv32; |
230 | 182 | ||
231 | iv16 = data[hdr_len] << 8; | 183 | iv16 = data[hdr_len + 2] | (data[hdr_len] << 8); |
232 | iv16 += data[hdr_len + 2]; | 184 | iv32 = get_unaligned_le32(data + hdr_len + 4); |
233 | iv32 = data[hdr_len + 4] | (data[hdr_len + 5] << 8) | | ||
234 | (data[hdr_len + 6] << 16) | (data[hdr_len + 7] << 24); | ||
235 | 185 | ||
236 | #ifdef CONFIG_TKIP_DEBUG | 186 | #ifdef CONFIG_TKIP_DEBUG |
237 | printk(KERN_DEBUG "TKIP encrypt: iv16 = 0x%04x, iv32 = 0x%08x\n", | 187 | printk(KERN_DEBUG "TKIP encrypt: iv16 = 0x%04x, iv32 = 0x%08x\n", |
@@ -281,7 +231,6 @@ void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm, | |||
281 | ieee80211_wep_encrypt_data(tfm, rc4key, 16, pos, payload_len); | 231 | ieee80211_wep_encrypt_data(tfm, rc4key, 16, pos, payload_len); |
282 | } | 232 | } |
283 | 233 | ||
284 | |||
285 | /* Decrypt packet payload with TKIP using @key. @pos is a pointer to the | 234 | /* Decrypt packet payload with TKIP using @key. @pos is a pointer to the |
286 | * beginning of the buffer containing IEEE 802.11 header payload, i.e., | 235 | * beginning of the buffer containing IEEE 802.11 header payload, i.e., |
287 | * including IV, Ext. IV, real data, Michael MIC, ICV. @payload_len is the | 236 | * including IV, Ext. IV, real data, Michael MIC, ICV. @payload_len is the |
@@ -302,7 +251,7 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, | |||
302 | 251 | ||
303 | iv16 = (pos[0] << 8) | pos[2]; | 252 | iv16 = (pos[0] << 8) | pos[2]; |
304 | keyid = pos[3]; | 253 | keyid = pos[3]; |
305 | iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24); | 254 | iv32 = get_unaligned_le32(pos + 4); |
306 | pos += 8; | 255 | pos += 8; |
307 | #ifdef CONFIG_TKIP_DEBUG | 256 | #ifdef CONFIG_TKIP_DEBUG |
308 | { | 257 | { |
@@ -409,5 +358,3 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, | |||
409 | 358 | ||
410 | return res; | 359 | return res; |
411 | } | 360 | } |
412 | |||
413 | |||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 1d7dd54aacef..aecec2a72b08 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -256,7 +256,7 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) | |||
256 | if (tx->flags & IEEE80211_TX_PS_BUFFERED) | 256 | if (tx->flags & IEEE80211_TX_PS_BUFFERED) |
257 | return TX_CONTINUE; | 257 | return TX_CONTINUE; |
258 | 258 | ||
259 | sta_flags = tx->sta ? tx->sta->flags : 0; | 259 | sta_flags = tx->sta ? get_sta_flags(tx->sta) : 0; |
260 | 260 | ||
261 | if (likely(tx->flags & IEEE80211_TX_UNICAST)) { | 261 | if (likely(tx->flags & IEEE80211_TX_UNICAST)) { |
262 | if (unlikely(!(sta_flags & WLAN_STA_ASSOC) && | 262 | if (unlikely(!(sta_flags & WLAN_STA_ASSOC) && |
@@ -391,6 +391,7 @@ static ieee80211_tx_result | |||
391 | ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | 391 | ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) |
392 | { | 392 | { |
393 | struct sta_info *sta = tx->sta; | 393 | struct sta_info *sta = tx->sta; |
394 | u32 staflags; | ||
394 | DECLARE_MAC_BUF(mac); | 395 | DECLARE_MAC_BUF(mac); |
395 | 396 | ||
396 | if (unlikely(!sta || | 397 | if (unlikely(!sta || |
@@ -398,8 +399,10 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
398 | (tx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP))) | 399 | (tx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP))) |
399 | return TX_CONTINUE; | 400 | return TX_CONTINUE; |
400 | 401 | ||
401 | if (unlikely((sta->flags & WLAN_STA_PS) && | 402 | staflags = get_sta_flags(sta); |
402 | !(sta->flags & WLAN_STA_PSPOLL))) { | 403 | |
404 | if (unlikely((staflags & WLAN_STA_PS) && | ||
405 | !(staflags & WLAN_STA_PSPOLL))) { | ||
403 | struct ieee80211_tx_packet_data *pkt_data; | 406 | struct ieee80211_tx_packet_data *pkt_data; |
404 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 407 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
405 | printk(KERN_DEBUG "STA %s aid %d: PS buffer (entries " | 408 | printk(KERN_DEBUG "STA %s aid %d: PS buffer (entries " |
@@ -430,13 +433,13 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
430 | return TX_QUEUED; | 433 | return TX_QUEUED; |
431 | } | 434 | } |
432 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 435 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
433 | else if (unlikely(sta->flags & WLAN_STA_PS)) { | 436 | else if (unlikely(test_sta_flags(sta, WLAN_STA_PS))) { |
434 | printk(KERN_DEBUG "%s: STA %s in PS mode, but pspoll " | 437 | printk(KERN_DEBUG "%s: STA %s in PS mode, but pspoll " |
435 | "set -> send frame\n", tx->dev->name, | 438 | "set -> send frame\n", tx->dev->name, |
436 | print_mac(mac, sta->addr)); | 439 | print_mac(mac, sta->addr)); |
437 | } | 440 | } |
438 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 441 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
439 | sta->flags &= ~WLAN_STA_PSPOLL; | 442 | clear_sta_flags(sta, WLAN_STA_PSPOLL); |
440 | 443 | ||
441 | return TX_CONTINUE; | 444 | return TX_CONTINUE; |
442 | } | 445 | } |
@@ -697,7 +700,7 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx) | |||
697 | if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && | 700 | if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && |
698 | (tx->rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) && | 701 | (tx->rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) && |
699 | tx->sdata->bss_conf.use_short_preamble && | 702 | tx->sdata->bss_conf.use_short_preamble && |
700 | (!tx->sta || (tx->sta->flags & WLAN_STA_SHORT_PREAMBLE))) { | 703 | (!tx->sta || test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE))) { |
701 | tx->control->flags |= IEEE80211_TXCTL_SHORT_PREAMBLE; | 704 | tx->control->flags |= IEEE80211_TXCTL_SHORT_PREAMBLE; |
702 | } | 705 | } |
703 | 706 | ||
@@ -1025,10 +1028,8 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx, | |||
1025 | 1028 | ||
1026 | if (!tx->sta) | 1029 | if (!tx->sta) |
1027 | control->flags |= IEEE80211_TXCTL_CLEAR_PS_FILT; | 1030 | control->flags |= IEEE80211_TXCTL_CLEAR_PS_FILT; |
1028 | else if (tx->sta->flags & WLAN_STA_CLEAR_PS_FILT) { | 1031 | else if (test_and_clear_sta_flags(tx->sta, WLAN_STA_CLEAR_PS_FILT)) |
1029 | control->flags |= IEEE80211_TXCTL_CLEAR_PS_FILT; | 1032 | control->flags |= IEEE80211_TXCTL_CLEAR_PS_FILT; |
1030 | tx->sta->flags &= ~WLAN_STA_CLEAR_PS_FILT; | ||
1031 | } | ||
1032 | 1033 | ||
1033 | hdrlen = ieee80211_get_hdrlen(tx->fc); | 1034 | hdrlen = ieee80211_get_hdrlen(tx->fc); |
1034 | if (skb->len > hdrlen + sizeof(rfc1042_header) + 2) { | 1035 | if (skb->len > hdrlen + sizeof(rfc1042_header) + 2) { |
@@ -1336,6 +1337,8 @@ int ieee80211_monitor_start_xmit(struct sk_buff *skb, | |||
1336 | pkt_data->ifindex = dev->ifindex; | 1337 | pkt_data->ifindex = dev->ifindex; |
1337 | 1338 | ||
1338 | pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT; | 1339 | pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT; |
1340 | /* Interfaces should always request a status report */ | ||
1341 | pkt_data->flags |= IEEE80211_TXPD_REQ_TX_STATUS; | ||
1339 | 1342 | ||
1340 | /* | 1343 | /* |
1341 | * fix up the pointers accounting for the radiotap | 1344 | * fix up the pointers accounting for the radiotap |
@@ -1486,12 +1489,12 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1486 | rcu_read_lock(); | 1489 | rcu_read_lock(); |
1487 | sta = sta_info_get(local, hdr.addr1); | 1490 | sta = sta_info_get(local, hdr.addr1); |
1488 | if (sta) | 1491 | if (sta) |
1489 | sta_flags = sta->flags; | 1492 | sta_flags = get_sta_flags(sta); |
1490 | rcu_read_unlock(); | 1493 | rcu_read_unlock(); |
1491 | } | 1494 | } |
1492 | 1495 | ||
1493 | /* receiver is QoS enabled, use a QoS type frame */ | 1496 | /* receiver and we are QoS enabled, use a QoS type frame */ |
1494 | if (sta_flags & WLAN_STA_WME) { | 1497 | if (sta_flags & WLAN_STA_WME && local->hw.queues >= 4) { |
1495 | fc |= IEEE80211_STYPE_QOS_DATA; | 1498 | fc |= IEEE80211_STYPE_QOS_DATA; |
1496 | hdrlen += 2; | 1499 | hdrlen += 2; |
1497 | } | 1500 | } |
@@ -1617,6 +1620,9 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1617 | if (ethertype == ETH_P_PAE) | 1620 | if (ethertype == ETH_P_PAE) |
1618 | pkt_data->flags |= IEEE80211_TXPD_EAPOL_FRAME; | 1621 | pkt_data->flags |= IEEE80211_TXPD_EAPOL_FRAME; |
1619 | 1622 | ||
1623 | /* Interfaces should always request a status report */ | ||
1624 | pkt_data->flags |= IEEE80211_TXPD_REQ_TX_STATUS; | ||
1625 | |||
1620 | skb->dev = local->mdev; | 1626 | skb->dev = local->mdev; |
1621 | dev->stats.tx_packets++; | 1627 | dev->stats.tx_packets++; |
1622 | dev->stats.tx_bytes += skb->len; | 1628 | dev->stats.tx_bytes += skb->len; |
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c index 76e1de1dc735..6a342a9a40cd 100644 --- a/net/mac80211/wext.c +++ b/net/mac80211/wext.c | |||
@@ -169,14 +169,26 @@ static int ieee80211_ioctl_giwrange(struct net_device *dev, | |||
169 | range->num_encoding_sizes = 2; | 169 | range->num_encoding_sizes = 2; |
170 | range->max_encoding_tokens = NUM_DEFAULT_KEYS; | 170 | range->max_encoding_tokens = NUM_DEFAULT_KEYS; |
171 | 171 | ||
172 | range->max_qual.qual = local->hw.max_signal; | 172 | if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC || |
173 | range->max_qual.level = local->hw.max_rssi; | 173 | local->hw.flags & IEEE80211_HW_SIGNAL_DB) |
174 | range->max_qual.noise = local->hw.max_noise; | 174 | range->max_qual.level = local->hw.max_signal; |
175 | else if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) | ||
176 | range->max_qual.level = -110; | ||
177 | else | ||
178 | range->max_qual.level = 0; | ||
179 | |||
180 | if (local->hw.flags & IEEE80211_HW_NOISE_DBM) | ||
181 | range->max_qual.noise = -110; | ||
182 | else | ||
183 | range->max_qual.noise = 0; | ||
184 | |||
185 | range->max_qual.qual = 100; | ||
175 | range->max_qual.updated = local->wstats_flags; | 186 | range->max_qual.updated = local->wstats_flags; |
176 | 187 | ||
177 | range->avg_qual.qual = local->hw.max_signal/2; | 188 | range->avg_qual.qual = 50; |
178 | range->avg_qual.level = 0; | 189 | /* not always true but better than nothing */ |
179 | range->avg_qual.noise = 0; | 190 | range->avg_qual.level = range->max_qual.level / 2; |
191 | range->avg_qual.noise = range->max_qual.noise / 2; | ||
180 | range->avg_qual.updated = local->wstats_flags; | 192 | range->avg_qual.updated = local->wstats_flags; |
181 | 193 | ||
182 | range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | | 194 | range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | |
@@ -996,8 +1008,8 @@ static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev | |||
996 | wstats->qual.noise = 0; | 1008 | wstats->qual.noise = 0; |
997 | wstats->qual.updated = IW_QUAL_ALL_INVALID; | 1009 | wstats->qual.updated = IW_QUAL_ALL_INVALID; |
998 | } else { | 1010 | } else { |
999 | wstats->qual.level = sta->last_rssi; | 1011 | wstats->qual.level = sta->last_signal; |
1000 | wstats->qual.qual = sta->last_signal; | 1012 | wstats->qual.qual = sta->last_qual; |
1001 | wstats->qual.noise = sta->last_noise; | 1013 | wstats->qual.noise = sta->last_noise; |
1002 | wstats->qual.updated = local->wstats_flags; | 1014 | wstats->qual.updated = local->wstats_flags; |
1003 | } | 1015 | } |
diff --git a/net/wireless/core.c b/net/wireless/core.c index 80afacdae46c..f1da0b93bc56 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -143,8 +143,11 @@ void cfg80211_put_dev(struct cfg80211_registered_device *drv) | |||
143 | int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, | 143 | int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, |
144 | char *newname) | 144 | char *newname) |
145 | { | 145 | { |
146 | struct cfg80211_registered_device *drv; | ||
146 | int idx, taken = -1, result, digits; | 147 | int idx, taken = -1, result, digits; |
147 | 148 | ||
149 | mutex_lock(&cfg80211_drv_mutex); | ||
150 | |||
148 | /* prohibit calling the thing phy%d when %d is not its number */ | 151 | /* prohibit calling the thing phy%d when %d is not its number */ |
149 | sscanf(newname, PHY_NAME "%d%n", &idx, &taken); | 152 | sscanf(newname, PHY_NAME "%d%n", &idx, &taken); |
150 | if (taken == strlen(newname) && idx != rdev->idx) { | 153 | if (taken == strlen(newname) && idx != rdev->idx) { |
@@ -156,14 +159,30 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, | |||
156 | * deny the name if it is phy<idx> where <idx> is printed | 159 | * deny the name if it is phy<idx> where <idx> is printed |
157 | * without leading zeroes. taken == strlen(newname) here | 160 | * without leading zeroes. taken == strlen(newname) here |
158 | */ | 161 | */ |
162 | result = -EINVAL; | ||
159 | if (taken == strlen(PHY_NAME) + digits) | 163 | if (taken == strlen(PHY_NAME) + digits) |
160 | return -EINVAL; | 164 | goto out_unlock; |
165 | } | ||
166 | |||
167 | |||
168 | /* Ignore nop renames */ | ||
169 | result = 0; | ||
170 | if (strcmp(newname, dev_name(&rdev->wiphy.dev)) == 0) | ||
171 | goto out_unlock; | ||
172 | |||
173 | /* Ensure another device does not already have this name. */ | ||
174 | list_for_each_entry(drv, &cfg80211_drv_list, list) { | ||
175 | result = -EINVAL; | ||
176 | if (strcmp(newname, dev_name(&drv->wiphy.dev)) == 0) | ||
177 | goto out_unlock; | ||
161 | } | 178 | } |
162 | 179 | ||
163 | /* this will check for collisions */ | 180 | /* this will only check for collisions in sysfs |
181 | * which is not even always compiled in. | ||
182 | */ | ||
164 | result = device_rename(&rdev->wiphy.dev, newname); | 183 | result = device_rename(&rdev->wiphy.dev, newname); |
165 | if (result) | 184 | if (result) |
166 | return result; | 185 | goto out_unlock; |
167 | 186 | ||
168 | if (!debugfs_rename(rdev->wiphy.debugfsdir->d_parent, | 187 | if (!debugfs_rename(rdev->wiphy.debugfsdir->d_parent, |
169 | rdev->wiphy.debugfsdir, | 188 | rdev->wiphy.debugfsdir, |
@@ -172,9 +191,13 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, | |||
172 | printk(KERN_ERR "cfg80211: failed to rename debugfs dir to %s!\n", | 191 | printk(KERN_ERR "cfg80211: failed to rename debugfs dir to %s!\n", |
173 | newname); | 192 | newname); |
174 | 193 | ||
175 | nl80211_notify_dev_rename(rdev); | 194 | result = 0; |
195 | out_unlock: | ||
196 | mutex_unlock(&cfg80211_drv_mutex); | ||
197 | if (result == 0) | ||
198 | nl80211_notify_dev_rename(rdev); | ||
176 | 199 | ||
177 | return 0; | 200 | return result; |
178 | } | 201 | } |
179 | 202 | ||
180 | /* exported functions */ | 203 | /* exported functions */ |
diff --git a/net/wireless/radiotap.c b/net/wireless/radiotap.c index 28fbd0b0b568..f591871a7b4f 100644 --- a/net/wireless/radiotap.c +++ b/net/wireless/radiotap.c | |||
@@ -59,23 +59,21 @@ int ieee80211_radiotap_iterator_init( | |||
59 | return -EINVAL; | 59 | return -EINVAL; |
60 | 60 | ||
61 | /* sanity check for allowed length and radiotap length field */ | 61 | /* sanity check for allowed length and radiotap length field */ |
62 | if (max_length < le16_to_cpu(get_unaligned(&radiotap_header->it_len))) | 62 | if (max_length < get_unaligned_le16(&radiotap_header->it_len)) |
63 | return -EINVAL; | 63 | return -EINVAL; |
64 | 64 | ||
65 | iterator->rtheader = radiotap_header; | 65 | iterator->rtheader = radiotap_header; |
66 | iterator->max_length = le16_to_cpu(get_unaligned( | 66 | iterator->max_length = get_unaligned_le16(&radiotap_header->it_len); |
67 | &radiotap_header->it_len)); | ||
68 | iterator->arg_index = 0; | 67 | iterator->arg_index = 0; |
69 | iterator->bitmap_shifter = le32_to_cpu(get_unaligned( | 68 | iterator->bitmap_shifter = get_unaligned_le32(&radiotap_header->it_present); |
70 | &radiotap_header->it_present)); | ||
71 | iterator->arg = (u8 *)radiotap_header + sizeof(*radiotap_header); | 69 | iterator->arg = (u8 *)radiotap_header + sizeof(*radiotap_header); |
72 | iterator->this_arg = NULL; | 70 | iterator->this_arg = NULL; |
73 | 71 | ||
74 | /* find payload start allowing for extended bitmap(s) */ | 72 | /* find payload start allowing for extended bitmap(s) */ |
75 | 73 | ||
76 | if (unlikely(iterator->bitmap_shifter & (1<<IEEE80211_RADIOTAP_EXT))) { | 74 | if (unlikely(iterator->bitmap_shifter & (1<<IEEE80211_RADIOTAP_EXT))) { |
77 | while (le32_to_cpu(get_unaligned((__le32 *)iterator->arg)) & | 75 | while (get_unaligned_le32(iterator->arg) & |
78 | (1<<IEEE80211_RADIOTAP_EXT)) { | 76 | (1 << IEEE80211_RADIOTAP_EXT)) { |
79 | iterator->arg += sizeof(u32); | 77 | iterator->arg += sizeof(u32); |
80 | 78 | ||
81 | /* | 79 | /* |
@@ -241,8 +239,8 @@ int ieee80211_radiotap_iterator_next( | |||
241 | if (iterator->bitmap_shifter & 1) { | 239 | if (iterator->bitmap_shifter & 1) { |
242 | /* b31 was set, there is more */ | 240 | /* b31 was set, there is more */ |
243 | /* move to next u32 bitmap */ | 241 | /* move to next u32 bitmap */ |
244 | iterator->bitmap_shifter = le32_to_cpu( | 242 | iterator->bitmap_shifter = |
245 | get_unaligned(iterator->next_bitmap)); | 243 | get_unaligned_le32(iterator->next_bitmap); |
246 | iterator->next_bitmap++; | 244 | iterator->next_bitmap++; |
247 | } else | 245 | } else |
248 | /* no more bitmaps: end */ | 246 | /* no more bitmaps: end */ |