Lines Matching +full:- +full:- +full:disable +full:- +full:mpath

1 // SPDX-License-Identifier: GPL-2.0-only
5 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
6 * Copyright 2013-2015 Intel Mobile Communications GmbH
7 * Copyright (C) 2015-2017 Intel Deutschland GmbH
8 * Copyright (C) 2018-2022 Intel Corporation
21 #include "driver-ops.h"
38 if (require_valid && ieee80211_vif_is_mld(&sdata->vif)) in ieee80211_link_or_deflink()
39 return ERR_PTR(-EINVAL); in ieee80211_link_or_deflink()
41 return &sdata->deflink; in ieee80211_link_or_deflink()
44 link = sdata_dereference(sdata->link[link_id], sdata); in ieee80211_link_or_deflink()
46 return ERR_PTR(-ENOLINK); in ieee80211_link_or_deflink()
56 if (params->vht_mumimo_groups) { in ieee80211_set_mu_mimo_follow()
61 memcpy(sdata->vif.bss_conf.mu_group.membership, in ieee80211_set_mu_mimo_follow()
62 params->vht_mumimo_groups, WLAN_MEMBERSHIP_LEN); in ieee80211_set_mu_mimo_follow()
63 memcpy(sdata->vif.bss_conf.mu_group.position, in ieee80211_set_mu_mimo_follow()
64 params->vht_mumimo_groups + WLAN_MEMBERSHIP_LEN, in ieee80211_set_mu_mimo_follow()
66 ieee80211_link_info_change_notify(sdata, &sdata->deflink, in ieee80211_set_mu_mimo_follow()
68 /* don't care about endianness - just check for 0 */ in ieee80211_set_mu_mimo_follow()
69 memcpy(&membership, params->vht_mumimo_groups, in ieee80211_set_mu_mimo_follow()
74 if (params->vht_mumimo_follow_addr) { in ieee80211_set_mu_mimo_follow()
76 is_valid_ether_addr(params->vht_mumimo_follow_addr); in ieee80211_set_mu_mimo_follow()
77 ether_addr_copy(sdata->u.mntr.mu_follow_addr, in ieee80211_set_mu_mimo_follow()
78 params->vht_mumimo_follow_addr); in ieee80211_set_mu_mimo_follow()
81 sdata->vif.bss_conf.mu_mimo_owner = mu_mimo_groups || mu_mimo_follow; in ieee80211_set_mu_mimo_follow()
87 struct ieee80211_local *local = sdata->local; in ieee80211_set_mon_options()
91 if (params->flags && ieee80211_sdata_running(sdata)) { in ieee80211_set_mon_options()
103 if ((params->flags & mask) != (sdata->u.mntr.flags & mask)) in ieee80211_set_mon_options()
104 return -EBUSY; in ieee80211_set_mon_options()
107 /* also validate MU-MIMO change */ in ieee80211_set_mon_options()
108 monitor_sdata = wiphy_dereference(local->hw.wiphy, in ieee80211_set_mon_options()
109 local->monitor_sdata); in ieee80211_set_mon_options()
112 (params->vht_mumimo_groups || params->vht_mumimo_follow_addr)) in ieee80211_set_mon_options()
113 return -EOPNOTSUPP; in ieee80211_set_mon_options()
115 /* apply all changes now - no failures allowed */ in ieee80211_set_mon_options()
120 if (params->flags) { in ieee80211_set_mon_options()
122 ieee80211_adjust_monitor_flags(sdata, -1); in ieee80211_set_mon_options()
123 sdata->u.mntr.flags = params->flags; in ieee80211_set_mon_options()
133 sdata->u.mntr.flags = params->flags; in ieee80211_set_mon_options()
146 sdata->vif.mbssid_tx_vif = NULL; in ieee80211_set_ap_mbssid_options()
147 link_conf->bssid_index = 0; in ieee80211_set_ap_mbssid_options()
148 link_conf->nontransmitted = false; in ieee80211_set_ap_mbssid_options()
149 link_conf->ema_ap = false; in ieee80211_set_ap_mbssid_options()
150 link_conf->bssid_indicator = 0; in ieee80211_set_ap_mbssid_options()
152 if (sdata->vif.type != NL80211_IFTYPE_AP || !params.tx_wdev) in ieee80211_set_ap_mbssid_options()
153 return -EINVAL; in ieee80211_set_ap_mbssid_options()
157 return -EINVAL; in ieee80211_set_ap_mbssid_options()
160 sdata->vif.mbssid_tx_vif = &sdata->vif; in ieee80211_set_ap_mbssid_options()
162 sdata->vif.mbssid_tx_vif = &tx_sdata->vif; in ieee80211_set_ap_mbssid_options()
163 link_conf->nontransmitted = true; in ieee80211_set_ap_mbssid_options()
164 link_conf->bssid_index = params.index; in ieee80211_set_ap_mbssid_options()
167 link_conf->ema_ap = true; in ieee80211_set_ap_mbssid_options()
213 struct ieee80211_local *local = sdata->local; in ieee80211_change_iface()
221 if (type == NL80211_IFTYPE_AP_VLAN && params->use_4addr == 0) { in ieee80211_change_iface()
222 RCU_INIT_POINTER(sdata->u.vlan.sta, NULL); in ieee80211_change_iface()
224 } else if (type == NL80211_IFTYPE_STATION && params->use_4addr >= 0) { in ieee80211_change_iface()
225 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; in ieee80211_change_iface()
227 if (params->use_4addr == ifmgd->use_4addr) in ieee80211_change_iface()
230 /* FIXME: no support for 4-addr MLO yet */ in ieee80211_change_iface()
231 if (ieee80211_vif_is_mld(&sdata->vif)) in ieee80211_change_iface()
232 return -EOPNOTSUPP; in ieee80211_change_iface()
234 sdata->u.mgd.use_4addr = params->use_4addr; in ieee80211_change_iface()
235 if (!ifmgd->associated) in ieee80211_change_iface()
238 mutex_lock(&local->sta_mtx); in ieee80211_change_iface()
239 sta = sta_info_get(sdata, sdata->deflink.u.mgd.bssid); in ieee80211_change_iface()
241 drv_sta_set_4addr(local, sdata, &sta->sta, in ieee80211_change_iface()
242 params->use_4addr); in ieee80211_change_iface()
243 mutex_unlock(&local->sta_mtx); in ieee80211_change_iface()
245 if (params->use_4addr) in ieee80211_change_iface()
249 if (sdata->vif.type == NL80211_IFTYPE_MONITOR) { in ieee80211_change_iface()
264 mutex_lock(&sdata->local->chanctx_mtx); in ieee80211_start_p2p_device()
266 mutex_unlock(&sdata->local->chanctx_mtx); in ieee80211_start_p2p_device()
286 mutex_lock(&sdata->local->chanctx_mtx); in ieee80211_start_nan()
288 mutex_unlock(&sdata->local->chanctx_mtx); in ieee80211_start_nan()
296 ret = drv_start_nan(sdata->local, sdata, conf); in ieee80211_start_nan()
300 sdata->u.nan.conf = *conf; in ieee80211_start_nan()
310 drv_stop_nan(sdata->local, sdata); in ieee80211_stop_nan()
323 if (sdata->vif.type != NL80211_IFTYPE_NAN) in ieee80211_nan_change_conf()
324 return -EOPNOTSUPP; in ieee80211_nan_change_conf()
327 return -ENETDOWN; in ieee80211_nan_change_conf()
329 new_conf = sdata->u.nan.conf; in ieee80211_nan_change_conf()
332 new_conf.master_pref = conf->master_pref; in ieee80211_nan_change_conf()
335 new_conf.bands = conf->bands; in ieee80211_nan_change_conf()
337 ret = drv_nan_change_conf(sdata->local, sdata, &new_conf, changes); in ieee80211_nan_change_conf()
339 sdata->u.nan.conf = new_conf; in ieee80211_nan_change_conf()
351 if (sdata->vif.type != NL80211_IFTYPE_NAN) in ieee80211_add_nan_func()
352 return -EOPNOTSUPP; in ieee80211_add_nan_func()
355 return -ENETDOWN; in ieee80211_add_nan_func()
357 spin_lock_bh(&sdata->u.nan.func_lock); in ieee80211_add_nan_func()
359 ret = idr_alloc(&sdata->u.nan.function_inst_ids, in ieee80211_add_nan_func()
360 nan_func, 1, sdata->local->hw.max_nan_de_entries + 1, in ieee80211_add_nan_func()
362 spin_unlock_bh(&sdata->u.nan.func_lock); in ieee80211_add_nan_func()
367 nan_func->instance_id = ret; in ieee80211_add_nan_func()
369 WARN_ON(nan_func->instance_id == 0); in ieee80211_add_nan_func()
371 ret = drv_add_nan_func(sdata->local, sdata, nan_func); in ieee80211_add_nan_func()
373 spin_lock_bh(&sdata->u.nan.func_lock); in ieee80211_add_nan_func()
374 idr_remove(&sdata->u.nan.function_inst_ids, in ieee80211_add_nan_func()
375 nan_func->instance_id); in ieee80211_add_nan_func()
376 spin_unlock_bh(&sdata->u.nan.func_lock); in ieee80211_add_nan_func()
389 lockdep_assert_held(&sdata->u.nan.func_lock); in ieee80211_find_nan_func_by_cookie()
391 idr_for_each_entry(&sdata->u.nan.function_inst_ids, func, id) { in ieee80211_find_nan_func_by_cookie()
392 if (func->cookie == cookie) in ieee80211_find_nan_func_by_cookie()
406 if (sdata->vif.type != NL80211_IFTYPE_NAN || in ieee80211_del_nan_func()
410 spin_lock_bh(&sdata->u.nan.func_lock); in ieee80211_del_nan_func()
414 instance_id = func->instance_id; in ieee80211_del_nan_func()
416 spin_unlock_bh(&sdata->u.nan.func_lock); in ieee80211_del_nan_func()
419 drv_del_nan_func(sdata->local, sdata, instance_id); in ieee80211_del_nan_func()
428 sdata->noack_map = noack_map; in ieee80211_set_noack_map()
438 struct ieee80211_local *local = sdata->local; in ieee80211_set_tx()
441 int ret = -EINVAL; in ieee80211_set_tx()
443 if (!wiphy_ext_feature_isset(local->hw.wiphy, in ieee80211_set_tx()
445 return -EINVAL; in ieee80211_set_tx()
450 return -EINVAL; in ieee80211_set_tx()
452 if (sta->ptk_idx == key_idx) in ieee80211_set_tx()
455 mutex_lock(&local->key_mtx); in ieee80211_set_tx()
456 key = key_mtx_dereference(local, sta->ptk[key_idx]); in ieee80211_set_tx()
458 if (key && key->conf.flags & IEEE80211_KEY_FLAG_NO_AUTO_TX) in ieee80211_set_tx()
461 mutex_unlock(&local->key_mtx); in ieee80211_set_tx()
472 struct ieee80211_local *local = sdata->local; in ieee80211_add_key()
478 return -ENETDOWN; in ieee80211_add_key()
483 if (pairwise && params->mode == NL80211_KEY_SET_TX) in ieee80211_add_key()
487 switch (params->cipher) { in ieee80211_add_key()
492 return -EINVAL; in ieee80211_add_key()
494 return -EINVAL; in ieee80211_add_key()
500 key = ieee80211_key_alloc(params->cipher, key_idx, params->key_len, in ieee80211_add_key()
501 params->key, params->seq_len, params->seq); in ieee80211_add_key()
505 key->conf.link_id = link_id; in ieee80211_add_key()
508 key->conf.flags |= IEEE80211_KEY_FLAG_PAIRWISE; in ieee80211_add_key()
510 if (params->mode == NL80211_KEY_NO_TX) in ieee80211_add_key()
511 key->conf.flags |= IEEE80211_KEY_FLAG_NO_AUTO_TX; in ieee80211_add_key()
513 mutex_lock(&local->sta_mtx); in ieee80211_add_key()
529 err = -ENOENT; in ieee80211_add_key()
534 switch (sdata->vif.type) { in ieee80211_add_key()
536 if (sdata->u.mgd.mfp != IEEE80211_MFP_DISABLED) in ieee80211_add_key()
537 key->conf.flags |= IEEE80211_KEY_FLAG_RX_MGMT; in ieee80211_add_key()
543 key->conf.flags |= IEEE80211_KEY_FLAG_RX_MGMT; in ieee80211_add_key()
550 if (sdata->u.mesh.security != IEEE80211_MESH_SEC_NONE) in ieee80211_add_key()
551 key->conf.flags |= IEEE80211_KEY_FLAG_RX_MGMT; in ieee80211_add_key()
570 if (err == -EALREADY) in ieee80211_add_key()
574 mutex_unlock(&local->sta_mtx); in ieee80211_add_key()
583 struct ieee80211_local *local __maybe_unused = sdata->local; in ieee80211_lookup_key()
584 struct ieee80211_link_data *link = &sdata->deflink; in ieee80211_lookup_key()
588 link = rcu_dereference_check(sdata->link[link_id], in ieee80211_lookup_key()
589 lockdep_is_held(&sdata->wdev.mtx)); in ieee80211_lookup_key()
603 link_sta = rcu_dereference_check(sta->link[link_id], in ieee80211_lookup_key()
604 lockdep_is_held(&local->sta_mtx)); in ieee80211_lookup_key()
608 link_sta = &sta->deflink; in ieee80211_lookup_key()
613 sta->ptk[key_idx]); in ieee80211_lookup_key()
620 link_sta->gtk[key_idx]); in ieee80211_lookup_key()
627 sdata->keys[key_idx]); in ieee80211_lookup_key()
629 key = rcu_dereference_check_key_mtx(local, link->gtk[key_idx]); in ieee80211_lookup_key()
635 return rcu_dereference_check_key_mtx(local, sdata->keys[key_idx]); in ieee80211_lookup_key()
645 struct ieee80211_local *local = sdata->local; in ieee80211_del_key()
649 mutex_lock(&local->sta_mtx); in ieee80211_del_key()
650 mutex_lock(&local->key_mtx); in ieee80211_del_key()
654 ret = -ENOENT; in ieee80211_del_key()
658 ieee80211_key_free(key, sdata->vif.type == NL80211_IFTYPE_STATION); in ieee80211_del_key()
662 mutex_unlock(&local->key_mtx); in ieee80211_del_key()
663 mutex_unlock(&local->sta_mtx); in ieee80211_del_key()
681 int err = -ENOENT; in ieee80211_get_key()
694 params.cipher = key->conf.cipher; in ieee80211_get_key()
696 switch (key->conf.cipher) { in ieee80211_get_key()
698 pn64 = atomic64_read(&key->conf.tx_pn); in ieee80211_get_key()
702 if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE && in ieee80211_get_key()
703 !(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { in ieee80211_get_key()
704 drv_get_key_seq(sdata->local, key, &kseq); in ieee80211_get_key()
735 if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE && in ieee80211_get_key()
736 !(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { in ieee80211_get_key()
737 drv_get_key_seq(sdata->local, key, &kseq); in ieee80211_get_key()
740 pn64 = atomic64_read(&key->conf.tx_pn); in ieee80211_get_key()
752 if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) in ieee80211_get_key()
754 if (WARN_ON(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) in ieee80211_get_key()
756 drv_get_key_seq(sdata->local, key, &kseq); in ieee80211_get_key()
762 params.key = key->conf.key; in ieee80211_get_key()
763 params.key_len = key->conf.keylen; in ieee80211_get_key()
826 rinfo->flags = 0; in sta_set_rate_info_tx()
827 if (rate->flags & IEEE80211_TX_RC_MCS) { in sta_set_rate_info_tx()
828 rinfo->flags |= RATE_INFO_FLAGS_MCS; in sta_set_rate_info_tx()
829 rinfo->mcs = rate->idx; in sta_set_rate_info_tx()
830 } else if (rate->flags & IEEE80211_TX_RC_VHT_MCS) { in sta_set_rate_info_tx()
831 rinfo->flags |= RATE_INFO_FLAGS_VHT_MCS; in sta_set_rate_info_tx()
832 rinfo->mcs = ieee80211_rate_get_vht_mcs(rate); in sta_set_rate_info_tx()
833 rinfo->nss = ieee80211_rate_get_vht_nss(rate); in sta_set_rate_info_tx()
836 int shift = ieee80211_vif_get_shift(&sta->sdata->vif); in sta_set_rate_info_tx()
839 sband = ieee80211_get_sband(sta->sdata); in sta_set_rate_info_tx()
840 WARN_ON_ONCE(sband && !sband->bitrates); in sta_set_rate_info_tx()
841 if (sband && sband->bitrates) { in sta_set_rate_info_tx()
842 brate = sband->bitrates[rate->idx].bitrate; in sta_set_rate_info_tx()
843 rinfo->legacy = DIV_ROUND_UP(brate, 1 << shift); in sta_set_rate_info_tx()
846 if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) in sta_set_rate_info_tx()
847 rinfo->bw = RATE_INFO_BW_40; in sta_set_rate_info_tx()
848 else if (rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH) in sta_set_rate_info_tx()
849 rinfo->bw = RATE_INFO_BW_80; in sta_set_rate_info_tx()
850 else if (rate->flags & IEEE80211_TX_RC_160_MHZ_WIDTH) in sta_set_rate_info_tx()
851 rinfo->bw = RATE_INFO_BW_160; in sta_set_rate_info_tx()
853 rinfo->bw = RATE_INFO_BW_20; in sta_set_rate_info_tx()
854 if (rate->flags & IEEE80211_TX_RC_SHORT_GI) in sta_set_rate_info_tx()
855 rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI; in sta_set_rate_info_tx()
862 struct ieee80211_local *local = sdata->local; in ieee80211_dump_station()
864 int ret = -ENOENT; in ieee80211_dump_station()
866 mutex_lock(&local->sta_mtx); in ieee80211_dump_station()
871 memcpy(mac, sta->sta.addr, ETH_ALEN); in ieee80211_dump_station()
875 mutex_unlock(&local->sta_mtx); in ieee80211_dump_station()
883 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); in ieee80211_dump_survey()
892 struct ieee80211_local *local = sdata->local; in ieee80211_get_station()
894 int ret = -ENOENT; in ieee80211_get_station()
896 mutex_lock(&local->sta_mtx); in ieee80211_get_station()
904 mutex_unlock(&local->sta_mtx); in ieee80211_get_station()
916 if (cfg80211_chandef_identical(&local->monitor_chandef, chandef)) in ieee80211_set_monitor_channel()
919 if (local->use_chanctx) { in ieee80211_set_monitor_channel()
920 sdata = wiphy_dereference(local->hw.wiphy, in ieee80211_set_monitor_channel()
921 local->monitor_sdata); in ieee80211_set_monitor_channel()
924 mutex_lock(&local->mtx); in ieee80211_set_monitor_channel()
925 ieee80211_link_release_channel(&sdata->deflink); in ieee80211_set_monitor_channel()
926 ret = ieee80211_link_use_channel(&sdata->deflink, in ieee80211_set_monitor_channel()
929 mutex_unlock(&local->mtx); in ieee80211_set_monitor_channel()
933 mutex_lock(&local->mtx); in ieee80211_set_monitor_channel()
934 if (local->open_count == local->monitors) { in ieee80211_set_monitor_channel()
935 local->_oper_chandef = *chandef; in ieee80211_set_monitor_channel()
938 mutex_unlock(&local->mtx); in ieee80211_set_monitor_channel()
942 local->monitor_chandef = *chandef; in ieee80211_set_monitor_channel()
959 old = sdata_dereference(link->u.ap.probe_resp, sdata); in ieee80211_set_probe_resp()
963 return -ENOMEM; in ieee80211_set_probe_resp()
965 new->len = resp_len; in ieee80211_set_probe_resp()
966 memcpy(new->data, resp, resp_len); in ieee80211_set_probe_resp()
969 memcpy(new->cntdwn_counter_offsets, csa->counter_offsets_presp, in ieee80211_set_probe_resp()
970 csa->n_counter_offsets_presp * in ieee80211_set_probe_resp()
971 sizeof(new->cntdwn_counter_offsets[0])); in ieee80211_set_probe_resp()
973 new->cntdwn_counter_offsets[0] = cca->counter_offset_presp; in ieee80211_set_probe_resp()
975 rcu_assign_pointer(link->u.ap.probe_resp, new); in ieee80211_set_probe_resp()
990 if (!params->tmpl || !params->tmpl_len) in ieee80211_set_fils_discovery()
991 return -EINVAL; in ieee80211_set_fils_discovery()
993 fd = &link_conf->fils_discovery; in ieee80211_set_fils_discovery()
994 fd->min_interval = params->min_interval; in ieee80211_set_fils_discovery()
995 fd->max_interval = params->max_interval; in ieee80211_set_fils_discovery()
997 old = sdata_dereference(link->u.ap.fils_discovery, sdata); in ieee80211_set_fils_discovery()
998 new = kzalloc(sizeof(*new) + params->tmpl_len, GFP_KERNEL); in ieee80211_set_fils_discovery()
1000 return -ENOMEM; in ieee80211_set_fils_discovery()
1001 new->len = params->tmpl_len; in ieee80211_set_fils_discovery()
1002 memcpy(new->data, params->tmpl, params->tmpl_len); in ieee80211_set_fils_discovery()
1003 rcu_assign_pointer(link->u.ap.fils_discovery, new); in ieee80211_set_fils_discovery()
1019 if (!params->tmpl || !params->tmpl_len) in ieee80211_set_unsol_bcast_probe_resp()
1020 return -EINVAL; in ieee80211_set_unsol_bcast_probe_resp()
1022 old = sdata_dereference(link->u.ap.unsol_bcast_probe_resp, sdata); in ieee80211_set_unsol_bcast_probe_resp()
1023 new = kzalloc(sizeof(*new) + params->tmpl_len, GFP_KERNEL); in ieee80211_set_unsol_bcast_probe_resp()
1025 return -ENOMEM; in ieee80211_set_unsol_bcast_probe_resp()
1026 new->len = params->tmpl_len; in ieee80211_set_unsol_bcast_probe_resp()
1027 memcpy(new->data, params->tmpl, params->tmpl_len); in ieee80211_set_unsol_bcast_probe_resp()
1028 rcu_assign_pointer(link->u.ap.unsol_bcast_probe_resp, new); in ieee80211_set_unsol_bcast_probe_resp()
1033 link_conf->unsol_bcast_probe_resp_interval = params->interval; in ieee80211_set_unsol_bcast_probe_resp()
1051 old = link_conf->ftmr_params; in ieee80211_set_ftm_responder_params()
1056 return -ENOMEM; in ieee80211_set_ftm_responder_params()
1060 new->lci_len = lci_len; in ieee80211_set_ftm_responder_params()
1061 new->lci = pos; in ieee80211_set_ftm_responder_params()
1067 new->civicloc_len = civicloc_len; in ieee80211_set_ftm_responder_params()
1068 new->civicloc = pos; in ieee80211_set_ftm_responder_params()
1073 link_conf->ftmr_params = new; in ieee80211_set_ftm_responder_params()
1085 dst->cnt = src->cnt; in ieee80211_copy_mbssid_beacon()
1086 for (i = 0; i < src->cnt; i++) { in ieee80211_copy_mbssid_beacon()
1087 memcpy(pos + offset, src->elem[i].data, src->elem[i].len); in ieee80211_copy_mbssid_beacon()
1088 dst->elem[i].len = src->elem[i].len; in ieee80211_copy_mbssid_beacon()
1089 dst->elem[i].data = pos + offset; in ieee80211_copy_mbssid_beacon()
1090 offset += dst->elem[i].len; in ieee80211_copy_mbssid_beacon()
1102 for (i = 0; i < src->cnt; i++) { in ieee80211_copy_rnr_beacon()
1103 memcpy(pos + offset, src->elem[i].data, src->elem[i].len); in ieee80211_copy_rnr_beacon()
1104 dst->elem[i].len = src->elem[i].len; in ieee80211_copy_rnr_beacon()
1105 dst->elem[i].data = pos + offset; in ieee80211_copy_rnr_beacon()
1106 offset += dst->elem[i].len; in ieee80211_copy_rnr_beacon()
1108 dst->cnt = src->cnt; in ieee80211_copy_rnr_beacon()
1127 struct ieee80211_bss_conf *link_conf = link->conf; in ieee80211_assign_beacon()
1129 old = sdata_dereference(link->u.ap.beacon, sdata); in ieee80211_assign_beacon()
1132 if (!params->head && !old) in ieee80211_assign_beacon()
1133 return -EINVAL; in ieee80211_assign_beacon()
1136 if (params->head) in ieee80211_assign_beacon()
1137 new_head_len = params->head_len; in ieee80211_assign_beacon()
1139 new_head_len = old->head_len; in ieee80211_assign_beacon()
1142 if (params->tail || !old) in ieee80211_assign_beacon()
1143 /* params->tail_len will be zero for !params->tail */ in ieee80211_assign_beacon()
1144 new_tail_len = params->tail_len; in ieee80211_assign_beacon()
1146 new_tail_len = old->tail_len; in ieee80211_assign_beacon()
1151 if (params->mbssid_ies) { in ieee80211_assign_beacon()
1152 mbssid = params->mbssid_ies; in ieee80211_assign_beacon()
1153 size += struct_size(new->mbssid_ies, elem, mbssid->cnt); in ieee80211_assign_beacon()
1154 if (params->rnr_ies) { in ieee80211_assign_beacon()
1155 rnr = params->rnr_ies; in ieee80211_assign_beacon()
1156 size += struct_size(new->rnr_ies, elem, rnr->cnt); in ieee80211_assign_beacon()
1159 mbssid->cnt); in ieee80211_assign_beacon()
1160 } else if (old && old->mbssid_ies) { in ieee80211_assign_beacon()
1161 mbssid = old->mbssid_ies; in ieee80211_assign_beacon()
1162 size += struct_size(new->mbssid_ies, elem, mbssid->cnt); in ieee80211_assign_beacon()
1163 if (old && old->rnr_ies) { in ieee80211_assign_beacon()
1164 rnr = old->rnr_ies; in ieee80211_assign_beacon()
1165 size += struct_size(new->rnr_ies, elem, rnr->cnt); in ieee80211_assign_beacon()
1168 mbssid->cnt); in ieee80211_assign_beacon()
1173 return -ENOMEM; in ieee80211_assign_beacon()
1181 new->head = ((u8 *) new) + sizeof(*new); in ieee80211_assign_beacon()
1182 new->tail = new->head + new_head_len; in ieee80211_assign_beacon()
1183 new->head_len = new_head_len; in ieee80211_assign_beacon()
1184 new->tail_len = new_tail_len; in ieee80211_assign_beacon()
1187 u8 *pos = new->tail + new->tail_len; in ieee80211_assign_beacon()
1189 new->mbssid_ies = (void *)pos; in ieee80211_assign_beacon()
1190 pos += struct_size(new->mbssid_ies, elem, mbssid->cnt); in ieee80211_assign_beacon()
1191 pos += ieee80211_copy_mbssid_beacon(pos, new->mbssid_ies, in ieee80211_assign_beacon()
1194 new->rnr_ies = (void *)pos; in ieee80211_assign_beacon()
1195 pos += struct_size(new->rnr_ies, elem, rnr->cnt); in ieee80211_assign_beacon()
1196 ieee80211_copy_rnr_beacon(pos, new->rnr_ies, rnr); in ieee80211_assign_beacon()
1199 link_conf->bssid_indicator = in ieee80211_assign_beacon()
1200 ilog2(__roundup_pow_of_two(mbssid->cnt + 1)); in ieee80211_assign_beacon()
1204 new->cntdwn_current_counter = csa->count; in ieee80211_assign_beacon()
1205 memcpy(new->cntdwn_counter_offsets, csa->counter_offsets_beacon, in ieee80211_assign_beacon()
1206 csa->n_counter_offsets_beacon * in ieee80211_assign_beacon()
1207 sizeof(new->cntdwn_counter_offsets[0])); in ieee80211_assign_beacon()
1209 new->cntdwn_current_counter = cca->count; in ieee80211_assign_beacon()
1210 new->cntdwn_counter_offsets[0] = cca->counter_offset_beacon; in ieee80211_assign_beacon()
1214 if (params->head) in ieee80211_assign_beacon()
1215 memcpy(new->head, params->head, new_head_len); in ieee80211_assign_beacon()
1217 memcpy(new->head, old->head, new_head_len); in ieee80211_assign_beacon()
1220 if (params->tail) in ieee80211_assign_beacon()
1221 memcpy(new->tail, params->tail, new_tail_len); in ieee80211_assign_beacon()
1224 memcpy(new->tail, old->tail, new_tail_len); in ieee80211_assign_beacon()
1226 err = ieee80211_set_probe_resp(sdata, params->probe_resp, in ieee80211_assign_beacon()
1227 params->probe_resp_len, csa, cca, link); in ieee80211_assign_beacon()
1235 if (params->ftm_responder != -1) { in ieee80211_assign_beacon()
1236 link_conf->ftm_responder = params->ftm_responder; in ieee80211_assign_beacon()
1238 params->lci, in ieee80211_assign_beacon()
1239 params->lci_len, in ieee80211_assign_beacon()
1240 params->civicloc, in ieee80211_assign_beacon()
1241 params->civicloc_len, in ieee80211_assign_beacon()
1252 rcu_assign_pointer(link->u.ap.beacon, new); in ieee80211_assign_beacon()
1253 sdata->u.ap.active = true; in ieee80211_assign_beacon()
1266 struct ieee80211_local *local = sdata->local; in ieee80211_start_ap()
1277 unsigned int link_id = params->beacon.link_id; in ieee80211_start_ap()
1281 link = sdata_dereference(sdata->link[link_id], sdata); in ieee80211_start_ap()
1283 return -ENOLINK; in ieee80211_start_ap()
1285 link_conf = link->conf; in ieee80211_start_ap()
1287 old = sdata_dereference(link->u.ap.beacon, sdata); in ieee80211_start_ap()
1289 return -EALREADY; in ieee80211_start_ap()
1291 if (params->smps_mode != NL80211_SMPS_OFF) in ieee80211_start_ap()
1292 return -ENOTSUPP; in ieee80211_start_ap()
1294 link->smps_mode = IEEE80211_SMPS_OFF; in ieee80211_start_ap()
1296 link->needed_rx_chains = sdata->local->rx_chains; in ieee80211_start_ap()
1298 prev_beacon_int = link_conf->beacon_int; in ieee80211_start_ap()
1299 link_conf->beacon_int = params->beacon_interval; in ieee80211_start_ap()
1301 if (params->ht_cap) in ieee80211_start_ap()
1302 link_conf->ht_ldpc = in ieee80211_start_ap()
1303 params->ht_cap->cap_info & in ieee80211_start_ap()
1306 if (params->vht_cap) { in ieee80211_start_ap()
1307 link_conf->vht_ldpc = in ieee80211_start_ap()
1308 params->vht_cap->vht_cap_info & in ieee80211_start_ap()
1310 link_conf->vht_su_beamformer = in ieee80211_start_ap()
1311 params->vht_cap->vht_cap_info & in ieee80211_start_ap()
1313 link_conf->vht_su_beamformee = in ieee80211_start_ap()
1314 params->vht_cap->vht_cap_info & in ieee80211_start_ap()
1316 link_conf->vht_mu_beamformer = in ieee80211_start_ap()
1317 params->vht_cap->vht_cap_info & in ieee80211_start_ap()
1319 link_conf->vht_mu_beamformee = in ieee80211_start_ap()
1320 params->vht_cap->vht_cap_info & in ieee80211_start_ap()
1324 if (params->he_cap && params->he_oper) { in ieee80211_start_ap()
1325 link_conf->he_support = true; in ieee80211_start_ap()
1326 link_conf->htc_trig_based_pkt_ext = in ieee80211_start_ap()
1327 le32_get_bits(params->he_oper->he_oper_params, in ieee80211_start_ap()
1329 link_conf->frame_time_rts_th = in ieee80211_start_ap()
1330 le32_get_bits(params->he_oper->he_oper_params, in ieee80211_start_ap()
1334 if (params->beacon.he_bss_color.enabled) in ieee80211_start_ap()
1338 if (params->he_cap) { in ieee80211_start_ap()
1339 link_conf->he_ldpc = in ieee80211_start_ap()
1340 params->he_cap->phy_cap_info[1] & in ieee80211_start_ap()
1342 link_conf->he_su_beamformer = in ieee80211_start_ap()
1343 params->he_cap->phy_cap_info[3] & in ieee80211_start_ap()
1345 link_conf->he_su_beamformee = in ieee80211_start_ap()
1346 params->he_cap->phy_cap_info[4] & in ieee80211_start_ap()
1348 link_conf->he_mu_beamformer = in ieee80211_start_ap()
1349 params->he_cap->phy_cap_info[4] & in ieee80211_start_ap()
1351 link_conf->he_full_ul_mumimo = in ieee80211_start_ap()
1352 params->he_cap->phy_cap_info[2] & in ieee80211_start_ap()
1356 if (params->eht_cap) { in ieee80211_start_ap()
1357 if (!link_conf->he_support) in ieee80211_start_ap()
1358 return -EOPNOTSUPP; in ieee80211_start_ap()
1360 link_conf->eht_support = true; in ieee80211_start_ap()
1361 link_conf->eht_puncturing = params->punct_bitmap; in ieee80211_start_ap()
1364 link_conf->eht_su_beamformer = in ieee80211_start_ap()
1365 params->eht_cap->fixed.phy_cap_info[0] & in ieee80211_start_ap()
1367 link_conf->eht_su_beamformee = in ieee80211_start_ap()
1368 params->eht_cap->fixed.phy_cap_info[0] & in ieee80211_start_ap()
1370 link_conf->eht_mu_beamformer = in ieee80211_start_ap()
1371 params->eht_cap->fixed.phy_cap_info[7] & in ieee80211_start_ap()
1376 link_conf->eht_su_beamformer = false; in ieee80211_start_ap()
1377 link_conf->eht_su_beamformee = false; in ieee80211_start_ap()
1378 link_conf->eht_mu_beamformer = false; in ieee80211_start_ap()
1381 if (sdata->vif.type == NL80211_IFTYPE_AP && in ieee80211_start_ap()
1382 params->mbssid_config.tx_wdev) { in ieee80211_start_ap()
1384 params->mbssid_config, in ieee80211_start_ap()
1390 mutex_lock(&local->mtx); in ieee80211_start_ap()
1391 err = ieee80211_link_use_channel(link, &params->chandef, in ieee80211_start_ap()
1395 mutex_unlock(&local->mtx); in ieee80211_start_ap()
1397 link_conf->beacon_int = prev_beacon_int; in ieee80211_start_ap()
1405 sdata->control_port_protocol = params->crypto.control_port_ethertype; in ieee80211_start_ap()
1406 sdata->control_port_no_encrypt = params->crypto.control_port_no_encrypt; in ieee80211_start_ap()
1407 sdata->control_port_over_nl80211 = in ieee80211_start_ap()
1408 params->crypto.control_port_over_nl80211; in ieee80211_start_ap()
1409 sdata->control_port_no_preauth = in ieee80211_start_ap()
1410 params->crypto.control_port_no_preauth; in ieee80211_start_ap()
1412 list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) { in ieee80211_start_ap()
1413 vlan->control_port_protocol = in ieee80211_start_ap()
1414 params->crypto.control_port_ethertype; in ieee80211_start_ap()
1415 vlan->control_port_no_encrypt = in ieee80211_start_ap()
1416 params->crypto.control_port_no_encrypt; in ieee80211_start_ap()
1417 vlan->control_port_over_nl80211 = in ieee80211_start_ap()
1418 params->crypto.control_port_over_nl80211; in ieee80211_start_ap()
1419 vlan->control_port_no_preauth = in ieee80211_start_ap()
1420 params->crypto.control_port_no_preauth; in ieee80211_start_ap()
1423 link_conf->dtim_period = params->dtim_period; in ieee80211_start_ap()
1424 link_conf->enable_beacon = true; in ieee80211_start_ap()
1425 link_conf->allow_p2p_go_ps = sdata->vif.p2p; in ieee80211_start_ap()
1426 link_conf->twt_responder = params->twt_responder; in ieee80211_start_ap()
1427 link_conf->he_obss_pd = params->he_obss_pd; in ieee80211_start_ap()
1428 link_conf->he_bss_color = params->beacon.he_bss_color; in ieee80211_start_ap()
1429 sdata->vif.cfg.s1g = params->chandef.chan->band == in ieee80211_start_ap()
1432 sdata->vif.cfg.ssid_len = params->ssid_len; in ieee80211_start_ap()
1433 if (params->ssid_len) in ieee80211_start_ap()
1434 memcpy(sdata->vif.cfg.ssid, params->ssid, in ieee80211_start_ap()
1435 params->ssid_len); in ieee80211_start_ap()
1436 link_conf->hidden_ssid = in ieee80211_start_ap()
1437 (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE); in ieee80211_start_ap()
1439 memset(&link_conf->p2p_noa_attr, 0, in ieee80211_start_ap()
1440 sizeof(link_conf->p2p_noa_attr)); in ieee80211_start_ap()
1441 link_conf->p2p_noa_attr.oppps_ctwindow = in ieee80211_start_ap()
1442 params->p2p_ctwindow & IEEE80211_P2P_OPPPS_CTWINDOW_MASK; in ieee80211_start_ap()
1443 if (params->p2p_opp_ps) in ieee80211_start_ap()
1444 link_conf->p2p_noa_attr.oppps_ctwindow |= in ieee80211_start_ap()
1447 sdata->beacon_rate_set = false; in ieee80211_start_ap()
1448 if (wiphy_ext_feature_isset(local->hw.wiphy, in ieee80211_start_ap()
1451 sdata->beacon_rateidx_mask[i] = in ieee80211_start_ap()
1452 params->beacon_rate.control[i].legacy; in ieee80211_start_ap()
1453 if (sdata->beacon_rateidx_mask[i]) in ieee80211_start_ap()
1454 sdata->beacon_rate_set = true; in ieee80211_start_ap()
1458 if (ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL)) in ieee80211_start_ap()
1459 link_conf->beacon_tx_rate = params->beacon_rate; in ieee80211_start_ap()
1461 err = ieee80211_assign_beacon(sdata, link, &params->beacon, NULL, NULL, in ieee80211_start_ap()
1466 if (params->fils_discovery.max_interval) { in ieee80211_start_ap()
1468 &params->fils_discovery, in ieee80211_start_ap()
1475 if (params->unsol_bcast_probe_resp.interval) { in ieee80211_start_ap()
1477 &params->unsol_bcast_probe_resp, in ieee80211_start_ap()
1484 err = drv_start_ap(sdata->local, sdata, link_conf); in ieee80211_start_ap()
1486 old = sdata_dereference(link->u.ap.beacon, sdata); in ieee80211_start_ap()
1490 RCU_INIT_POINTER(link->u.ap.beacon, NULL); in ieee80211_start_ap()
1491 sdata->u.ap.active = false; in ieee80211_start_ap()
1500 list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) in ieee80211_start_ap()
1501 netif_carrier_on(vlan->dev); in ieee80211_start_ap()
1506 mutex_lock(&local->mtx); in ieee80211_start_ap()
1508 mutex_unlock(&local->mtx); in ieee80211_start_ap()
1525 link = sdata_dereference(sdata->link[params->link_id], sdata); in ieee80211_change_beacon()
1527 return -ENOLINK; in ieee80211_change_beacon()
1529 link_conf = link->conf; in ieee80211_change_beacon()
1531 /* don't allow changing the beacon while a countdown is in place - offset in ieee80211_change_beacon()
1534 if (link_conf->csa_active || link_conf->color_change_active) in ieee80211_change_beacon()
1535 return -EBUSY; in ieee80211_change_beacon()
1537 old = sdata_dereference(link->u.ap.beacon, sdata); in ieee80211_change_beacon()
1539 return -ENOENT; in ieee80211_change_beacon()
1546 if (params->he_bss_color_valid && in ieee80211_change_beacon()
1547 params->he_bss_color.enabled != link_conf->he_bss_color.enabled) { in ieee80211_change_beacon()
1548 link_conf->he_bss_color.enabled = params->he_bss_color.enabled; in ieee80211_change_beacon()
1558 if (!link->u.ap.next_beacon) in ieee80211_free_next_beacon()
1561 kfree(link->u.ap.next_beacon->mbssid_ies); in ieee80211_free_next_beacon()
1562 kfree(link->u.ap.next_beacon->rnr_ies); in ieee80211_free_next_beacon()
1563 kfree(link->u.ap.next_beacon); in ieee80211_free_next_beacon()
1564 link->u.ap.next_beacon = NULL; in ieee80211_free_next_beacon()
1572 struct ieee80211_local *local = sdata->local; in ieee80211_stop_ap()
1579 sdata_dereference(sdata->link[link_id], sdata); in ieee80211_stop_ap()
1580 struct ieee80211_bss_conf *link_conf = link->conf; in ieee80211_stop_ap()
1584 old_beacon = sdata_dereference(link->u.ap.beacon, sdata); in ieee80211_stop_ap()
1586 return -ENOENT; in ieee80211_stop_ap()
1587 old_probe_resp = sdata_dereference(link->u.ap.probe_resp, in ieee80211_stop_ap()
1589 old_fils_discovery = sdata_dereference(link->u.ap.fils_discovery, in ieee80211_stop_ap()
1592 sdata_dereference(link->u.ap.unsol_bcast_probe_resp, in ieee80211_stop_ap()
1596 mutex_lock(&local->mtx); in ieee80211_stop_ap()
1597 link_conf->csa_active = false; in ieee80211_stop_ap()
1598 link_conf->color_change_active = false; in ieee80211_stop_ap()
1599 if (link->csa_block_tx) { in ieee80211_stop_ap()
1602 link->csa_block_tx = false; in ieee80211_stop_ap()
1605 mutex_unlock(&local->mtx); in ieee80211_stop_ap()
1610 list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) in ieee80211_stop_ap()
1611 netif_carrier_off(vlan->dev); in ieee80211_stop_ap()
1615 sdata->u.ap.active = false; in ieee80211_stop_ap()
1616 RCU_INIT_POINTER(link->u.ap.beacon, NULL); in ieee80211_stop_ap()
1617 RCU_INIT_POINTER(link->u.ap.probe_resp, NULL); in ieee80211_stop_ap()
1618 RCU_INIT_POINTER(link->u.ap.fils_discovery, NULL); in ieee80211_stop_ap()
1619 RCU_INIT_POINTER(link->u.ap.unsol_bcast_probe_resp, NULL); in ieee80211_stop_ap()
1628 kfree(link_conf->ftmr_params); in ieee80211_stop_ap()
1629 link_conf->ftmr_params = NULL; in ieee80211_stop_ap()
1631 sdata->vif.mbssid_tx_vif = NULL; in ieee80211_stop_ap()
1632 link_conf->bssid_index = 0; in ieee80211_stop_ap()
1633 link_conf->nontransmitted = false; in ieee80211_stop_ap()
1634 link_conf->ema_ap = false; in ieee80211_stop_ap()
1635 link_conf->bssid_indicator = 0; in ieee80211_stop_ap()
1640 link_conf->enable_beacon = false; in ieee80211_stop_ap()
1641 sdata->beacon_rate_set = false; in ieee80211_stop_ap()
1642 sdata->vif.cfg.ssid_len = 0; in ieee80211_stop_ap()
1643 clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state); in ieee80211_stop_ap()
1647 if (sdata->wdev.cac_started) { in ieee80211_stop_ap()
1648 chandef = link_conf->chandef; in ieee80211_stop_ap()
1649 cancel_delayed_work_sync(&link->dfs_cac_timer_work); in ieee80211_stop_ap()
1650 cfg80211_cac_event(sdata->dev, &chandef, in ieee80211_stop_ap()
1655 drv_stop_ap(sdata->local, sdata, link_conf); in ieee80211_stop_ap()
1658 local->total_ps_buffered -= skb_queue_len(&sdata->u.ap.ps.bc_buf); in ieee80211_stop_ap()
1659 ieee80211_purge_tx_queue(&local->hw, &sdata->u.ap.ps.bc_buf); in ieee80211_stop_ap()
1661 mutex_lock(&local->mtx); in ieee80211_stop_ap()
1664 mutex_unlock(&local->mtx); in ieee80211_stop_ap()
1734 struct ieee80211_sub_if_data *sdata = sta->sdata; in sta_apply_mesh_params()
1737 if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE) { in sta_apply_mesh_params()
1738 switch (params->plink_state) { in sta_apply_mesh_params()
1740 if (sta->mesh->plink_state != NL80211_PLINK_ESTAB) in sta_apply_mesh_params()
1742 sta->mesh->plink_state = params->plink_state; in sta_apply_mesh_params()
1743 sta->mesh->aid = params->peer_aid; in sta_apply_mesh_params()
1747 sdata->u.mesh.mshcfg.power_mode); in sta_apply_mesh_params()
1749 ewma_mesh_tx_rate_avg_init(&sta->mesh->tx_rate_avg); in sta_apply_mesh_params()
1751 ewma_mesh_tx_rate_avg_add(&sta->mesh->tx_rate_avg, 10); in sta_apply_mesh_params()
1760 if (sta->mesh->plink_state == NL80211_PLINK_ESTAB) in sta_apply_mesh_params()
1762 sta->mesh->plink_state = params->plink_state; in sta_apply_mesh_params()
1774 switch (params->plink_action) { in sta_apply_mesh_params()
1786 if (params->local_pm) in sta_apply_mesh_params()
1788 params->local_pm); in sta_apply_mesh_params()
1799 struct ieee80211_sub_if_data *sdata = sta->sdata; in sta_link_apply_parameters()
1800 u32 link_id = params->link_id < 0 ? 0 : params->link_id; in sta_link_apply_parameters()
1802 sdata_dereference(sdata->link[link_id], sdata); in sta_link_apply_parameters()
1804 rcu_dereference_protected(sta->link[link_id], in sta_link_apply_parameters()
1805 lockdep_is_held(&local->sta_mtx)); in sta_link_apply_parameters()
1811 if (params->link_id >= 0 && !new_link && in sta_link_apply_parameters()
1812 !params->link_mac && !params->txpwr_set && in sta_link_apply_parameters()
1813 !params->supported_rates_len && in sta_link_apply_parameters()
1814 !params->ht_capa && !params->vht_capa && in sta_link_apply_parameters()
1815 !params->he_capa && !params->eht_capa && in sta_link_apply_parameters()
1816 !params->opmode_notif_used) in sta_link_apply_parameters()
1820 return -EINVAL; in sta_link_apply_parameters()
1824 return -EINVAL; in sta_link_apply_parameters()
1826 if (params->link_mac) { in sta_link_apply_parameters()
1828 memcpy(link_sta->addr, params->link_mac, ETH_ALEN); in sta_link_apply_parameters()
1829 memcpy(link_sta->pub->addr, params->link_mac, ETH_ALEN); in sta_link_apply_parameters()
1830 } else if (!ether_addr_equal(link_sta->addr, in sta_link_apply_parameters()
1831 params->link_mac)) { in sta_link_apply_parameters()
1832 return -EINVAL; in sta_link_apply_parameters()
1835 return -EINVAL; in sta_link_apply_parameters()
1838 if (params->txpwr_set) { in sta_link_apply_parameters()
1841 link_sta->pub->txpwr.type = params->txpwr.type; in sta_link_apply_parameters()
1842 if (params->txpwr.type == NL80211_TX_POWER_LIMITED) in sta_link_apply_parameters()
1843 link_sta->pub->txpwr.power = params->txpwr.power; in sta_link_apply_parameters()
1849 if (params->supported_rates && in sta_link_apply_parameters()
1850 params->supported_rates_len) { in sta_link_apply_parameters()
1851 ieee80211_parse_bitrates(link->conf->chandef.width, in sta_link_apply_parameters()
1852 sband, params->supported_rates, in sta_link_apply_parameters()
1853 params->supported_rates_len, in sta_link_apply_parameters()
1854 &link_sta->pub->supp_rates[sband->band]); in sta_link_apply_parameters()
1857 if (params->ht_capa) in sta_link_apply_parameters()
1859 params->ht_capa, link_sta); in sta_link_apply_parameters()
1861 /* VHT can override some HT caps such as the A-MSDU max length */ in sta_link_apply_parameters()
1862 if (params->vht_capa) in sta_link_apply_parameters()
1864 params->vht_capa, NULL, in sta_link_apply_parameters()
1867 if (params->he_capa) in sta_link_apply_parameters()
1869 (void *)params->he_capa, in sta_link_apply_parameters()
1870 params->he_capa_len, in sta_link_apply_parameters()
1871 (void *)params->he_6ghz_capa, in sta_link_apply_parameters()
1874 if (params->he_capa && params->eht_capa) in sta_link_apply_parameters()
1876 (u8 *)params->he_capa, in sta_link_apply_parameters()
1877 params->he_capa_len, in sta_link_apply_parameters()
1878 params->eht_capa, in sta_link_apply_parameters()
1879 params->eht_capa_len, in sta_link_apply_parameters()
1884 if (params->opmode_notif_used) { in sta_link_apply_parameters()
1889 params->opmode_notif, in sta_link_apply_parameters()
1890 sband->band); in sta_link_apply_parameters()
1900 struct ieee80211_sub_if_data *sdata = sta->sdata; in sta_apply_parameters()
1904 mask = params->sta_flags_mask; in sta_apply_parameters()
1905 set = params->sta_flags_set; in sta_apply_parameters()
1907 if (ieee80211_vif_is_mesh(&sdata->vif)) { in sta_apply_parameters()
1918 * TDLS -- everything follows authorized, but in sta_apply_parameters()
1931 local->hw.queues >= IEEE80211_NUM_ACS) in sta_apply_parameters()
1932 sta->sta.wme = set & BIT(NL80211_STA_FLAG_WME); in sta_apply_parameters()
1952 sta->sta.mfp = !!(set & BIT(NL80211_STA_FLAG_MFP)); in sta_apply_parameters()
1968 !sdata->deflink.u.mgd.tdls_chan_switch_prohibited && in sta_apply_parameters()
1969 params->ext_capab_len >= 4 && in sta_apply_parameters()
1970 params->ext_capab[3] & WLAN_EXT_CAPA4_TDLS_CHAN_SWITCH) in sta_apply_parameters()
1974 !sdata->u.mgd.tdls_wider_bw_prohibited && in sta_apply_parameters()
1975 ieee80211_hw_check(&local->hw, TDLS_WIDER_BW) && in sta_apply_parameters()
1976 params->ext_capab_len >= 8 && in sta_apply_parameters()
1977 params->ext_capab[7] & WLAN_EXT_CAPA8_TDLS_WIDE_BW_ENABLED) in sta_apply_parameters()
1980 if (params->sta_modify_mask & STATION_PARAM_APPLY_UAPSD) { in sta_apply_parameters()
1981 sta->sta.uapsd_queues = params->uapsd_queues; in sta_apply_parameters()
1982 sta->sta.max_sp = params->max_sp; in sta_apply_parameters()
1985 ieee80211_sta_set_max_amsdu_subframes(sta, params->ext_capab, in sta_apply_parameters()
1986 params->ext_capab_len); in sta_apply_parameters()
1989 * cfg80211 validates this (1-2007) and allows setting the AID in sta_apply_parameters()
1992 if (params->aid) in sta_apply_parameters()
1993 sta->sta.aid = params->aid; in sta_apply_parameters()
2003 if (params->listen_interval >= 0) in sta_apply_parameters()
2004 sta->listen_interval = params->listen_interval; in sta_apply_parameters()
2007 &params->link_sta_params); in sta_apply_parameters()
2011 if (params->support_p2p_ps >= 0) in sta_apply_parameters()
2012 sta->sta.support_p2p_ps = params->support_p2p_ps; in sta_apply_parameters()
2014 if (ieee80211_vif_is_mesh(&sdata->vif)) in sta_apply_parameters()
2017 if (params->airtime_weight) in sta_apply_parameters()
2018 sta->airtime_weight = params->airtime_weight; in sta_apply_parameters()
2029 if (params->link_sta_params.mld_mac) in sta_apply_parameters()
2030 sta->sta.mlo = true; in sta_apply_parameters()
2044 if (params->vlan) { in ieee80211_add_station()
2045 sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan); in ieee80211_add_station()
2047 if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && in ieee80211_add_station()
2048 sdata->vif.type != NL80211_IFTYPE_AP) in ieee80211_add_station()
2049 return -EINVAL; in ieee80211_add_station()
2053 if (ether_addr_equal(mac, sdata->vif.addr)) in ieee80211_add_station()
2054 return -EINVAL; in ieee80211_add_station()
2057 return -EINVAL; in ieee80211_add_station()
2059 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER) && in ieee80211_add_station()
2060 sdata->vif.type == NL80211_IFTYPE_STATION && in ieee80211_add_station()
2061 !sdata->u.mgd.associated) in ieee80211_add_station()
2062 return -EINVAL; in ieee80211_add_station()
2065 * If we have a link ID, it can be a non-MLO station on an AP MLD, in ieee80211_add_station()
2069 if (params->link_sta_params.link_id >= 0) in ieee80211_add_station()
2071 params->link_sta_params.link_id, in ieee80211_add_station()
2072 params->link_sta_params.link_mac ?: mac, in ieee80211_add_station()
2078 return -ENOMEM; in ieee80211_add_station()
2080 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) in ieee80211_add_station()
2081 sta->sta.tdls = true; in ieee80211_add_station()
2087 mutex_lock(&local->sta_mtx); in ieee80211_add_station()
2089 mutex_unlock(&local->sta_mtx); in ieee80211_add_station()
2114 if (params->mac) in ieee80211_del_station()
2115 return sta_info_destroy_addr_bss(sdata, params->mac); in ieee80211_del_station()
2132 mutex_lock(&local->sta_mtx); in ieee80211_change_station()
2136 err = -ENOENT; in ieee80211_change_station()
2140 switch (sdata->vif.type) { in ieee80211_change_station()
2142 if (sdata->u.mesh.user_mpm) in ieee80211_change_station()
2168 err = -EOPNOTSUPP; in ieee80211_change_station()
2176 if (params->vlan && params->vlan != sta->sdata->dev) { in ieee80211_change_station()
2177 vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan); in ieee80211_change_station()
2179 if (params->vlan->ieee80211_ptr->use_4addr) { in ieee80211_change_station()
2180 if (vlansdata->u.vlan.sta) { in ieee80211_change_station()
2181 err = -EBUSY; in ieee80211_change_station()
2185 rcu_assign_pointer(vlansdata->u.vlan.sta, sta); in ieee80211_change_station()
2187 drv_sta_set_4addr(local, sta->sdata, &sta->sta, true); in ieee80211_change_station()
2190 if (sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN && in ieee80211_change_station()
2191 sta->sdata->u.vlan.sta) in ieee80211_change_station()
2192 RCU_INIT_POINTER(sta->sdata->u.vlan.sta, NULL); in ieee80211_change_station()
2195 ieee80211_vif_dec_num_mcast(sta->sdata); in ieee80211_change_station()
2197 sta->sdata = vlansdata; in ieee80211_change_station()
2202 ieee80211_vif_inc_num_mcast(sta->sdata); in ieee80211_change_station()
2203 cfg80211_send_layer2_update(sta->sdata->dev, in ieee80211_change_station()
2204 sta->sta.addr); in ieee80211_change_station()
2209 if (sdata != sta->sdata) { in ieee80211_change_station()
2210 mutex_lock_nested(&sta->sdata->wdev.mtx, 1); in ieee80211_change_station()
2212 mutex_unlock(&sta->sdata->wdev.mtx); in ieee80211_change_station()
2219 mutex_unlock(&local->sta_mtx); in ieee80211_change_station()
2221 if (sdata->vif.type == NL80211_IFTYPE_STATION && in ieee80211_change_station()
2222 params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) { in ieee80211_change_station()
2229 mutex_unlock(&local->sta_mtx); in ieee80211_change_station()
2238 struct mesh_path *mpath; in ieee80211_add_mpath() local
2247 return -ENOENT; in ieee80211_add_mpath()
2250 mpath = mesh_path_add(sdata, dst); in ieee80211_add_mpath()
2251 if (IS_ERR(mpath)) { in ieee80211_add_mpath()
2253 return PTR_ERR(mpath); in ieee80211_add_mpath()
2256 mesh_path_fix_nexthop(mpath, sta); in ieee80211_add_mpath()
2278 struct mesh_path *mpath; in ieee80211_change_mpath() local
2288 return -ENOENT; in ieee80211_change_mpath()
2291 mpath = mesh_path_lookup(sdata, dst); in ieee80211_change_mpath()
2292 if (!mpath) { in ieee80211_change_mpath()
2294 return -ENOENT; in ieee80211_change_mpath()
2297 mesh_path_fix_nexthop(mpath, sta); in ieee80211_change_mpath()
2303 static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop, in mpath_set_pinfo() argument
2306 struct sta_info *next_hop_sta = rcu_dereference(mpath->next_hop); in mpath_set_pinfo()
2309 memcpy(next_hop, next_hop_sta->sta.addr, ETH_ALEN); in mpath_set_pinfo()
2315 pinfo->generation = mpath->sdata->u.mesh.mesh_paths_generation; in mpath_set_pinfo()
2317 pinfo->filled = MPATH_INFO_FRAME_QLEN | in mpath_set_pinfo()
2327 pinfo->frame_qlen = mpath->frame_queue.qlen; in mpath_set_pinfo()
2328 pinfo->sn = mpath->sn; in mpath_set_pinfo()
2329 pinfo->metric = mpath->metric; in mpath_set_pinfo()
2330 if (time_before(jiffies, mpath->exp_time)) in mpath_set_pinfo()
2331 pinfo->exptime = jiffies_to_msecs(mpath->exp_time - jiffies); in mpath_set_pinfo()
2332 pinfo->discovery_timeout = in mpath_set_pinfo()
2333 jiffies_to_msecs(mpath->discovery_timeout); in mpath_set_pinfo()
2334 pinfo->discovery_retries = mpath->discovery_retries; in mpath_set_pinfo()
2335 if (mpath->flags & MESH_PATH_ACTIVE) in mpath_set_pinfo()
2336 pinfo->flags |= NL80211_MPATH_FLAG_ACTIVE; in mpath_set_pinfo()
2337 if (mpath->flags & MESH_PATH_RESOLVING) in mpath_set_pinfo()
2338 pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING; in mpath_set_pinfo()
2339 if (mpath->flags & MESH_PATH_SN_VALID) in mpath_set_pinfo()
2340 pinfo->flags |= NL80211_MPATH_FLAG_SN_VALID; in mpath_set_pinfo()
2341 if (mpath->flags & MESH_PATH_FIXED) in mpath_set_pinfo()
2342 pinfo->flags |= NL80211_MPATH_FLAG_FIXED; in mpath_set_pinfo()
2343 if (mpath->flags & MESH_PATH_RESOLVED) in mpath_set_pinfo()
2344 pinfo->flags |= NL80211_MPATH_FLAG_RESOLVED; in mpath_set_pinfo()
2345 pinfo->hop_count = mpath->hop_count; in mpath_set_pinfo()
2346 pinfo->path_change_count = mpath->path_change_count; in mpath_set_pinfo()
2354 struct mesh_path *mpath; in ieee80211_get_mpath() local
2359 mpath = mesh_path_lookup(sdata, dst); in ieee80211_get_mpath()
2360 if (!mpath) { in ieee80211_get_mpath()
2362 return -ENOENT; in ieee80211_get_mpath()
2364 memcpy(dst, mpath->dst, ETH_ALEN); in ieee80211_get_mpath()
2365 mpath_set_pinfo(mpath, next_hop, pinfo); in ieee80211_get_mpath()
2375 struct mesh_path *mpath; in ieee80211_dump_mpath() local
2380 mpath = mesh_path_lookup_by_idx(sdata, idx); in ieee80211_dump_mpath()
2381 if (!mpath) { in ieee80211_dump_mpath()
2383 return -ENOENT; in ieee80211_dump_mpath()
2385 memcpy(dst, mpath->dst, ETH_ALEN); in ieee80211_dump_mpath()
2386 mpath_set_pinfo(mpath, next_hop, pinfo); in ieee80211_dump_mpath()
2391 static void mpp_set_pinfo(struct mesh_path *mpath, u8 *mpp, in mpp_set_pinfo() argument
2395 memcpy(mpp, mpath->mpp, ETH_ALEN); in mpp_set_pinfo()
2397 pinfo->generation = mpath->sdata->u.mesh.mpp_paths_generation; in mpp_set_pinfo()
2405 struct mesh_path *mpath; in ieee80211_get_mpp() local
2410 mpath = mpp_path_lookup(sdata, dst); in ieee80211_get_mpp()
2411 if (!mpath) { in ieee80211_get_mpp()
2413 return -ENOENT; in ieee80211_get_mpp()
2415 memcpy(dst, mpath->dst, ETH_ALEN); in ieee80211_get_mpp()
2416 mpp_set_pinfo(mpath, mpp, pinfo); in ieee80211_get_mpp()
2426 struct mesh_path *mpath; in ieee80211_dump_mpp() local
2431 mpath = mpp_path_lookup_by_idx(sdata, idx); in ieee80211_dump_mpp()
2432 if (!mpath) { in ieee80211_dump_mpp()
2434 return -ENOENT; in ieee80211_dump_mpp()
2436 memcpy(dst, mpath->dst, ETH_ALEN); in ieee80211_dump_mpp()
2437 mpp_set_pinfo(mpath, mpp, pinfo); in ieee80211_dump_mpp()
2449 memcpy(conf, &(sdata->u.mesh.mshcfg), sizeof(struct mesh_config)); in ieee80211_get_mesh_config()
2455 return (mask >> (parm-1)) & 0x1; in _chg_mesh_attr()
2469 if (setup->ie_len) { in copy_mesh_setup()
2470 new_ie = kmemdup(setup->ie, setup->ie_len, in copy_mesh_setup()
2473 return -ENOMEM; in copy_mesh_setup()
2475 ifmsh->ie_len = setup->ie_len; in copy_mesh_setup()
2476 ifmsh->ie = new_ie; in copy_mesh_setup()
2479 ifmsh->mesh_id_len = setup->mesh_id_len; in copy_mesh_setup()
2480 memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len); in copy_mesh_setup()
2481 ifmsh->mesh_sp_id = setup->sync_method; in copy_mesh_setup()
2482 ifmsh->mesh_pp_id = setup->path_sel_proto; in copy_mesh_setup()
2483 ifmsh->mesh_pm_id = setup->path_metric; in copy_mesh_setup()
2484 ifmsh->user_mpm = setup->user_mpm; in copy_mesh_setup()
2485 ifmsh->mesh_auth_id = setup->auth_id; in copy_mesh_setup()
2486 ifmsh->security = IEEE80211_MESH_SEC_NONE; in copy_mesh_setup()
2487 ifmsh->userspace_handles_dfs = setup->userspace_handles_dfs; in copy_mesh_setup()
2488 if (setup->is_authenticated) in copy_mesh_setup()
2489 ifmsh->security |= IEEE80211_MESH_SEC_AUTHED; in copy_mesh_setup()
2490 if (setup->is_secure) in copy_mesh_setup()
2491 ifmsh->security |= IEEE80211_MESH_SEC_SECURED; in copy_mesh_setup()
2494 memcpy(sdata->vif.bss_conf.mcast_rate, setup->mcast_rate, in copy_mesh_setup()
2495 sizeof(setup->mcast_rate)); in copy_mesh_setup()
2496 sdata->vif.bss_conf.basic_rates = setup->basic_rates; in copy_mesh_setup()
2498 sdata->vif.bss_conf.beacon_int = setup->beacon_interval; in copy_mesh_setup()
2499 sdata->vif.bss_conf.dtim_period = setup->dtim_period; in copy_mesh_setup()
2501 sdata->beacon_rate_set = false; in copy_mesh_setup()
2502 if (wiphy_ext_feature_isset(sdata->local->hw.wiphy, in copy_mesh_setup()
2505 sdata->beacon_rateidx_mask[i] = in copy_mesh_setup()
2506 setup->beacon_rate.control[i].legacy; in copy_mesh_setup()
2507 if (sdata->beacon_rateidx_mask[i]) in copy_mesh_setup()
2508 sdata->beacon_rate_set = true; in copy_mesh_setup()
2524 ifmsh = &sdata->u.mesh; in ieee80211_update_mesh_config()
2527 conf = &(sdata->u.mesh.mshcfg); in ieee80211_update_mesh_config()
2529 conf->dot11MeshRetryTimeout = nconf->dot11MeshRetryTimeout; in ieee80211_update_mesh_config()
2531 conf->dot11MeshConfirmTimeout = nconf->dot11MeshConfirmTimeout; in ieee80211_update_mesh_config()
2533 conf->dot11MeshHoldingTimeout = nconf->dot11MeshHoldingTimeout; in ieee80211_update_mesh_config()
2535 conf->dot11MeshMaxPeerLinks = nconf->dot11MeshMaxPeerLinks; in ieee80211_update_mesh_config()
2537 conf->dot11MeshMaxRetries = nconf->dot11MeshMaxRetries; in ieee80211_update_mesh_config()
2539 conf->dot11MeshTTL = nconf->dot11MeshTTL; in ieee80211_update_mesh_config()
2541 conf->element_ttl = nconf->element_ttl; in ieee80211_update_mesh_config()
2543 if (ifmsh->user_mpm) in ieee80211_update_mesh_config()
2544 return -EBUSY; in ieee80211_update_mesh_config()
2545 conf->auto_open_plinks = nconf->auto_open_plinks; in ieee80211_update_mesh_config()
2548 conf->dot11MeshNbrOffsetMaxNeighbor = in ieee80211_update_mesh_config()
2549 nconf->dot11MeshNbrOffsetMaxNeighbor; in ieee80211_update_mesh_config()
2551 conf->dot11MeshHWMPmaxPREQretries = in ieee80211_update_mesh_config()
2552 nconf->dot11MeshHWMPmaxPREQretries; in ieee80211_update_mesh_config()
2554 conf->path_refresh_time = nconf->path_refresh_time; in ieee80211_update_mesh_config()
2556 conf->min_discovery_timeout = nconf->min_discovery_timeout; in ieee80211_update_mesh_config()
2558 conf->dot11MeshHWMPactivePathTimeout = in ieee80211_update_mesh_config()
2559 nconf->dot11MeshHWMPactivePathTimeout; in ieee80211_update_mesh_config()
2561 conf->dot11MeshHWMPpreqMinInterval = in ieee80211_update_mesh_config()
2562 nconf->dot11MeshHWMPpreqMinInterval; in ieee80211_update_mesh_config()
2564 conf->dot11MeshHWMPperrMinInterval = in ieee80211_update_mesh_config()
2565 nconf->dot11MeshHWMPperrMinInterval; in ieee80211_update_mesh_config()
2568 conf->dot11MeshHWMPnetDiameterTraversalTime = in ieee80211_update_mesh_config()
2569 nconf->dot11MeshHWMPnetDiameterTraversalTime; in ieee80211_update_mesh_config()
2571 conf->dot11MeshHWMPRootMode = nconf->dot11MeshHWMPRootMode; in ieee80211_update_mesh_config()
2578 if (nconf->dot11MeshGateAnnouncementProtocol && in ieee80211_update_mesh_config()
2579 !(conf->dot11MeshHWMPRootMode > IEEE80211_ROOTMODE_ROOT)) { in ieee80211_update_mesh_config()
2580 conf->dot11MeshHWMPRootMode = IEEE80211_PROACTIVE_RANN; in ieee80211_update_mesh_config()
2583 conf->dot11MeshGateAnnouncementProtocol = in ieee80211_update_mesh_config()
2584 nconf->dot11MeshGateAnnouncementProtocol; in ieee80211_update_mesh_config()
2587 conf->dot11MeshHWMPRannInterval = in ieee80211_update_mesh_config()
2588 nconf->dot11MeshHWMPRannInterval; in ieee80211_update_mesh_config()
2590 conf->dot11MeshForwarding = nconf->dot11MeshForwarding; in ieee80211_update_mesh_config()
2595 if (!ieee80211_hw_check(&sdata->local->hw, SIGNAL_DBM)) in ieee80211_update_mesh_config()
2596 return -ENOTSUPP; in ieee80211_update_mesh_config()
2597 conf->rssi_threshold = nconf->rssi_threshold; in ieee80211_update_mesh_config()
2600 conf->ht_opmode = nconf->ht_opmode; in ieee80211_update_mesh_config()
2601 sdata->vif.bss_conf.ht_operation_mode = nconf->ht_opmode; in ieee80211_update_mesh_config()
2602 ieee80211_link_info_change_notify(sdata, &sdata->deflink, in ieee80211_update_mesh_config()
2606 conf->dot11MeshHWMPactivePathToRootTimeout = in ieee80211_update_mesh_config()
2607 nconf->dot11MeshHWMPactivePathToRootTimeout; in ieee80211_update_mesh_config()
2609 conf->dot11MeshHWMProotInterval = in ieee80211_update_mesh_config()
2610 nconf->dot11MeshHWMProotInterval; in ieee80211_update_mesh_config()
2612 conf->dot11MeshHWMPconfirmationInterval = in ieee80211_update_mesh_config()
2613 nconf->dot11MeshHWMPconfirmationInterval; in ieee80211_update_mesh_config()
2615 conf->power_mode = nconf->power_mode; in ieee80211_update_mesh_config()
2619 conf->dot11MeshAwakeWindowDuration = in ieee80211_update_mesh_config()
2620 nconf->dot11MeshAwakeWindowDuration; in ieee80211_update_mesh_config()
2622 conf->plink_timeout = nconf->plink_timeout; in ieee80211_update_mesh_config()
2624 conf->dot11MeshConnectedToMeshGate = in ieee80211_update_mesh_config()
2625 nconf->dot11MeshConnectedToMeshGate; in ieee80211_update_mesh_config()
2627 conf->dot11MeshNolearn = nconf->dot11MeshNolearn; in ieee80211_update_mesh_config()
2629 conf->dot11MeshConnectedToAuthServer = in ieee80211_update_mesh_config()
2630 nconf->dot11MeshConnectedToAuthServer; in ieee80211_update_mesh_config()
2640 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; in ieee80211_join_mesh()
2643 memcpy(&ifmsh->mshcfg, conf, sizeof(struct mesh_config)); in ieee80211_join_mesh()
2648 sdata->control_port_over_nl80211 = setup->control_port_over_nl80211; in ieee80211_join_mesh()
2651 sdata->deflink.smps_mode = IEEE80211_SMPS_OFF; in ieee80211_join_mesh()
2652 sdata->deflink.needed_rx_chains = sdata->local->rx_chains; in ieee80211_join_mesh()
2654 mutex_lock(&sdata->local->mtx); in ieee80211_join_mesh()
2655 err = ieee80211_link_use_channel(&sdata->deflink, &setup->chandef, in ieee80211_join_mesh()
2657 mutex_unlock(&sdata->local->mtx); in ieee80211_join_mesh()
2669 mutex_lock(&sdata->local->mtx); in ieee80211_leave_mesh()
2670 ieee80211_link_release_channel(&sdata->deflink); in ieee80211_leave_mesh()
2671 kfree(sdata->u.mesh.ie); in ieee80211_leave_mesh()
2672 mutex_unlock(&sdata->local->mtx); in ieee80211_leave_mesh()
2687 link = ieee80211_link_or_deflink(sdata, params->link_id, true); in ieee80211_change_bss()
2691 if (!sdata_dereference(link->u.ap.beacon, sdata)) in ieee80211_change_bss()
2692 return -ENOENT; in ieee80211_change_bss()
2696 return -EINVAL; in ieee80211_change_bss()
2698 if (params->basic_rates) { in ieee80211_change_bss()
2699 if (!ieee80211_parse_bitrates(link->conf->chandef.width, in ieee80211_change_bss()
2700 wiphy->bands[sband->band], in ieee80211_change_bss()
2701 params->basic_rates, in ieee80211_change_bss()
2702 params->basic_rates_len, in ieee80211_change_bss()
2703 &link->conf->basic_rates)) in ieee80211_change_bss()
2704 return -EINVAL; in ieee80211_change_bss()
2709 if (params->use_cts_prot >= 0) { in ieee80211_change_bss()
2710 link->conf->use_cts_prot = params->use_cts_prot; in ieee80211_change_bss()
2713 if (params->use_short_preamble >= 0) { in ieee80211_change_bss()
2714 link->conf->use_short_preamble = params->use_short_preamble; in ieee80211_change_bss()
2718 if (!link->conf->use_short_slot && in ieee80211_change_bss()
2719 (sband->band == NL80211_BAND_5GHZ || in ieee80211_change_bss()
2720 sband->band == NL80211_BAND_6GHZ)) { in ieee80211_change_bss()
2721 link->conf->use_short_slot = true; in ieee80211_change_bss()
2725 if (params->use_short_slot_time >= 0) { in ieee80211_change_bss()
2726 link->conf->use_short_slot = params->use_short_slot_time; in ieee80211_change_bss()
2730 if (params->ap_isolate >= 0) { in ieee80211_change_bss()
2731 if (params->ap_isolate) in ieee80211_change_bss()
2732 sdata->flags |= IEEE80211_SDATA_DONT_BRIDGE_PACKETS; in ieee80211_change_bss()
2734 sdata->flags &= ~IEEE80211_SDATA_DONT_BRIDGE_PACKETS; in ieee80211_change_bss()
2738 if (params->ht_opmode >= 0) { in ieee80211_change_bss()
2739 link->conf->ht_operation_mode = (u16)params->ht_opmode; in ieee80211_change_bss()
2743 if (params->p2p_ctwindow >= 0) { in ieee80211_change_bss()
2744 link->conf->p2p_noa_attr.oppps_ctwindow &= in ieee80211_change_bss()
2746 link->conf->p2p_noa_attr.oppps_ctwindow |= in ieee80211_change_bss()
2747 params->p2p_ctwindow & IEEE80211_P2P_OPPPS_CTWINDOW_MASK; in ieee80211_change_bss()
2751 if (params->p2p_opp_ps > 0) { in ieee80211_change_bss()
2752 link->conf->p2p_noa_attr.oppps_ctwindow |= in ieee80211_change_bss()
2755 } else if (params->p2p_opp_ps == 0) { in ieee80211_change_bss()
2756 link->conf->p2p_noa_attr.oppps_ctwindow &= in ieee80211_change_bss()
2773 ieee80211_link_or_deflink(sdata, params->link_id, true); in ieee80211_set_txq_params()
2776 if (!local->ops->conf_tx) in ieee80211_set_txq_params()
2777 return -EOPNOTSUPP; in ieee80211_set_txq_params()
2779 if (local->hw.queues < IEEE80211_NUM_ACS) in ieee80211_set_txq_params()
2780 return -EOPNOTSUPP; in ieee80211_set_txq_params()
2786 p.aifs = params->aifs; in ieee80211_set_txq_params()
2787 p.cw_max = params->cwmax; in ieee80211_set_txq_params()
2788 p.cw_min = params->cwmin; in ieee80211_set_txq_params()
2789 p.txop = params->txop; in ieee80211_set_txq_params()
2792 * Setting tx queue params disables u-apsd because it's only in ieee80211_set_txq_params()
2797 ieee80211_regulatory_limit_wmm_params(sdata, &p, params->ac); in ieee80211_set_txq_params()
2799 link->tx_conf[params->ac] = p; in ieee80211_set_txq_params()
2800 if (drv_conf_tx(local, link, params->ac, &p)) { in ieee80211_set_txq_params()
2801 wiphy_debug(local->hw.wiphy, in ieee80211_set_txq_params()
2803 params->ac); in ieee80211_set_txq_params()
2804 return -EINVAL; in ieee80211_set_txq_params()
2834 sdata = IEEE80211_WDEV_TO_SUB_IF(req->wdev); in ieee80211_scan()
2836 switch (ieee80211_vif_type_p2p(&sdata->vif)) { in ieee80211_scan()
2844 if (sdata->local->ops->hw_scan) in ieee80211_scan()
2860 if (sdata->deflink.u.ap.beacon && in ieee80211_scan()
2861 (!(wiphy->features & NL80211_FEATURE_AP_SCAN) || in ieee80211_scan()
2862 !(req->flags & NL80211_SCAN_FLAG_AP))) in ieee80211_scan()
2863 return -EOPNOTSUPP; in ieee80211_scan()
2867 return -EOPNOTSUPP; in ieee80211_scan()
2885 if (!sdata->local->ops->sched_scan_start) in ieee80211_sched_scan_start()
2886 return -EOPNOTSUPP; in ieee80211_sched_scan_start()
2897 if (!local->ops->sched_scan_stop) in ieee80211_sched_scan_stop()
2898 return -EOPNOTSUPP; in ieee80211_sched_scan_stop()
2954 memcpy(sdata->vif.bss_conf.mcast_rate, rate, in ieee80211_set_mcast_rate()
2958 ieee80211_link_info_change_notify(sdata, &sdata->deflink, in ieee80211_set_mcast_rate()
2972 err = drv_set_frag_threshold(local, wiphy->frag_threshold); in ieee80211_set_wiphy_params()
2985 wiphy->coverage_class : -1; in ieee80211_set_wiphy_params()
2993 err = drv_set_rts_threshold(local, wiphy->rts_threshold); in ieee80211_set_wiphy_params()
3000 if (wiphy->retry_short > IEEE80211_MAX_TX_RETRY) in ieee80211_set_wiphy_params()
3001 return -EINVAL; in ieee80211_set_wiphy_params()
3002 local->hw.conf.short_frame_max_tx_count = wiphy->retry_short; in ieee80211_set_wiphy_params()
3005 if (wiphy->retry_long > IEEE80211_MAX_TX_RETRY) in ieee80211_set_wiphy_params()
3006 return -EINVAL; in ieee80211_set_wiphy_params()
3007 local->hw.conf.long_frame_max_tx_count = wiphy->retry_long; in ieee80211_set_wiphy_params()
3034 if (sdata->vif.type == NL80211_IFTYPE_MONITOR) { in ieee80211_set_tx_power()
3035 sdata = wiphy_dereference(local->hw.wiphy, in ieee80211_set_tx_power()
3036 local->monitor_sdata); in ieee80211_set_tx_power()
3038 return -EOPNOTSUPP; in ieee80211_set_tx_power()
3043 sdata->deflink.user_power_level = in ieee80211_set_tx_power()
3050 return -EOPNOTSUPP; in ieee80211_set_tx_power()
3051 sdata->deflink.user_power_level = MBM_TO_DBM(mbm); in ieee80211_set_tx_power()
3055 if (txp_type != sdata->vif.bss_conf.txpower_type) { in ieee80211_set_tx_power()
3057 sdata->vif.bss_conf.txpower_type = txp_type; in ieee80211_set_tx_power()
3067 local->user_power_level = IEEE80211_UNSET_POWER_LEVEL; in ieee80211_set_tx_power()
3073 return -EOPNOTSUPP; in ieee80211_set_tx_power()
3074 local->user_power_level = MBM_TO_DBM(mbm); in ieee80211_set_tx_power()
3078 mutex_lock(&local->iflist_mtx); in ieee80211_set_tx_power()
3079 list_for_each_entry(sdata, &local->interfaces, list) { in ieee80211_set_tx_power()
3080 if (sdata->vif.type == NL80211_IFTYPE_MONITOR) { in ieee80211_set_tx_power()
3084 sdata->deflink.user_power_level = local->user_power_level; in ieee80211_set_tx_power()
3085 if (txp_type != sdata->vif.bss_conf.txpower_type) in ieee80211_set_tx_power()
3087 sdata->vif.bss_conf.txpower_type = txp_type; in ieee80211_set_tx_power()
3089 list_for_each_entry(sdata, &local->interfaces, list) { in ieee80211_set_tx_power()
3090 if (sdata->vif.type == NL80211_IFTYPE_MONITOR) in ieee80211_set_tx_power()
3094 mutex_unlock(&local->iflist_mtx); in ieee80211_set_tx_power()
3097 sdata = wiphy_dereference(local->hw.wiphy, in ieee80211_set_tx_power()
3098 local->monitor_sdata); in ieee80211_set_tx_power()
3100 sdata->deflink.user_power_level = local->user_power_level; in ieee80211_set_tx_power()
3101 if (txp_type != sdata->vif.bss_conf.txpower_type) in ieee80211_set_tx_power()
3103 sdata->vif.bss_conf.txpower_type = txp_type; in ieee80211_set_tx_power()
3119 if (local->ops->get_txpower && in ieee80211_get_tx_power()
3120 (sdata->flags & IEEE80211_SDATA_IN_DRIVER)) in ieee80211_get_tx_power()
3123 if (!local->use_chanctx) in ieee80211_get_tx_power()
3124 *dbm = local->hw.conf.power_level; in ieee80211_get_tx_power()
3126 *dbm = sdata->vif.bss_conf.txpower; in ieee80211_get_tx_power()
3130 return -EINVAL; in ieee80211_get_tx_power()
3150 if (!local->ops->testmode_cmd) in ieee80211_testmode_cmd()
3151 return -EOPNOTSUPP; in ieee80211_testmode_cmd()
3157 if (sdata->flags & IEEE80211_SDATA_IN_DRIVER) in ieee80211_testmode_cmd()
3158 vif = &sdata->vif; in ieee80211_testmode_cmd()
3161 return local->ops->testmode_cmd(&local->hw, vif, data, len); in ieee80211_testmode_cmd()
3171 if (!local->ops->testmode_dump) in ieee80211_testmode_dump()
3172 return -EOPNOTSUPP; in ieee80211_testmode_dump()
3174 return local->ops->testmode_dump(&local->hw, skb, cb, data, len); in ieee80211_testmode_dump()
3188 lockdep_assert_held(&sdata->wdev.mtx); in __ieee80211_request_smps_mgd()
3190 if (WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION)) in __ieee80211_request_smps_mgd()
3191 return -EINVAL; in __ieee80211_request_smps_mgd()
3193 old_req = link->u.mgd.req_smps; in __ieee80211_request_smps_mgd()
3194 link->u.mgd.req_smps = smps_mode; in __ieee80211_request_smps_mgd()
3205 if (!sdata->u.mgd.associated || in __ieee80211_request_smps_mgd()
3206 link->conf->chandef.width == NL80211_CHAN_WIDTH_20_NOHT) in __ieee80211_request_smps_mgd()
3209 ap = link->u.mgd.bssid; in __ieee80211_request_smps_mgd()
3212 list_for_each_entry_rcu(sta, &sdata->local->sta_list, list) { in __ieee80211_request_smps_mgd()
3213 if (!sta->sta.tdls || sta->sdata != sdata || !sta->uploaded || in __ieee80211_request_smps_mgd()
3223 if (tdls_peer_found || !sdata->u.mgd.powersave) in __ieee80211_request_smps_mgd()
3233 link->u.mgd.req_smps = old_req; in __ieee80211_request_smps_mgd()
3244 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); in ieee80211_set_power_mgmt()
3247 if (sdata->vif.type != NL80211_IFTYPE_STATION) in ieee80211_set_power_mgmt()
3248 return -EOPNOTSUPP; in ieee80211_set_power_mgmt()
3250 if (!ieee80211_hw_check(&local->hw, SUPPORTS_PS)) in ieee80211_set_power_mgmt()
3251 return -EOPNOTSUPP; in ieee80211_set_power_mgmt()
3253 if (enabled == sdata->u.mgd.powersave && in ieee80211_set_power_mgmt()
3254 timeout == local->dynamic_ps_forced_timeout) in ieee80211_set_power_mgmt()
3257 sdata->u.mgd.powersave = enabled; in ieee80211_set_power_mgmt()
3258 local->dynamic_ps_forced_timeout = timeout; in ieee80211_set_power_mgmt()
3262 for (link_id = 0; link_id < ARRAY_SIZE(sdata->link); link_id++) { in ieee80211_set_power_mgmt()
3265 link = sdata_dereference(sdata->link[link_id], sdata); in ieee80211_set_power_mgmt()
3270 link->u.mgd.req_smps); in ieee80211_set_power_mgmt()
3274 if (ieee80211_hw_check(&local->hw, SUPPORTS_DYNAMIC_PS)) in ieee80211_set_power_mgmt()
3289 struct ieee80211_vif *vif = &sdata->vif; in ieee80211_set_cqm_rssi_config()
3290 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; in ieee80211_set_cqm_rssi_config()
3292 if (rssi_thold == bss_conf->cqm_rssi_thold && in ieee80211_set_cqm_rssi_config()
3293 rssi_hyst == bss_conf->cqm_rssi_hyst) in ieee80211_set_cqm_rssi_config()
3296 if (sdata->vif.driver_flags & IEEE80211_VIF_BEACON_FILTER && in ieee80211_set_cqm_rssi_config()
3297 !(sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI)) in ieee80211_set_cqm_rssi_config()
3298 return -EOPNOTSUPP; in ieee80211_set_cqm_rssi_config()
3300 bss_conf->cqm_rssi_thold = rssi_thold; in ieee80211_set_cqm_rssi_config()
3301 bss_conf->cqm_rssi_hyst = rssi_hyst; in ieee80211_set_cqm_rssi_config()
3302 bss_conf->cqm_rssi_low = 0; in ieee80211_set_cqm_rssi_config()
3303 bss_conf->cqm_rssi_high = 0; in ieee80211_set_cqm_rssi_config()
3304 sdata->deflink.u.mgd.last_cqm_event_signal = 0; in ieee80211_set_cqm_rssi_config()
3307 if (sdata->u.mgd.associated && in ieee80211_set_cqm_rssi_config()
3308 sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI) in ieee80211_set_cqm_rssi_config()
3309 ieee80211_link_info_change_notify(sdata, &sdata->deflink, in ieee80211_set_cqm_rssi_config()
3320 struct ieee80211_vif *vif = &sdata->vif; in ieee80211_set_cqm_rssi_range_config()
3321 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; in ieee80211_set_cqm_rssi_range_config()
3323 if (sdata->vif.driver_flags & IEEE80211_VIF_BEACON_FILTER) in ieee80211_set_cqm_rssi_range_config()
3324 return -EOPNOTSUPP; in ieee80211_set_cqm_rssi_range_config()
3326 bss_conf->cqm_rssi_low = rssi_low; in ieee80211_set_cqm_rssi_range_config()
3327 bss_conf->cqm_rssi_high = rssi_high; in ieee80211_set_cqm_rssi_range_config()
3328 bss_conf->cqm_rssi_thold = 0; in ieee80211_set_cqm_rssi_range_config()
3329 bss_conf->cqm_rssi_hyst = 0; in ieee80211_set_cqm_rssi_range_config()
3330 sdata->deflink.u.mgd.last_cqm_event_signal = 0; in ieee80211_set_cqm_rssi_range_config()
3333 if (sdata->u.mgd.associated && in ieee80211_set_cqm_rssi_range_config()
3334 sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI) in ieee80211_set_cqm_rssi_range_config()
3335 ieee80211_link_info_change_notify(sdata, &sdata->deflink, in ieee80211_set_cqm_rssi_range_config()
3348 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); in ieee80211_set_bitrate_mask()
3352 return -ENETDOWN; in ieee80211_set_bitrate_mask()
3360 if (rcu_access_pointer(sdata->vif.bss_conf.chanctx_conf) && in ieee80211_set_bitrate_mask()
3361 sdata->vif.bss_conf.chandef.chan) { in ieee80211_set_bitrate_mask()
3362 u32 basic_rates = sdata->vif.bss_conf.basic_rates; in ieee80211_set_bitrate_mask()
3363 enum nl80211_band band = sdata->vif.bss_conf.chandef.chan->band; in ieee80211_set_bitrate_mask()
3365 if (!(mask->control[band].legacy & basic_rates)) in ieee80211_set_bitrate_mask()
3366 return -EINVAL; in ieee80211_set_bitrate_mask()
3369 if (ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL)) { in ieee80211_set_bitrate_mask()
3376 struct ieee80211_supported_band *sband = wiphy->bands[i]; in ieee80211_set_bitrate_mask()
3379 sdata->rc_rateidx_mask[i] = mask->control[i].legacy; in ieee80211_set_bitrate_mask()
3380 memcpy(sdata->rc_rateidx_mcs_mask[i], mask->control[i].ht_mcs, in ieee80211_set_bitrate_mask()
3381 sizeof(mask->control[i].ht_mcs)); in ieee80211_set_bitrate_mask()
3382 memcpy(sdata->rc_rateidx_vht_mcs_mask[i], in ieee80211_set_bitrate_mask()
3383 mask->control[i].vht_mcs, in ieee80211_set_bitrate_mask()
3384 sizeof(mask->control[i].vht_mcs)); in ieee80211_set_bitrate_mask()
3386 sdata->rc_has_mcs_mask[i] = false; in ieee80211_set_bitrate_mask()
3387 sdata->rc_has_vht_mcs_mask[i] = false; in ieee80211_set_bitrate_mask()
3392 if (sdata->rc_rateidx_mcs_mask[i][j] != 0xff) { in ieee80211_set_bitrate_mask()
3393 sdata->rc_has_mcs_mask[i] = true; in ieee80211_set_bitrate_mask()
3399 if (sdata->rc_rateidx_vht_mcs_mask[i][j] != 0xffff) { in ieee80211_set_bitrate_mask()
3400 sdata->rc_has_vht_mcs_mask[i] = true; in ieee80211_set_bitrate_mask()
3415 struct ieee80211_local *local = sdata->local; in ieee80211_start_radar_detection()
3418 mutex_lock(&local->mtx); in ieee80211_start_radar_detection()
3419 if (!list_empty(&local->roc_list) || local->scanning) { in ieee80211_start_radar_detection()
3420 err = -EBUSY; in ieee80211_start_radar_detection()
3425 sdata->deflink.smps_mode = IEEE80211_SMPS_OFF; in ieee80211_start_radar_detection()
3426 sdata->deflink.needed_rx_chains = local->rx_chains; in ieee80211_start_radar_detection()
3428 err = ieee80211_link_use_channel(&sdata->deflink, chandef, in ieee80211_start_radar_detection()
3433 ieee80211_queue_delayed_work(&sdata->local->hw, in ieee80211_start_radar_detection()
3434 &sdata->deflink.dfs_cac_timer_work, in ieee80211_start_radar_detection()
3438 mutex_unlock(&local->mtx); in ieee80211_start_radar_detection()
3446 struct ieee80211_local *local = sdata->local; in ieee80211_end_cac()
3448 mutex_lock(&local->mtx); in ieee80211_end_cac()
3449 list_for_each_entry(sdata, &local->interfaces, list) { in ieee80211_end_cac()
3450 /* it might be waiting for the local->mtx, but then in ieee80211_end_cac()
3451 * by the time it gets it, sdata->wdev.cac_started in ieee80211_end_cac()
3454 cancel_delayed_work(&sdata->deflink.dfs_cac_timer_work); in ieee80211_end_cac()
3456 if (sdata->wdev.cac_started) { in ieee80211_end_cac()
3457 ieee80211_link_release_channel(&sdata->deflink); in ieee80211_end_cac()
3458 sdata->wdev.cac_started = false; in ieee80211_end_cac()
3461 mutex_unlock(&local->mtx); in ieee80211_end_cac()
3471 len = beacon->head_len + beacon->tail_len + beacon->beacon_ies_len + in cfg80211_beacon_dup()
3472 beacon->proberesp_ies_len + beacon->assocresp_ies_len + in cfg80211_beacon_dup()
3473 beacon->probe_resp_len + beacon->lci_len + beacon->civicloc_len; in cfg80211_beacon_dup()
3475 if (beacon->mbssid_ies) in cfg80211_beacon_dup()
3476 len += ieee80211_get_mbssid_beacon_len(beacon->mbssid_ies, in cfg80211_beacon_dup()
3477 beacon->rnr_ies, in cfg80211_beacon_dup()
3478 beacon->mbssid_ies->cnt); in cfg80211_beacon_dup()
3484 if (beacon->mbssid_ies && beacon->mbssid_ies->cnt) { in cfg80211_beacon_dup()
3485 new_beacon->mbssid_ies = in cfg80211_beacon_dup()
3486 kzalloc(struct_size(new_beacon->mbssid_ies, in cfg80211_beacon_dup()
3487 elem, beacon->mbssid_ies->cnt), in cfg80211_beacon_dup()
3489 if (!new_beacon->mbssid_ies) { in cfg80211_beacon_dup()
3494 if (beacon->rnr_ies && beacon->rnr_ies->cnt) { in cfg80211_beacon_dup()
3495 new_beacon->rnr_ies = in cfg80211_beacon_dup()
3496 kzalloc(struct_size(new_beacon->rnr_ies, in cfg80211_beacon_dup()
3497 elem, beacon->rnr_ies->cnt), in cfg80211_beacon_dup()
3499 if (!new_beacon->rnr_ies) { in cfg80211_beacon_dup()
3500 kfree(new_beacon->mbssid_ies); in cfg80211_beacon_dup()
3508 if (beacon->head_len) { in cfg80211_beacon_dup()
3509 new_beacon->head_len = beacon->head_len; in cfg80211_beacon_dup()
3510 new_beacon->head = pos; in cfg80211_beacon_dup()
3511 memcpy(pos, beacon->head, beacon->head_len); in cfg80211_beacon_dup()
3512 pos += beacon->head_len; in cfg80211_beacon_dup()
3514 if (beacon->tail_len) { in cfg80211_beacon_dup()
3515 new_beacon->tail_len = beacon->tail_len; in cfg80211_beacon_dup()
3516 new_beacon->tail = pos; in cfg80211_beacon_dup()
3517 memcpy(pos, beacon->tail, beacon->tail_len); in cfg80211_beacon_dup()
3518 pos += beacon->tail_len; in cfg80211_beacon_dup()
3520 if (beacon->beacon_ies_len) { in cfg80211_beacon_dup()
3521 new_beacon->beacon_ies_len = beacon->beacon_ies_len; in cfg80211_beacon_dup()
3522 new_beacon->beacon_ies = pos; in cfg80211_beacon_dup()
3523 memcpy(pos, beacon->beacon_ies, beacon->beacon_ies_len); in cfg80211_beacon_dup()
3524 pos += beacon->beacon_ies_len; in cfg80211_beacon_dup()
3526 if (beacon->proberesp_ies_len) { in cfg80211_beacon_dup()
3527 new_beacon->proberesp_ies_len = beacon->proberesp_ies_len; in cfg80211_beacon_dup()
3528 new_beacon->proberesp_ies = pos; in cfg80211_beacon_dup()
3529 memcpy(pos, beacon->proberesp_ies, beacon->proberesp_ies_len); in cfg80211_beacon_dup()
3530 pos += beacon->proberesp_ies_len; in cfg80211_beacon_dup()
3532 if (beacon->assocresp_ies_len) { in cfg80211_beacon_dup()
3533 new_beacon->assocresp_ies_len = beacon->assocresp_ies_len; in cfg80211_beacon_dup()
3534 new_beacon->assocresp_ies = pos; in cfg80211_beacon_dup()
3535 memcpy(pos, beacon->assocresp_ies, beacon->assocresp_ies_len); in cfg80211_beacon_dup()
3536 pos += beacon->assocresp_ies_len; in cfg80211_beacon_dup()
3538 if (beacon->probe_resp_len) { in cfg80211_beacon_dup()
3539 new_beacon->probe_resp_len = beacon->probe_resp_len; in cfg80211_beacon_dup()
3540 new_beacon->probe_resp = pos; in cfg80211_beacon_dup()
3541 memcpy(pos, beacon->probe_resp, beacon->probe_resp_len); in cfg80211_beacon_dup()
3542 pos += beacon->probe_resp_len; in cfg80211_beacon_dup()
3544 if (beacon->mbssid_ies && beacon->mbssid_ies->cnt) { in cfg80211_beacon_dup()
3546 new_beacon->mbssid_ies, in cfg80211_beacon_dup()
3547 beacon->mbssid_ies); in cfg80211_beacon_dup()
3548 if (beacon->rnr_ies && beacon->rnr_ies->cnt) in cfg80211_beacon_dup()
3550 new_beacon->rnr_ies, in cfg80211_beacon_dup()
3551 beacon->rnr_ies); in cfg80211_beacon_dup()
3554 /* might copy -1, meaning no changes requested */ in cfg80211_beacon_dup()
3555 new_beacon->ftm_responder = beacon->ftm_responder; in cfg80211_beacon_dup()
3556 if (beacon->lci) { in cfg80211_beacon_dup()
3557 new_beacon->lci_len = beacon->lci_len; in cfg80211_beacon_dup()
3558 new_beacon->lci = pos; in cfg80211_beacon_dup()
3559 memcpy(pos, beacon->lci, beacon->lci_len); in cfg80211_beacon_dup()
3560 pos += beacon->lci_len; in cfg80211_beacon_dup()
3562 if (beacon->civicloc) { in cfg80211_beacon_dup()
3563 new_beacon->civicloc_len = beacon->civicloc_len; in cfg80211_beacon_dup()
3564 new_beacon->civicloc = pos; in cfg80211_beacon_dup()
3565 memcpy(pos, beacon->civicloc, beacon->civicloc_len); in cfg80211_beacon_dup()
3566 pos += beacon->civicloc_len; in cfg80211_beacon_dup()
3575 struct ieee80211_local *local = sdata->local; in ieee80211_csa_finish()
3579 if (vif->mbssid_tx_vif == vif) { in ieee80211_csa_finish()
3580 /* Trigger ieee80211_csa_finish() on the non-transmitting in ieee80211_csa_finish()
3586 list_for_each_entry_rcu(iter, &local->interfaces, list) { in ieee80211_csa_finish()
3590 if (iter == sdata || iter->vif.mbssid_tx_vif != vif) in ieee80211_csa_finish()
3593 ieee80211_queue_work(&iter->local->hw, in ieee80211_csa_finish()
3594 &iter->deflink.csa_finalize_work); in ieee80211_csa_finish()
3597 ieee80211_queue_work(&local->hw, &sdata->deflink.csa_finalize_work); in ieee80211_csa_finish()
3606 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; in ieee80211_channel_switch_disconnect()
3607 struct ieee80211_local *local = sdata->local; in ieee80211_channel_switch_disconnect()
3609 sdata->deflink.csa_block_tx = block_tx; in ieee80211_channel_switch_disconnect()
3611 wiphy_work_queue(local->hw.wiphy, &ifmgd->csa_connection_drop_work); in ieee80211_channel_switch_disconnect()
3620 switch (sdata->vif.type) { in ieee80211_set_after_csa_beacon()
3622 if (!sdata->deflink.u.ap.next_beacon) in ieee80211_set_after_csa_beacon()
3623 return -EINVAL; in ieee80211_set_after_csa_beacon()
3625 err = ieee80211_assign_beacon(sdata, &sdata->deflink, in ieee80211_set_after_csa_beacon()
3626 sdata->deflink.u.ap.next_beacon, in ieee80211_set_after_csa_beacon()
3628 ieee80211_free_next_beacon(&sdata->deflink); in ieee80211_set_after_csa_beacon()
3647 return -EINVAL; in ieee80211_set_after_csa_beacon()
3655 struct ieee80211_local *local = sdata->local; in __ieee80211_csa_finalize()
3660 lockdep_assert_held(&local->mtx); in __ieee80211_csa_finalize()
3661 lockdep_assert_held(&local->chanctx_mtx); in __ieee80211_csa_finalize()
3665 * with multi-vif. once reservation is complete it will re-schedule the in __ieee80211_csa_finalize()
3670 if (sdata->deflink.reserved_chanctx) { in __ieee80211_csa_finalize()
3672 * with multi-vif csa driver may call ieee80211_csa_finish() in __ieee80211_csa_finalize()
3676 if (sdata->deflink.reserved_ready) in __ieee80211_csa_finalize()
3679 return ieee80211_link_use_reserved_context(&sdata->deflink); in __ieee80211_csa_finalize()
3682 if (!cfg80211_chandef_identical(&sdata->vif.bss_conf.chandef, in __ieee80211_csa_finalize()
3683 &sdata->deflink.csa_chandef)) in __ieee80211_csa_finalize()
3684 return -EINVAL; in __ieee80211_csa_finalize()
3686 sdata->vif.bss_conf.csa_active = false; in __ieee80211_csa_finalize()
3692 if (sdata->vif.bss_conf.eht_puncturing != sdata->vif.bss_conf.csa_punct_bitmap) { in __ieee80211_csa_finalize()
3693 sdata->vif.bss_conf.eht_puncturing = in __ieee80211_csa_finalize()
3694 sdata->vif.bss_conf.csa_punct_bitmap; in __ieee80211_csa_finalize()
3698 ieee80211_link_info_change_notify(sdata, &sdata->deflink, changed); in __ieee80211_csa_finalize()
3700 if (sdata->deflink.csa_block_tx) { in __ieee80211_csa_finalize()
3703 sdata->deflink.csa_block_tx = false; in __ieee80211_csa_finalize()
3710 cfg80211_ch_switch_notify(sdata->dev, &sdata->deflink.csa_chandef, 0, in __ieee80211_csa_finalize()
3711 sdata->vif.bss_conf.eht_puncturing); in __ieee80211_csa_finalize()
3720 cfg80211_stop_iface(sdata->local->hw.wiphy, &sdata->wdev, in ieee80211_csa_finalize()
3730 struct ieee80211_local *local = sdata->local; in ieee80211_csa_finalize_work()
3733 mutex_lock(&local->mtx); in ieee80211_csa_finalize_work()
3734 mutex_lock(&local->chanctx_mtx); in ieee80211_csa_finalize_work()
3737 if (!sdata->vif.bss_conf.csa_active) in ieee80211_csa_finalize_work()
3746 mutex_unlock(&local->chanctx_mtx); in ieee80211_csa_finalize_work()
3747 mutex_unlock(&local->mtx); in ieee80211_csa_finalize_work()
3758 switch (sdata->vif.type) { in ieee80211_set_csa_beacon()
3760 sdata->deflink.u.ap.next_beacon = in ieee80211_set_csa_beacon()
3761 cfg80211_beacon_dup(&params->beacon_after); in ieee80211_set_csa_beacon()
3762 if (!sdata->deflink.u.ap.next_beacon) in ieee80211_set_csa_beacon()
3763 return -ENOMEM; in ieee80211_set_csa_beacon()
3781 if (params->count <= 1) in ieee80211_set_csa_beacon()
3784 if ((params->n_counter_offsets_beacon > in ieee80211_set_csa_beacon()
3786 (params->n_counter_offsets_presp > in ieee80211_set_csa_beacon()
3788 ieee80211_free_next_beacon(&sdata->deflink); in ieee80211_set_csa_beacon()
3789 return -EINVAL; in ieee80211_set_csa_beacon()
3792 csa.counter_offsets_beacon = params->counter_offsets_beacon; in ieee80211_set_csa_beacon()
3793 csa.counter_offsets_presp = params->counter_offsets_presp; in ieee80211_set_csa_beacon()
3794 csa.n_counter_offsets_beacon = params->n_counter_offsets_beacon; in ieee80211_set_csa_beacon()
3795 csa.n_counter_offsets_presp = params->n_counter_offsets_presp; in ieee80211_set_csa_beacon()
3796 csa.count = params->count; in ieee80211_set_csa_beacon()
3798 err = ieee80211_assign_beacon(sdata, &sdata->deflink, in ieee80211_set_csa_beacon()
3799 &params->beacon_csa, &csa, in ieee80211_set_csa_beacon()
3802 ieee80211_free_next_beacon(&sdata->deflink); in ieee80211_set_csa_beacon()
3808 if (!sdata->vif.cfg.ibss_joined) in ieee80211_set_csa_beacon()
3809 return -EINVAL; in ieee80211_set_csa_beacon()
3811 if (params->chandef.width != sdata->u.ibss.chandef.width) in ieee80211_set_csa_beacon()
3812 return -EINVAL; in ieee80211_set_csa_beacon()
3814 switch (params->chandef.width) { in ieee80211_set_csa_beacon()
3816 if (cfg80211_get_chandef_type(&params->chandef) != in ieee80211_set_csa_beacon()
3817 cfg80211_get_chandef_type(&sdata->u.ibss.chandef)) in ieee80211_set_csa_beacon()
3818 return -EINVAL; in ieee80211_set_csa_beacon()
3826 return -EINVAL; in ieee80211_set_csa_beacon()
3830 if (sdata->u.ibss.chandef.chan->band != in ieee80211_set_csa_beacon()
3831 params->chandef.chan->band) in ieee80211_set_csa_beacon()
3832 return -EINVAL; in ieee80211_set_csa_beacon()
3835 if (params->count > 1) { in ieee80211_set_csa_beacon()
3846 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; in ieee80211_set_csa_beacon()
3849 if (sdata->vif.bss_conf.chandef.chan->band != in ieee80211_set_csa_beacon()
3850 params->chandef.chan->band) in ieee80211_set_csa_beacon()
3851 return -EINVAL; in ieee80211_set_csa_beacon()
3853 if (ifmsh->csa_role == IEEE80211_MESH_CSA_ROLE_NONE) { in ieee80211_set_csa_beacon()
3854 ifmsh->csa_role = IEEE80211_MESH_CSA_ROLE_INIT; in ieee80211_set_csa_beacon()
3855 if (!ifmsh->pre_value) in ieee80211_set_csa_beacon()
3856 ifmsh->pre_value = 1; in ieee80211_set_csa_beacon()
3858 ifmsh->pre_value++; in ieee80211_set_csa_beacon()
3862 if (params->count > 1) { in ieee80211_set_csa_beacon()
3865 ifmsh->csa_role = IEEE80211_MESH_CSA_ROLE_NONE; in ieee80211_set_csa_beacon()
3870 if (ifmsh->csa_role == IEEE80211_MESH_CSA_ROLE_INIT) in ieee80211_set_csa_beacon()
3877 return -EOPNOTSUPP; in ieee80211_set_csa_beacon()
3885 sdata->vif.bss_conf.color_change_active = false; in ieee80211_color_change_abort()
3887 ieee80211_free_next_beacon(&sdata->deflink); in ieee80211_color_change_abort()
3889 cfg80211_color_change_aborted_notify(sdata->dev); in ieee80211_color_change_abort()
3897 struct ieee80211_local *local = sdata->local; in __ieee80211_channel_switch()
3905 lockdep_assert_held(&local->mtx); in __ieee80211_channel_switch()
3907 if (!list_empty(&local->roc_list) || local->scanning) in __ieee80211_channel_switch()
3908 return -EBUSY; in __ieee80211_channel_switch()
3910 if (sdata->wdev.cac_started) in __ieee80211_channel_switch()
3911 return -EBUSY; in __ieee80211_channel_switch()
3913 if (cfg80211_chandef_identical(&params->chandef, in __ieee80211_channel_switch()
3914 &sdata->vif.bss_conf.chandef)) in __ieee80211_channel_switch()
3915 return -EINVAL; in __ieee80211_channel_switch()
3918 if (sdata->vif.bss_conf.csa_active) in __ieee80211_channel_switch()
3919 return -EBUSY; in __ieee80211_channel_switch()
3921 mutex_lock(&local->chanctx_mtx); in __ieee80211_channel_switch()
3922 conf = rcu_dereference_protected(sdata->vif.bss_conf.chanctx_conf, in __ieee80211_channel_switch()
3923 lockdep_is_held(&local->chanctx_mtx)); in __ieee80211_channel_switch()
3925 err = -EBUSY; in __ieee80211_channel_switch()
3929 if (params->chandef.chan->freq_offset) { in __ieee80211_channel_switch()
3931 err = -EOPNOTSUPP; in __ieee80211_channel_switch()
3939 ch_switch.block_tx = params->block_tx; in __ieee80211_channel_switch()
3940 ch_switch.chandef = params->chandef; in __ieee80211_channel_switch()
3941 ch_switch.count = params->count; in __ieee80211_channel_switch()
3947 err = ieee80211_link_reserve_chanctx(&sdata->deflink, &params->chandef, in __ieee80211_channel_switch()
3948 chanctx->mode, in __ieee80211_channel_switch()
3949 params->radar_required); in __ieee80211_channel_switch()
3954 err = ieee80211_check_combinations(sdata, NULL, chanctx->mode, 0); in __ieee80211_channel_switch()
3956 ieee80211_link_unreserve_chanctx(&sdata->deflink); in __ieee80211_channel_switch()
3961 if (sdata->vif.bss_conf.color_change_active) in __ieee80211_channel_switch()
3966 ieee80211_link_unreserve_chanctx(&sdata->deflink); in __ieee80211_channel_switch()
3970 if (params->punct_bitmap && !sdata->vif.bss_conf.eht_support) in __ieee80211_channel_switch()
3973 sdata->deflink.csa_chandef = params->chandef; in __ieee80211_channel_switch()
3974 sdata->deflink.csa_block_tx = params->block_tx; in __ieee80211_channel_switch()
3975 sdata->vif.bss_conf.csa_active = true; in __ieee80211_channel_switch()
3976 sdata->vif.bss_conf.csa_punct_bitmap = params->punct_bitmap; in __ieee80211_channel_switch()
3978 if (sdata->deflink.csa_block_tx) in __ieee80211_channel_switch()
3982 cfg80211_ch_switch_started_notify(sdata->dev, in __ieee80211_channel_switch()
3983 &sdata->deflink.csa_chandef, 0, in __ieee80211_channel_switch()
3984 params->count, params->block_tx, in __ieee80211_channel_switch()
3985 sdata->vif.bss_conf.csa_punct_bitmap); in __ieee80211_channel_switch()
3988 ieee80211_link_info_change_notify(sdata, &sdata->deflink, in __ieee80211_channel_switch()
3990 drv_channel_switch_beacon(sdata, &params->chandef); in __ieee80211_channel_switch()
3997 mutex_unlock(&local->chanctx_mtx); in __ieee80211_channel_switch()
4005 struct ieee80211_local *local = sdata->local; in ieee80211_channel_switch()
4008 mutex_lock(&local->mtx); in ieee80211_channel_switch()
4010 mutex_unlock(&local->mtx); in ieee80211_channel_switch()
4017 lockdep_assert_held(&local->mtx); in ieee80211_mgmt_tx_cookie()
4019 local->roc_cookie_counter++; in ieee80211_mgmt_tx_cookie()
4022 if (WARN_ON(local->roc_cookie_counter == 0)) in ieee80211_mgmt_tx_cookie()
4023 local->roc_cookie_counter++; in ieee80211_mgmt_tx_cookie()
4025 return local->roc_cookie_counter; in ieee80211_mgmt_tx_cookie()
4037 return -ENOMEM; in ieee80211_attach_ack_skb()
4039 spin_lock_irqsave(&local->ack_status_lock, spin_flags); in ieee80211_attach_ack_skb()
4040 id = idr_alloc(&local->ack_status_frames, ack_skb, in ieee80211_attach_ack_skb()
4042 spin_unlock_irqrestore(&local->ack_status_lock, spin_flags); in ieee80211_attach_ack_skb()
4046 return -ENOMEM; in ieee80211_attach_ack_skb()
4049 IEEE80211_SKB_CB(skb)->ack_frame_id = id; in ieee80211_attach_ack_skb()
4052 IEEE80211_SKB_CB(ack_skb)->ack.cookie = *cookie; in ieee80211_attach_ack_skb()
4069 (local->probe_req_reg != !!(upd->global_stypes & preq_mask)) || in ieee80211_update_mgmt_frame_registrations()
4070 (local->rx_mcast_action_reg != in ieee80211_update_mgmt_frame_registrations()
4071 !!(upd->global_mcast_stypes & action_mask)); in ieee80211_update_mgmt_frame_registrations()
4072 local->probe_req_reg = upd->global_stypes & preq_mask; in ieee80211_update_mgmt_frame_registrations()
4073 local->rx_mcast_action_reg = upd->global_mcast_stypes & action_mask; in ieee80211_update_mgmt_frame_registrations()
4075 intf_change = (sdata->vif.probe_req_reg != in ieee80211_update_mgmt_frame_registrations()
4076 !!(upd->interface_stypes & preq_mask)) || in ieee80211_update_mgmt_frame_registrations()
4077 (sdata->vif.rx_mcast_action_reg != in ieee80211_update_mgmt_frame_registrations()
4078 !!(upd->interface_mcast_stypes & action_mask)); in ieee80211_update_mgmt_frame_registrations()
4079 sdata->vif.probe_req_reg = upd->interface_stypes & preq_mask; in ieee80211_update_mgmt_frame_registrations()
4080 sdata->vif.rx_mcast_action_reg = in ieee80211_update_mgmt_frame_registrations()
4081 upd->interface_mcast_stypes & action_mask; in ieee80211_update_mgmt_frame_registrations()
4083 if (!local->open_count) in ieee80211_update_mgmt_frame_registrations()
4088 sdata->vif.probe_req_reg ? in ieee80211_update_mgmt_frame_registrations()
4100 if (local->started) in ieee80211_set_antenna()
4101 return -EOPNOTSUPP; in ieee80211_set_antenna()
4120 if (!local->ops->set_rekey_data) in ieee80211_set_rekey_data()
4121 return -EOPNOTSUPP; in ieee80211_set_rekey_data()
4132 struct ieee80211_local *local = sdata->local; in ieee80211_probe_client()
4145 mutex_lock(&local->mtx); in ieee80211_probe_client()
4150 ret = -ENOLINK; in ieee80211_probe_client()
4154 qos = sta->sta.wme; in ieee80211_probe_client()
4156 chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf); in ieee80211_probe_client()
4158 ret = -EINVAL; in ieee80211_probe_client()
4161 band = chanctx_conf->def.chan->band; in ieee80211_probe_client()
4168 size -= 2; in ieee80211_probe_client()
4174 skb = dev_alloc_skb(local->hw.extra_tx_headroom + size); in ieee80211_probe_client()
4176 ret = -ENOMEM; in ieee80211_probe_client()
4180 skb->dev = dev; in ieee80211_probe_client()
4182 skb_reserve(skb, local->hw.extra_tx_headroom); in ieee80211_probe_client()
4185 nullfunc->frame_control = fc; in ieee80211_probe_client()
4186 nullfunc->duration_id = 0; in ieee80211_probe_client()
4187 memcpy(nullfunc->addr1, sta->sta.addr, ETH_ALEN); in ieee80211_probe_client()
4188 memcpy(nullfunc->addr2, sdata->vif.addr, ETH_ALEN); in ieee80211_probe_client()
4189 memcpy(nullfunc->addr3, sdata->vif.addr, ETH_ALEN); in ieee80211_probe_client()
4190 nullfunc->seq_ctrl = 0; in ieee80211_probe_client()
4194 info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS | in ieee80211_probe_client()
4196 info->band = band; in ieee80211_probe_client()
4199 skb->priority = 7; in ieee80211_probe_client()
4201 nullfunc->qos_ctrl = cpu_to_le16(7); in ieee80211_probe_client()
4216 mutex_unlock(&local->mtx); in ieee80211_probe_client()
4230 int ret = -ENODATA; in ieee80211_cfg_get_channel()
4233 link = rcu_dereference(sdata->link[link_id]); in ieee80211_cfg_get_channel()
4235 ret = -ENOLINK; in ieee80211_cfg_get_channel()
4239 chanctx_conf = rcu_dereference(link->conf->chanctx_conf); in ieee80211_cfg_get_channel()
4241 *chandef = link->conf->chandef; in ieee80211_cfg_get_channel()
4243 } else if (local->open_count > 0 && in ieee80211_cfg_get_channel()
4244 local->open_count == local->monitors && in ieee80211_cfg_get_channel()
4245 sdata->vif.type == NL80211_IFTYPE_MONITOR) { in ieee80211_cfg_get_channel()
4246 if (local->use_chanctx) in ieee80211_cfg_get_channel()
4247 *chandef = local->monitor_chandef; in ieee80211_cfg_get_channel()
4249 *chandef = local->_oper_chandef; in ieee80211_cfg_get_channel()
4275 return -ENOMEM; in ieee80211_set_qos_map()
4276 memcpy(&new_qos_map->qos_map, qos_map, sizeof(*qos_map)); in ieee80211_set_qos_map()
4278 /* A NULL qos_map was passed to disable QoS mapping */ in ieee80211_set_qos_map()
4282 old_qos_map = sdata_dereference(sdata->qos_map, sdata); in ieee80211_set_qos_map()
4283 rcu_assign_pointer(sdata->qos_map, new_qos_map); in ieee80211_set_qos_map()
4300 link = sdata_dereference(sdata->link[link_id], sdata); in ieee80211_set_ap_chanwidth()
4314 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; in ieee80211_add_tx_ts()
4317 if (sdata->vif.type != NL80211_IFTYPE_STATION) in ieee80211_add_tx_ts()
4318 return -EOPNOTSUPP; in ieee80211_add_tx_ts()
4320 if (!(sdata->wmm_acm & BIT(up))) in ieee80211_add_tx_ts()
4321 return -EINVAL; in ieee80211_add_tx_ts()
4323 if (ifmgd->tx_tspec[ac].admitted_time) in ieee80211_add_tx_ts()
4324 return -EBUSY; in ieee80211_add_tx_ts()
4327 ifmgd->tx_tspec[ac].admitted_time = 32 * admitted_time; in ieee80211_add_tx_ts()
4328 ifmgd->tx_tspec[ac].tsid = tsid; in ieee80211_add_tx_ts()
4329 ifmgd->tx_tspec[ac].up = up; in ieee80211_add_tx_ts()
4339 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; in ieee80211_del_tx_ts()
4344 struct ieee80211_sta_tx_tspec *tx_tspec = &ifmgd->tx_tspec[ac]; in ieee80211_del_tx_ts()
4347 if (!tx_tspec->admitted_time) in ieee80211_del_tx_ts()
4350 if (tx_tspec->tsid != tsid) in ieee80211_del_tx_ts()
4353 /* due to this new packets will be reassigned to non-ACM ACs */ in ieee80211_del_tx_ts()
4354 tx_tspec->up = -1; in ieee80211_del_tx_ts()
4366 tx_tspec->action = TX_TSPEC_ACTION_STOP_DOWNGRADE; in ieee80211_del_tx_ts()
4367 tx_tspec->downgraded = false; in ieee80211_del_tx_ts()
4376 return -ENOENT; in ieee80211_del_tx_ts()
4388 if (WARN_ON(vif->type != NL80211_IFTYPE_NAN)) in ieee80211_nan_func_terminated()
4391 spin_lock_bh(&sdata->u.nan.func_lock); in ieee80211_nan_func_terminated()
4393 func = idr_find(&sdata->u.nan.function_inst_ids, inst_id); in ieee80211_nan_func_terminated()
4395 spin_unlock_bh(&sdata->u.nan.func_lock); in ieee80211_nan_func_terminated()
4399 cookie = func->cookie; in ieee80211_nan_func_terminated()
4400 idr_remove(&sdata->u.nan.function_inst_ids, inst_id); in ieee80211_nan_func_terminated()
4402 spin_unlock_bh(&sdata->u.nan.func_lock); in ieee80211_nan_func_terminated()
4418 if (WARN_ON(vif->type != NL80211_IFTYPE_NAN)) in ieee80211_nan_func_match()
4421 spin_lock_bh(&sdata->u.nan.func_lock); in ieee80211_nan_func_match()
4423 func = idr_find(&sdata->u.nan.function_inst_ids, match->inst_id); in ieee80211_nan_func_match()
4425 spin_unlock_bh(&sdata->u.nan.func_lock); in ieee80211_nan_func_match()
4428 match->cookie = func->cookie; in ieee80211_nan_func_match()
4430 spin_unlock_bh(&sdata->u.nan.func_lock); in ieee80211_nan_func_match()
4442 sdata->u.ap.multicast_to_unicast = enabled; in ieee80211_set_multicast_to_unicast()
4450 if (!(txqstats->filled & BIT(NL80211_TXQ_STATS_BACKLOG_BYTES))) { in ieee80211_fill_txq_stats()
4451 txqstats->filled |= BIT(NL80211_TXQ_STATS_BACKLOG_BYTES); in ieee80211_fill_txq_stats()
4452 txqstats->backlog_bytes = txqi->tin.backlog_bytes; in ieee80211_fill_txq_stats()
4455 if (!(txqstats->filled & BIT(NL80211_TXQ_STATS_BACKLOG_PACKETS))) { in ieee80211_fill_txq_stats()
4456 txqstats->filled |= BIT(NL80211_TXQ_STATS_BACKLOG_PACKETS); in ieee80211_fill_txq_stats()
4457 txqstats->backlog_packets = txqi->tin.backlog_packets; in ieee80211_fill_txq_stats()
4460 if (!(txqstats->filled & BIT(NL80211_TXQ_STATS_FLOWS))) { in ieee80211_fill_txq_stats()
4461 txqstats->filled |= BIT(NL80211_TXQ_STATS_FLOWS); in ieee80211_fill_txq_stats()
4462 txqstats->flows = txqi->tin.flows; in ieee80211_fill_txq_stats()
4465 if (!(txqstats->filled & BIT(NL80211_TXQ_STATS_DROPS))) { in ieee80211_fill_txq_stats()
4466 txqstats->filled |= BIT(NL80211_TXQ_STATS_DROPS); in ieee80211_fill_txq_stats()
4467 txqstats->drops = txqi->cstats.drop_count; in ieee80211_fill_txq_stats()
4470 if (!(txqstats->filled & BIT(NL80211_TXQ_STATS_ECN_MARKS))) { in ieee80211_fill_txq_stats()
4471 txqstats->filled |= BIT(NL80211_TXQ_STATS_ECN_MARKS); in ieee80211_fill_txq_stats()
4472 txqstats->ecn_marks = txqi->cstats.ecn_mark; in ieee80211_fill_txq_stats()
4475 if (!(txqstats->filled & BIT(NL80211_TXQ_STATS_OVERLIMIT))) { in ieee80211_fill_txq_stats()
4476 txqstats->filled |= BIT(NL80211_TXQ_STATS_OVERLIMIT); in ieee80211_fill_txq_stats()
4477 txqstats->overlimit = txqi->tin.overlimit; in ieee80211_fill_txq_stats()
4480 if (!(txqstats->filled & BIT(NL80211_TXQ_STATS_COLLISIONS))) { in ieee80211_fill_txq_stats()
4481 txqstats->filled |= BIT(NL80211_TXQ_STATS_COLLISIONS); in ieee80211_fill_txq_stats()
4482 txqstats->collisions = txqi->tin.collisions; in ieee80211_fill_txq_stats()
4485 if (!(txqstats->filled & BIT(NL80211_TXQ_STATS_TX_BYTES))) { in ieee80211_fill_txq_stats()
4486 txqstats->filled |= BIT(NL80211_TXQ_STATS_TX_BYTES); in ieee80211_fill_txq_stats()
4487 txqstats->tx_bytes = txqi->tin.tx_bytes; in ieee80211_fill_txq_stats()
4490 if (!(txqstats->filled & BIT(NL80211_TXQ_STATS_TX_PACKETS))) { in ieee80211_fill_txq_stats()
4491 txqstats->filled |= BIT(NL80211_TXQ_STATS_TX_PACKETS); in ieee80211_fill_txq_stats()
4492 txqstats->tx_packets = txqi->tin.tx_packets; in ieee80211_fill_txq_stats()
4504 spin_lock_bh(&local->fq.lock); in ieee80211_get_txq_stats()
4509 if (!sdata->vif.txq) { in ieee80211_get_txq_stats()
4513 ieee80211_fill_txq_stats(txqstats, to_txq_info(sdata->vif.txq)); in ieee80211_get_txq_stats()
4516 txqstats->filled |= BIT(NL80211_TXQ_STATS_BACKLOG_PACKETS) | in ieee80211_get_txq_stats()
4522 txqstats->backlog_packets = local->fq.backlog; in ieee80211_get_txq_stats()
4523 txqstats->backlog_bytes = local->fq.memory_usage; in ieee80211_get_txq_stats()
4524 txqstats->overlimit = local->fq.overlimit; in ieee80211_get_txq_stats()
4525 txqstats->overmemory = local->fq.overmemory; in ieee80211_get_txq_stats()
4526 txqstats->collisions = local->fq.collisions; in ieee80211_get_txq_stats()
4527 txqstats->max_flows = local->fq.flows_cnt; in ieee80211_get_txq_stats()
4532 spin_unlock_bh(&local->fq.lock); in ieee80211_get_txq_stats()
4576 if (!sdata->local->ops->set_tid_config) in ieee80211_set_tid_config()
4577 return -EOPNOTSUPP; in ieee80211_set_tid_config()
4579 if (!tid_conf->peer) in ieee80211_set_tid_config()
4580 return drv_set_tid_config(sdata->local, sdata, NULL, tid_conf); in ieee80211_set_tid_config()
4582 mutex_lock(&sdata->local->sta_mtx); in ieee80211_set_tid_config()
4583 sta = sta_info_get_bss(sdata, tid_conf->peer); in ieee80211_set_tid_config()
4585 mutex_unlock(&sdata->local->sta_mtx); in ieee80211_set_tid_config()
4586 return -ENOENT; in ieee80211_set_tid_config()
4589 ret = drv_set_tid_config(sdata->local, sdata, &sta->sta, tid_conf); in ieee80211_set_tid_config()
4590 mutex_unlock(&sdata->local->sta_mtx); in ieee80211_set_tid_config()
4603 if (!sdata->local->ops->reset_tid_config) in ieee80211_reset_tid_config()
4604 return -EOPNOTSUPP; in ieee80211_reset_tid_config()
4607 return drv_reset_tid_config(sdata->local, sdata, NULL, tids); in ieee80211_reset_tid_config()
4609 mutex_lock(&sdata->local->sta_mtx); in ieee80211_reset_tid_config()
4612 mutex_unlock(&sdata->local->sta_mtx); in ieee80211_reset_tid_config()
4613 return -ENOENT; in ieee80211_reset_tid_config()
4616 ret = drv_reset_tid_config(sdata->local, sdata, &sta->sta, tids); in ieee80211_reset_tid_config()
4617 mutex_unlock(&sdata->local->sta_mtx); in ieee80211_reset_tid_config()
4627 if (!local->ops->set_sar_specs) in ieee80211_set_sar_specs()
4628 return -EOPNOTSUPP; in ieee80211_set_sar_specs()
4630 return local->ops->set_sar_specs(&local->hw, sar); in ieee80211_set_sar_specs()
4637 switch (sdata->vif.type) { in ieee80211_set_after_color_change_beacon()
4641 if (!sdata->deflink.u.ap.next_beacon) in ieee80211_set_after_color_change_beacon()
4642 return -EINVAL; in ieee80211_set_after_color_change_beacon()
4644 ret = ieee80211_assign_beacon(sdata, &sdata->deflink, in ieee80211_set_after_color_change_beacon()
4645 sdata->deflink.u.ap.next_beacon, in ieee80211_set_after_color_change_beacon()
4647 ieee80211_free_next_beacon(&sdata->deflink); in ieee80211_set_after_color_change_beacon()
4656 return -EINVAL; in ieee80211_set_after_color_change_beacon()
4670 switch (sdata->vif.type) { in ieee80211_set_color_change_beacon()
4672 sdata->deflink.u.ap.next_beacon = in ieee80211_set_color_change_beacon()
4673 cfg80211_beacon_dup(&params->beacon_next); in ieee80211_set_color_change_beacon()
4674 if (!sdata->deflink.u.ap.next_beacon) in ieee80211_set_color_change_beacon()
4675 return -ENOMEM; in ieee80211_set_color_change_beacon()
4677 if (params->count <= 1) in ieee80211_set_color_change_beacon()
4681 params->counter_offset_beacon; in ieee80211_set_color_change_beacon()
4683 params->counter_offset_presp; in ieee80211_set_color_change_beacon()
4684 color_change.count = params->count; in ieee80211_set_color_change_beacon()
4686 err = ieee80211_assign_beacon(sdata, &sdata->deflink, in ieee80211_set_color_change_beacon()
4687 &params->beacon_color_change, in ieee80211_set_color_change_beacon()
4690 ieee80211_free_next_beacon(&sdata->deflink); in ieee80211_set_color_change_beacon()
4695 return -EOPNOTSUPP; in ieee80211_set_color_change_beacon()
4705 sdata->vif.bss_conf.he_bss_color.color = color; in ieee80211_color_change_bss_config_notify()
4706 sdata->vif.bss_conf.he_bss_color.enabled = enable; in ieee80211_color_change_bss_config_notify()
4709 ieee80211_link_info_change_notify(sdata, &sdata->deflink, changed); in ieee80211_color_change_bss_config_notify()
4711 if (!sdata->vif.bss_conf.nontransmitted && sdata->vif.mbssid_tx_vif) { in ieee80211_color_change_bss_config_notify()
4714 mutex_lock(&sdata->local->iflist_mtx); in ieee80211_color_change_bss_config_notify()
4715 list_for_each_entry(child, &sdata->local->interfaces, list) { in ieee80211_color_change_bss_config_notify()
4716 if (child != sdata && child->vif.mbssid_tx_vif == &sdata->vif) { in ieee80211_color_change_bss_config_notify()
4717 child->vif.bss_conf.he_bss_color.color = color; in ieee80211_color_change_bss_config_notify()
4718 child->vif.bss_conf.he_bss_color.enabled = enable; in ieee80211_color_change_bss_config_notify()
4720 &child->deflink, in ieee80211_color_change_bss_config_notify()
4724 mutex_unlock(&sdata->local->iflist_mtx); in ieee80211_color_change_bss_config_notify()
4730 struct ieee80211_local *local = sdata->local; in ieee80211_color_change_finalize()
4735 lockdep_assert_held(&local->mtx); in ieee80211_color_change_finalize()
4737 sdata->vif.bss_conf.color_change_active = false; in ieee80211_color_change_finalize()
4741 cfg80211_color_change_aborted_notify(sdata->dev); in ieee80211_color_change_finalize()
4746 sdata->vif.bss_conf.color_change_color, in ieee80211_color_change_finalize()
4748 cfg80211_color_change_notify(sdata->dev); in ieee80211_color_change_finalize()
4758 struct ieee80211_local *local = sdata->local; in ieee80211_color_change_finalize_work()
4761 mutex_lock(&local->mtx); in ieee80211_color_change_finalize_work()
4764 if (!sdata->vif.bss_conf.color_change_active) in ieee80211_color_change_finalize_work()
4773 mutex_unlock(&local->mtx); in ieee80211_color_change_finalize_work()
4783 struct ieee80211_sub_if_data *sdata = link->sdata; in ieee80211_color_collision_detection_work()
4786 cfg80211_obss_color_collision_notify(sdata->dev, link->color_bitmap); in ieee80211_color_collision_detection_work()
4794 ieee80211_queue_work(&sdata->local->hw, in ieee80211_color_change_finish()
4795 &sdata->deflink.color_change_finalize_work); in ieee80211_color_change_finish()
4804 struct ieee80211_link_data *link = &sdata->deflink; in ieee80211_obss_color_collision_notify()
4806 if (sdata->vif.bss_conf.color_change_active || sdata->vif.bss_conf.csa_active) in ieee80211_obss_color_collision_notify()
4809 if (delayed_work_pending(&link->color_collision_detect_work)) in ieee80211_obss_color_collision_notify()
4812 link->color_bitmap = color_bitmap; in ieee80211_obss_color_collision_notify()
4816 ieee80211_queue_delayed_work(&sdata->local->hw, in ieee80211_obss_color_collision_notify()
4817 &link->color_collision_detect_work, in ieee80211_obss_color_collision_notify()
4827 struct ieee80211_local *local = sdata->local; in ieee80211_color_change()
4833 if (sdata->vif.bss_conf.nontransmitted) in ieee80211_color_change()
4834 return -EINVAL; in ieee80211_color_change()
4836 mutex_lock(&local->mtx); in ieee80211_color_change()
4841 if (sdata->vif.bss_conf.color_change_active || sdata->vif.bss_conf.csa_active) { in ieee80211_color_change()
4842 err = -EBUSY; in ieee80211_color_change()
4850 sdata->vif.bss_conf.color_change_active = true; in ieee80211_color_change()
4851 sdata->vif.bss_conf.color_change_color = params->color; in ieee80211_color_change()
4853 cfg80211_color_change_started_notify(sdata->dev, params->count); in ieee80211_color_change()
4862 mutex_unlock(&local->mtx); in ieee80211_color_change()
4873 if (!local->ops->set_radar_background) in ieee80211_set_radar_background()
4874 return -EOPNOTSUPP; in ieee80211_set_radar_background()
4876 return local->ops->set_radar_background(&local->hw, chandef); in ieee80211_set_radar_background()
4886 if (wdev->use_4addr) in ieee80211_add_intf_link()
4887 return -EOPNOTSUPP; in ieee80211_add_intf_link()
4889 mutex_lock(&sdata->local->mtx); in ieee80211_add_intf_link()
4890 res = ieee80211_vif_set_links(sdata, wdev->valid_links, 0); in ieee80211_add_intf_link()
4891 mutex_unlock(&sdata->local->mtx); in ieee80211_add_intf_link()
4902 mutex_lock(&sdata->local->mtx); in ieee80211_del_intf_link()
4903 ieee80211_vif_set_links(sdata, wdev->valid_links, 0); in ieee80211_del_intf_link()
4904 mutex_unlock(&sdata->local->mtx); in ieee80211_del_intf_link()
4914 sta = sta_info_get_bss(sdata, params->mld_mac); in sta_add_link_station()
4916 return -ENOENT; in sta_add_link_station()
4918 if (!sta->sta.valid_links) in sta_add_link_station()
4919 return -EINVAL; in sta_add_link_station()
4921 if (sta->sta.valid_links & BIT(params->link_id)) in sta_add_link_station()
4922 return -EALREADY; in sta_add_link_station()
4924 ret = ieee80211_sta_allocate_link(sta, params->link_id); in sta_add_link_station()
4930 ieee80211_sta_free_link(sta, params->link_id); in sta_add_link_station()
4935 return ieee80211_sta_activate_link(sta, params->link_id); in sta_add_link_station()
4946 mutex_lock(&sdata->local->sta_mtx); in ieee80211_add_link_station()
4948 mutex_unlock(&sdata->local->sta_mtx); in ieee80211_add_link_station()
4959 sta = sta_info_get_bss(sdata, params->mld_mac); in sta_mod_link_station()
4961 return -ENOENT; in sta_mod_link_station()
4963 if (!(sta->sta.valid_links & BIT(params->link_id))) in sta_mod_link_station()
4964 return -EINVAL; in sta_mod_link_station()
4977 mutex_lock(&sdata->local->sta_mtx); in ieee80211_mod_link_station()
4979 mutex_unlock(&sdata->local->sta_mtx); in ieee80211_mod_link_station()
4989 sta = sta_info_get_bss(sdata, params->mld_mac); in sta_del_link_station()
4991 return -ENOENT; in sta_del_link_station()
4993 if (!(sta->sta.valid_links & BIT(params->link_id))) in sta_del_link_station()
4994 return -EINVAL; in sta_del_link_station()
4997 if (sta->sta.valid_links == BIT(params->link_id)) in sta_del_link_station()
4998 return -EINVAL; in sta_del_link_station()
5000 ieee80211_sta_remove_link(sta, params->link_id); in sta_del_link_station()
5012 mutex_lock(&sdata->local->sta_mtx); in ieee80211_del_link_station()
5014 mutex_unlock(&sdata->local->sta_mtx); in ieee80211_del_link_station()
5024 struct ieee80211_local *local = sdata->local; in ieee80211_set_hw_timestamp()
5026 if (!local->ops->set_hw_timestamp) in ieee80211_set_hw_timestamp()
5027 return -EOPNOTSUPP; in ieee80211_set_hw_timestamp()
5030 return -EIO; in ieee80211_set_hw_timestamp()
5032 return local->ops->set_hw_timestamp(&local->hw, &sdata->vif, hwts); in ieee80211_set_hw_timestamp()