[PATCH 38/44] net: mana: Add support for page sizes other than 4KB on ARM64
authorHaiyang Zhang <haiyangz@microsoft.com>
Mon, 17 Jun 2024 20:17:26 +0000 (13:17 -0700)
committerSalvatore Bonaccorso <carnil@debian.org>
Thu, 10 Apr 2025 19:32:42 +0000 (21:32 +0200)
As defined by the MANA Hardware spec, the queue size for DMA is 4KB
minimal, and power of 2. And, the HWC queue size has to be exactly
4KB.

To support page sizes other than 4KB on ARM64, define the minimal
queue size as a macro separately from the PAGE_SIZE, which we always
assumed it to be 4KB before supporting ARM64.

Also, add MANA specific macros and update code related to size
alignment, DMA region calculations, etc.

Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
Reviewed-by: Michael Kelley <mhklinux@outlook.com>
Link: https://lore.kernel.org/r/1718655446-6576-1-git-send-email-haiyangz@microsoft.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
(cherry picked from commit 382d1741b5b2feffef7942dd074206372afe1a96)
Signed-off-by: Bastian Blank <waldi@debian.org>
Gbp-Pq: Topic features/all/ethernet-microsoft
Gbp-Pq: Name 0038-net-mana-Add-support-for-page-sizes-other-than-4KB-o.patch

drivers/net/ethernet/microsoft/Kconfig
drivers/net/ethernet/microsoft/mana/gdma_main.c
drivers/net/ethernet/microsoft/mana/hw_channel.c
drivers/net/ethernet/microsoft/mana/mana_en.c
drivers/net/ethernet/microsoft/mana/shm_channel.c
include/net/mana/gdma.h
include/net/mana/mana.h

index 286f0d5697a16c0035215dfb1b4e6cd8dc2fe695..901fbffbf718ee87905b18e44d62bdee6645c428 100644 (file)
@@ -18,7 +18,7 @@ if NET_VENDOR_MICROSOFT
 config MICROSOFT_MANA
        tristate "Microsoft Azure Network Adapter (MANA) support"
        depends on PCI_MSI
-       depends on X86_64 || (ARM64 && !CPU_BIG_ENDIAN && ARM64_4K_PAGES)
+       depends on X86_64 || (ARM64 && !CPU_BIG_ENDIAN)
        depends on PCI_HYPERV
        select AUXILIARY_BUS
        select PAGE_POOL
index 4fa1901a2789aa83e670df1db6ce0822ebb00887..de36babf703159b19bb75b4a589febff8f4a9fef 100644 (file)
@@ -179,7 +179,7 @@ int mana_gd_alloc_memory(struct gdma_context *gc, unsigned int length,
        dma_addr_t dma_handle;
        void *buf;
 
-       if (length < PAGE_SIZE || !is_power_of_2(length))
+       if (length < MANA_PAGE_SIZE || !is_power_of_2(length))
                return -EINVAL;
 
        gmi->dev = gc->dev;
@@ -721,7 +721,7 @@ EXPORT_SYMBOL_NS(mana_gd_destroy_dma_region, NET_MANA);
 static int mana_gd_create_dma_region(struct gdma_dev *gd,
                                     struct gdma_mem_info *gmi)
 {
-       unsigned int num_page = gmi->length / PAGE_SIZE;
+       unsigned int num_page = gmi->length / MANA_PAGE_SIZE;
        struct gdma_create_dma_region_req *req = NULL;
        struct gdma_create_dma_region_resp resp = {};
        struct gdma_context *gc = gd->gdma_context;
@@ -731,10 +731,10 @@ static int mana_gd_create_dma_region(struct gdma_dev *gd,
        int err;
        int i;
 
-       if (length < PAGE_SIZE || !is_power_of_2(length))
+       if (length < MANA_PAGE_SIZE || !is_power_of_2(length))
                return -EINVAL;
 
-       if (offset_in_page(gmi->virt_addr) != 0)
+       if (!MANA_PAGE_ALIGNED(gmi->virt_addr))
                return -EINVAL;
 
        hwc = gc->hwc.driver_data;
@@ -755,7 +755,7 @@ static int mana_gd_create_dma_region(struct gdma_dev *gd,
        req->page_addr_list_len = num_page;
 
        for (i = 0; i < num_page; i++)
-               req->page_addr_list[i] = gmi->dma_handle +  i * PAGE_SIZE;
+               req->page_addr_list[i] = gmi->dma_handle +  i * MANA_PAGE_SIZE;
 
        err = mana_gd_send_request(gc, req_msg_size, req, sizeof(resp), &resp);
        if (err)
index 236daa0535ba008ed893e9b45d5db6205e19d304..9d6426d4158e31423bcd20643f329e189f18fdd0 100644 (file)
@@ -366,12 +366,12 @@ static int mana_hwc_create_cq(struct hw_channel_context *hwc, u16 q_depth,
        int err;
 
        eq_size = roundup_pow_of_two(GDMA_EQE_SIZE * q_depth);
-       if (eq_size < MINIMUM_SUPPORTED_PAGE_SIZE)
-               eq_size = MINIMUM_SUPPORTED_PAGE_SIZE;
+       if (eq_size < MANA_MIN_QSIZE)
+               eq_size = MANA_MIN_QSIZE;
 
        cq_size = roundup_pow_of_two(GDMA_CQE_SIZE * q_depth);
-       if (cq_size < MINIMUM_SUPPORTED_PAGE_SIZE)
-               cq_size = MINIMUM_SUPPORTED_PAGE_SIZE;
+       if (cq_size < MANA_MIN_QSIZE)
+               cq_size = MANA_MIN_QSIZE;
 
        hwc_cq = kzalloc(sizeof(*hwc_cq), GFP_KERNEL);
        if (!hwc_cq)
@@ -433,7 +433,7 @@ static int mana_hwc_alloc_dma_buf(struct hw_channel_context *hwc, u16 q_depth,
 
        dma_buf->num_reqs = q_depth;
 
-       buf_size = PAGE_ALIGN(q_depth * max_msg_size);
+       buf_size = MANA_PAGE_ALIGN(q_depth * max_msg_size);
 
        gmi = &dma_buf->mem_info;
        err = mana_gd_alloc_memory(gc, buf_size, gmi);
@@ -501,8 +501,8 @@ static int mana_hwc_create_wq(struct hw_channel_context *hwc,
        else
                queue_size = roundup_pow_of_two(GDMA_MAX_SQE_SIZE * q_depth);
 
-       if (queue_size < MINIMUM_SUPPORTED_PAGE_SIZE)
-               queue_size = MINIMUM_SUPPORTED_PAGE_SIZE;
+       if (queue_size < MANA_MIN_QSIZE)
+               queue_size = MANA_MIN_QSIZE;
 
        hwc_wq = kzalloc(sizeof(*hwc_wq), GFP_KERNEL);
        if (!hwc_wq)
index bcf0a86b5665c299cc4e85947332349c456b6aad..a5b4bdcd2f99288ead6185f6ca19b61a032b4a9b 100644 (file)
@@ -1803,10 +1803,10 @@ static int mana_create_txq(struct mana_port_context *apc,
         *  to prevent overflow.
         */
        txq_size = MAX_SEND_BUFFERS_PER_QUEUE * 32;
-       BUILD_BUG_ON(!PAGE_ALIGNED(txq_size));
+       BUILD_BUG_ON(!MANA_PAGE_ALIGNED(txq_size));
 
        cq_size = MAX_SEND_BUFFERS_PER_QUEUE * COMP_ENTRY_SIZE;
-       cq_size = PAGE_ALIGN(cq_size);
+       cq_size = MANA_PAGE_ALIGN(cq_size);
 
        gc = gd->gdma_context;
 
@@ -2066,8 +2066,8 @@ static struct mana_rxq *mana_create_rxq(struct mana_port_context *apc,
        if (err)
                goto out;
 
-       rq_size = PAGE_ALIGN(rq_size);
-       cq_size = PAGE_ALIGN(cq_size);
+       rq_size = MANA_PAGE_ALIGN(rq_size);
+       cq_size = MANA_PAGE_ALIGN(cq_size);
 
        /* Create RQ */
        memset(&spec, 0, sizeof(spec));
index 5553af9c8085a1b93735f40e3910e19f3e5daf29..0f1679ebad96babdcf5ba9a92910feaf77e4e22c 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/io.h>
 #include <linux/mm.h>
 
+#include <net/mana/gdma.h>
 #include <net/mana/shm_channel.h>
 
 #define PAGE_FRAME_L48_WIDTH_BYTES 6
@@ -155,8 +156,8 @@ int mana_smc_setup_hwc(struct shm_channel *sc, bool reset_vf, u64 eq_addr,
                return err;
        }
 
-       if (!PAGE_ALIGNED(eq_addr) || !PAGE_ALIGNED(cq_addr) ||
-           !PAGE_ALIGNED(rq_addr) || !PAGE_ALIGNED(sq_addr))
+       if (!MANA_PAGE_ALIGNED(eq_addr) || !MANA_PAGE_ALIGNED(cq_addr) ||
+           !MANA_PAGE_ALIGNED(rq_addr) || !MANA_PAGE_ALIGNED(sq_addr))
                return -EINVAL;
 
        if ((eq_msix_index & VECTOR_MASK) != eq_msix_index)
@@ -183,7 +184,7 @@ int mana_smc_setup_hwc(struct shm_channel *sc, bool reset_vf, u64 eq_addr,
 
        /* EQ addr: low 48 bits of frame address */
        shmem = (u64 *)ptr;
-       frame_addr = PHYS_PFN(eq_addr);
+       frame_addr = MANA_PFN(eq_addr);
        *shmem = frame_addr & PAGE_FRAME_L48_MASK;
        all_addr_h4bits |= (frame_addr >> PAGE_FRAME_L48_WIDTH_BITS) <<
                (frame_addr_seq++ * PAGE_FRAME_H4_WIDTH_BITS);
@@ -191,7 +192,7 @@ int mana_smc_setup_hwc(struct shm_channel *sc, bool reset_vf, u64 eq_addr,
 
        /* CQ addr: low 48 bits of frame address */
        shmem = (u64 *)ptr;
-       frame_addr = PHYS_PFN(cq_addr);
+       frame_addr = MANA_PFN(cq_addr);
        *shmem = frame_addr & PAGE_FRAME_L48_MASK;
        all_addr_h4bits |= (frame_addr >> PAGE_FRAME_L48_WIDTH_BITS) <<
                (frame_addr_seq++ * PAGE_FRAME_H4_WIDTH_BITS);
@@ -199,7 +200,7 @@ int mana_smc_setup_hwc(struct shm_channel *sc, bool reset_vf, u64 eq_addr,
 
        /* RQ addr: low 48 bits of frame address */
        shmem = (u64 *)ptr;
-       frame_addr = PHYS_PFN(rq_addr);
+       frame_addr = MANA_PFN(rq_addr);
        *shmem = frame_addr & PAGE_FRAME_L48_MASK;
        all_addr_h4bits |= (frame_addr >> PAGE_FRAME_L48_WIDTH_BITS) <<
                (frame_addr_seq++ * PAGE_FRAME_H4_WIDTH_BITS);
@@ -207,7 +208,7 @@ int mana_smc_setup_hwc(struct shm_channel *sc, bool reset_vf, u64 eq_addr,
 
        /* SQ addr: low 48 bits of frame address */
        shmem = (u64 *)ptr;
-       frame_addr = PHYS_PFN(sq_addr);
+       frame_addr = MANA_PFN(sq_addr);
        *shmem = frame_addr & PAGE_FRAME_L48_MASK;
        all_addr_h4bits |= (frame_addr >> PAGE_FRAME_L48_WIDTH_BITS) <<
                (frame_addr_seq++ * PAGE_FRAME_H4_WIDTH_BITS);
index 102bb73c7a4fabc733ba294831d754b8e06751da..941c356ef6b49ecfe0735b4b53f55d709cb9325d 100644 (file)
@@ -220,7 +220,15 @@ struct gdma_dev {
        struct auxiliary_device *adev;
 };
 
-#define MINIMUM_SUPPORTED_PAGE_SIZE PAGE_SIZE
+/* MANA_PAGE_SIZE is the DMA unit */
+#define MANA_PAGE_SHIFT 12
+#define MANA_PAGE_SIZE BIT(MANA_PAGE_SHIFT)
+#define MANA_PAGE_ALIGN(x) ALIGN((x), MANA_PAGE_SIZE)
+#define MANA_PAGE_ALIGNED(addr) IS_ALIGNED((unsigned long)(addr), MANA_PAGE_SIZE)
+#define MANA_PFN(a) ((a) >> MANA_PAGE_SHIFT)
+
+/* Required by HW */
+#define MANA_MIN_QSIZE MANA_PAGE_SIZE
 
 #define GDMA_CQE_SIZE 64
 #define GDMA_EQE_SIZE 16
index bfc9050b1f5e1df64f8a8c4256bca1ca336ac221..a5802cef3af0e08202dd9ba812076fecbeca38ac 100644 (file)
@@ -40,7 +40,8 @@ enum TRI_STATE {
 
 #define MAX_SEND_BUFFERS_PER_QUEUE 256
 
-#define EQ_SIZE (8 * PAGE_SIZE)
+#define EQ_SIZE (8 * MANA_PAGE_SIZE)
+
 #define LOG2_EQ_THROTTLE 3
 
 #define MAX_PORTS_IN_MANA_DEV 256