diff options
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r-- | net/mac80211/cfg.c | 250 |
1 files changed, 162 insertions, 88 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 364ce0c5962f..453e974287d1 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -133,7 +133,9 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, | |||
133 | struct key_params *params) | 133 | struct key_params *params) |
134 | { | 134 | { |
135 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 135 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
136 | struct ieee80211_local *local = sdata->local; | ||
136 | struct sta_info *sta = NULL; | 137 | struct sta_info *sta = NULL; |
138 | const struct ieee80211_cipher_scheme *cs = NULL; | ||
137 | struct ieee80211_key *key; | 139 | struct ieee80211_key *key; |
138 | int err; | 140 | int err; |
139 | 141 | ||
@@ -145,22 +147,28 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, | |||
145 | case WLAN_CIPHER_SUITE_WEP40: | 147 | case WLAN_CIPHER_SUITE_WEP40: |
146 | case WLAN_CIPHER_SUITE_TKIP: | 148 | case WLAN_CIPHER_SUITE_TKIP: |
147 | case WLAN_CIPHER_SUITE_WEP104: | 149 | case WLAN_CIPHER_SUITE_WEP104: |
148 | if (IS_ERR(sdata->local->wep_tx_tfm)) | 150 | if (IS_ERR(local->wep_tx_tfm)) |
149 | return -EINVAL; | 151 | return -EINVAL; |
150 | break; | 152 | break; |
153 | case WLAN_CIPHER_SUITE_CCMP: | ||
154 | case WLAN_CIPHER_SUITE_AES_CMAC: | ||
155 | case WLAN_CIPHER_SUITE_GCMP: | ||
156 | break; | ||
151 | default: | 157 | default: |
158 | cs = ieee80211_cs_get(local, params->cipher, sdata->vif.type); | ||
152 | break; | 159 | break; |
153 | } | 160 | } |
154 | 161 | ||
155 | key = ieee80211_key_alloc(params->cipher, key_idx, params->key_len, | 162 | key = ieee80211_key_alloc(params->cipher, key_idx, params->key_len, |
156 | params->key, params->seq_len, params->seq); | 163 | params->key, params->seq_len, params->seq, |
164 | cs); | ||
157 | if (IS_ERR(key)) | 165 | if (IS_ERR(key)) |
158 | return PTR_ERR(key); | 166 | return PTR_ERR(key); |
159 | 167 | ||
160 | if (pairwise) | 168 | if (pairwise) |
161 | key->conf.flags |= IEEE80211_KEY_FLAG_PAIRWISE; | 169 | key->conf.flags |= IEEE80211_KEY_FLAG_PAIRWISE; |
162 | 170 | ||
163 | mutex_lock(&sdata->local->sta_mtx); | 171 | mutex_lock(&local->sta_mtx); |
164 | 172 | ||
165 | if (mac_addr) { | 173 | if (mac_addr) { |
166 | if (ieee80211_vif_is_mesh(&sdata->vif)) | 174 | if (ieee80211_vif_is_mesh(&sdata->vif)) |
@@ -216,10 +224,13 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, | |||
216 | break; | 224 | break; |
217 | } | 225 | } |
218 | 226 | ||
227 | if (sta) | ||
228 | sta->cipher_scheme = cs; | ||
229 | |||
219 | err = ieee80211_key_link(key, sdata, sta); | 230 | err = ieee80211_key_link(key, sdata, sta); |
220 | 231 | ||
221 | out_unlock: | 232 | out_unlock: |
222 | mutex_unlock(&sdata->local->sta_mtx); | 233 | mutex_unlock(&local->sta_mtx); |
223 | 234 | ||
224 | return err; | 235 | return err; |
225 | } | 236 | } |
@@ -244,7 +255,7 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, | |||
244 | goto out_unlock; | 255 | goto out_unlock; |
245 | 256 | ||
246 | if (pairwise) | 257 | if (pairwise) |
247 | key = key_mtx_dereference(local, sta->ptk); | 258 | key = key_mtx_dereference(local, sta->ptk[key_idx]); |
248 | else | 259 | else |
249 | key = key_mtx_dereference(local, sta->gtk[key_idx]); | 260 | key = key_mtx_dereference(local, sta->gtk[key_idx]); |
250 | } else | 261 | } else |
@@ -290,9 +301,10 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, | |||
290 | if (!sta) | 301 | if (!sta) |
291 | goto out; | 302 | goto out; |
292 | 303 | ||
293 | if (pairwise) | 304 | if (pairwise && key_idx < NUM_DEFAULT_KEYS) |
294 | key = rcu_dereference(sta->ptk); | 305 | key = rcu_dereference(sta->ptk[key_idx]); |
295 | else if (key_idx < NUM_DEFAULT_KEYS) | 306 | else if (!pairwise && |
307 | key_idx < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) | ||
296 | key = rcu_dereference(sta->gtk[key_idx]); | 308 | key = rcu_dereference(sta->gtk[key_idx]); |
297 | } else | 309 | } else |
298 | key = rcu_dereference(sdata->keys[key_idx]); | 310 | key = rcu_dereference(sdata->keys[key_idx]); |
@@ -521,8 +533,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | |||
521 | STATION_INFO_PEER_PM | | 533 | STATION_INFO_PEER_PM | |
522 | STATION_INFO_NONPEER_PM; | 534 | STATION_INFO_NONPEER_PM; |
523 | 535 | ||
524 | sinfo->llid = le16_to_cpu(sta->llid); | 536 | sinfo->llid = sta->llid; |
525 | sinfo->plid = le16_to_cpu(sta->plid); | 537 | sinfo->plid = sta->plid; |
526 | sinfo->plink_state = sta->plink_state; | 538 | sinfo->plink_state = sta->plink_state; |
527 | if (test_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN)) { | 539 | if (test_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN)) { |
528 | sinfo->filled |= STATION_INFO_T_OFFSET; | 540 | sinfo->filled |= STATION_INFO_T_OFFSET; |
@@ -816,6 +828,7 @@ static int ieee80211_set_monitor_channel(struct wiphy *wiphy, | |||
816 | if (cfg80211_chandef_identical(&local->monitor_chandef, chandef)) | 828 | if (cfg80211_chandef_identical(&local->monitor_chandef, chandef)) |
817 | return 0; | 829 | return 0; |
818 | 830 | ||
831 | mutex_lock(&local->mtx); | ||
819 | mutex_lock(&local->iflist_mtx); | 832 | mutex_lock(&local->iflist_mtx); |
820 | if (local->use_chanctx) { | 833 | if (local->use_chanctx) { |
821 | sdata = rcu_dereference_protected( | 834 | sdata = rcu_dereference_protected( |
@@ -834,6 +847,7 @@ static int ieee80211_set_monitor_channel(struct wiphy *wiphy, | |||
834 | if (ret == 0) | 847 | if (ret == 0) |
835 | local->monitor_chandef = *chandef; | 848 | local->monitor_chandef = *chandef; |
836 | mutex_unlock(&local->iflist_mtx); | 849 | mutex_unlock(&local->iflist_mtx); |
850 | mutex_unlock(&local->mtx); | ||
837 | 851 | ||
838 | return ret; | 852 | return ret; |
839 | } | 853 | } |
@@ -846,7 +860,7 @@ static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata, | |||
846 | if (!resp || !resp_len) | 860 | if (!resp || !resp_len) |
847 | return 1; | 861 | return 1; |
848 | 862 | ||
849 | old = rtnl_dereference(sdata->u.ap.probe_resp); | 863 | old = sdata_dereference(sdata->u.ap.probe_resp, sdata); |
850 | 864 | ||
851 | new = kzalloc(sizeof(struct probe_resp) + resp_len, GFP_KERNEL); | 865 | new = kzalloc(sizeof(struct probe_resp) + resp_len, GFP_KERNEL); |
852 | if (!new) | 866 | if (!new) |
@@ -862,15 +876,16 @@ static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata, | |||
862 | return 0; | 876 | return 0; |
863 | } | 877 | } |
864 | 878 | ||
865 | int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata, | 879 | static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata, |
866 | struct cfg80211_beacon_data *params) | 880 | struct cfg80211_beacon_data *params) |
867 | { | 881 | { |
868 | struct beacon_data *new, *old; | 882 | struct beacon_data *new, *old; |
869 | int new_head_len, new_tail_len; | 883 | int new_head_len, new_tail_len; |
870 | int size, err; | 884 | int size, err; |
871 | u32 changed = BSS_CHANGED_BEACON; | 885 | u32 changed = BSS_CHANGED_BEACON; |
872 | 886 | ||
873 | old = rtnl_dereference(sdata->u.ap.beacon); | 887 | old = sdata_dereference(sdata->u.ap.beacon, sdata); |
888 | |||
874 | 889 | ||
875 | /* Need to have a beacon head if we don't have one yet */ | 890 | /* Need to have a beacon head if we don't have one yet */ |
876 | if (!params->head && !old) | 891 | if (!params->head && !old) |
@@ -938,6 +953,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev, | |||
938 | struct cfg80211_ap_settings *params) | 953 | struct cfg80211_ap_settings *params) |
939 | { | 954 | { |
940 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 955 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
956 | struct ieee80211_local *local = sdata->local; | ||
941 | struct beacon_data *old; | 957 | struct beacon_data *old; |
942 | struct ieee80211_sub_if_data *vlan; | 958 | struct ieee80211_sub_if_data *vlan; |
943 | u32 changed = BSS_CHANGED_BEACON_INT | | 959 | u32 changed = BSS_CHANGED_BEACON_INT | |
@@ -947,7 +963,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev, | |||
947 | BSS_CHANGED_P2P_PS; | 963 | BSS_CHANGED_P2P_PS; |
948 | int err; | 964 | int err; |
949 | 965 | ||
950 | old = rtnl_dereference(sdata->u.ap.beacon); | 966 | old = sdata_dereference(sdata->u.ap.beacon, sdata); |
951 | if (old) | 967 | if (old) |
952 | return -EALREADY; | 968 | return -EALREADY; |
953 | 969 | ||
@@ -956,8 +972,10 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev, | |||
956 | sdata->needed_rx_chains = sdata->local->rx_chains; | 972 | sdata->needed_rx_chains = sdata->local->rx_chains; |
957 | sdata->radar_required = params->radar_required; | 973 | sdata->radar_required = params->radar_required; |
958 | 974 | ||
975 | mutex_lock(&local->mtx); | ||
959 | err = ieee80211_vif_use_channel(sdata, ¶ms->chandef, | 976 | err = ieee80211_vif_use_channel(sdata, ¶ms->chandef, |
960 | IEEE80211_CHANCTX_SHARED); | 977 | IEEE80211_CHANCTX_SHARED); |
978 | mutex_unlock(&local->mtx); | ||
961 | if (err) | 979 | if (err) |
962 | return err; | 980 | return err; |
963 | ieee80211_vif_copy_chanctx_to_vlans(sdata, false); | 981 | ieee80211_vif_copy_chanctx_to_vlans(sdata, false); |
@@ -968,11 +986,19 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev, | |||
968 | */ | 986 | */ |
969 | sdata->control_port_protocol = params->crypto.control_port_ethertype; | 987 | sdata->control_port_protocol = params->crypto.control_port_ethertype; |
970 | sdata->control_port_no_encrypt = params->crypto.control_port_no_encrypt; | 988 | sdata->control_port_no_encrypt = params->crypto.control_port_no_encrypt; |
989 | sdata->encrypt_headroom = ieee80211_cs_headroom(sdata->local, | ||
990 | ¶ms->crypto, | ||
991 | sdata->vif.type); | ||
992 | |||
971 | list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) { | 993 | list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) { |
972 | vlan->control_port_protocol = | 994 | vlan->control_port_protocol = |
973 | params->crypto.control_port_ethertype; | 995 | params->crypto.control_port_ethertype; |
974 | vlan->control_port_no_encrypt = | 996 | vlan->control_port_no_encrypt = |
975 | params->crypto.control_port_no_encrypt; | 997 | params->crypto.control_port_no_encrypt; |
998 | vlan->encrypt_headroom = | ||
999 | ieee80211_cs_headroom(sdata->local, | ||
1000 | ¶ms->crypto, | ||
1001 | vlan->vif.type); | ||
976 | } | 1002 | } |
977 | 1003 | ||
978 | sdata->vif.bss_conf.beacon_int = params->beacon_interval; | 1004 | sdata->vif.bss_conf.beacon_int = params->beacon_interval; |
@@ -995,19 +1021,24 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev, | |||
995 | IEEE80211_P2P_OPPPS_ENABLE_BIT; | 1021 | IEEE80211_P2P_OPPPS_ENABLE_BIT; |
996 | 1022 | ||
997 | err = ieee80211_assign_beacon(sdata, ¶ms->beacon); | 1023 | err = ieee80211_assign_beacon(sdata, ¶ms->beacon); |
998 | if (err < 0) | 1024 | if (err < 0) { |
1025 | ieee80211_vif_release_channel(sdata); | ||
999 | return err; | 1026 | return err; |
1027 | } | ||
1000 | changed |= err; | 1028 | changed |= err; |
1001 | 1029 | ||
1002 | err = drv_start_ap(sdata->local, sdata); | 1030 | err = drv_start_ap(sdata->local, sdata); |
1003 | if (err) { | 1031 | if (err) { |
1004 | old = rtnl_dereference(sdata->u.ap.beacon); | 1032 | old = sdata_dereference(sdata->u.ap.beacon, sdata); |
1033 | |||
1005 | if (old) | 1034 | if (old) |
1006 | kfree_rcu(old, rcu_head); | 1035 | kfree_rcu(old, rcu_head); |
1007 | RCU_INIT_POINTER(sdata->u.ap.beacon, NULL); | 1036 | RCU_INIT_POINTER(sdata->u.ap.beacon, NULL); |
1037 | ieee80211_vif_release_channel(sdata); | ||
1008 | return err; | 1038 | return err; |
1009 | } | 1039 | } |
1010 | 1040 | ||
1041 | ieee80211_recalc_dtim(local, sdata); | ||
1011 | ieee80211_bss_info_change_notify(sdata, changed); | 1042 | ieee80211_bss_info_change_notify(sdata, changed); |
1012 | 1043 | ||
1013 | netif_carrier_on(dev); | 1044 | netif_carrier_on(dev); |
@@ -1032,7 +1063,7 @@ static int ieee80211_change_beacon(struct wiphy *wiphy, struct net_device *dev, | |||
1032 | if (sdata->vif.csa_active) | 1063 | if (sdata->vif.csa_active) |
1033 | return -EBUSY; | 1064 | return -EBUSY; |
1034 | 1065 | ||
1035 | old = rtnl_dereference(sdata->u.ap.beacon); | 1066 | old = sdata_dereference(sdata->u.ap.beacon, sdata); |
1036 | if (!old) | 1067 | if (!old) |
1037 | return -ENOENT; | 1068 | return -ENOENT; |
1038 | 1069 | ||
@@ -1050,16 +1081,17 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) | |||
1050 | struct ieee80211_local *local = sdata->local; | 1081 | struct ieee80211_local *local = sdata->local; |
1051 | struct beacon_data *old_beacon; | 1082 | struct beacon_data *old_beacon; |
1052 | struct probe_resp *old_probe_resp; | 1083 | struct probe_resp *old_probe_resp; |
1084 | struct cfg80211_chan_def chandef; | ||
1053 | 1085 | ||
1054 | old_beacon = rtnl_dereference(sdata->u.ap.beacon); | 1086 | old_beacon = sdata_dereference(sdata->u.ap.beacon, sdata); |
1055 | if (!old_beacon) | 1087 | if (!old_beacon) |
1056 | return -ENOENT; | 1088 | return -ENOENT; |
1057 | old_probe_resp = rtnl_dereference(sdata->u.ap.probe_resp); | 1089 | old_probe_resp = sdata_dereference(sdata->u.ap.probe_resp, sdata); |
1058 | 1090 | ||
1059 | /* abort any running channel switch */ | 1091 | /* abort any running channel switch */ |
1060 | sdata->vif.csa_active = false; | 1092 | sdata->vif.csa_active = false; |
1061 | cancel_work_sync(&sdata->csa_finalize_work); | 1093 | kfree(sdata->u.ap.next_beacon); |
1062 | cancel_work_sync(&sdata->u.ap.request_smps_work); | 1094 | sdata->u.ap.next_beacon = NULL; |
1063 | 1095 | ||
1064 | /* turn off carrier for this interface and dependent VLANs */ | 1096 | /* turn off carrier for this interface and dependent VLANs */ |
1065 | list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) | 1097 | list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) |
@@ -1072,18 +1104,10 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) | |||
1072 | kfree_rcu(old_beacon, rcu_head); | 1104 | kfree_rcu(old_beacon, rcu_head); |
1073 | if (old_probe_resp) | 1105 | if (old_probe_resp) |
1074 | kfree_rcu(old_probe_resp, rcu_head); | 1106 | kfree_rcu(old_probe_resp, rcu_head); |
1107 | sdata->u.ap.driver_smps_mode = IEEE80211_SMPS_OFF; | ||
1075 | 1108 | ||
1076 | list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) | 1109 | __sta_info_flush(sdata, true); |
1077 | sta_info_flush_defer(vlan); | 1110 | ieee80211_free_keys(sdata, true); |
1078 | sta_info_flush_defer(sdata); | ||
1079 | synchronize_net(); | ||
1080 | rcu_barrier(); | ||
1081 | list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) { | ||
1082 | sta_info_flush_cleanup(vlan); | ||
1083 | ieee80211_free_keys(vlan); | ||
1084 | } | ||
1085 | sta_info_flush_cleanup(sdata); | ||
1086 | ieee80211_free_keys(sdata); | ||
1087 | 1111 | ||
1088 | sdata->vif.bss_conf.enable_beacon = false; | 1112 | sdata->vif.bss_conf.enable_beacon = false; |
1089 | sdata->vif.bss_conf.ssid_len = 0; | 1113 | sdata->vif.bss_conf.ssid_len = 0; |
@@ -1091,8 +1115,10 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) | |||
1091 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); | 1115 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); |
1092 | 1116 | ||
1093 | if (sdata->wdev.cac_started) { | 1117 | if (sdata->wdev.cac_started) { |
1118 | chandef = sdata->vif.bss_conf.chandef; | ||
1094 | cancel_delayed_work_sync(&sdata->dfs_cac_timer_work); | 1119 | cancel_delayed_work_sync(&sdata->dfs_cac_timer_work); |
1095 | cfg80211_cac_event(sdata->dev, NL80211_RADAR_CAC_ABORTED, | 1120 | cfg80211_cac_event(sdata->dev, &chandef, |
1121 | NL80211_RADAR_CAC_ABORTED, | ||
1096 | GFP_KERNEL); | 1122 | GFP_KERNEL); |
1097 | } | 1123 | } |
1098 | 1124 | ||
@@ -1103,7 +1129,9 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) | |||
1103 | skb_queue_purge(&sdata->u.ap.ps.bc_buf); | 1129 | skb_queue_purge(&sdata->u.ap.ps.bc_buf); |
1104 | 1130 | ||
1105 | ieee80211_vif_copy_chanctx_to_vlans(sdata, true); | 1131 | ieee80211_vif_copy_chanctx_to_vlans(sdata, true); |
1132 | mutex_lock(&local->mtx); | ||
1106 | ieee80211_vif_release_channel(sdata); | 1133 | ieee80211_vif_release_channel(sdata); |
1134 | mutex_unlock(&local->mtx); | ||
1107 | 1135 | ||
1108 | return 0; | 1136 | return 0; |
1109 | } | 1137 | } |
@@ -1926,8 +1954,10 @@ static int ieee80211_join_mesh(struct wiphy *wiphy, struct net_device *dev, | |||
1926 | sdata->smps_mode = IEEE80211_SMPS_OFF; | 1954 | sdata->smps_mode = IEEE80211_SMPS_OFF; |
1927 | sdata->needed_rx_chains = sdata->local->rx_chains; | 1955 | sdata->needed_rx_chains = sdata->local->rx_chains; |
1928 | 1956 | ||
1957 | mutex_lock(&sdata->local->mtx); | ||
1929 | err = ieee80211_vif_use_channel(sdata, &setup->chandef, | 1958 | err = ieee80211_vif_use_channel(sdata, &setup->chandef, |
1930 | IEEE80211_CHANCTX_SHARED); | 1959 | IEEE80211_CHANCTX_SHARED); |
1960 | mutex_unlock(&sdata->local->mtx); | ||
1931 | if (err) | 1961 | if (err) |
1932 | return err; | 1962 | return err; |
1933 | 1963 | ||
@@ -1939,7 +1969,9 @@ static int ieee80211_leave_mesh(struct wiphy *wiphy, struct net_device *dev) | |||
1939 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1969 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
1940 | 1970 | ||
1941 | ieee80211_stop_mesh(sdata); | 1971 | ieee80211_stop_mesh(sdata); |
1972 | mutex_lock(&sdata->local->mtx); | ||
1942 | ieee80211_vif_release_channel(sdata); | 1973 | ieee80211_vif_release_channel(sdata); |
1974 | mutex_unlock(&sdata->local->mtx); | ||
1943 | 1975 | ||
1944 | return 0; | 1976 | return 0; |
1945 | } | 1977 | } |
@@ -1953,7 +1985,7 @@ static int ieee80211_change_bss(struct wiphy *wiphy, | |||
1953 | enum ieee80211_band band; | 1985 | enum ieee80211_band band; |
1954 | u32 changed = 0; | 1986 | u32 changed = 0; |
1955 | 1987 | ||
1956 | if (!rtnl_dereference(sdata->u.ap.beacon)) | 1988 | if (!sdata_dereference(sdata->u.ap.beacon, sdata)) |
1957 | return -ENOENT; | 1989 | return -ENOENT; |
1958 | 1990 | ||
1959 | band = ieee80211_get_sdata_band(sdata); | 1991 | band = ieee80211_get_sdata_band(sdata); |
@@ -2561,8 +2593,8 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy, | |||
2561 | int j; | 2593 | int j; |
2562 | 2594 | ||
2563 | sdata->rc_rateidx_mask[i] = mask->control[i].legacy; | 2595 | sdata->rc_rateidx_mask[i] = mask->control[i].legacy; |
2564 | memcpy(sdata->rc_rateidx_mcs_mask[i], mask->control[i].mcs, | 2596 | memcpy(sdata->rc_rateidx_mcs_mask[i], mask->control[i].ht_mcs, |
2565 | sizeof(mask->control[i].mcs)); | 2597 | sizeof(mask->control[i].ht_mcs)); |
2566 | 2598 | ||
2567 | sdata->rc_has_mcs_mask[i] = false; | 2599 | sdata->rc_has_mcs_mask[i] = false; |
2568 | if (!sband) | 2600 | if (!sband) |
@@ -2608,6 +2640,24 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local, | |||
2608 | INIT_DELAYED_WORK(&roc->work, ieee80211_sw_roc_work); | 2640 | INIT_DELAYED_WORK(&roc->work, ieee80211_sw_roc_work); |
2609 | INIT_LIST_HEAD(&roc->dependents); | 2641 | INIT_LIST_HEAD(&roc->dependents); |
2610 | 2642 | ||
2643 | /* | ||
2644 | * cookie is either the roc cookie (for normal roc) | ||
2645 | * or the SKB (for mgmt TX) | ||
2646 | */ | ||
2647 | if (!txskb) { | ||
2648 | /* local->mtx protects this */ | ||
2649 | local->roc_cookie_counter++; | ||
2650 | roc->cookie = local->roc_cookie_counter; | ||
2651 | /* wow, you wrapped 64 bits ... more likely a bug */ | ||
2652 | if (WARN_ON(roc->cookie == 0)) { | ||
2653 | roc->cookie = 1; | ||
2654 | local->roc_cookie_counter++; | ||
2655 | } | ||
2656 | *cookie = roc->cookie; | ||
2657 | } else { | ||
2658 | *cookie = (unsigned long)txskb; | ||
2659 | } | ||
2660 | |||
2611 | /* if there's one pending or we're scanning, queue this one */ | 2661 | /* if there's one pending or we're scanning, queue this one */ |
2612 | if (!list_empty(&local->roc_list) || | 2662 | if (!list_empty(&local->roc_list) || |
2613 | local->scanning || local->radar_detect_enabled) | 2663 | local->scanning || local->radar_detect_enabled) |
@@ -2742,24 +2792,6 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local, | |||
2742 | if (!queued) | 2792 | if (!queued) |
2743 | list_add_tail(&roc->list, &local->roc_list); | 2793 | list_add_tail(&roc->list, &local->roc_list); |
2744 | 2794 | ||
2745 | /* | ||
2746 | * cookie is either the roc cookie (for normal roc) | ||
2747 | * or the SKB (for mgmt TX) | ||
2748 | */ | ||
2749 | if (!txskb) { | ||
2750 | /* local->mtx protects this */ | ||
2751 | local->roc_cookie_counter++; | ||
2752 | roc->cookie = local->roc_cookie_counter; | ||
2753 | /* wow, you wrapped 64 bits ... more likely a bug */ | ||
2754 | if (WARN_ON(roc->cookie == 0)) { | ||
2755 | roc->cookie = 1; | ||
2756 | local->roc_cookie_counter++; | ||
2757 | } | ||
2758 | *cookie = roc->cookie; | ||
2759 | } else { | ||
2760 | *cookie = (unsigned long)txskb; | ||
2761 | } | ||
2762 | |||
2763 | return 0; | 2795 | return 0; |
2764 | } | 2796 | } |
2765 | 2797 | ||
@@ -2877,26 +2909,29 @@ static int ieee80211_start_radar_detection(struct wiphy *wiphy, | |||
2877 | unsigned long timeout; | 2909 | unsigned long timeout; |
2878 | int err; | 2910 | int err; |
2879 | 2911 | ||
2880 | if (!list_empty(&local->roc_list) || local->scanning) | 2912 | mutex_lock(&local->mtx); |
2881 | return -EBUSY; | 2913 | if (!list_empty(&local->roc_list) || local->scanning) { |
2914 | err = -EBUSY; | ||
2915 | goto out_unlock; | ||
2916 | } | ||
2882 | 2917 | ||
2883 | /* whatever, but channel contexts should not complain about that one */ | 2918 | /* whatever, but channel contexts should not complain about that one */ |
2884 | sdata->smps_mode = IEEE80211_SMPS_OFF; | 2919 | sdata->smps_mode = IEEE80211_SMPS_OFF; |
2885 | sdata->needed_rx_chains = local->rx_chains; | 2920 | sdata->needed_rx_chains = local->rx_chains; |
2886 | sdata->radar_required = true; | 2921 | sdata->radar_required = true; |
2887 | 2922 | ||
2888 | mutex_lock(&local->iflist_mtx); | ||
2889 | err = ieee80211_vif_use_channel(sdata, chandef, | 2923 | err = ieee80211_vif_use_channel(sdata, chandef, |
2890 | IEEE80211_CHANCTX_SHARED); | 2924 | IEEE80211_CHANCTX_SHARED); |
2891 | mutex_unlock(&local->iflist_mtx); | ||
2892 | if (err) | 2925 | if (err) |
2893 | return err; | 2926 | goto out_unlock; |
2894 | 2927 | ||
2895 | timeout = msecs_to_jiffies(IEEE80211_DFS_MIN_CAC_TIME_MS); | 2928 | timeout = msecs_to_jiffies(IEEE80211_DFS_MIN_CAC_TIME_MS); |
2896 | ieee80211_queue_delayed_work(&sdata->local->hw, | 2929 | ieee80211_queue_delayed_work(&sdata->local->hw, |
2897 | &sdata->dfs_cac_timer_work, timeout); | 2930 | &sdata->dfs_cac_timer_work, timeout); |
2898 | 2931 | ||
2899 | return 0; | 2932 | out_unlock: |
2933 | mutex_unlock(&local->mtx); | ||
2934 | return err; | ||
2900 | } | 2935 | } |
2901 | 2936 | ||
2902 | static struct cfg80211_beacon_data * | 2937 | static struct cfg80211_beacon_data * |
@@ -2963,27 +2998,35 @@ void ieee80211_csa_finalize_work(struct work_struct *work) | |||
2963 | struct ieee80211_local *local = sdata->local; | 2998 | struct ieee80211_local *local = sdata->local; |
2964 | int err, changed = 0; | 2999 | int err, changed = 0; |
2965 | 3000 | ||
3001 | sdata_lock(sdata); | ||
3002 | /* AP might have been stopped while waiting for the lock. */ | ||
3003 | if (!sdata->vif.csa_active) | ||
3004 | goto unlock; | ||
3005 | |||
2966 | if (!ieee80211_sdata_running(sdata)) | 3006 | if (!ieee80211_sdata_running(sdata)) |
2967 | return; | 3007 | goto unlock; |
2968 | 3008 | ||
2969 | sdata->radar_required = sdata->csa_radar_required; | 3009 | sdata->radar_required = sdata->csa_radar_required; |
2970 | err = ieee80211_vif_change_channel(sdata, &local->csa_chandef, | 3010 | mutex_lock(&local->mtx); |
2971 | &changed); | 3011 | err = ieee80211_vif_change_channel(sdata, &changed); |
3012 | mutex_unlock(&local->mtx); | ||
2972 | if (WARN_ON(err < 0)) | 3013 | if (WARN_ON(err < 0)) |
2973 | return; | 3014 | goto unlock; |
2974 | 3015 | ||
2975 | if (!local->use_chanctx) { | 3016 | if (!local->use_chanctx) { |
2976 | local->_oper_chandef = local->csa_chandef; | 3017 | local->_oper_chandef = sdata->csa_chandef; |
2977 | ieee80211_hw_config(local, 0); | 3018 | ieee80211_hw_config(local, 0); |
2978 | } | 3019 | } |
2979 | 3020 | ||
2980 | ieee80211_bss_info_change_notify(sdata, changed); | 3021 | ieee80211_bss_info_change_notify(sdata, changed); |
2981 | 3022 | ||
3023 | sdata->vif.csa_active = false; | ||
2982 | switch (sdata->vif.type) { | 3024 | switch (sdata->vif.type) { |
2983 | case NL80211_IFTYPE_AP: | 3025 | case NL80211_IFTYPE_AP: |
2984 | err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon); | 3026 | err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon); |
2985 | if (err < 0) | 3027 | if (err < 0) |
2986 | return; | 3028 | goto unlock; |
3029 | |||
2987 | changed |= err; | 3030 | changed |= err; |
2988 | kfree(sdata->u.ap.next_beacon); | 3031 | kfree(sdata->u.ap.next_beacon); |
2989 | sdata->u.ap.next_beacon = NULL; | 3032 | sdata->u.ap.next_beacon = NULL; |
@@ -2997,24 +3040,26 @@ void ieee80211_csa_finalize_work(struct work_struct *work) | |||
2997 | case NL80211_IFTYPE_MESH_POINT: | 3040 | case NL80211_IFTYPE_MESH_POINT: |
2998 | err = ieee80211_mesh_finish_csa(sdata); | 3041 | err = ieee80211_mesh_finish_csa(sdata); |
2999 | if (err < 0) | 3042 | if (err < 0) |
3000 | return; | 3043 | goto unlock; |
3001 | break; | 3044 | break; |
3002 | #endif | 3045 | #endif |
3003 | default: | 3046 | default: |
3004 | WARN_ON(1); | 3047 | WARN_ON(1); |
3005 | return; | 3048 | goto unlock; |
3006 | } | 3049 | } |
3007 | sdata->vif.csa_active = false; | ||
3008 | 3050 | ||
3009 | ieee80211_wake_queues_by_reason(&sdata->local->hw, | 3051 | ieee80211_wake_queues_by_reason(&sdata->local->hw, |
3010 | IEEE80211_MAX_QUEUE_MAP, | 3052 | IEEE80211_MAX_QUEUE_MAP, |
3011 | IEEE80211_QUEUE_STOP_REASON_CSA); | 3053 | IEEE80211_QUEUE_STOP_REASON_CSA); |
3012 | 3054 | ||
3013 | cfg80211_ch_switch_notify(sdata->dev, &local->csa_chandef); | 3055 | cfg80211_ch_switch_notify(sdata->dev, &sdata->csa_chandef); |
3056 | |||
3057 | unlock: | ||
3058 | sdata_unlock(sdata); | ||
3014 | } | 3059 | } |
3015 | 3060 | ||
3016 | static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, | 3061 | int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, |
3017 | struct cfg80211_csa_settings *params) | 3062 | struct cfg80211_csa_settings *params) |
3018 | { | 3063 | { |
3019 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 3064 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
3020 | struct ieee80211_local *local = sdata->local; | 3065 | struct ieee80211_local *local = sdata->local; |
@@ -3023,6 +3068,8 @@ static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, | |||
3023 | struct ieee80211_if_mesh __maybe_unused *ifmsh; | 3068 | struct ieee80211_if_mesh __maybe_unused *ifmsh; |
3024 | int err, num_chanctx; | 3069 | int err, num_chanctx; |
3025 | 3070 | ||
3071 | lockdep_assert_held(&sdata->wdev.mtx); | ||
3072 | |||
3026 | if (!list_empty(&local->roc_list) || local->scanning) | 3073 | if (!list_empty(&local->roc_list) || local->scanning) |
3027 | return -EBUSY; | 3074 | return -EBUSY; |
3028 | 3075 | ||
@@ -3143,7 +3190,7 @@ static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, | |||
3143 | IEEE80211_MAX_QUEUE_MAP, | 3190 | IEEE80211_MAX_QUEUE_MAP, |
3144 | IEEE80211_QUEUE_STOP_REASON_CSA); | 3191 | IEEE80211_QUEUE_STOP_REASON_CSA); |
3145 | 3192 | ||
3146 | local->csa_chandef = params->chandef; | 3193 | sdata->csa_chandef = params->chandef; |
3147 | sdata->vif.csa_active = true; | 3194 | sdata->vif.csa_active = true; |
3148 | 3195 | ||
3149 | ieee80211_bss_info_change_notify(sdata, err); | 3196 | ieee80211_bss_info_change_notify(sdata, err); |
@@ -3153,26 +3200,25 @@ static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, | |||
3153 | } | 3200 | } |
3154 | 3201 | ||
3155 | static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, | 3202 | static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, |
3156 | struct ieee80211_channel *chan, bool offchan, | 3203 | struct cfg80211_mgmt_tx_params *params, |
3157 | unsigned int wait, const u8 *buf, size_t len, | 3204 | u64 *cookie) |
3158 | bool no_cck, bool dont_wait_for_ack, u64 *cookie) | ||
3159 | { | 3205 | { |
3160 | struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); | 3206 | struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); |
3161 | struct ieee80211_local *local = sdata->local; | 3207 | struct ieee80211_local *local = sdata->local; |
3162 | struct sk_buff *skb; | 3208 | struct sk_buff *skb; |
3163 | struct sta_info *sta; | 3209 | struct sta_info *sta; |
3164 | const struct ieee80211_mgmt *mgmt = (void *)buf; | 3210 | const struct ieee80211_mgmt *mgmt = (void *)params->buf; |
3165 | bool need_offchan = false; | 3211 | bool need_offchan = false; |
3166 | u32 flags; | 3212 | u32 flags; |
3167 | int ret; | 3213 | int ret; |
3168 | 3214 | ||
3169 | if (dont_wait_for_ack) | 3215 | if (params->dont_wait_for_ack) |
3170 | flags = IEEE80211_TX_CTL_NO_ACK; | 3216 | flags = IEEE80211_TX_CTL_NO_ACK; |
3171 | else | 3217 | else |
3172 | flags = IEEE80211_TX_INTFL_NL80211_FRAME_TX | | 3218 | flags = IEEE80211_TX_INTFL_NL80211_FRAME_TX | |
3173 | IEEE80211_TX_CTL_REQ_TX_STATUS; | 3219 | IEEE80211_TX_CTL_REQ_TX_STATUS; |
3174 | 3220 | ||
3175 | if (no_cck) | 3221 | if (params->no_cck) |
3176 | flags |= IEEE80211_TX_CTL_NO_CCK_RATE; | 3222 | flags |= IEEE80211_TX_CTL_NO_CCK_RATE; |
3177 | 3223 | ||
3178 | switch (sdata->vif.type) { | 3224 | switch (sdata->vif.type) { |
@@ -3220,7 +3266,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, | |||
3220 | /* configurations requiring offchan cannot work if no channel has been | 3266 | /* configurations requiring offchan cannot work if no channel has been |
3221 | * specified | 3267 | * specified |
3222 | */ | 3268 | */ |
3223 | if (need_offchan && !chan) | 3269 | if (need_offchan && !params->chan) |
3224 | return -EINVAL; | 3270 | return -EINVAL; |
3225 | 3271 | ||
3226 | mutex_lock(&local->mtx); | 3272 | mutex_lock(&local->mtx); |
@@ -3233,8 +3279,10 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, | |||
3233 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); | 3279 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); |
3234 | 3280 | ||
3235 | if (chanctx_conf) { | 3281 | if (chanctx_conf) { |
3236 | need_offchan = chan && (chan != chanctx_conf->def.chan); | 3282 | need_offchan = params->chan && |
3237 | } else if (!chan) { | 3283 | (params->chan != |
3284 | chanctx_conf->def.chan); | ||
3285 | } else if (!params->chan) { | ||
3238 | ret = -EINVAL; | 3286 | ret = -EINVAL; |
3239 | rcu_read_unlock(); | 3287 | rcu_read_unlock(); |
3240 | goto out_unlock; | 3288 | goto out_unlock; |
@@ -3244,19 +3292,19 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, | |||
3244 | rcu_read_unlock(); | 3292 | rcu_read_unlock(); |
3245 | } | 3293 | } |
3246 | 3294 | ||
3247 | if (need_offchan && !offchan) { | 3295 | if (need_offchan && !params->offchan) { |
3248 | ret = -EBUSY; | 3296 | ret = -EBUSY; |
3249 | goto out_unlock; | 3297 | goto out_unlock; |
3250 | } | 3298 | } |
3251 | 3299 | ||
3252 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + len); | 3300 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + params->len); |
3253 | if (!skb) { | 3301 | if (!skb) { |
3254 | ret = -ENOMEM; | 3302 | ret = -ENOMEM; |
3255 | goto out_unlock; | 3303 | goto out_unlock; |
3256 | } | 3304 | } |
3257 | skb_reserve(skb, local->hw.extra_tx_headroom); | 3305 | skb_reserve(skb, local->hw.extra_tx_headroom); |
3258 | 3306 | ||
3259 | memcpy(skb_put(skb, len), buf, len); | 3307 | memcpy(skb_put(skb, params->len), params->buf, params->len); |
3260 | 3308 | ||
3261 | IEEE80211_SKB_CB(skb)->flags = flags; | 3309 | IEEE80211_SKB_CB(skb)->flags = flags; |
3262 | 3310 | ||
@@ -3276,8 +3324,8 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, | |||
3276 | local->hw.offchannel_tx_hw_queue; | 3324 | local->hw.offchannel_tx_hw_queue; |
3277 | 3325 | ||
3278 | /* This will handle all kinds of coalescing and immediate TX */ | 3326 | /* This will handle all kinds of coalescing and immediate TX */ |
3279 | ret = ieee80211_start_roc_work(local, sdata, chan, | 3327 | ret = ieee80211_start_roc_work(local, sdata, params->chan, |
3280 | wait, cookie, skb, | 3328 | params->wait, cookie, skb, |
3281 | IEEE80211_ROC_TYPE_MGMT_TX); | 3329 | IEEE80211_ROC_TYPE_MGMT_TX); |
3282 | if (ret) | 3330 | if (ret) |
3283 | kfree_skb(skb); | 3331 | kfree_skb(skb); |
@@ -3792,6 +3840,31 @@ static void ieee80211_set_wakeup(struct wiphy *wiphy, bool enabled) | |||
3792 | } | 3840 | } |
3793 | #endif | 3841 | #endif |
3794 | 3842 | ||
3843 | static int ieee80211_set_qos_map(struct wiphy *wiphy, | ||
3844 | struct net_device *dev, | ||
3845 | struct cfg80211_qos_map *qos_map) | ||
3846 | { | ||
3847 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
3848 | struct mac80211_qos_map *new_qos_map, *old_qos_map; | ||
3849 | |||
3850 | if (qos_map) { | ||
3851 | new_qos_map = kzalloc(sizeof(*new_qos_map), GFP_KERNEL); | ||
3852 | if (!new_qos_map) | ||
3853 | return -ENOMEM; | ||
3854 | memcpy(&new_qos_map->qos_map, qos_map, sizeof(*qos_map)); | ||
3855 | } else { | ||
3856 | /* A NULL qos_map was passed to disable QoS mapping */ | ||
3857 | new_qos_map = NULL; | ||
3858 | } | ||
3859 | |||
3860 | old_qos_map = sdata_dereference(sdata->qos_map, sdata); | ||
3861 | rcu_assign_pointer(sdata->qos_map, new_qos_map); | ||
3862 | if (old_qos_map) | ||
3863 | kfree_rcu(old_qos_map, rcu_head); | ||
3864 | |||
3865 | return 0; | ||
3866 | } | ||
3867 | |||
3795 | struct cfg80211_ops mac80211_config_ops = { | 3868 | struct cfg80211_ops mac80211_config_ops = { |
3796 | .add_virtual_intf = ieee80211_add_iface, | 3869 | .add_virtual_intf = ieee80211_add_iface, |
3797 | .del_virtual_intf = ieee80211_del_iface, | 3870 | .del_virtual_intf = ieee80211_del_iface, |
@@ -3871,4 +3944,5 @@ struct cfg80211_ops mac80211_config_ops = { | |||
3871 | .get_channel = ieee80211_cfg_get_channel, | 3944 | .get_channel = ieee80211_cfg_get_channel, |
3872 | .start_radar_detection = ieee80211_start_radar_detection, | 3945 | .start_radar_detection = ieee80211_start_radar_detection, |
3873 | .channel_switch = ieee80211_channel_switch, | 3946 | .channel_switch = ieee80211_channel_switch, |
3947 | .set_qos_map = ieee80211_set_qos_map, | ||
3874 | }; | 3948 | }; |