From patchwork Tue Mar 11 17:45:00 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 872803 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D1CC526159F for ; Tue, 11 Mar 2025 17:45:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741715118; cv=none; b=U4udMMGwa8GwUNXrK6SFpu6Z+joKMaRux25vOmLWUBqjJ4hhrkw9SxNw/2zDAQZoixAge4/W3S6qyN0artxyO5oetg2YpGAihzSu83hlsM+xaXl7m1lAASSLa55VA6DuGbTsjdv6KG/FcbGGxwUjXICPGsxy2Wc5qSJMaqSDXyE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741715118; c=relaxed/simple; bh=iTxm09vzIwOGZsrbO6SwdKjRP6DnRsKoA/tAzDLV3+w=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=FnsF4ec4gHF4yU93UYBpKnzkIWpu7VMiiom9G6RNIiiHx0my/dVppI82yGVimjZzo06eXujlsZoYvU3IDMSAPjbhEPorGcXSzlkfc7WUQrueTOu1Zl+eFhBpBZc52NTMTLhh/8LQFkrpMA31QU6rCN+1XgggYjfkmyt6PoqcJV4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=EFtkSaTp; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="EFtkSaTp" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5C0F1C4CEEC; Tue, 11 Mar 2025 17:45:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1741715118; bh=iTxm09vzIwOGZsrbO6SwdKjRP6DnRsKoA/tAzDLV3+w=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=EFtkSaTpBXdx2hNabFoaSSPMyDP1I4bHIRE5td75prZ7aWgciiuT4ds//BbtMGCuH 0EBrXqY/QER9KqQMYoaVRg9RZaZdmVTPvbUU36uTez+P8zwuXYiyOJEj7ra/gMwrgk zcmFKyQRfckF2SPGNGFylAANHJ1wPqidaOEa/9lp/hzVxvgxuDYyf14HPECH4c3QoF 8hs9Q1ZsfLDxse7DnhWIN4XNTkePpXcgzZfpk+kaU7ADQ75I+TIjLmv6TQ+uGsa8i1 zqvcTi+6XYXPNRBf/zaWiERjfGMGN2D8EnyTBGh38NicLoI19EXnvAE5iXEWYyNOPM egOu5AQqnSChw== From: Lorenzo Bianconi Date: Tue, 11 Mar 2025 18:45:00 +0100 Subject: [PATCH v2 01/13] wifi: mt76: mt7996: Add chage_vif_links stub Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250311-mt7996-mlo-v2-1-31df6972519b@kernel.org> References: <20250311-mt7996-mlo-v2-0-31df6972519b@kernel.org> In-Reply-To: <20250311-mt7996-mlo-v2-0-31df6972519b@kernel.org> To: Felix Fietkau , Ryder Lee , Shayne Chen , Sean Wang , Kalle Valo , Matthias Brugger , AngeloGioacchino Del Regno , Lorenzo Bianconi , Johannes Berg Cc: linux-wireless@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org X-Mailer: b4 0.14.2 chage_vif_links callback is required by mac80211. This is a preliminary patch to introduce MLO support for MT7996 driver. Signed-off-by: Lorenzo Bianconi --- drivers/net/wireless/mediatek/mt76/mt7996/main.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c index b01cc7ef47999793f4815e4f3c6650c573f8cb28..c0e7ab9bcae5fcd503c10e1a02508977b6921d17 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c @@ -1650,6 +1650,14 @@ mt7996_net_fill_forward_path(struct ieee80211_hw *hw, #endif +static int +mt7996_change_vif_links(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + u16 old_links, u16 new_links, + struct ieee80211_bss_conf *old[IEEE80211_MLD_MAX_NUM_LINKS]) +{ + return 0; +} + const struct ieee80211_ops mt7996_ops = { .add_chanctx = mt76_add_chanctx, .remove_chanctx = mt76_remove_chanctx, @@ -1705,4 +1713,5 @@ const struct ieee80211_ops mt7996_ops = { .net_fill_forward_path = mt7996_net_fill_forward_path, .net_setup_tc = mt76_wed_net_setup_tc, #endif + .change_vif_links = mt7996_change_vif_links, }; From patchwork Tue Mar 11 17:45:02 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 872802 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1491B26388C for ; Tue, 11 Mar 2025 17:45:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741715125; cv=none; b=T2phFAwZWO6Tzf5NISptgm3Wx2m+1SfhcAdaD74Sag5A0hIFJpJRiKuxdRJp6TAhdQb4no/7WKw1q+/Fr1Py5x0AEzkLUy5GluClraka/oah/7qxXjwziR61gYz0Uo/4ybA7HrPq5Fiq8020cqSRysQRPL2zt1SS+SC05D2ycUo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741715125; c=relaxed/simple; bh=yMGvzqosXKLOg9r7y8NE7dLNPaEiAHvwtMOrKej2gDM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=bCizIr+FU1XwBamVSYNsk1JrqkIUYAzjtOMMs5I7XGNXBLwQvPhQVBYBwTxbGM2+bjTjtIvPMjx7vL8qq4uHU6/c/UQWs2Ny+RpFE8RQ8chfKTswG/BVMDGNtl+B/wZCIaepWP5lC7KllsjAKbbPR8yZUbMjIedZjL9jjaFLqjA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=UOvNErM8; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="UOvNErM8" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2EABCC4CEEA; Tue, 11 Mar 2025 17:45:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1741715124; bh=yMGvzqosXKLOg9r7y8NE7dLNPaEiAHvwtMOrKej2gDM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=UOvNErM86huTmpVRVXTsFHd3gq/GhF0LLFJLFNh9lEIga3OHhvWdOolRKdKDn3MQs UUTvVHOk6QzOUbVDSeuY+V8xmzoXwcDuv/Zio4EPYDS7lA2ahdFdl6lY8A2WfFn/Lt r79pU2+9MVn9oEdk4Px4STQC8KFlPiXuhEqiMvtigwg19vNXcQt7pnN3Qbksn1LqIe n/hO4j2QUkvvf9I0W7MSBvg+QvrUJYvg/31NPns9RDLGgAHoqztCkTL+eJtsYGypW6 Or7OP+yGWNCkgzrRx4akTDOp6YL6qJIZiwoyaoc/rbsFsQ7c1wfgZwKmkirdv+NDEM L/EK99ryY2MtQ== From: Lorenzo Bianconi Date: Tue, 11 Mar 2025 18:45:02 +0100 Subject: [PATCH v2 03/13] wifi: mt76: mt7996: Add mt7996_sta_link struct in mt7996_vif_link Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250311-mt7996-mlo-v2-3-31df6972519b@kernel.org> References: <20250311-mt7996-mlo-v2-0-31df6972519b@kernel.org> In-Reply-To: <20250311-mt7996-mlo-v2-0-31df6972519b@kernel.org> To: Felix Fietkau , Ryder Lee , Shayne Chen , Sean Wang , Kalle Valo , Matthias Brugger , AngeloGioacchino Del Regno , Lorenzo Bianconi , Johannes Berg Cc: linux-wireless@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org X-Mailer: b4 0.14.2 Introduce mt7996_sta_link field in mt7996_vif_link structure instead of mt7996_sta. This is a preliminary patch to support MLO in MT7996 driver. Signed-off-by: Lorenzo Bianconi --- drivers/net/wireless/mediatek/mt76/mt7996/mac.c | 6 +++--- drivers/net/wireless/mediatek/mt76/mt7996/main.c | 24 ++++++++++++---------- drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 10 ++++----- drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h | 2 +- 4 files changed, 22 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c index 754f8e520f52f6abf70daa148bf4289f68b1252b..456666eb7080c50493dcde61c5399adc6a987d2d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c @@ -72,10 +72,10 @@ static struct mt76_wcid *mt7996_rx_get_wcid(struct mt7996_dev *dev, msta_link = container_of(wcid, struct mt7996_sta_link, wcid); msta = msta_link->sta; - if (!msta->vif) + if (!msta || !msta->vif) return NULL; - return &msta->vif->deflink.sta.deflink.wcid; + return &msta->vif->deflink.msta_link.wcid; } bool mt7996_mac_wtbl_update(struct mt7996_dev *dev, int idx, u32 mask) @@ -202,7 +202,7 @@ void mt7996_mac_enable_rtscts(struct mt7996_dev *dev, struct ieee80211_vif *vif, bool enable) { struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; - struct mt7996_sta_link *msta_link = &mvif->deflink.sta.deflink; + struct mt7996_sta_link *msta_link = &mvif->deflink.msta_link; u32 addr; addr = mt7996_mac_wtbl_lmac_addr(dev, msta_link->wcid.idx, 5); diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c index 0cd011619fd3fc6f6994e4a8a896668340969cf5..34f984387c00714fbe72af5220ec067760510bb8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c @@ -161,19 +161,23 @@ mt7996_set_hw_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, struct mt7996_vif_link *mlink, struct ieee80211_key_conf *key) { struct mt7996_dev *dev = mt7996_hw_dev(hw); - struct mt7996_sta *msta = sta ? (struct mt7996_sta *)sta->drv_priv : - &mlink->sta; - struct mt76_wcid *wcid = &msta->deflink.wcid; - u8 *wcid_keyidx = &wcid->hw_key_idx; + struct mt76_wcid *wcid = &mlink->msta_link.wcid; struct mt7996_phy *phy; int idx = key->keyidx; + u8 *wcid_keyidx; phy = mt7996_vif_link_phy(mlink); if (!phy) return -EINVAL; - if (sta && !wcid->sta) - return -EOPNOTSUPP; + if (sta) { + struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv; + + wcid = &msta->deflink.wcid; + if (!wcid->sta) + return -EOPNOTSUPP; + } + wcid_keyidx = &wcid->hw_key_idx; switch (key->cipher) { case WLAN_CIPHER_SUITE_AES_CMAC: @@ -229,7 +233,7 @@ int mt7996_vif_link_add(struct mt76_phy *mphy, struct ieee80211_vif *vif, struct mt76_vif_link *mlink) { struct mt7996_vif_link *link = container_of(mlink, struct mt7996_vif_link, mt76); - struct mt7996_sta_link *msta_link = &link->sta.deflink; + struct mt7996_sta_link *msta_link = &link->msta_link; struct mt7996_phy *phy = mphy->priv; struct mt7996_dev *dev = phy->dev; u8 band_idx = phy->mt76->band_idx; @@ -261,7 +265,6 @@ int mt7996_vif_link_add(struct mt76_phy *mphy, struct ieee80211_vif *vif, idx = MT7996_WTBL_RESERVED - mlink->idx; INIT_LIST_HEAD(&msta_link->rc_list); - msta_link->sta = &link->sta; msta_link->wcid.idx = idx; msta_link->wcid.tx_info |= MT_WCID_TX_INFO_SET; mt76_wcid_init(&msta_link->wcid, band_idx); @@ -303,10 +306,9 @@ void mt7996_vif_link_remove(struct mt76_phy *mphy, struct ieee80211_vif *vif, struct mt76_vif_link *mlink) { struct mt7996_vif_link *link = container_of(mlink, struct mt7996_vif_link, mt76); + struct mt7996_sta_link *msta_link = &link->msta_link; struct mt7996_phy *phy = mphy->priv; struct mt7996_dev *dev = phy->dev; - struct mt7996_sta *msta = &link->sta; - struct mt7996_sta_link *msta_link = &msta->deflink; int idx = msta_link->wcid.idx; mt7996_mcu_add_sta(dev, vif, mlink, NULL, CONN_STATE_DISCONNECT, false); @@ -892,7 +894,7 @@ static void mt7996_tx(struct ieee80211_hw *hw, struct mt7996_vif *mvif; mvif = (struct mt7996_vif *)vif->drv_priv; - wcid = &mvif->deflink.sta.deflink.wcid; + wcid = &mvif->deflink.msta_link.wcid; if (mvif->mt76.roc_phy && (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN)) { diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c index b0ddc2af1516995fc11f030ef8360bae4ea3be3b..9018ede6efed49241205ddc042f3df149cd58530 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c @@ -2171,8 +2171,8 @@ mt7996_mcu_add_group(struct mt7996_dev *dev, struct ieee80211_vif *vif, .val = cpu_to_le32(mvif->deflink.mt76.idx % 16), }; - msta = sta ? (struct mt7996_sta *)sta->drv_priv : &mvif->deflink.sta; - msta_link = &msta->deflink; + msta = sta ? (struct mt7996_sta *)sta->drv_priv : NULL; + msta_link = msta ? &msta->deflink : &mvif->deflink.msta_link; req.wlan_idx = cpu_to_le16(msta_link->wcid.idx); return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(VOW), &req, @@ -2319,7 +2319,7 @@ static int mt7996_mcu_get_pn(struct mt7996_dev *dev, struct ieee80211_vif *vif, { #define TSC_TYPE_BIGTK_PN 2 struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; - struct mt7996_sta_link *msta_link = &mvif->deflink.sta.deflink; + struct mt7996_sta_link *msta_link = &mvif->deflink.msta_link; struct sta_rec_pn_info *pn_info; struct sk_buff *skb, *rskb; struct tlv *tlv; @@ -4357,8 +4357,8 @@ int mt7996_mcu_wtbl_update_hdr_trans(struct mt7996_dev *dev, struct mt7996_sta *msta; struct sk_buff *skb; - msta = sta ? (struct mt7996_sta *)sta->drv_priv : &mvif->deflink.sta; - msta_link = &msta->deflink; + msta = sta ? (struct mt7996_sta *)sta->drv_priv : NULL; + msta_link = msta ? &msta->deflink : &mvif->deflink.msta_link; skb = __mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->deflink.mt76, &msta_link->wcid, diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h index d0a4240f12a482895659e3a359daadcdca7bf7c9..ac5b94e1315ec610f5182563e3fb9d504a67c16f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h @@ -215,7 +215,7 @@ struct mt7996_sta { struct mt7996_vif_link { struct mt76_vif_link mt76; /* must be first */ - struct mt7996_sta sta; + struct mt7996_sta_link msta_link; struct mt7996_phy *phy; struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS]; From patchwork Tue Mar 11 17:45:04 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 872801 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E38741EBA1E for ; Tue, 11 Mar 2025 17:45:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741715130; cv=none; b=cXQod87CbSNJtN4VINb3ts5uR8yoWYIN8a4gwcc15reHxEfPLTveZmQQ70UZOHFvGUKDtWeMRW8Bz38nRUqOQSldX2CIVqaVSARu7CAjMMoi9SvYMUXUjXo+RZ8lp7F1+0wugY03NN+gAE3h/5wcUMIt8YpkZK7CrimuP8recq0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741715130; c=relaxed/simple; bh=mazpjGa8VjPIR8E7D94wthNV7G/W5waliDEdO1oOjQk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=jWGXy7bdJ4QdDAPPezOpoEfGq7YTvTNizqzqkI6Tcaj8u4UuEkR5UokcQmhNjNnKNMNc1ZZAU2LSc1WEOZvOAbcwRn33FbyOq1lW5wW13pxv5BivCNLxw3jM7qWUaGkFv5aefCXNS7R4o6kTEy2RvI/064l/ClMIhn/vjKc92Xo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=D/BSaTEm; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="D/BSaTEm" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 55F7DC4CEEA; Tue, 11 Mar 2025 17:45:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1741715129; bh=mazpjGa8VjPIR8E7D94wthNV7G/W5waliDEdO1oOjQk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=D/BSaTEmQYR1+6DRannWuJr6Qm+K84XJ48t1+z6dgIq7QEXx/v/Clgz5NFct26FdN YwvAJufwbqR7B7zhtWeDBefrAzRp5+ts/c8tDKEd8bmwEyEUhMzM2quTGNU8nZEQdq Zj9uEz/XsHfSJQVJmna/SEhfZCGr1hGqMOty9j7yvXvqB5ftg4LbEOJRy9kK4CVzTJ asr1QIaiaJqVXC92JHFpTpL2CgC8tTTzB7ILH764SgUBCMEs61lPqnfmXvmWJcwjd8 0gRugKBdX8+drp2sReYfdnef2MHdp3clwKdZojAsbYD55Hla6F9+ctFfrjUX2e3i3D cCYlG8ytEcXkg== From: Lorenzo Bianconi Date: Tue, 11 Mar 2025 18:45:04 +0100 Subject: [PATCH v2 05/13] wifi: mt76: mt7996: Add link_info_changed callback Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250311-mt7996-mlo-v2-5-31df6972519b@kernel.org> References: <20250311-mt7996-mlo-v2-0-31df6972519b@kernel.org> In-Reply-To: <20250311-mt7996-mlo-v2-0-31df6972519b@kernel.org> To: Felix Fietkau , Ryder Lee , Shayne Chen , Sean Wang , Kalle Valo , Matthias Brugger , AngeloGioacchino Del Regno , Lorenzo Bianconi , Johannes Berg Cc: linux-wireless@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org X-Mailer: b4 0.14.2 Convert bss_info_changed mac80211 callback in link_info_changed one. This is a preliminary patch to enable MLO support in MT7996 driver. Signed-off-by: Lorenzo Bianconi --- drivers/net/wireless/mediatek/mt76/mt7996/main.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c index 59a1e5e52450accc5b01fbe0c3af7e84bcc87df6..81a13662db24ec268fdd7a9b3d6b1d829a91430f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c @@ -712,10 +712,9 @@ mt7996_vif_cfg_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, mutex_unlock(&dev->mt76.mutex); } -static void mt7996_bss_info_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *info, - u64 changed) +static void +mt7996_link_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *info, u64 changed) { struct mt7996_dev *dev = mt7996_hw_dev(hw); struct mt76_vif_link *mvif; @@ -1719,8 +1718,8 @@ const struct ieee80211_ops mt7996_ops = { .config = mt7996_config, .conf_tx = mt7996_conf_tx, .configure_filter = mt7996_configure_filter, - .bss_info_changed = mt7996_bss_info_changed, .vif_cfg_changed = mt7996_vif_cfg_changed, + .link_info_changed = mt7996_link_info_changed, .sta_state = mt76_sta_state, .sta_pre_rcu_remove = mt76_sta_pre_rcu_remove, .link_sta_rc_update = mt7996_sta_rc_update, From patchwork Tue Mar 11 17:45:06 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 872800 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 82F3E41C72 for ; Tue, 11 Mar 2025 17:45:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741715135; cv=none; b=QlK24+Qnkond+AJzMLldfBf0d3qowUGRd+s4Cttrz+aH0dG7LrJth06KWq5NnbcmD05TF46hTOnknmH8pDhjmhNYSWIscdm0NwCarWnPVL1HKyru8K+x9ChlfIiGIgsJZLIGgInJ/RYqcPJOQMPHpqDeQJ1kRIZ7VhWQHBtxYvs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741715135; c=relaxed/simple; bh=WiSiQt/8p6iw9Vai6lwBuEr3mqR4pqcErC0Asy+CIpA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=LseH2B1z/hDD20VaiwwyhSDYfU/CCCHXoRBUu3SRYrohjr6Hqn/dxsf9ccw7qIwEHeGybc7ySJJmarN6YipLPDhlUGTOeRaQkS15rb7YQhOfOCgcT1N9+m2HB+OB3CthAQzDPhcIYbnIKUbHSc6eaPrvbTXPsgibSLmXSEA3wFI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=n9owl/yQ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="n9owl/yQ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A4657C4CEE9; Tue, 11 Mar 2025 17:45:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1741715135; bh=WiSiQt/8p6iw9Vai6lwBuEr3mqR4pqcErC0Asy+CIpA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=n9owl/yQYB63ttXTcrRu7AX3Ixqueb2ZenTAxQ7+npiNQ1zMpFitrMrseDkxbGC9B MlEF3eua5Q9L00TxG96f89ks89ud3ZjRVHMe1tnV7TtdkEFoA6SS5u8JHz4HMJh9tp hjda4dQnkaNROV4W3eLn6xu027EVGB6526FaIlVvRdf2A/RNrtmqeOka0kE5tCYjjc Dg6S2NpToyfjdnLB6f860U2bN+Hq1roU6emzaHHsQZ4WjajOgS7PIyHuGkCRhhwPW3 yR/pLqas7SLWzJM7WqA52hqK3gKT7AH7W2NiaVUKGO49i0WKqSba0DJ3vbFbEUEoS9 7K4sVotSWr1tQ== From: Lorenzo Bianconi Date: Tue, 11 Mar 2025 18:45:06 +0100 Subject: [PATCH v2 07/13] wifi: mt76: mt7996: Rely on mt7996_sta_link in sta_add/sta_remove callbacks Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250311-mt7996-mlo-v2-7-31df6972519b@kernel.org> References: <20250311-mt7996-mlo-v2-0-31df6972519b@kernel.org> In-Reply-To: <20250311-mt7996-mlo-v2-0-31df6972519b@kernel.org> To: Felix Fietkau , Ryder Lee , Shayne Chen , Sean Wang , Kalle Valo , Matthias Brugger , AngeloGioacchino Del Regno , Lorenzo Bianconi , Johannes Berg Cc: linux-wireless@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, Bo Jiao , Peter Chiu X-Mailer: b4 0.14.2 Generalize mt7996_mac_sta_add() and mt7996_mac_sta_remove() routines to deal with mt7996_sta_link structure. This is a preliminary patch to introduce MLO support for MT7996 driver. Co-developed-by: Bo Jiao Signed-off-by: Bo Jiao Co-developed-by: Peter Chiu Signed-off-by: Peter Chiu Co-developed-by: Shayne Chen Signed-off-by: Shayne Chen Signed-off-by: Lorenzo Bianconi --- drivers/net/wireless/mediatek/mt76/mt7996/main.c | 189 +++++++++++++++------ drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h | 4 + 2 files changed, 143 insertions(+), 50 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c index d99a98d57142fb4826b68c78864614d2c9132fe7..1bca444d2d02333cabd31ba2c8565769a42ab581 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c @@ -816,59 +816,164 @@ mt7996_channel_switch_beacon(struct ieee80211_hw *hw, } static int -mt7996_mac_sta_add(struct mt76_phy *mphy, struct ieee80211_vif *vif, - struct ieee80211_sta *sta) +mt7996_mac_sta_init_link(struct mt7996_dev *dev, struct ieee80211_vif *vif, + struct mt7996_vif_link *link, + struct ieee80211_sta *sta, unsigned int link_id) { - struct mt76_dev *mdev = mphy->dev; - struct mt7996_dev *dev = container_of(mdev, struct mt7996_dev, mt76); struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv; - struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; - struct mt7996_sta_link *msta_link = &msta->deflink; - struct mt7996_vif_link *link = &mvif->deflink; - u8 band_idx = mphy->band_idx; - int i, idx, ret = 0; + struct mt7996_phy *phy = link->phy; + struct mt7996_sta_link *msta_link; + int idx; - mutex_lock(&mdev->mutex); + idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7996_WTBL_STA); + if (idx < 0) + return -ENOSPC; + + if (msta->deflink_id == IEEE80211_LINK_UNSPECIFIED) { + int i; + + msta_link = &msta->deflink; + msta->deflink_id = link_id; + + for (i = 0; i < ARRAY_SIZE(sta->txq); i++) { + struct mt76_txq *mtxq; + + if (!sta->txq[i]) + continue; - idx = mt76_wcid_alloc(mdev->wcid_mask, MT7996_WTBL_STA); - if (idx < 0) { - ret = -ENOSPC; - goto unlock; + mtxq = (struct mt76_txq *)sta->txq[i]->drv_priv; + mtxq->wcid = idx; + } + } else { + msta_link = kzalloc(sizeof(*msta_link), GFP_KERNEL); + if (!msta_link) + return -ENOMEM; } - msta->vif = mvif; INIT_LIST_HEAD(&msta_link->rc_list); INIT_LIST_HEAD(&msta_link->wcid.poll_list); msta_link->sta = msta; msta_link->wcid.sta = 1; msta_link->wcid.idx = idx; - msta_link->wcid.phy_idx = band_idx; + msta_link->wcid.link_id = link_id; + + ewma_avg_signal_init(&msta_link->avg_ack_signal); + ewma_signal_init(&msta_link->wcid.rssi); - for (i = 0; i < ARRAY_SIZE(sta->txq); i++) { - struct mt76_txq *mtxq; + rcu_assign_pointer(msta->link[link_id], msta_link); - if (!sta->txq[i]) + mt7996_mac_wtbl_update(dev, idx, MT_WTBL_UPDATE_ADM_COUNT_CLEAR); + mt7996_mcu_add_sta(dev, vif, &link->mt76, sta, CONN_STATE_DISCONNECT, + true); + + rcu_assign_pointer(dev->mt76.wcid[idx], &msta_link->wcid); + mt76_wcid_init(&msta_link->wcid, phy->mt76->band_idx); + + return 0; +} + +static void +mt7996_mac_sta_deinit_link(struct mt7996_dev *dev, + struct mt7996_sta_link *msta_link) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(msta_link->wcid.aggr); i++) + mt76_rx_aggr_stop(&dev->mt76, &msta_link->wcid, i); + + mt7996_mac_wtbl_update(dev, msta_link->wcid.idx, + MT_WTBL_UPDATE_ADM_COUNT_CLEAR); + + spin_lock_bh(&dev->mt76.sta_poll_lock); + if (!list_empty(&msta_link->wcid.poll_list)) + list_del_init(&msta_link->wcid.poll_list); + if (!list_empty(&msta_link->rc_list)) + list_del_init(&msta_link->rc_list); + spin_unlock_bh(&dev->mt76.sta_poll_lock); + + mt76_wcid_cleanup(&dev->mt76, &msta_link->wcid); + mt76_wcid_mask_clear(dev->mt76.wcid_mask, msta_link->wcid.idx); +} + +static void +mt7996_mac_sta_remove_links(struct mt7996_dev *dev, struct ieee80211_sta *sta, + unsigned long links) +{ + struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv; + struct mt76_dev *mdev = &dev->mt76; + unsigned int link_id; + + for_each_set_bit(link_id, &links, IEEE80211_MLD_MAX_NUM_LINKS) { + struct mt7996_sta_link *msta_link = NULL; + + msta_link = rcu_replace_pointer(msta->link[link_id], msta_link, + lockdep_is_held(&mdev->mutex)); + if (!msta_link) continue; - mtxq = (struct mt76_txq *)sta->txq[i]->drv_priv; - mtxq->wcid = idx; + mt7996_mac_sta_deinit_link(dev, msta_link); + if (msta->deflink_id == link_id) { + msta->deflink_id = IEEE80211_LINK_UNSPECIFIED; + continue; + } + + kfree_rcu(msta_link, rcu_head); } +} - ewma_avg_signal_init(&msta_link->avg_ack_signal); - ewma_signal_init(&msta_link->wcid.rssi); +static int +mt7996_mac_sta_add_links(struct mt7996_dev *dev, struct ieee80211_vif *vif, + struct ieee80211_sta *sta, unsigned long new_links) +{ + struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv; + unsigned int link_id; + int err; - mt7996_mac_wtbl_update(dev, idx, - MT_WTBL_UPDATE_ADM_COUNT_CLEAR); - mt7996_mcu_add_sta(dev, vif, &link->mt76, sta, CONN_STATE_DISCONNECT, - true); + for_each_set_bit(link_id, &new_links, IEEE80211_MLD_MAX_NUM_LINKS) { + struct mt7996_vif_link *link; + + if (rcu_access_pointer(msta->link[link_id])) + continue; + + link = mt7996_vif_link(dev, vif, link_id); + if (!link) + goto error_unlink; + + err = mt7996_mac_sta_init_link(dev, vif, link, sta, link_id); + if (err) + goto error_unlink; + } + + return 0; + +error_unlink: + mt7996_mac_sta_remove_links(dev, sta, new_links); + + return err; +} + +static int +mt7996_mac_sta_add(struct mt76_phy *mphy, struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct mt76_dev *mdev = mphy->dev; + struct mt7996_dev *dev = container_of(mdev, struct mt7996_dev, mt76); + struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv; + struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; + unsigned long links = sta->mlo ? sta->valid_links : BIT(0); + int err; + + mutex_lock(&mdev->mutex); + + msta->deflink_id = IEEE80211_LINK_UNSPECIFIED; + msta->vif = mvif; + err = mt7996_mac_sta_add_links(dev, vif, sta, links); + if (!err) + mphy->num_sta++; - rcu_assign_pointer(mdev->wcid[idx], &msta_link->wcid); - mt76_wcid_init(&msta_link->wcid, band_idx); - mphy->num_sta++; -unlock: mutex_unlock(&mdev->mutex); - return ret; + return err; } static int @@ -922,27 +1027,11 @@ mt7996_mac_sta_remove(struct mt76_phy *mphy, struct ieee80211_vif *vif, { struct mt76_dev *mdev = mphy->dev; struct mt7996_dev *dev = container_of(mdev, struct mt7996_dev, mt76); - struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv; - struct mt7996_sta_link *msta_link = &msta->deflink; - int i, idx = msta_link->wcid.idx; + unsigned long links = sta->mlo ? sta->valid_links : BIT(0); mutex_lock(&mdev->mutex); - for (i = 0; i < ARRAY_SIZE(msta_link->wcid.aggr); i++) - mt76_rx_aggr_stop(mdev, &msta_link->wcid, i); - - mt7996_mac_wtbl_update(dev, msta_link->wcid.idx, - MT_WTBL_UPDATE_ADM_COUNT_CLEAR); - - spin_lock_bh(&mdev->sta_poll_lock); - if (!list_empty(&msta_link->wcid.poll_list)) - list_del_init(&msta_link->wcid.poll_list); - if (!list_empty(&msta_link->rc_list)) - list_del_init(&msta_link->rc_list); - spin_unlock_bh(&mdev->sta_poll_lock); - - mt76_wcid_cleanup(mdev, &msta_link->wcid); - mt76_wcid_mask_clear(mdev->wcid_mask, idx); + mt7996_mac_sta_remove_links(dev, sta, links); mphy->num_sta--; mutex_unlock(&mdev->mutex); diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h index 117a9e6c49645e847c579d15809bb5553a64ccfd..cf37baa91a8ba1cfafb07a4166aed0a0e84968fa 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h @@ -204,10 +204,14 @@ struct mt7996_sta_link { u8 flowid_mask; struct mt7996_twt_flow flow[MT7996_MAX_STA_TWT_AGRT]; } twt; + + struct rcu_head rcu_head; }; struct mt7996_sta { struct mt7996_sta_link deflink; /* must be first */ + struct mt7996_sta_link __rcu *link[IEEE80211_MLD_MAX_NUM_LINKS]; + u8 deflink_id; struct mt7996_vif *vif; }; From patchwork Tue Mar 11 17:45:08 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 872799 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 454B1263C71 for ; Tue, 11 Mar 2025 17:45:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741715140; cv=none; b=ZBW3ykCWpljmyIVTrul41tuYeZ+Xr8UN+2g2RvDzguVRj3vCr0S8mlbO+8XsWqNVVxCBHMW1WISWrm/pw6FGp9BEp/JW3xwH1y+Jr9x2jfkmInADa9Xi2O/1l/aqZcC8ca7hj57PKpV9nK+3JBUfpMaSX53iLveTDGbuDBRmSU8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741715140; c=relaxed/simple; bh=R6gtg/TQgZku/lKJqB18xCV0J8UOG6HPluWCjQVyBro=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=uE9U2clOlQhO1ZEf681mTsdGcEh0gZ/Xvtf40bZTAPZvo1rrHfzizUv7RZqHfRVOsOmRTlOgZKE1MNzp/BNxWKRhWdv86IR/siL3+sS0qa9EAYYeci8BNk8V8f/Tq4RNU5umn2923Sz7m8z0bxiQf1sFbfpEz5bbSA+B7qTPY1w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=mYDikKAR; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="mYDikKAR" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C5247C4CEE9; Tue, 11 Mar 2025 17:45:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1741715140; bh=R6gtg/TQgZku/lKJqB18xCV0J8UOG6HPluWCjQVyBro=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=mYDikKAR2jNfzHfGL/PSDYSCJCpSiliCotsLvB91EjDjDgVVftrJYUUh8mg2FPJLf ZxSaNXjYYJzwLaRxIXd8w3ckJQ2EsWiG1pt1X2qKk9tA4HmCzaBq9WKX/YrGqRgeuN DXerEjDgu1mMLsQ3sJJJfRo+UHrvK0T6iCNYpFFOx9kzuRdp/3NdINXAMu7Dl7FiF3 7bM5v0LU76iRzQaBQHj2mbXRItScgXpLd0QDUIJyj9eXT7JuTlgWiVlIArb/mW3jNy NuGZPfb52r5t47qaATo0rcM2MKSqZvFdhIKywqjhvI8fJTtVwWTopte6e8JKlDWkMf G0spAbPJNSVTg== From: Lorenzo Bianconi Date: Tue, 11 Mar 2025 18:45:08 +0100 Subject: [PATCH v2 09/13] wifi: mt76: mt7996: Support MLO in mt7996_mac_sta_event() Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250311-mt7996-mlo-v2-9-31df6972519b@kernel.org> References: <20250311-mt7996-mlo-v2-0-31df6972519b@kernel.org> In-Reply-To: <20250311-mt7996-mlo-v2-0-31df6972519b@kernel.org> To: Felix Fietkau , Ryder Lee , Shayne Chen , Sean Wang , Kalle Valo , Matthias Brugger , AngeloGioacchino Del Regno , Lorenzo Bianconi , Johannes Berg Cc: linux-wireless@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, Bo Jiao , Peter Chiu X-Mailer: b4 0.14.2 Similar to mt7996_mac_sta_add() adn mt7996_mac_sta_remove(), update mt7996_mac_sta_event routine to take into account MLO support. Please note mcu routines does not support MLO yet. Co-developed-by: Bo Jiao Signed-off-by: Bo Jiao Co-developed-by: Peter Chiu Signed-off-by: Peter Chiu Co-developed-by: Shayne Chen Signed-off-by: Shayne Chen Signed-off-by: Lorenzo Bianconi --- drivers/net/wireless/mediatek/mt76/mt7996/main.c | 69 ++++++++++++++---------- 1 file changed, 40 insertions(+), 29 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c index 307c68c6b0cd7c3acdbfd7be78a007a66d3183bf..6d323b5e4e8076ca963e585c12dc656dc5ec3fdb 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c @@ -1001,41 +1001,52 @@ mt7996_mac_sta_event(struct mt7996_dev *dev, struct ieee80211_vif *vif, struct ieee80211_sta *sta, enum mt76_sta_event ev) { struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv; - struct mt7996_sta_link *msta_link = &msta->deflink; - struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; - struct mt7996_vif_link *link = &mvif->deflink; - int i, ret; - - switch (ev) { - case MT76_STA_EVENT_ASSOC: - ret = mt7996_mcu_add_sta(dev, vif, &link->mt76, sta, - CONN_STATE_CONNECT, true); - if (ret) - return ret; - - ret = mt7996_mcu_add_rate_ctrl(dev, vif, sta, false); - if (ret) - return ret; + struct ieee80211_link_sta *link_sta; + unsigned int link_id; - msta_link->wcid.tx_info |= MT_WCID_TX_INFO_SET; - msta_link->wcid.sta = 1; + for_each_sta_active_link(vif, sta, link_sta, link_id) { + struct mt7996_sta_link *msta_link; + struct mt7996_vif_link *link; + int i, err; - return 0; + link = mt7996_vif_link(dev, vif, link_id); + if (!link) + continue; - case MT76_STA_EVENT_AUTHORIZE: - return mt7996_mcu_add_sta(dev, vif, &link->mt76, sta, - CONN_STATE_PORT_SECURE, false); + msta_link = mt76_dereference(msta->link[link_id], &dev->mt76); + if (!msta_link) + continue; - case MT76_STA_EVENT_DISASSOC: - for (i = 0; i < ARRAY_SIZE(msta_link->twt.flow); i++) - mt7996_mac_twt_teardown_flow(dev, msta, i); + switch (ev) { + case MT76_STA_EVENT_ASSOC: + err = mt7996_mcu_add_sta(dev, vif, &link->mt76, sta, + CONN_STATE_CONNECT, true); + if (err) + return err; - mt7996_mcu_add_sta(dev, vif, &link->mt76, sta, - CONN_STATE_DISCONNECT, false); - msta_link->wcid.sta_disabled = 1; - msta_link->wcid.sta = 0; + err = mt7996_mcu_add_rate_ctrl(dev, vif, sta, false); + if (err) + return err; - return 0; + msta_link->wcid.tx_info |= MT_WCID_TX_INFO_SET; + msta_link->wcid.sta = 1; + break; + case MT76_STA_EVENT_AUTHORIZE: + err = mt7996_mcu_add_sta(dev, vif, &link->mt76, sta, + CONN_STATE_PORT_SECURE, false); + if (err) + return err; + break; + case MT76_STA_EVENT_DISASSOC: + for (i = 0; i < ARRAY_SIZE(msta_link->twt.flow); i++) + mt7996_mac_twt_teardown_flow(dev, msta, i); + + mt7996_mcu_add_sta(dev, vif, &link->mt76, sta, + CONN_STATE_DISCONNECT, false); + msta_link->wcid.sta_disabled = 1; + msta_link->wcid.sta = 0; + break; + } } return 0; From patchwork Tue Mar 11 17:45:10 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 872798 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1408C262D21 for ; Tue, 11 Mar 2025 17:45:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741715146; cv=none; b=EumXuR7bI8Y37JSuNuSxRk5wKfjRg+sUbXuwYXePRveyGtLVn9zP973Xu+fM68y3+wNrIhd5YvYAsKHhK3Vt5807WSAzrP1oYXq2NuIgBEmu5VRxlwplT4BsjajG8ewqPPH1MsVzo/YRVCD/ZPop6RxTO/aj6+2kLnLBzmm/XZs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741715146; c=relaxed/simple; bh=qv13+ZY2axgdcgBj5VVQvrZErwdM/s1uSjnNxo6Ap6Y=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=j8oMX65vcA0p2F2ivuyhiG8FU8YFlAz4/jWEY/FKXGCqPqrkMa6I5TCx17Bt+zm+isXahLZvBTNoN3je9/I0AtFd7ZKKV3CiMuqMRxUhVXjxEpkN0IzJ9wzJzx3t0zVUNuIE2vAvlowe/G6Cjjq0x/NhmmQBssH/cuWJIYh/vjg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=OP9IFEXi; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="OP9IFEXi" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 008EEC4CEE9; Tue, 11 Mar 2025 17:45:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1741715145; bh=qv13+ZY2axgdcgBj5VVQvrZErwdM/s1uSjnNxo6Ap6Y=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=OP9IFEXiJKGO6Nb0AzXseBe2lI5+eEzGQdA0ekgYTs+6KOg9bCFsa1pUbUsYfsOOR uZKZDfyXaapMNwCfyxMj8Xu2bqMYme3xBsdyLvz+9OVMNU517MzsCeB8oV0bD5Tapf uENw8VBC8sJJZ9U57+CfOFxxttI3IjlIzdR8IWGXDrqr95FYI3GmkLbxqythfqwFB1 9p46PKb8+h9cV0gRgaObnnw4rdBQQ3wP4UtJldqG1V2CpuF7lkB7xpb7jdB3/Kd+U1 9piaW/BqqU6hLJ7Jnh+3Gfa6TL1VFM8lFqOpJ3dNpPCBWR7pVZkCko5ZksDzEQPr5v cIwJwMmZJPIKw== From: Lorenzo Bianconi Date: Tue, 11 Mar 2025 18:45:10 +0100 Subject: [PATCH v2 11/13] wifi: mt76: mt7996: Update mt7996_mcu_add_sta to MLO support Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250311-mt7996-mlo-v2-11-31df6972519b@kernel.org> References: <20250311-mt7996-mlo-v2-0-31df6972519b@kernel.org> In-Reply-To: <20250311-mt7996-mlo-v2-0-31df6972519b@kernel.org> To: Felix Fietkau , Ryder Lee , Shayne Chen , Sean Wang , Kalle Valo , Matthias Brugger , AngeloGioacchino Del Regno , Lorenzo Bianconi , Johannes Berg Cc: linux-wireless@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, Bo Jiao , Peter Chiu X-Mailer: b4 0.14.2 From: Shayne Chen Update mt7996_mcu_add_sta routine and all the called subroutines to support MLO. This is a preliminary patch to enable MLO for MT7996 driver. Co-developed-by: Bo Jiao Signed-off-by: Bo Jiao Co-developed-by: Peter Chiu Signed-off-by: Peter Chiu Signed-off-by: Shayne Chen Co-developed-by: Lorenzo Bianconi Signed-off-by: Lorenzo Bianconi --- drivers/net/wireless/mediatek/mt76/mt7996/main.c | 72 +++-- drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 296 +++++++++++---------- drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h | 9 +- 3 files changed, 208 insertions(+), 169 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c index 6d323b5e4e8076ca963e585c12dc656dc5ec3fdb..5ab4f08dba06fdf95ee4e6bc0261749016f07e6a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c @@ -293,7 +293,8 @@ int mt7996_vif_link_add(struct mt76_phy *mphy, struct ieee80211_vif *vif, * interface, since firmware only records BSSID when the entry is new */ if (vif->type != NL80211_IFTYPE_STATION) - mt7996_mcu_add_sta(dev, vif, mlink, NULL, CONN_STATE_PORT_SECURE, true); + mt7996_mcu_add_sta(dev, link_conf, NULL, link, NULL, + CONN_STATE_PORT_SECURE, true); rcu_assign_pointer(dev->mt76.wcid[idx], &msta_link->wcid); ieee80211_iter_keys(mphy->hw, vif, mt7996_key_iter, link); @@ -311,7 +312,8 @@ void mt7996_vif_link_remove(struct mt76_phy *mphy, struct ieee80211_vif *vif, struct mt7996_dev *dev = phy->dev; int idx = msta_link->wcid.idx; - mt7996_mcu_add_sta(dev, vif, mlink, NULL, CONN_STATE_DISCONNECT, false); + mt7996_mcu_add_sta(dev, link_conf, NULL, link, NULL, + CONN_STATE_DISCONNECT, false); mt7996_mcu_add_bss_info(phy, vif, link_conf, mlink, false); mt7996_mcu_add_dev_info(phy, vif, link_conf, mlink, false); @@ -703,7 +705,7 @@ mt7996_vif_cfg_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, mt7996_mcu_add_bss_info(link->phy, vif, link_conf, &link->mt76, true); - mt7996_mcu_add_sta(dev, vif, &link->mt76, NULL, + mt7996_mcu_add_sta(dev, link_conf, NULL, link, NULL, CONN_STATE_PORT_SECURE, !!(changed & BSS_CHANGED_BSSID)); } @@ -717,17 +719,17 @@ mt7996_link_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *info, u64 changed) { struct mt7996_dev *dev = mt7996_hw_dev(hw); - struct mt76_vif_link *mvif; + struct mt7996_vif_link *link; struct mt7996_phy *phy; struct mt76_phy *mphy; mutex_lock(&dev->mt76.mutex); - mvif = mt76_vif_conf_link(&dev->mt76, vif, info); - if (!mvif) + link = mt7996_vif_conf_link(dev, vif, info); + if (!link) goto out; - mphy = mt76_vif_link_phy(mvif); + mphy = mt76_vif_link_phy(&link->mt76); if (!mphy) goto out; @@ -738,8 +740,9 @@ mt7996_link_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, */ if ((changed & BSS_CHANGED_BSSID && !is_zero_ether_addr(info->bssid)) || (changed & BSS_CHANGED_BEACON_ENABLED && info->enable_beacon)) { - mt7996_mcu_add_bss_info(phy, vif, info, mvif, true); - mt7996_mcu_add_sta(dev, vif, mvif, NULL, CONN_STATE_PORT_SECURE, + mt7996_mcu_add_bss_info(phy, vif, info, &link->mt76, true); + mt7996_mcu_add_sta(dev, info, NULL, link, NULL, + CONN_STATE_PORT_SECURE, !!(changed & BSS_CHANGED_BSSID)); } @@ -756,11 +759,11 @@ mt7996_link_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, } if (changed & BSS_CHANGED_MCAST_RATE) - mvif->mcast_rates_idx = + link->mt76.mcast_rates_idx = mt7996_get_rates_table(phy, info, false, true); if (changed & BSS_CHANGED_BASIC_RATES) - mvif->basic_rates_idx = + link->mt76.basic_rates_idx = mt7996_get_rates_table(phy, info, false, false); /* ensure that enable txcmd_mode after bss_info */ @@ -772,15 +775,15 @@ mt7996_link_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, if (changed & BSS_CHANGED_HE_BSS_COLOR) { if ((vif->type == NL80211_IFTYPE_AP && - mvif->omac_idx <= HW_BSSID_MAX) || + link->mt76.omac_idx <= HW_BSSID_MAX) || vif->type == NL80211_IFTYPE_STATION) - mt7996_mcu_update_bss_color(dev, mvif, + mt7996_mcu_update_bss_color(dev, &link->mt76, &info->he_bss_color); } if (changed & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED)) { - mvif->beacon_rates_idx = + link->mt76.beacon_rates_idx = mt7996_get_rates_table(phy, info, true, false); mt7996_mcu_add_beacon(hw, vif, info); @@ -816,10 +819,12 @@ mt7996_channel_switch_beacon(struct ieee80211_hw *hw, } static int -mt7996_mac_sta_init_link(struct mt7996_dev *dev, struct ieee80211_vif *vif, - struct mt7996_vif_link *link, - struct ieee80211_sta *sta, unsigned int link_id) +mt7996_mac_sta_init_link(struct mt7996_dev *dev, + struct ieee80211_bss_conf *link_conf, + struct ieee80211_link_sta *link_sta, + struct mt7996_vif_link *link, unsigned int link_id) { + struct ieee80211_sta *sta = link_sta->sta; struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv; struct mt7996_phy *phy = link->phy; struct mt7996_sta_link *msta_link; @@ -863,8 +868,8 @@ mt7996_mac_sta_init_link(struct mt7996_dev *dev, struct ieee80211_vif *vif, rcu_assign_pointer(msta->link[link_id], msta_link); mt7996_mac_wtbl_update(dev, idx, MT_WTBL_UPDATE_ADM_COUNT_CLEAR); - mt7996_mcu_add_sta(dev, vif, &link->mt76, sta, CONN_STATE_DISCONNECT, - true); + mt7996_mcu_add_sta(dev, link_conf, link_sta, link, msta_link, + CONN_STATE_DISCONNECT, true); rcu_assign_pointer(dev->mt76.wcid[idx], &msta_link->wcid); mt76_wcid_init(&msta_link->wcid, phy->mt76->band_idx); @@ -930,16 +935,27 @@ mt7996_mac_sta_add_links(struct mt7996_dev *dev, struct ieee80211_vif *vif, int err; for_each_set_bit(link_id, &new_links, IEEE80211_MLD_MAX_NUM_LINKS) { + struct ieee80211_bss_conf *link_conf; + struct ieee80211_link_sta *link_sta; struct mt7996_vif_link *link; if (rcu_access_pointer(msta->link[link_id])) continue; + link_conf = link_conf_dereference_protected(vif, link_id); + if (!link_conf) + goto error_unlink; + link = mt7996_vif_link(dev, vif, link_id); if (!link) goto error_unlink; - err = mt7996_mac_sta_init_link(dev, vif, link, sta, link_id); + link_sta = link_sta_dereference_protected(sta, link_id); + if (!link_sta) + goto error_unlink; + + err = mt7996_mac_sta_init_link(dev, link_conf, link_sta, link, + link_id); if (err) goto error_unlink; } @@ -1005,10 +1021,15 @@ mt7996_mac_sta_event(struct mt7996_dev *dev, struct ieee80211_vif *vif, unsigned int link_id; for_each_sta_active_link(vif, sta, link_sta, link_id) { + struct ieee80211_bss_conf *link_conf; struct mt7996_sta_link *msta_link; struct mt7996_vif_link *link; int i, err; + link_conf = link_conf_dereference_protected(vif, link_id); + if (!link_conf) + continue; + link = mt7996_vif_link(dev, vif, link_id); if (!link) continue; @@ -1019,7 +1040,8 @@ mt7996_mac_sta_event(struct mt7996_dev *dev, struct ieee80211_vif *vif, switch (ev) { case MT76_STA_EVENT_ASSOC: - err = mt7996_mcu_add_sta(dev, vif, &link->mt76, sta, + err = mt7996_mcu_add_sta(dev, link_conf, link_sta, + link, msta_link, CONN_STATE_CONNECT, true); if (err) return err; @@ -1032,7 +1054,8 @@ mt7996_mac_sta_event(struct mt7996_dev *dev, struct ieee80211_vif *vif, msta_link->wcid.sta = 1; break; case MT76_STA_EVENT_AUTHORIZE: - err = mt7996_mcu_add_sta(dev, vif, &link->mt76, sta, + err = mt7996_mcu_add_sta(dev, link_conf, link_sta, + link, msta_link, CONN_STATE_PORT_SECURE, false); if (err) return err; @@ -1041,8 +1064,9 @@ mt7996_mac_sta_event(struct mt7996_dev *dev, struct ieee80211_vif *vif, for (i = 0; i < ARRAY_SIZE(msta_link->twt.flow); i++) mt7996_mac_twt_teardown_flow(dev, msta, i); - mt7996_mcu_add_sta(dev, vif, &link->mt76, sta, - CONN_STATE_DISCONNECT, false); + mt7996_mcu_add_sta(dev, link_conf, link_sta, link, + msta_link, CONN_STATE_DISCONNECT, + false); msta_link->wcid.sta_disabled = 1; msta_link->wcid.sta = 0; break; diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c index 9018ede6efed49241205ddc042f3df149cd58530..43e85308132e5ed80d8199858014b31a29b2e3b5 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c @@ -118,13 +118,13 @@ mt7996_mcu_get_sta_nss(u16 mcs_map) } static void -mt7996_mcu_set_sta_he_mcs(struct ieee80211_sta *sta, __le16 *he_mcs, - u16 mcs_map) +mt7996_mcu_set_sta_he_mcs(struct ieee80211_link_sta *link_sta, + struct mt7996_vif_link *link, + __le16 *he_mcs, u16 mcs_map) { - struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv; - enum nl80211_band band = msta->vif->deflink.phy->mt76->chandef.chan->band; - const u16 *mask = msta->vif->deflink.bitrate_mask.control[band].he_mcs; - int nss, max_nss = sta->deflink.rx_nss > 3 ? 4 : sta->deflink.rx_nss; + int nss, max_nss = link_sta->rx_nss > 3 ? 4 : link_sta->rx_nss; + enum nl80211_band band = link->phy->mt76->chandef.chan->band; + const u16 *mask = link->bitrate_mask.control[band].he_mcs; for (nss = 0; nss < max_nss; nss++) { int mcs; @@ -1182,15 +1182,17 @@ int mt7996_mcu_add_rx_ba(struct mt7996_dev *dev, } static void -mt7996_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta) +mt7996_mcu_sta_he_tlv(struct sk_buff *skb, + struct ieee80211_link_sta *link_sta, + struct mt7996_vif_link *link) { - struct ieee80211_he_cap_elem *elem = &sta->deflink.he_cap.he_cap_elem; + struct ieee80211_he_cap_elem *elem = &link_sta->he_cap.he_cap_elem; struct ieee80211_he_mcs_nss_supp mcs_map; struct sta_rec_he_v2 *he; struct tlv *tlv; int i = 0; - if (!sta->deflink.he_cap.has_he) + if (!link_sta->he_cap.has_he) return; tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HE_V2, sizeof(*he)); @@ -1202,21 +1204,21 @@ mt7996_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta) he->he_phy_cap[i] = elem->phy_cap_info[i]; } - mcs_map = sta->deflink.he_cap.he_mcs_nss_supp; - switch (sta->deflink.bandwidth) { + mcs_map = link_sta->he_cap.he_mcs_nss_supp; + switch (link_sta->bandwidth) { case IEEE80211_STA_RX_BW_160: if (elem->phy_cap_info[0] & IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) - mt7996_mcu_set_sta_he_mcs(sta, + mt7996_mcu_set_sta_he_mcs(link_sta, link, &he->max_nss_mcs[CMD_HE_MCS_BW8080], le16_to_cpu(mcs_map.rx_mcs_80p80)); - mt7996_mcu_set_sta_he_mcs(sta, + mt7996_mcu_set_sta_he_mcs(link_sta, link, &he->max_nss_mcs[CMD_HE_MCS_BW160], le16_to_cpu(mcs_map.rx_mcs_160)); fallthrough; default: - mt7996_mcu_set_sta_he_mcs(sta, + mt7996_mcu_set_sta_he_mcs(link_sta, link, &he->max_nss_mcs[CMD_HE_MCS_BW80], le16_to_cpu(mcs_map.rx_mcs_80)); break; @@ -1226,24 +1228,26 @@ mt7996_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta) } static void -mt7996_mcu_sta_he_6g_tlv(struct sk_buff *skb, struct ieee80211_sta *sta) +mt7996_mcu_sta_he_6g_tlv(struct sk_buff *skb, + struct ieee80211_link_sta *link_sta) { struct sta_rec_he_6g_capa *he_6g; struct tlv *tlv; - if (!sta->deflink.he_6ghz_capa.capa) + if (!link_sta->he_6ghz_capa.capa) return; tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HE_6G, sizeof(*he_6g)); he_6g = (struct sta_rec_he_6g_capa *)tlv; - he_6g->capa = sta->deflink.he_6ghz_capa.capa; + he_6g->capa = link_sta->he_6ghz_capa.capa; } static void -mt7996_mcu_sta_eht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta) +mt7996_mcu_sta_eht_tlv(struct sk_buff *skb, + struct ieee80211_link_sta *link_sta) { - struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv; + struct mt7996_sta *msta = (struct mt7996_sta *)link_sta->sta->drv_priv; struct ieee80211_vif *vif = container_of((void *)msta->vif, struct ieee80211_vif, drv_priv); struct ieee80211_eht_mcs_nss_supp *mcs_map; @@ -1251,11 +1255,11 @@ mt7996_mcu_sta_eht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta) struct sta_rec_eht *eht; struct tlv *tlv; - if (!sta->deflink.eht_cap.has_eht) + if (!link_sta->eht_cap.has_eht) return; - mcs_map = &sta->deflink.eht_cap.eht_mcs_nss_supp; - elem = &sta->deflink.eht_cap.eht_cap_elem; + mcs_map = &link_sta->eht_cap.eht_mcs_nss_supp; + elem = &link_sta->eht_cap.eht_cap_elem; tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_EHT, sizeof(*eht)); @@ -1266,7 +1270,7 @@ mt7996_mcu_sta_eht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta) eht->phy_cap_ext = cpu_to_le64(elem->phy_cap_info[8]); if (vif->type != NL80211_IFTYPE_STATION && - (sta->deflink.he_cap.he_cap_elem.phy_cap_info[0] & + (link_sta->he_cap.he_cap_elem.phy_cap_info[0] & (IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G | IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G | IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G | @@ -1282,48 +1286,48 @@ mt7996_mcu_sta_eht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta) } static void -mt7996_mcu_sta_ht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta) +mt7996_mcu_sta_ht_tlv(struct sk_buff *skb, struct ieee80211_link_sta *link_sta) { struct sta_rec_ht_uni *ht; struct tlv *tlv; - if (!sta->deflink.ht_cap.ht_supported) + if (!link_sta->ht_cap.ht_supported) return; tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HT, sizeof(*ht)); ht = (struct sta_rec_ht_uni *)tlv; - ht->ht_cap = cpu_to_le16(sta->deflink.ht_cap.cap); - ht->ampdu_param = u8_encode_bits(sta->deflink.ht_cap.ampdu_factor, + ht->ht_cap = cpu_to_le16(link_sta->ht_cap.cap); + ht->ampdu_param = u8_encode_bits(link_sta->ht_cap.ampdu_factor, IEEE80211_HT_AMPDU_PARM_FACTOR) | - u8_encode_bits(sta->deflink.ht_cap.ampdu_density, + u8_encode_bits(link_sta->ht_cap.ampdu_density, IEEE80211_HT_AMPDU_PARM_DENSITY); } static void -mt7996_mcu_sta_vht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta) +mt7996_mcu_sta_vht_tlv(struct sk_buff *skb, struct ieee80211_link_sta *link_sta) { struct sta_rec_vht *vht; struct tlv *tlv; /* For 6G band, this tlv is necessary to let hw work normally */ - if (!sta->deflink.he_6ghz_capa.capa && !sta->deflink.vht_cap.vht_supported) + if (!link_sta->he_6ghz_capa.capa && !link_sta->vht_cap.vht_supported) return; tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_VHT, sizeof(*vht)); vht = (struct sta_rec_vht *)tlv; - vht->vht_cap = cpu_to_le32(sta->deflink.vht_cap.cap); - vht->vht_rx_mcs_map = sta->deflink.vht_cap.vht_mcs.rx_mcs_map; - vht->vht_tx_mcs_map = sta->deflink.vht_cap.vht_mcs.tx_mcs_map; + vht->vht_cap = cpu_to_le32(link_sta->vht_cap.cap); + vht->vht_rx_mcs_map = link_sta->vht_cap.vht_mcs.rx_mcs_map; + vht->vht_tx_mcs_map = link_sta->vht_cap.vht_mcs.tx_mcs_map; } static void mt7996_mcu_sta_amsdu_tlv(struct mt7996_dev *dev, struct sk_buff *skb, - struct ieee80211_vif *vif, struct ieee80211_sta *sta) + struct ieee80211_vif *vif, + struct ieee80211_link_sta *link_sta, + struct mt7996_sta_link *msta_link) { - struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv; - struct mt7996_sta_link *msta_link = &msta->deflink; struct sta_rec_amsdu *amsdu; struct tlv *tlv; @@ -1332,7 +1336,7 @@ mt7996_mcu_sta_amsdu_tlv(struct mt7996_dev *dev, struct sk_buff *skb, vif->type != NL80211_IFTYPE_AP) return; - if (!sta->deflink.agg.max_amsdu_len) + if (!link_sta->agg.max_amsdu_len) return; tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HW_AMSDU, sizeof(*amsdu)); @@ -1341,7 +1345,7 @@ mt7996_mcu_sta_amsdu_tlv(struct mt7996_dev *dev, struct sk_buff *skb, amsdu->amsdu_en = true; msta_link->wcid.amsdu = true; - switch (sta->deflink.agg.max_amsdu_len) { + switch (link_sta->agg.max_amsdu_len) { case IEEE80211_MAX_MPDU_LEN_VHT_11454: amsdu->max_mpdu_size = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454; @@ -1358,30 +1362,31 @@ mt7996_mcu_sta_amsdu_tlv(struct mt7996_dev *dev, struct sk_buff *skb, static void mt7996_mcu_sta_muru_tlv(struct mt7996_dev *dev, struct sk_buff *skb, - struct ieee80211_vif *vif, struct ieee80211_sta *sta) + struct ieee80211_bss_conf *link_conf, + struct ieee80211_link_sta *link_sta) { - struct ieee80211_he_cap_elem *elem = &sta->deflink.he_cap.he_cap_elem; + struct ieee80211_he_cap_elem *elem = &link_sta->he_cap.he_cap_elem; struct sta_rec_muru *muru; struct tlv *tlv; - if (vif->type != NL80211_IFTYPE_STATION && - vif->type != NL80211_IFTYPE_AP) + if (link_conf->vif->type != NL80211_IFTYPE_STATION && + link_conf->vif->type != NL80211_IFTYPE_AP) return; tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_MURU, sizeof(*muru)); muru = (struct sta_rec_muru *)tlv; - muru->cfg.mimo_dl_en = vif->bss_conf.eht_mu_beamformer || - vif->bss_conf.he_mu_beamformer || - vif->bss_conf.vht_mu_beamformer || - vif->bss_conf.vht_mu_beamformee; + muru->cfg.mimo_dl_en = link_conf->eht_mu_beamformer || + link_conf->he_mu_beamformer || + link_conf->vht_mu_beamformer || + link_conf->vht_mu_beamformee; muru->cfg.ofdma_dl_en = true; - if (sta->deflink.vht_cap.vht_supported) + if (link_sta->vht_cap.vht_supported) muru->mimo_dl.vht_mu_bfee = - !!(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE); + !!(link_sta->vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE); - if (!sta->deflink.he_cap.has_he) + if (!link_sta->he_cap.has_he) return; muru->mimo_dl.partial_bw_dl_mimo = @@ -1412,49 +1417,50 @@ mt7996_mcu_sta_muru_tlv(struct mt7996_dev *dev, struct sk_buff *skb, } static inline bool -mt7996_is_ebf_supported(struct mt7996_phy *phy, struct ieee80211_vif *vif, - struct ieee80211_sta *sta, bool bfee) +mt7996_is_ebf_supported(struct mt7996_phy *phy, + struct ieee80211_bss_conf *link_conf, + struct ieee80211_link_sta *link_sta, bool bfee) { int sts = hweight16(phy->mt76->chainmask); - if (vif->type != NL80211_IFTYPE_STATION && - vif->type != NL80211_IFTYPE_AP) + if (link_conf->vif->type != NL80211_IFTYPE_STATION && + link_conf->vif->type != NL80211_IFTYPE_AP) return false; if (!bfee && sts < 2) return false; - if (sta->deflink.eht_cap.has_eht) { - struct ieee80211_sta_eht_cap *pc = &sta->deflink.eht_cap; + if (link_sta->eht_cap.has_eht) { + struct ieee80211_sta_eht_cap *pc = &link_sta->eht_cap; struct ieee80211_eht_cap_elem_fixed *pe = &pc->eht_cap_elem; if (bfee) - return vif->bss_conf.eht_su_beamformee && + return link_conf->eht_su_beamformee && EHT_PHY(CAP0_SU_BEAMFORMER, pe->phy_cap_info[0]); else - return vif->bss_conf.eht_su_beamformer && + return link_conf->eht_su_beamformer && EHT_PHY(CAP0_SU_BEAMFORMEE, pe->phy_cap_info[0]); } - if (sta->deflink.he_cap.has_he) { - struct ieee80211_he_cap_elem *pe = &sta->deflink.he_cap.he_cap_elem; + if (link_sta->he_cap.has_he) { + struct ieee80211_he_cap_elem *pe = &link_sta->he_cap.he_cap_elem; if (bfee) - return vif->bss_conf.he_su_beamformee && + return link_conf->he_su_beamformee && HE_PHY(CAP3_SU_BEAMFORMER, pe->phy_cap_info[3]); else - return vif->bss_conf.he_su_beamformer && + return link_conf->he_su_beamformer && HE_PHY(CAP4_SU_BEAMFORMEE, pe->phy_cap_info[4]); } - if (sta->deflink.vht_cap.vht_supported) { - u32 cap = sta->deflink.vht_cap.cap; + if (link_sta->vht_cap.vht_supported) { + u32 cap = link_sta->vht_cap.cap; if (bfee) - return vif->bss_conf.vht_su_beamformee && + return link_conf->vht_su_beamformee && (cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE); else - return vif->bss_conf.vht_su_beamformer && + return link_conf->vht_su_beamformer && (cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE); } @@ -1475,10 +1481,11 @@ mt7996_mcu_sta_sounding_rate(struct sta_rec_bf *bf, struct mt7996_phy *phy) } static void -mt7996_mcu_sta_bfer_ht(struct ieee80211_sta *sta, struct mt7996_phy *phy, - struct sta_rec_bf *bf, bool explicit) +mt7996_mcu_sta_bfer_ht(struct ieee80211_link_sta *link_sta, + struct mt7996_phy *phy, struct sta_rec_bf *bf, + bool explicit) { - struct ieee80211_mcs_info *mcs = &sta->deflink.ht_cap.mcs; + struct ieee80211_mcs_info *mcs = &link_sta->ht_cap.mcs; u8 n = 0; bf->tx_mode = MT_PHY_TYPE_HT; @@ -1501,10 +1508,11 @@ mt7996_mcu_sta_bfer_ht(struct ieee80211_sta *sta, struct mt7996_phy *phy, } static void -mt7996_mcu_sta_bfer_vht(struct ieee80211_sta *sta, struct mt7996_phy *phy, - struct sta_rec_bf *bf, bool explicit) +mt7996_mcu_sta_bfer_vht(struct ieee80211_link_sta *link_sta, + struct mt7996_phy *phy, struct sta_rec_bf *bf, + bool explicit) { - struct ieee80211_sta_vht_cap *pc = &sta->deflink.vht_cap; + struct ieee80211_sta_vht_cap *pc = &link_sta->vht_cap; struct ieee80211_sta_vht_cap *vc = &phy->mt76->sband_5g.sband.vht_cap; u16 mcs_map = le16_to_cpu(pc->vht_mcs.rx_mcs_map); u8 nss_mcs = mt7996_mcu_get_sta_nss(mcs_map); @@ -1525,24 +1533,24 @@ mt7996_mcu_sta_bfer_vht(struct ieee80211_sta *sta, struct mt7996_phy *phy, bf->ncol = min_t(u8, nss_mcs, bf->nrow); bf->ibf_ncol = min_t(u8, MT7996_IBF_MAX_NC, bf->ncol); - if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_160) + if (link_sta->bandwidth == IEEE80211_STA_RX_BW_160) bf->nrow = 1; } else { bf->nrow = tx_ant; bf->ncol = min_t(u8, nss_mcs, bf->nrow); bf->ibf_ncol = min_t(u8, MT7996_IBF_MAX_NC, nss_mcs); - if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_160) + if (link_sta->bandwidth == IEEE80211_STA_RX_BW_160) bf->ibf_nrow = 1; } } static void -mt7996_mcu_sta_bfer_he(struct ieee80211_sta *sta, struct ieee80211_vif *vif, - struct mt7996_phy *phy, struct sta_rec_bf *bf, - bool explicit) +mt7996_mcu_sta_bfer_he(struct ieee80211_link_sta *link_sta, + struct ieee80211_vif *vif, struct mt7996_phy *phy, + struct sta_rec_bf *bf, bool explicit) { - struct ieee80211_sta_he_cap *pc = &sta->deflink.he_cap; + struct ieee80211_sta_he_cap *pc = &link_sta->he_cap; struct ieee80211_he_cap_elem *pe = &pc->he_cap_elem; const struct ieee80211_sta_he_cap *vc = mt76_connac_get_he_phy_cap(phy->mt76, vif); @@ -1571,7 +1579,7 @@ mt7996_mcu_sta_bfer_he(struct ieee80211_sta *sta, struct ieee80211_vif *vif, bf->ibf_ncol = explicit ? min_t(u8, MT7996_IBF_MAX_NC, bf->ncol) : min_t(u8, MT7996_IBF_MAX_NC, nss_mcs); - if (sta->deflink.bandwidth != IEEE80211_STA_RX_BW_160) + if (link_sta->bandwidth != IEEE80211_STA_RX_BW_160) return; /* go over for 160MHz and 80p80 */ @@ -1603,11 +1611,11 @@ mt7996_mcu_sta_bfer_he(struct ieee80211_sta *sta, struct ieee80211_vif *vif, } static void -mt7996_mcu_sta_bfer_eht(struct ieee80211_sta *sta, struct ieee80211_vif *vif, - struct mt7996_phy *phy, struct sta_rec_bf *bf, - bool explicit) +mt7996_mcu_sta_bfer_eht(struct ieee80211_link_sta *link_sta, + struct ieee80211_vif *vif, struct mt7996_phy *phy, + struct sta_rec_bf *bf, bool explicit) { - struct ieee80211_sta_eht_cap *pc = &sta->deflink.eht_cap; + struct ieee80211_sta_eht_cap *pc = &link_sta->eht_cap; struct ieee80211_eht_cap_elem_fixed *pe = &pc->eht_cap_elem; struct ieee80211_eht_mcs_nss_supp *eht_nss = &pc->eht_mcs_nss_supp; const struct ieee80211_sta_eht_cap *vc = @@ -1631,10 +1639,10 @@ mt7996_mcu_sta_bfer_eht(struct ieee80211_sta *sta, struct ieee80211_vif *vif, bf->ibf_ncol = explicit ? min_t(u8, MT7996_IBF_MAX_NC, bf->ncol) : min_t(u8, MT7996_IBF_MAX_NC, nss_mcs); - if (sta->deflink.bandwidth < IEEE80211_STA_RX_BW_160) + if (link_sta->bandwidth < IEEE80211_STA_RX_BW_160) return; - switch (sta->deflink.bandwidth) { + switch (link_sta->bandwidth) { case IEEE80211_STA_RX_BW_160: snd_dim = EHT_PHY(CAP2_SOUNDING_DIM_160MHZ_MASK, ve->phy_cap_info[2]); sts = EHT_PHY(CAP1_BEAMFORMEE_SS_160MHZ_MASK, pe->phy_cap_info[1]); @@ -1662,13 +1670,15 @@ mt7996_mcu_sta_bfer_eht(struct ieee80211_sta *sta, struct ieee80211_vif *vif, static void mt7996_mcu_sta_bfer_tlv(struct mt7996_dev *dev, struct sk_buff *skb, - struct ieee80211_vif *vif, struct ieee80211_sta *sta) + struct ieee80211_bss_conf *link_conf, + struct ieee80211_link_sta *link_sta, + struct mt7996_vif_link *link) { #define EBF_MODE BIT(0) #define IBF_MODE BIT(1) #define BF_MAT_ORDER 4 - struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; - struct mt7996_phy *phy = mvif->deflink.phy; + struct ieee80211_vif *vif = link_conf->vif; + struct mt7996_phy *phy = link->phy; int tx_ant = hweight16(phy->mt76->chainmask) - 1; struct sta_rec_bf *bf; struct tlv *tlv; @@ -1680,10 +1690,10 @@ mt7996_mcu_sta_bfer_tlv(struct mt7996_dev *dev, struct sk_buff *skb, }; bool ebf; - if (!(sta->deflink.ht_cap.ht_supported || sta->deflink.he_cap.has_he)) + if (!(link_sta->ht_cap.ht_supported || link_sta->he_cap.has_he)) return; - ebf = mt7996_is_ebf_supported(phy, vif, sta, false); + ebf = mt7996_is_ebf_supported(phy, link_conf, link_sta, false); if (!ebf && !dev->ibf) return; @@ -1694,28 +1704,29 @@ mt7996_mcu_sta_bfer_tlv(struct mt7996_dev *dev, struct sk_buff *skb, * vht: support eBF and iBF * ht: iBF only, since mac80211 lacks of eBF support */ - if (sta->deflink.eht_cap.has_eht) - mt7996_mcu_sta_bfer_eht(sta, vif, phy, bf, ebf); - else if (sta->deflink.he_cap.has_he) - mt7996_mcu_sta_bfer_he(sta, vif, phy, bf, ebf); - else if (sta->deflink.vht_cap.vht_supported) - mt7996_mcu_sta_bfer_vht(sta, phy, bf, ebf); - else if (sta->deflink.ht_cap.ht_supported) - mt7996_mcu_sta_bfer_ht(sta, phy, bf, ebf); + if (link_sta->eht_cap.has_eht) + mt7996_mcu_sta_bfer_eht(link_sta, vif, link->phy, bf, ebf); + else if (link_sta->he_cap.has_he) + mt7996_mcu_sta_bfer_he(link_sta, vif, link->phy, bf, ebf); + else if (link_sta->vht_cap.vht_supported) + mt7996_mcu_sta_bfer_vht(link_sta, link->phy, bf, ebf); + else if (link_sta->ht_cap.ht_supported) + mt7996_mcu_sta_bfer_ht(link_sta, link->phy, bf, ebf); else return; bf->bf_cap = ebf ? EBF_MODE : (dev->ibf ? IBF_MODE : 0); if (is_mt7992(&dev->mt76) && tx_ant == 4) bf->bf_cap |= IBF_MODE; - bf->bw = sta->deflink.bandwidth; - bf->ibf_dbw = sta->deflink.bandwidth; + + bf->bw = link_sta->bandwidth; + bf->ibf_dbw = link_sta->bandwidth; bf->ibf_nrow = tx_ant; - if (sta->deflink.eht_cap.has_eht || sta->deflink.he_cap.has_he) + if (link_sta->eht_cap.has_eht || link_sta->he_cap.has_he) bf->ibf_timeout = is_mt7996(&dev->mt76) ? MT7996_IBF_TIMEOUT : MT7992_IBF_TIMEOUT; - else if (!ebf && sta->deflink.bandwidth <= IEEE80211_STA_RX_BW_40 && !bf->ncol) + else if (!ebf && link_sta->bandwidth <= IEEE80211_STA_RX_BW_40 && !bf->ncol) bf->ibf_timeout = MT7996_IBF_TIMEOUT_LEGACY; else bf->ibf_timeout = MT7996_IBF_TIMEOUT; @@ -1729,7 +1740,7 @@ mt7996_mcu_sta_bfer_tlv(struct mt7996_dev *dev, struct sk_buff *skb, matrix[bf->nrow][bf->ncol] : 0; } - switch (sta->deflink.bandwidth) { + switch (link_sta->bandwidth) { case IEEE80211_STA_RX_BW_160: case IEEE80211_STA_RX_BW_80: bf->mem_total = bf->mem_20m * 2; @@ -1745,31 +1756,32 @@ mt7996_mcu_sta_bfer_tlv(struct mt7996_dev *dev, struct sk_buff *skb, static void mt7996_mcu_sta_bfee_tlv(struct mt7996_dev *dev, struct sk_buff *skb, - struct ieee80211_vif *vif, struct ieee80211_sta *sta) + struct ieee80211_bss_conf *link_conf, + struct ieee80211_link_sta *link_sta, + struct mt7996_vif_link *link) { - struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; - struct mt7996_phy *phy = mvif->deflink.phy; + struct mt7996_phy *phy = link->phy; int tx_ant = hweight8(phy->mt76->antenna_mask) - 1; struct sta_rec_bfee *bfee; struct tlv *tlv; u8 nrow = 0; - if (!(sta->deflink.vht_cap.vht_supported || sta->deflink.he_cap.has_he)) + if (!(link_sta->vht_cap.vht_supported || link_sta->he_cap.has_he)) return; - if (!mt7996_is_ebf_supported(phy, vif, sta, true)) + if (!mt7996_is_ebf_supported(phy, link_conf, link_sta, true)) return; tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_BFEE, sizeof(*bfee)); bfee = (struct sta_rec_bfee *)tlv; - if (sta->deflink.he_cap.has_he) { - struct ieee80211_he_cap_elem *pe = &sta->deflink.he_cap.he_cap_elem; + if (link_sta->he_cap.has_he) { + struct ieee80211_he_cap_elem *pe = &link_sta->he_cap.he_cap_elem; nrow = HE_PHY(CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK, pe->phy_cap_info[5]); - } else if (sta->deflink.vht_cap.vht_supported) { - struct ieee80211_sta_vht_cap *pc = &sta->deflink.vht_cap; + } else if (link_sta->vht_cap.vht_supported) { + struct ieee80211_sta_vht_cap *pc = &link_sta->vht_cap; nrow = FIELD_GET(IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK, pc->cap); @@ -2131,7 +2143,7 @@ int mt7996_mcu_add_rate_ctrl(struct mt7996_dev *dev, struct ieee80211_vif *vif, * update sta_rec_he here. */ if (changed) - mt7996_mcu_sta_he_tlv(skb, sta); + mt7996_mcu_sta_he_tlv(skb, &sta->deflink, &mvif->deflink); /* sta_rec_ra accommodates BW, NSS and only MCS range format * i.e 0-{7,8,9} for VHT. @@ -2179,67 +2191,67 @@ mt7996_mcu_add_group(struct mt7996_dev *dev, struct ieee80211_vif *vif, sizeof(req), true); } -int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif, - struct mt76_vif_link *mlink, - struct ieee80211_sta *sta, int conn_state, bool newly) +int mt7996_mcu_add_sta(struct mt7996_dev *dev, + struct ieee80211_bss_conf *link_conf, + struct ieee80211_link_sta *link_sta, + struct mt7996_vif_link *link, + struct mt7996_sta_link *msta_link, + int conn_state, bool newly) { - struct ieee80211_link_sta *link_sta = NULL; - struct mt76_wcid *wcid = mlink->wcid; + struct mt76_wcid *wcid = msta_link ? &msta_link->wcid : link->mt76.wcid; + struct ieee80211_sta *sta = link_sta ? link_sta->sta : NULL; struct sk_buff *skb; int ret; - if (sta) { - struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv; - struct mt7996_sta_link *msta_link = &msta->deflink; - - wcid = &msta_link->wcid; - link_sta = &sta->deflink; - } - - skb = __mt76_connac_mcu_alloc_sta_req(&dev->mt76, mlink, wcid, + skb = __mt76_connac_mcu_alloc_sta_req(&dev->mt76, &link->mt76, wcid, MT7996_STA_UPDATE_MAX_SIZE); if (IS_ERR(skb)) return PTR_ERR(skb); /* starec basic */ - mt76_connac_mcu_sta_basic_tlv(&dev->mt76, skb, &vif->bss_conf, link_sta, + mt76_connac_mcu_sta_basic_tlv(&dev->mt76, skb, link_conf, link_sta, conn_state, newly); if (conn_state == CONN_STATE_DISCONNECT) goto out; /* starec hdr trans */ - mt7996_mcu_sta_hdr_trans_tlv(dev, skb, vif, wcid); + mt7996_mcu_sta_hdr_trans_tlv(dev, skb, link_conf->vif, wcid); /* starec tx proc */ mt7996_mcu_sta_tx_proc_tlv(skb); /* tag order is in accordance with firmware dependency. */ - if (sta) { + if (link_sta) { /* starec hdrt mode */ mt7996_mcu_sta_hdrt_tlv(dev, skb); - /* starec bfer */ - mt7996_mcu_sta_bfer_tlv(dev, skb, vif, sta); + if (conn_state == CONN_STATE_CONNECT) { + /* starec bfer */ + mt7996_mcu_sta_bfer_tlv(dev, skb, link_conf, link_sta, + link); + /* starec bfee */ + mt7996_mcu_sta_bfee_tlv(dev, skb, link_conf, link_sta, + link); + } /* starec ht */ - mt7996_mcu_sta_ht_tlv(skb, sta); + mt7996_mcu_sta_ht_tlv(skb, link_sta); /* starec vht */ - mt7996_mcu_sta_vht_tlv(skb, sta); + mt7996_mcu_sta_vht_tlv(skb, link_sta); /* starec uapsd */ - mt76_connac_mcu_sta_uapsd(skb, vif, sta); + mt76_connac_mcu_sta_uapsd(skb, link_conf->vif, sta); /* starec amsdu */ - mt7996_mcu_sta_amsdu_tlv(dev, skb, vif, sta); + mt7996_mcu_sta_amsdu_tlv(dev, skb, link_conf->vif, link_sta, + msta_link); /* starec he */ - mt7996_mcu_sta_he_tlv(skb, sta); + mt7996_mcu_sta_he_tlv(skb, link_sta, link); /* starec he 6g*/ - mt7996_mcu_sta_he_6g_tlv(skb, sta); + mt7996_mcu_sta_he_6g_tlv(skb, link_sta); /* starec eht */ - mt7996_mcu_sta_eht_tlv(skb, sta); + mt7996_mcu_sta_eht_tlv(skb, link_sta); /* starec muru */ - mt7996_mcu_sta_muru_tlv(dev, skb, vif, sta); - /* starec bfee */ - mt7996_mcu_sta_bfee_tlv(dev, skb, vif, sta); + mt7996_mcu_sta_muru_tlv(dev, skb, link_conf, link_sta); } - ret = mt7996_mcu_add_group(dev, vif, sta); + ret = mt7996_mcu_add_group(dev, link_conf->vif, sta); if (ret) { dev_kfree_skb(skb); return ret; diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h index cf37baa91a8ba1cfafb07a4166aed0a0e84968fa..0dd9d798541f95f82bf8606512052eca79115f5c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h @@ -572,9 +572,12 @@ int mt7996_mcu_add_dev_info(struct mt7996_phy *phy, struct ieee80211_vif *vif, int mt7996_mcu_add_bss_info(struct mt7996_phy *phy, struct ieee80211_vif *vif, struct ieee80211_bss_conf *link_conf, struct mt76_vif_link *mlink, int enable); -int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif, - struct mt76_vif_link *mlink, - struct ieee80211_sta *sta, int conn_state, bool newly); +int mt7996_mcu_add_sta(struct mt7996_dev *dev, + struct ieee80211_bss_conf *link_conf, + struct ieee80211_link_sta *link_sta, + struct mt7996_vif_link *link, + struct mt7996_sta_link *msta_link, + int conn_state, bool newly); int mt7996_mcu_add_tx_ba(struct mt7996_dev *dev, struct ieee80211_ampdu_params *params, bool add); From patchwork Tue Mar 11 17:45:12 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 872797 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B81E7262D3E for ; Tue, 11 Mar 2025 17:45:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741715150; cv=none; b=Oab0YfpUqfVLNNu11PGhklfXu9jml9jOrHUt+N8bvKQCGU5GKRoH7mb1rYVMGM5+ZK9fPbyMPV2DQe81q9b3R85J5CPllfFoNiT1tCU1s0haBKLw3ct336+Xs0kPlBsqw5m9MUrOw4W4ZxgiOQXUtgTdkktSEFM35nqvcAtH2VA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741715150; c=relaxed/simple; bh=JIhU6JAVFL/APQj30jcuDhgBR6k5qvCBmItYlZMcFKk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=GUHS8YuNh4dJ03abv63J8RnBDY2SOLrwLxL3uBpdcTWDEGxVhEnOe43aTcr/t46j9fn7zWeJfdZcLHYayQTDB2lt9uQy6E1hP46BzS2IO63x8807scAmK2Bi0AVN3LV2OFa10OOWsA8Z33QcRS1r1lWBv3muNrXj6aL24BjhcU8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=HYcGBZpQ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="HYcGBZpQ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 43210C4CEEA; Tue, 11 Mar 2025 17:45:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1741715150; bh=JIhU6JAVFL/APQj30jcuDhgBR6k5qvCBmItYlZMcFKk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=HYcGBZpQ8Wjl+SydLan7w9Kx9t/CN5dObhPKM4VAT69WmSPv8Q4Zhl7Pgu70SHEmZ RuIiIQNLHpEFiJmyBjvi7DJ9/lo2PHdKqd22cW9KHn+wNjpIWMk7STjhrRKzzuvNqX 7sXobGglfDYN9uoEX/VXXhiqAV3o/PIrj3cc5Xw6qjv2VQ9J6ZP3c1LQ3PZTeJ9/A8 RlAKWIIEp/enJdRSGr+d+KK21ft1LJWXPUeVlbU8vbk5Px/5hFbr2lavrYn6qXDas+ yztZGR2IBYcaYQU/bwYuQJ47pVSMQ7DRpb57jN2IgObsVJV5A46+iMD2nsjSk716EI Qcj4p59QLnu6Q== From: Lorenzo Bianconi Date: Tue, 11 Mar 2025 18:45:12 +0100 Subject: [PATCH v2 13/13] wifi: mt76: mt7996: Rely on mt7996_vif_link and mt7996_sta_link in mt7996_mac_twt_teardown_flow signature Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250311-mt7996-mlo-v2-13-31df6972519b@kernel.org> References: <20250311-mt7996-mlo-v2-0-31df6972519b@kernel.org> In-Reply-To: <20250311-mt7996-mlo-v2-0-31df6972519b@kernel.org> To: Felix Fietkau , Ryder Lee , Shayne Chen , Sean Wang , Kalle Valo , Matthias Brugger , AngeloGioacchino Del Regno , Lorenzo Bianconi , Johannes Berg Cc: linux-wireless@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org X-Mailer: b4 0.14.2 This is a preliminary patch to enable MLO for MT7996 driver Signed-off-by: Lorenzo Bianconi --- drivers/net/wireless/mediatek/mt76/mt7996/mac.c | 7 +++---- drivers/net/wireless/mediatek/mt76/mt7996/main.c | 7 +++++-- drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h | 3 ++- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c index 4a7f6fd9025297f0ffa8ea7e91efd34164a26196..7ddd4b0cadf5d1983379a93ba56da461748ca60e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c @@ -2691,10 +2691,10 @@ void mt7996_mac_add_twt_setup(struct ieee80211_hw *hw, } void mt7996_mac_twt_teardown_flow(struct mt7996_dev *dev, - struct mt7996_sta *msta, + struct mt7996_vif_link *link, + struct mt7996_sta_link *msta_link, u8 flowid) { - struct mt7996_sta_link *msta_link = &msta->deflink; struct mt7996_twt_flow *flow; lockdep_assert_held(&dev->mt76.mutex); @@ -2706,8 +2706,7 @@ void mt7996_mac_twt_teardown_flow(struct mt7996_dev *dev, return; flow = &msta_link->twt.flow[flowid]; - if (mt7996_mcu_twt_agrt_update(dev, &msta->vif->deflink, flow, - MCU_TWT_AGRT_DELETE)) + if (mt7996_mcu_twt_agrt_update(dev, link, flow, MCU_TWT_AGRT_DELETE)) return; list_del_init(&flow->list); diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c index 5ab4f08dba06fdf95ee4e6bc0261749016f07e6a..11ad95e05b94857c95375cdf877518e7ee89f08e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c @@ -1062,7 +1062,8 @@ mt7996_mac_sta_event(struct mt7996_dev *dev, struct ieee80211_vif *vif, break; case MT76_STA_EVENT_DISASSOC: for (i = 0; i < ARRAY_SIZE(msta_link->twt.flow); i++) - mt7996_mac_twt_teardown_flow(dev, msta, i); + mt7996_mac_twt_teardown_flow(dev, link, + msta_link, i); mt7996_mcu_add_sta(dev, link_conf, link_sta, link, msta_link, CONN_STATE_DISCONNECT, @@ -1804,10 +1805,12 @@ mt7996_twt_teardown_request(struct ieee80211_hw *hw, u8 flowid) { struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv; + struct mt7996_sta_link *msta_link = &msta->deflink; + struct mt7996_vif_link *link = &msta->vif->deflink; struct mt7996_dev *dev = mt7996_hw_dev(hw); mutex_lock(&dev->mt76.mutex); - mt7996_mac_twt_teardown_flow(dev, msta, flowid); + mt7996_mac_twt_teardown_flow(dev, link, msta_link, flowid); mutex_unlock(&dev->mt76.mutex); } diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h index 962022c7eec9fd82ebba8e0d5aa6b6eae769ee32..84b9ff707d56501d212932a9fa6a3037259a1077 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h @@ -709,7 +709,8 @@ void mt7996_mac_dump_work(struct work_struct *work); void mt7996_mac_sta_rc_work(struct work_struct *work); void mt7996_mac_update_stats(struct mt7996_phy *phy); void mt7996_mac_twt_teardown_flow(struct mt7996_dev *dev, - struct mt7996_sta *msta, + struct mt7996_vif_link *link, + struct mt7996_sta_link *msta_link, u8 flowid); void mt7996_mac_add_twt_setup(struct ieee80211_hw *hw, struct ieee80211_sta *sta,