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>
This commit is contained in:
committed by
Johannes Berg
parent
62c16f219a
commit
81f67d60eb
+5
-4
@@ -1110,18 +1110,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))
|
||||
|
||||
+19
-5
@@ -10121,7 +10121,20 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
|
||||
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;
|
||||
}
|
||||
@@ -10141,7 +10154,8 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
|
||||
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:
|
||||
@@ -16515,10 +16529,10 @@ nl80211_set_ttlm(struct sk_buff *skb, struct genl_info *info)
|
||||
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) \
|
||||
@@ -17413,7 +17427,7 @@ static const struct genl_small_ops nl80211_small_ops[] = {
|
||||
.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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
+11
-8
@@ -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(struct cfg80211_registered_device *rdev)
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+20
-11
@@ -806,17 +806,21 @@ DEFINE_EVENT(wiphy_netdev_evt, rdev_flush_pmksa,
|
||||
);
|
||||
|
||||
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,
|
||||
|
||||
Reference in New Issue
Block a user