Skip to content

Commit

Permalink
mt76: mt7915: rework starec TLV tags
Browse files Browse the repository at this point in the history
Rework starec tags to the order which firmware expected. This also fixes
some weird behaviors during generating SPL of HE-MU.

Co-developed-by: Ryder Lee <ryder.lee@mediatek.com>
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
  • Loading branch information
csyuanc authored and nbd168 committed Oct 19, 2021
1 parent 53c6a3c commit f517845
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 141 deletions.
3 changes: 1 addition & 2 deletions mt7915/main.c
Expand Up @@ -663,7 +663,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
if (ret)
return ret;

return mt7915_mcu_add_sta_adv(dev, vif, sta, true);
return mt7915_mcu_add_rate_ctrl(dev, vif, sta);
}

void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
Expand All @@ -673,7 +673,6 @@ void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
int i;

mt7915_mcu_add_sta_adv(dev, vif, sta, false);
mt7915_mcu_add_sta(dev, vif, sta, false);

mt7915_mac_wtbl_update(dev, msta->wcid.idx,
Expand Down
229 changes: 92 additions & 137 deletions mt7915/mcu.c
Expand Up @@ -1342,14 +1342,16 @@ mt7915_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
{
struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
struct ieee80211_sta_he_cap *he_cap = &sta->he_cap;
struct ieee80211_he_cap_elem *elem = &he_cap->he_cap_elem;
struct ieee80211_he_cap_elem *elem = &sta->he_cap.he_cap_elem;
enum nl80211_band band = msta->vif->phy->mt76->chandef.chan->band;
const u16 *mcs_mask = msta->vif->bitrate_mask.control[band].he_mcs;
struct sta_rec_he *he;
struct tlv *tlv;
u32 cap = 0;

if (!sta->he_cap.has_he)
return;

tlv = mt7915_mcu_add_tlv(skb, STA_REC_HE, sizeof(*he));

he = (struct sta_rec_he *)tlv;
Expand Down Expand Up @@ -1514,11 +1516,13 @@ mt7915_mcu_sta_muru_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
struct ieee80211_vif *vif)
{
struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
struct ieee80211_sta_he_cap *he_cap = &sta->he_cap;
struct ieee80211_he_cap_elem *elem = &he_cap->he_cap_elem;
struct ieee80211_he_cap_elem *elem = &sta->he_cap.he_cap_elem;
struct sta_rec_muru *muru;
struct tlv *tlv;

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

tlv = mt7915_mcu_add_tlv(skb, STA_REC_MURU, sizeof(*muru));

muru = (struct sta_rec_muru *)tlv;
Expand Down Expand Up @@ -1563,12 +1567,27 @@ 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]);
}

static void
mt7915_mcu_sta_ht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
{
struct sta_rec_ht *ht;
struct tlv *tlv;

tlv = mt7915_mcu_add_tlv(skb, STA_REC_HT, sizeof(*ht));

ht = (struct sta_rec_ht *)tlv;
ht->ht_cap = cpu_to_le16(sta->ht_cap.cap);
}

static void
mt7915_mcu_sta_vht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
{
struct sta_rec_vht *vht;
struct tlv *tlv;

if (!sta->vht_cap.vht_supported)
return;

tlv = mt7915_mcu_add_tlv(skb, STA_REC_VHT, sizeof(*vht));

vht = (struct sta_rec_vht *)tlv;
Expand All @@ -1578,12 +1597,17 @@ mt7915_mcu_sta_vht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
}

static void
mt7915_mcu_sta_amsdu_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
mt7915_mcu_sta_amsdu_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
struct ieee80211_sta *sta)
{
struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
struct sta_rec_amsdu *amsdu;
struct tlv *tlv;

if (vif->type != NL80211_IFTYPE_STATION &&
vif->type != NL80211_IFTYPE_AP)
return;

if (!sta->max_amsdu_len)
return;

Expand All @@ -1596,44 +1620,6 @@ mt7915_mcu_sta_amsdu_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
msta->wcid.amsdu = true;
}

static bool
mt7915_hw_amsdu_supported(struct ieee80211_vif *vif)
{
switch (vif->type) {
case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_STATION:
return true;
default:
return false;
}
}

static void
mt7915_mcu_sta_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
struct ieee80211_sta *sta, struct ieee80211_vif *vif)
{
struct tlv *tlv;

/* starec ht */
if (sta->ht_cap.ht_supported) {
struct sta_rec_ht *ht;

tlv = mt7915_mcu_add_tlv(skb, STA_REC_HT, sizeof(*ht));
ht = (struct sta_rec_ht *)tlv;
ht->ht_cap = cpu_to_le16(sta->ht_cap.cap);

if (mt7915_hw_amsdu_supported(vif))
mt7915_mcu_sta_amsdu_tlv(skb, sta);
}

/* starec he */
if (sta->he_cap.has_he)
mt7915_mcu_sta_he_tlv(skb, sta, vif);

/* starec uapsd */
mt7915_mcu_sta_uapsd_tlv(skb, sta, vif);
}

static void
mt7915_mcu_wtbl_smps_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
void *sta_wtbl, void *wtbl_tlv)
Expand All @@ -1644,9 +1630,7 @@ mt7915_mcu_wtbl_smps_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
tlv = mt7915_mcu_add_nested_tlv(skb, WTBL_SMPS, sizeof(*smps),
wtbl_tlv, sta_wtbl);
smps = (struct wtbl_smps *)tlv;

if (sta->smps_mode == IEEE80211_SMPS_DYNAMIC)
smps->smps = true;
smps->smps = (sta->smps_mode == IEEE80211_SMPS_DYNAMIC);
}

static void
Expand Down Expand Up @@ -1720,6 +1704,32 @@ mt7915_mcu_wtbl_hdr_trans_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
}
}

static int
mt7915_mcu_sta_wtbl_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
struct ieee80211_vif *vif, struct ieee80211_sta *sta)
{
struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
struct mt7915_sta *msta;
struct wtbl_req_hdr *wtbl_hdr;
struct tlv *tlv;

msta = sta ? (struct mt7915_sta *)sta->drv_priv : &mvif->sta;

tlv = mt7915_mcu_add_tlv(skb, STA_REC_WTBL, sizeof(struct tlv));
wtbl_hdr = mt7915_mcu_alloc_wtbl_req(dev, msta, WTBL_RESET_AND_SET,
tlv, &skb);
if (IS_ERR(wtbl_hdr))
return PTR_ERR(wtbl_hdr);

mt7915_mcu_wtbl_generic_tlv(skb, vif, sta, tlv, wtbl_hdr);
mt7915_mcu_wtbl_hdr_trans_tlv(skb, vif, sta, tlv, wtbl_hdr);

if (sta)
mt7915_mcu_wtbl_ht_tlv(skb, vif, sta, tlv, wtbl_hdr);

return 0;
}

int mt7915_mcu_sta_update_hdr_trans(struct mt7915_dev *dev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta)
Expand Down Expand Up @@ -2039,28 +2049,6 @@ mt7915_mcu_sta_bfee_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
bfee->fb_identity_matrix = (nrow == 1 && tx_ant == 2);
}

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

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

/* starec bf */
mt7915_mcu_sta_bfer_tlv(dev, skb, vif, sta);
/* starec bfee */
mt7915_mcu_sta_bfee_tlv(dev, skb, vif, sta);

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

static void
mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev,
struct ieee80211_vif *vif, struct ieee80211_sta *sta)
Expand Down Expand Up @@ -2206,7 +2194,7 @@ mt7915_mcu_add_group(struct mt7915_dev *dev, struct ieee80211_vif *vif,
{
#define MT_STA_BSS_GROUP 1
struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
struct mt7915_sta *msta;
struct {
__le32 action;
u8 wlan_idx_lo;
Expand All @@ -2217,75 +2205,24 @@ mt7915_mcu_add_group(struct mt7915_dev *dev, struct ieee80211_vif *vif,
u8 rsv1[8];
} __packed req = {
.action = cpu_to_le32(MT_STA_BSS_GROUP),
.wlan_idx_lo = to_wcid_lo(msta->wcid.idx),
.wlan_idx_hi = to_wcid_hi(msta->wcid.idx),
.val = cpu_to_le32(mvif->idx % 16),
};

msta = sta ? (struct mt7915_sta *)sta->drv_priv : &mvif->sta;
req.wlan_idx_lo = to_wcid_lo(msta->wcid.idx);
req.wlan_idx_hi = to_wcid_hi(msta->wcid.idx);

return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(SET_DRR_CTRL), &req,
sizeof(req), true);
}

static int
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;

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

ret = mt7915_mcu_add_group(dev, vif, sta);
if (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, vif);
/* 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);
if (ret || !enable)
return ret;

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

return mt7915_mcu_add_rate_ctrl(dev, vif, sta);
}

int mt7915_mcu_add_sta(struct mt7915_dev *dev, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, bool enable)
{
struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
struct wtbl_req_hdr *wtbl_hdr;
struct mt7915_sta *msta;
struct tlv *sta_wtbl;
struct sk_buff *skb;
int ret;

msta = sta ? (struct mt7915_sta *)sta->drv_priv : &mvif->sta;

Expand All @@ -2294,24 +2231,42 @@ int mt7915_mcu_add_sta(struct mt7915_dev *dev, struct ieee80211_vif *vif,
if (IS_ERR(skb))
return PTR_ERR(skb);

/* starec basic */
mt7915_mcu_sta_basic_tlv(skb, vif, sta, enable);
if (enable && sta)
mt7915_mcu_sta_tlv(dev, skb, sta, vif);
if (!enable)
goto out;

sta_wtbl = mt7915_mcu_add_tlv(skb, STA_REC_WTBL, sizeof(struct tlv));
/* tag order is in accordance with firmware dependency. */
if (sta && sta->ht_cap.ht_supported) {
/* starec bfer */
mt7915_mcu_sta_bfer_tlv(dev, skb, vif, sta);
/* starec ht */
mt7915_mcu_sta_ht_tlv(skb, sta);
/* starec vht */
mt7915_mcu_sta_vht_tlv(skb, sta);
/* starec uapsd */
mt7915_mcu_sta_uapsd_tlv(skb, sta, vif);
}

wtbl_hdr = mt7915_mcu_alloc_wtbl_req(dev, msta, WTBL_RESET_AND_SET,
sta_wtbl, &skb);
if (IS_ERR(wtbl_hdr))
return PTR_ERR(wtbl_hdr);
ret = mt7915_mcu_sta_wtbl_tlv(dev, skb, vif, sta);
if (ret)
return ret;

if (enable) {
mt7915_mcu_wtbl_generic_tlv(skb, vif, sta, sta_wtbl, wtbl_hdr);
mt7915_mcu_wtbl_hdr_trans_tlv(skb, vif, sta, sta_wtbl, wtbl_hdr);
if (sta)
mt7915_mcu_wtbl_ht_tlv(skb, vif, sta, sta_wtbl, wtbl_hdr);
if (sta && sta->ht_cap.ht_supported) {
/* starec amsdu */
mt7915_mcu_sta_amsdu_tlv(skb, vif, sta);
/* starec he */
mt7915_mcu_sta_he_tlv(skb, sta, vif);
/* starec muru */
mt7915_mcu_sta_muru_tlv(skb, sta, vif);
/* starec bfee */
mt7915_mcu_sta_bfee_tlv(dev, skb, vif, sta);
}

ret = mt7915_mcu_add_group(dev, vif, sta);
if (ret)
return ret;
out:
return mt76_mcu_skb_send_msg(&dev->mt76, skb,
MCU_EXT_CMD(STA_REC_UPDATE), true);
}
Expand Down
1 change: 1 addition & 0 deletions mt7915/mcu.h
Expand Up @@ -1110,6 +1110,7 @@ enum {
sizeof(struct sta_rec_vht) + \
sizeof(struct sta_rec_uapsd) + \
sizeof(struct sta_rec_amsdu) + \
sizeof(struct sta_rec_muru) + \
sizeof(struct sta_rec_bfee) + \
sizeof(struct tlv) + \
MT7915_WTBL_UPDATE_MAX_SIZE)
Expand Down
2 changes: 0 additions & 2 deletions mt7915/mt7915.h
Expand Up @@ -394,8 +394,6 @@ int mt7915_mcu_add_bss_info(struct mt7915_phy *phy,
struct ieee80211_vif *vif, int enable);
int mt7915_mcu_add_sta(struct mt7915_dev *dev, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, bool enable);
int mt7915_mcu_add_sta_adv(struct mt7915_dev *dev, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, bool enable);
int mt7915_mcu_sta_update_hdr_trans(struct mt7915_dev *dev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta);
Expand Down

0 comments on commit f517845

Please sign in to comment.