diff options
author | Johannes Berg <johannes.berg@intel.com> | 2022-06-10 11:07:55 +0200 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2022-06-20 12:56:11 +0200 |
commit | f2a0290b2df2b0e65ab78b71c4a15e732afd4458 (patch) | |
tree | 8e3f641dfd925f1a349697c37c6596da3c7fe62a /net/wireless | |
parent | c8a11ed5539f6df98d06259b5177975162b88510 (diff) | |
download | linux-stable-f2a0290b2df2b0e65ab78b71c4a15e732afd4458.tar.gz linux-stable-f2a0290b2df2b0e65ab78b71c4a15e732afd4458.tar.bz2 linux-stable-f2a0290b2df2b0e65ab78b71c4a15e732afd4458.zip |
wifi: cfg80211: add optional link add/remove callbacks
Add some optional callbacks for link add/remove so that
drivers can react here. Initially, I thought it would be
sufficient to just create the link in start_ap etc., but
it turns out that's not so simple, since there are quite
a few callbacks that can be called: if they're erroneously
without start_ap, things might crash.
Thus it might be easier for drivers to allocate all the
necessary data structures immediately, to not have to
worry about it in each callback, since cfg80211 checks
that the link ID is valid (has been added.)
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless')
-rw-r--r-- | net/wireless/nl80211.c | 14 | ||||
-rw-r--r-- | net/wireless/rdev-ops.h | 26 | ||||
-rw-r--r-- | net/wireless/trace.h | 20 |
3 files changed, 58 insertions, 2 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 9bc66a21ac3a..0a69a5a6b74d 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -15556,9 +15556,11 @@ static int nl80211_set_fils_aad(struct sk_buff *skb, static int nl80211_add_link(struct sk_buff *skb, struct genl_info *info) { + struct cfg80211_registered_device *rdev = info->user_ptr[0]; unsigned int link_id = nl80211_link_id(info->attrs); struct net_device *dev = info->user_ptr[1]; struct wireless_dev *wdev = dev->ieee80211_ptr; + int ret; if (!(wdev->wiphy->flags & WIPHY_FLAG_SUPPORTS_MLO)) return -EINVAL; @@ -15578,13 +15580,20 @@ static int nl80211_add_link(struct sk_buff *skb, struct genl_info *info) wdev->valid_links |= BIT(link_id); ether_addr_copy(wdev->links[link_id].addr, nla_data(info->attrs[NL80211_ATTR_MAC])); + + ret = rdev_add_intf_link(rdev, wdev, link_id); + if (ret) { + wdev->valid_links &= ~BIT(link_id); + eth_zero_addr(wdev->links[link_id].addr); + } wdev_unlock(wdev); - return 0; + return ret; } static int nl80211_remove_link(struct sk_buff *skb, struct genl_info *info) { + struct cfg80211_registered_device *rdev = info->user_ptr[0]; unsigned int link_id = nl80211_link_id(info->attrs); struct net_device *dev = info->user_ptr[1]; struct wireless_dev *wdev = dev->ieee80211_ptr; @@ -15604,6 +15613,9 @@ static int nl80211_remove_link(struct sk_buff *skb, struct genl_info *info) wdev_lock(wdev); wdev->valid_links &= ~BIT(link_id); + + rdev_del_intf_link(rdev, wdev, link_id); + eth_zero_addr(wdev->links[link_id].addr); wdev_unlock(wdev); diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index d2300eff03ae..a329ba036989 100644 --- a/net/wireless/rdev-ops.h +++ b/net/wireless/rdev-ops.h @@ -1422,4 +1422,30 @@ rdev_set_radar_background(struct cfg80211_registered_device *rdev, return ret; } +static inline int +rdev_add_intf_link(struct cfg80211_registered_device *rdev, + struct wireless_dev *wdev, + unsigned int link_id) +{ + int ret = 0; + + trace_rdev_add_intf_link(&rdev->wiphy, wdev, link_id); + if (rdev->ops->add_intf_link) + ret = rdev->ops->add_intf_link(&rdev->wiphy, wdev, link_id); + trace_rdev_return_int(&rdev->wiphy, ret); + + return ret; +} + +static inline void +rdev_del_intf_link(struct cfg80211_registered_device *rdev, + struct wireless_dev *wdev, + unsigned int link_id) +{ + trace_rdev_del_intf_link(&rdev->wiphy, wdev, link_id); + if (rdev->ops->add_intf_link) + rdev->ops->add_intf_link(&rdev->wiphy, wdev, link_id); + trace_rdev_return_void(&rdev->wiphy); +} + #endif /* __CFG80211_RDEV_OPS */ diff --git a/net/wireless/trace.h b/net/wireless/trace.h index 92742430958e..65f8b814ecd0 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h @@ -2064,7 +2064,7 @@ TRACE_EVENT(rdev_set_noack_map, WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->noack_map) ); -TRACE_EVENT(rdev_get_channel, +DECLARE_EVENT_CLASS(wiphy_wdev_link_evt, TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, unsigned int link_id), TP_ARGS(wiphy, wdev, link_id), @@ -2082,6 +2082,12 @@ TRACE_EVENT(rdev_get_channel, WIPHY_PR_ARG, WDEV_PR_ARG, __entry->link_id) ); +DEFINE_EVENT(wiphy_wdev_link_evt, rdev_get_channel, + TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, + unsigned int link_id), + TP_ARGS(wiphy, wdev, link_id) +); + TRACE_EVENT(rdev_return_chandef, TP_PROTO(struct wiphy *wiphy, int ret, struct cfg80211_chan_def *chandef), @@ -2823,6 +2829,18 @@ TRACE_EVENT(rdev_set_radar_background, WIPHY_PR_ARG, CHAN_DEF_PR_ARG) ); +DEFINE_EVENT(wiphy_wdev_link_evt, rdev_add_intf_link, + TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, + unsigned int link_id), + TP_ARGS(wiphy, wdev, link_id) +); + +DEFINE_EVENT(wiphy_wdev_link_evt, rdev_del_intf_link, + TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, + unsigned int link_id), + TP_ARGS(wiphy, wdev, link_id) +); + /************************************************************* * cfg80211 exported functions traces * *************************************************************/ |