summaryrefslogtreecommitdiffhomepage
path: root/net/wireless/mlme.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/mlme.c')
-rw-r--r--net/wireless/mlme.c64
1 files changed, 38 insertions, 26 deletions
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 3fc175f9f868..bd72317c4964 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -4,7 +4,7 @@
*
* Copyright (c) 2009, Jouni Malinen <j@w1.fi>
* Copyright (c) 2015 Intel Deutschland GmbH
- * Copyright (C) 2019-2020, 2022-2025 Intel Corporation
+ * Copyright (C) 2019-2020, 2022-2026 Intel Corporation
*/
#include <linux/kernel.h>
@@ -782,8 +782,8 @@ void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlportid)
rdev_crit_proto_stop(rdev, wdev);
}
- if (nlportid == wdev->ap_unexpected_nlportid)
- wdev->ap_unexpected_nlportid = 0;
+ if (nlportid == wdev->unexpected_nlportid)
+ wdev->unexpected_nlportid = 0;
}
void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev)
@@ -933,12 +933,17 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
* cfg80211 doesn't track the stations
*/
break;
+ case NL80211_IFTYPE_NAN:
+ case NL80211_IFTYPE_NAN_DATA:
+ if (mgmt->u.action.category !=
+ WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION)
+ err = -EOPNOTSUPP;
+ break;
case NL80211_IFTYPE_P2P_DEVICE:
/*
* fall through, P2P device only supports
* public action frames
*/
- case NL80211_IFTYPE_NAN:
default:
err = -EOPNOTSUPP;
break;
@@ -1115,8 +1120,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 +1167,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 +1196,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 +1220,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 +1227,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 +1318,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 +1336,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,