@@ -1460,17 +1460,21 @@ mt7996_is_ebf_supported(struct mt7996_phy *phy, struct ieee80211_vif *vif,
14601460}
14611461
14621462static 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
14711475static void
14721476mt7996_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
14961501static 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
15331538static void
15341539mt7996_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
15961603static void
15971604mt7996_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
16531662mt7996_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 :
0 commit comments