Commit 68ee6a14 authored by Ryder Lee's avatar Ryder Lee Committed by Felix Fietkau
Browse files

mt76: mt7915: enable configured beacon tx rate



The user is allowed to change beacon tx rate (HT/VHT/HE) from hostapd.

Signed-off-by: default avatarRyder Lee <ryder.lee@mediatek.com>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent 970be1df
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -326,6 +326,10 @@ mt7915_init_wiphy(struct ieee80211_hw *hw)

	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BSS_COLOR);
	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
	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, HAS_RATE_CONTROL);
	ieee80211_hw_set(hw, SUPPORTS_TX_ENCAP_OFFLOAD);
+46 −13
Original line number Diff line number Diff line
@@ -981,6 +981,51 @@ mt7915_mac_write_txwi_80211(struct mt7915_dev *dev, __le32 *txwi,
	txwi[7] |= cpu_to_le32(val);
}

static u16
mt7915_mac_tx_rate_val(struct mt76_phy *mphy, struct ieee80211_vif *vif,
		       bool beacon, bool mcast)
{
	u8 mode = 0, band = mphy->chandef.chan->band;
	int rateidx = 0, mcast_rate;

	if (beacon) {
		struct cfg80211_bitrate_mask *mask;

		mask = &vif->bss_conf.beacon_tx_rate;
		if (hweight16(mask->control[band].he_mcs[0]) == 1) {
			rateidx = ffs(mask->control[band].he_mcs[0]) - 1;
			mode = MT_PHY_TYPE_HE_SU;
			goto out;
		} else if (hweight16(mask->control[band].vht_mcs[0]) == 1) {
			rateidx = ffs(mask->control[band].vht_mcs[0]) - 1;
			mode = MT_PHY_TYPE_VHT;
			goto out;
		} else if (hweight8(mask->control[band].ht_mcs[0]) == 1) {
			rateidx = ffs(mask->control[band].ht_mcs[0]) - 1;
			mode = MT_PHY_TYPE_HT;
			goto out;
		} else if (hweight32(mask->control[band].legacy) == 1) {
			rateidx = ffs(mask->control[band].legacy) - 1;
			goto legacy;
		}
	}

	mcast_rate = vif->bss_conf.mcast_rate[band];
	if (mcast && mcast_rate > 0)
		rateidx = mcast_rate - 1;
	else
		rateidx = ffs(vif->bss_conf.basic_rates) - 1;

legacy:
	rateidx = mt76_calculate_default_rate(mphy, rateidx);
	mode = rateidx >> 8;
	rateidx &= GENMASK(7, 0);

out:
	return FIELD_PREP(MT_TX_RATE_IDX, rateidx) |
	       FIELD_PREP(MT_TX_RATE_MODE, mode);
}

void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi,
			   struct sk_buff *skb, struct mt76_wcid *wcid, int pid,
			   struct ieee80211_key_conf *key, bool beacon)
@@ -1057,23 +1102,11 @@ void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi,
		mt7915_mac_write_txwi_80211(dev, txwi, skb, key, &mcast);

	if (txwi[2] & cpu_to_le32(MT_TXD2_FIX_RATE)) {
		u8 band = mphy->chandef.chan->band;
		int rateidx, mcast_rate = vif->bss_conf.mcast_rate[band];
		u16 rate, mode;
		u16 rate = mt7915_mac_tx_rate_val(mphy, vif, beacon, mcast);

		/* hardware won't add HTC for mgmt/ctrl frame */
		txwi[2] |= cpu_to_le32(MT_TXD2_HTC_VLD);

		if (mcast && mcast_rate > 0)
			rateidx = mcast_rate - 1;
		else
			rateidx = ffs(vif->bss_conf.basic_rates) - 1;

		rate = mt76_calculate_default_rate(mphy, rateidx);
		mode = rate >> 8;
		rate &= GENMASK(7, 0);
		rate |= FIELD_PREP(MT_TX_RATE_MODE, mode);

		val = MT_TXD6_FIXED_BW |
		      FIELD_PREP(MT_TXD6_TX_RATE, rate);
		txwi[6] |= cpu_to_le32(val);