aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-12-23 07:15:39 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-12-28 16:54:59 -0500
commit0c1ad2cac1cb54db38fd4cc1822965071ee83f6e (patch)
treed5af632483584b7579ad8b24ba870f9b18e1aaa7 /net/mac80211
parent8e664fb3fd2b04e3ac5fad7f046000ba54e0e275 (diff)
mac80211: proper bss private data handling
cfg80211 offers private data for each BSS struct, which mac80211 uses. However, mac80211 uses internal and external (cfg80211) BSS pointers interchangeably and has a hack to put the cfg80211 bss struct into the private struct. Remove this hack, properly converting between the pointers wherever necessary. 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/cfg.c2
-rw-r--r--net/mac80211/ibss.c45
-rw-r--r--net/mac80211/ieee80211_i.h7
-rw-r--r--net/mac80211/main.c4
-rw-r--r--net/mac80211/mlme.c64
-rw-r--r--net/mac80211/scan.c29
-rw-r--r--net/mac80211/work.c3
7 files changed, 82 insertions, 72 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index fdac1bcbfcc0..ea862dfc08ed 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1343,7 +1343,7 @@ int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
1343 return 0; 1343 return 0;
1344 } 1344 }
1345 1345
1346 ap = sdata->u.mgd.associated->cbss.bssid; 1346 ap = sdata->u.mgd.associated->bssid;
1347 1347
1348 if (smps_mode == IEEE80211_SMPS_AUTOMATIC) { 1348 if (smps_mode == IEEE80211_SMPS_AUTOMATIC) {
1349 if (sdata->u.mgd.powersave) 1349 if (sdata->u.mgd.powersave)
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 3a61f3ba85c9..621a54c0573a 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -187,15 +187,17 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
187static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, 187static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
188 struct ieee80211_bss *bss) 188 struct ieee80211_bss *bss)
189{ 189{
190 struct cfg80211_bss *cbss =
191 container_of((void *)bss, struct cfg80211_bss, priv);
190 struct ieee80211_supported_band *sband; 192 struct ieee80211_supported_band *sband;
191 u32 basic_rates; 193 u32 basic_rates;
192 int i, j; 194 int i, j;
193 u16 beacon_int = bss->cbss.beacon_interval; 195 u16 beacon_int = cbss->beacon_interval;
194 196
195 if (beacon_int < 10) 197 if (beacon_int < 10)
196 beacon_int = 10; 198 beacon_int = 10;
197 199
198 sband = sdata->local->hw.wiphy->bands[bss->cbss.channel->band]; 200 sband = sdata->local->hw.wiphy->bands[cbss->channel->band];
199 201
200 basic_rates = 0; 202 basic_rates = 0;
201 203
@@ -212,12 +214,12 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
212 } 214 }
213 } 215 }
214 216
215 __ieee80211_sta_join_ibss(sdata, bss->cbss.bssid, 217 __ieee80211_sta_join_ibss(sdata, cbss->bssid,
216 beacon_int, 218 beacon_int,
217 bss->cbss.channel, 219 cbss->channel,
218 basic_rates, 220 basic_rates,
219 bss->cbss.capability, 221 cbss->capability,
220 bss->cbss.tsf); 222 cbss->tsf);
221} 223}
222 224
223static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, 225static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
@@ -229,6 +231,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
229{ 231{
230 struct ieee80211_local *local = sdata->local; 232 struct ieee80211_local *local = sdata->local;
231 int freq; 233 int freq;
234 struct cfg80211_bss *cbss;
232 struct ieee80211_bss *bss; 235 struct ieee80211_bss *bss;
233 struct sta_info *sta; 236 struct sta_info *sta;
234 struct ieee80211_channel *channel; 237 struct ieee80211_channel *channel;
@@ -283,8 +286,10 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
283 if (!bss) 286 if (!bss)
284 return; 287 return;
285 288
289 cbss = container_of((void *)bss, struct cfg80211_bss, priv);
290
286 /* was just updated in ieee80211_bss_info_update */ 291 /* was just updated in ieee80211_bss_info_update */
287 beacon_timestamp = bss->cbss.tsf; 292 beacon_timestamp = cbss->tsf;
288 293
289 /* check if we need to merge IBSS */ 294 /* check if we need to merge IBSS */
290 295
@@ -297,11 +302,11 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
297 goto put_bss; 302 goto put_bss;
298 303
299 /* not an IBSS */ 304 /* not an IBSS */
300 if (!(bss->cbss.capability & WLAN_CAPABILITY_IBSS)) 305 if (!(cbss->capability & WLAN_CAPABILITY_IBSS))
301 goto put_bss; 306 goto put_bss;
302 307
303 /* different channel */ 308 /* different channel */
304 if (bss->cbss.channel != local->oper_channel) 309 if (cbss->channel != local->oper_channel)
305 goto put_bss; 310 goto put_bss;
306 311
307 /* different SSID */ 312 /* different SSID */
@@ -311,7 +316,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
311 goto put_bss; 316 goto put_bss;
312 317
313 /* same BSSID */ 318 /* same BSSID */
314 if (memcmp(bss->cbss.bssid, sdata->u.ibss.bssid, ETH_ALEN) == 0) 319 if (memcmp(cbss->bssid, sdata->u.ibss.bssid, ETH_ALEN) == 0)
315 goto put_bss; 320 goto put_bss;
316 321
317 if (rx_status->flag & RX_FLAG_TSFT) { 322 if (rx_status->flag & RX_FLAG_TSFT) {
@@ -514,7 +519,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
514{ 519{
515 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 520 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
516 struct ieee80211_local *local = sdata->local; 521 struct ieee80211_local *local = sdata->local;
517 struct ieee80211_bss *bss; 522 struct cfg80211_bss *cbss;
518 struct ieee80211_channel *chan = NULL; 523 struct ieee80211_channel *chan = NULL;
519 const u8 *bssid = NULL; 524 const u8 *bssid = NULL;
520 int active_ibss; 525 int active_ibss;
@@ -538,21 +543,23 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
538 chan = ifibss->channel; 543 chan = ifibss->channel;
539 if (!is_zero_ether_addr(ifibss->bssid)) 544 if (!is_zero_ether_addr(ifibss->bssid))
540 bssid = ifibss->bssid; 545 bssid = ifibss->bssid;
541 bss = (void *)cfg80211_get_bss(local->hw.wiphy, chan, bssid, 546 cbss = cfg80211_get_bss(local->hw.wiphy, chan, bssid,
542 ifibss->ssid, ifibss->ssid_len, 547 ifibss->ssid, ifibss->ssid_len,
543 WLAN_CAPABILITY_IBSS | 548 WLAN_CAPABILITY_IBSS | WLAN_CAPABILITY_PRIVACY,
544 WLAN_CAPABILITY_PRIVACY, 549 capability);
545 capability); 550
551 if (cbss) {
552 struct ieee80211_bss *bss;
546 553
547 if (bss) { 554 bss = (void *)cbss->priv;
548#ifdef CONFIG_MAC80211_IBSS_DEBUG 555#ifdef CONFIG_MAC80211_IBSS_DEBUG
549 printk(KERN_DEBUG " sta_find_ibss: selected %pM current " 556 printk(KERN_DEBUG " sta_find_ibss: selected %pM current "
550 "%pM\n", bss->cbss.bssid, ifibss->bssid); 557 "%pM\n", cbss->bssid, ifibss->bssid);
551#endif /* CONFIG_MAC80211_IBSS_DEBUG */ 558#endif /* CONFIG_MAC80211_IBSS_DEBUG */
552 559
553 printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM" 560 printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM"
554 " based on configured SSID\n", 561 " based on configured SSID\n",
555 sdata->name, bss->cbss.bssid); 562 sdata->name, cbss->bssid);
556 563
557 ieee80211_sta_join_ibss(sdata, bss); 564 ieee80211_sta_join_ibss(sdata, bss);
558 ieee80211_rx_bss_put(local, bss); 565 ieee80211_rx_bss_put(local, bss);
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 6ea4ffbf84d8..de068ad6223b 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -71,9 +71,6 @@ struct ieee80211_fragment_entry {
71 71
72 72
73struct ieee80211_bss { 73struct ieee80211_bss {
74 /* Yes, this is a hack */
75 struct cfg80211_bss cbss;
76
77 /* don't want to look up all the time */ 74 /* don't want to look up all the time */
78 size_t ssid_len; 75 size_t ssid_len;
79 u8 ssid[IEEE80211_MAX_SSID_LEN]; 76 u8 ssid[IEEE80211_MAX_SSID_LEN];
@@ -274,7 +271,7 @@ struct ieee80211_work {
274 bool privacy; 271 bool privacy;
275 } probe_auth; 272 } probe_auth;
276 struct { 273 struct {
277 struct ieee80211_bss *bss; 274 struct cfg80211_bss *bss;
278 const u8 *supp_rates; 275 const u8 *supp_rates;
279 const u8 *ht_information_ie; 276 const u8 *ht_information_ie;
280 enum ieee80211_smps_mode smps; 277 enum ieee80211_smps_mode smps;
@@ -317,7 +314,7 @@ struct ieee80211_if_managed {
317 int probe_send_count; 314 int probe_send_count;
318 315
319 struct mutex mtx; 316 struct mutex mtx;
320 struct ieee80211_bss *associated; 317 struct cfg80211_bss *associated;
321 318
322 u8 bssid[ETH_ALEN]; 319 u8 bssid[ETH_ALEN];
323 320
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index d35023ce7fa1..5fcd3548417e 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -359,9 +359,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
359 WIPHY_FLAG_4ADDR_STATION; 359 WIPHY_FLAG_4ADDR_STATION;
360 wiphy->privid = mac80211_wiphy_privid; 360 wiphy->privid = mac80211_wiphy_privid;
361 361
362 /* Yes, putting cfg80211_bss into ieee80211_bss is a hack */ 362 wiphy->bss_priv_size = sizeof(struct ieee80211_bss);
363 wiphy->bss_priv_size = sizeof(struct ieee80211_bss) -
364 sizeof(struct cfg80211_bss);
365 363
366 local = wiphy_priv(wiphy); 364 local = wiphy_priv(wiphy);
367 365
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index ea434b5a779e..e44f1ed0b0da 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -330,7 +330,7 @@ static void ieee80211_chswitch_work(struct work_struct *work)
330 ieee80211_hw_config(sdata->local, IEEE80211_CONF_CHANGE_CHANNEL); 330 ieee80211_hw_config(sdata->local, IEEE80211_CONF_CHANGE_CHANNEL);
331 331
332 /* XXX: shouldn't really modify cfg80211-owned data! */ 332 /* XXX: shouldn't really modify cfg80211-owned data! */
333 ifmgd->associated->cbss.channel = sdata->local->oper_channel; 333 ifmgd->associated->channel = sdata->local->oper_channel;
334 334
335 ieee80211_wake_queues_by_reason(&sdata->local->hw, 335 ieee80211_wake_queues_by_reason(&sdata->local->hw,
336 IEEE80211_QUEUE_STOP_REASON_CSA); 336 IEEE80211_QUEUE_STOP_REASON_CSA);
@@ -357,6 +357,8 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
357 struct ieee80211_channel_sw_ie *sw_elem, 357 struct ieee80211_channel_sw_ie *sw_elem,
358 struct ieee80211_bss *bss) 358 struct ieee80211_bss *bss)
359{ 359{
360 struct cfg80211_bss *cbss =
361 container_of((void *)bss, struct cfg80211_bss, priv);
360 struct ieee80211_channel *new_ch; 362 struct ieee80211_channel *new_ch;
361 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 363 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
362 int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num); 364 int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num);
@@ -390,7 +392,7 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
390 mod_timer(&ifmgd->chswitch_timer, 392 mod_timer(&ifmgd->chswitch_timer,
391 jiffies + 393 jiffies +
392 msecs_to_jiffies(sw_elem->count * 394 msecs_to_jiffies(sw_elem->count *
393 bss->cbss.beacon_interval)); 395 cbss->beacon_interval));
394 } 396 }
395} 397}
396 398
@@ -670,23 +672,24 @@ static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
670} 672}
671 673
672static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, 674static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
673 struct ieee80211_bss *bss, 675 struct cfg80211_bss *cbss,
674 u32 bss_info_changed) 676 u32 bss_info_changed)
675{ 677{
678 struct ieee80211_bss *bss = (void *)cbss->priv;
676 struct ieee80211_local *local = sdata->local; 679 struct ieee80211_local *local = sdata->local;
677 680
678 bss_info_changed |= BSS_CHANGED_ASSOC; 681 bss_info_changed |= BSS_CHANGED_ASSOC;
679 /* set timing information */ 682 /* set timing information */
680 sdata->vif.bss_conf.beacon_int = bss->cbss.beacon_interval; 683 sdata->vif.bss_conf.beacon_int = cbss->beacon_interval;
681 sdata->vif.bss_conf.timestamp = bss->cbss.tsf; 684 sdata->vif.bss_conf.timestamp = cbss->tsf;
682 sdata->vif.bss_conf.dtim_period = bss->dtim_period; 685 sdata->vif.bss_conf.dtim_period = bss->dtim_period;
683 686
684 bss_info_changed |= BSS_CHANGED_BEACON_INT; 687 bss_info_changed |= BSS_CHANGED_BEACON_INT;
685 bss_info_changed |= ieee80211_handle_bss_capability(sdata, 688 bss_info_changed |= ieee80211_handle_bss_capability(sdata,
686 bss->cbss.capability, bss->has_erp_value, bss->erp_value); 689 cbss->capability, bss->has_erp_value, bss->erp_value);
687 690
688 sdata->u.mgd.associated = bss; 691 sdata->u.mgd.associated = cbss;
689 memcpy(sdata->u.mgd.bssid, bss->cbss.bssid, ETH_ALEN); 692 memcpy(sdata->u.mgd.bssid, cbss->bssid, ETH_ALEN);
690 693
691 /* just to be sure */ 694 /* just to be sure */
692 sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL | 695 sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL |
@@ -737,7 +740,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata)
737 if (WARN_ON(!ifmgd->associated)) 740 if (WARN_ON(!ifmgd->associated))
738 return; 741 return;
739 742
740 memcpy(bssid, ifmgd->associated->cbss.bssid, ETH_ALEN); 743 memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN);
741 744
742 ifmgd->associated = NULL; 745 ifmgd->associated = NULL;
743 memset(ifmgd->bssid, 0, ETH_ALEN); 746 memset(ifmgd->bssid, 0, ETH_ALEN);
@@ -833,8 +836,8 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
833 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 836 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
834 const u8 *ssid; 837 const u8 *ssid;
835 838
836 ssid = ieee80211_bss_get_ie(&ifmgd->associated->cbss, WLAN_EID_SSID); 839 ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID);
837 ieee80211_send_probe_req(sdata, ifmgd->associated->cbss.bssid, 840 ieee80211_send_probe_req(sdata, ifmgd->associated->bssid,
838 ssid + 2, ssid[1], NULL, 0); 841 ssid + 2, ssid[1], NULL, 0);
839 842
840 ifmgd->probe_send_count++; 843 ifmgd->probe_send_count++;
@@ -928,7 +931,7 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
928 931
929 ASSERT_MGD_MTX(ifmgd); 932 ASSERT_MGD_MTX(ifmgd);
930 933
931 bssid = ifmgd->associated->cbss.bssid; 934 bssid = ifmgd->associated->bssid;
932 935
933 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); 936 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
934 937
@@ -957,7 +960,7 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
957 if (WARN_ON(!ifmgd->associated)) 960 if (WARN_ON(!ifmgd->associated))
958 return RX_MGMT_NONE; 961 return RX_MGMT_NONE;
959 962
960 if (WARN_ON(memcmp(ifmgd->associated->cbss.bssid, mgmt->sa, ETH_ALEN))) 963 if (WARN_ON(memcmp(ifmgd->associated->bssid, mgmt->sa, ETH_ALEN)))
961 return RX_MGMT_NONE; 964 return RX_MGMT_NONE;
962 965
963 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); 966 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
@@ -979,7 +982,7 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
979 struct ieee80211_local *local = sdata->local; 982 struct ieee80211_local *local = sdata->local;
980 struct ieee80211_supported_band *sband; 983 struct ieee80211_supported_band *sband;
981 struct sta_info *sta; 984 struct sta_info *sta;
982 struct ieee80211_bss *bss = wk->assoc.bss; 985 struct cfg80211_bss *cbss = wk->assoc.bss;
983 u8 *pos; 986 u8 *pos;
984 u32 rates, basic_rates; 987 u32 rates, basic_rates;
985 u16 capab_info, aid; 988 u16 capab_info, aid;
@@ -1011,7 +1014,7 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
1011 1014
1012 ifmgd->aid = aid; 1015 ifmgd->aid = aid;
1013 1016
1014 sta = sta_info_alloc(sdata, bss->cbss.bssid, GFP_KERNEL); 1017 sta = sta_info_alloc(sdata, cbss->bssid, GFP_KERNEL);
1015 if (!sta) { 1018 if (!sta) {
1016 printk(KERN_DEBUG "%s: failed to alloc STA entry for" 1019 printk(KERN_DEBUG "%s: failed to alloc STA entry for"
1017 " the AP\n", sdata->name); 1020 " the AP\n", sdata->name);
@@ -1103,14 +1106,13 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
1103 (sdata->local->hw.queues >= 4) && 1106 (sdata->local->hw.queues >= 4) &&
1104 !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) 1107 !(ifmgd->flags & IEEE80211_STA_DISABLE_11N))
1105 changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem, 1108 changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem,
1106 bss->cbss.bssid, 1109 cbss->bssid, ap_ht_cap_flags);
1107 ap_ht_cap_flags);
1108 1110
1109 /* set AID and assoc capability, 1111 /* set AID and assoc capability,
1110 * ieee80211_set_associated() will tell the driver */ 1112 * ieee80211_set_associated() will tell the driver */
1111 bss_conf->aid = aid; 1113 bss_conf->aid = aid;
1112 bss_conf->assoc_capability = capab_info; 1114 bss_conf->assoc_capability = capab_info;
1113 ieee80211_set_associated(sdata, bss, changed); 1115 ieee80211_set_associated(sdata, cbss, changed);
1114 1116
1115 /* 1117 /*
1116 * Start timer to probe the connection to the AP now. 1118 * Start timer to probe the connection to the AP now.
@@ -1154,7 +1156,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
1154 return; 1156 return;
1155 1157
1156 if (elems->ch_switch_elem && (elems->ch_switch_elem_len == 3) && 1158 if (elems->ch_switch_elem && (elems->ch_switch_elem_len == 3) &&
1157 (memcmp(mgmt->bssid, sdata->u.mgd.associated->cbss.bssid, 1159 (memcmp(mgmt->bssid, sdata->u.mgd.associated->bssid,
1158 ETH_ALEN) == 0)) { 1160 ETH_ALEN) == 0)) {
1159 struct ieee80211_channel_sw_ie *sw_elem = 1161 struct ieee80211_channel_sw_ie *sw_elem =
1160 (struct ieee80211_channel_sw_ie *)elems->ch_switch_elem; 1162 (struct ieee80211_channel_sw_ie *)elems->ch_switch_elem;
@@ -1189,7 +1191,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
1189 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false); 1191 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false);
1190 1192
1191 if (ifmgd->associated && 1193 if (ifmgd->associated &&
1192 memcmp(mgmt->bssid, ifmgd->associated->cbss.bssid, ETH_ALEN) == 0 && 1194 memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN) == 0 &&
1193 ifmgd->flags & (IEEE80211_STA_BEACON_POLL | 1195 ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
1194 IEEE80211_STA_CONNECTION_POLL)) { 1196 IEEE80211_STA_CONNECTION_POLL)) {
1195 ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | 1197 ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
@@ -1262,7 +1264,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1262 if (!ifmgd->associated) 1264 if (!ifmgd->associated)
1263 return; 1265 return;
1264 1266
1265 bssid = ifmgd->associated->cbss.bssid; 1267 bssid = ifmgd->associated->bssid;
1266 1268
1267 /* 1269 /*
1268 * And in theory even frames from a different AP we were just 1270 * And in theory even frames from a different AP we were just
@@ -1428,8 +1430,7 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
1428 mutex_lock(&ifmgd->mtx); 1430 mutex_lock(&ifmgd->mtx);
1429 1431
1430 if (ifmgd->associated && 1432 if (ifmgd->associated &&
1431 memcmp(ifmgd->associated->cbss.bssid, mgmt->bssid, 1433 memcmp(ifmgd->associated->bssid, mgmt->bssid, ETH_ALEN) == 0) {
1432 ETH_ALEN) == 0) {
1433 switch (fc & IEEE80211_FCTL_STYPE) { 1434 switch (fc & IEEE80211_FCTL_STYPE) {
1434 case IEEE80211_STYPE_BEACON: 1435 case IEEE80211_STYPE_BEACON:
1435 ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len, 1436 ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len,
@@ -1448,7 +1449,7 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
1448 /* XXX: differentiate, can only happen for CSA now! */ 1449 /* XXX: differentiate, can only happen for CSA now! */
1449 ieee80211_sta_process_chanswitch(sdata, 1450 ieee80211_sta_process_chanswitch(sdata,
1450 &mgmt->u.action.u.chan_switch.sw_elem, 1451 &mgmt->u.action.u.chan_switch.sw_elem,
1451 ifmgd->associated); 1452 (void *)ifmgd->associated->priv);
1452 break; 1453 break;
1453 } 1454 }
1454 mutex_unlock(&ifmgd->mtx); 1455 mutex_unlock(&ifmgd->mtx);
@@ -1533,7 +1534,7 @@ static void ieee80211_sta_work(struct work_struct *work)
1533 ifmgd->associated) { 1534 ifmgd->associated) {
1534 u8 bssid[ETH_ALEN]; 1535 u8 bssid[ETH_ALEN];
1535 1536
1536 memcpy(bssid, ifmgd->associated->cbss.bssid, ETH_ALEN); 1537 memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN);
1537 if (time_is_after_jiffies(ifmgd->probe_timeout)) 1538 if (time_is_after_jiffies(ifmgd->probe_timeout))
1538 run_again(ifmgd, ifmgd->probe_timeout); 1539 run_again(ifmgd, ifmgd->probe_timeout);
1539 1540
@@ -1840,6 +1841,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
1840 struct cfg80211_assoc_request *req) 1841 struct cfg80211_assoc_request *req)
1841{ 1842{
1842 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1843 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1844 struct ieee80211_bss *bss = (void *)req->bss->priv;
1843 struct ieee80211_work *wk; 1845 struct ieee80211_work *wk;
1844 const u8 *ssid; 1846 const u8 *ssid;
1845 int i; 1847 int i;
@@ -1870,7 +1872,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
1870 } else 1872 } else
1871 wk->ie_len = 0; 1873 wk->ie_len = 0;
1872 1874
1873 wk->assoc.bss = (void *)req->bss; 1875 wk->assoc.bss = req->bss;
1874 1876
1875 memcpy(wk->filter_ta, req->bss->bssid, ETH_ALEN); 1877 memcpy(wk->filter_ta, req->bss->bssid, ETH_ALEN);
1876 1878
@@ -1893,9 +1895,9 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
1893 */ 1895 */
1894 wk->assoc.use_11n = !(ifmgd->flags & IEEE80211_STA_DISABLE_11N); 1896 wk->assoc.use_11n = !(ifmgd->flags & IEEE80211_STA_DISABLE_11N);
1895 wk->assoc.capability = req->bss->capability; 1897 wk->assoc.capability = req->bss->capability;
1896 wk->assoc.wmm_used = wk->assoc.bss->wmm_used; 1898 wk->assoc.wmm_used = bss->wmm_used;
1897 wk->assoc.supp_rates = wk->assoc.bss->supp_rates; 1899 wk->assoc.supp_rates = bss->supp_rates;
1898 wk->assoc.supp_rates_len = wk->assoc.bss->supp_rates_len; 1900 wk->assoc.supp_rates_len = bss->supp_rates_len;
1899 wk->assoc.ht_information_ie = 1901 wk->assoc.ht_information_ie =
1900 ieee80211_bss_get_ie(req->bss, WLAN_EID_HT_INFORMATION); 1902 ieee80211_bss_get_ie(req->bss, WLAN_EID_HT_INFORMATION);
1901 1903
@@ -1942,7 +1944,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
1942 1944
1943 mutex_lock(&ifmgd->mtx); 1945 mutex_lock(&ifmgd->mtx);
1944 1946
1945 if (ifmgd->associated && &ifmgd->associated->cbss == req->bss) { 1947 if (ifmgd->associated == req->bss) {
1946 bssid = req->bss->bssid; 1948 bssid = req->bss->bssid;
1947 ieee80211_set_disassoc(sdata); 1949 ieee80211_set_disassoc(sdata);
1948 mutex_unlock(&ifmgd->mtx); 1950 mutex_unlock(&ifmgd->mtx);
@@ -2004,7 +2006,7 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
2004 * to cfg80211 while that's in a locked section already 2006 * to cfg80211 while that's in a locked section already
2005 * trying to tell us that the user wants to disconnect. 2007 * trying to tell us that the user wants to disconnect.
2006 */ 2008 */
2007 if (&ifmgd->associated->cbss != req->bss) { 2009 if (ifmgd->associated != req->bss) {
2008 mutex_unlock(&ifmgd->mtx); 2010 mutex_unlock(&ifmgd->mtx);
2009 return -ENOLINK; 2011 return -ENOLINK;
2010 } 2012 }
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index fb89e4c0fbfd..2a2d7f6005af 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -29,16 +29,19 @@ struct ieee80211_bss *
29ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq, 29ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq,
30 u8 *ssid, u8 ssid_len) 30 u8 *ssid, u8 ssid_len)
31{ 31{
32 return (void *)cfg80211_get_bss(local->hw.wiphy, 32 struct cfg80211_bss *cbss;
33 ieee80211_get_channel(local->hw.wiphy, 33
34 freq), 34 cbss = cfg80211_get_bss(local->hw.wiphy,
35 bssid, ssid, ssid_len, 35 ieee80211_get_channel(local->hw.wiphy, freq),
36 0, 0); 36 bssid, ssid, ssid_len, 0, 0);
37 if (!cbss)
38 return NULL;
39 return (void *)cbss->priv;
37} 40}
38 41
39static void ieee80211_rx_bss_free(struct cfg80211_bss *cbss) 42static void ieee80211_rx_bss_free(struct cfg80211_bss *cbss)
40{ 43{
41 struct ieee80211_bss *bss = (void *)cbss; 44 struct ieee80211_bss *bss = (void *)cbss->priv;
42 45
43 kfree(bss_mesh_id(bss)); 46 kfree(bss_mesh_id(bss));
44 kfree(bss_mesh_cfg(bss)); 47 kfree(bss_mesh_cfg(bss));
@@ -47,7 +50,9 @@ static void ieee80211_rx_bss_free(struct cfg80211_bss *cbss)
47void ieee80211_rx_bss_put(struct ieee80211_local *local, 50void ieee80211_rx_bss_put(struct ieee80211_local *local,
48 struct ieee80211_bss *bss) 51 struct ieee80211_bss *bss)
49{ 52{
50 cfg80211_put_bss((struct cfg80211_bss *)bss); 53 if (!bss)
54 return;
55 cfg80211_put_bss(container_of((void *)bss, struct cfg80211_bss, priv));
51} 56}
52 57
53struct ieee80211_bss * 58struct ieee80211_bss *
@@ -59,6 +64,7 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
59 struct ieee80211_channel *channel, 64 struct ieee80211_channel *channel,
60 bool beacon) 65 bool beacon)
61{ 66{
67 struct cfg80211_bss *cbss;
62 struct ieee80211_bss *bss; 68 struct ieee80211_bss *bss;
63 int clen; 69 int clen;
64 s32 signal = 0; 70 s32 signal = 0;
@@ -68,13 +74,14 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
68 else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) 74 else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)
69 signal = (rx_status->signal * 100) / local->hw.max_signal; 75 signal = (rx_status->signal * 100) / local->hw.max_signal;
70 76
71 bss = (void *)cfg80211_inform_bss_frame(local->hw.wiphy, channel, 77 cbss = cfg80211_inform_bss_frame(local->hw.wiphy, channel,
72 mgmt, len, signal, GFP_ATOMIC); 78 mgmt, len, signal, GFP_ATOMIC);
73 79
74 if (!bss) 80 if (!cbss)
75 return NULL; 81 return NULL;
76 82
77 bss->cbss.free_priv = ieee80211_rx_bss_free; 83 cbss->free_priv = ieee80211_rx_bss_free;
84 bss = (void *)cbss->priv;
78 85
79 /* 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 */
80 if (elems->erp_info && elems->erp_info_len >= 1) { 87 if (elems->erp_info && elems->erp_info_len >= 1) {
diff --git a/net/mac80211/work.c b/net/mac80211/work.c
index affdd10b67ad..0b8c31c600aa 100644
--- a/net/mac80211/work.c
+++ b/net/mac80211/work.c
@@ -517,8 +517,7 @@ ieee80211_associate(struct ieee80211_work *wk)
517 * bss struct for that AP. 517 * bss struct for that AP.
518 */ 518 */
519 if (wk->assoc.bss) 519 if (wk->assoc.bss)
520 cfg80211_unlink_bss(local->hw.wiphy, 520 cfg80211_unlink_bss(local->hw.wiphy, wk->assoc.bss);
521 &wk->assoc.bss->cbss);
522 521
523 /* 522 /*
524 * We might have a pending scan which had no chance to run yet 523 * We might have a pending scan which had no chance to run yet