]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: cfg80211: Add support for controlling EPCS
authorIlan Peer <ilan.peer@intel.com>
Thu, 2 Jan 2025 14:19:59 +0000 (16:19 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Mon, 13 Jan 2025 14:34:09 +0000 (15:34 +0100)
Add support for configuring Emergency Preparedness Communication
Services (EPCS) for station mode.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20250102161730.ea54ac94445c.I11d750188bc0871e13e86146a3b5cc048d853e69@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/net/cfg80211.h
include/uapi/linux/nl80211.h
net/wireless/nl80211.c
net/wireless/rdev-ops.h
net/wireless/trace.h

index d4b4cabac029feac9d712de5160f7a616876b8ac..363d7dd2255aaeb9fb645dcb1d4bd5215f19a6be 100644 (file)
@@ -4594,6 +4594,7 @@ struct mgmt_frame_regs {
  *
  * @set_hw_timestamp: Enable/disable HW timestamping of TM/FTM frames.
  * @set_ttlm: set the TID to link mapping.
+ * @set_epcs: Enable/Disable EPCS for station mode.
  * @get_radio_mask: get bitmask of radios in use.
  *     (invoked with the wiphy mutex held)
  * @assoc_ml_reconf: Request a non-AP MLO connection to perform ML
@@ -4971,6 +4972,8 @@ struct cfg80211_ops {
        int     (*assoc_ml_reconf)(struct wiphy *wiphy, struct net_device *dev,
                                   struct cfg80211_assoc_link *add_links,
                                   u16 rem_links);
+       int     (*set_epcs)(struct wiphy *wiphy, struct net_device *dev,
+                           bool val);
 };
 
 /*
@@ -9771,6 +9774,13 @@ void cfg80211_mlo_reconf_add_done(struct net_device *dev,
  */
 void cfg80211_schedule_channels_check(struct wireless_dev *wdev);
 
+/**
+ * cfg80211_epcs_changed - Notify about a change in EPCS state
+ * @netdev: the wireless device whose EPCS state changed
+ * @enabled: set to true if EPCS was enabled, otherwise set to false.
+ */
+void cfg80211_epcs_changed(struct net_device *netdev, bool enabled);
+
 #ifdef CONFIG_CFG80211_DEBUGFS
 /**
  * wiphy_locked_debugfs_read - do a locked read in debugfs
index f900d7cc42bceb2ff156fdc7d834130e4572c9fa..f6c1b181c886d23089c8a7a48ffb3c3fe6d63275 100644 (file)
  * @NL80211_CMD_ASSOC_MLO_RECONF: For a non-AP MLD station, request to
  *      add/remove links to/from the association.
  *
+ * @NL80211_CMD_EPCS_CFG: EPCS configuration for a station. Used by userland to
+ *     control EPCS configuration. Used to notify userland on the current state
+ *     of EPCS.
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -1590,6 +1594,7 @@ enum nl80211_commands {
        NL80211_CMD_SET_TID_TO_LINK_MAPPING,
 
        NL80211_CMD_ASSOC_MLO_RECONF,
+       NL80211_CMD_EPCS_CFG,
 
        /* add new commands above here */
 
@@ -2885,6 +2890,9 @@ enum nl80211_commands {
  * @NL80211_ATTR_MLO_RECONF_REM_LINKS: (u16) A bitmask of the links requested
  *      to be removed from the MLO association.
  *
+ * @NL80211_ATTR_EPCS: Flag attribute indicating that EPCS is enabled for a
+ *     station interface.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -3438,6 +3446,7 @@ enum nl80211_attrs {
        NL80211_ATTR_SUPPORTED_SELECTORS,
 
        NL80211_ATTR_MLO_RECONF_REM_LINKS,
+       NL80211_ATTR_EPCS,
 
        /* add attributes here, update the policy in nl80211.c */
 
index 199fa3da31e9653edf564bf9d4e6d056cea27dd2..351b863623afce8fbb0ebb079908cf0997f27a0d 100644 (file)
@@ -849,6 +849,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
                NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_supported_selectors,
                                       NL80211_MAX_SUPP_SELECTORS),
        [NL80211_ATTR_MLO_RECONF_REM_LINKS] = { .type = NLA_U16 },
+       [NL80211_ATTR_EPCS] = { .type = NLA_FLAG },
 };
 
 /* policy for the key attributes */
@@ -16537,6 +16538,26 @@ out:
        return err;
 }
 
+static int
+nl80211_epcs_cfg(struct sk_buff *skb, struct genl_info *info)
+{
+       struct cfg80211_registered_device *rdev = info->user_ptr[0];
+       struct net_device *dev = info->user_ptr[1];
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+       bool val;
+
+       if (wdev->iftype != NL80211_IFTYPE_STATION &&
+           wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
+               return -EOPNOTSUPP;
+
+       if (!wdev->connected)
+               return -ENOLINK;
+
+       val = nla_get_flag(info->attrs[NL80211_ATTR_EPCS]);
+
+       return rdev_set_epcs(rdev, dev, val);
+}
+
 #define NL80211_FLAG_NEED_WIPHY                0x01
 #define NL80211_FLAG_NEED_NETDEV       0x02
 #define NL80211_FLAG_NEED_RTNL         0x04
@@ -17735,6 +17756,12 @@ static const struct genl_small_ops nl80211_small_ops[] = {
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
        },
+       {
+               .cmd = NL80211_CMD_EPCS_CFG,
+               .doit = nl80211_epcs_cfg,
+               .flags = GENL_UNS_ADMIN_PERM,
+               .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
+       },
 };
 
 static struct genl_family nl80211_fam __ro_after_init = {
@@ -20480,6 +20507,39 @@ void cfg80211_schedule_channels_check(struct wireless_dev *wdev)
 }
 EXPORT_SYMBOL(cfg80211_schedule_channels_check);
 
+void cfg80211_epcs_changed(struct net_device *netdev, bool enabled)
+{
+       struct wireless_dev *wdev = netdev->ieee80211_ptr;
+       struct wiphy *wiphy = wdev->wiphy;
+       struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
+       struct sk_buff *msg;
+       void *hdr;
+
+       trace_cfg80211_epcs_changed(wdev, enabled);
+
+       msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+       if (!msg)
+               return;
+
+       hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_EPCS_CFG);
+       if (!hdr) {
+               nlmsg_free(msg);
+               return;
+       }
+
+       if (enabled && nla_put_flag(msg, NL80211_ATTR_EPCS))
+               goto nla_put_failure;
+
+       genlmsg_end(msg, hdr);
+       genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
+                               NL80211_MCGRP_MLME, GFP_KERNEL);
+       return;
+
+ nla_put_failure:
+       nlmsg_free(msg);
+}
+EXPORT_SYMBOL(cfg80211_epcs_changed);
+
 /* initialisation/exit functions */
 
 int __init nl80211_init(void)
index 2393a25577ad3f8f95bd8c6c3e38a111f949e3f5..759da162334284158fa7b17c208fd88e83e39416 100644 (file)
@@ -1566,4 +1566,19 @@ rdev_assoc_ml_reconf(struct cfg80211_registered_device *rdev,
        return ret;
 }
 
+static inline int
+rdev_set_epcs(struct cfg80211_registered_device *rdev,
+             struct net_device *dev, bool val)
+{
+       struct wiphy *wiphy = &rdev->wiphy;
+       int ret = -EOPNOTSUPP;
+
+       trace_rdev_set_epcs(wiphy, dev, val);
+       if (rdev->ops->set_epcs)
+               ret = rdev->ops->set_epcs(wiphy, dev, val);
+       trace_rdev_return_int(wiphy, ret);
+
+       return ret;
+}
+
 #endif /* __CFG80211_RDEV_OPS */
index 627217e25c2f5000638dfda62858f521ca87d484..4f0abd5d49df8c55b52d7d46ecd400af76c143f1 100644 (file)
@@ -3049,6 +3049,24 @@ TRACE_EVENT(rdev_set_ttlm,
                  WIPHY_PR_ARG, NETDEV_PR_ARG)
 );
 
+TRACE_EVENT(rdev_set_epcs,
+       TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
+                bool val),
+       TP_ARGS(wiphy, netdev, val),
+       TP_STRUCT__entry(
+               WIPHY_ENTRY
+               NETDEV_ENTRY
+               __field(bool, val)
+       ),
+       TP_fast_assign(
+               WIPHY_ASSIGN;
+               NETDEV_ASSIGN;
+               __entry->val = val;
+       ),
+       TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", config=%u",
+                 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->val)
+);
+
 /*************************************************************
  *          cfg80211 exported functions traces              *
  *************************************************************/
@@ -4148,6 +4166,22 @@ TRACE_EVENT(rdev_assoc_ml_reconf,
                  WIPHY_PR_ARG, NETDEV_PR_ARG,
                  __entry->add_links, __entry->rem_links)
 );
+
+TRACE_EVENT(cfg80211_epcs_changed,
+       TP_PROTO(struct wireless_dev *wdev, bool enabled),
+       TP_ARGS(wdev, enabled),
+       TP_STRUCT__entry(
+               WDEV_ENTRY
+               __field(u32, enabled)
+       ),
+       TP_fast_assign(
+               WDEV_ASSIGN;
+               __entry->enabled = enabled;
+       ),
+       TP_printk(WDEV_PR_FMT ", enabled=%u",
+                 WDEV_PR_ARG, __entry->enabled)
+);
+
 #endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */
 
 #undef TRACE_INCLUDE_PATH