[net-next 13/18] net: mac802154: Inform device drivers about the scanning operation

From: Miquel Raynal
Date: Wed Dec 22 2021 - 10:58:30 EST


Let's create a couple of driver hooks in order to tell the device
drivers that a scan is ongoing, if they need to apply a particular
configuration. These hooks are optional.

Co-developed-by: David Girault <david.girault@xxxxxxxxx>
Signed-off-by: David Girault <david.girault@xxxxxxxxx>
Signed-off-by: Miquel Raynal <miquel.raynal@xxxxxxxxxxx>
---
include/net/mac802154.h | 13 +++++++++++++
net/mac802154/driver-ops.h | 33 +++++++++++++++++++++++++++++++++
net/mac802154/scan.c | 7 +++++++
net/mac802154/trace.h | 28 ++++++++++++++++++++++++++++
4 files changed, 81 insertions(+)

diff --git a/include/net/mac802154.h b/include/net/mac802154.h
index 19bfbf591ea1..97aefba7bf96 100644
--- a/include/net/mac802154.h
+++ b/include/net/mac802154.h
@@ -204,6 +204,16 @@ enum ieee802154_hw_flags {
*
* set_promiscuous_mode
* Enables or disable promiscuous mode.
+ *
+ * enter_scan_mode
+ * Enters the scan mode, may then refuse certain operations.
+ * Can be NULL, if the driver has no internal configuration to do.
+ * Returns either zero, or negative errno.
+ *
+ * exit_scan_mode
+ * 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.
*/
struct ieee802154_ops {
struct module *owner;
@@ -230,6 +240,9 @@ struct ieee802154_ops {
s8 retries);
int (*set_promiscuous_mode)(struct ieee802154_hw *hw,
const bool on);
+ int (*enter_scan_mode)(struct ieee802154_hw *hw,
+ struct cfg802154_scan_request *request);
+ int (*exit_scan_mode)(struct ieee802154_hw *hw);
};

/**
diff --git a/net/mac802154/driver-ops.h b/net/mac802154/driver-ops.h
index d23f0db98015..2f5650f7bf91 100644
--- a/net/mac802154/driver-ops.h
+++ b/net/mac802154/driver-ops.h
@@ -282,4 +282,37 @@ drv_set_promiscuous_mode(struct ieee802154_local *local, bool on)
return ret;
}

+static inline int drv_enter_scan_mode(struct ieee802154_local *local,
+ struct cfg802154_scan_request *request)
+{
+ int ret;
+
+ might_sleep();
+
+ if (!local->ops->enter_scan_mode || !local->ops->exit_scan_mode)
+ return 0;
+
+ trace_802154_drv_enter_scan_mode(local, request);
+ ret = local->ops->enter_scan_mode(&local->hw, request);
+ trace_802154_drv_return_int(local, ret);
+
+ return ret;
+}
+
+static inline int drv_exit_scan_mode(struct ieee802154_local *local)
+{
+ int ret;
+
+ might_sleep();
+
+ if (!local->ops->exit_scan_mode)
+ return 0;
+
+ trace_802154_drv_exit_scan_mode(local);
+ ret = local->ops->exit_scan_mode(&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 c5b85eaec319..1382489d4e58 100644
--- a/net/mac802154/scan.c
+++ b/net/mac802154/scan.c
@@ -87,6 +87,8 @@ int mac802154_abort_scan_locked(struct ieee802154_local *local)
if (!local->scanning)
return -ESRCH;

+ drv_exit_scan_mode(local);
+
cancel_delayed_work(&local->scan_work);

return mac802154_end_of_scan(local);
@@ -186,6 +188,11 @@ int mac802154_trigger_scan_locked(struct ieee802154_sub_if_data *sdata,
else
local->scan_addr = cpu_to_le64(get_unaligned_be64(sdata->dev->dev_addr));

+ /* Inform the hardware about the scanning operation starting */
+ ret = drv_enter_scan_mode(local, request);
+ if (ret)
+ return ret;
+
local->scan_channel_idx = -1;
local->scanning = true;

diff --git a/net/mac802154/trace.h b/net/mac802154/trace.h
index df855c33daf2..9c0a4f07ced1 100644
--- a/net/mac802154/trace.h
+++ b/net/mac802154/trace.h
@@ -264,6 +264,34 @@ TRACE_EVENT(802154_drv_set_promiscuous_mode,
BOOL_TO_STR(__entry->on))
);

+TRACE_EVENT(802154_drv_enter_scan_mode,
+ TP_PROTO(struct ieee802154_local *local,
+ struct cfg802154_scan_request *request),
+ TP_ARGS(local, request),
+ TP_STRUCT__entry(
+ LOCAL_ENTRY
+ __field(u8, page)
+ __field(u32, channels)
+ __field(u8, duration)
+ __field(u64, addr)
+ ),
+ TP_fast_assign(
+ LOCAL_ASSIGN;
+ __entry->page = request->page;
+ __entry->channels = request->channels;
+ __entry->duration = request->duration;
+ __entry->addr = local->scan_addr;
+ ),
+ TP_printk(LOCAL_PR_FMT ", scan, page: %d, channels: %x, duration %d, addr: 0x%llx",
+ LOCAL_PR_ARG, __entry->page, __entry->channels,
+ __entry->duration, __entry->addr)
+);
+
+DEFINE_EVENT(local_only_evt4, 802154_drv_exit_scan_mode,
+ TP_PROTO(struct ieee802154_local *local),
+ TP_ARGS(local)
+);
+
#endif /* !__MAC802154_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */

#undef TRACE_INCLUDE_PATH
--
2.27.0