mirror of
https://github.com/openwrt/openwrt.git
synced 2025-02-20 17:32:57 +00:00
mac80211: backport upstream DFS fixes
Mostly MLO related Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
parent
c1c2b61254
commit
ec61ccc0d3
@ -1,5 +1,14 @@
|
||||
--- a/ath10k-6.9/mac.c
|
||||
+++ b/ath10k-6.9/mac.c
|
||||
@@ -1675,7 +1675,7 @@ static void ath10k_recalc_radar_detectio
|
||||
* by indicating that radar was detected.
|
||||
*/
|
||||
ath10k_warn(ar, "failed to start CAC: %d\n", ret);
|
||||
- ieee80211_radar_detected(ar->hw);
|
||||
+ ieee80211_radar_detected(ar->hw, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6238,7 +6238,7 @@ err:
|
||||
return ret;
|
||||
}
|
||||
@ -9,3 +18,25 @@
|
||||
{
|
||||
struct ath10k *ar = hw->priv;
|
||||
u32 opt;
|
||||
--- a/ath10k-6.9/debug.c
|
||||
+++ b/ath10k-6.9/debug.c
|
||||
@@ -3319,7 +3319,7 @@ static ssize_t ath10k_write_simulate_rad
|
||||
if (!arvif->is_started)
|
||||
return -EINVAL;
|
||||
|
||||
- ieee80211_radar_detected(ar->hw);
|
||||
+ ieee80211_radar_detected(ar->hw, NULL);
|
||||
|
||||
return count;
|
||||
}
|
||||
--- a/ath10k-6.9/wmi.c
|
||||
+++ b/ath10k-6.9/wmi.c
|
||||
@@ -4402,7 +4402,7 @@ static void ath10k_radar_detected(struct
|
||||
if (ar->dfs_block_radar_events)
|
||||
ath10k_info(ar, "DFS Radar detected, but ignored as requested\n");
|
||||
else
|
||||
- ieee80211_radar_detected(ar->hw);
|
||||
+ ieee80211_radar_detected(ar->hw, NULL);
|
||||
}
|
||||
|
||||
static void ath10k_radar_confirmation_work(struct work_struct *work)
|
||||
|
@ -0,0 +1,64 @@
|
||||
From: Issam Hamdi <ih@simonwunderlich.de>
|
||||
Date: Fri, 16 Aug 2024 16:24:18 +0200
|
||||
Subject: [PATCH] wifi: cfg80211: Set correct chandef when starting CAC
|
||||
|
||||
When starting CAC in a mode other than AP mode, it return a
|
||||
"WARNING: CPU: 0 PID: 63 at cfg80211_chandef_dfs_usable+0x20/0xaf [cfg80211]"
|
||||
caused by the chandef.chan being null at the end of CAC.
|
||||
|
||||
Solution: Ensure the channel definition is set for the different modes
|
||||
when starting CAC to avoid getting a NULL 'chan' at the end of CAC.
|
||||
|
||||
Call Trace:
|
||||
? show_regs.part.0+0x14/0x16
|
||||
? __warn+0x67/0xc0
|
||||
? cfg80211_chandef_dfs_usable+0x20/0xaf [cfg80211]
|
||||
? report_bug+0xa7/0x130
|
||||
? exc_overflow+0x30/0x30
|
||||
? handle_bug+0x27/0x50
|
||||
? exc_invalid_op+0x18/0x60
|
||||
? handle_exception+0xf6/0xf6
|
||||
? exc_overflow+0x30/0x30
|
||||
? cfg80211_chandef_dfs_usable+0x20/0xaf [cfg80211]
|
||||
? exc_overflow+0x30/0x30
|
||||
? cfg80211_chandef_dfs_usable+0x20/0xaf [cfg80211]
|
||||
? regulatory_propagate_dfs_state.cold+0x1b/0x4c [cfg80211]
|
||||
? cfg80211_propagate_cac_done_wk+0x1a/0x30 [cfg80211]
|
||||
? process_one_work+0x165/0x280
|
||||
? worker_thread+0x120/0x3f0
|
||||
? kthread+0xc2/0xf0
|
||||
? process_one_work+0x280/0x280
|
||||
? kthread_complete_and_exit+0x20/0x20
|
||||
? ret_from_fork+0x19/0x24
|
||||
|
||||
Reported-by: Kretschmer Mathias <mathias.kretschmer@fit.fraunhofer.de>
|
||||
Signed-off-by: Issam Hamdi <ih@simonwunderlich.de>
|
||||
Link: https://patch.msgid.link/20240816142418.3381951-1-ih@simonwunderlich.de
|
||||
[shorten subject, remove OCB, reorder cases to match previous list]
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/net/wireless/nl80211.c
|
||||
+++ b/net/wireless/nl80211.c
|
||||
@@ -10144,7 +10144,20 @@ static int nl80211_start_radar_detection
|
||||
|
||||
err = rdev_start_radar_detection(rdev, dev, &chandef, cac_time_ms);
|
||||
if (!err) {
|
||||
- wdev->links[0].ap.chandef = chandef;
|
||||
+ switch (wdev->iftype) {
|
||||
+ case NL80211_IFTYPE_AP:
|
||||
+ case NL80211_IFTYPE_P2P_GO:
|
||||
+ wdev->links[0].ap.chandef = chandef;
|
||||
+ break;
|
||||
+ case NL80211_IFTYPE_ADHOC:
|
||||
+ wdev->u.ibss.chandef = chandef;
|
||||
+ break;
|
||||
+ case NL80211_IFTYPE_MESH_POINT:
|
||||
+ wdev->u.mesh.chandef = chandef;
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
wdev->cac_started = true;
|
||||
wdev->cac_start_time = jiffies;
|
||||
wdev->cac_time_ms = cac_time_ms;
|
@ -0,0 +1,136 @@
|
||||
From: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
Date: Fri, 6 Sep 2024 12:14:19 +0530
|
||||
Subject: [PATCH] Revert "wifi: mac80211: move radar detect work to sdata"
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This reverts commit ce9e660ef32e ("wifi: mac80211: move radar detect work to sdata").
|
||||
|
||||
To enable radar detection with MLO, it’s essential to handle it on a
|
||||
per-link basis. This is because when using MLO, multiple links may already
|
||||
be active and beaconing. In this scenario, another link should be able to
|
||||
initiate a radar detection. Also, if underlying links are associated with
|
||||
different hardware devices but grouped together for MLO, they could
|
||||
potentially start radar detection simultaneously. Therefore, it makes
|
||||
sense to manage radar detection settings separately for each link by moving
|
||||
them back to a per-link data structure.
|
||||
|
||||
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
Link: https://patch.msgid.link/20240906064426.2101315-2-quic_adisi@quicinc.com
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -1658,7 +1658,7 @@ static int ieee80211_stop_ap(struct wiph
|
||||
|
||||
if (sdata->wdev.cac_started) {
|
||||
chandef = link_conf->chanreq.oper;
|
||||
- wiphy_delayed_work_cancel(wiphy, &sdata->dfs_cac_timer_work);
|
||||
+ wiphy_delayed_work_cancel(wiphy, &link->dfs_cac_timer_work);
|
||||
cfg80211_cac_event(sdata->dev, &chandef,
|
||||
NL80211_RADAR_CAC_ABORTED,
|
||||
GFP_KERNEL);
|
||||
@@ -3482,7 +3482,7 @@ static int ieee80211_start_radar_detecti
|
||||
if (err)
|
||||
goto out_unlock;
|
||||
|
||||
- wiphy_delayed_work_queue(wiphy, &sdata->dfs_cac_timer_work,
|
||||
+ wiphy_delayed_work_queue(wiphy, &sdata->deflink.dfs_cac_timer_work,
|
||||
msecs_to_jiffies(cac_time_ms));
|
||||
|
||||
out_unlock:
|
||||
@@ -3499,7 +3499,7 @@ static void ieee80211_end_cac(struct wip
|
||||
|
||||
list_for_each_entry(sdata, &local->interfaces, list) {
|
||||
wiphy_delayed_work_cancel(wiphy,
|
||||
- &sdata->dfs_cac_timer_work);
|
||||
+ &sdata->deflink.dfs_cac_timer_work);
|
||||
|
||||
if (sdata->wdev.cac_started) {
|
||||
ieee80211_link_release_channel(&sdata->deflink);
|
||||
--- a/net/mac80211/ieee80211_i.h
|
||||
+++ b/net/mac80211/ieee80211_i.h
|
||||
@@ -1069,6 +1069,7 @@ struct ieee80211_link_data {
|
||||
int ap_power_level; /* in dBm */
|
||||
|
||||
bool radar_required;
|
||||
+ struct wiphy_delayed_work dfs_cac_timer_work;
|
||||
|
||||
union {
|
||||
struct ieee80211_link_data_managed mgd;
|
||||
@@ -1167,8 +1168,6 @@ struct ieee80211_sub_if_data {
|
||||
struct ieee80211_link_data deflink;
|
||||
struct ieee80211_link_data __rcu *link[IEEE80211_MLD_MAX_NUM_LINKS];
|
||||
|
||||
- struct wiphy_delayed_work dfs_cac_timer_work;
|
||||
-
|
||||
/* for ieee80211_set_active_links_async() */
|
||||
struct wiphy_work activate_links_work;
|
||||
u16 desired_active_links;
|
||||
--- a/net/mac80211/iface.c
|
||||
+++ b/net/mac80211/iface.c
|
||||
@@ -551,7 +551,7 @@ static void ieee80211_do_stop(struct iee
|
||||
wiphy_work_cancel(local->hw.wiphy,
|
||||
&sdata->deflink.color_change_finalize_work);
|
||||
wiphy_delayed_work_cancel(local->hw.wiphy,
|
||||
- &sdata->dfs_cac_timer_work);
|
||||
+ &sdata->deflink.dfs_cac_timer_work);
|
||||
|
||||
if (sdata->wdev.cac_started) {
|
||||
chandef = sdata->vif.bss_conf.chanreq.oper;
|
||||
@@ -1744,8 +1744,6 @@ static void ieee80211_setup_sdata(struct
|
||||
wiphy_work_init(&sdata->work, ieee80211_iface_work);
|
||||
wiphy_work_init(&sdata->activate_links_work,
|
||||
ieee80211_activate_links_work);
|
||||
- wiphy_delayed_work_init(&sdata->dfs_cac_timer_work,
|
||||
- ieee80211_dfs_cac_timer_work);
|
||||
|
||||
switch (type) {
|
||||
case NL80211_IFTYPE_P2P_GO:
|
||||
--- a/net/mac80211/link.c
|
||||
+++ b/net/mac80211/link.c
|
||||
@@ -45,6 +45,8 @@ void ieee80211_link_init(struct ieee8021
|
||||
ieee80211_color_collision_detection_work);
|
||||
INIT_LIST_HEAD(&link->assigned_chanctx_list);
|
||||
INIT_LIST_HEAD(&link->reserved_chanctx_list);
|
||||
+ wiphy_delayed_work_init(&link->dfs_cac_timer_work,
|
||||
+ ieee80211_dfs_cac_timer_work);
|
||||
|
||||
if (!deflink) {
|
||||
switch (sdata->vif.type) {
|
||||
--- a/net/mac80211/mlme.c
|
||||
+++ b/net/mac80211/mlme.c
|
||||
@@ -3031,15 +3031,16 @@ void ieee80211_dynamic_ps_timer(struct t
|
||||
|
||||
void ieee80211_dfs_cac_timer_work(struct wiphy *wiphy, struct wiphy_work *work)
|
||||
{
|
||||
- struct ieee80211_sub_if_data *sdata =
|
||||
- container_of(work, struct ieee80211_sub_if_data,
|
||||
+ struct ieee80211_link_data *link =
|
||||
+ container_of(work, struct ieee80211_link_data,
|
||||
dfs_cac_timer_work.work);
|
||||
- struct cfg80211_chan_def chandef = sdata->vif.bss_conf.chanreq.oper;
|
||||
+ struct cfg80211_chan_def chandef = link->conf->chanreq.oper;
|
||||
+ struct ieee80211_sub_if_data *sdata = link->sdata;
|
||||
|
||||
lockdep_assert_wiphy(sdata->local->hw.wiphy);
|
||||
|
||||
if (sdata->wdev.cac_started) {
|
||||
- ieee80211_link_release_channel(&sdata->deflink);
|
||||
+ ieee80211_link_release_channel(link);
|
||||
cfg80211_cac_event(sdata->dev, &chandef,
|
||||
NL80211_RADAR_CAC_FINISHED,
|
||||
GFP_KERNEL);
|
||||
--- a/net/mac80211/util.c
|
||||
+++ b/net/mac80211/util.c
|
||||
@@ -3460,7 +3460,7 @@ void ieee80211_dfs_cac_cancel(struct iee
|
||||
|
||||
list_for_each_entry(sdata, &local->interfaces, list) {
|
||||
wiphy_delayed_work_cancel(local->hw.wiphy,
|
||||
- &sdata->dfs_cac_timer_work);
|
||||
+ &sdata->deflink.dfs_cac_timer_work);
|
||||
|
||||
if (sdata->wdev.cac_started) {
|
||||
chandef = sdata->vif.bss_conf.chanreq.oper;
|
@ -0,0 +1,50 @@
|
||||
From: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
Date: Fri, 6 Sep 2024 12:14:20 +0530
|
||||
Subject: [PATCH] wifi: mac80211: remove label usage in
|
||||
ieee80211_start_radar_detection()
|
||||
|
||||
After locks rework [1], ieee80211_start_radar_detection() function is no
|
||||
longer acquiring any lock as such explicitly. Hence, it is not unlocking
|
||||
anything as well. However, label "out_unlock" is still used which creates
|
||||
confusion. Also, now there is no need of goto label as such.
|
||||
|
||||
Get rid of the goto logic and use direct return statements.
|
||||
|
||||
[1]: https://lore.kernel.org/all/20230828135928.b1c6efffe9ad.I4aec875e25abc9ef0b5ad1e70b5747fd483fbd3c@changeid/
|
||||
|
||||
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
Link: https://patch.msgid.link/20240906064426.2101315-3-quic_adisi@quicinc.com
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -3468,10 +3468,8 @@ static int ieee80211_start_radar_detecti
|
||||
|
||||
lockdep_assert_wiphy(local->hw.wiphy);
|
||||
|
||||
- if (!list_empty(&local->roc_list) || local->scanning) {
|
||||
- err = -EBUSY;
|
||||
- goto out_unlock;
|
||||
- }
|
||||
+ if (!list_empty(&local->roc_list) || local->scanning)
|
||||
+ return -EBUSY;
|
||||
|
||||
/* whatever, but channel contexts should not complain about that one */
|
||||
sdata->deflink.smps_mode = IEEE80211_SMPS_OFF;
|
||||
@@ -3480,13 +3478,12 @@ static int ieee80211_start_radar_detecti
|
||||
err = ieee80211_link_use_channel(&sdata->deflink, &chanreq,
|
||||
IEEE80211_CHANCTX_SHARED);
|
||||
if (err)
|
||||
- goto out_unlock;
|
||||
+ return err;
|
||||
|
||||
wiphy_delayed_work_queue(wiphy, &sdata->deflink.dfs_cac_timer_work,
|
||||
msecs_to_jiffies(cac_time_ms));
|
||||
|
||||
- out_unlock:
|
||||
- return err;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static void ieee80211_end_cac(struct wiphy *wiphy,
|
@ -0,0 +1,42 @@
|
||||
From: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
Date: Fri, 6 Sep 2024 12:14:21 +0530
|
||||
Subject: [PATCH] wifi: trace: unlink rdev_end_cac trace event from
|
||||
wiphy_netdev_evt class
|
||||
|
||||
rdev_end_cac trace event is linked with wiphy_netdev_evt event class.
|
||||
There is no option to pass link ID currently to wiphy_netdev_evt class.
|
||||
A subsequent change would pass link ID to rdev_end_cac event and hence
|
||||
it can no longer derive the event class from wiphy_netdev_evt.
|
||||
|
||||
Therefore, unlink rdev_end_cac event from wiphy_netdev_evt and define it's
|
||||
own independent trace event. Link ID would be passed in subsequent change.
|
||||
|
||||
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
Link: https://patch.msgid.link/20240906064426.2101315-4-quic_adisi@quicinc.com
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/net/wireless/trace.h
|
||||
+++ b/net/wireless/trace.h
|
||||
@@ -805,9 +805,18 @@ DEFINE_EVENT(wiphy_netdev_evt, rdev_flus
|
||||
TP_ARGS(wiphy, netdev)
|
||||
);
|
||||
|
||||
-DEFINE_EVENT(wiphy_netdev_evt, rdev_end_cac,
|
||||
- TP_PROTO(struct wiphy *wiphy, struct net_device *netdev),
|
||||
- TP_ARGS(wiphy, netdev)
|
||||
+TRACE_EVENT(rdev_end_cac,
|
||||
+ TP_PROTO(struct wiphy *wiphy, struct net_device *netdev),
|
||||
+ TP_ARGS(wiphy, netdev),
|
||||
+ TP_STRUCT__entry(
|
||||
+ WIPHY_ENTRY
|
||||
+ NETDEV_ENTRY
|
||||
+ ),
|
||||
+ TP_fast_assign(
|
||||
+ WIPHY_ASSIGN;
|
||||
+ NETDEV_ASSIGN;
|
||||
+ ),
|
||||
+ TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT, WIPHY_PR_ARG, NETDEV_PR_ARG)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(station_add_change,
|
@ -0,0 +1,309 @@
|
||||
From: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
Date: Fri, 6 Sep 2024 12:14:22 +0530
|
||||
Subject: [PATCH] wifi: cfg80211: move DFS related members to links[] in
|
||||
wireless_dev
|
||||
|
||||
A few members related to DFS handling are currently under per wireless
|
||||
device data structure. However, in order to support DFS with MLO, there is
|
||||
a need to have them on a per-link manner.
|
||||
|
||||
Hence, as a preliminary step, move members cac_started, cac_start_time
|
||||
and cac_time_ms to be on a per-link basis.
|
||||
|
||||
Since currently, link ID is not known at all places, use default value of
|
||||
0 for now.
|
||||
|
||||
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
Link: https://patch.msgid.link/20240906064426.2101315-5-quic_adisi@quicinc.com
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/marvell/mwifiex/11h.c
|
||||
+++ b/drivers/net/wireless/marvell/mwifiex/11h.c
|
||||
@@ -117,7 +117,7 @@ void mwifiex_dfs_cac_work_queue(struct w
|
||||
dfs_cac_work);
|
||||
|
||||
chandef = priv->dfs_chandef;
|
||||
- if (priv->wdev.cac_started) {
|
||||
+ if (priv->wdev.links[0].cac_started) {
|
||||
mwifiex_dbg(priv->adapter, MSG,
|
||||
"CAC timer finished; No radar detected\n");
|
||||
cfg80211_cac_event(priv->netdev, &chandef,
|
||||
@@ -174,7 +174,7 @@ int mwifiex_stop_radar_detection(struct
|
||||
*/
|
||||
void mwifiex_abort_cac(struct mwifiex_private *priv)
|
||||
{
|
||||
- if (priv->wdev.cac_started) {
|
||||
+ if (priv->wdev.links[0].cac_started) {
|
||||
if (mwifiex_stop_radar_detection(priv, &priv->dfs_chandef))
|
||||
mwifiex_dbg(priv->adapter, ERROR,
|
||||
"failed to stop CAC in FW\n");
|
||||
--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
|
||||
+++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
|
||||
@@ -1880,7 +1880,7 @@ mwifiex_cfg80211_del_station(struct wiph
|
||||
struct mwifiex_sta_node *sta_node;
|
||||
u8 deauth_mac[ETH_ALEN];
|
||||
|
||||
- if (!priv->bss_started && priv->wdev.cac_started) {
|
||||
+ if (!priv->bss_started && priv->wdev.links[0].cac_started) {
|
||||
mwifiex_dbg(priv->adapter, INFO, "%s: abort CAC!\n", __func__);
|
||||
mwifiex_abort_cac(priv);
|
||||
}
|
||||
@@ -3978,7 +3978,7 @@ mwifiex_cfg80211_channel_switch(struct w
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
- if (priv->wdev.cac_started)
|
||||
+ if (priv->wdev.links[0].cac_started)
|
||||
return -EBUSY;
|
||||
|
||||
if (cfg80211_chandef_identical(¶ms->chandef,
|
||||
--- a/drivers/net/wireless/quantenna/qtnfmac/event.c
|
||||
+++ b/drivers/net/wireless/quantenna/qtnfmac/event.c
|
||||
@@ -520,21 +520,21 @@ static int qtnf_event_handle_radar(struc
|
||||
cfg80211_radar_event(wiphy, &chandef, GFP_KERNEL);
|
||||
break;
|
||||
case QLINK_RADAR_CAC_FINISHED:
|
||||
- if (!vif->wdev.cac_started)
|
||||
+ if (!vif->wdev.links[0].cac_started)
|
||||
break;
|
||||
|
||||
cfg80211_cac_event(vif->netdev, &chandef,
|
||||
NL80211_RADAR_CAC_FINISHED, GFP_KERNEL);
|
||||
break;
|
||||
case QLINK_RADAR_CAC_ABORTED:
|
||||
- if (!vif->wdev.cac_started)
|
||||
+ if (!vif->wdev.links[0].cac_started)
|
||||
break;
|
||||
|
||||
cfg80211_cac_event(vif->netdev, &chandef,
|
||||
NL80211_RADAR_CAC_ABORTED, GFP_KERNEL);
|
||||
break;
|
||||
case QLINK_RADAR_CAC_STARTED:
|
||||
- if (vif->wdev.cac_started)
|
||||
+ if (vif->wdev.links[0].cac_started)
|
||||
break;
|
||||
|
||||
if (!wiphy_ext_feature_isset(wiphy,
|
||||
--- a/include/net/cfg80211.h
|
||||
+++ b/include/net/cfg80211.h
|
||||
@@ -6198,9 +6198,6 @@ enum ieee80211_ap_reg_power {
|
||||
* @address: The address for this device, valid only if @netdev is %NULL
|
||||
* @is_running: true if this is a non-netdev device that has been started, e.g.
|
||||
* the P2P Device.
|
||||
- * @cac_started: true if DFS channel availability check has been started
|
||||
- * @cac_start_time: timestamp (jiffies) when the dfs state was entered.
|
||||
- * @cac_time_ms: CAC time in ms
|
||||
* @ps: powersave mode is enabled
|
||||
* @ps_timeout: dynamic powersave timeout
|
||||
* @ap_unexpected_nlportid: (private) netlink port ID of application
|
||||
@@ -6224,6 +6221,11 @@ enum ieee80211_ap_reg_power {
|
||||
* unprotected beacon report
|
||||
* @links: array of %IEEE80211_MLD_MAX_NUM_LINKS elements containing @addr
|
||||
* @ap and @client for each link
|
||||
+ * @links[].cac_started: true if DFS channel availability check has been
|
||||
+ * started
|
||||
+ * @links[].cac_start_time: timestamp (jiffies) when the dfs state was
|
||||
+ * entered.
|
||||
+ * @links[].cac_time_ms: CAC time in ms
|
||||
* @valid_links: bitmap describing what elements of @links are valid
|
||||
*/
|
||||
struct wireless_dev {
|
||||
@@ -6265,11 +6267,6 @@ struct wireless_dev {
|
||||
u32 owner_nlportid;
|
||||
bool nl_owner_dead;
|
||||
|
||||
- /* FIXME: need to rework radar detection for MLO */
|
||||
- bool cac_started;
|
||||
- unsigned long cac_start_time;
|
||||
- unsigned int cac_time_ms;
|
||||
-
|
||||
#ifdef CPTCFG_CFG80211_WEXT
|
||||
/* wext data */
|
||||
struct {
|
||||
@@ -6336,6 +6333,10 @@ struct wireless_dev {
|
||||
struct cfg80211_internal_bss *current_bss;
|
||||
} client;
|
||||
};
|
||||
+
|
||||
+ bool cac_started;
|
||||
+ unsigned long cac_start_time;
|
||||
+ unsigned int cac_time_ms;
|
||||
} links[IEEE80211_MLD_MAX_NUM_LINKS];
|
||||
u16 valid_links;
|
||||
};
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -1656,7 +1656,7 @@ static int ieee80211_stop_ap(struct wiph
|
||||
ieee80211_link_info_change_notify(sdata, link,
|
||||
BSS_CHANGED_BEACON_ENABLED);
|
||||
|
||||
- if (sdata->wdev.cac_started) {
|
||||
+ if (sdata->wdev.links[0].cac_started) {
|
||||
chandef = link_conf->chanreq.oper;
|
||||
wiphy_delayed_work_cancel(wiphy, &link->dfs_cac_timer_work);
|
||||
cfg80211_cac_event(sdata->dev, &chandef,
|
||||
@@ -3498,9 +3498,9 @@ static void ieee80211_end_cac(struct wip
|
||||
wiphy_delayed_work_cancel(wiphy,
|
||||
&sdata->deflink.dfs_cac_timer_work);
|
||||
|
||||
- if (sdata->wdev.cac_started) {
|
||||
+ if (sdata->wdev.links[0].cac_started) {
|
||||
ieee80211_link_release_channel(&sdata->deflink);
|
||||
- sdata->wdev.cac_started = false;
|
||||
+ sdata->wdev.links[0].cac_started = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3955,7 +3955,7 @@ __ieee80211_channel_switch(struct wiphy
|
||||
if (!list_empty(&local->roc_list) || local->scanning)
|
||||
return -EBUSY;
|
||||
|
||||
- if (sdata->wdev.cac_started)
|
||||
+ if (sdata->wdev.links[0].cac_started)
|
||||
return -EBUSY;
|
||||
|
||||
if (WARN_ON(link_id >= IEEE80211_MLD_MAX_NUM_LINKS))
|
||||
--- a/net/mac80211/iface.c
|
||||
+++ b/net/mac80211/iface.c
|
||||
@@ -553,7 +553,7 @@ static void ieee80211_do_stop(struct iee
|
||||
wiphy_delayed_work_cancel(local->hw.wiphy,
|
||||
&sdata->deflink.dfs_cac_timer_work);
|
||||
|
||||
- if (sdata->wdev.cac_started) {
|
||||
+ if (sdata->wdev.links[0].cac_started) {
|
||||
chandef = sdata->vif.bss_conf.chanreq.oper;
|
||||
WARN_ON(local->suspended);
|
||||
ieee80211_link_release_channel(&sdata->deflink);
|
||||
--- a/net/mac80211/mlme.c
|
||||
+++ b/net/mac80211/mlme.c
|
||||
@@ -3039,7 +3039,7 @@ void ieee80211_dfs_cac_timer_work(struct
|
||||
|
||||
lockdep_assert_wiphy(sdata->local->hw.wiphy);
|
||||
|
||||
- if (sdata->wdev.cac_started) {
|
||||
+ if (sdata->wdev.links[0].cac_started) {
|
||||
ieee80211_link_release_channel(link);
|
||||
cfg80211_cac_event(sdata->dev, &chandef,
|
||||
NL80211_RADAR_CAC_FINISHED,
|
||||
--- a/net/mac80211/scan.c
|
||||
+++ b/net/mac80211/scan.c
|
||||
@@ -585,7 +585,7 @@ static bool __ieee80211_can_leave_ch(str
|
||||
return false;
|
||||
|
||||
list_for_each_entry(sdata_iter, &local->interfaces, list) {
|
||||
- if (sdata_iter->wdev.cac_started)
|
||||
+ if (sdata_iter->wdev.links[0].cac_started)
|
||||
return false;
|
||||
}
|
||||
|
||||
--- a/net/mac80211/util.c
|
||||
+++ b/net/mac80211/util.c
|
||||
@@ -3462,7 +3462,7 @@ void ieee80211_dfs_cac_cancel(struct iee
|
||||
wiphy_delayed_work_cancel(local->hw.wiphy,
|
||||
&sdata->deflink.dfs_cac_timer_work);
|
||||
|
||||
- if (sdata->wdev.cac_started) {
|
||||
+ if (sdata->wdev.links[0].cac_started) {
|
||||
chandef = sdata->vif.bss_conf.chanreq.oper;
|
||||
ieee80211_link_release_channel(&sdata->deflink);
|
||||
cfg80211_cac_event(sdata->dev,
|
||||
--- a/net/wireless/ibss.c
|
||||
+++ b/net/wireless/ibss.c
|
||||
@@ -94,7 +94,7 @@ int __cfg80211_join_ibss(struct cfg80211
|
||||
|
||||
lockdep_assert_held(&rdev->wiphy.mtx);
|
||||
|
||||
- if (wdev->cac_started)
|
||||
+ if (wdev->links[0].cac_started)
|
||||
return -EBUSY;
|
||||
|
||||
if (wdev->u.ibss.ssid_len)
|
||||
--- a/net/wireless/mesh.c
|
||||
+++ b/net/wireless/mesh.c
|
||||
@@ -127,7 +127,7 @@ int __cfg80211_join_mesh(struct cfg80211
|
||||
if (!rdev->ops->join_mesh)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
- if (wdev->cac_started)
|
||||
+ if (wdev->links[0].cac_started)
|
||||
return -EBUSY;
|
||||
|
||||
if (!setup->chandef.chan) {
|
||||
--- a/net/wireless/mlme.c
|
||||
+++ b/net/wireless/mlme.c
|
||||
@@ -1124,13 +1124,14 @@ void cfg80211_cac_event(struct net_devic
|
||||
|
||||
trace_cfg80211_cac_event(netdev, event);
|
||||
|
||||
- if (WARN_ON(!wdev->cac_started && event != NL80211_RADAR_CAC_STARTED))
|
||||
+ if (WARN_ON(!wdev->links[0].cac_started &&
|
||||
+ event != NL80211_RADAR_CAC_STARTED))
|
||||
return;
|
||||
|
||||
switch (event) {
|
||||
case NL80211_RADAR_CAC_FINISHED:
|
||||
- timeout = wdev->cac_start_time +
|
||||
- msecs_to_jiffies(wdev->cac_time_ms);
|
||||
+ timeout = wdev->links[0].cac_start_time +
|
||||
+ msecs_to_jiffies(wdev->links[0].cac_time_ms);
|
||||
WARN_ON(!time_after_eq(jiffies, timeout));
|
||||
cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_AVAILABLE);
|
||||
memcpy(&rdev->cac_done_chandef, chandef,
|
||||
@@ -1139,10 +1140,10 @@ void cfg80211_cac_event(struct net_devic
|
||||
cfg80211_sched_dfs_chan_update(rdev);
|
||||
fallthrough;
|
||||
case NL80211_RADAR_CAC_ABORTED:
|
||||
- wdev->cac_started = false;
|
||||
+ wdev->links[0].cac_started = false;
|
||||
break;
|
||||
case NL80211_RADAR_CAC_STARTED:
|
||||
- wdev->cac_started = true;
|
||||
+ wdev->links[0].cac_started = true;
|
||||
break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
--- a/net/wireless/nl80211.c
|
||||
+++ b/net/wireless/nl80211.c
|
||||
@@ -6066,7 +6066,7 @@ static int nl80211_start_ap(struct sk_bu
|
||||
if (!rdev->ops->start_ap)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
- if (wdev->cac_started)
|
||||
+ if (wdev->links[0].cac_started)
|
||||
return -EBUSY;
|
||||
|
||||
if (wdev->links[link_id].ap.beacon_interval)
|
||||
@@ -10122,7 +10122,7 @@ static int nl80211_start_radar_detection
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
- if (cfg80211_beaconing_iface_active(wdev) || wdev->cac_started) {
|
||||
+ if (cfg80211_beaconing_iface_active(wdev) || wdev->links[0].cac_started) {
|
||||
err = -EBUSY;
|
||||
goto unlock;
|
||||
}
|
||||
@@ -10158,9 +10158,9 @@ static int nl80211_start_radar_detection
|
||||
default:
|
||||
break;
|
||||
}
|
||||
- wdev->cac_started = true;
|
||||
- wdev->cac_start_time = jiffies;
|
||||
- wdev->cac_time_ms = cac_time_ms;
|
||||
+ wdev->links[0].cac_started = true;
|
||||
+ wdev->links[0].cac_start_time = jiffies;
|
||||
+ wdev->links[0].cac_time_ms = cac_time_ms;
|
||||
}
|
||||
unlock:
|
||||
wiphy_unlock(wiphy);
|
||||
--- a/net/wireless/reg.c
|
||||
+++ b/net/wireless/reg.c
|
||||
@@ -4241,7 +4241,7 @@ static void cfg80211_check_and_end_cac(s
|
||||
list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
|
||||
struct cfg80211_chan_def *chandef;
|
||||
|
||||
- if (!wdev->cac_started)
|
||||
+ if (!wdev->links[0].cac_started)
|
||||
continue;
|
||||
|
||||
/* FIXME: radar detection is tied to link 0 for now */
|
@ -0,0 +1,435 @@
|
||||
From: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
Date: Fri, 6 Sep 2024 12:14:23 +0530
|
||||
Subject: [PATCH] wifi: cfg80211: handle DFS per link
|
||||
|
||||
Currently, during starting a radar detection, no link id information is
|
||||
parsed and passed down. In order to support starting radar detection
|
||||
during Multi Link Operation, it is required to pass link id as well.
|
||||
|
||||
Add changes to first parse and then pass link id in the start radar
|
||||
detection path.
|
||||
|
||||
Additionally, update notification APIs to allow drivers/mac80211 to
|
||||
pass the link ID.
|
||||
|
||||
However, everything is handled at link 0 only until all API's are ready to
|
||||
handle it per link.
|
||||
|
||||
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
Link: https://patch.msgid.link/20240906064426.2101315-6-quic_adisi@quicinc.com
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/marvell/mwifiex/11h.c
|
||||
+++ b/drivers/net/wireless/marvell/mwifiex/11h.c
|
||||
@@ -122,7 +122,7 @@ void mwifiex_dfs_cac_work_queue(struct w
|
||||
"CAC timer finished; No radar detected\n");
|
||||
cfg80211_cac_event(priv->netdev, &chandef,
|
||||
NL80211_RADAR_CAC_FINISHED,
|
||||
- GFP_KERNEL);
|
||||
+ GFP_KERNEL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,7 +182,8 @@ void mwifiex_abort_cac(struct mwifiex_pr
|
||||
"Aborting delayed work for CAC.\n");
|
||||
cancel_delayed_work_sync(&priv->dfs_cac_work);
|
||||
cfg80211_cac_event(priv->netdev, &priv->dfs_chandef,
|
||||
- NL80211_RADAR_CAC_ABORTED, GFP_KERNEL);
|
||||
+ NL80211_RADAR_CAC_ABORTED, GFP_KERNEL,
|
||||
+ 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,7 +222,7 @@ int mwifiex_11h_handle_chanrpt_ready(str
|
||||
cfg80211_cac_event(priv->netdev,
|
||||
&priv->dfs_chandef,
|
||||
NL80211_RADAR_DETECTED,
|
||||
- GFP_KERNEL);
|
||||
+ GFP_KERNEL, 0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
|
||||
+++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
|
||||
@@ -4145,7 +4145,7 @@ static int
|
||||
mwifiex_cfg80211_start_radar_detection(struct wiphy *wiphy,
|
||||
struct net_device *dev,
|
||||
struct cfg80211_chan_def *chandef,
|
||||
- u32 cac_time_ms)
|
||||
+ u32 cac_time_ms, int link_id)
|
||||
{
|
||||
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
|
||||
struct mwifiex_radar_params radar_params;
|
||||
--- a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
|
||||
@@ -837,7 +837,7 @@ static int qtnf_channel_switch(struct wi
|
||||
static int qtnf_start_radar_detection(struct wiphy *wiphy,
|
||||
struct net_device *ndev,
|
||||
struct cfg80211_chan_def *chandef,
|
||||
- u32 cac_time_ms)
|
||||
+ u32 cac_time_ms, int link_id)
|
||||
{
|
||||
struct qtnf_vif *vif = qtnf_netdev_get_priv(ndev);
|
||||
int ret;
|
||||
--- a/drivers/net/wireless/quantenna/qtnfmac/event.c
|
||||
+++ b/drivers/net/wireless/quantenna/qtnfmac/event.c
|
||||
@@ -524,14 +524,14 @@ static int qtnf_event_handle_radar(struc
|
||||
break;
|
||||
|
||||
cfg80211_cac_event(vif->netdev, &chandef,
|
||||
- NL80211_RADAR_CAC_FINISHED, GFP_KERNEL);
|
||||
+ NL80211_RADAR_CAC_FINISHED, GFP_KERNEL, 0);
|
||||
break;
|
||||
case QLINK_RADAR_CAC_ABORTED:
|
||||
if (!vif->wdev.links[0].cac_started)
|
||||
break;
|
||||
|
||||
cfg80211_cac_event(vif->netdev, &chandef,
|
||||
- NL80211_RADAR_CAC_ABORTED, GFP_KERNEL);
|
||||
+ NL80211_RADAR_CAC_ABORTED, GFP_KERNEL, 0);
|
||||
break;
|
||||
case QLINK_RADAR_CAC_STARTED:
|
||||
if (vif->wdev.links[0].cac_started)
|
||||
@@ -542,7 +542,7 @@ static int qtnf_event_handle_radar(struc
|
||||
break;
|
||||
|
||||
cfg80211_cac_event(vif->netdev, &chandef,
|
||||
- NL80211_RADAR_CAC_STARTED, GFP_KERNEL);
|
||||
+ NL80211_RADAR_CAC_STARTED, GFP_KERNEL, 0);
|
||||
break;
|
||||
default:
|
||||
pr_warn("%s: unhandled radar event %u\n",
|
||||
--- a/include/net/cfg80211.h
|
||||
+++ b/include/net/cfg80211.h
|
||||
@@ -4841,9 +4841,9 @@ struct cfg80211_ops {
|
||||
int (*start_radar_detection)(struct wiphy *wiphy,
|
||||
struct net_device *dev,
|
||||
struct cfg80211_chan_def *chandef,
|
||||
- u32 cac_time_ms);
|
||||
+ u32 cac_time_ms, int link_id);
|
||||
void (*end_cac)(struct wiphy *wiphy,
|
||||
- struct net_device *dev);
|
||||
+ struct net_device *dev, unsigned int link_id);
|
||||
int (*update_ft_ies)(struct wiphy *wiphy, struct net_device *dev,
|
||||
struct cfg80211_update_ft_ies_params *ftie);
|
||||
int (*crit_proto_start)(struct wiphy *wiphy,
|
||||
@@ -8745,6 +8745,7 @@ void cfg80211_sta_opmode_change_notify(s
|
||||
* @chandef: chandef for the current channel
|
||||
* @event: type of event
|
||||
* @gfp: context flags
|
||||
+ * @link_id: valid link_id for MLO operation or 0 otherwise.
|
||||
*
|
||||
* This function is called when a Channel availability check (CAC) is finished
|
||||
* or aborted. This must be called to notify the completion of a CAC process,
|
||||
@@ -8752,7 +8753,8 @@ void cfg80211_sta_opmode_change_notify(s
|
||||
*/
|
||||
void cfg80211_cac_event(struct net_device *netdev,
|
||||
const struct cfg80211_chan_def *chandef,
|
||||
- enum nl80211_radar_event event, gfp_t gfp);
|
||||
+ enum nl80211_radar_event event, gfp_t gfp,
|
||||
+ unsigned int link_id);
|
||||
|
||||
/**
|
||||
* cfg80211_background_cac_abort - Channel Availability Check offchan abort event
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -1661,7 +1661,7 @@ static int ieee80211_stop_ap(struct wiph
|
||||
wiphy_delayed_work_cancel(wiphy, &link->dfs_cac_timer_work);
|
||||
cfg80211_cac_event(sdata->dev, &chandef,
|
||||
NL80211_RADAR_CAC_ABORTED,
|
||||
- GFP_KERNEL);
|
||||
+ GFP_KERNEL, 0);
|
||||
}
|
||||
|
||||
drv_stop_ap(sdata->local, sdata, link_conf);
|
||||
@@ -3459,7 +3459,7 @@ static int ieee80211_set_bitrate_mask(st
|
||||
static int ieee80211_start_radar_detection(struct wiphy *wiphy,
|
||||
struct net_device *dev,
|
||||
struct cfg80211_chan_def *chandef,
|
||||
- u32 cac_time_ms)
|
||||
+ u32 cac_time_ms, int link_id)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
struct ieee80211_chan_req chanreq = { .oper = *chandef };
|
||||
@@ -3487,7 +3487,7 @@ static int ieee80211_start_radar_detecti
|
||||
}
|
||||
|
||||
static void ieee80211_end_cac(struct wiphy *wiphy,
|
||||
- struct net_device *dev)
|
||||
+ struct net_device *dev, unsigned int link_id)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
--- a/net/mac80211/iface.c
|
||||
+++ b/net/mac80211/iface.c
|
||||
@@ -559,7 +559,7 @@ static void ieee80211_do_stop(struct iee
|
||||
ieee80211_link_release_channel(&sdata->deflink);
|
||||
cfg80211_cac_event(sdata->dev, &chandef,
|
||||
NL80211_RADAR_CAC_ABORTED,
|
||||
- GFP_KERNEL);
|
||||
+ GFP_KERNEL, 0);
|
||||
}
|
||||
|
||||
if (sdata->vif.type == NL80211_IFTYPE_AP) {
|
||||
--- a/net/mac80211/mlme.c
|
||||
+++ b/net/mac80211/mlme.c
|
||||
@@ -3043,7 +3043,7 @@ void ieee80211_dfs_cac_timer_work(struct
|
||||
ieee80211_link_release_channel(link);
|
||||
cfg80211_cac_event(sdata->dev, &chandef,
|
||||
NL80211_RADAR_CAC_FINISHED,
|
||||
- GFP_KERNEL);
|
||||
+ GFP_KERNEL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
--- a/net/mac80211/util.c
|
||||
+++ b/net/mac80211/util.c
|
||||
@@ -3468,7 +3468,7 @@ void ieee80211_dfs_cac_cancel(struct iee
|
||||
cfg80211_cac_event(sdata->dev,
|
||||
&chandef,
|
||||
NL80211_RADAR_CAC_ABORTED,
|
||||
- GFP_KERNEL);
|
||||
+ GFP_KERNEL, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
--- a/net/wireless/mlme.c
|
||||
+++ b/net/wireless/mlme.c
|
||||
@@ -1111,18 +1111,19 @@ EXPORT_SYMBOL(__cfg80211_radar_event);
|
||||
|
||||
void cfg80211_cac_event(struct net_device *netdev,
|
||||
const struct cfg80211_chan_def *chandef,
|
||||
- enum nl80211_radar_event event, gfp_t gfp)
|
||||
+ enum nl80211_radar_event event, gfp_t gfp,
|
||||
+ unsigned int link_id)
|
||||
{
|
||||
struct wireless_dev *wdev = netdev->ieee80211_ptr;
|
||||
struct wiphy *wiphy = wdev->wiphy;
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|
||||
unsigned long timeout;
|
||||
|
||||
- /* not yet supported */
|
||||
- if (wdev->valid_links)
|
||||
+ if (WARN_ON(wdev->valid_links &&
|
||||
+ !(wdev->valid_links & BIT(link_id))))
|
||||
return;
|
||||
|
||||
- trace_cfg80211_cac_event(netdev, event);
|
||||
+ trace_cfg80211_cac_event(netdev, event, link_id);
|
||||
|
||||
if (WARN_ON(!wdev->links[0].cac_started &&
|
||||
event != NL80211_RADAR_CAC_STARTED))
|
||||
--- a/net/wireless/nl80211.c
|
||||
+++ b/net/wireless/nl80211.c
|
||||
@@ -10122,7 +10122,20 @@ static int nl80211_start_radar_detection
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
- if (cfg80211_beaconing_iface_active(wdev) || wdev->links[0].cac_started) {
|
||||
+ if (cfg80211_beaconing_iface_active(wdev)) {
|
||||
+ /* During MLO other link(s) can beacon, only the current link
|
||||
+ * can not already beacon
|
||||
+ */
|
||||
+ if (wdev->valid_links &&
|
||||
+ !wdev->links[0].ap.beacon_interval) {
|
||||
+ /* nothing */
|
||||
+ } else {
|
||||
+ err = -EBUSY;
|
||||
+ goto unlock;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (wdev->links[0].cac_started) {
|
||||
err = -EBUSY;
|
||||
goto unlock;
|
||||
}
|
||||
@@ -10142,7 +10155,8 @@ static int nl80211_start_radar_detection
|
||||
if (WARN_ON(!cac_time_ms))
|
||||
cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
|
||||
|
||||
- err = rdev_start_radar_detection(rdev, dev, &chandef, cac_time_ms);
|
||||
+ err = rdev_start_radar_detection(rdev, dev, &chandef, cac_time_ms,
|
||||
+ 0);
|
||||
if (!err) {
|
||||
switch (wdev->iftype) {
|
||||
case NL80211_IFTYPE_AP:
|
||||
@@ -16512,10 +16526,10 @@ nl80211_set_ttlm(struct sk_buff *skb, st
|
||||
SELECTOR(__sel, NETDEV_UP_NOTMX, \
|
||||
NL80211_FLAG_NEED_NETDEV_UP | \
|
||||
NL80211_FLAG_NO_WIPHY_MTX) \
|
||||
- SELECTOR(__sel, NETDEV_UP_NOTMX_NOMLO, \
|
||||
+ SELECTOR(__sel, NETDEV_UP_NOTMX_MLO, \
|
||||
NL80211_FLAG_NEED_NETDEV_UP | \
|
||||
NL80211_FLAG_NO_WIPHY_MTX | \
|
||||
- NL80211_FLAG_MLO_UNSUPPORTED) \
|
||||
+ NL80211_FLAG_MLO_VALID_LINK_ID) \
|
||||
SELECTOR(__sel, NETDEV_UP_CLEAR, \
|
||||
NL80211_FLAG_NEED_NETDEV_UP | \
|
||||
NL80211_FLAG_CLEAR_SKB) \
|
||||
@@ -17410,7 +17424,7 @@ static const struct genl_small_ops nl802
|
||||
.flags = GENL_UNS_ADMIN_PERM,
|
||||
.internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
|
||||
NL80211_FLAG_NO_WIPHY_MTX |
|
||||
- NL80211_FLAG_MLO_UNSUPPORTED),
|
||||
+ NL80211_FLAG_MLO_VALID_LINK_ID),
|
||||
},
|
||||
{
|
||||
.cmd = NL80211_CMD_GET_PROTOCOL_FEATURES,
|
||||
--- a/net/wireless/rdev-ops.h
|
||||
+++ b/net/wireless/rdev-ops.h
|
||||
@@ -1200,26 +1200,27 @@ static inline int
|
||||
rdev_start_radar_detection(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev,
|
||||
struct cfg80211_chan_def *chandef,
|
||||
- u32 cac_time_ms)
|
||||
+ u32 cac_time_ms, int link_id)
|
||||
{
|
||||
int ret = -EOPNOTSUPP;
|
||||
|
||||
trace_rdev_start_radar_detection(&rdev->wiphy, dev, chandef,
|
||||
- cac_time_ms);
|
||||
+ cac_time_ms, link_id);
|
||||
if (rdev->ops->start_radar_detection)
|
||||
ret = rdev->ops->start_radar_detection(&rdev->wiphy, dev,
|
||||
- chandef, cac_time_ms);
|
||||
+ chandef, cac_time_ms,
|
||||
+ link_id);
|
||||
trace_rdev_return_int(&rdev->wiphy, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void
|
||||
rdev_end_cac(struct cfg80211_registered_device *rdev,
|
||||
- struct net_device *dev)
|
||||
+ struct net_device *dev, unsigned int link_id)
|
||||
{
|
||||
- trace_rdev_end_cac(&rdev->wiphy, dev);
|
||||
+ trace_rdev_end_cac(&rdev->wiphy, dev, link_id);
|
||||
if (rdev->ops->end_cac)
|
||||
- rdev->ops->end_cac(&rdev->wiphy, dev);
|
||||
+ rdev->ops->end_cac(&rdev->wiphy, dev, link_id);
|
||||
trace_rdev_return_void(&rdev->wiphy);
|
||||
}
|
||||
|
||||
--- a/net/wireless/reg.c
|
||||
+++ b/net/wireless/reg.c
|
||||
@@ -4229,6 +4229,8 @@ EXPORT_SYMBOL(regulatory_pre_cac_allowed
|
||||
static void cfg80211_check_and_end_cac(struct cfg80211_registered_device *rdev)
|
||||
{
|
||||
struct wireless_dev *wdev;
|
||||
+ unsigned int link_id;
|
||||
+
|
||||
/* If we finished CAC or received radar, we should end any
|
||||
* CAC running on the same channels.
|
||||
* the check !cfg80211_chandef_dfs_usable contain 2 options:
|
||||
@@ -4241,16 +4243,17 @@ static void cfg80211_check_and_end_cac(s
|
||||
list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
|
||||
struct cfg80211_chan_def *chandef;
|
||||
|
||||
- if (!wdev->links[0].cac_started)
|
||||
- continue;
|
||||
+ for_each_valid_link(wdev, link_id) {
|
||||
+ if (!wdev->links[link_id].cac_started)
|
||||
+ continue;
|
||||
|
||||
- /* FIXME: radar detection is tied to link 0 for now */
|
||||
- chandef = wdev_chandef(wdev, 0);
|
||||
- if (!chandef)
|
||||
- continue;
|
||||
+ chandef = wdev_chandef(wdev, link_id);
|
||||
+ if (!chandef)
|
||||
+ continue;
|
||||
|
||||
- if (!cfg80211_chandef_dfs_usable(&rdev->wiphy, chandef))
|
||||
- rdev_end_cac(rdev, wdev->netdev);
|
||||
+ if (!cfg80211_chandef_dfs_usable(&rdev->wiphy, chandef))
|
||||
+ rdev_end_cac(rdev, wdev->netdev, link_id);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
--- a/net/wireless/trace.h
|
||||
+++ b/net/wireless/trace.h
|
||||
@@ -806,17 +806,21 @@ DEFINE_EVENT(wiphy_netdev_evt, rdev_flus
|
||||
);
|
||||
|
||||
TRACE_EVENT(rdev_end_cac,
|
||||
- TP_PROTO(struct wiphy *wiphy, struct net_device *netdev),
|
||||
- TP_ARGS(wiphy, netdev),
|
||||
+ TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
|
||||
+ unsigned int link_id),
|
||||
+ TP_ARGS(wiphy, netdev, link_id),
|
||||
TP_STRUCT__entry(
|
||||
WIPHY_ENTRY
|
||||
NETDEV_ENTRY
|
||||
+ __field(unsigned int, link_id)
|
||||
),
|
||||
TP_fast_assign(
|
||||
WIPHY_ASSIGN;
|
||||
NETDEV_ASSIGN;
|
||||
+ __entry->link_id = link_id;
|
||||
),
|
||||
- TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT, WIPHY_PR_ARG, NETDEV_PR_ARG)
|
||||
+ TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", link_id: %d",
|
||||
+ WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->link_id)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(station_add_change,
|
||||
@@ -2661,24 +2665,26 @@ TRACE_EVENT(rdev_external_auth,
|
||||
TRACE_EVENT(rdev_start_radar_detection,
|
||||
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
|
||||
struct cfg80211_chan_def *chandef,
|
||||
- u32 cac_time_ms),
|
||||
- TP_ARGS(wiphy, netdev, chandef, cac_time_ms),
|
||||
+ u32 cac_time_ms, int link_id),
|
||||
+ TP_ARGS(wiphy, netdev, chandef, cac_time_ms, link_id),
|
||||
TP_STRUCT__entry(
|
||||
WIPHY_ENTRY
|
||||
NETDEV_ENTRY
|
||||
CHAN_DEF_ENTRY
|
||||
__field(u32, cac_time_ms)
|
||||
+ __field(int, link_id)
|
||||
),
|
||||
TP_fast_assign(
|
||||
WIPHY_ASSIGN;
|
||||
NETDEV_ASSIGN;
|
||||
CHAN_DEF_ASSIGN(chandef);
|
||||
__entry->cac_time_ms = cac_time_ms;
|
||||
+ __entry->link_id = link_id;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " CHAN_DEF_PR_FMT
|
||||
- ", cac_time_ms=%u",
|
||||
+ ", cac_time_ms=%u, link_id=%d",
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, CHAN_DEF_PR_ARG,
|
||||
- __entry->cac_time_ms)
|
||||
+ __entry->cac_time_ms, __entry->link_id)
|
||||
);
|
||||
|
||||
TRACE_EVENT(rdev_set_mcast_rate,
|
||||
@@ -3492,18 +3498,21 @@ TRACE_EVENT(cfg80211_radar_event,
|
||||
);
|
||||
|
||||
TRACE_EVENT(cfg80211_cac_event,
|
||||
- TP_PROTO(struct net_device *netdev, enum nl80211_radar_event evt),
|
||||
- TP_ARGS(netdev, evt),
|
||||
+ TP_PROTO(struct net_device *netdev, enum nl80211_radar_event evt,
|
||||
+ unsigned int link_id),
|
||||
+ TP_ARGS(netdev, evt, link_id),
|
||||
TP_STRUCT__entry(
|
||||
NETDEV_ENTRY
|
||||
__field(enum nl80211_radar_event, evt)
|
||||
+ __field(unsigned int, link_id)
|
||||
),
|
||||
TP_fast_assign(
|
||||
NETDEV_ASSIGN;
|
||||
__entry->evt = evt;
|
||||
+ __entry->link_id = link_id;
|
||||
),
|
||||
- TP_printk(NETDEV_PR_FMT ", event: %d",
|
||||
- NETDEV_PR_ARG, __entry->evt)
|
||||
+ TP_printk(NETDEV_PR_FMT ", event: %d, link_id=%u",
|
||||
+ NETDEV_PR_ARG, __entry->evt, __entry->link_id)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(cfg80211_rx_evt,
|
@ -0,0 +1,134 @@
|
||||
From: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
Date: Fri, 6 Sep 2024 12:14:24 +0530
|
||||
Subject: [PATCH] wifi: mac80211: handle DFS per link
|
||||
|
||||
In order to support DFS with MLO, handle the link ID now passed from
|
||||
cfg80211, adjust the code to do everything per link and call the
|
||||
notifications to cfg80211 correctly.
|
||||
|
||||
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
Link: https://patch.msgid.link/20240906064426.2101315-7-quic_adisi@quicinc.com
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -3464,6 +3464,7 @@ static int ieee80211_start_radar_detecti
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
struct ieee80211_chan_req chanreq = { .oper = *chandef };
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
+ struct ieee80211_link_data *link_data;
|
||||
int err;
|
||||
|
||||
lockdep_assert_wiphy(local->hw.wiphy);
|
||||
@@ -3471,16 +3472,20 @@ static int ieee80211_start_radar_detecti
|
||||
if (!list_empty(&local->roc_list) || local->scanning)
|
||||
return -EBUSY;
|
||||
|
||||
+ link_data = sdata_dereference(sdata->link[link_id], sdata);
|
||||
+ if (!link_data)
|
||||
+ return -ENOLINK;
|
||||
+
|
||||
/* whatever, but channel contexts should not complain about that one */
|
||||
- sdata->deflink.smps_mode = IEEE80211_SMPS_OFF;
|
||||
- sdata->deflink.needed_rx_chains = local->rx_chains;
|
||||
+ link_data->smps_mode = IEEE80211_SMPS_OFF;
|
||||
+ link_data->needed_rx_chains = local->rx_chains;
|
||||
|
||||
- err = ieee80211_link_use_channel(&sdata->deflink, &chanreq,
|
||||
+ err = ieee80211_link_use_channel(link_data, &chanreq,
|
||||
IEEE80211_CHANCTX_SHARED);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
- wiphy_delayed_work_queue(wiphy, &sdata->deflink.dfs_cac_timer_work,
|
||||
+ wiphy_delayed_work_queue(wiphy, &link_data->dfs_cac_timer_work,
|
||||
msecs_to_jiffies(cac_time_ms));
|
||||
|
||||
return 0;
|
||||
@@ -3491,16 +3496,21 @@ static void ieee80211_end_cac(struct wip
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
+ struct ieee80211_link_data *link_data;
|
||||
|
||||
lockdep_assert_wiphy(local->hw.wiphy);
|
||||
|
||||
list_for_each_entry(sdata, &local->interfaces, list) {
|
||||
+ link_data = sdata_dereference(sdata->link[link_id], sdata);
|
||||
+ if (!link_data)
|
||||
+ continue;
|
||||
+
|
||||
wiphy_delayed_work_cancel(wiphy,
|
||||
- &sdata->deflink.dfs_cac_timer_work);
|
||||
+ &link_data->dfs_cac_timer_work);
|
||||
|
||||
- if (sdata->wdev.links[0].cac_started) {
|
||||
- ieee80211_link_release_channel(&sdata->deflink);
|
||||
- sdata->wdev.links[0].cac_started = false;
|
||||
+ if (sdata->wdev.links[link_id].cac_started) {
|
||||
+ ieee80211_link_release_channel(link_data);
|
||||
+ sdata->wdev.links[link_id].cac_started = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
--- a/net/mac80211/link.c
|
||||
+++ b/net/mac80211/link.c
|
||||
@@ -77,6 +77,16 @@ void ieee80211_link_stop(struct ieee8021
|
||||
&link->color_change_finalize_work);
|
||||
wiphy_work_cancel(link->sdata->local->hw.wiphy,
|
||||
&link->csa.finalize_work);
|
||||
+
|
||||
+ if (link->sdata->wdev.links[link->link_id].cac_started) {
|
||||
+ wiphy_delayed_work_cancel(link->sdata->local->hw.wiphy,
|
||||
+ &link->dfs_cac_timer_work);
|
||||
+ cfg80211_cac_event(link->sdata->dev,
|
||||
+ &link->conf->chanreq.oper,
|
||||
+ NL80211_RADAR_CAC_ABORTED,
|
||||
+ GFP_KERNEL, link->link_id);
|
||||
+ }
|
||||
+
|
||||
ieee80211_link_release_channel(link);
|
||||
}
|
||||
|
||||
--- a/net/mac80211/util.c
|
||||
+++ b/net/mac80211/util.c
|
||||
@@ -3455,20 +3455,30 @@ void ieee80211_dfs_cac_cancel(struct iee
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
struct cfg80211_chan_def chandef;
|
||||
+ struct ieee80211_link_data *link;
|
||||
+ unsigned int link_id;
|
||||
|
||||
lockdep_assert_wiphy(local->hw.wiphy);
|
||||
|
||||
list_for_each_entry(sdata, &local->interfaces, list) {
|
||||
- wiphy_delayed_work_cancel(local->hw.wiphy,
|
||||
- &sdata->deflink.dfs_cac_timer_work);
|
||||
+ for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS;
|
||||
+ link_id++) {
|
||||
+ link = sdata_dereference(sdata->link[link_id],
|
||||
+ sdata);
|
||||
+ if (!link)
|
||||
+ continue;
|
||||
|
||||
- if (sdata->wdev.links[0].cac_started) {
|
||||
- chandef = sdata->vif.bss_conf.chanreq.oper;
|
||||
- ieee80211_link_release_channel(&sdata->deflink);
|
||||
- cfg80211_cac_event(sdata->dev,
|
||||
- &chandef,
|
||||
+ wiphy_delayed_work_cancel(local->hw.wiphy,
|
||||
+ &link->dfs_cac_timer_work);
|
||||
+
|
||||
+ if (!sdata->wdev.links[link_id].cac_started)
|
||||
+ continue;
|
||||
+
|
||||
+ chandef = link->conf->chanreq.oper;
|
||||
+ ieee80211_link_release_channel(link);
|
||||
+ cfg80211_cac_event(sdata->dev, &chandef,
|
||||
NL80211_RADAR_CAC_ABORTED,
|
||||
- GFP_KERNEL, 0);
|
||||
+ GFP_KERNEL, link_id);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,168 @@
|
||||
From: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
Date: Fri, 6 Sep 2024 12:14:25 +0530
|
||||
Subject: [PATCH] wifi: cfg80211/mac80211: use proper link ID for DFS
|
||||
|
||||
Now that all APIs have support to handle DFS per link, use proper link ID
|
||||
instead of 0.
|
||||
|
||||
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
Link: https://patch.msgid.link/20240906064426.2101315-8-quic_adisi@quicinc.com
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -1656,12 +1656,12 @@ static int ieee80211_stop_ap(struct wiph
|
||||
ieee80211_link_info_change_notify(sdata, link,
|
||||
BSS_CHANGED_BEACON_ENABLED);
|
||||
|
||||
- if (sdata->wdev.links[0].cac_started) {
|
||||
+ if (sdata->wdev.links[link_id].cac_started) {
|
||||
chandef = link_conf->chanreq.oper;
|
||||
wiphy_delayed_work_cancel(wiphy, &link->dfs_cac_timer_work);
|
||||
cfg80211_cac_event(sdata->dev, &chandef,
|
||||
NL80211_RADAR_CAC_ABORTED,
|
||||
- GFP_KERNEL, 0);
|
||||
+ GFP_KERNEL, link_id);
|
||||
}
|
||||
|
||||
drv_stop_ap(sdata->local, sdata, link_conf);
|
||||
@@ -3965,7 +3965,7 @@ __ieee80211_channel_switch(struct wiphy
|
||||
if (!list_empty(&local->roc_list) || local->scanning)
|
||||
return -EBUSY;
|
||||
|
||||
- if (sdata->wdev.links[0].cac_started)
|
||||
+ if (sdata->wdev.links[link_id].cac_started)
|
||||
return -EBUSY;
|
||||
|
||||
if (WARN_ON(link_id >= IEEE80211_MLD_MAX_NUM_LINKS))
|
||||
--- a/net/mac80211/mlme.c
|
||||
+++ b/net/mac80211/mlme.c
|
||||
@@ -3039,11 +3039,11 @@ void ieee80211_dfs_cac_timer_work(struct
|
||||
|
||||
lockdep_assert_wiphy(sdata->local->hw.wiphy);
|
||||
|
||||
- if (sdata->wdev.links[0].cac_started) {
|
||||
+ if (sdata->wdev.links[link->link_id].cac_started) {
|
||||
ieee80211_link_release_channel(link);
|
||||
cfg80211_cac_event(sdata->dev, &chandef,
|
||||
NL80211_RADAR_CAC_FINISHED,
|
||||
- GFP_KERNEL, 0);
|
||||
+ GFP_KERNEL, link->link_id);
|
||||
}
|
||||
}
|
||||
|
||||
--- a/net/mac80211/scan.c
|
||||
+++ b/net/mac80211/scan.c
|
||||
@@ -575,6 +575,7 @@ static bool __ieee80211_can_leave_ch(str
|
||||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct ieee80211_sub_if_data *sdata_iter;
|
||||
+ unsigned int link_id;
|
||||
|
||||
lockdep_assert_wiphy(local->hw.wiphy);
|
||||
|
||||
@@ -585,8 +586,9 @@ static bool __ieee80211_can_leave_ch(str
|
||||
return false;
|
||||
|
||||
list_for_each_entry(sdata_iter, &local->interfaces, list) {
|
||||
- if (sdata_iter->wdev.links[0].cac_started)
|
||||
- return false;
|
||||
+ for_each_valid_link(&sdata_iter->wdev, link_id)
|
||||
+ if (sdata_iter->wdev.links[link_id].cac_started)
|
||||
+ return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
--- a/net/wireless/mlme.c
|
||||
+++ b/net/wireless/mlme.c
|
||||
@@ -1125,14 +1125,14 @@ void cfg80211_cac_event(struct net_devic
|
||||
|
||||
trace_cfg80211_cac_event(netdev, event, link_id);
|
||||
|
||||
- if (WARN_ON(!wdev->links[0].cac_started &&
|
||||
+ if (WARN_ON(!wdev->links[link_id].cac_started &&
|
||||
event != NL80211_RADAR_CAC_STARTED))
|
||||
return;
|
||||
|
||||
switch (event) {
|
||||
case NL80211_RADAR_CAC_FINISHED:
|
||||
- timeout = wdev->links[0].cac_start_time +
|
||||
- msecs_to_jiffies(wdev->links[0].cac_time_ms);
|
||||
+ timeout = wdev->links[link_id].cac_start_time +
|
||||
+ msecs_to_jiffies(wdev->links[link_id].cac_time_ms);
|
||||
WARN_ON(!time_after_eq(jiffies, timeout));
|
||||
cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_AVAILABLE);
|
||||
memcpy(&rdev->cac_done_chandef, chandef,
|
||||
@@ -1141,10 +1141,10 @@ void cfg80211_cac_event(struct net_devic
|
||||
cfg80211_sched_dfs_chan_update(rdev);
|
||||
fallthrough;
|
||||
case NL80211_RADAR_CAC_ABORTED:
|
||||
- wdev->links[0].cac_started = false;
|
||||
+ wdev->links[link_id].cac_started = false;
|
||||
break;
|
||||
case NL80211_RADAR_CAC_STARTED:
|
||||
- wdev->links[0].cac_started = true;
|
||||
+ wdev->links[link_id].cac_started = true;
|
||||
break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
--- a/net/wireless/nl80211.c
|
||||
+++ b/net/wireless/nl80211.c
|
||||
@@ -6066,7 +6066,7 @@ static int nl80211_start_ap(struct sk_bu
|
||||
if (!rdev->ops->start_ap)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
- if (wdev->links[0].cac_started)
|
||||
+ if (wdev->links[link_id].cac_started)
|
||||
return -EBUSY;
|
||||
|
||||
if (wdev->links[link_id].ap.beacon_interval)
|
||||
@@ -10073,6 +10073,7 @@ static int nl80211_start_radar_detection
|
||||
struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
||||
struct net_device *dev = info->user_ptr[1];
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
+ int link_id = nl80211_link_id(info->attrs);
|
||||
struct wiphy *wiphy = wdev->wiphy;
|
||||
struct cfg80211_chan_def chandef;
|
||||
enum nl80211_dfs_regions dfs_region;
|
||||
@@ -10127,7 +10128,7 @@ static int nl80211_start_radar_detection
|
||||
* can not already beacon
|
||||
*/
|
||||
if (wdev->valid_links &&
|
||||
- !wdev->links[0].ap.beacon_interval) {
|
||||
+ !wdev->links[link_id].ap.beacon_interval) {
|
||||
/* nothing */
|
||||
} else {
|
||||
err = -EBUSY;
|
||||
@@ -10135,7 +10136,7 @@ static int nl80211_start_radar_detection
|
||||
}
|
||||
}
|
||||
|
||||
- if (wdev->links[0].cac_started) {
|
||||
+ if (wdev->links[link_id].cac_started) {
|
||||
err = -EBUSY;
|
||||
goto unlock;
|
||||
}
|
||||
@@ -10156,7 +10157,7 @@ static int nl80211_start_radar_detection
|
||||
cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
|
||||
|
||||
err = rdev_start_radar_detection(rdev, dev, &chandef, cac_time_ms,
|
||||
- 0);
|
||||
+ link_id);
|
||||
if (!err) {
|
||||
switch (wdev->iftype) {
|
||||
case NL80211_IFTYPE_AP:
|
||||
@@ -10172,9 +10173,9 @@ static int nl80211_start_radar_detection
|
||||
default:
|
||||
break;
|
||||
}
|
||||
- wdev->links[0].cac_started = true;
|
||||
- wdev->links[0].cac_start_time = jiffies;
|
||||
- wdev->links[0].cac_time_ms = cac_time_ms;
|
||||
+ 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;
|
||||
}
|
||||
unlock:
|
||||
wiphy_unlock(wiphy);
|
@ -0,0 +1,360 @@
|
||||
From: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
Date: Fri, 6 Sep 2024 12:14:26 +0530
|
||||
Subject: [PATCH] wifi: mac80211: handle ieee80211_radar_detected() for MLO
|
||||
|
||||
Currently DFS works under assumption there could be only one channel
|
||||
context in the hardware. Hence, drivers just calls the function
|
||||
ieee80211_radar_detected() passing the hardware structure. However, with
|
||||
MLO, this obviously will not work since number of channel contexts will be
|
||||
more than one and hence drivers would need to pass the channel information
|
||||
as well on which the radar is detected.
|
||||
|
||||
Also, when radar is detected in one of the links, other link's CAC should
|
||||
not be cancelled.
|
||||
|
||||
Hence, in order to support DFS with MLO, do the following changes -
|
||||
* Add channel context conf pointer as an argument to the function
|
||||
ieee80211_radar_detected(). During MLO, drivers would have to pass on
|
||||
which channel context conf radar is detected. Otherwise, drivers could
|
||||
just pass NULL.
|
||||
* ieee80211_radar_detected() will iterate over all channel contexts
|
||||
present and
|
||||
* if channel context conf is passed, only mark that as radar
|
||||
detected
|
||||
* if NULL is passed, then mark all channel contexts as radar
|
||||
detected
|
||||
* Then as usual, schedule the radar detected work.
|
||||
* In the worker, go over all the contexts again and for all such context
|
||||
which is marked with radar detected, cancel the ongoing CAC by calling
|
||||
ieee80211_dfs_cac_cancel() and then notify cfg80211 via
|
||||
cfg80211_radar_event().
|
||||
* To cancel the CAC, pass the channel context as well where radar is
|
||||
detected to ieee80211_dfs_cac_cancel(). This ensures that CAC is
|
||||
canceled only on the links using the provided context, leaving other
|
||||
links unaffected.
|
||||
|
||||
This would also help in scenarios where there is split phy 5 GHz radio,
|
||||
which is capable of DFS channels in both lower and upper band. In this
|
||||
case, simultaneous radars can be detected.
|
||||
|
||||
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
Link: https://patch.msgid.link/20240906064426.2101315-9-quic_adisi@quicinc.com
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/debug.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/debug.c
|
||||
@@ -3,7 +3,7 @@
|
||||
* Copyright (c) 2005-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
|
||||
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
+ * Copyright (c) 2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
@@ -1774,7 +1774,7 @@ static ssize_t ath10k_write_simulate_rad
|
||||
if (!arvif->is_started)
|
||||
return -EINVAL;
|
||||
|
||||
- ieee80211_radar_detected(ar->hw);
|
||||
+ ieee80211_radar_detected(ar->hw, NULL);
|
||||
|
||||
return count;
|
||||
}
|
||||
--- a/drivers/net/wireless/ath/ath10k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/mac.c
|
||||
@@ -1437,7 +1437,7 @@ static void ath10k_recalc_radar_detectio
|
||||
* by indicating that radar was detected.
|
||||
*/
|
||||
ath10k_warn(ar, "failed to start CAC: %d\n", ret);
|
||||
- ieee80211_radar_detected(ar->hw);
|
||||
+ ieee80211_radar_detected(ar->hw, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
|
||||
@@ -3990,7 +3990,7 @@ static void ath10k_radar_detected(struct
|
||||
if (ar->dfs_block_radar_events)
|
||||
ath10k_info(ar, "DFS Radar detected, but ignored as requested\n");
|
||||
else
|
||||
- ieee80211_radar_detected(ar->hw);
|
||||
+ ieee80211_radar_detected(ar->hw, NULL);
|
||||
}
|
||||
|
||||
static void ath10k_radar_confirmation_work(struct work_struct *work)
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
@@ -8358,7 +8358,7 @@ ath11k_wmi_pdev_dfs_radar_detected_event
|
||||
if (ar->dfs_block_radar_events)
|
||||
ath11k_info(ab, "DFS Radar detected, but ignored as requested\n");
|
||||
else
|
||||
- ieee80211_radar_detected(ar->hw);
|
||||
+ ieee80211_radar_detected(ar->hw, NULL);
|
||||
|
||||
exit:
|
||||
rcu_read_unlock();
|
||||
--- a/drivers/net/wireless/ath/ath12k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
|
||||
@@ -6789,7 +6789,7 @@ ath12k_wmi_pdev_dfs_radar_detected_event
|
||||
if (ar->dfs_block_radar_events)
|
||||
ath12k_info(ab, "DFS Radar detected, but ignored as requested\n");
|
||||
else
|
||||
- ieee80211_radar_detected(ath12k_ar_to_hw(ar));
|
||||
+ ieee80211_radar_detected(ath12k_ar_to_hw(ar), NULL);
|
||||
|
||||
exit:
|
||||
rcu_read_unlock();
|
||||
--- a/drivers/net/wireless/ath/ath9k/dfs.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/dfs.c
|
||||
@@ -280,7 +280,7 @@ ath9k_dfs_process_radar_pulse(struct ath
|
||||
if (!pd->add_pulse(pd, pe, NULL))
|
||||
return;
|
||||
DFS_STAT_INC(sc, radar_detected);
|
||||
- ieee80211_radar_detected(sc->hw);
|
||||
+ ieee80211_radar_detected(sc->hw, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
--- a/drivers/net/wireless/ath/ath9k/dfs_debug.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/dfs_debug.c
|
||||
@@ -116,7 +116,7 @@ static ssize_t write_file_simulate_radar
|
||||
{
|
||||
struct ath_softc *sc = file->private_data;
|
||||
|
||||
- ieee80211_radar_detected(sc->hw);
|
||||
+ ieee80211_radar_detected(sc->hw, NULL);
|
||||
|
||||
return count;
|
||||
}
|
||||
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
|
||||
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
|
||||
@@ -394,7 +394,7 @@ mt7615_mcu_rx_radar_detected(struct mt76
|
||||
if (mt76_phy_dfs_state(mphy) < MT_DFS_STATE_CAC)
|
||||
return;
|
||||
|
||||
- ieee80211_radar_detected(mphy->hw);
|
||||
+ ieee80211_radar_detected(mphy->hw, NULL);
|
||||
dev->hw_pattern++;
|
||||
}
|
||||
|
||||
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_dfs.c
|
||||
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_dfs.c
|
||||
@@ -630,7 +630,7 @@ static void mt76x02_dfs_tasklet(struct t
|
||||
radar_detected = mt76x02_dfs_check_detection(dev);
|
||||
if (radar_detected) {
|
||||
/* sw detector rx radar pattern */
|
||||
- ieee80211_radar_detected(dev->mt76.hw);
|
||||
+ ieee80211_radar_detected(dev->mt76.hw, NULL);
|
||||
mt76x02_dfs_detector_reset(dev);
|
||||
|
||||
return;
|
||||
@@ -658,7 +658,7 @@ static void mt76x02_dfs_tasklet(struct t
|
||||
|
||||
/* hw detector rx radar pattern */
|
||||
dfs_pd->stats[i].hw_pattern++;
|
||||
- ieee80211_radar_detected(dev->mt76.hw);
|
||||
+ ieee80211_radar_detected(dev->mt76.hw, NULL);
|
||||
mt76x02_dfs_detector_reset(dev);
|
||||
|
||||
return;
|
||||
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
|
||||
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
|
||||
@@ -293,7 +293,7 @@ mt7915_mcu_rx_radar_detected(struct mt79
|
||||
&dev->rdd2_chandef,
|
||||
GFP_ATOMIC);
|
||||
else
|
||||
- ieee80211_radar_detected(mphy->hw);
|
||||
+ ieee80211_radar_detected(mphy->hw, NULL);
|
||||
dev->hw_pattern++;
|
||||
}
|
||||
|
||||
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
|
||||
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
|
||||
@@ -371,7 +371,7 @@ mt7996_mcu_rx_radar_detected(struct mt79
|
||||
&dev->rdd2_chandef,
|
||||
GFP_ATOMIC);
|
||||
else
|
||||
- ieee80211_radar_detected(mphy->hw);
|
||||
+ ieee80211_radar_detected(mphy->hw, NULL);
|
||||
dev->hw_pattern++;
|
||||
}
|
||||
|
||||
--- a/drivers/net/wireless/ti/wl18xx/event.c
|
||||
+++ b/drivers/net/wireless/ti/wl18xx/event.c
|
||||
@@ -142,7 +142,7 @@ int wl18xx_process_mailbox_events(struct
|
||||
wl18xx_radar_type_decode(mbox->radar_type));
|
||||
|
||||
if (!wl->radar_debug_mode)
|
||||
- ieee80211_radar_detected(wl->hw);
|
||||
+ ieee80211_radar_detected(wl->hw, NULL);
|
||||
}
|
||||
|
||||
if (vector & PERIODIC_SCAN_REPORT_EVENT_ID) {
|
||||
--- a/drivers/net/wireless/virtual/mac80211_hwsim.c
|
||||
+++ b/drivers/net/wireless/virtual/mac80211_hwsim.c
|
||||
@@ -1146,7 +1146,7 @@ static int hwsim_write_simulate_radar(vo
|
||||
{
|
||||
struct mac80211_hwsim_data *data = dat;
|
||||
|
||||
- ieee80211_radar_detected(data->hw);
|
||||
+ ieee80211_radar_detected(data->hw, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
--- a/include/net/mac80211.h
|
||||
+++ b/include/net/mac80211.h
|
||||
@@ -6717,8 +6717,11 @@ void ieee80211_cqm_beacon_loss_notify(st
|
||||
* ieee80211_radar_detected - inform that a radar was detected
|
||||
*
|
||||
* @hw: pointer as obtained from ieee80211_alloc_hw()
|
||||
+ * @chanctx_conf: Channel context on which radar is detected. Mandatory to
|
||||
+ * pass a valid pointer during MLO. For non-MLO %NULL can be passed
|
||||
*/
|
||||
-void ieee80211_radar_detected(struct ieee80211_hw *hw);
|
||||
+void ieee80211_radar_detected(struct ieee80211_hw *hw,
|
||||
+ struct ieee80211_chanctx_conf *chanctx_conf);
|
||||
|
||||
/**
|
||||
* ieee80211_chswitch_done - Complete channel switch process
|
||||
--- a/net/mac80211/chan.c
|
||||
+++ b/net/mac80211/chan.c
|
||||
@@ -681,6 +681,7 @@ ieee80211_alloc_chanctx(struct ieee80211
|
||||
ctx->mode = mode;
|
||||
ctx->conf.radar_enabled = false;
|
||||
ctx->conf.radio_idx = radio_idx;
|
||||
+ ctx->radar_detected = false;
|
||||
_ieee80211_recalc_chanctx_min_def(local, ctx, NULL, false);
|
||||
|
||||
return ctx;
|
||||
--- a/net/mac80211/ieee80211_i.h
|
||||
+++ b/net/mac80211/ieee80211_i.h
|
||||
@@ -895,6 +895,8 @@ struct ieee80211_chanctx {
|
||||
struct ieee80211_chan_req req;
|
||||
|
||||
struct ieee80211_chanctx_conf conf;
|
||||
+
|
||||
+ bool radar_detected;
|
||||
};
|
||||
|
||||
struct mac80211_qos_map {
|
||||
@@ -2632,7 +2634,8 @@ void ieee80211_recalc_chanctx_min_def(st
|
||||
bool ieee80211_is_radar_required(struct ieee80211_local *local);
|
||||
|
||||
void ieee80211_dfs_cac_timer_work(struct wiphy *wiphy, struct wiphy_work *work);
|
||||
-void ieee80211_dfs_cac_cancel(struct ieee80211_local *local);
|
||||
+void ieee80211_dfs_cac_cancel(struct ieee80211_local *local,
|
||||
+ struct ieee80211_chanctx *chanctx);
|
||||
void ieee80211_dfs_radar_detected_work(struct wiphy *wiphy,
|
||||
struct wiphy_work *work);
|
||||
int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata,
|
||||
--- a/net/mac80211/pm.c
|
||||
+++ b/net/mac80211/pm.c
|
||||
@@ -32,7 +32,7 @@ int __ieee80211_suspend(struct ieee80211
|
||||
|
||||
ieee80211_scan_cancel(local);
|
||||
|
||||
- ieee80211_dfs_cac_cancel(local);
|
||||
+ ieee80211_dfs_cac_cancel(local, NULL);
|
||||
|
||||
ieee80211_roc_purge(local, NULL);
|
||||
|
||||
--- a/net/mac80211/util.c
|
||||
+++ b/net/mac80211/util.c
|
||||
@@ -3451,11 +3451,16 @@ u64 ieee80211_calculate_rx_timestamp(str
|
||||
return ts;
|
||||
}
|
||||
|
||||
-void ieee80211_dfs_cac_cancel(struct ieee80211_local *local)
|
||||
+/* Cancel CAC for the interfaces under the specified @local. If @ctx is
|
||||
+ * also provided, only the interfaces using that ctx will be canceled.
|
||||
+ */
|
||||
+void ieee80211_dfs_cac_cancel(struct ieee80211_local *local,
|
||||
+ struct ieee80211_chanctx *ctx)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
struct cfg80211_chan_def chandef;
|
||||
struct ieee80211_link_data *link;
|
||||
+ struct ieee80211_chanctx_conf *chanctx_conf;
|
||||
unsigned int link_id;
|
||||
|
||||
lockdep_assert_wiphy(local->hw.wiphy);
|
||||
@@ -3468,6 +3473,11 @@ void ieee80211_dfs_cac_cancel(struct iee
|
||||
if (!link)
|
||||
continue;
|
||||
|
||||
+ chanctx_conf = sdata_dereference(link->conf->chanctx_conf,
|
||||
+ sdata);
|
||||
+ if (ctx && &ctx->conf != chanctx_conf)
|
||||
+ continue;
|
||||
+
|
||||
wiphy_delayed_work_cancel(local->hw.wiphy,
|
||||
&link->dfs_cac_timer_work);
|
||||
|
||||
@@ -3488,9 +3498,8 @@ void ieee80211_dfs_radar_detected_work(s
|
||||
{
|
||||
struct ieee80211_local *local =
|
||||
container_of(work, struct ieee80211_local, radar_detected_work);
|
||||
- struct cfg80211_chan_def chandef = local->hw.conf.chandef;
|
||||
+ struct cfg80211_chan_def chandef;
|
||||
struct ieee80211_chanctx *ctx;
|
||||
- int num_chanctx = 0;
|
||||
|
||||
lockdep_assert_wiphy(local->hw.wiphy);
|
||||
|
||||
@@ -3498,25 +3507,46 @@ void ieee80211_dfs_radar_detected_work(s
|
||||
if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER)
|
||||
continue;
|
||||
|
||||
- num_chanctx++;
|
||||
+ if (!ctx->radar_detected)
|
||||
+ continue;
|
||||
+
|
||||
+ ctx->radar_detected = false;
|
||||
+
|
||||
chandef = ctx->conf.def;
|
||||
+
|
||||
+ ieee80211_dfs_cac_cancel(local, ctx);
|
||||
+ cfg80211_radar_event(local->hw.wiphy, &chandef, GFP_KERNEL);
|
||||
}
|
||||
+}
|
||||
|
||||
- ieee80211_dfs_cac_cancel(local);
|
||||
+static void
|
||||
+ieee80211_radar_mark_chan_ctx_iterator(struct ieee80211_hw *hw,
|
||||
+ struct ieee80211_chanctx_conf *chanctx_conf,
|
||||
+ void *data)
|
||||
+{
|
||||
+ struct ieee80211_chanctx *ctx =
|
||||
+ container_of(chanctx_conf, struct ieee80211_chanctx,
|
||||
+ conf);
|
||||
|
||||
- if (num_chanctx > 1)
|
||||
- /* XXX: multi-channel is not supported yet */
|
||||
- WARN_ON(1);
|
||||
- else
|
||||
- cfg80211_radar_event(local->hw.wiphy, &chandef, GFP_KERNEL);
|
||||
+ if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER)
|
||||
+ return;
|
||||
+
|
||||
+ if (data && data != chanctx_conf)
|
||||
+ return;
|
||||
+
|
||||
+ ctx->radar_detected = true;
|
||||
}
|
||||
|
||||
-void ieee80211_radar_detected(struct ieee80211_hw *hw)
|
||||
+void ieee80211_radar_detected(struct ieee80211_hw *hw,
|
||||
+ struct ieee80211_chanctx_conf *chanctx_conf)
|
||||
{
|
||||
struct ieee80211_local *local = hw_to_local(hw);
|
||||
|
||||
trace_api_radar_detected(local);
|
||||
|
||||
+ ieee80211_iter_chan_contexts_atomic(hw, ieee80211_radar_mark_chan_ctx_iterator,
|
||||
+ chanctx_conf);
|
||||
+
|
||||
wiphy_work_queue(hw->wiphy, &local->radar_detected_work);
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_radar_detected);
|
@ -9,3 +9,56 @@
|
||||
head = &wcid->tx_offchannel;
|
||||
else
|
||||
head = &wcid->tx_pending;
|
||||
--- a/mt7615/mcu.c
|
||||
+++ b/mt7615/mcu.c
|
||||
@@ -394,7 +394,7 @@ mt7615_mcu_rx_radar_detected(struct mt76
|
||||
if (mt76_phy_dfs_state(mphy) < MT_DFS_STATE_CAC)
|
||||
return;
|
||||
|
||||
- ieee80211_radar_detected(mphy->hw);
|
||||
+ ieee80211_radar_detected(mphy->hw, NULL);
|
||||
dev->hw_pattern++;
|
||||
}
|
||||
|
||||
--- a/mt76x02_dfs.c
|
||||
+++ b/mt76x02_dfs.c
|
||||
@@ -630,7 +630,7 @@ static void mt76x02_dfs_tasklet(struct t
|
||||
radar_detected = mt76x02_dfs_check_detection(dev);
|
||||
if (radar_detected) {
|
||||
/* sw detector rx radar pattern */
|
||||
- ieee80211_radar_detected(dev->mt76.hw);
|
||||
+ ieee80211_radar_detected(dev->mt76.hw, NULL);
|
||||
mt76x02_dfs_detector_reset(dev);
|
||||
|
||||
return;
|
||||
@@ -658,7 +658,7 @@ static void mt76x02_dfs_tasklet(struct t
|
||||
|
||||
/* hw detector rx radar pattern */
|
||||
dfs_pd->stats[i].hw_pattern++;
|
||||
- ieee80211_radar_detected(dev->mt76.hw);
|
||||
+ ieee80211_radar_detected(dev->mt76.hw, NULL);
|
||||
mt76x02_dfs_detector_reset(dev);
|
||||
|
||||
return;
|
||||
--- a/mt7915/mcu.c
|
||||
+++ b/mt7915/mcu.c
|
||||
@@ -297,7 +297,7 @@ mt7915_mcu_rx_radar_detected(struct mt79
|
||||
&dev->rdd2_chandef,
|
||||
GFP_ATOMIC);
|
||||
else
|
||||
- ieee80211_radar_detected(mphy->hw);
|
||||
+ ieee80211_radar_detected(mphy->hw, NULL);
|
||||
dev->hw_pattern++;
|
||||
}
|
||||
|
||||
--- a/mt7996/mcu.c
|
||||
+++ b/mt7996/mcu.c
|
||||
@@ -383,7 +383,7 @@ mt7996_mcu_rx_radar_detected(struct mt79
|
||||
&dev->rdd2_chandef,
|
||||
GFP_ATOMIC);
|
||||
else
|
||||
- ieee80211_radar_detected(mphy->hw);
|
||||
+ ieee80211_radar_detected(mphy->hw, NULL);
|
||||
dev->hw_pattern++;
|
||||
}
|
||||
|
||||
|
@ -68,6 +68,15 @@
|
||||
sta->tdls,
|
||||
sta->tdls_initiator,
|
||||
sta->wme,
|
||||
@@ -1158,7 +1158,7 @@ static ssize_t mwl_debugfs_dfs_radar_wri
|
||||
struct mwl_priv *priv = (struct mwl_priv *)file->private_data;
|
||||
|
||||
wiphy_info(priv->hw->wiphy, "simulate radar detected\n");
|
||||
- ieee80211_radar_detected(priv->hw);
|
||||
+ ieee80211_radar_detected(priv->hw, NULL);
|
||||
|
||||
return count;
|
||||
}
|
||||
--- a/hif/fwcmd.c
|
||||
+++ b/hif/fwcmd.c
|
||||
@@ -633,11 +633,15 @@ einval:
|
||||
@ -491,3 +500,32 @@
|
||||
|
||||
switch (format) {
|
||||
case TX_RATE_FORMAT_LEGACY:
|
||||
--- a/hif/pcie/pcie.c
|
||||
+++ b/hif/pcie/pcie.c
|
||||
@@ -546,7 +546,7 @@ static irqreturn_t pcie_isr_8864(struct
|
||||
|
||||
if (int_status & MACREG_A2HRIC_BIT_RADAR_DETECT) {
|
||||
wiphy_info(hw->wiphy, "radar detected by firmware\n");
|
||||
- ieee80211_radar_detected(hw);
|
||||
+ ieee80211_radar_detected(hw, NULL);
|
||||
}
|
||||
|
||||
if (int_status & MACREG_A2HRIC_BIT_CHAN_SWITCH) ieee80211_queue_work(hw, &priv->chnl_switch_handle);
|
||||
@@ -593,7 +593,7 @@ static irqreturn_t pcie_isr_8997(struct
|
||||
|
||||
if (int_status & MACREG_A2HRIC_BIT_RADAR_DETECT) {
|
||||
wiphy_info(hw->wiphy, "radar detected by firmware\n");
|
||||
- ieee80211_radar_detected(hw);
|
||||
+ ieee80211_radar_detected(hw, NULL);
|
||||
}
|
||||
|
||||
if (int_status & MACREG_A2HRIC_BIT_CHAN_SWITCH)
|
||||
@@ -1071,7 +1071,7 @@ static irqreturn_t pcie_isr_ndp(struct i
|
||||
|
||||
if (int_status & MACREG_A2HRIC_NEWDP_DFS) {
|
||||
wiphy_info(hw->wiphy, "radar detected by firmware\n");
|
||||
- ieee80211_radar_detected(hw);
|
||||
+ ieee80211_radar_detected(hw, NULL);
|
||||
}
|
||||
|
||||
if (int_status & MACREG_A2HRIC_NEWDP_CHANNEL_SWITCH)
|
||||
|
Loading…
x
Reference in New Issue
Block a user