Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion drivers/net/wireless/mediatek/mt76/mac80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
11 changes: 9 additions & 2 deletions drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/mediatek/mt76/mt7921/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
5 changes: 2 additions & 3 deletions drivers/net/wireless/mediatek/mt76/mt7925/mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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]);
Expand Down Expand Up @@ -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;

Expand Down
2 changes: 2 additions & 0 deletions drivers/net/wireless/mediatek/mt76/mt7996/eeprom.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
114 changes: 86 additions & 28 deletions drivers/net/wireless/mediatek/mt76/mt7996/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
};

Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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 |
Expand Down Expand Up @@ -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 */
Expand All @@ -1011,15 +1047,18 @@ 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) |
FIELD_PREP(IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_MASK,
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;
Expand Down Expand Up @@ -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);
Expand All @@ -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)),
Expand All @@ -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 { \
Expand All @@ -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
Expand Down
17 changes: 13 additions & 4 deletions drivers/net/wireless/mediatek/mt76/mt7996/mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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));
Expand All @@ -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;
Expand Down
14 changes: 9 additions & 5 deletions drivers/net/wireless/mediatek/mt76/mt7996/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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:
Expand Down
Loading