mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-26 00:41:17 +00:00
ec61ccc0d3
Mostly MLO related Signed-off-by: Felix Fietkau <nbd@nbd.name>
436 lines
14 KiB
Diff
436 lines
14 KiB
Diff
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,
|