[][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/agg-rx.c b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/agg-rx.c
index 7262222..10cbd9e 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/agg-rx.c
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/agg-rx.c
@@ -162,15 +162,15 @@
if (!sta)
return;
- if (!status->aggr && !(status->flag & RX_FLAG_8023)) {
- mt76_rx_aggr_check_ctl(skb, frames);
+ if (!status->aggr) {
+ if (!(status->flag & RX_FLAG_8023))
+ mt76_rx_aggr_check_ctl(skb, frames);
return;
}
/* not part of a BA session */
ackp = status->qos_ctl & IEEE80211_QOS_CTL_ACK_POLICY_MASK;
- if (ackp != IEEE80211_QOS_CTL_ACK_POLICY_BLOCKACK &&
- ackp != IEEE80211_QOS_CTL_ACK_POLICY_NORMAL)
+ if (ackp == IEEE80211_QOS_CTL_ACK_POLICY_NOACK)
return;
tid = rcu_dereference(wcid->aggr[tidno]);
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, ®val, 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;
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/dma.c b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/dma.c
index c68d127..be46da1 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/dma.c
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/dma.c
@@ -7,6 +7,37 @@
#include "mt76.h"
#include "dma.h"
+#if IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED)
+
+#define Q_READ(_dev, _q, _field) ({ \
+ u32 _offset = offsetof(struct mt76_queue_regs, _field); \
+ u32 _val; \
+ if ((_q)->flags & MT_QFLAG_WED) \
+ _val = mtk_wed_device_reg_read(&(_dev)->mmio.wed, \
+ ((_q)->wed_regs + \
+ _offset)); \
+ else \
+ _val = readl(&(_q)->regs->_field); \
+ _val; \
+})
+
+#define Q_WRITE(_dev, _q, _field, _val) do { \
+ u32 _offset = offsetof(struct mt76_queue_regs, _field); \
+ if ((_q)->flags & MT_QFLAG_WED) \
+ mtk_wed_device_reg_write(&(_dev)->mmio.wed, \
+ ((_q)->wed_regs + _offset), \
+ _val); \
+ else \
+ writel(_val, &(_q)->regs->_field); \
+} while (0)
+
+#else
+
+#define Q_READ(_dev, _q, _field) readl(&(_q)->regs->_field)
+#define Q_WRITE(_dev, _q, _field, _val) writel(_val, &(_q)->regs->_field)
+
+#endif
+
static struct mt76_txwi_cache *
mt76_alloc_txwi(struct mt76_dev *dev)
{
@@ -20,7 +51,7 @@
if (!txwi)
return NULL;
- addr = dma_map_single(dev->dev, txwi, dev->drv->txwi_size,
+ addr = dma_map_single(dev->dma_dev, txwi, dev->drv->txwi_size,
DMA_TO_DEVICE);
t = (struct mt76_txwi_cache *)(txwi + dev->drv->txwi_size);
t->dma_addr = addr;
@@ -74,7 +105,7 @@
local_bh_disable();
while ((t = __mt76_get_txwi(dev)) != NULL) {
- dma_unmap_single(dev->dev, t->dma_addr, dev->drv->txwi_size,
+ dma_unmap_single(dev->dma_dev, t->dma_addr, dev->drv->txwi_size,
DMA_TO_DEVICE);
kfree(mt76_get_txwi_ptr(dev, t));
}
@@ -84,9 +115,9 @@
static void
mt76_dma_sync_idx(struct mt76_dev *dev, struct mt76_queue *q)
{
- writel(q->desc_dma, &q->regs->desc_base);
- writel(q->ndesc, &q->regs->ring_size);
- q->head = readl(&q->regs->dma_idx);
+ Q_WRITE(dev, q, desc_base, q->desc_dma);
+ Q_WRITE(dev, q, ring_size, q->ndesc);
+ q->head = Q_READ(dev, q, dma_idx);
q->tail = q->head;
}
@@ -102,42 +133,12 @@
for (i = 0; i < q->ndesc; i++)
q->desc[i].ctrl = cpu_to_le32(MT_DMA_CTL_DMA_DONE);
- writel(0, &q->regs->cpu_idx);
- writel(0, &q->regs->dma_idx);
+ Q_WRITE(dev, q, cpu_idx, 0);
+ Q_WRITE(dev, q, dma_idx, 0);
mt76_dma_sync_idx(dev, q);
}
static int
-mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
- int idx, int n_desc, int bufsize,
- u32 ring_base)
-{
- int size;
-
- spin_lock_init(&q->lock);
- spin_lock_init(&q->cleanup_lock);
-
- q->regs = dev->mmio.regs + ring_base + idx * MT_RING_SIZE;
- q->ndesc = n_desc;
- q->buf_size = bufsize;
- q->hw_idx = idx;
-
- size = q->ndesc * sizeof(struct mt76_desc);
- q->desc = dmam_alloc_coherent(dev->dev, size, &q->desc_dma, GFP_KERNEL);
- if (!q->desc)
- return -ENOMEM;
-
- size = q->ndesc * sizeof(*q->entry);
- q->entry = devm_kzalloc(dev->dev, size, GFP_KERNEL);
- if (!q->entry)
- return -ENOMEM;
-
- mt76_dma_queue_reset(dev, q);
-
- return 0;
-}
-
-static int
mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q,
struct mt76_queue_buf *buf, int nbufs, u32 info,
struct sk_buff *skb, void *txwi)
@@ -205,11 +206,11 @@
struct mt76_queue_entry *e = &q->entry[idx];
if (!e->skip_buf0)
- dma_unmap_single(dev->dev, e->dma_addr[0], e->dma_len[0],
+ dma_unmap_single(dev->dma_dev, e->dma_addr[0], e->dma_len[0],
DMA_TO_DEVICE);
if (!e->skip_buf1)
- dma_unmap_single(dev->dev, e->dma_addr[1], e->dma_len[1],
+ dma_unmap_single(dev->dma_dev, e->dma_addr[1], e->dma_len[1],
DMA_TO_DEVICE);
if (e->txwi == DMA_DUMMY_DATA)
@@ -226,7 +227,7 @@
mt76_dma_kick_queue(struct mt76_dev *dev, struct mt76_queue *q)
{
wmb();
- writel(q->head, &q->regs->cpu_idx);
+ Q_WRITE(dev, q, cpu_idx, q->head);
}
static void
@@ -242,7 +243,7 @@
if (flush)
last = -1;
else
- last = readl(&q->regs->dma_idx);
+ last = Q_READ(dev, q, dma_idx);
while (q->queued > 0 && q->tail != last) {
mt76_dma_tx_cleanup_idx(dev, q, q->tail, &entry);
@@ -254,8 +255,7 @@
}
if (!flush && q->tail == last)
- last = readl(&q->regs->dma_idx);
-
+ last = Q_READ(dev, q, dma_idx);
}
spin_unlock_bh(&q->cleanup_lock);
@@ -290,7 +290,7 @@
if (info)
*info = le32_to_cpu(desc->info);
- dma_unmap_single(dev->dev, buf_addr, buf_len, DMA_FROM_DEVICE);
+ dma_unmap_single(dev->dma_dev, buf_addr, buf_len, DMA_FROM_DEVICE);
e->buf = NULL;
return buf;
@@ -327,9 +327,9 @@
if (q->queued + 1 >= q->ndesc - 1)
goto error;
- addr = dma_map_single(dev->dev, skb->data, skb->len,
+ addr = dma_map_single(dev->dma_dev, skb->data, skb->len,
DMA_TO_DEVICE);
- if (unlikely(dma_mapping_error(dev->dev, addr)))
+ if (unlikely(dma_mapping_error(dev->dma_dev, addr)))
goto error;
buf.addr = addr;
@@ -376,8 +376,8 @@
mt76_insert_hdr_pad(skb);
len = skb_headlen(skb);
- addr = dma_map_single(dev->dev, skb->data, len, DMA_TO_DEVICE);
- if (unlikely(dma_mapping_error(dev->dev, addr)))
+ addr = dma_map_single(dev->dma_dev, skb->data, len, DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(dev->dma_dev, addr)))
goto free;
tx_info.buf[n].addr = t->dma_addr;
@@ -389,9 +389,9 @@
if (n == ARRAY_SIZE(tx_info.buf))
goto unmap;
- addr = dma_map_single(dev->dev, iter->data, iter->len,
+ addr = dma_map_single(dev->dma_dev, iter->data, iter->len,
DMA_TO_DEVICE);
- if (unlikely(dma_mapping_error(dev->dev, addr)))
+ if (unlikely(dma_mapping_error(dev->dma_dev, addr)))
goto unmap;
tx_info.buf[n].addr = addr;
@@ -404,10 +404,10 @@
goto unmap;
}
- dma_sync_single_for_cpu(dev->dev, t->dma_addr, dev->drv->txwi_size,
+ dma_sync_single_for_cpu(dev->dma_dev, t->dma_addr, dev->drv->txwi_size,
DMA_TO_DEVICE);
ret = dev->drv->tx_prepare_skb(dev, txwi, q->qid, wcid, sta, &tx_info);
- dma_sync_single_for_device(dev->dev, t->dma_addr, dev->drv->txwi_size,
+ dma_sync_single_for_device(dev->dma_dev, t->dma_addr, dev->drv->txwi_size,
DMA_TO_DEVICE);
if (ret < 0)
goto unmap;
@@ -417,7 +417,7 @@
unmap:
for (n--; n > 0; n--)
- dma_unmap_single(dev->dev, tx_info.buf[n].addr,
+ dma_unmap_single(dev->dma_dev, tx_info.buf[n].addr,
tx_info.buf[n].len, DMA_TO_DEVICE);
free:
@@ -462,8 +462,8 @@
if (!buf)
break;
- addr = dma_map_single(dev->dev, buf, len, DMA_FROM_DEVICE);
- if (unlikely(dma_mapping_error(dev->dev, addr))) {
+ addr = dma_map_single(dev->dma_dev, buf, len, DMA_FROM_DEVICE);
+ if (unlikely(dma_mapping_error(dev->dma_dev, addr))) {
skb_free_frag(buf);
break;
}
@@ -483,6 +483,85 @@
return frames;
}
+static int
+mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q)
+{
+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
+ struct mtk_wed_device *wed = &dev->mmio.wed;
+ int ret, type, ring;
+ u8 flags = q->flags;
+
+ if (!mtk_wed_device_active(wed))
+ q->flags &= ~MT_QFLAG_WED;
+
+ if (!(q->flags & MT_QFLAG_WED))
+ return 0;
+
+ type = FIELD_GET(MT_QFLAG_WED_TYPE, q->flags);
+ ring = FIELD_GET(MT_QFLAG_WED_RING, q->flags);
+
+ switch (type) {
+ case MT76_WED_Q_TX:
+ ret = mtk_wed_device_tx_ring_setup(wed, ring, q->regs);
+ if (!ret)
+ q->wed_regs = wed->tx_ring[ring].reg_base;
+ break;
+ case MT76_WED_Q_TXFREE:
+ /* WED txfree queue needs ring to be initialized before setup */
+ q->flags = 0;
+ mt76_dma_queue_reset(dev, q);
+ mt76_dma_rx_fill(dev, q);
+ q->flags = flags;
+
+ ret = mtk_wed_device_txfree_ring_setup(wed, q->regs);
+ if (!ret)
+ q->wed_regs = wed->txfree_ring.reg_base;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+#else
+ return 0;
+#endif
+}
+
+static int
+mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
+ int idx, int n_desc, int bufsize,
+ u32 ring_base)
+{
+ int ret, size;
+
+ spin_lock_init(&q->lock);
+ spin_lock_init(&q->cleanup_lock);
+
+ q->regs = dev->mmio.regs + ring_base + idx * MT_RING_SIZE;
+ q->ndesc = n_desc;
+ q->buf_size = bufsize;
+ q->hw_idx = idx;
+
+ size = q->ndesc * sizeof(struct mt76_desc);
+ q->desc = dmam_alloc_coherent(dev->dma_dev, size, &q->desc_dma, GFP_KERNEL);
+ if (!q->desc)
+ return -ENOMEM;
+
+ size = q->ndesc * sizeof(*q->entry);
+ q->entry = devm_kzalloc(dev->dev, size, GFP_KERNEL);
+ if (!q->entry)
+ return -ENOMEM;
+
+ ret = mt76_dma_wed_setup(dev, q);
+ if (ret)
+ return ret;
+
+ if (q->flags != MT_WED_Q_TXFREE)
+ mt76_dma_queue_reset(dev, q);
+
+ return 0;
+}
+
static void
mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
{
@@ -564,14 +643,29 @@
static int
mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
{
- int len, data_len, done = 0;
+ int len, data_len, done = 0, dma_idx;
struct sk_buff *skb;
unsigned char *data;
+ bool check_ddone = false;
bool more;
+ if (IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED) &&
+ q->flags == MT_WED_Q_TXFREE) {
+ dma_idx = Q_READ(dev, q, dma_idx);
+ check_ddone = true;
+ }
+
while (done < budget) {
u32 info;
+ if (check_ddone) {
+ if (q->tail == dma_idx)
+ dma_idx = Q_READ(dev, q, dma_idx);
+
+ if (q->tail == dma_idx)
+ break;
+ }
+
data = mt76_dma_dequeue(dev, q, false, &len, &info, &more);
if (!data)
break;
@@ -714,5 +808,8 @@
}
mt76_free_pending_txwi(dev);
+
+ if (mtk_wed_device_active(&dev->mmio.wed))
+ mtk_wed_device_detach(&dev->mmio.wed);
}
EXPORT_SYMBOL_GPL(mt76_dma_cleanup);
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mac80211.c b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mac80211.c
index e8b9b0f..7818bc7 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mac80211.c
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mac80211.c
@@ -248,6 +248,8 @@
vht_cap->cap |= IEEE80211_VHT_CAP_TXSTBC;
else
vht_cap->cap &= ~IEEE80211_VHT_CAP_TXSTBC;
+ vht_cap->cap |= IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN |
+ IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN;
for (i = 0; i < 8; i++) {
if (i < nstream)
@@ -323,8 +325,6 @@
vht_cap->cap |= IEEE80211_VHT_CAP_RXLDPC |
IEEE80211_VHT_CAP_RXSTBC_1 |
IEEE80211_VHT_CAP_SHORT_GI_80 |
- IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN |
- IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN |
(3 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT);
return 0;
@@ -549,6 +549,7 @@
dev->hw = hw;
dev->dev = pdev;
dev->drv = drv_ops;
+ dev->dma_dev = pdev;
phy = &dev->phy;
phy->dev = dev;
@@ -585,6 +586,7 @@
INIT_LIST_HEAD(&dev->wcid_list);
INIT_LIST_HEAD(&dev->txwi_cache);
+ dev->token_size = dev->drv->token_size;
for (i = 0; i < ARRAY_SIZE(dev->q_rx); i++)
skb_queue_head_init(&dev->rx_skb[i]);
@@ -1391,7 +1393,9 @@
struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
mutex_lock(&dev->mutex);
+ spin_lock_bh(&dev->status_lock);
rcu_assign_pointer(dev->wcid[wcid->idx], NULL);
+ spin_unlock_bh(&dev->status_lock);
mutex_unlock(&dev->mutex);
}
EXPORT_SYMBOL_GPL(mt76_sta_pre_rcu_remove);
@@ -1588,7 +1592,7 @@
struct mt76_queue *
mt76_init_queue(struct mt76_dev *dev, int qid, int idx, int n_desc,
- int ring_base)
+ int ring_base, u32 flags)
{
struct mt76_queue *hwq;
int err;
@@ -1597,6 +1601,8 @@
if (!hwq)
return ERR_PTR(-ENOMEM);
+ hwq->flags = flags;
+
err = dev->queue_ops->alloc(dev, hwq, idx, n_desc, 0, ring_base);
if (err < 0)
return ERR_PTR(err);
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mmio.c b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mmio.c
index 26353b6..86e3d2a 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mmio.c
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mmio.c
@@ -73,8 +73,13 @@
spin_lock_irqsave(&dev->mmio.irq_lock, flags);
dev->mmio.irqmask &= ~clear;
dev->mmio.irqmask |= set;
- if (addr)
- mt76_mmio_wr(dev, addr, dev->mmio.irqmask);
+ if (addr) {
+ if (mtk_wed_device_active(&dev->mmio.wed))
+ mtk_wed_device_irq_set_mask(&dev->mmio.wed,
+ dev->mmio.irqmask);
+ else
+ mt76_mmio_wr(dev, addr, dev->mmio.irqmask);
+ }
spin_unlock_irqrestore(&dev->mmio.irq_lock, flags);
}
EXPORT_SYMBOL_GPL(mt76_set_irq_mask);
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt76.h b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt76.h
index b5d1dc3..3b8cd99 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt76.h
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt76.h
@@ -13,6 +13,7 @@
#include <linux/leds.h>
#include <linux/usb.h>
#include <linux/average.h>
+#include <linux/soc/mediatek/mtk_wed.h>
#include <net/mac80211.h>
#include "util.h"
#include "testmode.h"
@@ -26,6 +27,16 @@
#define MT76_TOKEN_FREE_THR 64
+#define MT_QFLAG_WED_RING GENMASK(1, 0)
+#define MT_QFLAG_WED_TYPE GENMASK(3, 2)
+#define MT_QFLAG_WED BIT(4)
+
+#define __MT_WED_Q(_type, _n) (MT_QFLAG_WED | \
+ FIELD_PREP(MT_QFLAG_WED_TYPE, _type) | \
+ FIELD_PREP(MT_QFLAG_WED_RING, _n))
+#define MT_WED_Q_TX(_n) __MT_WED_Q(MT76_WED_Q_TX, _n)
+#define MT_WED_Q_TXFREE __MT_WED_Q(MT76_WED_Q_TXFREE, 0)
+
struct mt76_dev;
struct mt76_phy;
struct mt76_wcid;
@@ -42,6 +53,11 @@
MT76_BUS_SDIO,
};
+enum mt76_wed_type {
+ MT76_WED_Q_TX,
+ MT76_WED_Q_TXFREE,
+};
+
struct mt76_bus_ops {
u32 (*rr)(struct mt76_dev *dev, u32 offset);
void (*wr)(struct mt76_dev *dev, u32 offset, u32 val);
@@ -186,6 +202,9 @@
u8 buf_offset;
u8 hw_idx;
u8 qid;
+ u8 flags;
+
+ u32 wed_regs;
dma_addr_t desc_dma;
struct sk_buff *rx_head;
@@ -554,6 +573,8 @@
void __iomem *regs;
spinlock_t irq_lock;
u32 irqmask;
+
+ struct mtk_wed_device wed;
};
struct mt76_rx_status {
@@ -717,6 +738,7 @@
const struct mt76_driver_ops *drv;
const struct mt76_mcu_ops *mcu_ops;
struct device *dev;
+ struct device *dma_dev;
struct mt76_mcu mcu;
@@ -737,7 +759,9 @@
spinlock_t token_lock;
struct idr token;
- int token_count;
+ u16 wed_token_count;
+ u16 token_count;
+ u16 token_size;
wait_queue_head_t tx_wait;
/* spinclock used to protect wcid pktid linked list */
@@ -977,14 +1001,14 @@
struct mt76_queue *
mt76_init_queue(struct mt76_dev *dev, int qid, int idx, int n_desc,
- int ring_base);
+ int ring_base, u32 flags);
u16 mt76_calculate_default_rate(struct mt76_phy *phy, int rateidx);
static inline int mt76_init_tx_queue(struct mt76_phy *phy, int qid, int idx,
- int n_desc, int ring_base)
+ int n_desc, int ring_base, u32 flags)
{
struct mt76_queue *q;
- q = mt76_init_queue(phy->dev, qid, idx, n_desc, ring_base);
+ q = mt76_init_queue(phy->dev, qid, idx, n_desc, ring_base, flags);
if (IS_ERR(q))
return PTR_ERR(q);
@@ -999,7 +1023,7 @@
{
struct mt76_queue *q;
- q = mt76_init_queue(dev, qid, idx, n_desc, ring_base);
+ q = mt76_init_queue(dev, qid, idx, n_desc, ring_base, 0);
if (IS_ERR(q))
return PTR_ERR(q);
@@ -1433,8 +1457,7 @@
int token;
spin_lock_bh(&dev->token_lock);
- token = idr_alloc(&dev->token, *ptxwi, 0, dev->drv->token_size,
- GFP_ATOMIC);
+ token = idr_alloc(&dev->token, *ptxwi, 0, dev->token_size, GFP_ATOMIC);
spin_unlock_bh(&dev->token_lock);
return token;
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7603/beacon.c b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7603/beacon.c
index 5d4522f..b5e8308 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7603/beacon.c
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7603/beacon.c
@@ -82,12 +82,12 @@
__skb_queue_head_init(&data.q);
q = dev->mphy.q_tx[MT_TXQ_BEACON];
- spin_lock_bh(&q->lock);
+ spin_lock(&q->lock);
ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev),
IEEE80211_IFACE_ITER_RESUME_ALL,
mt7603_update_beacon_iter, dev);
mt76_queue_kick(dev, q);
- spin_unlock_bh(&q->lock);
+ spin_unlock(&q->lock);
/* Flush all previous CAB queue packets */
mt76_wr(dev, MT_WF_ARB_CAB_FLUSH, GENMASK(30, 16) | BIT(0));
@@ -117,7 +117,7 @@
mt76_skb_set_moredata(data.tail[i], false);
}
- spin_lock_bh(&q->lock);
+ spin_lock(&q->lock);
while ((skb = __skb_dequeue(&data.q)) != NULL) {
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_vif *vif = info->control.vif;
@@ -126,7 +126,7 @@
mt76_tx_queue_skb(dev, q, skb, &mvif->sta.wcid, NULL);
}
mt76_queue_kick(dev, q);
- spin_unlock_bh(&q->lock);
+ spin_unlock(&q->lock);
for (i = 0; i < ARRAY_SIZE(data.count); i++)
mt76_wr(dev, MT_WF_ARB_CAB_COUNT_B0_REG(i),
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7603/dma.c b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7603/dma.c
index 37b092e..590cff9 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7603/dma.c
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7603/dma.c
@@ -173,13 +173,13 @@
for (i = 0; i < ARRAY_SIZE(wmm_queue_map); i++) {
ret = mt76_init_tx_queue(&dev->mphy, i, wmm_queue_map[i],
- MT7603_TX_RING_SIZE, MT_TX_RING_BASE);
+ MT7603_TX_RING_SIZE, MT_TX_RING_BASE, 0);
if (ret)
return ret;
}
ret = mt76_init_tx_queue(&dev->mphy, MT_TXQ_PSD, MT_TX_HW_QUEUE_MGMT,
- MT7603_PSD_RING_SIZE, MT_TX_RING_BASE);
+ MT7603_PSD_RING_SIZE, MT_TX_RING_BASE, 0);
if (ret)
return ret;
@@ -189,12 +189,12 @@
return ret;
ret = mt76_init_tx_queue(&dev->mphy, MT_TXQ_BEACON, MT_TX_HW_QUEUE_BCN,
- MT_MCU_RING_SIZE, MT_TX_RING_BASE);
+ MT_MCU_RING_SIZE, MT_TX_RING_BASE, 0);
if (ret)
return ret;
ret = mt76_init_tx_queue(&dev->mphy, MT_TXQ_CAB, MT_TX_HW_QUEUE_BMC,
- MT_MCU_RING_SIZE, MT_TX_RING_BASE);
+ MT_MCU_RING_SIZE, MT_TX_RING_BASE, 0);
if (ret)
return ret;
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7615/dma.c b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7615/dma.c
index 00aefea..3a79a2d 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7615/dma.c
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7615/dma.c
@@ -26,14 +26,14 @@
for (i = 0; i < ARRAY_SIZE(wmm_queue_map); i++) {
ret = mt76_init_tx_queue(&dev->mphy, i, wmm_queue_map[i],
MT7615_TX_RING_SIZE / 2,
- MT_TX_RING_BASE);
+ MT_TX_RING_BASE, 0);
if (ret)
return ret;
}
ret = mt76_init_tx_queue(&dev->mphy, MT_TXQ_PSD, MT7622_TXQ_MGMT,
MT7615_TX_MGMT_RING_SIZE,
- MT_TX_RING_BASE);
+ MT_TX_RING_BASE, 0);
if (ret)
return ret;
@@ -55,7 +55,7 @@
return mt7622_init_tx_queues_multi(dev);
ret = mt76_init_tx_queue(&dev->mphy, 0, 0, MT7615_TX_RING_SIZE,
- MT_TX_RING_BASE);
+ MT_TX_RING_BASE, 0);
if (ret)
return ret;
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt76_connac_mcu.c b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt76_connac_mcu.c
index e8e5910..acd6e72 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt76_connac_mcu.c
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt76_connac_mcu.c
@@ -2184,11 +2184,8 @@
return -ENOMEM;
skb_put_data(skb, &req_hdr, sizeof(req_hdr));
- for (i = 0; i < len; i++) {
- u8 *addr = (u8 *)skb_put(skb, sizeof(__be32));
-
- memcpy(addr, &info->arp_addr_list[i], sizeof(__be32));
- }
+ for (i = 0; i < len; i++)
+ skb_put_data(skb, &info->arp_addr_list[i], sizeof(__be32));
return mt76_mcu_skb_send_msg(dev, skb, MCU_UNI_CMD(OFFLOAD), true);
}
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt76_connac_mcu.h b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt76_connac_mcu.h
index 9288d46..207569d 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt76_connac_mcu.h
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt76_connac_mcu.h
@@ -473,6 +473,15 @@
u8 mmps_mode;
} __packed;
+struct sta_rec_hdr_trans {
+ __le16 tag;
+ __le16 len;
+ u8 from_ds;
+ u8 to_ds;
+ u8 dis_rx_hdr_tran;
+ u8 rsv;
+} __packed;
+
/* wtbl_rec */
struct wtbl_req_hdr {
@@ -640,6 +649,7 @@
sizeof(struct sta_rec_sec) + \
sizeof(struct sta_rec_ra_fixed) + \
sizeof(struct sta_rec_he_6g_capa) + \
+ sizeof(struct sta_rec_hdr_trans) + \
sizeof(struct tlv) + \
MT76_CONNAC_WTBL_UPDATE_MAX_SIZE)
@@ -668,6 +678,7 @@
STA_REC_PHY = 0x15,
STA_REC_HE_6G = 0x17,
STA_REC_HE_V2 = 0x19,
+ STA_REC_HDR_TRANS = 0x2B,
STA_REC_MAX_NUM
};
@@ -1042,7 +1053,6 @@
MCU_EXT_CMD_SET_RDD_PATTERN = 0x7d,
MCU_EXT_CMD_MWDS_SUPPORT = 0x80,
MCU_EXT_CMD_SET_SER_TRIGGER = 0x81,
- 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,
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt76x02_mmio.c b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt76x02_mmio.c
index 8bcd8af..0fa3c7c 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt76x02_mmio.c
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt76x02_mmio.c
@@ -191,13 +191,13 @@
for (i = 0; i < IEEE80211_NUM_ACS; i++) {
ret = mt76_init_tx_queue(&dev->mphy, i, mt76_ac_to_hwq(i),
MT76x02_TX_RING_SIZE,
- MT_TX_RING_BASE);
+ MT_TX_RING_BASE, 0);
if (ret)
return ret;
}
ret = mt76_init_tx_queue(&dev->mphy, MT_TXQ_PSD, MT_TX_HW_QUEUE_MGMT,
- MT76x02_PSD_RING_SIZE, MT_TX_RING_BASE);
+ MT76x02_PSD_RING_SIZE, MT_TX_RING_BASE, 0);
if (ret)
return ret;
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/debugfs.c b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/debugfs.c
index 4e1ecae..77bbeee 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/debugfs.c
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/debugfs.c
@@ -95,7 +95,7 @@
struct mt7915_dev *dev = data;
dev->muru_debug = val;
- mt7915_mcu_muru_debug_set(dev, data);
+ mt7915_mcu_muru_debug_set(dev, dev->muru_debug);
return 0;
}
@@ -867,6 +867,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
+mt7915_rf_regval_get(void *data, u64 *val)
+{
+ struct mt7915_dev *dev = data;
+ u32 regval;
+ int ret;
+
+ ret = mt7915_mcu_rf_regval(dev, dev->mt76.debugfs_reg, ®val, false);
+ if (ret)
+ return ret;
+
+ *val = le32_to_cpu(regval);
+
+ return 0;
+}
+
+static int
+mt7915_rf_regval_set(void *data, u64 val)
+{
+ struct mt7915_dev *dev = data;
+
+ return mt7915_mcu_rf_regval(dev, dev->mt76.debugfs_reg, (u32 *)&val, true);
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(fops_rf_regval, mt7915_rf_regval_get,
+ mt7915_rf_regval_set, "0x%08llx\n");
+
int mt7915_init_debugfs(struct mt7915_phy *phy)
{
struct mt7915_dev *dev = phy->dev;
@@ -898,6 +928,8 @@
debugfs_create_devm_seqfile(dev->mt76.dev, "twt_stats", dir,
mt7915_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);
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/dma.c b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/dma.c
index 66a312a..c2d655c 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/dma.c
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/dma.c
@@ -8,9 +8,16 @@
static int
mt7915_init_tx_queues(struct mt7915_phy *phy, int idx, int n_desc, int ring_base)
{
+ struct mt7915_dev *dev = phy->dev;
int i, err;
- err = mt76_init_tx_queue(phy->mt76, 0, idx, n_desc, ring_base);
+ if (mtk_wed_device_active(&phy->dev->mt76.mmio.wed)) {
+ ring_base = MT_WED_TX_RING_BASE;
+ idx -= MT_TXQ_ID(0);
+ }
+
+ err = mt76_init_tx_queue(phy->mt76, 0, idx, n_desc, ring_base,
+ MT_WED_Q_TX(idx));
if (err < 0)
return err;
@@ -319,6 +326,14 @@
if (dev->dbdc_support || dev->phy.band_idx)
irq_mask |= MT_INT_BAND1_RX_DONE;
+ if (mtk_wed_device_active(&dev->mt76.mmio.wed)) {
+ u32 wed_irq_mask = irq_mask;
+
+ wed_irq_mask |= MT_INT_TX_DONE_BAND0 | MT_INT_TX_DONE_BAND1;
+ mt76_wr(dev, MT_INT_WED_MASK_CSR, wed_irq_mask);
+ mtk_wed_device_start(&dev->mt76.mmio.wed, wed_irq_mask);
+ }
+
mt7915_irq_enable(dev, irq_mask);
return 0;
@@ -327,6 +342,7 @@
int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)
{
struct mt76_dev *mdev = &dev->mt76;
+ u32 wa_rx_base, wa_rx_idx;
u32 hif1_ofs = 0;
int ret;
@@ -339,6 +355,17 @@
mt7915_dma_disable(dev, true);
+ if (mtk_wed_device_active(&dev->mt76.mmio.wed)) {
+ mt76_set(dev, MT_WFDMA_HOST_CONFIG, MT_WFDMA_HOST_CONFIG_WED);
+
+ mt76_wr(dev, MT_WFDMA_WED_RING_CONTROL,
+ FIELD_PREP(MT_WFDMA_WED_RING_CONTROL_TX0, 18) |
+ FIELD_PREP(MT_WFDMA_WED_RING_CONTROL_TX1, 19) |
+ FIELD_PREP(MT_WFDMA_WED_RING_CONTROL_RX1, 1));
+ } else {
+ mt76_clear(dev, MT_WFDMA_HOST_CONFIG, MT_WFDMA_HOST_CONFIG_WED);
+ }
+
/* init tx queue */
ret = mt7915_init_tx_queues(&dev->phy,
MT_TXQ_ID(dev->phy.band_idx),
@@ -390,11 +417,17 @@
return ret;
/* event from WA */
+ if (mtk_wed_device_active(&dev->mt76.mmio.wed)) {
+ wa_rx_base = MT_WED_RX_RING_BASE;
+ wa_rx_idx = MT7915_RXQ_MCU_WA;
+ dev->mt76.q_rx[MT_RXQ_MCU_WA].flags = MT_WED_Q_TXFREE;
+ } else {
+ wa_rx_base = MT_RXQ_RING_BASE(MT_RXQ_MCU_WA);
+ wa_rx_idx = MT_RXQ_ID(MT_RXQ_MCU_WA);
+ }
ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU_WA],
- MT_RXQ_ID(MT_RXQ_MCU_WA),
- MT7915_RX_MCU_RING_SIZE,
- MT_RX_BUF_SIZE,
- MT_RXQ_RING_BASE(MT_RXQ_MCU_WA));
+ wa_rx_idx, MT7915_RX_MCU_RING_SIZE,
+ MT_RX_BUF_SIZE, wa_rx_base);
if (ret)
return ret;
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/init.c b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/init.c
index ed9d64d..f8cfa68 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/init.c
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/init.c
@@ -453,6 +453,9 @@
mt76_rmw_field(dev, MT_MDP_DCR1, MT_MDP_DCR1_MAX_RX_LEN, rx_len);
+ if (!is_mt7915(&dev->mt76))
+ 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);
@@ -804,7 +807,7 @@
mt7915_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,
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/mac.c b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/mac.c
index a8df65c..6b32478 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/mac.c
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/mac.c
@@ -309,7 +309,7 @@
}
static void
-mt7915_mac_decode_he_radiotap(struct sk_buff *skb, __le32 *rxv, u32 mode)
+mt7915_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 = {
@@ -474,10 +474,10 @@
mt7915_mac_fill_rx_rate(struct mt7915_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;
@@ -490,18 +490,18 @@
if (!is_mt7915(&dev->mt76)) {
stbc = FIELD_GET(MT_PRXV_HT_STBC, v0);
gi = FIELD_GET(MT_PRXV_HT_SHORT_GI, v0);
- mode = FIELD_GET(MT_PRXV_TX_MODE, v0);
+ *mode = FIELD_GET(MT_PRXV_TX_MODE, v0);
dcm = FIELD_GET(MT_PRXV_DCM, v0);
bw = FIELD_GET(MT_PRXV_FRAME_MODE, v0);
} else {
stbc = FIELD_GET(MT_CRXV_HT_STBC, v2);
gi = FIELD_GET(MT_CRXV_HT_SHORT_GI, v2);
- mode = FIELD_GET(MT_CRXV_TX_MODE, v2);
+ *mode = FIELD_GET(MT_CRXV_TX_MODE, v2);
dcm = !!(idx & GENMASK(3, 0) & MT_PRXV_TX_DCM);
bw = FIELD_GET(MT_CRXV_FRAME_MODE, v2);
}
- switch (mode) {
+ switch (*mode) {
case MT_PHY_TYPE_CCK:
cck = true;
fallthrough;
@@ -546,7 +546,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 =
@@ -566,7 +566,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;
@@ -581,7 +581,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]);
@@ -590,10 +589,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;
@@ -766,7 +765,8 @@
}
if (!is_mt7915(&dev->mt76) || (rxd1 & MT_RXD1_NORMAL_GROUP_5)) {
- ret = mt7915_mac_fill_rx_rate(dev, status, sband, rxv);
+ ret = mt7915_mac_fill_rx_rate(dev, status, sband, rxv,
+ &mode);
if (ret < 0)
return ret;
}
@@ -837,10 +837,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;
@@ -864,8 +860,11 @@
int i;
band_idx = le32_get_bits(rxv_hdr[1], MT_RXV_HDR_BAND_IDX);
- if (band_idx && !phy->band_idx)
+ if (band_idx && !phy->band_idx) {
phy = mt7915_ext_phy(dev);
+ if (!phy)
+ goto out;
+ }
rcpi = le32_to_cpu(rxv[6]);
ib_rssi = le32_to_cpu(rxv[7]);
@@ -890,8 +889,8 @@
phy->test.last_freq_offset = foe;
phy->test.last_snr = snr;
+out:
#endif
-
dev_kfree_skb(skb);
}
@@ -1017,6 +1016,7 @@
u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
u8 fc_type, fc_stype;
+ u16 ethertype;
bool wmm = false;
u32 val;
@@ -1030,7 +1030,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);
@@ -1347,6 +1348,29 @@
return 0;
}
+u32 mt7915_wed_init_buf(void *ptr, dma_addr_t phys, int token_id)
+{
+ struct mt7915_txp *txp = ptr + MT_TXD_SIZE;
+ __le32 *txwi = ptr;
+ u32 val;
+
+ memset(ptr, 0, MT_TXD_SIZE + sizeof(*txp));
+
+ val = FIELD_PREP(MT_TXD0_TX_BYTES, MT_TXD_SIZE) |
+ FIELD_PREP(MT_TXD0_PKT_FMT, MT_TX_TYPE_CT);
+ txwi[0] = cpu_to_le32(val);
+
+ val = MT_TXD1_LONG_FORMAT |
+ FIELD_PREP(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_802_3);
+ txwi[1] = cpu_to_le32(val);
+
+ txp->token = cpu_to_le16(token_id);
+ txp->nbuf = 1;
+ txp->buf[0] = cpu_to_le32(phys + MT_TXD_SIZE + sizeof(*txp));
+
+ return MT_TXD_SIZE + sizeof(*txp);
+}
+
static void
mt7915_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi)
{
@@ -1380,7 +1404,7 @@
txp = mt7915_txwi_to_txp(dev, t);
for (i = 0; i < txp->nbuf; i++)
- dma_unmap_single(dev->dev, le32_to_cpu(txp->buf[i]),
+ dma_unmap_single(dev->dma_dev, le32_to_cpu(txp->buf[i]),
le16_to_cpu(txp->len[i]), DMA_TO_DEVICE);
}
@@ -1389,6 +1413,7 @@
struct ieee80211_sta *sta, struct list_head *free_list)
{
struct mt76_dev *mdev = &dev->mt76;
+ struct mt7915_sta *msta;
struct mt76_wcid *wcid;
__le32 *txwi;
u16 wcid_idx;
@@ -1401,13 +1426,24 @@
if (sta) {
wcid = (struct mt76_wcid *)sta->drv_priv;
wcid_idx = wcid->idx;
-
- if (likely(t->skb->protocol != cpu_to_be16(ETH_P_PAE)))
- mt7915_tx_check_aggr(sta, txwi);
} else {
wcid_idx = le32_get_bits(txwi[1], MT_TXD1_WLAN_IDX);
+ wcid = rcu_dereference(dev->mt76.wcid[wcid_idx]);
+
+ if (wcid && wcid->sta) {
+ msta = container_of(wcid, struct mt7915_sta, wcid);
+ sta = container_of((void *)msta, struct ieee80211_sta,
+ drv_priv);
+ spin_lock_bh(&dev->sta_poll_lock);
+ if (list_empty(&msta->poll_list))
+ list_add_tail(&msta->poll_list, &dev->sta_poll_list);
+ spin_unlock_bh(&dev->sta_poll_lock);
+ }
}
+ if (sta && likely(t->skb->protocol != cpu_to_be16(ETH_P_PAE)))
+ mt7915_tx_check_aggr(sta, txwi);
+
__mt76_tx_complete_skb(mdev, wcid_idx, t->skb, free_list);
out:
@@ -1416,28 +1452,54 @@
}
static void
+mt7915_mac_tx_free_prepare(struct mt7915_dev *dev)
+{
+ struct mt76_dev *mdev = &dev->mt76;
+ struct mt76_phy *mphy_ext = mdev->phy2;
+
+ /* clean DMA queues and unmap buffers first */
+ mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[MT_TXQ_PSD], false);
+ mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[MT_TXQ_BE], false);
+ if (mphy_ext) {
+ mt76_queue_tx_cleanup(dev, mphy_ext->q_tx[MT_TXQ_PSD], false);
+ mt76_queue_tx_cleanup(dev, mphy_ext->q_tx[MT_TXQ_BE], false);
+ }
+}
+
+static void
+mt7915_mac_tx_free_done(struct mt7915_dev *dev,
+ struct list_head *free_list, bool wake)
+{
+ struct sk_buff *skb, *tmp;
+
+ mt7915_mac_sta_poll(dev);
+
+ if (wake)
+ mt76_set_tx_blocked(&dev->mt76, false);
+
+ mt76_worker_schedule(&dev->mt76.tx_worker);
+
+ list_for_each_entry_safe(skb, tmp, free_list, list) {
+ skb_list_del_init(skb);
+ napi_consume_skb(skb, 1);
+ }
+}
+
+static void
mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
{
struct mt7915_tx_free *free = (struct mt7915_tx_free *)data;
struct mt76_dev *mdev = &dev->mt76;
- struct mt76_phy *mphy_ext = mdev->phy2;
struct mt76_txwi_cache *txwi;
struct ieee80211_sta *sta = NULL;
LIST_HEAD(free_list);
- struct sk_buff *skb, *tmp;
void *end = data + len;
bool v3, wake = false;
u16 total, count = 0;
u32 txd = le32_to_cpu(free->txd);
__le32 *cur_info;
- /* clean DMA queues and unmap buffers first */
- mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[MT_TXQ_PSD], false);
- mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[MT_TXQ_BE], false);
- if (mphy_ext) {
- mt76_queue_tx_cleanup(dev, mphy_ext->q_tx[MT_TXQ_PSD], false);
- mt76_queue_tx_cleanup(dev, mphy_ext->q_tx[MT_TXQ_BE], false);
- }
+ mt7915_mac_tx_free_prepare(dev);
total = le16_get_bits(free->ctrl, MT_TX_FREE_MSDU_CNT);
v3 = (FIELD_GET(MT_TX_FREE_VER, txd) == 0x4);
@@ -1491,17 +1553,38 @@
}
}
- mt7915_mac_sta_poll(dev);
+ mt7915_mac_tx_free_done(dev, &free_list, wake);
+}
- if (wake)
- mt76_set_tx_blocked(&dev->mt76, false);
+static void
+mt7915_mac_tx_free_v0(struct mt7915_dev *dev, void *data, int len)
+{
+ struct mt7915_tx_free *free = (struct mt7915_tx_free *)data;
+ struct mt76_dev *mdev = &dev->mt76;
+ __le16 *info = (__le16 *)free->info;
+ void *end = data + len;
+ LIST_HEAD(free_list);
+ bool wake = false;
+ u8 i, count;
- mt76_worker_schedule(&dev->mt76.tx_worker);
+ mt7915_mac_tx_free_prepare(dev);
- list_for_each_entry_safe(skb, tmp, &free_list, list) {
- skb_list_del_init(skb);
- napi_consume_skb(skb, 1);
+ count = FIELD_GET(MT_TX_FREE_MSDU_CNT_V0, le16_to_cpu(free->ctrl));
+ if (WARN_ON_ONCE((void *)&info[count] > end))
+ return;
+
+ for (i = 0; i < count; i++) {
+ struct mt76_txwi_cache *txwi;
+ u16 msdu = le16_to_cpu(info[i]);
+
+ txwi = mt76_token_release(mdev, msdu, &wake);
+ if (!txwi)
+ continue;
+
+ mt7915_txwi_free(dev, txwi, NULL, &free_list);
}
+
+ mt7915_mac_tx_free_done(dev, &free_list, wake);
}
static bool
@@ -1681,6 +1764,9 @@
case PKT_TYPE_TXRX_NOTIFY:
mt7915_mac_tx_free(dev, data, len);
return false;
+ case PKT_TYPE_TXRX_NOTIFY_V0:
+ mt7915_mac_tx_free_v0(dev, data, len);
+ return false;
case PKT_TYPE_TXS:
for (rxd += 2; rxd + 8 <= end; rxd += 8)
mt7915_mac_add_txs(dev, rxd);
@@ -1708,6 +1794,10 @@
mt7915_mac_tx_free(dev, skb->data, skb->len);
napi_consume_skb(skb, 1);
break;
+ case PKT_TYPE_TXRX_NOTIFY_V0:
+ mt7915_mac_tx_free_v0(dev, skb->data, skb->len);
+ napi_consume_skb(skb, 1);
+ break;
case PKT_TYPE_RX_EVENT:
mt7915_mcu_rx_event(dev, skb);
break;
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/mac.h b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/mac.h
index 5add1dd..c5fd1a6 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/mac.h
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/mac.h
@@ -24,6 +24,7 @@
PKT_TYPE_TXRX_NOTIFY,
PKT_TYPE_RX_EVENT,
PKT_TYPE_RX_FW_MONITOR = 0x0c,
+ PKT_TYPE_TXRX_NOTIFY_V0 = 0x18,
};
/* RXD DW1 */
@@ -311,6 +312,7 @@
#define MT_TX_FREE_VER GENMASK(18, 16)
#define MT_TX_FREE_MSDU_CNT GENMASK(9, 0)
+#define MT_TX_FREE_MSDU_CNT_V0 GENMASK(6, 0)
#define MT_TX_FREE_WLAN_ID GENMASK(23, 14)
#define MT_TX_FREE_LATENCY GENMASK(12, 0)
/* 0: success, others: dropped */
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/main.c b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/main.c
index 865694c..78bf5ff 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/main.c
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/main.c
@@ -42,10 +42,6 @@
if (ret)
goto out;
- ret = mt7915_mcu_set_scs(dev, 0, true);
- if (ret)
- goto out;
-
mt7915_mac_enable_nf(dev, 0);
}
@@ -58,10 +54,6 @@
if (ret)
goto out;
- ret = mt7915_mcu_set_scs(dev, 1, true);
- if (ret)
- goto out;
-
mt7915_mac_enable_nf(dev, 1);
}
@@ -174,14 +166,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));
}
}
@@ -1381,6 +1373,39 @@
return ret;
}
+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
+static int
+mt7915_net_fill_forward_path(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+ struct net_device_path_ctx *ctx,
+ struct net_device_path *path)
+{
+ struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
+ struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
+ struct mt7915_dev *dev = mt7915_hw_dev(hw);
+ struct mt7915_phy *phy = mt7915_hw_phy(hw);
+ struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
+
+ if (!mtk_wed_device_active(wed))
+ return -ENODEV;
+
+ if (msta->wcid.idx > 0xff)
+ return -EIO;
+
+ path->type = DEV_PATH_MTK_WDMA;
+ path->dev = ctx->dev;
+ path->mtk_wdma.wdma_idx = wed->wdma_idx;
+ path->mtk_wdma.bss = mvif->mt76.idx;
+ path->mtk_wdma.wcid = msta->wcid.idx;
+ path->mtk_wdma.queue = phy != &dev->phy;
+
+ ctx->dev = NULL;
+
+ return 0;
+}
+#endif
+
const struct ieee80211_ops mt7915_ops = {
.tx = mt7915_tx,
.start = mt7915_start,
@@ -1428,4 +1453,7 @@
.sta_add_debugfs = mt7915_sta_add_debugfs,
#endif
.set_radar_background = mt7915_set_radar_background,
+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
+ .net_fill_forward_path = mt7915_net_fill_forward_path,
+#endif
};
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/mcu.c b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/mcu.c
index ec93a92..ac2083f 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/mcu.c
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/mcu.c
@@ -2499,6 +2499,9 @@
if (ret)
return ret;
+ if (mtk_wed_device_active(&dev->mt76.mmio.wed))
+ mt7915_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(CAPABILITY), 0, 0, 0);
+
ret = mt7915_mcu_set_mwds(dev, 1);
if (ret)
return ret;
@@ -2589,22 +2592,6 @@
&req_mac, sizeof(req_mac), true);
}
-int mt7915_mcu_set_scs(struct mt7915_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 mt7915_mcu_update_edca(struct mt7915_dev *dev, void *param)
{
struct mt7915_mcu_tx *req = (struct mt7915_mcu_tx *)param;
@@ -3677,3 +3664,32 @@
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(TWT_AGRT_UPDATE),
&req, sizeof(req), true);
}
+
+int mt7915_mcu_rf_regval(struct mt7915_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/mt7915/mcu.h b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/mcu.h
index 960072a..064d33e 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/mcu.h
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/mcu.h
@@ -304,16 +304,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_info_bmc_rate {
__le16 tag;
__le16 len;
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/mmio.c b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/mmio.c
index 5062e0d..89ea285 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/mmio.c
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/mmio.c
@@ -547,15 +547,21 @@
static void mt7915_irq_tasklet(struct tasklet_struct *t)
{
struct mt7915_dev *dev = from_tasklet(dev, t, irq_tasklet);
+ struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
u32 intr, intr1, mask;
- mt76_wr(dev, MT_INT_MASK_CSR, 0);
- if (dev->hif2)
- mt76_wr(dev, MT_INT1_MASK_CSR, 0);
+ if (mtk_wed_device_active(wed)) {
+ mtk_wed_device_irq_set_mask(wed, 0);
+ intr = mtk_wed_device_irq_get(wed, dev->mt76.mmio.irqmask);
+ } else {
+ mt76_wr(dev, MT_INT_MASK_CSR, 0);
+ if (dev->hif2)
+ mt76_wr(dev, MT_INT1_MASK_CSR, 0);
- intr = mt76_rr(dev, MT_INT_SOURCE_CSR);
- intr &= dev->mt76.mmio.irqmask;
- mt76_wr(dev, MT_INT_SOURCE_CSR, intr);
+ intr = mt76_rr(dev, MT_INT_SOURCE_CSR);
+ intr &= dev->mt76.mmio.irqmask;
+ mt76_wr(dev, MT_INT_SOURCE_CSR, intr);
+ }
if (dev->hif2) {
intr1 = mt76_rr(dev, MT_INT1_SOURCE_CSR);
@@ -610,10 +616,15 @@
irqreturn_t mt7915_irq_handler(int irq, void *dev_instance)
{
struct mt7915_dev *dev = dev_instance;
+ struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
- mt76_wr(dev, MT_INT_MASK_CSR, 0);
- if (dev->hif2)
- mt76_wr(dev, MT_INT1_MASK_CSR, 0);
+ if (mtk_wed_device_active(wed)) {
+ mtk_wed_device_irq_set_mask(wed, 0);
+ } else {
+ mt76_wr(dev, MT_INT_MASK_CSR, 0);
+ if (dev->hif2)
+ mt76_wr(dev, MT_INT1_MASK_CSR, 0);
+ }
if (!test_bit(MT76_STATE_INITIALIZED, &dev->mphy.state))
return IRQ_NONE;
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/mt7915.h b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/mt7915.h
index ca129e5..43dc27c 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/mt7915.h
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/mt7915.h
@@ -432,6 +432,8 @@
void mt7915_wfsys_reset(struct mt7915_dev *dev);
irqreturn_t mt7915_irq_handler(int irq, void *dev_instance);
u64 __mt7915_get_tsf(struct ieee80211_hw *hw, struct mt7915_vif *mvif);
+u32 mt7915_wed_init_buf(void *ptr, dma_addr_t phys, int token_id);
+
int mt7915_register_device(struct mt7915_dev *dev);
void mt7915_unregister_device(struct mt7915_dev *dev);
int mt7915_eeprom_init(struct mt7915_dev *dev);
@@ -486,7 +488,6 @@
bool hdr_trans);
int mt7915_mcu_set_test_param(struct mt7915_dev *dev, u8 param, bool test_mode,
u8 en);
-int mt7915_mcu_set_scs(struct mt7915_dev *dev, u8 band, bool enable);
int mt7915_mcu_set_ser(struct mt7915_dev *dev, u8 action, u8 set, u8 band);
int mt7915_mcu_set_sku_en(struct mt7915_phy *phy, bool enable);
int mt7915_mcu_set_txpower_sku(struct mt7915_phy *phy);
@@ -507,6 +508,7 @@
struct ieee80211_sta *sta, struct rate_info *rate);
int mt7915_mcu_rdd_background_enable(struct mt7915_phy *phy,
struct cfg80211_chan_def *chandef);
+int mt7915_mcu_rf_regval(struct mt7915_dev *dev, u32 regidx, u32 *val, bool set);
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);
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/pci.c b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/pci.c
index 1bab1cb..f6222ef 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/pci.c
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/pci.c
@@ -12,6 +12,9 @@
#include "mac.h"
#include "../trace.h"
+static bool wed_enable = false;
+module_param(wed_enable, bool, 0644);
+
static LIST_HEAD(hif_list);
static DEFINE_SPINLOCK(hif_lock);
static u32 hif_idx;
@@ -89,15 +92,82 @@
spin_unlock_bh(&hif_lock);
pci_set_drvdata(pdev, hif);
+ return 0;
+}
+
+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
+static int mt7915_wed_offload_enable(struct mtk_wed_device *wed)
+{
+ struct mt7915_dev *dev;
+ int ret;
+
+ dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
+
+ spin_lock_bh(&dev->mt76.token_lock);
+ dev->mt76.token_size = wed->wlan.token_start;
+ spin_unlock_bh(&dev->mt76.token_lock);
+
+ ret = wait_event_timeout(dev->mt76.tx_wait,
+ !dev->mt76.wed_token_count, HZ);
+ if (!ret)
+ return -EAGAIN;
+
+ return 0;
+}
+
+static void mt7915_wed_offload_disable(struct mtk_wed_device *wed)
+{
+ struct mt7915_dev *dev;
+
+ dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
+
+ spin_lock_bh(&dev->mt76.token_lock);
+ dev->mt76.token_size = MT7915_TOKEN_SIZE;
+ spin_unlock_bh(&dev->mt76.token_lock);
+}
+#endif
+
+static int
+mt7915_pci_wed_init(struct mt7915_dev *dev, struct pci_dev *pdev, int *irq)
+{
+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
+ struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
+ int ret;
+
+ if (!wed_enable)
+ return 0;
+
+ wed->wlan.pci_dev = pdev;
+ wed->wlan.wpdma_phys = pci_resource_start(pdev, 0) +
+ MT_WFDMA_EXT_CSR_BASE;
+ wed->wlan.nbuf = 4096;
+ wed->wlan.token_start = MT7915_TOKEN_SIZE - wed->wlan.nbuf;
+ wed->wlan.init_buf = mt7915_wed_init_buf;
+ wed->wlan.offload_enable = mt7915_wed_offload_enable;
+ wed->wlan.offload_disable = mt7915_wed_offload_disable;
+
+ if (mtk_wed_device_attach(wed) != 0)
+ return 0;
+
+ *irq = wed->irq;
+ dev->mt76.dma_dev = wed->dev;
+
+ ret = dma_set_mask(wed->dev, DMA_BIT_MASK(32));
+ if (ret)
+ return ret;
+
+ return 1;
+#else
return 0;
+#endif
}
static int mt7915_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
+ struct mt7915_hif *hif2 = NULL;
struct mt7915_dev *dev;
struct mt76_dev *mdev;
- struct mt7915_hif *hif2;
int irq;
int ret;
@@ -129,15 +199,24 @@
mt7915_wfsys_reset(dev);
hif2 = mt7915_pci_init_hif2(pdev);
- ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
+ ret = mt7915_pci_wed_init(dev, pdev, &irq);
if (ret < 0)
- goto free_device;
+ goto free_wed_or_irq_vector;
- irq = pdev->irq;
+ if (!ret) {
+ hif2 = mt7915_pci_init_hif2(pdev);
+
+ ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
+ if (ret < 0)
+ goto free_device;
+
+ irq = pdev->irq;
+ }
+
ret = devm_request_irq(mdev->dev, irq, mt7915_irq_handler,
IRQF_SHARED, KBUILD_MODNAME, dev);
if (ret)
- goto free_irq_vector;
+ goto free_wed_or_irq_vector;
mt76_wr(dev, MT_INT_MASK_CSR, 0);
@@ -174,8 +253,11 @@
if (dev->hif2)
put_device(dev->hif2->dev);
devm_free_irq(mdev->dev, irq, dev);
-free_irq_vector:
- pci_free_irq_vectors(pdev);
+free_wed_or_irq_vector:
+ if (mtk_wed_device_active(&mdev->mmio.wed))
+ mtk_wed_device_detach(&mdev->mmio.wed);
+ else
+ pci_free_irq_vectors(pdev);
free_device:
mt76_free_device(&dev->mt76);
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/regs.h b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/regs.h
index e5f93c4..bb0dec8 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/regs.h
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/regs.h
@@ -158,6 +158,9 @@
#define MT_MDP_DCR1 MT_MDP(0x004)
#define MT_MDP_DCR1_MAX_RX_LEN GENMASK(15, 3)
+#define MT_MDP_DCR2 MT_MDP(0x0e8)
+#define MT_MDP_DCR2_RX_TRANS_SHORT BIT(2)
+
#define MT_MDP_BNRCFR0(_band) MT_MDP(__OFFS(MDP_BNRCFR0) + \
((_band) << 8))
#define MT_MDP_RCFR0_MCU_RX_MGMT GENMASK(5, 4)
@@ -565,18 +568,31 @@
/* WFDMA CSR */
#define MT_WFDMA_EXT_CSR_BASE __REG(WFDMA_EXT_CSR_ADDR)
+#define MT_WFDMA_EXT_CSR_PHYS_BASE 0x18027000
#define MT_WFDMA_EXT_CSR(ofs) (MT_WFDMA_EXT_CSR_BASE + (ofs))
+#define MT_WFDMA_EXT_CSR_PHYS(ofs) (MT_WFDMA_EXT_CSR_PHYS_BASE + (ofs))
-#define MT_WFDMA_HOST_CONFIG MT_WFDMA_EXT_CSR(0x30)
+#define MT_WFDMA_HOST_CONFIG MT_WFDMA_EXT_CSR_PHYS(0x30)
#define MT_WFDMA_HOST_CONFIG_PDMA_BAND BIT(0)
+#define MT_WFDMA_HOST_CONFIG_WED BIT(1)
+
+#define MT_WFDMA_WED_RING_CONTROL MT_WFDMA_EXT_CSR_PHYS(0x34)
+#define MT_WFDMA_WED_RING_CONTROL_TX0 GENMASK(4, 0)
+#define MT_WFDMA_WED_RING_CONTROL_TX1 GENMASK(12, 8)
+#define MT_WFDMA_WED_RING_CONTROL_RX1 GENMASK(20, 16)
-#define MT_WFDMA_EXT_CSR_HIF_MISC MT_WFDMA_EXT_CSR(0x44)
+#define MT_WFDMA_EXT_CSR_HIF_MISC MT_WFDMA_EXT_CSR_PHYS(0x44)
#define MT_WFDMA_EXT_CSR_HIF_MISC_BUSY BIT(0)
#define MT_PCIE_RECOG_ID 0xd7090
#define MT_PCIE_RECOG_ID_MASK GENMASK(30, 0)
#define MT_PCIE_RECOG_ID_SEM BIT(31)
+#define MT_INT_WED_MASK_CSR MT_WFDMA_EXT_CSR(0x204)
+
+#define MT_WED_TX_RING_BASE MT_WFDMA_EXT_CSR(0x300)
+#define MT_WED_RX_RING_BASE MT_WFDMA_EXT_CSR(0x400)
+
/* WFDMA0 PCIE1 */
#define MT_WFDMA0_PCIE1_BASE __REG(WFDMA0_PCIE1_ADDR)
#define MT_WFDMA0_PCIE1(ofs) (MT_WFDMA0_PCIE1_BASE + (ofs))
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/soc.c b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/soc.c
index 5592e9e..0694750 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/soc.c
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7915/soc.c
@@ -11,6 +11,7 @@
#include <linux/iopoll.h>
#include <linux/reset.h>
#include <linux/of_net.h>
+#include <linux/clk.h>
#include "mt7915.h"
@@ -209,6 +210,8 @@
if (IS_ERR_OR_NULL(state))
return -EINVAL;
break;
+ default:
+ return -EINVAL;
}
ret = pinctrl_select_state(pinctrl, state);
@@ -1114,6 +1117,19 @@
{
struct device *pdev = dev->mt76.dev;
struct platform_device *pfdev = to_platform_device(pdev);
+ struct clk *mcu_clk, *ap_conn_clk;
+
+ mcu_clk = devm_clk_get(pdev, "mcu");
+ if (IS_ERR(mcu_clk))
+ dev_err(pdev, "mcu clock not found\n");
+ else if (clk_prepare_enable(mcu_clk))
+ dev_err(pdev, "mcu clock configuration failed\n");
+
+ ap_conn_clk = devm_clk_get(pdev, "ap2conn");
+ if (IS_ERR(ap_conn_clk))
+ dev_err(pdev, "ap2conn clock not found\n");
+ else if (clk_prepare_enable(ap_conn_clk))
+ dev_err(pdev, "ap2conn clock configuration failed\n");
dev->dcm = devm_platform_ioremap_resource(pfdev, 1);
if (IS_ERR(dev->dcm))
@@ -1127,7 +1143,7 @@
if (IS_ERR(dev->rstc))
return PTR_ERR(dev->rstc);
- return mt7986_wmac_enable(dev);
+ return 0;
}
static int mt7986_wmac_probe(struct platform_device *pdev)
@@ -1160,13 +1176,13 @@
if (ret)
goto free_device;
- mt7915_wfsys_reset(dev);
- mt76_wr(dev, MT_INT_MASK_CSR, 0);
-
ret = mt7986_wmac_init(dev);
if (ret)
goto free_irq;
+ mt7915_wfsys_reset(dev);
+ mt76_wr(dev, MT_INT_MASK_CSR, 0);
+
ret = mt7915_register_device(dev);
if (ret)
goto free_irq;
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7921/dma.c b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7921/dma.c
index ca7e20f..2939cf9 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7921/dma.c
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7921/dma.c
@@ -9,7 +9,7 @@
{
int i, err;
- err = mt76_init_tx_queue(phy->mt76, 0, idx, n_desc, MT_TX_RING_BASE);
+ err = mt76_init_tx_queue(phy->mt76, 0, idx, n_desc, MT_TX_RING_BASE, 0);
if (err < 0)
return err;
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7921/init.c b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7921/init.c
index 91fc419..f9e1255 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7921/init.c
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7921/init.c
@@ -11,6 +11,10 @@
{
.max = MT7921_MAX_INTERFACES,
.types = BIT(NL80211_IFTYPE_STATION)
+ },
+ {
+ .max = 1,
+ .types = BIT(NL80211_IFTYPE_AP)
}
};
@@ -64,7 +68,8 @@
wiphy->iface_combinations = if_comb;
wiphy->flags &= ~(WIPHY_FLAG_IBSS_RSN | WIPHY_FLAG_4ADDR_AP |
WIPHY_FLAG_4ADDR_STATION);
- wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+ wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+ BIT(NL80211_IFTYPE_AP);
wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
wiphy->max_scan_ie_len = MT76_CONNAC_SCAN_IE_LEN;
wiphy->max_scan_ssids = 4;
@@ -80,6 +85,10 @@
wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR |
NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_SET_SCAN_DWELL);
+ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_LEGACY);
+ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_HT);
+ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_VHT);
+ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_HE);
ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS);
ieee80211_hw_set(hw, HAS_RATE_CONTROL);
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7921/mac.c b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7921/mac.c
index f34070c..ac11e8b 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7921/mac.c
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7921/mac.c
@@ -814,6 +814,7 @@
{
u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
u8 fc_type, fc_stype;
+ u16 ethertype;
bool wmm = false;
u32 val;
@@ -827,7 +828,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);
@@ -1361,12 +1363,21 @@
{
struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
struct mt7921_dev *dev = mvif->phy->dev;
+ struct ieee80211_hw *hw = mt76_hw(dev);
if (vif->type == NL80211_IFTYPE_STATION)
ieee80211_disconnect(vif, true);
mt76_connac_mcu_uni_add_dev(&dev->mphy, vif, &mvif->sta.wcid, true);
mt7921_mcu_set_tx(dev, vif);
+
+ if (vif->type == NL80211_IFTYPE_AP) {
+ mt76_connac_mcu_uni_add_bss(dev->phy.mt76, vif, &mvif->sta.wcid,
+ true);
+ mt7921_mcu_sta_update(dev, NULL, vif, true,
+ MT76_STA_INFO_STATE_NONE);
+ mt7921_mcu_uni_add_beacon_offload(dev, hw, vif, true);
+ }
}
/* system error recovery */
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7921/main.c b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7921/main.c
index 8e88cca..a6d9cc8 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7921/main.c
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7921/main.c
@@ -12,7 +12,7 @@
mt7921_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,
@@ -53,6 +53,7 @@
switch (i) {
case NL80211_IFTYPE_STATION:
+ case NL80211_IFTYPE_AP:
break;
default:
continue;
@@ -86,6 +87,23 @@
IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO;
switch (i) {
+ case NL80211_IFTYPE_AP:
+ he_cap_elem->mac_cap_info[2] |=
+ IEEE80211_HE_MAC_CAP2_BSR;
+ he_cap_elem->mac_cap_info[4] |=
+ IEEE80211_HE_MAC_CAP4_BQR;
+ he_cap_elem->mac_cap_info[5] |=
+ IEEE80211_HE_MAC_CAP5_OM_CTRL_UL_MU_DATA_DIS_RX;
+ he_cap_elem->phy_cap_info[3] |=
+ IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_QPSK |
+ IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_QPSK;
+ he_cap_elem->phy_cap_info[6] |=
+ IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE |
+ IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT;
+ he_cap_elem->phy_cap_info[9] |=
+ IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU |
+ IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU;
+ break;
case NL80211_IFTYPE_STATION:
he_cap_elem->mac_cap_info[1] |=
IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US;
@@ -633,6 +651,20 @@
}
}
+ if (changed & BSS_CHANGED_BEACON_ENABLED && info->enable_beacon) {
+ struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
+
+ mt76_connac_mcu_uni_add_bss(phy->mt76, vif, &mvif->sta.wcid,
+ true);
+ mt7921_mcu_sta_update(dev, NULL, vif, true,
+ MT76_STA_INFO_STATE_NONE);
+ }
+
+ if (changed & (BSS_CHANGED_BEACON |
+ BSS_CHANGED_BEACON_ENABLED))
+ mt7921_mcu_uni_add_beacon_offload(dev, hw, vif,
+ info->enable_beacon);
+
/* ensure that enable txcmd_mode after bss_info */
if (changed & (BSS_CHANGED_QOS | BSS_CHANGED_BEACON_ENABLED))
mt7921_mcu_set_tx(dev, vif);
@@ -1393,6 +1425,18 @@
return err;
}
+static void
+mt7921_channel_switch_beacon(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct cfg80211_chan_def *chandef)
+{
+ struct mt7921_dev *dev = mt7921_hw_dev(hw);
+
+ mt7921_mutex_acquire(dev);
+ mt7921_mcu_uni_add_beacon_offload(dev, hw, vif, true);
+ mt7921_mutex_release(dev);
+}
+
const struct ieee80211_ops mt7921_ops = {
.tx = mt7921_tx,
.start = mt7921_start,
@@ -1411,6 +1455,7 @@
.set_rts_threshold = mt7921_set_rts_threshold,
.wake_tx_queue = mt76_wake_tx_queue,
.release_buffered_frames = mt76_release_buffered_frames,
+ .channel_switch_beacon = mt7921_channel_switch_beacon,
.get_txpower = mt76_get_txpower,
.get_stats = mt7921_get_stats,
.get_et_sset_count = mt7921_get_et_sset_count,
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7921/mcu.c b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7921/mcu.c
index da2be05..1ecbbe4 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7921/mcu.c
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7921/mcu.c
@@ -248,7 +248,8 @@
if (mvif->idx != event->bss_idx)
return;
- if (!(vif->driver_flags & IEEE80211_VIF_BEACON_FILTER))
+ if (!(vif->driver_flags & IEEE80211_VIF_BEACON_FILTER) ||
+ vif->type != NL80211_IFTYPE_STATION)
return;
ieee80211_connection_loss(vif);
@@ -1166,3 +1167,79 @@
return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD(SNIFFER), &req, sizeof(req),
true);
}
+
+int
+mt7921_mcu_uni_add_beacon_offload(struct mt7921_dev *dev,
+ struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ bool enable)
+{
+ struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
+ struct mt76_wcid *wcid = &dev->mt76.global_wcid;
+ struct ieee80211_mutable_offsets offs;
+ struct {
+ struct req_hdr {
+ u8 bss_idx;
+ u8 pad[3];
+ } __packed hdr;
+ struct bcn_content_tlv {
+ __le16 tag;
+ __le16 len;
+ __le16 tim_ie_pos;
+ __le16 csa_ie_pos;
+ __le16 bcc_ie_pos;
+ /* 0: disable beacon offload
+ * 1: enable beacon offload
+ * 2: update probe respond offload
+ */
+ u8 enable;
+ /* 0: legacy format (TXD + payload)
+ * 1: only cap field IE
+ */
+ u8 type;
+ __le16 pkt_len;
+ u8 pkt[512];
+ } __packed beacon_tlv;
+ } req = {
+ .hdr = {
+ .bss_idx = mvif->mt76.idx,
+ },
+ .beacon_tlv = {
+ .tag = cpu_to_le16(UNI_BSS_INFO_BCN_CONTENT),
+ .len = cpu_to_le16(sizeof(struct bcn_content_tlv)),
+ .enable = enable,
+ },
+ };
+ struct sk_buff *skb;
+
+ if (!enable)
+ goto out;
+
+ skb = ieee80211_beacon_get_template(mt76_hw(dev), vif, &offs);
+ if (!skb)
+ return -EINVAL;
+
+ if (skb->len > 512 - MT_TXD_SIZE) {
+ dev_err(dev->mt76.dev, "beacon size limit exceed\n");
+ dev_kfree_skb(skb);
+ return -EINVAL;
+ }
+
+ mt7921_mac_write_txwi(dev, (__le32 *)(req.beacon_tlv.pkt), skb,
+ wcid, NULL, 0, true);
+ memcpy(req.beacon_tlv.pkt + MT_TXD_SIZE, skb->data, skb->len);
+ req.beacon_tlv.pkt_len = cpu_to_le16(MT_TXD_SIZE + skb->len);
+ req.beacon_tlv.tim_ie_pos = cpu_to_le16(MT_TXD_SIZE + offs.tim_offset);
+
+ if (offs.cntdwn_counter_offs[0]) {
+ u16 csa_offs;
+
+ csa_offs = MT_TXD_SIZE + offs.cntdwn_counter_offs[0] - 4;
+ req.beacon_tlv.csa_ie_pos = cpu_to_le16(csa_offs);
+ }
+ dev_kfree_skb(skb);
+
+out:
+ return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD(BSS_INFO_UPDATE),
+ &req, sizeof(req), true);
+}
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7921/mt7921.h b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7921/mt7921.h
index eae223a..adbdb2e 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7921/mt7921.h
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7921/mt7921.h
@@ -469,4 +469,8 @@
int mt7921u_dma_init(struct mt7921_dev *dev, bool resume);
int mt7921u_init_reset(struct mt7921_dev *dev);
int mt7921u_mac_reset(struct mt7921_dev *dev);
+int mt7921_mcu_uni_add_beacon_offload(struct mt7921_dev *dev,
+ struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ bool enable);
#endif
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7921/pci.c b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7921/pci.c
index 1a01d02..b5fb22b 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7921/pci.c
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/mt7921/pci.c
@@ -119,7 +119,6 @@
mt7921_mcu_exit(dev);
tasklet_disable(&dev->irq_tasklet);
- mt76_free_device(&dev->mt76);
}
static u32 __mt7921_reg_addr(struct mt7921_dev *dev, u32 addr)
@@ -302,8 +301,10 @@
dev->bus_ops = dev->mt76.bus;
bus_ops = devm_kmemdup(dev->mt76.dev, dev->bus_ops, sizeof(*bus_ops),
GFP_KERNEL);
- if (!bus_ops)
- return -ENOMEM;
+ if (!bus_ops) {
+ ret = -ENOMEM;
+ goto err_free_dev;
+ }
bus_ops->rr = mt7921_rr;
bus_ops->wr = mt7921_wr;
@@ -312,7 +313,7 @@
ret = __mt7921e_mcu_drv_pmctrl(dev);
if (ret)
- return ret;
+ goto err_free_dev;
mdev->rev = (mt7921_l1_rr(dev, MT_HW_CHIPID) << 16) |
(mt7921_l1_rr(dev, MT_HW_REV) & 0xff);
@@ -354,6 +355,7 @@
mt7921e_unregister_device(dev);
devm_free_irq(&pdev->dev, pdev->irq, dev);
+ mt76_free_device(&dev->mt76);
pci_free_irq_vectors(pdev);
}
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/tx.c b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/tx.c
index e0174bd..59a382a 100644
--- a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/tx.c
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/tx.c
@@ -120,7 +120,7 @@
memset(cb, 0, sizeof(*cb));
- if (!wcid)
+ if (!wcid || !rcu_access_pointer(dev->wcid[wcid->idx]))
return MT_PACKET_ID_NO_ACK;
if (info->flags & IEEE80211_TX_CTL_NO_ACK)
@@ -729,12 +729,17 @@
spin_lock_bh(&dev->token_lock);
- token = idr_alloc(&dev->token, *ptxwi, 0, dev->drv->token_size,
- GFP_ATOMIC);
+ token = idr_alloc(&dev->token, *ptxwi, 0, dev->token_size, GFP_ATOMIC);
if (token >= 0)
dev->token_count++;
- if (dev->token_count >= dev->drv->token_size - MT76_TOKEN_FREE_THR)
+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
+ if (mtk_wed_device_active(&dev->mmio.wed) &&
+ token >= dev->mmio.wed.wlan.token_start)
+ dev->wed_token_count++;
+#endif
+
+ if (dev->token_count >= dev->token_size - MT76_TOKEN_FREE_THR)
__mt76_set_tx_blocked(dev, true);
spin_unlock_bh(&dev->token_lock);
@@ -751,10 +756,18 @@
spin_lock_bh(&dev->token_lock);
txwi = idr_remove(&dev->token, token);
- if (txwi)
+ if (txwi) {
dev->token_count--;
+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
+ if (mtk_wed_device_active(&dev->mmio.wed) &&
+ token >= dev->mmio.wed.wlan.token_start &&
+ --dev->wed_token_count == 0)
+ wake_up(&dev->tx_wait);
+#endif
+ }
+
- if (dev->token_count < dev->drv->token_size - MT76_TOKEN_FREE_THR &&
+ if (dev->token_count < dev->token_size - MT76_TOKEN_FREE_THR &&
dev->phy.q_tx[0]->blocked)
*wake = true;