blob: 29f951041b4f3d4694d8d989d058feafe866d5e0 [file] [log] [blame]
From 6b95665d9e183c522e051a18177afe8b91ea817c Mon Sep 17 00:00:00 2001
From: Shayne Chen <shayne.chen@mediatek.com>
Date: Wed, 26 Jun 2024 19:09:46 +0800
Subject: [PATCH 167/199] mtk: mt76: mt7996: rework the setting flow of starec
RA and MLD tags
1. STA_REC_RA and STA_REC_MLD tags need to be set when newly is true,
so that FW can correctly set non-setup link(s) to powersave mode when
the peer is a MLSR MLD STA. (reported by Peter)
2. This patch also tries to fix random EAPOL timeout issue.
Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
---
mt7996/main.c | 4 --
mt7996/mcu.c | 187 +++++++++++++++++++++---------------------------
mt7996/mcu.h | 3 +
mt7996/mt7996.h | 2 -
4 files changed, 83 insertions(+), 113 deletions(-)
diff --git a/mt7996/main.c b/mt7996/main.c
index 35a77609..b5d45d19 100644
--- a/mt7996/main.c
+++ b/mt7996/main.c
@@ -1318,10 +1318,6 @@ mt7996_mac_sta_add_links(struct mt7996_dev *dev, struct ieee80211_vif *vif,
mtxq->wcid = mlink->wcid.idx;
}
- ret = mt7996_mcu_add_mld_sta(dev, vif, sta, add);
- if (ret)
- goto error;
-
return 0;
error:
mt7996_mac_sta_remove_links(dev, vif, sta, add);
diff --git a/mt7996/mcu.c b/mt7996/mcu.c
index 54295414..9b3c6e3d 100644
--- a/mt7996/mcu.c
+++ b/mt7996/mcu.c
@@ -2911,6 +2911,77 @@ int mt7996_mcu_add_rate_ctrl(struct mt7996_dev *dev,
return mt7996_mcu_add_rate_ctrl_fixed(dev, conf, mconf, link_sta, mlink);
}
+static void
+mt7996_mcu_sta_mld_setup_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
+ struct ieee80211_sta *sta, unsigned long valid_links)
+{
+ struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
+ struct sta_rec_mld_setup *mld_setup;
+ struct mld_setup_link *mld_setup_link;
+ struct mt7996_link_sta *mlink;
+ struct mt7996_bss_conf *mconf;
+ struct tlv *tlv;
+ unsigned int link_id;
+ struct ieee80211_vif *vif = container_of((void *)msta->vif, struct ieee80211_vif,
+ drv_priv);
+
+ mlink = mlink_dereference_protected(msta, msta->pri_link);
+ if (!mlink)
+ return;
+
+ tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_MLD,
+ sizeof(*mld_setup) +
+ sizeof(struct mld_setup_link) *
+ hweight16(valid_links));
+
+ mld_setup = (struct sta_rec_mld_setup *)tlv;
+ memcpy(mld_setup->mld_addr, sta->addr, ETH_ALEN);
+ mld_setup->setup_wcid = cpu_to_le16(mlink->wcid.idx);
+ mld_setup->primary_id = cpu_to_le16(mlink->wcid.idx);
+ if (msta->sec_link != msta->pri_link) {
+ mlink = mlink_dereference_protected(msta, msta->sec_link);
+ if (!mlink)
+ return;
+ }
+ mld_setup->seconed_id = cpu_to_le16(mlink->wcid.idx);
+ mld_setup->link_num = hweight16(valid_links);
+
+ mld_setup_link = (struct mld_setup_link *)mld_setup->link_info;
+ mt76_trace(vif, "STA %pM pri_link=%u, pri_wcid=%u, sec_link=%u, sec_wcid=%u\n",
+ sta->addr, msta->pri_link, le16_to_cpu(mld_setup->primary_id),
+ msta->sec_link, le16_to_cpu(mld_setup->seconed_id));
+ for_each_set_bit(link_id, &valid_links, IEEE80211_MLD_MAX_NUM_LINKS) {
+ mlink = mlink_dereference_protected(msta, link_id);
+ mconf = mconf_dereference_protected(msta->vif, link_id);
+
+ mld_setup_link->wcid = cpu_to_le16(mlink->wcid.idx);
+ mld_setup_link->bss_idx = mconf->mt76.idx;
+ mt76_trace(vif, "link_id(%d) wcid(%d) bss_idx(%d)\n",
+ link_id, mld_setup_link->wcid, mld_setup_link->bss_idx);
+ mld_setup_link++;
+ }
+}
+
+static void
+mt7996_mcu_sta_eht_mld_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
+ struct ieee80211_sta *sta)
+{
+ struct sta_rec_eht_mld *eht_mld;
+ struct tlv *tlv;
+ int i;
+
+ tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_EHT_MLD, sizeof(*eht_mld));
+ eht_mld = (struct sta_rec_eht_mld *)tlv;
+
+ for (i = 0; i < ARRAY_SIZE(eht_mld->str_cap); i++)
+ eht_mld->str_cap[i] = 0x7;
+
+ eht_mld->eml_cap = cpu_to_le16(sta->eml_capa);
+ /* TODO:
+ eht_mld->nsep = ;
+ */
+}
+
#if 0
static int
mt7996_mcu_sta_init_vow(struct mt7996_bss_conf *mconf,
@@ -2978,6 +3049,8 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_bss_conf *conf,
/* tag order is in accordance with firmware dependency. */
if (link_sta) {
+ struct ieee80211_sta *sta = link_sta->sta;
+
/* starec hdrt mode */
mt7996_mcu_sta_hdrt_tlv(dev, skb);
/* starec bfer */
@@ -2987,7 +3060,7 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_bss_conf *conf,
/* starec vht */
mt7996_mcu_sta_vht_tlv(skb, link_sta);
/* starec uapsd */
- mt76_connac_mcu_sta_uapsd(skb, vif, link_sta->sta);
+ mt76_connac_mcu_sta_uapsd(skb, vif, sta);
/* starec amsdu */
mt7996_mcu_sta_amsdu_tlv(dev, skb, vif, link_sta, mlink);
/* starec he */
@@ -3000,6 +3073,12 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_bss_conf *conf,
mt7996_mcu_sta_muru_tlv(dev, skb, conf, mconf, link_sta);
/* starec bfee */
mt7996_mcu_sta_bfee_tlv(dev, skb, conf, mconf, link_sta);
+
+ if (sta->mlo) {
+ /* starec mld setup */
+ mt7996_mcu_sta_mld_setup_tlv(dev, skb, sta, sta->valid_links);
+ mt7996_mcu_sta_eht_mld_tlv(dev, skb, sta);
+ }
}
#if 0
@@ -3014,112 +3093,6 @@ out:
MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true);
}
-static void
-mt7996_mcu_sta_mld_setup_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
- struct ieee80211_sta *sta)
-{
- struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
- struct sta_rec_mld_setup *mld_setup;
- struct mld_setup_link *mld_setup_link;
- struct mt7996_link_sta *mlink;
- struct mt7996_bss_conf *mconf;
- struct tlv *tlv;
- unsigned long valid_links = sta->valid_links;
- unsigned int link_id;
- struct ieee80211_vif *vif = container_of((void *)msta->vif, struct ieee80211_vif,
- drv_priv);
-
- mlink = mlink_dereference_protected(msta, msta->pri_link);
- if (!mlink)
- return;
-
- tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_MLD,
- sizeof(*mld_setup) +
- sizeof(struct mld_setup_link) *
- hweight16(sta->valid_links));
-
- mld_setup = (struct sta_rec_mld_setup *)tlv;
- memcpy(mld_setup->mld_addr, sta->addr, ETH_ALEN);
- mld_setup->setup_wcid = cpu_to_le16(mlink->wcid.idx);
- mld_setup->primary_id = cpu_to_le16(mlink->wcid.idx);
- if (msta->sec_link != msta->pri_link) {
- mlink = mlink_dereference_protected(msta, msta->sec_link);
- if (!mlink)
- return;
- }
- mld_setup->seconed_id = cpu_to_le16(mlink->wcid.idx);
- mld_setup->link_num = hweight16(sta->valid_links);
-
- mld_setup_link = (struct mld_setup_link *)mld_setup->link_info;
- mt76_trace(vif, "STA %pM pri_link=%u, pri_wcid=%u, sec_link=%u, sec_wcid=%u\n",
- sta->addr, msta->pri_link, le16_to_cpu(mld_setup->primary_id),
- msta->sec_link, le16_to_cpu(mld_setup->seconed_id));
- for_each_set_bit(link_id, &valid_links, IEEE80211_MLD_MAX_NUM_LINKS) {
- mlink = mlink_dereference_protected(msta, link_id);
- mconf = mconf_dereference_protected(msta->vif, link_id);
-
- mld_setup_link->wcid = cpu_to_le16(mlink->wcid.idx);
- mld_setup_link->bss_idx = mconf->mt76.idx;
- mt76_trace(vif, "link_id(%d) wcid(%d) bss_idx(%d)\n",
- link_id, mld_setup_link->wcid, mld_setup_link->bss_idx);
- mld_setup_link++;
- }
-}
-
-static void
-mt7996_mcu_sta_eht_mld_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
- struct ieee80211_sta *sta)
-{
- struct sta_rec_eht_mld *eht_mld;
- struct tlv *tlv;
- int i;
-
- tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_EHT_MLD, sizeof(*eht_mld));
- eht_mld = (struct sta_rec_eht_mld *)tlv;
-
- for (i = 0; i < ARRAY_SIZE(eht_mld->str_cap); i++)
- eht_mld->str_cap[i] = 0x7;
-
- eht_mld->eml_cap = cpu_to_le16(sta->eml_capa);
- /* TODO:
- eht_mld->nsep = ;
- */
-}
-
-int mt7996_mcu_add_mld_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif,
- struct ieee80211_sta *sta, unsigned long add)
-{
- struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
- struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
- unsigned int link_id;
-
- if (!sta->mlo)
- return 0;
-
- for_each_set_bit(link_id, &add, IEEE80211_MLD_MAX_NUM_LINKS) {
- struct mt7996_bss_conf *mconf =
- mconf_dereference_protected(mvif, link_id);
- struct mt7996_link_sta *mlink =
- mlink_dereference_protected(msta, link_id);
- struct sk_buff *skb;
- int ret;
-
- skb = __mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mconf->mt76,
- &mlink->wcid,
- MT7996_STA_UPDATE_MAX_SIZE);
- if (IS_ERR(skb))
- return PTR_ERR(skb);
- /* starec mld setup */
- mt7996_mcu_sta_mld_setup_tlv(dev, skb, sta);
- /* starec eht mld */
- mt7996_mcu_sta_eht_mld_tlv(dev, skb, sta);
- ret = mt76_mcu_skb_send_msg(&dev->mt76, skb,
- MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true);
- if (ret)
- return ret;
- }
- return 0;
-}
int mt7996_mcu_teardown_mld_sta(struct mt7996_dev *dev,
struct mt7996_bss_conf *mconf,
struct mt7996_link_sta *mlink)
diff --git a/mt7996/mcu.h b/mt7996/mcu.h
index 20eaf20d..05b29c90 100644
--- a/mt7996/mcu.h
+++ b/mt7996/mcu.h
@@ -983,6 +983,9 @@ enum {
sizeof(struct sta_rec_hdrt) + \
sizeof(struct sta_rec_hdr_trans) + \
sizeof(struct sta_rec_tx_cap) + \
+ sizeof(struct sta_rec_mld_setup) + \
+ sizeof(struct mld_setup_link) * 3 + \
+ sizeof(struct sta_rec_eht_mld) + \
sizeof(struct tlv))
#define MT7996_MAX_BEACON_SIZE 1338
diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
index 3ee8156c..1e507b1c 100644
--- a/mt7996/mt7996.h
+++ b/mt7996/mt7996.h
@@ -1083,8 +1083,6 @@ int mt7996_mcu_add_rate_ctrl(struct mt7996_dev *dev,
struct mt7996_bss_conf *mconf,
struct ieee80211_link_sta *link_sta,
struct mt7996_link_sta *mlink, bool changed);
-int mt7996_mcu_add_mld_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif,
- struct ieee80211_sta *sta, unsigned long add);
int mt7996_set_channel(struct mt7996_phy *phy, struct cfg80211_chan_def *chandef);
int mt7996_mcu_set_chan_info(struct mt7996_phy *phy, u16 tag, bool sta);
int mt7996_mcu_set_tx(struct mt7996_dev *dev, struct mt7996_bss_conf *mconf);
--
2.18.0