aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/ieee80211.h4
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/mlme.c20
-rw-r--r--net/mac80211/util.c4
4 files changed, 27 insertions, 3 deletions
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 9fe1948d28d3..7800e20f197f 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -914,6 +914,9 @@ enum ieee80211_statuscode {
914 /* 802.11g */ 914 /* 802.11g */
915 WLAN_STATUS_ASSOC_DENIED_NOSHORTTIME = 25, 915 WLAN_STATUS_ASSOC_DENIED_NOSHORTTIME = 25,
916 WLAN_STATUS_ASSOC_DENIED_NODSSSOFDM = 26, 916 WLAN_STATUS_ASSOC_DENIED_NODSSSOFDM = 26,
917 /* 802.11w */
918 WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY = 30,
919 WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION = 31,
917 /* 802.11i */ 920 /* 802.11i */
918 WLAN_STATUS_INVALID_IE = 40, 921 WLAN_STATUS_INVALID_IE = 40,
919 WLAN_STATUS_INVALID_GROUP_CIPHER = 41, 922 WLAN_STATUS_INVALID_GROUP_CIPHER = 41,
@@ -1034,6 +1037,7 @@ enum ieee80211_eid {
1034 /* 802.11i */ 1037 /* 802.11i */
1035 WLAN_EID_RSN = 48, 1038 WLAN_EID_RSN = 48,
1036 WLAN_EID_MMIE = 76 /* 802.11w */, 1039 WLAN_EID_MMIE = 76 /* 802.11w */,
1040 WLAN_EID_ASSOC_COMEBACK_TIME = 77,
1037 WLAN_EID_WPA = 221, 1041 WLAN_EID_WPA = 221,
1038 WLAN_EID_GENERIC = 221, 1042 WLAN_EID_GENERIC = 221,
1039 WLAN_EID_VENDOR_SPECIFIC = 221, 1043 WLAN_EID_VENDOR_SPECIFIC = 221,
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 212c732fbba7..9112c5247c35 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -820,6 +820,7 @@ struct ieee802_11_elems {
820 u8 *country_elem; 820 u8 *country_elem;
821 u8 *pwr_constr_elem; 821 u8 *pwr_constr_elem;
822 u8 *quiet_elem; /* first quite element */ 822 u8 *quiet_elem; /* first quite element */
823 u8 *assoc_comeback;
823 824
824 /* length of them, respectively */ 825 /* length of them, respectively */
825 u8 ssid_len; 826 u8 ssid_len;
@@ -847,6 +848,7 @@ struct ieee802_11_elems {
847 u8 pwr_constr_elem_len; 848 u8 pwr_constr_elem_len;
848 u8 quiet_elem_len; 849 u8 quiet_elem_len;
849 u8 num_of_quiet_elem; /* can be more the one */ 850 u8 num_of_quiet_elem; /* can be more the one */
851 u8 assoc_comeback_len;
850}; 852};
851 853
852static inline struct ieee80211_local *hw_to_local( 854static inline struct ieee80211_local *hw_to_local(
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 42c5f981c715..82c598a83687 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1275,6 +1275,23 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1275 sdata->dev->name, reassoc ? "Rea" : "A", mgmt->sa, 1275 sdata->dev->name, reassoc ? "Rea" : "A", mgmt->sa,
1276 capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14)))); 1276 capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14))));
1277 1277
1278 pos = mgmt->u.assoc_resp.variable;
1279 ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
1280
1281 if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY &&
1282 elems.assoc_comeback && elems.assoc_comeback_len == 4) {
1283 u32 tu, ms;
1284 tu = get_unaligned_le32(elems.assoc_comeback);
1285 ms = tu * 1024 / 1000;
1286 printk(KERN_DEBUG "%s: AP rejected association temporarily; "
1287 "comeback duration %u TU (%u ms)\n",
1288 sdata->dev->name, tu, ms);
1289 if (ms > IEEE80211_ASSOC_TIMEOUT)
1290 mod_timer(&ifsta->timer,
1291 jiffies + msecs_to_jiffies(ms));
1292 return;
1293 }
1294
1278 if (status_code != WLAN_STATUS_SUCCESS) { 1295 if (status_code != WLAN_STATUS_SUCCESS) {
1279 printk(KERN_DEBUG "%s: AP denied association (code=%d)\n", 1296 printk(KERN_DEBUG "%s: AP denied association (code=%d)\n",
1280 sdata->dev->name, status_code); 1297 sdata->dev->name, status_code);
@@ -1290,9 +1307,6 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1290 "set\n", sdata->dev->name, aid); 1307 "set\n", sdata->dev->name, aid);
1291 aid &= ~(BIT(15) | BIT(14)); 1308 aid &= ~(BIT(15) | BIT(14));
1292 1309
1293 pos = mgmt->u.assoc_resp.variable;
1294 ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
1295
1296 if (!elems.supp_rates) { 1310 if (!elems.supp_rates) {
1297 printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n", 1311 printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n",
1298 sdata->dev->name); 1312 sdata->dev->name);
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 5cd430333f08..963e0473205c 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -653,6 +653,10 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
653 elems->pwr_constr_elem = pos; 653 elems->pwr_constr_elem = pos;
654 elems->pwr_constr_elem_len = elen; 654 elems->pwr_constr_elem_len = elen;
655 break; 655 break;
656 case WLAN_EID_ASSOC_COMEBACK_TIME:
657 elems->assoc_comeback = pos;
658 elems->assoc_comeback_len = elen;
659 break;
656 default: 660 default:
657 break; 661 break;
658 } 662 }