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

mt76: mt7915: improve MU stability



- Adjust starec flow since VHT MU group is only updated by starec_vht
  follows starec_bf settings.
- Drop unnecessary MU BF checks.

TX MPDU PER (Status = Success):
                                           TOT_MPDU_CNT  FAIL_MPDU_CNT  TX_PER
WCID Rate
1      VHT_BW80_2SS_MCS7_LGI_LDPC_MUBF              114              0   0.00%
       VHT_BW80_2SS_MCS7_LGI_LDPC_MUBF_MU            64              0   0.00%
       VHT_BW80_2SS_MCS7_SGI_LDPC_MUBF              128              0   0.00%
       VHT_BW80_2SS_MCS7_SGI_LDPC_MUBF_MU           745              0   0.00%
       VHT_BW80_2SS_MCS8_LGI_LDPC_MUBF_MU           856              0   0.00%
       VHT_BW80_2SS_MCS8_SGI_LDPC_MUBF_MU          1430              4   0.28%
       VHT_BW80_2SS_MCS9_LGI_LDPC_MUBF_MU          5220             31   0.59%
       VHT_BW80_2SS_MCS9_LGI_LDPC_iBF                59              0   0.00%
       VHT_BW80_2SS_MCS9_SGI_LDPC_MUBF               64              2   3.12%
       VHT_BW80_2SS_MCS9_SGI_LDPC_MUBF_MU         22132             76   0.34%
       VHT_BW80_2SS_MCS9_SGI_LDPC_iBF              2866              1   0.03%
2      VHT_BW80_2SS_MCS7_LGI_LDPC_MUBF_MU          3781              5   0.13%
       VHT_BW80_2SS_MCS7_SGI_LDPC_MUBF_MU           735              0   0.00%
       VHT_BW80_2SS_MCS8_LGI_LDPC_MUBF_MU          1270            365  28.74%
       VHT_BW80_2SS_MCS8_SGI_LDPC_MUBF_MU          3420             57   1.67%
       VHT_BW80_2SS_MCS9_LGI_LDPC_MUBF              128              0   0.00%
       VHT_BW80_2SS_MCS9_LGI_LDPC_MUBF_MU            64              0   0.00%
       VHT_BW80_2SS_MCS9_SGI_LDPC_MUBF              191              0   0.00%
       VHT_BW80_2SS_MCS9_SGI_LDPC_MUBF_MU         18833            320   1.70%
       VHT_BW80_2SS_MCS9_SGI_LDPC_iBF              6040              0   0.00%
287    OFDM 6M

Tested-by: default avatarEvelyn Tsai <evelyn.tsai@mediatek.com>
Signed-off-by: default avatarRyder Lee <ryder.lee@mediatek.com>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent fd843822
Loading
Loading
Loading
Loading
+10 −2
Original line number Original line Diff line number Diff line
@@ -148,6 +148,9 @@ mt7915_txbf_stat_read_phy(struct mt7915_phy *phy, struct seq_file *s)
{
{
	struct mt7915_dev *dev = s->private;
	struct mt7915_dev *dev = s->private;
	bool ext_phy = phy != &dev->phy;
	bool ext_phy = phy != &dev->phy;
	static const char * const bw[] = {
		"BW20", "BW40", "BW80", "BW160"
	};
	int cnt;
	int cnt;


	if (!phy)
	if (!phy)
@@ -165,11 +168,16 @@ mt7915_txbf_stat_read_phy(struct mt7915_phy *phy, struct seq_file *s)
	seq_puts(s, "Tx Beamformer Rx feedback statistics: ");
	seq_puts(s, "Tx Beamformer Rx feedback statistics: ");


	cnt = mt76_rr(dev, MT_ETBF_RX_FB_CNT(ext_phy));
	cnt = mt76_rr(dev, MT_ETBF_RX_FB_CNT(ext_phy));
	seq_printf(s, "All: %ld, HE: %ld, VHT: %ld, HT: %ld\n",
	seq_printf(s, "All: %ld, HE: %ld, VHT: %ld, HT: %ld, ",
		   FIELD_GET(MT_ETBF_RX_FB_ALL, cnt),
		   FIELD_GET(MT_ETBF_RX_FB_ALL, cnt),
		   FIELD_GET(MT_ETBF_RX_FB_HE, cnt),
		   FIELD_GET(MT_ETBF_RX_FB_HE, cnt),
		   FIELD_GET(MT_ETBF_RX_FB_VHT, cnt),
		   FIELD_GET(MT_ETBF_RX_FB_VHT, cnt),
		   FIELD_GET(MT_ETBF_RX_FB_HT, cnt));
		   FIELD_GET(MT_ETBF_RX_FB_HT, cnt));
	cnt = mt76_rr(dev, MT_ETBF_RX_FB_CONT(ext_phy));
	seq_printf(s, "%s, NC: %ld, NR: %ld\n",
		   bw[FIELD_GET(MT_ETBF_RX_FB_BW, cnt)],
		   FIELD_GET(MT_ETBF_RX_FB_NC, cnt),
		   FIELD_GET(MT_ETBF_RX_FB_NR, cnt));


	/* Tx Beamformee Rx NDPA & Tx feedback report */
	/* Tx Beamformee Rx NDPA & Tx feedback report */
	cnt = mt76_rr(dev, MT_ETBF_TX_NDP_BFRP(ext_phy));
	cnt = mt76_rr(dev, MT_ETBF_TX_NDP_BFRP(ext_phy));
@@ -205,7 +213,7 @@ mt7915_tx_stats_show(struct seq_file *file, void *data)
	mt7915_txbf_stat_read_phy(mt7915_ext_phy(dev), file);
	mt7915_txbf_stat_read_phy(mt7915_ext_phy(dev), file);


	/* Tx amsdu info */
	/* Tx amsdu info */
	seq_puts(file, "Tx MSDU stat:\n");
	seq_puts(file, "Tx MSDU statistics:\n");
	for (i = 0, n = 0; i < ARRAY_SIZE(stat); i++) {
	for (i = 0, n = 0; i < ARRAY_SIZE(stat); i++) {
		stat[i] = mt76_rr(dev,  MT_PLE_AMSDU_PACK_MSDU_CNT(i));
		stat[i] = mt76_rr(dev,  MT_PLE_AMSDU_PACK_MSDU_CNT(i));
		n += stat[i];
		n += stat[i];
+49 −49
Original line number Original line Diff line number Diff line
@@ -1685,27 +1685,18 @@ mt7915_mcu_sta_muru_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
		HE_PHY(CAP2_UL_MU_PARTIAL_MU_MIMO, elem->phy_cap_info[2]);
		HE_PHY(CAP2_UL_MU_PARTIAL_MU_MIMO, elem->phy_cap_info[2]);
}
}


static int
static void
mt7915_mcu_add_mu(struct mt7915_dev *dev, struct ieee80211_vif *vif,
mt7915_mcu_sta_vht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
		  struct ieee80211_sta *sta)
{
{
	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
	struct sta_rec_vht *vht;
	struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
	struct tlv *tlv;
	struct sk_buff *skb;
	int len = sizeof(struct sta_req_hdr) + sizeof(struct sta_rec_muru);

	if (!sta->vht_cap.vht_supported && !sta->he_cap.has_he)
		return 0;

	skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta, len);
	if (IS_ERR(skb))
		return PTR_ERR(skb);


	/* starec muru */
	tlv = mt7915_mcu_add_tlv(skb, STA_REC_VHT, sizeof(*vht));
	mt7915_mcu_sta_muru_tlv(skb, sta);


	return mt76_mcu_skb_send_msg(&dev->mt76, skb,
	vht = (struct sta_rec_vht *)tlv;
				     MCU_EXT_CMD(STA_REC_UPDATE), true);
	vht->vht_cap = cpu_to_le32(sta->vht_cap.cap);
	vht->vht_rx_mcs_map = sta->vht_cap.vht_mcs.rx_mcs_map;
	vht->vht_tx_mcs_map = sta->vht_cap.vht_mcs.tx_mcs_map;
}
}


static void
static void
@@ -1757,17 +1748,6 @@ mt7915_mcu_sta_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
			mt7915_mcu_sta_amsdu_tlv(skb, sta);
			mt7915_mcu_sta_amsdu_tlv(skb, sta);
	}
	}


	/* starec vht */
	if (sta->vht_cap.vht_supported) {
		struct sta_rec_vht *vht;

		tlv = mt7915_mcu_add_tlv(skb, STA_REC_VHT, sizeof(*vht));
		vht = (struct sta_rec_vht *)tlv;
		vht->vht_cap = cpu_to_le32(sta->vht_cap.cap);
		vht->vht_rx_mcs_map = sta->vht_cap.vht_mcs.rx_mcs_map;
		vht->vht_tx_mcs_map = sta->vht_cap.vht_mcs.tx_mcs_map;
	}

	/* starec he */
	/* starec he */
	if (sta->he_cap.has_he)
	if (sta->he_cap.has_he)
		mt7915_mcu_sta_he_tlv(skb, sta);
		mt7915_mcu_sta_he_tlv(skb, sta);
@@ -2157,26 +2137,21 @@ mt7915_mcu_add_txbf(struct mt7915_dev *dev, struct ieee80211_vif *vif,
		vc = mt7915_get_he_phy_cap(phy, vif);
		vc = mt7915_get_he_phy_cap(phy, vif);
		ve = &vc->he_cap_elem;
		ve = &vc->he_cap_elem;


		ebfee = !!((HE_PHY(CAP3_SU_BEAMFORMER, pe->phy_cap_info[3]) ||
		ebfee = !!(HE_PHY(CAP3_SU_BEAMFORMER, pe->phy_cap_info[3]) &&
			    HE_PHY(CAP4_MU_BEAMFORMER, pe->phy_cap_info[4])) &&
			   HE_PHY(CAP4_SU_BEAMFORMEE, ve->phy_cap_info[4]));
			   HE_PHY(CAP4_SU_BEAMFORMEE, ve->phy_cap_info[4]));
		ebf = !!((HE_PHY(CAP3_SU_BEAMFORMER, ve->phy_cap_info[3]) ||
		ebf = !!(HE_PHY(CAP3_SU_BEAMFORMER, ve->phy_cap_info[3]) &&
			  HE_PHY(CAP4_MU_BEAMFORMER, ve->phy_cap_info[4])) &&
			 HE_PHY(CAP4_SU_BEAMFORMEE, pe->phy_cap_info[4]));
			 HE_PHY(CAP4_SU_BEAMFORMEE, pe->phy_cap_info[4]));
	} else if (sta->vht_cap.vht_supported) {
	} else if (sta->vht_cap.vht_supported) {
		struct ieee80211_sta_vht_cap *pc;
		struct ieee80211_sta_vht_cap *pc;
		struct ieee80211_sta_vht_cap *vc;
		struct ieee80211_sta_vht_cap *vc;
		u32 cr, ce;


		pc = &sta->vht_cap;
		pc = &sta->vht_cap;
		vc = &phy->mt76->sband_5g.sband.vht_cap;
		vc = &phy->mt76->sband_5g.sband.vht_cap;
		cr = IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
		     IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
		ce = IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
		     IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;


		ebfee = !!((pc->cap & cr) && (vc->cap & ce));
		ebfee = !!((pc->cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE) &&
		ebf = !!((vc->cap & cr) && (pc->cap & ce));
			   (vc->cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE));
		ebf = !!((vc->cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE) &&
			 (pc->cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE));
	}
	}


	/* must keep each tag independent */
	/* must keep each tag independent */
@@ -2379,31 +2354,56 @@ mt7915_mcu_add_group(struct mt7915_dev *dev, struct ieee80211_vif *vif,
				 sizeof(req), true);
				 sizeof(req), true);
}
}


int mt7915_mcu_add_sta_adv(struct mt7915_dev *dev, struct ieee80211_vif *vif,
static int
			   struct ieee80211_sta *sta, bool enable)
mt7915_mcu_add_mu(struct mt7915_dev *dev, struct ieee80211_vif *vif,
		  struct ieee80211_sta *sta)
{
{
	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
	struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
	struct sk_buff *skb;
	int ret;
	int ret;


	if (!sta)
	if (!sta->vht_cap.vht_supported && !sta->he_cap.has_he)
		return 0;
		return 0;


	/* must keep the order */
	ret = mt7915_mcu_add_group(dev, vif, sta);
	ret = mt7915_mcu_add_group(dev, vif, sta);
	if (ret)
	if (ret)
		return ret;
		return ret;


	skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta,
				       MT7915_STA_UPDATE_MAX_SIZE);
	if (IS_ERR(skb))
		return PTR_ERR(skb);

	/* wait until TxBF and MU ready to update stare vht */

	/* starec muru */
	mt7915_mcu_sta_muru_tlv(skb, sta);
	/* starec vht */
	mt7915_mcu_sta_vht_tlv(skb, sta);

	return mt76_mcu_skb_send_msg(&dev->mt76, skb,
				     MCU_EXT_CMD(STA_REC_UPDATE), true);
}

int mt7915_mcu_add_sta_adv(struct mt7915_dev *dev, struct ieee80211_vif *vif,
			   struct ieee80211_sta *sta, bool enable)
{
	int ret;

	if (!sta)
		return 0;

	/* must keep the order */
	ret = mt7915_mcu_add_txbf(dev, vif, sta, enable);
	ret = mt7915_mcu_add_txbf(dev, vif, sta, enable);
	if (ret)
	if (ret || !enable)
		return ret;
		return ret;


	ret = mt7915_mcu_add_mu(dev, vif, sta);
	ret = mt7915_mcu_add_mu(dev, vif, sta);
	if (ret)
	if (ret)
		return ret;
		return ret;


	if (enable)
	return mt7915_mcu_add_rate_ctrl(dev, vif, sta);
	return mt7915_mcu_add_rate_ctrl(dev, vif, sta);

	return 0;
}
}


int mt7915_mcu_add_sta(struct mt7915_dev *dev, struct ieee80211_vif *vif,
int mt7915_mcu_add_sta(struct mt7915_dev *dev, struct ieee80211_vif *vif,
+5 −0
Original line number Original line Diff line number Diff line
@@ -99,6 +99,11 @@
#define MT_ETBF_TX_FB_CPL		GENMASK(31, 16)
#define MT_ETBF_TX_FB_CPL		GENMASK(31, 16)
#define MT_ETBF_TX_FB_TRI		GENMASK(15, 0)
#define MT_ETBF_TX_FB_TRI		GENMASK(15, 0)


#define MT_ETBF_RX_FB_CONT(_band)	MT_WF_ETBF(_band, 0x068)
#define MT_ETBF_RX_FB_BW		GENMASK(7, 6)
#define MT_ETBF_RX_FB_NC		GENMASK(5, 3)
#define MT_ETBF_RX_FB_NR		GENMASK(2, 0)

#define MT_ETBF_TX_APP_CNT(_band)	MT_WF_ETBF(_band, 0x0f0)
#define MT_ETBF_TX_APP_CNT(_band)	MT_WF_ETBF(_band, 0x0f0)
#define MT_ETBF_TX_IBF_CNT		GENMASK(31, 16)
#define MT_ETBF_TX_IBF_CNT		GENMASK(31, 16)
#define MT_ETBF_TX_EBF_CNT		GENMASK(15, 0)
#define MT_ETBF_TX_EBF_CNT		GENMASK(15, 0)