summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorJakub Kicinski <kuba@kernel.org>2026-03-05 02:30:04 +0300
committerJakub Kicinski <kuba@kernel.org>2026-03-05 02:30:05 +0300
commitdbbda7dd6835d1ac7ee7ea095be306ad9c90f7b4 (patch)
tree7c3eb8fb22ec6f648b3d8b3750ae7e8085b182e4 /net
parent4ad96a7c9e2cebbbdc68369438a736a133539f1d (diff)
parent44d93cf1abb6a85d65c3b4b027c82d44263de6a5 (diff)
downloadlinux-dbbda7dd6835d1ac7ee7ea095be306ad9c90f7b4.tar.xz
Merge tag 'wireless-next-2026-03-04' of https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next
Johannes Berg says: ==================== Notable features this time: - cfg80211/mac80211 - finished assoc frame encryption/EPPKE/802.1X-over-auth (also hwsim) - radar detection improvements - 6 GHz incumbent signal detection APIs - multi-link support for FILS, probe response templates and client probling - ath12k: - monitor mode support on IPQ5332 - basic hwmon temperature reporting * tag 'wireless-next-2026-03-04' of https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next: (38 commits) wifi: UHR: define DPS/DBE/P-EDCA elements and fix size parsing wifi: mac80211_hwsim: change hwsim_class to a const struct wifi: mac80211: give the AP more time for EPPKE as well wifi: ath12k: Remove the unused argument from the Rx data path wifi: ath12k: Enable monitor mode support on IPQ5332 wifi: ath12k: Set up MLO after SSR wifi: ath11k: Silence remoteproc probe deferral prints wifi: cfg80211: support key installation on non-netdev wdevs wifi: cfg80211: make cluster id an array wifi: mac80211: update outdated comment wifi: mac80211: Advertise IEEE 802.1X authentication support wifi: mac80211: Add support for IEEE 802.1X authentication protocol in non-AP STA mode wifi: cfg80211: add support for IEEE 802.1X Authentication Protocol wifi: mac80211: Advertise EPPKE support based on driver capabilities wifi: mac80211_hwsim: Advertise support for (Re)Association frame encryption wifi: mac80211: Fix AAD/Nonce computation for management frames with MLO wifi: rt2x00: use generic nvmem_cell_get wifi: mac80211: fetch unsolicited probe response template by link ID wifi: mac80211: fetch FILS discovery template by link ID wifi: nl80211: don't allow DFS channels for NAN ... ==================== Link: https://patch.msgid.link/20260304113707.175181-3-johannes@sipsolutions.net Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/cfg.c99
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/main.c10
-rw-r--r--net/mac80211/mlme.c81
-rw-r--r--net/mac80211/rx.c5
-rw-r--r--net/mac80211/sta_info.c4
-rw-r--r--net/mac80211/tx.c77
-rw-r--r--net/mac80211/wpa.c55
-rw-r--r--net/wireless/chan.c29
-rw-r--r--net/wireless/core.c1
-rw-r--r--net/wireless/core.h4
-rw-r--r--net/wireless/ibss.c4
-rw-r--r--net/wireless/mlme.c51
-rw-r--r--net/wireless/nl80211.c279
-rw-r--r--net/wireless/nl80211.h5
-rw-r--r--net/wireless/pmsr.c5
-rw-r--r--net/wireless/rdev-ops.h62
-rw-r--r--net/wireless/sme.c4
-rw-r--r--net/wireless/sysfs.c33
-rw-r--r--net/wireless/trace.h185
-rw-r--r--net/wireless/util.c4
-rw-r--r--net/wireless/wext-compat.c12
22 files changed, 695 insertions, 316 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index b92b4a5c2636..ee64ac8e0f61 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -330,7 +330,6 @@ static void ieee80211_stop_p2p_device(struct wiphy *wiphy,
static void ieee80211_nan_conf_free(struct cfg80211_nan_conf *conf)
{
- kfree(conf->cluster_id);
kfree(conf->extra_nan_attrs);
kfree(conf->vendor_elems);
memset(conf, 0, sizeof(*conf));
@@ -372,9 +371,6 @@ static int ieee80211_nan_conf_copy(struct cfg80211_nan_conf *dst,
memcpy(&dst->band_cfgs, &src->band_cfgs,
sizeof(dst->band_cfgs));
- kfree(dst->cluster_id);
- dst->cluster_id = NULL;
-
kfree(dst->extra_nan_attrs);
dst->extra_nan_attrs = NULL;
dst->extra_nan_attrs_len = 0;
@@ -383,12 +379,8 @@ static int ieee80211_nan_conf_copy(struct cfg80211_nan_conf *dst,
dst->vendor_elems = NULL;
dst->vendor_elems_len = 0;
- if (src->cluster_id) {
- dst->cluster_id = kmemdup(src->cluster_id, ETH_ALEN,
- GFP_KERNEL);
- if (!dst->cluster_id)
- goto no_mem;
- }
+ if (is_zero_ether_addr(dst->cluster_id))
+ ether_addr_copy(dst->cluster_id, src->cluster_id);
if (src->extra_nan_attrs && src->extra_nan_attrs_len) {
dst->extra_nan_attrs = kmemdup(src->extra_nan_attrs,
@@ -616,11 +608,11 @@ static int ieee80211_set_tx(struct ieee80211_sub_if_data *sdata,
return ret;
}
-static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
+static int ieee80211_add_key(struct wiphy *wiphy, struct wireless_dev *wdev,
int link_id, u8 key_idx, bool pairwise,
const u8 *mac_addr, struct key_params *params)
{
- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
struct ieee80211_link_data *link =
ieee80211_link_or_deflink(sdata, link_id, false);
struct ieee80211_local *local = sdata->local;
@@ -798,11 +790,11 @@ ieee80211_lookup_key(struct ieee80211_sub_if_data *sdata, int link_id,
return NULL;
}
-static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
+static int ieee80211_del_key(struct wiphy *wiphy, struct wireless_dev *wdev,
int link_id, u8 key_idx, bool pairwise,
const u8 *mac_addr)
{
- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
struct ieee80211_local *local = sdata->local;
struct ieee80211_key *key;
@@ -817,7 +809,7 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
return 0;
}
-static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
+static int ieee80211_get_key(struct wiphy *wiphy, struct wireless_dev *wdev,
int link_id, u8 key_idx, bool pairwise,
const u8 *mac_addr, void *cookie,
void (*callback)(void *cookie,
@@ -833,7 +825,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
int err = -ENOENT;
struct ieee80211_key_seq kseq = {};
- sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
rcu_read_lock();
@@ -937,10 +929,10 @@ static int ieee80211_config_default_key(struct wiphy *wiphy,
}
static int ieee80211_config_default_mgmt_key(struct wiphy *wiphy,
- struct net_device *dev,
+ struct wireless_dev *wdev,
int link_id, u8 key_idx)
{
- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
struct ieee80211_link_data *link =
ieee80211_link_or_deflink(sdata, link_id, true);
@@ -953,10 +945,10 @@ static int ieee80211_config_default_mgmt_key(struct wiphy *wiphy,
}
static int ieee80211_config_default_beacon_key(struct wiphy *wiphy,
- struct net_device *dev,
+ struct wireless_dev *wdev,
int link_id, u8 key_idx)
{
- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
struct ieee80211_link_data *link =
ieee80211_link_or_deflink(sdata, link_id, true);
@@ -1000,10 +992,10 @@ void sta_set_rate_info_tx(struct sta_info *sta,
rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI;
}
-static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
+static int ieee80211_dump_station(struct wiphy *wiphy, struct wireless_dev *wdev,
int idx, u8 *mac, struct station_info *sinfo)
{
- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
struct ieee80211_local *local = sdata->local;
struct sta_info *sta;
int ret = -ENOENT;
@@ -1035,10 +1027,11 @@ static int ieee80211_dump_survey(struct wiphy *wiphy, struct net_device *dev,
return drv_get_survey(local, idx, survey);
}
-static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
+static int ieee80211_get_station(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
const u8 *mac, struct station_info *sinfo)
{
- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
struct ieee80211_local *local = sdata->local;
struct sta_info *sta;
int ret = -ENOENT;
@@ -2363,7 +2356,7 @@ static int sta_apply_parameters(struct ieee80211_local *local,
return 0;
}
-static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
+static int ieee80211_add_station(struct wiphy *wiphy, struct wireless_dev *wdev,
const u8 *mac,
struct station_parameters *params)
{
@@ -2381,7 +2374,7 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
sdata->vif.type != NL80211_IFTYPE_AP)
return -EINVAL;
} else
- sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
if (ether_addr_equal(mac, sdata->vif.addr))
return -EINVAL;
@@ -2435,12 +2428,12 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
return sta_info_insert(sta);
}
-static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev,
+static int ieee80211_del_station(struct wiphy *wiphy, struct wireless_dev *wdev,
struct station_del_parameters *params)
{
struct ieee80211_sub_if_data *sdata;
- sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
if (params->mac)
return sta_info_destroy_addr_bss(sdata, params->mac);
@@ -2450,10 +2443,10 @@ static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev,
}
static int ieee80211_change_station(struct wiphy *wiphy,
- struct net_device *dev, const u8 *mac,
+ struct wireless_dev *wdev, const u8 *mac,
struct station_parameters *params)
{
- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
struct ieee80211_local *local = wiphy_priv(wiphy);
struct sta_info *sta;
struct ieee80211_sub_if_data *vlansdata;
@@ -4614,7 +4607,9 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
struct ieee80211_tx_info *info;
struct sta_info *sta;
struct ieee80211_chanctx_conf *chanctx_conf;
+ struct ieee80211_bss_conf *conf;
enum nl80211_band band;
+ u8 link_id;
int ret;
/* the lock is needed to assign the cookie later */
@@ -4629,12 +4624,35 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
qos = sta->sta.wme;
- chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf);
- if (WARN_ON(!chanctx_conf)) {
- ret = -EINVAL;
- goto unlock;
+ if (ieee80211_vif_is_mld(&sdata->vif)) {
+ if (sta->sta.mlo) {
+ link_id = IEEE80211_LINK_UNSPECIFIED;
+ } else {
+ /*
+ * For non-MLO clients connected to an AP MLD, band
+ * information is not used; instead, sta->deflink is
+ * used to send packets.
+ */
+ link_id = sta->deflink.link_id;
+
+ conf = rcu_dereference(sdata->vif.link_conf[link_id]);
+
+ if (unlikely(!conf)) {
+ ret = -ENOLINK;
+ goto unlock;
+ }
+ }
+ /* MLD transmissions must not rely on the band */
+ band = 0;
+ } else {
+ chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf);
+ if (WARN_ON(!chanctx_conf)) {
+ ret = -EINVAL;
+ goto unlock;
+ }
+ band = chanctx_conf->def.chan->band;
+ link_id = 0;
}
- band = chanctx_conf->def.chan->band;
if (qos) {
fc = cpu_to_le16(IEEE80211_FTYPE_DATA |
@@ -4661,8 +4679,13 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
nullfunc->frame_control = fc;
nullfunc->duration_id = 0;
memcpy(nullfunc->addr1, sta->sta.addr, ETH_ALEN);
- memcpy(nullfunc->addr2, sdata->vif.addr, ETH_ALEN);
- memcpy(nullfunc->addr3, sdata->vif.addr, ETH_ALEN);
+ if (ieee80211_vif_is_mld(&sdata->vif) && !sta->sta.mlo) {
+ memcpy(nullfunc->addr2, conf->addr, ETH_ALEN);
+ memcpy(nullfunc->addr3, conf->addr, ETH_ALEN);
+ } else {
+ memcpy(nullfunc->addr2, sdata->vif.addr, ETH_ALEN);
+ memcpy(nullfunc->addr3, sdata->vif.addr, ETH_ALEN);
+ }
nullfunc->seq_ctrl = 0;
info = IEEE80211_SKB_CB(skb);
@@ -4671,6 +4694,8 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
IEEE80211_TX_INTFL_NL80211_FRAME_TX;
info->band = band;
+ info->control.flags |= u32_encode_bits(link_id,
+ IEEE80211_TX_CTRL_MLO_LINK);
skb_set_queue_mapping(skb, IEEE80211_AC_VO);
skb->priority = 7;
if (qos)
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index e60b814dd89e..a4babf7624e5 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -256,6 +256,8 @@ struct ieee80211_rx_data {
u8 pn[IEEE80211_CCMP_PN_LEN];
} ccm_gcm;
};
+
+ u8 link_addrs[3 * ETH_ALEN];
};
struct ieee80211_csa_settings {
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 616f86b1a7e4..b0451f1c8e79 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -915,6 +915,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_TXQS);
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_RRM);
+ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_IEEE8021X_AUTH);
wiphy->bss_priv_size = sizeof(struct ieee80211_bss);
@@ -1597,6 +1598,15 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
local->sband_allocated |= BIT(band);
}
+ /*
+ * mac80211 supports EPPKE, if the driver supports (Re)Association
+ * frame encryption
+ */
+ if (wiphy_ext_feature_isset(local->hw.wiphy,
+ NL80211_EXT_FEATURE_ASSOC_FRAME_ENCRYPTION))
+ wiphy_ext_feature_set(local->hw.wiphy,
+ NL80211_EXT_FEATURE_EPPKE);
+
result = wiphy_register(local->hw.wiphy);
if (result < 0)
goto fail_wiphy_register;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 810bea1aacc5..170330d924a3 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -4920,7 +4920,7 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
struct ieee80211_mgmt *mgmt, size_t len)
{
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
- u16 auth_alg, auth_transaction, status_code;
+ u16 auth_alg, auth_transaction, status_code, encap_len;
struct ieee80211_event event = {
.type = MLME_EVENT,
.u.mlme.data = AUTH_EVENT,
@@ -4929,6 +4929,7 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
.subtype = IEEE80211_STYPE_AUTH,
};
bool sae_need_confirm = false;
+ bool auth_fail = false;
lockdep_assert_wiphy(sdata->local->hw.wiphy);
@@ -4945,6 +4946,15 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
status_code = le16_to_cpu(mgmt->u.auth.status_code);
+ /*
+ * IEEE 802.1X Authentication:
+ * Header + Authentication Algorithm Number(2 byte) + Authentication
+ * Transaction Sequence Number(2 byte) + Status Code(2 byte) +
+ * Encapsulation Length(2 byte).
+ */
+ if (auth_alg == WLAN_AUTH_IEEE8021X && len < 24 + 8)
+ return;
+
info.link_id = ifmgd->auth_data->link_id;
if (auth_alg != ifmgd->auth_data->algorithm ||
@@ -4960,7 +4970,24 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
goto notify_driver;
}
- if (status_code != WLAN_STATUS_SUCCESS) {
+ switch (auth_alg) {
+ case WLAN_AUTH_IEEE8021X:
+ if (status_code != WLAN_STATUS_SUCCESS &&
+ status_code != WLAN_STATUS_8021X_AUTH_SUCCESS)
+ auth_fail = true;
+
+ if (!auth_fail) {
+ /* Indicates length of encapsulated EAPOL PDU */
+ encap_len = get_unaligned_le16(mgmt->u.auth.variable);
+ }
+ break;
+ default:
+ if (status_code != WLAN_STATUS_SUCCESS)
+ auth_fail = true;
+ break;
+ }
+
+ if (auth_fail) {
cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len);
if (auth_alg == WLAN_AUTH_SAE &&
@@ -4997,6 +5024,7 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
case WLAN_AUTH_FILS_SK_PFS:
case WLAN_AUTH_FILS_PK:
case WLAN_AUTH_EPPKE:
+ case WLAN_AUTH_IEEE8021X:
break;
case WLAN_AUTH_SHARED_KEY:
if (ifmgd->auth_data->expected_transaction != 4) {
@@ -5017,8 +5045,37 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
if (ifmgd->auth_data->algorithm != WLAN_AUTH_SAE ||
(auth_transaction == 2 &&
ifmgd->auth_data->expected_transaction == 2)) {
- if (!ieee80211_mark_sta_auth(sdata))
- return; /* ignore frame -- wait for timeout */
+ switch (ifmgd->auth_data->algorithm) {
+ case WLAN_AUTH_IEEE8021X:
+ /*
+ * IEEE 802.1X authentication:
+ * - When the full EAP handshake completes over the
+ * Authentication process, the responder sets the
+ * Status Code to WLAN_STATUS_8021X_AUTH_SUCCESS as
+ * specified in "IEEE P802.11bi/D4.0, 12.16.5".
+ *
+ * - In the PMKSA caching case, only two Authentication
+ * frames are exchanged if the responder (e.g., AP)
+ * identifies a valid PMKSA, then as specified in
+ * "IEEE P802.11bi/D4.0, 12.16.8.3", the responder
+ * shall set the Status Code to SUCCESS in the final
+ * Authentication frame and must not include an
+ * encapsulated EAPOL PDU.
+ *
+ * Both conditions are treated as successful
+ * authentication, so mark the state to Authenticated.
+ */
+ if (status_code != WLAN_STATUS_8021X_AUTH_SUCCESS &&
+ !(status_code == WLAN_STATUS_SUCCESS &&
+ encap_len == 0))
+ break;
+ fallthrough;
+ default:
+ if (!ieee80211_mark_sta_auth(sdata))
+ return; /* ignore frame -- wait for timeout */
+
+ break;
+ }
} else if (ifmgd->auth_data->algorithm == WLAN_AUTH_SAE &&
auth_transaction == 1) {
sae_need_confirm = true;
@@ -8441,7 +8498,8 @@ static int ieee80211_auth(struct ieee80211_sub_if_data *sdata)
return -ETIMEDOUT;
}
- if (auth_data->algorithm == WLAN_AUTH_SAE)
+ if (auth_data->algorithm == WLAN_AUTH_SAE ||
+ auth_data->algorithm == WLAN_AUTH_EPPKE)
info.duration = jiffies_to_msecs(IEEE80211_AUTH_TIMEOUT_SAE);
info.link_id = auth_data->link_id;
@@ -8460,6 +8518,10 @@ static int ieee80211_auth(struct ieee80211_sub_if_data *sdata)
} else if (auth_data->algorithm == WLAN_AUTH_EPPKE) {
trans = auth_data->trans;
status = auth_data->status;
+ } else if (auth_data->algorithm == WLAN_AUTH_IEEE8021X) {
+ trans = auth_data->trans;
+ status = auth_data->status;
+ auth_data->expected_transaction = trans + 1;
}
if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS))
@@ -9117,7 +9179,8 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
}
if (ifmgd->auth_data &&
- ifmgd->auth_data->algorithm == WLAN_AUTH_EPPKE)
+ (ifmgd->auth_data->algorithm == WLAN_AUTH_EPPKE ||
+ ifmgd->auth_data->algorithm == WLAN_AUTH_IEEE8021X))
new_sta->sta.epp_peer = true;
new_sta->sta.mlo = mlo;
@@ -9377,6 +9440,9 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
case NL80211_AUTHTYPE_EPPKE:
auth_alg = WLAN_AUTH_EPPKE;
break;
+ case NL80211_AUTHTYPE_IEEE8021X:
+ auth_alg = WLAN_AUTH_IEEE8021X;
+ break;
default:
return -EOPNOTSUPP;
}
@@ -9402,7 +9468,8 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
if (req->auth_data_len >= 4) {
if (req->auth_type == NL80211_AUTHTYPE_SAE ||
- req->auth_type == NL80211_AUTHTYPE_EPPKE) {
+ req->auth_type == NL80211_AUTHTYPE_EPPKE ||
+ req->auth_type == NL80211_AUTHTYPE_IEEE8021X) {
__le16 *pos = (__le16 *) req->auth_data;
auth_data->trans = le16_to_cpu(pos[0]);
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 11d6c56c9d7e..6c4b549444c6 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -5127,6 +5127,11 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx,
hdr = (struct ieee80211_hdr *)rx->skb->data;
}
+ /* Store a copy of the pre-translated link addresses for SW crypto */
+ if (unlikely(is_unicast_ether_addr(hdr->addr1) &&
+ !ieee80211_is_data(hdr->frame_control)))
+ memcpy(rx->link_addrs, &hdr->addrs, 3 * ETH_ALEN);
+
if (unlikely(rx->sta && rx->sta->sta.mlo) &&
is_unicast_ether_addr(hdr->addr1) &&
!ieee80211_is_probe_resp(hdr->frame_control) &&
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 6dc22f1593be..4259e9c13ed7 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -974,7 +974,7 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU)
}
sinfo->generation = local->sta_generation;
- cfg80211_new_sta(sdata->dev, sta->sta.addr, sinfo, GFP_KERNEL);
+ cfg80211_new_sta(&sdata->wdev, sta->sta.addr, sinfo, GFP_KERNEL);
kfree(sinfo);
sta_dbg(sdata, "Inserted STA %pM\n", sta->sta.addr);
@@ -1557,7 +1557,7 @@ static void __sta_info_destroy_part2(struct sta_info *sta, bool recalc)
sta_dbg(sdata, "Removed STA %pM\n", sta->sta.addr);
- cfg80211_del_sta_sinfo(sdata->dev, sta->sta.addr, sinfo, GFP_KERNEL);
+ cfg80211_del_sta_sinfo(&sdata->wdev, sta->sta.addr, sinfo, GFP_KERNEL);
kfree(sinfo);
ieee80211_sta_debugfs_remove(sta);
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 8cdbd417d7be..3844c7fbb8a8 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -287,10 +287,7 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
* active scan) are allowed, all other frames should not be
* sent and we should not get here, but if we do
* nonetheless, drop them to avoid sending them
- * off-channel. See the link below and
- * ieee80211_start_scan() for more.
- *
- * http://article.gmane.org/gmane.linux.kernel.wireless.general/30089
+ * off-channel. See __ieee80211_start_scan() for more.
*/
return TX_DROP;
@@ -5315,6 +5312,38 @@ static int ieee80211_beacon_protect(struct sk_buff *skb,
return 0;
}
+int ieee80211_encrypt_tx_skb(struct sk_buff *skb)
+{
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_sub_if_data *sdata;
+ struct sk_buff *check_skb;
+ struct ieee80211_tx_data tx;
+ ieee80211_tx_result res;
+
+ if (!info->control.hw_key)
+ return 0;
+
+ memset(&tx, 0, sizeof(tx));
+ tx.key = container_of(info->control.hw_key, struct ieee80211_key, conf);
+ /* NULL it out now so we do full SW crypto */
+ info->control.hw_key = NULL;
+ __skb_queue_head_init(&tx.skbs);
+ __skb_queue_tail(&tx.skbs, skb);
+
+ sdata = IEEE80211_DEV_TO_SUB_IF(skb->dev);
+ tx.sdata = sdata;
+ tx.local = sdata->local;
+ res = ieee80211_tx_h_encrypt(&tx);
+ check_skb = __skb_dequeue(&tx.skbs);
+ /* we may crash after this, but it'd be a bug in crypto */
+ WARN_ON(check_skb != skb);
+ if (WARN_ON_ONCE(res != TX_CONTINUE))
+ return -EINVAL;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(ieee80211_encrypt_tx_skb);
+
static void
ieee80211_beacon_get_finish(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
@@ -5837,21 +5866,28 @@ out:
EXPORT_SYMBOL(ieee80211_proberesp_get);
struct sk_buff *ieee80211_get_fils_discovery_tmpl(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif)
+ struct ieee80211_vif *vif,
+ unsigned int link_id)
{
struct sk_buff *skb = NULL;
struct fils_discovery_data *tmpl = NULL;
struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
+ struct ieee80211_link_data *link;
if (sdata->vif.type != NL80211_IFTYPE_AP)
return NULL;
- rcu_read_lock();
- tmpl = rcu_dereference(sdata->deflink.u.ap.fils_discovery);
- if (!tmpl) {
- rcu_read_unlock();
+ if (link_id >= IEEE80211_MLD_MAX_NUM_LINKS)
+ return NULL;
+
+ guard(rcu)();
+ link = rcu_dereference(sdata->link[link_id]);
+ if (!link)
+ return NULL;
+
+ tmpl = rcu_dereference(link->u.ap.fils_discovery);
+ if (!tmpl)
return NULL;
- }
skb = dev_alloc_skb(sdata->local->hw.extra_tx_headroom + tmpl->len);
if (skb) {
@@ -5859,28 +5895,34 @@ struct sk_buff *ieee80211_get_fils_discovery_tmpl(struct ieee80211_hw *hw,
skb_put_data(skb, tmpl->data, tmpl->len);
}
- rcu_read_unlock();
return skb;
}
EXPORT_SYMBOL(ieee80211_get_fils_discovery_tmpl);
struct sk_buff *
ieee80211_get_unsol_bcast_probe_resp_tmpl(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif)
+ struct ieee80211_vif *vif,
+ unsigned int link_id)
{
struct sk_buff *skb = NULL;
struct unsol_bcast_probe_resp_data *tmpl = NULL;
struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
+ struct ieee80211_link_data *link;
if (sdata->vif.type != NL80211_IFTYPE_AP)
return NULL;
- rcu_read_lock();
- tmpl = rcu_dereference(sdata->deflink.u.ap.unsol_bcast_probe_resp);
- if (!tmpl) {
- rcu_read_unlock();
+ if (link_id >= IEEE80211_MLD_MAX_NUM_LINKS)
+ return NULL;
+
+ guard(rcu)();
+ link = rcu_dereference(sdata->link[link_id]);
+ if (!link)
+ return NULL;
+
+ tmpl = rcu_dereference(link->u.ap.unsol_bcast_probe_resp);
+ if (!tmpl)
return NULL;
- }
skb = dev_alloc_skb(sdata->local->hw.extra_tx_headroom + tmpl->len);
if (skb) {
@@ -5888,7 +5930,6 @@ ieee80211_get_unsol_bcast_probe_resp_tmpl(struct ieee80211_hw *hw,
skb_put_data(skb, tmpl->data, tmpl->len);
}
- rcu_read_unlock();
return skb;
}
EXPORT_SYMBOL(ieee80211_get_unsol_bcast_probe_resp_tmpl);
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index fdf98c21d32c..64a57475ce50 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -315,7 +315,8 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx)
* Calculate AAD for CCMP/GCMP, returning qos_tid since we
* need that in CCMP also for b_0.
*/
-static u8 ccmp_gcmp_aad(struct sk_buff *skb, u8 *aad, bool spp_amsdu)
+static u8 ccmp_gcmp_aad(struct sk_buff *skb, u8 *aad, bool spp_amsdu,
+ bool aad_nonce_computed)
{
struct ieee80211_hdr *hdr = (void *)skb->data;
__le16 mask_fc;
@@ -358,7 +359,8 @@ static u8 ccmp_gcmp_aad(struct sk_buff *skb, u8 *aad, bool spp_amsdu)
* FC | A1 | A2 | A3 | SC | [A4] | [QC] */
put_unaligned_be16(len_a, &aad[0]);
put_unaligned(mask_fc, (__le16 *)&aad[2]);
- memcpy(&aad[4], &hdr->addrs, 3 * ETH_ALEN);
+ if (!aad_nonce_computed)
+ memcpy(&aad[4], &hdr->addrs, 3 * ETH_ALEN);
/* Mask Seq#, leave Frag# */
aad[22] = *((u8 *) &hdr->seq_ctrl) & 0x0f;
@@ -377,10 +379,10 @@ static u8 ccmp_gcmp_aad(struct sk_buff *skb, u8 *aad, bool spp_amsdu)
}
static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad,
- bool spp_amsdu)
+ bool spp_amsdu, bool aad_nonce_computed)
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- u8 qos_tid = ccmp_gcmp_aad(skb, aad, spp_amsdu);
+ u8 qos_tid = ccmp_gcmp_aad(skb, aad, spp_amsdu, aad_nonce_computed);
/* In CCM, the initial vectors (IV) used for CTR mode encryption and CBC
* mode authentication are not allowed to collide, yet both are derived
@@ -395,7 +397,8 @@ static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad,
* Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7)
*/
b_0[1] = qos_tid | (ieee80211_is_mgmt(hdr->frame_control) << 4);
- memcpy(&b_0[2], hdr->addr2, ETH_ALEN);
+ if (!aad_nonce_computed)
+ memcpy(&b_0[2], hdr->addr2, ETH_ALEN);
memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN);
}
@@ -488,7 +491,8 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb,
pos += IEEE80211_CCMP_HDR_LEN;
ccmp_special_blocks(skb, pn, b_0, aad,
- key->conf.flags & IEEE80211_KEY_FLAG_SPP_AMSDU);
+ key->conf.flags & IEEE80211_KEY_FLAG_SPP_AMSDU,
+ false);
return ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len,
skb_put(skb, mic_len));
}
@@ -566,9 +570,22 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx,
if (!(status->flag & RX_FLAG_DECRYPTED)) {
u8 aad[2 * AES_BLOCK_SIZE];
u8 b_0[AES_BLOCK_SIZE];
+ bool aad_nonce_computed = false;
+
+ if (is_unicast_ether_addr(hdr->addr1) &&
+ !ieee80211_is_data(hdr->frame_control)) {
+ /* AAD computation */
+ memcpy(&aad[4], rx->link_addrs, 3 * ETH_ALEN);
+ /* Nonce computation */
+ ether_addr_copy(&b_0[2],
+ &rx->link_addrs[ETH_ALEN]);
+ aad_nonce_computed = true;
+ }
+
/* hardware didn't decrypt/verify MIC */
ccmp_special_blocks(skb, pn, b_0, aad,
- key->conf.flags & IEEE80211_KEY_FLAG_SPP_AMSDU);
+ key->conf.flags & IEEE80211_KEY_FLAG_SPP_AMSDU,
+ aad_nonce_computed);
if (ieee80211_aes_ccm_decrypt(
key->u.ccmp.tfm, b_0, aad,
@@ -593,14 +610,15 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx,
}
static void gcmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *j_0, u8 *aad,
- bool spp_amsdu)
+ bool spp_amsdu, bool aad_nonce_computed)
{
struct ieee80211_hdr *hdr = (void *)skb->data;
- memcpy(j_0, hdr->addr2, ETH_ALEN);
+ if (!aad_nonce_computed)
+ memcpy(j_0, hdr->addr2, ETH_ALEN);
memcpy(&j_0[ETH_ALEN], pn, IEEE80211_GCMP_PN_LEN);
- ccmp_gcmp_aad(skb, aad, spp_amsdu);
+ ccmp_gcmp_aad(skb, aad, spp_amsdu, aad_nonce_computed);
}
static inline void gcmp_pn2hdr(u8 *hdr, const u8 *pn, int key_id)
@@ -690,7 +708,8 @@ static int gcmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
pos += IEEE80211_GCMP_HDR_LEN;
gcmp_special_blocks(skb, pn, j_0, aad,
- key->conf.flags & IEEE80211_KEY_FLAG_SPP_AMSDU);
+ key->conf.flags & IEEE80211_KEY_FLAG_SPP_AMSDU,
+ false);
return ieee80211_aes_gcm_encrypt(key->u.gcmp.tfm, j_0, aad, pos, len,
skb_put(skb, IEEE80211_GCMP_MIC_LEN));
}
@@ -763,9 +782,21 @@ ieee80211_crypto_gcmp_decrypt(struct ieee80211_rx_data *rx)
if (!(status->flag & RX_FLAG_DECRYPTED)) {
u8 aad[2 * AES_BLOCK_SIZE];
u8 j_0[AES_BLOCK_SIZE];
+ bool aad_nonce_computed = false;
+
+ if (is_unicast_ether_addr(hdr->addr1) &&
+ !ieee80211_is_data(hdr->frame_control)) {
+ /* AAD computation */
+ memcpy(&aad[4], rx->link_addrs, 3 * ETH_ALEN);
+ /* Nonce computation */
+ ether_addr_copy(&j_0[0],
+ &rx->link_addrs[ETH_ALEN]);
+ aad_nonce_computed = true;
+ }
/* hardware didn't decrypt/verify MIC */
gcmp_special_blocks(skb, pn, j_0, aad,
- key->conf.flags & IEEE80211_KEY_FLAG_SPP_AMSDU);
+ key->conf.flags & IEEE80211_KEY_FLAG_SPP_AMSDU,
+ aad_nonce_computed);
if (ieee80211_aes_gcm_decrypt(
key->u.gcmp.tfm, j_0, aad,
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 68221b1ab45e..d9d4e043bb39 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -642,6 +642,33 @@ void cfg80211_set_dfs_state(struct wiphy *wiphy,
}
}
+void cfg80211_set_cac_state(struct wiphy *wiphy,
+ const struct cfg80211_chan_def *chandef,
+ bool cac_ongoing)
+{
+ struct ieee80211_channel *c;
+ int width;
+ u64 cac_time;
+
+ if (WARN_ON(!cfg80211_chandef_valid(chandef)))
+ return;
+
+ width = cfg80211_chandef_get_width(chandef);
+ if (width < 0)
+ return;
+
+ /* Get the same timestamp for all subchannels */
+ cac_time = cac_ongoing ? ktime_get_boottime_ns() : 0;
+
+ for_each_subchan(chandef, freq, cf) {
+ c = ieee80211_get_channel_khz(wiphy, freq);
+ if (!c)
+ continue;
+
+ c->cac_start_time = cac_time;
+ }
+}
+
static bool
cfg80211_dfs_permissive_check_wdev(struct cfg80211_registered_device *rdev,
enum nl80211_iftype iftype,
@@ -754,6 +781,7 @@ int cfg80211_chandef_dfs_required(struct wiphy *wiphy,
case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_P2P_GO:
case NL80211_IFTYPE_MESH_POINT:
+ case NL80211_IFTYPE_NAN:
width = cfg80211_chandef_get_width(chandef);
if (width < 0)
return -EINVAL;
@@ -768,7 +796,6 @@ int cfg80211_chandef_dfs_required(struct wiphy *wiphy,
case NL80211_IFTYPE_MONITOR:
case NL80211_IFTYPE_AP_VLAN:
case NL80211_IFTYPE_P2P_DEVICE:
- case NL80211_IFTYPE_NAN:
break;
case NL80211_IFTYPE_WDS:
case NL80211_IFTYPE_UNSPECIFIED:
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 28ca4290ca99..23afc250bc10 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -349,7 +349,6 @@ void cfg80211_destroy_ifaces(struct cfg80211_registered_device *rdev)
guard(wiphy)(&rdev->wiphy);
- cfg80211_leave(rdev, wdev, -1);
cfg80211_remove_virtual_intf(rdev, wdev);
}
}
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 6ac57b7b2615..6cace846d7a3 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -481,6 +481,10 @@ void cfg80211_set_dfs_state(struct wiphy *wiphy,
const struct cfg80211_chan_def *chandef,
enum nl80211_dfs_state dfs_state);
+void cfg80211_set_cac_state(struct wiphy *wiphy,
+ const struct cfg80211_chan_def *chandef,
+ bool cac_ongoing);
+
void cfg80211_dfs_channels_update_work(struct work_struct *work);
void cfg80211_sched_dfs_chan_update(struct cfg80211_registered_device *rdev);
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
index a7024af39b40..b1d748bdb504 100644
--- a/net/wireless/ibss.c
+++ b/net/wireless/ibss.c
@@ -3,7 +3,7 @@
* Some IBSS support code for cfg80211.
*
* Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
- * Copyright (C) 2020-2024 Intel Corporation
+ * Copyright (C) 2020-2026 Intel Corporation
*/
#include <linux/etherdevice.h>
@@ -172,7 +172,7 @@ void cfg80211_clear_ibss(struct net_device *dev, bool nowext)
*/
if (rdev->ops->del_key)
for (i = 0; i < 6; i++)
- rdev_del_key(rdev, dev, -1, i, false, NULL);
+ rdev_del_key(rdev, wdev, -1, i, false, NULL);
if (wdev->u.ibss.current_bss) {
cfg80211_unhold_bss(wdev->u.ibss.current_bss);
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 3fc175f9f868..5cd86253a62e 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -1115,8 +1115,10 @@ void __cfg80211_radar_event(struct wiphy *wiphy,
*/
cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_UNAVAILABLE);
- if (offchan)
+ if (offchan) {
+ cancel_delayed_work(&rdev->background_cac_done_wk);
queue_work(cfg80211_wq, &rdev->background_cac_abort_wk);
+ }
cfg80211_sched_dfs_chan_update(rdev);
@@ -1160,9 +1162,11 @@ void cfg80211_cac_event(struct net_device *netdev,
fallthrough;
case NL80211_RADAR_CAC_ABORTED:
wdev->links[link_id].cac_started = false;
+ cfg80211_set_cac_state(wiphy, chandef, false);
break;
case NL80211_RADAR_CAC_STARTED:
wdev->links[link_id].cac_started = true;
+ cfg80211_set_cac_state(wiphy, chandef, true);
break;
default:
WARN_ON(1);
@@ -1187,23 +1191,21 @@ __cfg80211_background_cac_event(struct cfg80211_registered_device *rdev,
if (!cfg80211_chandef_valid(chandef))
return;
- if (!rdev->background_radar_wdev)
- return;
-
switch (event) {
case NL80211_RADAR_CAC_FINISHED:
cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_AVAILABLE);
+ cfg80211_set_cac_state(wiphy, chandef, false);
memcpy(&rdev->cac_done_chandef, chandef, sizeof(*chandef));
queue_work(cfg80211_wq, &rdev->propagate_cac_done_wk);
cfg80211_sched_dfs_chan_update(rdev);
- wdev = rdev->background_radar_wdev;
break;
case NL80211_RADAR_CAC_ABORTED:
+ cfg80211_set_cac_state(wiphy, chandef, false);
if (!cancel_delayed_work(&rdev->background_cac_done_wk))
return;
- wdev = rdev->background_radar_wdev;
break;
case NL80211_RADAR_CAC_STARTED:
+ cfg80211_set_cac_state(wiphy, chandef, true);
break;
default:
return;
@@ -1213,17 +1215,6 @@ __cfg80211_background_cac_event(struct cfg80211_registered_device *rdev,
nl80211_radar_notify(rdev, chandef, event, netdev, GFP_KERNEL);
}
-static void
-cfg80211_background_cac_event(struct cfg80211_registered_device *rdev,
- const struct cfg80211_chan_def *chandef,
- enum nl80211_radar_event event)
-{
- guard(wiphy)(&rdev->wiphy);
-
- __cfg80211_background_cac_event(rdev, rdev->background_radar_wdev,
- chandef, event);
-}
-
void cfg80211_background_cac_done_wk(struct work_struct *work)
{
struct delayed_work *delayed_work = to_delayed_work(work);
@@ -1231,18 +1222,31 @@ void cfg80211_background_cac_done_wk(struct work_struct *work)
rdev = container_of(delayed_work, struct cfg80211_registered_device,
background_cac_done_wk);
- cfg80211_background_cac_event(rdev, &rdev->background_radar_chandef,
- NL80211_RADAR_CAC_FINISHED);
+
+ guard(wiphy)(&rdev->wiphy);
+
+ rdev_set_radar_background(rdev, NULL);
+
+ __cfg80211_background_cac_event(rdev, rdev->background_radar_wdev,
+ &rdev->background_radar_chandef,
+ NL80211_RADAR_CAC_FINISHED);
+
+ rdev->background_radar_wdev = NULL;
}
void cfg80211_background_cac_abort_wk(struct work_struct *work)
{
struct cfg80211_registered_device *rdev;
+ struct wireless_dev *wdev;
rdev = container_of(work, struct cfg80211_registered_device,
background_cac_abort_wk);
- cfg80211_background_cac_event(rdev, &rdev->background_radar_chandef,
- NL80211_RADAR_CAC_ABORTED);
+
+ guard(wiphy)(&rdev->wiphy);
+
+ wdev = rdev->background_radar_wdev;
+ if (wdev)
+ cfg80211_stop_background_radar_detection(wdev);
}
void cfg80211_background_cac_abort(struct wiphy *wiphy)
@@ -1309,6 +1313,8 @@ void cfg80211_stop_radar_detection(struct wireless_dev *wdev)
chandef = *wdev_chandef(wdev, link_id);
rdev_end_cac(rdev, wdev->netdev, link_id);
+ wdev->links[link_id].cac_started = false;
+ cfg80211_set_cac_state(wiphy, &chandef, false);
nl80211_radar_notify(rdev, &chandef, NL80211_RADAR_CAC_ABORTED,
wdev->netdev, GFP_KERNEL);
}
@@ -1325,11 +1331,12 @@ void cfg80211_stop_background_radar_detection(struct wireless_dev *wdev)
return;
rdev_set_radar_background(rdev, NULL);
- rdev->background_radar_wdev = NULL; /* Release offchain ownership */
__cfg80211_background_cac_event(rdev, wdev,
&rdev->background_radar_chandef,
NL80211_RADAR_CAC_ABORTED);
+
+ rdev->background_radar_wdev = NULL;
}
int cfg80211_assoc_ml_reconf(struct cfg80211_registered_device *rdev,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index b94231c8441c..2225f5d0b124 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -21,6 +21,7 @@
#include <linux/nospec.h>
#include <linux/etherdevice.h>
#include <linux/if_vlan.h>
+#include <linux/random.h>
#include <net/net_namespace.h>
#include <net/genetlink.h>
#include <net/cfg80211.h>
@@ -1333,6 +1334,12 @@ static int nl80211_msg_put_channel(struct sk_buff *msg, struct wiphy *wiphy,
if ((chan->flags & IEEE80211_CHAN_NO_UHR) &&
nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_UHR))
goto nla_put_failure;
+ if (chan->cac_start_time &&
+ nla_put_u64_64bit(msg,
+ NL80211_FREQUENCY_ATTR_CAC_START_TIME,
+ chan->cac_start_time,
+ NL80211_FREQUENCY_ATTR_PAD))
+ goto nla_put_failure;
}
if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
@@ -3567,11 +3574,10 @@ static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev)
}
static int _nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
- struct genl_info *info, bool monitor,
+ struct netlink_ext_ack *extack,
+ struct nlattr **attrs, bool monitor,
struct cfg80211_chan_def *chandef)
{
- struct netlink_ext_ack *extack = info->extack;
- struct nlattr **attrs = info->attrs;
u32 control_freq;
if (!attrs[NL80211_ATTR_WIPHY_FREQ]) {
@@ -3581,10 +3587,10 @@ static int _nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
}
control_freq = MHZ_TO_KHZ(
- nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
- if (info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET])
+ nla_get_u32(attrs[NL80211_ATTR_WIPHY_FREQ]));
+ if (attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET])
control_freq +=
- nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]);
+ nla_get_u32(attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]);
memset(chandef, 0, sizeof(*chandef));
chandef->chan = ieee80211_get_channel_khz(&rdev->wiphy, control_freq);
@@ -3655,40 +3661,43 @@ static int _nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
attrs[NL80211_ATTR_S1G_PRIMARY_2MHZ]);
}
- if (info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]) {
+ if (attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]) {
chandef->edmg.channels =
- nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]);
+ nla_get_u8(attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]);
- if (info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG])
+ if (attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG])
chandef->edmg.bw_config =
- nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG]);
+ nla_get_u8(attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG]);
} else {
chandef->edmg.bw_config = 0;
chandef->edmg.channels = 0;
}
- if (info->attrs[NL80211_ATTR_PUNCT_BITMAP]) {
+ if (attrs[NL80211_ATTR_PUNCT_BITMAP]) {
chandef->punctured =
- nla_get_u32(info->attrs[NL80211_ATTR_PUNCT_BITMAP]);
+ nla_get_u32(attrs[NL80211_ATTR_PUNCT_BITMAP]);
if (chandef->punctured &&
!wiphy_ext_feature_isset(&rdev->wiphy,
NL80211_EXT_FEATURE_PUNCT)) {
- NL_SET_ERR_MSG(extack,
- "driver doesn't support puncturing");
+ NL_SET_ERR_MSG_ATTR(extack,
+ attrs[NL80211_ATTR_WIPHY_FREQ],
+ "driver doesn't support puncturing");
return -EINVAL;
}
}
if (!cfg80211_chandef_valid(chandef)) {
- NL_SET_ERR_MSG(extack, "invalid channel definition");
+ NL_SET_ERR_MSG_ATTR(extack, attrs[NL80211_ATTR_WIPHY_FREQ],
+ "invalid channel definition");
return -EINVAL;
}
if (!_cfg80211_chandef_usable(&rdev->wiphy, chandef,
IEEE80211_CHAN_DISABLED,
monitor ? IEEE80211_CHAN_CAN_MONITOR : 0)) {
- NL_SET_ERR_MSG(extack, "(extension) channel is disabled");
+ NL_SET_ERR_MSG_ATTR(extack, attrs[NL80211_ATTR_WIPHY_FREQ],
+ "(extension) channel is disabled");
return -EINVAL;
}
@@ -3703,10 +3712,11 @@ static int _nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
}
int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
- struct genl_info *info,
+ struct netlink_ext_ack *extack,
+ struct nlattr **attrs,
struct cfg80211_chan_def *chandef)
{
- return _nl80211_parse_chandef(rdev, info, false, chandef);
+ return _nl80211_parse_chandef(rdev, extack, attrs, false, chandef);
}
static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
@@ -3733,7 +3743,7 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
link_id = 0;
}
- result = _nl80211_parse_chandef(rdev, info,
+ result = _nl80211_parse_chandef(rdev, info->extack, info->attrs,
iftype == NL80211_IFTYPE_MONITOR,
&chandef);
if (result)
@@ -4950,7 +4960,7 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev = info->user_ptr[0];
int err;
- struct net_device *dev = info->user_ptr[1];
+ struct wireless_dev *wdev = info->user_ptr[1];
u8 key_idx = 0;
const u8 *mac_addr = NULL;
bool pairwise;
@@ -4961,7 +4971,6 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
struct sk_buff *msg;
bool bigtk_support = false;
int link_id = nl80211_link_id_or_invalid(info->attrs);
- struct wireless_dev *wdev = dev->ieee80211_ptr;
if (wiphy_ext_feature_isset(&rdev->wiphy,
NL80211_EXT_FEATURE_BEACON_PROTECTION))
@@ -5013,7 +5022,10 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
cookie.msg = msg;
cookie.idx = key_idx;
- if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
+ if ((wdev->netdev &&
+ nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex)) ||
+ nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
+ NL80211_ATTR_PAD) ||
nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_idx))
goto nla_put_failure;
if (mac_addr &&
@@ -5024,7 +5036,7 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
if (err)
goto free_msg;
- err = rdev_get_key(rdev, dev, link_id, key_idx, pairwise, mac_addr,
+ err = rdev_get_key(rdev, wdev, link_id, key_idx, pairwise, mac_addr,
&cookie, get_key_callback);
if (err)
@@ -5048,9 +5060,8 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
struct cfg80211_registered_device *rdev = info->user_ptr[0];
struct key_parse key;
int err;
- struct net_device *dev = info->user_ptr[1];
+ struct wireless_dev *wdev = info->user_ptr[1];
int link_id = nl80211_link_id_or_invalid(info->attrs);
- struct wireless_dev *wdev = dev->ieee80211_ptr;
err = nl80211_parse_key(info, &key);
if (err)
@@ -5070,6 +5081,9 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
if (!rdev->ops->set_default_key)
return -EOPNOTSUPP;
+ if (!wdev->netdev)
+ return -EINVAL;
+
err = nl80211_key_allowed(wdev);
if (err)
return err;
@@ -5078,7 +5092,7 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
if (err)
return err;
- err = rdev_set_default_key(rdev, dev, link_id, key.idx,
+ err = rdev_set_default_key(rdev, wdev->netdev, link_id, key.idx,
key.def_uni, key.def_multi);
if (err)
@@ -5103,7 +5117,7 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
if (err)
return err;
- err = rdev_set_default_mgmt_key(rdev, dev, link_id, key.idx);
+ err = rdev_set_default_mgmt_key(rdev, wdev, link_id, key.idx);
if (err)
return err;
@@ -5126,7 +5140,8 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
if (err)
return err;
- return rdev_set_default_beacon_key(rdev, dev, link_id, key.idx);
+ return rdev_set_default_beacon_key(rdev, wdev, link_id,
+ key.idx);
} else if (key.p.mode == NL80211_KEY_SET_TX &&
wiphy_ext_feature_isset(&rdev->wiphy,
NL80211_EXT_FEATURE_EXT_KEY_ID)) {
@@ -5142,7 +5157,7 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
if (err)
return err;
- return rdev_add_key(rdev, dev, link_id, key.idx,
+ return rdev_add_key(rdev, wdev, link_id, key.idx,
NL80211_KEYTYPE_PAIRWISE,
mac_addr, &key.p);
}
@@ -5154,11 +5169,10 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev = info->user_ptr[0];
int err;
- struct net_device *dev = info->user_ptr[1];
+ struct wireless_dev *wdev = info->user_ptr[1];
struct key_parse key;
const u8 *mac_addr = NULL;
int link_id = nl80211_link_id_or_invalid(info->attrs);
- struct wireless_dev *wdev = dev->ieee80211_ptr;
err = nl80211_parse_key(info, &key);
if (err)
@@ -5209,7 +5223,7 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
key.type == NL80211_KEYTYPE_PAIRWISE);
if (!err) {
- err = rdev_add_key(rdev, dev, link_id, key.idx,
+ err = rdev_add_key(rdev, wdev, link_id, key.idx,
key.type == NL80211_KEYTYPE_PAIRWISE,
mac_addr, &key.p);
if (err)
@@ -5223,11 +5237,10 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev = info->user_ptr[0];
int err;
- struct net_device *dev = info->user_ptr[1];
+ struct wireless_dev *wdev = info->user_ptr[1];
u8 *mac_addr = NULL;
struct key_parse key;
int link_id = nl80211_link_id_or_invalid(info->attrs);
- struct wireless_dev *wdev = dev->ieee80211_ptr;
err = nl80211_parse_key(info, &key);
if (err)
@@ -5266,7 +5279,7 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
key.type == NL80211_KEYTYPE_PAIRWISE);
if (!err)
- err = rdev_del_key(rdev, dev, link_id, key.idx,
+ err = rdev_del_key(rdev, wdev, link_id, key.idx,
key.type == NL80211_KEYTYPE_PAIRWISE,
mac_addr);
@@ -6541,6 +6554,10 @@ static bool nl80211_valid_auth_type(struct cfg80211_registered_device *rdev,
NL80211_EXT_FEATURE_EPPKE) &&
auth_type == NL80211_AUTHTYPE_EPPKE)
return false;
+ if (!wiphy_ext_feature_isset(&rdev->wiphy,
+ NL80211_EXT_FEATURE_IEEE8021X_AUTH) &&
+ auth_type == NL80211_AUTHTYPE_IEEE8021X)
+ return false;
return true;
case NL80211_CMD_CONNECT:
if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) &&
@@ -6562,6 +6579,10 @@ static bool nl80211_valid_auth_type(struct cfg80211_registered_device *rdev,
NL80211_EXT_FEATURE_EPPKE) &&
auth_type == NL80211_AUTHTYPE_EPPKE)
return false;
+ if (!wiphy_ext_feature_isset(&rdev->wiphy,
+ NL80211_EXT_FEATURE_IEEE8021X_AUTH) &&
+ auth_type == NL80211_AUTHTYPE_IEEE8021X)
+ return false;
return true;
case NL80211_CMD_START_AP:
if (!wiphy_ext_feature_isset(&rdev->wiphy,
@@ -6811,7 +6832,8 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
}
if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
- err = nl80211_parse_chandef(rdev, info, &params->chandef);
+ err = nl80211_parse_chandef(rdev, info->extack, info->attrs,
+ &params->chandef);
if (err)
goto out;
} else if (wdev->valid_links) {
@@ -7497,7 +7519,7 @@ nla_put_failure:
static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
u32 seq, int flags,
struct cfg80211_registered_device *rdev,
- struct net_device *dev,
+ struct wireless_dev *wdev,
const u8 *mac_addr, struct station_info *sinfo,
bool link_stats)
{
@@ -7513,7 +7535,10 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
return -1;
}
- if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
+ if ((wdev->netdev &&
+ nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex)) ||
+ nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
+ NL80211_ATTR_PAD) ||
nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) ||
nla_put_u32(msg, NL80211_ATTR_GENERATION, sinfo->generation))
goto nla_put_failure;
@@ -7992,7 +8017,7 @@ static int nl80211_dump_station(struct sk_buff *skb,
sinfo_alloc = true;
}
- err = rdev_dump_station(rdev, wdev->netdev, sta_idx,
+ err = rdev_dump_station(rdev, wdev, sta_idx,
mac_addr, &sinfo);
if (err == -ENOENT)
break;
@@ -8010,7 +8035,7 @@ static int nl80211_dump_station(struct sk_buff *skb,
if (nl80211_send_station(skb, NL80211_CMD_NEW_STATION,
NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq, NLM_F_MULTI,
- rdev, wdev->netdev, mac_addr,
+ rdev, wdev, mac_addr,
&sinfo, false) < 0)
goto out;
@@ -8031,7 +8056,7 @@ static int nl80211_dump_station(struct sk_buff *skb,
static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev = info->user_ptr[0];
- struct net_device *dev = info->user_ptr[1];
+ struct wireless_dev *wdev = info->user_ptr[1];
struct station_info sinfo;
struct sk_buff *msg;
u8 *mac_addr = NULL;
@@ -8039,6 +8064,9 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
memset(&sinfo, 0, sizeof(sinfo));
+ if (!wdev->netdev)
+ return -EINVAL;
+
if (!info->attrs[NL80211_ATTR_MAC])
return -EINVAL;
@@ -8055,7 +8083,7 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
}
}
- err = rdev_get_station(rdev, dev, mac_addr, &sinfo);
+ err = rdev_get_station(rdev, wdev, mac_addr, &sinfo);
if (err) {
cfg80211_sinfo_release_content(&sinfo);
return err;
@@ -8072,7 +8100,7 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION,
info->snd_portid, info->snd_seq, 0,
- rdev, dev, mac_addr, &sinfo, false) < 0) {
+ rdev, wdev, mac_addr, &sinfo, false) < 0) {
nlmsg_free(msg);
return -ENOBUFS;
}
@@ -8434,13 +8462,17 @@ static int nl80211_parse_sta_txpower_setting(struct genl_info *info,
static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev = info->user_ptr[0];
- struct net_device *dev = info->user_ptr[1];
+ struct wireless_dev *wdev = info->user_ptr[1];
+ struct net_device *dev = wdev->netdev;
struct station_parameters params;
u8 *mac_addr;
int err;
memset(&params, 0, sizeof(params));
+ if (!dev)
+ return -EINVAL;
+
if (!rdev->ops->change_station)
return -EOPNOTSUPP;
@@ -8513,7 +8545,7 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
}
- if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
+ if (parse_station_flags(info, wdev->iftype, &params))
return -EINVAL;
if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
@@ -8573,7 +8605,7 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
if (IS_ERR(params.vlan))
return PTR_ERR(params.vlan);
- switch (dev->ieee80211_ptr->iftype) {
+ switch (wdev->iftype) {
case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_AP_VLAN:
case NL80211_IFTYPE_P2P_GO:
@@ -8588,7 +8620,7 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
}
/* driver will call cfg80211_check_station_change() */
- err = rdev_change_station(rdev, dev, mac_addr, &params);
+ err = rdev_change_station(rdev, wdev, mac_addr, &params);
out_put_vlan:
dev_put(params.vlan);
@@ -8600,8 +8632,8 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev = info->user_ptr[0];
int err;
- struct net_device *dev = info->user_ptr[1];
- struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct wireless_dev *wdev = info->user_ptr[1];
+ struct net_device *dev = wdev->netdev;
struct station_parameters params;
u8 *mac_addr = NULL;
u32 auth_assoc = BIT(NL80211_STA_FLAG_AUTHENTICATED) |
@@ -8609,6 +8641,9 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
memset(&params, 0, sizeof(params));
+ if (!dev)
+ return -EINVAL;
+
if (!rdev->ops->add_station)
return -EOPNOTSUPP;
@@ -8658,7 +8693,7 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
* and is NOT supported for AP interface
*/
params.support_p2p_ps =
- dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO;
+ wdev->iftype == NL80211_IFTYPE_P2P_GO;
}
if (info->attrs[NL80211_ATTR_PEER_AID])
@@ -8764,7 +8799,7 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
if (err)
return err;
- if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
+ if (parse_station_flags(info, wdev->iftype, &params))
return -EINVAL;
/* HT/VHT requires QoS, but if we don't have that just ignore HT/VHT
@@ -8792,7 +8827,7 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
/* When you run into this, adjust the code below for the new flag */
BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 8);
- switch (dev->ieee80211_ptr->iftype) {
+ switch (wdev->iftype) {
case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_AP_VLAN:
case NL80211_IFTYPE_P2P_GO:
@@ -8901,7 +8936,7 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
params.epp_peer =
nla_get_flag(info->attrs[NL80211_ATTR_EPP_PEER]);
- err = rdev_add_station(rdev, dev, mac_addr, &params);
+ err = rdev_add_station(rdev, wdev, mac_addr, &params);
out:
dev_put(params.vlan);
return err;
@@ -8910,13 +8945,16 @@ out:
static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev = info->user_ptr[0];
- struct net_device *dev = info->user_ptr[1];
- struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct wireless_dev *wdev = info->user_ptr[1];
+ struct net_device *dev = wdev->netdev;
struct station_del_parameters params;
int link_id = nl80211_link_id_or_invalid(info->attrs);
memset(&params, 0, sizeof(params));
+ if (!dev)
+ return -EINVAL;
+
if (info->attrs[NL80211_ATTR_MAC])
params.mac = nla_data(info->attrs[NL80211_ATTR_MAC]);
@@ -8972,7 +9010,7 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
params.link_id = link_id;
- return rdev_del_station(rdev, dev, &params);
+ return rdev_del_station(rdev, wdev, &params);
}
static int nl80211_send_mpath(struct sk_buff *msg, u32 portid, u32 seq,
@@ -11287,7 +11325,7 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
if (dfs_region == NL80211_DFS_UNSET)
return -EINVAL;
- err = nl80211_parse_chandef(rdev, info, &chandef);
+ err = nl80211_parse_chandef(rdev, info->extack, info->attrs, &chandef);
if (err)
return err;
@@ -11353,6 +11391,7 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
wdev->links[link_id].cac_started = true;
wdev->links[link_id].cac_start_time = jiffies;
wdev->links[link_id].cac_time_ms = cac_time_ms;
+ cfg80211_set_cac_state(wiphy, &chandef, true);
return 0;
}
@@ -11375,7 +11414,7 @@ static int nl80211_notify_radar_detection(struct sk_buff *skb,
return -EINVAL;
}
- err = nl80211_parse_chandef(rdev, info, &chandef);
+ err = nl80211_parse_chandef(rdev, info->extack, info->attrs, &chandef);
if (err) {
GENL_SET_ERR_MSG(info, "Unable to extract chandef info");
return err;
@@ -11560,7 +11599,8 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
goto free;
skip_beacons:
- err = nl80211_parse_chandef(rdev, info, &params.chandef);
+ err = nl80211_parse_chandef(rdev, info->extack, info->attrs,
+ &params.chandef);
if (err)
goto free;
@@ -12075,7 +12115,8 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
auth_type == NL80211_AUTHTYPE_FILS_SK ||
auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
auth_type == NL80211_AUTHTYPE_FILS_PK ||
- auth_type == NL80211_AUTHTYPE_EPPKE) &&
+ auth_type == NL80211_AUTHTYPE_EPPKE ||
+ auth_type == NL80211_AUTHTYPE_IEEE8021X) &&
!info->attrs[NL80211_ATTR_AUTH_DATA])
return -EINVAL;
@@ -12084,7 +12125,8 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
auth_type != NL80211_AUTHTYPE_FILS_SK &&
auth_type != NL80211_AUTHTYPE_FILS_SK_PFS &&
auth_type != NL80211_AUTHTYPE_FILS_PK &&
- auth_type != NL80211_AUTHTYPE_EPPKE)
+ auth_type != NL80211_AUTHTYPE_EPPKE &&
+ auth_type != NL80211_AUTHTYPE_IEEE8021X)
return -EINVAL;
req.auth_data = nla_data(info->attrs[NL80211_ATTR_AUTH_DATA]);
req.auth_data_len = nla_len(info->attrs[NL80211_ATTR_AUTH_DATA]);
@@ -12781,7 +12823,8 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
}
- err = nl80211_parse_chandef(rdev, info, &ibss.chandef);
+ err = nl80211_parse_chandef(rdev, info->extack, info->attrs,
+ &ibss.chandef);
if (err)
return err;
@@ -13779,7 +13822,7 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
duration > rdev->wiphy.max_remain_on_channel_duration)
return -EINVAL;
- err = nl80211_parse_chandef(rdev, info, &chandef);
+ err = nl80211_parse_chandef(rdev, info->extack, info->attrs, &chandef);
if (err)
return err;
@@ -13995,7 +14038,8 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
*/
chandef.chan = NULL;
if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
- err = nl80211_parse_chandef(rdev, info, &chandef);
+ err = nl80211_parse_chandef(rdev, info->extack, info->attrs,
+ &chandef);
if (err)
return err;
}
@@ -14227,7 +14271,7 @@ static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev,
mac_addr = wdev->links[0].client.current_bss->pub.bssid;
- err = rdev_get_station(rdev, dev, mac_addr, &sinfo);
+ err = rdev_get_station(rdev, wdev, mac_addr, &sinfo);
if (err)
return err;
@@ -14397,7 +14441,8 @@ static int nl80211_join_ocb(struct sk_buff *skb, struct genl_info *info)
struct ocb_setup setup = {};
int err;
- err = nl80211_parse_chandef(rdev, info, &setup.chandef);
+ err = nl80211_parse_chandef(rdev, info->extack, info->attrs,
+ &setup.chandef);
if (err)
return err;
@@ -14472,7 +14517,8 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
cfg.auto_open_plinks = false;
if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
- err = nl80211_parse_chandef(rdev, info, &setup.chandef);
+ err = nl80211_parse_chandef(rdev, info->extack, info->attrs,
+ &setup.chandef);
if (err)
return err;
} else {
@@ -15725,9 +15771,16 @@ static int nl80211_parse_nan_conf(struct wiphy *wiphy,
return err;
changed |= CFG80211_NAN_CONF_CHANGED_CONFIG;
- if (attrs[NL80211_NAN_CONF_CLUSTER_ID] && start)
- conf->cluster_id =
- nla_data(attrs[NL80211_NAN_CONF_CLUSTER_ID]);
+ if (attrs[NL80211_NAN_CONF_CLUSTER_ID] && start) {
+ ether_addr_copy(conf->cluster_id,
+ nla_data(attrs[NL80211_NAN_CONF_CLUSTER_ID]));
+ } else if (start) {
+ conf->cluster_id[0] = 0x50;
+ conf->cluster_id[1] = 0x6f;
+ conf->cluster_id[2] = 0x9a;
+ conf->cluster_id[3] = 0x01;
+ get_random_bytes(&conf->cluster_id[4], 2);
+ }
if (attrs[NL80211_NAN_CONF_EXTRA_ATTRS]) {
conf->extra_nan_attrs =
@@ -16947,7 +17000,7 @@ static int nl80211_tdls_channel_switch(struct sk_buff *skb,
!info->attrs[NL80211_ATTR_OPER_CLASS])
return -EINVAL;
- err = nl80211_parse_chandef(rdev, info, &chandef);
+ err = nl80211_parse_chandef(rdev, info->extack, info->attrs, &chandef);
if (err)
return err;
@@ -17326,7 +17379,7 @@ static int nl80211_probe_mesh_link(struct sk_buff *skb, struct genl_info *info)
!ether_addr_equal(buf + ETH_ALEN, dev->dev_addr))
return -EINVAL;
- err = rdev_get_station(rdev, dev, dest, &sinfo);
+ err = rdev_get_station(rdev, wdev, dest, &sinfo);
if (err)
return err;
@@ -18021,6 +18074,9 @@ nl80211_epcs_cfg(struct sk_buff *skb, struct genl_info *info)
NL80211_FLAG_CLEAR_SKB) \
SELECTOR(__sel, WDEV_UP, \
NL80211_FLAG_NEED_WDEV_UP) \
+ SELECTOR(__sel, WDEV_UP_CLEAR, \
+ NL80211_FLAG_NEED_WDEV_UP | \
+ NL80211_FLAG_CLEAR_SKB) \
SELECTOR(__sel, WDEV_UP_LINK, \
NL80211_FLAG_NEED_WDEV_UP | \
NL80211_FLAG_MLO_VALID_LINK_ID) \
@@ -18353,7 +18409,7 @@ static const struct genl_small_ops nl80211_small_ops[] = {
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.doit = nl80211_get_key,
.flags = GENL_UNS_ADMIN_PERM,
- .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
+ .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
},
{
.cmd = NL80211_CMD_SET_KEY,
@@ -18361,7 +18417,7 @@ static const struct genl_small_ops nl80211_small_ops[] = {
.doit = nl80211_set_key,
.flags = GENL_UNS_ADMIN_PERM,
/* cannot use NL80211_FLAG_MLO_VALID_LINK_ID, depends on key */
- .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
+ .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP |
NL80211_FLAG_CLEAR_SKB),
},
{
@@ -18369,7 +18425,7 @@ static const struct genl_small_ops nl80211_small_ops[] = {
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.doit = nl80211_new_key,
.flags = GENL_UNS_ADMIN_PERM,
- .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
+ .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP |
NL80211_FLAG_CLEAR_SKB),
},
{
@@ -18377,7 +18433,7 @@ static const struct genl_small_ops nl80211_small_ops[] = {
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.doit = nl80211_del_key,
.flags = GENL_UNS_ADMIN_PERM,
- .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
+ .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
},
{
.cmd = NL80211_CMD_SET_BEACON,
@@ -18408,21 +18464,21 @@ static const struct genl_small_ops nl80211_small_ops[] = {
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.doit = nl80211_get_station,
.dumpit = nl80211_dump_station,
- .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV),
+ .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV),
},
{
.cmd = NL80211_CMD_SET_STATION,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.doit = nl80211_set_station,
.flags = GENL_UNS_ADMIN_PERM,
- .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
+ .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
},
{
.cmd = NL80211_CMD_NEW_STATION,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.doit = nl80211_new_station,
.flags = GENL_UNS_ADMIN_PERM,
- .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
+ .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
},
{
.cmd = NL80211_CMD_DEL_STATION,
@@ -18433,7 +18489,7 @@ static const struct genl_small_ops nl80211_small_ops[] = {
* whether MAC address is passed or not. If MAC address is
* passed, then even during MLO, link ID is not required.
*/
- .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
+ .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
},
{
.cmd = NL80211_CMD_GET_MPATH,
@@ -20364,21 +20420,21 @@ void cfg80211_tx_mgmt_expired(struct wireless_dev *wdev, u64 cookie,
}
EXPORT_SYMBOL(cfg80211_tx_mgmt_expired);
-void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
+void cfg80211_new_sta(struct wireless_dev *wdev, const u8 *mac_addr,
struct station_info *sinfo, gfp_t gfp)
{
- struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
+ struct wiphy *wiphy = wdev->wiphy;
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
struct sk_buff *msg;
- trace_cfg80211_new_sta(dev, mac_addr, sinfo);
+ trace_cfg80211_new_sta(wdev, mac_addr, sinfo);
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
if (!msg)
return;
if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION, 0, 0, 0,
- rdev, dev, mac_addr, sinfo, false) < 0) {
+ rdev, wdev, mac_addr, sinfo, false) < 0) {
nlmsg_free(msg);
return;
}
@@ -20388,10 +20444,10 @@ void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
}
EXPORT_SYMBOL(cfg80211_new_sta);
-void cfg80211_del_sta_sinfo(struct net_device *dev, const u8 *mac_addr,
+void cfg80211_del_sta_sinfo(struct wireless_dev *wdev, const u8 *mac_addr,
struct station_info *sinfo, gfp_t gfp)
{
- struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
+ struct wiphy *wiphy = wdev->wiphy;
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
struct sk_buff *msg;
struct station_info empty_sinfo = {};
@@ -20399,7 +20455,7 @@ void cfg80211_del_sta_sinfo(struct net_device *dev, const u8 *mac_addr,
if (!sinfo)
sinfo = &empty_sinfo;
- trace_cfg80211_del_sta(dev, mac_addr);
+ trace_cfg80211_del_sta(wdev, mac_addr);
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
if (!msg) {
@@ -20408,7 +20464,7 @@ void cfg80211_del_sta_sinfo(struct net_device *dev, const u8 *mac_addr,
}
if (nl80211_send_station(msg, NL80211_CMD_DEL_STATION, 0, 0, 0,
- rdev, dev, mac_addr, sinfo, false) < 0) {
+ rdev, wdev, mac_addr, sinfo, false) < 0) {
nlmsg_free(msg);
return;
}
@@ -21120,6 +21176,46 @@ void cfg80211_ch_switch_notify(struct net_device *dev,
}
EXPORT_SYMBOL(cfg80211_ch_switch_notify);
+void cfg80211_incumbent_signal_notify(struct wiphy *wiphy,
+ const struct cfg80211_chan_def *chandef,
+ u32 signal_interference_bitmap,
+ gfp_t gfp)
+{
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
+ struct sk_buff *msg;
+ void *hdr;
+
+ trace_cfg80211_incumbent_signal_notify(wiphy, chandef, signal_interference_bitmap);
+
+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
+ if (!msg)
+ return;
+
+ hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_INCUMBENT_SIGNAL_DETECT);
+ if (!hdr)
+ goto nla_put_failure;
+
+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
+ goto nla_put_failure;
+
+ if (nl80211_send_chandef(msg, chandef))
+ goto nla_put_failure;
+
+ if (nla_put_u32(msg, NL80211_ATTR_INCUMBENT_SIGNAL_INTERFERENCE_BITMAP,
+ signal_interference_bitmap))
+ goto nla_put_failure;
+
+ genlmsg_end(msg, hdr);
+
+ genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
+ NL80211_MCGRP_MLME, gfp);
+ return;
+
+nla_put_failure:
+ nlmsg_free(msg);
+}
+EXPORT_SYMBOL(cfg80211_incumbent_signal_notify);
+
void cfg80211_ch_switch_started_notify(struct net_device *dev,
struct cfg80211_chan_def *chandef,
unsigned int link_id, u8 count,
@@ -21222,6 +21318,13 @@ nl80211_radar_notify(struct cfg80211_registered_device *rdev,
goto nla_put_failure;
}
+ if (rdev->background_radar_wdev &&
+ cfg80211_chandef_identical(&rdev->background_radar_chandef,
+ chandef)) {
+ if (nla_put_flag(msg, NL80211_ATTR_RADAR_BACKGROUND))
+ goto nla_put_failure;
+ }
+
if (nla_put_u32(msg, NL80211_ATTR_RADAR_EVENT, event))
goto nla_put_failure;
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index 5e25782af1e0..048ba92c3e42 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Portions of this file
- * Copyright (C) 2018, 2020-2024 Intel Corporation
+ * Copyright (C) 2018, 2020-2025 Intel Corporation
*/
#ifndef __NET_WIRELESS_NL80211_H
#define __NET_WIRELESS_NL80211_H
@@ -23,7 +23,8 @@ static inline u64 wdev_id(struct wireless_dev *wdev)
}
int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
- struct genl_info *info,
+ struct netlink_ext_ack *extack,
+ struct nlattr **attrs,
struct cfg80211_chan_def *chandef);
int nl80211_parse_random_mac(struct nlattr **attrs,
u8 *mac_addr, u8 *mac_addr_mask);
diff --git a/net/wireless/pmsr.c b/net/wireless/pmsr.c
index 44bd88c9ea66..556f30f5d60a 100644
--- a/net/wireless/pmsr.c
+++ b/net/wireless/pmsr.c
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C) 2018 - 2021, 2023 - 2024 Intel Corporation
+ * Copyright (C) 2018 - 2021, 2023 - 2026 Intel Corporation
*/
#include <net/cfg80211.h>
#include "core.h"
@@ -237,7 +237,8 @@ static int pmsr_parse_peer(struct cfg80211_registered_device *rdev,
if (err)
return err;
- err = nl80211_parse_chandef(rdev, info, &out->chandef);
+ err = nl80211_parse_chandef(rdev, info->extack, info->attrs,
+ &out->chandef);
if (err)
return err;
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index ac6884bacf3f..2bad8b60b7c9 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -2,7 +2,7 @@
/*
* Portions of this file
* Copyright(c) 2016-2017 Intel Deutschland GmbH
- * Copyright (C) 2018, 2021-2025 Intel Corporation
+ * Copyright (C) 2018, 2021-2026 Intel Corporation
*/
#ifndef __CFG80211_RDEV_OPS
#define __CFG80211_RDEV_OPS
@@ -77,42 +77,42 @@ rdev_change_virtual_intf(struct cfg80211_registered_device *rdev,
}
static inline int rdev_add_key(struct cfg80211_registered_device *rdev,
- struct net_device *netdev, int link_id,
+ struct wireless_dev *wdev, int link_id,
u8 key_index, bool pairwise, const u8 *mac_addr,
struct key_params *params)
{
int ret;
- trace_rdev_add_key(&rdev->wiphy, netdev, link_id, key_index, pairwise,
+ trace_rdev_add_key(&rdev->wiphy, wdev, link_id, key_index, pairwise,
mac_addr, params->mode);
- ret = rdev->ops->add_key(&rdev->wiphy, netdev, link_id, key_index,
+ ret = rdev->ops->add_key(&rdev->wiphy, wdev, link_id, key_index,
pairwise, mac_addr, params);
trace_rdev_return_int(&rdev->wiphy, ret);
return ret;
}
static inline int
-rdev_get_key(struct cfg80211_registered_device *rdev, struct net_device *netdev,
+rdev_get_key(struct cfg80211_registered_device *rdev, struct wireless_dev *wdev,
int link_id, u8 key_index, bool pairwise, const u8 *mac_addr,
void *cookie,
void (*callback)(void *cookie, struct key_params*))
{
int ret;
- trace_rdev_get_key(&rdev->wiphy, netdev, link_id, key_index, pairwise,
+ trace_rdev_get_key(&rdev->wiphy, wdev, link_id, key_index, pairwise,
mac_addr);
- ret = rdev->ops->get_key(&rdev->wiphy, netdev, link_id, key_index,
+ ret = rdev->ops->get_key(&rdev->wiphy, wdev, link_id, key_index,
pairwise, mac_addr, cookie, callback);
trace_rdev_return_int(&rdev->wiphy, ret);
return ret;
}
static inline int rdev_del_key(struct cfg80211_registered_device *rdev,
- struct net_device *netdev, int link_id,
+ struct wireless_dev *wdev, int link_id,
u8 key_index, bool pairwise, const u8 *mac_addr)
{
int ret;
- trace_rdev_del_key(&rdev->wiphy, netdev, link_id, key_index, pairwise,
+ trace_rdev_del_key(&rdev->wiphy, wdev, link_id, key_index, pairwise,
mac_addr);
- ret = rdev->ops->del_key(&rdev->wiphy, netdev, link_id, key_index,
+ ret = rdev->ops->del_key(&rdev->wiphy, wdev, link_id, key_index,
pairwise, mac_addr);
trace_rdev_return_int(&rdev->wiphy, ret);
return ret;
@@ -134,12 +134,12 @@ rdev_set_default_key(struct cfg80211_registered_device *rdev,
static inline int
rdev_set_default_mgmt_key(struct cfg80211_registered_device *rdev,
- struct net_device *netdev, int link_id, u8 key_index)
+ struct wireless_dev *wdev, int link_id, u8 key_index)
{
int ret;
- trace_rdev_set_default_mgmt_key(&rdev->wiphy, netdev, link_id,
+ trace_rdev_set_default_mgmt_key(&rdev->wiphy, wdev, link_id,
key_index);
- ret = rdev->ops->set_default_mgmt_key(&rdev->wiphy, netdev, link_id,
+ ret = rdev->ops->set_default_mgmt_key(&rdev->wiphy, wdev, link_id,
key_index);
trace_rdev_return_int(&rdev->wiphy, ret);
return ret;
@@ -147,14 +147,14 @@ rdev_set_default_mgmt_key(struct cfg80211_registered_device *rdev,
static inline int
rdev_set_default_beacon_key(struct cfg80211_registered_device *rdev,
- struct net_device *netdev, int link_id,
+ struct wireless_dev *wdev, int link_id,
u8 key_index)
{
int ret;
- trace_rdev_set_default_beacon_key(&rdev->wiphy, netdev, link_id,
+ trace_rdev_set_default_beacon_key(&rdev->wiphy, wdev, link_id,
key_index);
- ret = rdev->ops->set_default_beacon_key(&rdev->wiphy, netdev, link_id,
+ ret = rdev->ops->set_default_beacon_key(&rdev->wiphy, wdev, link_id,
key_index);
trace_rdev_return_int(&rdev->wiphy, ret);
return ret;
@@ -193,56 +193,56 @@ static inline int rdev_stop_ap(struct cfg80211_registered_device *rdev,
}
static inline int rdev_add_station(struct cfg80211_registered_device *rdev,
- struct net_device *dev, u8 *mac,
+ struct wireless_dev *wdev, u8 *mac,
struct station_parameters *params)
{
int ret;
- trace_rdev_add_station(&rdev->wiphy, dev, mac, params);
- ret = rdev->ops->add_station(&rdev->wiphy, dev, mac, params);
+ trace_rdev_add_station(&rdev->wiphy, wdev, mac, params);
+ ret = rdev->ops->add_station(&rdev->wiphy, wdev, mac, params);
trace_rdev_return_int(&rdev->wiphy, ret);
return ret;
}
static inline int rdev_del_station(struct cfg80211_registered_device *rdev,
- struct net_device *dev,
+ struct wireless_dev *wdev,
struct station_del_parameters *params)
{
int ret;
- trace_rdev_del_station(&rdev->wiphy, dev, params);
- ret = rdev->ops->del_station(&rdev->wiphy, dev, params);
+ trace_rdev_del_station(&rdev->wiphy, wdev, params);
+ ret = rdev->ops->del_station(&rdev->wiphy, wdev, params);
trace_rdev_return_int(&rdev->wiphy, ret);
return ret;
}
static inline int rdev_change_station(struct cfg80211_registered_device *rdev,
- struct net_device *dev, u8 *mac,
+ struct wireless_dev *wdev, u8 *mac,
struct station_parameters *params)
{
int ret;
- trace_rdev_change_station(&rdev->wiphy, dev, mac, params);
- ret = rdev->ops->change_station(&rdev->wiphy, dev, mac, params);
+ trace_rdev_change_station(&rdev->wiphy, wdev, mac, params);
+ ret = rdev->ops->change_station(&rdev->wiphy, wdev, mac, params);
trace_rdev_return_int(&rdev->wiphy, ret);
return ret;
}
static inline int rdev_get_station(struct cfg80211_registered_device *rdev,
- struct net_device *dev, const u8 *mac,
+ struct wireless_dev *wdev, const u8 *mac,
struct station_info *sinfo)
{
int ret;
- trace_rdev_get_station(&rdev->wiphy, dev, mac);
- ret = rdev->ops->get_station(&rdev->wiphy, dev, mac, sinfo);
+ trace_rdev_get_station(&rdev->wiphy, wdev, mac);
+ ret = rdev->ops->get_station(&rdev->wiphy, wdev, mac, sinfo);
trace_rdev_return_int_station_info(&rdev->wiphy, ret, sinfo);
return ret;
}
static inline int rdev_dump_station(struct cfg80211_registered_device *rdev,
- struct net_device *dev, int idx, u8 *mac,
+ struct wireless_dev *wdev, int idx, u8 *mac,
struct station_info *sinfo)
{
int ret;
- trace_rdev_dump_station(&rdev->wiphy, dev, idx, mac);
- ret = rdev->ops->dump_station(&rdev->wiphy, dev, idx, mac, sinfo);
+ trace_rdev_dump_station(&rdev->wiphy, wdev, idx, mac);
+ ret = rdev->ops->dump_station(&rdev->wiphy, wdev, idx, mac, sinfo);
trace_rdev_return_int_station_info(&rdev->wiphy, ret, sinfo);
return ret;
}
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 5b21432450d5..86e2ccaa678c 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -5,7 +5,7 @@
* (for nl80211's connect() and wext)
*
* Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
- * Copyright (C) 2009, 2020, 2022-2025 Intel Corporation. All rights reserved.
+ * Copyright (C) 2009, 2020, 2022-2026 Intel Corporation. All rights reserved.
* Copyright 2017 Intel Deutschland GmbH
*/
@@ -1386,7 +1386,7 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT))
max_key_idx = 7;
for (i = 0; i <= max_key_idx; i++)
- rdev_del_key(rdev, dev, -1, i, false, NULL);
+ rdev_del_key(rdev, wdev, -1, i, false, NULL);
}
rdev_set_qos_map(rdev, dev, NULL);
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
index 2e0ea69b9604..3385a27468f7 100644
--- a/net/wireless/sysfs.c
+++ b/net/wireless/sysfs.c
@@ -99,26 +99,31 @@ static int wiphy_suspend(struct device *dev)
rdev->suspend_at = ktime_get_boottime_seconds();
rtnl_lock();
+ if (!rdev->wiphy.registered)
+ goto out_unlock_rtnl;
+
wiphy_lock(&rdev->wiphy);
- if (rdev->wiphy.registered) {
- if (!rdev->wiphy.wowlan_config) {
- cfg80211_leave_all(rdev);
- cfg80211_process_rdev_events(rdev);
- }
+ if (rdev->wiphy.wowlan_config) {
cfg80211_process_wiphy_works(rdev, NULL);
if (rdev->ops->suspend)
ret = rdev_suspend(rdev, rdev->wiphy.wowlan_config);
- if (ret == 1) {
- /* Driver refuse to configure wowlan */
- cfg80211_leave_all(rdev);
- cfg80211_process_rdev_events(rdev);
- cfg80211_process_wiphy_works(rdev, NULL);
- ret = rdev_suspend(rdev, NULL);
- }
- if (ret == 0)
- rdev->suspended = true;
+ if (ret <= 0)
+ goto out_unlock_wiphy;
}
+
+ /* Driver refused to configure wowlan (ret = 1) or no wowlan */
+
+ cfg80211_leave_all(rdev);
+ cfg80211_process_rdev_events(rdev);
+ cfg80211_process_wiphy_works(rdev, NULL);
+ if (rdev->ops->suspend)
+ ret = rdev_suspend(rdev, NULL);
+
+out_unlock_wiphy:
wiphy_unlock(&rdev->wiphy);
+out_unlock_rtnl:
+ if (ret == 0)
+ rdev->suspended = true;
rtnl_unlock();
return ret;
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 643ccf4f0227..af23f4fca90a 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -2,7 +2,7 @@
/*
* Portions of this file
* Copyright(c) 2016-2017 Intel Deutschland GmbH
- * Copyright (C) 2018, 2020-2025 Intel Corporation
+ * Copyright (C) 2018, 2020-2026 Intel Corporation
*/
#undef TRACE_SYSTEM
#define TRACE_SYSTEM cfg80211
@@ -546,12 +546,12 @@ TRACE_EVENT(rdev_change_virtual_intf,
);
DECLARE_EVENT_CLASS(key_handle,
- TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int link_id,
+ TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, int link_id,
u8 key_index, bool pairwise, const u8 *mac_addr),
- TP_ARGS(wiphy, netdev, link_id, key_index, pairwise, mac_addr),
+ TP_ARGS(wiphy, wdev, link_id, key_index, pairwise, mac_addr),
TP_STRUCT__entry(
WIPHY_ENTRY
- NETDEV_ENTRY
+ WDEV_ENTRY
MAC_ENTRY(mac_addr)
__field(int, link_id)
__field(u8, key_index)
@@ -559,38 +559,38 @@ DECLARE_EVENT_CLASS(key_handle,
),
TP_fast_assign(
WIPHY_ASSIGN;
- NETDEV_ASSIGN;
+ WDEV_ASSIGN;
MAC_ASSIGN(mac_addr, mac_addr);
__entry->link_id = link_id;
__entry->key_index = key_index;
__entry->pairwise = pairwise;
),
- TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", link_id: %d, "
+ TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", link_id: %d, "
"key_index: %u, pairwise: %s, mac addr: %pM",
- WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->link_id,
+ WIPHY_PR_ARG, WDEV_PR_ARG, __entry->link_id,
__entry->key_index, BOOL_TO_STR(__entry->pairwise),
__entry->mac_addr)
);
DEFINE_EVENT(key_handle, rdev_get_key,
- TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int link_id,
+ TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, int link_id,
u8 key_index, bool pairwise, const u8 *mac_addr),
- TP_ARGS(wiphy, netdev, link_id, key_index, pairwise, mac_addr)
+ TP_ARGS(wiphy, wdev, link_id, key_index, pairwise, mac_addr)
);
DEFINE_EVENT(key_handle, rdev_del_key,
- TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int link_id,
+ TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, int link_id,
u8 key_index, bool pairwise, const u8 *mac_addr),
- TP_ARGS(wiphy, netdev, link_id, key_index, pairwise, mac_addr)
+ TP_ARGS(wiphy, wdev, link_id, key_index, pairwise, mac_addr)
);
TRACE_EVENT(rdev_add_key,
- TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int link_id,
+ TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, int link_id,
u8 key_index, bool pairwise, const u8 *mac_addr, u8 mode),
- TP_ARGS(wiphy, netdev, link_id, key_index, pairwise, mac_addr, mode),
+ TP_ARGS(wiphy, wdev, link_id, key_index, pairwise, mac_addr, mode),
TP_STRUCT__entry(
WIPHY_ENTRY
- NETDEV_ENTRY
+ WDEV_ENTRY
MAC_ENTRY(mac_addr)
__field(int, link_id)
__field(u8, key_index)
@@ -599,17 +599,17 @@ TRACE_EVENT(rdev_add_key,
),
TP_fast_assign(
WIPHY_ASSIGN;
- NETDEV_ASSIGN;
+ WDEV_ASSIGN;
MAC_ASSIGN(mac_addr, mac_addr);
__entry->link_id = link_id;
__entry->key_index = key_index;
__entry->pairwise = pairwise;
__entry->mode = mode;
),
- TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", link_id: %d, "
+ TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", link_id: %d, "
"key_index: %u, mode: %u, pairwise: %s, "
"mac addr: %pM",
- WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->link_id,
+ WIPHY_PR_ARG, WDEV_PR_ARG, __entry->link_id,
__entry->key_index, __entry->mode,
BOOL_TO_STR(__entry->pairwise), __entry->mac_addr)
);
@@ -642,45 +642,45 @@ TRACE_EVENT(rdev_set_default_key,
);
TRACE_EVENT(rdev_set_default_mgmt_key,
- TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int link_id,
+ TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, int link_id,
u8 key_index),
- TP_ARGS(wiphy, netdev, link_id, key_index),
+ TP_ARGS(wiphy, wdev, link_id, key_index),
TP_STRUCT__entry(
WIPHY_ENTRY
- NETDEV_ENTRY
+ WDEV_ENTRY
__field(int, link_id)
__field(u8, key_index)
),
TP_fast_assign(
WIPHY_ASSIGN;
- NETDEV_ASSIGN;
+ WDEV_ASSIGN;
__entry->link_id = link_id;
__entry->key_index = key_index;
),
- TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", link_id: %d, "
- "key index: %u", WIPHY_PR_ARG, NETDEV_PR_ARG,
- __entry->link_id, __entry->key_index)
+ TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", link_id: %d, key index: %u",
+ WIPHY_PR_ARG, WDEV_PR_ARG, __entry->link_id,
+ __entry->key_index)
);
TRACE_EVENT(rdev_set_default_beacon_key,
- TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int link_id,
+ TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, int link_id,
u8 key_index),
- TP_ARGS(wiphy, netdev, link_id, key_index),
+ TP_ARGS(wiphy, wdev, link_id, key_index),
TP_STRUCT__entry(
WIPHY_ENTRY
- NETDEV_ENTRY
+ WDEV_ENTRY
__field(int, link_id)
__field(u8, key_index)
),
TP_fast_assign(
WIPHY_ASSIGN;
- NETDEV_ASSIGN;
+ WDEV_ASSIGN;
__entry->link_id = link_id;
__entry->key_index = key_index;
),
- TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", link_id: %d, "
- "key index: %u", WIPHY_PR_ARG, NETDEV_PR_ARG,
- __entry->link_id, __entry->key_index)
+ TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", link_id: %d, key index: %u",
+ WIPHY_PR_ARG, WDEV_PR_ARG, __entry->link_id,
+ __entry->key_index)
);
TRACE_EVENT(rdev_start_ap,
@@ -856,12 +856,12 @@ TRACE_EVENT(rdev_end_cac,
);
DECLARE_EVENT_CLASS(station_add_change,
- TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 *mac,
+ TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, u8 *mac,
struct station_parameters *params),
- TP_ARGS(wiphy, netdev, mac, params),
+ TP_ARGS(wiphy, wdev, mac, params),
TP_STRUCT__entry(
WIPHY_ENTRY
- NETDEV_ENTRY
+ WDEV_ENTRY
MAC_ENTRY(sta_mac)
__field(u32, sta_flags_mask)
__field(u32, sta_flags_set)
@@ -888,7 +888,7 @@ DECLARE_EVENT_CLASS(station_add_change,
),
TP_fast_assign(
WIPHY_ASSIGN;
- NETDEV_ASSIGN;
+ WDEV_ASSIGN;
MAC_ASSIGN(sta_mac, mac);
__entry->sta_flags_mask = params->sta_flags_mask;
__entry->sta_flags_set = params->sta_flags_set;
@@ -936,11 +936,11 @@ DECLARE_EVENT_CLASS(station_add_change,
__entry->opmode_notif_used =
params->link_sta_params.opmode_notif_used;
),
- TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", station mac: %pM"
+ TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", station mac: %pM"
", station flags mask: 0x%x, station flags set: 0x%x, "
"station modify mask: 0x%x, listen interval: %d, aid: %u, "
"plink action: %u, plink state: %u, uapsd queues: %u, vlan:%s",
- WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->sta_mac,
+ WIPHY_PR_ARG, WDEV_PR_ARG, __entry->sta_mac,
__entry->sta_flags_mask, __entry->sta_flags_set,
__entry->sta_modify_mask, __entry->listen_interval,
__entry->aid, __entry->plink_action, __entry->plink_state,
@@ -948,15 +948,15 @@ DECLARE_EVENT_CLASS(station_add_change,
);
DEFINE_EVENT(station_add_change, rdev_add_station,
- TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 *mac,
+ TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, u8 *mac,
struct station_parameters *params),
- TP_ARGS(wiphy, netdev, mac, params)
+ TP_ARGS(wiphy, wdev, mac, params)
);
DEFINE_EVENT(station_add_change, rdev_change_station,
- TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 *mac,
+ TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, u8 *mac,
struct station_parameters *params),
- TP_ARGS(wiphy, netdev, mac, params)
+ TP_ARGS(wiphy, wdev, mac, params)
);
DECLARE_EVENT_CLASS(wiphy_netdev_mac_evt,
@@ -977,12 +977,12 @@ DECLARE_EVENT_CLASS(wiphy_netdev_mac_evt,
);
DECLARE_EVENT_CLASS(station_del,
- TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
+ TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
struct station_del_parameters *params),
- TP_ARGS(wiphy, netdev, params),
+ TP_ARGS(wiphy, wdev, params),
TP_STRUCT__entry(
WIPHY_ENTRY
- NETDEV_ENTRY
+ WDEV_ENTRY
MAC_ENTRY(sta_mac)
__field(u8, subtype)
__field(u16, reason_code)
@@ -990,28 +990,45 @@ DECLARE_EVENT_CLASS(station_del,
),
TP_fast_assign(
WIPHY_ASSIGN;
- NETDEV_ASSIGN;
+ WDEV_ASSIGN;
MAC_ASSIGN(sta_mac, params->mac);
__entry->subtype = params->subtype;
__entry->reason_code = params->reason_code;
__entry->link_id = params->link_id;
),
- TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", station mac: %pM"
+ TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", station mac: %pM"
", subtype: %u, reason_code: %u, link_id: %d",
- WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->sta_mac,
+ WIPHY_PR_ARG, WDEV_PR_ARG, __entry->sta_mac,
__entry->subtype, __entry->reason_code,
__entry->link_id)
);
DEFINE_EVENT(station_del, rdev_del_station,
- TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
+ TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
struct station_del_parameters *params),
- TP_ARGS(wiphy, netdev, params)
+ TP_ARGS(wiphy, wdev, params)
);
-DEFINE_EVENT(wiphy_netdev_mac_evt, rdev_get_station,
- TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, const u8 *mac),
- TP_ARGS(wiphy, netdev, mac)
+DECLARE_EVENT_CLASS(wiphy_wdev_mac_evt,
+ TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, const u8 *mac),
+ TP_ARGS(wiphy, wdev, mac),
+ TP_STRUCT__entry(
+ WIPHY_ENTRY
+ WDEV_ENTRY
+ MAC_ENTRY(sta_mac)
+ ),
+ TP_fast_assign(
+ WIPHY_ASSIGN;
+ WDEV_ASSIGN;
+ MAC_ASSIGN(sta_mac, mac);
+ ),
+ TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", mac: %pM",
+ WIPHY_PR_ARG, WDEV_PR_ARG, __entry->sta_mac)
+);
+
+DEFINE_EVENT(wiphy_wdev_mac_evt, rdev_get_station,
+ TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, const u8 *mac),
+ TP_ARGS(wiphy, wdev, mac)
);
DEFINE_EVENT(wiphy_netdev_mac_evt, rdev_del_mpath,
@@ -1020,23 +1037,23 @@ DEFINE_EVENT(wiphy_netdev_mac_evt, rdev_del_mpath,
);
TRACE_EVENT(rdev_dump_station,
- TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int _idx,
+ TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, int _idx,
u8 *mac),
- TP_ARGS(wiphy, netdev, _idx, mac),
+ TP_ARGS(wiphy, wdev, _idx, mac),
TP_STRUCT__entry(
WIPHY_ENTRY
- NETDEV_ENTRY
+ WDEV_ENTRY
MAC_ENTRY(sta_mac)
__field(int, idx)
),
TP_fast_assign(
WIPHY_ASSIGN;
- NETDEV_ASSIGN;
+ WDEV_ASSIGN;
MAC_ASSIGN(sta_mac, mac);
__entry->idx = _idx;
),
- TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", station mac: %pM, idx: %d",
- WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->sta_mac,
+ TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", station mac: %pM, idx: %d",
+ WIPHY_PR_ARG, WDEV_PR_ARG, __entry->sta_mac,
__entry->idx)
);
@@ -3153,6 +3170,21 @@ DECLARE_EVENT_CLASS(cfg80211_netdev_mac_evt,
NETDEV_PR_ARG, __entry->macaddr)
);
+DECLARE_EVENT_CLASS(cfg80211_wdev_mac_evt,
+ TP_PROTO(struct wireless_dev *wdev, const u8 *macaddr),
+ TP_ARGS(wdev, macaddr),
+ TP_STRUCT__entry(
+ WDEV_ENTRY
+ MAC_ENTRY(macaddr)
+ ),
+ TP_fast_assign(
+ WDEV_ASSIGN;
+ MAC_ASSIGN(macaddr, macaddr);
+ ),
+ TP_printk(WDEV_PR_FMT ", mac: %pM",
+ WDEV_PR_ARG, __entry->macaddr)
+);
+
DEFINE_EVENT(cfg80211_netdev_mac_evt, cfg80211_notify_new_peer_candidate,
TP_PROTO(struct net_device *netdev, const u8 *macaddr),
TP_ARGS(netdev, macaddr)
@@ -3342,26 +3374,26 @@ TRACE_EVENT(cfg80211_tx_mgmt_expired,
);
TRACE_EVENT(cfg80211_new_sta,
- TP_PROTO(struct net_device *netdev, const u8 *mac_addr,
+ TP_PROTO(struct wireless_dev *wdev, const u8 *mac_addr,
struct station_info *sinfo),
- TP_ARGS(netdev, mac_addr, sinfo),
+ TP_ARGS(wdev, mac_addr, sinfo),
TP_STRUCT__entry(
- NETDEV_ENTRY
+ WDEV_ENTRY
MAC_ENTRY(mac_addr)
SINFO_ENTRY
),
TP_fast_assign(
- NETDEV_ASSIGN;
+ WDEV_ASSIGN;
MAC_ASSIGN(mac_addr, mac_addr);
SINFO_ASSIGN;
),
- TP_printk(NETDEV_PR_FMT ", %pM",
- NETDEV_PR_ARG, __entry->mac_addr)
+ TP_printk(WDEV_PR_FMT ", %pM",
+ WDEV_PR_ARG, __entry->mac_addr)
);
-DEFINE_EVENT(cfg80211_netdev_mac_evt, cfg80211_del_sta,
- TP_PROTO(struct net_device *netdev, const u8 *macaddr),
- TP_ARGS(netdev, macaddr)
+DEFINE_EVENT(cfg80211_wdev_mac_evt, cfg80211_del_sta,
+ TP_PROTO(struct wireless_dev *wdev, const u8 *macaddr),
+ TP_ARGS(wdev, macaddr)
);
TRACE_EVENT(cfg80211_rx_mgmt,
@@ -4225,6 +4257,25 @@ TRACE_EVENT(cfg80211_nan_cluster_joined,
WDEV_PR_ARG, __entry->cluster_id,
__entry->new_cluster ? " [new]" : "")
);
+
+TRACE_EVENT(cfg80211_incumbent_signal_notify,
+ TP_PROTO(struct wiphy *wiphy,
+ const struct cfg80211_chan_def *chandef,
+ u32 signal_interference_bitmap),
+ TP_ARGS(wiphy, chandef, signal_interference_bitmap),
+ TP_STRUCT__entry(
+ WIPHY_ENTRY
+ CHAN_DEF_ENTRY
+ __field(u32, signal_interference_bitmap)
+ ),
+ TP_fast_assign(
+ WIPHY_ASSIGN;
+ CHAN_DEF_ASSIGN(chandef);
+ __entry->signal_interference_bitmap = signal_interference_bitmap;
+ ),
+ TP_printk(WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT ", signal_interference_bitmap=0x%x",
+ WIPHY_PR_ARG, CHAN_DEF_PR_ARG, __entry->signal_interference_bitmap)
+);
#endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */
#undef TRACE_INCLUDE_PATH
diff --git a/net/wireless/util.c b/net/wireless/util.c
index b78530c3e3f8..0a0cea018fc5 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1095,7 +1095,7 @@ void cfg80211_upload_connect_keys(struct wireless_dev *wdev)
for (i = 0; i < 4; i++) {
if (!wdev->connect_keys->params[i].cipher)
continue;
- if (rdev_add_key(rdev, dev, -1, i, false, NULL,
+ if (rdev_add_key(rdev, wdev, -1, i, false, NULL,
&wdev->connect_keys->params[i])) {
netdev_err(dev, "failed to set key %d\n", i);
continue;
@@ -2669,7 +2669,7 @@ int cfg80211_get_station(struct net_device *dev, const u8 *mac_addr,
guard(wiphy)(&rdev->wiphy);
- return rdev_get_station(rdev, dev, mac_addr, sinfo);
+ return rdev_get_station(rdev, wdev, mac_addr, sinfo);
}
EXPORT_SYMBOL(cfg80211_get_station);
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 5a70a0120343..22d9d9bae8f5 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -7,7 +7,7 @@
* we directly assign the wireless handlers of wireless interfaces.
*
* Copyright 2008-2009 Johannes Berg <johannes@sipsolutions.net>
- * Copyright (C) 2019-2023 Intel Corporation
+ * Copyright (C) 2019-2023, 2026 Intel Corporation
*/
#include <linux/export.h>
@@ -457,7 +457,7 @@ static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
!(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
err = -ENOENT;
else
- err = rdev_del_key(rdev, dev, -1, idx, pairwise,
+ err = rdev_del_key(rdev, wdev, -1, idx, pairwise,
addr);
}
wdev->wext.connect.privacy = false;
@@ -496,7 +496,7 @@ static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
if (wdev->connected ||
(wdev->iftype == NL80211_IFTYPE_ADHOC &&
wdev->u.ibss.current_bss))
- err = rdev_add_key(rdev, dev, -1, idx, pairwise, addr, params);
+ err = rdev_add_key(rdev, wdev, -1, idx, pairwise, addr, params);
else if (params->cipher != WLAN_CIPHER_SUITE_WEP40 &&
params->cipher != WLAN_CIPHER_SUITE_WEP104)
return -EINVAL;
@@ -549,7 +549,7 @@ static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
if (wdev->connected ||
(wdev->iftype == NL80211_IFTYPE_ADHOC &&
wdev->u.ibss.current_bss))
- err = rdev_set_default_mgmt_key(rdev, dev, -1, idx);
+ err = rdev_set_default_mgmt_key(rdev, wdev, -1, idx);
if (!err)
wdev->wext.default_mgmt_key = idx;
return err;
@@ -1261,7 +1261,7 @@ static int cfg80211_wext_giwrate(struct net_device *dev,
return err;
scoped_guard(wiphy, &rdev->wiphy) {
- err = rdev_get_station(rdev, dev, addr, &sinfo);
+ err = rdev_get_station(rdev, wdev, addr, &sinfo);
}
if (err)
return err;
@@ -1305,7 +1305,7 @@ static struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev)
memset(&sinfo, 0, sizeof(sinfo));
- ret = rdev_get_station(rdev, dev, bssid, &sinfo);
+ ret = rdev_get_station(rdev, wdev, bssid, &sinfo);
wiphy_unlock(&rdev->wiphy);
if (ret)