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.c352
1 files changed, 262 insertions, 90 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 245dce969b31..b82a12a9f0f1 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -131,13 +131,13 @@ void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata)
131 if (unlikely(!sdata->u.mgd.associated)) 131 if (unlikely(!sdata->u.mgd.associated))
132 return; 132 return;
133 133
134 ifmgd->probe_send_count = 0;
135
134 if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) 136 if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
135 return; 137 return;
136 138
137 mod_timer(&sdata->u.mgd.conn_mon_timer, 139 mod_timer(&sdata->u.mgd.conn_mon_timer,
138 round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME)); 140 round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME));
139
140 ifmgd->probe_send_count = 0;
141} 141}
142 142
143static int ecw2cw(int ecw) 143static int ecw2cw(int ecw)
@@ -531,6 +531,7 @@ static void ieee80211_add_vht_ie(struct ieee80211_sub_if_data *sdata,
531 u8 *pos; 531 u8 *pos;
532 u32 cap; 532 u32 cap;
533 struct ieee80211_sta_vht_cap vht_cap; 533 struct ieee80211_sta_vht_cap vht_cap;
534 u32 mask, ap_bf_sts, our_bf_sts;
534 535
535 BUILD_BUG_ON(sizeof(vht_cap) != sizeof(sband->vht_cap)); 536 BUILD_BUG_ON(sizeof(vht_cap) != sizeof(sband->vht_cap));
536 537
@@ -558,6 +559,16 @@ static void ieee80211_add_vht_ie(struct ieee80211_sub_if_data *sdata,
558 cpu_to_le32(IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE))) 559 cpu_to_le32(IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)))
559 cap &= ~IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE; 560 cap &= ~IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
560 561
562 mask = IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
563
564 ap_bf_sts = le32_to_cpu(ap_vht_cap->vht_cap_info) & mask;
565 our_bf_sts = cap & mask;
566
567 if (ap_bf_sts < our_bf_sts) {
568 cap &= ~mask;
569 cap |= ap_bf_sts;
570 }
571
561 /* reserve and fill IE */ 572 /* reserve and fill IE */
562 pos = skb_put(skb, sizeof(struct ieee80211_vht_cap) + 2); 573 pos = skb_put(skb, sizeof(struct ieee80211_vht_cap) + 2);
563 ieee80211_ie_build_vht_cap(pos, &vht_cap, cap); 574 ieee80211_ie_build_vht_cap(pos, &vht_cap, cap);
@@ -768,6 +779,34 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
768 ieee80211_add_ht_ie(sdata, skb, assoc_data->ap_ht_param, 779 ieee80211_add_ht_ie(sdata, skb, assoc_data->ap_ht_param,
769 sband, chan, sdata->smps_mode); 780 sband, chan, sdata->smps_mode);
770 781
782 /* if present, add any custom IEs that go before VHT */
783 if (assoc_data->ie_len) {
784 static const u8 before_vht[] = {
785 WLAN_EID_SSID,
786 WLAN_EID_SUPP_RATES,
787 WLAN_EID_EXT_SUPP_RATES,
788 WLAN_EID_PWR_CAPABILITY,
789 WLAN_EID_SUPPORTED_CHANNELS,
790 WLAN_EID_RSN,
791 WLAN_EID_QOS_CAPA,
792 WLAN_EID_RRM_ENABLED_CAPABILITIES,
793 WLAN_EID_MOBILITY_DOMAIN,
794 WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
795 WLAN_EID_HT_CAPABILITY,
796 WLAN_EID_BSS_COEX_2040,
797 WLAN_EID_EXT_CAPABILITY,
798 WLAN_EID_QOS_TRAFFIC_CAPA,
799 WLAN_EID_TIM_BCAST_REQ,
800 WLAN_EID_INTERWORKING,
801 };
802 noffset = ieee80211_ie_split(assoc_data->ie, assoc_data->ie_len,
803 before_vht, ARRAY_SIZE(before_vht),
804 offset);
805 pos = skb_put(skb, noffset - offset);
806 memcpy(pos, assoc_data->ie + offset, noffset - offset);
807 offset = noffset;
808 }
809
771 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) 810 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
772 ieee80211_add_vht_ie(sdata, skb, sband, 811 ieee80211_add_vht_ie(sdata, skb, sband,
773 &assoc_data->ap_vht_cap); 812 &assoc_data->ap_vht_cap);
@@ -791,16 +830,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
791 qos_info = 0; 830 qos_info = 0;
792 } 831 }
793 832
794 pos = skb_put(skb, 9); 833 pos = ieee80211_add_wmm_info_ie(skb_put(skb, 9), qos_info);
795 *pos++ = WLAN_EID_VENDOR_SPECIFIC;
796 *pos++ = 7; /* len */
797 *pos++ = 0x00; /* Microsoft OUI 00:50:F2 */
798 *pos++ = 0x50;
799 *pos++ = 0xf2;
800 *pos++ = 2; /* WME */
801 *pos++ = 0; /* WME info */
802 *pos++ = 1; /* WME ver */
803 *pos++ = qos_info;
804 } 834 }
805 835
806 /* add any remaining custom (i.e. vendor specific here) IEs */ 836 /* add any remaining custom (i.e. vendor specific here) IEs */
@@ -901,51 +931,77 @@ static void ieee80211_chswitch_work(struct work_struct *work)
901 container_of(work, struct ieee80211_sub_if_data, u.mgd.chswitch_work); 931 container_of(work, struct ieee80211_sub_if_data, u.mgd.chswitch_work);
902 struct ieee80211_local *local = sdata->local; 932 struct ieee80211_local *local = sdata->local;
903 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 933 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
904 u32 changed = 0;
905 int ret; 934 int ret;
906 935
907 if (!ieee80211_sdata_running(sdata)) 936 if (!ieee80211_sdata_running(sdata))
908 return; 937 return;
909 938
910 sdata_lock(sdata); 939 sdata_lock(sdata);
940 mutex_lock(&local->mtx);
941 mutex_lock(&local->chanctx_mtx);
942
911 if (!ifmgd->associated) 943 if (!ifmgd->associated)
912 goto out; 944 goto out;
913 945
914 mutex_lock(&local->mtx); 946 if (!sdata->vif.csa_active)
915 ret = ieee80211_vif_change_channel(sdata, &changed); 947 goto out;
916 mutex_unlock(&local->mtx); 948
917 if (ret) { 949 /*
950 * using reservation isn't immediate as it may be deferred until later
951 * with multi-vif. once reservation is complete it will re-schedule the
952 * work with no reserved_chanctx so verify chandef to check if it
953 * completed successfully
954 */
955
956 if (sdata->reserved_chanctx) {
957 /*
958 * with multi-vif csa driver may call ieee80211_csa_finish()
959 * many times while waiting for other interfaces to use their
960 * reservations
961 */
962 if (sdata->reserved_ready)
963 goto out;
964
965 ret = ieee80211_vif_use_reserved_context(sdata);
966 if (ret) {
967 sdata_info(sdata,
968 "failed to use reserved channel context, disconnecting (err=%d)\n",
969 ret);
970 ieee80211_queue_work(&sdata->local->hw,
971 &ifmgd->csa_connection_drop_work);
972 goto out;
973 }
974
975 goto out;
976 }
977
978 if (!cfg80211_chandef_identical(&sdata->vif.bss_conf.chandef,
979 &sdata->csa_chandef)) {
918 sdata_info(sdata, 980 sdata_info(sdata,
919 "vif channel switch failed, disconnecting\n"); 981 "failed to finalize channel switch, disconnecting\n");
920 ieee80211_queue_work(&sdata->local->hw, 982 ieee80211_queue_work(&sdata->local->hw,
921 &ifmgd->csa_connection_drop_work); 983 &ifmgd->csa_connection_drop_work);
922 goto out; 984 goto out;
923 } 985 }
924 986
925 if (!local->use_chanctx) {
926 local->_oper_chandef = sdata->csa_chandef;
927 /* Call "hw_config" only if doing sw channel switch.
928 * Otherwise update the channel directly
929 */
930 if (!local->ops->channel_switch)
931 ieee80211_hw_config(local, 0);
932 else
933 local->hw.conf.chandef = local->_oper_chandef;
934 }
935
936 /* XXX: shouldn't really modify cfg80211-owned data! */ 987 /* XXX: shouldn't really modify cfg80211-owned data! */
937 ifmgd->associated->channel = sdata->csa_chandef.chan; 988 ifmgd->associated->channel = sdata->csa_chandef.chan;
938 989
990 sdata->vif.csa_active = false;
991
939 /* XXX: wait for a beacon first? */ 992 /* XXX: wait for a beacon first? */
940 ieee80211_wake_queues_by_reason(&local->hw, 993 if (sdata->csa_block_tx) {
941 IEEE80211_MAX_QUEUE_MAP, 994 ieee80211_wake_vif_queues(local, sdata,
942 IEEE80211_QUEUE_STOP_REASON_CSA); 995 IEEE80211_QUEUE_STOP_REASON_CSA);
996 sdata->csa_block_tx = false;
997 }
943 998
944 ieee80211_bss_info_change_notify(sdata, changed); 999 ieee80211_sta_reset_beacon_monitor(sdata);
1000 ieee80211_sta_reset_conn_monitor(sdata);
945 1001
946 out: 1002out:
947 sdata->vif.csa_active = false; 1003 mutex_unlock(&local->chanctx_mtx);
948 ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED; 1004 mutex_unlock(&local->mtx);
949 sdata_unlock(sdata); 1005 sdata_unlock(sdata);
950} 1006}
951 1007
@@ -982,6 +1038,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
982 struct ieee80211_local *local = sdata->local; 1038 struct ieee80211_local *local = sdata->local;
983 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1039 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
984 struct cfg80211_bss *cbss = ifmgd->associated; 1040 struct cfg80211_bss *cbss = ifmgd->associated;
1041 struct ieee80211_chanctx_conf *conf;
985 struct ieee80211_chanctx *chanctx; 1042 struct ieee80211_chanctx *chanctx;
986 enum ieee80211_band current_band; 1043 enum ieee80211_band current_band;
987 struct ieee80211_csa_ie csa_ie; 1044 struct ieee80211_csa_ie csa_ie;
@@ -996,7 +1053,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
996 return; 1053 return;
997 1054
998 /* disregard subsequent announcements if we are already processing */ 1055 /* disregard subsequent announcements if we are already processing */
999 if (ifmgd->flags & IEEE80211_STA_CSA_RECEIVED) 1056 if (sdata->vif.csa_active)
1000 return; 1057 return;
1001 1058
1002 current_band = cbss->channel->band; 1059 current_band = cbss->channel->band;
@@ -1023,10 +1080,22 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
1023 return; 1080 return;
1024 } 1081 }
1025 1082
1026 ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED; 1083 mutex_lock(&local->mtx);
1027 sdata->vif.csa_active = true;
1028
1029 mutex_lock(&local->chanctx_mtx); 1084 mutex_lock(&local->chanctx_mtx);
1085 conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
1086 lockdep_is_held(&local->chanctx_mtx));
1087 if (!conf) {
1088 sdata_info(sdata,
1089 "no channel context assigned to vif?, disconnecting\n");
1090 ieee80211_queue_work(&local->hw,
1091 &ifmgd->csa_connection_drop_work);
1092 mutex_unlock(&local->chanctx_mtx);
1093 mutex_unlock(&local->mtx);
1094 return;
1095 }
1096
1097 chanctx = container_of(conf, struct ieee80211_chanctx, conf);
1098
1030 if (local->use_chanctx) { 1099 if (local->use_chanctx) {
1031 u32 num_chanctx = 0; 1100 u32 num_chanctx = 0;
1032 list_for_each_entry(chanctx, &local->chanctx_list, list) 1101 list_for_each_entry(chanctx, &local->chanctx_list, list)
@@ -1039,34 +1108,33 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
1039 ieee80211_queue_work(&local->hw, 1108 ieee80211_queue_work(&local->hw,
1040 &ifmgd->csa_connection_drop_work); 1109 &ifmgd->csa_connection_drop_work);
1041 mutex_unlock(&local->chanctx_mtx); 1110 mutex_unlock(&local->chanctx_mtx);
1111 mutex_unlock(&local->mtx);
1042 return; 1112 return;
1043 } 1113 }
1044 } 1114 }
1045 1115
1046 if (WARN_ON(!rcu_access_pointer(sdata->vif.chanctx_conf))) { 1116 res = ieee80211_vif_reserve_chanctx(sdata, &csa_ie.chandef,
1047 ieee80211_queue_work(&local->hw, 1117 chanctx->mode, false);
1048 &ifmgd->csa_connection_drop_work); 1118 if (res) {
1049 mutex_unlock(&local->chanctx_mtx);
1050 return;
1051 }
1052 chanctx = container_of(rcu_access_pointer(sdata->vif.chanctx_conf),
1053 struct ieee80211_chanctx, conf);
1054 if (chanctx->refcount > 1) {
1055 sdata_info(sdata, 1119 sdata_info(sdata,
1056 "channel switch with multiple interfaces on the same channel, disconnecting\n"); 1120 "failed to reserve channel context for channel switch, disconnecting (err=%d)\n",
1121 res);
1057 ieee80211_queue_work(&local->hw, 1122 ieee80211_queue_work(&local->hw,
1058 &ifmgd->csa_connection_drop_work); 1123 &ifmgd->csa_connection_drop_work);
1059 mutex_unlock(&local->chanctx_mtx); 1124 mutex_unlock(&local->chanctx_mtx);
1125 mutex_unlock(&local->mtx);
1060 return; 1126 return;
1061 } 1127 }
1062 mutex_unlock(&local->chanctx_mtx); 1128 mutex_unlock(&local->chanctx_mtx);
1063 1129
1130 sdata->vif.csa_active = true;
1064 sdata->csa_chandef = csa_ie.chandef; 1131 sdata->csa_chandef = csa_ie.chandef;
1132 sdata->csa_block_tx = csa_ie.mode;
1065 1133
1066 if (csa_ie.mode) 1134 if (sdata->csa_block_tx)
1067 ieee80211_stop_queues_by_reason(&local->hw, 1135 ieee80211_stop_vif_queues(local, sdata,
1068 IEEE80211_MAX_QUEUE_MAP, 1136 IEEE80211_QUEUE_STOP_REASON_CSA);
1069 IEEE80211_QUEUE_STOP_REASON_CSA); 1137 mutex_unlock(&local->mtx);
1070 1138
1071 if (local->ops->channel_switch) { 1139 if (local->ops->channel_switch) {
1072 /* use driver's channel switch callback */ 1140 /* use driver's channel switch callback */
@@ -1335,7 +1403,8 @@ void ieee80211_dynamic_ps_disable_work(struct work_struct *work)
1335 1403
1336 ieee80211_wake_queues_by_reason(&local->hw, 1404 ieee80211_wake_queues_by_reason(&local->hw,
1337 IEEE80211_MAX_QUEUE_MAP, 1405 IEEE80211_MAX_QUEUE_MAP,
1338 IEEE80211_QUEUE_STOP_REASON_PS); 1406 IEEE80211_QUEUE_STOP_REASON_PS,
1407 false);
1339} 1408}
1340 1409
1341void ieee80211_dynamic_ps_enable_work(struct work_struct *work) 1410void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
@@ -1778,6 +1847,13 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1778 ifmgd->flags = 0; 1847 ifmgd->flags = 0;
1779 mutex_lock(&local->mtx); 1848 mutex_lock(&local->mtx);
1780 ieee80211_vif_release_channel(sdata); 1849 ieee80211_vif_release_channel(sdata);
1850
1851 sdata->vif.csa_active = false;
1852 if (sdata->csa_block_tx) {
1853 ieee80211_wake_vif_queues(local, sdata,
1854 IEEE80211_QUEUE_STOP_REASON_CSA);
1855 sdata->csa_block_tx = false;
1856 }
1781 mutex_unlock(&local->mtx); 1857 mutex_unlock(&local->mtx);
1782 1858
1783 sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM; 1859 sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM;
@@ -2006,6 +2082,7 @@ EXPORT_SYMBOL(ieee80211_ap_probereq_get);
2006 2082
2007static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata) 2083static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
2008{ 2084{
2085 struct ieee80211_local *local = sdata->local;
2009 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2086 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2010 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; 2087 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
2011 2088
@@ -2018,11 +2095,14 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
2018 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, 2095 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
2019 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, 2096 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
2020 true, frame_buf); 2097 true, frame_buf);
2021 ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED; 2098 mutex_lock(&local->mtx);
2022 sdata->vif.csa_active = false; 2099 sdata->vif.csa_active = false;
2023 ieee80211_wake_queues_by_reason(&sdata->local->hw, 2100 if (sdata->csa_block_tx) {
2024 IEEE80211_MAX_QUEUE_MAP, 2101 ieee80211_wake_vif_queues(local, sdata,
2025 IEEE80211_QUEUE_STOP_REASON_CSA); 2102 IEEE80211_QUEUE_STOP_REASON_CSA);
2103 sdata->csa_block_tx = false;
2104 }
2105 mutex_unlock(&local->mtx);
2026 2106
2027 cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, 2107 cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
2028 IEEE80211_DEAUTH_FRAME_LEN); 2108 IEEE80211_DEAUTH_FRAME_LEN);
@@ -2233,6 +2313,62 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
2233 /* ignore frame -- wait for timeout */ 2313 /* ignore frame -- wait for timeout */
2234} 2314}
2235 2315
2316#define case_WLAN(type) \
2317 case WLAN_REASON_##type: return #type
2318
2319static const char *ieee80211_get_reason_code_string(u16 reason_code)
2320{
2321 switch (reason_code) {
2322 case_WLAN(UNSPECIFIED);
2323 case_WLAN(PREV_AUTH_NOT_VALID);
2324 case_WLAN(DEAUTH_LEAVING);
2325 case_WLAN(DISASSOC_DUE_TO_INACTIVITY);
2326 case_WLAN(DISASSOC_AP_BUSY);
2327 case_WLAN(CLASS2_FRAME_FROM_NONAUTH_STA);
2328 case_WLAN(CLASS3_FRAME_FROM_NONASSOC_STA);
2329 case_WLAN(DISASSOC_STA_HAS_LEFT);
2330 case_WLAN(STA_REQ_ASSOC_WITHOUT_AUTH);
2331 case_WLAN(DISASSOC_BAD_POWER);
2332 case_WLAN(DISASSOC_BAD_SUPP_CHAN);
2333 case_WLAN(INVALID_IE);
2334 case_WLAN(MIC_FAILURE);
2335 case_WLAN(4WAY_HANDSHAKE_TIMEOUT);
2336 case_WLAN(GROUP_KEY_HANDSHAKE_TIMEOUT);
2337 case_WLAN(IE_DIFFERENT);
2338 case_WLAN(INVALID_GROUP_CIPHER);
2339 case_WLAN(INVALID_PAIRWISE_CIPHER);
2340 case_WLAN(INVALID_AKMP);
2341 case_WLAN(UNSUPP_RSN_VERSION);
2342 case_WLAN(INVALID_RSN_IE_CAP);
2343 case_WLAN(IEEE8021X_FAILED);
2344 case_WLAN(CIPHER_SUITE_REJECTED);
2345 case_WLAN(DISASSOC_UNSPECIFIED_QOS);
2346 case_WLAN(DISASSOC_QAP_NO_BANDWIDTH);
2347 case_WLAN(DISASSOC_LOW_ACK);
2348 case_WLAN(DISASSOC_QAP_EXCEED_TXOP);
2349 case_WLAN(QSTA_LEAVE_QBSS);
2350 case_WLAN(QSTA_NOT_USE);
2351 case_WLAN(QSTA_REQUIRE_SETUP);
2352 case_WLAN(QSTA_TIMEOUT);
2353 case_WLAN(QSTA_CIPHER_NOT_SUPP);
2354 case_WLAN(MESH_PEER_CANCELED);
2355 case_WLAN(MESH_MAX_PEERS);
2356 case_WLAN(MESH_CONFIG);
2357 case_WLAN(MESH_CLOSE);
2358 case_WLAN(MESH_MAX_RETRIES);
2359 case_WLAN(MESH_CONFIRM_TIMEOUT);
2360 case_WLAN(MESH_INVALID_GTK);
2361 case_WLAN(MESH_INCONSISTENT_PARAM);
2362 case_WLAN(MESH_INVALID_SECURITY);
2363 case_WLAN(MESH_PATH_ERROR);
2364 case_WLAN(MESH_PATH_NOFORWARD);
2365 case_WLAN(MESH_PATH_DEST_UNREACHABLE);
2366 case_WLAN(MAC_EXISTS_IN_MBSS);
2367 case_WLAN(MESH_CHAN_REGULATORY);
2368 case_WLAN(MESH_CHAN);
2369 default: return "<unknown>";
2370 }
2371}
2236 2372
2237static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, 2373static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
2238 struct ieee80211_mgmt *mgmt, size_t len) 2374 struct ieee80211_mgmt *mgmt, size_t len)
@@ -2254,8 +2390,8 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
2254 2390
2255 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); 2391 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
2256 2392
2257 sdata_info(sdata, "deauthenticated from %pM (Reason: %u)\n", 2393 sdata_info(sdata, "deauthenticated from %pM (Reason: %u=%s)\n",
2258 bssid, reason_code); 2394 bssid, reason_code, ieee80211_get_reason_code_string(reason_code));
2259 2395
2260 ieee80211_set_disassoc(sdata, 0, 0, false, NULL); 2396 ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
2261 2397
@@ -2688,28 +2824,20 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
2688 struct ieee802_11_elems *elems) 2824 struct ieee802_11_elems *elems)
2689{ 2825{
2690 struct ieee80211_local *local = sdata->local; 2826 struct ieee80211_local *local = sdata->local;
2691 int freq;
2692 struct ieee80211_bss *bss; 2827 struct ieee80211_bss *bss;
2693 struct ieee80211_channel *channel; 2828 struct ieee80211_channel *channel;
2694 2829
2695 sdata_assert_lock(sdata); 2830 sdata_assert_lock(sdata);
2696 2831
2697 if (elems->ds_params) 2832 channel = ieee80211_get_channel(local->hw.wiphy, rx_status->freq);
2698 freq = ieee80211_channel_to_frequency(elems->ds_params[0], 2833 if (!channel)
2699 rx_status->band);
2700 else
2701 freq = rx_status->freq;
2702
2703 channel = ieee80211_get_channel(local->hw.wiphy, freq);
2704
2705 if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
2706 return; 2834 return;
2707 2835
2708 bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems, 2836 bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems,
2709 channel); 2837 channel);
2710 if (bss) { 2838 if (bss) {
2711 ieee80211_rx_bss_put(local, bss);
2712 sdata->vif.bss_conf.beacon_rate = bss->beacon_rate; 2839 sdata->vif.bss_conf.beacon_rate = bss->beacon_rate;
2840 ieee80211_rx_bss_put(local, bss);
2713 } 2841 }
2714} 2842}
2715 2843
@@ -3459,6 +3587,9 @@ static void ieee80211_sta_bcn_mon_timer(unsigned long data)
3459 if (local->quiescing) 3587 if (local->quiescing)
3460 return; 3588 return;
3461 3589
3590 if (sdata->vif.csa_active)
3591 return;
3592
3462 sdata->u.mgd.connection_loss = false; 3593 sdata->u.mgd.connection_loss = false;
3463 ieee80211_queue_work(&sdata->local->hw, 3594 ieee80211_queue_work(&sdata->local->hw,
3464 &sdata->u.mgd.beacon_connection_loss_work); 3595 &sdata->u.mgd.beacon_connection_loss_work);
@@ -3474,6 +3605,9 @@ static void ieee80211_sta_conn_mon_timer(unsigned long data)
3474 if (local->quiescing) 3605 if (local->quiescing)
3475 return; 3606 return;
3476 3607
3608 if (sdata->vif.csa_active)
3609 return;
3610
3477 ieee80211_queue_work(&local->hw, &ifmgd->monitor_work); 3611 ieee80211_queue_work(&local->hw, &ifmgd->monitor_work);
3478} 3612}
3479 3613
@@ -3504,6 +3638,38 @@ static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata)
3504} 3638}
3505 3639
3506#ifdef CONFIG_PM 3640#ifdef CONFIG_PM
3641void ieee80211_mgd_quiesce(struct ieee80211_sub_if_data *sdata)
3642{
3643 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3644 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
3645
3646 sdata_lock(sdata);
3647
3648 if (ifmgd->auth_data || ifmgd->assoc_data) {
3649 const u8 *bssid = ifmgd->auth_data ?
3650 ifmgd->auth_data->bss->bssid :
3651 ifmgd->assoc_data->bss->bssid;
3652
3653 /*
3654 * If we are trying to authenticate / associate while suspending,
3655 * cfg80211 won't know and won't actually abort those attempts,
3656 * thus we need to do that ourselves.
3657 */
3658 ieee80211_send_deauth_disassoc(sdata, bssid,
3659 IEEE80211_STYPE_DEAUTH,
3660 WLAN_REASON_DEAUTH_LEAVING,
3661 false, frame_buf);
3662 if (ifmgd->assoc_data)
3663 ieee80211_destroy_assoc_data(sdata, false);
3664 if (ifmgd->auth_data)
3665 ieee80211_destroy_auth_data(sdata, false);
3666 cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
3667 IEEE80211_DEAUTH_FRAME_LEN);
3668 }
3669
3670 sdata_unlock(sdata);
3671}
3672
3507void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata) 3673void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
3508{ 3674{
3509 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 3675 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
@@ -3541,6 +3707,8 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
3541 INIT_WORK(&ifmgd->csa_connection_drop_work, 3707 INIT_WORK(&ifmgd->csa_connection_drop_work,
3542 ieee80211_csa_connection_drop_work); 3708 ieee80211_csa_connection_drop_work);
3543 INIT_WORK(&ifmgd->request_smps_work, ieee80211_request_smps_mgd_work); 3709 INIT_WORK(&ifmgd->request_smps_work, ieee80211_request_smps_mgd_work);
3710 INIT_DELAYED_WORK(&ifmgd->tdls_peer_del_work,
3711 ieee80211_tdls_peer_del_work);
3544 setup_timer(&ifmgd->timer, ieee80211_sta_timer, 3712 setup_timer(&ifmgd->timer, ieee80211_sta_timer,
3545 (unsigned long) sdata); 3713 (unsigned long) sdata);
3546 setup_timer(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer, 3714 setup_timer(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer,
@@ -3588,7 +3756,7 @@ int ieee80211_max_network_latency(struct notifier_block *nb,
3588 ieee80211_recalc_ps(local, latency_usec); 3756 ieee80211_recalc_ps(local, latency_usec);
3589 mutex_unlock(&local->iflist_mtx); 3757 mutex_unlock(&local->iflist_mtx);
3590 3758
3591 return 0; 3759 return NOTIFY_OK;
3592} 3760}
3593 3761
3594static u8 ieee80211_ht_vht_rx_chains(struct ieee80211_sub_if_data *sdata, 3762static u8 ieee80211_ht_vht_rx_chains(struct ieee80211_sub_if_data *sdata,
@@ -4208,8 +4376,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
4208 rcu_read_unlock(); 4376 rcu_read_unlock();
4209 4377
4210 if (bss->wmm_used && bss->uapsd_supported && 4378 if (bss->wmm_used && bss->uapsd_supported &&
4211 (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD) && 4379 (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) {
4212 sdata->wmm_acm != 0xff) {
4213 assoc_data->uapsd = true; 4380 assoc_data->uapsd = true;
4214 ifmgd->flags |= IEEE80211_STA_UAPSD_ENABLED; 4381 ifmgd->flags |= IEEE80211_STA_UAPSD_ENABLED;
4215 } else { 4382 } else {
@@ -4322,37 +4489,41 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
4322 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 4489 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
4323 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; 4490 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
4324 bool tx = !req->local_state_change; 4491 bool tx = !req->local_state_change;
4325 bool report_frame = false;
4326 4492
4327 sdata_info(sdata, 4493 if (ifmgd->auth_data &&
4328 "deauthenticating from %pM by local choice (reason=%d)\n", 4494 ether_addr_equal(ifmgd->auth_data->bss->bssid, req->bssid)) {
4329 req->bssid, req->reason_code); 4495 sdata_info(sdata,
4496 "aborting authentication with %pM by local choice (Reason: %u=%s)\n",
4497 req->bssid, req->reason_code,
4498 ieee80211_get_reason_code_string(req->reason_code));
4330 4499
4331 if (ifmgd->auth_data) {
4332 drv_mgd_prepare_tx(sdata->local, sdata); 4500 drv_mgd_prepare_tx(sdata->local, sdata);
4333 ieee80211_send_deauth_disassoc(sdata, req->bssid, 4501 ieee80211_send_deauth_disassoc(sdata, req->bssid,
4334 IEEE80211_STYPE_DEAUTH, 4502 IEEE80211_STYPE_DEAUTH,
4335 req->reason_code, tx, 4503 req->reason_code, tx,
4336 frame_buf); 4504 frame_buf);
4337 ieee80211_destroy_auth_data(sdata, false); 4505 ieee80211_destroy_auth_data(sdata, false);
4506 cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
4507 IEEE80211_DEAUTH_FRAME_LEN);
4338 4508
4339 report_frame = true; 4509 return 0;
4340 goto out;
4341 } 4510 }
4342 4511
4343 if (ifmgd->associated && 4512 if (ifmgd->associated &&
4344 ether_addr_equal(ifmgd->associated->bssid, req->bssid)) { 4513 ether_addr_equal(ifmgd->associated->bssid, req->bssid)) {
4514 sdata_info(sdata,
4515 "deauthenticating from %pM by local choice (Reason: %u=%s)\n",
4516 req->bssid, req->reason_code,
4517 ieee80211_get_reason_code_string(req->reason_code));
4518
4345 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, 4519 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
4346 req->reason_code, tx, frame_buf); 4520 req->reason_code, tx, frame_buf);
4347 report_frame = true;
4348 }
4349
4350 out:
4351 if (report_frame)
4352 cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, 4521 cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
4353 IEEE80211_DEAUTH_FRAME_LEN); 4522 IEEE80211_DEAUTH_FRAME_LEN);
4523 return 0;
4524 }
4354 4525
4355 return 0; 4526 return -ENOTCONN;
4356} 4527}
4357 4528
4358int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, 4529int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
@@ -4372,8 +4543,8 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
4372 return -ENOLINK; 4543 return -ENOLINK;
4373 4544
4374 sdata_info(sdata, 4545 sdata_info(sdata,
4375 "disassociating from %pM by local choice (reason=%d)\n", 4546 "disassociating from %pM by local choice (Reason: %u=%s)\n",
4376 req->bss->bssid, req->reason_code); 4547 req->bss->bssid, req->reason_code, ieee80211_get_reason_code_string(req->reason_code));
4377 4548
4378 memcpy(bssid, req->bss->bssid, ETH_ALEN); 4549 memcpy(bssid, req->bss->bssid, ETH_ALEN);
4379 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DISASSOC, 4550 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DISASSOC,
@@ -4400,6 +4571,7 @@ void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata)
4400 cancel_work_sync(&ifmgd->request_smps_work); 4571 cancel_work_sync(&ifmgd->request_smps_work);
4401 cancel_work_sync(&ifmgd->csa_connection_drop_work); 4572 cancel_work_sync(&ifmgd->csa_connection_drop_work);
4402 cancel_work_sync(&ifmgd->chswitch_work); 4573 cancel_work_sync(&ifmgd->chswitch_work);
4574 cancel_delayed_work_sync(&ifmgd->tdls_peer_del_work);
4403 4575
4404 sdata_lock(sdata); 4576 sdata_lock(sdata);
4405 if (ifmgd->assoc_data) { 4577 if (ifmgd->assoc_data) {