]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
wifi: mt76: mt7915: deal with special variant of mt7916
authorPeter Chiu <chui-hao.chiu@mediatek.com>
Fri, 30 Sep 2022 15:13:11 +0000 (23:13 +0800)
committerFelix Fietkau <nbd@nbd.name>
Thu, 1 Dec 2022 16:29:12 +0000 (17:29 +0100)
A variant of mt7916 supports up to 3 tx/rx paths but with only
2 spatial streams. An example usage of the 3rd path is to server as
an auxiliary for beamforming.
In order to deal with this case, this patch reworks some parts to
correctly use paths or streams.

Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/mt7915/init.c
drivers/net/wireless/mediatek/mt76/mt7915/main.c
drivers/net/wireless/mediatek/mt76/mt7915/mcu.c

index cc2aac86bcfb6ad69f38b6f5b8bdee55e57464bf..324db5291c85364215c3f7f5480b041265eac572 100644 (file)
@@ -700,13 +700,13 @@ mt7915_init_hardware(struct mt7915_dev *dev, struct mt7915_phy *phy2)
 
 void mt7915_set_stream_vht_txbf_caps(struct mt7915_phy *phy)
 {
-       int nss;
+       int sts;
        u32 *cap;
 
        if (!phy->mt76->cap.has_5ghz)
                return;
 
-       nss = hweight8(phy->mt76->chainmask);
+       sts = hweight8(phy->mt76->chainmask);
        cap = &phy->mt76->sband_5g.sband.vht_cap.cap;
 
        *cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
@@ -717,28 +717,27 @@ void mt7915_set_stream_vht_txbf_caps(struct mt7915_phy *phy)
                  IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
                  IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE);
 
-       if (nss < 2)
+       if (sts < 2)
                return;
 
        *cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
                IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE |
                FIELD_PREP(IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK,
-                          nss - 1);
+                          sts - 1);
 }
 
 static void
-mt7915_set_stream_he_txbf_caps(struct mt7915_dev *dev,
-                              struct ieee80211_sta_he_cap *he_cap,
-                              int vif, int nss)
+mt7915_set_stream_he_txbf_caps(struct mt7915_phy *phy,
+                              struct ieee80211_sta_he_cap *he_cap, int vif)
 {
+       struct mt7915_dev *dev = phy->dev;
        struct ieee80211_he_cap_elem *elem = &he_cap->he_cap_elem;
-       u8 c, nss_160;
+       int sts = hweight8(phy->mt76->chainmask);
+       u8 c, sts_160 = sts;
 
-       /* Can do 1/2 of NSS streams in 160Mhz mode for mt7915 */
+       /* Can do 1/2 of STS in 160Mhz mode for mt7915 */
        if (is_mt7915(&dev->mt76) && !dev->dbdc_support)
-               nss_160 = nss / 2;
-       else
-               nss_160 = nss;
+               sts_160 /= 2;
 
 #ifdef CONFIG_MAC80211_MESH
        if (vif == NL80211_IFTYPE_MESH_POINT)
@@ -778,11 +777,11 @@ mt7915_set_stream_he_txbf_caps(struct mt7915_dev *dev,
 
        elem->phy_cap_info[6] |= c;
 
-       if (nss < 2)
+       if (sts < 2)
                return;
 
        /* the maximum cap is 4 x 3, (Nr, Nc) = (3, 2) */
-       elem->phy_cap_info[7] |= min_t(int, nss - 1, 2) << 3;
+       elem->phy_cap_info[7] |= min_t(int, sts - 1, 2) << 3;
 
        if (vif != NL80211_IFTYPE_AP)
                return;
@@ -791,12 +790,12 @@ mt7915_set_stream_he_txbf_caps(struct mt7915_dev *dev,
        elem->phy_cap_info[4] |= IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER;
 
        /* num_snd_dim
-        * for mt7915, max supported nss is 2 for bw > 80MHz
+        * for mt7915, max supported sts is 2 for bw > 80MHz
         */
        c = FIELD_PREP(IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK,
-                      nss - 1) |
+                      sts - 1) |
            FIELD_PREP(IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_MASK,
-                      nss_160 - 1);
+                      sts_160 - 1);
        elem->phy_cap_info[5] |= c;
 
        c = IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB |
@@ -836,7 +835,7 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band,
                    struct ieee80211_sband_iftype_data *data)
 {
        struct mt7915_dev *dev = phy->dev;
-       int i, idx = 0, nss = hweight8(phy->mt76->chainmask);
+       int i, idx = 0, nss = hweight8(phy->mt76->antenna_mask);
        u16 mcs_map = 0;
        u16 mcs_map_160 = 0;
        u8 nss_160;
@@ -969,7 +968,7 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band,
                he_mcs->rx_mcs_80p80 = cpu_to_le16(mcs_map_160);
                he_mcs->tx_mcs_80p80 = cpu_to_le16(mcs_map_160);
 
-               mt7915_set_stream_he_txbf_caps(dev, he_cap, i, nss);
+               mt7915_set_stream_he_txbf_caps(phy, he_cap, i);
 
                memset(he_cap->ppe_thres, 0, sizeof(he_cap->ppe_thres));
                if (he_cap_elem->phy_cap_info[6] &
index 89b519cfd14c3bb272c8f977ba00542a0975c2f3..0e852a7d3ecd8b7105cc04179213ecb91fbfbe8a 100644 (file)
@@ -953,7 +953,7 @@ mt7915_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
        struct mt7915_dev *dev = mt7915_hw_dev(hw);
        struct mt7915_phy *phy = mt7915_hw_phy(hw);
        int max_nss = hweight8(hw->wiphy->available_antennas_tx);
-       bool ext_phy = phy != &dev->phy;
+       u8 chainshift = dev->chainshift;
 
        if (!tx_ant || tx_ant != rx_ant || ffs(tx_ant) > max_nss)
                return -EINVAL;
@@ -965,10 +965,11 @@ mt7915_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
 
        phy->mt76->antenna_mask = tx_ant;
 
-       if (ext_phy)
-               tx_ant <<= dev->chainshift;
-
-       phy->mt76->chainmask = tx_ant;
+       /* handle a variant of mt7916 which has 3T3R but nss2 on 5 GHz band */
+       if (is_mt7916(&dev->mt76) && phy->band_idx && hweight8(tx_ant) == max_nss)
+               phy->mt76->chainmask = (dev->chainmask >> chainshift) << chainshift;
+       else
+               phy->mt76->chainmask = tx_ant << (chainshift * phy->band_idx);
 
        mt76_set_stream_caps(phy->mt76, true);
        mt7915_set_stream_vht_txbf_caps(phy);
index 1b9f3da8ae96c2012e40dae2d8e25a0107f10a86..b9ad24b1935a905ea7f4e712b87a32c9d4cfafb7 100644 (file)
@@ -485,7 +485,7 @@ static void
 mt7915_mcu_bss_ra_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
                      struct mt7915_phy *phy)
 {
-       int max_nss = hweight8(phy->mt76->chainmask);
+       int max_nss = hweight8(phy->mt76->antenna_mask);
        struct bss_info_ra *ra;
        struct tlv *tlv;
 
@@ -2617,8 +2617,8 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd)
                u8 control_ch;
                u8 center_ch;
                u8 bw;
-               u8 tx_streams_num;
-               u8 rx_streams;  /* mask or num */
+               u8 tx_path_num;
+               u8 rx_path;     /* mask or num */
                u8 switch_reason;
                u8 band_idx;
                u8 center_ch2;  /* for 80+80 only */
@@ -2634,8 +2634,8 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd)
                .control_ch = chandef->chan->hw_value,
                .center_ch = ieee80211_frequency_to_channel(freq1),
                .bw = mt76_connac_chan_bw(chandef),
-               .tx_streams_num = hweight8(phy->mt76->antenna_mask),
-               .rx_streams = phy->mt76->antenna_mask,
+               .tx_path_num = hweight16(phy->mt76->chainmask),
+               .rx_path = phy->mt76->chainmask >> (dev->chainshift * phy->band_idx),
                .band_idx = phy->band_idx,
                .channel_band = ch_band[chandef->chan->band],
        };
@@ -2645,8 +2645,8 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd)
            (phy->mt76->test.state == MT76_TM_STATE_TX_FRAMES ||
             phy->mt76->test.state == MT76_TM_STATE_RX_FRAMES ||
             phy->mt76->test.state == MT76_TM_STATE_TX_CONT)) {
-               req.tx_streams_num = fls(phy->mt76->test.tx_antenna_mask);
-               req.rx_streams = phy->mt76->test.tx_antenna_mask;
+               req.tx_path_num = fls(phy->mt76->test.tx_antenna_mask);
+               req.rx_path = phy->mt76->test.tx_antenna_mask;
 
                if (phy != &dev->phy)
                        req.rx_streams >>= dev->chainshift;
@@ -2665,7 +2665,7 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd)
                req.switch_reason = CH_SWITCH_NORMAL;
 
        if (cmd == MCU_EXT_CMD(CHANNEL_SWITCH))
-               req.rx_streams = hweight8(req.rx_streams);
+               req.rx_path = hweight8(req.rx_path);
 
        if (chandef->width == NL80211_CHAN_WIDTH_80P80) {
                int freq2 = chandef->center_freq2;