All of lore.kernel.org
 help / color / mirror / Atom feed
From: "lorenzo@kernel.org" <lorenzo@kernel.org>
To: Ryder Lee <Ryder.Lee@mediatek.com>
Cc: "lorenzo.bianconi@redhat.com" <lorenzo.bianconi@redhat.com>,
	"linux-wireless@vger.kernel.org" <linux-wireless@vger.kernel.org>,
	"nbd@nbd.name" <nbd@nbd.name>, Deren Wu <deren.wu@mediatek.com>
Subject: Re: [PATCH v2 15/15] wifi: mt76: connac: add connac3 mac library
Date: Fri, 9 Jun 2023 18:45:12 +0200	[thread overview]
Message-ID: <ZINXGP6TmDLaZ+lu@localhost.localdomain> (raw)
In-Reply-To: <82971c76999ae90be44a524fb95141c5051a9ba0.camel@mediatek.com>

[-- Attachment #1: Type: text/plain, Size: 33683 bytes --]

> On Fri, 2023-06-09 at 18:34 +0200, lorenzo.bianconi@redhat.com wrote:
> > On Jun 09, Ryder Lee wrote:
> > > On Fri, 2023-06-09 at 10:15 +0200, Lorenzo Bianconi wrote:
> > > >  	 
> > > > External email : Please do not click links or open attachments
> > > > until
> > > > you have verified the sender or the content.
> > > >  Introduce connac3_mac in mt76_connac library to reuse mac code
> > > > shared
> > > > between WiFi7 chipsets.
> > > > 
> > > > Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> > > > ---
> > > >  drivers/net/wireless/mediatek/mt76/Makefile   |   2 +-
> > > >  .../net/wireless/mediatek/mt76/mt76_connac.h  |  19 +
> > > >  .../wireless/mediatek/mt76/mt76_connac3_mac.c | 742
> > > > +++++++++++++++++
> > > >  .../wireless/mediatek/mt76/mt76_connac3_mac.h |  18 +
> > > >  .../net/wireless/mediatek/mt76/mt7996/init.c  |   4 +-
> > > >  .../net/wireless/mediatek/mt76/mt7996/mac.c   | 761 +-----------
> > > > ----
> > > > --
> > > >  .../net/wireless/mediatek/mt76/mt7996/main.c  |   8 +-
> > > >  .../net/wireless/mediatek/mt76/mt7996/mcu.c   |   9 +-
> > > >  .../wireless/mediatek/mt76/mt7996/mt7996.h    |  28 +-
> > > >  9 files changed, 807 insertions(+), 784 deletions(-)
> > > >  create mode 100644
> > > > drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c
> > > > 
> > > > diff --git a/drivers/net/wireless/mediatek/mt76/Makefile
> > > > b/drivers/net/wireless/mediatek/mt76/Makefile
> > > > index 84c99b7e57f9..d8e8079c8b54 100644
> > > > --- a/drivers/net/wireless/mediatek/mt76/Makefile
> > > > +++ b/drivers/net/wireless/mediatek/mt76/Makefile
> > > > @@ -27,7 +27,7 @@ mt76x02-lib-y := mt76x02_util.o mt76x02_mac.o
> > > > mt76x02_mcu.o \
> > > >  
> > > >  mt76x02-usb-y := mt76x02_usb_mcu.o mt76x02_usb_core.o
> > > >  
> > > > -mt76-connac-lib-y := mt76_connac_mcu.o mt76_connac_mac.o
> > > > +mt76-connac-lib-y := mt76_connac_mcu.o mt76_connac_mac.o
> > > > mt76_connac3_mac.o
> > > >  
> > > >  obj-$(CONFIG_MT76x0_COMMON) += mt76x0/
> > > >  obj-$(CONFIG_MT76x2_COMMON) += mt76x2/
> > > > diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac.h
> > > > b/drivers/net/wireless/mediatek/mt76/mt76_connac.h
> > > > index 68bdeada1421..20111678537b 100644
> > > > --- a/drivers/net/wireless/mediatek/mt76/mt76_connac.h
> > > > +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac.h
> > > > @@ -415,4 +415,23 @@ void mt76_connac2_txwi_free(struct mt76_dev
> > > > *dev, struct mt76_txwi_cache *t,
> > > >  			    struct list_head *free_list);
> > > >  void mt76_connac2_tx_token_put(struct mt76_dev *dev);
> > > >  
> > > > +/* connac3 */
> > > > +void mt76_connac3_tx_check_aggr(struct ieee80211_sta *sta,
> > > > __le32
> > > > *txwi);
> > > > +void mt76_connac3_mac_decode_he_radiotap(struct sk_buff *skb,
> > > > __le32
> > > > *rxv,
> > > > +					 u8 mode);
> > > > +int mt76_connac3_mac_fill_rx_rate(struct mt76_dev *dev,
> > > > +				  struct mt76_rx_status *status,
> > > > +				  struct ieee80211_supported_band
> > > > *sband,
> > > > +				  __le32 *rxv, u8 *mode);
> > > > +void mt76_connac3_mac_write_txwi(struct mt76_dev *dev, __le32
> > > > *txwi,
> > > > +				 struct sk_buff *skb, struct mt76_wcid
> > > > *wcid,
> > > > +				 struct ieee80211_key_conf *key, int
> > > > pid,
> > > > +				 enum mt76_txq_id qid, u32 changed);
> > > > +void mt76_connac3_txwi_free(struct mt76_dev *dev, struct
> > > > mt76_txwi_cache *t,
> > > > +			    struct ieee80211_sta *sta,
> > > > +			    struct list_head *free_list);
> > > > +void mt76_connac3_mac_add_txs(struct mt76_dev *dev, void *data,
> > > > +			      u32 max_wtbl_size);
> > > > +void mt76_connac3_tx_token_put(struct mt76_dev *dev);
> > > > +
> > > >  #endif /* __MT76_CONNAC_H */
> > > > diff --git
> > > > a/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c
> > > > b/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c
> > > > new file mode 100644
> > > > index 000000000000..4b745bb74ca0
> > > > --- /dev/null
> > > > +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c
> > > > @@ -0,0 +1,742 @@
> > > > +// SPDX-License-Identifier: ISC
> > > > +/* Copyright (C) 2023 MediaTek Inc. */
> > > > +
> > > > +#include "mt76_connac.h"
> > > > +#include "mt76_connac3_mac.h"
> > > > +#include "dma.h"
> > > > +
> > > > +#define HE_BITS(f)		cpu_to_le16(IEEE80211_RADIOTAP_
> > > > HE_##f)
> > > > +#define HE_PREP(f, m, v)	le16_encode_bits(le32_get_bits(v,
> > > > MT_CRXV_HE_##m),\
> > > > +						 IEEE80211_RADIOTAP_HE_
> > > > ##f)
> > > > +
> > > > +void mt76_connac3_tx_check_aggr(struct ieee80211_sta *sta,
> > > > __le32
> > > > *txwi)
> > > > +{
> > > > +	struct mt76_wcid *wcid;
> > > > +	u16 fc, tid;
> > > > +	u32 val;
> > > > +
> > > > +	if (!sta ||
> > > > +	    !(sta->deflink.ht_cap.ht_supported || sta-
> > > > > deflink.he_cap.has_he))
> > > > 
> > > > +		return;
> > > > +
> > > > +	tid = le32_get_bits(txwi[1], MT_TXD1_TID);
> > > > +	if (tid >= 6) /* skip VO queue */
> > > > +		return;
> > > > +
> > > > +	val = le32_to_cpu(txwi[2]);
> > > > +	fc = FIELD_GET(MT_TXD2_FRAME_TYPE, val) << 2 |
> > > > +	     FIELD_GET(MT_TXD2_SUB_TYPE, val) << 4;
> > > > +	if (unlikely(fc != (IEEE80211_FTYPE_DATA |
> > > > IEEE80211_STYPE_QOS_DATA)))
> > > > +		return;
> > > > +
> > > > +	wcid = (struct mt76_wcid *)sta->drv_priv;
> > > > +	if (!test_and_set_bit(tid, &wcid->ampdu_state))
> > > > +		ieee80211_start_tx_ba_session(sta, tid, 0);
> > > > +}
> > > > +EXPORT_SYMBOL_GPL(mt76_connac3_tx_check_aggr);
> > > > +
> > > > +static void
> > > > +mt76_connac3_mac_decode_he_radiotap_ru(struct mt76_rx_status
> > > > *status,
> > > > +				       struct ieee80211_radiotap_he
> > > > *he,
> > > > +				       __le32 *rxv)
> > > > +{
> > > > +	u32 ru = le32_get_bits(rxv[0], MT_PRXV_HE_RU_ALLOC), offs = 0;
> > > > +
> > > > +	status->bw = RATE_INFO_BW_HE_RU;
> > > > +
> > > > +	switch (ru) {
> > > > +	case 0 ... 36:
> > > > +		status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_26;
> > > > +		offs = ru;
> > > > +		break;
> > > > +	case 37 ... 52:
> > > > +		status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_52;
> > > > +		offs = ru - 37;
> > > > +		break;
> > > > +	case 53 ... 60:
> > > > +		status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_106;
> > > > +		offs = ru - 53;
> > > > +		break;
> > > > +	case 61 ... 64:
> > > > +		status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_242;
> > > > +		offs = ru - 61;
> > > > +		break;
> > > > +	case 65 ... 66:
> > > > +		status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_484;
> > > > +		offs = ru - 65;
> > > > +		break;
> > > > +	case 67:
> > > > +		status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_996;
> > > > +		break;
> > > > +	case 68:
> > > > +		status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_2x996;
> > > > +		break;
> > > > +	}
> > > > +
> > > > +	he->data1 |= HE_BITS(DATA1_BW_RU_ALLOC_KNOWN);
> > > > +	he->data2 |= HE_BITS(DATA2_RU_OFFSET_KNOWN) |
> > > > +		     le16_encode_bits(offs,
> > > > +				      IEEE80211_RADIOTAP_HE_DATA2_RU_OF
> > > > FSET);
> > > > +}
> > > > +
> > > > +#define MU_PREP(f, v)	le16_encode_bits(v,
> > > > IEEE80211_RADIOTAP_HE_MU_##f)
> > > > +static void
> > > > +mt76_connac3_mac_decode_he_mu_radiotap(struct sk_buff *skb,
> > > > __le32
> > > > *rxv)
> > > > +{
> > > > +	struct mt76_rx_status *status = (struct mt76_rx_status *)skb-
> > > > > cb;
> > > > 
> > > > +	static const struct ieee80211_radiotap_he_mu mu_known = {
> > > > +		.flags1 = HE_BITS(MU_FLAGS1_SIG_B_MCS_KNOWN) |
> > > > +			  HE_BITS(MU_FLAGS1_SIG_B_DCM_KNOWN) |
> > > > +			  HE_BITS(MU_FLAGS1_CH1_RU_KNOWN) |
> > > > +			  HE_BITS(MU_FLAGS1_SIG_B_SYMS_USERS_KNOWN),
> > > > +		.flags2 = HE_BITS(MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN),
> > > > +	};
> > > > +	struct ieee80211_radiotap_he_mu *he_mu;
> > > > +
> > > > +	status->flag |= RX_FLAG_RADIOTAP_HE_MU;
> > > > +
> > > > +	he_mu = skb_push(skb, sizeof(mu_known));
> > > > +	memcpy(he_mu, &mu_known, sizeof(mu_known));
> > > > +
> > > > +	he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_MCS, status->rate_idx);
> > > > +	if (status->he_dcm)
> > > > +		he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_DCM, status-
> > > > > he_dcm);
> > > > 
> > > > +
> > > > +	he_mu->flags2 |= MU_PREP(FLAGS2_BW_FROM_SIG_A_BW, status->bw) |
> > > > +			 MU_PREP(FLAGS2_SIG_B_SYMS_USERS,
> > > > +				 le32_get_bits(rxv[4],
> > > > MT_CRXV_HE_NUM_USER));
> > > > +
> > > > +	he_mu->ru_ch1[0] = le32_get_bits(rxv[16], MT_CRXV_HE_RU0) &
> > > > 0xff;
> > > > +
> > > > +	if (status->bw >= RATE_INFO_BW_40) {
> > > > +		he_mu->flags1 |= HE_BITS(MU_FLAGS1_CH2_RU_KNOWN);
> > > > +		he_mu->ru_ch2[0] = le32_get_bits(rxv[16],
> > > > MT_CRXV_HE_RU1) & 0xff;
> > > > +	}
> > > > +
> > > > +	if (status->bw >= RATE_INFO_BW_80) {
> > > > +		u32 ru_h, ru_l;
> > > > +
> > > > +		he_mu->ru_ch1[1] = le32_get_bits(rxv[16],
> > > > MT_CRXV_HE_RU2) & 0xff;
> > > > +
> > > > +		ru_l = le32_get_bits(rxv[16], MT_CRXV_HE_RU3_L);
> > > > +		ru_h = le32_get_bits(rxv[17], MT_CRXV_HE_RU3_H) & 0x7;
> > > > +		he_mu->ru_ch2[1] = (u8)(ru_l | ru_h << 4);
> > > > +	}
> > > > +}
> > > > +
> > > > +void mt76_connac3_mac_decode_he_radiotap(struct sk_buff *skb,
> > > > __le32
> > > > *rxv,
> > > > +					 u8 mode)
> > > > +{
> > > > +	struct mt76_rx_status *status = (struct mt76_rx_status *)skb-
> > > > > cb;
> > > > 
> > > > +	static const struct ieee80211_radiotap_he known = {
> > > > +		.data1 = HE_BITS(DATA1_DATA_MCS_KNOWN) |
> > > > +			 HE_BITS(DATA1_DATA_DCM_KNOWN) |
> > > > +			 HE_BITS(DATA1_STBC_KNOWN) |
> > > > +			 HE_BITS(DATA1_CODING_KNOWN) |
> > > > +			 HE_BITS(DATA1_LDPC_XSYMSEG_KNOWN) |
> > > > +			 HE_BITS(DATA1_DOPPLER_KNOWN) |
> > > > +			 HE_BITS(DATA1_SPTL_REUSE_KNOWN) |
> > > > +			 HE_BITS(DATA1_BSS_COLOR_KNOWN),
> > > > +		.data2 = HE_BITS(DATA2_GI_KNOWN) |
> > > > +			 HE_BITS(DATA2_TXBF_KNOWN) |
> > > > +			 HE_BITS(DATA2_PE_DISAMBIG_KNOWN) |
> > > > +			 HE_BITS(DATA2_TXOP_KNOWN),
> > > > +	};
> > > > +	u32 ltf_size = le32_get_bits(rxv[4], MT_CRXV_HE_LTF_SIZE) + 1;
> > > > +	struct ieee80211_radiotap_he *he;
> > > > +
> > > > +	status->flag |= RX_FLAG_RADIOTAP_HE;
> > > > +
> > > > +	he = skb_push(skb, sizeof(known));
> > > > +	memcpy(he, &known, sizeof(known));
> > > > +
> > > > +	he->data3 = HE_PREP(DATA3_BSS_COLOR, BSS_COLOR, rxv[9]) |
> > > > +		    HE_PREP(DATA3_LDPC_XSYMSEG, LDPC_EXT_SYM, rxv[4]);
> > > > +	he->data4 = HE_PREP(DATA4_SU_MU_SPTL_REUSE, SR_MASK, rxv[13]);
> > > > +	he->data5 = HE_PREP(DATA5_PE_DISAMBIG, PE_DISAMBIG, rxv[5]) |
> > > > +		    le16_encode_bits(ltf_size,
> > > > +				     IEEE80211_RADIOTAP_HE_DATA5_LTF_SI
> > > > ZE);
> > > > +	if (le32_to_cpu(rxv[0]) & MT_PRXV_TXBF)
> > > > +		he->data5 |= HE_BITS(DATA5_TXBF);
> > > > +	he->data6 = HE_PREP(DATA6_TXOP, TXOP_DUR, rxv[9]) |
> > > > +		    HE_PREP(DATA6_DOPPLER, DOPPLER, rxv[9]);
> > > > +
> > > > +	switch (mode) {
> > > > +	case MT_PHY_TYPE_HE_SU:
> > > > +		he->data1 |= HE_BITS(DATA1_FORMAT_SU) |
> > > > +			     HE_BITS(DATA1_UL_DL_KNOWN) |
> > > > +			     HE_BITS(DATA1_BEAM_CHANGE_KNOWN) |
> > > > +			     HE_BITS(DATA1_BW_RU_ALLOC_KNOWN);
> > > > +
> > > > +		he->data3 |= HE_PREP(DATA3_BEAM_CHANGE, BEAM_CHNG,
> > > > rxv[8]) |
> > > > +			     HE_PREP(DATA3_UL_DL, UPLINK, rxv[5]);
> > > > +		break;
> > > > +	case MT_PHY_TYPE_HE_EXT_SU:
> > > > +		he->data1 |= HE_BITS(DATA1_FORMAT_EXT_SU) |
> > > > +			     HE_BITS(DATA1_UL_DL_KNOWN) |
> > > > +			     HE_BITS(DATA1_BW_RU_ALLOC_KNOWN);
> > > > +
> > > > +		he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK, rxv[5]);
> > > > +		break;
> > > > +	case MT_PHY_TYPE_HE_MU:
> > > > +		he->data1 |= HE_BITS(DATA1_FORMAT_MU) |
> > > > +			     HE_BITS(DATA1_UL_DL_KNOWN);
> > > > +
> > > > +		he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK, rxv[5]);
> > > > +		he->data4 |= HE_PREP(DATA4_MU_STA_ID, MU_AID, rxv[8]);
> > > > +
> > > > +		mt76_connac3_mac_decode_he_radiotap_ru(status, he,
> > > > rxv);
> > > > +		mt76_connac3_mac_decode_he_mu_radiotap(skb, rxv);
> > > > +		break;
> > > > +	case MT_PHY_TYPE_HE_TB:
> > > > +		he->data1 |= HE_BITS(DATA1_FORMAT_TRIG) |
> > > > +			     HE_BITS(DATA1_SPTL_REUSE2_KNOWN) |
> > > > +			     HE_BITS(DATA1_SPTL_REUSE3_KNOWN) |
> > > > +			     HE_BITS(DATA1_SPTL_REUSE4_KNOWN);
> > > > +
> > > > +		he->data4 |= HE_PREP(DATA4_TB_SPTL_REUSE1, SR_MASK,
> > > > rxv[13]) |
> > > > +			     HE_PREP(DATA4_TB_SPTL_REUSE2, SR1_MASK,
> > > > rxv[13]) |
> > > > +			     HE_PREP(DATA4_TB_SPTL_REUSE3, SR2_MASK,
> > > > rxv[13]) |
> > > > +			     HE_PREP(DATA4_TB_SPTL_REUSE4, SR3_MASK,
> > > > rxv[13]);
> > > > +
> > > > +		mt76_connac3_mac_decode_he_radiotap_ru(status, he,
> > > > rxv);
> > > > +		break;
> > > > +	default:
> > > > +		break;
> > > > +	}
> > > > +}
> > > > +EXPORT_SYMBOL_GPL(mt76_connac3_mac_decode_he_radiotap);
> > > > +
> > > > +int mt76_connac3_mac_fill_rx_rate(struct mt76_dev *dev,
> > > > +				  struct mt76_rx_status *status,
> > > > +				  struct ieee80211_supported_band
> > > > *sband,
> > > > +				  __le32 *rxv, u8 *mode)
> > > > +{
> > > > +	u8 stbc, gi, bw, dcm, nss;
> > > > +	bool cck = false;
> > > > +	u32 v0, v2;
> > > > +	int i, idx;
> > > > +
> > > > +	v0 = le32_to_cpu(rxv[0]);
> > > > +	v2 = le32_to_cpu(rxv[2]);
> > > > +
> > > > +	idx = FIELD_GET(MT_PRXV_TX_RATE, v0);
> > > > +	i = idx;
> > > > +	nss = FIELD_GET(MT_PRXV_NSTS, v0) + 1;
> > > > +
> > > > +	stbc = FIELD_GET(MT_PRXV_HT_STBC, v2);
> > > > +	gi = FIELD_GET(MT_PRXV_HT_SHORT_GI, v2);
> > > > +	*mode = FIELD_GET(MT_PRXV_TX_MODE, v2);
> > > > +	dcm = FIELD_GET(MT_PRXV_DCM, v2);
> > > > +	bw = FIELD_GET(MT_PRXV_FRAME_MODE, v2);
> > > > +
> > > > +	switch (*mode) {
> > > > +	case MT_PHY_TYPE_CCK:
> > > > +		cck = true;
> > > > +		fallthrough;
> > > > +	case MT_PHY_TYPE_OFDM:
> > > > +		i = mt76_get_rate(dev, sband, i, cck);
> > > > +		break;
> > > > +	case MT_PHY_TYPE_HT_GF:
> > > > +	case MT_PHY_TYPE_HT:
> > > > +		status->encoding = RX_ENC_HT;
> > > > +		if (gi)
> > > > +			status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
> > > > +		if (i > 31)
> > > > +			return -EINVAL;
> > > > +		break;
> > > > +	case MT_PHY_TYPE_VHT:
> > > > +		status->nss = nss;
> > > > +		status->encoding = RX_ENC_VHT;
> > > > +		if (gi)
> > > > +			status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
> > > > +		if (i > 11)
> > > > +			return -EINVAL;
> > > > +		break;
> > > > +	case MT_PHY_TYPE_HE_MU:
> > > > +	case MT_PHY_TYPE_HE_SU:
> > > > +	case MT_PHY_TYPE_HE_EXT_SU:
> > > > +	case MT_PHY_TYPE_HE_TB:
> > > > +		status->nss = nss;
> > > > +		status->encoding = RX_ENC_HE;
> > > > +		i &= GENMASK(3, 0);
> > > > +
> > > > +		if (gi <= NL80211_RATE_INFO_HE_GI_3_2)
> > > > +			status->he_gi = gi;
> > > > +
> > > > +		status->he_dcm = dcm;
> > > > +		break;
> > > > +	case MT_PHY_TYPE_EHT_SU:
> > > > +	case MT_PHY_TYPE_EHT_TRIG:
> > > > +	case MT_PHY_TYPE_EHT_MU:
> > > > +		status->nss = nss;
> > > > +		status->encoding = RX_ENC_EHT;
> > > > +		i &= GENMASK(3, 0);
> > > > +
> > > > +		if (gi <= NL80211_RATE_INFO_EHT_GI_3_2)
> > > > +			status->eht.gi = gi;
> > > > +		break;
> > > > +	default:
> > > > +		return -EINVAL;
> > > > +	}
> > > > +	status->rate_idx = i;
> > > > +
> > > > +	switch (bw) {
> > > > +	case IEEE80211_STA_RX_BW_20:
> > > > +		break;
> > > > +	case IEEE80211_STA_RX_BW_40:
> > > > +		if (*mode & MT_PHY_TYPE_HE_EXT_SU &&
> > > > +		    (idx & MT_PRXV_TX_ER_SU_106T)) {
> > > > +			status->bw = RATE_INFO_BW_HE_RU;
> > > > +			status->he_ru =
> > > > +				NL80211_RATE_INFO_HE_RU_ALLOC_106;
> > > > +		} else {
> > > > +			status->bw = RATE_INFO_BW_40;
> > > > +		}
> > > > +		break;
> > > > +	case IEEE80211_STA_RX_BW_80:
> > > > +		status->bw = RATE_INFO_BW_80;
> > > > +		break;
> > > > +	case IEEE80211_STA_RX_BW_160:
> > > > +		status->bw = RATE_INFO_BW_160;
> > > > +		break;
> > > > +	case IEEE80211_STA_RX_BW_320:
> > > > +		status->bw = RATE_INFO_BW_320;
> > > > +		break;
> > > > +	default:
> > > > +		return -EINVAL;
> > > > +	}
> > > > +
> > > > +	status->enc_flags |= RX_ENC_FLAG_STBC_MASK * stbc;
> > > > +	if (*mode < MT_PHY_TYPE_HE_SU && gi)
> > > > +		status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
> > > > +
> > > > +	return 0;
> > > > +}
> > > > +EXPORT_SYMBOL_GPL(mt76_connac3_mac_fill_rx_rate);
> > > > +
> > > > +static void
> > > > +mt76_connac3_mac_write_txwi_8023(__le32 *txwi, struct sk_buff
> > > > *skb,
> > > > +				 struct mt76_wcid *wcid)
> > > > +{
> > > > +	u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
> > > > +	u8 fc_type, fc_stype;
> > > > +	u16 ethertype;
> > > > +	bool wmm = false;
> > > > +	u32 val;
> > > > +
> > > > +	if (wcid->sta) {
> > > > +		struct ieee80211_sta *sta;
> > > > +
> > > > +		sta = container_of((void *)wcid, struct ieee80211_sta,
> > > > drv_priv);
> > > > +		wmm = sta->wme;
> > > > +	}
> > > > +
> > > > +	val = FIELD_PREP(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_802_3) |
> > > > +	      FIELD_PREP(MT_TXD1_TID, tid);
> > > > +
> > > > +	ethertype = get_unaligned_be16(&skb->data[12]);
> > > > +	if (ethertype >= ETH_P_802_3_MIN)
> > > > +		val |= MT_TXD1_ETH_802_3;
> > > > +
> > > > +	txwi[1] |= cpu_to_le32(val);
> > > > +
> > > > +	fc_type = IEEE80211_FTYPE_DATA >> 2;
> > > > +	fc_stype = wmm ? IEEE80211_STYPE_QOS_DATA >> 4 : 0;
> > > > +
> > > > +	val = FIELD_PREP(MT_TXD2_FRAME_TYPE, fc_type) |
> > > > +	      FIELD_PREP(MT_TXD2_SUB_TYPE, fc_stype);
> > > > +
> > > > +	txwi[2] |= cpu_to_le32(val);
> > > > +}
> > > > +
> > > > +static void
> > > > +mt76_connac3_mac_write_txwi_80211(struct mt76_dev *dev, __le32
> > > > *txwi,
> > > > +				  struct sk_buff *skb,
> > > > +				  struct ieee80211_key_conf *key)
> > > > +{
> > > > +	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
> > > > +	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb-
> > > > > data;
> > > > 
> > > > +	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
> > > > +	bool multicast = is_multicast_ether_addr(hdr->addr1);
> > > > +	u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
> > > > +	__le16 fc = hdr->frame_control;
> > > > +	u8 fc_type, fc_stype;
> > > > +	u32 val;
> > > > +
> > > > +	if (ieee80211_is_action(fc) &&
> > > > +	    mgmt->u.action.category == WLAN_CATEGORY_BACK &&
> > > > +	    mgmt->u.action.u.addba_req.action_code ==
> > > > WLAN_ACTION_ADDBA_REQ)
> > > > +		tid = MT_TX_ADDBA;
> > > > +	else if (ieee80211_is_mgmt(hdr->frame_control))
> > > > +		tid = MT_TX_NORMAL;
> > > > +
> > > > +	val = FIELD_PREP(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_802_11) |
> > > > +	      FIELD_PREP(MT_TXD1_HDR_INFO,
> > > > +			 ieee80211_get_hdrlen_from_skb(skb) / 2) |
> > > > +	      FIELD_PREP(MT_TXD1_TID, tid);
> > > > +
> > > > +	if (!ieee80211_is_data(fc) || multicast ||
> > > > +	    info->flags & IEEE80211_TX_CTL_USE_MINRATE)
> > > > +		val |= MT_TXD1_FIXED_RATE;
> > > > +
> > > > +	if (key && multicast && ieee80211_is_robust_mgmt_frame(skb) &&
> > > > +	    key->cipher == WLAN_CIPHER_SUITE_AES_CMAC) {
> > > > +		val |= MT_TXD1_BIP;
> > > > +		txwi[3] &= ~cpu_to_le32(MT_TXD3_PROTECT_FRAME);
> > > > +	}
> > > > +
> > > > +	txwi[1] |= cpu_to_le32(val);
> > > > +
> > > > +	fc_type = (le16_to_cpu(fc) & IEEE80211_FCTL_FTYPE) >> 2;
> > > > +	fc_stype = (le16_to_cpu(fc) & IEEE80211_FCTL_STYPE) >> 4;
> > > > +
> > > > +	val = FIELD_PREP(MT_TXD2_FRAME_TYPE, fc_type) |
> > > > +	      FIELD_PREP(MT_TXD2_SUB_TYPE, fc_stype);
> > > > +
> > > > +	txwi[2] |= cpu_to_le32(val);
> > > > +
> > > > +	txwi[3] |= cpu_to_le32(FIELD_PREP(MT_TXD3_BCM, multicast));
> > > > +	if (ieee80211_is_beacon(fc)) {
> > > > +		txwi[3] &= ~cpu_to_le32(MT_TXD3_SW_POWER_MGMT);
> > > > +		txwi[3] |= cpu_to_le32(MT_TXD3_REM_TX_COUNT);
> > > > +	}
> > > > +
> > > > +	if (info->flags & IEEE80211_TX_CTL_INJECTED) {
> > > > +		u16 seqno = le16_to_cpu(hdr->seq_ctrl);
> > > > +
> > > > +		if (ieee80211_is_back_req(hdr->frame_control)) {
> > > > +			struct ieee80211_bar *bar;
> > > > +
> > > > +			bar = (struct ieee80211_bar *)skb->data;
> > > > +			seqno = le16_to_cpu(bar->start_seq_num);
> > > > +		}
> > > > +
> > > > +		val = MT_TXD3_SN_VALID |
> > > > +		      FIELD_PREP(MT_TXD3_SEQ,
> > > > IEEE80211_SEQ_TO_SN(seqno));
> > > > +		txwi[3] |= cpu_to_le32(val);
> > > > +		txwi[3] &= ~cpu_to_le32(MT_TXD3_HW_AMSDU);
> > > > +	}
> > > > +}
> > > > +
> > > > +void mt76_connac3_mac_write_txwi(struct mt76_dev *dev, __le32
> > > > *txwi,
> > > > +				 struct sk_buff *skb, struct mt76_wcid
> > > > *wcid,
> > > > +				 struct ieee80211_key_conf *key, int
> > > > pid,
> > > > +				 enum mt76_txq_id qid, u32 changed)
> > > > +{
> > > > +	u32 val, sz_txd = mt76_is_mmio(dev) ? MT_TXD_SIZE :
> > > > MT_SDIO_TXD_SIZE;
> > > > +	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
> > > > +	struct ieee80211_vif *vif = info->control.vif;
> > > > +	u8 band_idx = (info->hw_queue & MT_TX_HW_QUEUE_PHY) >> 2;
> > > > +	u8 p_fmt, q_idx, omac_idx = 0, wmm_idx = 0;
> > > > +	bool is_8023 = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP;
> > > > +	struct mt76_vif *mvif;
> > > > +	u16 tx_count = 15;
> > > > +	bool beacon = !!(changed & (BSS_CHANGED_BEACON |
> > > > +				    BSS_CHANGED_BEACON_ENABLED));
> > > > +	bool inband_disc = !!(changed &
> > > > (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP |
> > > > +					 BSS_CHANGED_FILS_DISCOVERY));
> > > > +
> > > > +	mvif = vif ? (struct mt76_vif *)vif->drv_priv : NULL;
> > > > +	if (mvif) {
> > > > +		omac_idx = mvif->omac_idx;
> > > > +		wmm_idx = mvif->wmm_idx;
> > > > +		band_idx = mvif->band_idx;
> > > > +	}
> > > > +
> > > > +	if (inband_disc) {
> > > > +		p_fmt = MT_TX_TYPE_FW;
> > > > +		q_idx = MT_LMAC_ALTX0;
> > > > +	} else if (beacon) {
> > > > +		p_fmt = MT_TX_TYPE_FW;
> > > > +		q_idx = MT_LMAC_BCN0;
> > > > +	} else if (qid >= MT_TXQ_PSD) {
> > > > +		p_fmt = mt76_is_mmio(dev) ? MT_TX_TYPE_CT :
> > > > MT_TX_TYPE_SF;
> > > > +		q_idx = MT_LMAC_ALTX0;
> > > > +	} else {
> > > > +		p_fmt = mt76_is_mmio(dev) ? MT_TX_TYPE_CT :
> > > > MT_TX_TYPE_SF;
> > > > +		q_idx = wmm_idx * MT76_CONNAC_MAX_WMM_SETS +
> > > > +			mt76_connac_lmac_mapping(skb_get_queue_mapping(
> > > > skb));
> > > > +	}
> > > > +
> > > > +	val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len + sz_txd) |
> > > > +	      FIELD_PREP(MT_TXD0_PKT_FMT, p_fmt) |
> > > > +	      FIELD_PREP(MT_TXD0_Q_IDX, q_idx);
> > > > +	txwi[0] = cpu_to_le32(val);
> > > > +
> > > > +	val = FIELD_PREP(MT_TXD1_WLAN_IDX, wcid->idx) |
> > > > +	      FIELD_PREP(MT_TXD1_OWN_MAC, omac_idx);
> > > > +
> > > > +	if (band_idx)
> > > > +		val |= FIELD_PREP(MT_TXD1_TGID, band_idx);
> > > > +
> > > > +	txwi[1] = cpu_to_le32(val);
> > > > +	txwi[2] = 0;
> > > > +
> > > > +	val = MT_TXD3_SW_POWER_MGMT |
> > > > +	      FIELD_PREP(MT_TXD3_REM_TX_COUNT, tx_count);
> > > > +	if (key)
> > > > +		val |= MT_TXD3_PROTECT_FRAME;
> > > > +	if (info->flags & IEEE80211_TX_CTL_NO_ACK)
> > > > +		val |= MT_TXD3_NO_ACK;
> > > > +	if (wcid->amsdu)
> > > > +		val |= MT_TXD3_HW_AMSDU;
> > > > +
> > > > +	txwi[3] = cpu_to_le32(val);
> > > > +	txwi[4] = 0;
> > > > +
> > > > +	val = FIELD_PREP(MT_TXD5_PID, pid);
> > > > +	if (pid >= MT_PACKET_ID_FIRST)
> > > > +		val |= MT_TXD5_TX_STATUS_HOST;
> > > > +	txwi[5] = cpu_to_le32(val);
> > > > +
> > > > +	val = MT_TXD6_DIS_MAT | MT_TXD6_DAS |
> > > > +	      FIELD_PREP(MT_TXD6_MSDU_CNT, 1);
> > > > +	txwi[6] = cpu_to_le32(val);
> > > > +	txwi[7] = 0;
> > > > +
> > > > +	if (is_8023)
> > > > +		mt76_connac3_mac_write_txwi_8023(txwi, skb, wcid);
> > > > +	else
> > > > +		mt76_connac3_mac_write_txwi_80211(dev, txwi, skb, key);
> > > > +
> > > > +	if (txwi[1] & cpu_to_le32(MT_TXD1_FIXED_RATE)) {
> > > > +		struct ieee80211_hdr *hdr = (struct ieee80211_hdr
> > > > *)skb->data;
> > > > +		bool mcast = ieee80211_is_data(hdr->frame_control) &&
> > > > +			     is_multicast_ether_addr(hdr->addr1);
> > > > +		u8 idx = MT76_CONNAC3_BASIC_RATES_TBL;
> > > > +
> > > > +		if (mvif) {
> > > > +			if (mcast && mvif->mcast_rates_idx)
> > > > +				idx = mvif->mcast_rates_idx;
> > > > +			else if (beacon && mvif->beacon_rates_idx)
> > > > +				idx = mvif->beacon_rates_idx;
> > > > +			else
> > > > +				idx = mvif->basic_rates_idx;
> > > > +		}
> > > > +
> > > > +		txwi[6] |= cpu_to_le32(FIELD_PREP(MT_TXD6_TX_RATE,
> > > > idx));
> > > > +		txwi[3] |= cpu_to_le32(MT_TXD3_BA_DISABLE);
> > > > +	}
> > > > +}
> > > > +EXPORT_SYMBOL_GPL(mt76_connac3_mac_write_txwi);
> > > > +
> > > > +void mt76_connac3_txwi_free(struct mt76_dev *dev, struct
> > > > mt76_txwi_cache *t,
> > > > +			    struct ieee80211_sta *sta,
> > > > +			    struct list_head *free_list)
> > > > +{
> > > > +	__le32 *txwi;
> > > > +	u16 wcid_idx;
> > > > +
> > > > +	mt76_connac_txp_skb_unmap(dev, t);
> > > > +	if (!t->skb)
> > > > +		goto out;
> > > > +
> > > > +	txwi = (__le32 *)mt76_get_txwi_ptr(dev, t);
> > > > +	if (sta) {
> > > > +		struct mt76_wcid *wcid = (struct mt76_wcid *)sta-
> > > > > drv_priv;
> > > > 
> > > > +
> > > > +		wcid_idx = wcid->idx;
> > > > +		if (likely(t->skb->protocol != cpu_to_be16(ETH_P_PAE)))
> > > > +			mt76_connac3_tx_check_aggr(sta, txwi);
> > > > +	} else {
> > > > +		wcid_idx = le32_get_bits(txwi[1], MT_TXD1_WLAN_IDX);
> > > > +	}
> > > > +
> > > > +	__mt76_tx_complete_skb(dev, wcid_idx, t->skb, free_list);
> > > > +out:
> > > > +	t->skb = NULL;
> > > > +	mt76_put_txwi(dev, t);
> > > > +}
> > > > +EXPORT_SYMBOL_GPL(mt76_connac3_txwi_free);
> > > > +
> > > > +static bool
> > > > +mt76_connac3_mac_add_txs_skb(struct mt76_dev *dev, struct
> > > > mt76_wcid
> > > > *wcid,
> > > > +			     int pid, __le32 *txs_data)
> > > > +{
> > > > +	struct mt76_sta_stats *stats = &wcid->stats;
> > > > +	struct ieee80211_supported_band *sband;
> > > > +	struct ieee80211_tx_info *info;
> > > > +	u32 txrate, txs, mode, stbc;
> > > > +	struct rate_info rate = {};
> > > > +	struct sk_buff_head list;
> > > > +	struct mt76_phy *mphy;
> > > > +	struct sk_buff *skb;
> > > > +	bool cck = false;
> > > > +
> > > > +	mt76_tx_status_lock(dev, &list);
> > > > +	skb = mt76_tx_status_skb_get(dev, wcid, pid, &list);
> > > > +	if (!skb)
> > > > +		goto out_no_skb;
> > > > +
> > > > +	txs = le32_to_cpu(txs_data[0]);
> > > > +
> > > > +	info = IEEE80211_SKB_CB(skb);
> > > > +	if (!(txs & MT_TXS0_ACK_ERROR_MASK))
> > > > +		info->flags |= IEEE80211_TX_STAT_ACK;
> > > > +
> > > > +	info->status.ampdu_len = 1;
> > > > +	info->status.ampdu_ack_len = !!(info->flags &
> > > > +					IEEE80211_TX_STAT_ACK);
> > > > +	info->status.rates[0].idx = -1;
> > > > +
> > > > +	txrate = FIELD_GET(MT_TXS0_TX_RATE, txs);
> > > > +
> > > > +	rate.mcs = FIELD_GET(MT_TX_RATE_IDX, txrate);
> > > > +	rate.nss = FIELD_GET(MT_TX_RATE_NSS, txrate) + 1;
> > > > +	stbc = le32_get_bits(txs_data[3], MT_TXS3_RATE_STBC);
> > > > +
> > > > +	if (stbc && rate.nss > 1)
> > > > +		rate.nss >>= 1;
> > > > +
> > > > +	if (rate.nss - 1 < ARRAY_SIZE(stats->tx_nss))
> > > > +		stats->tx_nss[rate.nss - 1]++;
> > > > +	if (rate.mcs < ARRAY_SIZE(stats->tx_mcs))
> > > > +		stats->tx_mcs[rate.mcs]++;
> > > > +
> > > > +	mode = FIELD_GET(MT_TX_RATE_MODE, txrate);
> > > > +	switch (mode) {
> > > > +	case MT_PHY_TYPE_CCK:
> > > > +		cck = true;
> > > > +		fallthrough;
> > > > +	case MT_PHY_TYPE_OFDM:
> > > > +		mphy = mt76_dev_phy(dev, wcid->phy_idx);
> > > > +
> > > > +		if (mphy->chandef.chan->band == NL80211_BAND_5GHZ)
> > > > +			sband = &mphy->sband_5g.sband;
> > > > +		else if (mphy->chandef.chan->band == NL80211_BAND_6GHZ)
> > > > +			sband = &mphy->sband_6g.sband;
> > > > +		else
> > > > +			sband = &mphy->sband_2g.sband;
> > > > +
> > > > +		rate.mcs = mt76_get_rate(mphy->dev, sband, rate.mcs,
> > > > cck);
> > > > +		rate.legacy = sband->bitrates[rate.mcs].bitrate;
> > > > +		break;
> > > > +	case MT_PHY_TYPE_HT:
> > > > +	case MT_PHY_TYPE_HT_GF:
> > > > +		if (rate.mcs > 31)
> > > > +			goto out;
> > > > +
> > > > +		rate.flags = RATE_INFO_FLAGS_MCS;
> > > > +		if (wcid->rate.flags & RATE_INFO_FLAGS_SHORT_GI)
> > > > +			rate.flags |= RATE_INFO_FLAGS_SHORT_GI;
> > > > +		break;
> > > > +	case MT_PHY_TYPE_VHT:
> > > > +		if (rate.mcs > 9)
> > > > +			goto out;
> > > > +
> > > > +		rate.flags = RATE_INFO_FLAGS_VHT_MCS;
> > > > +		break;
> > > > +	case MT_PHY_TYPE_HE_SU:
> > > > +	case MT_PHY_TYPE_HE_EXT_SU:
> > > > +	case MT_PHY_TYPE_HE_TB:
> > > > +	case MT_PHY_TYPE_HE_MU:
> > > > +		if (rate.mcs > 11)
> > > > +			goto out;
> > > > +
> > > > +		rate.he_gi = wcid->rate.he_gi;
> > > > +		rate.he_dcm = FIELD_GET(MT_TX_RATE_DCM, txrate);
> > > > +		rate.flags = RATE_INFO_FLAGS_HE_MCS;
> > > > +		break;
> > > > +	case MT_PHY_TYPE_EHT_SU:
> > > > +	case MT_PHY_TYPE_EHT_TRIG:
> > > > +	case MT_PHY_TYPE_EHT_MU:
> > > > +		if (rate.mcs > 13)
> > > > +			goto out;
> > > > +
> > > > +		rate.eht_gi = wcid->rate.eht_gi;
> > > > +		rate.flags = RATE_INFO_FLAGS_EHT_MCS;
> > > > +		break;
> > > > +	default:
> > > > +		goto out;
> > > > +	}
> > > > +
> > > > +	stats->tx_mode[mode]++;
> > > > +
> > > > +	switch (FIELD_GET(MT_TXS0_BW, txs)) {
> > > > +	case IEEE80211_STA_RX_BW_320:
> > > > +		rate.bw = RATE_INFO_BW_320;
> > > > +		stats->tx_bw[4]++;
> > > > +		break;
> > > > +	case IEEE80211_STA_RX_BW_160:
> > > > +		rate.bw = RATE_INFO_BW_160;
> > > > +		stats->tx_bw[3]++;
> > > > +		break;
> > > > +	case IEEE80211_STA_RX_BW_80:
> > > > +		rate.bw = RATE_INFO_BW_80;
> > > > +		stats->tx_bw[2]++;
> > > > +		break;
> > > > +	case IEEE80211_STA_RX_BW_40:
> > > > +		rate.bw = RATE_INFO_BW_40;
> > > > +		stats->tx_bw[1]++;
> > > > +		break;
> > > > +	default:
> > > > +		rate.bw = RATE_INFO_BW_20;
> > > > +		stats->tx_bw[0]++;
> > > > +		break;
> > > > +	}
> > > > +	wcid->rate = rate;
> > > > +
> > > > +out:
> > > > +	mt76_tx_status_skb_done(dev, skb, &list);
> > > > +
> > > > +out_no_skb:
> > > > +	mt76_tx_status_unlock(dev, &list);
> > > > +
> > > > +	return !!skb;
> > > > +}
> > > > +
> > > > +void mt76_connac3_mac_add_txs(struct mt76_dev *dev, void *data,
> > > > +			      u32 max_wtbl_size)
> > > > +{
> > > > +	struct mt76_wcid *wcid;
> > > > +	__le32 *txs_data = data;
> > > > +	u16 wcidx;
> > > > +	u8 pid;
> > > > +
> > > > +	if (le32_get_bits(txs_data[0], MT_TXS0_TXS_FORMAT) > 1)
> > > > +		return;
> > > > +
> > > > +	wcidx = le32_get_bits(txs_data[2], MT_TXS2_WCID);
> > > > +	pid = le32_get_bits(txs_data[3], MT_TXS3_PID);
> > > > +
> > > > +	if (pid < MT_PACKET_ID_FIRST)
> > > > +		return;
> > > > +
> > > > +	if (wcidx >= max_wtbl_size)
> > > > +		return;
> > > > +
> > > > +	rcu_read_lock();
> > > > +
> > > > +	wcid = rcu_dereference(dev->wcid[wcidx]);
> > > > +	if (!wcid)
> > > > +		goto out;
> > > > +
> > > > +	mt76_connac3_mac_add_txs_skb(dev, wcid, pid, txs_data);
> > > > +	if (!wcid->sta)
> > > > +		goto out;
> > > > +
> > > > +	spin_lock_bh(&dev->sta_poll_lock);
> > > > +	if (list_empty(&wcid->poll_list))
> > > > +		list_add_tail(&wcid->poll_list, &dev->sta_poll_list);
> > > > +	spin_unlock_bh(&dev->sta_poll_lock);
> > > > +
> > > > +out:
> > > > +	rcu_read_unlock();
> > > > +}
> > > > +EXPORT_SYMBOL_GPL(mt76_connac3_mac_add_txs);
> > > > +
> > > > +void mt76_connac3_tx_token_put(struct mt76_dev *dev)
> > > > +{
> > > > +	struct mt76_txwi_cache *txwi;
> > > > +	int id;
> > > > +
> > > > +	spin_lock_bh(&dev->token_lock);
> > > > +	idr_for_each_entry(&dev->token, txwi, id) {
> > > > +		mt76_connac3_txwi_free(dev, txwi, NULL, NULL);
> > > > +		dev->token_count--;
> > > > +	}
> > > > +	spin_unlock_bh(&dev->token_lock);
> > > > +	idr_destroy(&dev->token);
> > > > +}
> > > > +EXPORT_SYMBOL_GPL(mt76_connac3_tx_token_put);
> > > > diff --git
> > > > a/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h
> > > > b/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h
> > > > index 6663a0b46541..bcc1d976b2b0 100644
> > > > --- a/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h
> > > > +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h
> > > > @@ -4,6 +4,24 @@
> > > >  #ifndef __MT76_CONNAC3_MAC_H
> > > >  #define __MT76_CONNAC3_MAC_H
> > > >  
> > > > +/* NOTE: used to map mt76_rates. idx may change if firmware
> > > > expands
> > > > table */
> > > > +#define MT76_CONNAC3_BASIC_RATES_TBL	11
> > > > +#define MT76_CONNAC3_BEACON_RATES_TBL	25
> > > > 
> > > 
> > > Different devices may have different defined value. 
> > 
> > The other WiFi7 device I am working on relies on the values I moved
> > in
> > mt76_connac3_mac.h (in common with mt7996). Moreover you can still
> > have per-device values in mt7996/mac.h (I have not removed it).
> > 
> 
> Please double check with the mtk folk you work with. The 11 and 25 is
> the value I discussed with firmware folks to avoid overlapping the tbl
> mt7996 use (MU/other algo in fw), or it causes something hardly solving
> issue

sure, thx for pointing this out.
@Deren: can you please double check?

Regards,
Lorenzo

>  
> > > 
> > > I'm thinking if it's too early to create this patch for just moving
> > > mt7996 to connac3_lib?
> > 
> > The code I moved is used by the other device as well. This series is
> > a
> > preliminary series to support it.
> > 
> > Regards,
> > Lorenzo
> > 
> > > 
> > > Ryder
> > > 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

  reply	other threads:[~2023-06-09 16:43 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-09  8:15 [PATCH v2 00/15] mt76: introduce connac3_mac support Lorenzo Bianconi
2023-06-09  8:15 ` [PATCH v2 01/15] wifi: mt76: mt7915: move sta_poll_list and sta_poll_lock in mt76_dev Lorenzo Bianconi
2023-06-09  8:15 ` [PATCH v2 02/15] wifi: mt76: mt7603: rely on shared sta_poll_list and sta_poll_lock Lorenzo Bianconi
2023-06-09  8:15 ` [PATCH v2 03/15] wifi: mt76: mt7615: " Lorenzo Bianconi
2023-06-09  8:15 ` [PATCH v2 04/15] wifi: mt76: mt7996: " Lorenzo Bianconi
2023-06-09  8:15 ` [PATCH v2 05/15] wifi: mt76: mt7921: " Lorenzo Bianconi
2023-06-09  8:15 ` [PATCH v2 06/15] wifi: mt76: mt7915: move poll_list in mt76_wcid Lorenzo Bianconi
2023-06-09  8:15 ` [PATCH v2 07/15] wifi: mt76: mt7603: rely on shared poll_list field Lorenzo Bianconi
2023-06-09  8:15 ` [PATCH v2 08/15] wifi: mt76: mt7615: " Lorenzo Bianconi
2023-06-09  8:15 ` [PATCH v2 09/15] wifi: mt76: mt7996: " Lorenzo Bianconi
2023-06-09  8:15 ` [PATCH v2 10/15] wifi: mt76: mt7921: " Lorenzo Bianconi
2023-06-09  8:15 ` [PATCH v2 11/15] wifi: mt76: move ampdu_state in mt76_wcid Lorenzo Bianconi
2023-06-09  8:15 ` [PATCH v2 12/15] mt76: connac: move more mt7921/mt7915 mac shared code in connac lib Lorenzo Bianconi
2023-06-09  8:15 ` [PATCH v2 13/15] wifi: mt76: move rate info in mt76_vif Lorenzo Bianconi
2023-06-09  8:15 ` [PATCH v2 14/15] wifi: mt76: connac: move connac3 definitions in mt76_connac3_mac.h Lorenzo Bianconi
2023-06-09  8:15 ` [PATCH v2 15/15] wifi: mt76: connac: add connac3 mac library Lorenzo Bianconi
2023-06-09 16:15   ` Ryder Lee
2023-06-09 16:34     ` lorenzo.bianconi
2023-06-09 16:38       ` Ryder Lee
2023-06-09 16:45         ` lorenzo [this message]
     [not found]           ` <PH8PR12MB7230DC95457EF9C667E679AEAC51A@PH8PR12MB7230.namprd12.prod.outlook.com>
     [not found]             ` <3cae89c45b0f17eaab20876eb50572ef202f92bc.camel@mediatek.com>
2023-06-09 19:04               ` shayne.chen
2023-06-10 10:06                 ` lorenzo
2023-06-10 13:49                   ` shayne.chen
2023-06-10 14:59                     ` Ryder Lee
2023-06-10  2:22           ` Deren Wu (武德仁)
2023-06-10  7:49             ` lorenzo
2023-06-12  8:58               ` Kalle Valo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZINXGP6TmDLaZ+lu@localhost.localdomain \
    --to=lorenzo@kernel.org \
    --cc=Ryder.Lee@mediatek.com \
    --cc=deren.wu@mediatek.com \
    --cc=linux-wireless@vger.kernel.org \
    --cc=lorenzo.bianconi@redhat.com \
    --cc=nbd@nbd.name \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.