wifi: cfg80211: add a function for reporting TX status with hardware timestamps
authorAvraham Stern <avraham.stern@intel.com>
Wed, 26 Jan 2022 17:13:47 +0000 (19:13 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 22 Jul 2022 12:28:24 +0000 (14:28 +0200)
Add a function for reporting TX status with hardware timestamps. This
function shall be used for reporting the TX status of Timing
measurement and Fine timing measurement action frames by devices that
support reporting hardware timestamps.

Signed-off-by: Avraham Stern <avraham.stern@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/net/cfg80211.h
net/wireless/nl80211.c

index d5af3a7fc2b424d4d78ecc56b368137f767479c8..43d54f5c84f914aae024c2fe87ccfebf0e28d7a1 100644 (file)
@@ -7837,6 +7837,38 @@ static inline bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq,
                                    flags);
 }
 
+/**
+ * struct cfg80211_tx_status - TX status for management frame information
+ *
+ * @cookie: Cookie returned by cfg80211_ops::mgmt_tx()
+ * @tx_tstamp: hardware TX timestamp in nanoseconds
+ * @ack_tstamp: hardware ack RX timestamp in nanoseconds
+ * @buf: Management frame (header + body)
+ * @len: length of the frame data
+ * @ack: Whether frame was acknowledged
+ */
+struct cfg80211_tx_status {
+       u64 cookie;
+       u64 tx_tstamp;
+       u64 ack_tstamp;
+       const u8 *buf;
+       size_t len;
+       bool ack;
+};
+
+/**
+ * cfg80211_mgmt_tx_status_ext - TX status notification with extended info
+ * @wdev: wireless device receiving the frame
+ * @status: TX status data
+ * @gfp: context flags
+ *
+ * This function is called whenever a management frame was requested to be
+ * transmitted with cfg80211_ops::mgmt_tx() to report the TX status of the
+ * transmission attempt with extended info.
+ */
+void cfg80211_mgmt_tx_status_ext(struct wireless_dev *wdev,
+                                struct cfg80211_tx_status *status, gfp_t gfp);
+
 /**
  * cfg80211_mgmt_tx_status - notification of TX status for management frame
  * @wdev: wireless device receiving the frame
@@ -7850,8 +7882,19 @@ static inline bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq,
  * transmitted with cfg80211_ops::mgmt_tx() to report the TX status of the
  * transmission attempt.
  */
-void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie,
-                            const u8 *buf, size_t len, bool ack, gfp_t gfp);
+static inline void cfg80211_mgmt_tx_status(struct wireless_dev *wdev,
+                                          u64 cookie, const u8 *buf,
+                                          size_t len, bool ack, gfp_t gfp)
+{
+       struct cfg80211_tx_status status = {
+               .cookie = cookie,
+               .buf = buf,
+               .len = len,
+               .ack = ack
+       };
+
+       cfg80211_mgmt_tx_status_ext(wdev, &status, gfp);
+}
 
 /**
  * cfg80211_control_port_tx_status - notification of TX status for control
index 310d22b263d1b75f88af0ddd31e785cbdb9620ef..a3934f443a845be90eedee10eb12c3ede4c76571 100644 (file)
@@ -18396,8 +18396,8 @@ int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
        return -ENOBUFS;
 }
 
-static void nl80211_frame_tx_status(struct wireless_dev *wdev, u64 cookie,
-                                   const u8 *buf, size_t len, bool ack,
+static void nl80211_frame_tx_status(struct wireless_dev *wdev,
+                                   struct cfg80211_tx_status *status,
                                    gfp_t gfp, enum nl80211_commands command)
 {
        struct wiphy *wiphy = wdev->wiphy;
@@ -18407,11 +18407,13 @@ static void nl80211_frame_tx_status(struct wireless_dev *wdev, u64 cookie,
        void *hdr;
 
        if (command == NL80211_CMD_FRAME_TX_STATUS)
-               trace_cfg80211_mgmt_tx_status(wdev, cookie, ack);
+               trace_cfg80211_mgmt_tx_status(wdev, status->cookie,
+                                             status->ack);
        else
-               trace_cfg80211_control_port_tx_status(wdev, cookie, ack);
+               trace_cfg80211_control_port_tx_status(wdev, status->cookie,
+                                                     status->ack);
 
-       msg = nlmsg_new(100 + len, gfp);
+       msg = nlmsg_new(100 + status->len, gfp);
        if (!msg)
                return;
 
@@ -18426,10 +18428,16 @@ static void nl80211_frame_tx_status(struct wireless_dev *wdev, u64 cookie,
                                   netdev->ifindex)) ||
            nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
                              NL80211_ATTR_PAD) ||
-           nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
-           nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
+           nla_put(msg, NL80211_ATTR_FRAME, status->len, status->buf) ||
+           nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, status->cookie,
                              NL80211_ATTR_PAD) ||
-           (ack && nla_put_flag(msg, NL80211_ATTR_ACK)))
+           (status->ack && nla_put_flag(msg, NL80211_ATTR_ACK)) ||
+           (status->tx_tstamp &&
+            nla_put_u64_64bit(msg, NL80211_ATTR_TX_HW_TIMESTAMP,
+                              status->tx_tstamp, NL80211_ATTR_PAD)) ||
+           (status->ack_tstamp &&
+            nla_put_u64_64bit(msg, NL80211_ATTR_RX_HW_TIMESTAMP,
+                              status->ack_tstamp, NL80211_ATTR_PAD)))
                goto nla_put_failure;
 
        genlmsg_end(msg, hdr);
@@ -18446,18 +18454,24 @@ void cfg80211_control_port_tx_status(struct wireless_dev *wdev, u64 cookie,
                                     const u8 *buf, size_t len, bool ack,
                                     gfp_t gfp)
 {
-       nl80211_frame_tx_status(wdev, cookie, buf, len, ack, gfp,
+       struct cfg80211_tx_status status = {
+               .cookie = cookie,
+               .buf = buf,
+               .len = len,
+               .ack = ack
+       };
+
+       nl80211_frame_tx_status(wdev, &status, gfp,
                                NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS);
 }
 EXPORT_SYMBOL(cfg80211_control_port_tx_status);
 
-void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie,
-                            const u8 *buf, size_t len, bool ack, gfp_t gfp)
+void cfg80211_mgmt_tx_status_ext(struct wireless_dev *wdev,
+                                struct cfg80211_tx_status *status, gfp_t gfp)
 {
-       nl80211_frame_tx_status(wdev, cookie, buf, len, ack, gfp,
-                               NL80211_CMD_FRAME_TX_STATUS);
+       nl80211_frame_tx_status(wdev, status, gfp, NL80211_CMD_FRAME_TX_STATUS);
 }
-EXPORT_SYMBOL(cfg80211_mgmt_tx_status);
+EXPORT_SYMBOL(cfg80211_mgmt_tx_status_ext);
 
 static int __nl80211_rx_control_port(struct net_device *dev,
                                     struct sk_buff *skb,