Subject: [PATCH RFC] cfg80211: add new command for reporting wiphy crashes

From: Rafał Miłecki <[email-masked]>
Date: Fri, 20 Sep 2019 15:37:08 +0200

From: Rafał Miłecki <[email-masked]>

Hardware or firmware instability may result in unusable wiphy. In such
cases usually a hardware reset is needed. To allow a full recovery
kernel has to indicate problem to the user space.

This new nl80211 command lets user space known wiphy has crashed and has
been just recovered. When applicable it should result in supplicant or
authenticator reconfiguring all interfaces.

Signed-off-by: Rafał Miłecki <[email-masked]>
---
I'd like to use this new cfg80211_crash_report() in brcmfmac after a
successful recovery from a FullMAC firmware crash.

Later on I'd like to modify hostapd to reconfigure wiphy using a
previously used setup.

I'm OpenWrt developer & user and I got annoyed by my devices not auto
recovering after various failures. There are things I cannot fix (hw
failures or closed fw crashes) but I still expect my devices to get
back to operational state as soon as possible on their own.
---
 include/net/cfg80211.h       |  7 +++++++
 include/uapi/linux/nl80211.h |  2 ++
 net/wireless/nl80211.c       | 29 +++++++++++++++++++++++++++++
 3 files changed, 38 insertions(+)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index ff45c3e1abff..668fa27c88cc 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -7437,6 +7437,13 @@ void cfg80211_pmsr_complete(struct wireless_dev *wdev,
 bool cfg80211_iftype_allowed(struct wiphy *wiphy, enum nl80211_iftype iftype,
 			     bool is_4addr, u8 check_swif);
 
+/**
+ * cfg80211_crash_report - report crashed wiphy that requires a setup
+ *
+ * @wiphy: the wiphy
+ * @gfp: allocation flags
+ */
+void cfg80211_crash_report(struct wiphy *wiphy, gfp_t gfp);
 
 /* Logging, debugging and troubleshooting/diagnostic helpers. */
 
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index beee59c831a7..9e17feb03849 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1325,6 +1325,8 @@ enum nl80211_commands {
 
 	NL80211_CMD_PROBE_MESH_LINK,
 
+	NL80211_CMD_CRASH_REPORT,
+
 	/* 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 d21b1581a665..d29785fb0676 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -16940,6 +16940,35 @@ void cfg80211_update_owe_info_event(struct net_device *netdev,
 }
 EXPORT_SYMBOL(cfg80211_update_owe_info_event);
 
+void cfg80211_crash_report(struct wiphy *wiphy, gfp_t gfp)
+{
+	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
+	struct sk_buff *msg;
+	void *hdr;
+
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
+	if (!msg)
+		return;
+
+	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CRASH_REPORT);
+	if (!hdr)
+		goto nla_put_failure;
+
+	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
+		goto nla_put_failure;
+
+	genlmsg_end(msg, hdr);
+
+	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
+				NL80211_MCGRP_CONFIG, gfp);
+
+	return;
+
+nla_put_failure:
+	nlmsg_free(msg);
+}
+EXPORT_SYMBOL(cfg80211_crash_report);
+
 /* initialisation/exit functions */
 
 int __init nl80211_init(void)
-- 
2.21.0