blob: 6f1b34d58e9f587480766d37ed96d9bbda1f266d [file] [log] [blame]
From 886e275bd0450cfa2fd5dd971a3b81aa34d5636e Mon Sep 17 00:00:00 2001
From: Shayne Chen <shayne.chen@mediatek.com>
Date: Thu, 7 Dec 2023 15:39:03 +0800
Subject: [PATCH 113/120] wifi: mt76: connac: rework mcu functions for
multi-link support
This is a preliminary patch to add MLO support for mt7996 chipsets.
Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
---
mt7615/mcu.c | 4 +--
mt76_connac_mcu.c | 11 ++++----
mt76_connac_mcu.h | 2 +-
mt7915/mcu.c | 3 +-
mt7925/mcu.c | 3 +-
mt7996/mcu.c | 70 +++++++++++++++++++++++++++++++++--------------
6 files changed, 63 insertions(+), 30 deletions(-)
diff --git a/mt7615/mcu.c b/mt7615/mcu.c
index 8f4f203ef..e72dd654c 100644
--- a/mt7615/mcu.c
+++ b/mt7615/mcu.c
@@ -862,8 +862,8 @@ mt7615_mcu_wtbl_sta_add(struct mt7615_phy *phy, struct ieee80211_vif *vif,
else
mvif->sta_added = true;
}
- mt76_connac_mcu_sta_basic_tlv(&dev->mt76, sskb, vif, &sta->deflink,
- enable, new_entry);
+ mt76_connac_mcu_sta_basic_tlv(&dev->mt76, sskb, &vif->bss_conf,
+ &sta->deflink, enable, new_entry);
if (enable && sta)
mt76_connac_mcu_sta_tlv(phy->mt76, sskb, sta, vif, 0,
MT76_STA_INFO_STATE_ASSOC);
diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
index da2fe01ac..e7039a21f 100644
--- a/mt76_connac_mcu.c
+++ b/mt76_connac_mcu.c
@@ -370,10 +370,11 @@ void mt76_connac_mcu_bss_omac_tlv(struct sk_buff *skb,
EXPORT_SYMBOL_GPL(mt76_connac_mcu_bss_omac_tlv);
void mt76_connac_mcu_sta_basic_tlv(struct mt76_dev *dev, struct sk_buff *skb,
- struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *conf,
struct ieee80211_link_sta *link_sta,
bool enable, bool newly)
{
+ struct ieee80211_vif *vif = conf->vif;
struct ieee80211_sta *sta = link_sta ? link_sta->sta : NULL;
struct sta_rec_basic *basic;
struct tlv *tlv;
@@ -394,10 +395,9 @@ void mt76_connac_mcu_sta_basic_tlv(struct mt76_dev *dev, struct sk_buff *skb,
if (!sta) {
basic->conn_type = cpu_to_le32(CONNECTION_INFRA_BC);
-
if (is_mt799x(dev) && vif->type == NL80211_IFTYPE_STATION &&
- !is_zero_ether_addr(vif->bss_conf.bssid)) {
- memcpy(basic->peer_addr, vif->bss_conf.bssid, ETH_ALEN);
+ conf && !is_zero_ether_addr(conf->bssid)) {
+ memcpy(basic->peer_addr, conf->bssid, ETH_ALEN);
basic->aid = cpu_to_le16(vif->cfg.aid);
} else {
eth_broadcast_addr(basic->peer_addr);
@@ -1056,7 +1056,8 @@ int mt76_connac_mcu_sta_cmd(struct mt76_phy *phy,
return PTR_ERR(skb);
if (info->sta || !info->offload_fw)
- mt76_connac_mcu_sta_basic_tlv(dev, skb, info->vif, &info->sta->deflink,
+ mt76_connac_mcu_sta_basic_tlv(dev, skb, &info->vif->bss_conf,
+ &info->sta->deflink,
info->enable, info->newly);
if (info->sta && info->enable)
mt76_connac_mcu_sta_tlv(phy, skb, info->sta,
diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
index d45765beb..7f1562b8e 100644
--- a/mt76_connac_mcu.h
+++ b/mt76_connac_mcu.h
@@ -1904,7 +1904,7 @@ mt76_connac_mcu_add_tlv(struct sk_buff *skb, int tag, int len)
int mt76_connac_mcu_set_channel_domain(struct mt76_phy *phy);
int mt76_connac_mcu_set_vif_ps(struct mt76_dev *dev, struct ieee80211_vif *vif);
void mt76_connac_mcu_sta_basic_tlv(struct mt76_dev *dev, struct sk_buff *skb,
- struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *conf,
struct ieee80211_link_sta *link_sta,
bool enable, bool newly);
void mt76_connac_mcu_wtbl_generic_tlv(struct mt76_dev *dev, struct sk_buff *skb,
diff --git a/mt7915/mcu.c b/mt7915/mcu.c
index 1d1b3cead..366f2bba2 100644
--- a/mt7915/mcu.c
+++ b/mt7915/mcu.c
@@ -1669,7 +1669,8 @@ int mt7915_mcu_add_sta(struct mt7915_dev *dev, struct ieee80211_vif *vif,
return PTR_ERR(skb);
/* starec basic */
- mt76_connac_mcu_sta_basic_tlv(&dev->mt76, skb, vif, &sta->deflink, enable,
+ mt76_connac_mcu_sta_basic_tlv(&dev->mt76, skb, &vif->bss_conf,
+ &sta->deflink, enable,
!rcu_access_pointer(dev->mt76.wcid[msta->wcid.idx]));
if (!enable)
goto out;
diff --git a/mt7925/mcu.c b/mt7925/mcu.c
index 1cb556302..e9cf442b8 100644
--- a/mt7925/mcu.c
+++ b/mt7925/mcu.c
@@ -1626,7 +1626,8 @@ mt7925_mcu_sta_cmd(struct mt76_phy *phy,
return PTR_ERR(skb);
if (info->sta || !info->offload_fw)
- mt76_connac_mcu_sta_basic_tlv(dev, skb, info->vif, &info->sta->deflink,
+ mt76_connac_mcu_sta_basic_tlv(dev, skb, &info->vif->bss_conf,
+ &info->sta->deflink,
info->enable, info->newly);
if (info->sta && info->enable) {
mt7925_mcu_sta_phy_tlv(skb, info->vif, info->sta);
diff --git a/mt7996/mcu.c b/mt7996/mcu.c
index 72daf69dd..31c4733c4 100644
--- a/mt7996/mcu.c
+++ b/mt7996/mcu.c
@@ -1167,10 +1167,12 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb, struct ieee80211_bss_conf *conf,
sta = ieee80211_find_sta(vif, conf->bssid);
/* TODO: enable BSS_INFO_UAPSD & BSS_INFO_PM */
if (sta) {
- struct mt76_wcid *wcid;
+ struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
+ struct mt7996_link_sta *mlink;
- wcid = (struct mt76_wcid *)sta->drv_priv;
- sta_wlan_idx = wcid->idx;
+ mlink = rcu_dereference(msta->link[conf->link_id]);
+ if (mlink)
+ sta_wlan_idx = mlink->wcid.idx;
}
rcu_read_unlock();
}
@@ -1304,9 +1306,8 @@ int mt7996_mcu_set_timing(struct mt7996_phy *phy, struct mt7996_bss_conf *mconf)
static int
mt7996_mcu_sta_ba(struct mt7996_dev *dev, struct mt76_vif *mvif,
struct ieee80211_ampdu_params *params,
- bool enable, bool tx)
+ struct mt76_wcid *wcid, bool enable, bool tx)
{
- struct mt76_wcid *wcid = (struct mt76_wcid *)params->sta->drv_priv;
struct sta_rec_ba_uni *ba;
struct sk_buff *skb;
struct tlv *tlv;
@@ -1336,24 +1337,53 @@ int mt7996_mcu_add_tx_ba(struct mt7996_dev *dev,
struct ieee80211_ampdu_params *params,
bool enable)
{
- struct mt7996_sta *msta = (struct mt7996_sta *)params->sta->drv_priv;
- struct mt7996_bss_conf *mconf = mconf_dereference_protected(msta->vif, 0);
- struct mt7996_link_sta *mlink = mlink_dereference_protected(msta, 0);
+ struct ieee80211_sta *sta = params->sta;
+ struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
+ unsigned long valid_links = sta->valid_links ?: BIT(0);
+ unsigned int link_id;
+
+ for_each_set_bit(link_id, &valid_links, IEEE80211_MLD_MAX_NUM_LINKS) {
+ struct mt7996_link_sta *mlink =
+ mlink_dereference_protected(msta, link_id);
+ struct mt7996_bss_conf *mconf =
+ mconf_dereference_protected(msta->vif, link_id);
+ int ret;
- if (enable && !params->amsdu)
- mlink->wcid.amsdu = false;
+ if (enable && !params->amsdu)
+ mlink->wcid.amsdu = false;
- return mt7996_mcu_sta_ba(dev, &mconf->mt76, params, enable, true);
+ ret = mt7996_mcu_sta_ba(dev, &mconf->mt76, params,
+ &mlink->wcid, enable, true);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
}
int mt7996_mcu_add_rx_ba(struct mt7996_dev *dev,
struct ieee80211_ampdu_params *params,
bool enable)
{
- struct mt7996_sta *msta = (struct mt7996_sta *)params->sta->drv_priv;
- struct mt7996_bss_conf *mconf = mconf_dereference_protected(msta->vif, 0);
+ struct ieee80211_sta *sta = params->sta;
+ struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
+ unsigned long valid_links = sta->valid_links ?: BIT(0);
+ unsigned int link_id;
- return mt7996_mcu_sta_ba(dev, &mconf->mt76, params, enable, false);
+ for_each_set_bit(link_id, &valid_links, IEEE80211_MLD_MAX_NUM_LINKS) {
+ struct mt7996_link_sta *mlink =
+ mlink_dereference_protected(msta, link_id);
+ struct mt7996_bss_conf *mconf =
+ mconf_dereference_protected(msta->vif, link_id);
+ int ret;
+
+ ret = mt7996_mcu_sta_ba(dev, &mconf->mt76, params, &mlink->wcid,
+ enable, false);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
}
static void
@@ -2377,7 +2407,7 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_bss_conf *conf,
return PTR_ERR(skb);
/* starec basic */
- mt76_connac_mcu_sta_basic_tlv(&dev->mt76, skb, vif, link_sta, enable, newly);
+ mt76_connac_mcu_sta_basic_tlv(&dev->mt76, skb, conf, link_sta, enable, newly);
if (!enable)
goto out;
@@ -2838,7 +2868,7 @@ int mt7996_mcu_add_beacon(struct ieee80211_hw *hw,
struct mt7996_bss_conf *mconf, int en)
{
struct mt7996_dev *dev = mt7996_hw_dev(hw);
- struct mt7996_phy *phy = mt7996_hw_phy(hw);
+ struct mt7996_phy *phy = mconf->phy;
struct ieee80211_mutable_offsets offs;
struct ieee80211_tx_info *info;
struct sk_buff *skb, *rskb;
@@ -2854,7 +2884,7 @@ int mt7996_mcu_add_beacon(struct ieee80211_hw *hw,
if (IS_ERR(rskb))
return PTR_ERR(rskb);
- skb = ieee80211_beacon_get_template(hw, conf->vif, &offs, 0);
+ skb = ieee80211_beacon_get_template(hw, conf->vif, &offs, conf->link_id);
if (!skb) {
dev_kfree_skb(rskb);
return -EINVAL;
@@ -2892,9 +2922,9 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev,
{
#define OFFLOAD_TX_MODE_SU BIT(0)
#define OFFLOAD_TX_MODE_MU BIT(1)
- struct ieee80211_hw *hw = mt76_hw(dev);
struct ieee80211_vif *vif = conf->vif;
- struct mt7996_phy *phy = mt7996_hw_phy(hw);
+ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
+ struct mt7996_phy *phy = mconf->phy;
struct cfg80211_chan_def *chandef = &mconf->phy->mt76->chandef;
enum nl80211_band band = chandef->chan->band;
struct mt76_wcid *wcid = &dev->mt76.global_wcid;
@@ -5137,7 +5167,7 @@ int mt7996_mcu_get_per_sta_info(struct mt76_dev *dev, u16 tag,
rssi[3] = to_rssi(MT_PRXV_RCPI0, rcpi[3]);
mlink = container_of(wcid, struct mt7996_link_sta, wcid);
- phy = mlink->sta->vif->deflink.phy->mt76;
+ phy = dev->phys[wcid->phy_idx];
mlink->ack_signal = mt76_rx_signal(phy->antenna_mask, rssi);
ewma_avg_signal_add(&mlink->avg_ack_signal, -mlink->ack_signal);
} else {
--
2.39.2