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

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
...@@ -148,6 +148,9 @@ mt7915_txbf_stat_read_phy(struct mt7915_phy *phy, struct seq_file *s) ...@@ -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) ...@@ -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) ...@@ -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];
......
...@@ -1685,27 +1685,18 @@ mt7915_mcu_sta_muru_tlv(struct sk_buff *skb, struct ieee80211_sta *sta) ...@@ -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); tlv = mt7915_mcu_add_tlv(skb, STA_REC_VHT, sizeof(*vht));
if (IS_ERR(skb))
return PTR_ERR(skb);
/* starec muru */ vht = (struct sta_rec_vht *)tlv;
mt7915_mcu_sta_muru_tlv(skb, sta); vht->vht_cap = cpu_to_le32(sta->vht_cap.cap);
vht->vht_rx_mcs_map = sta->vht_cap.vht_mcs.rx_mcs_map;
return mt76_mcu_skb_send_msg(&dev->mt76, skb, vht->vht_tx_mcs_map = sta->vht_cap.vht_mcs.tx_mcs_map;
MCU_EXT_CMD(STA_REC_UPDATE), true);
} }
static void static void
...@@ -1757,17 +1748,6 @@ mt7915_mcu_sta_tlv(struct mt7915_dev *dev, struct sk_buff *skb, ...@@ -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, ...@@ -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, ...@@ -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,
......
...@@ -99,6 +99,11 @@ ...@@ -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)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment