[][openwrt-patches-21.02: remove mt76 zw-dfs]

[Description]
Remove zero-wait dfs related patches of mac80211 and mt76, since they're
already merged in openwrt and mt76 master.

[Release-log]
N/A

Change-Id: Ib1fceb9c5cdbcaf315ee0be51c6b625db2c91818
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/5583121
diff --git a/openwrt_patches-21.02/402-master-mac80211-zero-wait-dfs.patch b/openwrt_patches-21.02/402-master-mac80211-zero-wait-dfs.patch
deleted file mode 100644
index cbf29b2..0000000
--- a/openwrt_patches-21.02/402-master-mac80211-zero-wait-dfs.patch
+++ /dev/null
@@ -1,715 +0,0 @@
-diff --git a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh
-index 27eecf3..ff3169c 100644
---- a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh
-+++ b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh
-@@ -61,7 +61,8 @@ drv_mac80211_init_device_config() {
- 		rx_stbc \
- 		tx_stbc \
- 		he_bss_color \
--		he_spr_non_srg_obss_pd_max_offset
-+		he_spr_non_srg_obss_pd_max_offset \
-+		radar_offchan
- 	config_add_boolean \
- 		ldpc \
- 		greenfield \
-@@ -137,12 +138,9 @@ mac80211_hostapd_setup_base() {
- 	[ -n "$acs_exclude_dfs" ] && [ "$acs_exclude_dfs" -gt 0 ] &&
- 		append base_cfg "acs_exclude_dfs=1" "$N"
- 
--	json_get_vars noscan ht_coex
-+	json_get_vars noscan ht_coex radar_offchan:0
- 	json_get_values ht_capab_list ht_capab tx_burst
--	json_get_values channel_list channels
--
--	[ "$auto_channel" = 0 ] && [ -z "$channel_list" ] && \
--		channel_list="$channel"
-+	json_get_values channels
- 
- 	set_default noscan 0
- 
-@@ -462,10 +460,11 @@ mac80211_hostapd_setup_base() {
- 		append base_cfg "he_mu_edca_ac_vo_timer=255" "$N"
- 	fi
- 
-+	append base_cfg "radar_offchan=$radar_offchan" "$N"
-+
- 	hostapd_prepare_device_config "$hostapd_conf_file" nl80211
- 	cat >> "$hostapd_conf_file" <<EOF
- ${channel:+channel=$channel}
--${channel_list:+chanlist=$channel_list}
- ${hostapd_noscan:+noscan=1}
- ${tx_burst:+tx_queue_data2_burst=$tx_burst}
- $base_cfg
-diff --git a/package/kernel/mac80211/patches/subsys/900-mac80211-zero-wait-dfs.patch b/package/kernel/mac80211/patches/subsys/900-mac80211-zero-wait-dfs.patch
-new file mode 100644
-index 0000000..ba3ac4b
---- /dev/null
-+++ b/package/kernel/mac80211/patches/subsys/900-mac80211-zero-wait-dfs.patch
-@@ -0,0 +1,667 @@
-+diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
-+index 080d220..6278545 100644
-+--- a/include/net/cfg80211.h
-++++ b/include/net/cfg80211.h
-+@@ -4024,6 +4024,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);
-+@@ -4355,6 +4364,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);
-+ };
-+ 
-+ /*
-+@@ -7529,15 +7540,33 @@ void cfg80211_cqm_txe_notify(struct net_device *dev, const u8 *peer,
-+ 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
-+@@ -7568,6 +7597,14 @@ void cfg80211_cac_event(struct net_device *netdev,
-+ 			const struct cfg80211_chan_def *chandef,
-+ 			enum nl80211_radar_event event, gfp_t gfp);
-+ 
-++/**
-++ * cfg80211_offchan_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);
-+ 
-+ /**
-+  * cfg80211_gtk_rekey_notify - notify userspace about driver rekeying
-+diff --git a/include/net/mac80211.h b/include/net/mac80211.h
-+index afab7ec..acf637d 100644
-+--- a/include/net/mac80211.h
-++++ b/include/net/mac80211.h
-+@@ -3939,6 +3939,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.
-+  */
-+ struct ieee80211_ops {
-+ 	void (*tx)(struct ieee80211_hw *hw,
-+@@ -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);
-+ };
-+ 
-+ /**
-+diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
-+index 5f4a094..7634ba0 100644
-+--- a/include/uapi/linux/nl80211.h
-++++ b/include/uapi/linux/nl80211.h
-+@@ -2596,6 +2596,13 @@ enum nl80211_commands {
-+  * @NL80211_ATTR_WIPHY_ANTENNA_GAIN: Configured antenna gain. Used to reduce
-+  *	transmit power to stay within regulatory limits. u32, dBi.
-+  *
-++ * @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
-+@@ -3101,6 +3108,8 @@ enum nl80211_attrs {
-+ 
-+ 	NL80211_ATTR_WIPHY_ANTENNA_GAIN,
-+ 
-++	NL80211_ATTR_RADAR_OFFCHAN,
-++
-+ 	/* add attributes here, update the policy in nl80211.c */
-+ 
-+ 	__NL80211_ATTR_AFTER_LAST,
-+@@ -6000,6 +6009,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.
-+  */
-+@@ -6065,6 +6077,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,
-+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
-+index 8b7c12a..887af1e 100644
-+--- a/net/mac80211/cfg.c
-++++ b/net/mac80211/cfg.c
-+@@ -4353,6 +4353,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,
-+@@ -4458,4 +4470,5 @@ const struct cfg80211_ops mac80211_config_ops = {
-+ 	.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/net/wireless/chan.c b/net/wireless/chan.c
-+index 1382a5f..75b4151 100644
-+--- a/net/wireless/chan.c
-++++ b/net/wireless/chan.c
-+@@ -712,6 +712,20 @@ static bool cfg80211_is_wiphy_oper_chan(struct wiphy *wiphy,
-+ 	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 +742,9 @@ bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy,
-+ 
-+ 		if (cfg80211_is_wiphy_oper_chan(&rdev->wiphy, chan))
-+ 			return true;
-++
-++		if (cfg80211_offchan_chain_is_active(rdev, chan))
-++			return true;
-+ 	}
-+ 
-+ 	return false;
-+diff --git a/net/wireless/core.c b/net/wireless/core.c
-+index b181dad..378fb4e 100644
-+--- a/net/wireless/core.c
-++++ b/net/wireless/core.c
-+@@ -551,6 +551,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_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);
-+ 
-+@@ -1045,11 +1048,13 @@ void wiphy_unregister(struct wiphy *wiphy)
-+ 	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)
-+@@ -1188,6 +1193,8 @@ void __cfg80211_leave(struct cfg80211_registered_device *rdev,
-+ 
-+ 	cfg80211_pmsr_wdev_down(wdev);
-+ 
-++	cfg80211_stop_offchan_radar_detection(wdev);
-++
-+ 	switch (wdev->iftype) {
-+ 	case NL80211_IFTYPE_ADHOC:
-+ 		__cfg80211_leave_ibss(rdev, dev, true);
-+diff --git a/net/wireless/core.h b/net/wireless/core.h
-+index 19fcdd7..7fe31aa 100644
-+--- a/net/wireless/core.h
-++++ b/net/wireless/core.h
-+@@ -84,6 +84,11 @@ 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;
-++
-+ 	/* netlink port which started critical protocol (0 means not started) */
-+ 	u32 crit_proto_nlportid;
-+ 
-+@@ -489,6 +494,17 @@ cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy,
-+ 
-+ 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_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);
-+ 
-+diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
-+index a8a17b9..8f230d3 100644
-+--- a/net/wireless/mlme.c
-++++ b/net/wireless/mlme.c
-+@@ -903,13 +903,13 @@ void cfg80211_dfs_channels_update_work(struct work_struct *work)
-+ }
-+ 
-+ 
-+-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
-+@@ -917,6 +917,9 @@ void cfg80211_radar_event(struct wiphy *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);
-+@@ -924,7 +927,7 @@ void cfg80211_radar_event(struct wiphy *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,
-+@@ -968,3 +971,142 @@ void cfg80211_cac_event(struct net_device *netdev,
-+ 	nl80211_radar_notify(rdev, chandef, event, netdev, gfp);
-+ }
-+ 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)
-++{
-++	struct wiphy *wiphy = &rdev->wiphy;
-++	struct net_device *netdev;
-++
-++	lockdep_assert_wiphy(&rdev->wiphy);
-++
-++	if (!cfg80211_chandef_valid(chandef))
-++		return;
-++
-++	if (!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;
-++		break;
-++	case NL80211_RADAR_CAC_ABORTED:
-++		if (!cancel_delayed_work(&rdev->offchan_cac_done_wk))
-++			return;
-++		wdev = rdev->offchan_radar_wdev;
-++		break;
-++	case NL80211_RADAR_CAC_STARTED:
-++		break;
-++	default:
-++		return;
-++	}
-++
-++	netdev = wdev ? wdev->netdev : NULL;
-++	nl80211_radar_notify(rdev, chandef, event, netdev, GFP_KERNEL);
-++}
-++
-++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, rdev->offchan_radar_wdev,
-++				     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);
-++
-++	queue_work(cfg80211_wq, &rdev->offchan_cac_abort_wk);
-++}
-++EXPORT_SYMBOL(cfg80211_offchan_cac_abort);
-++
-++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;
-++
-++	/* 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);
-++	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;
-++	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,
-++			   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);
-++	rdev->offchan_radar_wdev = NULL; /* Release offchain ownership */
-++
-++	__cfg80211_offchan_cac_event(rdev, wdev, &rdev->offchan_radar_chandef,
-++				     NL80211_RADAR_CAC_ABORTED);
-++}
-+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
-+index 4a3de61..0cf9f68 100644
-+--- a/net/wireless/nl80211.c
-++++ b/net/wireless/nl80211.c
-+@@ -781,6 +781,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
-+ 	[NL80211_ATTR_COLOR_CHANGE_COLOR] = { .type = NLA_U8 },
-+ 	[NL80211_ATTR_COLOR_CHANGE_ELEMS] = NLA_POLICY_NESTED(nl80211_policy),
-+ 	[NL80211_ATTR_WIPHY_ANTENNA_GAIN] = { .type = NLA_U32 },
-++	[NL80211_ATTR_RADAR_OFFCHAN] = { .type = NLA_FLAG },
-+ };
-+ 
-+ /* policy for the key attributes */
-+@@ -9106,38 +9107,60 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
-+ 	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;
-+-
-+-	if (netif_carrier_ok(dev))
-+-		return -EBUSY;
-+-
-+-	if (wdev->cac_started)
-+-		return -EBUSY;
-++		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])) {
-++		err = cfg80211_start_offchan_radar_detection(rdev, wdev,
-++							     &chandef);
-++		goto unlock;
-++	}
-++
-++	if (netif_carrier_ok(dev)) {
-++		err = -EBUSY;
-++		goto unlock;
-++	}
-++
-++	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))
-+@@ -9150,6 +9173,9 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
-+ 		wdev->cac_start_time = jiffies;
-+ 		wdev->cac_time_ms = cac_time_ms;
-+ 	}
-++unlock:
-++	wiphy_unlock(wiphy);
-++
-+ 	return err;
-+ }
-+ 
-+@@ -15762,7 +15788,8 @@ static const struct genl_small_ops nl80211_small_ops[] = {
-+ 		.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/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
-+index 36422cf..c566f47 100644
-+--- a/net/wireless/rdev-ops.h
-++++ b/net/wireless/rdev-ops.h
-+@@ -1381,4 +1381,21 @@ static inline int rdev_color_change(struct cfg80211_registered_device *rdev,
-+ 	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 */
-+diff --git a/net/wireless/trace.h b/net/wireless/trace.h
-+index 973ce68..cd60ada 100644
-+--- a/net/wireless/trace.h
-++++ b/net/wireless/trace.h
-+@@ -3022,18 +3022,21 @@ TRACE_EVENT(cfg80211_ch_switch_started_notify,
-+ );
-+ 
-+ 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,
-+@@ -3643,6 +3646,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/openwrt_patches-21.02/403-master-mt76-zero-wait-dfs.patch b/openwrt_patches-21.02/403-master-mt76-zero-wait-dfs.patch
deleted file mode 100644
index 600210d..0000000
--- a/openwrt_patches-21.02/403-master-mt76-zero-wait-dfs.patch
+++ /dev/null
@@ -1,375 +0,0 @@
-diff --git a/package/kernel/mt76/patches/1005-mt76-zero-wait-dfs.patch b/package/kernel/mt76/patches/1005-mt76-zero-wait-dfs.patch
-new file mode 100644
-index 0000000..68883e4
---- /dev/null
-+++ b/package/kernel/mt76/patches/1005-mt76-zero-wait-dfs.patch
-@@ -0,0 +1,369 @@
-+diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c
-+index 3a0ec43..2ce6973 100644
-+--- a/mt7915/debugfs.c
-++++ b/mt7915/debugfs.c
-+@@ -75,12 +75,62 @@ mt7915_radar_trigger(void *data, u64 val)
-+ {
-+ 	struct mt7915_dev *dev = data;
-+ 
-+-	return mt7915_mcu_rdd_cmd(dev, RDD_RADAR_EMULATE, 1, 0, 0);
-++	if (val > MT_RX_SEL2)
-++		return -EINVAL;
-++
-++	return mt7915_mcu_rdd_cmd(dev, RDD_RADAR_EMULATE, val, 0, 0);
-+ }
-+ 
-+ DEFINE_DEBUGFS_ATTRIBUTE(fops_radar_trigger, NULL,
-+ 			 mt7915_radar_trigger, "%lld\n");
-+ 
-++static int
-++mt7915_rdd_monitor(struct seq_file *s, void *data)
-++{
-++	struct mt7915_dev *dev = dev_get_drvdata(s->private);
-++	struct cfg80211_chan_def *chandef = &dev->rdd2_chandef;
-++	const char *bw;
-++	int ret = 0;
-++
-++	mutex_lock(&dev->mt76.mutex);
-++
-++	if (!cfg80211_chandef_valid(chandef)) {
-++		ret = -EINVAL;
-++		goto out;
-++	}
-++
-++	if (!dev->rdd2_phy) {
-++		seq_printf(s, "not running\n");
-++		goto out;
-++	}
-++
-++	switch (chandef->width) {
-++	case NL80211_CHAN_WIDTH_40:
-++		bw = "40";
-++		break;
-++	case NL80211_CHAN_WIDTH_80:
-++		bw = "80";
-++		break;
-++	case NL80211_CHAN_WIDTH_160:
-++		bw = "160";
-++		break;
-++	case NL80211_CHAN_WIDTH_80P80:
-++		bw = "80P80";
-++		break;
-++	default:
-++		bw = "20";
-++		break;
-++	}
-++
-++	seq_printf(s, "channel %d (%d MHz) width %s MHz center1: %d MHz\n",
-++		   chandef->chan->hw_value, chandef->chan->center_freq,
-++		   bw, chandef->center_freq1);
-++out:
-++	mutex_unlock(&dev->mt76.mutex);
-++
-++	return ret;
-++}
-++
-+ static int
-+ mt7915_fw_debug_wm_set(void *data, u64 val)
-+ {
-+@@ -552,6 +602,8 @@ int mt7915_init_debugfs(struct mt7915_phy *phy)
-+ 				   &dev->hw_pattern);
-+ 		debugfs_create_file("radar_trigger", 0200, dir, dev,
-+ 				    &fops_radar_trigger);
-++		debugfs_create_devm_seqfile(dev->mt76.dev, "rdd_monitor", dir,
-++					    mt7915_rdd_monitor);
-+ 	}
-+ 
-+ #ifdef MTK_DEBUG
-+diff --git a/mt7915/init.c b/mt7915/init.c
-+index e32cefc..6767702 100644
-+--- a/mt7915/init.c
-++++ b/mt7915/init.c
-+@@ -294,6 +294,9 @@ mt7915_regd_notifier(struct wiphy *wiphy,
-+ 	memcpy(dev->mt76.alpha2, request->alpha2, sizeof(dev->mt76.alpha2));
-+ 	dev->mt76.region = request->dfs_region;
-+ 
-++	if (dev->mt76.region == NL80211_DFS_UNSET)
-++		mt7915_mcu_rdd_offchan_enable(phy, NULL);
-++
-+ 	mt7915_init_txpower(dev, &mphy->sband_2g.sband);
-+ 	mt7915_init_txpower(dev, &mphy->sband_5g.sband);
-+ 
-+@@ -307,6 +310,7 @@ static void
-+ mt7915_init_wiphy(struct ieee80211_hw *hw)
-+ {
-+ 	struct mt7915_phy *phy = mt7915_hw_phy(hw);
-++	struct mt76_dev *mdev = &phy->dev->mt76;
-+ 	struct wiphy *wiphy = hw->wiphy;
-+ 
-+ 	hw->queues = 4;
-+@@ -334,6 +338,12 @@ mt7915_init_wiphy(struct ieee80211_hw *hw)
-+ 	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_VHT);
-+ 	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_HE);
-+ 
-++	if (!mdev->dev->of_node ||
-++	    !of_property_read_bool(mdev->dev->of_node,
-++				   "mediatek,disable-radar-offchan"))
-++		wiphy_ext_feature_set(wiphy,
-++				      NL80211_EXT_FEATURE_RADAR_OFFCHAN);
-++
-+ 	ieee80211_hw_set(hw, HAS_RATE_CONTROL);
-+ 	ieee80211_hw_set(hw, SUPPORTS_TX_ENCAP_OFFLOAD);
-+ 	ieee80211_hw_set(hw, SUPPORTS_RX_DECAP_OFFLOAD);
-+diff --git a/mt7915/main.c b/mt7915/main.c
-+index 31efe2c..c9dba1f 100644
-+--- a/mt7915/main.c
-++++ b/mt7915/main.c
-+@@ -1312,6 +1312,55 @@ mt7915_twt_teardown_request(struct ieee80211_hw *hw,
-+ 	mutex_unlock(&dev->mt76.mutex);
-+ }
-+ 
-++static int
-++mt7915_set_radar_offchan(struct ieee80211_hw *hw,
-++			 struct cfg80211_chan_def *chandef)
-++{
-++	struct mt7915_phy *phy = mt7915_hw_phy(hw);
-++	struct mt7915_dev *dev = phy->dev;
-++	int ret = -EINVAL;
-++	bool running;
-++
-++	mutex_lock(&dev->mt76.mutex);
-++
-++	if (dev->mt76.region == NL80211_DFS_UNSET)
-++		goto out;
-++
-++	if (dev->rdd2_phy && dev->rdd2_phy != phy) {
-++		/* rdd2 is already locked */
-++		ret = -EBUSY;
-++		goto out;
-++	}
-++
-++	/* rdd2 already configured on a radar channel */
-++	running = dev->rdd2_phy &&
-++		  cfg80211_chandef_valid(&dev->rdd2_chandef) &&
-++		  !!(dev->rdd2_chandef.chan->flags & IEEE80211_CHAN_RADAR);
-++
-++	if (!chandef || running ||
-++	    !(chandef->chan->flags & IEEE80211_CHAN_RADAR)) {
-++		ret = mt7915_mcu_rdd_offchan_enable(phy, NULL);
-++		if (ret)
-++			goto out;
-++
-++		if (!running)
-++			goto update_phy;
-++	}
-++
-++	ret = mt7915_mcu_rdd_offchan_enable(phy, chandef);
-++	if (ret)
-++		goto out;
-++
-++update_phy:
-++	dev->rdd2_phy = chandef ? phy : NULL;
-++	if (chandef)
-++		dev->rdd2_chandef = *chandef;
-++out:
-++	mutex_unlock(&dev->mt76.mutex);
-++
-++	return ret;
-++}
-++
-+ const struct ieee80211_ops mt7915_ops = {
-+ 	.tx = mt7915_tx,
-+ 	.start = mt7915_start,
-+@@ -1357,4 +1406,5 @@ const struct ieee80211_ops mt7915_ops = {
-+ #ifdef CONFIG_MAC80211_DEBUGFS
-+ 	.sta_add_debugfs = mt7915_sta_add_debugfs,
-+ #endif
-++	.set_radar_offchan = mt7915_set_radar_offchan,
-+ };
-+diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-+index a5fb821..b361f68 100644
-+--- a/mt7915/mcu.c
-++++ b/mt7915/mcu.c
-+@@ -487,7 +487,12 @@ mt7915_mcu_rx_radar_detected(struct mt7915_dev *dev, struct sk_buff *skb)
-+ 	if (r->band_idx && dev->mt76.phy2)
-+ 		mphy = dev->mt76.phy2;
-+ 
-+-	ieee80211_radar_detected(mphy->hw);
-++	if (r->band_idx == MT_RX_SEL2)
-++		cfg80211_offchan_radar_event(mphy->hw->wiphy,
-++					     &dev->rdd2_chandef,
-++					     GFP_ATOMIC);
-++	else
-++		ieee80211_radar_detected(mphy->hw);
-+ 	dev->hw_pattern++;
-+ }
-+ 
-+@@ -3409,6 +3414,97 @@ int mt7915_mcu_set_radar_th(struct mt7915_dev *dev, int index,
-+ 				 sizeof(req), true);
-+ }
-+ 
-++static int
-++mt7915_mcu_offchan_chain_ctrl(struct mt7915_phy *phy,
-++			      struct cfg80211_chan_def *chandef,
-++			      int cmd)
-++{
-++	struct mt7915_dev *dev = phy->dev;
-++	struct mt76_phy *mphy = phy->mt76;
-++	struct ieee80211_channel *chan = mphy->chandef.chan;
-++	int freq = mphy->chandef.center_freq1;
-++	struct mt7915_mcu_offchan_chain_ctrl req = {
-++		.monitor_scan_type = 2, /* simple rx */
-++	};
-++
-++	if (!chandef && cmd != CH_SWITCH_BACKGROUND_SCAN_STOP)
-++		return -EINVAL;
-++
-++	if (!cfg80211_chandef_valid(&mphy->chandef))
-++		return -EINVAL;
-++
-++	switch (cmd) {
-++	case CH_SWITCH_BACKGROUND_SCAN_START: {
-++		req.chan = chan->hw_value;
-++		req.central_chan = ieee80211_frequency_to_channel(freq);
-++		req.bw = mt7915_mcu_chan_bw(&mphy->chandef);
-++		req.monitor_chan = chandef->chan->hw_value;
-++		req.monitor_central_chan =
-++			ieee80211_frequency_to_channel(chandef->center_freq1);
-++		req.monitor_bw = mt7915_mcu_chan_bw(chandef);
-++		req.band_idx = phy != &dev->phy;
-++		req.scan_mode = 1;
-++		break;
-++	}
-++	case CH_SWITCH_BACKGROUND_SCAN_RUNNING:
-++		req.monitor_chan = chandef->chan->hw_value;
-++		req.monitor_central_chan =
-++			ieee80211_frequency_to_channel(chandef->center_freq1);
-++		req.band_idx = phy != &dev->phy;
-++		req.scan_mode = 2;
-++		break;
-++	case CH_SWITCH_BACKGROUND_SCAN_STOP:
-++		req.chan = chan->hw_value;
-++		req.central_chan = ieee80211_frequency_to_channel(freq);
-++		req.bw = mt7915_mcu_chan_bw(&mphy->chandef);
-++		req.tx_stream = hweight8(mphy->antenna_mask);
-++		req.rx_stream = mphy->antenna_mask;
-++		break;
-++	default:
-++		return -EINVAL;
-++	}
-++	req.band = chandef ? chandef->chan->band == NL80211_BAND_5GHZ : 1;
-++
-++	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(OFFCH_SCAN_CTRL),
-++				 &req, sizeof(req), false);
-++}
-++
-++int mt7915_mcu_rdd_offchan_enable(struct mt7915_phy *phy,
-++				  struct cfg80211_chan_def *chandef)
-++{
-++	struct mt7915_dev *dev = phy->dev;
-++	int err, region;
-++
-++	if (!chandef) { /* disable offchain */
-++		err = mt7915_mcu_rdd_cmd(dev, RDD_STOP, MT_RX_SEL2, 0, 0);
-++		if (err)
-++			return err;
-++
-++		return mt7915_mcu_offchan_chain_ctrl(phy, NULL,
-++				CH_SWITCH_BACKGROUND_SCAN_STOP);
-++	}
-++
-++	err = mt7915_mcu_offchan_chain_ctrl(phy, chandef,
-++					    CH_SWITCH_BACKGROUND_SCAN_START);
-++	if (err)
-++		return err;
-++
-++	switch (dev->mt76.region) {
-++	case NL80211_DFS_ETSI:
-++		region = 0;
-++		break;
-++	case NL80211_DFS_JP:
-++		region = 2;
-++		break;
-++	case NL80211_DFS_FCC:
-++	default:
-++		region = 1;
-++		break;
-++	}
-++
-++	return mt7915_mcu_rdd_cmd(dev, RDD_START, MT_RX_SEL2, 0, region);
-++}
-++
-+ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd)
-+ {
-+ 	struct mt7915_dev *dev = phy->dev;
-+diff --git a/mt7915/mcu.h b/mt7915/mcu.h
-+index 2f856ae..64bea9a 100644
-+--- a/mt7915/mcu.h
-++++ b/mt7915/mcu.h
-+@@ -153,6 +153,29 @@ struct mt7915_mcu_rdd_report {
-+ 	} hw_pulse[32];
-+ } __packed;
-+ 
-++struct mt7915_mcu_offchan_chain_ctrl {
-++	u8 chan;		/* primary channel */
-++	u8 central_chan;	/* central channel */
-++	u8 bw;
-++	u8 tx_stream;
-++	u8 rx_stream;
-++
-++	u8 monitor_chan;	/* monitor channel */
-++	u8 monitor_central_chan;/* monitor central channel */
-++	u8 monitor_bw;
-++	u8 monitor_tx_stream;
-++	u8 monitor_rx_stream;
-++
-++	u8 scan_mode;		/* 0: ScanStop
-++				 * 1: ScanStart
-++				 * 2: ScanRunning
-++				 */
-++	u8 band_idx;		/* DBDC */
-++	u8 monitor_scan_type;
-++	u8 band;		/* 0: 2.4GHz, 1: 5GHz */
-++	u8 rsv[2];
-++} __packed;
-++
-+ struct mt7915_mcu_eeprom {
-+ 	u8 buffer_mode;
-+ 	u8 format;
-+@@ -286,6 +309,7 @@ enum {
-+ 	MCU_EXT_CMD_SCS_CTRL = 0x82,
-+ 	MCU_EXT_CMD_TWT_AGRT_UPDATE = 0x94,
-+ 	MCU_EXT_CMD_FW_DBG_CTRL = 0x95,
-++	MCU_EXT_CMD_OFFCH_SCAN_CTRL = 0x9a,
-+ 	MCU_EXT_CMD_SET_RDD_TH = 0x9d,
-+ 	MCU_EXT_CMD_MURU_CTRL = 0x9f,
-+ 	MCU_EXT_CMD_SET_SPR = 0xa8,
-+diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-+index 27dcd3f..f3449eb 100644
-+--- a/mt7915/mt7915.h
-++++ b/mt7915/mt7915.h
-+@@ -298,6 +298,10 @@ struct mt7915_dev {
-+ 	struct tasklet_struct irq_tasklet;
-+ 	struct mt7915_phy phy;
-+ 
-++	/* monitor rx chain configured channel */
-++	struct cfg80211_chan_def rdd2_chandef;
-++	struct mt7915_phy *rdd2_phy;
-++
-+ 	u16 chainmask;
-+ 	u32 hif_idx;
-+ 
-+@@ -379,6 +383,7 @@ enum {
-+ enum {
-+ 	MT_RX_SEL0,
-+ 	MT_RX_SEL1,
-++	MT_RX_SEL2, /* monitor chain */
-+ };
-+ 
-+ enum mt7915_rdd_cmd {
-+@@ -516,6 +521,8 @@ int mt7915_mcu_get_rx_rate(struct mt7915_phy *phy, struct ieee80211_vif *vif,
-+ 			   struct ieee80211_sta *sta, struct rate_info *rate);
-+ int mt7915_mcu_rdd_cmd(struct mt7915_dev *dev, enum mt7915_rdd_cmd cmd,
-+ 		       u8 index, u8 rx_sel, u8 val);
-++int mt7915_mcu_rdd_offchan_enable(struct mt7915_phy *phy,
-++				  struct cfg80211_chan_def *chandef);
-+ int mt7915_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3);
-+ int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 type, u8 ctrl);
-+ int mt7915_mcu_fw_dbg_ctrl(struct mt7915_dev *dev, u32 module, u8 level);
-+