^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * mac80211 configuration hooks for cfg80211
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright 2013-2015 Intel Mobile Communications GmbH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 2015-2017 Intel Deutschland GmbH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2018-2020 Intel Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/ieee80211.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/nl80211.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/rtnetlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <net/net_namespace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/rcupdate.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/fips.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/if_ether.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <net/cfg80211.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "ieee80211_i.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "driver-ops.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "rate.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "mesh.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "wme.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) static void ieee80211_set_mu_mimo_follow(struct ieee80211_sub_if_data *sdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct vif_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) bool mu_mimo_groups = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) bool mu_mimo_follow = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) if (params->vht_mumimo_groups) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) u64 membership;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) BUILD_BUG_ON(sizeof(membership) != WLAN_MEMBERSHIP_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) memcpy(sdata->vif.bss_conf.mu_group.membership,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) params->vht_mumimo_groups, WLAN_MEMBERSHIP_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) memcpy(sdata->vif.bss_conf.mu_group.position,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) params->vht_mumimo_groups + WLAN_MEMBERSHIP_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) WLAN_USER_POSITION_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_MU_GROUPS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /* don't care about endianness - just check for 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) memcpy(&membership, params->vht_mumimo_groups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) WLAN_MEMBERSHIP_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) mu_mimo_groups = membership != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) if (params->vht_mumimo_follow_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) mu_mimo_follow =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) is_valid_ether_addr(params->vht_mumimo_follow_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) ether_addr_copy(sdata->u.mntr.mu_follow_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) params->vht_mumimo_follow_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) sdata->vif.mu_mimo_owner = mu_mimo_groups || mu_mimo_follow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) static int ieee80211_set_mon_options(struct ieee80211_sub_if_data *sdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct vif_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct ieee80211_local *local = sdata->local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct ieee80211_sub_if_data *monitor_sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /* check flags first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) if (params->flags && ieee80211_sdata_running(sdata)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) u32 mask = MONITOR_FLAG_COOK_FRAMES | MONITOR_FLAG_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * Prohibit MONITOR_FLAG_COOK_FRAMES and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * MONITOR_FLAG_ACTIVE to be changed while the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * interface is up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * Else we would need to add a lot of cruft
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * to update everything:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * cooked_mntrs, monitor and all fif_* counters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * reconfigure hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) if ((params->flags & mask) != (sdata->u.mntr.flags & mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /* also validate MU-MIMO change */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) monitor_sdata = rtnl_dereference(local->monitor_sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (!monitor_sdata &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) (params->vht_mumimo_groups || params->vht_mumimo_follow_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) /* apply all changes now - no failures allowed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (monitor_sdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) ieee80211_set_mu_mimo_follow(monitor_sdata, params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (params->flags) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (ieee80211_sdata_running(sdata)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) ieee80211_adjust_monitor_flags(sdata, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) sdata->u.mntr.flags = params->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) ieee80211_adjust_monitor_flags(sdata, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) ieee80211_configure_filter(local);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * Because the interface is down, ieee80211_do_stop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * and ieee80211_do_open take care of "everything"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * mentioned in the comment above.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) sdata->u.mntr.flags = params->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static struct wireless_dev *ieee80211_add_iface(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) unsigned char name_assign_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) enum nl80211_iftype type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct vif_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) struct ieee80211_local *local = wiphy_priv(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct wireless_dev *wdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct ieee80211_sub_if_data *sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) err = ieee80211_if_add(local, name, name_assign_type, &wdev, type, params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (type == NL80211_IFTYPE_MONITOR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) err = ieee80211_set_mon_options(sdata, params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) ieee80211_if_remove(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) return wdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static int ieee80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) ieee80211_if_remove(IEEE80211_WDEV_TO_SUB_IF(wdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) static int ieee80211_change_iface(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) enum nl80211_iftype type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) struct vif_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) struct ieee80211_local *local = sdata->local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) struct sta_info *sta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) ret = ieee80211_if_change_type(sdata, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (type == NL80211_IFTYPE_AP_VLAN && params->use_4addr == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) RCU_INIT_POINTER(sdata->u.vlan.sta, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) ieee80211_check_fast_rx_iface(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) } else if (type == NL80211_IFTYPE_STATION && params->use_4addr >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (params->use_4addr == ifmgd->use_4addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) sdata->u.mgd.use_4addr = params->use_4addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (!ifmgd->associated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) mutex_lock(&local->sta_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) sta = sta_info_get(sdata, ifmgd->bssid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (sta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) drv_sta_set_4addr(local, sdata, &sta->sta,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) params->use_4addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) mutex_unlock(&local->sta_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (params->use_4addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) ieee80211_send_4addr_nullfunc(local, sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (sdata->vif.type == NL80211_IFTYPE_MONITOR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) ret = ieee80211_set_mon_options(sdata, params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) static int ieee80211_start_p2p_device(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) struct wireless_dev *wdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) mutex_lock(&sdata->local->chanctx_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) ret = ieee80211_check_combinations(sdata, NULL, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) mutex_unlock(&sdata->local->chanctx_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return ieee80211_do_open(wdev, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) static void ieee80211_stop_p2p_device(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) struct wireless_dev *wdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) ieee80211_sdata_stop(IEEE80211_WDEV_TO_SUB_IF(wdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) static int ieee80211_start_nan(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) struct wireless_dev *wdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) struct cfg80211_nan_conf *conf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) mutex_lock(&sdata->local->chanctx_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) ret = ieee80211_check_combinations(sdata, NULL, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) mutex_unlock(&sdata->local->chanctx_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) ret = ieee80211_do_open(wdev, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) ret = drv_start_nan(sdata->local, sdata, conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) ieee80211_sdata_stop(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) sdata->u.nan.conf = *conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) static void ieee80211_stop_nan(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) struct wireless_dev *wdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) drv_stop_nan(sdata->local, sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) ieee80211_sdata_stop(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) static int ieee80211_nan_change_conf(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) struct wireless_dev *wdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) struct cfg80211_nan_conf *conf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) u32 changes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) struct cfg80211_nan_conf new_conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (sdata->vif.type != NL80211_IFTYPE_NAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (!ieee80211_sdata_running(sdata))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return -ENETDOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) new_conf = sdata->u.nan.conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (changes & CFG80211_NAN_CONF_CHANGED_PREF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) new_conf.master_pref = conf->master_pref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (changes & CFG80211_NAN_CONF_CHANGED_BANDS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) new_conf.bands = conf->bands;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) ret = drv_nan_change_conf(sdata->local, sdata, &new_conf, changes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) sdata->u.nan.conf = new_conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) static int ieee80211_add_nan_func(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) struct wireless_dev *wdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) struct cfg80211_nan_func *nan_func)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (sdata->vif.type != NL80211_IFTYPE_NAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (!ieee80211_sdata_running(sdata))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) return -ENETDOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) spin_lock_bh(&sdata->u.nan.func_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) ret = idr_alloc(&sdata->u.nan.function_inst_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) nan_func, 1, sdata->local->hw.max_nan_de_entries + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) spin_unlock_bh(&sdata->u.nan.func_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) nan_func->instance_id = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) WARN_ON(nan_func->instance_id == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) ret = drv_add_nan_func(sdata->local, sdata, nan_func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) spin_lock_bh(&sdata->u.nan.func_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) idr_remove(&sdata->u.nan.function_inst_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) nan_func->instance_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) spin_unlock_bh(&sdata->u.nan.func_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) static struct cfg80211_nan_func *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) ieee80211_find_nan_func_by_cookie(struct ieee80211_sub_if_data *sdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) u64 cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) struct cfg80211_nan_func *func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) lockdep_assert_held(&sdata->u.nan.func_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) idr_for_each_entry(&sdata->u.nan.function_inst_ids, func, id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (func->cookie == cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) return func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) static void ieee80211_del_nan_func(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) struct wireless_dev *wdev, u64 cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) struct cfg80211_nan_func *func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) u8 instance_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (sdata->vif.type != NL80211_IFTYPE_NAN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) !ieee80211_sdata_running(sdata))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) spin_lock_bh(&sdata->u.nan.func_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) func = ieee80211_find_nan_func_by_cookie(sdata, cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) if (func)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) instance_id = func->instance_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) spin_unlock_bh(&sdata->u.nan.func_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (instance_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) drv_del_nan_func(sdata->local, sdata, instance_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) static int ieee80211_set_noack_map(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) u16 noack_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) sdata->noack_map = noack_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) ieee80211_check_fast_xmit_iface(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) static int ieee80211_set_tx(struct ieee80211_sub_if_data *sdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) const u8 *mac_addr, u8 key_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) struct ieee80211_local *local = sdata->local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) struct ieee80211_key *key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) struct sta_info *sta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) int ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (!wiphy_ext_feature_isset(local->hw.wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) NL80211_EXT_FEATURE_EXT_KEY_ID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) sta = sta_info_get_bss(sdata, mac_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) if (!sta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (sta->ptk_idx == key_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) mutex_lock(&local->key_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) key = key_mtx_dereference(local, sta->ptk[key_idx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (key && key->conf.flags & IEEE80211_KEY_FLAG_NO_AUTO_TX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) ret = ieee80211_set_tx_key(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) mutex_unlock(&local->key_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) u8 key_idx, bool pairwise, const u8 *mac_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) struct key_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) struct ieee80211_local *local = sdata->local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) struct sta_info *sta = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) const struct ieee80211_cipher_scheme *cs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) struct ieee80211_key *key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) if (!ieee80211_sdata_running(sdata))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) return -ENETDOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (pairwise && params->mode == NL80211_KEY_SET_TX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return ieee80211_set_tx(sdata, mac_addr, key_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) /* reject WEP and TKIP keys if WEP failed to initialize */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) switch (params->cipher) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) case WLAN_CIPHER_SUITE_WEP40:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) case WLAN_CIPHER_SUITE_TKIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) case WLAN_CIPHER_SUITE_WEP104:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (WARN_ON_ONCE(fips_enabled))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) case WLAN_CIPHER_SUITE_CCMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) case WLAN_CIPHER_SUITE_CCMP_256:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) case WLAN_CIPHER_SUITE_AES_CMAC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) case WLAN_CIPHER_SUITE_BIP_CMAC_256:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) case WLAN_CIPHER_SUITE_BIP_GMAC_128:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) case WLAN_CIPHER_SUITE_BIP_GMAC_256:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) case WLAN_CIPHER_SUITE_GCMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) case WLAN_CIPHER_SUITE_GCMP_256:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) cs = ieee80211_cs_get(local, params->cipher, sdata->vif.type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) key = ieee80211_key_alloc(params->cipher, key_idx, params->key_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) params->key, params->seq_len, params->seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) cs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (IS_ERR(key))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) return PTR_ERR(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (pairwise)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) key->conf.flags |= IEEE80211_KEY_FLAG_PAIRWISE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (params->mode == NL80211_KEY_NO_TX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) key->conf.flags |= IEEE80211_KEY_FLAG_NO_AUTO_TX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) mutex_lock(&local->sta_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if (mac_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) sta = sta_info_get_bss(sdata, mac_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) * The ASSOC test makes sure the driver is ready to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) * receive the key. When wpa_supplicant has roamed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) * using FT, it attempts to set the key before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) * association has completed, this rejects that attempt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) * so it will set the key again after association.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) * TODO: accept the key if we have a station entry and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) * add it to the device after the station.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if (!sta || !test_sta_flag(sta, WLAN_STA_ASSOC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) ieee80211_key_free_unused(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) err = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) switch (sdata->vif.type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) case NL80211_IFTYPE_STATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (sdata->u.mgd.mfp != IEEE80211_MFP_DISABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) key->conf.flags |= IEEE80211_KEY_FLAG_RX_MGMT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) case NL80211_IFTYPE_AP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) case NL80211_IFTYPE_AP_VLAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) /* Keys without a station are used for TX only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (sta && test_sta_flag(sta, WLAN_STA_MFP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) key->conf.flags |= IEEE80211_KEY_FLAG_RX_MGMT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) case NL80211_IFTYPE_ADHOC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) /* no MFP (yet) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) case NL80211_IFTYPE_MESH_POINT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) #ifdef CONFIG_MAC80211_MESH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (sdata->u.mesh.security != IEEE80211_MESH_SEC_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) key->conf.flags |= IEEE80211_KEY_FLAG_RX_MGMT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) case NL80211_IFTYPE_WDS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) case NL80211_IFTYPE_MONITOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) case NL80211_IFTYPE_P2P_DEVICE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) case NL80211_IFTYPE_NAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) case NL80211_IFTYPE_UNSPECIFIED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) case NUM_NL80211_IFTYPES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) case NL80211_IFTYPE_P2P_CLIENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) case NL80211_IFTYPE_P2P_GO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) case NL80211_IFTYPE_OCB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) /* shouldn't happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) WARN_ON_ONCE(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) if (sta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) sta->cipher_scheme = cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) err = ieee80211_key_link(key, sdata, sta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) mutex_unlock(&local->sta_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) u8 key_idx, bool pairwise, const u8 *mac_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) struct ieee80211_local *local = sdata->local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) struct sta_info *sta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) struct ieee80211_key *key = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) mutex_lock(&local->sta_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) mutex_lock(&local->key_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) if (mac_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) sta = sta_info_get_bss(sdata, mac_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) if (!sta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) if (pairwise)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) key = key_mtx_dereference(local, sta->ptk[key_idx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) key = key_mtx_dereference(local, sta->gtk[key_idx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) key = key_mtx_dereference(local, sdata->keys[key_idx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (!key) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) ieee80211_key_free(key, sdata->vif.type == NL80211_IFTYPE_STATION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) mutex_unlock(&local->key_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) mutex_unlock(&local->sta_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) u8 key_idx, bool pairwise, const u8 *mac_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) void *cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) void (*callback)(void *cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) struct key_params *params))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) struct ieee80211_sub_if_data *sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) struct sta_info *sta = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) u8 seq[6] = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) struct key_params params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) struct ieee80211_key *key = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) u64 pn64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) u32 iv32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) u16 iv16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) int err = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) struct ieee80211_key_seq kseq = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) if (mac_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) sta = sta_info_get_bss(sdata, mac_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) if (!sta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (pairwise && key_idx < NUM_DEFAULT_KEYS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) key = rcu_dereference(sta->ptk[key_idx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) else if (!pairwise &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) key_idx < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) NUM_DEFAULT_BEACON_KEYS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) key = rcu_dereference(sta->gtk[key_idx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) key = rcu_dereference(sdata->keys[key_idx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) if (!key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) memset(¶ms, 0, sizeof(params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) params.cipher = key->conf.cipher;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) switch (key->conf.cipher) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) case WLAN_CIPHER_SUITE_TKIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) pn64 = atomic64_read(&key->conf.tx_pn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) iv32 = TKIP_PN_TO_IV32(pn64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) iv16 = TKIP_PN_TO_IV16(pn64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) !(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) drv_get_key_seq(sdata->local, key, &kseq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) iv32 = kseq.tkip.iv32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) iv16 = kseq.tkip.iv16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) seq[0] = iv16 & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) seq[1] = (iv16 >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) seq[2] = iv32 & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) seq[3] = (iv32 >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) seq[4] = (iv32 >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) seq[5] = (iv32 >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) params.seq = seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) params.seq_len = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) case WLAN_CIPHER_SUITE_CCMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) case WLAN_CIPHER_SUITE_CCMP_256:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) case WLAN_CIPHER_SUITE_AES_CMAC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) case WLAN_CIPHER_SUITE_BIP_CMAC_256:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) BUILD_BUG_ON(offsetof(typeof(kseq), ccmp) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) offsetof(typeof(kseq), aes_cmac));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) case WLAN_CIPHER_SUITE_BIP_GMAC_128:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) case WLAN_CIPHER_SUITE_BIP_GMAC_256:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) BUILD_BUG_ON(offsetof(typeof(kseq), ccmp) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) offsetof(typeof(kseq), aes_gmac));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) case WLAN_CIPHER_SUITE_GCMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) case WLAN_CIPHER_SUITE_GCMP_256:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) BUILD_BUG_ON(offsetof(typeof(kseq), ccmp) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) offsetof(typeof(kseq), gcmp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) !(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) drv_get_key_seq(sdata->local, key, &kseq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) memcpy(seq, kseq.ccmp.pn, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) pn64 = atomic64_read(&key->conf.tx_pn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) seq[0] = pn64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) seq[1] = pn64 >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) seq[2] = pn64 >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) seq[3] = pn64 >> 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) seq[4] = pn64 >> 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) seq[5] = pn64 >> 40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) params.seq = seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) params.seq_len = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) if (WARN_ON(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) drv_get_key_seq(sdata->local, key, &kseq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) params.seq = kseq.hw.seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) params.seq_len = kseq.hw.seq_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) params.key = key->conf.key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) params.key_len = key->conf.keylen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) callback(cookie, ¶ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) static int ieee80211_config_default_key(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) u8 key_idx, bool uni,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) bool multi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) ieee80211_set_default_key(sdata, key_idx, uni, multi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) static int ieee80211_config_default_mgmt_key(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) u8 key_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) ieee80211_set_default_mgmt_key(sdata, key_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) static int ieee80211_config_default_beacon_key(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) u8 key_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) ieee80211_set_default_beacon_key(sdata, key_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) void sta_set_rate_info_tx(struct sta_info *sta,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) const struct ieee80211_tx_rate *rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) struct rate_info *rinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) rinfo->flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) if (rate->flags & IEEE80211_TX_RC_MCS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) rinfo->flags |= RATE_INFO_FLAGS_MCS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) rinfo->mcs = rate->idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) } else if (rate->flags & IEEE80211_TX_RC_VHT_MCS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) rinfo->flags |= RATE_INFO_FLAGS_VHT_MCS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) rinfo->mcs = ieee80211_rate_get_vht_mcs(rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) rinfo->nss = ieee80211_rate_get_vht_nss(rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) struct ieee80211_supported_band *sband;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) int shift = ieee80211_vif_get_shift(&sta->sdata->vif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) u16 brate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) sband = ieee80211_get_sband(sta->sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) WARN_ON_ONCE(sband && !sband->bitrates);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) if (sband && sband->bitrates) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) brate = sband->bitrates[rate->idx].bitrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) rinfo->legacy = DIV_ROUND_UP(brate, 1 << shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) rinfo->bw = RATE_INFO_BW_40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) else if (rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) rinfo->bw = RATE_INFO_BW_80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) else if (rate->flags & IEEE80211_TX_RC_160_MHZ_WIDTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) rinfo->bw = RATE_INFO_BW_160;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) rinfo->bw = RATE_INFO_BW_20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) int idx, u8 *mac, struct station_info *sinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) struct ieee80211_local *local = sdata->local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) struct sta_info *sta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) int ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) mutex_lock(&local->sta_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) sta = sta_info_get_by_idx(sdata, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) if (sta) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) memcpy(mac, sta->sta.addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) sta_set_sinfo(sta, sinfo, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) mutex_unlock(&local->sta_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) static int ieee80211_dump_survey(struct wiphy *wiphy, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) int idx, struct survey_info *survey)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) return drv_get_survey(local, idx, survey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) const u8 *mac, struct station_info *sinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) struct ieee80211_local *local = sdata->local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) struct sta_info *sta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) int ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) mutex_lock(&local->sta_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) sta = sta_info_get_bss(sdata, mac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) if (sta) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) sta_set_sinfo(sta, sinfo, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) mutex_unlock(&local->sta_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) struct cfg80211_chan_def *chandef)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) struct ieee80211_local *local = wiphy_priv(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) struct ieee80211_sub_if_data *sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) if (cfg80211_chandef_identical(&local->monitor_chandef, chandef))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) mutex_lock(&local->mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) if (local->use_chanctx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) sdata = rtnl_dereference(local->monitor_sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) if (sdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) ieee80211_vif_release_channel(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) ret = ieee80211_vif_use_channel(sdata, chandef,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) IEEE80211_CHANCTX_EXCLUSIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) } else if (local->open_count == local->monitors) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) local->_oper_chandef = *chandef;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) ieee80211_hw_config(local, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) local->monitor_chandef = *chandef;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) mutex_unlock(&local->mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) const u8 *resp, size_t resp_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) const struct ieee80211_csa_settings *csa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) struct probe_resp *new, *old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) if (!resp || !resp_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) old = sdata_dereference(sdata->u.ap.probe_resp, sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) new = kzalloc(sizeof(struct probe_resp) + resp_len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) if (!new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) new->len = resp_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) memcpy(new->data, resp, resp_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) if (csa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) memcpy(new->cntdwn_counter_offsets, csa->counter_offsets_presp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) csa->n_counter_offsets_presp *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) sizeof(new->cntdwn_counter_offsets[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) rcu_assign_pointer(sdata->u.ap.probe_resp, new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) if (old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) kfree_rcu(old, rcu_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) static int ieee80211_set_fils_discovery(struct ieee80211_sub_if_data *sdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) struct cfg80211_fils_discovery *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) struct fils_discovery_data *new, *old = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) struct ieee80211_fils_discovery *fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if (!params->tmpl || !params->tmpl_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) fd = &sdata->vif.bss_conf.fils_discovery;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) fd->min_interval = params->min_interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) fd->max_interval = params->max_interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) old = sdata_dereference(sdata->u.ap.fils_discovery, sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) new = kzalloc(sizeof(*new) + params->tmpl_len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) if (!new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) new->len = params->tmpl_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) memcpy(new->data, params->tmpl, params->tmpl_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) rcu_assign_pointer(sdata->u.ap.fils_discovery, new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) if (old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) kfree_rcu(old, rcu_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) ieee80211_set_unsol_bcast_probe_resp(struct ieee80211_sub_if_data *sdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) struct cfg80211_unsol_bcast_probe_resp *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) struct unsol_bcast_probe_resp_data *new, *old = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) if (!params->tmpl || !params->tmpl_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) old = sdata_dereference(sdata->u.ap.unsol_bcast_probe_resp, sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) new = kzalloc(sizeof(*new) + params->tmpl_len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) if (!new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) new->len = params->tmpl_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) memcpy(new->data, params->tmpl, params->tmpl_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) rcu_assign_pointer(sdata->u.ap.unsol_bcast_probe_resp, new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) if (old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) kfree_rcu(old, rcu_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) sdata->vif.bss_conf.unsol_bcast_probe_resp_interval =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) params->interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) static int ieee80211_set_ftm_responder_params(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) struct ieee80211_sub_if_data *sdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) const u8 *lci, size_t lci_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) const u8 *civicloc, size_t civicloc_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) struct ieee80211_ftm_responder_params *new, *old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) struct ieee80211_bss_conf *bss_conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) u8 *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) if (!lci_len && !civicloc_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) bss_conf = &sdata->vif.bss_conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) old = bss_conf->ftmr_params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) len = lci_len + civicloc_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) new = kzalloc(sizeof(*new) + len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) if (!new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) pos = (u8 *)(new + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) if (lci_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) new->lci_len = lci_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) new->lci = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) memcpy(pos, lci, lci_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) pos += lci_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) if (civicloc_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) new->civicloc_len = civicloc_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) new->civicloc = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) memcpy(pos, civicloc, civicloc_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) pos += civicloc_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) bss_conf->ftmr_params = new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) kfree(old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) struct cfg80211_beacon_data *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) const struct ieee80211_csa_settings *csa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) struct beacon_data *new, *old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) int new_head_len, new_tail_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) int size, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) u32 changed = BSS_CHANGED_BEACON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) old = sdata_dereference(sdata->u.ap.beacon, sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) /* Need to have a beacon head if we don't have one yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) if (!params->head && !old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) /* new or old head? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) if (params->head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) new_head_len = params->head_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) new_head_len = old->head_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) /* new or old tail? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) if (params->tail || !old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) /* params->tail_len will be zero for !params->tail */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) new_tail_len = params->tail_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) new_tail_len = old->tail_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) size = sizeof(*new) + new_head_len + new_tail_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) new = kzalloc(size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) if (!new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) /* start filling the new info now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) * pointers go into the block we allocated,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) * memory is | beacon_data | head | tail |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) new->head = ((u8 *) new) + sizeof(*new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) new->tail = new->head + new_head_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) new->head_len = new_head_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) new->tail_len = new_tail_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) if (csa) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) new->cntdwn_current_counter = csa->count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) memcpy(new->cntdwn_counter_offsets, csa->counter_offsets_beacon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) csa->n_counter_offsets_beacon *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) sizeof(new->cntdwn_counter_offsets[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) /* copy in head */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) if (params->head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) memcpy(new->head, params->head, new_head_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) memcpy(new->head, old->head, new_head_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) /* copy in optional tail */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) if (params->tail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) memcpy(new->tail, params->tail, new_tail_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) if (old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) memcpy(new->tail, old->tail, new_tail_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) err = ieee80211_set_probe_resp(sdata, params->probe_resp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) params->probe_resp_len, csa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) kfree(new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) if (err == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) changed |= BSS_CHANGED_AP_PROBE_RESP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) if (params->ftm_responder != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) sdata->vif.bss_conf.ftm_responder = params->ftm_responder;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) err = ieee80211_set_ftm_responder_params(sdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) params->lci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) params->lci_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) params->civicloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) params->civicloc_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) kfree(new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) changed |= BSS_CHANGED_FTM_RESPONDER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) rcu_assign_pointer(sdata->u.ap.beacon, new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) if (old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) kfree_rcu(old, rcu_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) struct cfg80211_ap_settings *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) struct ieee80211_local *local = sdata->local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) struct beacon_data *old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) struct ieee80211_sub_if_data *vlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) u32 changed = BSS_CHANGED_BEACON_INT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) BSS_CHANGED_BEACON_ENABLED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) BSS_CHANGED_BEACON |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) BSS_CHANGED_SSID |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) BSS_CHANGED_P2P_PS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) BSS_CHANGED_TXPOWER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) BSS_CHANGED_TWT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) int prev_beacon_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) old = sdata_dereference(sdata->u.ap.beacon, sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) if (old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) return -EALREADY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) if (params->smps_mode != NL80211_SMPS_OFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) sdata->smps_mode = IEEE80211_SMPS_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) sdata->needed_rx_chains = sdata->local->rx_chains;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) prev_beacon_int = sdata->vif.bss_conf.beacon_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) sdata->vif.bss_conf.beacon_int = params->beacon_interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) if (params->he_cap && params->he_oper) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) sdata->vif.bss_conf.he_support = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) sdata->vif.bss_conf.htc_trig_based_pkt_ext =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) le32_get_bits(params->he_oper->he_oper_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) IEEE80211_HE_OPERATION_DFLT_PE_DURATION_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) sdata->vif.bss_conf.frame_time_rts_th =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) le32_get_bits(params->he_oper->he_oper_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) IEEE80211_HE_OPERATION_RTS_THRESHOLD_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) changed |= BSS_CHANGED_HE_OBSS_PD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) if (params->he_bss_color.enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) changed |= BSS_CHANGED_HE_BSS_COLOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) mutex_lock(&local->mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) err = ieee80211_vif_use_channel(sdata, ¶ms->chandef,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) IEEE80211_CHANCTX_SHARED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) ieee80211_vif_copy_chanctx_to_vlans(sdata, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) mutex_unlock(&local->mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) sdata->vif.bss_conf.beacon_int = prev_beacon_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) * Apply control port protocol, this allows us to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) * not encrypt dynamic WEP control frames.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) sdata->control_port_protocol = params->crypto.control_port_ethertype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) sdata->control_port_no_encrypt = params->crypto.control_port_no_encrypt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) sdata->control_port_over_nl80211 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) params->crypto.control_port_over_nl80211;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) sdata->control_port_no_preauth =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) params->crypto.control_port_no_preauth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) sdata->encrypt_headroom = ieee80211_cs_headroom(sdata->local,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) ¶ms->crypto,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) sdata->vif.type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) vlan->control_port_protocol =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) params->crypto.control_port_ethertype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) vlan->control_port_no_encrypt =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) params->crypto.control_port_no_encrypt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) vlan->control_port_over_nl80211 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) params->crypto.control_port_over_nl80211;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) vlan->control_port_no_preauth =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) params->crypto.control_port_no_preauth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) vlan->encrypt_headroom =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) ieee80211_cs_headroom(sdata->local,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) ¶ms->crypto,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) vlan->vif.type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) sdata->vif.bss_conf.dtim_period = params->dtim_period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) sdata->vif.bss_conf.enable_beacon = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) sdata->vif.bss_conf.allow_p2p_go_ps = sdata->vif.p2p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) sdata->vif.bss_conf.twt_responder = params->twt_responder;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) memcpy(&sdata->vif.bss_conf.he_obss_pd, ¶ms->he_obss_pd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) sizeof(struct ieee80211_he_obss_pd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) memcpy(&sdata->vif.bss_conf.he_bss_color, ¶ms->he_bss_color,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) sizeof(struct ieee80211_he_bss_color));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) sdata->vif.bss_conf.s1g = params->chandef.chan->band ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) NL80211_BAND_S1GHZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) sdata->vif.bss_conf.ssid_len = params->ssid_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) if (params->ssid_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) memcpy(sdata->vif.bss_conf.ssid, params->ssid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) params->ssid_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) sdata->vif.bss_conf.hidden_ssid =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) memset(&sdata->vif.bss_conf.p2p_noa_attr, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) sizeof(sdata->vif.bss_conf.p2p_noa_attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) sdata->vif.bss_conf.p2p_noa_attr.oppps_ctwindow =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) params->p2p_ctwindow & IEEE80211_P2P_OPPPS_CTWINDOW_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) if (params->p2p_opp_ps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) sdata->vif.bss_conf.p2p_noa_attr.oppps_ctwindow |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) IEEE80211_P2P_OPPPS_ENABLE_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) sdata->beacon_rate_set = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) if (wiphy_ext_feature_isset(local->hw.wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) NL80211_EXT_FEATURE_BEACON_RATE_LEGACY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) for (i = 0; i < NUM_NL80211_BANDS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) sdata->beacon_rateidx_mask[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) params->beacon_rate.control[i].legacy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) if (sdata->beacon_rateidx_mask[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) sdata->beacon_rate_set = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) if (ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) sdata->vif.bss_conf.beacon_tx_rate = params->beacon_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) err = ieee80211_assign_beacon(sdata, ¶ms->beacon, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) changed |= err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) if (params->fils_discovery.max_interval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) err = ieee80211_set_fils_discovery(sdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) ¶ms->fils_discovery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) changed |= BSS_CHANGED_FILS_DISCOVERY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) if (params->unsol_bcast_probe_resp.interval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) err = ieee80211_set_unsol_bcast_probe_resp(sdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) ¶ms->unsol_bcast_probe_resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) changed |= BSS_CHANGED_UNSOL_BCAST_PROBE_RESP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) err = drv_start_ap(sdata->local, sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) old = sdata_dereference(sdata->u.ap.beacon, sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) if (old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) kfree_rcu(old, rcu_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) RCU_INIT_POINTER(sdata->u.ap.beacon, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) ieee80211_recalc_dtim(local, sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) ieee80211_bss_info_change_notify(sdata, changed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) netif_carrier_on(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) netif_carrier_on(vlan->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) mutex_lock(&local->mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) ieee80211_vif_release_channel(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) mutex_unlock(&local->mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) static int ieee80211_change_beacon(struct wiphy *wiphy, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) struct cfg80211_beacon_data *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) struct ieee80211_sub_if_data *sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) struct beacon_data *old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) sdata_assert_lock(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) /* don't allow changing the beacon while CSA is in place - offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) * of channel switch counter may change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) if (sdata->vif.csa_active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) old = sdata_dereference(sdata->u.ap.beacon, sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) if (!old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) err = ieee80211_assign_beacon(sdata, params, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) ieee80211_bss_info_change_notify(sdata, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) struct ieee80211_sub_if_data *vlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) struct ieee80211_local *local = sdata->local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) struct beacon_data *old_beacon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) struct probe_resp *old_probe_resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) struct fils_discovery_data *old_fils_discovery;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) struct unsol_bcast_probe_resp_data *old_unsol_bcast_probe_resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) struct cfg80211_chan_def chandef;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) sdata_assert_lock(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) old_beacon = sdata_dereference(sdata->u.ap.beacon, sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) if (!old_beacon)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) old_probe_resp = sdata_dereference(sdata->u.ap.probe_resp, sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) old_fils_discovery = sdata_dereference(sdata->u.ap.fils_discovery,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) old_unsol_bcast_probe_resp =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) sdata_dereference(sdata->u.ap.unsol_bcast_probe_resp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) /* abort any running channel switch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) mutex_lock(&local->mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) sdata->vif.csa_active = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) if (sdata->csa_block_tx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) ieee80211_wake_vif_queues(local, sdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) IEEE80211_QUEUE_STOP_REASON_CSA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) sdata->csa_block_tx = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) mutex_unlock(&local->mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) kfree(sdata->u.ap.next_beacon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) sdata->u.ap.next_beacon = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) /* turn off carrier for this interface and dependent VLANs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) netif_carrier_off(vlan->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) netif_carrier_off(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) /* remove beacon and probe response */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) RCU_INIT_POINTER(sdata->u.ap.beacon, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) RCU_INIT_POINTER(sdata->u.ap.probe_resp, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) RCU_INIT_POINTER(sdata->u.ap.fils_discovery, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) RCU_INIT_POINTER(sdata->u.ap.unsol_bcast_probe_resp, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) kfree_rcu(old_beacon, rcu_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) if (old_probe_resp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) kfree_rcu(old_probe_resp, rcu_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) if (old_fils_discovery)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) kfree_rcu(old_fils_discovery, rcu_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) if (old_unsol_bcast_probe_resp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) kfree_rcu(old_unsol_bcast_probe_resp, rcu_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) kfree(sdata->vif.bss_conf.ftmr_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) sdata->vif.bss_conf.ftmr_params = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) __sta_info_flush(sdata, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) ieee80211_free_keys(sdata, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) sdata->vif.bss_conf.enable_beacon = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) sdata->beacon_rate_set = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) sdata->vif.bss_conf.ssid_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) if (sdata->wdev.cac_started) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) chandef = sdata->vif.bss_conf.chandef;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) cancel_delayed_work_sync(&sdata->dfs_cac_timer_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) cfg80211_cac_event(sdata->dev, &chandef,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) NL80211_RADAR_CAC_ABORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) drv_stop_ap(sdata->local, sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) /* free all potentially still buffered bcast frames */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) local->total_ps_buffered -= skb_queue_len(&sdata->u.ap.ps.bc_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) ieee80211_purge_tx_queue(&local->hw, &sdata->u.ap.ps.bc_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) mutex_lock(&local->mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) ieee80211_vif_copy_chanctx_to_vlans(sdata, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) ieee80211_vif_release_channel(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) mutex_unlock(&local->mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) static int sta_apply_auth_flags(struct ieee80211_local *local,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) struct sta_info *sta,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) u32 mask, u32 set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) if (mask & BIT(NL80211_STA_FLAG_AUTHENTICATED) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) set & BIT(NL80211_STA_FLAG_AUTHENTICATED) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) !test_sta_flag(sta, WLAN_STA_AUTH)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) ret = sta_info_move_state(sta, IEEE80211_STA_AUTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) if (mask & BIT(NL80211_STA_FLAG_ASSOCIATED) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) set & BIT(NL80211_STA_FLAG_ASSOCIATED) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) !test_sta_flag(sta, WLAN_STA_ASSOC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) * When peer becomes associated, init rate control as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) * well. Some drivers require rate control initialized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) * before drv_sta_state() is called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) if (!test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) rate_control_rate_init(sta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) ret = sta_info_move_state(sta, IEEE80211_STA_ASSOC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) if (mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) if (set & BIT(NL80211_STA_FLAG_AUTHORIZED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) ret = sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) else if (test_sta_flag(sta, WLAN_STA_AUTHORIZED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) ret = sta_info_move_state(sta, IEEE80211_STA_ASSOC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) if (mask & BIT(NL80211_STA_FLAG_ASSOCIATED) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) !(set & BIT(NL80211_STA_FLAG_ASSOCIATED)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) test_sta_flag(sta, WLAN_STA_ASSOC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) ret = sta_info_move_state(sta, IEEE80211_STA_AUTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) if (mask & BIT(NL80211_STA_FLAG_AUTHENTICATED) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) !(set & BIT(NL80211_STA_FLAG_AUTHENTICATED)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) test_sta_flag(sta, WLAN_STA_AUTH)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) ret = sta_info_move_state(sta, IEEE80211_STA_NONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) static void sta_apply_mesh_params(struct ieee80211_local *local,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) struct sta_info *sta,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) struct station_parameters *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) #ifdef CONFIG_MAC80211_MESH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) struct ieee80211_sub_if_data *sdata = sta->sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) u32 changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) switch (params->plink_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) case NL80211_PLINK_ESTAB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) if (sta->mesh->plink_state != NL80211_PLINK_ESTAB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) changed = mesh_plink_inc_estab_count(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) sta->mesh->plink_state = params->plink_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) sta->mesh->aid = params->peer_aid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) ieee80211_mps_sta_status_update(sta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) changed |= ieee80211_mps_set_sta_local_pm(sta,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) sdata->u.mesh.mshcfg.power_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) ewma_mesh_tx_rate_avg_init(&sta->mesh->tx_rate_avg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) /* init at low value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) ewma_mesh_tx_rate_avg_add(&sta->mesh->tx_rate_avg, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) case NL80211_PLINK_LISTEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) case NL80211_PLINK_BLOCKED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) case NL80211_PLINK_OPN_SNT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) case NL80211_PLINK_OPN_RCVD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) case NL80211_PLINK_CNF_RCVD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) case NL80211_PLINK_HOLDING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) if (sta->mesh->plink_state == NL80211_PLINK_ESTAB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) changed = mesh_plink_dec_estab_count(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) sta->mesh->plink_state = params->plink_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) ieee80211_mps_sta_status_update(sta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) changed |= ieee80211_mps_set_sta_local_pm(sta,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) NL80211_MESH_POWER_UNKNOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) /* nothing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) switch (params->plink_action) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) case NL80211_PLINK_ACTION_NO_ACTION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) /* nothing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) case NL80211_PLINK_ACTION_OPEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) changed |= mesh_plink_open(sta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) case NL80211_PLINK_ACTION_BLOCK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) changed |= mesh_plink_block(sta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) if (params->local_pm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) changed |= ieee80211_mps_set_sta_local_pm(sta,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) params->local_pm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) ieee80211_mbss_info_change_notify(sdata, changed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) static int sta_apply_parameters(struct ieee80211_local *local,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) struct sta_info *sta,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) struct station_parameters *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) struct ieee80211_supported_band *sband;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) struct ieee80211_sub_if_data *sdata = sta->sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) u32 mask, set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) sband = ieee80211_get_sband(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) if (!sband)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) mask = params->sta_flags_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) set = params->sta_flags_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) if (ieee80211_vif_is_mesh(&sdata->vif)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) * In mesh mode, ASSOCIATED isn't part of the nl80211
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) * API but must follow AUTHENTICATED for driver state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) if (mask & BIT(NL80211_STA_FLAG_AUTHENTICATED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) mask |= BIT(NL80211_STA_FLAG_ASSOCIATED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) if (set & BIT(NL80211_STA_FLAG_AUTHENTICATED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) set |= BIT(NL80211_STA_FLAG_ASSOCIATED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) } else if (test_sta_flag(sta, WLAN_STA_TDLS_PEER)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) * TDLS -- everything follows authorized, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) * only becoming authorized is possible, not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) * going back
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) if (set & BIT(NL80211_STA_FLAG_AUTHORIZED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) set |= BIT(NL80211_STA_FLAG_AUTHENTICATED) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) BIT(NL80211_STA_FLAG_ASSOCIATED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) mask |= BIT(NL80211_STA_FLAG_AUTHENTICATED) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) BIT(NL80211_STA_FLAG_ASSOCIATED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) if (mask & BIT(NL80211_STA_FLAG_WME) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) local->hw.queues >= IEEE80211_NUM_ACS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) sta->sta.wme = set & BIT(NL80211_STA_FLAG_WME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) /* auth flags will be set later for TDLS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) * and for unassociated stations that move to assocaited */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) if (!test_sta_flag(sta, WLAN_STA_TDLS_PEER) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) !((mask & BIT(NL80211_STA_FLAG_ASSOCIATED)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) (set & BIT(NL80211_STA_FLAG_ASSOCIATED)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) ret = sta_apply_auth_flags(local, sta, mask, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) if (mask & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) if (set & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) set_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) clear_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) if (mask & BIT(NL80211_STA_FLAG_MFP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) sta->sta.mfp = !!(set & BIT(NL80211_STA_FLAG_MFP));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) if (set & BIT(NL80211_STA_FLAG_MFP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) set_sta_flag(sta, WLAN_STA_MFP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) clear_sta_flag(sta, WLAN_STA_MFP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) if (set & BIT(NL80211_STA_FLAG_TDLS_PEER))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) set_sta_flag(sta, WLAN_STA_TDLS_PEER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) clear_sta_flag(sta, WLAN_STA_TDLS_PEER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) /* mark TDLS channel switch support, if the AP allows it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) !sdata->u.mgd.tdls_chan_switch_prohibited &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) params->ext_capab_len >= 4 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) params->ext_capab[3] & WLAN_EXT_CAPA4_TDLS_CHAN_SWITCH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) set_sta_flag(sta, WLAN_STA_TDLS_CHAN_SWITCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) !sdata->u.mgd.tdls_wider_bw_prohibited &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) ieee80211_hw_check(&local->hw, TDLS_WIDER_BW) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) params->ext_capab_len >= 8 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) params->ext_capab[7] & WLAN_EXT_CAPA8_TDLS_WIDE_BW_ENABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) set_sta_flag(sta, WLAN_STA_TDLS_WIDER_BW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) if (params->sta_modify_mask & STATION_PARAM_APPLY_UAPSD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) sta->sta.uapsd_queues = params->uapsd_queues;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) sta->sta.max_sp = params->max_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) /* The sender might not have sent the last bit, consider it to be 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) if (params->ext_capab_len >= 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) u8 val = (params->ext_capab[7] &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) WLAN_EXT_CAPA8_MAX_MSDU_IN_AMSDU_LSB) >> 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) /* we did get all the bits, take the MSB as well */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) if (params->ext_capab_len >= 9) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) u8 val_msb = params->ext_capab[8] &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) WLAN_EXT_CAPA9_MAX_MSDU_IN_AMSDU_MSB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) val_msb <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) val |= val_msb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) switch (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) sta->sta.max_amsdu_subframes = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) sta->sta.max_amsdu_subframes = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) sta->sta.max_amsdu_subframes = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) sta->sta.max_amsdu_subframes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) * cfg80211 validates this (1-2007) and allows setting the AID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) * only when creating a new station entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) if (params->aid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) sta->sta.aid = params->aid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) * Some of the following updates would be racy if called on an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) * existing station, via ieee80211_change_station(). However,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) * all such changes are rejected by cfg80211 except for updates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) * changing the supported rates on an existing but not yet used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) * TDLS peer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) if (params->listen_interval >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) sta->listen_interval = params->listen_interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) if (params->sta_modify_mask & STATION_PARAM_APPLY_STA_TXPOWER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) sta->sta.txpwr.type = params->txpwr.type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) if (params->txpwr.type == NL80211_TX_POWER_LIMITED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) sta->sta.txpwr.power = params->txpwr.power;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) ret = drv_sta_set_txpwr(local, sdata, sta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) if (params->supported_rates && params->supported_rates_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) ieee80211_parse_bitrates(&sdata->vif.bss_conf.chandef,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) sband, params->supported_rates,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) params->supported_rates_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) &sta->sta.supp_rates[sband->band]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) if (params->ht_capa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) params->ht_capa, sta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) /* VHT can override some HT caps such as the A-MSDU max length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) if (params->vht_capa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) params->vht_capa, sta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) if (params->he_capa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) ieee80211_he_cap_ie_to_sta_he_cap(sdata, sband,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) (void *)params->he_capa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) params->he_capa_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) (void *)params->he_6ghz_capa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) sta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) if (params->opmode_notif_used) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) /* returned value is only needed for rc update, but the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) * rc isn't initialized here yet, so ignore it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) __ieee80211_vht_handle_opmode(sdata, sta, params->opmode_notif,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) sband->band);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) if (params->support_p2p_ps >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) sta->sta.support_p2p_ps = params->support_p2p_ps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) if (ieee80211_vif_is_mesh(&sdata->vif))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) sta_apply_mesh_params(local, sta, params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) if (params->airtime_weight)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) sta->airtime_weight = params->airtime_weight;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) /* set the STA state after all sta info from usermode has been set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) set & BIT(NL80211_STA_FLAG_ASSOCIATED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) ret = sta_apply_auth_flags(local, sta, mask, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) const u8 *mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) struct station_parameters *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) struct ieee80211_local *local = wiphy_priv(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) struct sta_info *sta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) struct ieee80211_sub_if_data *sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) if (params->vlan) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) sdata->vif.type != NL80211_IFTYPE_AP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) if (ether_addr_equal(mac, sdata->vif.addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) if (!is_valid_ether_addr(mac))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) sdata->vif.type == NL80211_IFTYPE_STATION &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) !sdata->u.mgd.associated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) sta = sta_info_alloc(sdata, mac, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) if (!sta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) sta->sta.tdls = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) err = sta_apply_parameters(local, sta, params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) sta_info_free(local, sta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) * for TDLS and for unassociated station, rate control should be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) * initialized only when rates are known and station is marked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) * authorized/associated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) if (!test_sta_flag(sta, WLAN_STA_TDLS_PEER) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) test_sta_flag(sta, WLAN_STA_ASSOC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) rate_control_rate_init(sta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) err = sta_info_insert_rcu(sta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) struct station_del_parameters *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) struct ieee80211_sub_if_data *sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) if (params->mac)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) return sta_info_destroy_addr_bss(sdata, params->mac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) sta_info_flush(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) static int ieee80211_change_station(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) struct net_device *dev, const u8 *mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) struct station_parameters *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) struct ieee80211_local *local = wiphy_priv(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) struct sta_info *sta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) struct ieee80211_sub_if_data *vlansdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) enum cfg80211_station_type statype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) mutex_lock(&local->sta_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) sta = sta_info_get_bss(sdata, mac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) if (!sta) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) err = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) switch (sdata->vif.type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) case NL80211_IFTYPE_MESH_POINT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) if (sdata->u.mesh.user_mpm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) statype = CFG80211_STA_MESH_PEER_USER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) statype = CFG80211_STA_MESH_PEER_KERNEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) case NL80211_IFTYPE_ADHOC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) statype = CFG80211_STA_IBSS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) case NL80211_IFTYPE_STATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) if (!test_sta_flag(sta, WLAN_STA_TDLS_PEER)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) statype = CFG80211_STA_AP_STA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) if (test_sta_flag(sta, WLAN_STA_AUTHORIZED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) statype = CFG80211_STA_TDLS_PEER_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) statype = CFG80211_STA_TDLS_PEER_SETUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) case NL80211_IFTYPE_AP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) case NL80211_IFTYPE_AP_VLAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) if (test_sta_flag(sta, WLAN_STA_ASSOC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) statype = CFG80211_STA_AP_CLIENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) statype = CFG80211_STA_AP_CLIENT_UNASSOC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) err = cfg80211_check_station_change(wiphy, params, statype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) if (params->vlan && params->vlan != sta->sdata->dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) if (params->vlan->ieee80211_ptr->use_4addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) if (vlansdata->u.vlan.sta) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) err = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) rcu_assign_pointer(vlansdata->u.vlan.sta, sta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) __ieee80211_check_fast_rx_iface(vlansdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) drv_sta_set_4addr(local, sta->sdata, &sta->sta, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) if (sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) sta->sdata->u.vlan.sta) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) ieee80211_clear_fast_rx(sta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) RCU_INIT_POINTER(sta->sdata->u.vlan.sta, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) if (test_sta_flag(sta, WLAN_STA_AUTHORIZED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) ieee80211_vif_dec_num_mcast(sta->sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) sta->sdata = vlansdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) ieee80211_check_fast_xmit(sta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) if (test_sta_flag(sta, WLAN_STA_AUTHORIZED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) ieee80211_vif_inc_num_mcast(sta->sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) cfg80211_send_layer2_update(sta->sdata->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) sta->sta.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) err = sta_apply_parameters(local, sta, params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) mutex_unlock(&local->sta_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) if (sdata->vif.type == NL80211_IFTYPE_STATION &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) ieee80211_recalc_ps(local);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) ieee80211_recalc_ps_vif(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) mutex_unlock(&local->sta_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) #ifdef CONFIG_MAC80211_MESH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) const u8 *dst, const u8 *next_hop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) struct ieee80211_sub_if_data *sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) struct mesh_path *mpath;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) struct sta_info *sta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) sta = sta_info_get(sdata, next_hop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) if (!sta) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) mpath = mesh_path_add(sdata, dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) if (IS_ERR(mpath)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) return PTR_ERR(mpath);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) mesh_path_fix_nexthop(mpath, sta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) static int ieee80211_del_mpath(struct wiphy *wiphy, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) const u8 *dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) if (dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) return mesh_path_del(sdata, dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) mesh_path_flush_by_iface(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) static int ieee80211_change_mpath(struct wiphy *wiphy, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) const u8 *dst, const u8 *next_hop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) struct ieee80211_sub_if_data *sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) struct mesh_path *mpath;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) struct sta_info *sta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) sta = sta_info_get(sdata, next_hop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) if (!sta) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) mpath = mesh_path_lookup(sdata, dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) if (!mpath) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) mesh_path_fix_nexthop(mpath, sta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) struct mpath_info *pinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) struct sta_info *next_hop_sta = rcu_dereference(mpath->next_hop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) if (next_hop_sta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) memcpy(next_hop, next_hop_sta->sta.addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) eth_zero_addr(next_hop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) memset(pinfo, 0, sizeof(*pinfo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) pinfo->generation = mpath->sdata->u.mesh.mesh_paths_generation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) pinfo->filled = MPATH_INFO_FRAME_QLEN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) MPATH_INFO_SN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) MPATH_INFO_METRIC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) MPATH_INFO_EXPTIME |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) MPATH_INFO_DISCOVERY_TIMEOUT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) MPATH_INFO_DISCOVERY_RETRIES |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) MPATH_INFO_FLAGS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) MPATH_INFO_HOP_COUNT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) MPATH_INFO_PATH_CHANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) pinfo->frame_qlen = mpath->frame_queue.qlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) pinfo->sn = mpath->sn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) pinfo->metric = mpath->metric;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) if (time_before(jiffies, mpath->exp_time))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) pinfo->exptime = jiffies_to_msecs(mpath->exp_time - jiffies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) pinfo->discovery_timeout =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) jiffies_to_msecs(mpath->discovery_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) pinfo->discovery_retries = mpath->discovery_retries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) if (mpath->flags & MESH_PATH_ACTIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) pinfo->flags |= NL80211_MPATH_FLAG_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) if (mpath->flags & MESH_PATH_RESOLVING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) if (mpath->flags & MESH_PATH_SN_VALID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) pinfo->flags |= NL80211_MPATH_FLAG_SN_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) if (mpath->flags & MESH_PATH_FIXED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) pinfo->flags |= NL80211_MPATH_FLAG_FIXED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) if (mpath->flags & MESH_PATH_RESOLVED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) pinfo->flags |= NL80211_MPATH_FLAG_RESOLVED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) pinfo->hop_count = mpath->hop_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) pinfo->path_change_count = mpath->path_change_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) static int ieee80211_get_mpath(struct wiphy *wiphy, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) u8 *dst, u8 *next_hop, struct mpath_info *pinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) struct ieee80211_sub_if_data *sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) struct mesh_path *mpath;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) mpath = mesh_path_lookup(sdata, dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) if (!mpath) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) memcpy(dst, mpath->dst, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) mpath_set_pinfo(mpath, next_hop, pinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) int idx, u8 *dst, u8 *next_hop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) struct mpath_info *pinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) struct ieee80211_sub_if_data *sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) struct mesh_path *mpath;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) mpath = mesh_path_lookup_by_idx(sdata, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) if (!mpath) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) memcpy(dst, mpath->dst, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) mpath_set_pinfo(mpath, next_hop, pinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) static void mpp_set_pinfo(struct mesh_path *mpath, u8 *mpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) struct mpath_info *pinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) memset(pinfo, 0, sizeof(*pinfo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) memcpy(mpp, mpath->mpp, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) pinfo->generation = mpath->sdata->u.mesh.mpp_paths_generation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) static int ieee80211_get_mpp(struct wiphy *wiphy, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) u8 *dst, u8 *mpp, struct mpath_info *pinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) struct ieee80211_sub_if_data *sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) struct mesh_path *mpath;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) mpath = mpp_path_lookup(sdata, dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) if (!mpath) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) memcpy(dst, mpath->dst, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) mpp_set_pinfo(mpath, mpp, pinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) static int ieee80211_dump_mpp(struct wiphy *wiphy, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) int idx, u8 *dst, u8 *mpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) struct mpath_info *pinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) struct ieee80211_sub_if_data *sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) struct mesh_path *mpath;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) mpath = mpp_path_lookup_by_idx(sdata, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) if (!mpath) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) memcpy(dst, mpath->dst, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) mpp_set_pinfo(mpath, mpp, pinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) static int ieee80211_get_mesh_config(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) struct mesh_config *conf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) struct ieee80211_sub_if_data *sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) memcpy(conf, &(sdata->u.mesh.mshcfg), sizeof(struct mesh_config));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) static inline bool _chg_mesh_attr(enum nl80211_meshconf_params parm, u32 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) return (mask >> (parm-1)) & 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) const struct mesh_setup *setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) u8 *new_ie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) struct ieee80211_sub_if_data *sdata = container_of(ifmsh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) struct ieee80211_sub_if_data, u.mesh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) /* allocate information elements */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) new_ie = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) if (setup->ie_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) new_ie = kmemdup(setup->ie, setup->ie_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) if (!new_ie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) ifmsh->ie_len = setup->ie_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) ifmsh->ie = new_ie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) /* now copy the rest of the setup parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) ifmsh->mesh_id_len = setup->mesh_id_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) ifmsh->mesh_sp_id = setup->sync_method;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) ifmsh->mesh_pp_id = setup->path_sel_proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) ifmsh->mesh_pm_id = setup->path_metric;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) ifmsh->user_mpm = setup->user_mpm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) ifmsh->mesh_auth_id = setup->auth_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) ifmsh->security = IEEE80211_MESH_SEC_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) ifmsh->userspace_handles_dfs = setup->userspace_handles_dfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) if (setup->is_authenticated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) ifmsh->security |= IEEE80211_MESH_SEC_AUTHED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) if (setup->is_secure)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) ifmsh->security |= IEEE80211_MESH_SEC_SECURED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) /* mcast rate setting in Mesh Node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) memcpy(sdata->vif.bss_conf.mcast_rate, setup->mcast_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) sizeof(setup->mcast_rate));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) sdata->vif.bss_conf.basic_rates = setup->basic_rates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) sdata->vif.bss_conf.beacon_int = setup->beacon_interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) sdata->vif.bss_conf.dtim_period = setup->dtim_period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) sdata->beacon_rate_set = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) if (wiphy_ext_feature_isset(sdata->local->hw.wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) NL80211_EXT_FEATURE_BEACON_RATE_LEGACY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) for (i = 0; i < NUM_NL80211_BANDS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) sdata->beacon_rateidx_mask[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) setup->beacon_rate.control[i].legacy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) if (sdata->beacon_rateidx_mask[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) sdata->beacon_rate_set = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) static int ieee80211_update_mesh_config(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) struct net_device *dev, u32 mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) const struct mesh_config *nconf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) struct mesh_config *conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) struct ieee80211_sub_if_data *sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) struct ieee80211_if_mesh *ifmsh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) ifmsh = &sdata->u.mesh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) /* Set the config options which we are interested in setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) conf = &(sdata->u.mesh.mshcfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) if (_chg_mesh_attr(NL80211_MESHCONF_RETRY_TIMEOUT, mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) conf->dot11MeshRetryTimeout = nconf->dot11MeshRetryTimeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) if (_chg_mesh_attr(NL80211_MESHCONF_CONFIRM_TIMEOUT, mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) conf->dot11MeshConfirmTimeout = nconf->dot11MeshConfirmTimeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) if (_chg_mesh_attr(NL80211_MESHCONF_HOLDING_TIMEOUT, mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) conf->dot11MeshHoldingTimeout = nconf->dot11MeshHoldingTimeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) if (_chg_mesh_attr(NL80211_MESHCONF_MAX_PEER_LINKS, mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) conf->dot11MeshMaxPeerLinks = nconf->dot11MeshMaxPeerLinks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) if (_chg_mesh_attr(NL80211_MESHCONF_MAX_RETRIES, mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) conf->dot11MeshMaxRetries = nconf->dot11MeshMaxRetries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) if (_chg_mesh_attr(NL80211_MESHCONF_TTL, mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) conf->dot11MeshTTL = nconf->dot11MeshTTL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) if (_chg_mesh_attr(NL80211_MESHCONF_ELEMENT_TTL, mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) conf->element_ttl = nconf->element_ttl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) if (_chg_mesh_attr(NL80211_MESHCONF_AUTO_OPEN_PLINKS, mask)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) if (ifmsh->user_mpm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) conf->auto_open_plinks = nconf->auto_open_plinks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) if (_chg_mesh_attr(NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR, mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) conf->dot11MeshNbrOffsetMaxNeighbor =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) nconf->dot11MeshNbrOffsetMaxNeighbor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) conf->dot11MeshHWMPmaxPREQretries =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) nconf->dot11MeshHWMPmaxPREQretries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) if (_chg_mesh_attr(NL80211_MESHCONF_PATH_REFRESH_TIME, mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) conf->path_refresh_time = nconf->path_refresh_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) if (_chg_mesh_attr(NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT, mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) conf->min_discovery_timeout = nconf->min_discovery_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT, mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) conf->dot11MeshHWMPactivePathTimeout =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) nconf->dot11MeshHWMPactivePathTimeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) conf->dot11MeshHWMPpreqMinInterval =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) nconf->dot11MeshHWMPpreqMinInterval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL, mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) conf->dot11MeshHWMPperrMinInterval =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) nconf->dot11MeshHWMPperrMinInterval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) conf->dot11MeshHWMPnetDiameterTraversalTime =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) nconf->dot11MeshHWMPnetDiameterTraversalTime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_ROOTMODE, mask)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) conf->dot11MeshHWMPRootMode = nconf->dot11MeshHWMPRootMode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) ieee80211_mesh_root_setup(ifmsh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) if (_chg_mesh_attr(NL80211_MESHCONF_GATE_ANNOUNCEMENTS, mask)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) /* our current gate announcement implementation rides on root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) * announcements, so require this ifmsh to also be a root node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) * */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) if (nconf->dot11MeshGateAnnouncementProtocol &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) !(conf->dot11MeshHWMPRootMode > IEEE80211_ROOTMODE_ROOT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) conf->dot11MeshHWMPRootMode = IEEE80211_PROACTIVE_RANN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) ieee80211_mesh_root_setup(ifmsh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) conf->dot11MeshGateAnnouncementProtocol =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) nconf->dot11MeshGateAnnouncementProtocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_RANN_INTERVAL, mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) conf->dot11MeshHWMPRannInterval =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) nconf->dot11MeshHWMPRannInterval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) if (_chg_mesh_attr(NL80211_MESHCONF_FORWARDING, mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) conf->dot11MeshForwarding = nconf->dot11MeshForwarding;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) if (_chg_mesh_attr(NL80211_MESHCONF_RSSI_THRESHOLD, mask)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) /* our RSSI threshold implementation is supported only for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) * devices that report signal in dBm.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) if (!ieee80211_hw_check(&sdata->local->hw, SIGNAL_DBM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) conf->rssi_threshold = nconf->rssi_threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) if (_chg_mesh_attr(NL80211_MESHCONF_HT_OPMODE, mask)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) conf->ht_opmode = nconf->ht_opmode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) sdata->vif.bss_conf.ht_operation_mode = nconf->ht_opmode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_HT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT, mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) conf->dot11MeshHWMPactivePathToRootTimeout =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) nconf->dot11MeshHWMPactivePathToRootTimeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_ROOT_INTERVAL, mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) conf->dot11MeshHWMProotInterval =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) nconf->dot11MeshHWMProotInterval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL, mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) conf->dot11MeshHWMPconfirmationInterval =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) nconf->dot11MeshHWMPconfirmationInterval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) if (_chg_mesh_attr(NL80211_MESHCONF_POWER_MODE, mask)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) conf->power_mode = nconf->power_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) ieee80211_mps_local_status_update(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) if (_chg_mesh_attr(NL80211_MESHCONF_AWAKE_WINDOW, mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) conf->dot11MeshAwakeWindowDuration =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) nconf->dot11MeshAwakeWindowDuration;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) if (_chg_mesh_attr(NL80211_MESHCONF_PLINK_TIMEOUT, mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) conf->plink_timeout = nconf->plink_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) if (_chg_mesh_attr(NL80211_MESHCONF_CONNECTED_TO_GATE, mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) conf->dot11MeshConnectedToMeshGate =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) nconf->dot11MeshConnectedToMeshGate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) if (_chg_mesh_attr(NL80211_MESHCONF_NOLEARN, mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) conf->dot11MeshNolearn = nconf->dot11MeshNolearn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) if (_chg_mesh_attr(NL80211_MESHCONF_CONNECTED_TO_AS, mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) conf->dot11MeshConnectedToAuthServer =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) nconf->dot11MeshConnectedToAuthServer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) ieee80211_mbss_info_change_notify(sdata, BSS_CHANGED_BEACON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) static int ieee80211_join_mesh(struct wiphy *wiphy, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) const struct mesh_config *conf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) const struct mesh_setup *setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) memcpy(&ifmsh->mshcfg, conf, sizeof(struct mesh_config));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) err = copy_mesh_setup(ifmsh, setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) sdata->control_port_over_nl80211 = setup->control_port_over_nl80211;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) /* can mesh use other SMPS modes? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) sdata->smps_mode = IEEE80211_SMPS_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) sdata->needed_rx_chains = sdata->local->rx_chains;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) mutex_lock(&sdata->local->mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) err = ieee80211_vif_use_channel(sdata, &setup->chandef,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) IEEE80211_CHANCTX_SHARED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) mutex_unlock(&sdata->local->mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) return ieee80211_start_mesh(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) static int ieee80211_leave_mesh(struct wiphy *wiphy, struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) ieee80211_stop_mesh(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) mutex_lock(&sdata->local->mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) ieee80211_vif_release_channel(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) kfree(sdata->u.mesh.ie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) mutex_unlock(&sdata->local->mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) static int ieee80211_change_bss(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) struct bss_parameters *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) struct ieee80211_supported_band *sband;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) u32 changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) if (!sdata_dereference(sdata->u.ap.beacon, sdata))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) sband = ieee80211_get_sband(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) if (!sband)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) if (params->use_cts_prot >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) sdata->vif.bss_conf.use_cts_prot = params->use_cts_prot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) changed |= BSS_CHANGED_ERP_CTS_PROT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) if (params->use_short_preamble >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) sdata->vif.bss_conf.use_short_preamble =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) params->use_short_preamble;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) changed |= BSS_CHANGED_ERP_PREAMBLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) if (!sdata->vif.bss_conf.use_short_slot &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) (sband->band == NL80211_BAND_5GHZ ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) sband->band == NL80211_BAND_6GHZ)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) sdata->vif.bss_conf.use_short_slot = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) changed |= BSS_CHANGED_ERP_SLOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) if (params->use_short_slot_time >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) sdata->vif.bss_conf.use_short_slot =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) params->use_short_slot_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) changed |= BSS_CHANGED_ERP_SLOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) if (params->basic_rates) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) ieee80211_parse_bitrates(&sdata->vif.bss_conf.chandef,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) wiphy->bands[sband->band],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) params->basic_rates,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) params->basic_rates_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) &sdata->vif.bss_conf.basic_rates);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) changed |= BSS_CHANGED_BASIC_RATES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) ieee80211_check_rate_mask(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) if (params->ap_isolate >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) if (params->ap_isolate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) sdata->flags |= IEEE80211_SDATA_DONT_BRIDGE_PACKETS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) sdata->flags &= ~IEEE80211_SDATA_DONT_BRIDGE_PACKETS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) ieee80211_check_fast_rx_iface(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) if (params->ht_opmode >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) sdata->vif.bss_conf.ht_operation_mode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) (u16) params->ht_opmode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) changed |= BSS_CHANGED_HT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) if (params->p2p_ctwindow >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) sdata->vif.bss_conf.p2p_noa_attr.oppps_ctwindow &=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) ~IEEE80211_P2P_OPPPS_CTWINDOW_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) sdata->vif.bss_conf.p2p_noa_attr.oppps_ctwindow |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) params->p2p_ctwindow & IEEE80211_P2P_OPPPS_CTWINDOW_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) changed |= BSS_CHANGED_P2P_PS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) if (params->p2p_opp_ps > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) sdata->vif.bss_conf.p2p_noa_attr.oppps_ctwindow |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) IEEE80211_P2P_OPPPS_ENABLE_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) changed |= BSS_CHANGED_P2P_PS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) } else if (params->p2p_opp_ps == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) sdata->vif.bss_conf.p2p_noa_attr.oppps_ctwindow &=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) ~IEEE80211_P2P_OPPPS_ENABLE_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) changed |= BSS_CHANGED_P2P_PS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) ieee80211_bss_info_change_notify(sdata, changed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) static int ieee80211_set_txq_params(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) struct ieee80211_txq_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) struct ieee80211_local *local = wiphy_priv(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) struct ieee80211_tx_queue_params p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) if (!local->ops->conf_tx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) if (local->hw.queues < IEEE80211_NUM_ACS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) memset(&p, 0, sizeof(p));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) p.aifs = params->aifs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) p.cw_max = params->cwmax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) p.cw_min = params->cwmin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) p.txop = params->txop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) * Setting tx queue params disables u-apsd because it's only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) * called in master mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) p.uapsd = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) ieee80211_regulatory_limit_wmm_params(sdata, &p, params->ac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) sdata->tx_conf[params->ac] = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) if (drv_conf_tx(local, sdata, params->ac, &p)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) wiphy_debug(local->hw.wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) "failed to set TX queue parameters for AC %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) params->ac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_QOS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) static int ieee80211_suspend(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) struct cfg80211_wowlan *wowlan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) return __ieee80211_suspend(wiphy_priv(wiphy), wowlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) static int ieee80211_resume(struct wiphy *wiphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) return __ieee80211_resume(wiphy_priv(wiphy));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) #define ieee80211_suspend NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) #define ieee80211_resume NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) static int ieee80211_scan(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) struct cfg80211_scan_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) struct ieee80211_sub_if_data *sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) sdata = IEEE80211_WDEV_TO_SUB_IF(req->wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) switch (ieee80211_vif_type_p2p(&sdata->vif)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) case NL80211_IFTYPE_STATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) case NL80211_IFTYPE_ADHOC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) case NL80211_IFTYPE_MESH_POINT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) case NL80211_IFTYPE_P2P_CLIENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) case NL80211_IFTYPE_P2P_DEVICE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) case NL80211_IFTYPE_P2P_GO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) if (sdata->local->ops->hw_scan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) * FIXME: implement NoA while scanning in software,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) * for now fall through to allow scanning only when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) * beaconing hasn't been configured yet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) case NL80211_IFTYPE_AP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) * If the scan has been forced (and the driver supports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) * forcing), don't care about being beaconing already.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) * This will create problems to the attached stations (e.g. all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) * the frames sent while scanning on other channel will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) * lost)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) if (sdata->u.ap.beacon &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) (!(wiphy->features & NL80211_FEATURE_AP_SCAN) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) !(req->flags & NL80211_SCAN_FLAG_AP)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) case NL80211_IFTYPE_NAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) return ieee80211_request_scan(sdata, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) static void ieee80211_abort_scan(struct wiphy *wiphy, struct wireless_dev *wdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) ieee80211_scan_cancel(wiphy_priv(wiphy));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) ieee80211_sched_scan_start(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) struct cfg80211_sched_scan_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) if (!sdata->local->ops->sched_scan_start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) return ieee80211_request_sched_scan_start(sdata, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) ieee80211_sched_scan_stop(struct wiphy *wiphy, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) u64 reqid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) struct ieee80211_local *local = wiphy_priv(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) if (!local->ops->sched_scan_stop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) return ieee80211_request_sched_scan_stop(local);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) static int ieee80211_auth(struct wiphy *wiphy, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) struct cfg80211_auth_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) return ieee80211_mgd_auth(IEEE80211_DEV_TO_SUB_IF(dev), req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) struct cfg80211_assoc_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) return ieee80211_mgd_assoc(IEEE80211_DEV_TO_SUB_IF(dev), req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) static int ieee80211_deauth(struct wiphy *wiphy, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) struct cfg80211_deauth_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) return ieee80211_mgd_deauth(IEEE80211_DEV_TO_SUB_IF(dev), req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) static int ieee80211_disassoc(struct wiphy *wiphy, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) struct cfg80211_disassoc_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) return ieee80211_mgd_disassoc(IEEE80211_DEV_TO_SUB_IF(dev), req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) static int ieee80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) struct cfg80211_ibss_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) return ieee80211_ibss_join(IEEE80211_DEV_TO_SUB_IF(dev), params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) static int ieee80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) return ieee80211_ibss_leave(IEEE80211_DEV_TO_SUB_IF(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) static int ieee80211_join_ocb(struct wiphy *wiphy, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) struct ocb_setup *setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) return ieee80211_ocb_join(IEEE80211_DEV_TO_SUB_IF(dev), setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) static int ieee80211_leave_ocb(struct wiphy *wiphy, struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) return ieee80211_ocb_leave(IEEE80211_DEV_TO_SUB_IF(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) static int ieee80211_set_mcast_rate(struct wiphy *wiphy, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) int rate[NUM_NL80211_BANDS])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) memcpy(sdata->vif.bss_conf.mcast_rate, rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) sizeof(int) * NUM_NL80211_BANDS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_MCAST_RATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) struct ieee80211_local *local = wiphy_priv(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) ieee80211_check_fast_xmit_all(local);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) err = drv_set_frag_threshold(local, wiphy->frag_threshold);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) ieee80211_check_fast_xmit_all(local);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) if ((changed & WIPHY_PARAM_COVERAGE_CLASS) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) (changed & WIPHY_PARAM_DYN_ACK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) s16 coverage_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) coverage_class = changed & WIPHY_PARAM_COVERAGE_CLASS ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) wiphy->coverage_class : -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) err = drv_set_coverage_class(local, coverage_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) err = drv_set_rts_threshold(local, wiphy->rts_threshold);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) if (changed & WIPHY_PARAM_RETRY_SHORT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) if (wiphy->retry_short > IEEE80211_MAX_TX_RETRY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) local->hw.conf.short_frame_max_tx_count = wiphy->retry_short;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) if (changed & WIPHY_PARAM_RETRY_LONG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) if (wiphy->retry_long > IEEE80211_MAX_TX_RETRY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) local->hw.conf.long_frame_max_tx_count = wiphy->retry_long;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) if (changed &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) (WIPHY_PARAM_RETRY_SHORT | WIPHY_PARAM_RETRY_LONG))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_RETRY_LIMITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) if (changed & (WIPHY_PARAM_TXQ_LIMIT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) WIPHY_PARAM_TXQ_MEMORY_LIMIT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) WIPHY_PARAM_TXQ_QUANTUM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) ieee80211_txq_set_params(local);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) static int ieee80211_set_tx_power(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) struct wireless_dev *wdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) enum nl80211_tx_power_setting type, int mbm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) struct ieee80211_local *local = wiphy_priv(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) struct ieee80211_sub_if_data *sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) enum nl80211_tx_power_setting txp_type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) bool update_txp_type = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) bool has_monitor = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) if (wdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) if (sdata->vif.type == NL80211_IFTYPE_MONITOR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) sdata = rtnl_dereference(local->monitor_sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) if (!sdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) case NL80211_TX_POWER_AUTOMATIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) sdata->user_power_level = IEEE80211_UNSET_POWER_LEVEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) txp_type = NL80211_TX_POWER_LIMITED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) case NL80211_TX_POWER_LIMITED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) case NL80211_TX_POWER_FIXED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) if (mbm < 0 || (mbm % 100))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) sdata->user_power_level = MBM_TO_DBM(mbm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) if (txp_type != sdata->vif.bss_conf.txpower_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) update_txp_type = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) sdata->vif.bss_conf.txpower_type = txp_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) ieee80211_recalc_txpower(sdata, update_txp_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) case NL80211_TX_POWER_AUTOMATIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) local->user_power_level = IEEE80211_UNSET_POWER_LEVEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) txp_type = NL80211_TX_POWER_LIMITED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) case NL80211_TX_POWER_LIMITED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) case NL80211_TX_POWER_FIXED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) if (mbm < 0 || (mbm % 100))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) local->user_power_level = MBM_TO_DBM(mbm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) mutex_lock(&local->iflist_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) list_for_each_entry(sdata, &local->interfaces, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) if (sdata->vif.type == NL80211_IFTYPE_MONITOR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) has_monitor = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) sdata->user_power_level = local->user_power_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) if (txp_type != sdata->vif.bss_conf.txpower_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) update_txp_type = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) sdata->vif.bss_conf.txpower_type = txp_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) list_for_each_entry(sdata, &local->interfaces, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) ieee80211_recalc_txpower(sdata, update_txp_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) mutex_unlock(&local->iflist_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) if (has_monitor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) sdata = rtnl_dereference(local->monitor_sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) if (sdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) sdata->user_power_level = local->user_power_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) if (txp_type != sdata->vif.bss_conf.txpower_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) update_txp_type = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) sdata->vif.bss_conf.txpower_type = txp_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) ieee80211_recalc_txpower(sdata, update_txp_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) static int ieee80211_get_tx_power(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) struct wireless_dev *wdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) int *dbm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) struct ieee80211_local *local = wiphy_priv(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) if (local->ops->get_txpower)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) return drv_get_txpower(local, sdata, dbm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) if (!local->use_chanctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) *dbm = local->hw.conf.power_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) *dbm = sdata->vif.bss_conf.txpower;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) const u8 *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) memcpy(&sdata->u.wds.remote_addr, addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) static void ieee80211_rfkill_poll(struct wiphy *wiphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) struct ieee80211_local *local = wiphy_priv(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) drv_rfkill_poll(local);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) #ifdef CONFIG_NL80211_TESTMODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) static int ieee80211_testmode_cmd(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) struct wireless_dev *wdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) void *data, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) struct ieee80211_local *local = wiphy_priv(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) struct ieee80211_vif *vif = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) if (!local->ops->testmode_cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) if (wdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) struct ieee80211_sub_if_data *sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) if (sdata->flags & IEEE80211_SDATA_IN_DRIVER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) vif = &sdata->vif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) return local->ops->testmode_cmd(&local->hw, vif, data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) static int ieee80211_testmode_dump(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) struct netlink_callback *cb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) void *data, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) struct ieee80211_local *local = wiphy_priv(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) if (!local->ops->testmode_dump)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) return local->ops->testmode_dump(&local->hw, skb, cb, data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) int __ieee80211_request_smps_mgd(struct ieee80211_sub_if_data *sdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) enum ieee80211_smps_mode smps_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) const u8 *ap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) enum ieee80211_smps_mode old_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) struct sta_info *sta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) bool tdls_peer_found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) lockdep_assert_held(&sdata->wdev.mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) if (WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) old_req = sdata->u.mgd.req_smps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) sdata->u.mgd.req_smps = smps_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) if (old_req == smps_mode &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) smps_mode != IEEE80211_SMPS_AUTOMATIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) * If not associated, or current association is not an HT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) * association, there's no need to do anything, just store
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) * the new value until we associate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) if (!sdata->u.mgd.associated ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) ap = sdata->u.mgd.associated->bssid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) list_for_each_entry_rcu(sta, &sdata->local->sta_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) if (!sta->sta.tdls || sta->sdata != sdata || !sta->uploaded ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) !test_sta_flag(sta, WLAN_STA_AUTHORIZED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) tdls_peer_found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) if (smps_mode == IEEE80211_SMPS_AUTOMATIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) if (tdls_peer_found || !sdata->u.mgd.powersave)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) smps_mode = IEEE80211_SMPS_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) smps_mode = IEEE80211_SMPS_DYNAMIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) /* send SM PS frame to AP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) err = ieee80211_send_smps_action(sdata, smps_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) ap, ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) sdata->u.mgd.req_smps = old_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) else if (smps_mode != IEEE80211_SMPS_OFF && tdls_peer_found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) ieee80211_teardown_tdls_peers(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) bool enabled, int timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) if (sdata->vif.type != NL80211_IFTYPE_STATION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) if (!ieee80211_hw_check(&local->hw, SUPPORTS_PS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) if (enabled == sdata->u.mgd.powersave &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) timeout == local->dynamic_ps_forced_timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) sdata->u.mgd.powersave = enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) local->dynamic_ps_forced_timeout = timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) /* no change, but if automatic follow powersave */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) sdata_lock(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) __ieee80211_request_smps_mgd(sdata, sdata->u.mgd.req_smps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) sdata_unlock(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) if (ieee80211_hw_check(&local->hw, SUPPORTS_DYNAMIC_PS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) ieee80211_recalc_ps(local);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) ieee80211_recalc_ps_vif(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) ieee80211_check_fast_rx_iface(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) static int ieee80211_set_cqm_rssi_config(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) s32 rssi_thold, u32 rssi_hyst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) struct ieee80211_vif *vif = &sdata->vif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) if (rssi_thold == bss_conf->cqm_rssi_thold &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) rssi_hyst == bss_conf->cqm_rssi_hyst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) if (sdata->vif.driver_flags & IEEE80211_VIF_BEACON_FILTER &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) !(sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) bss_conf->cqm_rssi_thold = rssi_thold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) bss_conf->cqm_rssi_hyst = rssi_hyst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) bss_conf->cqm_rssi_low = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) bss_conf->cqm_rssi_high = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) sdata->u.mgd.last_cqm_event_signal = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) /* tell the driver upon association, unless already associated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) if (sdata->u.mgd.associated &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_CQM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) static int ieee80211_set_cqm_rssi_range_config(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) s32 rssi_low, s32 rssi_high)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) struct ieee80211_vif *vif = &sdata->vif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) if (sdata->vif.driver_flags & IEEE80211_VIF_BEACON_FILTER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) bss_conf->cqm_rssi_low = rssi_low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) bss_conf->cqm_rssi_high = rssi_high;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) bss_conf->cqm_rssi_thold = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) bss_conf->cqm_rssi_hyst = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) sdata->u.mgd.last_cqm_event_signal = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) /* tell the driver upon association, unless already associated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) if (sdata->u.mgd.associated &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_CQM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) const u8 *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) const struct cfg80211_bitrate_mask *mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) if (!ieee80211_sdata_running(sdata))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) return -ENETDOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) * If active validate the setting and reject it if it doesn't leave
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) * at least one basic rate usable, since we really have to be able
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) * to send something, and if we're an AP we have to be able to do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) * so at a basic rate so that all clients can receive it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) if (rcu_access_pointer(sdata->vif.chanctx_conf) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) sdata->vif.bss_conf.chandef.chan) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) u32 basic_rates = sdata->vif.bss_conf.basic_rates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) enum nl80211_band band = sdata->vif.bss_conf.chandef.chan->band;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) if (!(mask->control[band].legacy & basic_rates))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) if (ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) ret = drv_set_bitrate_mask(local, sdata, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) for (i = 0; i < NUM_NL80211_BANDS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) struct ieee80211_supported_band *sband = wiphy->bands[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) sdata->rc_rateidx_mask[i] = mask->control[i].legacy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) memcpy(sdata->rc_rateidx_mcs_mask[i], mask->control[i].ht_mcs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) sizeof(mask->control[i].ht_mcs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) memcpy(sdata->rc_rateidx_vht_mcs_mask[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) mask->control[i].vht_mcs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) sizeof(mask->control[i].vht_mcs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) sdata->rc_has_mcs_mask[i] = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) sdata->rc_has_vht_mcs_mask[i] = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) if (!sband)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) for (j = 0; j < IEEE80211_HT_MCS_MASK_LEN; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) if (sdata->rc_rateidx_mcs_mask[i][j] != 0xff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) sdata->rc_has_mcs_mask[i] = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) for (j = 0; j < NL80211_VHT_NSS_MAX; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) if (sdata->rc_rateidx_vht_mcs_mask[i][j] != 0xffff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) sdata->rc_has_vht_mcs_mask[i] = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) static int ieee80211_start_radar_detection(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) struct cfg80211_chan_def *chandef,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) u32 cac_time_ms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) struct ieee80211_local *local = sdata->local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) mutex_lock(&local->mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) if (!list_empty(&local->roc_list) || local->scanning) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) err = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) /* whatever, but channel contexts should not complain about that one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) sdata->smps_mode = IEEE80211_SMPS_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) sdata->needed_rx_chains = local->rx_chains;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) err = ieee80211_vif_use_channel(sdata, chandef,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) IEEE80211_CHANCTX_SHARED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) ieee80211_queue_delayed_work(&sdata->local->hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) &sdata->dfs_cac_timer_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) msecs_to_jiffies(cac_time_ms));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) mutex_unlock(&local->mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) static void ieee80211_end_cac(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) struct ieee80211_local *local = sdata->local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) mutex_lock(&local->mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) list_for_each_entry(sdata, &local->interfaces, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) /* it might be waiting for the local->mtx, but then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) * by the time it gets it, sdata->wdev.cac_started
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) * will no longer be true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) cancel_delayed_work(&sdata->dfs_cac_timer_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) if (sdata->wdev.cac_started) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) ieee80211_vif_release_channel(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) sdata->wdev.cac_started = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) mutex_unlock(&local->mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) static struct cfg80211_beacon_data *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) cfg80211_beacon_dup(struct cfg80211_beacon_data *beacon)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) struct cfg80211_beacon_data *new_beacon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) u8 *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) len = beacon->head_len + beacon->tail_len + beacon->beacon_ies_len +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) beacon->proberesp_ies_len + beacon->assocresp_ies_len +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) beacon->probe_resp_len + beacon->lci_len + beacon->civicloc_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) new_beacon = kzalloc(sizeof(*new_beacon) + len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) if (!new_beacon)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) pos = (u8 *)(new_beacon + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) if (beacon->head_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) new_beacon->head_len = beacon->head_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) new_beacon->head = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) memcpy(pos, beacon->head, beacon->head_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) pos += beacon->head_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) if (beacon->tail_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) new_beacon->tail_len = beacon->tail_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) new_beacon->tail = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) memcpy(pos, beacon->tail, beacon->tail_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) pos += beacon->tail_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) if (beacon->beacon_ies_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) new_beacon->beacon_ies_len = beacon->beacon_ies_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) new_beacon->beacon_ies = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) memcpy(pos, beacon->beacon_ies, beacon->beacon_ies_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) pos += beacon->beacon_ies_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) if (beacon->proberesp_ies_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) new_beacon->proberesp_ies_len = beacon->proberesp_ies_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) new_beacon->proberesp_ies = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) memcpy(pos, beacon->proberesp_ies, beacon->proberesp_ies_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) pos += beacon->proberesp_ies_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) if (beacon->assocresp_ies_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) new_beacon->assocresp_ies_len = beacon->assocresp_ies_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) new_beacon->assocresp_ies = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) memcpy(pos, beacon->assocresp_ies, beacon->assocresp_ies_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) pos += beacon->assocresp_ies_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) if (beacon->probe_resp_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) new_beacon->probe_resp_len = beacon->probe_resp_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) new_beacon->probe_resp = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) memcpy(pos, beacon->probe_resp, beacon->probe_resp_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) pos += beacon->probe_resp_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) /* might copy -1, meaning no changes requested */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) new_beacon->ftm_responder = beacon->ftm_responder;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) if (beacon->lci) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) new_beacon->lci_len = beacon->lci_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) new_beacon->lci = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) memcpy(pos, beacon->lci, beacon->lci_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) pos += beacon->lci_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) if (beacon->civicloc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) new_beacon->civicloc_len = beacon->civicloc_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) new_beacon->civicloc = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) memcpy(pos, beacon->civicloc, beacon->civicloc_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) pos += beacon->civicloc_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) return new_beacon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) void ieee80211_csa_finish(struct ieee80211_vif *vif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) ieee80211_queue_work(&sdata->local->hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) &sdata->csa_finalize_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) EXPORT_SYMBOL(ieee80211_csa_finish);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) static int ieee80211_set_after_csa_beacon(struct ieee80211_sub_if_data *sdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) u32 *changed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) switch (sdata->vif.type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) case NL80211_IFTYPE_AP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) kfree(sdata->u.ap.next_beacon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) sdata->u.ap.next_beacon = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) *changed |= err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) case NL80211_IFTYPE_ADHOC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) err = ieee80211_ibss_finish_csa(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) *changed |= err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) #ifdef CONFIG_MAC80211_MESH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) case NL80211_IFTYPE_MESH_POINT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) err = ieee80211_mesh_finish_csa(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) *changed |= err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) static int __ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) struct ieee80211_local *local = sdata->local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) u32 changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) sdata_assert_lock(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) lockdep_assert_held(&local->mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) lockdep_assert_held(&local->chanctx_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) * using reservation isn't immediate as it may be deferred until later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) * with multi-vif. once reservation is complete it will re-schedule the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) * work with no reserved_chanctx so verify chandef to check if it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) * completed successfully
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) if (sdata->reserved_chanctx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) * with multi-vif csa driver may call ieee80211_csa_finish()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) * many times while waiting for other interfaces to use their
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) * reservations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) if (sdata->reserved_ready)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) return ieee80211_vif_use_reserved_context(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) if (!cfg80211_chandef_identical(&sdata->vif.bss_conf.chandef,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) &sdata->csa_chandef))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) sdata->vif.csa_active = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) err = ieee80211_set_after_csa_beacon(sdata, &changed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) ieee80211_bss_info_change_notify(sdata, changed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) if (sdata->csa_block_tx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) ieee80211_wake_vif_queues(local, sdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) IEEE80211_QUEUE_STOP_REASON_CSA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) sdata->csa_block_tx = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) err = drv_post_channel_switch(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) cfg80211_ch_switch_notify(sdata->dev, &sdata->csa_chandef);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) static void ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) if (__ieee80211_csa_finalize(sdata)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) sdata_info(sdata, "failed to finalize CSA, disconnecting\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) cfg80211_stop_iface(sdata->local->hw.wiphy, &sdata->wdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) void ieee80211_csa_finalize_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) struct ieee80211_sub_if_data *sdata =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) container_of(work, struct ieee80211_sub_if_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) csa_finalize_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) struct ieee80211_local *local = sdata->local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) sdata_lock(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) mutex_lock(&local->mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) mutex_lock(&local->chanctx_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) /* AP might have been stopped while waiting for the lock. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) if (!sdata->vif.csa_active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) if (!ieee80211_sdata_running(sdata))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) ieee80211_csa_finalize(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) mutex_unlock(&local->chanctx_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) mutex_unlock(&local->mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) sdata_unlock(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) static int ieee80211_set_csa_beacon(struct ieee80211_sub_if_data *sdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) struct cfg80211_csa_settings *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) u32 *changed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) struct ieee80211_csa_settings csa = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) switch (sdata->vif.type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) case NL80211_IFTYPE_AP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) sdata->u.ap.next_beacon =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) cfg80211_beacon_dup(¶ms->beacon_after);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) if (!sdata->u.ap.next_beacon)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) * With a count of 0, we don't have to wait for any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) * TBTT before switching, so complete the CSA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) * immediately. In theory, with a count == 1 we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) * should delay the switch until just before the next
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) * TBTT, but that would complicate things so we switch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) * immediately too. If we would delay the switch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) * until the next TBTT, we would have to set the probe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) * response here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) * TODO: A channel switch with count <= 1 without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) * sending a CSA action frame is kind of useless,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) * because the clients won't know we're changing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) * channels. The action frame must be implemented
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) * either here or in the userspace.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) if (params->count <= 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) if ((params->n_counter_offsets_beacon >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) IEEE80211_MAX_CNTDWN_COUNTERS_NUM) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) (params->n_counter_offsets_presp >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) IEEE80211_MAX_CNTDWN_COUNTERS_NUM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) csa.counter_offsets_beacon = params->counter_offsets_beacon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) csa.counter_offsets_presp = params->counter_offsets_presp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) csa.n_counter_offsets_beacon = params->n_counter_offsets_beacon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) csa.n_counter_offsets_presp = params->n_counter_offsets_presp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) csa.count = params->count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) err = ieee80211_assign_beacon(sdata, ¶ms->beacon_csa, &csa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) kfree(sdata->u.ap.next_beacon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) *changed |= err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) case NL80211_IFTYPE_ADHOC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) if (!sdata->vif.bss_conf.ibss_joined)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) if (params->chandef.width != sdata->u.ibss.chandef.width)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) switch (params->chandef.width) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) case NL80211_CHAN_WIDTH_40:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) if (cfg80211_get_chandef_type(¶ms->chandef) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) cfg80211_get_chandef_type(&sdata->u.ibss.chandef))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) case NL80211_CHAN_WIDTH_5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) case NL80211_CHAN_WIDTH_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) case NL80211_CHAN_WIDTH_20_NOHT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) case NL80211_CHAN_WIDTH_20:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) /* changes into another band are not supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) if (sdata->u.ibss.chandef.chan->band !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) params->chandef.chan->band)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) /* see comments in the NL80211_IFTYPE_AP block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) if (params->count > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) err = ieee80211_ibss_csa_beacon(sdata, params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) *changed |= err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) ieee80211_send_action_csa(sdata, params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) #ifdef CONFIG_MAC80211_MESH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) case NL80211_IFTYPE_MESH_POINT: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) if (params->chandef.width != sdata->vif.bss_conf.chandef.width)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) /* changes into another band are not supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) if (sdata->vif.bss_conf.chandef.chan->band !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) params->chandef.chan->band)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) if (ifmsh->csa_role == IEEE80211_MESH_CSA_ROLE_NONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) ifmsh->csa_role = IEEE80211_MESH_CSA_ROLE_INIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) if (!ifmsh->pre_value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) ifmsh->pre_value = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) ifmsh->pre_value++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) /* see comments in the NL80211_IFTYPE_AP block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) if (params->count > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) err = ieee80211_mesh_csa_beacon(sdata, params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) ifmsh->csa_role = IEEE80211_MESH_CSA_ROLE_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) *changed |= err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) if (ifmsh->csa_role == IEEE80211_MESH_CSA_ROLE_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) ieee80211_send_action_csa(sdata, params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) struct cfg80211_csa_settings *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) struct ieee80211_local *local = sdata->local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) struct ieee80211_channel_switch ch_switch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) struct ieee80211_chanctx_conf *conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) struct ieee80211_chanctx *chanctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) u32 changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) sdata_assert_lock(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) lockdep_assert_held(&local->mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) if (!list_empty(&local->roc_list) || local->scanning)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) if (sdata->wdev.cac_started)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) if (cfg80211_chandef_identical(¶ms->chandef,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) &sdata->vif.bss_conf.chandef))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) /* don't allow another channel switch if one is already active. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) if (sdata->vif.csa_active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) mutex_lock(&local->chanctx_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) lockdep_is_held(&local->chanctx_mtx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) if (!conf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) err = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) if (params->chandef.chan->freq_offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) /* this may work, but is untested */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) chanctx = container_of(conf, struct ieee80211_chanctx, conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) ch_switch.timestamp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) ch_switch.device_timestamp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) ch_switch.block_tx = params->block_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) ch_switch.chandef = params->chandef;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) ch_switch.count = params->count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) err = drv_pre_channel_switch(sdata, &ch_switch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) err = ieee80211_vif_reserve_chanctx(sdata, ¶ms->chandef,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) chanctx->mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) params->radar_required);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) /* if reservation is invalid then this will fail */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) err = ieee80211_check_combinations(sdata, NULL, chanctx->mode, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) ieee80211_vif_unreserve_chanctx(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) err = ieee80211_set_csa_beacon(sdata, params, &changed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) ieee80211_vif_unreserve_chanctx(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) sdata->csa_chandef = params->chandef;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) sdata->csa_block_tx = params->block_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) sdata->vif.csa_active = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) if (sdata->csa_block_tx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) ieee80211_stop_vif_queues(local, sdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) IEEE80211_QUEUE_STOP_REASON_CSA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) cfg80211_ch_switch_started_notify(sdata->dev, &sdata->csa_chandef,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) params->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) if (changed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) ieee80211_bss_info_change_notify(sdata, changed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) drv_channel_switch_beacon(sdata, ¶ms->chandef);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) /* if the beacon didn't change, we can finalize immediately */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) ieee80211_csa_finalize(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) mutex_unlock(&local->chanctx_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) struct cfg80211_csa_settings *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) struct ieee80211_local *local = sdata->local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) mutex_lock(&local->mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) err = __ieee80211_channel_switch(wiphy, dev, params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) mutex_unlock(&local->mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) u64 ieee80211_mgmt_tx_cookie(struct ieee80211_local *local)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) lockdep_assert_held(&local->mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) local->roc_cookie_counter++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) /* wow, you wrapped 64 bits ... more likely a bug */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) if (WARN_ON(local->roc_cookie_counter == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) local->roc_cookie_counter++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) return local->roc_cookie_counter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) int ieee80211_attach_ack_skb(struct ieee80211_local *local, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) u64 *cookie, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) unsigned long spin_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) struct sk_buff *ack_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) ack_skb = skb_copy(skb, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) if (!ack_skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) spin_lock_irqsave(&local->ack_status_lock, spin_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) id = idr_alloc(&local->ack_status_frames, ack_skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) 1, 0x2000, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) spin_unlock_irqrestore(&local->ack_status_lock, spin_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) if (id < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) kfree_skb(ack_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) IEEE80211_SKB_CB(skb)->ack_frame_id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) *cookie = ieee80211_mgmt_tx_cookie(local);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) IEEE80211_SKB_CB(ack_skb)->ack.cookie = *cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) ieee80211_update_mgmt_frame_registrations(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) struct wireless_dev *wdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) struct mgmt_frame_regs *upd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) struct ieee80211_local *local = wiphy_priv(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) u32 preq_mask = BIT(IEEE80211_STYPE_PROBE_REQ >> 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) u32 action_mask = BIT(IEEE80211_STYPE_ACTION >> 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) bool global_change, intf_change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) global_change =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) (local->probe_req_reg != !!(upd->global_stypes & preq_mask)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) (local->rx_mcast_action_reg !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) !!(upd->global_mcast_stypes & action_mask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) local->probe_req_reg = upd->global_stypes & preq_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) local->rx_mcast_action_reg = upd->global_mcast_stypes & action_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) intf_change = (sdata->vif.probe_req_reg !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) !!(upd->interface_stypes & preq_mask)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) (sdata->vif.rx_mcast_action_reg !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) !!(upd->interface_mcast_stypes & action_mask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) sdata->vif.probe_req_reg = upd->interface_stypes & preq_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) sdata->vif.rx_mcast_action_reg =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) upd->interface_mcast_stypes & action_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) if (!local->open_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) if (intf_change && ieee80211_sdata_running(sdata))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) drv_config_iface_filter(local, sdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) sdata->vif.probe_req_reg ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) FIF_PROBE_REQ : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) FIF_PROBE_REQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) if (global_change)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) ieee80211_configure_filter(local);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) static int ieee80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) struct ieee80211_local *local = wiphy_priv(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) if (local->started)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) return drv_set_antenna(local, tx_ant, rx_ant);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) static int ieee80211_get_antenna(struct wiphy *wiphy, u32 *tx_ant, u32 *rx_ant)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) struct ieee80211_local *local = wiphy_priv(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) return drv_get_antenna(local, tx_ant, rx_ant);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) static int ieee80211_set_rekey_data(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) struct cfg80211_gtk_rekey_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) struct ieee80211_local *local = wiphy_priv(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) if (!local->ops->set_rekey_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) drv_set_rekey_data(local, sdata, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) const u8 *peer, u64 *cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) struct ieee80211_local *local = sdata->local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) struct ieee80211_qos_hdr *nullfunc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) int size = sizeof(*nullfunc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) __le16 fc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) bool qos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) struct ieee80211_tx_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) struct sta_info *sta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) struct ieee80211_chanctx_conf *chanctx_conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) enum nl80211_band band;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) /* the lock is needed to assign the cookie later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) mutex_lock(&local->mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) if (WARN_ON(!chanctx_conf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) band = chanctx_conf->def.chan->band;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) sta = sta_info_get_bss(sdata, peer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) if (sta) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) qos = sta->sta.wme;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) ret = -ENOLINK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) if (qos) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) fc = cpu_to_le16(IEEE80211_FTYPE_DATA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) IEEE80211_STYPE_QOS_NULLFUNC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) IEEE80211_FCTL_FROMDS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) size -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) fc = cpu_to_le16(IEEE80211_FTYPE_DATA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) IEEE80211_STYPE_NULLFUNC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) IEEE80211_FCTL_FROMDS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) skb = dev_alloc_skb(local->hw.extra_tx_headroom + size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) if (!skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675) skb->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) skb_reserve(skb, local->hw.extra_tx_headroom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) nullfunc = skb_put(skb, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) nullfunc->frame_control = fc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) nullfunc->duration_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) memcpy(nullfunc->addr1, sta->sta.addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) memcpy(nullfunc->addr2, sdata->vif.addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) memcpy(nullfunc->addr3, sdata->vif.addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) nullfunc->seq_ctrl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) info = IEEE80211_SKB_CB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) IEEE80211_TX_INTFL_NL80211_FRAME_TX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) info->band = band;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) skb_set_queue_mapping(skb, IEEE80211_AC_VO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) skb->priority = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) if (qos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) nullfunc->qos_ctrl = cpu_to_le16(7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698) ret = ieee80211_attach_ack_skb(local, skb, cookie, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704) local_bh_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705) ieee80211_xmit(sdata, sta, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) local_bh_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) mutex_unlock(&local->mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) static int ieee80211_cfg_get_channel(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) struct wireless_dev *wdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) struct cfg80211_chan_def *chandef)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) struct ieee80211_local *local = wiphy_priv(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) struct ieee80211_chanctx_conf *chanctx_conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) int ret = -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) if (chanctx_conf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) *chandef = sdata->vif.bss_conf.chandef;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) } else if (local->open_count > 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) local->open_count == local->monitors &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) sdata->vif.type == NL80211_IFTYPE_MONITOR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) if (local->use_chanctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) *chandef = local->monitor_chandef;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) *chandef = local->_oper_chandef;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) static void ieee80211_set_wakeup(struct wiphy *wiphy, bool enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) drv_set_wakeup(wiphy_priv(wiphy), enabled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) static int ieee80211_set_qos_map(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753) struct cfg80211_qos_map *qos_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756) struct mac80211_qos_map *new_qos_map, *old_qos_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) if (qos_map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759) new_qos_map = kzalloc(sizeof(*new_qos_map), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760) if (!new_qos_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) memcpy(&new_qos_map->qos_map, qos_map, sizeof(*qos_map));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) /* A NULL qos_map was passed to disable QoS mapping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) new_qos_map = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) old_qos_map = sdata_dereference(sdata->qos_map, sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) rcu_assign_pointer(sdata->qos_map, new_qos_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) if (old_qos_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) kfree_rcu(old_qos_map, rcu_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) static int ieee80211_set_ap_chanwidth(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) struct cfg80211_chan_def *chandef)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) u32 changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) ret = ieee80211_vif_change_bandwidth(sdata, chandef, &changed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786) ieee80211_bss_info_change_notify(sdata, changed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) static int ieee80211_add_tx_ts(struct wiphy *wiphy, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) u8 tsid, const u8 *peer, u8 up,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) u16 admitted_time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) int ac = ieee802_1d_to_ac[up];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) if (sdata->vif.type != NL80211_IFTYPE_STATION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) if (!(sdata->wmm_acm & BIT(up)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) if (ifmgd->tx_tspec[ac].admitted_time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) if (admitted_time) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) ifmgd->tx_tspec[ac].admitted_time = 32 * admitted_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) ifmgd->tx_tspec[ac].tsid = tsid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) ifmgd->tx_tspec[ac].up = up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) static int ieee80211_del_tx_ts(struct wiphy *wiphy, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) u8 tsid, const u8 *peer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) struct ieee80211_local *local = wiphy_priv(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) int ac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825) for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) struct ieee80211_sta_tx_tspec *tx_tspec = &ifmgd->tx_tspec[ac];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) /* skip unused entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) if (!tx_tspec->admitted_time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) if (tx_tspec->tsid != tsid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835) /* due to this new packets will be reassigned to non-ACM ACs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836) tx_tspec->up = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838) /* Make sure that all packets have been sent to avoid to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) * restore the QoS params on packets that are still on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) * queues.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) synchronize_net();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) ieee80211_flush_queues(local, sdata, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845) /* restore the normal QoS parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) * (unconditionally to avoid races)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) tx_tspec->action = TX_TSPEC_ACTION_STOP_DOWNGRADE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) tx_tspec->downgraded = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) ieee80211_sta_handle_tspec_ac_params(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852) /* finally clear all the data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) memset(tx_tspec, 0, sizeof(*tx_tspec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) void ieee80211_nan_func_terminated(struct ieee80211_vif *vif,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) u8 inst_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) enum nl80211_nan_func_term_reason reason,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867) struct cfg80211_nan_func *func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) u64 cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870) if (WARN_ON(vif->type != NL80211_IFTYPE_NAN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873) spin_lock_bh(&sdata->u.nan.func_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) func = idr_find(&sdata->u.nan.function_inst_ids, inst_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) if (WARN_ON(!func)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877) spin_unlock_bh(&sdata->u.nan.func_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881) cookie = func->cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) idr_remove(&sdata->u.nan.function_inst_ids, inst_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884) spin_unlock_bh(&sdata->u.nan.func_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) cfg80211_free_nan_func(func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888) cfg80211_nan_func_terminated(ieee80211_vif_to_wdev(vif), inst_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889) reason, cookie, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891) EXPORT_SYMBOL(ieee80211_nan_func_terminated);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893) void ieee80211_nan_func_match(struct ieee80211_vif *vif,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894) struct cfg80211_nan_match_params *match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897) struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898) struct cfg80211_nan_func *func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900) if (WARN_ON(vif->type != NL80211_IFTYPE_NAN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) spin_lock_bh(&sdata->u.nan.func_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905) func = idr_find(&sdata->u.nan.function_inst_ids, match->inst_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) if (WARN_ON(!func)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) spin_unlock_bh(&sdata->u.nan.func_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910) match->cookie = func->cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912) spin_unlock_bh(&sdata->u.nan.func_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) cfg80211_nan_match(ieee80211_vif_to_wdev(vif), match, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916) EXPORT_SYMBOL(ieee80211_nan_func_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918) static int ieee80211_set_multicast_to_unicast(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919) struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920) const bool enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924) sdata->u.ap.multicast_to_unicast = enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929) void ieee80211_fill_txq_stats(struct cfg80211_txq_stats *txqstats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930) struct txq_info *txqi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932) if (!(txqstats->filled & BIT(NL80211_TXQ_STATS_BACKLOG_BYTES))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933) txqstats->filled |= BIT(NL80211_TXQ_STATS_BACKLOG_BYTES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934) txqstats->backlog_bytes = txqi->tin.backlog_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937) if (!(txqstats->filled & BIT(NL80211_TXQ_STATS_BACKLOG_PACKETS))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938) txqstats->filled |= BIT(NL80211_TXQ_STATS_BACKLOG_PACKETS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939) txqstats->backlog_packets = txqi->tin.backlog_packets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942) if (!(txqstats->filled & BIT(NL80211_TXQ_STATS_FLOWS))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943) txqstats->filled |= BIT(NL80211_TXQ_STATS_FLOWS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944) txqstats->flows = txqi->tin.flows;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947) if (!(txqstats->filled & BIT(NL80211_TXQ_STATS_DROPS))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948) txqstats->filled |= BIT(NL80211_TXQ_STATS_DROPS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949) txqstats->drops = txqi->cstats.drop_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952) if (!(txqstats->filled & BIT(NL80211_TXQ_STATS_ECN_MARKS))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953) txqstats->filled |= BIT(NL80211_TXQ_STATS_ECN_MARKS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954) txqstats->ecn_marks = txqi->cstats.ecn_mark;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957) if (!(txqstats->filled & BIT(NL80211_TXQ_STATS_OVERLIMIT))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958) txqstats->filled |= BIT(NL80211_TXQ_STATS_OVERLIMIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959) txqstats->overlimit = txqi->tin.overlimit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962) if (!(txqstats->filled & BIT(NL80211_TXQ_STATS_COLLISIONS))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963) txqstats->filled |= BIT(NL80211_TXQ_STATS_COLLISIONS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964) txqstats->collisions = txqi->tin.collisions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967) if (!(txqstats->filled & BIT(NL80211_TXQ_STATS_TX_BYTES))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968) txqstats->filled |= BIT(NL80211_TXQ_STATS_TX_BYTES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969) txqstats->tx_bytes = txqi->tin.tx_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3972) if (!(txqstats->filled & BIT(NL80211_TXQ_STATS_TX_PACKETS))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3973) txqstats->filled |= BIT(NL80211_TXQ_STATS_TX_PACKETS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3974) txqstats->tx_packets = txqi->tin.tx_packets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3978) static int ieee80211_get_txq_stats(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3979) struct wireless_dev *wdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3980) struct cfg80211_txq_stats *txqstats)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3981) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3982) struct ieee80211_local *local = wiphy_priv(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3983) struct ieee80211_sub_if_data *sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3984) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3986) if (!local->ops->wake_tx_queue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3987) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3989) spin_lock_bh(&local->fq.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3990) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3992) if (wdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3993) sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3994) if (!sdata->vif.txq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3995) ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3996) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3998) ieee80211_fill_txq_stats(txqstats, to_txq_info(sdata->vif.txq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3999) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4000) /* phy stats */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4001) txqstats->filled |= BIT(NL80211_TXQ_STATS_BACKLOG_PACKETS) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4002) BIT(NL80211_TXQ_STATS_BACKLOG_BYTES) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4003) BIT(NL80211_TXQ_STATS_OVERLIMIT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4004) BIT(NL80211_TXQ_STATS_OVERMEMORY) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4005) BIT(NL80211_TXQ_STATS_COLLISIONS) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4006) BIT(NL80211_TXQ_STATS_MAX_FLOWS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4007) txqstats->backlog_packets = local->fq.backlog;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4008) txqstats->backlog_bytes = local->fq.memory_usage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4009) txqstats->overlimit = local->fq.overlimit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4010) txqstats->overmemory = local->fq.overmemory;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4011) txqstats->collisions = local->fq.collisions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4012) txqstats->max_flows = local->fq.flows_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4015) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4016) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4017) spin_unlock_bh(&local->fq.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4019) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4020) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4022) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4023) ieee80211_get_ftm_responder_stats(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4024) struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4025) struct cfg80211_ftm_responder_stats *ftm_stats)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4026) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4027) struct ieee80211_local *local = wiphy_priv(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4028) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4030) return drv_get_ftm_responder_stats(local, sdata, ftm_stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4031) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4033) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4034) ieee80211_start_pmsr(struct wiphy *wiphy, struct wireless_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4035) struct cfg80211_pmsr_request *request)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4036) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4037) struct ieee80211_local *local = wiphy_priv(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4038) struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4040) return drv_start_pmsr(local, sdata, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4041) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4043) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4044) ieee80211_abort_pmsr(struct wiphy *wiphy, struct wireless_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4045) struct cfg80211_pmsr_request *request)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4046) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4047) struct ieee80211_local *local = wiphy_priv(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4048) struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4050) return drv_abort_pmsr(local, sdata, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4051) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4053) static int ieee80211_set_tid_config(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4054) struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4055) struct cfg80211_tid_config *tid_conf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4056) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4057) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4058) struct sta_info *sta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4059) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4061) if (!sdata->local->ops->set_tid_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4062) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4064) if (!tid_conf->peer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4065) return drv_set_tid_config(sdata->local, sdata, NULL, tid_conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4067) mutex_lock(&sdata->local->sta_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4068) sta = sta_info_get_bss(sdata, tid_conf->peer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4069) if (!sta) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4070) mutex_unlock(&sdata->local->sta_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4071) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4074) ret = drv_set_tid_config(sdata->local, sdata, &sta->sta, tid_conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4075) mutex_unlock(&sdata->local->sta_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4077) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4080) static int ieee80211_reset_tid_config(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4081) struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4082) const u8 *peer, u8 tids)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4083) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4084) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4085) struct sta_info *sta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4086) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4088) if (!sdata->local->ops->reset_tid_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4089) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4091) if (!peer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4092) return drv_reset_tid_config(sdata->local, sdata, NULL, tids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4094) mutex_lock(&sdata->local->sta_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4095) sta = sta_info_get_bss(sdata, peer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4096) if (!sta) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4097) mutex_unlock(&sdata->local->sta_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4098) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4101) ret = drv_reset_tid_config(sdata->local, sdata, &sta->sta, tids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4102) mutex_unlock(&sdata->local->sta_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4104) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4107) const struct cfg80211_ops mac80211_config_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4108) .add_virtual_intf = ieee80211_add_iface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4109) .del_virtual_intf = ieee80211_del_iface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4110) .change_virtual_intf = ieee80211_change_iface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4111) .start_p2p_device = ieee80211_start_p2p_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4112) .stop_p2p_device = ieee80211_stop_p2p_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4113) .add_key = ieee80211_add_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4114) .del_key = ieee80211_del_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4115) .get_key = ieee80211_get_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4116) .set_default_key = ieee80211_config_default_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4117) .set_default_mgmt_key = ieee80211_config_default_mgmt_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4118) .set_default_beacon_key = ieee80211_config_default_beacon_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4119) .start_ap = ieee80211_start_ap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4120) .change_beacon = ieee80211_change_beacon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4121) .stop_ap = ieee80211_stop_ap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4122) .add_station = ieee80211_add_station,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4123) .del_station = ieee80211_del_station,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4124) .change_station = ieee80211_change_station,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4125) .get_station = ieee80211_get_station,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4126) .dump_station = ieee80211_dump_station,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4127) .dump_survey = ieee80211_dump_survey,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4128) #ifdef CONFIG_MAC80211_MESH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4129) .add_mpath = ieee80211_add_mpath,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4130) .del_mpath = ieee80211_del_mpath,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4131) .change_mpath = ieee80211_change_mpath,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4132) .get_mpath = ieee80211_get_mpath,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4133) .dump_mpath = ieee80211_dump_mpath,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4134) .get_mpp = ieee80211_get_mpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4135) .dump_mpp = ieee80211_dump_mpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4136) .update_mesh_config = ieee80211_update_mesh_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4137) .get_mesh_config = ieee80211_get_mesh_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4138) .join_mesh = ieee80211_join_mesh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4139) .leave_mesh = ieee80211_leave_mesh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4140) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4141) .join_ocb = ieee80211_join_ocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4142) .leave_ocb = ieee80211_leave_ocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4143) .change_bss = ieee80211_change_bss,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4144) .set_txq_params = ieee80211_set_txq_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4145) .set_monitor_channel = ieee80211_set_monitor_channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4146) .suspend = ieee80211_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4147) .resume = ieee80211_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4148) .scan = ieee80211_scan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4149) .abort_scan = ieee80211_abort_scan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4150) .sched_scan_start = ieee80211_sched_scan_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4151) .sched_scan_stop = ieee80211_sched_scan_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4152) .auth = ieee80211_auth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4153) .assoc = ieee80211_assoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4154) .deauth = ieee80211_deauth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4155) .disassoc = ieee80211_disassoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4156) .join_ibss = ieee80211_join_ibss,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4157) .leave_ibss = ieee80211_leave_ibss,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4158) .set_mcast_rate = ieee80211_set_mcast_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4159) .set_wiphy_params = ieee80211_set_wiphy_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4160) .set_tx_power = ieee80211_set_tx_power,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4161) .get_tx_power = ieee80211_get_tx_power,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4162) .set_wds_peer = ieee80211_set_wds_peer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4163) .rfkill_poll = ieee80211_rfkill_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4164) CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4165) CFG80211_TESTMODE_DUMP(ieee80211_testmode_dump)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4166) .set_power_mgmt = ieee80211_set_power_mgmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4167) .set_bitrate_mask = ieee80211_set_bitrate_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4168) .remain_on_channel = ieee80211_remain_on_channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4169) .cancel_remain_on_channel = ieee80211_cancel_remain_on_channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4170) .mgmt_tx = ieee80211_mgmt_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4171) .mgmt_tx_cancel_wait = ieee80211_mgmt_tx_cancel_wait,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4172) .set_cqm_rssi_config = ieee80211_set_cqm_rssi_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4173) .set_cqm_rssi_range_config = ieee80211_set_cqm_rssi_range_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4174) .update_mgmt_frame_registrations =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4175) ieee80211_update_mgmt_frame_registrations,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4176) .set_antenna = ieee80211_set_antenna,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4177) .get_antenna = ieee80211_get_antenna,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4178) .set_rekey_data = ieee80211_set_rekey_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4179) .tdls_oper = ieee80211_tdls_oper,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4180) .tdls_mgmt = ieee80211_tdls_mgmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4181) .tdls_channel_switch = ieee80211_tdls_channel_switch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4182) .tdls_cancel_channel_switch = ieee80211_tdls_cancel_channel_switch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4183) .probe_client = ieee80211_probe_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4184) .set_noack_map = ieee80211_set_noack_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4185) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4186) .set_wakeup = ieee80211_set_wakeup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4187) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4188) .get_channel = ieee80211_cfg_get_channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4189) .start_radar_detection = ieee80211_start_radar_detection,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4190) .end_cac = ieee80211_end_cac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4191) .channel_switch = ieee80211_channel_switch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4192) .set_qos_map = ieee80211_set_qos_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4193) .set_ap_chanwidth = ieee80211_set_ap_chanwidth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4194) .add_tx_ts = ieee80211_add_tx_ts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4195) .del_tx_ts = ieee80211_del_tx_ts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4196) .start_nan = ieee80211_start_nan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4197) .stop_nan = ieee80211_stop_nan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4198) .nan_change_conf = ieee80211_nan_change_conf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4199) .add_nan_func = ieee80211_add_nan_func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4200) .del_nan_func = ieee80211_del_nan_func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4201) .set_multicast_to_unicast = ieee80211_set_multicast_to_unicast,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4202) .tx_control_port = ieee80211_tx_control_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4203) .get_txq_stats = ieee80211_get_txq_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4204) .get_ftm_responder_stats = ieee80211_get_ftm_responder_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4205) .start_pmsr = ieee80211_start_pmsr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4206) .abort_pmsr = ieee80211_abort_pmsr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4207) .probe_mesh_link = ieee80211_probe_mesh_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4208) .set_tid_config = ieee80211_set_tid_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4209) .reset_tid_config = ieee80211_reset_tid_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4210) };