]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: rtw89: pci: add group BD address design
authorPing-Ke Shih <pkshih@realtek.com>
Tue, 26 Aug 2025 08:53:18 +0000 (16:53 +0800)
committerPing-Ke Shih <pkshih@realtek.com>
Mon, 1 Sep 2025 02:53:51 +0000 (10:53 +0800)
The newly designed group BD address is to use the same starting DMA address
with offset as below picture:

 Original            DMA memory         Group BD address

 +--------+  (*1)   +---------+   (*2)  +--------+
 |  CH 0 -|-------> |         | <-------|- CH 0  | <-+--+--+--+
 +--------+         |         |         |        |   |  |  |  |
 |  CH 1 -|-------> |         |         |  CH 1 -|---+  |  |  |
 +--------+         |         |         |        |      |  |  |
 |  CH 2 -|-------> |         |         |  CH 2 -|------+  |  |
 +--------+         |         |         |        |         |  |
 |  CH 3 -|-------> |         |         |  CH 3 -|---------+  |
 +--------+         |         |         |        |            |
 |    :  -|-------> |         |         |    :  -|------------+
 +--------+         |         |         +--------+   (*3; offset from CH 0)
 |  CH 8 -|-------> |         | <-------|- CH 8  | <-+
 +--------+         |         |         |        |   | (offset from CH 8)
 |    :  -|-------> |         |         |    :  -|---+
 +--------+         +---------+         +--------+

Compare (*1) and (*2), for original design, each DMA channel has
individual DMA address, so it is not necessary to allocate continual
DMA address across channels. For group BD address, only two DMA address
are set, and each channel set the offset (*3) from base address.

The element number and offset of a channel are encoded rather than a
raw number, so add a function to translate numbers into hardware format.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20250826085318.28361-1-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/pci.c
drivers/net/wireless/realtek/rtw89/pci.h
drivers/net/wireless/realtek/rtw89/rtw8851be.c
drivers/net/wireless/realtek/rtw89/rtw8852ae.c
drivers/net/wireless/realtek/rtw89/rtw8852be.c
drivers/net/wireless/realtek/rtw89/rtw8852bte.c
drivers/net/wireless/realtek/rtw89/rtw8852ce.c
drivers/net/wireless/realtek/rtw89/rtw8922ae.c

index d4f78396dfdef9faf9f07d61b81d779debd7601e..55d82af732c007596b518a4ae606428a454ff349 100644 (file)
@@ -988,6 +988,24 @@ exit:
        return irqret;
 }
 
+#define DEF_TXCHADDRS_TYPE3(gen, ch_idx, txch, v...) \
+       [RTW89_TXCH_##ch_idx] = { \
+               .num = R_##gen##_##txch##_TXBD_CFG, \
+               .idx = R_##gen##_##txch##_TXBD_IDX ##v, \
+               .bdram = 0, \
+               .desa_l = 0, \
+               .desa_h = 0, \
+       }
+
+#define DEF_TXCHADDRS_TYPE3_GRP_BASE(gen, ch_idx, txch, grp, v...) \
+       [RTW89_TXCH_##ch_idx] = { \
+               .num = R_##gen##_##txch##_TXBD_CFG, \
+               .idx = R_##gen##_##txch##_TXBD_IDX ##v, \
+               .bdram = 0, \
+               .desa_l = R_##gen##_##grp##_TXBD_DESA_L, \
+               .desa_h = R_##gen##_##grp##_TXBD_DESA_H, \
+       }
+
 #define DEF_TXCHADDRS_TYPE2(gen, ch_idx, txch, v...) \
        [RTW89_TXCH_##ch_idx] = { \
                .num = R_##gen##_##txch##_TXBD_NUM ##v, \
@@ -1015,6 +1033,22 @@ exit:
                .desa_h = R_AX_##txch##_TXBD_DESA_H ##v, \
        }
 
+#define DEF_RXCHADDRS_TYPE3(gen, ch_idx, rxch, v...) \
+       [RTW89_RXCH_##ch_idx] = { \
+               .num = R_##gen##_RX_##rxch##_RXBD_CONFIG, \
+               .idx = R_##gen##_##ch_idx##0_RXBD_IDX ##v, \
+               .desa_l = 0, \
+               .desa_h = 0, \
+       }
+
+#define DEF_RXCHADDRS_TYPE3_GRP_BASE(gen, ch_idx, rxch, grp, v...) \
+       [RTW89_RXCH_##ch_idx] = { \
+               .num = R_##gen##_RX_##rxch##_RXBD_CONFIG, \
+               .idx = R_##gen##_##ch_idx##0_RXBD_IDX ##v, \
+               .desa_l = R_##gen##_##grp##_RXBD_DESA_L, \
+               .desa_h = R_##gen##_##grp##_RXBD_DESA_H, \
+       }
+
 #define DEF_RXCHADDRS(gen, ch_idx, rxch, v...) \
        [RTW89_RXCH_##ch_idx] = { \
                .num = R_##gen##_##rxch##_RXBD_NUM ##v, \
@@ -1092,8 +1126,36 @@ const struct rtw89_pci_ch_dma_addr_set rtw89_pci_ch_dma_addr_set_be = {
 };
 EXPORT_SYMBOL(rtw89_pci_ch_dma_addr_set_be);
 
+const struct rtw89_pci_ch_dma_addr_set rtw89_pci_ch_dma_addr_set_be_v1 = {
+       .tx = {
+               DEF_TXCHADDRS_TYPE3_GRP_BASE(BE, ACH0, CH0, ACQ, _V1),
+               /* no CH1 */
+               DEF_TXCHADDRS_TYPE3(BE, ACH2, CH2, _V1),
+               /* no CH3 */
+               DEF_TXCHADDRS_TYPE3(BE, ACH4, CH4, _V1),
+               /* no CH5 */
+               DEF_TXCHADDRS_TYPE3(BE, ACH6, CH6, _V1),
+               /* no CH7 */
+               DEF_TXCHADDRS_TYPE3_GRP_BASE(BE, CH8, CH8, NACQ, _V1),
+               /* no CH9 */
+               DEF_TXCHADDRS_TYPE3(BE, CH10, CH10, _V1),
+               /* no CH11 */
+               DEF_TXCHADDRS_TYPE3(BE, CH12, CH12, _V1),
+       },
+       .rx = {
+               DEF_RXCHADDRS_TYPE3_GRP_BASE(BE, RXQ, CH0, HOST0, _V1),
+               DEF_RXCHADDRS_TYPE3(BE, RPQ, CH1, _V1),
+       },
+};
+EXPORT_SYMBOL(rtw89_pci_ch_dma_addr_set_be_v1);
+
+#undef DEF_TXCHADDRS_TYPE3
+#undef DEF_TXCHADDRS_TYPE3_GRP_BASE
+#undef DEF_TXCHADDRS_TYPE2
 #undef DEF_TXCHADDRS_TYPE1
 #undef DEF_TXCHADDRS
+#undef DEF_RXCHADDRS_TYPE3
+#undef DEF_RXCHADDRS_TYPE3_GRP_BASE
 #undef DEF_RXCHADDRS
 
 static int rtw89_pci_get_txch_addrs(struct rtw89_dev *rtwdev,
@@ -1645,6 +1707,41 @@ static void rtw89_pci_init_wp_16sel(struct rtw89_dev *rtwdev)
        }
 }
 
+static u16 rtw89_pci_enc_bd_cfg(struct rtw89_dev *rtwdev, u16 bd_num,
+                               u32 dma_offset)
+{
+       u16 dma_offset_sel;
+       u16 num_sel;
+
+       /* B_BE_TX_NUM_SEL_MASK, B_BE_RX_NUM_SEL_MASK:
+        *  0 -> 0
+        *  1 -> 64 = 2^6
+        *  2 -> 128 = 2^7
+        *    ...
+        *  7 -> 4096 = 2^12
+        */
+       num_sel = ilog2(bd_num) - 5;
+
+       if (hweight16(bd_num) != 1)
+               rtw89_warn(rtwdev, "bd_num %u is not power of 2\n", bd_num);
+
+       /* B_BE_TX_START_OFFSET_MASK, B_BE_RX_START_OFFSET_MASK:
+        *  0 -> 0    = 0 * 2^9
+        *  1 -> 512  = 1 * 2^9
+        *  2 -> 1024 = 2 * 2^9
+        *  3 -> 1536 = 3 * 2^9
+        *    ...
+        *  255 -> 130560 = 255 * 2^9
+        */
+       dma_offset_sel = dma_offset >> 9;
+
+       if (dma_offset % 512)
+               rtw89_warn(rtwdev, "offset %u is not multiple of 512\n", dma_offset);
+
+       return u16_encode_bits(num_sel, B_BE_TX_NUM_SEL_MASK) |
+              u16_encode_bits(dma_offset_sel, B_BE_TX_START_OFFSET_MASK);
+}
+
 static void rtw89_pci_reset_trx_rings(struct rtw89_dev *rtwdev)
 {
        struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
@@ -1654,10 +1751,12 @@ static void rtw89_pci_reset_trx_rings(struct rtw89_dev *rtwdev)
        struct rtw89_pci_rx_ring *rx_ring;
        struct rtw89_pci_dma_ring *bd_ring;
        const struct rtw89_pci_bd_ram *bd_ram;
+       dma_addr_t group_dma_base = 0;
+       u16 num_or_offset;
+       u32 addr_desa_l;
+       u32 addr_bdram;
        u32 addr_num;
        u32 addr_idx;
-       u32 addr_bdram;
-       u32 addr_desa_l;
        u32 val32;
        int i;
 
@@ -1674,7 +1773,18 @@ static void rtw89_pci_reset_trx_rings(struct rtw89_dev *rtwdev)
                bd_ring->wp = 0;
                bd_ring->rp = 0;
 
-               rtw89_write16(rtwdev, addr_num, bd_ring->len);
+               if (info->group_bd_addr) {
+                       if (addr_desa_l)
+                               group_dma_base = bd_ring->dma;
+
+                       num_or_offset =
+                               rtw89_pci_enc_bd_cfg(rtwdev, bd_ring->len,
+                                                    bd_ring->dma - group_dma_base);
+               } else {
+                       num_or_offset = bd_ring->len;
+               }
+               rtw89_write16(rtwdev, addr_num, num_or_offset);
+
                if (addr_bdram && bd_ram) {
                        val32 = FIELD_PREP(BDRAM_SIDX_MASK, bd_ram->start_idx) |
                                FIELD_PREP(BDRAM_MAX_MASK, bd_ram->max_num) |
@@ -1682,8 +1792,10 @@ static void rtw89_pci_reset_trx_rings(struct rtw89_dev *rtwdev)
 
                        rtw89_write32(rtwdev, addr_bdram, val32);
                }
-               rtw89_write32(rtwdev, addr_desa_l, bd_ring->dma);
-               rtw89_write32(rtwdev, addr_desa_l + 4, upper_32_bits(bd_ring->dma));
+               if (addr_desa_l) {
+                       rtw89_write32(rtwdev, addr_desa_l, bd_ring->dma);
+                       rtw89_write32(rtwdev, addr_desa_l + 4, upper_32_bits(bd_ring->dma));
+               }
        }
 
        for (i = 0; i < RTW89_RXCH_NUM; i++) {
@@ -1701,9 +1813,22 @@ static void rtw89_pci_reset_trx_rings(struct rtw89_dev *rtwdev)
                rx_ring->diliver_desc.ready = false;
                rx_ring->target_rx_tag = 0;
 
-               rtw89_write16(rtwdev, addr_num, bd_ring->len);
-               rtw89_write32(rtwdev, addr_desa_l, bd_ring->dma);
-               rtw89_write32(rtwdev, addr_desa_l + 4, upper_32_bits(bd_ring->dma));
+               if (info->group_bd_addr) {
+                       if (addr_desa_l)
+                               group_dma_base = bd_ring->dma;
+
+                       num_or_offset =
+                               rtw89_pci_enc_bd_cfg(rtwdev, bd_ring->len,
+                                                    bd_ring->dma - group_dma_base);
+               } else {
+                       num_or_offset = bd_ring->len;
+               }
+               rtw89_write16(rtwdev, addr_num, num_or_offset);
+
+               if (addr_desa_l) {
+                       rtw89_write32(rtwdev, addr_desa_l, bd_ring->dma);
+                       rtw89_write32(rtwdev, addr_desa_l + 4, upper_32_bits(bd_ring->dma));
+               }
 
                if (info->rx_ring_eq_is_full)
                        rtw89_write16(rtwdev, addr_idx, bd_ring->wp);
index f00d717b668bfaaeb7216a68e1cc03644e8b770a..e8a856537b7c51ffeceb4e8efcd1499784b1b4e9 100644 (file)
 #define R_BE_CH13_TXBD_NUM_V1 0xB04C
 #define R_BE_CH14_TXBD_NUM_V1 0xB04E
 
+#define R_BE_CH0_TXBD_CFG 0xB030
+#define R_BE_CH2_TXBD_CFG 0xB034
+#define R_BE_CH4_TXBD_CFG 0xB038
+#define R_BE_CH6_TXBD_CFG 0xB03C
+#define R_BE_CH8_TXBD_CFG 0xB040
+#define R_BE_CH10_TXBD_CFG 0xB044
+#define R_BE_CH12_TXBD_CFG 0xB048
+#define B_BE_TX_FLAG BIT(14)
+#define B_BE_TX_START_OFFSET_MASK GENMASK(12, 4)
+#define B_BE_TX_NUM_SEL_MASK GENMASK(2, 0)
+
 #define R_BE_RXQ0_RXBD_NUM_V1 0xB050
 #define R_BE_RPQ0_RXBD_NUM_V1 0xB052
 
+#define R_BE_RX_CH0_RXBD_CONFIG 0xB050
+#define R_BE_RX_CH1_RXBD_CONFIG 0xB052
+#define B_BE_RX_START_OFFSET_MASK GENMASK(11, 4)
+#define B_BE_RX_NUM_SEL_MASK GENMASK(2, 0)
+
 #define R_BE_CH0_TXBD_IDX_V1 0xB100
 #define R_BE_CH1_TXBD_IDX_V1 0xB104
 #define R_BE_CH2_TXBD_IDX_V1 0xB108
 #define R_BE_CH14_TXBD_DESA_L_V1 0xB270
 #define R_BE_CH14_TXBD_DESA_H_V1 0xB274
 
+#define R_BE_ACQ_TXBD_DESA_L 0xB200
+#define B_BE_TX_ACQ_DESA_L_MASK GENMASK(31, 3)
+#define R_BE_ACQ_TXBD_DESA_H 0xB204
+#define B_BE_TX_ACQ_DESA_H_MASK GENMASK(7, 0)
+#define R_BE_NACQ_TXBD_DESA_L 0xB240
+#define B_BE_TX_NACQ_DESA_L_MASK GENMASK(31, 3)
+#define R_BE_NACQ_TXBD_DESA_H 0xB244
+#define B_BE_TX_NACQ_DESA_H_MASK GENMASK(7, 0)
+
 #define R_BE_RXQ0_RXBD_DESA_L_V1 0xB300
 #define R_BE_RXQ0_RXBD_DESA_H_V1 0xB304
 #define R_BE_RPQ0_RXBD_DESA_L_V1 0xB308
 #define R_BE_RPQ0_RXBD_DESA_H_V1 0xB30C
 
+#define R_BE_HOST0_RXBD_DESA_L 0xB300
+#define B_BE_RX_HOST0_DESA_L_MASK GENMASK(31, 3)
+#define R_BE_HOST0_RXBD_DESA_H 0xB304
+#define B_BE_RX_HOST0_DESA_H_MASK GENMASK(7, 0)
+
 #define R_BE_WP_ADDR_H_SEL0_3_V1 0xB420
 #define R_BE_WP_ADDR_H_SEL4_7_V1 0xB424
 #define R_BE_WP_ADDR_H_SEL8_11_V1 0xB428
@@ -1273,7 +1303,7 @@ struct rtw89_pci_bd_idx_addr {
 };
 
 struct rtw89_pci_ch_dma_addr {
-       u32 num;
+       u32 num; /* also `offset` addr for group_bd_addr design */
        u32 idx;
        u32 bdram;
        u32 desa_l;
@@ -1355,6 +1385,7 @@ struct rtw89_pci_info {
        bool rx_ring_eq_is_full;
        bool check_rx_tag;
        bool no_rxbd_fs;
+       bool group_bd_addr;
 
        u32 init_cfg_reg;
        u32 txhci_en_bit;
@@ -1669,6 +1700,7 @@ extern const struct pci_error_handlers rtw89_pci_err_handler;
 extern const struct rtw89_pci_ch_dma_addr_set rtw89_pci_ch_dma_addr_set;
 extern const struct rtw89_pci_ch_dma_addr_set rtw89_pci_ch_dma_addr_set_v1;
 extern const struct rtw89_pci_ch_dma_addr_set rtw89_pci_ch_dma_addr_set_be;
+extern const struct rtw89_pci_ch_dma_addr_set rtw89_pci_ch_dma_addr_set_be_v1;
 extern const struct rtw89_pci_bd_ram rtw89_bd_ram_table_dual[RTW89_TXCH_NUM];
 extern const struct rtw89_pci_bd_ram rtw89_bd_ram_table_single[RTW89_TXCH_NUM];
 extern const struct rtw89_pci_isr_def rtw89_pci_isr_ax;
index c9d60870ed9e046269097b79b0f660ddd37df052..d2ea1e237a1f3b23201e0ee514b9763eb6375e59 100644 (file)
@@ -29,6 +29,7 @@ static const struct rtw89_pci_info rtw8851b_pci_info = {
        .rx_ring_eq_is_full     = false,
        .check_rx_tag           = false,
        .no_rxbd_fs             = false,
+       .group_bd_addr          = false,
 
        .init_cfg_reg           = R_AX_PCIE_INIT_CFG1,
        .txhci_en_bit           = B_AX_TXHCI_EN,
index 1bfade7e7e1b7aa9da0b16f2ea3a23fca632d07c..d733264b5dd1834f6e7b34b1782bb67bc0203955 100644 (file)
@@ -29,6 +29,7 @@ static const struct rtw89_pci_info rtw8852a_pci_info = {
        .rx_ring_eq_is_full     = false,
        .check_rx_tag           = false,
        .no_rxbd_fs             = false,
+       .group_bd_addr          = false,
 
        .init_cfg_reg           = R_AX_PCIE_INIT_CFG1,
        .txhci_en_bit           = B_AX_TXHCI_EN,
index 8f7676a0a89e315faea3e92081a6dadb4ade7cb9..146a1f2292d7c3e09bb003f99d7473a4701132b9 100644 (file)
@@ -29,6 +29,7 @@ static const struct rtw89_pci_info rtw8852b_pci_info = {
        .rx_ring_eq_is_full     = false,
        .check_rx_tag           = false,
        .no_rxbd_fs             = false,
+       .group_bd_addr          = false,
 
        .init_cfg_reg           = R_AX_PCIE_INIT_CFG1,
        .txhci_en_bit           = B_AX_TXHCI_EN,
index 642ab20e9d06b8a003f13ecc365fc2ccf242a586..5373b13e34708f09a345e27819305f0d00970ce6 100644 (file)
@@ -35,6 +35,7 @@ static const struct rtw89_pci_info rtw8852bt_pci_info = {
        .rx_ring_eq_is_full     = false,
        .check_rx_tag           = false,
        .no_rxbd_fs             = false,
+       .group_bd_addr          = false,
 
        .init_cfg_reg           = R_AX_PCIE_INIT_CFG1,
        .txhci_en_bit           = B_AX_TXHCI_EN,
index 4c7682f1d00c4df1b13a558c81a96f31ffece1c1..b2bf4ba6ddd84bcf3c881740480f5f60171c3d2e 100644 (file)
@@ -38,6 +38,7 @@ static const struct rtw89_pci_info rtw8852c_pci_info = {
        .rx_ring_eq_is_full     = false,
        .check_rx_tag           = false,
        .no_rxbd_fs             = false,
+       .group_bd_addr          = false,
 
        .init_cfg_reg           = R_AX_HAXI_INIT_CFG1,
        .txhci_en_bit           = B_AX_TXHCI_EN_V1,
index a0fc6b2832e16f313e2a9fb2026c832f145b25ee..32144fc66e4ad83a76baa78ce8bd8403b84b61e5 100644 (file)
@@ -35,6 +35,7 @@ static const struct rtw89_pci_info rtw8922a_pci_info = {
        .rx_ring_eq_is_full     = true,
        .check_rx_tag           = true,
        .no_rxbd_fs             = true,
+       .group_bd_addr          = false,
 
        .init_cfg_reg           = R_BE_HAXI_INIT_CFG1,
        .txhci_en_bit           = B_BE_TXDMA_EN,