aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c64
1 files changed, 33 insertions, 31 deletions
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 }