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