aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2007-10-05 14:23:27 -0400
committerJohn W. Linville <linville@tuxdriver.com>2007-10-16 21:17:26 -0400
commit65c107ab3befc37b21d1c970a6159525bc0121b8 (patch)
treeb82fae89b41e9f22f8219f6c06be14c266a04d37 /net/mac80211
parent1dd84aa213d0f98a91a1ec9be2f750f5f48e75a0 (diff)
[PATCH] mac80211: store channel info in sta_bss_list
Some AP equipment "in the wild" uses the same BSSID on multiple channels (particularly "a" vs. "b/g"). This patch changes the key of sta_bss_list to include both the BSSID and the channel so as to prevent a BSSID on one channel from eclipsing the same BSSID on another channel. Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/ieee80211_sta.c34
1 files changed, 19 insertions, 15 deletions
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
index 8dae26bbfdf9..c1cc79e9f1f7 100644
--- a/net/mac80211/ieee80211_sta.c
+++ b/net/mac80211/ieee80211_sta.c
@@ -61,7 +61,7 @@
61static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst, 61static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst,
62 u8 *ssid, size_t ssid_len); 62 u8 *ssid, size_t ssid_len);
63static struct ieee80211_sta_bss * 63static struct ieee80211_sta_bss *
64ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid); 64ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel);
65static void ieee80211_rx_bss_put(struct net_device *dev, 65static void ieee80211_rx_bss_put(struct net_device *dev,
66 struct ieee80211_sta_bss *bss); 66 struct ieee80211_sta_bss *bss);
67static int ieee80211_sta_find_ibss(struct net_device *dev, 67static int ieee80211_sta_find_ibss(struct net_device *dev,
@@ -427,7 +427,8 @@ static void ieee80211_set_associated(struct net_device *dev,
427 if (sdata->type != IEEE80211_IF_TYPE_STA) 427 if (sdata->type != IEEE80211_IF_TYPE_STA)
428 return; 428 return;
429 429
430 bss = ieee80211_rx_bss_get(dev, ifsta->bssid); 430 bss = ieee80211_rx_bss_get(dev, ifsta->bssid,
431 local->hw.conf.channel);
431 if (bss) { 432 if (bss) {
432 if (bss->has_erp_value) 433 if (bss->has_erp_value)
433 ieee80211_handle_erp_ie(dev, bss->erp_value); 434 ieee80211_handle_erp_ie(dev, bss->erp_value);
@@ -574,7 +575,7 @@ static void ieee80211_send_assoc(struct net_device *dev,
574 capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME | 575 capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME |
575 WLAN_CAPABILITY_SHORT_PREAMBLE; 576 WLAN_CAPABILITY_SHORT_PREAMBLE;
576 } 577 }
577 bss = ieee80211_rx_bss_get(dev, ifsta->bssid); 578 bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel);
578 if (bss) { 579 if (bss) {
579 if (bss->capability & WLAN_CAPABILITY_PRIVACY) 580 if (bss->capability & WLAN_CAPABILITY_PRIVACY)
580 capab |= WLAN_CAPABILITY_PRIVACY; 581 capab |= WLAN_CAPABILITY_PRIVACY;
@@ -722,6 +723,7 @@ static void ieee80211_send_disassoc(struct net_device *dev,
722static int ieee80211_privacy_mismatch(struct net_device *dev, 723static int ieee80211_privacy_mismatch(struct net_device *dev,
723 struct ieee80211_if_sta *ifsta) 724 struct ieee80211_if_sta *ifsta)
724{ 725{
726 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
725 struct ieee80211_sta_bss *bss; 727 struct ieee80211_sta_bss *bss;
726 int res = 0; 728 int res = 0;
727 729
@@ -729,7 +731,7 @@ static int ieee80211_privacy_mismatch(struct net_device *dev,
729 ifsta->key_management_enabled) 731 ifsta->key_management_enabled)
730 return 0; 732 return 0;
731 733
732 bss = ieee80211_rx_bss_get(dev, ifsta->bssid); 734 bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel);
733 if (!bss) 735 if (!bss)
734 return 0; 736 return 0;
735 737
@@ -1242,7 +1244,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev,
1242 * update our stored copy */ 1244 * update our stored copy */
1243 if (elems.erp_info && elems.erp_info_len >= 1) { 1245 if (elems.erp_info && elems.erp_info_len >= 1) {
1244 struct ieee80211_sta_bss *bss 1246 struct ieee80211_sta_bss *bss
1245 = ieee80211_rx_bss_get(dev, ifsta->bssid); 1247 = ieee80211_rx_bss_get(dev, ifsta->bssid,
1248 local->hw.conf.channel);
1246 if (bss) { 1249 if (bss) {
1247 bss->erp_value = elems.erp_info[0]; 1250 bss->erp_value = elems.erp_info[0];
1248 bss->has_erp_value = 1; 1251 bss->has_erp_value = 1;
@@ -1272,7 +1275,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev,
1272 " AP\n", dev->name); 1275 " AP\n", dev->name);
1273 return; 1276 return;
1274 } 1277 }
1275 bss = ieee80211_rx_bss_get(dev, ifsta->bssid); 1278 bss = ieee80211_rx_bss_get(dev, ifsta->bssid,
1279 local->hw.conf.channel);
1276 if (bss) { 1280 if (bss) {
1277 sta->last_rssi = bss->rssi; 1281 sta->last_rssi = bss->rssi;
1278 sta->last_signal = bss->signal; 1282 sta->last_signal = bss->signal;
@@ -1348,7 +1352,7 @@ static void __ieee80211_rx_bss_hash_del(struct net_device *dev,
1348 1352
1349 1353
1350static struct ieee80211_sta_bss * 1354static struct ieee80211_sta_bss *
1351ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid) 1355ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int channel)
1352{ 1356{
1353 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1357 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1354 struct ieee80211_sta_bss *bss; 1358 struct ieee80211_sta_bss *bss;
@@ -1359,6 +1363,7 @@ ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid)
1359 atomic_inc(&bss->users); 1363 atomic_inc(&bss->users);
1360 atomic_inc(&bss->users); 1364 atomic_inc(&bss->users);
1361 memcpy(bss->bssid, bssid, ETH_ALEN); 1365 memcpy(bss->bssid, bssid, ETH_ALEN);
1366 bss->channel = channel;
1362 1367
1363 spin_lock_bh(&local->sta_bss_lock); 1368 spin_lock_bh(&local->sta_bss_lock);
1364 /* TODO: order by RSSI? */ 1369 /* TODO: order by RSSI? */
@@ -1370,7 +1375,7 @@ ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid)
1370 1375
1371 1376
1372static struct ieee80211_sta_bss * 1377static struct ieee80211_sta_bss *
1373ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid) 1378ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel)
1374{ 1379{
1375 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1380 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1376 struct ieee80211_sta_bss *bss; 1381 struct ieee80211_sta_bss *bss;
@@ -1378,7 +1383,8 @@ ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid)
1378 spin_lock_bh(&local->sta_bss_lock); 1383 spin_lock_bh(&local->sta_bss_lock);
1379 bss = local->sta_bss_hash[STA_HASH(bssid)]; 1384 bss = local->sta_bss_hash[STA_HASH(bssid)];
1380 while (bss) { 1385 while (bss) {
1381 if (memcmp(bss->bssid, bssid, ETH_ALEN) == 0) { 1386 if (memcmp(bss->bssid, bssid, ETH_ALEN) == 0 &&
1387 bss->channel == channel) {
1382 atomic_inc(&bss->users); 1388 atomic_inc(&bss->users);
1383 break; 1389 break;
1384 } 1390 }
@@ -1546,9 +1552,9 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
1546 else 1552 else
1547 channel = rx_status->channel; 1553 channel = rx_status->channel;
1548 1554
1549 bss = ieee80211_rx_bss_get(dev, mgmt->bssid); 1555 bss = ieee80211_rx_bss_get(dev, mgmt->bssid, channel);
1550 if (!bss) { 1556 if (!bss) {
1551 bss = ieee80211_rx_bss_add(dev, mgmt->bssid); 1557 bss = ieee80211_rx_bss_add(dev, mgmt->bssid, channel);
1552 if (!bss) 1558 if (!bss)
1553 return; 1559 return;
1554 } else { 1560 } else {
@@ -1648,7 +1654,6 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
1648 1654
1649 1655
1650 bss->hw_mode = rx_status->phymode; 1656 bss->hw_mode = rx_status->phymode;
1651 bss->channel = channel;
1652 bss->freq = rx_status->freq; 1657 bss->freq = rx_status->freq;
1653 if (channel != rx_status->channel && 1658 if (channel != rx_status->channel &&
1654 (bss->hw_mode == MODE_IEEE80211G || 1659 (bss->hw_mode == MODE_IEEE80211G ||
@@ -2399,7 +2404,7 @@ static int ieee80211_sta_create_ibss(struct net_device *dev,
2399 printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %s\n", 2404 printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %s\n",
2400 dev->name, print_mac(mac, bssid)); 2405 dev->name, print_mac(mac, bssid));
2401 2406
2402 bss = ieee80211_rx_bss_add(dev, bssid); 2407 bss = ieee80211_rx_bss_add(dev, bssid, local->hw.conf.channel);
2403 if (!bss) 2408 if (!bss)
2404 return -ENOMEM; 2409 return -ENOMEM;
2405 2410
@@ -2410,7 +2415,6 @@ static int ieee80211_sta_create_ibss(struct net_device *dev,
2410 local->hw.conf.beacon_int = 100; 2415 local->hw.conf.beacon_int = 100;
2411 bss->beacon_int = local->hw.conf.beacon_int; 2416 bss->beacon_int = local->hw.conf.beacon_int;
2412 bss->hw_mode = local->hw.conf.phymode; 2417 bss->hw_mode = local->hw.conf.phymode;
2413 bss->channel = local->hw.conf.channel;
2414 bss->freq = local->hw.conf.freq; 2418 bss->freq = local->hw.conf.freq;
2415 bss->last_update = jiffies; 2419 bss->last_update = jiffies;
2416 bss->capability = WLAN_CAPABILITY_IBSS; 2420 bss->capability = WLAN_CAPABILITY_IBSS;
@@ -2470,7 +2474,7 @@ static int ieee80211_sta_find_ibss(struct net_device *dev,
2470 "%s\n", print_mac(mac, bssid), print_mac(mac2, ifsta->bssid)); 2474 "%s\n", print_mac(mac, bssid), print_mac(mac2, ifsta->bssid));
2471#endif /* CONFIG_MAC80211_IBSS_DEBUG */ 2475#endif /* CONFIG_MAC80211_IBSS_DEBUG */
2472 if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 && 2476 if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 &&
2473 (bss = ieee80211_rx_bss_get(dev, bssid))) { 2477 (bss = ieee80211_rx_bss_get(dev, bssid, local->hw.conf.channel))) {
2474 printk(KERN_DEBUG "%s: Selected IBSS BSSID %s" 2478 printk(KERN_DEBUG "%s: Selected IBSS BSSID %s"
2475 " based on configured SSID\n", 2479 " based on configured SSID\n",
2476 dev->name, print_mac(mac, bssid)); 2480 dev->name, print_mac(mac, bssid));