lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20211222155743.256280-18-miquel.raynal@bootlin.com>
Date:   Wed, 22 Dec 2021 16:57:42 +0100
From:   Miquel Raynal <miquel.raynal@...tlin.com>
To:     "David S. Miller" <davem@...emloft.net>,
        Jakub Kicinski <kuba@...nel.org>, netdev@...r.kernel.org,
        Alexander Aring <alex.aring@...il.com>,
        Stefan Schmidt <stefan@...enfreihafen.org>,
        linux-wpan@...r.kernel.org
Cc:     David Girault <david.girault@...vo.com>,
        Romuald Despres <romuald.despres@...vo.com>,
        Frederic Blain <frederic.blain@...vo.com>,
        Thomas Petazzoni <thomas.petazzoni@...tlin.com>,
        <linux-kernel@...r.kernel.org>,
        Miquel Raynal <miquel.raynal@...tlin.com>
Subject: [net-next 17/18] net: mac802154: Let drivers provide their own beacons implementation

So far only a pure software procedure for sending beacons was possible.
Let's create a couple of driver's hooks in order to allow the device
drivers to provide their own implementation. If not provided, fallback
to the pure software logic.

It is possible for device drivers to only support a specific type of
request and return -EOPNOTSUPP otherwise, this will have the same effect
as not providing any hooks for these specific cases.

Co-developed-by: David Girault <david.girault@...vo.com>
Signed-off-by: David Girault <david.girault@...vo.com>
Signed-off-by: Miquel Raynal <miquel.raynal@...tlin.com>
---
 include/net/mac802154.h    | 13 +++++++++++++
 net/mac802154/driver-ops.h | 33 +++++++++++++++++++++++++++++++++
 net/mac802154/scan.c       | 17 +++++++++++++++++
 net/mac802154/trace.h      | 21 +++++++++++++++++++++
 4 files changed, 84 insertions(+)

diff --git a/include/net/mac802154.h b/include/net/mac802154.h
index 97aefba7bf96..72978fb72a3a 100644
--- a/include/net/mac802154.h
+++ b/include/net/mac802154.h
@@ -214,6 +214,16 @@ enum ieee802154_hw_flags {
  *	  Exits the scan mode and returns to a fully functioning state.
  *	  Should only be provided if ->enter_scan_mode() is populated.
  *	  Returns either zero, or negative errno.
+ *
+ * send_beacons
+ *	  Send beacons at a fixed rate over the current channel.
+ *	  Can be NULL, if the driver doesn't support sending beacons by itself.
+ *	  Returns either zero, or negative errno.
+ *
+ * stop_beacons
+ *	  Stops sending beacons.
+ *	  Should only be provided if ->send_beacons() is populated.
+ *	  Returns either zero, or negative errno.
  */
 struct ieee802154_ops {
 	struct module	*owner;
@@ -243,6 +253,9 @@ struct ieee802154_ops {
 	int		(*enter_scan_mode)(struct ieee802154_hw *hw,
 					   struct cfg802154_scan_request *request);
 	int		(*exit_scan_mode)(struct ieee802154_hw *hw);
+	int		(*send_beacons)(struct ieee802154_hw *hw,
+					struct cfg802154_beacons_request *request);
+	int		(*stop_beacons)(struct ieee802154_hw *hw);
 };
 
 /**
diff --git a/net/mac802154/driver-ops.h b/net/mac802154/driver-ops.h
index 2f5650f7bf91..003e6edee049 100644
--- a/net/mac802154/driver-ops.h
+++ b/net/mac802154/driver-ops.h
@@ -315,4 +315,37 @@ static inline int drv_exit_scan_mode(struct ieee802154_local *local)
 	return ret;
 }
 
+static inline int drv_send_beacons(struct ieee802154_local *local,
+				   struct cfg802154_beacons_request *request)
+{
+	int ret;
+
+	might_sleep();
+
+	if (!local->ops->send_beacons || !local->ops->stop_beacons)
+		return -EOPNOTSUPP;
+
+	trace_802154_drv_send_beacons(local, request);
+	ret = local->ops->send_beacons(&local->hw, request);
+	trace_802154_drv_return_int(local, ret);
+
+	return ret;
+}
+
+static inline int drv_stop_beacons(struct ieee802154_local *local)
+{
+	int ret;
+
+	might_sleep();
+
+	if (!local->ops->send_beacons || !local->ops->stop_beacons)
+		return -EOPNOTSUPP;
+
+	trace_802154_drv_stop_beacons(local);
+	ret = local->ops->stop_beacons(&local->hw);
+	trace_802154_drv_return_int(local, ret);
+
+	return ret;
+}
+
 #endif /* __MAC802154_DRIVER_OPS */
diff --git a/net/mac802154/scan.c b/net/mac802154/scan.c
index b334fa856c00..55af9d16744a 100644
--- a/net/mac802154/scan.c
+++ b/net/mac802154/scan.c
@@ -109,6 +109,7 @@ int mac802154_send_beacons_locked(struct ieee802154_sub_if_data *sdata,
 {
 	struct ieee802154_local *local = sdata->local;
 	unsigned int interval;
+	int ret;
 
 	lockdep_assert_held(&local->beacons_lock);
 
@@ -117,6 +118,14 @@ int mac802154_send_beacons_locked(struct ieee802154_sub_if_data *sdata,
 
 	local->ongoing_beacons_request = true;
 
+	/* Either let the hardware handle the beacons or handle them manually */
+	ret = drv_send_beacons(local, request);
+	if (ret != -EOPNOTSUPP) {
+		if (ret)
+			local->ongoing_beacons_request = false;
+		return ret;
+	}
+
 	interval = mac802154_scan_get_channel_time(request->interval,
 						   request->wpan_phy->symbol_duration);
 
@@ -151,6 +160,8 @@ int mac802154_send_beacons_locked(struct ieee802154_sub_if_data *sdata,
 
 int mac802154_stop_beacons_locked(struct ieee802154_local *local)
 {
+	int ret;
+
 	lockdep_assert_held(&local->beacons_lock);
 
 	if (!local->ongoing_beacons_request)
@@ -159,6 +170,12 @@ int mac802154_stop_beacons_locked(struct ieee802154_local *local)
 	local->ongoing_beacons_request = false;
 	cancel_delayed_work(&local->beacons_work);
 
+	ret = drv_stop_beacons(local);
+	if (ret != -EOPNOTSUPP)
+		return ret;
+
+	cancel_delayed_work(&local->beacons_work);
+
 	return 0;
 }
 
diff --git a/net/mac802154/trace.h b/net/mac802154/trace.h
index 9c0a4f07ced1..b487523f83c3 100644
--- a/net/mac802154/trace.h
+++ b/net/mac802154/trace.h
@@ -292,6 +292,27 @@ DEFINE_EVENT(local_only_evt4, 802154_drv_exit_scan_mode,
 	TP_ARGS(local)
 );
 
+TRACE_EVENT(802154_drv_send_beacons,
+	TP_PROTO(struct ieee802154_local *local,
+		 struct cfg802154_beacons_request *request),
+	TP_ARGS(local, request),
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+		__field(u8, interval)
+	),
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+		__entry->interval = request->interval;
+	),
+	TP_printk(LOCAL_PR_FMT ", send beacons at interval: %d",
+		  LOCAL_PR_ARG, __entry->interval)
+);
+
+DEFINE_EVENT(local_only_evt4, 802154_drv_stop_beacons,
+	TP_PROTO(struct ieee802154_local *local),
+	TP_ARGS(local)
+);
+
 #endif /* !__MAC802154_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */
 
 #undef TRACE_INCLUDE_PATH
-- 
2.27.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ