summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/net/cfg80211.h14
-rw-r--r--include/uapi/linux/nl80211.h5
-rw-r--r--net/wireless/nl80211.c43
-rw-r--r--net/wireless/trace.h21
4 files changed, 83 insertions, 0 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 0d19f34ea7ac..ee173f69c417 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -10574,6 +10574,20 @@ void cfg80211_nan_cluster_joined(struct wireless_dev *wdev,
const u8 *cluster_id, bool new_cluster,
gfp_t gfp);
+/**
+ * cfg80211_nan_ulw_update - Notify user space about ULW update
+ * @wdev: Pointer to the wireless device structure
+ * @ulw: Pointer to the ULW blob data
+ * @ulw_len: Length of the ULW blob in bytes
+ * @gfp: Memory allocation flags
+ *
+ * This function is used by drivers to notify user space when the device's
+ * ULW (Unaligned Schedule) blob has been updated. User space can use this
+ * blob to attach to frames sent to peers.
+ */
+void cfg80211_nan_ulw_update(struct wireless_dev *wdev,
+ const u8 *ulw, size_t ulw_len, gfp_t gfp);
+
#ifdef CONFIG_CFG80211_DEBUGFS
/**
* wiphy_locked_debugfs_read - do a locked read in debugfs
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index cf6f1f6b9e36..947ec7079484 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1402,6 +1402,10 @@
* completely replace the previous one.
* The peer schedule is automatically removed when the NMI station is
* removed.
+ * @NL80211_CMD_NAN_ULW_UPDATE: Notification from the driver to user space
+ * with the updated ULW blob of the device. User space can use this blob
+ * to attach to frames sent to peers. This notification contains
+ * %NL80211_ATTR_NAN_ULW with the ULW blob.
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
@@ -1673,6 +1677,7 @@ enum nl80211_commands {
NL80211_CMD_NAN_SET_PEER_SCHED,
+ NL80211_CMD_NAN_ULW_UPDATE,
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 7f47feaf4422..b5185655e687 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -22893,6 +22893,49 @@ void cfg80211_nan_cluster_joined(struct wireless_dev *wdev,
}
EXPORT_SYMBOL(cfg80211_nan_cluster_joined);
+void cfg80211_nan_ulw_update(struct wireless_dev *wdev,
+ const u8 *ulw, size_t ulw_len, gfp_t gfp)
+{
+ struct wiphy *wiphy = wdev->wiphy;
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
+ struct sk_buff *msg;
+ void *hdr;
+
+ trace_cfg80211_nan_ulw_update(wiphy, wdev, ulw, ulw_len);
+
+ if (!wdev->owner_nlportid)
+ return;
+
+ /* 32 for the wiphy idx, 64 for the wdev id, 100 for padding */
+ msg = nlmsg_new(nla_total_size(sizeof(u32)) +
+ nla_total_size(ulw_len) +
+ nla_total_size(sizeof(u64)) + 100,
+ gfp);
+ if (!msg)
+ return;
+
+ hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NAN_ULW_UPDATE);
+ if (!hdr)
+ goto nla_put_failure;
+
+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+ nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
+ NL80211_ATTR_PAD) ||
+ (ulw && ulw_len &&
+ nla_put(msg, NL80211_ATTR_NAN_ULW, ulw_len, ulw)))
+ goto nla_put_failure;
+
+ genlmsg_end(msg, hdr);
+
+ genlmsg_unicast(wiphy_net(wiphy), msg, wdev->owner_nlportid);
+
+ return;
+
+ nla_put_failure:
+ nlmsg_free(msg);
+}
+EXPORT_SYMBOL(cfg80211_nan_ulw_update);
+
/* initialisation/exit functions */
int __init nl80211_init(void)
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index df639d97cc0c..061bb84f1a48 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -4342,6 +4342,27 @@ TRACE_EVENT(cfg80211_nan_sched_update_done,
TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT " success=%d",
WIPHY_PR_ARG, WDEV_PR_ARG, __entry->success)
);
+
+TRACE_EVENT(cfg80211_nan_ulw_update,
+ TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
+ const u8 *ulw, size_t ulw_len),
+ TP_ARGS(wiphy, wdev, ulw, ulw_len),
+ TP_STRUCT__entry(
+ WIPHY_ENTRY
+ WDEV_ENTRY
+ __dynamic_array(u8, ulw, ulw_len)
+ ),
+ TP_fast_assign(
+ WIPHY_ASSIGN;
+ WDEV_ASSIGN;
+ if (ulw && ulw_len)
+ memcpy(__get_dynamic_array(ulw), ulw, ulw_len);
+ ),
+ TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT " ulw: %s",
+ WIPHY_PR_ARG, WDEV_PR_ARG,
+ __print_array(__get_dynamic_array(ulw),
+ __get_dynamic_array_len(ulw), 1))
+);
#endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */
#undef TRACE_INCLUDE_PATH