diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-23 14:47:02 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-23 14:47:02 -0400 |
commit | 5f05647dd81c11a6a165ccc8f0c1370b16f3bcb0 (patch) | |
tree | 7851ef1c93aa1aba7ef327ca4b75fd35e6d10f29 /net/mac80211 | |
parent | 02f36038c568111ad4fc433f6fa760ff5e38fab4 (diff) | |
parent | ec37a48d1d16c30b655ac5280209edf52a6775d4 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1699 commits)
bnx2/bnx2x: Unsupported Ethtool operations should return -EINVAL.
vlan: Calling vlan_hwaccel_do_receive() is always valid.
tproxy: use the interface primary IP address as a default value for --on-ip
tproxy: added IPv6 support to the socket match
cxgb3: function namespace cleanup
tproxy: added IPv6 support to the TPROXY target
tproxy: added IPv6 socket lookup function to nf_tproxy_core
be2net: Changes to use only priority codes allowed by f/w
tproxy: allow non-local binds of IPv6 sockets if IP_TRANSPARENT is enabled
tproxy: added tproxy sockopt interface in the IPV6 layer
tproxy: added udp6_lib_lookup function
tproxy: added const specifiers to udp lookup functions
tproxy: split off ipv6 defragmentation to a separate module
l2tp: small cleanup
nf_nat: restrict ICMP translation for embedded header
can: mcp251x: fix generation of error frames
can: mcp251x: fix endless loop in interrupt handler if CANINTF_MERRF is set
can-raw: add msg_flags to distinguish local traffic
9p: client code cleanup
rds: make local functions/variables static
...
Fix up conflicts in net/core/dev.c, drivers/net/pcmcia/smc91c92_cs.c and
drivers/net/wireless/ath/ath9k/debug.c as per David
Diffstat (limited to 'net/mac80211')
36 files changed, 2005 insertions, 1099 deletions
diff --git a/net/mac80211/aes_ccm.c b/net/mac80211/aes_ccm.c index a87cb3ba2df..d2b03e0851e 100644 --- a/net/mac80211/aes_ccm.c +++ b/net/mac80211/aes_ccm.c | |||
@@ -138,10 +138,8 @@ struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[]) | |||
138 | struct crypto_cipher *tfm; | 138 | struct crypto_cipher *tfm; |
139 | 139 | ||
140 | tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); | 140 | tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); |
141 | if (IS_ERR(tfm)) | 141 | if (!IS_ERR(tfm)) |
142 | return NULL; | 142 | crypto_cipher_setkey(tfm, key, ALG_CCMP_KEY_LEN); |
143 | |||
144 | crypto_cipher_setkey(tfm, key, ALG_CCMP_KEY_LEN); | ||
145 | 143 | ||
146 | return tfm; | 144 | return tfm; |
147 | } | 145 | } |
diff --git a/net/mac80211/aes_cmac.c b/net/mac80211/aes_cmac.c index 3d097b3d7b6..b4d66cca76d 100644 --- a/net/mac80211/aes_cmac.c +++ b/net/mac80211/aes_cmac.c | |||
@@ -119,10 +119,8 @@ struct crypto_cipher * ieee80211_aes_cmac_key_setup(const u8 key[]) | |||
119 | struct crypto_cipher *tfm; | 119 | struct crypto_cipher *tfm; |
120 | 120 | ||
121 | tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); | 121 | tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); |
122 | if (IS_ERR(tfm)) | 122 | if (!IS_ERR(tfm)) |
123 | return NULL; | 123 | crypto_cipher_setkey(tfm, key, AES_CMAC_KEY_LEN); |
124 | |||
125 | crypto_cipher_setkey(tfm, key, AES_CMAC_KEY_LEN); | ||
126 | 124 | ||
127 | return tfm; | 125 | return tfm; |
128 | } | 126 | } |
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index 965b272499f..720b7a84af5 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c | |||
@@ -56,7 +56,7 @@ static void ieee80211_free_tid_rx(struct rcu_head *h) | |||
56 | } | 56 | } |
57 | 57 | ||
58 | void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, | 58 | void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, |
59 | u16 initiator, u16 reason) | 59 | u16 initiator, u16 reason, bool tx) |
60 | { | 60 | { |
61 | struct ieee80211_local *local = sta->local; | 61 | struct ieee80211_local *local = sta->local; |
62 | struct tid_ampdu_rx *tid_rx; | 62 | struct tid_ampdu_rx *tid_rx; |
@@ -81,20 +81,21 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, | |||
81 | "aggregation for tid %d\n", tid); | 81 | "aggregation for tid %d\n", tid); |
82 | 82 | ||
83 | /* check if this is a self generated aggregation halt */ | 83 | /* check if this is a self generated aggregation halt */ |
84 | if (initiator == WLAN_BACK_RECIPIENT) | 84 | if (initiator == WLAN_BACK_RECIPIENT && tx) |
85 | ieee80211_send_delba(sta->sdata, sta->sta.addr, | 85 | ieee80211_send_delba(sta->sdata, sta->sta.addr, |
86 | tid, 0, reason); | 86 | tid, 0, reason); |
87 | 87 | ||
88 | del_timer_sync(&tid_rx->session_timer); | 88 | del_timer_sync(&tid_rx->session_timer); |
89 | del_timer_sync(&tid_rx->reorder_timer); | ||
89 | 90 | ||
90 | call_rcu(&tid_rx->rcu_head, ieee80211_free_tid_rx); | 91 | call_rcu(&tid_rx->rcu_head, ieee80211_free_tid_rx); |
91 | } | 92 | } |
92 | 93 | ||
93 | void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, | 94 | void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, |
94 | u16 initiator, u16 reason) | 95 | u16 initiator, u16 reason, bool tx) |
95 | { | 96 | { |
96 | mutex_lock(&sta->ampdu_mlme.mtx); | 97 | mutex_lock(&sta->ampdu_mlme.mtx); |
97 | ___ieee80211_stop_rx_ba_session(sta, tid, initiator, reason); | 98 | ___ieee80211_stop_rx_ba_session(sta, tid, initiator, reason, tx); |
98 | mutex_unlock(&sta->ampdu_mlme.mtx); | 99 | mutex_unlock(&sta->ampdu_mlme.mtx); |
99 | } | 100 | } |
100 | 101 | ||
@@ -120,6 +121,20 @@ static void sta_rx_agg_session_timer_expired(unsigned long data) | |||
120 | ieee80211_queue_work(&sta->local->hw, &sta->ampdu_mlme.work); | 121 | ieee80211_queue_work(&sta->local->hw, &sta->ampdu_mlme.work); |
121 | } | 122 | } |
122 | 123 | ||
124 | static void sta_rx_agg_reorder_timer_expired(unsigned long data) | ||
125 | { | ||
126 | u8 *ptid = (u8 *)data; | ||
127 | u8 *timer_to_id = ptid - *ptid; | ||
128 | struct sta_info *sta = container_of(timer_to_id, struct sta_info, | ||
129 | timer_to_tid[0]); | ||
130 | |||
131 | rcu_read_lock(); | ||
132 | spin_lock(&sta->lock); | ||
133 | ieee80211_release_reorder_timeout(sta, *ptid); | ||
134 | spin_unlock(&sta->lock); | ||
135 | rcu_read_unlock(); | ||
136 | } | ||
137 | |||
123 | static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid, | 138 | static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid, |
124 | u8 dialog_token, u16 status, u16 policy, | 139 | u8 dialog_token, u16 status, u16 policy, |
125 | u16 buf_size, u16 timeout) | 140 | u16 buf_size, u16 timeout) |
@@ -251,11 +266,18 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, | |||
251 | goto end; | 266 | goto end; |
252 | } | 267 | } |
253 | 268 | ||
269 | spin_lock_init(&tid_agg_rx->reorder_lock); | ||
270 | |||
254 | /* rx timer */ | 271 | /* rx timer */ |
255 | tid_agg_rx->session_timer.function = sta_rx_agg_session_timer_expired; | 272 | tid_agg_rx->session_timer.function = sta_rx_agg_session_timer_expired; |
256 | tid_agg_rx->session_timer.data = (unsigned long)&sta->timer_to_tid[tid]; | 273 | tid_agg_rx->session_timer.data = (unsigned long)&sta->timer_to_tid[tid]; |
257 | init_timer(&tid_agg_rx->session_timer); | 274 | init_timer(&tid_agg_rx->session_timer); |
258 | 275 | ||
276 | /* rx reorder timer */ | ||
277 | tid_agg_rx->reorder_timer.function = sta_rx_agg_reorder_timer_expired; | ||
278 | tid_agg_rx->reorder_timer.data = (unsigned long)&sta->timer_to_tid[tid]; | ||
279 | init_timer(&tid_agg_rx->reorder_timer); | ||
280 | |||
259 | /* prepare reordering buffer */ | 281 | /* prepare reordering buffer */ |
260 | tid_agg_rx->reorder_buf = | 282 | tid_agg_rx->reorder_buf = |
261 | kcalloc(buf_size, sizeof(struct sk_buff *), GFP_ATOMIC); | 283 | kcalloc(buf_size, sizeof(struct sk_buff *), GFP_ATOMIC); |
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index 8f23401832b..d4679b265ba 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c | |||
@@ -145,7 +145,8 @@ static void kfree_tid_tx(struct rcu_head *rcu_head) | |||
145 | } | 145 | } |
146 | 146 | ||
147 | int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | 147 | int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, |
148 | enum ieee80211_back_parties initiator) | 148 | enum ieee80211_back_parties initiator, |
149 | bool tx) | ||
149 | { | 150 | { |
150 | struct ieee80211_local *local = sta->local; | 151 | struct ieee80211_local *local = sta->local; |
151 | struct tid_ampdu_tx *tid_tx = sta->ampdu_mlme.tid_tx[tid]; | 152 | struct tid_ampdu_tx *tid_tx = sta->ampdu_mlme.tid_tx[tid]; |
@@ -185,6 +186,7 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | |||
185 | clear_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state); | 186 | clear_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state); |
186 | 187 | ||
187 | tid_tx->stop_initiator = initiator; | 188 | tid_tx->stop_initiator = initiator; |
189 | tid_tx->tx_stop = tx; | ||
188 | 190 | ||
189 | ret = drv_ampdu_action(local, sta->sdata, | 191 | ret = drv_ampdu_action(local, sta->sdata, |
190 | IEEE80211_AMPDU_TX_STOP, | 192 | IEEE80211_AMPDU_TX_STOP, |
@@ -577,13 +579,14 @@ void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, | |||
577 | EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe); | 579 | EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe); |
578 | 580 | ||
579 | int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | 581 | int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, |
580 | enum ieee80211_back_parties initiator) | 582 | enum ieee80211_back_parties initiator, |
583 | bool tx) | ||
581 | { | 584 | { |
582 | int ret; | 585 | int ret; |
583 | 586 | ||
584 | mutex_lock(&sta->ampdu_mlme.mtx); | 587 | mutex_lock(&sta->ampdu_mlme.mtx); |
585 | 588 | ||
586 | ret = ___ieee80211_stop_tx_ba_session(sta, tid, initiator); | 589 | ret = ___ieee80211_stop_tx_ba_session(sta, tid, initiator, tx); |
587 | 590 | ||
588 | mutex_unlock(&sta->ampdu_mlme.mtx); | 591 | mutex_unlock(&sta->ampdu_mlme.mtx); |
589 | 592 | ||
@@ -672,7 +675,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid) | |||
672 | goto unlock_sta; | 675 | goto unlock_sta; |
673 | } | 676 | } |
674 | 677 | ||
675 | if (tid_tx->stop_initiator == WLAN_BACK_INITIATOR) | 678 | if (tid_tx->stop_initiator == WLAN_BACK_INITIATOR && tid_tx->tx_stop) |
676 | ieee80211_send_delba(sta->sdata, ra, tid, | 679 | ieee80211_send_delba(sta->sdata, ra, tid, |
677 | WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE); | 680 | WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE); |
678 | 681 | ||
@@ -772,7 +775,8 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, | |||
772 | 775 | ||
773 | sta->ampdu_mlme.addba_req_num[tid] = 0; | 776 | sta->ampdu_mlme.addba_req_num[tid] = 0; |
774 | } else { | 777 | } else { |
775 | ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR); | 778 | ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR, |
779 | true); | ||
776 | } | 780 | } |
777 | 781 | ||
778 | out: | 782 | out: |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 29ac8e1a509..18bd0e55060 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -19,33 +19,6 @@ | |||
19 | #include "rate.h" | 19 | #include "rate.h" |
20 | #include "mesh.h" | 20 | #include "mesh.h" |
21 | 21 | ||
22 | static bool nl80211_type_check(enum nl80211_iftype type) | ||
23 | { | ||
24 | switch (type) { | ||
25 | case NL80211_IFTYPE_ADHOC: | ||
26 | case NL80211_IFTYPE_STATION: | ||
27 | case NL80211_IFTYPE_MONITOR: | ||
28 | #ifdef CONFIG_MAC80211_MESH | ||
29 | case NL80211_IFTYPE_MESH_POINT: | ||
30 | #endif | ||
31 | case NL80211_IFTYPE_AP: | ||
32 | case NL80211_IFTYPE_AP_VLAN: | ||
33 | case NL80211_IFTYPE_WDS: | ||
34 | return true; | ||
35 | default: | ||
36 | return false; | ||
37 | } | ||
38 | } | ||
39 | |||
40 | static bool nl80211_params_check(enum nl80211_iftype type, | ||
41 | struct vif_params *params) | ||
42 | { | ||
43 | if (!nl80211_type_check(type)) | ||
44 | return false; | ||
45 | |||
46 | return true; | ||
47 | } | ||
48 | |||
49 | static int ieee80211_add_iface(struct wiphy *wiphy, char *name, | 22 | static int ieee80211_add_iface(struct wiphy *wiphy, char *name, |
50 | enum nl80211_iftype type, u32 *flags, | 23 | enum nl80211_iftype type, u32 *flags, |
51 | struct vif_params *params) | 24 | struct vif_params *params) |
@@ -55,9 +28,6 @@ static int ieee80211_add_iface(struct wiphy *wiphy, char *name, | |||
55 | struct ieee80211_sub_if_data *sdata; | 28 | struct ieee80211_sub_if_data *sdata; |
56 | int err; | 29 | int err; |
57 | 30 | ||
58 | if (!nl80211_params_check(type, params)) | ||
59 | return -EINVAL; | ||
60 | |||
61 | err = ieee80211_if_add(local, name, &dev, type, params); | 31 | err = ieee80211_if_add(local, name, &dev, type, params); |
62 | if (err || type != NL80211_IFTYPE_MONITOR || !flags) | 32 | if (err || type != NL80211_IFTYPE_MONITOR || !flags) |
63 | return err; | 33 | return err; |
@@ -82,12 +52,6 @@ static int ieee80211_change_iface(struct wiphy *wiphy, | |||
82 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 52 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
83 | int ret; | 53 | int ret; |
84 | 54 | ||
85 | if (ieee80211_sdata_running(sdata)) | ||
86 | return -EBUSY; | ||
87 | |||
88 | if (!nl80211_params_check(type, params)) | ||
89 | return -EINVAL; | ||
90 | |||
91 | ret = ieee80211_if_change_type(sdata, type); | 55 | ret = ieee80211_if_change_type(sdata, type); |
92 | if (ret) | 56 | if (ret) |
93 | return ret; | 57 | return ret; |
@@ -104,54 +68,71 @@ static int ieee80211_change_iface(struct wiphy *wiphy, | |||
104 | params && params->use_4addr >= 0) | 68 | params && params->use_4addr >= 0) |
105 | sdata->u.mgd.use_4addr = params->use_4addr; | 69 | sdata->u.mgd.use_4addr = params->use_4addr; |
106 | 70 | ||
107 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR && flags) | 71 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR && flags) { |
108 | sdata->u.mntr_flags = *flags; | 72 | struct ieee80211_local *local = sdata->local; |
73 | |||
74 | if (ieee80211_sdata_running(sdata)) { | ||
75 | /* | ||
76 | * Prohibit MONITOR_FLAG_COOK_FRAMES to be | ||
77 | * changed while the interface is up. | ||
78 | * Else we would need to add a lot of cruft | ||
79 | * to update everything: | ||
80 | * cooked_mntrs, monitor and all fif_* counters | ||
81 | * reconfigure hardware | ||
82 | */ | ||
83 | if ((*flags & MONITOR_FLAG_COOK_FRAMES) != | ||
84 | (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES)) | ||
85 | return -EBUSY; | ||
86 | |||
87 | ieee80211_adjust_monitor_flags(sdata, -1); | ||
88 | sdata->u.mntr_flags = *flags; | ||
89 | ieee80211_adjust_monitor_flags(sdata, 1); | ||
90 | |||
91 | ieee80211_configure_filter(local); | ||
92 | } else { | ||
93 | /* | ||
94 | * Because the interface is down, ieee80211_do_stop | ||
95 | * and ieee80211_do_open take care of "everything" | ||
96 | * mentioned in the comment above. | ||
97 | */ | ||
98 | sdata->u.mntr_flags = *flags; | ||
99 | } | ||
100 | } | ||
109 | 101 | ||
110 | return 0; | 102 | return 0; |
111 | } | 103 | } |
112 | 104 | ||
113 | static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, | 105 | static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, |
114 | u8 key_idx, const u8 *mac_addr, | 106 | u8 key_idx, bool pairwise, const u8 *mac_addr, |
115 | struct key_params *params) | 107 | struct key_params *params) |
116 | { | 108 | { |
117 | struct ieee80211_sub_if_data *sdata; | 109 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
118 | struct sta_info *sta = NULL; | 110 | struct sta_info *sta = NULL; |
119 | enum ieee80211_key_alg alg; | ||
120 | struct ieee80211_key *key; | 111 | struct ieee80211_key *key; |
121 | int err; | 112 | int err; |
122 | 113 | ||
123 | if (!netif_running(dev)) | 114 | if (!ieee80211_sdata_running(sdata)) |
124 | return -ENETDOWN; | 115 | return -ENETDOWN; |
125 | 116 | ||
126 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 117 | /* reject WEP and TKIP keys if WEP failed to initialize */ |
127 | |||
128 | switch (params->cipher) { | 118 | switch (params->cipher) { |
129 | case WLAN_CIPHER_SUITE_WEP40: | 119 | case WLAN_CIPHER_SUITE_WEP40: |
130 | case WLAN_CIPHER_SUITE_WEP104: | ||
131 | alg = ALG_WEP; | ||
132 | break; | ||
133 | case WLAN_CIPHER_SUITE_TKIP: | 120 | case WLAN_CIPHER_SUITE_TKIP: |
134 | alg = ALG_TKIP; | 121 | case WLAN_CIPHER_SUITE_WEP104: |
135 | break; | 122 | if (IS_ERR(sdata->local->wep_tx_tfm)) |
136 | case WLAN_CIPHER_SUITE_CCMP: | 123 | return -EINVAL; |
137 | alg = ALG_CCMP; | ||
138 | break; | ||
139 | case WLAN_CIPHER_SUITE_AES_CMAC: | ||
140 | alg = ALG_AES_CMAC; | ||
141 | break; | 124 | break; |
142 | default: | 125 | default: |
143 | return -EINVAL; | 126 | break; |
144 | } | 127 | } |
145 | 128 | ||
146 | /* reject WEP and TKIP keys if WEP failed to initialize */ | 129 | key = ieee80211_key_alloc(params->cipher, key_idx, params->key_len, |
147 | if ((alg == ALG_WEP || alg == ALG_TKIP) && | 130 | params->key, params->seq_len, params->seq); |
148 | IS_ERR(sdata->local->wep_tx_tfm)) | 131 | if (IS_ERR(key)) |
149 | return -EINVAL; | 132 | return PTR_ERR(key); |
150 | 133 | ||
151 | key = ieee80211_key_alloc(alg, key_idx, params->key_len, params->key, | 134 | if (pairwise) |
152 | params->seq_len, params->seq); | 135 | key->conf.flags |= IEEE80211_KEY_FLAG_PAIRWISE; |
153 | if (!key) | ||
154 | return -ENOMEM; | ||
155 | 136 | ||
156 | mutex_lock(&sdata->local->sta_mtx); | 137 | mutex_lock(&sdata->local->sta_mtx); |
157 | 138 | ||
@@ -164,9 +145,10 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, | |||
164 | } | 145 | } |
165 | } | 146 | } |
166 | 147 | ||
167 | ieee80211_key_link(key, sdata, sta); | 148 | err = ieee80211_key_link(key, sdata, sta); |
149 | if (err) | ||
150 | ieee80211_key_free(sdata->local, key); | ||
168 | 151 | ||
169 | err = 0; | ||
170 | out_unlock: | 152 | out_unlock: |
171 | mutex_unlock(&sdata->local->sta_mtx); | 153 | mutex_unlock(&sdata->local->sta_mtx); |
172 | 154 | ||
@@ -174,7 +156,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, | |||
174 | } | 156 | } |
175 | 157 | ||
176 | static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, | 158 | static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, |
177 | u8 key_idx, const u8 *mac_addr) | 159 | u8 key_idx, bool pairwise, const u8 *mac_addr) |
178 | { | 160 | { |
179 | struct ieee80211_sub_if_data *sdata; | 161 | struct ieee80211_sub_if_data *sdata; |
180 | struct sta_info *sta; | 162 | struct sta_info *sta; |
@@ -191,10 +173,17 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, | |||
191 | if (!sta) | 173 | if (!sta) |
192 | goto out_unlock; | 174 | goto out_unlock; |
193 | 175 | ||
194 | if (sta->key) { | 176 | if (pairwise) { |
195 | ieee80211_key_free(sdata->local, sta->key); | 177 | if (sta->ptk) { |
196 | WARN_ON(sta->key); | 178 | ieee80211_key_free(sdata->local, sta->ptk); |
197 | ret = 0; | 179 | ret = 0; |
180 | } | ||
181 | } else { | ||
182 | if (sta->gtk[key_idx]) { | ||
183 | ieee80211_key_free(sdata->local, | ||
184 | sta->gtk[key_idx]); | ||
185 | ret = 0; | ||
186 | } | ||
198 | } | 187 | } |
199 | 188 | ||
200 | goto out_unlock; | 189 | goto out_unlock; |
@@ -216,7 +205,8 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, | |||
216 | } | 205 | } |
217 | 206 | ||
218 | static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, | 207 | static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, |
219 | u8 key_idx, const u8 *mac_addr, void *cookie, | 208 | u8 key_idx, bool pairwise, const u8 *mac_addr, |
209 | void *cookie, | ||
220 | void (*callback)(void *cookie, | 210 | void (*callback)(void *cookie, |
221 | struct key_params *params)) | 211 | struct key_params *params)) |
222 | { | 212 | { |
@@ -224,7 +214,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, | |||
224 | struct sta_info *sta = NULL; | 214 | struct sta_info *sta = NULL; |
225 | u8 seq[6] = {0}; | 215 | u8 seq[6] = {0}; |
226 | struct key_params params; | 216 | struct key_params params; |
227 | struct ieee80211_key *key; | 217 | struct ieee80211_key *key = NULL; |
228 | u32 iv32; | 218 | u32 iv32; |
229 | u16 iv16; | 219 | u16 iv16; |
230 | int err = -ENOENT; | 220 | int err = -ENOENT; |
@@ -238,7 +228,10 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, | |||
238 | if (!sta) | 228 | if (!sta) |
239 | goto out; | 229 | goto out; |
240 | 230 | ||
241 | key = sta->key; | 231 | if (pairwise) |
232 | key = sta->ptk; | ||
233 | else if (key_idx < NUM_DEFAULT_KEYS) | ||
234 | key = sta->gtk[key_idx]; | ||
242 | } else | 235 | } else |
243 | key = sdata->keys[key_idx]; | 236 | key = sdata->keys[key_idx]; |
244 | 237 | ||
@@ -247,10 +240,10 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, | |||
247 | 240 | ||
248 | memset(¶ms, 0, sizeof(params)); | 241 | memset(¶ms, 0, sizeof(params)); |
249 | 242 | ||
250 | switch (key->conf.alg) { | 243 | params.cipher = key->conf.cipher; |
251 | case ALG_TKIP: | ||
252 | params.cipher = WLAN_CIPHER_SUITE_TKIP; | ||
253 | 244 | ||
245 | switch (key->conf.cipher) { | ||
246 | case WLAN_CIPHER_SUITE_TKIP: | ||
254 | iv32 = key->u.tkip.tx.iv32; | 247 | iv32 = key->u.tkip.tx.iv32; |
255 | iv16 = key->u.tkip.tx.iv16; | 248 | iv16 = key->u.tkip.tx.iv16; |
256 | 249 | ||
@@ -268,8 +261,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, | |||
268 | params.seq = seq; | 261 | params.seq = seq; |
269 | params.seq_len = 6; | 262 | params.seq_len = 6; |
270 | break; | 263 | break; |
271 | case ALG_CCMP: | 264 | case WLAN_CIPHER_SUITE_CCMP: |
272 | params.cipher = WLAN_CIPHER_SUITE_CCMP; | ||
273 | seq[0] = key->u.ccmp.tx_pn[5]; | 265 | seq[0] = key->u.ccmp.tx_pn[5]; |
274 | seq[1] = key->u.ccmp.tx_pn[4]; | 266 | seq[1] = key->u.ccmp.tx_pn[4]; |
275 | seq[2] = key->u.ccmp.tx_pn[3]; | 267 | seq[2] = key->u.ccmp.tx_pn[3]; |
@@ -279,14 +271,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, | |||
279 | params.seq = seq; | 271 | params.seq = seq; |
280 | params.seq_len = 6; | 272 | params.seq_len = 6; |
281 | break; | 273 | break; |
282 | case ALG_WEP: | 274 | case WLAN_CIPHER_SUITE_AES_CMAC: |
283 | if (key->conf.keylen == 5) | ||
284 | params.cipher = WLAN_CIPHER_SUITE_WEP40; | ||
285 | else | ||
286 | params.cipher = WLAN_CIPHER_SUITE_WEP104; | ||
287 | break; | ||
288 | case ALG_AES_CMAC: | ||
289 | params.cipher = WLAN_CIPHER_SUITE_AES_CMAC; | ||
290 | seq[0] = key->u.aes_cmac.tx_pn[5]; | 275 | seq[0] = key->u.aes_cmac.tx_pn[5]; |
291 | seq[1] = key->u.aes_cmac.tx_pn[4]; | 276 | seq[1] = key->u.aes_cmac.tx_pn[4]; |
292 | seq[2] = key->u.aes_cmac.tx_pn[3]; | 277 | seq[2] = key->u.aes_cmac.tx_pn[3]; |
@@ -342,13 +327,19 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | |||
342 | STATION_INFO_TX_BYTES | | 327 | STATION_INFO_TX_BYTES | |
343 | STATION_INFO_RX_PACKETS | | 328 | STATION_INFO_RX_PACKETS | |
344 | STATION_INFO_TX_PACKETS | | 329 | STATION_INFO_TX_PACKETS | |
345 | STATION_INFO_TX_BITRATE; | 330 | STATION_INFO_TX_RETRIES | |
331 | STATION_INFO_TX_FAILED | | ||
332 | STATION_INFO_TX_BITRATE | | ||
333 | STATION_INFO_RX_DROP_MISC; | ||
346 | 334 | ||
347 | sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); | 335 | sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); |
348 | sinfo->rx_bytes = sta->rx_bytes; | 336 | sinfo->rx_bytes = sta->rx_bytes; |
349 | sinfo->tx_bytes = sta->tx_bytes; | 337 | sinfo->tx_bytes = sta->tx_bytes; |
350 | sinfo->rx_packets = sta->rx_packets; | 338 | sinfo->rx_packets = sta->rx_packets; |
351 | sinfo->tx_packets = sta->tx_packets; | 339 | sinfo->tx_packets = sta->tx_packets; |
340 | sinfo->tx_retries = sta->tx_retry_count; | ||
341 | sinfo->tx_failed = sta->tx_retry_failed; | ||
342 | sinfo->rx_dropped_misc = sta->rx_dropped; | ||
352 | 343 | ||
353 | if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) || | 344 | if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) || |
354 | (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) { | 345 | (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) { |
@@ -634,6 +625,7 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
634 | struct sta_info *sta, | 625 | struct sta_info *sta, |
635 | struct station_parameters *params) | 626 | struct station_parameters *params) |
636 | { | 627 | { |
628 | unsigned long flags; | ||
637 | u32 rates; | 629 | u32 rates; |
638 | int i, j; | 630 | int i, j; |
639 | struct ieee80211_supported_band *sband; | 631 | struct ieee80211_supported_band *sband; |
@@ -642,7 +634,7 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
642 | 634 | ||
643 | sband = local->hw.wiphy->bands[local->oper_channel->band]; | 635 | sband = local->hw.wiphy->bands[local->oper_channel->band]; |
644 | 636 | ||
645 | spin_lock_bh(&sta->lock); | 637 | spin_lock_irqsave(&sta->flaglock, flags); |
646 | mask = params->sta_flags_mask; | 638 | mask = params->sta_flags_mask; |
647 | set = params->sta_flags_set; | 639 | set = params->sta_flags_set; |
648 | 640 | ||
@@ -669,7 +661,7 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
669 | if (set & BIT(NL80211_STA_FLAG_MFP)) | 661 | if (set & BIT(NL80211_STA_FLAG_MFP)) |
670 | sta->flags |= WLAN_STA_MFP; | 662 | sta->flags |= WLAN_STA_MFP; |
671 | } | 663 | } |
672 | spin_unlock_bh(&sta->lock); | 664 | spin_unlock_irqrestore(&sta->flaglock, flags); |
673 | 665 | ||
674 | /* | 666 | /* |
675 | * cfg80211 validates this (1-2007) and allows setting the AID | 667 | * cfg80211 validates this (1-2007) and allows setting the AID |
@@ -1143,9 +1135,9 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy, | |||
1143 | p.uapsd = false; | 1135 | p.uapsd = false; |
1144 | 1136 | ||
1145 | if (drv_conf_tx(local, params->queue, &p)) { | 1137 | if (drv_conf_tx(local, params->queue, &p)) { |
1146 | printk(KERN_DEBUG "%s: failed to set TX queue " | 1138 | wiphy_debug(local->hw.wiphy, |
1147 | "parameters for queue %d\n", | 1139 | "failed to set TX queue parameters for queue %d\n", |
1148 | wiphy_name(local->hw.wiphy), params->queue); | 1140 | params->queue); |
1149 | return -EINVAL; | 1141 | return -EINVAL; |
1150 | } | 1142 | } |
1151 | 1143 | ||
@@ -1207,15 +1199,26 @@ static int ieee80211_scan(struct wiphy *wiphy, | |||
1207 | struct net_device *dev, | 1199 | struct net_device *dev, |
1208 | struct cfg80211_scan_request *req) | 1200 | struct cfg80211_scan_request *req) |
1209 | { | 1201 | { |
1210 | struct ieee80211_sub_if_data *sdata; | 1202 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
1211 | |||
1212 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
1213 | 1203 | ||
1214 | if (sdata->vif.type != NL80211_IFTYPE_STATION && | 1204 | switch (ieee80211_vif_type_p2p(&sdata->vif)) { |
1215 | sdata->vif.type != NL80211_IFTYPE_ADHOC && | 1205 | case NL80211_IFTYPE_STATION: |
1216 | sdata->vif.type != NL80211_IFTYPE_MESH_POINT && | 1206 | case NL80211_IFTYPE_ADHOC: |
1217 | (sdata->vif.type != NL80211_IFTYPE_AP || sdata->u.ap.beacon)) | 1207 | case NL80211_IFTYPE_MESH_POINT: |
1208 | case NL80211_IFTYPE_P2P_CLIENT: | ||
1209 | break; | ||
1210 | case NL80211_IFTYPE_P2P_GO: | ||
1211 | if (sdata->local->ops->hw_scan) | ||
1212 | break; | ||
1213 | /* FIXME: implement NoA while scanning in software */ | ||
1214 | return -EOPNOTSUPP; | ||
1215 | case NL80211_IFTYPE_AP: | ||
1216 | if (sdata->u.ap.beacon) | ||
1217 | return -EOPNOTSUPP; | ||
1218 | break; | ||
1219 | default: | ||
1218 | return -EOPNOTSUPP; | 1220 | return -EOPNOTSUPP; |
1221 | } | ||
1219 | 1222 | ||
1220 | return ieee80211_request_scan(sdata, req); | 1223 | return ieee80211_request_scan(sdata, req); |
1221 | } | 1224 | } |
@@ -1362,7 +1365,7 @@ static int ieee80211_get_tx_power(struct wiphy *wiphy, int *dbm) | |||
1362 | } | 1365 | } |
1363 | 1366 | ||
1364 | static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev, | 1367 | static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev, |
1365 | u8 *addr) | 1368 | const u8 *addr) |
1366 | { | 1369 | { |
1367 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1370 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
1368 | 1371 | ||
@@ -1411,7 +1414,7 @@ int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata, | |||
1411 | if (!sdata->u.mgd.associated || | 1414 | if (!sdata->u.mgd.associated || |
1412 | sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) { | 1415 | sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) { |
1413 | mutex_lock(&sdata->local->iflist_mtx); | 1416 | mutex_lock(&sdata->local->iflist_mtx); |
1414 | ieee80211_recalc_smps(sdata->local, sdata); | 1417 | ieee80211_recalc_smps(sdata->local); |
1415 | mutex_unlock(&sdata->local->iflist_mtx); | 1418 | mutex_unlock(&sdata->local->iflist_mtx); |
1416 | return 0; | 1419 | return 0; |
1417 | } | 1420 | } |
@@ -1541,11 +1544,11 @@ static int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy, | |||
1541 | return ieee80211_wk_cancel_remain_on_channel(sdata, cookie); | 1544 | return ieee80211_wk_cancel_remain_on_channel(sdata, cookie); |
1542 | } | 1545 | } |
1543 | 1546 | ||
1544 | static int ieee80211_action(struct wiphy *wiphy, struct net_device *dev, | 1547 | static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, |
1545 | struct ieee80211_channel *chan, | 1548 | struct ieee80211_channel *chan, |
1546 | enum nl80211_channel_type channel_type, | 1549 | enum nl80211_channel_type channel_type, |
1547 | bool channel_type_valid, | 1550 | bool channel_type_valid, |
1548 | const u8 *buf, size_t len, u64 *cookie) | 1551 | const u8 *buf, size_t len, u64 *cookie) |
1549 | { | 1552 | { |
1550 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1553 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
1551 | struct ieee80211_local *local = sdata->local; | 1554 | struct ieee80211_local *local = sdata->local; |
@@ -1566,7 +1569,11 @@ static int ieee80211_action(struct wiphy *wiphy, struct net_device *dev, | |||
1566 | 1569 | ||
1567 | switch (sdata->vif.type) { | 1570 | switch (sdata->vif.type) { |
1568 | case NL80211_IFTYPE_ADHOC: | 1571 | case NL80211_IFTYPE_ADHOC: |
1569 | if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) | 1572 | case NL80211_IFTYPE_AP: |
1573 | case NL80211_IFTYPE_AP_VLAN: | ||
1574 | case NL80211_IFTYPE_P2P_GO: | ||
1575 | if (!ieee80211_is_action(mgmt->frame_control) || | ||
1576 | mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) | ||
1570 | break; | 1577 | break; |
1571 | rcu_read_lock(); | 1578 | rcu_read_lock(); |
1572 | sta = sta_info_get(sdata, mgmt->da); | 1579 | sta = sta_info_get(sdata, mgmt->da); |
@@ -1575,8 +1582,7 @@ static int ieee80211_action(struct wiphy *wiphy, struct net_device *dev, | |||
1575 | return -ENOLINK; | 1582 | return -ENOLINK; |
1576 | break; | 1583 | break; |
1577 | case NL80211_IFTYPE_STATION: | 1584 | case NL80211_IFTYPE_STATION: |
1578 | if (!(sdata->u.mgd.flags & IEEE80211_STA_MFP_ENABLED)) | 1585 | case NL80211_IFTYPE_P2P_CLIENT: |
1579 | flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; | ||
1580 | break; | 1586 | break; |
1581 | default: | 1587 | default: |
1582 | return -EOPNOTSUPP; | 1588 | return -EOPNOTSUPP; |
@@ -1598,6 +1604,23 @@ static int ieee80211_action(struct wiphy *wiphy, struct net_device *dev, | |||
1598 | return 0; | 1604 | return 0; |
1599 | } | 1605 | } |
1600 | 1606 | ||
1607 | static void ieee80211_mgmt_frame_register(struct wiphy *wiphy, | ||
1608 | struct net_device *dev, | ||
1609 | u16 frame_type, bool reg) | ||
1610 | { | ||
1611 | struct ieee80211_local *local = wiphy_priv(wiphy); | ||
1612 | |||
1613 | if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ)) | ||
1614 | return; | ||
1615 | |||
1616 | if (reg) | ||
1617 | local->probe_req_reg++; | ||
1618 | else | ||
1619 | local->probe_req_reg--; | ||
1620 | |||
1621 | ieee80211_queue_work(&local->hw, &local->reconfig_filter); | ||
1622 | } | ||
1623 | |||
1601 | struct cfg80211_ops mac80211_config_ops = { | 1624 | struct cfg80211_ops mac80211_config_ops = { |
1602 | .add_virtual_intf = ieee80211_add_iface, | 1625 | .add_virtual_intf = ieee80211_add_iface, |
1603 | .del_virtual_intf = ieee80211_del_iface, | 1626 | .del_virtual_intf = ieee80211_del_iface, |
@@ -1647,6 +1670,7 @@ struct cfg80211_ops mac80211_config_ops = { | |||
1647 | .set_bitrate_mask = ieee80211_set_bitrate_mask, | 1670 | .set_bitrate_mask = ieee80211_set_bitrate_mask, |
1648 | .remain_on_channel = ieee80211_remain_on_channel, | 1671 | .remain_on_channel = ieee80211_remain_on_channel, |
1649 | .cancel_remain_on_channel = ieee80211_cancel_remain_on_channel, | 1672 | .cancel_remain_on_channel = ieee80211_cancel_remain_on_channel, |
1650 | .action = ieee80211_action, | 1673 | .mgmt_tx = ieee80211_mgmt_tx, |
1651 | .set_cqm_rssi_config = ieee80211_set_cqm_rssi_config, | 1674 | .set_cqm_rssi_config = ieee80211_set_cqm_rssi_config, |
1675 | .mgmt_frame_register = ieee80211_mgmt_frame_register, | ||
1652 | }; | 1676 | }; |
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 32be11e4c4d..5b24740fc0b 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c | |||
@@ -11,7 +11,7 @@ __ieee80211_get_channel_mode(struct ieee80211_local *local, | |||
11 | { | 11 | { |
12 | struct ieee80211_sub_if_data *sdata; | 12 | struct ieee80211_sub_if_data *sdata; |
13 | 13 | ||
14 | WARN_ON(!mutex_is_locked(&local->iflist_mtx)); | 14 | lockdep_assert_held(&local->iflist_mtx); |
15 | 15 | ||
16 | list_for_each_entry(sdata, &local->interfaces, list) { | 16 | list_for_each_entry(sdata, &local->interfaces, list) { |
17 | if (sdata == ignore) | 17 | if (sdata == ignore) |
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index b8b0ae79a74..18260aa99c5 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c | |||
@@ -86,13 +86,15 @@ static ssize_t tsf_write(struct file *file, | |||
86 | if (strncmp(buf, "reset", 5) == 0) { | 86 | if (strncmp(buf, "reset", 5) == 0) { |
87 | if (local->ops->reset_tsf) { | 87 | if (local->ops->reset_tsf) { |
88 | drv_reset_tsf(local); | 88 | drv_reset_tsf(local); |
89 | printk(KERN_INFO "%s: debugfs reset TSF\n", wiphy_name(local->hw.wiphy)); | 89 | wiphy_info(local->hw.wiphy, "debugfs reset TSF\n"); |
90 | } | 90 | } |
91 | } else { | 91 | } else { |
92 | tsf = simple_strtoul(buf, NULL, 0); | 92 | tsf = simple_strtoul(buf, NULL, 0); |
93 | if (local->ops->set_tsf) { | 93 | if (local->ops->set_tsf) { |
94 | drv_set_tsf(local, tsf); | 94 | drv_set_tsf(local, tsf); |
95 | printk(KERN_INFO "%s: debugfs set TSF to %#018llx\n", wiphy_name(local->hw.wiphy), tsf); | 95 | wiphy_info(local->hw.wiphy, |
96 | "debugfs set TSF to %#018llx\n", tsf); | ||
97 | |||
96 | } | 98 | } |
97 | } | 99 | } |
98 | 100 | ||
@@ -375,7 +377,6 @@ void debugfs_hw_add(struct ieee80211_local *local) | |||
375 | if (!phyd) | 377 | if (!phyd) |
376 | return; | 378 | return; |
377 | 379 | ||
378 | local->debugfs.stations = debugfs_create_dir("stations", phyd); | ||
379 | local->debugfs.keys = debugfs_create_dir("keys", phyd); | 380 | local->debugfs.keys = debugfs_create_dir("keys", phyd); |
380 | 381 | ||
381 | DEBUGFS_ADD(frequency); | 382 | DEBUGFS_ADD(frequency); |
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c index 7cd8dd9fc24..4aa47d074a7 100644 --- a/net/mac80211/debugfs_key.c +++ b/net/mac80211/debugfs_key.c | |||
@@ -66,26 +66,13 @@ static ssize_t key_algorithm_read(struct file *file, | |||
66 | char __user *userbuf, | 66 | char __user *userbuf, |
67 | size_t count, loff_t *ppos) | 67 | size_t count, loff_t *ppos) |
68 | { | 68 | { |
69 | char *alg; | 69 | char buf[15]; |
70 | struct ieee80211_key *key = file->private_data; | 70 | struct ieee80211_key *key = file->private_data; |
71 | u32 c = key->conf.cipher; | ||
71 | 72 | ||
72 | switch (key->conf.alg) { | 73 | sprintf(buf, "%.2x-%.2x-%.2x:%d\n", |
73 | case ALG_WEP: | 74 | c >> 24, (c >> 16) & 0xff, (c >> 8) & 0xff, c & 0xff); |
74 | alg = "WEP\n"; | 75 | return simple_read_from_buffer(userbuf, count, ppos, buf, strlen(buf)); |
75 | break; | ||
76 | case ALG_TKIP: | ||
77 | alg = "TKIP\n"; | ||
78 | break; | ||
79 | case ALG_CCMP: | ||
80 | alg = "CCMP\n"; | ||
81 | break; | ||
82 | case ALG_AES_CMAC: | ||
83 | alg = "AES-128-CMAC\n"; | ||
84 | break; | ||
85 | default: | ||
86 | return 0; | ||
87 | } | ||
88 | return simple_read_from_buffer(userbuf, count, ppos, alg, strlen(alg)); | ||
89 | } | 76 | } |
90 | KEY_OPS(algorithm); | 77 | KEY_OPS(algorithm); |
91 | 78 | ||
@@ -97,21 +84,22 @@ static ssize_t key_tx_spec_read(struct file *file, char __user *userbuf, | |||
97 | int len; | 84 | int len; |
98 | struct ieee80211_key *key = file->private_data; | 85 | struct ieee80211_key *key = file->private_data; |
99 | 86 | ||
100 | switch (key->conf.alg) { | 87 | switch (key->conf.cipher) { |
101 | case ALG_WEP: | 88 | case WLAN_CIPHER_SUITE_WEP40: |
89 | case WLAN_CIPHER_SUITE_WEP104: | ||
102 | len = scnprintf(buf, sizeof(buf), "\n"); | 90 | len = scnprintf(buf, sizeof(buf), "\n"); |
103 | break; | 91 | break; |
104 | case ALG_TKIP: | 92 | case WLAN_CIPHER_SUITE_TKIP: |
105 | len = scnprintf(buf, sizeof(buf), "%08x %04x\n", | 93 | len = scnprintf(buf, sizeof(buf), "%08x %04x\n", |
106 | key->u.tkip.tx.iv32, | 94 | key->u.tkip.tx.iv32, |
107 | key->u.tkip.tx.iv16); | 95 | key->u.tkip.tx.iv16); |
108 | break; | 96 | break; |
109 | case ALG_CCMP: | 97 | case WLAN_CIPHER_SUITE_CCMP: |
110 | tpn = key->u.ccmp.tx_pn; | 98 | tpn = key->u.ccmp.tx_pn; |
111 | len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n", | 99 | len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n", |
112 | tpn[0], tpn[1], tpn[2], tpn[3], tpn[4], tpn[5]); | 100 | tpn[0], tpn[1], tpn[2], tpn[3], tpn[4], tpn[5]); |
113 | break; | 101 | break; |
114 | case ALG_AES_CMAC: | 102 | case WLAN_CIPHER_SUITE_AES_CMAC: |
115 | tpn = key->u.aes_cmac.tx_pn; | 103 | tpn = key->u.aes_cmac.tx_pn; |
116 | len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n", | 104 | len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n", |
117 | tpn[0], tpn[1], tpn[2], tpn[3], tpn[4], | 105 | tpn[0], tpn[1], tpn[2], tpn[3], tpn[4], |
@@ -132,11 +120,12 @@ static ssize_t key_rx_spec_read(struct file *file, char __user *userbuf, | |||
132 | int i, len; | 120 | int i, len; |
133 | const u8 *rpn; | 121 | const u8 *rpn; |
134 | 122 | ||
135 | switch (key->conf.alg) { | 123 | switch (key->conf.cipher) { |
136 | case ALG_WEP: | 124 | case WLAN_CIPHER_SUITE_WEP40: |
125 | case WLAN_CIPHER_SUITE_WEP104: | ||
137 | len = scnprintf(buf, sizeof(buf), "\n"); | 126 | len = scnprintf(buf, sizeof(buf), "\n"); |
138 | break; | 127 | break; |
139 | case ALG_TKIP: | 128 | case WLAN_CIPHER_SUITE_TKIP: |
140 | for (i = 0; i < NUM_RX_DATA_QUEUES; i++) | 129 | for (i = 0; i < NUM_RX_DATA_QUEUES; i++) |
141 | p += scnprintf(p, sizeof(buf)+buf-p, | 130 | p += scnprintf(p, sizeof(buf)+buf-p, |
142 | "%08x %04x\n", | 131 | "%08x %04x\n", |
@@ -144,7 +133,7 @@ static ssize_t key_rx_spec_read(struct file *file, char __user *userbuf, | |||
144 | key->u.tkip.rx[i].iv16); | 133 | key->u.tkip.rx[i].iv16); |
145 | len = p - buf; | 134 | len = p - buf; |
146 | break; | 135 | break; |
147 | case ALG_CCMP: | 136 | case WLAN_CIPHER_SUITE_CCMP: |
148 | for (i = 0; i < NUM_RX_DATA_QUEUES + 1; i++) { | 137 | for (i = 0; i < NUM_RX_DATA_QUEUES + 1; i++) { |
149 | rpn = key->u.ccmp.rx_pn[i]; | 138 | rpn = key->u.ccmp.rx_pn[i]; |
150 | p += scnprintf(p, sizeof(buf)+buf-p, | 139 | p += scnprintf(p, sizeof(buf)+buf-p, |
@@ -154,7 +143,7 @@ static ssize_t key_rx_spec_read(struct file *file, char __user *userbuf, | |||
154 | } | 143 | } |
155 | len = p - buf; | 144 | len = p - buf; |
156 | break; | 145 | break; |
157 | case ALG_AES_CMAC: | 146 | case WLAN_CIPHER_SUITE_AES_CMAC: |
158 | rpn = key->u.aes_cmac.rx_pn; | 147 | rpn = key->u.aes_cmac.rx_pn; |
159 | p += scnprintf(p, sizeof(buf)+buf-p, | 148 | p += scnprintf(p, sizeof(buf)+buf-p, |
160 | "%02x%02x%02x%02x%02x%02x\n", | 149 | "%02x%02x%02x%02x%02x%02x\n", |
@@ -176,11 +165,11 @@ static ssize_t key_replays_read(struct file *file, char __user *userbuf, | |||
176 | char buf[20]; | 165 | char buf[20]; |
177 | int len; | 166 | int len; |
178 | 167 | ||
179 | switch (key->conf.alg) { | 168 | switch (key->conf.cipher) { |
180 | case ALG_CCMP: | 169 | case WLAN_CIPHER_SUITE_CCMP: |
181 | len = scnprintf(buf, sizeof(buf), "%u\n", key->u.ccmp.replays); | 170 | len = scnprintf(buf, sizeof(buf), "%u\n", key->u.ccmp.replays); |
182 | break; | 171 | break; |
183 | case ALG_AES_CMAC: | 172 | case WLAN_CIPHER_SUITE_AES_CMAC: |
184 | len = scnprintf(buf, sizeof(buf), "%u\n", | 173 | len = scnprintf(buf, sizeof(buf), "%u\n", |
185 | key->u.aes_cmac.replays); | 174 | key->u.aes_cmac.replays); |
186 | break; | 175 | break; |
@@ -198,8 +187,8 @@ static ssize_t key_icverrors_read(struct file *file, char __user *userbuf, | |||
198 | char buf[20]; | 187 | char buf[20]; |
199 | int len; | 188 | int len; |
200 | 189 | ||
201 | switch (key->conf.alg) { | 190 | switch (key->conf.cipher) { |
202 | case ALG_AES_CMAC: | 191 | case WLAN_CIPHER_SUITE_AES_CMAC: |
203 | len = scnprintf(buf, sizeof(buf), "%u\n", | 192 | len = scnprintf(buf, sizeof(buf), "%u\n", |
204 | key->u.aes_cmac.icverrors); | 193 | key->u.aes_cmac.icverrors); |
205 | break; | 194 | break; |
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index 8ad33eef7dd..cbdf36d7841 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c | |||
@@ -410,6 +410,9 @@ void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata) | |||
410 | sprintf(buf, "netdev:%s", sdata->name); | 410 | sprintf(buf, "netdev:%s", sdata->name); |
411 | sdata->debugfs.dir = debugfs_create_dir(buf, | 411 | sdata->debugfs.dir = debugfs_create_dir(buf, |
412 | sdata->local->hw.wiphy->debugfsdir); | 412 | sdata->local->hw.wiphy->debugfsdir); |
413 | if (sdata->debugfs.dir) | ||
414 | sdata->debugfs.subdir_stations = debugfs_create_dir("stations", | ||
415 | sdata->debugfs.dir); | ||
413 | add_files(sdata); | 416 | add_files(sdata); |
414 | } | 417 | } |
415 | 418 | ||
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 6a8fdc372c4..4601fea1784 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c | |||
@@ -198,7 +198,8 @@ static ssize_t sta_agg_status_write(struct file *file, const char __user *userbu | |||
198 | else | 198 | else |
199 | ret = ieee80211_stop_tx_ba_session(&sta->sta, tid); | 199 | ret = ieee80211_stop_tx_ba_session(&sta->sta, tid); |
200 | } else { | 200 | } else { |
201 | __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT, 3); | 201 | __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT, |
202 | 3, true); | ||
202 | ret = 0; | 203 | ret = 0; |
203 | } | 204 | } |
204 | 205 | ||
@@ -302,7 +303,7 @@ STA_OPS(ht_capa); | |||
302 | 303 | ||
303 | void ieee80211_sta_debugfs_add(struct sta_info *sta) | 304 | void ieee80211_sta_debugfs_add(struct sta_info *sta) |
304 | { | 305 | { |
305 | struct dentry *stations_dir = sta->local->debugfs.stations; | 306 | struct dentry *stations_dir = sta->sdata->debugfs.subdir_stations; |
306 | u8 mac[3*ETH_ALEN]; | 307 | u8 mac[3*ETH_ALEN]; |
307 | 308 | ||
308 | sta->debugfs.add_has_run = true; | 309 | sta->debugfs.add_has_run = true; |
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 14123dce544..16983825f8e 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -54,6 +54,20 @@ static inline int drv_add_interface(struct ieee80211_local *local, | |||
54 | return ret; | 54 | return ret; |
55 | } | 55 | } |
56 | 56 | ||
57 | static inline int drv_change_interface(struct ieee80211_local *local, | ||
58 | struct ieee80211_sub_if_data *sdata, | ||
59 | enum nl80211_iftype type, bool p2p) | ||
60 | { | ||
61 | int ret; | ||
62 | |||
63 | might_sleep(); | ||
64 | |||
65 | trace_drv_change_interface(local, sdata, type, p2p); | ||
66 | ret = local->ops->change_interface(&local->hw, &sdata->vif, type, p2p); | ||
67 | trace_drv_return_int(local, ret); | ||
68 | return ret; | ||
69 | } | ||
70 | |||
57 | static inline void drv_remove_interface(struct ieee80211_local *local, | 71 | static inline void drv_remove_interface(struct ieee80211_local *local, |
58 | struct ieee80211_vif *vif) | 72 | struct ieee80211_vif *vif) |
59 | { | 73 | { |
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h index 5d5d2a97466..6831fb1641c 100644 --- a/net/mac80211/driver-trace.h +++ b/net/mac80211/driver-trace.h | |||
@@ -25,12 +25,14 @@ static inline void trace_ ## name(proto) {} | |||
25 | #define STA_PR_FMT " sta:%pM" | 25 | #define STA_PR_FMT " sta:%pM" |
26 | #define STA_PR_ARG __entry->sta_addr | 26 | #define STA_PR_ARG __entry->sta_addr |
27 | 27 | ||
28 | #define VIF_ENTRY __field(enum nl80211_iftype, vif_type) __field(void *, sdata) \ | 28 | #define VIF_ENTRY __field(enum nl80211_iftype, vif_type) __field(void *, sdata) \ |
29 | __field(bool, p2p) \ | ||
29 | __string(vif_name, sdata->dev ? sdata->dev->name : "<nodev>") | 30 | __string(vif_name, sdata->dev ? sdata->dev->name : "<nodev>") |
30 | #define VIF_ASSIGN __entry->vif_type = sdata->vif.type; __entry->sdata = sdata; \ | 31 | #define VIF_ASSIGN __entry->vif_type = sdata->vif.type; __entry->sdata = sdata; \ |
32 | __entry->p2p = sdata->vif.p2p; \ | ||
31 | __assign_str(vif_name, sdata->dev ? sdata->dev->name : "<nodev>") | 33 | __assign_str(vif_name, sdata->dev ? sdata->dev->name : "<nodev>") |
32 | #define VIF_PR_FMT " vif:%s(%d)" | 34 | #define VIF_PR_FMT " vif:%s(%d%s)" |
33 | #define VIF_PR_ARG __get_str(vif_name), __entry->vif_type | 35 | #define VIF_PR_ARG __get_str(vif_name), __entry->vif_type, __entry->p2p ? "/p2p" : "" |
34 | 36 | ||
35 | /* | 37 | /* |
36 | * Tracing for driver callbacks. | 38 | * Tracing for driver callbacks. |
@@ -136,6 +138,34 @@ TRACE_EVENT(drv_add_interface, | |||
136 | ) | 138 | ) |
137 | ); | 139 | ); |
138 | 140 | ||
141 | TRACE_EVENT(drv_change_interface, | ||
142 | TP_PROTO(struct ieee80211_local *local, | ||
143 | struct ieee80211_sub_if_data *sdata, | ||
144 | enum nl80211_iftype type, bool p2p), | ||
145 | |||
146 | TP_ARGS(local, sdata, type, p2p), | ||
147 | |||
148 | TP_STRUCT__entry( | ||
149 | LOCAL_ENTRY | ||
150 | VIF_ENTRY | ||
151 | __field(u32, new_type) | ||
152 | __field(bool, new_p2p) | ||
153 | ), | ||
154 | |||
155 | TP_fast_assign( | ||
156 | LOCAL_ASSIGN; | ||
157 | VIF_ASSIGN; | ||
158 | __entry->new_type = type; | ||
159 | __entry->new_p2p = p2p; | ||
160 | ), | ||
161 | |||
162 | TP_printk( | ||
163 | LOCAL_PR_FMT VIF_PR_FMT " new type:%d%s", | ||
164 | LOCAL_PR_ARG, VIF_PR_ARG, __entry->new_type, | ||
165 | __entry->new_p2p ? "/p2p" : "" | ||
166 | ) | ||
167 | ); | ||
168 | |||
139 | TRACE_EVENT(drv_remove_interface, | 169 | TRACE_EVENT(drv_remove_interface, |
140 | TP_PROTO(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata), | 170 | TP_PROTO(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata), |
141 | 171 | ||
@@ -336,7 +366,7 @@ TRACE_EVENT(drv_set_key, | |||
336 | LOCAL_ENTRY | 366 | LOCAL_ENTRY |
337 | VIF_ENTRY | 367 | VIF_ENTRY |
338 | STA_ENTRY | 368 | STA_ENTRY |
339 | __field(enum ieee80211_key_alg, alg) | 369 | __field(u32, cipher) |
340 | __field(u8, hw_key_idx) | 370 | __field(u8, hw_key_idx) |
341 | __field(u8, flags) | 371 | __field(u8, flags) |
342 | __field(s8, keyidx) | 372 | __field(s8, keyidx) |
@@ -346,7 +376,7 @@ TRACE_EVENT(drv_set_key, | |||
346 | LOCAL_ASSIGN; | 376 | LOCAL_ASSIGN; |
347 | VIF_ASSIGN; | 377 | VIF_ASSIGN; |
348 | STA_ASSIGN; | 378 | STA_ASSIGN; |
349 | __entry->alg = key->alg; | 379 | __entry->cipher = key->cipher; |
350 | __entry->flags = key->flags; | 380 | __entry->flags = key->flags; |
351 | __entry->keyidx = key->keyidx; | 381 | __entry->keyidx = key->keyidx; |
352 | __entry->hw_key_idx = key->hw_key_idx; | 382 | __entry->hw_key_idx = key->hw_key_idx; |
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 9d101fb3386..75d679d75e6 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c | |||
@@ -101,16 +101,16 @@ void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband, | |||
101 | ht_cap->mcs.rx_mask[32/8] |= 1; | 101 | ht_cap->mcs.rx_mask[32/8] |= 1; |
102 | } | 102 | } |
103 | 103 | ||
104 | void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta) | 104 | void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, bool tx) |
105 | { | 105 | { |
106 | int i; | 106 | int i; |
107 | 107 | ||
108 | cancel_work_sync(&sta->ampdu_mlme.work); | 108 | cancel_work_sync(&sta->ampdu_mlme.work); |
109 | 109 | ||
110 | for (i = 0; i < STA_TID_NUM; i++) { | 110 | for (i = 0; i < STA_TID_NUM; i++) { |
111 | __ieee80211_stop_tx_ba_session(sta, i, WLAN_BACK_INITIATOR); | 111 | __ieee80211_stop_tx_ba_session(sta, i, WLAN_BACK_INITIATOR, tx); |
112 | __ieee80211_stop_rx_ba_session(sta, i, WLAN_BACK_RECIPIENT, | 112 | __ieee80211_stop_rx_ba_session(sta, i, WLAN_BACK_RECIPIENT, |
113 | WLAN_REASON_QSTA_LEAVE_QBSS); | 113 | WLAN_REASON_QSTA_LEAVE_QBSS, tx); |
114 | } | 114 | } |
115 | } | 115 | } |
116 | 116 | ||
@@ -135,7 +135,7 @@ void ieee80211_ba_session_work(struct work_struct *work) | |||
135 | if (test_and_clear_bit(tid, sta->ampdu_mlme.tid_rx_timer_expired)) | 135 | if (test_and_clear_bit(tid, sta->ampdu_mlme.tid_rx_timer_expired)) |
136 | ___ieee80211_stop_rx_ba_session( | 136 | ___ieee80211_stop_rx_ba_session( |
137 | sta, tid, WLAN_BACK_RECIPIENT, | 137 | sta, tid, WLAN_BACK_RECIPIENT, |
138 | WLAN_REASON_QSTA_TIMEOUT); | 138 | WLAN_REASON_QSTA_TIMEOUT, true); |
139 | 139 | ||
140 | tid_tx = sta->ampdu_mlme.tid_tx[tid]; | 140 | tid_tx = sta->ampdu_mlme.tid_tx[tid]; |
141 | if (!tid_tx) | 141 | if (!tid_tx) |
@@ -146,7 +146,8 @@ void ieee80211_ba_session_work(struct work_struct *work) | |||
146 | else if (test_and_clear_bit(HT_AGG_STATE_WANT_STOP, | 146 | else if (test_and_clear_bit(HT_AGG_STATE_WANT_STOP, |
147 | &tid_tx->state)) | 147 | &tid_tx->state)) |
148 | ___ieee80211_stop_tx_ba_session(sta, tid, | 148 | ___ieee80211_stop_tx_ba_session(sta, tid, |
149 | WLAN_BACK_INITIATOR); | 149 | WLAN_BACK_INITIATOR, |
150 | true); | ||
150 | } | 151 | } |
151 | mutex_unlock(&sta->ampdu_mlme.mtx); | 152 | mutex_unlock(&sta->ampdu_mlme.mtx); |
152 | } | 153 | } |
@@ -214,9 +215,11 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, | |||
214 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 215 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
215 | 216 | ||
216 | if (initiator == WLAN_BACK_INITIATOR) | 217 | if (initiator == WLAN_BACK_INITIATOR) |
217 | __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_INITIATOR, 0); | 218 | __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_INITIATOR, 0, |
219 | true); | ||
218 | else | 220 | else |
219 | __ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_RECIPIENT); | 221 | __ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_RECIPIENT, |
222 | true); | ||
220 | } | 223 | } |
221 | 224 | ||
222 | int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata, | 225 | int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata, |
@@ -265,3 +268,33 @@ int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata, | |||
265 | 268 | ||
266 | return 0; | 269 | return 0; |
267 | } | 270 | } |
271 | |||
272 | void ieee80211_request_smps_work(struct work_struct *work) | ||
273 | { | ||
274 | struct ieee80211_sub_if_data *sdata = | ||
275 | container_of(work, struct ieee80211_sub_if_data, | ||
276 | u.mgd.request_smps_work); | ||
277 | |||
278 | mutex_lock(&sdata->u.mgd.mtx); | ||
279 | __ieee80211_request_smps(sdata, sdata->u.mgd.driver_smps_mode); | ||
280 | mutex_unlock(&sdata->u.mgd.mtx); | ||
281 | } | ||
282 | |||
283 | void ieee80211_request_smps(struct ieee80211_vif *vif, | ||
284 | enum ieee80211_smps_mode smps_mode) | ||
285 | { | ||
286 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | ||
287 | |||
288 | if (WARN_ON(vif->type != NL80211_IFTYPE_STATION)) | ||
289 | return; | ||
290 | |||
291 | if (WARN_ON(smps_mode == IEEE80211_SMPS_OFF)) | ||
292 | smps_mode = IEEE80211_SMPS_AUTOMATIC; | ||
293 | |||
294 | sdata->u.mgd.driver_smps_mode = smps_mode; | ||
295 | |||
296 | ieee80211_queue_work(&sdata->local->hw, | ||
297 | &sdata->u.mgd.request_smps_work); | ||
298 | } | ||
299 | /* this might change ... don't want non-open drivers using it */ | ||
300 | EXPORT_SYMBOL_GPL(ieee80211_request_smps); | ||
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index c691780725a..ff60c022f51 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -173,6 +173,19 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
173 | memcpy(skb_put(skb, ifibss->ie_len), | 173 | memcpy(skb_put(skb, ifibss->ie_len), |
174 | ifibss->ie, ifibss->ie_len); | 174 | ifibss->ie, ifibss->ie_len); |
175 | 175 | ||
176 | if (local->hw.queues >= 4) { | ||
177 | pos = skb_put(skb, 9); | ||
178 | *pos++ = WLAN_EID_VENDOR_SPECIFIC; | ||
179 | *pos++ = 7; /* len */ | ||
180 | *pos++ = 0x00; /* Microsoft OUI 00:50:F2 */ | ||
181 | *pos++ = 0x50; | ||
182 | *pos++ = 0xf2; | ||
183 | *pos++ = 2; /* WME */ | ||
184 | *pos++ = 0; /* WME info */ | ||
185 | *pos++ = 1; /* WME ver */ | ||
186 | *pos++ = 0; /* U-APSD no in use */ | ||
187 | } | ||
188 | |||
176 | rcu_assign_pointer(ifibss->presp, skb); | 189 | rcu_assign_pointer(ifibss->presp, skb); |
177 | 190 | ||
178 | sdata->vif.bss_conf.beacon_int = beacon_int; | 191 | sdata->vif.bss_conf.beacon_int = beacon_int; |
@@ -266,37 +279,45 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
266 | if (!channel || channel->flags & IEEE80211_CHAN_DISABLED) | 279 | if (!channel || channel->flags & IEEE80211_CHAN_DISABLED) |
267 | return; | 280 | return; |
268 | 281 | ||
269 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC && elems->supp_rates && | 282 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC && |
270 | memcmp(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN) == 0) { | 283 | memcmp(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN) == 0) { |
271 | supp_rates = ieee80211_sta_get_rates(local, elems, band); | ||
272 | 284 | ||
273 | rcu_read_lock(); | 285 | rcu_read_lock(); |
274 | |||
275 | sta = sta_info_get(sdata, mgmt->sa); | 286 | sta = sta_info_get(sdata, mgmt->sa); |
276 | if (sta) { | ||
277 | u32 prev_rates; | ||
278 | 287 | ||
279 | prev_rates = sta->sta.supp_rates[band]; | 288 | if (elems->supp_rates) { |
280 | /* make sure mandatory rates are always added */ | 289 | supp_rates = ieee80211_sta_get_rates(local, elems, |
281 | sta->sta.supp_rates[band] = supp_rates | | 290 | band); |
282 | ieee80211_mandatory_rates(local, band); | 291 | if (sta) { |
292 | u32 prev_rates; | ||
293 | |||
294 | prev_rates = sta->sta.supp_rates[band]; | ||
295 | /* make sure mandatory rates are always added */ | ||
296 | sta->sta.supp_rates[band] = supp_rates | | ||
297 | ieee80211_mandatory_rates(local, band); | ||
283 | 298 | ||
284 | if (sta->sta.supp_rates[band] != prev_rates) { | 299 | if (sta->sta.supp_rates[band] != prev_rates) { |
285 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 300 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
286 | printk(KERN_DEBUG "%s: updated supp_rates set " | 301 | printk(KERN_DEBUG |
287 | "for %pM based on beacon/probe_response " | 302 | "%s: updated supp_rates set " |
288 | "(0x%x -> 0x%x)\n", | 303 | "for %pM based on beacon" |
289 | sdata->name, sta->sta.addr, | 304 | "/probe_resp (0x%x -> 0x%x)\n", |
290 | prev_rates, sta->sta.supp_rates[band]); | 305 | sdata->name, sta->sta.addr, |
306 | prev_rates, | ||
307 | sta->sta.supp_rates[band]); | ||
291 | #endif | 308 | #endif |
292 | rate_control_rate_init(sta); | 309 | rate_control_rate_init(sta); |
293 | } | 310 | } |
294 | rcu_read_unlock(); | 311 | } else |
295 | } else { | 312 | sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid, |
296 | rcu_read_unlock(); | 313 | mgmt->sa, supp_rates, |
297 | ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, | 314 | GFP_ATOMIC); |
298 | supp_rates, GFP_KERNEL); | ||
299 | } | 315 | } |
316 | |||
317 | if (sta && elems->wmm_info) | ||
318 | set_sta_flags(sta, WLAN_STA_WME); | ||
319 | |||
320 | rcu_read_unlock(); | ||
300 | } | 321 | } |
301 | 322 | ||
302 | bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems, | 323 | bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems, |
@@ -427,8 +448,8 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, | |||
427 | return NULL; | 448 | return NULL; |
428 | 449 | ||
429 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 450 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
430 | printk(KERN_DEBUG "%s: Adding new IBSS station %pM (dev=%s)\n", | 451 | wiphy_debug(local->hw.wiphy, "Adding new IBSS station %pM (dev=%s)\n", |
431 | wiphy_name(local->hw.wiphy), addr, sdata->name); | 452 | addr, sdata->name); |
432 | #endif | 453 | #endif |
433 | 454 | ||
434 | sta = sta_info_alloc(sdata, addr, gfp); | 455 | sta = sta_info_alloc(sdata, addr, gfp); |
@@ -920,12 +941,14 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, | |||
920 | memcpy(sdata->u.ibss.ssid, params->ssid, IEEE80211_MAX_SSID_LEN); | 941 | memcpy(sdata->u.ibss.ssid, params->ssid, IEEE80211_MAX_SSID_LEN); |
921 | sdata->u.ibss.ssid_len = params->ssid_len; | 942 | sdata->u.ibss.ssid_len = params->ssid_len; |
922 | 943 | ||
944 | mutex_unlock(&sdata->u.ibss.mtx); | ||
945 | |||
946 | mutex_lock(&sdata->local->mtx); | ||
923 | ieee80211_recalc_idle(sdata->local); | 947 | ieee80211_recalc_idle(sdata->local); |
948 | mutex_unlock(&sdata->local->mtx); | ||
924 | 949 | ||
925 | ieee80211_queue_work(&sdata->local->hw, &sdata->work); | 950 | ieee80211_queue_work(&sdata->local->hw, &sdata->work); |
926 | 951 | ||
927 | mutex_unlock(&sdata->u.ibss.mtx); | ||
928 | |||
929 | return 0; | 952 | return 0; |
930 | } | 953 | } |
931 | 954 | ||
@@ -980,7 +1003,9 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) | |||
980 | 1003 | ||
981 | mutex_unlock(&sdata->u.ibss.mtx); | 1004 | mutex_unlock(&sdata->u.ibss.mtx); |
982 | 1005 | ||
1006 | mutex_lock(&local->mtx); | ||
983 | ieee80211_recalc_idle(sdata->local); | 1007 | ieee80211_recalc_idle(sdata->local); |
1008 | mutex_unlock(&local->mtx); | ||
984 | 1009 | ||
985 | return 0; | 1010 | return 0; |
986 | } | 1011 | } |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 65e0ed6c297..b80c3868992 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -50,12 +50,6 @@ struct ieee80211_local; | |||
50 | * increased memory use (about 2 kB of RAM per entry). */ | 50 | * increased memory use (about 2 kB of RAM per entry). */ |
51 | #define IEEE80211_FRAGMENT_MAX 4 | 51 | #define IEEE80211_FRAGMENT_MAX 4 |
52 | 52 | ||
53 | /* | ||
54 | * Time after which we ignore scan results and no longer report/use | ||
55 | * them in any way. | ||
56 | */ | ||
57 | #define IEEE80211_SCAN_RESULT_EXPIRE (10 * HZ) | ||
58 | |||
59 | #define TU_TO_EXP_TIME(x) (jiffies + usecs_to_jiffies((x) * 1024)) | 53 | #define TU_TO_EXP_TIME(x) (jiffies + usecs_to_jiffies((x) * 1024)) |
60 | 54 | ||
61 | #define IEEE80211_DEFAULT_UAPSD_QUEUES \ | 55 | #define IEEE80211_DEFAULT_UAPSD_QUEUES \ |
@@ -165,12 +159,37 @@ typedef unsigned __bitwise__ ieee80211_rx_result; | |||
165 | #define RX_DROP_MONITOR ((__force ieee80211_rx_result) 2u) | 159 | #define RX_DROP_MONITOR ((__force ieee80211_rx_result) 2u) |
166 | #define RX_QUEUED ((__force ieee80211_rx_result) 3u) | 160 | #define RX_QUEUED ((__force ieee80211_rx_result) 3u) |
167 | 161 | ||
168 | #define IEEE80211_RX_IN_SCAN BIT(0) | 162 | /** |
169 | /* frame is destined to interface currently processed (incl. multicast frames) */ | 163 | * enum ieee80211_packet_rx_flags - packet RX flags |
170 | #define IEEE80211_RX_RA_MATCH BIT(1) | 164 | * @IEEE80211_RX_RA_MATCH: frame is destined to interface currently processed |
171 | #define IEEE80211_RX_AMSDU BIT(2) | 165 | * (incl. multicast frames) |
172 | #define IEEE80211_RX_FRAGMENTED BIT(3) | 166 | * @IEEE80211_RX_IN_SCAN: received while scanning |
173 | /* only add flags here that do not change with subframes of an aMPDU */ | 167 | * @IEEE80211_RX_FRAGMENTED: fragmented frame |
168 | * @IEEE80211_RX_AMSDU: a-MSDU packet | ||
169 | * @IEEE80211_RX_MALFORMED_ACTION_FRM: action frame is malformed | ||
170 | * | ||
171 | * These are per-frame flags that are attached to a frame in the | ||
172 | * @rx_flags field of &struct ieee80211_rx_status. | ||
173 | */ | ||
174 | enum ieee80211_packet_rx_flags { | ||
175 | IEEE80211_RX_IN_SCAN = BIT(0), | ||
176 | IEEE80211_RX_RA_MATCH = BIT(1), | ||
177 | IEEE80211_RX_FRAGMENTED = BIT(2), | ||
178 | IEEE80211_RX_AMSDU = BIT(3), | ||
179 | IEEE80211_RX_MALFORMED_ACTION_FRM = BIT(4), | ||
180 | }; | ||
181 | |||
182 | /** | ||
183 | * enum ieee80211_rx_flags - RX data flags | ||
184 | * | ||
185 | * @IEEE80211_RX_CMNTR: received on cooked monitor already | ||
186 | * | ||
187 | * These flags are used across handling multiple interfaces | ||
188 | * for a single frame. | ||
189 | */ | ||
190 | enum ieee80211_rx_flags { | ||
191 | IEEE80211_RX_CMNTR = BIT(0), | ||
192 | }; | ||
174 | 193 | ||
175 | struct ieee80211_rx_data { | 194 | struct ieee80211_rx_data { |
176 | struct sk_buff *skb; | 195 | struct sk_buff *skb; |
@@ -343,10 +362,14 @@ struct ieee80211_if_managed { | |||
343 | unsigned long timers_running; /* used for quiesce/restart */ | 362 | unsigned long timers_running; /* used for quiesce/restart */ |
344 | bool powersave; /* powersave requested for this iface */ | 363 | bool powersave; /* powersave requested for this iface */ |
345 | enum ieee80211_smps_mode req_smps, /* requested smps mode */ | 364 | enum ieee80211_smps_mode req_smps, /* requested smps mode */ |
346 | ap_smps; /* smps mode AP thinks we're in */ | 365 | ap_smps, /* smps mode AP thinks we're in */ |
366 | driver_smps_mode; /* smps mode request */ | ||
367 | |||
368 | struct work_struct request_smps_work; | ||
347 | 369 | ||
348 | unsigned int flags; | 370 | unsigned int flags; |
349 | 371 | ||
372 | bool beacon_crc_valid; | ||
350 | u32 beacon_crc; | 373 | u32 beacon_crc; |
351 | 374 | ||
352 | enum { | 375 | enum { |
@@ -371,6 +394,13 @@ struct ieee80211_if_managed { | |||
371 | int ave_beacon_signal; | 394 | int ave_beacon_signal; |
372 | 395 | ||
373 | /* | 396 | /* |
397 | * Number of Beacon frames used in ave_beacon_signal. This can be used | ||
398 | * to avoid generating less reliable cqm events that would be based | ||
399 | * only on couple of received frames. | ||
400 | */ | ||
401 | unsigned int count_beacon_signal; | ||
402 | |||
403 | /* | ||
374 | * Last Beacon frame signal strength average (ave_beacon_signal / 16) | 404 | * Last Beacon frame signal strength average (ave_beacon_signal / 16) |
375 | * that triggered a cqm event. 0 indicates that no event has been | 405 | * that triggered a cqm event. 0 indicates that no event has been |
376 | * generated for the current association. | 406 | * generated for the current association. |
@@ -474,6 +504,19 @@ enum ieee80211_sub_if_data_flags { | |||
474 | IEEE80211_SDATA_DONT_BRIDGE_PACKETS = BIT(3), | 504 | IEEE80211_SDATA_DONT_BRIDGE_PACKETS = BIT(3), |
475 | }; | 505 | }; |
476 | 506 | ||
507 | /** | ||
508 | * enum ieee80211_sdata_state_bits - virtual interface state bits | ||
509 | * @SDATA_STATE_RUNNING: virtual interface is up & running; this | ||
510 | * mirrors netif_running() but is separate for interface type | ||
511 | * change handling while the interface is up | ||
512 | * @SDATA_STATE_OFFCHANNEL: This interface is currently in offchannel | ||
513 | * mode, so queues are stopped | ||
514 | */ | ||
515 | enum ieee80211_sdata_state_bits { | ||
516 | SDATA_STATE_RUNNING, | ||
517 | SDATA_STATE_OFFCHANNEL, | ||
518 | }; | ||
519 | |||
477 | struct ieee80211_sub_if_data { | 520 | struct ieee80211_sub_if_data { |
478 | struct list_head list; | 521 | struct list_head list; |
479 | 522 | ||
@@ -487,6 +530,8 @@ struct ieee80211_sub_if_data { | |||
487 | 530 | ||
488 | unsigned int flags; | 531 | unsigned int flags; |
489 | 532 | ||
533 | unsigned long state; | ||
534 | |||
490 | int drop_unencrypted; | 535 | int drop_unencrypted; |
491 | 536 | ||
492 | char name[IFNAMSIZ]; | 537 | char name[IFNAMSIZ]; |
@@ -497,17 +542,20 @@ struct ieee80211_sub_if_data { | |||
497 | */ | 542 | */ |
498 | bool ht_opmode_valid; | 543 | bool ht_opmode_valid; |
499 | 544 | ||
545 | /* to detect idle changes */ | ||
546 | bool old_idle; | ||
547 | |||
500 | /* Fragment table for host-based reassembly */ | 548 | /* Fragment table for host-based reassembly */ |
501 | struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX]; | 549 | struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX]; |
502 | unsigned int fragment_next; | 550 | unsigned int fragment_next; |
503 | 551 | ||
504 | #define NUM_DEFAULT_KEYS 4 | ||
505 | #define NUM_DEFAULT_MGMT_KEYS 2 | ||
506 | struct ieee80211_key *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS]; | 552 | struct ieee80211_key *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS]; |
507 | struct ieee80211_key *default_key; | 553 | struct ieee80211_key *default_key; |
508 | struct ieee80211_key *default_mgmt_key; | 554 | struct ieee80211_key *default_mgmt_key; |
509 | 555 | ||
510 | u16 sequence_number; | 556 | u16 sequence_number; |
557 | __be16 control_port_protocol; | ||
558 | bool control_port_no_encrypt; | ||
511 | 559 | ||
512 | struct work_struct work; | 560 | struct work_struct work; |
513 | struct sk_buff_head skb_queue; | 561 | struct sk_buff_head skb_queue; |
@@ -539,6 +587,7 @@ struct ieee80211_sub_if_data { | |||
539 | #ifdef CONFIG_MAC80211_DEBUGFS | 587 | #ifdef CONFIG_MAC80211_DEBUGFS |
540 | struct { | 588 | struct { |
541 | struct dentry *dir; | 589 | struct dentry *dir; |
590 | struct dentry *subdir_stations; | ||
542 | struct dentry *default_key; | 591 | struct dentry *default_key; |
543 | struct dentry *default_mgmt_key; | 592 | struct dentry *default_mgmt_key; |
544 | } debugfs; | 593 | } debugfs; |
@@ -595,11 +644,17 @@ enum queue_stop_reason { | |||
595 | * determine if we are on the operating channel or not | 644 | * determine if we are on the operating channel or not |
596 | * @SCAN_OFF_CHANNEL: We're off our operating channel for scanning, | 645 | * @SCAN_OFF_CHANNEL: We're off our operating channel for scanning, |
597 | * gets only set in conjunction with SCAN_SW_SCANNING | 646 | * gets only set in conjunction with SCAN_SW_SCANNING |
647 | * @SCAN_COMPLETED: Set for our scan work function when the driver reported | ||
648 | * that the scan completed. | ||
649 | * @SCAN_ABORTED: Set for our scan work function when the driver reported | ||
650 | * a scan complete for an aborted scan. | ||
598 | */ | 651 | */ |
599 | enum { | 652 | enum { |
600 | SCAN_SW_SCANNING, | 653 | SCAN_SW_SCANNING, |
601 | SCAN_HW_SCANNING, | 654 | SCAN_HW_SCANNING, |
602 | SCAN_OFF_CHANNEL, | 655 | SCAN_OFF_CHANNEL, |
656 | SCAN_COMPLETED, | ||
657 | SCAN_ABORTED, | ||
603 | }; | 658 | }; |
604 | 659 | ||
605 | /** | 660 | /** |
@@ -634,7 +689,6 @@ struct ieee80211_local { | |||
634 | /* | 689 | /* |
635 | * work stuff, potentially off-channel (in the future) | 690 | * work stuff, potentially off-channel (in the future) |
636 | */ | 691 | */ |
637 | struct mutex work_mtx; | ||
638 | struct list_head work_list; | 692 | struct list_head work_list; |
639 | struct timer_list work_timer; | 693 | struct timer_list work_timer; |
640 | struct work_struct work_work; | 694 | struct work_struct work_work; |
@@ -653,9 +707,13 @@ struct ieee80211_local { | |||
653 | int open_count; | 707 | int open_count; |
654 | int monitors, cooked_mntrs; | 708 | int monitors, cooked_mntrs; |
655 | /* number of interfaces with corresponding FIF_ flags */ | 709 | /* number of interfaces with corresponding FIF_ flags */ |
656 | int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll; | 710 | int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll, |
711 | fif_probe_req; | ||
712 | int probe_req_reg; | ||
657 | unsigned int filter_flags; /* FIF_* */ | 713 | unsigned int filter_flags; /* FIF_* */ |
658 | 714 | ||
715 | bool wiphy_ciphers_allocated; | ||
716 | |||
659 | /* protects the aggregated multicast list and filter calls */ | 717 | /* protects the aggregated multicast list and filter calls */ |
660 | spinlock_t filter_lock; | 718 | spinlock_t filter_lock; |
661 | 719 | ||
@@ -746,9 +804,10 @@ struct ieee80211_local { | |||
746 | */ | 804 | */ |
747 | struct mutex key_mtx; | 805 | struct mutex key_mtx; |
748 | 806 | ||
807 | /* mutex for scan and work locking */ | ||
808 | struct mutex mtx; | ||
749 | 809 | ||
750 | /* Scanning and BSS list */ | 810 | /* Scanning and BSS list */ |
751 | struct mutex scan_mtx; | ||
752 | unsigned long scanning; | 811 | unsigned long scanning; |
753 | struct cfg80211_ssid scan_ssid; | 812 | struct cfg80211_ssid scan_ssid; |
754 | struct cfg80211_scan_request *int_scan_req; | 813 | struct cfg80211_scan_request *int_scan_req; |
@@ -866,10 +925,14 @@ struct ieee80211_local { | |||
866 | #ifdef CONFIG_MAC80211_DEBUGFS | 925 | #ifdef CONFIG_MAC80211_DEBUGFS |
867 | struct local_debugfsdentries { | 926 | struct local_debugfsdentries { |
868 | struct dentry *rcdir; | 927 | struct dentry *rcdir; |
869 | struct dentry *stations; | ||
870 | struct dentry *keys; | 928 | struct dentry *keys; |
871 | } debugfs; | 929 | } debugfs; |
872 | #endif | 930 | #endif |
931 | |||
932 | /* dummy netdev for use w/ NAPI */ | ||
933 | struct net_device napi_dev; | ||
934 | |||
935 | struct napi_struct napi; | ||
873 | }; | 936 | }; |
874 | 937 | ||
875 | static inline struct ieee80211_sub_if_data * | 938 | static inline struct ieee80211_sub_if_data * |
@@ -1003,6 +1066,8 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata); | |||
1003 | void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata); | 1066 | void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata); |
1004 | void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | 1067 | void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, |
1005 | struct sk_buff *skb); | 1068 | struct sk_buff *skb); |
1069 | void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata); | ||
1070 | void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata); | ||
1006 | 1071 | ||
1007 | /* IBSS code */ | 1072 | /* IBSS code */ |
1008 | void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local); | 1073 | void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local); |
@@ -1068,10 +1133,12 @@ void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata); | |||
1068 | void ieee80211_remove_interfaces(struct ieee80211_local *local); | 1133 | void ieee80211_remove_interfaces(struct ieee80211_local *local); |
1069 | u32 __ieee80211_recalc_idle(struct ieee80211_local *local); | 1134 | u32 __ieee80211_recalc_idle(struct ieee80211_local *local); |
1070 | void ieee80211_recalc_idle(struct ieee80211_local *local); | 1135 | void ieee80211_recalc_idle(struct ieee80211_local *local); |
1136 | void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata, | ||
1137 | const int offset); | ||
1071 | 1138 | ||
1072 | static inline bool ieee80211_sdata_running(struct ieee80211_sub_if_data *sdata) | 1139 | static inline bool ieee80211_sdata_running(struct ieee80211_sub_if_data *sdata) |
1073 | { | 1140 | { |
1074 | return netif_running(sdata->dev); | 1141 | return test_bit(SDATA_STATE_RUNNING, &sdata->state); |
1075 | } | 1142 | } |
1076 | 1143 | ||
1077 | /* tx handling */ | 1144 | /* tx handling */ |
@@ -1105,12 +1172,13 @@ void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata, | |||
1105 | int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata, | 1172 | int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata, |
1106 | enum ieee80211_smps_mode smps, const u8 *da, | 1173 | enum ieee80211_smps_mode smps, const u8 *da, |
1107 | const u8 *bssid); | 1174 | const u8 *bssid); |
1175 | void ieee80211_request_smps_work(struct work_struct *work); | ||
1108 | 1176 | ||
1109 | void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, | 1177 | void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, |
1110 | u16 initiator, u16 reason); | 1178 | u16 initiator, u16 reason, bool stop); |
1111 | void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, | 1179 | void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, |
1112 | u16 initiator, u16 reason); | 1180 | u16 initiator, u16 reason, bool stop); |
1113 | void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta); | 1181 | void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, bool tx); |
1114 | void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, | 1182 | void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, |
1115 | struct sta_info *sta, | 1183 | struct sta_info *sta, |
1116 | struct ieee80211_mgmt *mgmt, size_t len); | 1184 | struct ieee80211_mgmt *mgmt, size_t len); |
@@ -1124,13 +1192,16 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, | |||
1124 | size_t len); | 1192 | size_t len); |
1125 | 1193 | ||
1126 | int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | 1194 | int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, |
1127 | enum ieee80211_back_parties initiator); | 1195 | enum ieee80211_back_parties initiator, |
1196 | bool tx); | ||
1128 | int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | 1197 | int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, |
1129 | enum ieee80211_back_parties initiator); | 1198 | enum ieee80211_back_parties initiator, |
1199 | bool tx); | ||
1130 | void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid); | 1200 | void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid); |
1131 | void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid); | 1201 | void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid); |
1132 | void ieee80211_ba_session_work(struct work_struct *work); | 1202 | void ieee80211_ba_session_work(struct work_struct *work); |
1133 | void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid); | 1203 | void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid); |
1204 | void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid); | ||
1134 | 1205 | ||
1135 | /* Spectrum management */ | 1206 | /* Spectrum management */ |
1136 | void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata, | 1207 | void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata, |
@@ -1146,6 +1217,12 @@ int __ieee80211_suspend(struct ieee80211_hw *hw); | |||
1146 | 1217 | ||
1147 | static inline int __ieee80211_resume(struct ieee80211_hw *hw) | 1218 | static inline int __ieee80211_resume(struct ieee80211_hw *hw) |
1148 | { | 1219 | { |
1220 | struct ieee80211_local *local = hw_to_local(hw); | ||
1221 | |||
1222 | WARN(test_bit(SCAN_HW_SCANNING, &local->scanning), | ||
1223 | "%s: resume with hardware scan still in progress\n", | ||
1224 | wiphy_name(hw->wiphy)); | ||
1225 | |||
1149 | return ieee80211_reconfig(hw_to_local(hw)); | 1226 | return ieee80211_reconfig(hw_to_local(hw)); |
1150 | } | 1227 | } |
1151 | #else | 1228 | #else |
@@ -1208,7 +1285,8 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, | |||
1208 | const u8 *key, u8 key_len, u8 key_idx); | 1285 | const u8 *key, u8 key_len, u8 key_idx); |
1209 | int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, | 1286 | int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, |
1210 | const u8 *ie, size_t ie_len, | 1287 | const u8 *ie, size_t ie_len, |
1211 | enum ieee80211_band band); | 1288 | enum ieee80211_band band, u32 rate_mask, |
1289 | u8 channel); | ||
1212 | void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, | 1290 | void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, |
1213 | const u8 *ssid, size_t ssid_len, | 1291 | const u8 *ssid, size_t ssid_len, |
1214 | const u8 *ie, size_t ie_len); | 1292 | const u8 *ie, size_t ie_len); |
@@ -1221,8 +1299,7 @@ u32 ieee80211_sta_get_rates(struct ieee80211_local *local, | |||
1221 | enum ieee80211_band band); | 1299 | enum ieee80211_band band); |
1222 | int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata, | 1300 | int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata, |
1223 | enum ieee80211_smps_mode smps_mode); | 1301 | enum ieee80211_smps_mode smps_mode); |
1224 | void ieee80211_recalc_smps(struct ieee80211_local *local, | 1302 | void ieee80211_recalc_smps(struct ieee80211_local *local); |
1225 | struct ieee80211_sub_if_data *forsdata); | ||
1226 | 1303 | ||
1227 | size_t ieee80211_ie_split(const u8 *ies, size_t ielen, | 1304 | size_t ieee80211_ie_split(const u8 *ies, size_t ielen, |
1228 | const u8 *ids, int n_ids, size_t offset); | 1305 | const u8 *ids, int n_ids, size_t offset); |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index ebbe264e2b0..f9163b12c7f 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include "led.h" | 24 | #include "led.h" |
25 | #include "driver-ops.h" | 25 | #include "driver-ops.h" |
26 | #include "wme.h" | 26 | #include "wme.h" |
27 | #include "rate.h" | ||
27 | 28 | ||
28 | /** | 29 | /** |
29 | * DOC: Interface list locking | 30 | * DOC: Interface list locking |
@@ -94,21 +95,14 @@ static inline int identical_mac_addr_allowed(int type1, int type2) | |||
94 | type2 == NL80211_IFTYPE_AP_VLAN)); | 95 | type2 == NL80211_IFTYPE_AP_VLAN)); |
95 | } | 96 | } |
96 | 97 | ||
97 | static int ieee80211_open(struct net_device *dev) | 98 | static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata, |
99 | enum nl80211_iftype iftype) | ||
98 | { | 100 | { |
99 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
100 | struct ieee80211_sub_if_data *nsdata; | ||
101 | struct ieee80211_local *local = sdata->local; | 101 | struct ieee80211_local *local = sdata->local; |
102 | struct sta_info *sta; | 102 | struct ieee80211_sub_if_data *nsdata; |
103 | u32 changed = 0; | 103 | struct net_device *dev = sdata->dev; |
104 | int res; | ||
105 | u32 hw_reconf_flags = 0; | ||
106 | u8 null_addr[ETH_ALEN] = {0}; | ||
107 | 104 | ||
108 | /* fail early if user set an invalid address */ | 105 | ASSERT_RTNL(); |
109 | if (compare_ether_addr(dev->dev_addr, null_addr) && | ||
110 | !is_valid_ether_addr(dev->dev_addr)) | ||
111 | return -EADDRNOTAVAIL; | ||
112 | 106 | ||
113 | /* we hold the RTNL here so can safely walk the list */ | 107 | /* we hold the RTNL here so can safely walk the list */ |
114 | list_for_each_entry(nsdata, &local->interfaces, list) { | 108 | list_for_each_entry(nsdata, &local->interfaces, list) { |
@@ -125,7 +119,7 @@ static int ieee80211_open(struct net_device *dev) | |||
125 | * belonging to the same hardware. Then, however, we're | 119 | * belonging to the same hardware. Then, however, we're |
126 | * faced with having to adopt two different TSF timers... | 120 | * faced with having to adopt two different TSF timers... |
127 | */ | 121 | */ |
128 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC && | 122 | if (iftype == NL80211_IFTYPE_ADHOC && |
129 | nsdata->vif.type == NL80211_IFTYPE_ADHOC) | 123 | nsdata->vif.type == NL80211_IFTYPE_ADHOC) |
130 | return -EBUSY; | 124 | return -EBUSY; |
131 | 125 | ||
@@ -139,19 +133,56 @@ static int ieee80211_open(struct net_device *dev) | |||
139 | /* | 133 | /* |
140 | * check whether it may have the same address | 134 | * check whether it may have the same address |
141 | */ | 135 | */ |
142 | if (!identical_mac_addr_allowed(sdata->vif.type, | 136 | if (!identical_mac_addr_allowed(iftype, |
143 | nsdata->vif.type)) | 137 | nsdata->vif.type)) |
144 | return -ENOTUNIQ; | 138 | return -ENOTUNIQ; |
145 | 139 | ||
146 | /* | 140 | /* |
147 | * can only add VLANs to enabled APs | 141 | * can only add VLANs to enabled APs |
148 | */ | 142 | */ |
149 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN && | 143 | if (iftype == NL80211_IFTYPE_AP_VLAN && |
150 | nsdata->vif.type == NL80211_IFTYPE_AP) | 144 | nsdata->vif.type == NL80211_IFTYPE_AP) |
151 | sdata->bss = &nsdata->u.ap; | 145 | sdata->bss = &nsdata->u.ap; |
152 | } | 146 | } |
153 | } | 147 | } |
154 | 148 | ||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata, | ||
153 | const int offset) | ||
154 | { | ||
155 | struct ieee80211_local *local = sdata->local; | ||
156 | u32 flags = sdata->u.mntr_flags; | ||
157 | |||
158 | #define ADJUST(_f, _s) do { \ | ||
159 | if (flags & MONITOR_FLAG_##_f) \ | ||
160 | local->fif_##_s += offset; \ | ||
161 | } while (0) | ||
162 | |||
163 | ADJUST(FCSFAIL, fcsfail); | ||
164 | ADJUST(PLCPFAIL, plcpfail); | ||
165 | ADJUST(CONTROL, control); | ||
166 | ADJUST(CONTROL, pspoll); | ||
167 | ADJUST(OTHER_BSS, other_bss); | ||
168 | |||
169 | #undef ADJUST | ||
170 | } | ||
171 | |||
172 | /* | ||
173 | * NOTE: Be very careful when changing this function, it must NOT return | ||
174 | * an error on interface type changes that have been pre-checked, so most | ||
175 | * checks should be in ieee80211_check_concurrent_iface. | ||
176 | */ | ||
177 | static int ieee80211_do_open(struct net_device *dev, bool coming_up) | ||
178 | { | ||
179 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
180 | struct ieee80211_local *local = sdata->local; | ||
181 | struct sta_info *sta; | ||
182 | u32 changed = 0; | ||
183 | int res; | ||
184 | u32 hw_reconf_flags = 0; | ||
185 | |||
155 | switch (sdata->vif.type) { | 186 | switch (sdata->vif.type) { |
156 | case NL80211_IFTYPE_WDS: | 187 | case NL80211_IFTYPE_WDS: |
157 | if (!is_valid_ether_addr(sdata->u.wds.remote_addr)) | 188 | if (!is_valid_ether_addr(sdata->u.wds.remote_addr)) |
@@ -177,7 +208,9 @@ static int ieee80211_open(struct net_device *dev) | |||
177 | /* no special treatment */ | 208 | /* no special treatment */ |
178 | break; | 209 | break; |
179 | case NL80211_IFTYPE_UNSPECIFIED: | 210 | case NL80211_IFTYPE_UNSPECIFIED: |
180 | case __NL80211_IFTYPE_AFTER_LAST: | 211 | case NUM_NL80211_IFTYPES: |
212 | case NL80211_IFTYPE_P2P_CLIENT: | ||
213 | case NL80211_IFTYPE_P2P_GO: | ||
181 | /* cannot happen */ | 214 | /* cannot happen */ |
182 | WARN_ON(1); | 215 | WARN_ON(1); |
183 | break; | 216 | break; |
@@ -187,39 +220,30 @@ static int ieee80211_open(struct net_device *dev) | |||
187 | res = drv_start(local); | 220 | res = drv_start(local); |
188 | if (res) | 221 | if (res) |
189 | goto err_del_bss; | 222 | goto err_del_bss; |
223 | if (local->ops->napi_poll) | ||
224 | napi_enable(&local->napi); | ||
190 | /* we're brought up, everything changes */ | 225 | /* we're brought up, everything changes */ |
191 | hw_reconf_flags = ~0; | 226 | hw_reconf_flags = ~0; |
192 | ieee80211_led_radio(local, true); | 227 | ieee80211_led_radio(local, true); |
193 | } | 228 | } |
194 | 229 | ||
195 | /* | 230 | /* |
196 | * Check all interfaces and copy the hopefully now-present | 231 | * Copy the hopefully now-present MAC address to |
197 | * MAC address to those that have the special null one. | 232 | * this interface, if it has the special null one. |
198 | */ | 233 | */ |
199 | list_for_each_entry(nsdata, &local->interfaces, list) { | 234 | if (is_zero_ether_addr(dev->dev_addr)) { |
200 | struct net_device *ndev = nsdata->dev; | 235 | memcpy(dev->dev_addr, |
201 | 236 | local->hw.wiphy->perm_addr, | |
202 | /* | 237 | ETH_ALEN); |
203 | * No need to check running since we do not allow | 238 | memcpy(dev->perm_addr, dev->dev_addr, ETH_ALEN); |
204 | * it to start up with this invalid address. | 239 | |
205 | */ | 240 | if (!is_valid_ether_addr(dev->dev_addr)) { |
206 | if (compare_ether_addr(null_addr, ndev->dev_addr) == 0) { | 241 | if (!local->open_count) |
207 | memcpy(ndev->dev_addr, | 242 | drv_stop(local); |
208 | local->hw.wiphy->perm_addr, | 243 | return -EADDRNOTAVAIL; |
209 | ETH_ALEN); | ||
210 | memcpy(ndev->perm_addr, ndev->dev_addr, ETH_ALEN); | ||
211 | } | 244 | } |
212 | } | 245 | } |
213 | 246 | ||
214 | /* | ||
215 | * Validate the MAC address for this device. | ||
216 | */ | ||
217 | if (!is_valid_ether_addr(dev->dev_addr)) { | ||
218 | if (!local->open_count) | ||
219 | drv_stop(local); | ||
220 | return -EADDRNOTAVAIL; | ||
221 | } | ||
222 | |||
223 | switch (sdata->vif.type) { | 247 | switch (sdata->vif.type) { |
224 | case NL80211_IFTYPE_AP_VLAN: | 248 | case NL80211_IFTYPE_AP_VLAN: |
225 | /* no need to tell driver */ | 249 | /* no need to tell driver */ |
@@ -237,25 +261,17 @@ static int ieee80211_open(struct net_device *dev) | |||
237 | hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR; | 261 | hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR; |
238 | } | 262 | } |
239 | 263 | ||
240 | if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL) | 264 | ieee80211_adjust_monitor_flags(sdata, 1); |
241 | local->fif_fcsfail++; | ||
242 | if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL) | ||
243 | local->fif_plcpfail++; | ||
244 | if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) { | ||
245 | local->fif_control++; | ||
246 | local->fif_pspoll++; | ||
247 | } | ||
248 | if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) | ||
249 | local->fif_other_bss++; | ||
250 | |||
251 | ieee80211_configure_filter(local); | 265 | ieee80211_configure_filter(local); |
252 | 266 | ||
253 | netif_carrier_on(dev); | 267 | netif_carrier_on(dev); |
254 | break; | 268 | break; |
255 | default: | 269 | default: |
256 | res = drv_add_interface(local, &sdata->vif); | 270 | if (coming_up) { |
257 | if (res) | 271 | res = drv_add_interface(local, &sdata->vif); |
258 | goto err_stop; | 272 | if (res) |
273 | goto err_stop; | ||
274 | } | ||
259 | 275 | ||
260 | if (ieee80211_vif_is_mesh(&sdata->vif)) { | 276 | if (ieee80211_vif_is_mesh(&sdata->vif)) { |
261 | local->fif_other_bss++; | 277 | local->fif_other_bss++; |
@@ -264,8 +280,11 @@ static int ieee80211_open(struct net_device *dev) | |||
264 | ieee80211_start_mesh(sdata); | 280 | ieee80211_start_mesh(sdata); |
265 | } else if (sdata->vif.type == NL80211_IFTYPE_AP) { | 281 | } else if (sdata->vif.type == NL80211_IFTYPE_AP) { |
266 | local->fif_pspoll++; | 282 | local->fif_pspoll++; |
283 | local->fif_probe_req++; | ||
267 | 284 | ||
268 | ieee80211_configure_filter(local); | 285 | ieee80211_configure_filter(local); |
286 | } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { | ||
287 | local->fif_probe_req++; | ||
269 | } | 288 | } |
270 | 289 | ||
271 | changed |= ieee80211_reset_erp_info(sdata); | 290 | changed |= ieee80211_reset_erp_info(sdata); |
@@ -277,6 +296,8 @@ static int ieee80211_open(struct net_device *dev) | |||
277 | netif_carrier_on(dev); | 296 | netif_carrier_on(dev); |
278 | } | 297 | } |
279 | 298 | ||
299 | set_bit(SDATA_STATE_RUNNING, &sdata->state); | ||
300 | |||
280 | if (sdata->vif.type == NL80211_IFTYPE_WDS) { | 301 | if (sdata->vif.type == NL80211_IFTYPE_WDS) { |
281 | /* Create STA entry for the WDS peer */ | 302 | /* Create STA entry for the WDS peer */ |
282 | sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr, | 303 | sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr, |
@@ -294,6 +315,8 @@ static int ieee80211_open(struct net_device *dev) | |||
294 | /* STA has been freed */ | 315 | /* STA has been freed */ |
295 | goto err_del_interface; | 316 | goto err_del_interface; |
296 | } | 317 | } |
318 | |||
319 | rate_control_rate_init(sta); | ||
297 | } | 320 | } |
298 | 321 | ||
299 | /* | 322 | /* |
@@ -307,9 +330,13 @@ static int ieee80211_open(struct net_device *dev) | |||
307 | if (sdata->flags & IEEE80211_SDATA_PROMISC) | 330 | if (sdata->flags & IEEE80211_SDATA_PROMISC) |
308 | atomic_inc(&local->iff_promiscs); | 331 | atomic_inc(&local->iff_promiscs); |
309 | 332 | ||
333 | mutex_lock(&local->mtx); | ||
310 | hw_reconf_flags |= __ieee80211_recalc_idle(local); | 334 | hw_reconf_flags |= __ieee80211_recalc_idle(local); |
335 | mutex_unlock(&local->mtx); | ||
336 | |||
337 | if (coming_up) | ||
338 | local->open_count++; | ||
311 | 339 | ||
312 | local->open_count++; | ||
313 | if (hw_reconf_flags) { | 340 | if (hw_reconf_flags) { |
314 | ieee80211_hw_config(local, hw_reconf_flags); | 341 | ieee80211_hw_config(local, hw_reconf_flags); |
315 | /* | 342 | /* |
@@ -334,22 +361,42 @@ static int ieee80211_open(struct net_device *dev) | |||
334 | sdata->bss = NULL; | 361 | sdata->bss = NULL; |
335 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | 362 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) |
336 | list_del(&sdata->u.vlan.list); | 363 | list_del(&sdata->u.vlan.list); |
364 | clear_bit(SDATA_STATE_RUNNING, &sdata->state); | ||
337 | return res; | 365 | return res; |
338 | } | 366 | } |
339 | 367 | ||
340 | static int ieee80211_stop(struct net_device *dev) | 368 | static int ieee80211_open(struct net_device *dev) |
341 | { | 369 | { |
342 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 370 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
371 | int err; | ||
372 | |||
373 | /* fail early if user set an invalid address */ | ||
374 | if (!is_zero_ether_addr(dev->dev_addr) && | ||
375 | !is_valid_ether_addr(dev->dev_addr)) | ||
376 | return -EADDRNOTAVAIL; | ||
377 | |||
378 | err = ieee80211_check_concurrent_iface(sdata, sdata->vif.type); | ||
379 | if (err) | ||
380 | return err; | ||
381 | |||
382 | return ieee80211_do_open(dev, true); | ||
383 | } | ||
384 | |||
385 | static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | ||
386 | bool going_down) | ||
387 | { | ||
343 | struct ieee80211_local *local = sdata->local; | 388 | struct ieee80211_local *local = sdata->local; |
344 | unsigned long flags; | 389 | unsigned long flags; |
345 | struct sk_buff *skb, *tmp; | 390 | struct sk_buff *skb, *tmp; |
346 | u32 hw_reconf_flags = 0; | 391 | u32 hw_reconf_flags = 0; |
347 | int i; | 392 | int i; |
348 | 393 | ||
394 | clear_bit(SDATA_STATE_RUNNING, &sdata->state); | ||
395 | |||
349 | /* | 396 | /* |
350 | * Stop TX on this interface first. | 397 | * Stop TX on this interface first. |
351 | */ | 398 | */ |
352 | netif_tx_stop_all_queues(dev); | 399 | netif_tx_stop_all_queues(sdata->dev); |
353 | 400 | ||
354 | /* | 401 | /* |
355 | * Purge work for this interface. | 402 | * Purge work for this interface. |
@@ -366,12 +413,9 @@ static int ieee80211_stop(struct net_device *dev) | |||
366 | * (because if we remove a STA after ops->remove_interface() | 413 | * (because if we remove a STA after ops->remove_interface() |
367 | * the driver will have removed the vif info already!) | 414 | * the driver will have removed the vif info already!) |
368 | * | 415 | * |
369 | * We could relax this and only unlink the stations from the | 416 | * This is relevant only in AP, WDS and mesh modes, since in |
370 | * hash table and list but keep them on a per-sdata list that | 417 | * all other modes we've already removed all stations when |
371 | * will be inserted back again when the interface is brought | 418 | * disconnecting etc. |
372 | * up again, but I don't currently see a use case for that, | ||
373 | * except with WDS which gets a STA entry created when it is | ||
374 | * brought up. | ||
375 | */ | 419 | */ |
376 | sta_info_flush(local, sdata); | 420 | sta_info_flush(local, sdata); |
377 | 421 | ||
@@ -387,14 +431,19 @@ static int ieee80211_stop(struct net_device *dev) | |||
387 | if (sdata->flags & IEEE80211_SDATA_PROMISC) | 431 | if (sdata->flags & IEEE80211_SDATA_PROMISC) |
388 | atomic_dec(&local->iff_promiscs); | 432 | atomic_dec(&local->iff_promiscs); |
389 | 433 | ||
390 | if (sdata->vif.type == NL80211_IFTYPE_AP) | 434 | if (sdata->vif.type == NL80211_IFTYPE_AP) { |
391 | local->fif_pspoll--; | 435 | local->fif_pspoll--; |
436 | local->fif_probe_req--; | ||
437 | } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { | ||
438 | local->fif_probe_req--; | ||
439 | } | ||
392 | 440 | ||
393 | netif_addr_lock_bh(dev); | 441 | netif_addr_lock_bh(sdata->dev); |
394 | spin_lock_bh(&local->filter_lock); | 442 | spin_lock_bh(&local->filter_lock); |
395 | __hw_addr_unsync(&local->mc_list, &dev->mc, dev->addr_len); | 443 | __hw_addr_unsync(&local->mc_list, &sdata->dev->mc, |
444 | sdata->dev->addr_len); | ||
396 | spin_unlock_bh(&local->filter_lock); | 445 | spin_unlock_bh(&local->filter_lock); |
397 | netif_addr_unlock_bh(dev); | 446 | netif_addr_unlock_bh(sdata->dev); |
398 | 447 | ||
399 | ieee80211_configure_filter(local); | 448 | ieee80211_configure_filter(local); |
400 | 449 | ||
@@ -406,11 +455,21 @@ static int ieee80211_stop(struct net_device *dev) | |||
406 | struct ieee80211_sub_if_data *vlan, *tmpsdata; | 455 | struct ieee80211_sub_if_data *vlan, *tmpsdata; |
407 | struct beacon_data *old_beacon = sdata->u.ap.beacon; | 456 | struct beacon_data *old_beacon = sdata->u.ap.beacon; |
408 | 457 | ||
458 | /* sdata_running will return false, so this will disable */ | ||
459 | ieee80211_bss_info_change_notify(sdata, | ||
460 | BSS_CHANGED_BEACON_ENABLED); | ||
461 | |||
409 | /* remove beacon */ | 462 | /* remove beacon */ |
410 | rcu_assign_pointer(sdata->u.ap.beacon, NULL); | 463 | rcu_assign_pointer(sdata->u.ap.beacon, NULL); |
411 | synchronize_rcu(); | 464 | synchronize_rcu(); |
412 | kfree(old_beacon); | 465 | kfree(old_beacon); |
413 | 466 | ||
467 | /* free all potentially still buffered bcast frames */ | ||
468 | while ((skb = skb_dequeue(&sdata->u.ap.ps_bc_buf))) { | ||
469 | local->total_ps_buffered--; | ||
470 | dev_kfree_skb(skb); | ||
471 | } | ||
472 | |||
414 | /* down all dependent devices, that is VLANs */ | 473 | /* down all dependent devices, that is VLANs */ |
415 | list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans, | 474 | list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans, |
416 | u.vlan.list) | 475 | u.vlan.list) |
@@ -418,7 +477,8 @@ static int ieee80211_stop(struct net_device *dev) | |||
418 | WARN_ON(!list_empty(&sdata->u.ap.vlans)); | 477 | WARN_ON(!list_empty(&sdata->u.ap.vlans)); |
419 | } | 478 | } |
420 | 479 | ||
421 | local->open_count--; | 480 | if (going_down) |
481 | local->open_count--; | ||
422 | 482 | ||
423 | switch (sdata->vif.type) { | 483 | switch (sdata->vif.type) { |
424 | case NL80211_IFTYPE_AP_VLAN: | 484 | case NL80211_IFTYPE_AP_VLAN: |
@@ -437,40 +497,9 @@ static int ieee80211_stop(struct net_device *dev) | |||
437 | hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR; | 497 | hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR; |
438 | } | 498 | } |
439 | 499 | ||
440 | if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL) | 500 | ieee80211_adjust_monitor_flags(sdata, -1); |
441 | local->fif_fcsfail--; | ||
442 | if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL) | ||
443 | local->fif_plcpfail--; | ||
444 | if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) { | ||
445 | local->fif_pspoll--; | ||
446 | local->fif_control--; | ||
447 | } | ||
448 | if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) | ||
449 | local->fif_other_bss--; | ||
450 | |||
451 | ieee80211_configure_filter(local); | 501 | ieee80211_configure_filter(local); |
452 | break; | 502 | break; |
453 | case NL80211_IFTYPE_STATION: | ||
454 | del_timer_sync(&sdata->u.mgd.chswitch_timer); | ||
455 | del_timer_sync(&sdata->u.mgd.timer); | ||
456 | del_timer_sync(&sdata->u.mgd.conn_mon_timer); | ||
457 | del_timer_sync(&sdata->u.mgd.bcn_mon_timer); | ||
458 | /* | ||
459 | * If any of the timers fired while we waited for it, it will | ||
460 | * have queued its work. Now the work will be running again | ||
461 | * but will not rearm the timer again because it checks | ||
462 | * whether the interface is running, which, at this point, | ||
463 | * it no longer is. | ||
464 | */ | ||
465 | cancel_work_sync(&sdata->u.mgd.chswitch_work); | ||
466 | cancel_work_sync(&sdata->u.mgd.monitor_work); | ||
467 | cancel_work_sync(&sdata->u.mgd.beacon_connection_loss_work); | ||
468 | |||
469 | /* fall through */ | ||
470 | case NL80211_IFTYPE_ADHOC: | ||
471 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) | ||
472 | del_timer_sync(&sdata->u.ibss.timer); | ||
473 | /* fall through */ | ||
474 | case NL80211_IFTYPE_MESH_POINT: | 503 | case NL80211_IFTYPE_MESH_POINT: |
475 | if (ieee80211_vif_is_mesh(&sdata->vif)) { | 504 | if (ieee80211_vif_is_mesh(&sdata->vif)) { |
476 | /* other_bss and allmulti are always set on mesh | 505 | /* other_bss and allmulti are always set on mesh |
@@ -498,27 +527,34 @@ static int ieee80211_stop(struct net_device *dev) | |||
498 | ieee80211_scan_cancel(local); | 527 | ieee80211_scan_cancel(local); |
499 | 528 | ||
500 | /* | 529 | /* |
501 | * Disable beaconing for AP and mesh, IBSS can't | 530 | * Disable beaconing here for mesh only, AP and IBSS |
502 | * still be joined to a network at this point. | 531 | * are already taken care of. |
503 | */ | 532 | */ |
504 | if (sdata->vif.type == NL80211_IFTYPE_AP || | 533 | if (sdata->vif.type == NL80211_IFTYPE_MESH_POINT) |
505 | sdata->vif.type == NL80211_IFTYPE_MESH_POINT) { | ||
506 | ieee80211_bss_info_change_notify(sdata, | 534 | ieee80211_bss_info_change_notify(sdata, |
507 | BSS_CHANGED_BEACON_ENABLED); | 535 | BSS_CHANGED_BEACON_ENABLED); |
508 | } | ||
509 | 536 | ||
510 | /* free all remaining keys, there shouldn't be any */ | 537 | /* |
538 | * Free all remaining keys, there shouldn't be any, | ||
539 | * except maybe group keys in AP more or WDS? | ||
540 | */ | ||
511 | ieee80211_free_keys(sdata); | 541 | ieee80211_free_keys(sdata); |
512 | drv_remove_interface(local, &sdata->vif); | 542 | |
543 | if (going_down) | ||
544 | drv_remove_interface(local, &sdata->vif); | ||
513 | } | 545 | } |
514 | 546 | ||
515 | sdata->bss = NULL; | 547 | sdata->bss = NULL; |
516 | 548 | ||
549 | mutex_lock(&local->mtx); | ||
517 | hw_reconf_flags |= __ieee80211_recalc_idle(local); | 550 | hw_reconf_flags |= __ieee80211_recalc_idle(local); |
551 | mutex_unlock(&local->mtx); | ||
518 | 552 | ||
519 | ieee80211_recalc_ps(local, -1); | 553 | ieee80211_recalc_ps(local, -1); |
520 | 554 | ||
521 | if (local->open_count == 0) { | 555 | if (local->open_count == 0) { |
556 | if (local->ops->napi_poll) | ||
557 | napi_disable(&local->napi); | ||
522 | ieee80211_clear_tx_pending(local); | 558 | ieee80211_clear_tx_pending(local); |
523 | ieee80211_stop_device(local); | 559 | ieee80211_stop_device(local); |
524 | 560 | ||
@@ -541,6 +577,13 @@ static int ieee80211_stop(struct net_device *dev) | |||
541 | } | 577 | } |
542 | } | 578 | } |
543 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | 579 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); |
580 | } | ||
581 | |||
582 | static int ieee80211_stop(struct net_device *dev) | ||
583 | { | ||
584 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
585 | |||
586 | ieee80211_do_stop(sdata, true); | ||
544 | 587 | ||
545 | return 0; | 588 | return 0; |
546 | } | 589 | } |
@@ -585,8 +628,6 @@ static void ieee80211_teardown_sdata(struct net_device *dev) | |||
585 | { | 628 | { |
586 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 629 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
587 | struct ieee80211_local *local = sdata->local; | 630 | struct ieee80211_local *local = sdata->local; |
588 | struct beacon_data *beacon; | ||
589 | struct sk_buff *skb; | ||
590 | int flushed; | 631 | int flushed; |
591 | int i; | 632 | int i; |
592 | 633 | ||
@@ -599,37 +640,8 @@ static void ieee80211_teardown_sdata(struct net_device *dev) | |||
599 | __skb_queue_purge(&sdata->fragments[i].skb_list); | 640 | __skb_queue_purge(&sdata->fragments[i].skb_list); |
600 | sdata->fragment_next = 0; | 641 | sdata->fragment_next = 0; |
601 | 642 | ||
602 | switch (sdata->vif.type) { | 643 | if (ieee80211_vif_is_mesh(&sdata->vif)) |
603 | case NL80211_IFTYPE_AP: | 644 | mesh_rmc_free(sdata); |
604 | beacon = sdata->u.ap.beacon; | ||
605 | rcu_assign_pointer(sdata->u.ap.beacon, NULL); | ||
606 | synchronize_rcu(); | ||
607 | kfree(beacon); | ||
608 | |||
609 | while ((skb = skb_dequeue(&sdata->u.ap.ps_bc_buf))) { | ||
610 | local->total_ps_buffered--; | ||
611 | dev_kfree_skb(skb); | ||
612 | } | ||
613 | |||
614 | break; | ||
615 | case NL80211_IFTYPE_MESH_POINT: | ||
616 | if (ieee80211_vif_is_mesh(&sdata->vif)) | ||
617 | mesh_rmc_free(sdata); | ||
618 | break; | ||
619 | case NL80211_IFTYPE_ADHOC: | ||
620 | if (WARN_ON(sdata->u.ibss.presp)) | ||
621 | kfree_skb(sdata->u.ibss.presp); | ||
622 | break; | ||
623 | case NL80211_IFTYPE_STATION: | ||
624 | case NL80211_IFTYPE_WDS: | ||
625 | case NL80211_IFTYPE_AP_VLAN: | ||
626 | case NL80211_IFTYPE_MONITOR: | ||
627 | break; | ||
628 | case NL80211_IFTYPE_UNSPECIFIED: | ||
629 | case __NL80211_IFTYPE_AFTER_LAST: | ||
630 | BUG(); | ||
631 | break; | ||
632 | } | ||
633 | 645 | ||
634 | flushed = sta_info_flush(local, sdata); | 646 | flushed = sta_info_flush(local, sdata); |
635 | WARN_ON(flushed); | 647 | WARN_ON(flushed); |
@@ -791,7 +803,8 @@ static void ieee80211_iface_work(struct work_struct *work) | |||
791 | 803 | ||
792 | __ieee80211_stop_rx_ba_session( | 804 | __ieee80211_stop_rx_ba_session( |
793 | sta, tid, WLAN_BACK_RECIPIENT, | 805 | sta, tid, WLAN_BACK_RECIPIENT, |
794 | WLAN_REASON_QSTA_REQUIRE_SETUP); | 806 | WLAN_REASON_QSTA_REQUIRE_SETUP, |
807 | true); | ||
795 | } | 808 | } |
796 | mutex_unlock(&local->sta_mtx); | 809 | mutex_unlock(&local->sta_mtx); |
797 | } else switch (sdata->vif.type) { | 810 | } else switch (sdata->vif.type) { |
@@ -844,9 +857,13 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, | |||
844 | 857 | ||
845 | /* and set some type-dependent values */ | 858 | /* and set some type-dependent values */ |
846 | sdata->vif.type = type; | 859 | sdata->vif.type = type; |
860 | sdata->vif.p2p = false; | ||
847 | sdata->dev->netdev_ops = &ieee80211_dataif_ops; | 861 | sdata->dev->netdev_ops = &ieee80211_dataif_ops; |
848 | sdata->wdev.iftype = type; | 862 | sdata->wdev.iftype = type; |
849 | 863 | ||
864 | sdata->control_port_protocol = cpu_to_be16(ETH_P_PAE); | ||
865 | sdata->control_port_no_encrypt = false; | ||
866 | |||
850 | /* only monitor differs */ | 867 | /* only monitor differs */ |
851 | sdata->dev->type = ARPHRD_ETHER; | 868 | sdata->dev->type = ARPHRD_ETHER; |
852 | 869 | ||
@@ -854,10 +871,20 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, | |||
854 | INIT_WORK(&sdata->work, ieee80211_iface_work); | 871 | INIT_WORK(&sdata->work, ieee80211_iface_work); |
855 | 872 | ||
856 | switch (type) { | 873 | switch (type) { |
874 | case NL80211_IFTYPE_P2P_GO: | ||
875 | type = NL80211_IFTYPE_AP; | ||
876 | sdata->vif.type = type; | ||
877 | sdata->vif.p2p = true; | ||
878 | /* fall through */ | ||
857 | case NL80211_IFTYPE_AP: | 879 | case NL80211_IFTYPE_AP: |
858 | skb_queue_head_init(&sdata->u.ap.ps_bc_buf); | 880 | skb_queue_head_init(&sdata->u.ap.ps_bc_buf); |
859 | INIT_LIST_HEAD(&sdata->u.ap.vlans); | 881 | INIT_LIST_HEAD(&sdata->u.ap.vlans); |
860 | break; | 882 | break; |
883 | case NL80211_IFTYPE_P2P_CLIENT: | ||
884 | type = NL80211_IFTYPE_STATION; | ||
885 | sdata->vif.type = type; | ||
886 | sdata->vif.p2p = true; | ||
887 | /* fall through */ | ||
861 | case NL80211_IFTYPE_STATION: | 888 | case NL80211_IFTYPE_STATION: |
862 | ieee80211_sta_setup_sdata(sdata); | 889 | ieee80211_sta_setup_sdata(sdata); |
863 | break; | 890 | break; |
@@ -878,7 +905,7 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, | |||
878 | case NL80211_IFTYPE_AP_VLAN: | 905 | case NL80211_IFTYPE_AP_VLAN: |
879 | break; | 906 | break; |
880 | case NL80211_IFTYPE_UNSPECIFIED: | 907 | case NL80211_IFTYPE_UNSPECIFIED: |
881 | case __NL80211_IFTYPE_AFTER_LAST: | 908 | case NUM_NL80211_IFTYPES: |
882 | BUG(); | 909 | BUG(); |
883 | break; | 910 | break; |
884 | } | 911 | } |
@@ -886,12 +913,85 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, | |||
886 | ieee80211_debugfs_add_netdev(sdata); | 913 | ieee80211_debugfs_add_netdev(sdata); |
887 | } | 914 | } |
888 | 915 | ||
916 | static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, | ||
917 | enum nl80211_iftype type) | ||
918 | { | ||
919 | struct ieee80211_local *local = sdata->local; | ||
920 | int ret, err; | ||
921 | enum nl80211_iftype internal_type = type; | ||
922 | bool p2p = false; | ||
923 | |||
924 | ASSERT_RTNL(); | ||
925 | |||
926 | if (!local->ops->change_interface) | ||
927 | return -EBUSY; | ||
928 | |||
929 | switch (sdata->vif.type) { | ||
930 | case NL80211_IFTYPE_AP: | ||
931 | case NL80211_IFTYPE_STATION: | ||
932 | case NL80211_IFTYPE_ADHOC: | ||
933 | /* | ||
934 | * Could maybe also all others here? | ||
935 | * Just not sure how that interacts | ||
936 | * with the RX/config path e.g. for | ||
937 | * mesh. | ||
938 | */ | ||
939 | break; | ||
940 | default: | ||
941 | return -EBUSY; | ||
942 | } | ||
943 | |||
944 | switch (type) { | ||
945 | case NL80211_IFTYPE_AP: | ||
946 | case NL80211_IFTYPE_STATION: | ||
947 | case NL80211_IFTYPE_ADHOC: | ||
948 | /* | ||
949 | * Could probably support everything | ||
950 | * but WDS here (WDS do_open can fail | ||
951 | * under memory pressure, which this | ||
952 | * code isn't prepared to handle). | ||
953 | */ | ||
954 | break; | ||
955 | case NL80211_IFTYPE_P2P_CLIENT: | ||
956 | p2p = true; | ||
957 | internal_type = NL80211_IFTYPE_STATION; | ||
958 | break; | ||
959 | case NL80211_IFTYPE_P2P_GO: | ||
960 | p2p = true; | ||
961 | internal_type = NL80211_IFTYPE_AP; | ||
962 | break; | ||
963 | default: | ||
964 | return -EBUSY; | ||
965 | } | ||
966 | |||
967 | ret = ieee80211_check_concurrent_iface(sdata, internal_type); | ||
968 | if (ret) | ||
969 | return ret; | ||
970 | |||
971 | ieee80211_do_stop(sdata, false); | ||
972 | |||
973 | ieee80211_teardown_sdata(sdata->dev); | ||
974 | |||
975 | ret = drv_change_interface(local, sdata, internal_type, p2p); | ||
976 | if (ret) | ||
977 | type = sdata->vif.type; | ||
978 | |||
979 | ieee80211_setup_sdata(sdata, type); | ||
980 | |||
981 | err = ieee80211_do_open(sdata->dev, false); | ||
982 | WARN(err, "type change: do_open returned %d", err); | ||
983 | |||
984 | return ret; | ||
985 | } | ||
986 | |||
889 | int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, | 987 | int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, |
890 | enum nl80211_iftype type) | 988 | enum nl80211_iftype type) |
891 | { | 989 | { |
990 | int ret; | ||
991 | |||
892 | ASSERT_RTNL(); | 992 | ASSERT_RTNL(); |
893 | 993 | ||
894 | if (type == sdata->vif.type) | 994 | if (type == ieee80211_vif_type_p2p(&sdata->vif)) |
895 | return 0; | 995 | return 0; |
896 | 996 | ||
897 | /* Setting ad-hoc mode on non-IBSS channel is not supported. */ | 997 | /* Setting ad-hoc mode on non-IBSS channel is not supported. */ |
@@ -899,18 +999,15 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, | |||
899 | type == NL80211_IFTYPE_ADHOC) | 999 | type == NL80211_IFTYPE_ADHOC) |
900 | return -EOPNOTSUPP; | 1000 | return -EOPNOTSUPP; |
901 | 1001 | ||
902 | /* | 1002 | if (ieee80211_sdata_running(sdata)) { |
903 | * We could, here, on changes between IBSS/STA/MESH modes, | 1003 | ret = ieee80211_runtime_change_iftype(sdata, type); |
904 | * invoke an MLME function instead that disassociates etc. | 1004 | if (ret) |
905 | * and goes into the requested mode. | 1005 | return ret; |
906 | */ | 1006 | } else { |
907 | 1007 | /* Purge and reset type-dependent state. */ | |
908 | if (ieee80211_sdata_running(sdata)) | 1008 | ieee80211_teardown_sdata(sdata->dev); |
909 | return -EBUSY; | 1009 | ieee80211_setup_sdata(sdata, type); |
910 | 1010 | } | |
911 | /* Purge and reset type-dependent state. */ | ||
912 | ieee80211_teardown_sdata(sdata->dev); | ||
913 | ieee80211_setup_sdata(sdata, type); | ||
914 | 1011 | ||
915 | /* reset some values that shouldn't be kept across type changes */ | 1012 | /* reset some values that shouldn't be kept across type changes */ |
916 | sdata->vif.bss_conf.basic_rates = | 1013 | sdata->vif.bss_conf.basic_rates = |
@@ -1167,8 +1264,7 @@ static u32 ieee80211_idle_off(struct ieee80211_local *local, | |||
1167 | return 0; | 1264 | return 0; |
1168 | 1265 | ||
1169 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 1266 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
1170 | printk(KERN_DEBUG "%s: device no longer idle - %s\n", | 1267 | wiphy_debug(local->hw.wiphy, "device no longer idle - %s\n", reason); |
1171 | wiphy_name(local->hw.wiphy), reason); | ||
1172 | #endif | 1268 | #endif |
1173 | 1269 | ||
1174 | local->hw.conf.flags &= ~IEEE80211_CONF_IDLE; | 1270 | local->hw.conf.flags &= ~IEEE80211_CONF_IDLE; |
@@ -1181,8 +1277,7 @@ static u32 ieee80211_idle_on(struct ieee80211_local *local) | |||
1181 | return 0; | 1277 | return 0; |
1182 | 1278 | ||
1183 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 1279 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
1184 | printk(KERN_DEBUG "%s: device now idle\n", | 1280 | wiphy_debug(local->hw.wiphy, "device now idle\n"); |
1185 | wiphy_name(local->hw.wiphy)); | ||
1186 | #endif | 1281 | #endif |
1187 | 1282 | ||
1188 | drv_flush(local, false); | 1283 | drv_flush(local, false); |
@@ -1195,28 +1290,61 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local) | |||
1195 | { | 1290 | { |
1196 | struct ieee80211_sub_if_data *sdata; | 1291 | struct ieee80211_sub_if_data *sdata; |
1197 | int count = 0; | 1292 | int count = 0; |
1293 | bool working = false, scanning = false; | ||
1294 | struct ieee80211_work *wk; | ||
1198 | 1295 | ||
1199 | if (!list_empty(&local->work_list)) | 1296 | #ifdef CONFIG_PROVE_LOCKING |
1200 | return ieee80211_idle_off(local, "working"); | 1297 | WARN_ON(debug_locks && !lockdep_rtnl_is_held() && |
1201 | 1298 | !lockdep_is_held(&local->iflist_mtx)); | |
1202 | if (local->scanning) | 1299 | #endif |
1203 | return ieee80211_idle_off(local, "scanning"); | 1300 | lockdep_assert_held(&local->mtx); |
1204 | 1301 | ||
1205 | list_for_each_entry(sdata, &local->interfaces, list) { | 1302 | list_for_each_entry(sdata, &local->interfaces, list) { |
1206 | if (!ieee80211_sdata_running(sdata)) | 1303 | if (!ieee80211_sdata_running(sdata)) { |
1304 | sdata->vif.bss_conf.idle = true; | ||
1207 | continue; | 1305 | continue; |
1306 | } | ||
1307 | |||
1308 | sdata->old_idle = sdata->vif.bss_conf.idle; | ||
1309 | |||
1208 | /* do not count disabled managed interfaces */ | 1310 | /* do not count disabled managed interfaces */ |
1209 | if (sdata->vif.type == NL80211_IFTYPE_STATION && | 1311 | if (sdata->vif.type == NL80211_IFTYPE_STATION && |
1210 | !sdata->u.mgd.associated) | 1312 | !sdata->u.mgd.associated) { |
1313 | sdata->vif.bss_conf.idle = true; | ||
1211 | continue; | 1314 | continue; |
1315 | } | ||
1212 | /* do not count unused IBSS interfaces */ | 1316 | /* do not count unused IBSS interfaces */ |
1213 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC && | 1317 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC && |
1214 | !sdata->u.ibss.ssid_len) | 1318 | !sdata->u.ibss.ssid_len) { |
1319 | sdata->vif.bss_conf.idle = true; | ||
1215 | continue; | 1320 | continue; |
1321 | } | ||
1216 | /* count everything else */ | 1322 | /* count everything else */ |
1217 | count++; | 1323 | count++; |
1218 | } | 1324 | } |
1219 | 1325 | ||
1326 | list_for_each_entry(wk, &local->work_list, list) { | ||
1327 | working = true; | ||
1328 | wk->sdata->vif.bss_conf.idle = false; | ||
1329 | } | ||
1330 | |||
1331 | if (local->scan_sdata) { | ||
1332 | scanning = true; | ||
1333 | local->scan_sdata->vif.bss_conf.idle = false; | ||
1334 | } | ||
1335 | |||
1336 | list_for_each_entry(sdata, &local->interfaces, list) { | ||
1337 | if (sdata->old_idle == sdata->vif.bss_conf.idle) | ||
1338 | continue; | ||
1339 | if (!ieee80211_sdata_running(sdata)) | ||
1340 | continue; | ||
1341 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE); | ||
1342 | } | ||
1343 | |||
1344 | if (working) | ||
1345 | return ieee80211_idle_off(local, "working"); | ||
1346 | if (scanning) | ||
1347 | return ieee80211_idle_off(local, "scanning"); | ||
1220 | if (!count) | 1348 | if (!count) |
1221 | return ieee80211_idle_on(local); | 1349 | return ieee80211_idle_on(local); |
1222 | else | 1350 | else |
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 1b9d87ed143..ccd676b2f59 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -49,7 +49,7 @@ static const u8 bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; | |||
49 | 49 | ||
50 | static void assert_key_lock(struct ieee80211_local *local) | 50 | static void assert_key_lock(struct ieee80211_local *local) |
51 | { | 51 | { |
52 | WARN_ON(!mutex_is_locked(&local->key_mtx)); | 52 | lockdep_assert_held(&local->key_mtx); |
53 | } | 53 | } |
54 | 54 | ||
55 | static struct ieee80211_sta *get_sta_for_key(struct ieee80211_key *key) | 55 | static struct ieee80211_sta *get_sta_for_key(struct ieee80211_key *key) |
@@ -60,7 +60,7 @@ static struct ieee80211_sta *get_sta_for_key(struct ieee80211_key *key) | |||
60 | return NULL; | 60 | return NULL; |
61 | } | 61 | } |
62 | 62 | ||
63 | static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key) | 63 | static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key) |
64 | { | 64 | { |
65 | struct ieee80211_sub_if_data *sdata; | 65 | struct ieee80211_sub_if_data *sdata; |
66 | struct ieee80211_sta *sta; | 66 | struct ieee80211_sta *sta; |
@@ -69,12 +69,20 @@ static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key) | |||
69 | might_sleep(); | 69 | might_sleep(); |
70 | 70 | ||
71 | if (!key->local->ops->set_key) | 71 | if (!key->local->ops->set_key) |
72 | return; | 72 | goto out_unsupported; |
73 | 73 | ||
74 | assert_key_lock(key->local); | 74 | assert_key_lock(key->local); |
75 | 75 | ||
76 | sta = get_sta_for_key(key); | 76 | sta = get_sta_for_key(key); |
77 | 77 | ||
78 | /* | ||
79 | * If this is a per-STA GTK, check if it | ||
80 | * is supported; if not, return. | ||
81 | */ | ||
82 | if (sta && !(key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE) && | ||
83 | !(key->local->hw.flags & IEEE80211_HW_SUPPORTS_PER_STA_GTK)) | ||
84 | goto out_unsupported; | ||
85 | |||
78 | sdata = key->sdata; | 86 | sdata = key->sdata; |
79 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | 87 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) |
80 | sdata = container_of(sdata->bss, | 88 | sdata = container_of(sdata->bss, |
@@ -83,14 +91,28 @@ static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key) | |||
83 | 91 | ||
84 | ret = drv_set_key(key->local, SET_KEY, sdata, sta, &key->conf); | 92 | ret = drv_set_key(key->local, SET_KEY, sdata, sta, &key->conf); |
85 | 93 | ||
86 | if (!ret) | 94 | if (!ret) { |
87 | key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE; | 95 | key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE; |
96 | return 0; | ||
97 | } | ||
88 | 98 | ||
89 | if (ret && ret != -ENOSPC && ret != -EOPNOTSUPP) | 99 | if (ret != -ENOSPC && ret != -EOPNOTSUPP) |
90 | printk(KERN_ERR "mac80211-%s: failed to set key " | 100 | wiphy_err(key->local->hw.wiphy, |
91 | "(%d, %pM) to hardware (%d)\n", | 101 | "failed to set key (%d, %pM) to hardware (%d)\n", |
92 | wiphy_name(key->local->hw.wiphy), | 102 | key->conf.keyidx, sta ? sta->addr : bcast_addr, ret); |
93 | key->conf.keyidx, sta ? sta->addr : bcast_addr, ret); | 103 | |
104 | out_unsupported: | ||
105 | switch (key->conf.cipher) { | ||
106 | case WLAN_CIPHER_SUITE_WEP40: | ||
107 | case WLAN_CIPHER_SUITE_WEP104: | ||
108 | case WLAN_CIPHER_SUITE_TKIP: | ||
109 | case WLAN_CIPHER_SUITE_CCMP: | ||
110 | case WLAN_CIPHER_SUITE_AES_CMAC: | ||
111 | /* all of these we can do in software */ | ||
112 | return 0; | ||
113 | default: | ||
114 | return -EINVAL; | ||
115 | } | ||
94 | } | 116 | } |
95 | 117 | ||
96 | static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) | 118 | static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) |
@@ -121,14 +143,33 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) | |||
121 | sta, &key->conf); | 143 | sta, &key->conf); |
122 | 144 | ||
123 | if (ret) | 145 | if (ret) |
124 | printk(KERN_ERR "mac80211-%s: failed to remove key " | 146 | wiphy_err(key->local->hw.wiphy, |
125 | "(%d, %pM) from hardware (%d)\n", | 147 | "failed to remove key (%d, %pM) from hardware (%d)\n", |
126 | wiphy_name(key->local->hw.wiphy), | 148 | key->conf.keyidx, sta ? sta->addr : bcast_addr, ret); |
127 | key->conf.keyidx, sta ? sta->addr : bcast_addr, ret); | ||
128 | 149 | ||
129 | key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; | 150 | key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; |
130 | } | 151 | } |
131 | 152 | ||
153 | void ieee80211_key_removed(struct ieee80211_key_conf *key_conf) | ||
154 | { | ||
155 | struct ieee80211_key *key; | ||
156 | |||
157 | key = container_of(key_conf, struct ieee80211_key, conf); | ||
158 | |||
159 | might_sleep(); | ||
160 | assert_key_lock(key->local); | ||
161 | |||
162 | key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; | ||
163 | |||
164 | /* | ||
165 | * Flush TX path to avoid attempts to use this key | ||
166 | * after this function returns. Until then, drivers | ||
167 | * must be prepared to handle the key. | ||
168 | */ | ||
169 | synchronize_rcu(); | ||
170 | } | ||
171 | EXPORT_SYMBOL_GPL(ieee80211_key_removed); | ||
172 | |||
132 | static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, | 173 | static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, |
133 | int idx) | 174 | int idx) |
134 | { | 175 | { |
@@ -184,6 +225,7 @@ void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, | |||
184 | 225 | ||
185 | static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata, | 226 | static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata, |
186 | struct sta_info *sta, | 227 | struct sta_info *sta, |
228 | bool pairwise, | ||
187 | struct ieee80211_key *old, | 229 | struct ieee80211_key *old, |
188 | struct ieee80211_key *new) | 230 | struct ieee80211_key *new) |
189 | { | 231 | { |
@@ -192,8 +234,14 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata, | |||
192 | if (new) | 234 | if (new) |
193 | list_add(&new->list, &sdata->key_list); | 235 | list_add(&new->list, &sdata->key_list); |
194 | 236 | ||
195 | if (sta) { | 237 | if (sta && pairwise) { |
196 | rcu_assign_pointer(sta->key, new); | 238 | rcu_assign_pointer(sta->ptk, new); |
239 | } else if (sta) { | ||
240 | if (old) | ||
241 | idx = old->conf.keyidx; | ||
242 | else | ||
243 | idx = new->conf.keyidx; | ||
244 | rcu_assign_pointer(sta->gtk[idx], new); | ||
197 | } else { | 245 | } else { |
198 | WARN_ON(new && old && new->conf.keyidx != old->conf.keyidx); | 246 | WARN_ON(new && old && new->conf.keyidx != old->conf.keyidx); |
199 | 247 | ||
@@ -227,20 +275,18 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata, | |||
227 | } | 275 | } |
228 | } | 276 | } |
229 | 277 | ||
230 | struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg, | 278 | struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len, |
231 | int idx, | ||
232 | size_t key_len, | ||
233 | const u8 *key_data, | 279 | const u8 *key_data, |
234 | size_t seq_len, const u8 *seq) | 280 | size_t seq_len, const u8 *seq) |
235 | { | 281 | { |
236 | struct ieee80211_key *key; | 282 | struct ieee80211_key *key; |
237 | int i, j; | 283 | int i, j, err; |
238 | 284 | ||
239 | BUG_ON(idx < 0 || idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS); | 285 | BUG_ON(idx < 0 || idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS); |
240 | 286 | ||
241 | key = kzalloc(sizeof(struct ieee80211_key) + key_len, GFP_KERNEL); | 287 | key = kzalloc(sizeof(struct ieee80211_key) + key_len, GFP_KERNEL); |
242 | if (!key) | 288 | if (!key) |
243 | return NULL; | 289 | return ERR_PTR(-ENOMEM); |
244 | 290 | ||
245 | /* | 291 | /* |
246 | * Default to software encryption; we'll later upload the | 292 | * Default to software encryption; we'll later upload the |
@@ -249,15 +295,16 @@ struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg, | |||
249 | key->conf.flags = 0; | 295 | key->conf.flags = 0; |
250 | key->flags = 0; | 296 | key->flags = 0; |
251 | 297 | ||
252 | key->conf.alg = alg; | 298 | key->conf.cipher = cipher; |
253 | key->conf.keyidx = idx; | 299 | key->conf.keyidx = idx; |
254 | key->conf.keylen = key_len; | 300 | key->conf.keylen = key_len; |
255 | switch (alg) { | 301 | switch (cipher) { |
256 | case ALG_WEP: | 302 | case WLAN_CIPHER_SUITE_WEP40: |
303 | case WLAN_CIPHER_SUITE_WEP104: | ||
257 | key->conf.iv_len = WEP_IV_LEN; | 304 | key->conf.iv_len = WEP_IV_LEN; |
258 | key->conf.icv_len = WEP_ICV_LEN; | 305 | key->conf.icv_len = WEP_ICV_LEN; |
259 | break; | 306 | break; |
260 | case ALG_TKIP: | 307 | case WLAN_CIPHER_SUITE_TKIP: |
261 | key->conf.iv_len = TKIP_IV_LEN; | 308 | key->conf.iv_len = TKIP_IV_LEN; |
262 | key->conf.icv_len = TKIP_ICV_LEN; | 309 | key->conf.icv_len = TKIP_ICV_LEN; |
263 | if (seq) { | 310 | if (seq) { |
@@ -269,7 +316,7 @@ struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg, | |||
269 | } | 316 | } |
270 | } | 317 | } |
271 | break; | 318 | break; |
272 | case ALG_CCMP: | 319 | case WLAN_CIPHER_SUITE_CCMP: |
273 | key->conf.iv_len = CCMP_HDR_LEN; | 320 | key->conf.iv_len = CCMP_HDR_LEN; |
274 | key->conf.icv_len = CCMP_MIC_LEN; | 321 | key->conf.icv_len = CCMP_MIC_LEN; |
275 | if (seq) { | 322 | if (seq) { |
@@ -278,42 +325,38 @@ struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg, | |||
278 | key->u.ccmp.rx_pn[i][j] = | 325 | key->u.ccmp.rx_pn[i][j] = |
279 | seq[CCMP_PN_LEN - j - 1]; | 326 | seq[CCMP_PN_LEN - j - 1]; |
280 | } | 327 | } |
281 | break; | ||
282 | case ALG_AES_CMAC: | ||
283 | key->conf.iv_len = 0; | ||
284 | key->conf.icv_len = sizeof(struct ieee80211_mmie); | ||
285 | if (seq) | ||
286 | for (j = 0; j < 6; j++) | ||
287 | key->u.aes_cmac.rx_pn[j] = seq[6 - j - 1]; | ||
288 | break; | ||
289 | } | ||
290 | memcpy(key->conf.key, key_data, key_len); | ||
291 | INIT_LIST_HEAD(&key->list); | ||
292 | |||
293 | if (alg == ALG_CCMP) { | ||
294 | /* | 328 | /* |
295 | * Initialize AES key state here as an optimization so that | 329 | * Initialize AES key state here as an optimization so that |
296 | * it does not need to be initialized for every packet. | 330 | * it does not need to be initialized for every packet. |
297 | */ | 331 | */ |
298 | key->u.ccmp.tfm = ieee80211_aes_key_setup_encrypt(key_data); | 332 | key->u.ccmp.tfm = ieee80211_aes_key_setup_encrypt(key_data); |
299 | if (!key->u.ccmp.tfm) { | 333 | if (IS_ERR(key->u.ccmp.tfm)) { |
334 | err = PTR_ERR(key->u.ccmp.tfm); | ||
300 | kfree(key); | 335 | kfree(key); |
301 | return NULL; | 336 | key = ERR_PTR(err); |
302 | } | 337 | } |
303 | } | 338 | break; |
304 | 339 | case WLAN_CIPHER_SUITE_AES_CMAC: | |
305 | if (alg == ALG_AES_CMAC) { | 340 | key->conf.iv_len = 0; |
341 | key->conf.icv_len = sizeof(struct ieee80211_mmie); | ||
342 | if (seq) | ||
343 | for (j = 0; j < 6; j++) | ||
344 | key->u.aes_cmac.rx_pn[j] = seq[6 - j - 1]; | ||
306 | /* | 345 | /* |
307 | * Initialize AES key state here as an optimization so that | 346 | * Initialize AES key state here as an optimization so that |
308 | * it does not need to be initialized for every packet. | 347 | * it does not need to be initialized for every packet. |
309 | */ | 348 | */ |
310 | key->u.aes_cmac.tfm = | 349 | key->u.aes_cmac.tfm = |
311 | ieee80211_aes_cmac_key_setup(key_data); | 350 | ieee80211_aes_cmac_key_setup(key_data); |
312 | if (!key->u.aes_cmac.tfm) { | 351 | if (IS_ERR(key->u.aes_cmac.tfm)) { |
352 | err = PTR_ERR(key->u.aes_cmac.tfm); | ||
313 | kfree(key); | 353 | kfree(key); |
314 | return NULL; | 354 | key = ERR_PTR(err); |
315 | } | 355 | } |
356 | break; | ||
316 | } | 357 | } |
358 | memcpy(key->conf.key, key_data, key_len); | ||
359 | INIT_LIST_HEAD(&key->list); | ||
317 | 360 | ||
318 | return key; | 361 | return key; |
319 | } | 362 | } |
@@ -326,9 +369,9 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key) | |||
326 | if (key->local) | 369 | if (key->local) |
327 | ieee80211_key_disable_hw_accel(key); | 370 | ieee80211_key_disable_hw_accel(key); |
328 | 371 | ||
329 | if (key->conf.alg == ALG_CCMP) | 372 | if (key->conf.cipher == WLAN_CIPHER_SUITE_CCMP) |
330 | ieee80211_aes_key_free(key->u.ccmp.tfm); | 373 | ieee80211_aes_key_free(key->u.ccmp.tfm); |
331 | if (key->conf.alg == ALG_AES_CMAC) | 374 | if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC) |
332 | ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm); | 375 | ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm); |
333 | if (key->local) | 376 | if (key->local) |
334 | ieee80211_debugfs_key_remove(key); | 377 | ieee80211_debugfs_key_remove(key); |
@@ -336,12 +379,13 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key) | |||
336 | kfree(key); | 379 | kfree(key); |
337 | } | 380 | } |
338 | 381 | ||
339 | void ieee80211_key_link(struct ieee80211_key *key, | 382 | int ieee80211_key_link(struct ieee80211_key *key, |
340 | struct ieee80211_sub_if_data *sdata, | 383 | struct ieee80211_sub_if_data *sdata, |
341 | struct sta_info *sta) | 384 | struct sta_info *sta) |
342 | { | 385 | { |
343 | struct ieee80211_key *old_key; | 386 | struct ieee80211_key *old_key; |
344 | int idx; | 387 | int idx, ret; |
388 | bool pairwise = key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE; | ||
345 | 389 | ||
346 | BUG_ON(!sdata); | 390 | BUG_ON(!sdata); |
347 | BUG_ON(!key); | 391 | BUG_ON(!key); |
@@ -358,13 +402,6 @@ void ieee80211_key_link(struct ieee80211_key *key, | |||
358 | */ | 402 | */ |
359 | if (test_sta_flags(sta, WLAN_STA_WME)) | 403 | if (test_sta_flags(sta, WLAN_STA_WME)) |
360 | key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA; | 404 | key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA; |
361 | |||
362 | /* | ||
363 | * This key is for a specific sta interface, | ||
364 | * inform the driver that it should try to store | ||
365 | * this key as pairwise key. | ||
366 | */ | ||
367 | key->conf.flags |= IEEE80211_KEY_FLAG_PAIRWISE; | ||
368 | } else { | 405 | } else { |
369 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { | 406 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { |
370 | struct sta_info *ap; | 407 | struct sta_info *ap; |
@@ -386,19 +423,23 @@ void ieee80211_key_link(struct ieee80211_key *key, | |||
386 | 423 | ||
387 | mutex_lock(&sdata->local->key_mtx); | 424 | mutex_lock(&sdata->local->key_mtx); |
388 | 425 | ||
389 | if (sta) | 426 | if (sta && pairwise) |
390 | old_key = sta->key; | 427 | old_key = sta->ptk; |
428 | else if (sta) | ||
429 | old_key = sta->gtk[idx]; | ||
391 | else | 430 | else |
392 | old_key = sdata->keys[idx]; | 431 | old_key = sdata->keys[idx]; |
393 | 432 | ||
394 | __ieee80211_key_replace(sdata, sta, old_key, key); | 433 | __ieee80211_key_replace(sdata, sta, pairwise, old_key, key); |
395 | __ieee80211_key_destroy(old_key); | 434 | __ieee80211_key_destroy(old_key); |
396 | 435 | ||
397 | ieee80211_debugfs_key_add(key); | 436 | ieee80211_debugfs_key_add(key); |
398 | 437 | ||
399 | ieee80211_key_enable_hw_accel(key); | 438 | ret = ieee80211_key_enable_hw_accel(key); |
400 | 439 | ||
401 | mutex_unlock(&sdata->local->key_mtx); | 440 | mutex_unlock(&sdata->local->key_mtx); |
441 | |||
442 | return ret; | ||
402 | } | 443 | } |
403 | 444 | ||
404 | static void __ieee80211_key_free(struct ieee80211_key *key) | 445 | static void __ieee80211_key_free(struct ieee80211_key *key) |
@@ -408,7 +449,8 @@ static void __ieee80211_key_free(struct ieee80211_key *key) | |||
408 | */ | 449 | */ |
409 | if (key->sdata) | 450 | if (key->sdata) |
410 | __ieee80211_key_replace(key->sdata, key->sta, | 451 | __ieee80211_key_replace(key->sdata, key->sta, |
411 | key, NULL); | 452 | key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE, |
453 | key, NULL); | ||
412 | __ieee80211_key_destroy(key); | 454 | __ieee80211_key_destroy(key); |
413 | } | 455 | } |
414 | 456 | ||
diff --git a/net/mac80211/key.h b/net/mac80211/key.h index b665bbb7a47..0db1c0f5f69 100644 --- a/net/mac80211/key.h +++ b/net/mac80211/key.h | |||
@@ -16,6 +16,9 @@ | |||
16 | #include <linux/rcupdate.h> | 16 | #include <linux/rcupdate.h> |
17 | #include <net/mac80211.h> | 17 | #include <net/mac80211.h> |
18 | 18 | ||
19 | #define NUM_DEFAULT_KEYS 4 | ||
20 | #define NUM_DEFAULT_MGMT_KEYS 2 | ||
21 | |||
19 | #define WEP_IV_LEN 4 | 22 | #define WEP_IV_LEN 4 |
20 | #define WEP_ICV_LEN 4 | 23 | #define WEP_ICV_LEN 4 |
21 | #define ALG_TKIP_KEY_LEN 32 | 24 | #define ALG_TKIP_KEY_LEN 32 |
@@ -123,18 +126,16 @@ struct ieee80211_key { | |||
123 | struct ieee80211_key_conf conf; | 126 | struct ieee80211_key_conf conf; |
124 | }; | 127 | }; |
125 | 128 | ||
126 | struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg, | 129 | struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len, |
127 | int idx, | ||
128 | size_t key_len, | ||
129 | const u8 *key_data, | 130 | const u8 *key_data, |
130 | size_t seq_len, const u8 *seq); | 131 | size_t seq_len, const u8 *seq); |
131 | /* | 132 | /* |
132 | * Insert a key into data structures (sdata, sta if necessary) | 133 | * Insert a key into data structures (sdata, sta if necessary) |
133 | * to make it used, free old key. | 134 | * to make it used, free old key. |
134 | */ | 135 | */ |
135 | void ieee80211_key_link(struct ieee80211_key *key, | 136 | int __must_check ieee80211_key_link(struct ieee80211_key *key, |
136 | struct ieee80211_sub_if_data *sdata, | 137 | struct ieee80211_sub_if_data *sdata, |
137 | struct sta_info *sta); | 138 | struct sta_info *sta); |
138 | void ieee80211_key_free(struct ieee80211_local *local, | 139 | void ieee80211_key_free(struct ieee80211_local *local, |
139 | struct ieee80211_key *key); | 140 | struct ieee80211_key *key); |
140 | void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx); | 141 | void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx); |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index ded5c3843e0..22bc42b1899 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -54,6 +54,9 @@ void ieee80211_configure_filter(struct ieee80211_local *local) | |||
54 | if (local->monitors || local->scanning) | 54 | if (local->monitors || local->scanning) |
55 | new_flags |= FIF_BCN_PRBRESP_PROMISC; | 55 | new_flags |= FIF_BCN_PRBRESP_PROMISC; |
56 | 56 | ||
57 | if (local->fif_probe_req || local->probe_req_reg) | ||
58 | new_flags |= FIF_PROBE_REQ; | ||
59 | |||
57 | if (local->fif_fcsfail) | 60 | if (local->fif_fcsfail) |
58 | new_flags |= FIF_FCSFAIL; | 61 | new_flags |= FIF_FCSFAIL; |
59 | 62 | ||
@@ -99,16 +102,19 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | |||
99 | int ret = 0; | 102 | int ret = 0; |
100 | int power; | 103 | int power; |
101 | enum nl80211_channel_type channel_type; | 104 | enum nl80211_channel_type channel_type; |
105 | u32 offchannel_flag; | ||
102 | 106 | ||
103 | might_sleep(); | 107 | might_sleep(); |
104 | 108 | ||
105 | scan_chan = local->scan_channel; | 109 | scan_chan = local->scan_channel; |
106 | 110 | ||
111 | offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; | ||
107 | if (scan_chan) { | 112 | if (scan_chan) { |
108 | chan = scan_chan; | 113 | chan = scan_chan; |
109 | channel_type = NL80211_CHAN_NO_HT; | 114 | channel_type = NL80211_CHAN_NO_HT; |
110 | local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; | 115 | local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; |
111 | } else if (local->tmp_channel) { | 116 | } else if (local->tmp_channel && |
117 | local->oper_channel != local->tmp_channel) { | ||
112 | chan = scan_chan = local->tmp_channel; | 118 | chan = scan_chan = local->tmp_channel; |
113 | channel_type = local->tmp_channel_type; | 119 | channel_type = local->tmp_channel_type; |
114 | local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; | 120 | local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; |
@@ -117,8 +123,9 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | |||
117 | channel_type = local->_oper_channel_type; | 123 | channel_type = local->_oper_channel_type; |
118 | local->hw.conf.flags &= ~IEEE80211_CONF_OFFCHANNEL; | 124 | local->hw.conf.flags &= ~IEEE80211_CONF_OFFCHANNEL; |
119 | } | 125 | } |
126 | offchannel_flag ^= local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; | ||
120 | 127 | ||
121 | if (chan != local->hw.conf.channel || | 128 | if (offchannel_flag || chan != local->hw.conf.channel || |
122 | channel_type != local->hw.conf.channel_type) { | 129 | channel_type != local->hw.conf.channel_type) { |
123 | local->hw.conf.channel = chan; | 130 | local->hw.conf.channel = chan; |
124 | local->hw.conf.channel_type = channel_type; | 131 | local->hw.conf.channel_type = channel_type; |
@@ -197,6 +204,8 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | |||
197 | sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid; | 204 | sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid; |
198 | else if (sdata->vif.type == NL80211_IFTYPE_AP) | 205 | else if (sdata->vif.type == NL80211_IFTYPE_AP) |
199 | sdata->vif.bss_conf.bssid = sdata->vif.addr; | 206 | sdata->vif.bss_conf.bssid = sdata->vif.addr; |
207 | else if (sdata->vif.type == NL80211_IFTYPE_WDS) | ||
208 | sdata->vif.bss_conf.bssid = NULL; | ||
200 | else if (ieee80211_vif_is_mesh(&sdata->vif)) { | 209 | else if (ieee80211_vif_is_mesh(&sdata->vif)) { |
201 | sdata->vif.bss_conf.bssid = zero; | 210 | sdata->vif.bss_conf.bssid = zero; |
202 | } else { | 211 | } else { |
@@ -207,6 +216,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | |||
207 | switch (sdata->vif.type) { | 216 | switch (sdata->vif.type) { |
208 | case NL80211_IFTYPE_AP: | 217 | case NL80211_IFTYPE_AP: |
209 | case NL80211_IFTYPE_ADHOC: | 218 | case NL80211_IFTYPE_ADHOC: |
219 | case NL80211_IFTYPE_WDS: | ||
210 | case NL80211_IFTYPE_MESH_POINT: | 220 | case NL80211_IFTYPE_MESH_POINT: |
211 | break; | 221 | break; |
212 | default: | 222 | default: |
@@ -291,7 +301,16 @@ static void ieee80211_restart_work(struct work_struct *work) | |||
291 | struct ieee80211_local *local = | 301 | struct ieee80211_local *local = |
292 | container_of(work, struct ieee80211_local, restart_work); | 302 | container_of(work, struct ieee80211_local, restart_work); |
293 | 303 | ||
304 | /* wait for scan work complete */ | ||
305 | flush_workqueue(local->workqueue); | ||
306 | |||
307 | mutex_lock(&local->mtx); | ||
308 | WARN(test_bit(SCAN_HW_SCANNING, &local->scanning), | ||
309 | "%s called with hardware scan in progress\n", __func__); | ||
310 | mutex_unlock(&local->mtx); | ||
311 | |||
294 | rtnl_lock(); | 312 | rtnl_lock(); |
313 | ieee80211_scan_cancel(local); | ||
295 | ieee80211_reconfig(local); | 314 | ieee80211_reconfig(local); |
296 | rtnl_unlock(); | 315 | rtnl_unlock(); |
297 | } | 316 | } |
@@ -302,7 +321,7 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw) | |||
302 | 321 | ||
303 | trace_api_restart_hw(local); | 322 | trace_api_restart_hw(local); |
304 | 323 | ||
305 | /* use this reason, __ieee80211_resume will unblock it */ | 324 | /* use this reason, ieee80211_reconfig will unblock it */ |
306 | ieee80211_stop_queues_by_reason(hw, | 325 | ieee80211_stop_queues_by_reason(hw, |
307 | IEEE80211_QUEUE_STOP_REASON_SUSPEND); | 326 | IEEE80211_QUEUE_STOP_REASON_SUSPEND); |
308 | 327 | ||
@@ -316,7 +335,7 @@ static void ieee80211_recalc_smps_work(struct work_struct *work) | |||
316 | container_of(work, struct ieee80211_local, recalc_smps); | 335 | container_of(work, struct ieee80211_local, recalc_smps); |
317 | 336 | ||
318 | mutex_lock(&local->iflist_mtx); | 337 | mutex_lock(&local->iflist_mtx); |
319 | ieee80211_recalc_smps(local, NULL); | 338 | ieee80211_recalc_smps(local); |
320 | mutex_unlock(&local->iflist_mtx); | 339 | mutex_unlock(&local->iflist_mtx); |
321 | } | 340 | } |
322 | 341 | ||
@@ -336,9 +355,6 @@ static int ieee80211_ifa_changed(struct notifier_block *nb, | |||
336 | struct ieee80211_if_managed *ifmgd; | 355 | struct ieee80211_if_managed *ifmgd; |
337 | int c = 0; | 356 | int c = 0; |
338 | 357 | ||
339 | if (!netif_running(ndev)) | ||
340 | return NOTIFY_DONE; | ||
341 | |||
342 | /* Make sure it's our interface that got changed */ | 358 | /* Make sure it's our interface that got changed */ |
343 | if (!wdev) | 359 | if (!wdev) |
344 | return NOTIFY_DONE; | 360 | return NOTIFY_DONE; |
@@ -349,11 +365,14 @@ static int ieee80211_ifa_changed(struct notifier_block *nb, | |||
349 | sdata = IEEE80211_DEV_TO_SUB_IF(ndev); | 365 | sdata = IEEE80211_DEV_TO_SUB_IF(ndev); |
350 | bss_conf = &sdata->vif.bss_conf; | 366 | bss_conf = &sdata->vif.bss_conf; |
351 | 367 | ||
368 | if (!ieee80211_sdata_running(sdata)) | ||
369 | return NOTIFY_DONE; | ||
370 | |||
352 | /* ARP filtering is only supported in managed mode */ | 371 | /* ARP filtering is only supported in managed mode */ |
353 | if (sdata->vif.type != NL80211_IFTYPE_STATION) | 372 | if (sdata->vif.type != NL80211_IFTYPE_STATION) |
354 | return NOTIFY_DONE; | 373 | return NOTIFY_DONE; |
355 | 374 | ||
356 | idev = sdata->dev->ip_ptr; | 375 | idev = __in_dev_get_rtnl(sdata->dev); |
357 | if (!idev) | 376 | if (!idev) |
358 | return NOTIFY_DONE; | 377 | return NOTIFY_DONE; |
359 | 378 | ||
@@ -390,6 +409,80 @@ static int ieee80211_ifa_changed(struct notifier_block *nb, | |||
390 | } | 409 | } |
391 | #endif | 410 | #endif |
392 | 411 | ||
412 | static int ieee80211_napi_poll(struct napi_struct *napi, int budget) | ||
413 | { | ||
414 | struct ieee80211_local *local = | ||
415 | container_of(napi, struct ieee80211_local, napi); | ||
416 | |||
417 | return local->ops->napi_poll(&local->hw, budget); | ||
418 | } | ||
419 | |||
420 | void ieee80211_napi_schedule(struct ieee80211_hw *hw) | ||
421 | { | ||
422 | struct ieee80211_local *local = hw_to_local(hw); | ||
423 | |||
424 | napi_schedule(&local->napi); | ||
425 | } | ||
426 | EXPORT_SYMBOL(ieee80211_napi_schedule); | ||
427 | |||
428 | void ieee80211_napi_complete(struct ieee80211_hw *hw) | ||
429 | { | ||
430 | struct ieee80211_local *local = hw_to_local(hw); | ||
431 | |||
432 | napi_complete(&local->napi); | ||
433 | } | ||
434 | EXPORT_SYMBOL(ieee80211_napi_complete); | ||
435 | |||
436 | /* There isn't a lot of sense in it, but you can transmit anything you like */ | ||
437 | static const struct ieee80211_txrx_stypes | ||
438 | ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { | ||
439 | [NL80211_IFTYPE_ADHOC] = { | ||
440 | .tx = 0xffff, | ||
441 | .rx = BIT(IEEE80211_STYPE_ACTION >> 4), | ||
442 | }, | ||
443 | [NL80211_IFTYPE_STATION] = { | ||
444 | .tx = 0xffff, | ||
445 | .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | | ||
446 | BIT(IEEE80211_STYPE_PROBE_REQ >> 4), | ||
447 | }, | ||
448 | [NL80211_IFTYPE_AP] = { | ||
449 | .tx = 0xffff, | ||
450 | .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | | ||
451 | BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | | ||
452 | BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | | ||
453 | BIT(IEEE80211_STYPE_DISASSOC >> 4) | | ||
454 | BIT(IEEE80211_STYPE_AUTH >> 4) | | ||
455 | BIT(IEEE80211_STYPE_DEAUTH >> 4) | | ||
456 | BIT(IEEE80211_STYPE_ACTION >> 4), | ||
457 | }, | ||
458 | [NL80211_IFTYPE_AP_VLAN] = { | ||
459 | /* copy AP */ | ||
460 | .tx = 0xffff, | ||
461 | .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | | ||
462 | BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | | ||
463 | BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | | ||
464 | BIT(IEEE80211_STYPE_DISASSOC >> 4) | | ||
465 | BIT(IEEE80211_STYPE_AUTH >> 4) | | ||
466 | BIT(IEEE80211_STYPE_DEAUTH >> 4) | | ||
467 | BIT(IEEE80211_STYPE_ACTION >> 4), | ||
468 | }, | ||
469 | [NL80211_IFTYPE_P2P_CLIENT] = { | ||
470 | .tx = 0xffff, | ||
471 | .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | | ||
472 | BIT(IEEE80211_STYPE_PROBE_REQ >> 4), | ||
473 | }, | ||
474 | [NL80211_IFTYPE_P2P_GO] = { | ||
475 | .tx = 0xffff, | ||
476 | .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | | ||
477 | BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | | ||
478 | BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | | ||
479 | BIT(IEEE80211_STYPE_DISASSOC >> 4) | | ||
480 | BIT(IEEE80211_STYPE_AUTH >> 4) | | ||
481 | BIT(IEEE80211_STYPE_DEAUTH >> 4) | | ||
482 | BIT(IEEE80211_STYPE_ACTION >> 4), | ||
483 | }, | ||
484 | }; | ||
485 | |||
393 | struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | 486 | struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, |
394 | const struct ieee80211_ops *ops) | 487 | const struct ieee80211_ops *ops) |
395 | { | 488 | { |
@@ -419,6 +512,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
419 | if (!wiphy) | 512 | if (!wiphy) |
420 | return NULL; | 513 | return NULL; |
421 | 514 | ||
515 | wiphy->mgmt_stypes = ieee80211_default_mgmt_stypes; | ||
516 | |||
422 | wiphy->flags |= WIPHY_FLAG_NETNS_OK | | 517 | wiphy->flags |= WIPHY_FLAG_NETNS_OK | |
423 | WIPHY_FLAG_4ADDR_AP | | 518 | WIPHY_FLAG_4ADDR_AP | |
424 | WIPHY_FLAG_4ADDR_STATION; | 519 | WIPHY_FLAG_4ADDR_STATION; |
@@ -444,6 +539,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
444 | /* set up some defaults */ | 539 | /* set up some defaults */ |
445 | local->hw.queues = 1; | 540 | local->hw.queues = 1; |
446 | local->hw.max_rates = 1; | 541 | local->hw.max_rates = 1; |
542 | local->hw.max_report_rates = 0; | ||
447 | local->hw.conf.long_frame_max_tx_count = wiphy->retry_long; | 543 | local->hw.conf.long_frame_max_tx_count = wiphy->retry_long; |
448 | local->hw.conf.short_frame_max_tx_count = wiphy->retry_short; | 544 | local->hw.conf.short_frame_max_tx_count = wiphy->retry_short; |
449 | local->user_power_level = -1; | 545 | local->user_power_level = -1; |
@@ -455,7 +551,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
455 | __hw_addr_init(&local->mc_list); | 551 | __hw_addr_init(&local->mc_list); |
456 | 552 | ||
457 | mutex_init(&local->iflist_mtx); | 553 | mutex_init(&local->iflist_mtx); |
458 | mutex_init(&local->scan_mtx); | 554 | mutex_init(&local->mtx); |
459 | 555 | ||
460 | mutex_init(&local->key_mtx); | 556 | mutex_init(&local->key_mtx); |
461 | spin_lock_init(&local->filter_lock); | 557 | spin_lock_init(&local->filter_lock); |
@@ -494,6 +590,9 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
494 | skb_queue_head_init(&local->skb_queue); | 590 | skb_queue_head_init(&local->skb_queue); |
495 | skb_queue_head_init(&local->skb_queue_unreliable); | 591 | skb_queue_head_init(&local->skb_queue_unreliable); |
496 | 592 | ||
593 | /* init dummy netdev for use w/ NAPI */ | ||
594 | init_dummy_netdev(&local->napi_dev); | ||
595 | |||
497 | return local_to_hw(local); | 596 | return local_to_hw(local); |
498 | } | 597 | } |
499 | EXPORT_SYMBOL(ieee80211_alloc_hw); | 598 | EXPORT_SYMBOL(ieee80211_alloc_hw); |
@@ -506,6 +605,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
506 | int channels, max_bitrates; | 605 | int channels, max_bitrates; |
507 | bool supp_ht; | 606 | bool supp_ht; |
508 | static const u32 cipher_suites[] = { | 607 | static const u32 cipher_suites[] = { |
608 | /* keep WEP first, it may be removed below */ | ||
509 | WLAN_CIPHER_SUITE_WEP40, | 609 | WLAN_CIPHER_SUITE_WEP40, |
510 | WLAN_CIPHER_SUITE_WEP104, | 610 | WLAN_CIPHER_SUITE_WEP104, |
511 | WLAN_CIPHER_SUITE_TKIP, | 611 | WLAN_CIPHER_SUITE_TKIP, |
@@ -515,6 +615,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
515 | WLAN_CIPHER_SUITE_AES_CMAC | 615 | WLAN_CIPHER_SUITE_AES_CMAC |
516 | }; | 616 | }; |
517 | 617 | ||
618 | if (hw->max_report_rates == 0) | ||
619 | hw->max_report_rates = hw->max_rates; | ||
620 | |||
518 | /* | 621 | /* |
519 | * generic code guarantees at least one band, | 622 | * generic code guarantees at least one band, |
520 | * set this very early because much code assumes | 623 | * set this very early because much code assumes |
@@ -554,6 +657,14 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
554 | /* mac80211 always supports monitor */ | 657 | /* mac80211 always supports monitor */ |
555 | local->hw.wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR); | 658 | local->hw.wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR); |
556 | 659 | ||
660 | #ifndef CONFIG_MAC80211_MESH | ||
661 | /* mesh depends on Kconfig, but drivers should set it if they want */ | ||
662 | local->hw.wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MESH_POINT); | ||
663 | #endif | ||
664 | |||
665 | /* mac80211 supports control port protocol changing */ | ||
666 | local->hw.wiphy->flags |= WIPHY_FLAG_CONTROL_PORT_PROTOCOL; | ||
667 | |||
557 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) | 668 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) |
558 | local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; | 669 | local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; |
559 | else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) | 670 | else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) |
@@ -589,10 +700,41 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
589 | if (local->hw.wiphy->max_scan_ie_len) | 700 | if (local->hw.wiphy->max_scan_ie_len) |
590 | local->hw.wiphy->max_scan_ie_len -= local->scan_ies_len; | 701 | local->hw.wiphy->max_scan_ie_len -= local->scan_ies_len; |
591 | 702 | ||
592 | local->hw.wiphy->cipher_suites = cipher_suites; | 703 | /* Set up cipher suites unless driver already did */ |
593 | local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); | 704 | if (!local->hw.wiphy->cipher_suites) { |
594 | if (!(local->hw.flags & IEEE80211_HW_MFP_CAPABLE)) | 705 | local->hw.wiphy->cipher_suites = cipher_suites; |
595 | local->hw.wiphy->n_cipher_suites--; | 706 | local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); |
707 | if (!(local->hw.flags & IEEE80211_HW_MFP_CAPABLE)) | ||
708 | local->hw.wiphy->n_cipher_suites--; | ||
709 | } | ||
710 | if (IS_ERR(local->wep_tx_tfm) || IS_ERR(local->wep_rx_tfm)) { | ||
711 | if (local->hw.wiphy->cipher_suites == cipher_suites) { | ||
712 | local->hw.wiphy->cipher_suites += 2; | ||
713 | local->hw.wiphy->n_cipher_suites -= 2; | ||
714 | } else { | ||
715 | u32 *suites; | ||
716 | int r, w = 0; | ||
717 | |||
718 | /* Filter out WEP */ | ||
719 | |||
720 | suites = kmemdup( | ||
721 | local->hw.wiphy->cipher_suites, | ||
722 | sizeof(u32) * local->hw.wiphy->n_cipher_suites, | ||
723 | GFP_KERNEL); | ||
724 | if (!suites) | ||
725 | return -ENOMEM; | ||
726 | for (r = 0; r < local->hw.wiphy->n_cipher_suites; r++) { | ||
727 | u32 suite = local->hw.wiphy->cipher_suites[r]; | ||
728 | if (suite == WLAN_CIPHER_SUITE_WEP40 || | ||
729 | suite == WLAN_CIPHER_SUITE_WEP104) | ||
730 | continue; | ||
731 | suites[w++] = suite; | ||
732 | } | ||
733 | local->hw.wiphy->cipher_suites = suites; | ||
734 | local->hw.wiphy->n_cipher_suites = w; | ||
735 | local->wiphy_ciphers_allocated = true; | ||
736 | } | ||
737 | } | ||
596 | 738 | ||
597 | result = wiphy_register(local->hw.wiphy); | 739 | result = wiphy_register(local->hw.wiphy); |
598 | if (result < 0) | 740 | if (result < 0) |
@@ -641,16 +783,16 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
641 | 783 | ||
642 | result = ieee80211_wep_init(local); | 784 | result = ieee80211_wep_init(local); |
643 | if (result < 0) | 785 | if (result < 0) |
644 | printk(KERN_DEBUG "%s: Failed to initialize wep: %d\n", | 786 | wiphy_debug(local->hw.wiphy, "Failed to initialize wep: %d\n", |
645 | wiphy_name(local->hw.wiphy), result); | 787 | result); |
646 | 788 | ||
647 | rtnl_lock(); | 789 | rtnl_lock(); |
648 | 790 | ||
649 | result = ieee80211_init_rate_ctrl_alg(local, | 791 | result = ieee80211_init_rate_ctrl_alg(local, |
650 | hw->rate_control_algorithm); | 792 | hw->rate_control_algorithm); |
651 | if (result < 0) { | 793 | if (result < 0) { |
652 | printk(KERN_DEBUG "%s: Failed to initialize rate control " | 794 | wiphy_debug(local->hw.wiphy, |
653 | "algorithm\n", wiphy_name(local->hw.wiphy)); | 795 | "Failed to initialize rate control algorithm\n"); |
654 | goto fail_rate; | 796 | goto fail_rate; |
655 | } | 797 | } |
656 | 798 | ||
@@ -659,8 +801,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
659 | result = ieee80211_if_add(local, "wlan%d", NULL, | 801 | result = ieee80211_if_add(local, "wlan%d", NULL, |
660 | NL80211_IFTYPE_STATION, NULL); | 802 | NL80211_IFTYPE_STATION, NULL); |
661 | if (result) | 803 | if (result) |
662 | printk(KERN_WARNING "%s: Failed to add default virtual iface\n", | 804 | wiphy_warn(local->hw.wiphy, |
663 | wiphy_name(local->hw.wiphy)); | 805 | "Failed to add default virtual iface\n"); |
664 | } | 806 | } |
665 | 807 | ||
666 | rtnl_unlock(); | 808 | rtnl_unlock(); |
@@ -683,6 +825,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
683 | goto fail_ifa; | 825 | goto fail_ifa; |
684 | #endif | 826 | #endif |
685 | 827 | ||
828 | netif_napi_add(&local->napi_dev, &local->napi, ieee80211_napi_poll, | ||
829 | local->hw.napi_weight); | ||
830 | |||
686 | return 0; | 831 | return 0; |
687 | 832 | ||
688 | #ifdef CONFIG_INET | 833 | #ifdef CONFIG_INET |
@@ -703,6 +848,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
703 | fail_workqueue: | 848 | fail_workqueue: |
704 | wiphy_unregister(local->hw.wiphy); | 849 | wiphy_unregister(local->hw.wiphy); |
705 | fail_wiphy_register: | 850 | fail_wiphy_register: |
851 | if (local->wiphy_ciphers_allocated) | ||
852 | kfree(local->hw.wiphy->cipher_suites); | ||
706 | kfree(local->int_scan_req); | 853 | kfree(local->int_scan_req); |
707 | return result; | 854 | return result; |
708 | } | 855 | } |
@@ -738,6 +885,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
738 | */ | 885 | */ |
739 | del_timer_sync(&local->work_timer); | 886 | del_timer_sync(&local->work_timer); |
740 | 887 | ||
888 | cancel_work_sync(&local->restart_work); | ||
741 | cancel_work_sync(&local->reconfig_filter); | 889 | cancel_work_sync(&local->reconfig_filter); |
742 | 890 | ||
743 | ieee80211_clear_tx_pending(local); | 891 | ieee80211_clear_tx_pending(local); |
@@ -746,8 +894,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
746 | 894 | ||
747 | if (skb_queue_len(&local->skb_queue) || | 895 | if (skb_queue_len(&local->skb_queue) || |
748 | skb_queue_len(&local->skb_queue_unreliable)) | 896 | skb_queue_len(&local->skb_queue_unreliable)) |
749 | printk(KERN_WARNING "%s: skb_queue not empty\n", | 897 | wiphy_warn(local->hw.wiphy, "skb_queue not empty\n"); |
750 | wiphy_name(local->hw.wiphy)); | ||
751 | skb_queue_purge(&local->skb_queue); | 898 | skb_queue_purge(&local->skb_queue); |
752 | skb_queue_purge(&local->skb_queue_unreliable); | 899 | skb_queue_purge(&local->skb_queue_unreliable); |
753 | 900 | ||
@@ -764,7 +911,10 @@ void ieee80211_free_hw(struct ieee80211_hw *hw) | |||
764 | struct ieee80211_local *local = hw_to_local(hw); | 911 | struct ieee80211_local *local = hw_to_local(hw); |
765 | 912 | ||
766 | mutex_destroy(&local->iflist_mtx); | 913 | mutex_destroy(&local->iflist_mtx); |
767 | mutex_destroy(&local->scan_mtx); | 914 | mutex_destroy(&local->mtx); |
915 | |||
916 | if (local->wiphy_ciphers_allocated) | ||
917 | kfree(local->hw.wiphy->cipher_suites); | ||
768 | 918 | ||
769 | wiphy_free(local->hw.wiphy); | 919 | wiphy_free(local->hw.wiphy); |
770 | } | 920 | } |
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index ea13a80a476..1c91f0f3c30 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c | |||
@@ -412,7 +412,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m | |||
412 | enum plink_event event; | 412 | enum plink_event event; |
413 | enum plink_frame_type ftype; | 413 | enum plink_frame_type ftype; |
414 | size_t baselen; | 414 | size_t baselen; |
415 | bool deactivated; | 415 | bool deactivated, matches_local = true; |
416 | u8 ie_len; | 416 | u8 ie_len; |
417 | u8 *baseaddr; | 417 | u8 *baseaddr; |
418 | __le16 plid, llid, reason; | 418 | __le16 plid, llid, reason; |
@@ -487,6 +487,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m | |||
487 | /* Now we will figure out the appropriate event... */ | 487 | /* Now we will figure out the appropriate event... */ |
488 | event = PLINK_UNDEFINED; | 488 | event = PLINK_UNDEFINED; |
489 | if (ftype != PLINK_CLOSE && (!mesh_matches_local(&elems, sdata))) { | 489 | if (ftype != PLINK_CLOSE && (!mesh_matches_local(&elems, sdata))) { |
490 | matches_local = false; | ||
490 | switch (ftype) { | 491 | switch (ftype) { |
491 | case PLINK_OPEN: | 492 | case PLINK_OPEN: |
492 | event = OPN_RJCT; | 493 | event = OPN_RJCT; |
@@ -498,7 +499,15 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m | |||
498 | /* avoid warning */ | 499 | /* avoid warning */ |
499 | break; | 500 | break; |
500 | } | 501 | } |
501 | spin_lock_bh(&sta->lock); | 502 | } |
503 | |||
504 | if (!sta && !matches_local) { | ||
505 | rcu_read_unlock(); | ||
506 | reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION); | ||
507 | llid = 0; | ||
508 | mesh_plink_frame_tx(sdata, PLINK_CLOSE, mgmt->sa, llid, | ||
509 | plid, reason); | ||
510 | return; | ||
502 | } else if (!sta) { | 511 | } else if (!sta) { |
503 | /* ftype == PLINK_OPEN */ | 512 | /* ftype == PLINK_OPEN */ |
504 | u32 rates; | 513 | u32 rates; |
@@ -522,7 +531,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m | |||
522 | } | 531 | } |
523 | event = OPN_ACPT; | 532 | event = OPN_ACPT; |
524 | spin_lock_bh(&sta->lock); | 533 | spin_lock_bh(&sta->lock); |
525 | } else { | 534 | } else if (matches_local) { |
526 | spin_lock_bh(&sta->lock); | 535 | spin_lock_bh(&sta->lock); |
527 | switch (ftype) { | 536 | switch (ftype) { |
528 | case PLINK_OPEN: | 537 | case PLINK_OPEN: |
@@ -564,6 +573,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m | |||
564 | rcu_read_unlock(); | 573 | rcu_read_unlock(); |
565 | return; | 574 | return; |
566 | } | 575 | } |
576 | } else { | ||
577 | spin_lock_bh(&sta->lock); | ||
567 | } | 578 | } |
568 | 579 | ||
569 | mpl_dbg("Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d\n", | 580 | mpl_dbg("Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d\n", |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index b6c163ac22d..a3a9421555a 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -54,6 +54,12 @@ | |||
54 | */ | 54 | */ |
55 | #define IEEE80211_SIGNAL_AVE_WEIGHT 3 | 55 | #define IEEE80211_SIGNAL_AVE_WEIGHT 3 |
56 | 56 | ||
57 | /* | ||
58 | * How many Beacon frames need to have been used in average signal strength | ||
59 | * before starting to indicate signal change events. | ||
60 | */ | ||
61 | #define IEEE80211_SIGNAL_AVE_MIN_COUNT 4 | ||
62 | |||
57 | #define TMR_RUNNING_TIMER 0 | 63 | #define TMR_RUNNING_TIMER 0 |
58 | #define TMR_RUNNING_CHANSW 1 | 64 | #define TMR_RUNNING_CHANSW 1 |
59 | 65 | ||
@@ -86,7 +92,7 @@ enum rx_mgmt_action { | |||
86 | /* utils */ | 92 | /* utils */ |
87 | static inline void ASSERT_MGD_MTX(struct ieee80211_if_managed *ifmgd) | 93 | static inline void ASSERT_MGD_MTX(struct ieee80211_if_managed *ifmgd) |
88 | { | 94 | { |
89 | WARN_ON(!mutex_is_locked(&ifmgd->mtx)); | 95 | lockdep_assert_held(&ifmgd->mtx); |
90 | } | 96 | } |
91 | 97 | ||
92 | /* | 98 | /* |
@@ -109,7 +115,7 @@ static void run_again(struct ieee80211_if_managed *ifmgd, | |||
109 | mod_timer(&ifmgd->timer, timeout); | 115 | mod_timer(&ifmgd->timer, timeout); |
110 | } | 116 | } |
111 | 117 | ||
112 | static void mod_beacon_timer(struct ieee80211_sub_if_data *sdata) | 118 | void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata) |
113 | { | 119 | { |
114 | if (sdata->local->hw.flags & IEEE80211_HW_BEACON_FILTER) | 120 | if (sdata->local->hw.flags & IEEE80211_HW_BEACON_FILTER) |
115 | return; | 121 | return; |
@@ -118,6 +124,19 @@ static void mod_beacon_timer(struct ieee80211_sub_if_data *sdata) | |||
118 | round_jiffies_up(jiffies + IEEE80211_BEACON_LOSS_TIME)); | 124 | round_jiffies_up(jiffies + IEEE80211_BEACON_LOSS_TIME)); |
119 | } | 125 | } |
120 | 126 | ||
127 | void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata) | ||
128 | { | ||
129 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | ||
130 | |||
131 | if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) | ||
132 | return; | ||
133 | |||
134 | mod_timer(&sdata->u.mgd.conn_mon_timer, | ||
135 | round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME)); | ||
136 | |||
137 | ifmgd->probe_send_count = 0; | ||
138 | } | ||
139 | |||
121 | static int ecw2cw(int ecw) | 140 | static int ecw2cw(int ecw) |
122 | { | 141 | { |
123 | return (1 << ecw) - 1; | 142 | return (1 << ecw) - 1; |
@@ -778,16 +797,17 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, | |||
778 | params.uapsd = uapsd; | 797 | params.uapsd = uapsd; |
779 | 798 | ||
780 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 799 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
781 | printk(KERN_DEBUG "%s: WMM queue=%d aci=%d acm=%d aifs=%d " | 800 | wiphy_debug(local->hw.wiphy, |
782 | "cWmin=%d cWmax=%d txop=%d uapsd=%d\n", | 801 | "WMM queue=%d aci=%d acm=%d aifs=%d " |
783 | wiphy_name(local->hw.wiphy), queue, aci, acm, | 802 | "cWmin=%d cWmax=%d txop=%d uapsd=%d\n", |
784 | params.aifs, params.cw_min, params.cw_max, params.txop, | 803 | queue, aci, acm, |
785 | params.uapsd); | 804 | params.aifs, params.cw_min, params.cw_max, |
805 | params.txop, params.uapsd); | ||
786 | #endif | 806 | #endif |
787 | if (drv_conf_tx(local, queue, ¶ms)) | 807 | if (drv_conf_tx(local, queue, ¶ms)) |
788 | printk(KERN_DEBUG "%s: failed to set TX queue " | 808 | wiphy_debug(local->hw.wiphy, |
789 | "parameters for queue %d\n", | 809 | "failed to set TX queue parameters for queue %d\n", |
790 | wiphy_name(local->hw.wiphy), queue); | 810 | queue); |
791 | } | 811 | } |
792 | 812 | ||
793 | /* enable WMM or activate new settings */ | 813 | /* enable WMM or activate new settings */ |
@@ -860,14 +880,6 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
860 | sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL | | 880 | sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL | |
861 | IEEE80211_STA_BEACON_POLL); | 881 | IEEE80211_STA_BEACON_POLL); |
862 | 882 | ||
863 | /* | ||
864 | * Always handle WMM once after association regardless | ||
865 | * of the first value the AP uses. Setting -1 here has | ||
866 | * that effect because the AP values is an unsigned | ||
867 | * 4-bit value. | ||
868 | */ | ||
869 | sdata->u.mgd.wmm_last_param_set = -1; | ||
870 | |||
871 | ieee80211_led_assoc(local, 1); | 883 | ieee80211_led_assoc(local, 1); |
872 | 884 | ||
873 | if (local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) | 885 | if (local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) |
@@ -901,7 +913,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
901 | 913 | ||
902 | mutex_lock(&local->iflist_mtx); | 914 | mutex_lock(&local->iflist_mtx); |
903 | ieee80211_recalc_ps(local, -1); | 915 | ieee80211_recalc_ps(local, -1); |
904 | ieee80211_recalc_smps(local, sdata); | 916 | ieee80211_recalc_smps(local); |
905 | mutex_unlock(&local->iflist_mtx); | 917 | mutex_unlock(&local->iflist_mtx); |
906 | 918 | ||
907 | netif_tx_start_all_queues(sdata->dev); | 919 | netif_tx_start_all_queues(sdata->dev); |
@@ -909,7 +921,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
909 | } | 921 | } |
910 | 922 | ||
911 | static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | 923 | static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, |
912 | bool remove_sta) | 924 | bool remove_sta, bool tx) |
913 | { | 925 | { |
914 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 926 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
915 | struct ieee80211_local *local = sdata->local; | 927 | struct ieee80211_local *local = sdata->local; |
@@ -948,7 +960,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
948 | sta = sta_info_get(sdata, bssid); | 960 | sta = sta_info_get(sdata, bssid); |
949 | if (sta) { | 961 | if (sta) { |
950 | set_sta_flags(sta, WLAN_STA_BLOCK_BA); | 962 | set_sta_flags(sta, WLAN_STA_BLOCK_BA); |
951 | ieee80211_sta_tear_down_BA_sessions(sta); | 963 | ieee80211_sta_tear_down_BA_sessions(sta, tx); |
952 | } | 964 | } |
953 | mutex_unlock(&local->sta_mtx); | 965 | mutex_unlock(&local->sta_mtx); |
954 | 966 | ||
@@ -990,6 +1002,11 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
990 | 1002 | ||
991 | if (remove_sta) | 1003 | if (remove_sta) |
992 | sta_info_destroy_addr(sdata, bssid); | 1004 | sta_info_destroy_addr(sdata, bssid); |
1005 | |||
1006 | del_timer_sync(&sdata->u.mgd.conn_mon_timer); | ||
1007 | del_timer_sync(&sdata->u.mgd.bcn_mon_timer); | ||
1008 | del_timer_sync(&sdata->u.mgd.timer); | ||
1009 | del_timer_sync(&sdata->u.mgd.chswitch_timer); | ||
993 | } | 1010 | } |
994 | 1011 | ||
995 | void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, | 1012 | void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, |
@@ -1006,21 +1023,26 @@ void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, | |||
1006 | if (is_multicast_ether_addr(hdr->addr1)) | 1023 | if (is_multicast_ether_addr(hdr->addr1)) |
1007 | return; | 1024 | return; |
1008 | 1025 | ||
1009 | if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) | 1026 | ieee80211_sta_reset_conn_monitor(sdata); |
1010 | return; | ||
1011 | |||
1012 | mod_timer(&sdata->u.mgd.conn_mon_timer, | ||
1013 | round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME)); | ||
1014 | } | 1027 | } |
1015 | 1028 | ||
1016 | static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) | 1029 | static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) |
1017 | { | 1030 | { |
1018 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 1031 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
1019 | const u8 *ssid; | 1032 | const u8 *ssid; |
1033 | u8 *dst = ifmgd->associated->bssid; | ||
1034 | u8 unicast_limit = max(1, IEEE80211_MAX_PROBE_TRIES - 3); | ||
1035 | |||
1036 | /* | ||
1037 | * Try sending broadcast probe requests for the last three | ||
1038 | * probe requests after the first ones failed since some | ||
1039 | * buggy APs only support broadcast probe requests. | ||
1040 | */ | ||
1041 | if (ifmgd->probe_send_count >= unicast_limit) | ||
1042 | dst = NULL; | ||
1020 | 1043 | ||
1021 | ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID); | 1044 | ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID); |
1022 | ieee80211_send_probe_req(sdata, ifmgd->associated->bssid, | 1045 | ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0); |
1023 | ssid + 2, ssid[1], NULL, 0); | ||
1024 | 1046 | ||
1025 | ifmgd->probe_send_count++; | 1047 | ifmgd->probe_send_count++; |
1026 | ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT; | 1048 | ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT; |
@@ -1102,9 +1124,12 @@ static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata) | |||
1102 | 1124 | ||
1103 | printk(KERN_DEBUG "Connection to AP %pM lost.\n", bssid); | 1125 | printk(KERN_DEBUG "Connection to AP %pM lost.\n", bssid); |
1104 | 1126 | ||
1105 | ieee80211_set_disassoc(sdata, true); | 1127 | ieee80211_set_disassoc(sdata, true, true); |
1106 | ieee80211_recalc_idle(local); | ||
1107 | mutex_unlock(&ifmgd->mtx); | 1128 | mutex_unlock(&ifmgd->mtx); |
1129 | |||
1130 | mutex_lock(&local->mtx); | ||
1131 | ieee80211_recalc_idle(local); | ||
1132 | mutex_unlock(&local->mtx); | ||
1108 | /* | 1133 | /* |
1109 | * must be outside lock due to cfg80211, | 1134 | * must be outside lock due to cfg80211, |
1110 | * but that's not a problem. | 1135 | * but that's not a problem. |
@@ -1172,8 +1197,10 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, | |||
1172 | printk(KERN_DEBUG "%s: deauthenticated from %pM (Reason: %u)\n", | 1197 | printk(KERN_DEBUG "%s: deauthenticated from %pM (Reason: %u)\n", |
1173 | sdata->name, bssid, reason_code); | 1198 | sdata->name, bssid, reason_code); |
1174 | 1199 | ||
1175 | ieee80211_set_disassoc(sdata, true); | 1200 | ieee80211_set_disassoc(sdata, true, false); |
1201 | mutex_lock(&sdata->local->mtx); | ||
1176 | ieee80211_recalc_idle(sdata->local); | 1202 | ieee80211_recalc_idle(sdata->local); |
1203 | mutex_unlock(&sdata->local->mtx); | ||
1177 | 1204 | ||
1178 | return RX_MGMT_CFG80211_DEAUTH; | 1205 | return RX_MGMT_CFG80211_DEAUTH; |
1179 | } | 1206 | } |
@@ -1202,8 +1229,10 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1202 | printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n", | 1229 | printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n", |
1203 | sdata->name, mgmt->sa, reason_code); | 1230 | sdata->name, mgmt->sa, reason_code); |
1204 | 1231 | ||
1205 | ieee80211_set_disassoc(sdata, true); | 1232 | ieee80211_set_disassoc(sdata, true, false); |
1233 | mutex_lock(&sdata->local->mtx); | ||
1206 | ieee80211_recalc_idle(sdata->local); | 1234 | ieee80211_recalc_idle(sdata->local); |
1235 | mutex_unlock(&sdata->local->mtx); | ||
1207 | return RX_MGMT_CFG80211_DISASSOC; | 1236 | return RX_MGMT_CFG80211_DISASSOC; |
1208 | } | 1237 | } |
1209 | 1238 | ||
@@ -1262,7 +1291,7 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk, | |||
1262 | 1291 | ||
1263 | rates = 0; | 1292 | rates = 0; |
1264 | basic_rates = 0; | 1293 | basic_rates = 0; |
1265 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | 1294 | sband = local->hw.wiphy->bands[wk->chan->band]; |
1266 | 1295 | ||
1267 | for (i = 0; i < elems.supp_rates_len; i++) { | 1296 | for (i = 0; i < elems.supp_rates_len; i++) { |
1268 | int rate = (elems.supp_rates[i] & 0x7f) * 5; | 1297 | int rate = (elems.supp_rates[i] & 0x7f) * 5; |
@@ -1298,11 +1327,11 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk, | |||
1298 | } | 1327 | } |
1299 | } | 1328 | } |
1300 | 1329 | ||
1301 | sta->sta.supp_rates[local->hw.conf.channel->band] = rates; | 1330 | sta->sta.supp_rates[wk->chan->band] = rates; |
1302 | sdata->vif.bss_conf.basic_rates = basic_rates; | 1331 | sdata->vif.bss_conf.basic_rates = basic_rates; |
1303 | 1332 | ||
1304 | /* cf. IEEE 802.11 9.2.12 */ | 1333 | /* cf. IEEE 802.11 9.2.12 */ |
1305 | if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ && | 1334 | if (wk->chan->band == IEEE80211_BAND_2GHZ && |
1306 | have_higher_than_11mbit) | 1335 | have_higher_than_11mbit) |
1307 | sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE; | 1336 | sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE; |
1308 | else | 1337 | else |
@@ -1330,6 +1359,14 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk, | |||
1330 | return false; | 1359 | return false; |
1331 | } | 1360 | } |
1332 | 1361 | ||
1362 | /* | ||
1363 | * Always handle WMM once after association regardless | ||
1364 | * of the first value the AP uses. Setting -1 here has | ||
1365 | * that effect because the AP values is an unsigned | ||
1366 | * 4-bit value. | ||
1367 | */ | ||
1368 | ifmgd->wmm_last_param_set = -1; | ||
1369 | |||
1333 | if (elems.wmm_param) | 1370 | if (elems.wmm_param) |
1334 | ieee80211_sta_wmm_params(local, sdata, elems.wmm_param, | 1371 | ieee80211_sta_wmm_params(local, sdata, elems.wmm_param, |
1335 | elems.wmm_param_len); | 1372 | elems.wmm_param_len); |
@@ -1362,7 +1399,7 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk, | |||
1362 | * Also start the timer that will detect beacon loss. | 1399 | * Also start the timer that will detect beacon loss. |
1363 | */ | 1400 | */ |
1364 | ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt); | 1401 | ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt); |
1365 | mod_beacon_timer(sdata); | 1402 | ieee80211_sta_reset_beacon_monitor(sdata); |
1366 | 1403 | ||
1367 | return true; | 1404 | return true; |
1368 | } | 1405 | } |
@@ -1465,7 +1502,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, | |||
1465 | * we have or will be receiving any beacons or data, so let's | 1502 | * we have or will be receiving any beacons or data, so let's |
1466 | * schedule the timers again, just in case. | 1503 | * schedule the timers again, just in case. |
1467 | */ | 1504 | */ |
1468 | mod_beacon_timer(sdata); | 1505 | ieee80211_sta_reset_beacon_monitor(sdata); |
1469 | 1506 | ||
1470 | mod_timer(&ifmgd->conn_mon_timer, | 1507 | mod_timer(&ifmgd->conn_mon_timer, |
1471 | round_jiffies_up(jiffies + | 1508 | round_jiffies_up(jiffies + |
@@ -1540,15 +1577,18 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
1540 | ifmgd->last_beacon_signal = rx_status->signal; | 1577 | ifmgd->last_beacon_signal = rx_status->signal; |
1541 | if (ifmgd->flags & IEEE80211_STA_RESET_SIGNAL_AVE) { | 1578 | if (ifmgd->flags & IEEE80211_STA_RESET_SIGNAL_AVE) { |
1542 | ifmgd->flags &= ~IEEE80211_STA_RESET_SIGNAL_AVE; | 1579 | ifmgd->flags &= ~IEEE80211_STA_RESET_SIGNAL_AVE; |
1543 | ifmgd->ave_beacon_signal = rx_status->signal; | 1580 | ifmgd->ave_beacon_signal = rx_status->signal * 16; |
1544 | ifmgd->last_cqm_event_signal = 0; | 1581 | ifmgd->last_cqm_event_signal = 0; |
1582 | ifmgd->count_beacon_signal = 1; | ||
1545 | } else { | 1583 | } else { |
1546 | ifmgd->ave_beacon_signal = | 1584 | ifmgd->ave_beacon_signal = |
1547 | (IEEE80211_SIGNAL_AVE_WEIGHT * rx_status->signal * 16 + | 1585 | (IEEE80211_SIGNAL_AVE_WEIGHT * rx_status->signal * 16 + |
1548 | (16 - IEEE80211_SIGNAL_AVE_WEIGHT) * | 1586 | (16 - IEEE80211_SIGNAL_AVE_WEIGHT) * |
1549 | ifmgd->ave_beacon_signal) / 16; | 1587 | ifmgd->ave_beacon_signal) / 16; |
1588 | ifmgd->count_beacon_signal++; | ||
1550 | } | 1589 | } |
1551 | if (bss_conf->cqm_rssi_thold && | 1590 | if (bss_conf->cqm_rssi_thold && |
1591 | ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT && | ||
1552 | !(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) { | 1592 | !(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) { |
1553 | int sig = ifmgd->ave_beacon_signal / 16; | 1593 | int sig = ifmgd->ave_beacon_signal / 16; |
1554 | int last_event = ifmgd->last_cqm_event_signal; | 1594 | int last_event = ifmgd->last_cqm_event_signal; |
@@ -1588,7 +1628,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
1588 | * Push the beacon loss detection into the future since | 1628 | * Push the beacon loss detection into the future since |
1589 | * we are processing a beacon from the AP just now. | 1629 | * we are processing a beacon from the AP just now. |
1590 | */ | 1630 | */ |
1591 | mod_beacon_timer(sdata); | 1631 | ieee80211_sta_reset_beacon_monitor(sdata); |
1592 | 1632 | ||
1593 | ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4); | 1633 | ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4); |
1594 | ncrc = ieee802_11_parse_elems_crc(mgmt->u.beacon.variable, | 1634 | ncrc = ieee802_11_parse_elems_crc(mgmt->u.beacon.variable, |
@@ -1599,7 +1639,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
1599 | directed_tim = ieee80211_check_tim(elems.tim, elems.tim_len, | 1639 | directed_tim = ieee80211_check_tim(elems.tim, elems.tim_len, |
1600 | ifmgd->aid); | 1640 | ifmgd->aid); |
1601 | 1641 | ||
1602 | if (ncrc != ifmgd->beacon_crc) { | 1642 | if (ncrc != ifmgd->beacon_crc || !ifmgd->beacon_crc_valid) { |
1603 | ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, | 1643 | ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, |
1604 | true); | 1644 | true); |
1605 | 1645 | ||
@@ -1630,9 +1670,10 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
1630 | } | 1670 | } |
1631 | } | 1671 | } |
1632 | 1672 | ||
1633 | if (ncrc == ifmgd->beacon_crc) | 1673 | if (ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid) |
1634 | return; | 1674 | return; |
1635 | ifmgd->beacon_crc = ncrc; | 1675 | ifmgd->beacon_crc = ncrc; |
1676 | ifmgd->beacon_crc_valid = true; | ||
1636 | 1677 | ||
1637 | if (elems.erp_info && elems.erp_info_len >= 1) { | 1678 | if (elems.erp_info && elems.erp_info_len >= 1) { |
1638 | erp_valid = true; | 1679 | erp_valid = true; |
@@ -1751,7 +1792,7 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | |||
1751 | struct ieee80211_local *local = sdata->local; | 1792 | struct ieee80211_local *local = sdata->local; |
1752 | struct ieee80211_work *wk; | 1793 | struct ieee80211_work *wk; |
1753 | 1794 | ||
1754 | mutex_lock(&local->work_mtx); | 1795 | mutex_lock(&local->mtx); |
1755 | list_for_each_entry(wk, &local->work_list, list) { | 1796 | list_for_each_entry(wk, &local->work_list, list) { |
1756 | if (wk->sdata != sdata) | 1797 | if (wk->sdata != sdata) |
1757 | continue; | 1798 | continue; |
@@ -1783,7 +1824,7 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | |||
1783 | free_work(wk); | 1824 | free_work(wk); |
1784 | break; | 1825 | break; |
1785 | } | 1826 | } |
1786 | mutex_unlock(&local->work_mtx); | 1827 | mutex_unlock(&local->mtx); |
1787 | 1828 | ||
1788 | cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len); | 1829 | cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len); |
1789 | } | 1830 | } |
@@ -1823,10 +1864,12 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) | |||
1823 | 1864 | ||
1824 | else if (ifmgd->probe_send_count < IEEE80211_MAX_PROBE_TRIES) { | 1865 | else if (ifmgd->probe_send_count < IEEE80211_MAX_PROBE_TRIES) { |
1825 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 1866 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
1826 | printk(KERN_DEBUG "No probe response from AP %pM" | 1867 | wiphy_debug(local->hw.wiphy, |
1827 | " after %dms, try %d\n", bssid, | 1868 | "%s: No probe response from AP %pM" |
1828 | (1000 * IEEE80211_PROBE_WAIT)/HZ, | 1869 | " after %dms, try %d\n", |
1829 | ifmgd->probe_send_count); | 1870 | sdata->name, |
1871 | bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ, | ||
1872 | ifmgd->probe_send_count); | ||
1830 | #endif | 1873 | #endif |
1831 | ieee80211_mgd_probe_ap_send(sdata); | 1874 | ieee80211_mgd_probe_ap_send(sdata); |
1832 | } else { | 1875 | } else { |
@@ -1836,12 +1879,16 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) | |||
1836 | */ | 1879 | */ |
1837 | ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | | 1880 | ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | |
1838 | IEEE80211_STA_BEACON_POLL); | 1881 | IEEE80211_STA_BEACON_POLL); |
1839 | printk(KERN_DEBUG "No probe response from AP %pM" | 1882 | wiphy_debug(local->hw.wiphy, |
1840 | " after %dms, disconnecting.\n", | 1883 | "%s: No probe response from AP %pM" |
1841 | bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); | 1884 | " after %dms, disconnecting.\n", |
1842 | ieee80211_set_disassoc(sdata, true); | 1885 | sdata->name, |
1843 | ieee80211_recalc_idle(local); | 1886 | bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); |
1887 | ieee80211_set_disassoc(sdata, true, true); | ||
1844 | mutex_unlock(&ifmgd->mtx); | 1888 | mutex_unlock(&ifmgd->mtx); |
1889 | mutex_lock(&local->mtx); | ||
1890 | ieee80211_recalc_idle(local); | ||
1891 | mutex_unlock(&local->mtx); | ||
1845 | /* | 1892 | /* |
1846 | * must be outside lock due to cfg80211, | 1893 | * must be outside lock due to cfg80211, |
1847 | * but that's not a problem. | 1894 | * but that's not a problem. |
@@ -1917,6 +1964,8 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata) | |||
1917 | * time -- the code here is properly synchronised. | 1964 | * time -- the code here is properly synchronised. |
1918 | */ | 1965 | */ |
1919 | 1966 | ||
1967 | cancel_work_sync(&ifmgd->request_smps_work); | ||
1968 | |||
1920 | cancel_work_sync(&ifmgd->beacon_connection_loss_work); | 1969 | cancel_work_sync(&ifmgd->beacon_connection_loss_work); |
1921 | if (del_timer_sync(&ifmgd->timer)) | 1970 | if (del_timer_sync(&ifmgd->timer)) |
1922 | set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running); | 1971 | set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running); |
@@ -1952,6 +2001,7 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) | |||
1952 | INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work); | 2001 | INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work); |
1953 | INIT_WORK(&ifmgd->beacon_connection_loss_work, | 2002 | INIT_WORK(&ifmgd->beacon_connection_loss_work, |
1954 | ieee80211_beacon_connection_loss_work); | 2003 | ieee80211_beacon_connection_loss_work); |
2004 | INIT_WORK(&ifmgd->request_smps_work, ieee80211_request_smps_work); | ||
1955 | setup_timer(&ifmgd->timer, ieee80211_sta_timer, | 2005 | setup_timer(&ifmgd->timer, ieee80211_sta_timer, |
1956 | (unsigned long) sdata); | 2006 | (unsigned long) sdata); |
1957 | setup_timer(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer, | 2007 | setup_timer(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer, |
@@ -2158,7 +2208,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
2158 | } | 2208 | } |
2159 | 2209 | ||
2160 | /* Trying to reassociate - clear previous association state */ | 2210 | /* Trying to reassociate - clear previous association state */ |
2161 | ieee80211_set_disassoc(sdata, true); | 2211 | ieee80211_set_disassoc(sdata, true, false); |
2162 | } | 2212 | } |
2163 | mutex_unlock(&ifmgd->mtx); | 2213 | mutex_unlock(&ifmgd->mtx); |
2164 | 2214 | ||
@@ -2169,6 +2219,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
2169 | ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N; | 2219 | ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N; |
2170 | ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED; | 2220 | ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED; |
2171 | 2221 | ||
2222 | ifmgd->beacon_crc_valid = false; | ||
2223 | |||
2172 | for (i = 0; i < req->crypto.n_ciphers_pairwise; i++) | 2224 | for (i = 0; i < req->crypto.n_ciphers_pairwise; i++) |
2173 | if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 || | 2225 | if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 || |
2174 | req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP || | 2226 | req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP || |
@@ -2249,6 +2301,9 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
2249 | else | 2301 | else |
2250 | ifmgd->flags &= ~IEEE80211_STA_CONTROL_PORT; | 2302 | ifmgd->flags &= ~IEEE80211_STA_CONTROL_PORT; |
2251 | 2303 | ||
2304 | sdata->control_port_protocol = req->crypto.control_port_ethertype; | ||
2305 | sdata->control_port_no_encrypt = req->crypto.control_port_no_encrypt; | ||
2306 | |||
2252 | ieee80211_add_work(wk); | 2307 | ieee80211_add_work(wk); |
2253 | return 0; | 2308 | return 0; |
2254 | } | 2309 | } |
@@ -2267,7 +2322,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
2267 | 2322 | ||
2268 | memcpy(bssid, req->bss->bssid, ETH_ALEN); | 2323 | memcpy(bssid, req->bss->bssid, ETH_ALEN); |
2269 | if (ifmgd->associated == req->bss) { | 2324 | if (ifmgd->associated == req->bss) { |
2270 | ieee80211_set_disassoc(sdata, false); | 2325 | ieee80211_set_disassoc(sdata, false, true); |
2271 | mutex_unlock(&ifmgd->mtx); | 2326 | mutex_unlock(&ifmgd->mtx); |
2272 | assoc_bss = true; | 2327 | assoc_bss = true; |
2273 | } else { | 2328 | } else { |
@@ -2275,7 +2330,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
2275 | 2330 | ||
2276 | mutex_unlock(&ifmgd->mtx); | 2331 | mutex_unlock(&ifmgd->mtx); |
2277 | 2332 | ||
2278 | mutex_lock(&local->work_mtx); | 2333 | mutex_lock(&local->mtx); |
2279 | list_for_each_entry(wk, &local->work_list, list) { | 2334 | list_for_each_entry(wk, &local->work_list, list) { |
2280 | if (wk->sdata != sdata) | 2335 | if (wk->sdata != sdata) |
2281 | continue; | 2336 | continue; |
@@ -2294,7 +2349,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
2294 | free_work(wk); | 2349 | free_work(wk); |
2295 | break; | 2350 | break; |
2296 | } | 2351 | } |
2297 | mutex_unlock(&local->work_mtx); | 2352 | mutex_unlock(&local->mtx); |
2298 | 2353 | ||
2299 | /* | 2354 | /* |
2300 | * If somebody requests authentication and we haven't | 2355 | * If somebody requests authentication and we haven't |
@@ -2319,7 +2374,9 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
2319 | if (assoc_bss) | 2374 | if (assoc_bss) |
2320 | sta_info_destroy_addr(sdata, bssid); | 2375 | sta_info_destroy_addr(sdata, bssid); |
2321 | 2376 | ||
2377 | mutex_lock(&sdata->local->mtx); | ||
2322 | ieee80211_recalc_idle(sdata->local); | 2378 | ieee80211_recalc_idle(sdata->local); |
2379 | mutex_unlock(&sdata->local->mtx); | ||
2323 | 2380 | ||
2324 | return 0; | 2381 | return 0; |
2325 | } | 2382 | } |
@@ -2348,7 +2405,7 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, | |||
2348 | sdata->name, req->bss->bssid, req->reason_code); | 2405 | sdata->name, req->bss->bssid, req->reason_code); |
2349 | 2406 | ||
2350 | memcpy(bssid, req->bss->bssid, ETH_ALEN); | 2407 | memcpy(bssid, req->bss->bssid, ETH_ALEN); |
2351 | ieee80211_set_disassoc(sdata, false); | 2408 | ieee80211_set_disassoc(sdata, false, true); |
2352 | 2409 | ||
2353 | mutex_unlock(&ifmgd->mtx); | 2410 | mutex_unlock(&ifmgd->mtx); |
2354 | 2411 | ||
@@ -2357,7 +2414,9 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, | |||
2357 | cookie, !req->local_state_change); | 2414 | cookie, !req->local_state_change); |
2358 | sta_info_destroy_addr(sdata, bssid); | 2415 | sta_info_destroy_addr(sdata, bssid); |
2359 | 2416 | ||
2417 | mutex_lock(&sdata->local->mtx); | ||
2360 | ieee80211_recalc_idle(sdata->local); | 2418 | ieee80211_recalc_idle(sdata->local); |
2419 | mutex_unlock(&sdata->local->mtx); | ||
2361 | 2420 | ||
2362 | return 0; | 2421 | return 0; |
2363 | } | 2422 | } |
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index c36b1911987..4b564091e51 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c | |||
@@ -22,12 +22,16 @@ | |||
22 | static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata) | 22 | static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata) |
23 | { | 23 | { |
24 | struct ieee80211_local *local = sdata->local; | 24 | struct ieee80211_local *local = sdata->local; |
25 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | ||
25 | 26 | ||
26 | local->offchannel_ps_enabled = false; | 27 | local->offchannel_ps_enabled = false; |
27 | 28 | ||
28 | /* FIXME: what to do when local->pspolling is true? */ | 29 | /* FIXME: what to do when local->pspolling is true? */ |
29 | 30 | ||
30 | del_timer_sync(&local->dynamic_ps_timer); | 31 | del_timer_sync(&local->dynamic_ps_timer); |
32 | del_timer_sync(&ifmgd->bcn_mon_timer); | ||
33 | del_timer_sync(&ifmgd->conn_mon_timer); | ||
34 | |||
31 | cancel_work_sync(&local->dynamic_ps_enable_work); | 35 | cancel_work_sync(&local->dynamic_ps_enable_work); |
32 | 36 | ||
33 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { | 37 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { |
@@ -85,6 +89,9 @@ static void ieee80211_offchannel_ps_disable(struct ieee80211_sub_if_data *sdata) | |||
85 | mod_timer(&local->dynamic_ps_timer, jiffies + | 89 | mod_timer(&local->dynamic_ps_timer, jiffies + |
86 | msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout)); | 90 | msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout)); |
87 | } | 91 | } |
92 | |||
93 | ieee80211_sta_reset_beacon_monitor(sdata); | ||
94 | ieee80211_sta_reset_conn_monitor(sdata); | ||
88 | } | 95 | } |
89 | 96 | ||
90 | void ieee80211_offchannel_stop_beaconing(struct ieee80211_local *local) | 97 | void ieee80211_offchannel_stop_beaconing(struct ieee80211_local *local) |
@@ -112,8 +119,10 @@ void ieee80211_offchannel_stop_beaconing(struct ieee80211_local *local) | |||
112 | * used from user space controlled off-channel operations. | 119 | * used from user space controlled off-channel operations. |
113 | */ | 120 | */ |
114 | if (sdata->vif.type != NL80211_IFTYPE_STATION && | 121 | if (sdata->vif.type != NL80211_IFTYPE_STATION && |
115 | sdata->vif.type != NL80211_IFTYPE_MONITOR) | 122 | sdata->vif.type != NL80211_IFTYPE_MONITOR) { |
123 | set_bit(SDATA_STATE_OFFCHANNEL, &sdata->state); | ||
116 | netif_tx_stop_all_queues(sdata->dev); | 124 | netif_tx_stop_all_queues(sdata->dev); |
125 | } | ||
117 | } | 126 | } |
118 | mutex_unlock(&local->iflist_mtx); | 127 | mutex_unlock(&local->iflist_mtx); |
119 | } | 128 | } |
@@ -131,6 +140,7 @@ void ieee80211_offchannel_stop_station(struct ieee80211_local *local) | |||
131 | continue; | 140 | continue; |
132 | 141 | ||
133 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { | 142 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { |
143 | set_bit(SDATA_STATE_OFFCHANNEL, &sdata->state); | ||
134 | netif_tx_stop_all_queues(sdata->dev); | 144 | netif_tx_stop_all_queues(sdata->dev); |
135 | if (sdata->u.mgd.associated) | 145 | if (sdata->u.mgd.associated) |
136 | ieee80211_offchannel_ps_enable(sdata); | 146 | ieee80211_offchannel_ps_enable(sdata); |
@@ -155,8 +165,20 @@ void ieee80211_offchannel_return(struct ieee80211_local *local, | |||
155 | ieee80211_offchannel_ps_disable(sdata); | 165 | ieee80211_offchannel_ps_disable(sdata); |
156 | } | 166 | } |
157 | 167 | ||
158 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR) | 168 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { |
169 | clear_bit(SDATA_STATE_OFFCHANNEL, &sdata->state); | ||
170 | /* | ||
171 | * This may wake up queues even though the driver | ||
172 | * currently has them stopped. This is not very | ||
173 | * likely, since the driver won't have gotten any | ||
174 | * (or hardly any) new packets while we weren't | ||
175 | * on the right channel, and even if it happens | ||
176 | * it will at most lead to queueing up one more | ||
177 | * packet per queue in mac80211 rather than on | ||
178 | * the interface qdisc. | ||
179 | */ | ||
159 | netif_tx_wake_all_queues(sdata->dev); | 180 | netif_tx_wake_all_queues(sdata->dev); |
181 | } | ||
160 | 182 | ||
161 | /* re-enable beaconing */ | 183 | /* re-enable beaconing */ |
162 | if (enable_beaconing && | 184 | if (enable_beaconing && |
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index d287fde0431..e37355193ed 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c | |||
@@ -45,7 +45,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw) | |||
45 | list_for_each_entry(sta, &local->sta_list, list) { | 45 | list_for_each_entry(sta, &local->sta_list, list) { |
46 | if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) { | 46 | if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) { |
47 | set_sta_flags(sta, WLAN_STA_BLOCK_BA); | 47 | set_sta_flags(sta, WLAN_STA_BLOCK_BA); |
48 | ieee80211_sta_tear_down_BA_sessions(sta); | 48 | ieee80211_sta_tear_down_BA_sessions(sta, true); |
49 | } | 49 | } |
50 | 50 | ||
51 | if (sta->uploaded) { | 51 | if (sta->uploaded) { |
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index 334cbd3d2aa..809cf230d25 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c | |||
@@ -208,7 +208,7 @@ static bool rc_no_data_or_no_ack(struct ieee80211_tx_rate_control *txrc) | |||
208 | 208 | ||
209 | fc = hdr->frame_control; | 209 | fc = hdr->frame_control; |
210 | 210 | ||
211 | return ((info->flags & IEEE80211_TX_CTL_NO_ACK) || !ieee80211_is_data(fc)); | 211 | return (info->flags & IEEE80211_TX_CTL_NO_ACK) || !ieee80211_is_data(fc); |
212 | } | 212 | } |
213 | 213 | ||
214 | static void rc_send_low_broadcast(s8 *idx, u32 basic_rates, u8 max_rate_idx) | 214 | static void rc_send_low_broadcast(s8 *idx, u32 basic_rates, u8 max_rate_idx) |
@@ -369,8 +369,8 @@ int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local, | |||
369 | 369 | ||
370 | ref = rate_control_alloc(name, local); | 370 | ref = rate_control_alloc(name, local); |
371 | if (!ref) { | 371 | if (!ref) { |
372 | printk(KERN_WARNING "%s: Failed to select rate control " | 372 | wiphy_warn(local->hw.wiphy, |
373 | "algorithm\n", wiphy_name(local->hw.wiphy)); | 373 | "Failed to select rate control algorithm\n"); |
374 | return -ENOENT; | 374 | return -ENOENT; |
375 | } | 375 | } |
376 | 376 | ||
@@ -381,9 +381,8 @@ int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local, | |||
381 | sta_info_flush(local, NULL); | 381 | sta_info_flush(local, NULL); |
382 | } | 382 | } |
383 | 383 | ||
384 | printk(KERN_DEBUG "%s: Selected rate control " | 384 | wiphy_debug(local->hw.wiphy, "Selected rate control algorithm '%s'\n", |
385 | "algorithm '%s'\n", wiphy_name(local->hw.wiphy), | 385 | ref->ops->name); |
386 | ref->ops->name); | ||
387 | 386 | ||
388 | return 0; | 387 | return 0; |
389 | } | 388 | } |
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index c5b465904e3..2a18d6602d4 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c | |||
@@ -397,8 +397,9 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband, | |||
397 | !(info->flags & IEEE80211_TX_STAT_AMPDU)) | 397 | !(info->flags & IEEE80211_TX_STAT_AMPDU)) |
398 | return; | 398 | return; |
399 | 399 | ||
400 | if (!info->status.ampdu_len) { | 400 | if (!(info->flags & IEEE80211_TX_STAT_AMPDU)) { |
401 | info->status.ampdu_ack_len = 1; | 401 | info->status.ampdu_ack_len = |
402 | (info->flags & IEEE80211_TX_STAT_ACK ? 1 : 0); | ||
402 | info->status.ampdu_len = 1; | 403 | info->status.ampdu_len = 1; |
403 | } | 404 | } |
404 | 405 | ||
@@ -426,7 +427,7 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband, | |||
426 | group = minstrel_ht_get_group_idx(&ar[i]); | 427 | group = minstrel_ht_get_group_idx(&ar[i]); |
427 | rate = &mi->groups[group].rates[ar[i].idx % 8]; | 428 | rate = &mi->groups[group].rates[ar[i].idx % 8]; |
428 | 429 | ||
429 | if (last && (info->flags & IEEE80211_TX_STAT_ACK)) | 430 | if (last) |
430 | rate->success += info->status.ampdu_ack_len; | 431 | rate->success += info->status.ampdu_ack_len; |
431 | 432 | ||
432 | rate->attempts += ar[i].count * info->status.ampdu_len; | 433 | rate->attempts += ar[i].count * info->status.ampdu_len; |
diff --git a/net/mac80211/rc80211_pid_debugfs.c b/net/mac80211/rc80211_pid_debugfs.c index 7905f79cc2e..4851e9e2dae 100644 --- a/net/mac80211/rc80211_pid_debugfs.c +++ b/net/mac80211/rc80211_pid_debugfs.c | |||
@@ -162,7 +162,7 @@ static ssize_t rate_control_pid_events_read(struct file *file, char __user *buf, | |||
162 | file_info->next_entry = (file_info->next_entry + 1) % | 162 | file_info->next_entry = (file_info->next_entry + 1) % |
163 | RC_PID_EVENT_RING_SIZE; | 163 | RC_PID_EVENT_RING_SIZE; |
164 | 164 | ||
165 | /* Print information about the event. Note that userpace needs to | 165 | /* Print information about the event. Note that userspace needs to |
166 | * provide large enough buffers. */ | 166 | * provide large enough buffers. */ |
167 | length = length < RC_PID_PRINT_BUF_SIZE ? | 167 | length = length < RC_PID_PRINT_BUF_SIZE ? |
168 | length : RC_PID_PRINT_BUF_SIZE; | 168 | length : RC_PID_PRINT_BUF_SIZE; |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 28624282c5f..902b03ee8f6 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -315,6 +315,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, | |||
315 | static void ieee80211_parse_qos(struct ieee80211_rx_data *rx) | 315 | static void ieee80211_parse_qos(struct ieee80211_rx_data *rx) |
316 | { | 316 | { |
317 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; | 317 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; |
318 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | ||
318 | int tid; | 319 | int tid; |
319 | 320 | ||
320 | /* does the frame have a qos control field? */ | 321 | /* does the frame have a qos control field? */ |
@@ -323,9 +324,7 @@ static void ieee80211_parse_qos(struct ieee80211_rx_data *rx) | |||
323 | /* frame has qos control */ | 324 | /* frame has qos control */ |
324 | tid = *qc & IEEE80211_QOS_CTL_TID_MASK; | 325 | tid = *qc & IEEE80211_QOS_CTL_TID_MASK; |
325 | if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT) | 326 | if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT) |
326 | rx->flags |= IEEE80211_RX_AMSDU; | 327 | status->rx_flags |= IEEE80211_RX_AMSDU; |
327 | else | ||
328 | rx->flags &= ~IEEE80211_RX_AMSDU; | ||
329 | } else { | 328 | } else { |
330 | /* | 329 | /* |
331 | * IEEE 802.11-2007, 7.1.3.4.1 ("Sequence Number field"): | 330 | * IEEE 802.11-2007, 7.1.3.4.1 ("Sequence Number field"): |
@@ -387,26 +386,25 @@ static ieee80211_rx_result debug_noinline | |||
387 | ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx) | 386 | ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx) |
388 | { | 387 | { |
389 | struct ieee80211_local *local = rx->local; | 388 | struct ieee80211_local *local = rx->local; |
389 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | ||
390 | struct sk_buff *skb = rx->skb; | 390 | struct sk_buff *skb = rx->skb; |
391 | 391 | ||
392 | if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning))) | 392 | if (likely(!(status->rx_flags & IEEE80211_RX_IN_SCAN))) |
393 | return RX_CONTINUE; | ||
394 | |||
395 | if (test_bit(SCAN_HW_SCANNING, &local->scanning)) | ||
393 | return ieee80211_scan_rx(rx->sdata, skb); | 396 | return ieee80211_scan_rx(rx->sdata, skb); |
394 | 397 | ||
395 | if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning) && | 398 | if (test_bit(SCAN_SW_SCANNING, &local->scanning)) { |
396 | (rx->flags & IEEE80211_RX_IN_SCAN))) { | ||
397 | /* drop all the other packets during a software scan anyway */ | 399 | /* drop all the other packets during a software scan anyway */ |
398 | if (ieee80211_scan_rx(rx->sdata, skb) != RX_QUEUED) | 400 | if (ieee80211_scan_rx(rx->sdata, skb) != RX_QUEUED) |
399 | dev_kfree_skb(skb); | 401 | dev_kfree_skb(skb); |
400 | return RX_QUEUED; | 402 | return RX_QUEUED; |
401 | } | 403 | } |
402 | 404 | ||
403 | if (unlikely(rx->flags & IEEE80211_RX_IN_SCAN)) { | 405 | /* scanning finished during invoking of handlers */ |
404 | /* scanning finished during invoking of handlers */ | 406 | I802_DEBUG_INC(local->rx_handlers_drop_passive_scan); |
405 | I802_DEBUG_INC(local->rx_handlers_drop_passive_scan); | 407 | return RX_DROP_UNUSABLE; |
406 | return RX_DROP_UNUSABLE; | ||
407 | } | ||
408 | |||
409 | return RX_CONTINUE; | ||
410 | } | 408 | } |
411 | 409 | ||
412 | 410 | ||
@@ -538,20 +536,12 @@ static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw, | |||
538 | int index, | 536 | int index, |
539 | struct sk_buff_head *frames) | 537 | struct sk_buff_head *frames) |
540 | { | 538 | { |
541 | struct ieee80211_supported_band *sband; | ||
542 | struct ieee80211_rate *rate = NULL; | ||
543 | struct sk_buff *skb = tid_agg_rx->reorder_buf[index]; | 539 | struct sk_buff *skb = tid_agg_rx->reorder_buf[index]; |
544 | struct ieee80211_rx_status *status; | ||
545 | 540 | ||
546 | if (!skb) | 541 | if (!skb) |
547 | goto no_frame; | 542 | goto no_frame; |
548 | 543 | ||
549 | status = IEEE80211_SKB_RXCB(skb); | 544 | /* release the frame from the reorder ring buffer */ |
550 | |||
551 | /* release the reordered frames to stack */ | ||
552 | sband = hw->wiphy->bands[status->band]; | ||
553 | if (!(status->flag & RX_FLAG_HT)) | ||
554 | rate = &sband->bitrates[status->rate_idx]; | ||
555 | tid_agg_rx->stored_mpdu_num--; | 545 | tid_agg_rx->stored_mpdu_num--; |
556 | tid_agg_rx->reorder_buf[index] = NULL; | 546 | tid_agg_rx->reorder_buf[index] = NULL; |
557 | __skb_queue_tail(frames, skb); | 547 | __skb_queue_tail(frames, skb); |
@@ -580,9 +570,102 @@ static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw, | |||
580 | * frames that have not yet been received are assumed to be lost and the skb | 570 | * frames that have not yet been received are assumed to be lost and the skb |
581 | * can be released for processing. This may also release other skb's from the | 571 | * can be released for processing. This may also release other skb's from the |
582 | * reorder buffer if there are no additional gaps between the frames. | 572 | * reorder buffer if there are no additional gaps between the frames. |
573 | * | ||
574 | * Callers must hold tid_agg_rx->reorder_lock. | ||
583 | */ | 575 | */ |
584 | #define HT_RX_REORDER_BUF_TIMEOUT (HZ / 10) | 576 | #define HT_RX_REORDER_BUF_TIMEOUT (HZ / 10) |
585 | 577 | ||
578 | static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, | ||
579 | struct tid_ampdu_rx *tid_agg_rx, | ||
580 | struct sk_buff_head *frames) | ||
581 | { | ||
582 | int index, j; | ||
583 | |||
584 | /* release the buffer until next missing frame */ | ||
585 | index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % | ||
586 | tid_agg_rx->buf_size; | ||
587 | if (!tid_agg_rx->reorder_buf[index] && | ||
588 | tid_agg_rx->stored_mpdu_num > 1) { | ||
589 | /* | ||
590 | * No buffers ready to be released, but check whether any | ||
591 | * frames in the reorder buffer have timed out. | ||
592 | */ | ||
593 | int skipped = 1; | ||
594 | for (j = (index + 1) % tid_agg_rx->buf_size; j != index; | ||
595 | j = (j + 1) % tid_agg_rx->buf_size) { | ||
596 | if (!tid_agg_rx->reorder_buf[j]) { | ||
597 | skipped++; | ||
598 | continue; | ||
599 | } | ||
600 | if (!time_after(jiffies, tid_agg_rx->reorder_time[j] + | ||
601 | HT_RX_REORDER_BUF_TIMEOUT)) | ||
602 | goto set_release_timer; | ||
603 | |||
604 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
605 | if (net_ratelimit()) | ||
606 | wiphy_debug(hw->wiphy, | ||
607 | "release an RX reorder frame due to timeout on earlier frames\n"); | ||
608 | #endif | ||
609 | ieee80211_release_reorder_frame(hw, tid_agg_rx, | ||
610 | j, frames); | ||
611 | |||
612 | /* | ||
613 | * Increment the head seq# also for the skipped slots. | ||
614 | */ | ||
615 | tid_agg_rx->head_seq_num = | ||
616 | (tid_agg_rx->head_seq_num + skipped) & SEQ_MASK; | ||
617 | skipped = 0; | ||
618 | } | ||
619 | } else while (tid_agg_rx->reorder_buf[index]) { | ||
620 | ieee80211_release_reorder_frame(hw, tid_agg_rx, index, frames); | ||
621 | index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % | ||
622 | tid_agg_rx->buf_size; | ||
623 | } | ||
624 | |||
625 | /* | ||
626 | * Disable the reorder release timer for now. | ||
627 | * | ||
628 | * The current implementation lacks a proper locking scheme | ||
629 | * which would protect vital statistic and debug counters | ||
630 | * from being updated by two different but concurrent BHs. | ||
631 | * | ||
632 | * More information about the topic is available from: | ||
633 | * - thread: http://marc.info/?t=128635927000001 | ||
634 | * | ||
635 | * What was wrong: | ||
636 | * => http://marc.info/?l=linux-wireless&m=128636170811964 | ||
637 | * "Basically the thing is that until your patch, the data | ||
638 | * in the struct didn't actually need locking because it | ||
639 | * was accessed by the RX path only which is not concurrent." | ||
640 | * | ||
641 | * List of what needs to be fixed: | ||
642 | * => http://marc.info/?l=linux-wireless&m=128656352920957 | ||
643 | * | ||
644 | |||
645 | if (tid_agg_rx->stored_mpdu_num) { | ||
646 | j = index = seq_sub(tid_agg_rx->head_seq_num, | ||
647 | tid_agg_rx->ssn) % tid_agg_rx->buf_size; | ||
648 | |||
649 | for (; j != (index - 1) % tid_agg_rx->buf_size; | ||
650 | j = (j + 1) % tid_agg_rx->buf_size) { | ||
651 | if (tid_agg_rx->reorder_buf[j]) | ||
652 | break; | ||
653 | } | ||
654 | |||
655 | set_release_timer: | ||
656 | |||
657 | mod_timer(&tid_agg_rx->reorder_timer, | ||
658 | tid_agg_rx->reorder_time[j] + | ||
659 | HT_RX_REORDER_BUF_TIMEOUT); | ||
660 | } else { | ||
661 | del_timer(&tid_agg_rx->reorder_timer); | ||
662 | } | ||
663 | */ | ||
664 | |||
665 | set_release_timer: | ||
666 | return; | ||
667 | } | ||
668 | |||
586 | /* | 669 | /* |
587 | * As this function belongs to the RX path it must be under | 670 | * As this function belongs to the RX path it must be under |
588 | * rcu_read_lock protection. It returns false if the frame | 671 | * rcu_read_lock protection. It returns false if the frame |
@@ -598,14 +681,16 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
598 | u16 mpdu_seq_num = (sc & IEEE80211_SCTL_SEQ) >> 4; | 681 | u16 mpdu_seq_num = (sc & IEEE80211_SCTL_SEQ) >> 4; |
599 | u16 head_seq_num, buf_size; | 682 | u16 head_seq_num, buf_size; |
600 | int index; | 683 | int index; |
684 | bool ret = true; | ||
601 | 685 | ||
602 | buf_size = tid_agg_rx->buf_size; | 686 | buf_size = tid_agg_rx->buf_size; |
603 | head_seq_num = tid_agg_rx->head_seq_num; | 687 | head_seq_num = tid_agg_rx->head_seq_num; |
604 | 688 | ||
689 | spin_lock(&tid_agg_rx->reorder_lock); | ||
605 | /* frame with out of date sequence number */ | 690 | /* frame with out of date sequence number */ |
606 | if (seq_less(mpdu_seq_num, head_seq_num)) { | 691 | if (seq_less(mpdu_seq_num, head_seq_num)) { |
607 | dev_kfree_skb(skb); | 692 | dev_kfree_skb(skb); |
608 | return true; | 693 | goto out; |
609 | } | 694 | } |
610 | 695 | ||
611 | /* | 696 | /* |
@@ -626,7 +711,7 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
626 | /* check if we already stored this frame */ | 711 | /* check if we already stored this frame */ |
627 | if (tid_agg_rx->reorder_buf[index]) { | 712 | if (tid_agg_rx->reorder_buf[index]) { |
628 | dev_kfree_skb(skb); | 713 | dev_kfree_skb(skb); |
629 | return true; | 714 | goto out; |
630 | } | 715 | } |
631 | 716 | ||
632 | /* | 717 | /* |
@@ -636,58 +721,19 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
636 | if (mpdu_seq_num == tid_agg_rx->head_seq_num && | 721 | if (mpdu_seq_num == tid_agg_rx->head_seq_num && |
637 | tid_agg_rx->stored_mpdu_num == 0) { | 722 | tid_agg_rx->stored_mpdu_num == 0) { |
638 | tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); | 723 | tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); |
639 | return false; | 724 | ret = false; |
725 | goto out; | ||
640 | } | 726 | } |
641 | 727 | ||
642 | /* put the frame in the reordering buffer */ | 728 | /* put the frame in the reordering buffer */ |
643 | tid_agg_rx->reorder_buf[index] = skb; | 729 | tid_agg_rx->reorder_buf[index] = skb; |
644 | tid_agg_rx->reorder_time[index] = jiffies; | 730 | tid_agg_rx->reorder_time[index] = jiffies; |
645 | tid_agg_rx->stored_mpdu_num++; | 731 | tid_agg_rx->stored_mpdu_num++; |
646 | /* release the buffer until next missing frame */ | 732 | ieee80211_sta_reorder_release(hw, tid_agg_rx, frames); |
647 | index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % | ||
648 | tid_agg_rx->buf_size; | ||
649 | if (!tid_agg_rx->reorder_buf[index] && | ||
650 | tid_agg_rx->stored_mpdu_num > 1) { | ||
651 | /* | ||
652 | * No buffers ready to be released, but check whether any | ||
653 | * frames in the reorder buffer have timed out. | ||
654 | */ | ||
655 | int j; | ||
656 | int skipped = 1; | ||
657 | for (j = (index + 1) % tid_agg_rx->buf_size; j != index; | ||
658 | j = (j + 1) % tid_agg_rx->buf_size) { | ||
659 | if (!tid_agg_rx->reorder_buf[j]) { | ||
660 | skipped++; | ||
661 | continue; | ||
662 | } | ||
663 | if (!time_after(jiffies, tid_agg_rx->reorder_time[j] + | ||
664 | HT_RX_REORDER_BUF_TIMEOUT)) | ||
665 | break; | ||
666 | 733 | ||
667 | #ifdef CONFIG_MAC80211_HT_DEBUG | 734 | out: |
668 | if (net_ratelimit()) | 735 | spin_unlock(&tid_agg_rx->reorder_lock); |
669 | printk(KERN_DEBUG "%s: release an RX reorder " | 736 | return ret; |
670 | "frame due to timeout on earlier " | ||
671 | "frames\n", | ||
672 | wiphy_name(hw->wiphy)); | ||
673 | #endif | ||
674 | ieee80211_release_reorder_frame(hw, tid_agg_rx, | ||
675 | j, frames); | ||
676 | |||
677 | /* | ||
678 | * Increment the head seq# also for the skipped slots. | ||
679 | */ | ||
680 | tid_agg_rx->head_seq_num = | ||
681 | (tid_agg_rx->head_seq_num + skipped) & SEQ_MASK; | ||
682 | skipped = 0; | ||
683 | } | ||
684 | } else while (tid_agg_rx->reorder_buf[index]) { | ||
685 | ieee80211_release_reorder_frame(hw, tid_agg_rx, index, frames); | ||
686 | index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % | ||
687 | tid_agg_rx->buf_size; | ||
688 | } | ||
689 | |||
690 | return true; | ||
691 | } | 737 | } |
692 | 738 | ||
693 | /* | 739 | /* |
@@ -761,13 +807,14 @@ static ieee80211_rx_result debug_noinline | |||
761 | ieee80211_rx_h_check(struct ieee80211_rx_data *rx) | 807 | ieee80211_rx_h_check(struct ieee80211_rx_data *rx) |
762 | { | 808 | { |
763 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; | 809 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; |
810 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | ||
764 | 811 | ||
765 | /* Drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.2.9) */ | 812 | /* Drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.2.9) */ |
766 | if (rx->sta && !is_multicast_ether_addr(hdr->addr1)) { | 813 | if (rx->sta && !is_multicast_ether_addr(hdr->addr1)) { |
767 | if (unlikely(ieee80211_has_retry(hdr->frame_control) && | 814 | if (unlikely(ieee80211_has_retry(hdr->frame_control) && |
768 | rx->sta->last_seq_ctrl[rx->queue] == | 815 | rx->sta->last_seq_ctrl[rx->queue] == |
769 | hdr->seq_ctrl)) { | 816 | hdr->seq_ctrl)) { |
770 | if (rx->flags & IEEE80211_RX_RA_MATCH) { | 817 | if (status->rx_flags & IEEE80211_RX_RA_MATCH) { |
771 | rx->local->dot11FrameDuplicateCount++; | 818 | rx->local->dot11FrameDuplicateCount++; |
772 | rx->sta->num_duplicates++; | 819 | rx->sta->num_duplicates++; |
773 | } | 820 | } |
@@ -796,11 +843,12 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) | |||
796 | if (unlikely((ieee80211_is_data(hdr->frame_control) || | 843 | if (unlikely((ieee80211_is_data(hdr->frame_control) || |
797 | ieee80211_is_pspoll(hdr->frame_control)) && | 844 | ieee80211_is_pspoll(hdr->frame_control)) && |
798 | rx->sdata->vif.type != NL80211_IFTYPE_ADHOC && | 845 | rx->sdata->vif.type != NL80211_IFTYPE_ADHOC && |
846 | rx->sdata->vif.type != NL80211_IFTYPE_WDS && | ||
799 | (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) { | 847 | (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) { |
800 | if ((!ieee80211_has_fromds(hdr->frame_control) && | 848 | if ((!ieee80211_has_fromds(hdr->frame_control) && |
801 | !ieee80211_has_tods(hdr->frame_control) && | 849 | !ieee80211_has_tods(hdr->frame_control) && |
802 | ieee80211_is_data(hdr->frame_control)) || | 850 | ieee80211_is_data(hdr->frame_control)) || |
803 | !(rx->flags & IEEE80211_RX_RA_MATCH)) { | 851 | !(status->rx_flags & IEEE80211_RX_RA_MATCH)) { |
804 | /* Drop IBSS frames and frames for other hosts | 852 | /* Drop IBSS frames and frames for other hosts |
805 | * silently. */ | 853 | * silently. */ |
806 | return RX_DROP_MONITOR; | 854 | return RX_DROP_MONITOR; |
@@ -822,7 +870,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
822 | int keyidx; | 870 | int keyidx; |
823 | int hdrlen; | 871 | int hdrlen; |
824 | ieee80211_rx_result result = RX_DROP_UNUSABLE; | 872 | ieee80211_rx_result result = RX_DROP_UNUSABLE; |
825 | struct ieee80211_key *stakey = NULL; | 873 | struct ieee80211_key *sta_ptk = NULL; |
826 | int mmie_keyidx = -1; | 874 | int mmie_keyidx = -1; |
827 | __le16 fc; | 875 | __le16 fc; |
828 | 876 | ||
@@ -857,22 +905,25 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
857 | * No point in finding a key and decrypting if the frame is neither | 905 | * No point in finding a key and decrypting if the frame is neither |
858 | * addressed to us nor a multicast frame. | 906 | * addressed to us nor a multicast frame. |
859 | */ | 907 | */ |
860 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) | 908 | if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) |
861 | return RX_CONTINUE; | 909 | return RX_CONTINUE; |
862 | 910 | ||
863 | /* start without a key */ | 911 | /* start without a key */ |
864 | rx->key = NULL; | 912 | rx->key = NULL; |
865 | 913 | ||
866 | if (rx->sta) | 914 | if (rx->sta) |
867 | stakey = rcu_dereference(rx->sta->key); | 915 | sta_ptk = rcu_dereference(rx->sta->ptk); |
868 | 916 | ||
869 | fc = hdr->frame_control; | 917 | fc = hdr->frame_control; |
870 | 918 | ||
871 | if (!ieee80211_has_protected(fc)) | 919 | if (!ieee80211_has_protected(fc)) |
872 | mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb); | 920 | mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb); |
873 | 921 | ||
874 | if (!is_multicast_ether_addr(hdr->addr1) && stakey) { | 922 | if (!is_multicast_ether_addr(hdr->addr1) && sta_ptk) { |
875 | rx->key = stakey; | 923 | rx->key = sta_ptk; |
924 | if ((status->flag & RX_FLAG_DECRYPTED) && | ||
925 | (status->flag & RX_FLAG_IV_STRIPPED)) | ||
926 | return RX_CONTINUE; | ||
876 | /* Skip decryption if the frame is not protected. */ | 927 | /* Skip decryption if the frame is not protected. */ |
877 | if (!ieee80211_has_protected(fc)) | 928 | if (!ieee80211_has_protected(fc)) |
878 | return RX_CONTINUE; | 929 | return RX_CONTINUE; |
@@ -885,7 +936,10 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
885 | if (mmie_keyidx < NUM_DEFAULT_KEYS || | 936 | if (mmie_keyidx < NUM_DEFAULT_KEYS || |
886 | mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) | 937 | mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) |
887 | return RX_DROP_MONITOR; /* unexpected BIP keyidx */ | 938 | return RX_DROP_MONITOR; /* unexpected BIP keyidx */ |
888 | rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]); | 939 | if (rx->sta) |
940 | rx->key = rcu_dereference(rx->sta->gtk[mmie_keyidx]); | ||
941 | if (!rx->key) | ||
942 | rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]); | ||
889 | } else if (!ieee80211_has_protected(fc)) { | 943 | } else if (!ieee80211_has_protected(fc)) { |
890 | /* | 944 | /* |
891 | * The frame was not protected, so skip decryption. However, we | 945 | * The frame was not protected, so skip decryption. However, we |
@@ -928,16 +982,25 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
928 | skb_copy_bits(rx->skb, hdrlen + 3, &keyid, 1); | 982 | skb_copy_bits(rx->skb, hdrlen + 3, &keyid, 1); |
929 | keyidx = keyid >> 6; | 983 | keyidx = keyid >> 6; |
930 | 984 | ||
931 | rx->key = rcu_dereference(rx->sdata->keys[keyidx]); | 985 | /* check per-station GTK first, if multicast packet */ |
986 | if (is_multicast_ether_addr(hdr->addr1) && rx->sta) | ||
987 | rx->key = rcu_dereference(rx->sta->gtk[keyidx]); | ||
932 | 988 | ||
933 | /* | 989 | /* if not found, try default key */ |
934 | * RSNA-protected unicast frames should always be sent with | 990 | if (!rx->key) { |
935 | * pairwise or station-to-station keys, but for WEP we allow | 991 | rx->key = rcu_dereference(rx->sdata->keys[keyidx]); |
936 | * using a key index as well. | 992 | |
937 | */ | 993 | /* |
938 | if (rx->key && rx->key->conf.alg != ALG_WEP && | 994 | * RSNA-protected unicast frames should always be |
939 | !is_multicast_ether_addr(hdr->addr1)) | 995 | * sent with pairwise or station-to-station keys, |
940 | rx->key = NULL; | 996 | * but for WEP we allow using a key index as well. |
997 | */ | ||
998 | if (rx->key && | ||
999 | rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP40 && | ||
1000 | rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP104 && | ||
1001 | !is_multicast_ether_addr(hdr->addr1)) | ||
1002 | rx->key = NULL; | ||
1003 | } | ||
941 | } | 1004 | } |
942 | 1005 | ||
943 | if (rx->key) { | 1006 | if (rx->key) { |
@@ -951,8 +1014,9 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
951 | return RX_DROP_UNUSABLE; | 1014 | return RX_DROP_UNUSABLE; |
952 | /* the hdr variable is invalid now! */ | 1015 | /* the hdr variable is invalid now! */ |
953 | 1016 | ||
954 | switch (rx->key->conf.alg) { | 1017 | switch (rx->key->conf.cipher) { |
955 | case ALG_WEP: | 1018 | case WLAN_CIPHER_SUITE_WEP40: |
1019 | case WLAN_CIPHER_SUITE_WEP104: | ||
956 | /* Check for weak IVs if possible */ | 1020 | /* Check for weak IVs if possible */ |
957 | if (rx->sta && ieee80211_is_data(fc) && | 1021 | if (rx->sta && ieee80211_is_data(fc) && |
958 | (!(status->flag & RX_FLAG_IV_STRIPPED) || | 1022 | (!(status->flag & RX_FLAG_IV_STRIPPED) || |
@@ -962,15 +1026,21 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
962 | 1026 | ||
963 | result = ieee80211_crypto_wep_decrypt(rx); | 1027 | result = ieee80211_crypto_wep_decrypt(rx); |
964 | break; | 1028 | break; |
965 | case ALG_TKIP: | 1029 | case WLAN_CIPHER_SUITE_TKIP: |
966 | result = ieee80211_crypto_tkip_decrypt(rx); | 1030 | result = ieee80211_crypto_tkip_decrypt(rx); |
967 | break; | 1031 | break; |
968 | case ALG_CCMP: | 1032 | case WLAN_CIPHER_SUITE_CCMP: |
969 | result = ieee80211_crypto_ccmp_decrypt(rx); | 1033 | result = ieee80211_crypto_ccmp_decrypt(rx); |
970 | break; | 1034 | break; |
971 | case ALG_AES_CMAC: | 1035 | case WLAN_CIPHER_SUITE_AES_CMAC: |
972 | result = ieee80211_crypto_aes_cmac_decrypt(rx); | 1036 | result = ieee80211_crypto_aes_cmac_decrypt(rx); |
973 | break; | 1037 | break; |
1038 | default: | ||
1039 | /* | ||
1040 | * We can reach here only with HW-only algorithms | ||
1041 | * but why didn't it decrypt the frame?! | ||
1042 | */ | ||
1043 | return RX_DROP_UNUSABLE; | ||
974 | } | 1044 | } |
975 | 1045 | ||
976 | /* either the frame has been decrypted or will be dropped */ | 1046 | /* either the frame has been decrypted or will be dropped */ |
@@ -1079,7 +1149,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | |||
1079 | sta->last_rx = jiffies; | 1149 | sta->last_rx = jiffies; |
1080 | } | 1150 | } |
1081 | 1151 | ||
1082 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) | 1152 | if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) |
1083 | return RX_CONTINUE; | 1153 | return RX_CONTINUE; |
1084 | 1154 | ||
1085 | if (rx->sdata->vif.type == NL80211_IFTYPE_STATION) | 1155 | if (rx->sdata->vif.type == NL80211_IFTYPE_STATION) |
@@ -1236,6 +1306,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | |||
1236 | unsigned int frag, seq; | 1306 | unsigned int frag, seq; |
1237 | struct ieee80211_fragment_entry *entry; | 1307 | struct ieee80211_fragment_entry *entry; |
1238 | struct sk_buff *skb; | 1308 | struct sk_buff *skb; |
1309 | struct ieee80211_rx_status *status; | ||
1239 | 1310 | ||
1240 | hdr = (struct ieee80211_hdr *)rx->skb->data; | 1311 | hdr = (struct ieee80211_hdr *)rx->skb->data; |
1241 | fc = hdr->frame_control; | 1312 | fc = hdr->frame_control; |
@@ -1265,7 +1336,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | |||
1265 | /* This is the first fragment of a new frame. */ | 1336 | /* This is the first fragment of a new frame. */ |
1266 | entry = ieee80211_reassemble_add(rx->sdata, frag, seq, | 1337 | entry = ieee80211_reassemble_add(rx->sdata, frag, seq, |
1267 | rx->queue, &(rx->skb)); | 1338 | rx->queue, &(rx->skb)); |
1268 | if (rx->key && rx->key->conf.alg == ALG_CCMP && | 1339 | if (rx->key && rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP && |
1269 | ieee80211_has_protected(fc)) { | 1340 | ieee80211_has_protected(fc)) { |
1270 | int queue = ieee80211_is_mgmt(fc) ? | 1341 | int queue = ieee80211_is_mgmt(fc) ? |
1271 | NUM_RX_DATA_QUEUES : rx->queue; | 1342 | NUM_RX_DATA_QUEUES : rx->queue; |
@@ -1294,7 +1365,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | |||
1294 | int i; | 1365 | int i; |
1295 | u8 pn[CCMP_PN_LEN], *rpn; | 1366 | u8 pn[CCMP_PN_LEN], *rpn; |
1296 | int queue; | 1367 | int queue; |
1297 | if (!rx->key || rx->key->conf.alg != ALG_CCMP) | 1368 | if (!rx->key || rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP) |
1298 | return RX_DROP_UNUSABLE; | 1369 | return RX_DROP_UNUSABLE; |
1299 | memcpy(pn, entry->last_pn, CCMP_PN_LEN); | 1370 | memcpy(pn, entry->last_pn, CCMP_PN_LEN); |
1300 | for (i = CCMP_PN_LEN - 1; i >= 0; i--) { | 1371 | for (i = CCMP_PN_LEN - 1; i >= 0; i--) { |
@@ -1335,7 +1406,8 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | |||
1335 | } | 1406 | } |
1336 | 1407 | ||
1337 | /* Complete frame has been reassembled - process it now */ | 1408 | /* Complete frame has been reassembled - process it now */ |
1338 | rx->flags |= IEEE80211_RX_FRAGMENTED; | 1409 | status = IEEE80211_SKB_RXCB(rx->skb); |
1410 | status->rx_flags |= IEEE80211_RX_FRAGMENTED; | ||
1339 | 1411 | ||
1340 | out: | 1412 | out: |
1341 | if (rx->sta) | 1413 | if (rx->sta) |
@@ -1352,9 +1424,10 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) | |||
1352 | { | 1424 | { |
1353 | struct ieee80211_sub_if_data *sdata = rx->sdata; | 1425 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
1354 | __le16 fc = ((struct ieee80211_hdr *)rx->skb->data)->frame_control; | 1426 | __le16 fc = ((struct ieee80211_hdr *)rx->skb->data)->frame_control; |
1427 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | ||
1355 | 1428 | ||
1356 | if (likely(!rx->sta || !ieee80211_is_pspoll(fc) || | 1429 | if (likely(!rx->sta || !ieee80211_is_pspoll(fc) || |
1357 | !(rx->flags & IEEE80211_RX_RA_MATCH))) | 1430 | !(status->rx_flags & IEEE80211_RX_RA_MATCH))) |
1358 | return RX_CONTINUE; | 1431 | return RX_CONTINUE; |
1359 | 1432 | ||
1360 | if ((sdata->vif.type != NL80211_IFTYPE_AP) && | 1433 | if ((sdata->vif.type != NL80211_IFTYPE_AP) && |
@@ -1492,7 +1565,7 @@ static bool ieee80211_frame_allowed(struct ieee80211_rx_data *rx, __le16 fc) | |||
1492 | * Allow EAPOL frames to us/the PAE group address regardless | 1565 | * Allow EAPOL frames to us/the PAE group address regardless |
1493 | * of whether the frame was encrypted or not. | 1566 | * of whether the frame was encrypted or not. |
1494 | */ | 1567 | */ |
1495 | if (ehdr->h_proto == htons(ETH_P_PAE) && | 1568 | if (ehdr->h_proto == rx->sdata->control_port_protocol && |
1496 | (compare_ether_addr(ehdr->h_dest, rx->sdata->vif.addr) == 0 || | 1569 | (compare_ether_addr(ehdr->h_dest, rx->sdata->vif.addr) == 0 || |
1497 | compare_ether_addr(ehdr->h_dest, pae_group_addr) == 0)) | 1570 | compare_ether_addr(ehdr->h_dest, pae_group_addr) == 0)) |
1498 | return true; | 1571 | return true; |
@@ -1515,6 +1588,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) | |||
1515 | struct sk_buff *skb, *xmit_skb; | 1588 | struct sk_buff *skb, *xmit_skb; |
1516 | struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data; | 1589 | struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data; |
1517 | struct sta_info *dsta; | 1590 | struct sta_info *dsta; |
1591 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | ||
1518 | 1592 | ||
1519 | skb = rx->skb; | 1593 | skb = rx->skb; |
1520 | xmit_skb = NULL; | 1594 | xmit_skb = NULL; |
@@ -1522,7 +1596,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) | |||
1522 | if ((sdata->vif.type == NL80211_IFTYPE_AP || | 1596 | if ((sdata->vif.type == NL80211_IFTYPE_AP || |
1523 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) && | 1597 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) && |
1524 | !(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) && | 1598 | !(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) && |
1525 | (rx->flags & IEEE80211_RX_RA_MATCH) && | 1599 | (status->rx_flags & IEEE80211_RX_RA_MATCH) && |
1526 | (sdata->vif.type != NL80211_IFTYPE_AP_VLAN || !sdata->u.vlan.sta)) { | 1600 | (sdata->vif.type != NL80211_IFTYPE_AP_VLAN || !sdata->u.vlan.sta)) { |
1527 | if (is_multicast_ether_addr(ehdr->h_dest)) { | 1601 | if (is_multicast_ether_addr(ehdr->h_dest)) { |
1528 | /* | 1602 | /* |
@@ -1599,6 +1673,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) | |||
1599 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 1673 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
1600 | __le16 fc = hdr->frame_control; | 1674 | __le16 fc = hdr->frame_control; |
1601 | struct sk_buff_head frame_list; | 1675 | struct sk_buff_head frame_list; |
1676 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | ||
1602 | 1677 | ||
1603 | if (unlikely(!ieee80211_is_data(fc))) | 1678 | if (unlikely(!ieee80211_is_data(fc))) |
1604 | return RX_CONTINUE; | 1679 | return RX_CONTINUE; |
@@ -1606,7 +1681,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) | |||
1606 | if (unlikely(!ieee80211_is_data_present(fc))) | 1681 | if (unlikely(!ieee80211_is_data_present(fc))) |
1607 | return RX_DROP_MONITOR; | 1682 | return RX_DROP_MONITOR; |
1608 | 1683 | ||
1609 | if (!(rx->flags & IEEE80211_RX_AMSDU)) | 1684 | if (!(status->rx_flags & IEEE80211_RX_AMSDU)) |
1610 | return RX_CONTINUE; | 1685 | return RX_CONTINUE; |
1611 | 1686 | ||
1612 | if (ieee80211_has_a4(hdr->frame_control) && | 1687 | if (ieee80211_has_a4(hdr->frame_control) && |
@@ -1657,6 +1732,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1657 | struct sk_buff *skb = rx->skb, *fwd_skb; | 1732 | struct sk_buff *skb = rx->skb, *fwd_skb; |
1658 | struct ieee80211_local *local = rx->local; | 1733 | struct ieee80211_local *local = rx->local; |
1659 | struct ieee80211_sub_if_data *sdata = rx->sdata; | 1734 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
1735 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
1660 | 1736 | ||
1661 | hdr = (struct ieee80211_hdr *) skb->data; | 1737 | hdr = (struct ieee80211_hdr *) skb->data; |
1662 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 1738 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
@@ -1702,7 +1778,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1702 | 1778 | ||
1703 | mesh_hdr->ttl--; | 1779 | mesh_hdr->ttl--; |
1704 | 1780 | ||
1705 | if (rx->flags & IEEE80211_RX_RA_MATCH) { | 1781 | if (status->rx_flags & IEEE80211_RX_RA_MATCH) { |
1706 | if (!mesh_hdr->ttl) | 1782 | if (!mesh_hdr->ttl) |
1707 | IEEE80211_IFSTA_MESH_CTR_INC(&rx->sdata->u.mesh, | 1783 | IEEE80211_IFSTA_MESH_CTR_INC(&rx->sdata->u.mesh, |
1708 | dropped_frames_ttl); | 1784 | dropped_frames_ttl); |
@@ -1909,13 +1985,38 @@ static void ieee80211_process_sa_query_req(struct ieee80211_sub_if_data *sdata, | |||
1909 | } | 1985 | } |
1910 | 1986 | ||
1911 | static ieee80211_rx_result debug_noinline | 1987 | static ieee80211_rx_result debug_noinline |
1988 | ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx) | ||
1989 | { | ||
1990 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; | ||
1991 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | ||
1992 | |||
1993 | /* | ||
1994 | * From here on, look only at management frames. | ||
1995 | * Data and control frames are already handled, | ||
1996 | * and unknown (reserved) frames are useless. | ||
1997 | */ | ||
1998 | if (rx->skb->len < 24) | ||
1999 | return RX_DROP_MONITOR; | ||
2000 | |||
2001 | if (!ieee80211_is_mgmt(mgmt->frame_control)) | ||
2002 | return RX_DROP_MONITOR; | ||
2003 | |||
2004 | if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) | ||
2005 | return RX_DROP_MONITOR; | ||
2006 | |||
2007 | if (ieee80211_drop_unencrypted_mgmt(rx)) | ||
2008 | return RX_DROP_UNUSABLE; | ||
2009 | |||
2010 | return RX_CONTINUE; | ||
2011 | } | ||
2012 | |||
2013 | static ieee80211_rx_result debug_noinline | ||
1912 | ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | 2014 | ieee80211_rx_h_action(struct ieee80211_rx_data *rx) |
1913 | { | 2015 | { |
1914 | struct ieee80211_local *local = rx->local; | 2016 | struct ieee80211_local *local = rx->local; |
1915 | struct ieee80211_sub_if_data *sdata = rx->sdata; | 2017 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
1916 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; | 2018 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; |
1917 | struct sk_buff *nskb; | 2019 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); |
1918 | struct ieee80211_rx_status *status; | ||
1919 | int len = rx->skb->len; | 2020 | int len = rx->skb->len; |
1920 | 2021 | ||
1921 | if (!ieee80211_is_action(mgmt->frame_control)) | 2022 | if (!ieee80211_is_action(mgmt->frame_control)) |
@@ -1928,10 +2029,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
1928 | if (!rx->sta && mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) | 2029 | if (!rx->sta && mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) |
1929 | return RX_DROP_UNUSABLE; | 2030 | return RX_DROP_UNUSABLE; |
1930 | 2031 | ||
1931 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) | 2032 | if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) |
1932 | return RX_DROP_UNUSABLE; | ||
1933 | |||
1934 | if (ieee80211_drop_unencrypted_mgmt(rx)) | ||
1935 | return RX_DROP_UNUSABLE; | 2033 | return RX_DROP_UNUSABLE; |
1936 | 2034 | ||
1937 | switch (mgmt->u.action.category) { | 2035 | switch (mgmt->u.action.category) { |
@@ -2024,17 +2122,36 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
2024 | goto queue; | 2122 | goto queue; |
2025 | } | 2123 | } |
2026 | 2124 | ||
2125 | return RX_CONTINUE; | ||
2126 | |||
2027 | invalid: | 2127 | invalid: |
2028 | /* | 2128 | status->rx_flags |= IEEE80211_RX_MALFORMED_ACTION_FRM; |
2029 | * For AP mode, hostapd is responsible for handling any action | 2129 | /* will return in the next handlers */ |
2030 | * frames that we didn't handle, including returning unknown | 2130 | return RX_CONTINUE; |
2031 | * ones. For all other modes we will return them to the sender, | 2131 | |
2032 | * setting the 0x80 bit in the action category, as required by | 2132 | handled: |
2033 | * 802.11-2007 7.3.1.11. | 2133 | if (rx->sta) |
2034 | */ | 2134 | rx->sta->rx_packets++; |
2035 | if (sdata->vif.type == NL80211_IFTYPE_AP || | 2135 | dev_kfree_skb(rx->skb); |
2036 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | 2136 | return RX_QUEUED; |
2037 | return RX_DROP_MONITOR; | 2137 | |
2138 | queue: | ||
2139 | rx->skb->pkt_type = IEEE80211_SDATA_QUEUE_TYPE_FRAME; | ||
2140 | skb_queue_tail(&sdata->skb_queue, rx->skb); | ||
2141 | ieee80211_queue_work(&local->hw, &sdata->work); | ||
2142 | if (rx->sta) | ||
2143 | rx->sta->rx_packets++; | ||
2144 | return RX_QUEUED; | ||
2145 | } | ||
2146 | |||
2147 | static ieee80211_rx_result debug_noinline | ||
2148 | ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx) | ||
2149 | { | ||
2150 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | ||
2151 | |||
2152 | /* skip known-bad action frames and return them in the next handler */ | ||
2153 | if (status->rx_flags & IEEE80211_RX_MALFORMED_ACTION_FRM) | ||
2154 | return RX_CONTINUE; | ||
2038 | 2155 | ||
2039 | /* | 2156 | /* |
2040 | * Getting here means the kernel doesn't know how to handle | 2157 | * Getting here means the kernel doesn't know how to handle |
@@ -2042,12 +2159,46 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
2042 | * so userspace can register for those to know whether ones | 2159 | * so userspace can register for those to know whether ones |
2043 | * it transmitted were processed or returned. | 2160 | * it transmitted were processed or returned. |
2044 | */ | 2161 | */ |
2045 | status = IEEE80211_SKB_RXCB(rx->skb); | ||
2046 | 2162 | ||
2047 | if (cfg80211_rx_action(rx->sdata->dev, status->freq, | 2163 | if (cfg80211_rx_mgmt(rx->sdata->dev, status->freq, |
2048 | rx->skb->data, rx->skb->len, | 2164 | rx->skb->data, rx->skb->len, |
2049 | GFP_ATOMIC)) | 2165 | GFP_ATOMIC)) { |
2050 | goto handled; | 2166 | if (rx->sta) |
2167 | rx->sta->rx_packets++; | ||
2168 | dev_kfree_skb(rx->skb); | ||
2169 | return RX_QUEUED; | ||
2170 | } | ||
2171 | |||
2172 | |||
2173 | return RX_CONTINUE; | ||
2174 | } | ||
2175 | |||
2176 | static ieee80211_rx_result debug_noinline | ||
2177 | ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx) | ||
2178 | { | ||
2179 | struct ieee80211_local *local = rx->local; | ||
2180 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; | ||
2181 | struct sk_buff *nskb; | ||
2182 | struct ieee80211_sub_if_data *sdata = rx->sdata; | ||
2183 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | ||
2184 | |||
2185 | if (!ieee80211_is_action(mgmt->frame_control)) | ||
2186 | return RX_CONTINUE; | ||
2187 | |||
2188 | /* | ||
2189 | * For AP mode, hostapd is responsible for handling any action | ||
2190 | * frames that we didn't handle, including returning unknown | ||
2191 | * ones. For all other modes we will return them to the sender, | ||
2192 | * setting the 0x80 bit in the action category, as required by | ||
2193 | * 802.11-2007 7.3.1.11. | ||
2194 | * Newer versions of hostapd shall also use the management frame | ||
2195 | * registration mechanisms, but older ones still use cooked | ||
2196 | * monitor interfaces so push all frames there. | ||
2197 | */ | ||
2198 | if (!(status->rx_flags & IEEE80211_RX_MALFORMED_ACTION_FRM) && | ||
2199 | (sdata->vif.type == NL80211_IFTYPE_AP || | ||
2200 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) | ||
2201 | return RX_DROP_MONITOR; | ||
2051 | 2202 | ||
2052 | /* do not return rejected action frames */ | 2203 | /* do not return rejected action frames */ |
2053 | if (mgmt->u.action.category & 0x80) | 2204 | if (mgmt->u.action.category & 0x80) |
@@ -2066,20 +2217,8 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
2066 | 2217 | ||
2067 | ieee80211_tx_skb(rx->sdata, nskb); | 2218 | ieee80211_tx_skb(rx->sdata, nskb); |
2068 | } | 2219 | } |
2069 | |||
2070 | handled: | ||
2071 | if (rx->sta) | ||
2072 | rx->sta->rx_packets++; | ||
2073 | dev_kfree_skb(rx->skb); | 2220 | dev_kfree_skb(rx->skb); |
2074 | return RX_QUEUED; | 2221 | return RX_QUEUED; |
2075 | |||
2076 | queue: | ||
2077 | rx->skb->pkt_type = IEEE80211_SDATA_QUEUE_TYPE_FRAME; | ||
2078 | skb_queue_tail(&sdata->skb_queue, rx->skb); | ||
2079 | ieee80211_queue_work(&local->hw, &sdata->work); | ||
2080 | if (rx->sta) | ||
2081 | rx->sta->rx_packets++; | ||
2082 | return RX_QUEUED; | ||
2083 | } | 2222 | } |
2084 | 2223 | ||
2085 | static ieee80211_rx_result debug_noinline | 2224 | static ieee80211_rx_result debug_noinline |
@@ -2090,15 +2229,6 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) | |||
2090 | struct ieee80211_mgmt *mgmt = (void *)rx->skb->data; | 2229 | struct ieee80211_mgmt *mgmt = (void *)rx->skb->data; |
2091 | __le16 stype; | 2230 | __le16 stype; |
2092 | 2231 | ||
2093 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) | ||
2094 | return RX_DROP_MONITOR; | ||
2095 | |||
2096 | if (rx->skb->len < 24) | ||
2097 | return RX_DROP_MONITOR; | ||
2098 | |||
2099 | if (ieee80211_drop_unencrypted_mgmt(rx)) | ||
2100 | return RX_DROP_UNUSABLE; | ||
2101 | |||
2102 | rxs = ieee80211_work_rx_mgmt(rx->sdata, rx->skb); | 2232 | rxs = ieee80211_work_rx_mgmt(rx->sdata, rx->skb); |
2103 | if (rxs != RX_CONTINUE) | 2233 | if (rxs != RX_CONTINUE) |
2104 | return rxs; | 2234 | return rxs; |
@@ -2199,6 +2329,14 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, | |||
2199 | struct net_device *prev_dev = NULL; | 2329 | struct net_device *prev_dev = NULL; |
2200 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 2330 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
2201 | 2331 | ||
2332 | /* | ||
2333 | * If cooked monitor has been processed already, then | ||
2334 | * don't do it again. If not, set the flag. | ||
2335 | */ | ||
2336 | if (rx->flags & IEEE80211_RX_CMNTR) | ||
2337 | goto out_free_skb; | ||
2338 | rx->flags |= IEEE80211_RX_CMNTR; | ||
2339 | |||
2202 | if (skb_headroom(skb) < sizeof(*rthdr) && | 2340 | if (skb_headroom(skb) < sizeof(*rthdr) && |
2203 | pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC)) | 2341 | pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC)) |
2204 | goto out_free_skb; | 2342 | goto out_free_skb; |
@@ -2253,29 +2391,53 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, | |||
2253 | if (prev_dev) { | 2391 | if (prev_dev) { |
2254 | skb->dev = prev_dev; | 2392 | skb->dev = prev_dev; |
2255 | netif_receive_skb(skb); | 2393 | netif_receive_skb(skb); |
2256 | skb = NULL; | 2394 | return; |
2257 | } else | 2395 | } |
2258 | goto out_free_skb; | ||
2259 | |||
2260 | return; | ||
2261 | 2396 | ||
2262 | out_free_skb: | 2397 | out_free_skb: |
2263 | dev_kfree_skb(skb); | 2398 | dev_kfree_skb(skb); |
2264 | } | 2399 | } |
2265 | 2400 | ||
2401 | static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx, | ||
2402 | ieee80211_rx_result res) | ||
2403 | { | ||
2404 | switch (res) { | ||
2405 | case RX_DROP_MONITOR: | ||
2406 | I802_DEBUG_INC(rx->sdata->local->rx_handlers_drop); | ||
2407 | if (rx->sta) | ||
2408 | rx->sta->rx_dropped++; | ||
2409 | /* fall through */ | ||
2410 | case RX_CONTINUE: { | ||
2411 | struct ieee80211_rate *rate = NULL; | ||
2412 | struct ieee80211_supported_band *sband; | ||
2413 | struct ieee80211_rx_status *status; | ||
2414 | |||
2415 | status = IEEE80211_SKB_RXCB((rx->skb)); | ||
2416 | |||
2417 | sband = rx->local->hw.wiphy->bands[status->band]; | ||
2418 | if (!(status->flag & RX_FLAG_HT)) | ||
2419 | rate = &sband->bitrates[status->rate_idx]; | ||
2420 | |||
2421 | ieee80211_rx_cooked_monitor(rx, rate); | ||
2422 | break; | ||
2423 | } | ||
2424 | case RX_DROP_UNUSABLE: | ||
2425 | I802_DEBUG_INC(rx->sdata->local->rx_handlers_drop); | ||
2426 | if (rx->sta) | ||
2427 | rx->sta->rx_dropped++; | ||
2428 | dev_kfree_skb(rx->skb); | ||
2429 | break; | ||
2430 | case RX_QUEUED: | ||
2431 | I802_DEBUG_INC(rx->sdata->local->rx_handlers_queued); | ||
2432 | break; | ||
2433 | } | ||
2434 | } | ||
2266 | 2435 | ||
2267 | static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata, | 2436 | static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx, |
2268 | struct ieee80211_rx_data *rx, | 2437 | struct sk_buff_head *frames) |
2269 | struct sk_buff *skb, | ||
2270 | struct ieee80211_rate *rate) | ||
2271 | { | 2438 | { |
2272 | struct sk_buff_head reorder_release; | ||
2273 | ieee80211_rx_result res = RX_DROP_MONITOR; | 2439 | ieee80211_rx_result res = RX_DROP_MONITOR; |
2274 | 2440 | struct sk_buff *skb; | |
2275 | __skb_queue_head_init(&reorder_release); | ||
2276 | |||
2277 | rx->skb = skb; | ||
2278 | rx->sdata = sdata; | ||
2279 | 2441 | ||
2280 | #define CALL_RXH(rxh) \ | 2442 | #define CALL_RXH(rxh) \ |
2281 | do { \ | 2443 | do { \ |
@@ -2284,23 +2446,14 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata, | |||
2284 | goto rxh_next; \ | 2446 | goto rxh_next; \ |
2285 | } while (0); | 2447 | } while (0); |
2286 | 2448 | ||
2287 | /* | 2449 | while ((skb = __skb_dequeue(frames))) { |
2288 | * NB: the rxh_next label works even if we jump | ||
2289 | * to it from here because then the list will | ||
2290 | * be empty, which is a trivial check | ||
2291 | */ | ||
2292 | CALL_RXH(ieee80211_rx_h_passive_scan) | ||
2293 | CALL_RXH(ieee80211_rx_h_check) | ||
2294 | |||
2295 | ieee80211_rx_reorder_ampdu(rx, &reorder_release); | ||
2296 | |||
2297 | while ((skb = __skb_dequeue(&reorder_release))) { | ||
2298 | /* | 2450 | /* |
2299 | * all the other fields are valid across frames | 2451 | * all the other fields are valid across frames |
2300 | * that belong to an aMPDU since they are on the | 2452 | * that belong to an aMPDU since they are on the |
2301 | * same TID from the same station | 2453 | * same TID from the same station |
2302 | */ | 2454 | */ |
2303 | rx->skb = skb; | 2455 | rx->skb = skb; |
2456 | rx->flags = 0; | ||
2304 | 2457 | ||
2305 | CALL_RXH(ieee80211_rx_h_decrypt) | 2458 | CALL_RXH(ieee80211_rx_h_decrypt) |
2306 | CALL_RXH(ieee80211_rx_h_check_more_data) | 2459 | CALL_RXH(ieee80211_rx_h_check_more_data) |
@@ -2312,50 +2465,92 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata, | |||
2312 | CALL_RXH(ieee80211_rx_h_remove_qos_control) | 2465 | CALL_RXH(ieee80211_rx_h_remove_qos_control) |
2313 | CALL_RXH(ieee80211_rx_h_amsdu) | 2466 | CALL_RXH(ieee80211_rx_h_amsdu) |
2314 | #ifdef CONFIG_MAC80211_MESH | 2467 | #ifdef CONFIG_MAC80211_MESH |
2315 | if (ieee80211_vif_is_mesh(&sdata->vif)) | 2468 | if (ieee80211_vif_is_mesh(&rx->sdata->vif)) |
2316 | CALL_RXH(ieee80211_rx_h_mesh_fwding); | 2469 | CALL_RXH(ieee80211_rx_h_mesh_fwding); |
2317 | #endif | 2470 | #endif |
2318 | CALL_RXH(ieee80211_rx_h_data) | 2471 | CALL_RXH(ieee80211_rx_h_data) |
2319 | 2472 | ||
2320 | /* special treatment -- needs the queue */ | 2473 | /* special treatment -- needs the queue */ |
2321 | res = ieee80211_rx_h_ctrl(rx, &reorder_release); | 2474 | res = ieee80211_rx_h_ctrl(rx, frames); |
2322 | if (res != RX_CONTINUE) | 2475 | if (res != RX_CONTINUE) |
2323 | goto rxh_next; | 2476 | goto rxh_next; |
2324 | 2477 | ||
2478 | CALL_RXH(ieee80211_rx_h_mgmt_check) | ||
2325 | CALL_RXH(ieee80211_rx_h_action) | 2479 | CALL_RXH(ieee80211_rx_h_action) |
2480 | CALL_RXH(ieee80211_rx_h_userspace_mgmt) | ||
2481 | CALL_RXH(ieee80211_rx_h_action_return) | ||
2326 | CALL_RXH(ieee80211_rx_h_mgmt) | 2482 | CALL_RXH(ieee80211_rx_h_mgmt) |
2327 | 2483 | ||
2484 | rxh_next: | ||
2485 | ieee80211_rx_handlers_result(rx, res); | ||
2486 | |||
2328 | #undef CALL_RXH | 2487 | #undef CALL_RXH |
2488 | } | ||
2489 | } | ||
2490 | |||
2491 | static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx) | ||
2492 | { | ||
2493 | struct sk_buff_head reorder_release; | ||
2494 | ieee80211_rx_result res = RX_DROP_MONITOR; | ||
2495 | |||
2496 | __skb_queue_head_init(&reorder_release); | ||
2497 | |||
2498 | #define CALL_RXH(rxh) \ | ||
2499 | do { \ | ||
2500 | res = rxh(rx); \ | ||
2501 | if (res != RX_CONTINUE) \ | ||
2502 | goto rxh_next; \ | ||
2503 | } while (0); | ||
2504 | |||
2505 | CALL_RXH(ieee80211_rx_h_passive_scan) | ||
2506 | CALL_RXH(ieee80211_rx_h_check) | ||
2507 | |||
2508 | ieee80211_rx_reorder_ampdu(rx, &reorder_release); | ||
2509 | |||
2510 | ieee80211_rx_handlers(rx, &reorder_release); | ||
2511 | return; | ||
2329 | 2512 | ||
2330 | rxh_next: | 2513 | rxh_next: |
2331 | switch (res) { | 2514 | ieee80211_rx_handlers_result(rx, res); |
2332 | case RX_DROP_MONITOR: | 2515 | |
2333 | I802_DEBUG_INC(sdata->local->rx_handlers_drop); | 2516 | #undef CALL_RXH |
2334 | if (rx->sta) | 2517 | } |
2335 | rx->sta->rx_dropped++; | 2518 | |
2336 | /* fall through */ | 2519 | /* |
2337 | case RX_CONTINUE: | 2520 | * This function makes calls into the RX path. Therefore the |
2338 | ieee80211_rx_cooked_monitor(rx, rate); | 2521 | * caller must hold the sta_info->lock and everything has to |
2339 | break; | 2522 | * be under rcu_read_lock protection as well. |
2340 | case RX_DROP_UNUSABLE: | 2523 | */ |
2341 | I802_DEBUG_INC(sdata->local->rx_handlers_drop); | 2524 | void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid) |
2342 | if (rx->sta) | 2525 | { |
2343 | rx->sta->rx_dropped++; | 2526 | struct sk_buff_head frames; |
2344 | dev_kfree_skb(rx->skb); | 2527 | struct ieee80211_rx_data rx = { |
2345 | break; | 2528 | .sta = sta, |
2346 | case RX_QUEUED: | 2529 | .sdata = sta->sdata, |
2347 | I802_DEBUG_INC(sdata->local->rx_handlers_queued); | 2530 | .local = sta->local, |
2348 | break; | 2531 | .queue = tid, |
2349 | } | 2532 | }; |
2350 | } | 2533 | struct tid_ampdu_rx *tid_agg_rx; |
2534 | |||
2535 | tid_agg_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]); | ||
2536 | if (!tid_agg_rx) | ||
2537 | return; | ||
2538 | |||
2539 | __skb_queue_head_init(&frames); | ||
2540 | |||
2541 | spin_lock(&tid_agg_rx->reorder_lock); | ||
2542 | ieee80211_sta_reorder_release(&sta->local->hw, tid_agg_rx, &frames); | ||
2543 | spin_unlock(&tid_agg_rx->reorder_lock); | ||
2544 | |||
2545 | ieee80211_rx_handlers(&rx, &frames); | ||
2351 | } | 2546 | } |
2352 | 2547 | ||
2353 | /* main receive path */ | 2548 | /* main receive path */ |
2354 | 2549 | ||
2355 | static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | 2550 | static int prepare_for_handlers(struct ieee80211_rx_data *rx, |
2356 | struct ieee80211_rx_data *rx, | ||
2357 | struct ieee80211_hdr *hdr) | 2551 | struct ieee80211_hdr *hdr) |
2358 | { | 2552 | { |
2553 | struct ieee80211_sub_if_data *sdata = rx->sdata; | ||
2359 | struct sk_buff *skb = rx->skb; | 2554 | struct sk_buff *skb = rx->skb; |
2360 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 2555 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
2361 | u8 *bssid = ieee80211_get_bssid(hdr, skb->len, sdata->vif.type); | 2556 | u8 *bssid = ieee80211_get_bssid(hdr, skb->len, sdata->vif.type); |
@@ -2369,7 +2564,7 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | |||
2369 | compare_ether_addr(sdata->vif.addr, hdr->addr1) != 0) { | 2564 | compare_ether_addr(sdata->vif.addr, hdr->addr1) != 0) { |
2370 | if (!(sdata->dev->flags & IFF_PROMISC)) | 2565 | if (!(sdata->dev->flags & IFF_PROMISC)) |
2371 | return 0; | 2566 | return 0; |
2372 | rx->flags &= ~IEEE80211_RX_RA_MATCH; | 2567 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; |
2373 | } | 2568 | } |
2374 | break; | 2569 | break; |
2375 | case NL80211_IFTYPE_ADHOC: | 2570 | case NL80211_IFTYPE_ADHOC: |
@@ -2379,15 +2574,15 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | |||
2379 | return 1; | 2574 | return 1; |
2380 | } | 2575 | } |
2381 | else if (!ieee80211_bssid_match(bssid, sdata->u.ibss.bssid)) { | 2576 | else if (!ieee80211_bssid_match(bssid, sdata->u.ibss.bssid)) { |
2382 | if (!(rx->flags & IEEE80211_RX_IN_SCAN)) | 2577 | if (!(status->rx_flags & IEEE80211_RX_IN_SCAN)) |
2383 | return 0; | 2578 | return 0; |
2384 | rx->flags &= ~IEEE80211_RX_RA_MATCH; | 2579 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; |
2385 | } else if (!multicast && | 2580 | } else if (!multicast && |
2386 | compare_ether_addr(sdata->vif.addr, | 2581 | compare_ether_addr(sdata->vif.addr, |
2387 | hdr->addr1) != 0) { | 2582 | hdr->addr1) != 0) { |
2388 | if (!(sdata->dev->flags & IFF_PROMISC)) | 2583 | if (!(sdata->dev->flags & IFF_PROMISC)) |
2389 | return 0; | 2584 | return 0; |
2390 | rx->flags &= ~IEEE80211_RX_RA_MATCH; | 2585 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; |
2391 | } else if (!rx->sta) { | 2586 | } else if (!rx->sta) { |
2392 | int rate_idx; | 2587 | int rate_idx; |
2393 | if (status->flag & RX_FLAG_HT) | 2588 | if (status->flag & RX_FLAG_HT) |
@@ -2405,7 +2600,7 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | |||
2405 | if (!(sdata->dev->flags & IFF_PROMISC)) | 2600 | if (!(sdata->dev->flags & IFF_PROMISC)) |
2406 | return 0; | 2601 | return 0; |
2407 | 2602 | ||
2408 | rx->flags &= ~IEEE80211_RX_RA_MATCH; | 2603 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; |
2409 | } | 2604 | } |
2410 | break; | 2605 | break; |
2411 | case NL80211_IFTYPE_AP_VLAN: | 2606 | case NL80211_IFTYPE_AP_VLAN: |
@@ -2416,9 +2611,9 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | |||
2416 | return 0; | 2611 | return 0; |
2417 | } else if (!ieee80211_bssid_match(bssid, | 2612 | } else if (!ieee80211_bssid_match(bssid, |
2418 | sdata->vif.addr)) { | 2613 | sdata->vif.addr)) { |
2419 | if (!(rx->flags & IEEE80211_RX_IN_SCAN)) | 2614 | if (!(status->rx_flags & IEEE80211_RX_IN_SCAN)) |
2420 | return 0; | 2615 | return 0; |
2421 | rx->flags &= ~IEEE80211_RX_RA_MATCH; | 2616 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; |
2422 | } | 2617 | } |
2423 | break; | 2618 | break; |
2424 | case NL80211_IFTYPE_WDS: | 2619 | case NL80211_IFTYPE_WDS: |
@@ -2427,9 +2622,7 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | |||
2427 | if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2)) | 2622 | if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2)) |
2428 | return 0; | 2623 | return 0; |
2429 | break; | 2624 | break; |
2430 | case NL80211_IFTYPE_MONITOR: | 2625 | default: |
2431 | case NL80211_IFTYPE_UNSPECIFIED: | ||
2432 | case __NL80211_IFTYPE_AFTER_LAST: | ||
2433 | /* should never get here */ | 2626 | /* should never get here */ |
2434 | WARN_ON(1); | 2627 | WARN_ON(1); |
2435 | break; | 2628 | break; |
@@ -2439,12 +2632,56 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | |||
2439 | } | 2632 | } |
2440 | 2633 | ||
2441 | /* | 2634 | /* |
2635 | * This function returns whether or not the SKB | ||
2636 | * was destined for RX processing or not, which, | ||
2637 | * if consume is true, is equivalent to whether | ||
2638 | * or not the skb was consumed. | ||
2639 | */ | ||
2640 | static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx, | ||
2641 | struct sk_buff *skb, bool consume) | ||
2642 | { | ||
2643 | struct ieee80211_local *local = rx->local; | ||
2644 | struct ieee80211_sub_if_data *sdata = rx->sdata; | ||
2645 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
2646 | struct ieee80211_hdr *hdr = (void *)skb->data; | ||
2647 | int prepares; | ||
2648 | |||
2649 | rx->skb = skb; | ||
2650 | status->rx_flags |= IEEE80211_RX_RA_MATCH; | ||
2651 | prepares = prepare_for_handlers(rx, hdr); | ||
2652 | |||
2653 | if (!prepares) | ||
2654 | return false; | ||
2655 | |||
2656 | if (status->flag & RX_FLAG_MMIC_ERROR) { | ||
2657 | if (status->rx_flags & IEEE80211_RX_RA_MATCH) | ||
2658 | ieee80211_rx_michael_mic_report(hdr, rx); | ||
2659 | return false; | ||
2660 | } | ||
2661 | |||
2662 | if (!consume) { | ||
2663 | skb = skb_copy(skb, GFP_ATOMIC); | ||
2664 | if (!skb) { | ||
2665 | if (net_ratelimit()) | ||
2666 | wiphy_debug(local->hw.wiphy, | ||
2667 | "failed to copy multicast frame for %s\n", | ||
2668 | sdata->name); | ||
2669 | return true; | ||
2670 | } | ||
2671 | |||
2672 | rx->skb = skb; | ||
2673 | } | ||
2674 | |||
2675 | ieee80211_invoke_rx_handlers(rx); | ||
2676 | return true; | ||
2677 | } | ||
2678 | |||
2679 | /* | ||
2442 | * This is the actual Rx frames handler. as it blongs to Rx path it must | 2680 | * This is the actual Rx frames handler. as it blongs to Rx path it must |
2443 | * be called with rcu_read_lock protection. | 2681 | * be called with rcu_read_lock protection. |
2444 | */ | 2682 | */ |
2445 | static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | 2683 | static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, |
2446 | struct sk_buff *skb, | 2684 | struct sk_buff *skb) |
2447 | struct ieee80211_rate *rate) | ||
2448 | { | 2685 | { |
2449 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 2686 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
2450 | struct ieee80211_local *local = hw_to_local(hw); | 2687 | struct ieee80211_local *local = hw_to_local(hw); |
@@ -2452,11 +2689,8 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
2452 | struct ieee80211_hdr *hdr; | 2689 | struct ieee80211_hdr *hdr; |
2453 | __le16 fc; | 2690 | __le16 fc; |
2454 | struct ieee80211_rx_data rx; | 2691 | struct ieee80211_rx_data rx; |
2455 | int prepares; | 2692 | struct ieee80211_sub_if_data *prev; |
2456 | struct ieee80211_sub_if_data *prev = NULL; | 2693 | struct sta_info *sta, *tmp, *prev_sta; |
2457 | struct sk_buff *skb_new; | ||
2458 | struct sta_info *sta, *tmp; | ||
2459 | bool found_sta = false; | ||
2460 | int err = 0; | 2694 | int err = 0; |
2461 | 2695 | ||
2462 | fc = ((struct ieee80211_hdr *)skb->data)->frame_control; | 2696 | fc = ((struct ieee80211_hdr *)skb->data)->frame_control; |
@@ -2469,7 +2703,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
2469 | 2703 | ||
2470 | if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) || | 2704 | if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) || |
2471 | test_bit(SCAN_OFF_CHANNEL, &local->scanning))) | 2705 | test_bit(SCAN_OFF_CHANNEL, &local->scanning))) |
2472 | rx.flags |= IEEE80211_RX_IN_SCAN; | 2706 | status->rx_flags |= IEEE80211_RX_IN_SCAN; |
2473 | 2707 | ||
2474 | if (ieee80211_is_mgmt(fc)) | 2708 | if (ieee80211_is_mgmt(fc)) |
2475 | err = skb_linearize(skb); | 2709 | err = skb_linearize(skb); |
@@ -2486,91 +2720,67 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
2486 | ieee80211_verify_alignment(&rx); | 2720 | ieee80211_verify_alignment(&rx); |
2487 | 2721 | ||
2488 | if (ieee80211_is_data(fc)) { | 2722 | if (ieee80211_is_data(fc)) { |
2723 | prev_sta = NULL; | ||
2724 | |||
2489 | for_each_sta_info(local, hdr->addr2, sta, tmp) { | 2725 | for_each_sta_info(local, hdr->addr2, sta, tmp) { |
2490 | rx.sta = sta; | 2726 | if (!prev_sta) { |
2491 | found_sta = true; | 2727 | prev_sta = sta; |
2492 | rx.sdata = sta->sdata; | ||
2493 | |||
2494 | rx.flags |= IEEE80211_RX_RA_MATCH; | ||
2495 | prepares = prepare_for_handlers(rx.sdata, &rx, hdr); | ||
2496 | if (prepares) { | ||
2497 | if (status->flag & RX_FLAG_MMIC_ERROR) { | ||
2498 | if (rx.flags & IEEE80211_RX_RA_MATCH) | ||
2499 | ieee80211_rx_michael_mic_report(hdr, &rx); | ||
2500 | } else | ||
2501 | prev = rx.sdata; | ||
2502 | } | ||
2503 | } | ||
2504 | } | ||
2505 | if (!found_sta) { | ||
2506 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | ||
2507 | if (!ieee80211_sdata_running(sdata)) | ||
2508 | continue; | 2728 | continue; |
2729 | } | ||
2509 | 2730 | ||
2510 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR || | 2731 | rx.sta = prev_sta; |
2511 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | 2732 | rx.sdata = prev_sta->sdata; |
2512 | continue; | 2733 | ieee80211_prepare_and_rx_handle(&rx, skb, false); |
2513 | 2734 | ||
2514 | /* | 2735 | prev_sta = sta; |
2515 | * frame is destined for this interface, but if it's | 2736 | } |
2516 | * not also for the previous one we handle that after | ||
2517 | * the loop to avoid copying the SKB once too much | ||
2518 | */ | ||
2519 | 2737 | ||
2520 | if (!prev) { | 2738 | if (prev_sta) { |
2521 | prev = sdata; | 2739 | rx.sta = prev_sta; |
2522 | continue; | 2740 | rx.sdata = prev_sta->sdata; |
2523 | } | ||
2524 | 2741 | ||
2525 | rx.sta = sta_info_get_bss(prev, hdr->addr2); | 2742 | if (ieee80211_prepare_and_rx_handle(&rx, skb, true)) |
2743 | return; | ||
2744 | } | ||
2745 | } | ||
2526 | 2746 | ||
2527 | rx.flags |= IEEE80211_RX_RA_MATCH; | 2747 | prev = NULL; |
2528 | prepares = prepare_for_handlers(prev, &rx, hdr); | ||
2529 | 2748 | ||
2530 | if (!prepares) | 2749 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
2531 | goto next; | 2750 | if (!ieee80211_sdata_running(sdata)) |
2751 | continue; | ||
2532 | 2752 | ||
2533 | if (status->flag & RX_FLAG_MMIC_ERROR) { | 2753 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR || |
2534 | rx.sdata = prev; | 2754 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) |
2535 | if (rx.flags & IEEE80211_RX_RA_MATCH) | 2755 | continue; |
2536 | ieee80211_rx_michael_mic_report(hdr, | ||
2537 | &rx); | ||
2538 | goto next; | ||
2539 | } | ||
2540 | 2756 | ||
2541 | /* | 2757 | /* |
2542 | * frame was destined for the previous interface | 2758 | * frame is destined for this interface, but if it's |
2543 | * so invoke RX handlers for it | 2759 | * not also for the previous one we handle that after |
2544 | */ | 2760 | * the loop to avoid copying the SKB once too much |
2761 | */ | ||
2545 | 2762 | ||
2546 | skb_new = skb_copy(skb, GFP_ATOMIC); | 2763 | if (!prev) { |
2547 | if (!skb_new) { | ||
2548 | if (net_ratelimit()) | ||
2549 | printk(KERN_DEBUG "%s: failed to copy " | ||
2550 | "multicast frame for %s\n", | ||
2551 | wiphy_name(local->hw.wiphy), | ||
2552 | prev->name); | ||
2553 | goto next; | ||
2554 | } | ||
2555 | ieee80211_invoke_rx_handlers(prev, &rx, skb_new, rate); | ||
2556 | next: | ||
2557 | prev = sdata; | 2764 | prev = sdata; |
2765 | continue; | ||
2558 | } | 2766 | } |
2559 | 2767 | ||
2560 | if (prev) { | 2768 | rx.sta = sta_info_get_bss(prev, hdr->addr2); |
2561 | rx.sta = sta_info_get_bss(prev, hdr->addr2); | 2769 | rx.sdata = prev; |
2770 | ieee80211_prepare_and_rx_handle(&rx, skb, false); | ||
2562 | 2771 | ||
2563 | rx.flags |= IEEE80211_RX_RA_MATCH; | 2772 | prev = sdata; |
2564 | prepares = prepare_for_handlers(prev, &rx, hdr); | 2773 | } |
2565 | 2774 | ||
2566 | if (!prepares) | 2775 | if (prev) { |
2567 | prev = NULL; | 2776 | rx.sta = sta_info_get_bss(prev, hdr->addr2); |
2568 | } | 2777 | rx.sdata = prev; |
2778 | |||
2779 | if (ieee80211_prepare_and_rx_handle(&rx, skb, true)) | ||
2780 | return; | ||
2569 | } | 2781 | } |
2570 | if (prev) | 2782 | |
2571 | ieee80211_invoke_rx_handlers(prev, &rx, skb, rate); | 2783 | dev_kfree_skb(skb); |
2572 | else | ||
2573 | dev_kfree_skb(skb); | ||
2574 | } | 2784 | } |
2575 | 2785 | ||
2576 | /* | 2786 | /* |
@@ -2611,30 +2821,41 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
2611 | if (WARN_ON(!local->started)) | 2821 | if (WARN_ON(!local->started)) |
2612 | goto drop; | 2822 | goto drop; |
2613 | 2823 | ||
2614 | if (status->flag & RX_FLAG_HT) { | 2824 | if (likely(!(status->flag & RX_FLAG_FAILED_PLCP_CRC))) { |
2615 | /* | 2825 | /* |
2616 | * rate_idx is MCS index, which can be [0-76] as documented on: | 2826 | * Validate the rate, unless a PLCP error means that |
2617 | * | 2827 | * we probably can't have a valid rate here anyway. |
2618 | * http://wireless.kernel.org/en/developers/Documentation/ieee80211/802.11n | ||
2619 | * | ||
2620 | * Anything else would be some sort of driver or hardware error. | ||
2621 | * The driver should catch hardware errors. | ||
2622 | */ | 2828 | */ |
2623 | if (WARN((status->rate_idx < 0 || | 2829 | |
2624 | status->rate_idx > 76), | 2830 | if (status->flag & RX_FLAG_HT) { |
2625 | "Rate marked as an HT rate but passed " | 2831 | /* |
2626 | "status->rate_idx is not " | 2832 | * rate_idx is MCS index, which can be [0-76] |
2627 | "an MCS index [0-76]: %d (0x%02x)\n", | 2833 | * as documented on: |
2628 | status->rate_idx, | 2834 | * |
2629 | status->rate_idx)) | 2835 | * http://wireless.kernel.org/en/developers/Documentation/ieee80211/802.11n |
2630 | goto drop; | 2836 | * |
2631 | } else { | 2837 | * Anything else would be some sort of driver or |
2632 | if (WARN_ON(status->rate_idx < 0 || | 2838 | * hardware error. The driver should catch hardware |
2633 | status->rate_idx >= sband->n_bitrates)) | 2839 | * errors. |
2634 | goto drop; | 2840 | */ |
2635 | rate = &sband->bitrates[status->rate_idx]; | 2841 | if (WARN((status->rate_idx < 0 || |
2842 | status->rate_idx > 76), | ||
2843 | "Rate marked as an HT rate but passed " | ||
2844 | "status->rate_idx is not " | ||
2845 | "an MCS index [0-76]: %d (0x%02x)\n", | ||
2846 | status->rate_idx, | ||
2847 | status->rate_idx)) | ||
2848 | goto drop; | ||
2849 | } else { | ||
2850 | if (WARN_ON(status->rate_idx < 0 || | ||
2851 | status->rate_idx >= sband->n_bitrates)) | ||
2852 | goto drop; | ||
2853 | rate = &sband->bitrates[status->rate_idx]; | ||
2854 | } | ||
2636 | } | 2855 | } |
2637 | 2856 | ||
2857 | status->rx_flags = 0; | ||
2858 | |||
2638 | /* | 2859 | /* |
2639 | * key references and virtual interfaces are protected using RCU | 2860 | * key references and virtual interfaces are protected using RCU |
2640 | * and this requires that we are in a read-side RCU section during | 2861 | * and this requires that we are in a read-side RCU section during |
@@ -2654,7 +2875,7 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
2654 | return; | 2875 | return; |
2655 | } | 2876 | } |
2656 | 2877 | ||
2657 | __ieee80211_rx_handle_packet(hw, skb, rate); | 2878 | __ieee80211_rx_handle_packet(hw, skb); |
2658 | 2879 | ||
2659 | rcu_read_unlock(); | 2880 | rcu_read_unlock(); |
2660 | 2881 | ||
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 872d7b6ef6b..fb274db77e3 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -242,20 +242,19 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local) | |||
242 | local->hw_scan_req->n_channels = n_chans; | 242 | local->hw_scan_req->n_channels = n_chans; |
243 | 243 | ||
244 | ielen = ieee80211_build_preq_ies(local, (u8 *)local->hw_scan_req->ie, | 244 | ielen = ieee80211_build_preq_ies(local, (u8 *)local->hw_scan_req->ie, |
245 | req->ie, req->ie_len, band); | 245 | req->ie, req->ie_len, band, (u32) -1, |
246 | 0); | ||
246 | local->hw_scan_req->ie_len = ielen; | 247 | local->hw_scan_req->ie_len = ielen; |
247 | 248 | ||
248 | return true; | 249 | return true; |
249 | } | 250 | } |
250 | 251 | ||
251 | void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) | 252 | static bool __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted, |
253 | bool was_hw_scan) | ||
252 | { | 254 | { |
253 | struct ieee80211_local *local = hw_to_local(hw); | 255 | struct ieee80211_local *local = hw_to_local(hw); |
254 | bool was_hw_scan; | ||
255 | |||
256 | trace_api_scan_completed(local, aborted); | ||
257 | 256 | ||
258 | mutex_lock(&local->scan_mtx); | 257 | lockdep_assert_held(&local->mtx); |
259 | 258 | ||
260 | /* | 259 | /* |
261 | * It's ok to abort a not-yet-running scan (that | 260 | * It's ok to abort a not-yet-running scan (that |
@@ -266,17 +265,13 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) | |||
266 | if (WARN_ON(!local->scanning && !aborted)) | 265 | if (WARN_ON(!local->scanning && !aborted)) |
267 | aborted = true; | 266 | aborted = true; |
268 | 267 | ||
269 | if (WARN_ON(!local->scan_req)) { | 268 | if (WARN_ON(!local->scan_req)) |
270 | mutex_unlock(&local->scan_mtx); | 269 | return false; |
271 | return; | ||
272 | } | ||
273 | 270 | ||
274 | was_hw_scan = test_bit(SCAN_HW_SCANNING, &local->scanning); | ||
275 | if (was_hw_scan && !aborted && ieee80211_prep_hw_scan(local)) { | 271 | if (was_hw_scan && !aborted && ieee80211_prep_hw_scan(local)) { |
276 | ieee80211_queue_delayed_work(&local->hw, | 272 | int rc = drv_hw_scan(local, local->scan_sdata, local->hw_scan_req); |
277 | &local->scan_work, 0); | 273 | if (rc == 0) |
278 | mutex_unlock(&local->scan_mtx); | 274 | return false; |
279 | return; | ||
280 | } | 275 | } |
281 | 276 | ||
282 | kfree(local->hw_scan_req); | 277 | kfree(local->hw_scan_req); |
@@ -290,26 +285,42 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) | |||
290 | local->scanning = 0; | 285 | local->scanning = 0; |
291 | local->scan_channel = NULL; | 286 | local->scan_channel = NULL; |
292 | 287 | ||
293 | /* we only have to protect scan_req and hw/sw scan */ | 288 | return true; |
294 | mutex_unlock(&local->scan_mtx); | 289 | } |
295 | |||
296 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | ||
297 | if (was_hw_scan) | ||
298 | goto done; | ||
299 | |||
300 | ieee80211_configure_filter(local); | ||
301 | 290 | ||
302 | drv_sw_scan_complete(local); | 291 | static void __ieee80211_scan_completed_finish(struct ieee80211_hw *hw, |
292 | bool was_hw_scan) | ||
293 | { | ||
294 | struct ieee80211_local *local = hw_to_local(hw); | ||
303 | 295 | ||
304 | ieee80211_offchannel_return(local, true); | 296 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); |
297 | if (!was_hw_scan) { | ||
298 | ieee80211_configure_filter(local); | ||
299 | drv_sw_scan_complete(local); | ||
300 | ieee80211_offchannel_return(local, true); | ||
301 | } | ||
305 | 302 | ||
306 | done: | 303 | mutex_lock(&local->mtx); |
307 | ieee80211_recalc_idle(local); | 304 | ieee80211_recalc_idle(local); |
305 | mutex_unlock(&local->mtx); | ||
306 | |||
308 | ieee80211_mlme_notify_scan_completed(local); | 307 | ieee80211_mlme_notify_scan_completed(local); |
309 | ieee80211_ibss_notify_scan_completed(local); | 308 | ieee80211_ibss_notify_scan_completed(local); |
310 | ieee80211_mesh_notify_scan_completed(local); | 309 | ieee80211_mesh_notify_scan_completed(local); |
311 | ieee80211_queue_work(&local->hw, &local->work_work); | 310 | ieee80211_queue_work(&local->hw, &local->work_work); |
312 | } | 311 | } |
312 | |||
313 | void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) | ||
314 | { | ||
315 | struct ieee80211_local *local = hw_to_local(hw); | ||
316 | |||
317 | trace_api_scan_completed(local, aborted); | ||
318 | |||
319 | set_bit(SCAN_COMPLETED, &local->scanning); | ||
320 | if (aborted) | ||
321 | set_bit(SCAN_ABORTED, &local->scanning); | ||
322 | ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0); | ||
323 | } | ||
313 | EXPORT_SYMBOL(ieee80211_scan_completed); | 324 | EXPORT_SYMBOL(ieee80211_scan_completed); |
314 | 325 | ||
315 | static int ieee80211_start_sw_scan(struct ieee80211_local *local) | 326 | static int ieee80211_start_sw_scan(struct ieee80211_local *local) |
@@ -353,6 +364,8 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, | |||
353 | struct ieee80211_local *local = sdata->local; | 364 | struct ieee80211_local *local = sdata->local; |
354 | int rc; | 365 | int rc; |
355 | 366 | ||
367 | lockdep_assert_held(&local->mtx); | ||
368 | |||
356 | if (local->scan_req) | 369 | if (local->scan_req) |
357 | return -EBUSY; | 370 | return -EBUSY; |
358 | 371 | ||
@@ -434,8 +447,8 @@ ieee80211_scan_get_channel_time(struct ieee80211_channel *chan) | |||
434 | return IEEE80211_PROBE_DELAY + IEEE80211_CHANNEL_TIME; | 447 | return IEEE80211_PROBE_DELAY + IEEE80211_CHANNEL_TIME; |
435 | } | 448 | } |
436 | 449 | ||
437 | static int ieee80211_scan_state_decision(struct ieee80211_local *local, | 450 | static void ieee80211_scan_state_decision(struct ieee80211_local *local, |
438 | unsigned long *next_delay) | 451 | unsigned long *next_delay) |
439 | { | 452 | { |
440 | bool associated = false; | 453 | bool associated = false; |
441 | bool tx_empty = true; | 454 | bool tx_empty = true; |
@@ -445,12 +458,6 @@ static int ieee80211_scan_state_decision(struct ieee80211_local *local, | |||
445 | struct ieee80211_sub_if_data *sdata; | 458 | struct ieee80211_sub_if_data *sdata; |
446 | struct ieee80211_channel *next_chan; | 459 | struct ieee80211_channel *next_chan; |
447 | 460 | ||
448 | /* if no more bands/channels left, complete scan and advance to the idle state */ | ||
449 | if (local->scan_channel_idx >= local->scan_req->n_channels) { | ||
450 | ieee80211_scan_completed(&local->hw, false); | ||
451 | return 1; | ||
452 | } | ||
453 | |||
454 | /* | 461 | /* |
455 | * check if at least one STA interface is associated, | 462 | * check if at least one STA interface is associated, |
456 | * check if at least one STA interface has pending tx frames | 463 | * check if at least one STA interface has pending tx frames |
@@ -522,7 +529,6 @@ static int ieee80211_scan_state_decision(struct ieee80211_local *local, | |||
522 | } | 529 | } |
523 | 530 | ||
524 | *next_delay = 0; | 531 | *next_delay = 0; |
525 | return 0; | ||
526 | } | 532 | } |
527 | 533 | ||
528 | static void ieee80211_scan_state_leave_oper_channel(struct ieee80211_local *local, | 534 | static void ieee80211_scan_state_leave_oper_channel(struct ieee80211_local *local, |
@@ -638,21 +644,18 @@ void ieee80211_scan_work(struct work_struct *work) | |||
638 | container_of(work, struct ieee80211_local, scan_work.work); | 644 | container_of(work, struct ieee80211_local, scan_work.work); |
639 | struct ieee80211_sub_if_data *sdata = local->scan_sdata; | 645 | struct ieee80211_sub_if_data *sdata = local->scan_sdata; |
640 | unsigned long next_delay = 0; | 646 | unsigned long next_delay = 0; |
647 | bool aborted, hw_scan, finish; | ||
641 | 648 | ||
642 | mutex_lock(&local->scan_mtx); | 649 | mutex_lock(&local->mtx); |
643 | if (!sdata || !local->scan_req) { | ||
644 | mutex_unlock(&local->scan_mtx); | ||
645 | return; | ||
646 | } | ||
647 | 650 | ||
648 | if (local->hw_scan_req) { | 651 | if (test_and_clear_bit(SCAN_COMPLETED, &local->scanning)) { |
649 | int rc = drv_hw_scan(local, sdata, local->hw_scan_req); | 652 | aborted = test_and_clear_bit(SCAN_ABORTED, &local->scanning); |
650 | mutex_unlock(&local->scan_mtx); | 653 | goto out_complete; |
651 | if (rc) | ||
652 | ieee80211_scan_completed(&local->hw, true); | ||
653 | return; | ||
654 | } | 654 | } |
655 | 655 | ||
656 | if (!sdata || !local->scan_req) | ||
657 | goto out; | ||
658 | |||
656 | if (local->scan_req && !local->scanning) { | 659 | if (local->scan_req && !local->scanning) { |
657 | struct cfg80211_scan_request *req = local->scan_req; | 660 | struct cfg80211_scan_request *req = local->scan_req; |
658 | int rc; | 661 | int rc; |
@@ -661,21 +664,21 @@ void ieee80211_scan_work(struct work_struct *work) | |||
661 | local->scan_sdata = NULL; | 664 | local->scan_sdata = NULL; |
662 | 665 | ||
663 | rc = __ieee80211_start_scan(sdata, req); | 666 | rc = __ieee80211_start_scan(sdata, req); |
664 | mutex_unlock(&local->scan_mtx); | 667 | if (rc) { |
665 | 668 | /* need to complete scan in cfg80211 */ | |
666 | if (rc) | 669 | local->scan_req = req; |
667 | ieee80211_scan_completed(&local->hw, true); | 670 | aborted = true; |
668 | return; | 671 | goto out_complete; |
672 | } else | ||
673 | goto out; | ||
669 | } | 674 | } |
670 | 675 | ||
671 | mutex_unlock(&local->scan_mtx); | ||
672 | |||
673 | /* | 676 | /* |
674 | * Avoid re-scheduling when the sdata is going away. | 677 | * Avoid re-scheduling when the sdata is going away. |
675 | */ | 678 | */ |
676 | if (!ieee80211_sdata_running(sdata)) { | 679 | if (!ieee80211_sdata_running(sdata)) { |
677 | ieee80211_scan_completed(&local->hw, true); | 680 | aborted = true; |
678 | return; | 681 | goto out_complete; |
679 | } | 682 | } |
680 | 683 | ||
681 | /* | 684 | /* |
@@ -685,8 +688,12 @@ void ieee80211_scan_work(struct work_struct *work) | |||
685 | do { | 688 | do { |
686 | switch (local->next_scan_state) { | 689 | switch (local->next_scan_state) { |
687 | case SCAN_DECISION: | 690 | case SCAN_DECISION: |
688 | if (ieee80211_scan_state_decision(local, &next_delay)) | 691 | /* if no more bands/channels left, complete scan */ |
689 | return; | 692 | if (local->scan_channel_idx >= local->scan_req->n_channels) { |
693 | aborted = false; | ||
694 | goto out_complete; | ||
695 | } | ||
696 | ieee80211_scan_state_decision(local, &next_delay); | ||
690 | break; | 697 | break; |
691 | case SCAN_SET_CHANNEL: | 698 | case SCAN_SET_CHANNEL: |
692 | ieee80211_scan_state_set_channel(local, &next_delay); | 699 | ieee80211_scan_state_set_channel(local, &next_delay); |
@@ -704,6 +711,19 @@ void ieee80211_scan_work(struct work_struct *work) | |||
704 | } while (next_delay == 0); | 711 | } while (next_delay == 0); |
705 | 712 | ||
706 | ieee80211_queue_delayed_work(&local->hw, &local->scan_work, next_delay); | 713 | ieee80211_queue_delayed_work(&local->hw, &local->scan_work, next_delay); |
714 | mutex_unlock(&local->mtx); | ||
715 | return; | ||
716 | |||
717 | out_complete: | ||
718 | hw_scan = test_bit(SCAN_HW_SCANNING, &local->scanning); | ||
719 | finish = __ieee80211_scan_completed(&local->hw, aborted, hw_scan); | ||
720 | mutex_unlock(&local->mtx); | ||
721 | if (finish) | ||
722 | __ieee80211_scan_completed_finish(&local->hw, hw_scan); | ||
723 | return; | ||
724 | |||
725 | out: | ||
726 | mutex_unlock(&local->mtx); | ||
707 | } | 727 | } |
708 | 728 | ||
709 | int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, | 729 | int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, |
@@ -711,9 +731,9 @@ int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, | |||
711 | { | 731 | { |
712 | int res; | 732 | int res; |
713 | 733 | ||
714 | mutex_lock(&sdata->local->scan_mtx); | 734 | mutex_lock(&sdata->local->mtx); |
715 | res = __ieee80211_start_scan(sdata, req); | 735 | res = __ieee80211_start_scan(sdata, req); |
716 | mutex_unlock(&sdata->local->scan_mtx); | 736 | mutex_unlock(&sdata->local->mtx); |
717 | 737 | ||
718 | return res; | 738 | return res; |
719 | } | 739 | } |
@@ -726,7 +746,7 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, | |||
726 | int ret = -EBUSY; | 746 | int ret = -EBUSY; |
727 | enum ieee80211_band band; | 747 | enum ieee80211_band band; |
728 | 748 | ||
729 | mutex_lock(&local->scan_mtx); | 749 | mutex_lock(&local->mtx); |
730 | 750 | ||
731 | /* busy scanning */ | 751 | /* busy scanning */ |
732 | if (local->scan_req) | 752 | if (local->scan_req) |
@@ -761,25 +781,44 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, | |||
761 | 781 | ||
762 | ret = __ieee80211_start_scan(sdata, sdata->local->int_scan_req); | 782 | ret = __ieee80211_start_scan(sdata, sdata->local->int_scan_req); |
763 | unlock: | 783 | unlock: |
764 | mutex_unlock(&local->scan_mtx); | 784 | mutex_unlock(&local->mtx); |
765 | return ret; | 785 | return ret; |
766 | } | 786 | } |
767 | 787 | ||
788 | /* | ||
789 | * Only call this function when a scan can't be queued -- under RTNL. | ||
790 | */ | ||
768 | void ieee80211_scan_cancel(struct ieee80211_local *local) | 791 | void ieee80211_scan_cancel(struct ieee80211_local *local) |
769 | { | 792 | { |
770 | bool abortscan; | 793 | bool abortscan; |
771 | 794 | bool finish = false; | |
772 | cancel_delayed_work_sync(&local->scan_work); | ||
773 | 795 | ||
774 | /* | 796 | /* |
775 | * Only call this function when a scan can't be | 797 | * We are only canceling software scan, or deferred scan that was not |
776 | * queued -- mostly at suspend under RTNL. | 798 | * yet really started (see __ieee80211_start_scan ). |
799 | * | ||
800 | * Regarding hardware scan: | ||
801 | * - we can not call __ieee80211_scan_completed() as when | ||
802 | * SCAN_HW_SCANNING bit is set this function change | ||
803 | * local->hw_scan_req to operate on 5G band, what race with | ||
804 | * driver which can use local->hw_scan_req | ||
805 | * | ||
806 | * - we can not cancel scan_work since driver can schedule it | ||
807 | * by ieee80211_scan_completed(..., true) to finish scan | ||
808 | * | ||
809 | * Hence low lever driver is responsible for canceling HW scan. | ||
777 | */ | 810 | */ |
778 | mutex_lock(&local->scan_mtx); | ||
779 | abortscan = test_bit(SCAN_SW_SCANNING, &local->scanning) || | ||
780 | (!local->scanning && local->scan_req); | ||
781 | mutex_unlock(&local->scan_mtx); | ||
782 | 811 | ||
812 | mutex_lock(&local->mtx); | ||
813 | abortscan = local->scan_req && !test_bit(SCAN_HW_SCANNING, &local->scanning); | ||
783 | if (abortscan) | 814 | if (abortscan) |
784 | ieee80211_scan_completed(&local->hw, true); | 815 | finish = __ieee80211_scan_completed(&local->hw, true, false); |
816 | mutex_unlock(&local->mtx); | ||
817 | |||
818 | if (abortscan) { | ||
819 | /* The scan is canceled, but stop work from being pending */ | ||
820 | cancel_delayed_work_sync(&local->scan_work); | ||
821 | } | ||
822 | if (finish) | ||
823 | __ieee80211_scan_completed_finish(&local->hw, false); | ||
785 | } | 824 | } |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 6d86f0c1ad0..6d8f897d876 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -125,7 +125,7 @@ struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata, | |||
125 | lockdep_is_held(&local->sta_mtx)); | 125 | lockdep_is_held(&local->sta_mtx)); |
126 | while (sta) { | 126 | while (sta) { |
127 | if ((sta->sdata == sdata || | 127 | if ((sta->sdata == sdata || |
128 | sta->sdata->bss == sdata->bss) && | 128 | (sta->sdata->bss && sta->sdata->bss == sdata->bss)) && |
129 | memcmp(sta->sta.addr, addr, ETH_ALEN) == 0) | 129 | memcmp(sta->sta.addr, addr, ETH_ALEN) == 0) |
130 | break; | 130 | break; |
131 | sta = rcu_dereference_check(sta->hnext, | 131 | sta = rcu_dereference_check(sta->hnext, |
@@ -174,8 +174,7 @@ static void __sta_info_free(struct ieee80211_local *local, | |||
174 | } | 174 | } |
175 | 175 | ||
176 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 176 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
177 | printk(KERN_DEBUG "%s: Destroyed STA %pM\n", | 177 | wiphy_debug(local->hw.wiphy, "Destroyed STA %pM\n", sta->sta.addr); |
178 | wiphy_name(local->hw.wiphy), sta->sta.addr); | ||
179 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | 178 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ |
180 | 179 | ||
181 | kfree(sta); | 180 | kfree(sta); |
@@ -262,8 +261,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
262 | sta->last_seq_ctrl[i] = cpu_to_le16(USHRT_MAX); | 261 | sta->last_seq_ctrl[i] = cpu_to_le16(USHRT_MAX); |
263 | 262 | ||
264 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 263 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
265 | printk(KERN_DEBUG "%s: Allocated STA %pM\n", | 264 | wiphy_debug(local->hw.wiphy, "Allocated STA %pM\n", sta->sta.addr); |
266 | wiphy_name(local->hw.wiphy), sta->sta.addr); | ||
267 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | 265 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ |
268 | 266 | ||
269 | #ifdef CONFIG_MAC80211_MESH | 267 | #ifdef CONFIG_MAC80211_MESH |
@@ -282,7 +280,7 @@ static int sta_info_finish_insert(struct sta_info *sta, bool async) | |||
282 | unsigned long flags; | 280 | unsigned long flags; |
283 | int err = 0; | 281 | int err = 0; |
284 | 282 | ||
285 | WARN_ON(!mutex_is_locked(&local->sta_mtx)); | 283 | lockdep_assert_held(&local->sta_mtx); |
286 | 284 | ||
287 | /* notify driver */ | 285 | /* notify driver */ |
288 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | 286 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) |
@@ -300,8 +298,9 @@ static int sta_info_finish_insert(struct sta_info *sta, bool async) | |||
300 | sta->uploaded = true; | 298 | sta->uploaded = true; |
301 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 299 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
302 | if (async) | 300 | if (async) |
303 | printk(KERN_DEBUG "%s: Finished adding IBSS STA %pM\n", | 301 | wiphy_debug(local->hw.wiphy, |
304 | wiphy_name(local->hw.wiphy), sta->sta.addr); | 302 | "Finished adding IBSS STA %pM\n", |
303 | sta->sta.addr); | ||
305 | #endif | 304 | #endif |
306 | } | 305 | } |
307 | 306 | ||
@@ -411,8 +410,8 @@ int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU) | |||
411 | spin_unlock_irqrestore(&local->sta_lock, flags); | 410 | spin_unlock_irqrestore(&local->sta_lock, flags); |
412 | 411 | ||
413 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 412 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
414 | printk(KERN_DEBUG "%s: Added IBSS STA %pM\n", | 413 | wiphy_debug(local->hw.wiphy, "Added IBSS STA %pM\n", |
415 | wiphy_name(local->hw.wiphy), sta->sta.addr); | 414 | sta->sta.addr); |
416 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | 415 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ |
417 | 416 | ||
418 | ieee80211_queue_work(&local->hw, &local->sta_finish_work); | 417 | ieee80211_queue_work(&local->hw, &local->sta_finish_work); |
@@ -459,8 +458,7 @@ int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU) | |||
459 | } | 458 | } |
460 | 459 | ||
461 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 460 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
462 | printk(KERN_DEBUG "%s: Inserted STA %pM\n", | 461 | wiphy_debug(local->hw.wiphy, "Inserted STA %pM\n", sta->sta.addr); |
463 | wiphy_name(local->hw.wiphy), sta->sta.addr); | ||
464 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | 462 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ |
465 | 463 | ||
466 | /* move reference to rcu-protected */ | 464 | /* move reference to rcu-protected */ |
@@ -618,7 +616,7 @@ static int __must_check __sta_info_destroy(struct sta_info *sta) | |||
618 | struct ieee80211_sub_if_data *sdata; | 616 | struct ieee80211_sub_if_data *sdata; |
619 | struct sk_buff *skb; | 617 | struct sk_buff *skb; |
620 | unsigned long flags; | 618 | unsigned long flags; |
621 | int ret; | 619 | int ret, i; |
622 | 620 | ||
623 | might_sleep(); | 621 | might_sleep(); |
624 | 622 | ||
@@ -635,7 +633,7 @@ static int __must_check __sta_info_destroy(struct sta_info *sta) | |||
635 | * will be sufficient. | 633 | * will be sufficient. |
636 | */ | 634 | */ |
637 | set_sta_flags(sta, WLAN_STA_BLOCK_BA); | 635 | set_sta_flags(sta, WLAN_STA_BLOCK_BA); |
638 | ieee80211_sta_tear_down_BA_sessions(sta); | 636 | ieee80211_sta_tear_down_BA_sessions(sta, true); |
639 | 637 | ||
640 | spin_lock_irqsave(&local->sta_lock, flags); | 638 | spin_lock_irqsave(&local->sta_lock, flags); |
641 | ret = sta_info_hash_del(local, sta); | 639 | ret = sta_info_hash_del(local, sta); |
@@ -646,10 +644,10 @@ static int __must_check __sta_info_destroy(struct sta_info *sta) | |||
646 | if (ret) | 644 | if (ret) |
647 | return ret; | 645 | return ret; |
648 | 646 | ||
649 | if (sta->key) { | 647 | for (i = 0; i < NUM_DEFAULT_KEYS; i++) |
650 | ieee80211_key_free(local, sta->key); | 648 | ieee80211_key_free(local, sta->gtk[i]); |
651 | WARN_ON(sta->key); | 649 | if (sta->ptk) |
652 | } | 650 | ieee80211_key_free(local, sta->ptk); |
653 | 651 | ||
654 | sta->dead = true; | 652 | sta->dead = true; |
655 | 653 | ||
@@ -690,8 +688,7 @@ static int __must_check __sta_info_destroy(struct sta_info *sta) | |||
690 | #endif | 688 | #endif |
691 | 689 | ||
692 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 690 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
693 | printk(KERN_DEBUG "%s: Removed STA %pM\n", | 691 | wiphy_debug(local->hw.wiphy, "Removed STA %pM\n", sta->sta.addr); |
694 | wiphy_name(local->hw.wiphy), sta->sta.addr); | ||
695 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | 692 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ |
696 | cancel_work_sync(&sta->drv_unblock_wk); | 693 | cancel_work_sync(&sta->drv_unblock_wk); |
697 | 694 | ||
@@ -841,13 +838,20 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, | |||
841 | mutex_unlock(&local->sta_mtx); | 838 | mutex_unlock(&local->sta_mtx); |
842 | } | 839 | } |
843 | 840 | ||
844 | struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw, | 841 | struct ieee80211_sta *ieee80211_find_sta_by_ifaddr(struct ieee80211_hw *hw, |
845 | const u8 *addr) | 842 | const u8 *addr, |
843 | const u8 *localaddr) | ||
846 | { | 844 | { |
847 | struct sta_info *sta, *nxt; | 845 | struct sta_info *sta, *nxt; |
848 | 846 | ||
849 | /* Just return a random station ... first in list ... */ | 847 | /* |
848 | * Just return a random station if localaddr is NULL | ||
849 | * ... first in list. | ||
850 | */ | ||
850 | for_each_sta_info(hw_to_local(hw), addr, sta, nxt) { | 851 | for_each_sta_info(hw_to_local(hw), addr, sta, nxt) { |
852 | if (localaddr && | ||
853 | compare_ether_addr(sta->sdata->vif.addr, localaddr) != 0) | ||
854 | continue; | ||
851 | if (!sta->uploaded) | 855 | if (!sta->uploaded) |
852 | return NULL; | 856 | return NULL; |
853 | return &sta->sta; | 857 | return &sta->sta; |
@@ -855,7 +859,7 @@ struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw, | |||
855 | 859 | ||
856 | return NULL; | 860 | return NULL; |
857 | } | 861 | } |
858 | EXPORT_SYMBOL_GPL(ieee80211_find_sta_by_hw); | 862 | EXPORT_SYMBOL_GPL(ieee80211_find_sta_by_ifaddr); |
859 | 863 | ||
860 | struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif, | 864 | struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif, |
861 | const u8 *addr) | 865 | const u8 *addr) |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 54262e72376..9265acadef3 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -79,6 +79,7 @@ enum ieee80211_sta_info_flags { | |||
79 | * @dialog_token: dialog token for aggregation session | 79 | * @dialog_token: dialog token for aggregation session |
80 | * @state: session state (see above) | 80 | * @state: session state (see above) |
81 | * @stop_initiator: initiator of a session stop | 81 | * @stop_initiator: initiator of a session stop |
82 | * @tx_stop: TX DelBA frame when stopping | ||
82 | * | 83 | * |
83 | * This structure is protected by RCU and the per-station | 84 | * This structure is protected by RCU and the per-station |
84 | * spinlock. Assignments to the array holding it must hold | 85 | * spinlock. Assignments to the array holding it must hold |
@@ -95,6 +96,7 @@ struct tid_ampdu_tx { | |||
95 | unsigned long state; | 96 | unsigned long state; |
96 | u8 dialog_token; | 97 | u8 dialog_token; |
97 | u8 stop_initiator; | 98 | u8 stop_initiator; |
99 | bool tx_stop; | ||
98 | }; | 100 | }; |
99 | 101 | ||
100 | /** | 102 | /** |
@@ -103,6 +105,7 @@ struct tid_ampdu_tx { | |||
103 | * @reorder_buf: buffer to reorder incoming aggregated MPDUs | 105 | * @reorder_buf: buffer to reorder incoming aggregated MPDUs |
104 | * @reorder_time: jiffies when skb was added | 106 | * @reorder_time: jiffies when skb was added |
105 | * @session_timer: check if peer keeps Tx-ing on the TID (by timeout value) | 107 | * @session_timer: check if peer keeps Tx-ing on the TID (by timeout value) |
108 | * @reorder_timer: releases expired frames from the reorder buffer. | ||
106 | * @head_seq_num: head sequence number in reordering buffer. | 109 | * @head_seq_num: head sequence number in reordering buffer. |
107 | * @stored_mpdu_num: number of MPDUs in reordering buffer | 110 | * @stored_mpdu_num: number of MPDUs in reordering buffer |
108 | * @ssn: Starting Sequence Number expected to be aggregated. | 111 | * @ssn: Starting Sequence Number expected to be aggregated. |
@@ -110,20 +113,25 @@ struct tid_ampdu_tx { | |||
110 | * @timeout: reset timer value (in TUs). | 113 | * @timeout: reset timer value (in TUs). |
111 | * @dialog_token: dialog token for aggregation session | 114 | * @dialog_token: dialog token for aggregation session |
112 | * @rcu_head: RCU head used for freeing this struct | 115 | * @rcu_head: RCU head used for freeing this struct |
116 | * @reorder_lock: serializes access to reorder buffer, see below. | ||
113 | * | 117 | * |
114 | * This structure is protected by RCU and the per-station | 118 | * This structure is protected by RCU and the per-station |
115 | * spinlock. Assignments to the array holding it must hold | 119 | * spinlock. Assignments to the array holding it must hold |
116 | * the spinlock, only the RX path can access it under RCU | 120 | * the spinlock. |
117 | * lock-free. The RX path, since it is single-threaded, | 121 | * |
118 | * can even modify the structure without locking since the | 122 | * The @reorder_lock is used to protect the variables and |
119 | * only other modifications to it are done when the struct | 123 | * arrays such as @reorder_buf, @reorder_time, @head_seq_num, |
120 | * can not yet or no longer be found by the RX path. | 124 | * @stored_mpdu_num and @reorder_time from being corrupted by |
125 | * concurrent access of the RX path and the expired frame | ||
126 | * release timer. | ||
121 | */ | 127 | */ |
122 | struct tid_ampdu_rx { | 128 | struct tid_ampdu_rx { |
123 | struct rcu_head rcu_head; | 129 | struct rcu_head rcu_head; |
130 | spinlock_t reorder_lock; | ||
124 | struct sk_buff **reorder_buf; | 131 | struct sk_buff **reorder_buf; |
125 | unsigned long *reorder_time; | 132 | unsigned long *reorder_time; |
126 | struct timer_list session_timer; | 133 | struct timer_list session_timer; |
134 | struct timer_list reorder_timer; | ||
127 | u16 head_seq_num; | 135 | u16 head_seq_num; |
128 | u16 stored_mpdu_num; | 136 | u16 stored_mpdu_num; |
129 | u16 ssn; | 137 | u16 ssn; |
@@ -191,7 +199,8 @@ enum plink_state { | |||
191 | * @hnext: hash table linked list pointer | 199 | * @hnext: hash table linked list pointer |
192 | * @local: pointer to the global information | 200 | * @local: pointer to the global information |
193 | * @sdata: virtual interface this station belongs to | 201 | * @sdata: virtual interface this station belongs to |
194 | * @key: peer key negotiated with this station, if any | 202 | * @ptk: peer key negotiated with this station, if any |
203 | * @gtk: group keys negotiated with this station, if any | ||
195 | * @rate_ctrl: rate control algorithm reference | 204 | * @rate_ctrl: rate control algorithm reference |
196 | * @rate_ctrl_priv: rate control private per-STA pointer | 205 | * @rate_ctrl_priv: rate control private per-STA pointer |
197 | * @last_tx_rate: rate used for last transmit, to report to userspace as | 206 | * @last_tx_rate: rate used for last transmit, to report to userspace as |
@@ -246,7 +255,8 @@ struct sta_info { | |||
246 | struct sta_info *hnext; | 255 | struct sta_info *hnext; |
247 | struct ieee80211_local *local; | 256 | struct ieee80211_local *local; |
248 | struct ieee80211_sub_if_data *sdata; | 257 | struct ieee80211_sub_if_data *sdata; |
249 | struct ieee80211_key *key; | 258 | struct ieee80211_key *gtk[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS]; |
259 | struct ieee80211_key *ptk; | ||
250 | struct rate_control_ref *rate_ctrl; | 260 | struct rate_control_ref *rate_ctrl; |
251 | void *rate_ctrl_priv; | 261 | void *rate_ctrl_priv; |
252 | spinlock_t lock; | 262 | spinlock_t lock; |
diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 34da67995d9..3153c19893b 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c | |||
@@ -58,6 +58,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
58 | info->control.vif = &sta->sdata->vif; | 58 | info->control.vif = &sta->sdata->vif; |
59 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING | | 59 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING | |
60 | IEEE80211_TX_INTFL_RETRANSMISSION; | 60 | IEEE80211_TX_INTFL_RETRANSMISSION; |
61 | info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS; | ||
61 | 62 | ||
62 | sta->tx_filtered_count++; | 63 | sta->tx_filtered_count++; |
63 | 64 | ||
@@ -114,11 +115,10 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
114 | 115 | ||
115 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 116 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
116 | if (net_ratelimit()) | 117 | if (net_ratelimit()) |
117 | printk(KERN_DEBUG "%s: dropped TX filtered frame, " | 118 | wiphy_debug(local->hw.wiphy, |
118 | "queue_len=%d PS=%d @%lu\n", | 119 | "dropped TX filtered frame, queue_len=%d PS=%d @%lu\n", |
119 | wiphy_name(local->hw.wiphy), | 120 | skb_queue_len(&sta->tx_filtered), |
120 | skb_queue_len(&sta->tx_filtered), | 121 | !!test_sta_flags(sta, WLAN_STA_PS_STA), jiffies); |
121 | !!test_sta_flags(sta, WLAN_STA_PS_STA), jiffies); | ||
122 | #endif | 122 | #endif |
123 | dev_kfree_skb(skb); | 123 | dev_kfree_skb(skb); |
124 | } | 124 | } |
@@ -176,7 +176,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
176 | 176 | ||
177 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { | 177 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { |
178 | /* the HW cannot have attempted that rate */ | 178 | /* the HW cannot have attempted that rate */ |
179 | if (i >= hw->max_rates) { | 179 | if (i >= hw->max_report_rates) { |
180 | info->status.rates[i].idx = -1; | 180 | info->status.rates[i].idx = -1; |
181 | info->status.rates[i].count = 0; | 181 | info->status.rates[i].count = 0; |
182 | } else if (info->status.rates[i].idx >= 0) { | 182 | } else if (info->status.rates[i].idx >= 0) { |
@@ -296,7 +296,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
296 | } | 296 | } |
297 | 297 | ||
298 | if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX) | 298 | if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX) |
299 | cfg80211_action_tx_status( | 299 | cfg80211_mgmt_tx_status( |
300 | skb->dev, (unsigned long) skb, skb->data, skb->len, | 300 | skb->dev, (unsigned long) skb, skb->data, skb->len, |
301 | !!(info->flags & IEEE80211_TX_STAT_ACK), GFP_ATOMIC); | 301 | !!(info->flags & IEEE80211_TX_STAT_ACK), GFP_ATOMIC); |
302 | 302 | ||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index c54db966926..96c59430950 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -273,6 +273,9 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) | |||
273 | */ | 273 | */ |
274 | return TX_DROP; | 274 | return TX_DROP; |
275 | 275 | ||
276 | if (tx->sdata->vif.type == NL80211_IFTYPE_WDS) | ||
277 | return TX_CONTINUE; | ||
278 | |||
276 | if (tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT) | 279 | if (tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT) |
277 | return TX_CONTINUE; | 280 | return TX_CONTINUE; |
278 | 281 | ||
@@ -351,8 +354,8 @@ static void purge_old_ps_buffers(struct ieee80211_local *local) | |||
351 | 354 | ||
352 | local->total_ps_buffered = total; | 355 | local->total_ps_buffered = total; |
353 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 356 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
354 | printk(KERN_DEBUG "%s: PS buffers full - purged %d frames\n", | 357 | wiphy_debug(local->hw.wiphy, "PS buffers full - purged %d frames\n", |
355 | wiphy_name(local->hw.wiphy), purged); | 358 | purged); |
356 | #endif | 359 | #endif |
357 | } | 360 | } |
358 | 361 | ||
@@ -509,6 +512,18 @@ ieee80211_tx_h_ps_buf(struct ieee80211_tx_data *tx) | |||
509 | } | 512 | } |
510 | 513 | ||
511 | static ieee80211_tx_result debug_noinline | 514 | static ieee80211_tx_result debug_noinline |
515 | ieee80211_tx_h_check_control_port_protocol(struct ieee80211_tx_data *tx) | ||
516 | { | ||
517 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | ||
518 | |||
519 | if (unlikely(tx->sdata->control_port_protocol == tx->skb->protocol && | ||
520 | tx->sdata->control_port_no_encrypt)) | ||
521 | info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; | ||
522 | |||
523 | return TX_CONTINUE; | ||
524 | } | ||
525 | |||
526 | static ieee80211_tx_result debug_noinline | ||
512 | ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | 527 | ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) |
513 | { | 528 | { |
514 | struct ieee80211_key *key = NULL; | 529 | struct ieee80211_key *key = NULL; |
@@ -517,7 +532,7 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | |||
517 | 532 | ||
518 | if (unlikely(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) | 533 | if (unlikely(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) |
519 | tx->key = NULL; | 534 | tx->key = NULL; |
520 | else if (tx->sta && (key = rcu_dereference(tx->sta->key))) | 535 | else if (tx->sta && (key = rcu_dereference(tx->sta->ptk))) |
521 | tx->key = key; | 536 | tx->key = key; |
522 | else if (ieee80211_is_mgmt(hdr->frame_control) && | 537 | else if (ieee80211_is_mgmt(hdr->frame_control) && |
523 | is_multicast_ether_addr(hdr->addr1) && | 538 | is_multicast_ether_addr(hdr->addr1) && |
@@ -527,7 +542,7 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | |||
527 | else if ((key = rcu_dereference(tx->sdata->default_key))) | 542 | else if ((key = rcu_dereference(tx->sdata->default_key))) |
528 | tx->key = key; | 543 | tx->key = key; |
529 | else if (tx->sdata->drop_unencrypted && | 544 | else if (tx->sdata->drop_unencrypted && |
530 | (tx->skb->protocol != cpu_to_be16(ETH_P_PAE)) && | 545 | (tx->skb->protocol != tx->sdata->control_port_protocol) && |
531 | !(info->flags & IEEE80211_TX_CTL_INJECTED) && | 546 | !(info->flags & IEEE80211_TX_CTL_INJECTED) && |
532 | (!ieee80211_is_robust_mgmt_frame(hdr) || | 547 | (!ieee80211_is_robust_mgmt_frame(hdr) || |
533 | (ieee80211_is_action(hdr->frame_control) && | 548 | (ieee80211_is_action(hdr->frame_control) && |
@@ -543,15 +558,16 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | |||
543 | tx->key->tx_rx_count++; | 558 | tx->key->tx_rx_count++; |
544 | /* TODO: add threshold stuff again */ | 559 | /* TODO: add threshold stuff again */ |
545 | 560 | ||
546 | switch (tx->key->conf.alg) { | 561 | switch (tx->key->conf.cipher) { |
547 | case ALG_WEP: | 562 | case WLAN_CIPHER_SUITE_WEP40: |
563 | case WLAN_CIPHER_SUITE_WEP104: | ||
548 | if (ieee80211_is_auth(hdr->frame_control)) | 564 | if (ieee80211_is_auth(hdr->frame_control)) |
549 | break; | 565 | break; |
550 | case ALG_TKIP: | 566 | case WLAN_CIPHER_SUITE_TKIP: |
551 | if (!ieee80211_is_data_present(hdr->frame_control)) | 567 | if (!ieee80211_is_data_present(hdr->frame_control)) |
552 | tx->key = NULL; | 568 | tx->key = NULL; |
553 | break; | 569 | break; |
554 | case ALG_CCMP: | 570 | case WLAN_CIPHER_SUITE_CCMP: |
555 | if (!ieee80211_is_data_present(hdr->frame_control) && | 571 | if (!ieee80211_is_data_present(hdr->frame_control) && |
556 | !ieee80211_use_mfp(hdr->frame_control, tx->sta, | 572 | !ieee80211_use_mfp(hdr->frame_control, tx->sta, |
557 | tx->skb)) | 573 | tx->skb)) |
@@ -561,7 +577,7 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | |||
561 | IEEE80211_KEY_FLAG_SW_MGMT) && | 577 | IEEE80211_KEY_FLAG_SW_MGMT) && |
562 | ieee80211_is_mgmt(hdr->frame_control); | 578 | ieee80211_is_mgmt(hdr->frame_control); |
563 | break; | 579 | break; |
564 | case ALG_AES_CMAC: | 580 | case WLAN_CIPHER_SUITE_AES_CMAC: |
565 | if (!ieee80211_is_mgmt(hdr->frame_control)) | 581 | if (!ieee80211_is_mgmt(hdr->frame_control)) |
566 | tx->key = NULL; | 582 | tx->key = NULL; |
567 | break; | 583 | break; |
@@ -946,22 +962,31 @@ ieee80211_tx_h_stats(struct ieee80211_tx_data *tx) | |||
946 | static ieee80211_tx_result debug_noinline | 962 | static ieee80211_tx_result debug_noinline |
947 | ieee80211_tx_h_encrypt(struct ieee80211_tx_data *tx) | 963 | ieee80211_tx_h_encrypt(struct ieee80211_tx_data *tx) |
948 | { | 964 | { |
965 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | ||
966 | |||
949 | if (!tx->key) | 967 | if (!tx->key) |
950 | return TX_CONTINUE; | 968 | return TX_CONTINUE; |
951 | 969 | ||
952 | switch (tx->key->conf.alg) { | 970 | switch (tx->key->conf.cipher) { |
953 | case ALG_WEP: | 971 | case WLAN_CIPHER_SUITE_WEP40: |
972 | case WLAN_CIPHER_SUITE_WEP104: | ||
954 | return ieee80211_crypto_wep_encrypt(tx); | 973 | return ieee80211_crypto_wep_encrypt(tx); |
955 | case ALG_TKIP: | 974 | case WLAN_CIPHER_SUITE_TKIP: |
956 | return ieee80211_crypto_tkip_encrypt(tx); | 975 | return ieee80211_crypto_tkip_encrypt(tx); |
957 | case ALG_CCMP: | 976 | case WLAN_CIPHER_SUITE_CCMP: |
958 | return ieee80211_crypto_ccmp_encrypt(tx); | 977 | return ieee80211_crypto_ccmp_encrypt(tx); |
959 | case ALG_AES_CMAC: | 978 | case WLAN_CIPHER_SUITE_AES_CMAC: |
960 | return ieee80211_crypto_aes_cmac_encrypt(tx); | 979 | return ieee80211_crypto_aes_cmac_encrypt(tx); |
980 | default: | ||
981 | /* handle hw-only algorithm */ | ||
982 | if (info->control.hw_key) { | ||
983 | ieee80211_tx_set_protected(tx); | ||
984 | return TX_CONTINUE; | ||
985 | } | ||
986 | break; | ||
987 | |||
961 | } | 988 | } |
962 | 989 | ||
963 | /* not reached */ | ||
964 | WARN_ON(1); | ||
965 | return TX_DROP; | 990 | return TX_DROP; |
966 | } | 991 | } |
967 | 992 | ||
@@ -1339,6 +1364,7 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx) | |||
1339 | CALL_TXH(ieee80211_tx_h_dynamic_ps); | 1364 | CALL_TXH(ieee80211_tx_h_dynamic_ps); |
1340 | CALL_TXH(ieee80211_tx_h_check_assoc); | 1365 | CALL_TXH(ieee80211_tx_h_check_assoc); |
1341 | CALL_TXH(ieee80211_tx_h_ps_buf); | 1366 | CALL_TXH(ieee80211_tx_h_ps_buf); |
1367 | CALL_TXH(ieee80211_tx_h_check_control_port_protocol); | ||
1342 | CALL_TXH(ieee80211_tx_h_select_key); | 1368 | CALL_TXH(ieee80211_tx_h_select_key); |
1343 | if (!(tx->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)) | 1369 | if (!(tx->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)) |
1344 | CALL_TXH(ieee80211_tx_h_rate_ctrl); | 1370 | CALL_TXH(ieee80211_tx_h_rate_ctrl); |
@@ -1511,8 +1537,8 @@ static int ieee80211_skb_resize(struct ieee80211_local *local, | |||
1511 | I802_DEBUG_INC(local->tx_expand_skb_head); | 1537 | I802_DEBUG_INC(local->tx_expand_skb_head); |
1512 | 1538 | ||
1513 | if (pskb_expand_head(skb, head_need, tail_need, GFP_ATOMIC)) { | 1539 | if (pskb_expand_head(skb, head_need, tail_need, GFP_ATOMIC)) { |
1514 | printk(KERN_DEBUG "%s: failed to reallocate TX buffer\n", | 1540 | wiphy_debug(local->hw.wiphy, |
1515 | wiphy_name(local->hw.wiphy)); | 1541 | "failed to reallocate TX buffer\n"); |
1516 | return -ENOMEM; | 1542 | return -ENOMEM; |
1517 | } | 1543 | } |
1518 | 1544 | ||
@@ -1586,6 +1612,7 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | |||
1586 | return; | 1612 | return; |
1587 | } | 1613 | } |
1588 | 1614 | ||
1615 | hdr = (struct ieee80211_hdr *) skb->data; | ||
1589 | info->control.vif = &sdata->vif; | 1616 | info->control.vif = &sdata->vif; |
1590 | 1617 | ||
1591 | if (ieee80211_vif_is_mesh(&sdata->vif) && | 1618 | if (ieee80211_vif_is_mesh(&sdata->vif) && |
@@ -1699,7 +1726,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1699 | u16 ethertype, hdrlen, meshhdrlen = 0; | 1726 | u16 ethertype, hdrlen, meshhdrlen = 0; |
1700 | __le16 fc; | 1727 | __le16 fc; |
1701 | struct ieee80211_hdr hdr; | 1728 | struct ieee80211_hdr hdr; |
1702 | struct ieee80211s_hdr mesh_hdr; | 1729 | struct ieee80211s_hdr mesh_hdr __maybe_unused; |
1703 | const u8 *encaps_data; | 1730 | const u8 *encaps_data; |
1704 | int encaps_len, skip_header_bytes; | 1731 | int encaps_len, skip_header_bytes; |
1705 | int nh_pos, h_pos; | 1732 | int nh_pos, h_pos; |
@@ -1816,7 +1843,8 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1816 | #endif | 1843 | #endif |
1817 | case NL80211_IFTYPE_STATION: | 1844 | case NL80211_IFTYPE_STATION: |
1818 | memcpy(hdr.addr1, sdata->u.mgd.bssid, ETH_ALEN); | 1845 | memcpy(hdr.addr1, sdata->u.mgd.bssid, ETH_ALEN); |
1819 | if (sdata->u.mgd.use_4addr && ethertype != ETH_P_PAE) { | 1846 | if (sdata->u.mgd.use_4addr && |
1847 | cpu_to_be16(ethertype) != sdata->control_port_protocol) { | ||
1820 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); | 1848 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); |
1821 | /* RA TA DA SA */ | 1849 | /* RA TA DA SA */ |
1822 | memcpy(hdr.addr2, sdata->vif.addr, ETH_ALEN); | 1850 | memcpy(hdr.addr2, sdata->vif.addr, ETH_ALEN); |
@@ -1869,7 +1897,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1869 | if (!ieee80211_vif_is_mesh(&sdata->vif) && | 1897 | if (!ieee80211_vif_is_mesh(&sdata->vif) && |
1870 | unlikely(!is_multicast_ether_addr(hdr.addr1) && | 1898 | unlikely(!is_multicast_ether_addr(hdr.addr1) && |
1871 | !(sta_flags & WLAN_STA_AUTHORIZED) && | 1899 | !(sta_flags & WLAN_STA_AUTHORIZED) && |
1872 | !(ethertype == ETH_P_PAE && | 1900 | !(cpu_to_be16(ethertype) == sdata->control_port_protocol && |
1873 | compare_ether_addr(sdata->vif.addr, | 1901 | compare_ether_addr(sdata->vif.addr, |
1874 | skb->data + ETH_ALEN) == 0))) { | 1902 | skb->data + ETH_ALEN) == 0))) { |
1875 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 1903 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
@@ -2068,8 +2096,7 @@ void ieee80211_tx_pending(unsigned long data) | |||
2068 | 2096 | ||
2069 | if (skb_queue_empty(&local->pending[i])) | 2097 | if (skb_queue_empty(&local->pending[i])) |
2070 | list_for_each_entry_rcu(sdata, &local->interfaces, list) | 2098 | list_for_each_entry_rcu(sdata, &local->interfaces, list) |
2071 | netif_tx_wake_queue( | 2099 | netif_wake_subqueue(sdata->dev, i); |
2072 | netdev_get_tx_queue(sdata->dev, i)); | ||
2073 | } | 2100 | } |
2074 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | 2101 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); |
2075 | 2102 | ||
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 748387d45bc..0b6fc92bc0d 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -283,8 +283,11 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue, | |||
283 | 283 | ||
284 | if (skb_queue_empty(&local->pending[queue])) { | 284 | if (skb_queue_empty(&local->pending[queue])) { |
285 | rcu_read_lock(); | 285 | rcu_read_lock(); |
286 | list_for_each_entry_rcu(sdata, &local->interfaces, list) | 286 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
287 | netif_tx_wake_queue(netdev_get_tx_queue(sdata->dev, queue)); | 287 | if (test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state)) |
288 | continue; | ||
289 | netif_wake_subqueue(sdata->dev, queue); | ||
290 | } | ||
288 | rcu_read_unlock(); | 291 | rcu_read_unlock(); |
289 | } else | 292 | } else |
290 | tasklet_schedule(&local->tx_pending_tasklet); | 293 | tasklet_schedule(&local->tx_pending_tasklet); |
@@ -323,7 +326,7 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue, | |||
323 | 326 | ||
324 | rcu_read_lock(); | 327 | rcu_read_lock(); |
325 | list_for_each_entry_rcu(sdata, &local->interfaces, list) | 328 | list_for_each_entry_rcu(sdata, &local->interfaces, list) |
326 | netif_tx_stop_queue(netdev_get_tx_queue(sdata->dev, queue)); | 329 | netif_stop_subqueue(sdata->dev, queue); |
327 | rcu_read_unlock(); | 330 | rcu_read_unlock(); |
328 | } | 331 | } |
329 | 332 | ||
@@ -471,16 +474,10 @@ void ieee80211_iterate_active_interfaces( | |||
471 | 474 | ||
472 | list_for_each_entry(sdata, &local->interfaces, list) { | 475 | list_for_each_entry(sdata, &local->interfaces, list) { |
473 | switch (sdata->vif.type) { | 476 | switch (sdata->vif.type) { |
474 | case __NL80211_IFTYPE_AFTER_LAST: | ||
475 | case NL80211_IFTYPE_UNSPECIFIED: | ||
476 | case NL80211_IFTYPE_MONITOR: | 477 | case NL80211_IFTYPE_MONITOR: |
477 | case NL80211_IFTYPE_AP_VLAN: | 478 | case NL80211_IFTYPE_AP_VLAN: |
478 | continue; | 479 | continue; |
479 | case NL80211_IFTYPE_AP: | 480 | default: |
480 | case NL80211_IFTYPE_STATION: | ||
481 | case NL80211_IFTYPE_ADHOC: | ||
482 | case NL80211_IFTYPE_WDS: | ||
483 | case NL80211_IFTYPE_MESH_POINT: | ||
484 | break; | 481 | break; |
485 | } | 482 | } |
486 | if (ieee80211_sdata_running(sdata)) | 483 | if (ieee80211_sdata_running(sdata)) |
@@ -505,16 +502,10 @@ void ieee80211_iterate_active_interfaces_atomic( | |||
505 | 502 | ||
506 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | 503 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
507 | switch (sdata->vif.type) { | 504 | switch (sdata->vif.type) { |
508 | case __NL80211_IFTYPE_AFTER_LAST: | ||
509 | case NL80211_IFTYPE_UNSPECIFIED: | ||
510 | case NL80211_IFTYPE_MONITOR: | 505 | case NL80211_IFTYPE_MONITOR: |
511 | case NL80211_IFTYPE_AP_VLAN: | 506 | case NL80211_IFTYPE_AP_VLAN: |
512 | continue; | 507 | continue; |
513 | case NL80211_IFTYPE_AP: | 508 | default: |
514 | case NL80211_IFTYPE_STATION: | ||
515 | case NL80211_IFTYPE_ADHOC: | ||
516 | case NL80211_IFTYPE_WDS: | ||
517 | case NL80211_IFTYPE_MESH_POINT: | ||
518 | break; | 509 | break; |
519 | } | 510 | } |
520 | if (ieee80211_sdata_running(sdata)) | 511 | if (ieee80211_sdata_running(sdata)) |
@@ -904,26 +895,34 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, | |||
904 | 895 | ||
905 | int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, | 896 | int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, |
906 | const u8 *ie, size_t ie_len, | 897 | const u8 *ie, size_t ie_len, |
907 | enum ieee80211_band band) | 898 | enum ieee80211_band band, u32 rate_mask, |
899 | u8 channel) | ||
908 | { | 900 | { |
909 | struct ieee80211_supported_band *sband; | 901 | struct ieee80211_supported_band *sband; |
910 | u8 *pos; | 902 | u8 *pos; |
911 | size_t offset = 0, noffset; | 903 | size_t offset = 0, noffset; |
912 | int supp_rates_len, i; | 904 | int supp_rates_len, i; |
905 | u8 rates[32]; | ||
906 | int num_rates; | ||
907 | int ext_rates_len; | ||
913 | 908 | ||
914 | sband = local->hw.wiphy->bands[band]; | 909 | sband = local->hw.wiphy->bands[band]; |
915 | 910 | ||
916 | pos = buffer; | 911 | pos = buffer; |
917 | 912 | ||
918 | supp_rates_len = min_t(int, sband->n_bitrates, 8); | 913 | num_rates = 0; |
914 | for (i = 0; i < sband->n_bitrates; i++) { | ||
915 | if ((BIT(i) & rate_mask) == 0) | ||
916 | continue; /* skip rate */ | ||
917 | rates[num_rates++] = (u8) (sband->bitrates[i].bitrate / 5); | ||
918 | } | ||
919 | |||
920 | supp_rates_len = min_t(int, num_rates, 8); | ||
919 | 921 | ||
920 | *pos++ = WLAN_EID_SUPP_RATES; | 922 | *pos++ = WLAN_EID_SUPP_RATES; |
921 | *pos++ = supp_rates_len; | 923 | *pos++ = supp_rates_len; |
922 | 924 | memcpy(pos, rates, supp_rates_len); | |
923 | for (i = 0; i < supp_rates_len; i++) { | 925 | pos += supp_rates_len; |
924 | int rate = sband->bitrates[i].bitrate; | ||
925 | *pos++ = (u8) (rate / 5); | ||
926 | } | ||
927 | 926 | ||
928 | /* insert "request information" if in custom IEs */ | 927 | /* insert "request information" if in custom IEs */ |
929 | if (ie && ie_len) { | 928 | if (ie && ie_len) { |
@@ -941,14 +940,18 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, | |||
941 | offset = noffset; | 940 | offset = noffset; |
942 | } | 941 | } |
943 | 942 | ||
944 | if (sband->n_bitrates > i) { | 943 | ext_rates_len = num_rates - supp_rates_len; |
944 | if (ext_rates_len > 0) { | ||
945 | *pos++ = WLAN_EID_EXT_SUPP_RATES; | 945 | *pos++ = WLAN_EID_EXT_SUPP_RATES; |
946 | *pos++ = sband->n_bitrates - i; | 946 | *pos++ = ext_rates_len; |
947 | memcpy(pos, rates + supp_rates_len, ext_rates_len); | ||
948 | pos += ext_rates_len; | ||
949 | } | ||
947 | 950 | ||
948 | for (; i < sband->n_bitrates; i++) { | 951 | if (channel && sband->band == IEEE80211_BAND_2GHZ) { |
949 | int rate = sband->bitrates[i].bitrate; | 952 | *pos++ = WLAN_EID_DS_PARAMS; |
950 | *pos++ = (u8) (rate / 5); | 953 | *pos++ = 1; |
951 | } | 954 | *pos++ = channel; |
952 | } | 955 | } |
953 | 956 | ||
954 | /* insert custom IEs that go before HT */ | 957 | /* insert custom IEs that go before HT */ |
@@ -1017,6 +1020,7 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, | |||
1017 | struct ieee80211_mgmt *mgmt; | 1020 | struct ieee80211_mgmt *mgmt; |
1018 | size_t buf_len; | 1021 | size_t buf_len; |
1019 | u8 *buf; | 1022 | u8 *buf; |
1023 | u8 chan; | ||
1020 | 1024 | ||
1021 | /* FIXME: come up with a proper value */ | 1025 | /* FIXME: come up with a proper value */ |
1022 | buf = kmalloc(200 + ie_len, GFP_KERNEL); | 1026 | buf = kmalloc(200 + ie_len, GFP_KERNEL); |
@@ -1026,8 +1030,14 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, | |||
1026 | return; | 1030 | return; |
1027 | } | 1031 | } |
1028 | 1032 | ||
1033 | chan = ieee80211_frequency_to_channel( | ||
1034 | local->hw.conf.channel->center_freq); | ||
1035 | |||
1029 | buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len, | 1036 | buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len, |
1030 | local->hw.conf.channel->band); | 1037 | local->hw.conf.channel->band, |
1038 | sdata->rc_rateidx_mask | ||
1039 | [local->hw.conf.channel->band], | ||
1040 | chan); | ||
1031 | 1041 | ||
1032 | skb = ieee80211_probereq_get(&local->hw, &sdata->vif, | 1042 | skb = ieee80211_probereq_get(&local->hw, &sdata->vif, |
1033 | ssid, ssid_len, | 1043 | ssid, ssid_len, |
@@ -1189,7 +1199,9 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1189 | /* ignore virtual */ | 1199 | /* ignore virtual */ |
1190 | break; | 1200 | break; |
1191 | case NL80211_IFTYPE_UNSPECIFIED: | 1201 | case NL80211_IFTYPE_UNSPECIFIED: |
1192 | case __NL80211_IFTYPE_AFTER_LAST: | 1202 | case NUM_NL80211_IFTYPES: |
1203 | case NL80211_IFTYPE_P2P_CLIENT: | ||
1204 | case NL80211_IFTYPE_P2P_GO: | ||
1193 | WARN_ON(1); | 1205 | WARN_ON(1); |
1194 | break; | 1206 | break; |
1195 | } | 1207 | } |
@@ -1209,7 +1221,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1209 | mutex_lock(&local->sta_mtx); | 1221 | mutex_lock(&local->sta_mtx); |
1210 | 1222 | ||
1211 | list_for_each_entry(sta, &local->sta_list, list) { | 1223 | list_for_each_entry(sta, &local->sta_list, list) { |
1212 | ieee80211_sta_tear_down_BA_sessions(sta); | 1224 | ieee80211_sta_tear_down_BA_sessions(sta, true); |
1213 | clear_sta_flags(sta, WLAN_STA_BLOCK_BA); | 1225 | clear_sta_flags(sta, WLAN_STA_BLOCK_BA); |
1214 | } | 1226 | } |
1215 | 1227 | ||
@@ -1285,17 +1297,13 @@ static int check_mgd_smps(struct ieee80211_if_managed *ifmgd, | |||
1285 | } | 1297 | } |
1286 | 1298 | ||
1287 | /* must hold iflist_mtx */ | 1299 | /* must hold iflist_mtx */ |
1288 | void ieee80211_recalc_smps(struct ieee80211_local *local, | 1300 | void ieee80211_recalc_smps(struct ieee80211_local *local) |
1289 | struct ieee80211_sub_if_data *forsdata) | ||
1290 | { | 1301 | { |
1291 | struct ieee80211_sub_if_data *sdata; | 1302 | struct ieee80211_sub_if_data *sdata; |
1292 | enum ieee80211_smps_mode smps_mode = IEEE80211_SMPS_OFF; | 1303 | enum ieee80211_smps_mode smps_mode = IEEE80211_SMPS_OFF; |
1293 | int count = 0; | 1304 | int count = 0; |
1294 | 1305 | ||
1295 | if (forsdata) | 1306 | lockdep_assert_held(&local->iflist_mtx); |
1296 | WARN_ON(!mutex_is_locked(&forsdata->u.mgd.mtx)); | ||
1297 | |||
1298 | WARN_ON(!mutex_is_locked(&local->iflist_mtx)); | ||
1299 | 1307 | ||
1300 | /* | 1308 | /* |
1301 | * This function could be improved to handle multiple | 1309 | * This function could be improved to handle multiple |
@@ -1308,22 +1316,12 @@ void ieee80211_recalc_smps(struct ieee80211_local *local, | |||
1308 | */ | 1316 | */ |
1309 | 1317 | ||
1310 | list_for_each_entry(sdata, &local->interfaces, list) { | 1318 | list_for_each_entry(sdata, &local->interfaces, list) { |
1311 | if (!netif_running(sdata->dev)) | 1319 | if (!ieee80211_sdata_running(sdata)) |
1312 | continue; | 1320 | continue; |
1313 | if (sdata->vif.type != NL80211_IFTYPE_STATION) | 1321 | if (sdata->vif.type != NL80211_IFTYPE_STATION) |
1314 | goto set; | 1322 | goto set; |
1315 | if (sdata != forsdata) { | 1323 | |
1316 | /* | 1324 | count += check_mgd_smps(&sdata->u.mgd, &smps_mode); |
1317 | * This nested is ok -- we are holding the iflist_mtx | ||
1318 | * so can't get here twice or so. But it's required | ||
1319 | * since normally we acquire it first and then the | ||
1320 | * iflist_mtx. | ||
1321 | */ | ||
1322 | mutex_lock_nested(&sdata->u.mgd.mtx, SINGLE_DEPTH_NESTING); | ||
1323 | count += check_mgd_smps(&sdata->u.mgd, &smps_mode); | ||
1324 | mutex_unlock(&sdata->u.mgd.mtx); | ||
1325 | } else | ||
1326 | count += check_mgd_smps(&sdata->u.mgd, &smps_mode); | ||
1327 | 1325 | ||
1328 | if (count > 1) { | 1326 | if (count > 1) { |
1329 | smps_mode = IEEE80211_SMPS_OFF; | 1327 | smps_mode = IEEE80211_SMPS_OFF; |
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c index 9ebc8d8a1f5..2ff6d1e3ed2 100644 --- a/net/mac80211/wep.c +++ b/net/mac80211/wep.c | |||
@@ -222,7 +222,7 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local, | |||
222 | struct ieee80211_key *key) | 222 | struct ieee80211_key *key) |
223 | { | 223 | { |
224 | u32 klen; | 224 | u32 klen; |
225 | u8 *rc4key; | 225 | u8 rc4key[3 + WLAN_KEY_LEN_WEP104]; |
226 | u8 keyidx; | 226 | u8 keyidx; |
227 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 227 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
228 | unsigned int hdrlen; | 228 | unsigned int hdrlen; |
@@ -240,15 +240,11 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local, | |||
240 | 240 | ||
241 | keyidx = skb->data[hdrlen + 3] >> 6; | 241 | keyidx = skb->data[hdrlen + 3] >> 6; |
242 | 242 | ||
243 | if (!key || keyidx != key->conf.keyidx || key->conf.alg != ALG_WEP) | 243 | if (!key || keyidx != key->conf.keyidx) |
244 | return -1; | 244 | return -1; |
245 | 245 | ||
246 | klen = 3 + key->conf.keylen; | 246 | klen = 3 + key->conf.keylen; |
247 | 247 | ||
248 | rc4key = kmalloc(klen, GFP_ATOMIC); | ||
249 | if (!rc4key) | ||
250 | return -1; | ||
251 | |||
252 | /* Prepend 24-bit IV to RC4 key */ | 248 | /* Prepend 24-bit IV to RC4 key */ |
253 | memcpy(rc4key, skb->data + hdrlen, 3); | 249 | memcpy(rc4key, skb->data + hdrlen, 3); |
254 | 250 | ||
@@ -260,8 +256,6 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local, | |||
260 | len)) | 256 | len)) |
261 | ret = -1; | 257 | ret = -1; |
262 | 258 | ||
263 | kfree(rc4key); | ||
264 | |||
265 | /* Trim ICV */ | 259 | /* Trim ICV */ |
266 | skb_trim(skb, skb->len - WEP_ICV_LEN); | 260 | skb_trim(skb, skb->len - WEP_ICV_LEN); |
267 | 261 | ||
diff --git a/net/mac80211/work.c b/net/mac80211/work.c index 81d4ad64184..ae344d1ba05 100644 --- a/net/mac80211/work.c +++ b/net/mac80211/work.c | |||
@@ -43,7 +43,7 @@ enum work_action { | |||
43 | /* utils */ | 43 | /* utils */ |
44 | static inline void ASSERT_WORK_MTX(struct ieee80211_local *local) | 44 | static inline void ASSERT_WORK_MTX(struct ieee80211_local *local) |
45 | { | 45 | { |
46 | WARN_ON(!mutex_is_locked(&local->work_mtx)); | 46 | lockdep_assert_held(&local->mtx); |
47 | } | 47 | } |
48 | 48 | ||
49 | /* | 49 | /* |
@@ -757,7 +757,7 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local, | |||
757 | mgmt = (struct ieee80211_mgmt *) skb->data; | 757 | mgmt = (struct ieee80211_mgmt *) skb->data; |
758 | fc = le16_to_cpu(mgmt->frame_control); | 758 | fc = le16_to_cpu(mgmt->frame_control); |
759 | 759 | ||
760 | mutex_lock(&local->work_mtx); | 760 | mutex_lock(&local->mtx); |
761 | 761 | ||
762 | list_for_each_entry(wk, &local->work_list, list) { | 762 | list_for_each_entry(wk, &local->work_list, list) { |
763 | const u8 *bssid = NULL; | 763 | const u8 *bssid = NULL; |
@@ -833,7 +833,7 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local, | |||
833 | WARN(1, "unexpected: %d", rma); | 833 | WARN(1, "unexpected: %d", rma); |
834 | } | 834 | } |
835 | 835 | ||
836 | mutex_unlock(&local->work_mtx); | 836 | mutex_unlock(&local->mtx); |
837 | 837 | ||
838 | if (rma != WORK_ACT_DONE) | 838 | if (rma != WORK_ACT_DONE) |
839 | goto out; | 839 | goto out; |
@@ -845,9 +845,9 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local, | |||
845 | case WORK_DONE_REQUEUE: | 845 | case WORK_DONE_REQUEUE: |
846 | synchronize_rcu(); | 846 | synchronize_rcu(); |
847 | wk->started = false; /* restart */ | 847 | wk->started = false; /* restart */ |
848 | mutex_lock(&local->work_mtx); | 848 | mutex_lock(&local->mtx); |
849 | list_add_tail(&wk->list, &local->work_list); | 849 | list_add_tail(&wk->list, &local->work_list); |
850 | mutex_unlock(&local->work_mtx); | 850 | mutex_unlock(&local->mtx); |
851 | } | 851 | } |
852 | 852 | ||
853 | out: | 853 | out: |
@@ -888,9 +888,9 @@ static void ieee80211_work_work(struct work_struct *work) | |||
888 | while ((skb = skb_dequeue(&local->work_skb_queue))) | 888 | while ((skb = skb_dequeue(&local->work_skb_queue))) |
889 | ieee80211_work_rx_queued_mgmt(local, skb); | 889 | ieee80211_work_rx_queued_mgmt(local, skb); |
890 | 890 | ||
891 | ieee80211_recalc_idle(local); | 891 | mutex_lock(&local->mtx); |
892 | 892 | ||
893 | mutex_lock(&local->work_mtx); | 893 | ieee80211_recalc_idle(local); |
894 | 894 | ||
895 | list_for_each_entry_safe(wk, tmp, &local->work_list, list) { | 895 | list_for_each_entry_safe(wk, tmp, &local->work_list, list) { |
896 | bool started = wk->started; | 896 | bool started = wk->started; |
@@ -995,20 +995,16 @@ static void ieee80211_work_work(struct work_struct *work) | |||
995 | run_again(local, jiffies + HZ/2); | 995 | run_again(local, jiffies + HZ/2); |
996 | } | 996 | } |
997 | 997 | ||
998 | mutex_lock(&local->scan_mtx); | ||
999 | |||
1000 | if (list_empty(&local->work_list) && local->scan_req && | 998 | if (list_empty(&local->work_list) && local->scan_req && |
1001 | !local->scanning) | 999 | !local->scanning) |
1002 | ieee80211_queue_delayed_work(&local->hw, | 1000 | ieee80211_queue_delayed_work(&local->hw, |
1003 | &local->scan_work, | 1001 | &local->scan_work, |
1004 | round_jiffies_relative(0)); | 1002 | round_jiffies_relative(0)); |
1005 | 1003 | ||
1006 | mutex_unlock(&local->scan_mtx); | ||
1007 | |||
1008 | mutex_unlock(&local->work_mtx); | ||
1009 | |||
1010 | ieee80211_recalc_idle(local); | 1004 | ieee80211_recalc_idle(local); |
1011 | 1005 | ||
1006 | mutex_unlock(&local->mtx); | ||
1007 | |||
1012 | list_for_each_entry_safe(wk, tmp, &free_work, list) { | 1008 | list_for_each_entry_safe(wk, tmp, &free_work, list) { |
1013 | wk->done(wk, NULL); | 1009 | wk->done(wk, NULL); |
1014 | list_del(&wk->list); | 1010 | list_del(&wk->list); |
@@ -1035,16 +1031,15 @@ void ieee80211_add_work(struct ieee80211_work *wk) | |||
1035 | wk->started = false; | 1031 | wk->started = false; |
1036 | 1032 | ||
1037 | local = wk->sdata->local; | 1033 | local = wk->sdata->local; |
1038 | mutex_lock(&local->work_mtx); | 1034 | mutex_lock(&local->mtx); |
1039 | list_add_tail(&wk->list, &local->work_list); | 1035 | list_add_tail(&wk->list, &local->work_list); |
1040 | mutex_unlock(&local->work_mtx); | 1036 | mutex_unlock(&local->mtx); |
1041 | 1037 | ||
1042 | ieee80211_queue_work(&local->hw, &local->work_work); | 1038 | ieee80211_queue_work(&local->hw, &local->work_work); |
1043 | } | 1039 | } |
1044 | 1040 | ||
1045 | void ieee80211_work_init(struct ieee80211_local *local) | 1041 | void ieee80211_work_init(struct ieee80211_local *local) |
1046 | { | 1042 | { |
1047 | mutex_init(&local->work_mtx); | ||
1048 | INIT_LIST_HEAD(&local->work_list); | 1043 | INIT_LIST_HEAD(&local->work_list); |
1049 | setup_timer(&local->work_timer, ieee80211_work_timer, | 1044 | setup_timer(&local->work_timer, ieee80211_work_timer, |
1050 | (unsigned long)local); | 1045 | (unsigned long)local); |
@@ -1057,7 +1052,7 @@ void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata) | |||
1057 | struct ieee80211_local *local = sdata->local; | 1052 | struct ieee80211_local *local = sdata->local; |
1058 | struct ieee80211_work *wk; | 1053 | struct ieee80211_work *wk; |
1059 | 1054 | ||
1060 | mutex_lock(&local->work_mtx); | 1055 | mutex_lock(&local->mtx); |
1061 | list_for_each_entry(wk, &local->work_list, list) { | 1056 | list_for_each_entry(wk, &local->work_list, list) { |
1062 | if (wk->sdata != sdata) | 1057 | if (wk->sdata != sdata) |
1063 | continue; | 1058 | continue; |
@@ -1065,19 +1060,19 @@ void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata) | |||
1065 | wk->started = true; | 1060 | wk->started = true; |
1066 | wk->timeout = jiffies; | 1061 | wk->timeout = jiffies; |
1067 | } | 1062 | } |
1068 | mutex_unlock(&local->work_mtx); | 1063 | mutex_unlock(&local->mtx); |
1069 | 1064 | ||
1070 | /* run cleanups etc. */ | 1065 | /* run cleanups etc. */ |
1071 | ieee80211_work_work(&local->work_work); | 1066 | ieee80211_work_work(&local->work_work); |
1072 | 1067 | ||
1073 | mutex_lock(&local->work_mtx); | 1068 | mutex_lock(&local->mtx); |
1074 | list_for_each_entry(wk, &local->work_list, list) { | 1069 | list_for_each_entry(wk, &local->work_list, list) { |
1075 | if (wk->sdata != sdata) | 1070 | if (wk->sdata != sdata) |
1076 | continue; | 1071 | continue; |
1077 | WARN_ON(1); | 1072 | WARN_ON(1); |
1078 | break; | 1073 | break; |
1079 | } | 1074 | } |
1080 | mutex_unlock(&local->work_mtx); | 1075 | mutex_unlock(&local->mtx); |
1081 | } | 1076 | } |
1082 | 1077 | ||
1083 | ieee80211_rx_result ieee80211_work_rx_mgmt(struct ieee80211_sub_if_data *sdata, | 1078 | ieee80211_rx_result ieee80211_work_rx_mgmt(struct ieee80211_sub_if_data *sdata, |
@@ -1163,7 +1158,7 @@ int ieee80211_wk_cancel_remain_on_channel(struct ieee80211_sub_if_data *sdata, | |||
1163 | struct ieee80211_work *wk, *tmp; | 1158 | struct ieee80211_work *wk, *tmp; |
1164 | bool found = false; | 1159 | bool found = false; |
1165 | 1160 | ||
1166 | mutex_lock(&local->work_mtx); | 1161 | mutex_lock(&local->mtx); |
1167 | list_for_each_entry_safe(wk, tmp, &local->work_list, list) { | 1162 | list_for_each_entry_safe(wk, tmp, &local->work_list, list) { |
1168 | if ((unsigned long) wk == cookie) { | 1163 | if ((unsigned long) wk == cookie) { |
1169 | wk->timeout = jiffies; | 1164 | wk->timeout = jiffies; |
@@ -1171,7 +1166,7 @@ int ieee80211_wk_cancel_remain_on_channel(struct ieee80211_sub_if_data *sdata, | |||
1171 | break; | 1166 | break; |
1172 | } | 1167 | } |
1173 | } | 1168 | } |
1174 | mutex_unlock(&local->work_mtx); | 1169 | mutex_unlock(&local->mtx); |
1175 | 1170 | ||
1176 | if (!found) | 1171 | if (!found) |
1177 | return -ENOENT; | 1172 | return -ENOENT; |
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index 8d59d27d887..bee230d8fd1 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
@@ -36,8 +36,8 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx) | |||
36 | int tail; | 36 | int tail; |
37 | 37 | ||
38 | hdr = (struct ieee80211_hdr *)skb->data; | 38 | hdr = (struct ieee80211_hdr *)skb->data; |
39 | if (!tx->key || tx->key->conf.alg != ALG_TKIP || skb->len < 24 || | 39 | if (!tx->key || tx->key->conf.cipher != WLAN_CIPHER_SUITE_TKIP || |
40 | !ieee80211_is_data_present(hdr->frame_control)) | 40 | skb->len < 24 || !ieee80211_is_data_present(hdr->frame_control)) |
41 | return TX_CONTINUE; | 41 | return TX_CONTINUE; |
42 | 42 | ||
43 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 43 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
@@ -94,7 +94,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) | |||
94 | if (status->flag & RX_FLAG_MMIC_STRIPPED) | 94 | if (status->flag & RX_FLAG_MMIC_STRIPPED) |
95 | return RX_CONTINUE; | 95 | return RX_CONTINUE; |
96 | 96 | ||
97 | if (!rx->key || rx->key->conf.alg != ALG_TKIP || | 97 | if (!rx->key || rx->key->conf.cipher != WLAN_CIPHER_SUITE_TKIP || |
98 | !ieee80211_has_protected(hdr->frame_control) || | 98 | !ieee80211_has_protected(hdr->frame_control) || |
99 | !ieee80211_is_data_present(hdr->frame_control)) | 99 | !ieee80211_is_data_present(hdr->frame_control)) |
100 | return RX_CONTINUE; | 100 | return RX_CONTINUE; |
@@ -117,7 +117,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) | |||
117 | key = &rx->key->conf.key[key_offset]; | 117 | key = &rx->key->conf.key[key_offset]; |
118 | michael_mic(key, hdr, data, data_len, mic); | 118 | michael_mic(key, hdr, data, data_len, mic); |
119 | if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0 || wpa_test) { | 119 | if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0 || wpa_test) { |
120 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) | 120 | if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) |
121 | return RX_DROP_UNUSABLE; | 121 | return RX_DROP_UNUSABLE; |
122 | 122 | ||
123 | mac80211_ev_michael_mic_failure(rx->sdata, rx->key->conf.keyidx, | 123 | mac80211_ev_michael_mic_failure(rx->sdata, rx->key->conf.keyidx, |
@@ -221,19 +221,13 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) | |||
221 | if (!rx->sta || skb->len - hdrlen < 12) | 221 | if (!rx->sta || skb->len - hdrlen < 12) |
222 | return RX_DROP_UNUSABLE; | 222 | return RX_DROP_UNUSABLE; |
223 | 223 | ||
224 | if (status->flag & RX_FLAG_DECRYPTED) { | 224 | /* |
225 | if (status->flag & RX_FLAG_IV_STRIPPED) { | 225 | * Let TKIP code verify IV, but skip decryption. |
226 | /* | 226 | * In the case where hardware checks the IV as well, |
227 | * Hardware took care of all processing, including | 227 | * we don't even get here, see ieee80211_rx_h_decrypt() |
228 | * replay protection, and stripped the ICV/IV so | 228 | */ |
229 | * we cannot do any checks here. | 229 | if (status->flag & RX_FLAG_DECRYPTED) |
230 | */ | ||
231 | return RX_CONTINUE; | ||
232 | } | ||
233 | |||
234 | /* let TKIP code verify IV, but skip decryption */ | ||
235 | hwaccel = 1; | 230 | hwaccel = 1; |
236 | } | ||
237 | 231 | ||
238 | res = ieee80211_tkip_decrypt_data(rx->local->wep_rx_tfm, | 232 | res = ieee80211_tkip_decrypt_data(rx->local->wep_rx_tfm, |
239 | key, skb->data + hdrlen, | 233 | key, skb->data + hdrlen, |
@@ -447,10 +441,6 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) | |||
447 | if (!rx->sta || data_len < 0) | 441 | if (!rx->sta || data_len < 0) |
448 | return RX_DROP_UNUSABLE; | 442 | return RX_DROP_UNUSABLE; |
449 | 443 | ||
450 | if ((status->flag & RX_FLAG_DECRYPTED) && | ||
451 | (status->flag & RX_FLAG_IV_STRIPPED)) | ||
452 | return RX_CONTINUE; | ||
453 | |||
454 | ccmp_hdr2pn(pn, skb->data + hdrlen); | 444 | ccmp_hdr2pn(pn, skb->data + hdrlen); |
455 | 445 | ||
456 | queue = ieee80211_is_mgmt(hdr->frame_control) ? | 446 | queue = ieee80211_is_mgmt(hdr->frame_control) ? |
@@ -564,10 +554,6 @@ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx) | |||
564 | if (!ieee80211_is_mgmt(hdr->frame_control)) | 554 | if (!ieee80211_is_mgmt(hdr->frame_control)) |
565 | return RX_CONTINUE; | 555 | return RX_CONTINUE; |
566 | 556 | ||
567 | if ((status->flag & RX_FLAG_DECRYPTED) && | ||
568 | (status->flag & RX_FLAG_IV_STRIPPED)) | ||
569 | return RX_CONTINUE; | ||
570 | |||
571 | if (skb->len < 24 + sizeof(*mmie)) | 557 | if (skb->len < 24 + sizeof(*mmie)) |
572 | return RX_DROP_UNUSABLE; | 558 | return RX_DROP_UNUSABLE; |
573 | 559 | ||