@@ -1460,17 +1460,21 @@ mt7996_is_ebf_supported(struct mt7996_phy *phy, struct ieee80211_vif *vif,
1460
1460
}
1461
1461
1462
1462
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 )
1464
1464
{
1465
1465
bf -> sounding_phy = MT_PHY_TYPE_OFDM ;
1466
1466
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
+
1468
1472
bf -> rept_poll_rate = MT7996_CFEND_RATE_DEFAULT ; /* ofdm 24m */
1469
1473
}
1470
1474
1471
1475
static void
1472
1476
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 )
1474
1478
{
1475
1479
struct ieee80211_mcs_info * mcs = & sta -> deflink .ht_cap .mcs ;
1476
1480
u8 n = 0 ;
@@ -1490,7 +1494,8 @@ mt7996_mcu_sta_bfer_ht(struct ieee80211_sta *sta, struct mt7996_phy *phy,
1490
1494
1491
1495
bf -> nrow = hweight8 (phy -> mt76 -> antenna_mask ) - 1 ;
1492
1496
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 );
1494
1499
}
1495
1500
1496
1501
static void
@@ -1508,22 +1513,22 @@ mt7996_mcu_sta_bfer_vht(struct ieee80211_sta *sta, struct mt7996_phy *phy,
1508
1513
if (explicit ) {
1509
1514
u8 sts , snd_dim ;
1510
1515
1511
- mt7996_mcu_sta_sounding_rate (bf );
1516
+ mt7996_mcu_sta_sounding_rate (bf , phy );
1512
1517
1513
1518
sts = FIELD_GET (IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK ,
1514
1519
pc -> cap );
1515
1520
snd_dim = FIELD_GET (IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK ,
1516
1521
vc -> cap );
1517
1522
bf -> nrow = min_t (u8 , min_t (u8 , snd_dim , sts ), tx_ant );
1518
1523
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 ) ;
1520
1525
1521
1526
if (sta -> deflink .bandwidth == IEEE80211_STA_RX_BW_160 )
1522
1527
bf -> nrow = 1 ;
1523
1528
} else {
1524
1529
bf -> nrow = tx_ant ;
1525
1530
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 ) ;
1527
1532
1528
1533
if (sta -> deflink .bandwidth == IEEE80211_STA_RX_BW_160 )
1529
1534
bf -> ibf_nrow = 1 ;
@@ -1532,7 +1537,8 @@ mt7996_mcu_sta_bfer_vht(struct ieee80211_sta *sta, struct mt7996_phy *phy,
1532
1537
1533
1538
static void
1534
1539
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 )
1536
1542
{
1537
1543
struct ieee80211_sta_he_cap * pc = & sta -> deflink .he_cap ;
1538
1544
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,
1548
1554
1549
1555
bf -> tx_mode = MT_PHY_TYPE_HE_SU ;
1550
1556
1551
- mt7996_mcu_sta_sounding_rate (bf );
1557
+ mt7996_mcu_sta_sounding_rate (bf , phy );
1552
1558
1553
1559
bf -> trigger_su = HE_PHY (CAP6_TRIG_SU_BEAMFORMING_FB ,
1554
1560
pe -> phy_cap_info [6 ]);
@@ -1560,7 +1566,8 @@ mt7996_mcu_sta_bfer_he(struct ieee80211_sta *sta, struct ieee80211_vif *vif,
1560
1566
pe -> phy_cap_info [4 ]);
1561
1567
bf -> nrow = min_t (u8 , snd_dim , sts );
1562
1568
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 );
1564
1571
1565
1572
if (sta -> deflink .bandwidth != IEEE80211_STA_RX_BW_160 )
1566
1573
return ;
@@ -1595,7 +1602,8 @@ mt7996_mcu_sta_bfer_he(struct ieee80211_sta *sta, struct ieee80211_vif *vif,
1595
1602
1596
1603
static void
1597
1604
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 )
1599
1607
{
1600
1608
struct ieee80211_sta_eht_cap * pc = & sta -> deflink .eht_cap ;
1601
1609
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,
1609
1617
1610
1618
bf -> tx_mode = MT_PHY_TYPE_EHT_MU ;
1611
1619
1612
- mt7996_mcu_sta_sounding_rate (bf );
1620
+ mt7996_mcu_sta_sounding_rate (bf , phy );
1613
1621
1614
1622
bf -> trigger_su = EHT_PHY (CAP3_TRIG_SU_BF_FDBK , pe -> phy_cap_info [3 ]);
1615
1623
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,
1618
1626
(EHT_PHY (CAP1_BEAMFORMEE_SS_80MHZ_MASK , pe -> phy_cap_info [1 ]) << 1 );
1619
1627
bf -> nrow = min_t (u8 , snd_dim , sts );
1620
1628
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 );
1622
1631
1623
1632
if (sta -> deflink .bandwidth < IEEE80211_STA_RX_BW_160 )
1624
1633
return ;
@@ -1653,12 +1662,15 @@ static void
1653
1662
mt7996_mcu_sta_bfer_tlv (struct mt7996_dev * dev , struct sk_buff * skb ,
1654
1663
struct ieee80211_vif * vif , struct ieee80211_sta * sta )
1655
1664
{
1665
+ #define EBF_MODE BIT(0)
1666
+ #define IBF_MODE BIT(1)
1667
+ #define BF_MAT_ORDER 4
1656
1668
struct mt7996_vif * mvif = (struct mt7996_vif * )vif -> drv_priv ;
1657
1669
struct mt7996_phy * phy = mvif -> deflink .phy ;
1658
1670
int tx_ant = hweight16 (phy -> mt76 -> chainmask ) - 1 ;
1659
1671
struct sta_rec_bf * bf ;
1660
1672
struct tlv * tlv ;
1661
- static const u8 matrix [4 ][ 4 ] = {
1673
+ static const u8 matrix [BF_MAT_ORDER ][ BF_MAT_ORDER ] = {
1662
1674
{0 , 0 , 0 , 0 },
1663
1675
{1 , 1 , 0 , 0 }, /* 2x1, 2x2, 2x3, 2x4 */
1664
1676
{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,
1676
1688
tlv = mt76_connac_mcu_add_tlv (skb , STA_REC_BF , sizeof (* bf ));
1677
1689
bf = (struct sta_rec_bf * )tlv ;
1678
1690
1679
- /* he/eht: eBF only, in accordance with spec
1691
+ /* he/eht: eBF only, except mt7992 that has 5T on 5GHz also supports iBF
1680
1692
* vht: support eBF and iBF
1681
1693
* ht: iBF only, since mac80211 lacks of eBF support
1682
1694
*/
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 );
1687
1699
else if (sta -> deflink .vht_cap .vht_supported )
1688
1700
mt7996_mcu_sta_bfer_vht (sta , phy , bf , ebf );
1689
1701
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 );
1691
1703
else
1692
1704
return ;
1693
1705
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 ;
1695
1709
bf -> bw = sta -> deflink .bandwidth ;
1696
1710
bf -> ibf_dbw = sta -> deflink .bandwidth ;
1697
1711
bf -> ibf_nrow = tx_ant ;
1698
1712
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 ;
1701
1718
else
1702
- bf -> ibf_timeout = 0x18 ;
1719
+ bf -> ibf_timeout = MT7996_IBF_TIMEOUT ;
1703
1720
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
+ }
1708
1729
1709
1730
switch (sta -> deflink .bandwidth ) {
1710
1731
case IEEE80211_STA_RX_BW_160 :
0 commit comments