[][MAC80211][MT76][Update bersa to May 10, 2022]

[Description]
Change bersa support to May 10, 2022

[Release-log]
N/A

Change-Id: I8ac123b96cf5bb539a4bf87dc5eed1909733f170
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/5952988
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/bersa.h b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/bersa.h
index 1b7a975..63a9736 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/bersa.h
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/bersa.h
@@ -41,6 +41,7 @@
 #define BERSA_CFEND_RATE_11B		0x03	/* 11B LP, 11M */
 
 #define BERSA_THERMAL_THROTTLE_MAX	100
+#define BERSA_CDEV_THROTTLE_MAX	99
 
 #define BERSA_SKU_RATE_NUM		161
 
@@ -113,7 +114,9 @@
 };
 
 struct bersa_vif_cap {
-	bool ldpc:1;
+	bool ht_ldpc:1;
+	bool vht_ldpc:1;
+	bool he_ldpc:1;
 	bool vht_su_ebfer:1;
 	bool vht_su_ebfee:1;
 	bool vht_mu_ebfer:1;
@@ -200,11 +203,12 @@
 	struct mt76_phy *mt76;
 	struct bersa_dev *dev;
 
-	struct ieee80211_sband_iftype_data iftype[2][NUM_NL80211_IFTYPES];
+	struct ieee80211_sband_iftype_data iftype[NUM_NL80211_BANDS][NUM_NL80211_IFTYPES];
 
 	struct ieee80211_vif *monitor_vif;
 
 	struct thermal_cooling_device *cdev;
+	u8 cdev_state;
 	u8 throttle_state;
 	u32 throttle_temp[2]; /* 0: critical high, 1: maximum */
 
@@ -297,10 +301,6 @@
 		u8 table_mask;
 		u8 n_agrt;
 	} twt;
-
-	struct reset_control *rstc;
-	void __iomem *dcm;
-	void __iomem *sku;
 };
 
 enum {
@@ -403,6 +403,7 @@
 
 struct bersa_dev *bersa_mmio_probe(struct device *pdev,
 				     void __iomem *mem_base, u32 device_id);
+void bersa_wfsys_reset(struct bersa_dev *dev);
 irqreturn_t bersa_irq_handler(int irq, void *dev_instance);
 u64 __bersa_get_tsf(struct ieee80211_hw *hw, struct bersa_vif *mvif);
 int bersa_register_device(struct bersa_dev *dev);
@@ -458,7 +459,6 @@
 int bersa_mcu_get_eeprom_free_block(struct bersa_dev *dev, u8 *block_num);
 int bersa_mcu_set_test_param(struct bersa_dev *dev, u8 param, bool test_mode,
 			      u8 en);
-int bersa_mcu_set_scs(struct bersa_dev *dev, u8 band, bool enable);
 int bersa_mcu_set_ser(struct bersa_dev *dev, u8 action, u8 set, u8 band);
 int bersa_mcu_set_sku_en(struct bersa_phy *phy, bool enable);
 int bersa_mcu_set_txpower_sku(struct bersa_phy *phy);
@@ -486,6 +486,7 @@
 		      u8 rx_sel, u8 val);
 int bersa_mcu_rdd_background_enable(struct bersa_phy *phy,
 				     struct cfg80211_chan_def *chandef);
+int bersa_mcu_rf_regval(struct bersa_dev *dev, u32 regidx, u32 *val, bool set);
 int bersa_mcu_wa_cmd(struct bersa_dev *dev, int cmd, u32 a1, u32 a2, u32 a3);
 int bersa_mcu_fw_log_2_host(struct bersa_dev *dev, u8 type, u8 ctrl);
 int bersa_mcu_fw_dbg_ctrl(struct bersa_dev *dev, u32 module, u8 level);
@@ -563,6 +564,8 @@
 		      struct mt76_connac_sta_key_conf *sta_key_conf,
 		      struct ieee80211_key_conf *key, int mcu_cmd,
 		      struct mt76_wcid *wcid, enum set_key_cmd cmd);
+int bersa_mcu_wtbl_update_hdr_trans(struct bersa_dev *dev,
+			struct ieee80211_vif *vif, struct ieee80211_sta *sta);
 #ifdef CONFIG_MAC80211_DEBUGFS
 void bersa_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 			    struct ieee80211_sta *sta, struct dentry *dir);
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/debugfs.c b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/debugfs.c
index 96b2b6e..4be253e 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/debugfs.c
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/debugfs.c
@@ -95,7 +95,7 @@
 	struct bersa_dev *dev = data;
 
 	dev->muru_debug = val;
-	bersa_mcu_muru_debug_set(dev, data);
+	bersa_mcu_muru_debug_set(dev, dev->muru_debug);
 
 	return 0;
 }
@@ -871,6 +871,36 @@
 	return 0;
 }
 
+/* The index of RF registers use the generic regidx, combined with two parts:
+ * WF selection [31:28] and offset [27:0].
+ */
+static int
+bersa_rf_regval_get(void *data, u64 *val)
+{
+	struct bersa_dev *dev = data;
+	u32 regval;
+	int ret;
+
+	ret = bersa_mcu_rf_regval(dev, dev->mt76.debugfs_reg, &regval, false);
+	if (ret)
+		return ret;
+
+	*val = le32_to_cpu(regval);
+
+	return 0;
+}
+
+static int
+bersa_rf_regval_set(void *data, u64 val)
+{
+	struct bersa_dev *dev = data;
+
+	return bersa_mcu_rf_regval(dev, dev->mt76.debugfs_reg, (u32 *)&val, true);
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(fops_rf_regval, bersa_rf_regval_get,
+			 bersa_rf_regval_set, "0x%08llx\n");
+
 int bersa_init_debugfs(struct bersa_phy *phy)
 {
 	struct bersa_dev *dev = phy->dev;
@@ -901,6 +931,8 @@
 	debugfs_create_devm_seqfile(dev->mt76.dev, "twt_stats", dir,
 				    bersa_twt_stats);
 	debugfs_create_file("ser_trigger", 0200, dir, dev, &fops_ser_trigger);
+	debugfs_create_file("rf_regval", 0600, dir, dev, &fops_rf_regval);
+
 	if (!dev->dbdc_support || phy->band_idx) {
 		debugfs_create_u32("dfs_hw_pattern", 0400, dir,
 				   &dev->hw_pattern);
@@ -954,7 +986,7 @@
 	} hdr = {
 		.version = 0x1,
 		.magic = cpu_to_le32(FW_BIN_LOG_MAGIC),
-		.msg_type = PKT_TYPE_RX_FW_MONITOR,
+		.msg_type = cpu_to_le16(PKT_TYPE_RX_FW_MONITOR),
 	};
 
 	if (!dev->relay_fwlog)
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/eeprom.c b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/eeprom.c
index efc0882..ab8eede 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/eeprom.c
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/eeprom.c
@@ -114,10 +114,28 @@
 	/* val = eeprom[MT_EE_WIFI_CONF + phy->band_idx]; */
 	/* val = FIELD_GET(MT_EE_WIFI_CONF0_BAND_SEL, val); */
 
+	/* switch (val) { */
+	/* 	case MT_EE_V2_BAND_SEL_5GHZ: */
+	/* 		phy->mt76->cap.has_5ghz = true; */
+	/* 		return; */
+	/* 	case MT_EE_V2_BAND_SEL_6GHZ: */
+	/* 		phy->mt76->cap.has_6ghz = true; */
+	/* 		return; */
+	/* 	case MT_EE_V2_BAND_SEL_5GHZ_6GHZ: */
+	/* 		phy->mt76->cap.has_5ghz = true; */
+	/* 		phy->mt76->cap.has_6ghz = true; */
+	/* 		return; */
+	/* 	default */
+	/* 		phy->mt76->cap.has_2ghz = true; */
+	/* 		return; */
+	/* } */
+
 	if (phy->band_idx == 2)
 		phy->mt76->cap.has_2ghz = true;
-	else
+	else {
 		phy->mt76->cap.has_5ghz = true;
+		/* phy->mt76->cap.has_6ghz = true; */
+	}
 }
 
 void bersa_eeprom_parse_hw_cap(struct bersa_dev *dev,
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/eeprom.h b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/eeprom.h
index 21c861e..21e04e9 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/eeprom.h
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/eeprom.h
@@ -76,6 +76,13 @@
 	MT_EE_BAND_SEL_DUAL,
 };
 
+enum {
+	MT_EE_V2_BAND_SEL_2GHZ,
+	MT_EE_V2_BAND_SEL_5GHZ,
+	MT_EE_V2_BAND_SEL_6GHZ,
+	MT_EE_V2_BAND_SEL_5GHZ_6GHZ,
+};
+
 enum bersa_sku_rate_group {
 	SKU_CCK,
 	SKU_OFDM,
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/init.c b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/init.c
index 5594e63..613ca84 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/init.c
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/init.c
@@ -50,15 +50,22 @@
 	int i = to_sensor_dev_attr(attr)->index;
 	int temperature;
 
-	if (i)
-		return sprintf(buf, "%u\n", phy->throttle_temp[i - 1] * 1000);
-
-	temperature = bersa_mcu_get_temperature(phy);
-	if (temperature < 0)
-		return temperature;
-
-	/* display in millidegree celcius */
-	return sprintf(buf, "%u\n", temperature * 1000);
+	switch (i) {
+	case 0:
+		temperature = bersa_mcu_get_temperature(phy);
+		if (temperature < 0)
+			return temperature;
+		/* display in millidegree celcius */
+		return sprintf(buf, "%u\n", temperature * 1000);
+	case 1:
+	case 2:
+		return sprintf(buf, "%u\n",
+			       phy->throttle_temp[i - 1] * 1000);
+	case 3:
+		return sprintf(buf, "%hhu\n", phy->throttle_state);
+	default:
+		return -EINVAL;
+	}
 }
 
 static ssize_t bersa_thermal_temp_store(struct device *dev,
@@ -84,11 +91,13 @@
 static SENSOR_DEVICE_ATTR_RO(temp1_input, bersa_thermal_temp, 0);
 static SENSOR_DEVICE_ATTR_RW(temp1_crit, bersa_thermal_temp, 1);
 static SENSOR_DEVICE_ATTR_RW(temp1_max, bersa_thermal_temp, 2);
+static SENSOR_DEVICE_ATTR_RO(throttle1, bersa_thermal_temp, 3);
 
 static struct attribute *bersa_hwmon_attrs[] = {
 	&sensor_dev_attr_temp1_input.dev_attr.attr,
 	&sensor_dev_attr_temp1_crit.dev_attr.attr,
 	&sensor_dev_attr_temp1_max.dev_attr.attr,
+	&sensor_dev_attr_throttle1.dev_attr.attr,
 	NULL,
 };
 ATTRIBUTE_GROUPS(bersa_hwmon);
@@ -97,7 +106,7 @@
 bersa_thermal_get_max_throttle_state(struct thermal_cooling_device *cdev,
 				      unsigned long *state)
 {
-	*state = BERSA_THERMAL_THROTTLE_MAX;
+	*state = BERSA_CDEV_THROTTLE_MAX;
 
 	return 0;
 }
@@ -108,7 +117,7 @@
 {
 	struct bersa_phy *phy = cdev->devdata;
 
-	*state = phy->throttle_state;
+	*state = phy->cdev_state;
 
 	return 0;
 }
@@ -118,22 +127,27 @@
 				      unsigned long state)
 {
 	struct bersa_phy *phy = cdev->devdata;
+	u8 throttling = BERSA_THERMAL_THROTTLE_MAX - state;
 	int ret;
 
-	if (state > BERSA_THERMAL_THROTTLE_MAX)
+	if (state > BERSA_CDEV_THROTTLE_MAX)
 		return -EINVAL;
 
 	if (phy->throttle_temp[0] > phy->throttle_temp[1])
 		return 0;
 
-	if (state == phy->throttle_state)
+	if (state == phy->cdev_state)
 		return 0;
 
-	ret = bersa_mcu_set_thermal_throttling(phy, state);
+	/*
+	 * cooling_device convention: 0 = no cooling, more = more cooling
+	 * mcu convention: 1 = max cooling, more = less cooling
+	 */
+	ret = bersa_mcu_set_thermal_throttling(phy, throttling);
 	if (ret)
 		return ret;
 
-	phy->throttle_state = state;
+	phy->cdev_state = state;
 
 	return 0;
 }
@@ -186,7 +200,8 @@
 	phy->throttle_temp[0] = 110;
 	phy->throttle_temp[1] = 120;
 
-	return 0;
+	return bersa_mcu_set_thermal_throttling(phy,
+						 BERSA_THERMAL_THROTTLE_MAX);
 }
 
 static void bersa_led_set_config(struct led_classdev *led_cdev,
@@ -422,6 +437,8 @@
 
 	/* mt76_rmw_field(dev, MT_MDP_DCR1, MT_MDP_DCR1_MAX_RX_LEN, 0x680); */
 
+	/* mt76_clear(dev, MT_MDP_DCR2, MT_MDP_DCR2_RX_TRANS_SHORT); */
+
 	/* enable hardware de-agg */
 	/* mt76_set(dev, MT_MDP_DCR0, MT_MDP_DCR0_DAMSDU_EN); */
 
@@ -604,7 +621,7 @@
 	bersa_txbf_init(dev);
 }
 
-static void bersa_wfsys_reset(struct bersa_dev *dev)
+void bersa_wfsys_reset(struct bersa_dev *dev)
 {
 	if (is_mt7902(&dev->mt76))
 		return;
@@ -648,11 +665,6 @@
 			return ret;
 	}
 
-	/* If MCU was already running, it is likely in a bad state */
-	if (mt76_get_field(dev, MT_TOP_MISC, MT_TOP_MISC_FW_STATE) >
-	    FW_STATE_FW_DOWNLOAD)
-		bersa_wfsys_reset(dev);
-
 	ret = bersa_dma_init(dev);
 	if (ret)
 		return ret;
@@ -660,14 +672,8 @@
 	set_bit(MT76_STATE_INITIALIZED, &dev->mphy.state);
 
 	ret = bersa_mcu_init(dev);
-	if (ret) {
-		/* Reset and try again */
-		bersa_wfsys_reset(dev);
-
-		ret = bersa_mcu_init(dev);
-		if (ret)
-			return ret;
-	}
+	if (ret)
+		return ret;
 
 	ret = bersa_eeprom_init(dev);
 	if (ret < 0)
@@ -776,23 +782,26 @@
 	elem->phy_cap_info[3] |= IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER;
 	elem->phy_cap_info[4] |= IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER;
 
-	/* num_snd_dim
-	 * for bersa, max supported nss is 2 for bw > 80MHz
-	 */
-	c = (nss - 1) |
-	    IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_2;
+	c = FIELD_PREP(IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK,
+		       nss - 1) |
+	    FIELD_PREP(IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_MASK,
+		       nss - 1);
 	elem->phy_cap_info[5] |= c;
 
 	c = IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB |
 	    IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB;
 	elem->phy_cap_info[6] |= c;
+
+	c = IEEE80211_HE_PHY_CAP7_STBC_TX_ABOVE_80MHZ |
+	    IEEE80211_HE_PHY_CAP7_STBC_RX_ABOVE_80MHZ;
+	elem->phy_cap_info[7] |= c;
 }
 
 static void
 bersa_gen_ppe_thresh(u8 *he_ppet, int nss)
 {
 	u8 i, ppet_bits, ppet_size, ru_bit_mask = 0x7; /* HE80 */
-	u8 ppet16_ppet8_ru3_ru0[] = {0x1c, 0xc7, 0x71};
+	static const u8 ppet16_ppet8_ru3_ru0[] = {0x1c, 0xc7, 0x71};
 
 	he_ppet[0] = FIELD_PREP(IEEE80211_PPE_THRES_NSS_MASK, nss - 1) |
 		     FIELD_PREP(IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK,
@@ -865,7 +874,7 @@
 		if (band == NL80211_BAND_2GHZ)
 			he_cap_elem->phy_cap_info[0] =
 				IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G;
-		else if (band == NL80211_BAND_5GHZ)
+		else
 			he_cap_elem->phy_cap_info[0] =
 				IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
 				IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G |
@@ -904,7 +913,7 @@
 			if (band == NL80211_BAND_2GHZ)
 				he_cap_elem->phy_cap_info[0] |=
 					IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_2G;
-			else if (band == NL80211_BAND_5GHZ)
+			else
 				he_cap_elem->phy_cap_info[0] |=
 					IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_5G;
 
@@ -953,6 +962,21 @@
 			he_cap_elem->phy_cap_info[9] |=
 				IEEE80211_HE_PHY_CAP9_NOMIMAL_PKT_PADDING_16US;
 		}
+
+		if (band == NL80211_BAND_6GHZ) {
+			u16 cap = IEEE80211_HE_6GHZ_CAP_TX_ANTPAT_CONS |
+				  IEEE80211_HE_6GHZ_CAP_RX_ANTPAT_CONS;
+
+			cap |= u16_encode_bits(IEEE80211_HT_MPDU_DENSITY_8,
+					       IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START) |
+			       u16_encode_bits(IEEE80211_VHT_MAX_AMPDU_1024K,
+					       IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP) |
+			       u16_encode_bits(IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454,
+					       IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN);
+
+			data[idx].he_6ghz_capa.capa = cpu_to_le16(cap);
+		}
+
 		idx++;
 	}
 
@@ -982,6 +1006,15 @@
 		band->iftype_data = data;
 		band->n_iftype_data = n;
 	}
+
+	if (phy->mt76->cap.has_6ghz) {
+		data = phy->iftype[NL80211_BAND_6GHZ];
+		n = bersa_init_he_caps(phy, NL80211_BAND_6GHZ, data);
+
+		band = &phy->mt76->sband_6g.sband;
+		band->iftype_data = data;
+		band->n_iftype_data = n;
+	}
 }
 
 static void bersa_unregister_ext_phy(struct bersa_dev *dev)
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/mac.c b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/mac.c
index 745ee3a..2d48a1a 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/mac.c
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/mac.c
@@ -226,8 +226,8 @@
 	u32 ru_h, ru_l;
 	u8 ru, offs = 0;
 
-	ru_l = FIELD_GET(MT_PRXV_HE_RU_ALLOC_L, le32_to_cpu(rxv[0]));
-	ru_h = FIELD_GET(MT_PRXV_HE_RU_ALLOC_H, le32_to_cpu(rxv[1]));
+	ru_l = le32_get_bits(rxv[0], MT_PRXV_HE_RU_ALLOC_L);
+	ru_h = le32_get_bits(rxv[1], MT_PRXV_HE_RU_ALLOC_H);
 	ru = (u8)(ru_l | ru_h << 4);
 
 	status->bw = RATE_INFO_BW_HE_RU;
@@ -309,7 +309,7 @@
 }
 
 static void
-bersa_mac_decode_he_radiotap(struct sk_buff *skb, __le32 *rxv, u32 mode)
+bersa_mac_decode_he_radiotap(struct sk_buff *skb, __le32 *rxv, u8 mode)
 {
 	struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
 	static const struct ieee80211_radiotap_he known = {
@@ -349,14 +349,16 @@
 	case MT_PHY_TYPE_HE_SU:
 		he->data1 |= HE_BITS(DATA1_FORMAT_SU) |
 			     HE_BITS(DATA1_UL_DL_KNOWN) |
-			     HE_BITS(DATA1_BEAM_CHANGE_KNOWN);
+			     HE_BITS(DATA1_BEAM_CHANGE_KNOWN) |
+			     HE_BITS(DATA1_BW_RU_ALLOC_KNOWN);
 
 		he->data3 |= HE_PREP(DATA3_BEAM_CHANGE, BEAM_CHNG, rxv[14]) |
 			     HE_PREP(DATA3_UL_DL, UPLINK, rxv[2]);
 		break;
 	case MT_PHY_TYPE_HE_EXT_SU:
 		he->data1 |= HE_BITS(DATA1_FORMAT_EXT_SU) |
-			     HE_BITS(DATA1_UL_DL_KNOWN);
+			     HE_BITS(DATA1_UL_DL_KNOWN) |
+			     HE_BITS(DATA1_BW_RU_ALLOC_KNOWN);
 
 		he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK, rxv[2]);
 		break;
@@ -398,9 +400,9 @@
 	struct ieee80211_sta *sta;
 	struct ieee80211_vif *vif;
 	struct ieee80211_hdr hdr;
-	__le32 qos_ctrl, ht_ctrl;
+	u16 frame_control;
 
-	if (FIELD_GET(MT_RXD3_NORMAL_ADDR_TYPE, le32_to_cpu(rxd[3])) !=
+	if (le32_get_bits(rxd[3], MT_RXD3_NORMAL_ADDR_TYPE) !=
 	    MT_RXD3_NORMAL_U2M)
 		return -EINVAL;
 
@@ -414,16 +416,15 @@
 	vif = container_of((void *)msta->vif, struct ieee80211_vif, drv_priv);
 
 	/* store the info from RXD and ethhdr to avoid being overridden */
-	hdr.frame_control = FIELD_GET(MT_RXD6_FRAME_CONTROL, rxd[6]);
-	hdr.seq_ctrl = FIELD_GET(MT_RXD8_SEQ_CTRL, rxd[8]);
-	qos_ctrl = FIELD_GET(MT_RXD8_QOS_CTL, rxd[8]);
-	ht_ctrl = FIELD_GET(MT_RXD9_HT_CONTROL, rxd[9]);
-
+	frame_control = le32_get_bits(rxd[6], MT_RXD6_FRAME_CONTROL);
+	hdr.frame_control = cpu_to_le16(frame_control);
+	hdr.seq_ctrl = cpu_to_le16(le32_get_bits(rxd[8], MT_RXD8_SEQ_CTRL));
 	hdr.duration_id = 0;
+
 	ether_addr_copy(hdr.addr1, vif->addr);
 	ether_addr_copy(hdr.addr2, sta->addr);
-	switch (le16_to_cpu(hdr.frame_control) &
-		(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) {
+	switch (frame_control & (IEEE80211_FCTL_TODS |
+				 IEEE80211_FCTL_FROMDS)) {
 	case 0:
 		ether_addr_copy(hdr.addr3, vif->bss_conf.bssid);
 		break;
@@ -445,15 +446,22 @@
 	if (eth_hdr->h_proto == cpu_to_be16(ETH_P_AARP) ||
 	    eth_hdr->h_proto == cpu_to_be16(ETH_P_IPX))
 		ether_addr_copy(skb_push(skb, ETH_ALEN), bridge_tunnel_header);
-	else if (eth_hdr->h_proto >= cpu_to_be16(ETH_P_802_3_MIN))
+	else if (be16_to_cpu(eth_hdr->h_proto) >= ETH_P_802_3_MIN)
 		ether_addr_copy(skb_push(skb, ETH_ALEN), rfc1042_header);
 	else
 		skb_pull(skb, 2);
 
 	if (ieee80211_has_order(hdr.frame_control))
-		memcpy(skb_push(skb, 2), &ht_ctrl, 2);
-	if (ieee80211_is_data_qos(hdr.frame_control))
-		memcpy(skb_push(skb, 2), &qos_ctrl, 2);
+		memcpy(skb_push(skb, IEEE80211_HT_CTL_LEN), &rxd[9],
+		       IEEE80211_HT_CTL_LEN);
+	if (ieee80211_is_data_qos(hdr.frame_control)) {
+		__le16 qos_ctrl;
+
+		qos_ctrl = cpu_to_le16(le32_get_bits(rxd[8], MT_RXD8_QOS_CTL));
+		memcpy(skb_push(skb, IEEE80211_QOS_CTL_LEN), &qos_ctrl,
+		       IEEE80211_QOS_CTL_LEN);
+	}
+
 	if (ieee80211_has_a4(hdr.frame_control))
 		memcpy(skb_push(skb, sizeof(hdr)), &hdr, sizeof(hdr));
 	else
@@ -466,10 +474,10 @@
 bersa_mac_fill_rx_rate(struct bersa_dev *dev,
 			struct mt76_rx_status *status,
 			struct ieee80211_supported_band *sband,
-			__le32 *rxv)
+			__le32 *rxv, u8 *mode)
 {
 	u32 v0, v2;
-	u8 stbc, gi, bw, dcm, mode, nss;
+	u8 stbc, gi, bw, dcm, nss;
 	int i, idx;
 	bool cck = false;
 
@@ -481,11 +489,11 @@
 
 	stbc = FIELD_GET(MT_PRXV_HT_STBC, v2);
 	gi = FIELD_GET(MT_PRXV_HT_SHORT_GI, v2);
-	mode = FIELD_GET(MT_PRXV_TX_MODE, v2);
+	*mode = FIELD_GET(MT_PRXV_TX_MODE, v2);
 	dcm = FIELD_GET(MT_PRXV_DCM, v2);
 	bw = FIELD_GET(MT_PRXV_FRAME_MODE, v2);
 
-	switch (mode) {
+	switch (*mode) {
 	case MT_PHY_TYPE_CCK:
 		cck = true;
 		fallthrough;
@@ -505,7 +513,7 @@
 		status->encoding = RX_ENC_VHT;
 		if (gi)
 			status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
-		if (i > 9)
+		if (i > 11)
 			return -EINVAL;
 		break;
 	case MT_PHY_TYPE_HE_MU:
@@ -530,7 +538,7 @@
 	case IEEE80211_STA_RX_BW_20:
 		break;
 	case IEEE80211_STA_RX_BW_40:
-		if (mode & MT_PHY_TYPE_HE_EXT_SU &&
+		if (*mode & MT_PHY_TYPE_HE_EXT_SU &&
 		    (idx & MT_PRXV_TX_ER_SU_106T)) {
 			status->bw = RATE_INFO_BW_HE_RU;
 			status->he_ru =
@@ -550,7 +558,7 @@
 	}
 
 	status->enc_flags |= RX_ENC_FLAG_STBC_MASK * stbc;
-	if (mode < MT_PHY_TYPE_HE_SU && gi)
+	if (*mode < MT_PHY_TYPE_HE_SU && gi)
 		status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
 
 	return 0;
@@ -565,7 +573,6 @@
 	struct ieee80211_supported_band *sband;
 	__le32 *rxd = (__le32 *)skb->data;
 	__le32 *rxv = NULL;
-	u32 mode = 0;
 	u32 rxd0 = le32_to_cpu(rxd[0]);
 	u32 rxd1 = le32_to_cpu(rxd[1]);
 	u32 rxd2 = le32_to_cpu(rxd[2]);
@@ -574,10 +581,10 @@
 	u32 csum_mask = MT_RXD0_NORMAL_IP_SUM | MT_RXD0_NORMAL_UDP_TCP_SUM;
 	bool unicast, insert_ccmp_hdr = false;
 	u8 remove_pad, amsdu_info;
+	u8 mode = 0, qos_ctl = 0;
 	bool hdr_trans;
 	u16 hdr_gap;
 	u16 seq_ctrl = 0;
-	u8 qos_ctl = 0;
 	__le16 fc = 0;
 	int idx;
 	u8 band_idx;
@@ -621,6 +628,8 @@
 	status->band = mphy->chandef.chan->band;
 	if (status->band == NL80211_BAND_5GHZ)
 		sband = &mphy->sband_5g.sband;
+	else if (status->band == NL80211_BAND_6GHZ)
+		sband = &mphy->sband_6g.sband;
 	else
 		sband = &mphy->sband_2g.sband;
 
@@ -741,7 +750,7 @@
 		}
 
 		/* TODO: parse rx rate from rxv */
-		ret = bersa_mac_fill_rx_rate(dev, status, sband, rxv);
+		ret = bersa_mac_fill_rx_rate(dev, status, sband, rxv, &mode);
 		if (ret < 0)
 			return ret;
 	}
@@ -811,10 +820,6 @@
 	if (!status->wcid || !ieee80211_is_data_qos(fc))
 		return 0;
 
-	/* drop no data frame */
-	if (fc & cpu_to_le16(IEEE80211_STYPE_NULLFUNC))
-		return -EINVAL;
-
 	status->aggr = unicast &&
 		       !ieee80211_is_qos_nullfunc(fc);
 	status->qos_ctl = qos_ctl;
@@ -837,12 +842,18 @@
 	u8 snr;
 	int i;
 
-	phy_idx = FIELD_GET(MT_RXV_HDR_BAND_IDX, le32_to_cpu(rxv_hdr[1]));
-	if (phy_idx == MT_EXT_PHY)
+	phy_idx = le32_get_bits(rxv_hdr[1], MT_RXV_HDR_BAND_IDX);
+	if (phy_idx == MT_EXT_PHY) {
 		phy = bersa_ext_phy(dev);
+		if (!phy)
+			goto out;
+	}
 
-	if (phy_idx == MT_TRI_PHY)
+	if (phy_idx == MT_TRI_PHY) {
 		phy = bersa_tri_phy(dev);
+		if (!phy)
+			goto out;
+	}
 
 	rcpi = le32_to_cpu(rxv[6]);
 	ib_rssi = le32_to_cpu(rxv[7]);
@@ -867,8 +878,8 @@
 
 	phy->test.last_freq_offset = foe;
 	phy->test.last_snr = snr;
+out:
 #endif
-
 	dev_kfree_skb(skb);
 }
 
@@ -994,6 +1005,7 @@
 
 	u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
 	u8 fc_type, fc_stype;
+	u16 ethertype;
 	bool wmm = false;
 	u32 val;
 
@@ -1007,7 +1019,8 @@
 	val = FIELD_PREP(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_802_3) |
 	      FIELD_PREP(MT_TXD1_TID, tid);
 
-	if (be16_to_cpu(skb->protocol) >= ETH_P_802_3_MIN)
+	ethertype = get_unaligned_be16(&skb->data[12]);
+	if (ethertype >= ETH_P_802_3_MIN)
 		val |= MT_TXD1_ETH_802_3;
 
 	txwi[1] |= cpu_to_le32(val);
@@ -1181,8 +1194,7 @@
 	val = FIELD_PREP(MT_TXD1_WLAN_IDX, wcid->idx) |
 	      FIELD_PREP(MT_TXD1_OWN_MAC, omac_idx);
 
-	if (band_idx &&
-	    q_idx >= MT_LMAC_ALTX0 && q_idx <= MT_LMAC_BCN0)
+	if (band_idx)
 		val |= FIELD_PREP(MT_TXD1_TGID, band_idx);
 
 	txwi[1] = cpu_to_le32(val);
@@ -1328,10 +1340,10 @@
 	u16 fc, tid;
 	u32 val;
 
-	if (!sta || !sta->ht_cap.ht_supported)
+	if (!sta || !(sta->ht_cap.ht_supported || sta->he_cap.has_he))
 		return;
 
-	tid = FIELD_GET(MT_TXD1_TID, le32_to_cpu(txwi[1]));
+	tid = le32_get_bits(txwi[1], MT_TXD1_TID);
 	if (tid >= 6) /* skip VO queue */
 		return;
 
@@ -1379,7 +1391,7 @@
 		if (likely(t->skb->protocol != cpu_to_be16(ETH_P_PAE)))
 			bersa_tx_check_aggr(sta, txwi);
 	} else {
-		wcid_idx = FIELD_GET(MT_TXD1_WLAN_IDX, le32_to_cpu(txwi[1]));
+		wcid_idx = le32_get_bits(txwi[1], MT_TXD1_WLAN_IDX);
 	}
 
 	__mt76_tx_complete_skb(mdev, wcid_idx, t->skb, free_list);
@@ -1418,12 +1430,7 @@
 		mt76_queue_tx_cleanup(dev, mphy_tri->q_tx[MT_TXQ_BE], false);
 	}
 
-	/*
-	 * TODO: MT_TX_FREE_LATENCY is msdu time from the TXD is queued into PLE,
-	 * to the time ack is received or dropped by hw (air + hw queue time).
-	 * Should avoid accessing WTBL to get Tx airtime, and use it instead.
-	 */
-	total = FIELD_GET(MT_TX_FREE_MSDU_CNT, le16_to_cpu(free->ctrl));
+	total = le16_get_bits(free->ctrl, MT_TX_FREE_MSDU_CNT);
 	v3 = (FIELD_GET(MT_TX_FREE_VER, txd) >= 0x4);
 	if (WARN_ON_ONCE((void *)&free->info[total >> v3] > end))
 		return;
@@ -1539,6 +1546,8 @@
 
 		if (mphy->chandef.chan->band == NL80211_BAND_5GHZ)
 			sband = &mphy->sband_5g.sband;
+		else if (mphy->chandef.chan->band == NL80211_BAND_6GHZ)
+			sband = &mphy->sband_6g.sband;
 		else
 			sband = &mphy->sband_2g.sband;
 
@@ -1612,18 +1621,13 @@
 	struct mt76_wcid *wcid;
 	__le32 *txs_data = data;
 	u16 wcidx;
-	u32 txs;
 	u8 pid;
 
-	txs = le32_to_cpu(txs_data[0]);
-	if (FIELD_GET(MT_TXS0_TXS_FORMAT, txs) > 1)
+	if (le32_get_bits(txs_data[0], MT_TXS0_TXS_FORMAT) > 1)
 		return;
 
-	txs = le32_to_cpu(txs_data[2]);
-	wcidx = FIELD_GET(MT_TXS2_WCID, txs);
-
-	txs = le32_to_cpu(txs_data[3]);
-	pid = FIELD_GET(MT_TXS3_PID, txs);
+	wcidx = le32_get_bits(txs_data[2], MT_TXS2_WCID);
+	pid = le32_get_bits(txs_data[3], MT_TXS3_PID);
 
 	if (pid < MT_PACKET_ID_FIRST)
 		return;
@@ -1660,7 +1664,7 @@
 	__le32 *end = (__le32 *)&rxd[len / 4];
 	enum rx_pkt_type type;
 
-	type = FIELD_GET(MT_RXD0_PKT_TYPE, le32_to_cpu(rxd[0]));
+	type = le32_get_bits(rxd[0], MT_RXD0_PKT_TYPE);
 	if (q == MT_RXQ_MCU || q == MT_RXQ_MCU_WA ||
 	    q == MT_RXQ_MAIN_WA || q == MT_RXQ_EXT_WA || q == MT_RXQ_TRI_WA) {
 		enum rx_pkt_type sw_type = FIELD_GET(MT_RXD0_SW_PKT_TYPE_MASK, le32_to_cpu(rxd[0]));
@@ -1693,7 +1697,7 @@
 	__le32 *end = (__le32 *)&skb->data[skb->len];
 	enum rx_pkt_type type;
 
-	type = FIELD_GET(MT_RXD0_PKT_TYPE, le32_to_cpu(rxd[0]));
+	type = le32_get_bits(rxd[0], MT_RXD0_PKT_TYPE);
 	if (q == MT_RXQ_MCU || q == MT_RXQ_MCU_WA ||
 	    q == MT_RXQ_MAIN_WA || q == MT_RXQ_EXT_WA || q == MT_RXQ_TRI_WA) {
 		enum rx_pkt_type sw_type = FIELD_GET(MT_RXD0_SW_PKT_TYPE_MASK, le32_to_cpu(rxd[0]));
@@ -1800,7 +1804,7 @@
 	u32 ofdm = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, 60) |
 		   FIELD_PREP(MT_TIMEOUT_VAL_CCA, 28);
 	int offset;
-	bool is_5ghz = phy->mt76->chandef.chan->band == NL80211_BAND_5GHZ;
+	bool a_band = !(phy->mt76->chandef.chan->band == NL80211_BAND_2GHZ);
 
 	if (!test_bit(MT76_STATE_RUNNING, &phy->mt76->state))
 		return;
@@ -1824,7 +1828,7 @@
 	mt76_wr(dev, MT_TMAC_CDTR(phy->band_idx), cck + reg_offset);
 	mt76_wr(dev, MT_TMAC_ODTR(phy->band_idx), ofdm + reg_offset);
 	mt76_wr(dev, MT_TMAC_ICR0(phy->band_idx),
-		FIELD_PREP(MT_IFS_EIFS_OFDM, is_5ghz ? 84 : 78) |
+		FIELD_PREP(MT_IFS_EIFS_OFDM, a_band ? 84 : 78) |
 		FIELD_PREP(MT_IFS_RIFS, 2) |
 		FIELD_PREP(MT_IFS_SIFS, 10) |
 		FIELD_PREP(MT_IFS_SLOT, phy->slottime));
@@ -1832,7 +1836,7 @@
 	mt76_wr(dev, MT_TMAC_ICR1(phy->band_idx),
 		FIELD_PREP(MT_IFS_EIFS_CCK, 314));
 
-	if (phy->slottime < 20 || is_5ghz)
+	if (phy->slottime < 20 || a_band)
 		val = BERSA_CFEND_RATE_DEFAULT;
 	else
 		val = BERSA_CFEND_RATE_11B;
@@ -2331,10 +2335,23 @@
 
 static int bersa_dfs_start_rdd(struct bersa_dev *dev, int chain)
 {
-	int err;
+	int err, region;
+
+	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;
+	}
 
 	err = bersa_mcu_rdd_cmd(dev, RDD_START, chain,
-				MT_RX_SEL0, 0);
+				MT_RX_SEL0, region);
 	if (err < 0)
 		return err;
 
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/main.c b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/main.c
index d55d3ba..1b07905 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/main.c
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/main.c
@@ -44,10 +44,6 @@
 		if (ret)
 			goto out;
 
-		/* 	ret = bersa_mcu_set_scs(dev, dev->phy.band_idx, true); */
-		/* 	if (ret) */
-		/* 		goto out; */
-
 		/* 	bersa_mac_enable_nf(dev, dev->phy.band_idx); */
 	}
 
@@ -56,10 +52,6 @@
 	/* 	if (ret) */
 	/* 		goto out; */
 
-	/* 	ret = bersa_mcu_set_scs(dev, phy->band_idx, true); */
-	/* 	if (ret) */
-	/* 		goto out; */
-
 	/* 	bersa_mac_enable_nf(dev, phy->band_idx); */
 	/* } */
 
@@ -181,14 +173,14 @@
 
 	for (i = 0; i < ARRAY_SIZE(mvif->bitrate_mask.control); i++) {
 		mvif->bitrate_mask.control[i].gi = NL80211_TXRATE_DEFAULT_GI;
-		mvif->bitrate_mask.control[i].he_gi = GENMASK(7, 0);
-		mvif->bitrate_mask.control[i].he_ltf = GENMASK(7, 0);
+		mvif->bitrate_mask.control[i].he_gi = 0xff;
+		mvif->bitrate_mask.control[i].he_ltf = 0xff;
 		mvif->bitrate_mask.control[i].legacy = GENMASK(31, 0);
-		memset(mvif->bitrate_mask.control[i].ht_mcs, GENMASK(7, 0),
+		memset(mvif->bitrate_mask.control[i].ht_mcs, 0xff,
 		       sizeof(mvif->bitrate_mask.control[i].ht_mcs));
-		memset(mvif->bitrate_mask.control[i].vht_mcs, GENMASK(15, 0),
+		memset(mvif->bitrate_mask.control[i].vht_mcs, 0xff,
 		       sizeof(mvif->bitrate_mask.control[i].vht_mcs));
-		memset(mvif->bitrate_mask.control[i].he_mcs, GENMASK(15, 0),
+		memset(mvif->bitrate_mask.control[i].he_mcs, 0xff,
 		       sizeof(mvif->bitrate_mask.control[i].he_mcs));
 	}
 }
@@ -211,8 +203,8 @@
 	    is_zero_ether_addr(vif->addr))
 		phy->monitor_vif = vif;
 
-	mvif->mt76.idx = ffs(~dev->mt76.vif_mask) - 1;
-	if (mvif->mt76.idx >= BERSA_MAX_INTERFACES) {
+	mvif->mt76.idx = __ffs64(~dev->mt76.vif_mask);
+	if (mvif->mt76.idx >= (BERSA_MAX_INTERFACES << dev->dbdc_support)) {
 		ret = -ENOSPC;
 		goto out;
 	}
@@ -241,7 +233,7 @@
 	if (ret)
 		goto out;
 
-	dev->mt76.vif_mask |= BIT(mvif->mt76.idx);
+	dev->mt76.vif_mask |= BIT_ULL(mvif->mt76.idx);
 	phy->omac_mask |= BIT_ULL(mvif->mt76.omac_idx);
 
 	/* TODO: force this to 201 during devlopment stage */
@@ -261,7 +253,7 @@
 	rcu_assign_pointer(dev->mt76.wcid[idx], &mvif->sta.wcid);
 	if (vif->txq) {
 		mtxq = (struct mt76_txq *)vif->txq->drv_priv;
-		mtxq->wcid = &mvif->sta.wcid;
+		mtxq->wcid = idx;
 	}
 
 	if (vif->type != NL80211_IFTYPE_AP &&
@@ -306,7 +298,7 @@
 	rcu_assign_pointer(dev->mt76.wcid[idx], NULL);
 
 	mutex_lock(&dev->mt76.mutex);
-	dev->mt76.vif_mask &= ~BIT(mvif->mt76.idx);
+	dev->mt76.vif_mask &= ~BIT_ULL(mvif->mt76.idx);
 	phy->omac_mask &= ~BIT_ULL(mvif->mt76.omac_idx);
 	mutex_unlock(&dev->mt76.mutex);
 
@@ -1080,7 +1072,7 @@
 	else
 		clear_bit(MT_WCID_FLAG_4ADDR, &msta->wcid.flags);
 
-	mt76_connac_mcu_wtbl_update_hdr_trans(&dev->mt76, vif, sta);
+	bersa_mcu_wtbl_update_hdr_trans(dev, vif, sta);
 }
 
 static void bersa_sta_set_decap_offload(struct ieee80211_hw *hw,
@@ -1096,7 +1088,7 @@
 	else
 		clear_bit(MT_WCID_FLAG_HDR_TRANS, &msta->wcid.flags);
 
-	mt76_connac_mcu_wtbl_update_hdr_trans(&dev->mt76, vif, sta);
+	bersa_mcu_wtbl_update_hdr_trans(dev, vif, sta);
 }
 
 static const char bersa_gstrings_stats[][ETH_GSTRING_LEN] = {
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/mcu.c b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/mcu.c
index 04300c6..5276552 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/mcu.c
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/mcu.c
@@ -1446,6 +1446,32 @@
 		     FIELD_PREP(IEEE80211_HT_AMPDU_PARM_DENSITY, mm);
 }
 
+static void
+bersa_mcu_sta_hdr_trans_tlv(struct bersa_dev *dev, struct sk_buff *skb,
+			 struct ieee80211_vif *vif, struct ieee80211_sta *sta)
+{
+	struct sta_rec_hdr_trans *hdr_trans;
+	struct tlv *tlv;
+
+	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HDR_TRANS, sizeof(*hdr_trans));
+	hdr_trans = (struct sta_rec_hdr_trans*) tlv;
+	hdr_trans->dis_rx_hdr_tran = 0;
+	if (vif->type == NL80211_IFTYPE_STATION)
+		hdr_trans->to_ds = true;
+	else
+		hdr_trans->from_ds = true;
+
+	struct mt76_wcid *wcid;
+	wcid = (struct mt76_wcid *)sta->drv_priv;
+	if (!wcid)
+		return;
+
+	if (test_bit(MT_WCID_FLAG_4ADDR, &wcid->flags)) {
+		hdr_trans->to_ds = true;
+		hdr_trans->from_ds = true;
+	}
+}
+
 static enum mcu_mmps_mode
 bersa_mcu_get_mmps_mode(enum ieee80211_smps_mode smps)
 {
@@ -1684,7 +1710,7 @@
 			cap |= STA_CAP_TX_STBC;
 		if (sta->ht_cap.cap & IEEE80211_HT_CAP_RX_STBC)
 			cap |= STA_CAP_RX_STBC;
-		if (mvif->cap.ldpc &&
+		if (mvif->cap.ht_ldpc &&
 		    (sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING))
 			cap |= STA_CAP_LDPC;
 
@@ -1710,7 +1736,7 @@
 			cap |= STA_CAP_VHT_TX_STBC;
 		if (sta->vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_1)
 			cap |= STA_CAP_VHT_RX_STBC;
-		if (mvif->cap.ldpc &&
+		if (mvif->cap.vht_ldpc &&
 		    (sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC))
 			cap |= STA_CAP_VHT_LDPC;
 
@@ -1747,7 +1773,7 @@
 	 * once dev->rc_work changes the settings driver should also
 	 * update sta_rec_he here.
 	 */
-	if (sta->he_cap.has_he && changed)
+	if (changed)
 		bersa_mcu_sta_he_tlv(skb, sta, vif);
 
 	/* sta_rec_ra accommodates BW, NSS and only MCS range format
@@ -1842,6 +1868,8 @@
 		bersa_mcu_sta_muru_tlv(skb, sta, vif);
 		/* starec bfee */
 		bersa_mcu_sta_bfee_tlv(dev, skb, vif, sta);
+		/* starec hdr trans */
+		bersa_mcu_sta_hdr_trans_tlv(dev, skb, vif, sta);
 	}
 
 	ret = bersa_mcu_add_group(dev, vif, sta);
@@ -2054,8 +2082,8 @@
 			      len);
 	if (ie && ie[1] >= sizeof(*ht)) {
 		ht = (void *)(ie + 2);
-		vc->ldpc |= !!(le16_to_cpu(ht->cap_info) &
-			       IEEE80211_HT_CAP_LDPC_CODING);
+		vc->ht_ldpc |= !!(le16_to_cpu(ht->cap_info) &
+				  IEEE80211_HT_CAP_LDPC_CODING);
 	}
 
 	ie = cfg80211_find_ie(WLAN_EID_VHT_CAPABILITY, mgmt->u.beacon.variable,
@@ -2066,7 +2094,7 @@
 		vht = (void *)(ie + 2);
 		bc = le32_to_cpu(vht->vht_cap_info);
 
-		vc->ldpc |= !!(bc & IEEE80211_VHT_CAP_RXLDPC);
+		vc->vht_ldpc |= !!(bc & IEEE80211_VHT_CAP_RXLDPC);
 		vc->vht_su_ebfer =
 			(bc & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE) &&
 			(pc & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE);
@@ -2090,6 +2118,8 @@
 
 		he = (void *)(ie + 3);
 
+		vc->he_ldpc =
+			HE_PHY(CAP1_LDPC_CODING_IN_PAYLOAD, pe->phy_cap_info[1]);
 		vc->he_su_ebfer =
 			HE_PHY(CAP3_SU_BEAMFORMER, he->phy_cap_info[3]) &&
 			HE_PHY(CAP3_SU_BEAMFORMER, pe->phy_cap_info[3]);
@@ -2786,22 +2816,6 @@
 				     MCU_WM_UNI_CMD(RX_HDR_TRANS), true);
 }
 
-int bersa_mcu_set_scs(struct bersa_dev *dev, u8 band, bool enable)
-{
-	struct {
-		__le32 cmd;
-		u8 band;
-		u8 enable;
-	} __packed req = {
-		.cmd = cpu_to_le32(SCS_ENABLE),
-		.band = band,
-		.enable = enable + 1,
-	};
-
-	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(SCS_CTRL), &req,
-				 sizeof(req), false);
-}
-
 int bersa_mcu_set_tx(struct bersa_dev *dev, struct ieee80211_vif *vif)
 {
 	struct bersa_vif *mvif = (struct bersa_vif *)vif->drv_priv;
@@ -3041,6 +3055,11 @@
 
 int bersa_mcu_set_chan_info(struct bersa_phy *phy, int tag)
 {
+	static const u8 ch_band[] = {
+		[NL80211_BAND_2GHZ] = 0,
+		[NL80211_BAND_5GHZ] = 1,
+		[NL80211_BAND_6GHZ] = 2,
+	};
 	struct bersa_dev *dev = phy->dev;
 	struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
 	int freq1 = chandef->center_freq1;
@@ -3078,7 +3097,7 @@
 		.tx_streams_num = hweight8(phy->mt76->antenna_mask),
 		.rx_streams = phy->mt76->antenna_mask,
 		.band_idx = phy->band_idx,
-		.channel_band = chandef->chan->band,
+		.channel_band = ch_band[chandef->chan->band],
 	};
 
 #ifdef CONFIG_NL80211_TESTMODE
@@ -3100,10 +3119,13 @@
 	}
 #endif
 
-	if (phy->mt76->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)
+	if (tag == UNI_CHANNEL_RX_PATH ||
+	    dev->mt76.hw->conf.flags & IEEE80211_CONF_MONITOR)
+		req.switch_reason = CH_SWITCH_NORMAL;
+	else if (phy->mt76->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)
 		req.switch_reason = CH_SWITCH_SCAN_BYPASS_DPD;
-	else if (phy->mt76->hw->conf.radar_enabled &&
-		 chandef->chan->dfs_state != NL80211_DFS_AVAILABLE)
+	else if (!cfg80211_reg_can_beacon(phy->mt76->hw->wiphy, chandef,
+					  NL80211_IFTYPE_AP))
 		req.switch_reason = CH_SWITCH_DFS;
 	else
 		req.switch_reason = CH_SWITCH_NORMAL;
@@ -3770,6 +3792,8 @@
 	case MT_PHY_TYPE_OFDM:
 		if (mphy->chandef.chan->band == NL80211_BAND_5GHZ)
 			sband = &mphy->sband_5g.sband;
+		else if (mphy->chandef.chan->band == NL80211_BAND_6GHZ)
+			sband = &mphy->sband_6g.sband;
 		else
 			sband = &mphy->sband_2g.sband;
 
@@ -4050,3 +4074,53 @@
 			  &req, sizeof(req), true);
 	return 0;
 }
+
+
+int bersa_mcu_wtbl_update_hdr_trans(struct bersa_dev *dev,
+			struct ieee80211_vif *vif, struct ieee80211_sta *sta)
+{
+	struct bersa_vif *mvif = (struct bersa_vif *)vif->drv_priv;
+	struct bersa_sta *msta;
+	struct sk_buff *skb;
+
+	msta = sta ? (struct bersa_sta *)sta->drv_priv : &mvif->sta;
+
+	skb = mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76,
+					    &msta->wcid);
+	if (IS_ERR(skb))
+		return PTR_ERR(skb);
+
+	/* starec hdr trans */
+	bersa_mcu_sta_hdr_trans_tlv(dev, skb, vif, sta);
+	return mt76_mcu_skb_send_msg(&dev->mt76, skb,
+				     MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true);
+}
+
+int bersa_mcu_rf_regval(struct bersa_dev *dev, u32 regidx, u32 *val, bool set)
+{
+	struct {
+		__le32 idx;
+		__le32 ofs;
+		__le32 data;
+	} __packed req = {
+	.idx = cpu_to_le32(u32_get_bits(regidx, GENMASK(31, 28))),
+		.ofs = cpu_to_le32(u32_get_bits(regidx, GENMASK(27, 0))),
+		.data = set ? cpu_to_le32(*val) : 0,
+	};
+	struct sk_buff *skb;
+	int ret;
+
+	if (set)
+		return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(RF_REG_ACCESS),
+					 &req, sizeof(req), false);
+
+	ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_QUERY(RF_REG_ACCESS),
+					&req, sizeof(req), true, &skb);
+	if (ret)
+		return ret;
+
+	*val = le32_to_cpu(*(__le32 *)(skb->data + 8));
+	dev_kfree_skb(skb);
+
+	return 0;
+}
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/mcu.h b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/mcu.h
index 581f48c..c3bd8af 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/mcu.h
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/mcu.h
@@ -349,16 +349,6 @@
 	MCU_MMPS_DISABLE,
 };
 
-enum {
-	SCS_SEND_DATA,
-	SCS_SET_MANUAL_PD_TH,
-	SCS_CONFIG,
-	SCS_ENABLE,
-	SCS_SHOW_INFO,
-	SCS_GET_GLO_ADDR,
-	SCS_GET_GLO_ADDR_EVENT,
-};
-
 struct bss_rate_tlv {
 	__le16 tag;
 	__le16 len;
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/pci.c b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/pci.c
index a5e5e56..6656ef5 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/pci.c
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/pci.c
@@ -123,6 +123,7 @@
 		return PTR_ERR(dev);
 
 	mdev = &dev->mt76;
+	bersa_wfsys_reset(dev);
 	hif2 = bersa_pci_init_hif2(pdev);
 
 	ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/regs.h b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/regs.h
index d939c47..c3182e3 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/regs.h
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/regs.h
@@ -72,7 +72,7 @@
 #define MT_PSE(ofs)			(MT_PSE_BASE + (ofs))
 
 /* WF MDP TOP */
-#define MT_MDP_BASE			0x820cd000
+#define MT_MDP_BASE			0x820cc000
 #define MT_MDP(ofs)			(MT_MDP_BASE + (ofs))
 
 #define MT_MDP_DCR0			MT_MDP(0x000)
@@ -81,6 +81,9 @@
 #define MT_MDP_DCR1			MT_MDP(0x004)
 #define MT_MDP_DCR1_MAX_RX_LEN		GENMASK(15, 3)
 
+#define MT_MDP_DCR2			MT_MDP(0x8e8)
+#define MT_MDP_DCR2_RX_TRANS_SHORT	BIT(2)
+
 #define MT_MDP_BNRCFR0(_band)		MT_MDP(0x090 + ((_band) << 8))
 #define MT_MDP_RCFR0_MCU_RX_MGMT	GENMASK(5, 4)
 #define MT_MDP_RCFR0_MCU_RX_CTL_NON_BAR	GENMASK(7, 6)
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/testmode.c b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/testmode.c
index 88c5f82..197a922 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/testmode.c
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/bersa/testmode.c
@@ -230,12 +230,8 @@
 
 		ipg -= aifsn * slot_time;
 
-		if (ipg > TM_DEFAULT_SIFS) {
-			if (ipg < TM_MAX_SIFS)
-				sifs = ipg;
-			else
-				sifs = TM_MAX_SIFS;
-		}
+		if (ipg > TM_DEFAULT_SIFS)
+			sifs = min_t(u32, ipg, TM_MAX_SIFS);
 	}
 done:
 	txv_time = mt76_get_field(dev, MT_TMAC_ATCR(phy->band_idx),
@@ -278,6 +274,8 @@
 	case MT76_TM_TX_MODE_OFDM:
 		if (mphy->chandef.chan->band == NL80211_BAND_5GHZ)
 			sband = &mphy->sband_5g.sband;
+		else if (mphy->chandef.chan->band == NL80211_BAND_6GHZ)
+			sband = &mphy->sband_6g.sband;
 		else
 			sband = &mphy->sband_2g.sband;
 
@@ -588,6 +586,8 @@
 
 		if (chandef->chan->band == NL80211_BAND_5GHZ)
 			sband = &phy->mt76->sband_5g.sband;
+		else if (chandef->chan->band == NL80211_BAND_6GHZ)
+			sband = &phy->mt76->sband_6g.sband;
 		else
 			sband = &phy->mt76->sband_2g.sband;