summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7996/mac.c6
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7996/main.c12
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7996/mcu.c3
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h1
4 files changed, 18 insertions, 4 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
index c8ada309d73f..fbb92c39beee 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
@@ -1070,8 +1070,14 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
mt7996_mac_write_txwi_80211(dev, txwi, skb, key);
if (txwi[1] & cpu_to_le32(MT_TXD1_FIXED_RATE)) {
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ bool mcast = ieee80211_is_data(hdr->frame_control) &&
+ is_multicast_ether_addr(hdr->addr1);
u8 idx = mvif->basic_rates_idx;
+ if (mcast && mvif->mcast_rates_idx)
+ idx = mvif->mcast_rates_idx;
+
txwi[6] |= FIELD_PREP(MT_TXD6_TX_RATE, idx);
txwi[3] |= cpu_to_le32(MT_TXD3_BA_DISABLE);
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
index 1243e5f925ad..f861fbb7de47 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
@@ -503,14 +503,15 @@ mt7996_update_bss_color(struct ieee80211_hw *hw,
}
static u8
-mt7996_get_rates_table(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+mt7996_get_rates_table(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ bool mcast)
{
struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
struct mt76_phy *mphy = hw->priv;
u16 rate;
u8 i, idx;
- rate = mt76_connac2_mac_tx_rate_val(mphy, vif, false, false);
+ rate = mt76_connac2_mac_tx_rate_val(mphy, vif, false, mcast);
idx = FIELD_GET(MT_TX_RATE_IDX, rate);
for (i = 0; i < ARRAY_SIZE(mt76_rates); i++)
@@ -557,8 +558,13 @@ static void mt7996_bss_info_changed(struct ieee80211_hw *hw,
}
}
+ if (changed & BSS_CHANGED_MCAST_RATE)
+ mvif->mcast_rates_idx =
+ mt7996_get_rates_table(hw, vif, true);
+
if (changed & BSS_CHANGED_BASIC_RATES)
- mvif->basic_rates_idx = mt7996_get_rates_table(hw, vif);
+ mvif->basic_rates_idx =
+ mt7996_get_rates_table(hw, vif, false);
if (changed & BSS_CHANGED_BEACON_ENABLED && info->enable_beacon) {
mt7996_mcu_add_bss_info(phy, vif, true);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
index 3db74ae109dc..f96992b55c7a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
@@ -605,7 +605,8 @@ mt7996_mcu_bss_bmc_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
enum nl80211_band band = chandef->chan->band;
struct tlv *tlv;
- u8 idx = mvif->basic_rates_idx;
+ u8 idx = mvif->mcast_rates_idx ?
+ mvif->mcast_rates_idx : mvif->basic_rates_idx;
tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_RATE, sizeof(*bmc));
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
index 5cf5ea8cece9..a1a6ee0de2ff 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
@@ -125,6 +125,7 @@ struct mt7996_vif {
struct cfg80211_bitrate_mask bitrate_mask;
u8 basic_rates_idx;
+ u8 mcast_rates_idx;
};
/* per-phy stats. */