aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/mac80211/agg-rx.c3
-rw-r--r--net/mac80211/agg-tx.c4
-rw-r--r--net/mac80211/cfg.c25
-rw-r--r--net/mac80211/ibss.c2
-rw-r--r--net/mac80211/key.c2
-rw-r--r--net/mac80211/mesh_hwmp.c2
-rw-r--r--net/mac80211/mesh_plink.c4
-rw-r--r--net/mac80211/mlme.c10
-rw-r--r--net/mac80211/rx.c119
-rw-r--r--net/mac80211/sta_info.c18
-rw-r--r--net/mac80211/sta_info.h29
-rw-r--r--net/mac80211/status.c8
-rw-r--r--net/mac80211/tx.c9
13 files changed, 134 insertions, 101 deletions
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index 51c7dc3c4c3b..f16d49d474b4 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -83,12 +83,11 @@ void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
83void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, 83void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid,
84 u16 initiator, u16 reason) 84 u16 initiator, u16 reason)
85{ 85{
86 struct ieee80211_local *local = sdata->local;
87 struct sta_info *sta; 86 struct sta_info *sta;
88 87
89 rcu_read_lock(); 88 rcu_read_lock();
90 89
91 sta = sta_info_get(local, ra); 90 sta = sta_info_get(sdata, ra);
92 if (!sta) { 91 if (!sta) {
93 rcu_read_unlock(); 92 rcu_read_unlock();
94 return; 93 return;
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 5e3a7eccef5a..b05de532c379 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -441,7 +441,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid)
441 } 441 }
442 442
443 rcu_read_lock(); 443 rcu_read_lock();
444 sta = sta_info_get(local, ra); 444 sta = sta_info_get(sdata, ra);
445 if (!sta) { 445 if (!sta) {
446 rcu_read_unlock(); 446 rcu_read_unlock();
447#ifdef CONFIG_MAC80211_HT_DEBUG 447#ifdef CONFIG_MAC80211_HT_DEBUG
@@ -564,7 +564,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid)
564#endif /* CONFIG_MAC80211_HT_DEBUG */ 564#endif /* CONFIG_MAC80211_HT_DEBUG */
565 565
566 rcu_read_lock(); 566 rcu_read_lock();
567 sta = sta_info_get(local, ra); 567 sta = sta_info_get(sdata, ra);
568 if (!sta) { 568 if (!sta) {
569#ifdef CONFIG_MAC80211_HT_DEBUG 569#ifdef CONFIG_MAC80211_HT_DEBUG
570 printk(KERN_DEBUG "Could not find station: %pM\n", ra); 570 printk(KERN_DEBUG "Could not find station: %pM\n", ra);
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 93ee1fd5c08d..14e1f4015a72 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -150,7 +150,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
150 rcu_read_lock(); 150 rcu_read_lock();
151 151
152 if (mac_addr) { 152 if (mac_addr) {
153 sta = sta_info_get(sdata->local, mac_addr); 153 sta = sta_info_get(sdata, mac_addr);
154 if (!sta) { 154 if (!sta) {
155 ieee80211_key_free(key); 155 ieee80211_key_free(key);
156 err = -ENOENT; 156 err = -ENOENT;
@@ -181,7 +181,7 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
181 if (mac_addr) { 181 if (mac_addr) {
182 ret = -ENOENT; 182 ret = -ENOENT;
183 183
184 sta = sta_info_get(sdata->local, mac_addr); 184 sta = sta_info_get(sdata, mac_addr);
185 if (!sta) 185 if (!sta)
186 goto out_unlock; 186 goto out_unlock;
187 187
@@ -228,7 +228,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
228 rcu_read_lock(); 228 rcu_read_lock();
229 229
230 if (mac_addr) { 230 if (mac_addr) {
231 sta = sta_info_get(sdata->local, mac_addr); 231 sta = sta_info_get(sdata, mac_addr);
232 if (!sta) 232 if (!sta)
233 goto out; 233 goto out;
234 234
@@ -414,15 +414,13 @@ static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
414static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev, 414static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
415 u8 *mac, struct station_info *sinfo) 415 u8 *mac, struct station_info *sinfo)
416{ 416{
417 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 417 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
418 struct sta_info *sta; 418 struct sta_info *sta;
419 int ret = -ENOENT; 419 int ret = -ENOENT;
420 420
421 rcu_read_lock(); 421 rcu_read_lock();
422 422
423 /* XXX: verify sta->dev == dev */ 423 sta = sta_info_get(sdata, mac);
424
425 sta = sta_info_get(local, mac);
426 if (sta) { 424 if (sta) {
427 ret = 0; 425 ret = 0;
428 sta_set_sinfo(sta, sinfo); 426 sta_set_sinfo(sta, sinfo);
@@ -778,8 +776,7 @@ static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev,
778 if (mac) { 776 if (mac) {
779 rcu_read_lock(); 777 rcu_read_lock();
780 778
781 /* XXX: get sta belonging to dev */ 779 sta = sta_info_get(sdata, mac);
782 sta = sta_info_get(local, mac);
783 if (!sta) { 780 if (!sta) {
784 rcu_read_unlock(); 781 rcu_read_unlock();
785 return -ENOENT; 782 return -ENOENT;
@@ -800,14 +797,14 @@ static int ieee80211_change_station(struct wiphy *wiphy,
800 u8 *mac, 797 u8 *mac,
801 struct station_parameters *params) 798 struct station_parameters *params)
802{ 799{
800 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
803 struct ieee80211_local *local = wiphy_priv(wiphy); 801 struct ieee80211_local *local = wiphy_priv(wiphy);
804 struct sta_info *sta; 802 struct sta_info *sta;
805 struct ieee80211_sub_if_data *vlansdata; 803 struct ieee80211_sub_if_data *vlansdata;
806 804
807 rcu_read_lock(); 805 rcu_read_lock();
808 806
809 /* XXX: get sta belonging to dev */ 807 sta = sta_info_get(sdata, mac);
810 sta = sta_info_get(local, mac);
811 if (!sta) { 808 if (!sta) {
812 rcu_read_unlock(); 809 rcu_read_unlock();
813 return -ENOENT; 810 return -ENOENT;
@@ -846,7 +843,6 @@ static int ieee80211_change_station(struct wiphy *wiphy,
846static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev, 843static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
847 u8 *dst, u8 *next_hop) 844 u8 *dst, u8 *next_hop)
848{ 845{
849 struct ieee80211_local *local = wiphy_priv(wiphy);
850 struct ieee80211_sub_if_data *sdata; 846 struct ieee80211_sub_if_data *sdata;
851 struct mesh_path *mpath; 847 struct mesh_path *mpath;
852 struct sta_info *sta; 848 struct sta_info *sta;
@@ -855,7 +851,7 @@ static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
855 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 851 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
856 852
857 rcu_read_lock(); 853 rcu_read_lock();
858 sta = sta_info_get(local, next_hop); 854 sta = sta_info_get(sdata, next_hop);
859 if (!sta) { 855 if (!sta) {
860 rcu_read_unlock(); 856 rcu_read_unlock();
861 return -ENOENT; 857 return -ENOENT;
@@ -894,7 +890,6 @@ static int ieee80211_change_mpath(struct wiphy *wiphy,
894 struct net_device *dev, 890 struct net_device *dev,
895 u8 *dst, u8 *next_hop) 891 u8 *dst, u8 *next_hop)
896{ 892{
897 struct ieee80211_local *local = wiphy_priv(wiphy);
898 struct ieee80211_sub_if_data *sdata; 893 struct ieee80211_sub_if_data *sdata;
899 struct mesh_path *mpath; 894 struct mesh_path *mpath;
900 struct sta_info *sta; 895 struct sta_info *sta;
@@ -903,7 +898,7 @@ static int ieee80211_change_mpath(struct wiphy *wiphy,
903 898
904 rcu_read_lock(); 899 rcu_read_lock();
905 900
906 sta = sta_info_get(local, next_hop); 901 sta = sta_info_get(sdata, next_hop);
907 if (!sta) { 902 if (!sta) {
908 rcu_read_unlock(); 903 rcu_read_unlock();
909 return -ENOENT; 904 return -ENOENT;
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 10d13856f86c..1925be9b82fb 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -252,7 +252,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
252 252
253 rcu_read_lock(); 253 rcu_read_lock();
254 254
255 sta = sta_info_get(local, mgmt->sa); 255 sta = sta_info_get(sdata, mgmt->sa);
256 if (sta) { 256 if (sta) {
257 u32 prev_rates; 257 u32 prev_rates;
258 258
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 659a42d529e3..ac1a777674f6 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -421,7 +421,7 @@ void ieee80211_key_link(struct ieee80211_key *key,
421 */ 421 */
422 422
423 /* same here, the AP could be using QoS */ 423 /* same here, the AP could be using QoS */
424 ap = sta_info_get(key->local, key->sdata->u.mgd.bssid); 424 ap = sta_info_get(key->sdata, key->sdata->u.mgd.bssid);
425 if (ap) { 425 if (ap) {
426 if (test_sta_flags(ap, WLAN_STA_WME)) 426 if (test_sta_flags(ap, WLAN_STA_WME))
427 key->conf.flags |= 427 key->conf.flags |=
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 833b2f3670c5..b836892f0ba9 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -335,7 +335,7 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
335 bool process = true; 335 bool process = true;
336 336
337 rcu_read_lock(); 337 rcu_read_lock();
338 sta = sta_info_get(local, mgmt->sa); 338 sta = sta_info_get(sdata, mgmt->sa);
339 if (!sta) { 339 if (!sta) {
340 rcu_read_unlock(); 340 rcu_read_unlock();
341 return 0; 341 return 0;
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 0f7c6e6a4248..8fcf56ee7743 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -234,7 +234,7 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates, struct ieee80211_sub_if_data
234 234
235 rcu_read_lock(); 235 rcu_read_lock();
236 236
237 sta = sta_info_get(local, hw_addr); 237 sta = sta_info_get(sdata, hw_addr);
238 if (!sta) { 238 if (!sta) {
239 sta = mesh_plink_alloc(sdata, hw_addr, rates); 239 sta = mesh_plink_alloc(sdata, hw_addr, rates);
240 if (!sta) { 240 if (!sta) {
@@ -455,7 +455,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
455 455
456 rcu_read_lock(); 456 rcu_read_lock();
457 457
458 sta = sta_info_get(local, mgmt->sa); 458 sta = sta_info_get(sdata, mgmt->sa);
459 if (!sta && ftype != PLINK_OPEN) { 459 if (!sta && ftype != PLINK_OPEN) {
460 mpl_dbg("Mesh plink: cls or cnf from unknown peer\n"); 460 mpl_dbg("Mesh plink: cls or cnf from unknown peer\n");
461 rcu_read_unlock(); 461 rcu_read_unlock();
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 6dc7b5ad9a41..c16667a7c8df 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -202,7 +202,7 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
202 ieee80211_hw_config(local, 0); 202 ieee80211_hw_config(local, 0);
203 203
204 rcu_read_lock(); 204 rcu_read_lock();
205 sta = sta_info_get(local, bssid); 205 sta = sta_info_get(sdata, bssid);
206 if (sta) 206 if (sta)
207 rate_control_rate_update(local, sband, sta, 207 rate_control_rate_update(local, sband, sta,
208 IEEE80211_RC_HT_CHANGED); 208 IEEE80211_RC_HT_CHANGED);
@@ -1070,7 +1070,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1070 netif_carrier_off(sdata->dev); 1070 netif_carrier_off(sdata->dev);
1071 1071
1072 rcu_read_lock(); 1072 rcu_read_lock();
1073 sta = sta_info_get(local, bssid); 1073 sta = sta_info_get(sdata, bssid);
1074 if (sta) 1074 if (sta)
1075 ieee80211_sta_tear_down_BA_sessions(sta); 1075 ieee80211_sta_tear_down_BA_sessions(sta);
1076 rcu_read_unlock(); 1076 rcu_read_unlock();
@@ -1109,7 +1109,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1109 1109
1110 rcu_read_lock(); 1110 rcu_read_lock();
1111 1111
1112 sta = sta_info_get(local, bssid); 1112 sta = sta_info_get(sdata, bssid);
1113 if (!sta) { 1113 if (!sta) {
1114 rcu_read_unlock(); 1114 rcu_read_unlock();
1115 return; 1115 return;
@@ -1489,7 +1489,7 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1489 rcu_read_lock(); 1489 rcu_read_lock();
1490 1490
1491 /* Add STA entry for the AP */ 1491 /* Add STA entry for the AP */
1492 sta = sta_info_get(local, wk->bss->cbss.bssid); 1492 sta = sta_info_get(sdata, wk->bss->cbss.bssid);
1493 if (!sta) { 1493 if (!sta) {
1494 newsta = true; 1494 newsta = true;
1495 1495
@@ -1857,7 +1857,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1857 1857
1858 rcu_read_lock(); 1858 rcu_read_lock();
1859 1859
1860 sta = sta_info_get(local, bssid); 1860 sta = sta_info_get(sdata, bssid);
1861 if (WARN_ON(!sta)) { 1861 if (WARN_ON(!sta)) {
1862 rcu_read_unlock(); 1862 rcu_read_unlock();
1863 return; 1863 return;
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index f237df408378..5bae28693da8 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1472,7 +1472,6 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
1472{ 1472{
1473 struct ieee80211_sub_if_data *sdata = rx->sdata; 1473 struct ieee80211_sub_if_data *sdata = rx->sdata;
1474 struct net_device *dev = sdata->dev; 1474 struct net_device *dev = sdata->dev;
1475 struct ieee80211_local *local = rx->local;
1476 struct sk_buff *skb, *xmit_skb; 1475 struct sk_buff *skb, *xmit_skb;
1477 struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data; 1476 struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data;
1478 struct sta_info *dsta; 1477 struct sta_info *dsta;
@@ -1495,8 +1494,8 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
1495 printk(KERN_DEBUG "%s: failed to clone " 1494 printk(KERN_DEBUG "%s: failed to clone "
1496 "multicast frame\n", dev->name); 1495 "multicast frame\n", dev->name);
1497 } else { 1496 } else {
1498 dsta = sta_info_get(local, skb->data); 1497 dsta = sta_info_get(sdata, skb->data);
1499 if (dsta && dsta->sdata->dev == dev) { 1498 if (dsta) {
1500 /* 1499 /*
1501 * The destination station is associated to 1500 * The destination station is associated to
1502 * this AP (in this VLAN), so send the frame 1501 * this AP (in this VLAN), so send the frame
@@ -2363,6 +2362,8 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2363 int prepares; 2362 int prepares;
2364 struct ieee80211_sub_if_data *prev = NULL; 2363 struct ieee80211_sub_if_data *prev = NULL;
2365 struct sk_buff *skb_new; 2364 struct sk_buff *skb_new;
2365 struct sta_info *sta, *tmp;
2366 bool found_sta = false;
2366 2367
2367 hdr = (struct ieee80211_hdr *)skb->data; 2368 hdr = (struct ieee80211_hdr *)skb->data;
2368 memset(&rx, 0, sizeof(rx)); 2369 memset(&rx, 0, sizeof(rx));
@@ -2379,68 +2380,76 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2379 ieee80211_parse_qos(&rx); 2380 ieee80211_parse_qos(&rx);
2380 ieee80211_verify_alignment(&rx); 2381 ieee80211_verify_alignment(&rx);
2381 2382
2382 rx.sta = sta_info_get(local, hdr->addr2); 2383 if (ieee80211_is_data(hdr->frame_control)) {
2383 if (rx.sta) 2384 for_each_sta_info(local, hdr->addr2, sta, tmp) {
2384 rx.sdata = rx.sta->sdata; 2385 rx.sta = sta;
2385 2386 found_sta = true;
2386 if (rx.sdata && ieee80211_is_data(hdr->frame_control)) { 2387 rx.sdata = sta->sdata;
2387 rx.flags |= IEEE80211_RX_RA_MATCH; 2388
2388 prepares = prepare_for_handlers(rx.sdata, &rx, hdr); 2389 rx.flags |= IEEE80211_RX_RA_MATCH;
2389 if (prepares) { 2390 prepares = prepare_for_handlers(rx.sdata, &rx, hdr);
2390 if (status->flag & RX_FLAG_MMIC_ERROR) { 2391 if (prepares) {
2391 if (rx.flags & IEEE80211_RX_RA_MATCH) 2392 if (status->flag & RX_FLAG_MMIC_ERROR) {
2392 ieee80211_rx_michael_mic_report(hdr, &rx); 2393 if (rx.flags & IEEE80211_RX_RA_MATCH)
2393 } else 2394 ieee80211_rx_michael_mic_report(hdr, &rx);
2394 prev = rx.sdata; 2395 } else
2396 prev = rx.sdata;
2397 }
2395 } 2398 }
2396 } else list_for_each_entry_rcu(sdata, &local->interfaces, list) { 2399 }
2397 if (!netif_running(sdata->dev)) 2400 if (!found_sta) {
2398 continue; 2401 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
2402 if (!netif_running(sdata->dev))
2403 continue;
2399 2404
2400 if (sdata->vif.type == NL80211_IFTYPE_MONITOR || 2405 if (sdata->vif.type == NL80211_IFTYPE_MONITOR ||
2401 sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 2406 sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
2402 continue; 2407 continue;
2403 2408
2404 rx.flags |= IEEE80211_RX_RA_MATCH; 2409 rx.sta = sta_info_get(sdata, hdr->addr2);
2405 prepares = prepare_for_handlers(sdata, &rx, hdr);
2406 2410
2407 if (!prepares) 2411 rx.flags |= IEEE80211_RX_RA_MATCH;
2408 continue; 2412 prepares = prepare_for_handlers(sdata, &rx, hdr);
2409 2413
2410 if (status->flag & RX_FLAG_MMIC_ERROR) { 2414 if (!prepares)
2411 rx.sdata = sdata; 2415 continue;
2412 if (rx.flags & IEEE80211_RX_RA_MATCH)
2413 ieee80211_rx_michael_mic_report(hdr, &rx);
2414 continue;
2415 }
2416 2416
2417 /* 2417 if (status->flag & RX_FLAG_MMIC_ERROR) {
2418 * frame is destined for this interface, but if it's not 2418 rx.sdata = sdata;
2419 * also for the previous one we handle that after the 2419 if (rx.flags & IEEE80211_RX_RA_MATCH)
2420 * loop to avoid copying the SKB once too much 2420 ieee80211_rx_michael_mic_report(hdr,
2421 */ 2421 &rx);
2422 continue;
2423 }
2422 2424
2423 if (!prev) { 2425 /*
2424 prev = sdata; 2426 * frame is destined for this interface, but if it's
2425 continue; 2427 * not also for the previous one we handle that after
2426 } 2428 * the loop to avoid copying the SKB once too much
2429 */
2427 2430
2428 /* 2431 if (!prev) {
2429 * frame was destined for the previous interface 2432 prev = sdata;
2430 * so invoke RX handlers for it 2433 continue;
2431 */ 2434 }
2432 2435
2433 skb_new = skb_copy(skb, GFP_ATOMIC); 2436 /*
2434 if (!skb_new) { 2437 * frame was destined for the previous interface
2435 if (net_ratelimit()) 2438 * so invoke RX handlers for it
2436 printk(KERN_DEBUG "%s: failed to copy " 2439 */
2437 "multicast frame for %s\n", 2440
2438 wiphy_name(local->hw.wiphy), 2441 skb_new = skb_copy(skb, GFP_ATOMIC);
2439 prev->dev->name); 2442 if (!skb_new) {
2440 continue; 2443 if (net_ratelimit())
2444 printk(KERN_DEBUG "%s: failed to copy "
2445 "multicast frame for %s\n",
2446 wiphy_name(local->hw.wiphy),
2447 prev->dev->name);
2448 continue;
2449 }
2450 ieee80211_invoke_rx_handlers(prev, &rx, skb_new, rate);
2451 prev = sdata;
2441 } 2452 }
2442 ieee80211_invoke_rx_handlers(prev, &rx, skb_new, rate);
2443 prev = sdata;
2444 } 2453 }
2445 if (prev) 2454 if (prev)
2446 ieee80211_invoke_rx_handlers(prev, &rx, skb, rate); 2455 ieee80211_invoke_rx_handlers(prev, &rx, skb, rate);
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 71f370dd24bc..c58a23eea58c 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -103,13 +103,16 @@ static int sta_info_hash_del(struct ieee80211_local *local,
103} 103}
104 104
105/* protected by RCU */ 105/* protected by RCU */
106struct sta_info *sta_info_get(struct ieee80211_local *local, const u8 *addr) 106struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata,
107 const u8 *addr)
107{ 108{
109 struct ieee80211_local *local = sdata->local;
108 struct sta_info *sta; 110 struct sta_info *sta;
109 111
110 sta = rcu_dereference(local->sta_hash[STA_HASH(addr)]); 112 sta = rcu_dereference(local->sta_hash[STA_HASH(addr)]);
111 while (sta) { 113 while (sta) {
112 if (memcmp(sta->sta.addr, addr, ETH_ALEN) == 0) 114 if (sta->sdata == sdata &&
115 memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
113 break; 116 break;
114 sta = rcu_dereference(sta->hnext); 117 sta = rcu_dereference(sta->hnext);
115 } 118 }
@@ -377,7 +380,7 @@ int sta_info_insert(struct sta_info *sta)
377 380
378 spin_lock_irqsave(&local->sta_lock, flags); 381 spin_lock_irqsave(&local->sta_lock, flags);
379 /* check if STA exists already */ 382 /* check if STA exists already */
380 if (sta_info_get(local, sta->sta.addr)) { 383 if (sta_info_get(sdata, sta->sta.addr)) {
381 spin_unlock_irqrestore(&local->sta_lock, flags); 384 spin_unlock_irqrestore(&local->sta_lock, flags);
382 err = -EEXIST; 385 err = -EEXIST;
383 goto out_free; 386 goto out_free;
@@ -843,11 +846,12 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
843struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw, 846struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw,
844 const u8 *addr) 847 const u8 *addr)
845{ 848{
846 struct sta_info *sta = sta_info_get(hw_to_local(hw), addr); 849 struct sta_info *sta, *nxt;
847 850
848 if (!sta) 851 /* Just return a random station ... first in list ... */
849 return NULL; 852 for_each_sta_info(hw_to_local(hw), addr, sta, nxt)
850 return &sta->sta; 853 return &sta->sta;
854 return NULL;
851} 855}
852EXPORT_SYMBOL_GPL(ieee80211_find_sta_by_hw); 856EXPORT_SYMBOL_GPL(ieee80211_find_sta_by_hw);
853 857
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index b4810f6aa94f..c8208236e896 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -403,9 +403,34 @@ static inline u32 get_sta_flags(struct sta_info *sta)
403#define STA_INFO_CLEANUP_INTERVAL (10 * HZ) 403#define STA_INFO_CLEANUP_INTERVAL (10 * HZ)
404 404
405/* 405/*
406 * Get a STA info, must have be under RCU read lock. 406 * Get a STA info, must be under RCU read lock.
407 */ 407 */
408struct sta_info *sta_info_get(struct ieee80211_local *local, const u8 *addr); 408struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata,
409 const u8 *addr);
410
411static inline
412void for_each_sta_info_type_check(struct ieee80211_local *local,
413 const u8 *addr,
414 struct sta_info *sta,
415 struct sta_info *nxt)
416{
417}
418
419#define for_each_sta_info(local, _addr, sta, nxt) \
420 for ( /* initialise loop */ \
421 sta = rcu_dereference(local->sta_hash[STA_HASH(_addr)]),\
422 nxt = sta ? rcu_dereference(sta->hnext) : NULL; \
423 /* typecheck */ \
424 for_each_sta_info_type_check(local, (_addr), sta, nxt), \
425 /* continue condition */ \
426 sta; \
427 /* advance loop */ \
428 sta = nxt, \
429 nxt = sta ? rcu_dereference(sta->hnext) : NULL \
430 ) \
431 /* compare address and run code only if it matches */ \
432 if (memcmp(sta->sta.addr, (_addr), ETH_ALEN) == 0)
433
409/* 434/*
410 * Get STA info by index, BROKEN! 435 * Get STA info by index, BROKEN!
411 */ 436 */
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index d78f36c64c7b..32fe327acf4e 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -146,7 +146,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
146 struct ieee80211_tx_status_rtap_hdr *rthdr; 146 struct ieee80211_tx_status_rtap_hdr *rthdr;
147 struct ieee80211_sub_if_data *sdata; 147 struct ieee80211_sub_if_data *sdata;
148 struct net_device *prev_dev = NULL; 148 struct net_device *prev_dev = NULL;
149 struct sta_info *sta; 149 struct sta_info *sta, *tmp;
150 int retry_count = -1, i; 150 int retry_count = -1, i;
151 bool injected; 151 bool injected;
152 152
@@ -166,9 +166,11 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
166 166
167 sband = local->hw.wiphy->bands[info->band]; 167 sband = local->hw.wiphy->bands[info->band];
168 168
169 sta = sta_info_get(local, hdr->addr1); 169 for_each_sta_info(local, hdr->addr1, sta, tmp) {
170 /* skip wrong virtual interface */
171 if (memcmp(hdr->addr2, sta->sdata->dev->dev_addr, ETH_ALEN))
172 continue;
170 173
171 if (sta) {
172 if (!(info->flags & IEEE80211_TX_STAT_ACK) && 174 if (!(info->flags & IEEE80211_TX_STAT_ACK) &&
173 test_sta_flags(sta, WLAN_STA_PS_STA)) { 175 test_sta_flags(sta, WLAN_STA_PS_STA)) {
174 /* 176 /*
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 8834cc93c716..b913bfc34a9f 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1055,7 +1055,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
1055 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 1055 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
1056 tx->sta = rcu_dereference(sdata->u.vlan.sta); 1056 tx->sta = rcu_dereference(sdata->u.vlan.sta);
1057 if (!tx->sta) 1057 if (!tx->sta)
1058 tx->sta = sta_info_get(local, hdr->addr1); 1058 tx->sta = sta_info_get(sdata, hdr->addr1);
1059 1059
1060 if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) && 1060 if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) &&
1061 (local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION)) { 1061 (local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION)) {
@@ -1761,9 +1761,8 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1761 */ 1761 */
1762 if (!is_multicast_ether_addr(hdr.addr1)) { 1762 if (!is_multicast_ether_addr(hdr.addr1)) {
1763 rcu_read_lock(); 1763 rcu_read_lock();
1764 sta = sta_info_get(local, hdr.addr1); 1764 sta = sta_info_get(sdata, hdr.addr1);
1765 /* XXX: in the future, use sdata to look up the sta */ 1765 if (sta)
1766 if (sta && sta->sdata == sdata)
1767 sta_flags = get_sta_flags(sta); 1766 sta_flags = get_sta_flags(sta);
1768 rcu_read_unlock(); 1767 rcu_read_unlock();
1769 } 1768 }
@@ -1922,7 +1921,7 @@ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local,
1922 ieee80211_tx(sdata, skb, true); 1921 ieee80211_tx(sdata, skb, true);
1923 } else { 1922 } else {
1924 hdr = (struct ieee80211_hdr *)skb->data; 1923 hdr = (struct ieee80211_hdr *)skb->data;
1925 sta = sta_info_get(local, hdr->addr1); 1924 sta = sta_info_get(sdata, hdr->addr1);
1926 1925
1927 ret = __ieee80211_tx(local, &skb, sta, true); 1926 ret = __ieee80211_tx(local, &skb, sta, true);
1928 if (ret != IEEE80211_TX_OK) 1927 if (ret != IEEE80211_TX_OK)