]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: rtw89: 8922d: add set channel of MAC part
authorPing-Ke Shih <pkshih@realtek.com>
Tue, 24 Mar 2026 06:20:47 +0000 (14:20 +0800)
committerPing-Ke Shih <pkshih@realtek.com>
Mon, 30 Mar 2026 02:08:37 +0000 (10:08 +0800)
The set channel is a key function to switch to specific operating channel.
For MAC part, configure hardware according to channel bandwidth, and
enable CCK rate for 2GHz band only.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20260324062049.52266-6-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/reg.h
drivers/net/wireless/realtek/rtw89/rtw8922d.c

index 179006c8e4996986049276cd85da46a1f1ffd7f8..2195f576faccadc15cb08320949a4ec31b7fcdfa 100644 (file)
 #define R_BE_MUEDCA_EN 0x10370
 #define R_BE_MUEDCA_EN_C1 0x14370
 #define B_BE_SIFS_TIMEOUT_TB_T2_MASK GENMASK(30, 24)
+#define B_BE_SIFS_MACTXEN_TB_T1_DOT05US_MASK GENMASK(23, 16)
 #define B_BE_SIFS_MACTXEN_TB_T1_MASK GENMASK(22, 16)
 #define B_BE_MUEDCA_WMM_SEL BIT(8)
 #define B_BE_SET_MUEDCATIMER_TF_MASK GENMASK(5, 4)
index cbe8e067ae55d98472f69e2261568412b17da7dd..a341734ef54d55528ef844f0ebe7bf5c9ec35f5a 100644 (file)
@@ -5,6 +5,7 @@
 #include "debug.h"
 #include "efuse.h"
 #include "mac.h"
+#include "phy.h"
 #include "reg.h"
 #include "rtw8922d.h"
 
@@ -835,6 +836,97 @@ static void rtw8922d_power_trim(struct rtw89_dev *rtwdev)
        rtw8922d_pad_bias_trim(rtwdev);
 }
 
+static void rtw8922d_set_channel_mac(struct rtw89_dev *rtwdev,
+                                    const struct rtw89_chan *chan,
+                                    u8 mac_idx)
+{
+       u32 sub_carr = rtw89_mac_reg_by_idx(rtwdev, R_BE_TX_SUB_BAND_VALUE, mac_idx);
+       u32 chk_rate = rtw89_mac_reg_by_idx(rtwdev, R_BE_TXRATE_CHK, mac_idx);
+       u32 rf_mod = rtw89_mac_reg_by_idx(rtwdev, R_BE_WMAC_RFMOD, mac_idx);
+       u8 txsb20 = 0, txsb40 = 0, txsb80 = 0;
+       u8 rf_mod_val, chk_rate_mask, sifs;
+       u32 txsb;
+       u32 reg;
+
+       switch (chan->band_width) {
+       case RTW89_CHANNEL_WIDTH_160:
+               txsb80 = rtw89_phy_get_txsb(rtwdev, chan, RTW89_CHANNEL_WIDTH_80);
+               fallthrough;
+       case RTW89_CHANNEL_WIDTH_80:
+               txsb40 = rtw89_phy_get_txsb(rtwdev, chan, RTW89_CHANNEL_WIDTH_40);
+               fallthrough;
+       case RTW89_CHANNEL_WIDTH_40:
+               txsb20 = rtw89_phy_get_txsb(rtwdev, chan, RTW89_CHANNEL_WIDTH_20);
+               break;
+       default:
+               break;
+       }
+
+       switch (chan->band_width) {
+       case RTW89_CHANNEL_WIDTH_160:
+               rf_mod_val = BE_WMAC_RFMOD_160M;
+               txsb = u32_encode_bits(txsb20, B_BE_TXSB_20M_MASK) |
+                      u32_encode_bits(txsb40, B_BE_TXSB_40M_MASK) |
+                      u32_encode_bits(txsb80, B_BE_TXSB_80M_MASK);
+               break;
+       case RTW89_CHANNEL_WIDTH_80:
+               rf_mod_val = BE_WMAC_RFMOD_80M;
+               txsb = u32_encode_bits(txsb20, B_BE_TXSB_20M_MASK) |
+                      u32_encode_bits(txsb40, B_BE_TXSB_40M_MASK);
+               break;
+       case RTW89_CHANNEL_WIDTH_40:
+               rf_mod_val = BE_WMAC_RFMOD_40M;
+               txsb = u32_encode_bits(txsb20, B_BE_TXSB_20M_MASK);
+               break;
+       case RTW89_CHANNEL_WIDTH_20:
+       default:
+               rf_mod_val = BE_WMAC_RFMOD_20M;
+               txsb = 0;
+               break;
+       }
+
+       if (txsb20 <= BE_PRI20_BITMAP_MAX)
+               txsb |= u32_encode_bits(BIT(txsb20), B_BE_PRI20_BITMAP_MASK);
+
+       rtw89_write8_mask(rtwdev, rf_mod, B_BE_WMAC_RFMOD_MASK, rf_mod_val);
+       rtw89_write32(rtwdev, sub_carr, txsb);
+
+       switch (chan->band_type) {
+       case RTW89_BAND_2G:
+               chk_rate_mask = B_BE_BAND_MODE;
+               break;
+       case RTW89_BAND_5G:
+       case RTW89_BAND_6G:
+               chk_rate_mask = B_BE_CHECK_CCK_EN | B_BE_RTS_LIMIT_IN_OFDM6;
+               break;
+       default:
+               rtw89_warn(rtwdev, "Invalid band_type:%d\n", chan->band_type);
+               return;
+       }
+
+       rtw89_write8_clr(rtwdev, chk_rate, B_BE_BAND_MODE | B_BE_CHECK_CCK_EN |
+                                          B_BE_RTS_LIMIT_IN_OFDM6);
+       rtw89_write8_set(rtwdev, chk_rate, chk_rate_mask);
+
+       switch (chan->band_width) {
+       case RTW89_CHANNEL_WIDTH_160:
+               sifs = 0x8C;
+               break;
+       case RTW89_CHANNEL_WIDTH_80:
+               sifs = 0x8A;
+               break;
+       case RTW89_CHANNEL_WIDTH_40:
+               sifs = 0x84;
+               break;
+       case RTW89_CHANNEL_WIDTH_20:
+       default:
+               sifs = 0x82;
+       }
+
+       reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_MUEDCA_EN, mac_idx);
+       rtw89_write32_mask(rtwdev, reg, B_BE_SIFS_MACTXEN_TB_T1_DOT05US_MASK, sifs);
+}
+
 MODULE_FIRMWARE(RTW8922D_MODULE_FIRMWARE);
 MODULE_FIRMWARE(RTW8922DS_MODULE_FIRMWARE);
 MODULE_AUTHOR("Realtek Corporation");