diff options
author | Felix Fietkau <nbd@nbd.name> | 2022-01-28 14:32:21 +0100 |
---|---|---|
committer | Felix Fietkau <nbd@nbd.name> | 2022-02-03 15:16:47 +0100 |
commit | 0b5a547ef0310a95467bbf8cce8c3e28a7ab1cfc (patch) | |
tree | 16f0fd833d3b766bc337d138e19e689e0d8c6cac /package/kernel/mac80211 | |
parent | 03ea0405a6db0e5144d486a682e97a0be47a47c1 (diff) | |
download | upstream-0b5a547ef0310a95467bbf8cce8c3e28a7ab1cfc.tar.gz upstream-0b5a547ef0310a95467bbf8cce8c3e28a7ab1cfc.tar.bz2 upstream-0b5a547ef0310a95467bbf8cce8c3e28a7ab1cfc.zip |
mac80211: backport support for background radar detection
Will be used in an upcoming mt76 update
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'package/kernel/mac80211')
9 files changed, 1627 insertions, 12 deletions
diff --git a/package/kernel/mac80211/patches/subsys/314-cfg80211-implement-APIs-for-dedicated-radar-detectio.patch b/package/kernel/mac80211/patches/subsys/314-cfg80211-implement-APIs-for-dedicated-radar-detectio.patch new file mode 100644 index 0000000000..032bcf7a0c --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/314-cfg80211-implement-APIs-for-dedicated-radar-detectio.patch @@ -0,0 +1,378 @@ +From: Lorenzo Bianconi <lorenzo@kernel.org> +Date: Sat, 23 Oct 2021 11:10:50 +0200 +Subject: [PATCH] cfg80211: implement APIs for dedicated radar detection HW + +If a dedicated (off-channel) radar detection hardware (chain) +is available in the hardware/driver, allow this to be used by +calling the NL80211_CMD_RADAR_DETECT command with a new flag +attribute requesting off-channel radar detection is used. + +Offchannel CAC (channel availability check) avoids the CAC +downtime when switching to a radar channel or when turning on +the AP. + +Drivers advertise support for this using the new feature flag +NL80211_EXT_FEATURE_RADAR_OFFCHAN. + +Tested-by: Evelyn Tsai <evelyn.tsai@mediatek.com> +Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> +Link: https://lore.kernel.org/r/7468e291ef5d05d692c1738d25b8f778d8ea5c3f.1634979655.git.lorenzo@kernel.org +Link: https://lore.kernel.org/r/1e60e60fef00e14401adae81c3d49f3e5f307537.1634979655.git.lorenzo@kernel.org +Link: https://lore.kernel.org/r/85fa50f57fc3adb2934c8d9ca0be30394de6b7e8.1634979655.git.lorenzo@kernel.org +Link: https://lore.kernel.org/r/4b6c08671ad59aae0ac46fc94c02f31b1610eb72.1634979655.git.lorenzo@kernel.org +Link: https://lore.kernel.org/r/241849ccaf2c228873c6f8495bf87b19159ba458.1634979655.git.lorenzo@kernel.org +[remove offchan_mutex, fix cfg80211_stop_offchan_radar_detection(), + remove gfp_t argument, fix documentation, fix tracing] +Signed-off-by: Johannes Berg <johannes.berg@intel.com> +--- + +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -4057,6 +4057,15 @@ struct mgmt_frame_regs { + * @set_sar_specs: Update the SAR (TX power) settings. + * + * @color_change: Initiate a color change. ++ * ++ * @set_radar_offchan: Configure dedicated offchannel chain available for ++ * radar/CAC detection on some hw. This chain can't be used to transmit ++ * or receive frames and it is bounded to a running wdev. ++ * Offchannel radar/CAC detection allows to avoid the CAC downtime ++ * switching to a different channel during CAC detection on the selected ++ * radar channel. ++ * The caller is expected to set chandef pointer to NULL in order to ++ * disable offchannel CAC/radar detection. + */ + struct cfg80211_ops { + int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); +@@ -4387,6 +4396,8 @@ struct cfg80211_ops { + int (*color_change)(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_color_change_settings *params); ++ int (*set_radar_offchan)(struct wiphy *wiphy, ++ struct cfg80211_chan_def *chandef); + }; + + /* +@@ -7608,6 +7619,20 @@ void cfg80211_cac_event(struct net_devic + const struct cfg80211_chan_def *chandef, + enum nl80211_radar_event event, gfp_t gfp); + ++/** ++ * cfg80211_offchan_cac_event - Channel Availability Check (CAC) offchan event ++ * @wiphy: the wiphy ++ * @chandef: chandef for the current channel ++ * @event: type of event ++ * ++ * This function is called when a Channel Availability Check (CAC) is finished, ++ * started or aborted by a offchannel dedicated chain. ++ * ++ * Note that this acquires the wiphy lock. ++ */ ++void cfg80211_offchan_cac_event(struct wiphy *wiphy, ++ const struct cfg80211_chan_def *chandef, ++ enum nl80211_radar_event event); + + /** + * cfg80211_gtk_rekey_notify - notify userspace about driver rekeying +--- a/include/uapi/linux/nl80211.h ++++ b/include/uapi/linux/nl80211.h +@@ -2608,6 +2608,13 @@ enum nl80211_commands { + * Mandatory parameter for the transmitting interface to enable MBSSID. + * Optional for the non-transmitting interfaces. + * ++ * @NL80211_ATTR_RADAR_OFFCHAN: Configure dedicated offchannel chain available for ++ * radar/CAC detection on some hw. This chain can't be used to transmit ++ * or receive frames and it is bounded to a running wdev. ++ * Offchannel radar/CAC detection allows to avoid the CAC downtime ++ * switching on a different channel during CAC detection on the selected ++ * radar channel. ++ * + * @NUM_NL80211_ATTR: total number of nl80211_attrs available + * @NL80211_ATTR_MAX: highest attribute number currently defined + * @__NL80211_ATTR_AFTER_LAST: internal use +@@ -3114,6 +3121,8 @@ enum nl80211_attrs { + NL80211_ATTR_MBSSID_CONFIG, + NL80211_ATTR_MBSSID_ELEMS, + ++ NL80211_ATTR_RADAR_OFFCHAN, ++ + /* add attributes here, update the policy in nl80211.c */ + + __NL80211_ATTR_AFTER_LAST, +@@ -6013,6 +6022,9 @@ enum nl80211_feature_flags { + * @NL80211_EXT_FEATURE_BSS_COLOR: The driver supports BSS color collision + * detection and change announcemnts. + * ++ * @NL80211_EXT_FEATURE_RADAR_OFFCHAN: Device supports offchannel radar/CAC ++ * detection. ++ * + * @NUM_NL80211_EXT_FEATURES: number of extended features. + * @MAX_NL80211_EXT_FEATURES: highest extended feature index. + */ +@@ -6078,6 +6090,7 @@ enum nl80211_ext_feature_index { + NL80211_EXT_FEATURE_SECURE_RTT, + NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE, + NL80211_EXT_FEATURE_BSS_COLOR, ++ NL80211_EXT_FEATURE_RADAR_OFFCHAN, + + /* add new features before the definition below */ + NUM_NL80211_EXT_FEATURES, +--- a/net/wireless/core.c ++++ b/net/wireless/core.c +@@ -552,6 +552,7 @@ use_default_name: + INIT_WORK(&rdev->rfkill_block, cfg80211_rfkill_block_work); + INIT_WORK(&rdev->conn_work, cfg80211_conn_work); + INIT_WORK(&rdev->event_work, cfg80211_event_work); ++ INIT_DELAYED_WORK(&rdev->offchan_cac_work, cfg80211_offchan_cac_work); + + init_waitqueue_head(&rdev->dev_wait); + +@@ -1214,6 +1215,8 @@ void __cfg80211_leave(struct cfg80211_re + + cfg80211_pmsr_wdev_down(wdev); + ++ cfg80211_stop_offchan_radar_detection(wdev); ++ + switch (wdev->iftype) { + case NL80211_IFTYPE_ADHOC: + __cfg80211_leave_ibss(rdev, dev, true); +--- a/net/wireless/core.h ++++ b/net/wireless/core.h +@@ -84,6 +84,10 @@ struct cfg80211_registered_device { + + struct delayed_work dfs_update_channels_wk; + ++ struct wireless_dev *offchan_radar_wdev; ++ struct cfg80211_chan_def offchan_radar_chandef; ++ struct delayed_work offchan_cac_work; ++ + /* netlink port which started critical protocol (0 means not started) */ + u32 crit_proto_nlportid; + +@@ -491,6 +495,15 @@ cfg80211_chandef_dfs_cac_time(struct wip + + void cfg80211_sched_dfs_chan_update(struct cfg80211_registered_device *rdev); + ++int ++cfg80211_start_offchan_radar_detection(struct cfg80211_registered_device *rdev, ++ struct wireless_dev *wdev, ++ struct cfg80211_chan_def *chandef); ++ ++void cfg80211_stop_offchan_radar_detection(struct wireless_dev *wdev); ++ ++void cfg80211_offchan_cac_work(struct work_struct *work); ++ + bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy, + struct ieee80211_channel *chan); + +--- a/net/wireless/mlme.c ++++ b/net/wireless/mlme.c +@@ -970,3 +970,116 @@ void cfg80211_cac_event(struct net_devic + nl80211_radar_notify(rdev, chandef, event, netdev, gfp); + } + EXPORT_SYMBOL(cfg80211_cac_event); ++ ++void cfg80211_offchan_cac_work(struct work_struct *work) ++{ ++ struct delayed_work *delayed_work = to_delayed_work(work); ++ struct cfg80211_registered_device *rdev; ++ ++ rdev = container_of(delayed_work, struct cfg80211_registered_device, ++ offchan_cac_work); ++ cfg80211_offchan_cac_event(&rdev->wiphy, &rdev->offchan_radar_chandef, ++ NL80211_RADAR_CAC_FINISHED); ++} ++ ++static void ++__cfg80211_offchan_cac_event(struct cfg80211_registered_device *rdev, ++ struct wireless_dev *wdev, ++ const struct cfg80211_chan_def *chandef, ++ enum nl80211_radar_event event) ++{ ++ struct wiphy *wiphy = &rdev->wiphy; ++ struct net_device *netdev; ++ ++ lockdep_assert_wiphy(&rdev->wiphy); ++ ++ if (event != NL80211_RADAR_CAC_STARTED && !rdev->offchan_radar_wdev) ++ return; ++ ++ switch (event) { ++ case NL80211_RADAR_CAC_FINISHED: ++ cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_AVAILABLE); ++ memcpy(&rdev->cac_done_chandef, chandef, sizeof(*chandef)); ++ queue_work(cfg80211_wq, &rdev->propagate_cac_done_wk); ++ cfg80211_sched_dfs_chan_update(rdev); ++ wdev = rdev->offchan_radar_wdev; ++ rdev->offchan_radar_wdev = NULL; ++ break; ++ case NL80211_RADAR_CAC_ABORTED: ++ cancel_delayed_work(&rdev->offchan_cac_work); ++ wdev = rdev->offchan_radar_wdev; ++ rdev->offchan_radar_wdev = NULL; ++ break; ++ case NL80211_RADAR_CAC_STARTED: ++ WARN_ON(!wdev); ++ rdev->offchan_radar_wdev = wdev; ++ break; ++ default: ++ return; ++ } ++ ++ netdev = wdev ? wdev->netdev : NULL; ++ nl80211_radar_notify(rdev, chandef, event, netdev, GFP_KERNEL); ++} ++ ++void cfg80211_offchan_cac_event(struct wiphy *wiphy, ++ const struct cfg80211_chan_def *chandef, ++ enum nl80211_radar_event event) ++{ ++ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); ++ ++ wiphy_lock(wiphy); ++ __cfg80211_offchan_cac_event(rdev, NULL, chandef, event); ++ wiphy_unlock(wiphy); ++} ++EXPORT_SYMBOL(cfg80211_offchan_cac_event); ++ ++int ++cfg80211_start_offchan_radar_detection(struct cfg80211_registered_device *rdev, ++ struct wireless_dev *wdev, ++ struct cfg80211_chan_def *chandef) ++{ ++ unsigned int cac_time_ms; ++ int err; ++ ++ lockdep_assert_wiphy(&rdev->wiphy); ++ ++ if (!wiphy_ext_feature_isset(&rdev->wiphy, ++ NL80211_EXT_FEATURE_RADAR_OFFCHAN)) ++ return -EOPNOTSUPP; ++ ++ if (rdev->offchan_radar_wdev) ++ return -EBUSY; ++ ++ err = rdev_set_radar_offchan(rdev, chandef); ++ if (err) ++ return err; ++ ++ cac_time_ms = cfg80211_chandef_dfs_cac_time(&rdev->wiphy, chandef); ++ if (!cac_time_ms) ++ cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS; ++ ++ rdev->offchan_radar_chandef = *chandef; ++ __cfg80211_offchan_cac_event(rdev, wdev, chandef, ++ NL80211_RADAR_CAC_STARTED); ++ queue_delayed_work(cfg80211_wq, &rdev->offchan_cac_work, ++ msecs_to_jiffies(cac_time_ms)); ++ ++ return 0; ++} ++ ++void cfg80211_stop_offchan_radar_detection(struct wireless_dev *wdev) ++{ ++ struct wiphy *wiphy = wdev->wiphy; ++ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); ++ ++ lockdep_assert_wiphy(wiphy); ++ ++ if (wdev != rdev->offchan_radar_wdev) ++ return; ++ ++ rdev_set_radar_offchan(rdev, NULL); ++ ++ __cfg80211_offchan_cac_event(rdev, NULL, NULL, ++ NL80211_RADAR_CAC_ABORTED); ++} +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -793,6 +793,7 @@ static const struct nla_policy nl80211_p + [NL80211_ATTR_MBSSID_CONFIG] = + NLA_POLICY_NESTED(nl80211_mbssid_config_policy), + [NL80211_ATTR_MBSSID_ELEMS] = { .type = NLA_NESTED }, ++ [NL80211_ATTR_RADAR_OFFCHAN] = { .type = NLA_FLAG }, + }; + + /* policy for the key attributes */ +@@ -9269,12 +9270,6 @@ static int nl80211_start_radar_detection + if (err) + return err; + +- if (netif_carrier_ok(dev)) +- return -EBUSY; +- +- if (wdev->cac_started) +- return -EBUSY; +- + err = cfg80211_chandef_dfs_required(wiphy, &chandef, wdev->iftype); + if (err < 0) + return err; +@@ -9285,6 +9280,16 @@ static int nl80211_start_radar_detection + if (!cfg80211_chandef_dfs_usable(wiphy, &chandef)) + return -EINVAL; + ++ if (nla_get_flag(info->attrs[NL80211_ATTR_RADAR_OFFCHAN])) ++ return cfg80211_start_offchan_radar_detection(rdev, wdev, ++ &chandef); ++ ++ if (netif_carrier_ok(dev)) ++ return -EBUSY; ++ ++ if (wdev->cac_started) ++ return -EBUSY; ++ + /* CAC start is offloaded to HW and can't be started manually */ + if (wiphy_ext_feature_isset(wiphy, NL80211_EXT_FEATURE_DFS_OFFLOAD)) + return -EOPNOTSUPP; +--- a/net/wireless/rdev-ops.h ++++ b/net/wireless/rdev-ops.h +@@ -1381,4 +1381,21 @@ static inline int rdev_color_change(stru + return ret; + } + ++static inline int ++rdev_set_radar_offchan(struct cfg80211_registered_device *rdev, ++ struct cfg80211_chan_def *chandef) ++{ ++ struct wiphy *wiphy = &rdev->wiphy; ++ int ret; ++ ++ if (!rdev->ops->set_radar_offchan) ++ return -EOPNOTSUPP; ++ ++ trace_rdev_set_radar_offchan(wiphy, chandef); ++ ret = rdev->ops->set_radar_offchan(wiphy, chandef); ++ trace_rdev_return_int(wiphy, ret); ++ ++ return ret; ++} ++ + #endif /* __CFG80211_RDEV_OPS */ +--- a/net/wireless/trace.h ++++ b/net/wireless/trace.h +@@ -3643,6 +3643,25 @@ TRACE_EVENT(cfg80211_bss_color_notify, + __entry->color_bitmap) + ); + ++TRACE_EVENT(rdev_set_radar_offchan, ++ TP_PROTO(struct wiphy *wiphy, struct cfg80211_chan_def *chandef), ++ ++ TP_ARGS(wiphy, chandef), ++ ++ TP_STRUCT__entry( ++ WIPHY_ENTRY ++ CHAN_DEF_ENTRY ++ ), ++ ++ TP_fast_assign( ++ WIPHY_ASSIGN; ++ CHAN_DEF_ASSIGN(chandef) ++ ), ++ ++ TP_printk(WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT, ++ WIPHY_PR_ARG, CHAN_DEF_PR_ARG) ++); ++ + #endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */ + + #undef TRACE_INCLUDE_PATH diff --git a/package/kernel/mac80211/patches/subsys/315-cfg80211-move-offchan_cac_event-to-a-dedicated-work.patch b/package/kernel/mac80211/patches/subsys/315-cfg80211-move-offchan_cac_event-to-a-dedicated-work.patch new file mode 100644 index 0000000000..e58c3b99be --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/315-cfg80211-move-offchan_cac_event-to-a-dedicated-work.patch @@ -0,0 +1,183 @@ +From: Lorenzo Bianconi <lorenzo@kernel.org> +Date: Wed, 27 Oct 2021 11:03:42 +0200 +Subject: [PATCH] cfg80211: move offchan_cac_event to a dedicated work + +In order to make cfg80211_offchan_cac_abort() (renamed from +cfg80211_offchan_cac_event) callable in other contexts and +without so much locking restrictions, make it trigger a new +work instead of operating directly. + +Do some other renames while at it to clarify. + +Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> +Link: https://lore.kernel.org/r/6145c3d0f30400a568023f67981981d24c7c6133.1635325205.git.lorenzo@kernel.org +[rewrite commit log] +Signed-off-by: Johannes Berg <johannes.berg@intel.com> +--- + +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -7620,19 +7620,13 @@ void cfg80211_cac_event(struct net_devic + enum nl80211_radar_event event, gfp_t gfp); + + /** +- * cfg80211_offchan_cac_event - Channel Availability Check (CAC) offchan event ++ * cfg80211_offchan_cac_abort - Channel Availability Check offchan abort event + * @wiphy: the wiphy +- * @chandef: chandef for the current channel +- * @event: type of event + * +- * This function is called when a Channel Availability Check (CAC) is finished, +- * started or aborted by a offchannel dedicated chain. +- * +- * Note that this acquires the wiphy lock. ++ * This function is called by the driver when a Channel Availability Check ++ * (CAC) is aborted by a offchannel dedicated chain. + */ +-void cfg80211_offchan_cac_event(struct wiphy *wiphy, +- const struct cfg80211_chan_def *chandef, +- enum nl80211_radar_event event); ++void cfg80211_offchan_cac_abort(struct wiphy *wiphy); + + /** + * cfg80211_gtk_rekey_notify - notify userspace about driver rekeying +--- a/net/wireless/core.c ++++ b/net/wireless/core.c +@@ -552,7 +552,9 @@ use_default_name: + INIT_WORK(&rdev->rfkill_block, cfg80211_rfkill_block_work); + INIT_WORK(&rdev->conn_work, cfg80211_conn_work); + INIT_WORK(&rdev->event_work, cfg80211_event_work); +- INIT_DELAYED_WORK(&rdev->offchan_cac_work, cfg80211_offchan_cac_work); ++ INIT_WORK(&rdev->offchan_cac_abort_wk, cfg80211_offchan_cac_abort_wk); ++ INIT_DELAYED_WORK(&rdev->offchan_cac_done_wk, ++ cfg80211_offchan_cac_done_wk); + + init_waitqueue_head(&rdev->dev_wait); + +@@ -1062,11 +1064,13 @@ void wiphy_unregister(struct wiphy *wiph + cancel_work_sync(&rdev->conn_work); + flush_work(&rdev->event_work); + cancel_delayed_work_sync(&rdev->dfs_update_channels_wk); ++ cancel_delayed_work_sync(&rdev->offchan_cac_done_wk); + flush_work(&rdev->destroy_work); + flush_work(&rdev->sched_scan_stop_wk); + flush_work(&rdev->propagate_radar_detect_wk); + flush_work(&rdev->propagate_cac_done_wk); + flush_work(&rdev->mgmt_registrations_update_wk); ++ flush_work(&rdev->offchan_cac_abort_wk); + + #ifdef CONFIG_PM + if (rdev->wiphy.wowlan_config && rdev->ops->set_wakeup) +--- a/net/wireless/core.h ++++ b/net/wireless/core.h +@@ -86,7 +86,8 @@ struct cfg80211_registered_device { + + struct wireless_dev *offchan_radar_wdev; + struct cfg80211_chan_def offchan_radar_chandef; +- struct delayed_work offchan_cac_work; ++ struct delayed_work offchan_cac_done_wk; ++ struct work_struct offchan_cac_abort_wk; + + /* netlink port which started critical protocol (0 means not started) */ + u32 crit_proto_nlportid; +@@ -502,7 +503,9 @@ cfg80211_start_offchan_radar_detection(s + + void cfg80211_stop_offchan_radar_detection(struct wireless_dev *wdev); + +-void cfg80211_offchan_cac_work(struct work_struct *work); ++void cfg80211_offchan_cac_done_wk(struct work_struct *work); ++ ++void cfg80211_offchan_cac_abort_wk(struct work_struct *work); + + bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy, + struct ieee80211_channel *chan); +--- a/net/wireless/mlme.c ++++ b/net/wireless/mlme.c +@@ -971,17 +971,6 @@ void cfg80211_cac_event(struct net_devic + } + EXPORT_SYMBOL(cfg80211_cac_event); + +-void cfg80211_offchan_cac_work(struct work_struct *work) +-{ +- struct delayed_work *delayed_work = to_delayed_work(work); +- struct cfg80211_registered_device *rdev; +- +- rdev = container_of(delayed_work, struct cfg80211_registered_device, +- offchan_cac_work); +- cfg80211_offchan_cac_event(&rdev->wiphy, &rdev->offchan_radar_chandef, +- NL80211_RADAR_CAC_FINISHED); +-} +- + static void + __cfg80211_offchan_cac_event(struct cfg80211_registered_device *rdev, + struct wireless_dev *wdev, +@@ -1006,7 +995,7 @@ __cfg80211_offchan_cac_event(struct cfg8 + rdev->offchan_radar_wdev = NULL; + break; + case NL80211_RADAR_CAC_ABORTED: +- cancel_delayed_work(&rdev->offchan_cac_work); ++ cancel_delayed_work(&rdev->offchan_cac_done_wk); + wdev = rdev->offchan_radar_wdev; + rdev->offchan_radar_wdev = NULL; + break; +@@ -1022,17 +1011,44 @@ __cfg80211_offchan_cac_event(struct cfg8 + nl80211_radar_notify(rdev, chandef, event, netdev, GFP_KERNEL); + } + +-void cfg80211_offchan_cac_event(struct wiphy *wiphy, +- const struct cfg80211_chan_def *chandef, +- enum nl80211_radar_event event) ++static void ++cfg80211_offchan_cac_event(struct cfg80211_registered_device *rdev, ++ const struct cfg80211_chan_def *chandef, ++ enum nl80211_radar_event event) ++{ ++ wiphy_lock(&rdev->wiphy); ++ __cfg80211_offchan_cac_event(rdev, NULL, chandef, event); ++ wiphy_unlock(&rdev->wiphy); ++} ++ ++void cfg80211_offchan_cac_done_wk(struct work_struct *work) ++{ ++ struct delayed_work *delayed_work = to_delayed_work(work); ++ struct cfg80211_registered_device *rdev; ++ ++ rdev = container_of(delayed_work, struct cfg80211_registered_device, ++ offchan_cac_done_wk); ++ cfg80211_offchan_cac_event(rdev, &rdev->offchan_radar_chandef, ++ NL80211_RADAR_CAC_FINISHED); ++} ++ ++void cfg80211_offchan_cac_abort_wk(struct work_struct *work) ++{ ++ struct cfg80211_registered_device *rdev; ++ ++ rdev = container_of(work, struct cfg80211_registered_device, ++ offchan_cac_abort_wk); ++ cfg80211_offchan_cac_event(rdev, &rdev->offchan_radar_chandef, ++ NL80211_RADAR_CAC_ABORTED); ++} ++ ++void cfg80211_offchan_cac_abort(struct wiphy *wiphy) + { + struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); + +- wiphy_lock(wiphy); +- __cfg80211_offchan_cac_event(rdev, NULL, chandef, event); +- wiphy_unlock(wiphy); ++ queue_work(cfg80211_wq, &rdev->offchan_cac_abort_wk); + } +-EXPORT_SYMBOL(cfg80211_offchan_cac_event); ++EXPORT_SYMBOL(cfg80211_offchan_cac_abort); + + int + cfg80211_start_offchan_radar_detection(struct cfg80211_registered_device *rdev, +@@ -1062,7 +1078,7 @@ cfg80211_start_offchan_radar_detection(s + rdev->offchan_radar_chandef = *chandef; + __cfg80211_offchan_cac_event(rdev, wdev, chandef, + NL80211_RADAR_CAC_STARTED); +- queue_delayed_work(cfg80211_wq, &rdev->offchan_cac_work, ++ queue_delayed_work(cfg80211_wq, &rdev->offchan_cac_done_wk, + msecs_to_jiffies(cac_time_ms)); + + return 0; diff --git a/package/kernel/mac80211/patches/subsys/316-cfg80211-fix-possible-NULL-pointer-dereference-in-cf.patch b/package/kernel/mac80211/patches/subsys/316-cfg80211-fix-possible-NULL-pointer-dereference-in-cf.patch new file mode 100644 index 0000000000..362bb885d7 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/316-cfg80211-fix-possible-NULL-pointer-dereference-in-cf.patch @@ -0,0 +1,99 @@ +From: Lorenzo Bianconi <lorenzo@kernel.org> +Date: Wed, 3 Nov 2021 18:02:35 +0100 +Subject: [PATCH] cfg80211: fix possible NULL pointer dereference in + cfg80211_stop_offchan_radar_detection + +Fix the following NULL pointer dereference in +cfg80211_stop_offchan_radar_detection routine that occurs when hostapd +is stopped during the CAC on offchannel chain: + +Sat Jan 1 0[ 779.567851] ESR = 0x96000005 +0:12:50 2000 dae[ 779.572346] EC = 0x25: DABT (current EL), IL = 32 bits +mon.debug hostap[ 779.578984] SET = 0, FnV = 0 +d: hostapd_inter[ 779.583445] EA = 0, S1PTW = 0 +face_deinit_free[ 779.587936] Data abort info: +: num_bss=1 conf[ 779.592224] ISV = 0, ISS = 0x00000005 +->num_bss=1 +Sat[ 779.597403] CM = 0, WnR = 0 + Jan 1 00:12:50[ 779.601749] user pgtable: 4k pages, 39-bit VAs, pgdp=00000000418b2000 + 2000 daemon.deb[ 779.609601] [0000000000000000] pgd=0000000000000000, p4d=0000000000000000, pud=0000000000000000 +ug hostapd: host[ 779.619657] Internal error: Oops: 96000005 [#1] SMP +[ 779.770810] CPU: 0 PID: 2202 Comm: hostapd Not tainted 5.10.75 #0 +[ 779.776892] Hardware name: MediaTek MT7622 RFB1 board (DT) +[ 779.782370] pstate: 80000005 (Nzcv daif -PAN -UAO -TCO BTYPE=--) +[ 779.788384] pc : cfg80211_chandef_valid+0x10/0x490 [cfg80211] +[ 779.794128] lr : cfg80211_check_station_change+0x3190/0x3950 [cfg80211] +[ 779.800731] sp : ffffffc01204b7e0 +[ 779.804036] x29: ffffffc01204b7e0 x28: ffffff80039bdc00 +[ 779.809340] x27: 0000000000000000 x26: ffffffc008cb3050 +[ 779.814644] x25: 0000000000000000 x24: 0000000000000002 +[ 779.819948] x23: ffffff8002630000 x22: ffffff8003e748d0 +[ 779.825252] x21: 0000000000000cc0 x20: ffffff8003da4a00 +[ 779.830556] x19: 0000000000000000 x18: ffffff8001bf7ce0 +[ 779.835860] x17: 00000000ffffffff x16: 0000000000000000 +[ 779.841164] x15: 0000000040d59200 x14: 00000000000019c0 +[ 779.846467] x13: 00000000000001c8 x12: 000636b9e9dab1c6 +[ 779.851771] x11: 0000000000000141 x10: 0000000000000820 +[ 779.857076] x9 : 0000000000000000 x8 : ffffff8003d7d038 +[ 779.862380] x7 : 0000000000000000 x6 : ffffff8003d7d038 +[ 779.867683] x5 : 0000000000000e90 x4 : 0000000000000038 +[ 779.872987] x3 : 0000000000000002 x2 : 0000000000000004 +[ 779.878291] x1 : 0000000000000000 x0 : 0000000000000000 +[ 779.883594] Call trace: +[ 779.886039] cfg80211_chandef_valid+0x10/0x490 [cfg80211] +[ 779.891434] cfg80211_check_station_change+0x3190/0x3950 [cfg80211] +[ 779.897697] nl80211_radar_notify+0x138/0x19c [cfg80211] +[ 779.903005] cfg80211_stop_offchan_radar_detection+0x7c/0x8c [cfg80211] +[ 779.909616] __cfg80211_leave+0x2c/0x190 [cfg80211] +[ 779.914490] cfg80211_register_netdevice+0x1c0/0x6d0 [cfg80211] +[ 779.920404] raw_notifier_call_chain+0x50/0x70 +[ 779.924841] call_netdevice_notifiers_info+0x54/0xa0 +[ 779.929796] __dev_close_many+0x40/0x100 +[ 779.933712] __dev_change_flags+0x98/0x190 +[ 779.937800] dev_change_flags+0x20/0x60 +[ 779.941628] devinet_ioctl+0x534/0x6d0 +[ 779.945370] inet_ioctl+0x1bc/0x230 +[ 779.948849] sock_do_ioctl+0x44/0x200 +[ 779.952502] sock_ioctl+0x268/0x4c0 +[ 779.955985] __arm64_sys_ioctl+0xac/0xd0 +[ 779.959900] el0_svc_common.constprop.0+0x60/0x110 +[ 779.964682] do_el0_svc+0x1c/0x24 +[ 779.967990] el0_svc+0x10/0x1c +[ 779.971036] el0_sync_handler+0x9c/0x120 +[ 779.974950] el0_sync+0x148/0x180 +[ 779.978259] Code: a9bc7bfd 910003fd a90153f3 aa0003f3 (f9400000) +[ 779.984344] ---[ end trace 0e67b4f5d6cdeec7 ]--- +[ 779.996400] Kernel panic - not syncing: Oops: Fatal exception +[ 780.002139] SMP: stopping secondary CPUs +[ 780.006057] Kernel Offset: disabled +[ 780.009537] CPU features: 0x0000002,04002004 +[ 780.013796] Memory Limit: none + +Fixes: b8f5facf286b ("cfg80211: implement APIs for dedicated radar detection HW") +Reported-by: Evelyn Tsai <evelyn.tsai@mediatek.com> +Tested-by: Evelyn Tsai <evelyn.tsai@mediatek.com> +Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> +Link: https://lore.kernel.org/r/c2e34c065bf8839c5ffa45498ae154021a72a520.1635958796.git.lorenzo@kernel.org +Signed-off-by: Johannes Berg <johannes.berg@intel.com> +--- + +--- a/net/wireless/mlme.c ++++ b/net/wireless/mlme.c +@@ -982,6 +982,9 @@ __cfg80211_offchan_cac_event(struct cfg8 + + lockdep_assert_wiphy(&rdev->wiphy); + ++ if (!cfg80211_chandef_valid(chandef)) ++ return; ++ + if (event != NL80211_RADAR_CAC_STARTED && !rdev->offchan_radar_wdev) + return; + +@@ -1096,6 +1099,6 @@ void cfg80211_stop_offchan_radar_detecti + + rdev_set_radar_offchan(rdev, NULL); + +- __cfg80211_offchan_cac_event(rdev, NULL, NULL, ++ __cfg80211_offchan_cac_event(rdev, wdev, &rdev->offchan_radar_chandef, + NL80211_RADAR_CAC_ABORTED); + } diff --git a/package/kernel/mac80211/patches/subsys/317-cfg80211-schedule-offchan_cac_abort_wk-in-cfg80211_r.patch b/package/kernel/mac80211/patches/subsys/317-cfg80211-schedule-offchan_cac_abort_wk-in-cfg80211_r.patch new file mode 100644 index 0000000000..df7afefb34 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/317-cfg80211-schedule-offchan_cac_abort_wk-in-cfg80211_r.patch @@ -0,0 +1,136 @@ +From: Lorenzo Bianconi <lorenzo@kernel.org> +Date: Tue, 16 Nov 2021 12:41:52 +0100 +Subject: [PATCH] cfg80211: schedule offchan_cac_abort_wk in + cfg80211_radar_event + +If necessary schedule offchan_cac_abort_wk work in cfg80211_radar_event +routine adding offchan parameter to cfg80211_radar_event signature. +Rename cfg80211_radar_event in __cfg80211_radar_event and introduce +the two following inline helpers: +- cfg80211_radar_event +- cfg80211_offchan_radar_event +Doing so the drv will not need to run cfg80211_offchan_cac_abort() after +radar detection on the offchannel chain. + +Tested-by: Owen Peng <owen.peng@mediatek.com> +Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> +Link: https://lore.kernel.org/r/3ff583e021e3343a3ced54a7b09b5e184d1880dc.1637062727.git.lorenzo@kernel.org +Signed-off-by: Johannes Berg <johannes.berg@intel.com> +--- + +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -7580,15 +7580,33 @@ void cfg80211_cqm_txe_notify(struct net_ + void cfg80211_cqm_beacon_loss_notify(struct net_device *dev, gfp_t gfp); + + /** +- * cfg80211_radar_event - radar detection event ++ * __cfg80211_radar_event - radar detection event + * @wiphy: the wiphy + * @chandef: chandef for the current channel ++ * @offchan: the radar has been detected on the offchannel chain + * @gfp: context flags + * + * This function is called when a radar is detected on the current chanenl. + */ +-void cfg80211_radar_event(struct wiphy *wiphy, +- struct cfg80211_chan_def *chandef, gfp_t gfp); ++void __cfg80211_radar_event(struct wiphy *wiphy, ++ struct cfg80211_chan_def *chandef, ++ bool offchan, gfp_t gfp); ++ ++static inline void ++cfg80211_radar_event(struct wiphy *wiphy, ++ struct cfg80211_chan_def *chandef, ++ gfp_t gfp) ++{ ++ __cfg80211_radar_event(wiphy, chandef, false, gfp); ++} ++ ++static inline void ++cfg80211_offchan_radar_event(struct wiphy *wiphy, ++ struct cfg80211_chan_def *chandef, ++ gfp_t gfp) ++{ ++ __cfg80211_radar_event(wiphy, chandef, true, gfp); ++} + + /** + * cfg80211_sta_opmode_change_notify - STA's ht/vht operation mode change event +--- a/net/wireless/mlme.c ++++ b/net/wireless/mlme.c +@@ -905,13 +905,13 @@ void cfg80211_dfs_channels_update_work(s + } + + +-void cfg80211_radar_event(struct wiphy *wiphy, +- struct cfg80211_chan_def *chandef, +- gfp_t gfp) ++void __cfg80211_radar_event(struct wiphy *wiphy, ++ struct cfg80211_chan_def *chandef, ++ bool offchan, gfp_t gfp) + { + struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); + +- trace_cfg80211_radar_event(wiphy, chandef); ++ trace_cfg80211_radar_event(wiphy, chandef, offchan); + + /* only set the chandef supplied channel to unavailable, in + * case the radar is detected on only one of multiple channels +@@ -919,6 +919,9 @@ void cfg80211_radar_event(struct wiphy * + */ + cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_UNAVAILABLE); + ++ if (offchan) ++ queue_work(cfg80211_wq, &rdev->offchan_cac_abort_wk); ++ + cfg80211_sched_dfs_chan_update(rdev); + + nl80211_radar_notify(rdev, chandef, NL80211_RADAR_DETECTED, NULL, gfp); +@@ -926,7 +929,7 @@ void cfg80211_radar_event(struct wiphy * + memcpy(&rdev->radar_chandef, chandef, sizeof(struct cfg80211_chan_def)); + queue_work(cfg80211_wq, &rdev->propagate_radar_detect_wk); + } +-EXPORT_SYMBOL(cfg80211_radar_event); ++EXPORT_SYMBOL(__cfg80211_radar_event); + + void cfg80211_cac_event(struct net_device *netdev, + const struct cfg80211_chan_def *chandef, +@@ -998,7 +1001,8 @@ __cfg80211_offchan_cac_event(struct cfg8 + rdev->offchan_radar_wdev = NULL; + break; + case NL80211_RADAR_CAC_ABORTED: +- cancel_delayed_work(&rdev->offchan_cac_done_wk); ++ if (!cancel_delayed_work(&rdev->offchan_cac_done_wk)) ++ return; + wdev = rdev->offchan_radar_wdev; + rdev->offchan_radar_wdev = NULL; + break; +--- a/net/wireless/trace.h ++++ b/net/wireless/trace.h +@@ -3022,18 +3022,21 @@ TRACE_EVENT(cfg80211_ch_switch_started_n + ); + + TRACE_EVENT(cfg80211_radar_event, +- TP_PROTO(struct wiphy *wiphy, struct cfg80211_chan_def *chandef), +- TP_ARGS(wiphy, chandef), ++ TP_PROTO(struct wiphy *wiphy, struct cfg80211_chan_def *chandef, ++ bool offchan), ++ TP_ARGS(wiphy, chandef, offchan), + TP_STRUCT__entry( + WIPHY_ENTRY + CHAN_DEF_ENTRY ++ __field(bool, offchan) + ), + TP_fast_assign( + WIPHY_ASSIGN; + CHAN_DEF_ASSIGN(chandef); ++ __entry->offchan = offchan; + ), +- TP_printk(WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT, +- WIPHY_PR_ARG, CHAN_DEF_PR_ARG) ++ TP_printk(WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT ", offchan %d", ++ WIPHY_PR_ARG, CHAN_DEF_PR_ARG, __entry->offchan) + ); + + TRACE_EVENT(cfg80211_cac_event, diff --git a/package/kernel/mac80211/patches/subsys/318-cfg80211-allow-continuous-radar-monitoring-on-offcha.patch b/package/kernel/mac80211/patches/subsys/318-cfg80211-allow-continuous-radar-monitoring-on-offcha.patch new file mode 100644 index 0000000000..ae97947fab --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/318-cfg80211-allow-continuous-radar-monitoring-on-offcha.patch @@ -0,0 +1,220 @@ +From: Lorenzo Bianconi <lorenzo@kernel.org> +Date: Tue, 16 Nov 2021 15:03:36 +0100 +Subject: [PATCH] cfg80211: allow continuous radar monitoring on offchannel + chain + +Allow continuous radar detection on the offchannel chain in order +to switch to the monitored channel whenever the underlying driver +reports a radar pattern on the main channel. + +Tested-by: Owen Peng <owen.peng@mediatek.com> +Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> +Link: https://lore.kernel.org/r/d46217310a49b14ff0e9c002f0a6e0547d70fd2c.1637071350.git.lorenzo@kernel.org +Signed-off-by: Johannes Berg <johannes.berg@intel.com> +--- + +--- a/net/wireless/chan.c ++++ b/net/wireless/chan.c +@@ -712,6 +712,19 @@ static bool cfg80211_is_wiphy_oper_chan( + return false; + } + ++static bool ++cfg80211_offchan_chain_is_active(struct cfg80211_registered_device *rdev, ++ struct ieee80211_channel *channel) ++{ ++ if (!rdev->offchan_radar_wdev) ++ return false; ++ ++ if (!cfg80211_chandef_valid(&rdev->offchan_radar_chandef)) ++ return false; ++ ++ return cfg80211_is_sub_chan(&rdev->offchan_radar_chandef, channel); ++} ++ + bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy, + struct ieee80211_channel *chan) + { +@@ -728,6 +741,9 @@ bool cfg80211_any_wiphy_oper_chan(struct + + if (cfg80211_is_wiphy_oper_chan(&rdev->wiphy, chan)) + return true; ++ ++ if (cfg80211_offchan_chain_is_active(rdev, chan)) ++ return true; + } + + return false; +--- a/net/wireless/mlme.c ++++ b/net/wireless/mlme.c +@@ -988,7 +988,7 @@ __cfg80211_offchan_cac_event(struct cfg8 + if (!cfg80211_chandef_valid(chandef)) + return; + +- if (event != NL80211_RADAR_CAC_STARTED && !rdev->offchan_radar_wdev) ++ if (!rdev->offchan_radar_wdev) + return; + + switch (event) { +@@ -998,17 +998,13 @@ __cfg80211_offchan_cac_event(struct cfg8 + queue_work(cfg80211_wq, &rdev->propagate_cac_done_wk); + cfg80211_sched_dfs_chan_update(rdev); + wdev = rdev->offchan_radar_wdev; +- rdev->offchan_radar_wdev = NULL; + break; + case NL80211_RADAR_CAC_ABORTED: + if (!cancel_delayed_work(&rdev->offchan_cac_done_wk)) + return; + wdev = rdev->offchan_radar_wdev; +- rdev->offchan_radar_wdev = NULL; + break; + case NL80211_RADAR_CAC_STARTED: +- WARN_ON(!wdev); +- rdev->offchan_radar_wdev = wdev; + break; + default: + return; +@@ -1024,7 +1020,8 @@ cfg80211_offchan_cac_event(struct cfg802 + enum nl80211_radar_event event) + { + wiphy_lock(&rdev->wiphy); +- __cfg80211_offchan_cac_event(rdev, NULL, chandef, event); ++ __cfg80211_offchan_cac_event(rdev, rdev->offchan_radar_wdev, ++ chandef, event); + wiphy_unlock(&rdev->wiphy); + } + +@@ -1071,7 +1068,13 @@ cfg80211_start_offchan_radar_detection(s + NL80211_EXT_FEATURE_RADAR_OFFCHAN)) + return -EOPNOTSUPP; + +- if (rdev->offchan_radar_wdev) ++ /* Offchannel chain already locked by another wdev */ ++ if (rdev->offchan_radar_wdev && rdev->offchan_radar_wdev != wdev) ++ return -EBUSY; ++ ++ /* CAC already in progress on the offchannel chain */ ++ if (rdev->offchan_radar_wdev == wdev && ++ delayed_work_pending(&rdev->offchan_cac_done_wk)) + return -EBUSY; + + err = rdev_set_radar_offchan(rdev, chandef); +@@ -1083,6 +1086,8 @@ cfg80211_start_offchan_radar_detection(s + cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS; + + rdev->offchan_radar_chandef = *chandef; ++ rdev->offchan_radar_wdev = wdev; /* Get offchain ownership */ ++ + __cfg80211_offchan_cac_event(rdev, wdev, chandef, + NL80211_RADAR_CAC_STARTED); + queue_delayed_work(cfg80211_wq, &rdev->offchan_cac_done_wk, +@@ -1102,6 +1107,7 @@ void cfg80211_stop_offchan_radar_detecti + return; + + rdev_set_radar_offchan(rdev, NULL); ++ rdev->offchan_radar_wdev = NULL; /* Release offchain ownership */ + + __cfg80211_offchan_cac_event(rdev, wdev, &rdev->offchan_radar_chandef, + NL80211_RADAR_CAC_ABORTED); +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -9260,42 +9260,60 @@ static int nl80211_start_radar_detection + struct cfg80211_chan_def chandef; + enum nl80211_dfs_regions dfs_region; + unsigned int cac_time_ms; +- int err; ++ int err = -EINVAL; ++ ++ flush_delayed_work(&rdev->dfs_update_channels_wk); ++ ++ wiphy_lock(wiphy); + + dfs_region = reg_get_dfs_region(wiphy); + if (dfs_region == NL80211_DFS_UNSET) +- return -EINVAL; ++ goto unlock; + + err = nl80211_parse_chandef(rdev, info, &chandef); + if (err) +- return err; ++ goto unlock; + + err = cfg80211_chandef_dfs_required(wiphy, &chandef, wdev->iftype); + if (err < 0) +- return err; ++ goto unlock; + +- if (err == 0) +- return -EINVAL; ++ if (err == 0) { ++ err = -EINVAL; ++ goto unlock; ++ } + +- if (!cfg80211_chandef_dfs_usable(wiphy, &chandef)) +- return -EINVAL; ++ if (!cfg80211_chandef_dfs_usable(wiphy, &chandef)) { ++ err = -EINVAL; ++ goto unlock; ++ } + +- if (nla_get_flag(info->attrs[NL80211_ATTR_RADAR_OFFCHAN])) +- return cfg80211_start_offchan_radar_detection(rdev, wdev, +- &chandef); ++ if (nla_get_flag(info->attrs[NL80211_ATTR_RADAR_OFFCHAN])) { ++ err = cfg80211_start_offchan_radar_detection(rdev, wdev, ++ &chandef); ++ goto unlock; ++ } + +- if (netif_carrier_ok(dev)) +- return -EBUSY; ++ if (netif_carrier_ok(dev)) { ++ err = -EBUSY; ++ goto unlock; ++ } + +- if (wdev->cac_started) +- return -EBUSY; ++ if (wdev->cac_started) { ++ err = -EBUSY; ++ goto unlock; ++ } + + /* CAC start is offloaded to HW and can't be started manually */ +- if (wiphy_ext_feature_isset(wiphy, NL80211_EXT_FEATURE_DFS_OFFLOAD)) +- return -EOPNOTSUPP; ++ if (wiphy_ext_feature_isset(wiphy, NL80211_EXT_FEATURE_DFS_OFFLOAD)) { ++ err = -EOPNOTSUPP; ++ goto unlock; ++ } + +- if (!rdev->ops->start_radar_detection) +- return -EOPNOTSUPP; ++ if (!rdev->ops->start_radar_detection) { ++ err = -EOPNOTSUPP; ++ goto unlock; ++ } + + cac_time_ms = cfg80211_chandef_dfs_cac_time(&rdev->wiphy, &chandef); + if (WARN_ON(!cac_time_ms)) +@@ -9308,6 +9326,9 @@ static int nl80211_start_radar_detection + wdev->cac_start_time = jiffies; + wdev->cac_time_ms = cac_time_ms; + } ++unlock: ++ wiphy_unlock(wiphy); ++ + return err; + } + +@@ -15926,7 +15947,8 @@ static const struct genl_small_ops nl802 + .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, + .doit = nl80211_start_radar_detection, + .flags = GENL_UNS_ADMIN_PERM, +- .internal_flags = NL80211_FLAG_NEED_NETDEV_UP, ++ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | ++ NL80211_FLAG_NO_WIPHY_MTX, + }, + { + .cmd = NL80211_CMD_GET_PROTOCOL_FEATURES, diff --git a/package/kernel/mac80211/patches/subsys/319-mac80211-introduce-set_radar_offchan-callback.patch b/package/kernel/mac80211/patches/subsys/319-mac80211-introduce-set_radar_offchan-callback.patch new file mode 100644 index 0000000000..127b86e76d --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/319-mac80211-introduce-set_radar_offchan-callback.patch @@ -0,0 +1,67 @@ +From: Lorenzo Bianconi <lorenzo@kernel.org> +Date: Sat, 23 Oct 2021 11:10:51 +0200 +Subject: [PATCH] mac80211: introduce set_radar_offchan callback + +Similar to cfg80211, introduce set_radar_offchan callback in mac80211_ops +in order to configure a dedicated offchannel chain available on some hw +(e.g. mt7915) to perform offchannel CAC detection and avoid tx/rx downtime. + +Tested-by: Evelyn Tsai <evelyn.tsai@mediatek.com> +Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> +Link: https://lore.kernel.org/r/201110606d4f3a7dfdf31440e351f2e2c375d4f0.1634979655.git.lorenzo@kernel.org +Signed-off-by: Johannes Berg <johannes.berg@intel.com> +--- + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -3937,6 +3937,14 @@ struct ieee80211_prep_tx_info { + * twt structure. + * @twt_teardown_request: Update the hw with TWT teardown request received + * from the peer. ++ * @set_radar_offchan: Configure dedicated offchannel chain available for ++ * radar/CAC detection on some hw. This chain can't be used to transmit ++ * or receive frames and it is bounded to a running wdev. ++ * Offchannel radar/CAC detection allows to avoid the CAC downtime ++ * switching to a different channel during CAC detection on the selected ++ * radar channel. ++ * The caller is expected to set chandef pointer to NULL in order to ++ * disable offchannel CAC/radar detection. + * @net_fill_forward_path: Called from .ndo_fill_forward_path in order to + * resolve a path for hardware flow offloading + */ +@@ -4267,6 +4275,8 @@ struct ieee80211_ops { + struct ieee80211_twt_setup *twt); + void (*twt_teardown_request)(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, u8 flowid); ++ int (*set_radar_offchan)(struct ieee80211_hw *hw, ++ struct cfg80211_chan_def *chandef); + int (*net_fill_forward_path)(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -4344,6 +4344,18 @@ out: + return err; + } + ++static int ++ieee80211_set_radar_offchan(struct wiphy *wiphy, ++ struct cfg80211_chan_def *chandef) ++{ ++ struct ieee80211_local *local = wiphy_priv(wiphy); ++ ++ if (!local->ops->set_radar_offchan) ++ return -EOPNOTSUPP; ++ ++ return local->ops->set_radar_offchan(&local->hw, chandef); ++} ++ + const struct cfg80211_ops mac80211_config_ops = { + .add_virtual_intf = ieee80211_add_iface, + .del_virtual_intf = ieee80211_del_iface, +@@ -4448,4 +4460,5 @@ const struct cfg80211_ops mac80211_confi + .reset_tid_config = ieee80211_reset_tid_config, + .set_sar_specs = ieee80211_set_sar_specs, + .color_change = ieee80211_color_change, ++ .set_radar_offchan = ieee80211_set_radar_offchan, + }; diff --git a/package/kernel/mac80211/patches/subsys/320-cfg80211-rename-offchannel_chain-structs-to-backgrou.patch b/package/kernel/mac80211/patches/subsys/320-cfg80211-rename-offchannel_chain-structs-to-backgrou.patch new file mode 100644 index 0000000000..ce4611b145 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/320-cfg80211-rename-offchannel_chain-structs-to-backgrou.patch @@ -0,0 +1,532 @@ +From: Lorenzo Bianconi <lorenzo@kernel.org> +Date: Mon, 29 Nov 2021 14:11:24 +0100 +Subject: [PATCH] cfg80211: rename offchannel_chain structs to background_chain + to avoid confusion with ETSI standard + +ETSI standard defines "Offchannel CAC" as: +"Off-Channel CAC is performed by a number of non-continuous checks +spread over a period in time. This period, which is required to +determine the presence of radar signals, is defined as the Off-Channel +CAC Time.. +Minimum Off-Channel CAC Time 6 minutes and Maximum Off-Channel CAC Time +4 hours..". +mac80211 implementation refers to a dedicated hw chain used for continuous +radar monitoring. Rename offchannel_* references to background_* in +order to avoid confusion with ETSI standard. + +Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> +Link: https://lore.kernel.org/r/4204cc1d648d76b44557981713231e030a3bd991.1638190762.git.lorenzo@kernel.org +Signed-off-by: Johannes Berg <johannes.berg@intel.com> +--- + +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -4058,14 +4058,14 @@ struct mgmt_frame_regs { + * + * @color_change: Initiate a color change. + * +- * @set_radar_offchan: Configure dedicated offchannel chain available for ++ * @set_radar_background: Configure dedicated offchannel chain available for + * radar/CAC detection on some hw. This chain can't be used to transmit + * or receive frames and it is bounded to a running wdev. +- * Offchannel radar/CAC detection allows to avoid the CAC downtime ++ * Background radar/CAC detection allows to avoid the CAC downtime + * switching to a different channel during CAC detection on the selected + * radar channel. + * The caller is expected to set chandef pointer to NULL in order to +- * disable offchannel CAC/radar detection. ++ * disable background CAC/radar detection. + */ + struct cfg80211_ops { + int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); +@@ -4396,8 +4396,8 @@ struct cfg80211_ops { + int (*color_change)(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_color_change_settings *params); +- int (*set_radar_offchan)(struct wiphy *wiphy, +- struct cfg80211_chan_def *chandef); ++ int (*set_radar_background)(struct wiphy *wiphy, ++ struct cfg80211_chan_def *chandef); + }; + + /* +@@ -7601,9 +7601,9 @@ cfg80211_radar_event(struct wiphy *wiphy + } + + static inline void +-cfg80211_offchan_radar_event(struct wiphy *wiphy, +- struct cfg80211_chan_def *chandef, +- gfp_t gfp) ++cfg80211_background_radar_event(struct wiphy *wiphy, ++ struct cfg80211_chan_def *chandef, ++ gfp_t gfp) + { + __cfg80211_radar_event(wiphy, chandef, true, gfp); + } +@@ -7638,13 +7638,13 @@ void cfg80211_cac_event(struct net_devic + enum nl80211_radar_event event, gfp_t gfp); + + /** +- * cfg80211_offchan_cac_abort - Channel Availability Check offchan abort event ++ * cfg80211_background_cac_abort - Channel Availability Check offchan abort event + * @wiphy: the wiphy + * + * This function is called by the driver when a Channel Availability Check + * (CAC) is aborted by a offchannel dedicated chain. + */ +-void cfg80211_offchan_cac_abort(struct wiphy *wiphy); ++void cfg80211_background_cac_abort(struct wiphy *wiphy); + + /** + * cfg80211_gtk_rekey_notify - notify userspace about driver rekeying +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -3937,14 +3937,14 @@ struct ieee80211_prep_tx_info { + * twt structure. + * @twt_teardown_request: Update the hw with TWT teardown request received + * from the peer. +- * @set_radar_offchan: Configure dedicated offchannel chain available for ++ * @set_radar_background: Configure dedicated offchannel chain available for + * radar/CAC detection on some hw. This chain can't be used to transmit + * or receive frames and it is bounded to a running wdev. +- * Offchannel radar/CAC detection allows to avoid the CAC downtime ++ * Background radar/CAC detection allows to avoid the CAC downtime + * switching to a different channel during CAC detection on the selected + * radar channel. + * The caller is expected to set chandef pointer to NULL in order to +- * disable offchannel CAC/radar detection. ++ * disable background CAC/radar detection. + * @net_fill_forward_path: Called from .ndo_fill_forward_path in order to + * resolve a path for hardware flow offloading + */ +@@ -4275,8 +4275,8 @@ struct ieee80211_ops { + struct ieee80211_twt_setup *twt); + void (*twt_teardown_request)(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, u8 flowid); +- int (*set_radar_offchan)(struct ieee80211_hw *hw, +- struct cfg80211_chan_def *chandef); ++ int (*set_radar_background)(struct ieee80211_hw *hw, ++ struct cfg80211_chan_def *chandef); + int (*net_fill_forward_path)(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, +--- a/include/uapi/linux/nl80211.h ++++ b/include/uapi/linux/nl80211.h +@@ -2608,10 +2608,10 @@ enum nl80211_commands { + * Mandatory parameter for the transmitting interface to enable MBSSID. + * Optional for the non-transmitting interfaces. + * +- * @NL80211_ATTR_RADAR_OFFCHAN: Configure dedicated offchannel chain available for +- * radar/CAC detection on some hw. This chain can't be used to transmit +- * or receive frames and it is bounded to a running wdev. +- * Offchannel radar/CAC detection allows to avoid the CAC downtime ++ * @NL80211_ATTR_RADAR_BACKGROUND: Configure dedicated offchannel chain ++ * available for radar/CAC detection on some hw. This chain can't be used ++ * to transmit or receive frames and it is bounded to a running wdev. ++ * Background radar/CAC detection allows to avoid the CAC downtime + * switching on a different channel during CAC detection on the selected + * radar channel. + * +@@ -3121,7 +3121,7 @@ enum nl80211_attrs { + NL80211_ATTR_MBSSID_CONFIG, + NL80211_ATTR_MBSSID_ELEMS, + +- NL80211_ATTR_RADAR_OFFCHAN, ++ NL80211_ATTR_RADAR_BACKGROUND, + + /* add attributes here, update the policy in nl80211.c */ + +@@ -6022,7 +6022,7 @@ enum nl80211_feature_flags { + * @NL80211_EXT_FEATURE_BSS_COLOR: The driver supports BSS color collision + * detection and change announcemnts. + * +- * @NL80211_EXT_FEATURE_RADAR_OFFCHAN: Device supports offchannel radar/CAC ++ * @NL80211_EXT_FEATURE_RADAR_BACKGROUND: Device supports background radar/CAC + * detection. + * + * @NUM_NL80211_EXT_FEATURES: number of extended features. +@@ -6090,7 +6090,7 @@ enum nl80211_ext_feature_index { + NL80211_EXT_FEATURE_SECURE_RTT, + NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE, + NL80211_EXT_FEATURE_BSS_COLOR, +- NL80211_EXT_FEATURE_RADAR_OFFCHAN, ++ NL80211_EXT_FEATURE_RADAR_BACKGROUND, + + /* add new features before the definition below */ + NUM_NL80211_EXT_FEATURES, +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -4345,15 +4345,15 @@ out: + } + + static int +-ieee80211_set_radar_offchan(struct wiphy *wiphy, +- struct cfg80211_chan_def *chandef) ++ieee80211_set_radar_background(struct wiphy *wiphy, ++ struct cfg80211_chan_def *chandef) + { + struct ieee80211_local *local = wiphy_priv(wiphy); + +- if (!local->ops->set_radar_offchan) ++ if (!local->ops->set_radar_background) + return -EOPNOTSUPP; + +- return local->ops->set_radar_offchan(&local->hw, chandef); ++ return local->ops->set_radar_background(&local->hw, chandef); + } + + const struct cfg80211_ops mac80211_config_ops = { +@@ -4460,5 +4460,5 @@ const struct cfg80211_ops mac80211_confi + .reset_tid_config = ieee80211_reset_tid_config, + .set_sar_specs = ieee80211_set_sar_specs, + .color_change = ieee80211_color_change, +- .set_radar_offchan = ieee80211_set_radar_offchan, ++ .set_radar_background = ieee80211_set_radar_background, + }; +--- a/net/wireless/chan.c ++++ b/net/wireless/chan.c +@@ -716,13 +716,13 @@ static bool + cfg80211_offchan_chain_is_active(struct cfg80211_registered_device *rdev, + struct ieee80211_channel *channel) + { +- if (!rdev->offchan_radar_wdev) ++ if (!rdev->background_radar_wdev) + return false; + +- if (!cfg80211_chandef_valid(&rdev->offchan_radar_chandef)) ++ if (!cfg80211_chandef_valid(&rdev->background_radar_chandef)) + return false; + +- return cfg80211_is_sub_chan(&rdev->offchan_radar_chandef, channel); ++ return cfg80211_is_sub_chan(&rdev->background_radar_chandef, channel); + } + + bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy, +--- a/net/wireless/core.c ++++ b/net/wireless/core.c +@@ -552,9 +552,10 @@ use_default_name: + INIT_WORK(&rdev->rfkill_block, cfg80211_rfkill_block_work); + INIT_WORK(&rdev->conn_work, cfg80211_conn_work); + INIT_WORK(&rdev->event_work, cfg80211_event_work); +- INIT_WORK(&rdev->offchan_cac_abort_wk, cfg80211_offchan_cac_abort_wk); +- INIT_DELAYED_WORK(&rdev->offchan_cac_done_wk, +- cfg80211_offchan_cac_done_wk); ++ INIT_WORK(&rdev->background_cac_abort_wk, ++ cfg80211_background_cac_abort_wk); ++ INIT_DELAYED_WORK(&rdev->background_cac_done_wk, ++ cfg80211_background_cac_done_wk); + + init_waitqueue_head(&rdev->dev_wait); + +@@ -1064,13 +1065,13 @@ void wiphy_unregister(struct wiphy *wiph + cancel_work_sync(&rdev->conn_work); + flush_work(&rdev->event_work); + cancel_delayed_work_sync(&rdev->dfs_update_channels_wk); +- cancel_delayed_work_sync(&rdev->offchan_cac_done_wk); ++ cancel_delayed_work_sync(&rdev->background_cac_done_wk); + flush_work(&rdev->destroy_work); + flush_work(&rdev->sched_scan_stop_wk); + flush_work(&rdev->propagate_radar_detect_wk); + flush_work(&rdev->propagate_cac_done_wk); + flush_work(&rdev->mgmt_registrations_update_wk); +- flush_work(&rdev->offchan_cac_abort_wk); ++ flush_work(&rdev->background_cac_abort_wk); + + #ifdef CONFIG_PM + if (rdev->wiphy.wowlan_config && rdev->ops->set_wakeup) +@@ -1219,7 +1220,7 @@ void __cfg80211_leave(struct cfg80211_re + + cfg80211_pmsr_wdev_down(wdev); + +- cfg80211_stop_offchan_radar_detection(wdev); ++ cfg80211_stop_background_radar_detection(wdev); + + switch (wdev->iftype) { + case NL80211_IFTYPE_ADHOC: +--- a/net/wireless/core.h ++++ b/net/wireless/core.h +@@ -84,10 +84,10 @@ struct cfg80211_registered_device { + + struct delayed_work dfs_update_channels_wk; + +- struct wireless_dev *offchan_radar_wdev; +- struct cfg80211_chan_def offchan_radar_chandef; +- struct delayed_work offchan_cac_done_wk; +- struct work_struct offchan_cac_abort_wk; ++ struct wireless_dev *background_radar_wdev; ++ struct cfg80211_chan_def background_radar_chandef; ++ struct delayed_work background_cac_done_wk; ++ struct work_struct background_cac_abort_wk; + + /* netlink port which started critical protocol (0 means not started) */ + u32 crit_proto_nlportid; +@@ -497,15 +497,15 @@ cfg80211_chandef_dfs_cac_time(struct wip + void cfg80211_sched_dfs_chan_update(struct cfg80211_registered_device *rdev); + + int +-cfg80211_start_offchan_radar_detection(struct cfg80211_registered_device *rdev, +- struct wireless_dev *wdev, +- struct cfg80211_chan_def *chandef); ++cfg80211_start_background_radar_detection(struct cfg80211_registered_device *rdev, ++ struct wireless_dev *wdev, ++ struct cfg80211_chan_def *chandef); + +-void cfg80211_stop_offchan_radar_detection(struct wireless_dev *wdev); ++void cfg80211_stop_background_radar_detection(struct wireless_dev *wdev); + +-void cfg80211_offchan_cac_done_wk(struct work_struct *work); ++void cfg80211_background_cac_done_wk(struct work_struct *work); + +-void cfg80211_offchan_cac_abort_wk(struct work_struct *work); ++void cfg80211_background_cac_abort_wk(struct work_struct *work); + + bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy, + struct ieee80211_channel *chan); +--- a/net/wireless/mlme.c ++++ b/net/wireless/mlme.c +@@ -920,7 +920,7 @@ void __cfg80211_radar_event(struct wiphy + cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_UNAVAILABLE); + + if (offchan) +- queue_work(cfg80211_wq, &rdev->offchan_cac_abort_wk); ++ queue_work(cfg80211_wq, &rdev->background_cac_abort_wk); + + cfg80211_sched_dfs_chan_update(rdev); + +@@ -975,10 +975,10 @@ void cfg80211_cac_event(struct net_devic + EXPORT_SYMBOL(cfg80211_cac_event); + + static void +-__cfg80211_offchan_cac_event(struct cfg80211_registered_device *rdev, +- struct wireless_dev *wdev, +- const struct cfg80211_chan_def *chandef, +- enum nl80211_radar_event event) ++__cfg80211_background_cac_event(struct cfg80211_registered_device *rdev, ++ struct wireless_dev *wdev, ++ const struct cfg80211_chan_def *chandef, ++ enum nl80211_radar_event event) + { + struct wiphy *wiphy = &rdev->wiphy; + struct net_device *netdev; +@@ -988,7 +988,7 @@ __cfg80211_offchan_cac_event(struct cfg8 + if (!cfg80211_chandef_valid(chandef)) + return; + +- if (!rdev->offchan_radar_wdev) ++ if (!rdev->background_radar_wdev) + return; + + switch (event) { +@@ -997,12 +997,12 @@ __cfg80211_offchan_cac_event(struct cfg8 + memcpy(&rdev->cac_done_chandef, chandef, sizeof(*chandef)); + queue_work(cfg80211_wq, &rdev->propagate_cac_done_wk); + cfg80211_sched_dfs_chan_update(rdev); +- wdev = rdev->offchan_radar_wdev; ++ wdev = rdev->background_radar_wdev; + break; + case NL80211_RADAR_CAC_ABORTED: +- if (!cancel_delayed_work(&rdev->offchan_cac_done_wk)) ++ if (!cancel_delayed_work(&rdev->background_cac_done_wk)) + return; +- wdev = rdev->offchan_radar_wdev; ++ wdev = rdev->background_radar_wdev; + break; + case NL80211_RADAR_CAC_STARTED: + break; +@@ -1015,49 +1015,49 @@ __cfg80211_offchan_cac_event(struct cfg8 + } + + static void +-cfg80211_offchan_cac_event(struct cfg80211_registered_device *rdev, +- const struct cfg80211_chan_def *chandef, +- enum nl80211_radar_event event) ++cfg80211_background_cac_event(struct cfg80211_registered_device *rdev, ++ const struct cfg80211_chan_def *chandef, ++ enum nl80211_radar_event event) + { + wiphy_lock(&rdev->wiphy); +- __cfg80211_offchan_cac_event(rdev, rdev->offchan_radar_wdev, +- chandef, event); ++ __cfg80211_background_cac_event(rdev, rdev->background_radar_wdev, ++ chandef, event); + wiphy_unlock(&rdev->wiphy); + } + +-void cfg80211_offchan_cac_done_wk(struct work_struct *work) ++void cfg80211_background_cac_done_wk(struct work_struct *work) + { + struct delayed_work *delayed_work = to_delayed_work(work); + struct cfg80211_registered_device *rdev; + + rdev = container_of(delayed_work, struct cfg80211_registered_device, +- offchan_cac_done_wk); +- cfg80211_offchan_cac_event(rdev, &rdev->offchan_radar_chandef, +- NL80211_RADAR_CAC_FINISHED); ++ background_cac_done_wk); ++ cfg80211_background_cac_event(rdev, &rdev->background_radar_chandef, ++ NL80211_RADAR_CAC_FINISHED); + } + +-void cfg80211_offchan_cac_abort_wk(struct work_struct *work) ++void cfg80211_background_cac_abort_wk(struct work_struct *work) + { + struct cfg80211_registered_device *rdev; + + rdev = container_of(work, struct cfg80211_registered_device, +- offchan_cac_abort_wk); +- cfg80211_offchan_cac_event(rdev, &rdev->offchan_radar_chandef, +- NL80211_RADAR_CAC_ABORTED); ++ background_cac_abort_wk); ++ cfg80211_background_cac_event(rdev, &rdev->background_radar_chandef, ++ NL80211_RADAR_CAC_ABORTED); + } + +-void cfg80211_offchan_cac_abort(struct wiphy *wiphy) ++void cfg80211_background_cac_abort(struct wiphy *wiphy) + { + struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); + +- queue_work(cfg80211_wq, &rdev->offchan_cac_abort_wk); ++ queue_work(cfg80211_wq, &rdev->background_cac_abort_wk); + } +-EXPORT_SYMBOL(cfg80211_offchan_cac_abort); ++EXPORT_SYMBOL(cfg80211_background_cac_abort); + + int +-cfg80211_start_offchan_radar_detection(struct cfg80211_registered_device *rdev, +- struct wireless_dev *wdev, +- struct cfg80211_chan_def *chandef) ++cfg80211_start_background_radar_detection(struct cfg80211_registered_device *rdev, ++ struct wireless_dev *wdev, ++ struct cfg80211_chan_def *chandef) + { + unsigned int cac_time_ms; + int err; +@@ -1065,19 +1065,19 @@ cfg80211_start_offchan_radar_detection(s + lockdep_assert_wiphy(&rdev->wiphy); + + if (!wiphy_ext_feature_isset(&rdev->wiphy, +- NL80211_EXT_FEATURE_RADAR_OFFCHAN)) ++ NL80211_EXT_FEATURE_RADAR_BACKGROUND)) + return -EOPNOTSUPP; + + /* Offchannel chain already locked by another wdev */ +- if (rdev->offchan_radar_wdev && rdev->offchan_radar_wdev != wdev) ++ if (rdev->background_radar_wdev && rdev->background_radar_wdev != wdev) + return -EBUSY; + + /* CAC already in progress on the offchannel chain */ +- if (rdev->offchan_radar_wdev == wdev && +- delayed_work_pending(&rdev->offchan_cac_done_wk)) ++ if (rdev->background_radar_wdev == wdev && ++ delayed_work_pending(&rdev->background_cac_done_wk)) + return -EBUSY; + +- err = rdev_set_radar_offchan(rdev, chandef); ++ err = rdev_set_radar_background(rdev, chandef); + if (err) + return err; + +@@ -1085,30 +1085,31 @@ cfg80211_start_offchan_radar_detection(s + if (!cac_time_ms) + cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS; + +- rdev->offchan_radar_chandef = *chandef; +- rdev->offchan_radar_wdev = wdev; /* Get offchain ownership */ ++ rdev->background_radar_chandef = *chandef; ++ rdev->background_radar_wdev = wdev; /* Get offchain ownership */ + +- __cfg80211_offchan_cac_event(rdev, wdev, chandef, +- NL80211_RADAR_CAC_STARTED); +- queue_delayed_work(cfg80211_wq, &rdev->offchan_cac_done_wk, ++ __cfg80211_background_cac_event(rdev, wdev, chandef, ++ NL80211_RADAR_CAC_STARTED); ++ queue_delayed_work(cfg80211_wq, &rdev->background_cac_done_wk, + msecs_to_jiffies(cac_time_ms)); + + return 0; + } + +-void cfg80211_stop_offchan_radar_detection(struct wireless_dev *wdev) ++void cfg80211_stop_background_radar_detection(struct wireless_dev *wdev) + { + struct wiphy *wiphy = wdev->wiphy; + struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); + + lockdep_assert_wiphy(wiphy); + +- if (wdev != rdev->offchan_radar_wdev) ++ if (wdev != rdev->background_radar_wdev) + return; + +- rdev_set_radar_offchan(rdev, NULL); +- rdev->offchan_radar_wdev = NULL; /* Release offchain ownership */ ++ rdev_set_radar_background(rdev, NULL); ++ rdev->background_radar_wdev = NULL; /* Release offchain ownership */ + +- __cfg80211_offchan_cac_event(rdev, wdev, &rdev->offchan_radar_chandef, +- NL80211_RADAR_CAC_ABORTED); ++ __cfg80211_background_cac_event(rdev, wdev, ++ &rdev->background_radar_chandef, ++ NL80211_RADAR_CAC_ABORTED); + } +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -793,7 +793,7 @@ static const struct nla_policy nl80211_p + [NL80211_ATTR_MBSSID_CONFIG] = + NLA_POLICY_NESTED(nl80211_mbssid_config_policy), + [NL80211_ATTR_MBSSID_ELEMS] = { .type = NLA_NESTED }, +- [NL80211_ATTR_RADAR_OFFCHAN] = { .type = NLA_FLAG }, ++ [NL80211_ATTR_RADAR_BACKGROUND] = { .type = NLA_FLAG }, + }; + + /* policy for the key attributes */ +@@ -9288,9 +9288,9 @@ static int nl80211_start_radar_detection + goto unlock; + } + +- if (nla_get_flag(info->attrs[NL80211_ATTR_RADAR_OFFCHAN])) { +- err = cfg80211_start_offchan_radar_detection(rdev, wdev, +- &chandef); ++ if (nla_get_flag(info->attrs[NL80211_ATTR_RADAR_BACKGROUND])) { ++ err = cfg80211_start_background_radar_detection(rdev, wdev, ++ &chandef); + goto unlock; + } + +--- a/net/wireless/rdev-ops.h ++++ b/net/wireless/rdev-ops.h +@@ -1382,17 +1382,17 @@ static inline int rdev_color_change(stru + } + + static inline int +-rdev_set_radar_offchan(struct cfg80211_registered_device *rdev, +- struct cfg80211_chan_def *chandef) ++rdev_set_radar_background(struct cfg80211_registered_device *rdev, ++ struct cfg80211_chan_def *chandef) + { + struct wiphy *wiphy = &rdev->wiphy; + int ret; + +- if (!rdev->ops->set_radar_offchan) ++ if (!rdev->ops->set_radar_background) + return -EOPNOTSUPP; + +- trace_rdev_set_radar_offchan(wiphy, chandef); +- ret = rdev->ops->set_radar_offchan(wiphy, chandef); ++ trace_rdev_set_radar_background(wiphy, chandef); ++ ret = rdev->ops->set_radar_background(wiphy, chandef); + trace_rdev_return_int(wiphy, ret); + + return ret; +--- a/net/wireless/trace.h ++++ b/net/wireless/trace.h +@@ -3646,7 +3646,7 @@ TRACE_EVENT(cfg80211_bss_color_notify, + __entry->color_bitmap) + ); + +-TRACE_EVENT(rdev_set_radar_offchan, ++TRACE_EVENT(rdev_set_radar_background, + TP_PROTO(struct wiphy *wiphy, struct cfg80211_chan_def *chandef), + + TP_ARGS(wiphy, chandef), diff --git a/package/kernel/mac80211/patches/subsys/400-allow-ibss-mixed.patch b/package/kernel/mac80211/patches/subsys/400-allow-ibss-mixed.patch index 3df4062ec5..d12c8ada31 100644 --- a/package/kernel/mac80211/patches/subsys/400-allow-ibss-mixed.patch +++ b/package/kernel/mac80211/patches/subsys/400-allow-ibss-mixed.patch @@ -5,7 +5,7 @@ and we should ignore this. --- a/net/wireless/core.c +++ b/net/wireless/core.c -@@ -630,21 +630,6 @@ static int wiphy_verify_combinations(str +@@ -634,21 +634,6 @@ static int wiphy_verify_combinations(str c->limits[j].max > 1)) return -EINVAL; diff --git a/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch b/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch index 3140eee5d0..2dbbb2cc96 100644 --- a/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch +++ b/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch @@ -8,7 +8,7 @@ * * @rfkill_poll: polls the hw rfkill line, use cfg80211 reporting * functions to adjust rfkill hw state -@@ -4193,6 +4194,7 @@ struct cfg80211_ops { +@@ -4202,6 +4203,7 @@ struct cfg80211_ops { enum nl80211_tx_power_setting type, int mbm); int (*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev, int *dbm); @@ -36,9 +36,9 @@ u8 ps_dtim_period; --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h -@@ -2608,6 +2608,9 @@ enum nl80211_commands { - * Mandatory parameter for the transmitting interface to enable MBSSID. - * Optional for the non-transmitting interfaces. +@@ -2615,6 +2615,9 @@ enum nl80211_commands { + * switching on a different channel during CAC detection on the selected + * radar channel. * + * @NL80211_ATTR_WIPHY_ANTENNA_GAIN: Configured antenna gain. Used to reduce + * transmit power to stay within regulatory limits. u32, dBi. @@ -46,9 +46,9 @@ * @NUM_NL80211_ATTR: total number of nl80211_attrs available * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use -@@ -3114,6 +3117,8 @@ enum nl80211_attrs { - NL80211_ATTR_MBSSID_CONFIG, - NL80211_ATTR_MBSSID_ELEMS, +@@ -3123,6 +3126,8 @@ enum nl80211_attrs { + + NL80211_ATTR_RADAR_BACKGROUND, + NL80211_ATTR_WIPHY_ANTENNA_GAIN, + @@ -77,7 +77,7 @@ static void ieee80211_rfkill_poll(struct wiphy *wiphy) { struct ieee80211_local *local = wiphy_priv(wiphy); -@@ -4399,6 +4412,7 @@ const struct cfg80211_ops mac80211_confi +@@ -4411,6 +4424,7 @@ const struct cfg80211_ops mac80211_confi .set_wiphy_params = ieee80211_set_wiphy_params, .set_tx_power = ieee80211_set_tx_power, .get_tx_power = ieee80211_get_tx_power, @@ -129,15 +129,15 @@ local->hw.max_mtu = IEEE80211_MAX_DATA_LEN; --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c -@@ -793,6 +793,7 @@ static const struct nla_policy nl80211_p - [NL80211_ATTR_MBSSID_CONFIG] = +@@ -794,6 +794,7 @@ static const struct nla_policy nl80211_p NLA_POLICY_NESTED(nl80211_mbssid_config_policy), [NL80211_ATTR_MBSSID_ELEMS] = { .type = NLA_NESTED }, + [NL80211_ATTR_RADAR_BACKGROUND] = { .type = NLA_FLAG }, + [NL80211_ATTR_WIPHY_ANTENNA_GAIN] = { .type = NLA_U32 }, }; /* policy for the key attributes */ -@@ -3374,6 +3375,22 @@ static int nl80211_set_wiphy(struct sk_b +@@ -3375,6 +3376,22 @@ static int nl80211_set_wiphy(struct sk_b goto out; } |