diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c index bb291fe314fb4..d96ee759828ed 100644 --- a/drivers/net/wireless/mediatek/mt76/mac80211.c +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c @@ -1529,7 +1529,7 @@ EXPORT_SYMBOL_GPL(mt76_wcid_init); void mt76_wcid_cleanup(struct mt76_dev *dev, struct mt76_wcid *wcid) { - struct mt76_phy *phy = dev->phys[wcid->phy_idx]; + struct mt76_phy *phy = mt76_dev_phy(dev, wcid->phy_idx); struct ieee80211_hw *hw; struct sk_buff_head list; struct sk_buff *skb; diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h b/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h index 353e660698409..db0c29e65185c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h @@ -28,8 +28,6 @@ enum { #define MT_RXD0_MESH BIT(18) #define MT_RXD0_MHCP BIT(19) #define MT_RXD0_NORMAL_ETH_TYPE_OFS GENMASK(22, 16) -#define MT_RXD0_NORMAL_IP_SUM BIT(23) -#define MT_RXD0_NORMAL_UDP_TCP_SUM BIT(24) #define MT_RXD0_SW_PKT_TYPE_MASK GENMASK(31, 16) #define MT_RXD0_SW_PKT_TYPE_MAP 0x380F @@ -80,6 +78,8 @@ enum { #define MT_RXD3_NORMAL_BEACON_UC BIT(21) #define MT_RXD3_NORMAL_CO_ANT BIT(22) #define MT_RXD3_NORMAL_FCS_ERR BIT(24) +#define MT_RXD3_NORMAL_IP_SUM BIT(26) +#define MT_RXD3_NORMAL_UDP_TCP_SUM BIT(27) #define MT_RXD3_NORMAL_VLAN2ETH BIT(31) /* RXD DW4 */ @@ -197,6 +197,13 @@ enum tx_mgnt_type { MT_TX_ADDBA, }; +enum tx_frag_idx { + MT_TX_FRAG_NONE, + MT_TX_FRAG_FIRST, + MT_TX_FRAG_MID, + MT_TX_FRAG_LAST +}; + #define MT_CT_INFO_APPLY_TXD BIT(0) #define MT_CT_INFO_COPY_HOST_TXD_ALL BIT(1) #define MT_CT_INFO_MGMT_FRAME BIT(2) diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c index ef0c721d26e33..57672c69150e4 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c @@ -83,7 +83,7 @@ mt7921_regd_channel_update(struct wiphy *wiphy, struct mt792x_dev *dev) } /* UNII-4 */ - if (IS_UNII_INVALID(0, 5850, 5925)) + if (IS_UNII_INVALID(0, 5845, 5925)) ch->flags |= IEEE80211_CHAN_DISABLED; } diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mac.c b/drivers/net/wireless/mediatek/mt76/mt7925/mac.c index cf36750cf7092..634c42bbf23f6 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/mac.c @@ -352,7 +352,7 @@ mt7925_mac_fill_rx_rate(struct mt792x_dev *dev, static int mt7925_mac_fill_rx(struct mt792x_dev *dev, struct sk_buff *skb) { - u32 csum_mask = MT_RXD0_NORMAL_IP_SUM | MT_RXD0_NORMAL_UDP_TCP_SUM; + u32 csum_mask = MT_RXD3_NORMAL_IP_SUM | MT_RXD3_NORMAL_UDP_TCP_SUM; struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb; bool hdr_trans, unicast, insert_ccmp_hdr = false; u8 chfreq, qos_ctl = 0, remove_pad, amsdu_info; @@ -362,7 +362,6 @@ mt7925_mac_fill_rx(struct mt792x_dev *dev, struct sk_buff *skb) struct mt792x_phy *phy = &dev->phy; struct ieee80211_supported_band *sband; u32 csum_status = *(u32 *)skb->cb; - u32 rxd0 = le32_to_cpu(rxd[0]); u32 rxd1 = le32_to_cpu(rxd[1]); u32 rxd2 = le32_to_cpu(rxd[2]); u32 rxd3 = le32_to_cpu(rxd[3]); @@ -420,7 +419,7 @@ mt7925_mac_fill_rx(struct mt792x_dev *dev, struct sk_buff *skb) if (!sband->channels) return -EINVAL; - if (mt76_is_mmio(&dev->mt76) && (rxd0 & csum_mask) == csum_mask && + if (mt76_is_mmio(&dev->mt76) && (rxd3 & csum_mask) == csum_mask && !(csum_status & (BIT(0) | BIT(2) | BIT(3)))) skb->ip_summed = CHECKSUM_UNNECESSARY; diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7996/eeprom.c index 4a82371182873..7e2d585a2e21e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/eeprom.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/eeprom.c @@ -26,6 +26,8 @@ static char *mt7996_eeprom_name(struct mt7996_dev *dev) { switch (mt76_chip(&dev->mt76)) { case 0x7990: + if (dev->var_type == MT7996_VAR_TYPE_233) + return MT7996_EEPROM_DEFAULT_233; return MT7996_EEPROM_DEFAULT; case 0x7992: return MT7992_EEPROM_DEFAULT; diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/init.c b/drivers/net/wireless/mediatek/mt76/mt7996/init.c index 283df84f1b433..ab1a9a8eebe9a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/init.c @@ -42,6 +42,7 @@ static const struct ieee80211_iface_combination if_comb[] = { BIT(NL80211_CHAN_WIDTH_40) | BIT(NL80211_CHAN_WIDTH_80) | BIT(NL80211_CHAN_WIDTH_160), + .beacon_int_min_gcd = 100, } }; @@ -883,6 +884,27 @@ static void mt7996_wed_rro_work(struct work_struct *work) #endif } +static int mt7996_chip_variant_init(struct mt7996_dev *dev) +{ + u32 val = mt76_rr(dev, MT_PAD_GPIO); + + switch (mt76_chip(&dev->mt76)) { + case 0x7990: + if (u32_get_bits(val, MT_PAD_GPIO_2ADIE_TBTC)) + dev->var_type = MT7996_VAR_TYPE_233; + else + dev->var_type = MT7996_VAR_TYPE_444; + break; + case 0x7992: + dev->var_type = MT7992_VAR_TYPE_44; + break; + default: + return -EINVAL; + } + + return 0; +} + static int mt7996_init_hardware(struct mt7996_dev *dev) { int ret, idx; @@ -898,6 +920,10 @@ static int mt7996_init_hardware(struct mt7996_dev *dev) INIT_LIST_HEAD(&dev->wed_rro.poll_list); spin_lock_init(&dev->wed_rro.lock); + ret = mt7996_chip_variant_init(dev); + if (ret) + return ret; + ret = mt7996_dma_init(dev); if (ret) return ret; @@ -941,8 +967,12 @@ void mt7996_set_stream_vht_txbf_caps(struct mt7996_phy *phy) cap = &phy->mt76->sband_5g.sband.vht_cap.cap; *cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE | - IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE | - FIELD_PREP(IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK, sts - 1); + IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE; + + if (is_mt7996(phy->mt76->dev)) + *cap |= FIELD_PREP(IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK, 3); + else + *cap |= FIELD_PREP(IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK, 4); *cap &= ~(IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK | IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE | @@ -987,9 +1017,15 @@ mt7996_set_stream_he_txbf_caps(struct mt7996_phy *phy, IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO; elem->phy_cap_info[2] |= c; - c = IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE | - IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_4 | - IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_4; + c = IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE; + + if (is_mt7996(phy->mt76->dev)) + c |= IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_4 | + IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_4; + else + c |= IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_5 | + IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_5; + elem->phy_cap_info[4] |= c; /* do not support NG16 due to spec D4.0 changes subcarrier idx */ @@ -1011,8 +1047,6 @@ mt7996_set_stream_he_txbf_caps(struct mt7996_phy *phy, return; elem->phy_cap_info[3] |= IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER; - if (vif == NL80211_IFTYPE_AP) - elem->phy_cap_info[4] |= IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER; c = FIELD_PREP(IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK, sts - 1) | @@ -1020,6 +1054,11 @@ mt7996_set_stream_he_txbf_caps(struct mt7996_phy *phy, sts - 1); elem->phy_cap_info[5] |= c; + if (vif != NL80211_IFTYPE_AP) + return; + + elem->phy_cap_info[4] |= IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER; + 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; @@ -1179,12 +1218,12 @@ mt7996_init_eht_caps(struct mt7996_phy *phy, enum nl80211_band band, IEEE80211_EHT_MAC_CAP0_OM_CONTROL; eht_cap_elem->phy_cap_info[0] = - IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ | IEEE80211_EHT_PHY_CAP0_NDP_4_EHT_LFT_32_GI | IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMER | IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMEE; - val = max_t(u8, sts - 1, 3); + /* Set the maximum capability regardless of the antenna configuration. */ + val = is_mt7992(phy->mt76->dev) ? 4 : 3; eht_cap_elem->phy_cap_info[0] |= u8_encode_bits(u8_get_bits(val, BIT(0)), IEEE80211_EHT_PHY_CAP0_BEAMFORMEE_SS_80MHZ_MASK); @@ -1193,30 +1232,36 @@ mt7996_init_eht_caps(struct mt7996_phy *phy, enum nl80211_band band, u8_encode_bits(u8_get_bits(val, GENMASK(2, 1)), IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_80MHZ_MASK) | u8_encode_bits(val, - IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_160MHZ_MASK) | - u8_encode_bits(val, - IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_320MHZ_MASK); + IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_160MHZ_MASK); eht_cap_elem->phy_cap_info[2] = u8_encode_bits(sts - 1, IEEE80211_EHT_PHY_CAP2_SOUNDING_DIM_80MHZ_MASK) | - u8_encode_bits(sts - 1, IEEE80211_EHT_PHY_CAP2_SOUNDING_DIM_160MHZ_MASK) | - u8_encode_bits(sts - 1, IEEE80211_EHT_PHY_CAP2_SOUNDING_DIM_320MHZ_MASK); + u8_encode_bits(sts - 1, IEEE80211_EHT_PHY_CAP2_SOUNDING_DIM_160MHZ_MASK); + + if (band == NL80211_BAND_6GHZ) { + eht_cap_elem->phy_cap_info[0] |= + IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ; + + eht_cap_elem->phy_cap_info[1] |= + u8_encode_bits(val, + IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_320MHZ_MASK); + + eht_cap_elem->phy_cap_info[2] |= + u8_encode_bits(sts - 1, + IEEE80211_EHT_PHY_CAP2_SOUNDING_DIM_320MHZ_MASK); + } eht_cap_elem->phy_cap_info[3] = IEEE80211_EHT_PHY_CAP3_NG_16_SU_FEEDBACK | IEEE80211_EHT_PHY_CAP3_NG_16_MU_FEEDBACK | IEEE80211_EHT_PHY_CAP3_CODEBOOK_4_2_SU_FDBK | - IEEE80211_EHT_PHY_CAP3_CODEBOOK_7_5_MU_FDBK | - IEEE80211_EHT_PHY_CAP3_TRIG_SU_BF_FDBK | - IEEE80211_EHT_PHY_CAP3_TRIG_MU_BF_PART_BW_FDBK | - IEEE80211_EHT_PHY_CAP3_TRIG_CQI_FDBK; + IEEE80211_EHT_PHY_CAP3_CODEBOOK_7_5_MU_FDBK; eht_cap_elem->phy_cap_info[4] = u8_encode_bits(min_t(int, sts - 1, 2), IEEE80211_EHT_PHY_CAP4_MAX_NC_MASK); eht_cap_elem->phy_cap_info[5] = - IEEE80211_EHT_PHY_CAP5_NON_TRIG_CQI_FEEDBACK | u8_encode_bits(IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_16US, IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_MASK) | u8_encode_bits(u8_get_bits(0x11, GENMASK(1, 0)), @@ -1230,14 +1275,6 @@ mt7996_init_eht_caps(struct mt7996_phy *phy, enum nl80211_band band, IEEE80211_EHT_PHY_CAP6_MAX_NUM_SUPP_EHT_LTF_MASK) | u8_encode_bits(val, IEEE80211_EHT_PHY_CAP6_MCS15_SUPP_MASK); - eht_cap_elem->phy_cap_info[7] = - IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_80MHZ | - IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_160MHZ | - IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_320MHZ | - IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_80MHZ | - IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_160MHZ | - IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_320MHZ; - val = u8_encode_bits(nss, IEEE80211_EHT_MCS_NSS_RX) | u8_encode_bits(nss, IEEE80211_EHT_MCS_NSS_TX); #define SET_EHT_MAX_NSS(_bw, _val) do { \ @@ -1248,8 +1285,29 @@ mt7996_init_eht_caps(struct mt7996_phy *phy, enum nl80211_band band, SET_EHT_MAX_NSS(80, val); SET_EHT_MAX_NSS(160, val); - SET_EHT_MAX_NSS(320, val); + if (band == NL80211_BAND_6GHZ) + SET_EHT_MAX_NSS(320, val); #undef SET_EHT_MAX_NSS + + if (iftype != NL80211_IFTYPE_AP) + return; + + eht_cap_elem->phy_cap_info[3] |= + IEEE80211_EHT_PHY_CAP3_TRIG_SU_BF_FDBK | + IEEE80211_EHT_PHY_CAP3_TRIG_MU_BF_PART_BW_FDBK; + + eht_cap_elem->phy_cap_info[7] = + IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_80MHZ | + IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_160MHZ | + IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_80MHZ | + IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_160MHZ; + + if (band != NL80211_BAND_6GHZ) + return; + + eht_cap_elem->phy_cap_info[7] |= + IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_320MHZ | + IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_320MHZ; } static void diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c index bc7111a71f98c..0d21414e2c884 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c @@ -435,7 +435,7 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, enum mt76_rxq_id q, u32 rxd2 = le32_to_cpu(rxd[2]); u32 rxd3 = le32_to_cpu(rxd[3]); u32 rxd4 = le32_to_cpu(rxd[4]); - u32 csum_mask = MT_RXD0_NORMAL_IP_SUM | MT_RXD0_NORMAL_UDP_TCP_SUM; + u32 csum_mask = MT_RXD3_NORMAL_IP_SUM | MT_RXD3_NORMAL_UDP_TCP_SUM; u32 csum_status = *(u32 *)skb->cb; u32 mesh_mask = MT_RXD0_MESH | MT_RXD0_MHCP; bool is_mesh = (rxd0 & mesh_mask) == mesh_mask; @@ -497,7 +497,7 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, enum mt76_rxq_id q, if (!sband->channels) return -EINVAL; - if ((rxd0 & csum_mask) == csum_mask && + if ((rxd3 & csum_mask) == csum_mask && !(csum_status & (BIT(0) | BIT(2) | BIT(3)))) skb->ip_summed = CHECKSUM_UNNECESSARY; @@ -746,7 +746,7 @@ mt7996_mac_write_txwi_80211(struct mt7996_dev *dev, __le32 *txwi, struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); bool multicast = is_multicast_ether_addr(hdr->addr1); u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK; - __le16 fc = hdr->frame_control; + __le16 fc = hdr->frame_control, sc = hdr->seq_ctrl; u8 fc_type, fc_stype; u32 val; @@ -780,6 +780,15 @@ mt7996_mac_write_txwi_80211(struct mt7996_dev *dev, __le32 *txwi, val = FIELD_PREP(MT_TXD2_FRAME_TYPE, fc_type) | FIELD_PREP(MT_TXD2_SUB_TYPE, fc_stype); + if (ieee80211_has_morefrags(fc) && ieee80211_is_first_frag(sc)) + val |= FIELD_PREP(MT_TXD2_FRAG, MT_TX_FRAG_FIRST); + else if (ieee80211_has_morefrags(fc) && !ieee80211_is_first_frag(sc)) + val |= FIELD_PREP(MT_TXD2_FRAG, MT_TX_FRAG_MID); + else if (!ieee80211_has_morefrags(fc) && !ieee80211_is_first_frag(sc)) + val |= FIELD_PREP(MT_TXD2_FRAG, MT_TX_FRAG_LAST); + else + val |= FIELD_PREP(MT_TXD2_FRAG, MT_TX_FRAG_NONE); + txwi[2] |= cpu_to_le32(val); txwi[3] |= cpu_to_le32(FIELD_PREP(MT_TXD3_BCM, multicast)); @@ -789,7 +798,7 @@ mt7996_mac_write_txwi_80211(struct mt7996_dev *dev, __le32 *txwi, } if (info->flags & IEEE80211_TX_CTL_INJECTED) { - u16 seqno = le16_to_cpu(hdr->seq_ctrl); + u16 seqno = le16_to_cpu(sc); if (ieee80211_is_back_req(hdr->frame_control)) { struct ieee80211_bar *bar; diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c index bce0820382194..d43bd5c2432e7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c @@ -206,7 +206,7 @@ static int mt7996_add_interface(struct ieee80211_hw *hw, mvif->mt76.omac_idx = idx; mvif->phy = phy; mvif->mt76.band_idx = band_idx; - mvif->mt76.wmm_idx = vif->type != NL80211_IFTYPE_AP; + mvif->mt76.wmm_idx = vif->type == NL80211_IFTYPE_AP ? 0 : 3; ret = mt7996_mcu_add_dev_info(phy, vif, true); if (ret) @@ -307,6 +307,10 @@ int mt7996_set_channel(struct mt7996_phy *phy) if (ret) goto out; + ret = mt7996_mcu_set_chan_info(phy, UNI_CHANNEL_RX_PATH); + if (ret) + goto out; + ret = mt7996_dfs_init_radar_detector(phy); mt7996_mac_cca_stats_reset(phy); @@ -360,14 +364,14 @@ static int mt7996_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, case WLAN_CIPHER_SUITE_SMS4: break; case WLAN_CIPHER_SUITE_AES_CMAC: - wcid_keyidx = &wcid->hw_key_idx2; - key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIE; - fallthrough; case WLAN_CIPHER_SUITE_BIP_CMAC_256: case WLAN_CIPHER_SUITE_BIP_GMAC_128: case WLAN_CIPHER_SUITE_BIP_GMAC_256: - if (key->keyidx == 6 || key->keyidx == 7) + if (key->keyidx == 6 || key->keyidx == 7) { + wcid_keyidx = &wcid->hw_key_idx2; + key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIE; break; + } fallthrough; case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c index 2e4fa9f48dfbe..60941e5cd7c8c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c @@ -17,6 +17,11 @@ _fw = MT7992_##name; \ break; \ case 0x7990: \ + if ((_dev)->var_type == MT7996_VAR_TYPE_233) \ + _fw = MT7996_##name##_233; \ + else \ + _fw = MT7996_##name; \ + break; \ default: \ _fw = MT7996_##name; \ break; \ @@ -822,7 +827,7 @@ mt7996_mcu_bss_mbssid_tlv(struct sk_buff *skb, struct ieee80211_vif *vif, struct bss_info_uni_mbssid *mbssid; struct tlv *tlv; - if (!vif->bss_conf.bssid_indicator) + if (!vif->bss_conf.bssid_indicator && enable) return; tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_11V_MBSSID, sizeof(*mbssid)); @@ -1429,10 +1434,10 @@ mt7996_is_ebf_supported(struct mt7996_phy *phy, struct ieee80211_vif *vif, if (bfee) return vif->bss_conf.eht_su_beamformee && - EHT_PHY(CAP0_SU_BEAMFORMEE, pe->phy_cap_info[0]); + EHT_PHY(CAP0_SU_BEAMFORMER, pe->phy_cap_info[0]); else return vif->bss_conf.eht_su_beamformer && - EHT_PHY(CAP0_SU_BEAMFORMER, pe->phy_cap_info[0]); + EHT_PHY(CAP0_SU_BEAMFORMEE, pe->phy_cap_info[0]); } if (sta->deflink.he_cap.has_he) { @@ -1544,6 +1549,9 @@ mt7996_mcu_sta_bfer_he(struct ieee80211_sta *sta, struct ieee80211_vif *vif, u8 nss_mcs = mt7996_mcu_get_sta_nss(mcs_map); u8 snd_dim, sts; + if (!vc) + return; + bf->tx_mode = MT_PHY_TYPE_HE_SU; mt7996_mcu_sta_sounding_rate(bf); @@ -1653,7 +1661,7 @@ mt7996_mcu_sta_bfer_tlv(struct mt7996_dev *dev, struct sk_buff *skb, { struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; struct mt7996_phy *phy = mvif->phy; - int tx_ant = hweight8(phy->mt76->chainmask) - 1; + int tx_ant = hweight16(phy->mt76->chainmask) - 1; struct sta_rec_bf *bf; struct tlv *tlv; static const u8 matrix[4][4] = { @@ -2849,6 +2857,7 @@ static int __mt7996_load_ram(struct mt7996_dev *dev, const char *fw_type, static int mt7996_load_ram(struct mt7996_dev *dev) { + const char *dsp_name; int ret; ret = __mt7996_load_ram(dev, "WM", fw_name(dev, FIRMWARE_WM), @@ -2856,7 +2865,8 @@ static int mt7996_load_ram(struct mt7996_dev *dev) if (ret) return ret; - ret = __mt7996_load_ram(dev, "DSP", fw_name(dev, FIRMWARE_DSP), + dsp_name = is_mt7996(&dev->mt76) ? MT7996_FIRMWARE_DSP : MT7992_FIRMWARE_DSP; + ret = __mt7996_load_ram(dev, "DSP", dsp_name, MT7996_RAM_TYPE_DSP); if (ret) return ret; @@ -3923,8 +3933,9 @@ int mt7996_mcu_set_txbf(struct mt7996_dev *dev, u8 action) tlv = mt7996_mcu_add_uni_tlv(skb, action, sizeof(*req_mod_en)); req_mod_en = (struct bf_mod_en_ctrl *)tlv; - req_mod_en->bf_num = 3; - req_mod_en->bf_bitmap = GENMASK(2, 0); + req_mod_en->bf_num = mt7996_band_valid(dev, MT_BAND2) ? 3 : 2; + req_mod_en->bf_bitmap = mt7996_band_valid(dev, MT_BAND2) ? + GENMASK(2, 0) : GENMASK(1, 0); break; } default: diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h index 177cfff31120e..583b49c15dd0d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h @@ -34,12 +34,17 @@ #define MT7996_FIRMWARE_DSP "mediatek/mt7996/mt7996_dsp.bin" #define MT7996_ROM_PATCH "mediatek/mt7996/mt7996_rom_patch.bin" +#define MT7996_FIRMWARE_WA_233 "mediatek/mt7996/mt7996_wa_233.bin" +#define MT7996_FIRMWARE_WM_233 "mediatek/mt7996/mt7996_wm_233.bin" +#define MT7996_ROM_PATCH_233 "mediatek/mt7996/mt7996_rom_patch_233.bin" + #define MT7992_FIRMWARE_WA "mediatek/mt7996/mt7992_wa.bin" #define MT7992_FIRMWARE_WM "mediatek/mt7996/mt7992_wm.bin" #define MT7992_FIRMWARE_DSP "mediatek/mt7996/mt7992_dsp.bin" #define MT7992_ROM_PATCH "mediatek/mt7996/mt7992_rom_patch.bin" #define MT7996_EEPROM_DEFAULT "mediatek/mt7996/mt7996_eeprom.bin" +#define MT7996_EEPROM_DEFAULT_233 "mediatek/mt7996/mt7996_eeprom_233.bin" #define MT7992_EEPROM_DEFAULT "mediatek/mt7996/mt7992_eeprom.bin" #define MT7996_EEPROM_SIZE 7680 #define MT7996_EEPROM_BLOCK_SIZE 16 @@ -89,6 +94,14 @@ struct mt7996_sta; struct mt7996_dfs_pulse; struct mt7996_dfs_pattern; +enum mt7996_var_type { + MT7996_VAR_TYPE_444, + MT7996_VAR_TYPE_233, + + /* mt7992 */ + MT7992_VAR_TYPE_44, +}; + enum mt7996_ram_type { MT7996_RAM_TYPE_WM, MT7996_RAM_TYPE_WA, @@ -329,6 +342,7 @@ struct mt7996_dev { spinlock_t reg_lock; u8 wtbl_size_group; + u8 var_type; }; enum { @@ -406,8 +420,7 @@ mt7996_band_valid(struct mt7996_dev *dev, u8 band) return band <= MT_BAND1; /* tri-band support */ - if (band <= MT_BAND2 && - mt76_get_field(dev, MT_PAD_GPIO, MT_PAD_GPIO_ADIE_COMB) <= 1) + if (band <= MT_BAND2 && dev->var_type) return true; return band == MT_BAND0 || band == MT_BAND2; diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/regs.h b/drivers/net/wireless/mediatek/mt76/mt7996/regs.h index 47b429d8bfbe5..734abec45676a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/regs.h +++ b/drivers/net/wireless/mediatek/mt76/mt7996/regs.h @@ -662,6 +662,7 @@ enum offs_rev { #define MT_PAD_GPIO 0x700056f0 #define MT_PAD_GPIO_ADIE_COMB GENMASK(16, 15) +#define MT_PAD_GPIO_2ADIE_TBTC BIT(19) #define MT_HW_REV 0x70010204 #define MT_HW_REV1 0x8a00