diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2009-02-10 15:26:00 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-02-13 13:45:58 -0500 |
commit | 00d3f14cf9f12c21428121026a5e1d5f65926447 (patch) | |
tree | e5f355deef7b9ebb5b3bf65f9d589bd2a1cfbafa /net/mac80211 | |
parent | 79420f09e76e8e1dd1149d6ce9c20e06cbb5802a (diff) |
mac80211: use cfg80211s BSS infrastructure
Remove all the code from mac80211 to keep track of BSSes
and use the cfg80211-provided code completely.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/ieee80211_i.h | 42 | ||||
-rw-r--r-- | net/mac80211/main.c | 6 | ||||
-rw-r--r-- | net/mac80211/mesh.c | 10 | ||||
-rw-r--r-- | net/mac80211/mesh.h | 1 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 213 | ||||
-rw-r--r-- | net/mac80211/scan.c | 253 | ||||
-rw-r--r-- | net/mac80211/spectmgmt.c | 7 |
7 files changed, 114 insertions, 418 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 87d63fe61bf9..678278344d79 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -72,43 +72,36 @@ struct ieee80211_fragment_entry { | |||
72 | 72 | ||
73 | 73 | ||
74 | struct ieee80211_bss { | 74 | struct ieee80211_bss { |
75 | struct list_head list; | 75 | /* Yes, this is a hack */ |
76 | struct ieee80211_bss *hnext; | 76 | struct cfg80211_bss cbss; |
77 | size_t ssid_len; | ||
78 | 77 | ||
79 | atomic_t users; | 78 | /* don't want to look up all the time */ |
80 | 79 | size_t ssid_len; | |
81 | u8 bssid[ETH_ALEN]; | ||
82 | u8 ssid[IEEE80211_MAX_SSID_LEN]; | 80 | u8 ssid[IEEE80211_MAX_SSID_LEN]; |
81 | |||
83 | u8 dtim_period; | 82 | u8 dtim_period; |
84 | u16 capability; /* host byte order */ | 83 | |
85 | enum ieee80211_band band; | ||
86 | int freq; | ||
87 | int signal, noise, qual; | ||
88 | u8 *ies; /* all information elements from the last Beacon or Probe | ||
89 | * Response frames; note Beacon frame is not allowed to | ||
90 | * override values from Probe Response */ | ||
91 | size_t ies_len; | ||
92 | bool wmm_used; | 84 | bool wmm_used; |
85 | |||
86 | unsigned long last_probe_resp; | ||
87 | |||
93 | #ifdef CONFIG_MAC80211_MESH | 88 | #ifdef CONFIG_MAC80211_MESH |
94 | u8 *mesh_id; | 89 | u8 *mesh_id; |
95 | size_t mesh_id_len; | 90 | size_t mesh_id_len; |
96 | u8 *mesh_cfg; | 91 | u8 *mesh_cfg; |
97 | #endif | 92 | #endif |
93 | |||
98 | #define IEEE80211_MAX_SUPP_RATES 32 | 94 | #define IEEE80211_MAX_SUPP_RATES 32 |
99 | u8 supp_rates[IEEE80211_MAX_SUPP_RATES]; | 95 | u8 supp_rates[IEEE80211_MAX_SUPP_RATES]; |
100 | size_t supp_rates_len; | 96 | size_t supp_rates_len; |
101 | u64 timestamp; | ||
102 | int beacon_int; | ||
103 | 97 | ||
104 | unsigned long last_probe_resp; | 98 | /* |
105 | unsigned long last_update; | 99 | * During assocation, we save an ERP value from a probe response so |
106 | |||
107 | /* during assocation, we save an ERP value from a probe response so | ||
108 | * that we can feed ERP info to the driver when handling the | 100 | * that we can feed ERP info to the driver when handling the |
109 | * association completes. these fields probably won't be up-to-date | 101 | * association completes. these fields probably won't be up-to-date |
110 | * otherwise, you probably don't want to use them. */ | 102 | * otherwise, you probably don't want to use them. |
111 | int has_erp_value; | 103 | */ |
104 | bool has_erp_value; | ||
112 | u8 erp_value; | 105 | u8 erp_value; |
113 | }; | 106 | }; |
114 | 107 | ||
@@ -668,9 +661,6 @@ struct ieee80211_local { | |||
668 | struct ieee80211_sub_if_data *scan_sdata; | 661 | struct ieee80211_sub_if_data *scan_sdata; |
669 | enum nl80211_channel_type oper_channel_type; | 662 | enum nl80211_channel_type oper_channel_type; |
670 | struct ieee80211_channel *oper_channel, *csa_channel; | 663 | struct ieee80211_channel *oper_channel, *csa_channel; |
671 | struct list_head bss_list; | ||
672 | struct ieee80211_bss *bss_hash[STA_HASH_SIZE]; | ||
673 | spinlock_t bss_lock; | ||
674 | 664 | ||
675 | /* SNMP counters */ | 665 | /* SNMP counters */ |
676 | /* dot11CountersTable */ | 666 | /* dot11CountersTable */ |
@@ -936,8 +926,6 @@ ieee80211_rx_result | |||
936 | ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, | 926 | ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, |
937 | struct sk_buff *skb, | 927 | struct sk_buff *skb, |
938 | struct ieee80211_rx_status *rx_status); | 928 | struct ieee80211_rx_status *rx_status); |
939 | void ieee80211_rx_bss_list_init(struct ieee80211_local *local); | ||
940 | void ieee80211_rx_bss_list_deinit(struct ieee80211_local *local); | ||
941 | int ieee80211_sta_set_extra_ie(struct ieee80211_sub_if_data *sdata, | 929 | int ieee80211_sta_set_extra_ie(struct ieee80211_sub_if_data *sdata, |
942 | char *ie, size_t len); | 930 | char *ie, size_t len); |
943 | 931 | ||
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 954edfbb6b6f..b4973a1b6595 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -734,6 +734,9 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
734 | 734 | ||
735 | wiphy->privid = mac80211_wiphy_privid; | 735 | wiphy->privid = mac80211_wiphy_privid; |
736 | wiphy->max_scan_ssids = 4; | 736 | wiphy->max_scan_ssids = 4; |
737 | /* Yes, putting cfg80211_bss into ieee80211_bss is a hack */ | ||
738 | wiphy->bss_priv_size = sizeof(struct ieee80211_bss) - | ||
739 | sizeof(struct cfg80211_bss); | ||
737 | 740 | ||
738 | local = wiphy_priv(wiphy); | 741 | local = wiphy_priv(wiphy); |
739 | local->hw.wiphy = wiphy; | 742 | local->hw.wiphy = wiphy; |
@@ -877,8 +880,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
877 | mpriv->local = local; | 880 | mpriv->local = local; |
878 | local->mdev = mdev; | 881 | local->mdev = mdev; |
879 | 882 | ||
880 | ieee80211_rx_bss_list_init(local); | ||
881 | |||
882 | local->hw.workqueue = | 883 | local->hw.workqueue = |
883 | create_singlethread_workqueue(wiphy_name(local->hw.wiphy)); | 884 | create_singlethread_workqueue(wiphy_name(local->hw.wiphy)); |
884 | if (!local->hw.workqueue) { | 885 | if (!local->hw.workqueue) { |
@@ -1018,7 +1019,6 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
1018 | 1019 | ||
1019 | rtnl_unlock(); | 1020 | rtnl_unlock(); |
1020 | 1021 | ||
1021 | ieee80211_rx_bss_list_deinit(local); | ||
1022 | ieee80211_clear_tx_pending(local); | 1022 | ieee80211_clear_tx_pending(local); |
1023 | sta_info_stop(local); | 1023 | sta_info_stop(local); |
1024 | rate_control_deinitialize(local); | 1024 | rate_control_deinitialize(local); |
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 8a1fcaeee4f2..9a3e5de0410a 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -275,16 +275,6 @@ u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata, struct mesh_t | |||
275 | & tbl->hash_mask; | 275 | & tbl->hash_mask; |
276 | } | 276 | } |
277 | 277 | ||
278 | u8 mesh_id_hash(u8 *mesh_id, int mesh_id_len) | ||
279 | { | ||
280 | if (!mesh_id_len) | ||
281 | return 1; | ||
282 | else if (mesh_id_len == 1) | ||
283 | return (u8) mesh_id[0]; | ||
284 | else | ||
285 | return (u8) (mesh_id[0] + 2 * mesh_id[1]); | ||
286 | } | ||
287 | |||
288 | struct mesh_table *mesh_table_alloc(int size_order) | 278 | struct mesh_table *mesh_table_alloc(int size_order) |
289 | { | 279 | { |
290 | int i; | 280 | int i; |
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index 9e064ee98ee0..d891d7ddccd7 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h | |||
@@ -196,7 +196,6 @@ struct mesh_rmc { | |||
196 | 196 | ||
197 | /* Public interfaces */ | 197 | /* Public interfaces */ |
198 | /* Various */ | 198 | /* Various */ |
199 | u8 mesh_id_hash(u8 *mesh_id, int mesh_id_len); | ||
200 | int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr); | 199 | int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr); |
201 | int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr, | 200 | int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr, |
202 | struct ieee80211_sub_if_data *sdata); | 201 | struct ieee80211_sub_if_data *sdata); |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index c5991ec047be..c51860f66731 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -55,10 +55,10 @@ static u8 *ieee80211_bss_get_ie(struct ieee80211_bss *bss, u8 ie) | |||
55 | { | 55 | { |
56 | u8 *end, *pos; | 56 | u8 *end, *pos; |
57 | 57 | ||
58 | pos = bss->ies; | 58 | pos = bss->cbss.information_elements; |
59 | if (pos == NULL) | 59 | if (pos == NULL) |
60 | return NULL; | 60 | return NULL; |
61 | end = pos + bss->ies_len; | 61 | end = pos + bss->cbss.len_information_elements; |
62 | 62 | ||
63 | while (pos + 1 < end) { | 63 | while (pos + 1 < end) { |
64 | if (pos + 2 + pos[1] > end) | 64 | if (pos + 2 + pos[1] > end) |
@@ -289,7 +289,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, | |||
289 | local->hw.conf.channel->center_freq, | 289 | local->hw.conf.channel->center_freq, |
290 | ifsta->ssid, ifsta->ssid_len); | 290 | ifsta->ssid, ifsta->ssid_len); |
291 | if (bss) { | 291 | if (bss) { |
292 | if (bss->capability & WLAN_CAPABILITY_PRIVACY) | 292 | if (bss->cbss.capability & WLAN_CAPABILITY_PRIVACY) |
293 | capab |= WLAN_CAPABILITY_PRIVACY; | 293 | capab |= WLAN_CAPABILITY_PRIVACY; |
294 | if (bss->wmm_used) | 294 | if (bss->wmm_used) |
295 | wmm = 1; | 295 | wmm = 1; |
@@ -300,7 +300,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, | |||
300 | * b-only mode) */ | 300 | * b-only mode) */ |
301 | rates_len = ieee80211_compatible_rates(bss, sband, &rates); | 301 | rates_len = ieee80211_compatible_rates(bss, sband, &rates); |
302 | 302 | ||
303 | if ((bss->capability & WLAN_CAPABILITY_SPECTRUM_MGMT) && | 303 | if ((bss->cbss.capability & WLAN_CAPABILITY_SPECTRUM_MGMT) && |
304 | (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT)) | 304 | (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT)) |
305 | capab |= WLAN_CAPABILITY_SPECTRUM_MGMT; | 305 | capab |= WLAN_CAPABILITY_SPECTRUM_MGMT; |
306 | 306 | ||
@@ -816,12 +816,12 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
816 | ifsta->ssid, ifsta->ssid_len); | 816 | ifsta->ssid, ifsta->ssid_len); |
817 | if (bss) { | 817 | if (bss) { |
818 | /* set timing information */ | 818 | /* set timing information */ |
819 | sdata->vif.bss_conf.beacon_int = bss->beacon_int; | 819 | sdata->vif.bss_conf.beacon_int = bss->cbss.beacon_interval; |
820 | sdata->vif.bss_conf.timestamp = bss->timestamp; | 820 | sdata->vif.bss_conf.timestamp = bss->cbss.tsf; |
821 | sdata->vif.bss_conf.dtim_period = bss->dtim_period; | 821 | sdata->vif.bss_conf.dtim_period = bss->dtim_period; |
822 | 822 | ||
823 | bss_info_changed |= ieee80211_handle_bss_capability(sdata, | 823 | bss_info_changed |= ieee80211_handle_bss_capability(sdata, |
824 | bss->capability, bss->has_erp_value, bss->erp_value); | 824 | bss->cbss.capability, bss->has_erp_value, bss->erp_value); |
825 | 825 | ||
826 | ieee80211_rx_bss_put(local, bss); | 826 | ieee80211_rx_bss_put(local, bss); |
827 | } | 827 | } |
@@ -1041,7 +1041,7 @@ static int ieee80211_privacy_mismatch(struct ieee80211_sub_if_data *sdata, | |||
1041 | if (!bss) | 1041 | if (!bss) |
1042 | return 0; | 1042 | return 0; |
1043 | 1043 | ||
1044 | bss_privacy = !!(bss->capability & WLAN_CAPABILITY_PRIVACY); | 1044 | bss_privacy = !!(bss->cbss.capability & WLAN_CAPABILITY_PRIVACY); |
1045 | wep_privacy = !!ieee80211_sta_wep_configured(sdata); | 1045 | wep_privacy = !!ieee80211_sta_wep_configured(sdata); |
1046 | privacy_invoked = !!(ifsta->flags & IEEE80211_STA_PRIVACY_INVOKED); | 1046 | privacy_invoked = !!(ifsta->flags & IEEE80211_STA_PRIVACY_INVOKED); |
1047 | 1047 | ||
@@ -1416,8 +1416,6 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1416 | /* Add STA entry for the AP */ | 1416 | /* Add STA entry for the AP */ |
1417 | sta = sta_info_get(local, ifsta->bssid); | 1417 | sta = sta_info_get(local, ifsta->bssid); |
1418 | if (!sta) { | 1418 | if (!sta) { |
1419 | struct ieee80211_bss *bss; | ||
1420 | |||
1421 | newsta = true; | 1419 | newsta = true; |
1422 | 1420 | ||
1423 | sta = sta_info_alloc(sdata, ifsta->bssid, GFP_ATOMIC); | 1421 | sta = sta_info_alloc(sdata, ifsta->bssid, GFP_ATOMIC); |
@@ -1427,15 +1425,6 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1427 | rcu_read_unlock(); | 1425 | rcu_read_unlock(); |
1428 | return; | 1426 | return; |
1429 | } | 1427 | } |
1430 | bss = ieee80211_rx_bss_get(local, ifsta->bssid, | ||
1431 | local->hw.conf.channel->center_freq, | ||
1432 | ifsta->ssid, ifsta->ssid_len); | ||
1433 | if (bss) { | ||
1434 | sta->last_signal = bss->signal; | ||
1435 | sta->last_qual = bss->qual; | ||
1436 | sta->last_noise = bss->noise; | ||
1437 | ieee80211_rx_bss_put(local, bss); | ||
1438 | } | ||
1439 | 1428 | ||
1440 | /* update new sta with its last rx activity */ | 1429 | /* update new sta with its last rx activity */ |
1441 | sta->last_rx = jiffies; | 1430 | sta->last_rx = jiffies; |
@@ -1691,10 +1680,11 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
1691 | struct ieee80211_bss *bss) | 1680 | struct ieee80211_bss *bss) |
1692 | { | 1681 | { |
1693 | return __ieee80211_sta_join_ibss(sdata, ifsta, | 1682 | return __ieee80211_sta_join_ibss(sdata, ifsta, |
1694 | bss->bssid, bss->beacon_int, | 1683 | bss->cbss.bssid, |
1695 | bss->freq, | 1684 | bss->cbss.beacon_interval, |
1685 | bss->cbss.channel->center_freq, | ||
1696 | bss->supp_rates_len, bss->supp_rates, | 1686 | bss->supp_rates_len, bss->supp_rates, |
1697 | bss->capability); | 1687 | bss->cbss.capability); |
1698 | } | 1688 | } |
1699 | 1689 | ||
1700 | static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | 1690 | static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, |
@@ -1769,7 +1759,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
1769 | } | 1759 | } |
1770 | 1760 | ||
1771 | /* was just updated in ieee80211_bss_info_update */ | 1761 | /* was just updated in ieee80211_bss_info_update */ |
1772 | beacon_timestamp = bss->timestamp; | 1762 | beacon_timestamp = bss->cbss.tsf; |
1773 | 1763 | ||
1774 | /* | 1764 | /* |
1775 | * In STA mode, the remaining parameters should not be overridden | 1765 | * In STA mode, the remaining parameters should not be overridden |
@@ -1784,8 +1774,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
1784 | /* check if we need to merge IBSS */ | 1774 | /* check if we need to merge IBSS */ |
1785 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC && beacon && | 1775 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC && beacon && |
1786 | (!(sdata->u.sta.flags & IEEE80211_STA_BSSID_SET)) && | 1776 | (!(sdata->u.sta.flags & IEEE80211_STA_BSSID_SET)) && |
1787 | bss->capability & WLAN_CAPABILITY_IBSS && | 1777 | bss->cbss.capability & WLAN_CAPABILITY_IBSS && |
1788 | bss->freq == local->oper_channel->center_freq && | 1778 | bss->cbss.channel == local->oper_channel && |
1789 | elems->ssid_len == sdata->u.sta.ssid_len && | 1779 | elems->ssid_len == sdata->u.sta.ssid_len && |
1790 | memcmp(elems->ssid, sdata->u.sta.ssid, | 1780 | memcmp(elems->ssid, sdata->u.sta.ssid, |
1791 | sdata->u.sta.ssid_len) == 0) { | 1781 | sdata->u.sta.ssid_len) == 0) { |
@@ -2230,37 +2220,6 @@ static void ieee80211_sta_reset_auth(struct ieee80211_sub_if_data *sdata, | |||
2230 | netif_carrier_off(sdata->dev); | 2220 | netif_carrier_off(sdata->dev); |
2231 | } | 2221 | } |
2232 | 2222 | ||
2233 | |||
2234 | static int ieee80211_sta_match_ssid(struct ieee80211_if_sta *ifsta, | ||
2235 | const char *ssid, int ssid_len) | ||
2236 | { | ||
2237 | int tmp, hidden_ssid; | ||
2238 | |||
2239 | if (ssid_len == ifsta->ssid_len && | ||
2240 | !memcmp(ifsta->ssid, ssid, ssid_len)) | ||
2241 | return 1; | ||
2242 | |||
2243 | if (ifsta->flags & IEEE80211_STA_AUTO_BSSID_SEL) | ||
2244 | return 0; | ||
2245 | |||
2246 | hidden_ssid = 1; | ||
2247 | tmp = ssid_len; | ||
2248 | while (tmp--) { | ||
2249 | if (ssid[tmp] != '\0') { | ||
2250 | hidden_ssid = 0; | ||
2251 | break; | ||
2252 | } | ||
2253 | } | ||
2254 | |||
2255 | if (hidden_ssid && (ifsta->ssid_len == ssid_len || ssid_len == 0)) | ||
2256 | return 1; | ||
2257 | |||
2258 | if (ssid_len == 1 && ssid[0] == ' ') | ||
2259 | return 1; | ||
2260 | |||
2261 | return 0; | ||
2262 | } | ||
2263 | |||
2264 | static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata, | 2223 | static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata, |
2265 | struct ieee80211_if_sta *ifsta) | 2224 | struct ieee80211_if_sta *ifsta) |
2266 | { | 2225 | { |
@@ -2319,8 +2278,6 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata, | |||
2319 | { | 2278 | { |
2320 | struct ieee80211_local *local = sdata->local; | 2279 | struct ieee80211_local *local = sdata->local; |
2321 | struct ieee80211_bss *bss; | 2280 | struct ieee80211_bss *bss; |
2322 | int found = 0; | ||
2323 | u8 bssid[ETH_ALEN]; | ||
2324 | int active_ibss; | 2281 | int active_ibss; |
2325 | 2282 | ||
2326 | if (ifsta->ssid_len == 0) | 2283 | if (ifsta->ssid_len == 0) |
@@ -2331,56 +2288,39 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata, | |||
2331 | printk(KERN_DEBUG "%s: sta_find_ibss (active_ibss=%d)\n", | 2288 | printk(KERN_DEBUG "%s: sta_find_ibss (active_ibss=%d)\n", |
2332 | sdata->dev->name, active_ibss); | 2289 | sdata->dev->name, active_ibss); |
2333 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | 2290 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ |
2334 | spin_lock_bh(&local->bss_lock); | 2291 | |
2335 | list_for_each_entry(bss, &local->bss_list, list) { | 2292 | if (active_ibss) |
2336 | if (ifsta->ssid_len != bss->ssid_len || | 2293 | return 0; |
2337 | memcmp(ifsta->ssid, bss->ssid, bss->ssid_len) != 0 | 2294 | |
2338 | || !(bss->capability & WLAN_CAPABILITY_IBSS)) | 2295 | if (ifsta->flags & IEEE80211_STA_BSSID_SET) |
2339 | continue; | 2296 | bss = ieee80211_rx_bss_get(local, ifsta->bssid, 0, |
2340 | if ((ifsta->flags & IEEE80211_STA_BSSID_SET) && | 2297 | ifsta->ssid, ifsta->ssid_len); |
2341 | memcmp(ifsta->bssid, bss->bssid, ETH_ALEN) != 0) | 2298 | else |
2342 | continue; | 2299 | bss = (void *)cfg80211_get_ibss(local->hw.wiphy, |
2343 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 2300 | NULL, |
2344 | printk(KERN_DEBUG " bssid=%pM found\n", bss->bssid); | 2301 | ifsta->ssid, ifsta->ssid_len); |
2345 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | ||
2346 | memcpy(bssid, bss->bssid, ETH_ALEN); | ||
2347 | found = 1; | ||
2348 | if (active_ibss || memcmp(bssid, ifsta->bssid, ETH_ALEN) != 0) | ||
2349 | break; | ||
2350 | } | ||
2351 | spin_unlock_bh(&local->bss_lock); | ||
2352 | 2302 | ||
2353 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 2303 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
2354 | if (found) | 2304 | if (bss) |
2355 | printk(KERN_DEBUG " sta_find_ibss: selected %pM current " | 2305 | printk(KERN_DEBUG " sta_find_ibss: selected %pM current " |
2356 | "%pM\n", bssid, ifsta->bssid); | 2306 | "%pM\n", bss->cbss.bssid, ifsta->bssid); |
2357 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | 2307 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ |
2358 | 2308 | ||
2359 | if (found && | 2309 | if (bss && |
2360 | ((!(ifsta->flags & IEEE80211_STA_PREV_BSSID_SET)) || | 2310 | (!(ifsta->flags & IEEE80211_STA_PREV_BSSID_SET) || |
2361 | memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0)) { | 2311 | memcmp(ifsta->bssid, bss->cbss.bssid, ETH_ALEN))) { |
2362 | int ret; | 2312 | int ret; |
2363 | int search_freq; | ||
2364 | |||
2365 | if (ifsta->flags & IEEE80211_STA_AUTO_CHANNEL_SEL) | ||
2366 | search_freq = bss->freq; | ||
2367 | else | ||
2368 | search_freq = local->hw.conf.channel->center_freq; | ||
2369 | |||
2370 | bss = ieee80211_rx_bss_get(local, bssid, search_freq, | ||
2371 | ifsta->ssid, ifsta->ssid_len); | ||
2372 | if (!bss) | ||
2373 | goto dont_join; | ||
2374 | 2313 | ||
2375 | printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM" | 2314 | printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM" |
2376 | " based on configured SSID\n", | 2315 | " based on configured SSID\n", |
2377 | sdata->dev->name, bssid); | 2316 | sdata->dev->name, bss->cbss.bssid); |
2317 | |||
2378 | ret = ieee80211_sta_join_ibss(sdata, ifsta, bss); | 2318 | ret = ieee80211_sta_join_ibss(sdata, ifsta, bss); |
2379 | ieee80211_rx_bss_put(local, bss); | 2319 | ieee80211_rx_bss_put(local, bss); |
2380 | return ret; | 2320 | return ret; |
2381 | } | 2321 | } else if (bss) |
2322 | ieee80211_rx_bss_put(local, bss); | ||
2382 | 2323 | ||
2383 | dont_join: | ||
2384 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 2324 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
2385 | printk(KERN_DEBUG " did not try to join ibss\n"); | 2325 | printk(KERN_DEBUG " did not try to join ibss\n"); |
2386 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | 2326 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ |
@@ -2436,51 +2376,44 @@ static int ieee80211_sta_config_auth(struct ieee80211_sub_if_data *sdata, | |||
2436 | struct ieee80211_if_sta *ifsta) | 2376 | struct ieee80211_if_sta *ifsta) |
2437 | { | 2377 | { |
2438 | struct ieee80211_local *local = sdata->local; | 2378 | struct ieee80211_local *local = sdata->local; |
2439 | struct ieee80211_bss *bss, *selected = NULL; | 2379 | struct ieee80211_bss *bss; |
2440 | int top_rssi = 0, freq; | 2380 | u8 *bssid = ifsta->bssid, *ssid = ifsta->ssid; |
2441 | 2381 | u8 ssid_len = ifsta->ssid_len; | |
2442 | spin_lock_bh(&local->bss_lock); | 2382 | u16 capa_mask = WLAN_CAPABILITY_ESS; |
2443 | freq = local->oper_channel->center_freq; | 2383 | u16 capa_val = WLAN_CAPABILITY_ESS; |
2444 | list_for_each_entry(bss, &local->bss_list, list) { | 2384 | struct ieee80211_channel *chan = local->oper_channel; |
2445 | if (!(bss->capability & WLAN_CAPABILITY_ESS)) | 2385 | |
2446 | continue; | 2386 | if (ifsta->flags & (IEEE80211_STA_AUTO_SSID_SEL | |
2447 | 2387 | IEEE80211_STA_AUTO_BSSID_SEL | | |
2448 | if ((ifsta->flags & (IEEE80211_STA_AUTO_SSID_SEL | | 2388 | IEEE80211_STA_AUTO_CHANNEL_SEL)) { |
2449 | IEEE80211_STA_AUTO_BSSID_SEL | | 2389 | capa_mask |= WLAN_CAPABILITY_PRIVACY; |
2450 | IEEE80211_STA_AUTO_CHANNEL_SEL)) && | 2390 | if (sdata->default_key) |
2451 | (!!(bss->capability & WLAN_CAPABILITY_PRIVACY) ^ | 2391 | capa_val |= WLAN_CAPABILITY_PRIVACY; |
2452 | !!sdata->default_key)) | ||
2453 | continue; | ||
2454 | |||
2455 | if (!(ifsta->flags & IEEE80211_STA_AUTO_CHANNEL_SEL) && | ||
2456 | bss->freq != freq) | ||
2457 | continue; | ||
2458 | |||
2459 | if (!(ifsta->flags & IEEE80211_STA_AUTO_BSSID_SEL) && | ||
2460 | memcmp(bss->bssid, ifsta->bssid, ETH_ALEN)) | ||
2461 | continue; | ||
2462 | |||
2463 | if (!(ifsta->flags & IEEE80211_STA_AUTO_SSID_SEL) && | ||
2464 | !ieee80211_sta_match_ssid(ifsta, bss->ssid, bss->ssid_len)) | ||
2465 | continue; | ||
2466 | |||
2467 | if (!selected || top_rssi < bss->signal) { | ||
2468 | selected = bss; | ||
2469 | top_rssi = bss->signal; | ||
2470 | } | ||
2471 | } | 2392 | } |
2472 | if (selected) | ||
2473 | atomic_inc(&selected->users); | ||
2474 | spin_unlock_bh(&local->bss_lock); | ||
2475 | 2393 | ||
2476 | if (selected) { | 2394 | if (ifsta->flags & IEEE80211_STA_AUTO_CHANNEL_SEL) |
2477 | ieee80211_set_freq(sdata, selected->freq); | 2395 | chan = NULL; |
2396 | |||
2397 | if (ifsta->flags & IEEE80211_STA_AUTO_BSSID_SEL) | ||
2398 | bssid = NULL; | ||
2399 | |||
2400 | if (ifsta->flags & IEEE80211_STA_AUTO_SSID_SEL) { | ||
2401 | ssid = NULL; | ||
2402 | ssid_len = 0; | ||
2403 | } | ||
2404 | |||
2405 | bss = (void *)cfg80211_get_bss(local->hw.wiphy, chan, | ||
2406 | bssid, ssid, ssid_len, | ||
2407 | capa_mask, capa_val); | ||
2408 | |||
2409 | if (bss) { | ||
2410 | ieee80211_set_freq(sdata, bss->cbss.channel->center_freq); | ||
2478 | if (!(ifsta->flags & IEEE80211_STA_SSID_SET)) | 2411 | if (!(ifsta->flags & IEEE80211_STA_SSID_SET)) |
2479 | ieee80211_sta_set_ssid(sdata, selected->ssid, | 2412 | ieee80211_sta_set_ssid(sdata, bss->ssid, |
2480 | selected->ssid_len); | 2413 | bss->ssid_len); |
2481 | ieee80211_sta_set_bssid(sdata, selected->bssid); | 2414 | ieee80211_sta_set_bssid(sdata, bss->cbss.bssid); |
2482 | ieee80211_sta_def_wmm_params(sdata, selected->supp_rates_len, | 2415 | ieee80211_sta_def_wmm_params(sdata, bss->supp_rates_len, |
2483 | selected->supp_rates); | 2416 | bss->supp_rates); |
2484 | if (sdata->u.sta.mfp == IEEE80211_MFP_REQUIRED) | 2417 | if (sdata->u.sta.mfp == IEEE80211_MFP_REQUIRED) |
2485 | sdata->u.sta.flags |= IEEE80211_STA_MFP_ENABLED; | 2418 | sdata->u.sta.flags |= IEEE80211_STA_MFP_ENABLED; |
2486 | else | 2419 | else |
@@ -2489,14 +2422,14 @@ static int ieee80211_sta_config_auth(struct ieee80211_sub_if_data *sdata, | |||
2489 | /* Send out direct probe if no probe resp was received or | 2422 | /* Send out direct probe if no probe resp was received or |
2490 | * the one we have is outdated | 2423 | * the one we have is outdated |
2491 | */ | 2424 | */ |
2492 | if (!selected->last_probe_resp || | 2425 | if (!bss->last_probe_resp || |
2493 | time_after(jiffies, selected->last_probe_resp | 2426 | time_after(jiffies, bss->last_probe_resp |
2494 | + IEEE80211_SCAN_RESULT_EXPIRE)) | 2427 | + IEEE80211_SCAN_RESULT_EXPIRE)) |
2495 | ifsta->state = IEEE80211_STA_MLME_DIRECT_PROBE; | 2428 | ifsta->state = IEEE80211_STA_MLME_DIRECT_PROBE; |
2496 | else | 2429 | else |
2497 | ifsta->state = IEEE80211_STA_MLME_AUTHENTICATE; | 2430 | ifsta->state = IEEE80211_STA_MLME_AUTHENTICATE; |
2498 | 2431 | ||
2499 | ieee80211_rx_bss_put(local, selected); | 2432 | ieee80211_rx_bss_put(local, bss); |
2500 | ieee80211_sta_reset_auth(sdata, ifsta); | 2433 | ieee80211_sta_reset_auth(sdata, ifsta); |
2501 | return 0; | 2434 | return 0; |
2502 | } else { | 2435 | } else { |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index fc88e2e2f923..f883ab9f1e6e 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -12,10 +12,7 @@ | |||
12 | * published by the Free Software Foundation. | 12 | * published by the Free Software Foundation. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | /* TODO: | 15 | /* TODO: figure out how to avoid that the "current BSS" expires */ |
16 | * figure out how to avoid that the "current BSS" expires | ||
17 | * use cfg80211's BSS handling | ||
18 | */ | ||
19 | 16 | ||
20 | #include <linux/wireless.h> | 17 | #include <linux/wireless.h> |
21 | #include <linux/if_arp.h> | 18 | #include <linux/if_arp.h> |
@@ -30,192 +27,29 @@ | |||
30 | #define IEEE80211_CHANNEL_TIME (HZ / 33) | 27 | #define IEEE80211_CHANNEL_TIME (HZ / 33) |
31 | #define IEEE80211_PASSIVE_CHANNEL_TIME (HZ / 5) | 28 | #define IEEE80211_PASSIVE_CHANNEL_TIME (HZ / 5) |
32 | 29 | ||
33 | void ieee80211_rx_bss_list_init(struct ieee80211_local *local) | ||
34 | { | ||
35 | spin_lock_init(&local->bss_lock); | ||
36 | INIT_LIST_HEAD(&local->bss_list); | ||
37 | } | ||
38 | |||
39 | void ieee80211_rx_bss_list_deinit(struct ieee80211_local *local) | ||
40 | { | ||
41 | struct ieee80211_bss *bss, *tmp; | ||
42 | |||
43 | list_for_each_entry_safe(bss, tmp, &local->bss_list, list) | ||
44 | ieee80211_rx_bss_put(local, bss); | ||
45 | } | ||
46 | |||
47 | struct ieee80211_bss * | 30 | struct ieee80211_bss * |
48 | ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq, | 31 | ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq, |
49 | u8 *ssid, u8 ssid_len) | 32 | u8 *ssid, u8 ssid_len) |
50 | { | 33 | { |
51 | struct ieee80211_bss *bss; | 34 | return (void *)cfg80211_get_bss(local->hw.wiphy, |
52 | 35 | ieee80211_get_channel(local->hw.wiphy, | |
53 | spin_lock_bh(&local->bss_lock); | 36 | freq), |
54 | bss = local->bss_hash[STA_HASH(bssid)]; | 37 | bssid, ssid, ssid_len, |
55 | while (bss) { | 38 | 0, 0); |
56 | if (!bss_mesh_cfg(bss) && | ||
57 | !memcmp(bss->bssid, bssid, ETH_ALEN) && | ||
58 | bss->freq == freq && | ||
59 | bss->ssid_len == ssid_len && | ||
60 | (ssid_len == 0 || !memcmp(bss->ssid, ssid, ssid_len))) { | ||
61 | atomic_inc(&bss->users); | ||
62 | break; | ||
63 | } | ||
64 | bss = bss->hnext; | ||
65 | } | ||
66 | spin_unlock_bh(&local->bss_lock); | ||
67 | return bss; | ||
68 | } | ||
69 | |||
70 | /* Caller must hold local->bss_lock */ | ||
71 | static void __ieee80211_rx_bss_hash_add(struct ieee80211_local *local, | ||
72 | struct ieee80211_bss *bss) | ||
73 | { | ||
74 | u8 hash_idx; | ||
75 | |||
76 | if (bss_mesh_cfg(bss)) | ||
77 | hash_idx = mesh_id_hash(bss_mesh_id(bss), | ||
78 | bss_mesh_id_len(bss)); | ||
79 | else | ||
80 | hash_idx = STA_HASH(bss->bssid); | ||
81 | |||
82 | bss->hnext = local->bss_hash[hash_idx]; | ||
83 | local->bss_hash[hash_idx] = bss; | ||
84 | } | ||
85 | |||
86 | /* Caller must hold local->bss_lock */ | ||
87 | static void __ieee80211_rx_bss_hash_del(struct ieee80211_local *local, | ||
88 | struct ieee80211_bss *bss) | ||
89 | { | ||
90 | struct ieee80211_bss *b, *prev = NULL; | ||
91 | b = local->bss_hash[STA_HASH(bss->bssid)]; | ||
92 | while (b) { | ||
93 | if (b == bss) { | ||
94 | if (!prev) | ||
95 | local->bss_hash[STA_HASH(bss->bssid)] = | ||
96 | bss->hnext; | ||
97 | else | ||
98 | prev->hnext = bss->hnext; | ||
99 | break; | ||
100 | } | ||
101 | prev = b; | ||
102 | b = b->hnext; | ||
103 | } | ||
104 | } | ||
105 | |||
106 | static struct ieee80211_bss * | ||
107 | ieee80211_rx_bss_add(struct ieee80211_local *local, u8 *bssid, int freq, | ||
108 | u8 *ssid, u8 ssid_len) | ||
109 | { | ||
110 | struct ieee80211_bss *bss; | ||
111 | |||
112 | bss = kzalloc(sizeof(*bss), GFP_ATOMIC); | ||
113 | if (!bss) | ||
114 | return NULL; | ||
115 | atomic_set(&bss->users, 2); | ||
116 | memcpy(bss->bssid, bssid, ETH_ALEN); | ||
117 | bss->freq = freq; | ||
118 | if (ssid && ssid_len <= IEEE80211_MAX_SSID_LEN) { | ||
119 | memcpy(bss->ssid, ssid, ssid_len); | ||
120 | bss->ssid_len = ssid_len; | ||
121 | } | ||
122 | |||
123 | spin_lock_bh(&local->bss_lock); | ||
124 | /* TODO: order by RSSI? */ | ||
125 | list_add_tail(&bss->list, &local->bss_list); | ||
126 | __ieee80211_rx_bss_hash_add(local, bss); | ||
127 | spin_unlock_bh(&local->bss_lock); | ||
128 | return bss; | ||
129 | } | ||
130 | |||
131 | #ifdef CONFIG_MAC80211_MESH | ||
132 | static struct ieee80211_bss * | ||
133 | ieee80211_rx_mesh_bss_get(struct ieee80211_local *local, u8 *mesh_id, int mesh_id_len, | ||
134 | u8 *mesh_cfg, int freq) | ||
135 | { | ||
136 | struct ieee80211_bss *bss; | ||
137 | |||
138 | spin_lock_bh(&local->bss_lock); | ||
139 | bss = local->bss_hash[mesh_id_hash(mesh_id, mesh_id_len)]; | ||
140 | while (bss) { | ||
141 | if (bss_mesh_cfg(bss) && | ||
142 | !memcmp(bss_mesh_cfg(bss), mesh_cfg, MESH_CFG_CMP_LEN) && | ||
143 | bss->freq == freq && | ||
144 | mesh_id_len == bss->mesh_id_len && | ||
145 | (mesh_id_len == 0 || !memcmp(bss->mesh_id, mesh_id, | ||
146 | mesh_id_len))) { | ||
147 | atomic_inc(&bss->users); | ||
148 | break; | ||
149 | } | ||
150 | bss = bss->hnext; | ||
151 | } | ||
152 | spin_unlock_bh(&local->bss_lock); | ||
153 | return bss; | ||
154 | } | 39 | } |
155 | 40 | ||
156 | static struct ieee80211_bss * | 41 | static void ieee80211_rx_bss_free(struct cfg80211_bss *cbss) |
157 | ieee80211_rx_mesh_bss_add(struct ieee80211_local *local, u8 *mesh_id, int mesh_id_len, | ||
158 | u8 *mesh_cfg, int mesh_config_len, int freq) | ||
159 | { | 42 | { |
160 | struct ieee80211_bss *bss; | 43 | struct ieee80211_bss *bss = (void *)cbss; |
161 | |||
162 | if (mesh_config_len != IEEE80211_MESH_CONFIG_LEN) | ||
163 | return NULL; | ||
164 | |||
165 | bss = kzalloc(sizeof(*bss), GFP_ATOMIC); | ||
166 | if (!bss) | ||
167 | return NULL; | ||
168 | |||
169 | bss->mesh_cfg = kmalloc(MESH_CFG_CMP_LEN, GFP_ATOMIC); | ||
170 | if (!bss->mesh_cfg) { | ||
171 | kfree(bss); | ||
172 | return NULL; | ||
173 | } | ||
174 | |||
175 | if (mesh_id_len && mesh_id_len <= IEEE80211_MAX_MESH_ID_LEN) { | ||
176 | bss->mesh_id = kmalloc(mesh_id_len, GFP_ATOMIC); | ||
177 | if (!bss->mesh_id) { | ||
178 | kfree(bss->mesh_cfg); | ||
179 | kfree(bss); | ||
180 | return NULL; | ||
181 | } | ||
182 | memcpy(bss->mesh_id, mesh_id, mesh_id_len); | ||
183 | } | ||
184 | |||
185 | atomic_set(&bss->users, 2); | ||
186 | memcpy(bss->mesh_cfg, mesh_cfg, MESH_CFG_CMP_LEN); | ||
187 | bss->mesh_id_len = mesh_id_len; | ||
188 | bss->freq = freq; | ||
189 | spin_lock_bh(&local->bss_lock); | ||
190 | /* TODO: order by RSSI? */ | ||
191 | list_add_tail(&bss->list, &local->bss_list); | ||
192 | __ieee80211_rx_bss_hash_add(local, bss); | ||
193 | spin_unlock_bh(&local->bss_lock); | ||
194 | return bss; | ||
195 | } | ||
196 | #endif | ||
197 | 44 | ||
198 | static void ieee80211_rx_bss_free(struct ieee80211_bss *bss) | ||
199 | { | ||
200 | kfree(bss->ies); | ||
201 | kfree(bss_mesh_id(bss)); | 45 | kfree(bss_mesh_id(bss)); |
202 | kfree(bss_mesh_cfg(bss)); | 46 | kfree(bss_mesh_cfg(bss)); |
203 | kfree(bss); | ||
204 | } | 47 | } |
205 | 48 | ||
206 | void ieee80211_rx_bss_put(struct ieee80211_local *local, | 49 | void ieee80211_rx_bss_put(struct ieee80211_local *local, |
207 | struct ieee80211_bss *bss) | 50 | struct ieee80211_bss *bss) |
208 | { | 51 | { |
209 | local_bh_disable(); | 52 | cfg80211_put_bss((struct cfg80211_bss *)bss); |
210 | if (!atomic_dec_and_lock(&bss->users, &local->bss_lock)) { | ||
211 | local_bh_enable(); | ||
212 | return; | ||
213 | } | ||
214 | |||
215 | __ieee80211_rx_bss_hash_del(local, bss); | ||
216 | list_del(&bss->list); | ||
217 | spin_unlock_bh(&local->bss_lock); | ||
218 | ieee80211_rx_bss_free(bss); | ||
219 | } | 53 | } |
220 | 54 | ||
221 | struct ieee80211_bss * | 55 | struct ieee80211_bss * |
@@ -228,7 +62,7 @@ ieee80211_bss_info_update(struct ieee80211_local *local, | |||
228 | bool beacon) | 62 | bool beacon) |
229 | { | 63 | { |
230 | struct ieee80211_bss *bss; | 64 | struct ieee80211_bss *bss; |
231 | int clen, freq = channel->center_freq; | 65 | int clen; |
232 | enum cfg80211_signal_type sigtype = CFG80211_SIGNAL_TYPE_NONE; | 66 | enum cfg80211_signal_type sigtype = CFG80211_SIGNAL_TYPE_NONE; |
233 | s32 signal = 0; | 67 | s32 signal = 0; |
234 | 68 | ||
@@ -240,39 +74,14 @@ ieee80211_bss_info_update(struct ieee80211_local *local, | |||
240 | signal = (rx_status->signal * 100) / local->hw.max_signal; | 74 | signal = (rx_status->signal * 100) / local->hw.max_signal; |
241 | } | 75 | } |
242 | 76 | ||
243 | cfg80211_put_bss( | 77 | bss = (void *)cfg80211_inform_bss_frame(local->hw.wiphy, channel, |
244 | cfg80211_inform_bss_frame(local->hw.wiphy, channel, | 78 | mgmt, len, signal, sigtype, |
245 | mgmt, len, signal, sigtype, | 79 | GFP_ATOMIC); |
246 | GFP_ATOMIC)); | ||
247 | 80 | ||
248 | #ifdef CONFIG_MAC80211_MESH | 81 | if (!bss) |
249 | if (elems->mesh_config) | 82 | return NULL; |
250 | bss = ieee80211_rx_mesh_bss_get(local, elems->mesh_id, | 83 | |
251 | elems->mesh_id_len, elems->mesh_config, freq); | 84 | bss->cbss.free_priv = ieee80211_rx_bss_free; |
252 | else | ||
253 | #endif | ||
254 | bss = ieee80211_rx_bss_get(local, mgmt->bssid, freq, | ||
255 | elems->ssid, elems->ssid_len); | ||
256 | if (!bss) { | ||
257 | #ifdef CONFIG_MAC80211_MESH | ||
258 | if (elems->mesh_config) | ||
259 | bss = ieee80211_rx_mesh_bss_add(local, elems->mesh_id, | ||
260 | elems->mesh_id_len, elems->mesh_config, | ||
261 | elems->mesh_config_len, freq); | ||
262 | else | ||
263 | #endif | ||
264 | bss = ieee80211_rx_bss_add(local, mgmt->bssid, freq, | ||
265 | elems->ssid, elems->ssid_len); | ||
266 | if (!bss) | ||
267 | return NULL; | ||
268 | } else { | ||
269 | #if 0 | ||
270 | /* TODO: order by RSSI? */ | ||
271 | spin_lock_bh(&local->bss_lock); | ||
272 | list_move_tail(&bss->list, &local->bss_list); | ||
273 | spin_unlock_bh(&local->bss_lock); | ||
274 | #endif | ||
275 | } | ||
276 | 85 | ||
277 | /* save the ERP value so that it is available at association time */ | 86 | /* save the ERP value so that it is available at association time */ |
278 | if (elems->erp_info && elems->erp_info_len >= 1) { | 87 | if (elems->erp_info && elems->erp_info_len >= 1) { |
@@ -280,9 +89,6 @@ ieee80211_bss_info_update(struct ieee80211_local *local, | |||
280 | bss->has_erp_value = 1; | 89 | bss->has_erp_value = 1; |
281 | } | 90 | } |
282 | 91 | ||
283 | bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int); | ||
284 | bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info); | ||
285 | |||
286 | if (elems->tim) { | 92 | if (elems->tim) { |
287 | struct ieee80211_tim_ie *tim_ie = | 93 | struct ieee80211_tim_ie *tim_ie = |
288 | (struct ieee80211_tim_ie *)elems->tim; | 94 | (struct ieee80211_tim_ie *)elems->tim; |
@@ -311,34 +117,11 @@ ieee80211_bss_info_update(struct ieee80211_local *local, | |||
311 | bss->supp_rates_len += clen; | 117 | bss->supp_rates_len += clen; |
312 | } | 118 | } |
313 | 119 | ||
314 | bss->band = rx_status->band; | ||
315 | |||
316 | bss->timestamp = le64_to_cpu(mgmt->u.beacon.timestamp); | ||
317 | bss->last_update = jiffies; | ||
318 | bss->signal = rx_status->signal; | ||
319 | bss->noise = rx_status->noise; | ||
320 | bss->qual = rx_status->qual; | ||
321 | bss->wmm_used = elems->wmm_param || elems->wmm_info; | 120 | bss->wmm_used = elems->wmm_param || elems->wmm_info; |
322 | 121 | ||
323 | if (!beacon) | 122 | if (!beacon) |
324 | bss->last_probe_resp = jiffies; | 123 | bss->last_probe_resp = jiffies; |
325 | 124 | ||
326 | /* | ||
327 | * For probe responses, or if we don't have any information yet, | ||
328 | * use the IEs from the beacon. | ||
329 | */ | ||
330 | if (!bss->ies || !beacon) { | ||
331 | if (bss->ies == NULL || bss->ies_len < elems->total_len) { | ||
332 | kfree(bss->ies); | ||
333 | bss->ies = kmalloc(elems->total_len, GFP_ATOMIC); | ||
334 | } | ||
335 | if (bss->ies) { | ||
336 | memcpy(bss->ies, elems->ie_start, elems->total_len); | ||
337 | bss->ies_len = elems->total_len; | ||
338 | } else | ||
339 | bss->ies_len = 0; | ||
340 | } | ||
341 | |||
342 | return bss; | 125 | return bss; |
343 | } | 126 | } |
344 | 127 | ||
@@ -350,7 +133,7 @@ void ieee80211_rx_bss_remove(struct ieee80211_sub_if_data *sdata, u8 *bssid, | |||
350 | 133 | ||
351 | bss = ieee80211_rx_bss_get(local, bssid, freq, ssid, ssid_len); | 134 | bss = ieee80211_rx_bss_get(local, bssid, freq, ssid, ssid_len); |
352 | if (bss) { | 135 | if (bss) { |
353 | atomic_dec(&bss->users); | 136 | cfg80211_unlink_bss(local->hw.wiphy, (void *)bss); |
354 | ieee80211_rx_bss_put(local, bss); | 137 | ieee80211_rx_bss_put(local, bss); |
355 | } | 138 | } |
356 | } | 139 | } |
diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c index 8d4ec2968f8f..47bb2aed2813 100644 --- a/net/mac80211/spectmgmt.c +++ b/net/mac80211/spectmgmt.c | |||
@@ -102,8 +102,9 @@ void ieee80211_chswitch_work(struct work_struct *work) | |||
102 | goto exit; | 102 | goto exit; |
103 | 103 | ||
104 | sdata->local->oper_channel = sdata->local->csa_channel; | 104 | sdata->local->oper_channel = sdata->local->csa_channel; |
105 | /* XXX: shouldn't really modify cfg80211-owned data! */ | ||
105 | if (!ieee80211_hw_config(sdata->local, IEEE80211_CONF_CHANGE_CHANNEL)) | 106 | if (!ieee80211_hw_config(sdata->local, IEEE80211_CONF_CHANGE_CHANNEL)) |
106 | bss->freq = sdata->local->oper_channel->center_freq; | 107 | bss->cbss.channel = sdata->local->oper_channel; |
107 | 108 | ||
108 | ieee80211_rx_bss_put(sdata->local, bss); | 109 | ieee80211_rx_bss_put(sdata->local, bss); |
109 | exit: | 110 | exit: |
@@ -158,7 +159,9 @@ void ieee80211_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
158 | IEEE80211_QUEUE_STOP_REASON_CSA); | 159 | IEEE80211_QUEUE_STOP_REASON_CSA); |
159 | ifsta->flags |= IEEE80211_STA_CSA_RECEIVED; | 160 | ifsta->flags |= IEEE80211_STA_CSA_RECEIVED; |
160 | mod_timer(&ifsta->chswitch_timer, | 161 | mod_timer(&ifsta->chswitch_timer, |
161 | jiffies + msecs_to_jiffies(sw_elem->count * bss->beacon_int)); | 162 | jiffies + |
163 | msecs_to_jiffies(sw_elem->count * | ||
164 | bss->cbss.beacon_interval)); | ||
162 | } | 165 | } |
163 | } | 166 | } |
164 | 167 | ||