Skip to content

Commit ad4c9a8

Browse files
haogrootnbd168
authored andcommitted
wifi: mt76: mt7996: add implicit beamforming support for mt7992
The configuration of mt7992 iBF has some differences to mt7996, rework related code to make it work. Also, most of our chipsets support iBF only on HT and VHT mode, except mt7992 variant that has 5T on 5GHz band also supports iBF on HE and EHT mode. Co-developed-by: Shayne Chen <[email protected]> Signed-off-by: Shayne Chen <[email protected]> Signed-off-by: Howard Hsu <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Felix Fietkau <[email protected]>
1 parent 57ccb37 commit ad4c9a8

File tree

2 files changed

+55
-28
lines changed

2 files changed

+55
-28
lines changed

drivers/net/wireless/mediatek/mt76/mt7996/mcu.c

Lines changed: 49 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1460,17 +1460,21 @@ mt7996_is_ebf_supported(struct mt7996_phy *phy, struct ieee80211_vif *vif,
14601460
}
14611461

14621462
static void
1463-
mt7996_mcu_sta_sounding_rate(struct sta_rec_bf *bf)
1463+
mt7996_mcu_sta_sounding_rate(struct sta_rec_bf *bf, struct mt7996_phy *phy)
14641464
{
14651465
bf->sounding_phy = MT_PHY_TYPE_OFDM;
14661466
bf->ndp_rate = 0; /* mcs0 */
1467-
bf->ndpa_rate = MT7996_CFEND_RATE_DEFAULT; /* ofdm 24m */
1467+
if (is_mt7996(phy->mt76->dev))
1468+
bf->ndpa_rate = MT7996_CFEND_RATE_DEFAULT; /* ofdm 24m */
1469+
else
1470+
bf->ndpa_rate = MT7992_CFEND_RATE_DEFAULT; /* ofdm 6m */
1471+
14681472
bf->rept_poll_rate = MT7996_CFEND_RATE_DEFAULT; /* ofdm 24m */
14691473
}
14701474

14711475
static void
14721476
mt7996_mcu_sta_bfer_ht(struct ieee80211_sta *sta, struct mt7996_phy *phy,
1473-
struct sta_rec_bf *bf)
1477+
struct sta_rec_bf *bf, bool explicit)
14741478
{
14751479
struct ieee80211_mcs_info *mcs = &sta->deflink.ht_cap.mcs;
14761480
u8 n = 0;
@@ -1490,7 +1494,8 @@ mt7996_mcu_sta_bfer_ht(struct ieee80211_sta *sta, struct mt7996_phy *phy,
14901494

14911495
bf->nrow = hweight8(phy->mt76->antenna_mask) - 1;
14921496
bf->ncol = min_t(u8, bf->nrow, n);
1493-
bf->ibf_ncol = n;
1497+
bf->ibf_ncol = explicit ? min_t(u8, MT7996_IBF_MAX_NC, bf->ncol) :
1498+
min_t(u8, MT7996_IBF_MAX_NC, n);
14941499
}
14951500

14961501
static void
@@ -1508,22 +1513,22 @@ mt7996_mcu_sta_bfer_vht(struct ieee80211_sta *sta, struct mt7996_phy *phy,
15081513
if (explicit) {
15091514
u8 sts, snd_dim;
15101515

1511-
mt7996_mcu_sta_sounding_rate(bf);
1516+
mt7996_mcu_sta_sounding_rate(bf, phy);
15121517

15131518
sts = FIELD_GET(IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK,
15141519
pc->cap);
15151520
snd_dim = FIELD_GET(IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK,
15161521
vc->cap);
15171522
bf->nrow = min_t(u8, min_t(u8, snd_dim, sts), tx_ant);
15181523
bf->ncol = min_t(u8, nss_mcs, bf->nrow);
1519-
bf->ibf_ncol = bf->ncol;
1524+
bf->ibf_ncol = min_t(u8, MT7996_IBF_MAX_NC, bf->ncol);
15201525

15211526
if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_160)
15221527
bf->nrow = 1;
15231528
} else {
15241529
bf->nrow = tx_ant;
15251530
bf->ncol = min_t(u8, nss_mcs, bf->nrow);
1526-
bf->ibf_ncol = nss_mcs;
1531+
bf->ibf_ncol = min_t(u8, MT7996_IBF_MAX_NC, nss_mcs);
15271532

15281533
if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_160)
15291534
bf->ibf_nrow = 1;
@@ -1532,7 +1537,8 @@ mt7996_mcu_sta_bfer_vht(struct ieee80211_sta *sta, struct mt7996_phy *phy,
15321537

15331538
static void
15341539
mt7996_mcu_sta_bfer_he(struct ieee80211_sta *sta, struct ieee80211_vif *vif,
1535-
struct mt7996_phy *phy, struct sta_rec_bf *bf)
1540+
struct mt7996_phy *phy, struct sta_rec_bf *bf,
1541+
bool explicit)
15361542
{
15371543
struct ieee80211_sta_he_cap *pc = &sta->deflink.he_cap;
15381544
struct ieee80211_he_cap_elem *pe = &pc->he_cap_elem;
@@ -1548,7 +1554,7 @@ mt7996_mcu_sta_bfer_he(struct ieee80211_sta *sta, struct ieee80211_vif *vif,
15481554

15491555
bf->tx_mode = MT_PHY_TYPE_HE_SU;
15501556

1551-
mt7996_mcu_sta_sounding_rate(bf);
1557+
mt7996_mcu_sta_sounding_rate(bf, phy);
15521558

15531559
bf->trigger_su = HE_PHY(CAP6_TRIG_SU_BEAMFORMING_FB,
15541560
pe->phy_cap_info[6]);
@@ -1560,7 +1566,8 @@ mt7996_mcu_sta_bfer_he(struct ieee80211_sta *sta, struct ieee80211_vif *vif,
15601566
pe->phy_cap_info[4]);
15611567
bf->nrow = min_t(u8, snd_dim, sts);
15621568
bf->ncol = min_t(u8, nss_mcs, bf->nrow);
1563-
bf->ibf_ncol = bf->ncol;
1569+
bf->ibf_ncol = explicit ? min_t(u8, MT7996_IBF_MAX_NC, bf->ncol) :
1570+
min_t(u8, MT7996_IBF_MAX_NC, nss_mcs);
15641571

15651572
if (sta->deflink.bandwidth != IEEE80211_STA_RX_BW_160)
15661573
return;
@@ -1595,7 +1602,8 @@ mt7996_mcu_sta_bfer_he(struct ieee80211_sta *sta, struct ieee80211_vif *vif,
15951602

15961603
static void
15971604
mt7996_mcu_sta_bfer_eht(struct ieee80211_sta *sta, struct ieee80211_vif *vif,
1598-
struct mt7996_phy *phy, struct sta_rec_bf *bf)
1605+
struct mt7996_phy *phy, struct sta_rec_bf *bf,
1606+
bool explicit)
15991607
{
16001608
struct ieee80211_sta_eht_cap *pc = &sta->deflink.eht_cap;
16011609
struct ieee80211_eht_cap_elem_fixed *pe = &pc->eht_cap_elem;
@@ -1609,7 +1617,7 @@ mt7996_mcu_sta_bfer_eht(struct ieee80211_sta *sta, struct ieee80211_vif *vif,
16091617

16101618
bf->tx_mode = MT_PHY_TYPE_EHT_MU;
16111619

1612-
mt7996_mcu_sta_sounding_rate(bf);
1620+
mt7996_mcu_sta_sounding_rate(bf, phy);
16131621

16141622
bf->trigger_su = EHT_PHY(CAP3_TRIG_SU_BF_FDBK, pe->phy_cap_info[3]);
16151623
bf->trigger_mu = EHT_PHY(CAP3_TRIG_MU_BF_PART_BW_FDBK, pe->phy_cap_info[3]);
@@ -1618,7 +1626,8 @@ mt7996_mcu_sta_bfer_eht(struct ieee80211_sta *sta, struct ieee80211_vif *vif,
16181626
(EHT_PHY(CAP1_BEAMFORMEE_SS_80MHZ_MASK, pe->phy_cap_info[1]) << 1);
16191627
bf->nrow = min_t(u8, snd_dim, sts);
16201628
bf->ncol = min_t(u8, nss_mcs, bf->nrow);
1621-
bf->ibf_ncol = bf->ncol;
1629+
bf->ibf_ncol = explicit ? min_t(u8, MT7996_IBF_MAX_NC, bf->ncol) :
1630+
min_t(u8, MT7996_IBF_MAX_NC, nss_mcs);
16221631

16231632
if (sta->deflink.bandwidth < IEEE80211_STA_RX_BW_160)
16241633
return;
@@ -1653,12 +1662,15 @@ static void
16531662
mt7996_mcu_sta_bfer_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
16541663
struct ieee80211_vif *vif, struct ieee80211_sta *sta)
16551664
{
1665+
#define EBF_MODE BIT(0)
1666+
#define IBF_MODE BIT(1)
1667+
#define BF_MAT_ORDER 4
16561668
struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
16571669
struct mt7996_phy *phy = mvif->deflink.phy;
16581670
int tx_ant = hweight16(phy->mt76->chainmask) - 1;
16591671
struct sta_rec_bf *bf;
16601672
struct tlv *tlv;
1661-
static const u8 matrix[4][4] = {
1673+
static const u8 matrix[BF_MAT_ORDER][BF_MAT_ORDER] = {
16621674
{0, 0, 0, 0},
16631675
{1, 1, 0, 0}, /* 2x1, 2x2, 2x3, 2x4 */
16641676
{2, 4, 4, 0}, /* 3x1, 3x2, 3x3, 3x4 */
@@ -1676,35 +1688,44 @@ mt7996_mcu_sta_bfer_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
16761688
tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_BF, sizeof(*bf));
16771689
bf = (struct sta_rec_bf *)tlv;
16781690

1679-
/* he/eht: eBF only, in accordance with spec
1691+
/* he/eht: eBF only, except mt7992 that has 5T on 5GHz also supports iBF
16801692
* vht: support eBF and iBF
16811693
* ht: iBF only, since mac80211 lacks of eBF support
16821694
*/
1683-
if (sta->deflink.eht_cap.has_eht && ebf)
1684-
mt7996_mcu_sta_bfer_eht(sta, vif, phy, bf);
1685-
else if (sta->deflink.he_cap.has_he && ebf)
1686-
mt7996_mcu_sta_bfer_he(sta, vif, phy, bf);
1695+
if (sta->deflink.eht_cap.has_eht)
1696+
mt7996_mcu_sta_bfer_eht(sta, vif, phy, bf, ebf);
1697+
else if (sta->deflink.he_cap.has_he)
1698+
mt7996_mcu_sta_bfer_he(sta, vif, phy, bf, ebf);
16871699
else if (sta->deflink.vht_cap.vht_supported)
16881700
mt7996_mcu_sta_bfer_vht(sta, phy, bf, ebf);
16891701
else if (sta->deflink.ht_cap.ht_supported)
1690-
mt7996_mcu_sta_bfer_ht(sta, phy, bf);
1702+
mt7996_mcu_sta_bfer_ht(sta, phy, bf, ebf);
16911703
else
16921704
return;
16931705

1694-
bf->bf_cap = ebf ? ebf : dev->ibf << 1;
1706+
bf->bf_cap = ebf ? EBF_MODE : (dev->ibf ? IBF_MODE : 0);
1707+
if (is_mt7992(&dev->mt76) && tx_ant == 4)
1708+
bf->bf_cap |= IBF_MODE;
16951709
bf->bw = sta->deflink.bandwidth;
16961710
bf->ibf_dbw = sta->deflink.bandwidth;
16971711
bf->ibf_nrow = tx_ant;
16981712

1699-
if (!ebf && sta->deflink.bandwidth <= IEEE80211_STA_RX_BW_40 && !bf->ncol)
1700-
bf->ibf_timeout = 0x48;
1713+
if (sta->deflink.eht_cap.has_eht || sta->deflink.he_cap.has_he)
1714+
bf->ibf_timeout = is_mt7996(&dev->mt76) ? MT7996_IBF_TIMEOUT :
1715+
MT7992_IBF_TIMEOUT;
1716+
else if (!ebf && sta->deflink.bandwidth <= IEEE80211_STA_RX_BW_40 && !bf->ncol)
1717+
bf->ibf_timeout = MT7996_IBF_TIMEOUT_LEGACY;
17011718
else
1702-
bf->ibf_timeout = 0x18;
1719+
bf->ibf_timeout = MT7996_IBF_TIMEOUT;
17031720

1704-
if (ebf && bf->nrow != tx_ant)
1705-
bf->mem_20m = matrix[tx_ant][bf->ncol];
1706-
else
1707-
bf->mem_20m = matrix[bf->nrow][bf->ncol];
1721+
if (bf->ncol < BF_MAT_ORDER) {
1722+
if (ebf)
1723+
bf->mem_20m = tx_ant < BF_MAT_ORDER ?
1724+
matrix[tx_ant][bf->ncol] : 0;
1725+
else
1726+
bf->mem_20m = bf->nrow < BF_MAT_ORDER ?
1727+
matrix[bf->nrow][bf->ncol] : 0;
1728+
}
17081729

17091730
switch (sta->deflink.bandwidth) {
17101731
case IEEE80211_STA_RX_BW_160:

drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,12 @@
6868

6969
#define MT7996_CFEND_RATE_DEFAULT 0x49 /* OFDM 24M */
7070
#define MT7996_CFEND_RATE_11B 0x03 /* 11B LP, 11M */
71+
#define MT7996_IBF_MAX_NC 2
72+
#define MT7996_IBF_TIMEOUT 0x18
73+
#define MT7996_IBF_TIMEOUT_LEGACY 0x48
74+
75+
#define MT7992_CFEND_RATE_DEFAULT 0x4b /* OFDM 6M */
76+
#define MT7992_IBF_TIMEOUT 0xff
7177

7278
#define MT7996_SKU_RATE_NUM 417
7379
#define MT7996_SKU_PATH_NUM 494

0 commit comments

Comments
 (0)