]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: ti: icssg-prueth: Fix buffer allocation for ICSSG
authorHimanshu Mittal <h-mittal1@ti.com>
Thu, 17 Jul 2025 09:42:20 +0000 (15:12 +0530)
committerJakub Kicinski <kuba@kernel.org>
Sat, 19 Jul 2025 00:20:45 +0000 (17:20 -0700)
Fixes overlapping buffer allocation for ICSSG peripheral
used for storing packets to be received/transmitted.
There are 3 buffers:
1. Buffer for Locally Injected Packets
2. Buffer for Forwarding Packets
3. Buffer for Host Egress Packets

In existing allocation buffers for 2. and 3. are overlapping causing
packet corruption.

Packet corruption observations:
During tcp iperf testing, due to overlapping buffers the received ack
packet overwrites the packet to be transmitted. So, we see packets on
wire with the ack packet content inside the content of next TCP packet
from sender device.

Details for AM64x switch mode:
-> Allocation by existing driver:
+---------+-------------------------------------------------------------+
|         |          SLICE 0             |          SLICE 1             |
|         +------+--------------+--------+------+--------------+--------+
|         | Slot | Base Address | Size   | Slot | Base Address | Size   |
|---------+------+--------------+--------+------+--------------+--------+
|         | 0    | 70000000     | 0x2000 | 0    | 70010000     | 0x2000 |
|         | 1    | 70002000     | 0x2000 | 1    | 70012000     | 0x2000 |
|         | 2    | 70004000     | 0x2000 | 2    | 70014000     | 0x2000 |
| FWD     | 3    | 70006000     | 0x2000 | 3    | 70016000     | 0x2000 |
| Buffers | 4    | 70008000     | 0x2000 | 4    | 70018000     | 0x2000 |
|         | 5    | 7000A000     | 0x2000 | 5    | 7001A000     | 0x2000 |
|         | 6    | 7000C000     | 0x2000 | 6    | 7001C000     | 0x2000 |
|         | 7    | 7000E000     | 0x2000 | 7    | 7001E000     | 0x2000 |
+---------+------+--------------+--------+------+--------------+--------+
|         | 8    | 70020000     | 0x1000 | 8    | 70028000     | 0x1000 |
|         | 9    | 70021000     | 0x1000 | 9    | 70029000     | 0x1000 |
|         | 10   | 70022000     | 0x1000 | 10   | 7002A000     | 0x1000 |
| Our     | 11   | 70023000     | 0x1000 | 11   | 7002B000     | 0x1000 |
| LI      | 12   | 00000000     | 0x0    | 12   | 00000000     | 0x0    |
| Buffers | 13   | 00000000     | 0x0    | 13   | 00000000     | 0x0    |
|         | 14   | 00000000     | 0x0    | 14   | 00000000     | 0x0    |
|         | 15   | 00000000     | 0x0    | 15   | 00000000     | 0x0    |
+---------+------+--------------+--------+------+--------------+--------+
|         | 16   | 70024000     | 0x1000 | 16   | 7002C000     | 0x1000 |
|         | 17   | 70025000     | 0x1000 | 17   | 7002D000     | 0x1000 |
|         | 18   | 70026000     | 0x1000 | 18   | 7002E000     | 0x1000 |
| Their   | 19   | 70027000     | 0x1000 | 19   | 7002F000     | 0x1000 |
| LI      | 20   | 00000000     | 0x0    | 20   | 00000000     | 0x0    |
| Buffers | 21   | 00000000     | 0x0    | 21   | 00000000     | 0x0    |
|         | 22   | 00000000     | 0x0    | 22   | 00000000     | 0x0    |
|         | 23   | 00000000     | 0x0    | 23   | 00000000     | 0x0    |
+---------+------+--------------+--------+------+--------------+--------+
--> here 16, 17, 18, 19 overlapping with below express buffer

+-----+-----------------------------------------------+
|     |       SLICE 0       |        SLICE 1          |
|     +------------+----------+------------+----------+
|     | Start addr | End addr | Start addr | End addr |
+-----+------------+----------+------------+----------+
| EXP | 70024000   | 70028000 | 7002C000   | 70030000 | <-- Overlapping
| PRE | 70030000   | 70033800 | 70034000   | 70037800 |
+-----+------------+----------+------------+----------+

+---------------------+----------+----------+
|                     | SLICE 0  |  SLICE 1 |
+---------------------+----------+----------+
| Default Drop Offset | 00000000 | 00000000 |     <-- Field not configured
+---------------------+----------+----------+

-> Allocation this patch brings:
+---------+-------------------------------------------------------------+
|         |          SLICE 0             |          SLICE 1             |
|         +------+--------------+--------+------+--------------+--------+
|         | Slot | Base Address | Size   | Slot | Base Address | Size   |
|---------+------+--------------+--------+------+--------------+--------+
|         | 0    | 70000000     | 0x2000 | 0    | 70040000     | 0x2000 |
|         | 1    | 70002000     | 0x2000 | 1    | 70042000     | 0x2000 |
|         | 2    | 70004000     | 0x2000 | 2    | 70044000     | 0x2000 |
| FWD     | 3    | 70006000     | 0x2000 | 3    | 70046000     | 0x2000 |
| Buffers | 4    | 70008000     | 0x2000 | 4    | 70048000     | 0x2000 |
|         | 5    | 7000A000     | 0x2000 | 5    | 7004A000     | 0x2000 |
|         | 6    | 7000C000     | 0x2000 | 6    | 7004C000     | 0x2000 |
|         | 7    | 7000E000     | 0x2000 | 7    | 7004E000     | 0x2000 |
+---------+------+--------------+--------+------+--------------+--------+
|         | 8    | 70010000     | 0x1000 | 8    | 70050000     | 0x1000 |
|         | 9    | 70011000     | 0x1000 | 9    | 70051000     | 0x1000 |
|         | 10   | 70012000     | 0x1000 | 10   | 70052000     | 0x1000 |
| Our     | 11   | 70013000     | 0x1000 | 11   | 70053000     | 0x1000 |
| LI      | 12   | 00000000     | 0x0    | 12   | 00000000     | 0x0    |
| Buffers | 13   | 00000000     | 0x0    | 13   | 00000000     | 0x0    |
|         | 14   | 00000000     | 0x0    | 14   | 00000000     | 0x0    |
|         | 15   | 00000000     | 0x0    | 15   | 00000000     | 0x0    |
+---------+------+--------------+--------+------+--------------+--------+
|         | 16   | 70014000     | 0x1000 | 16   | 70054000     | 0x1000 |
|         | 17   | 70015000     | 0x1000 | 17   | 70055000     | 0x1000 |
|         | 18   | 70016000     | 0x1000 | 18   | 70056000     | 0x1000 |
| Their   | 19   | 70017000     | 0x1000 | 19   | 70057000     | 0x1000 |
| LI      | 20   | 00000000     | 0x0    | 20   | 00000000     | 0x0    |
| Buffers | 21   | 00000000     | 0x0    | 21   | 00000000     | 0x0    |
|         | 22   | 00000000     | 0x0    | 22   | 00000000     | 0x0    |
|         | 23   | 00000000     | 0x0    | 23   | 00000000     | 0x0    |
+---------+------+--------------+--------+------+--------------+--------+

+-----+-----------------------------------------------+
|     |       SLICE 0       |        SLICE 1          |
|     +------------+----------+------------+----------+
|     | Start addr | End addr | Start addr | End addr |
+-----+------------+----------+------------+----------+
| EXP | 70018000   | 7001C000 | 70058000   | 7005C000 |
| PRE | 7001C000   | 7001F800 | 7005C000   | 7005F800 |
+-----+------------+----------+------------+----------+

+---------------------+----------+----------+
|                     | SLICE 0  |  SLICE 1 |
+---------------------+----------+----------+
| Default Drop Offset | 7001F800 | 7005F800 |
+---------------------+----------+----------+

Rootcause: missing buffer configuration for Express frames in
function: prueth_fw_offload_buffer_setup()

Details:
Driver implements two distinct buffer configuration functions that are
invoked based on the driver state and ICSSG firmware:-
- prueth_fw_offload_buffer_setup()
- prueth_emac_buffer_setup()

During initialization, driver creates standard network interfaces
(netdevs) and configures buffers via prueth_emac_buffer_setup().
This function properly allocates and configures all required memory
regions including:
- LI buffers
- Express packet buffers
- Preemptible packet buffers

However, when the driver transitions to an offload mode (switch/HSR/PRP),
buffer reconfiguration is handled by prueth_fw_offload_buffer_setup().
This function does not reconfigure the buffer regions required for
Express packets, leading to incorrect buffer allocation.

Fixes: abd5576b9c57 ("net: ti: icssg-prueth: Add support for ICSSG switch firmware")
Signed-off-by: Himanshu Mittal <h-mittal1@ti.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20250717094220.546388-1-h-mittal1@ti.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/ti/icssg/icssg_config.c
drivers/net/ethernet/ti/icssg/icssg_config.h
drivers/net/ethernet/ti/icssg/icssg_prueth.c
drivers/net/ethernet/ti/icssg/icssg_prueth.h
drivers/net/ethernet/ti/icssg/icssg_switch_map.h

index ddfd1c02a8854452ab8e7a17f9d5f268531cbf99..da53eb04b0a43dd2baed05d7c46cdfceaf0f0100 100644 (file)
@@ -288,8 +288,12 @@ static int prueth_fw_offload_buffer_setup(struct prueth_emac *emac)
        int i;
 
        addr = lower_32_bits(prueth->msmcram.pa);
-       if (slice)
-               addr += PRUETH_NUM_BUF_POOLS * PRUETH_EMAC_BUF_POOL_SIZE;
+       if (slice) {
+               if (prueth->pdata.banked_ms_ram)
+                       addr += MSMC_RAM_BANK_SIZE;
+               else
+                       addr += PRUETH_SW_TOTAL_BUF_SIZE_PER_SLICE;
+       }
 
        if (addr % SZ_64K) {
                dev_warn(prueth->dev, "buffer pool needs to be 64KB aligned\n");
@@ -297,43 +301,66 @@ static int prueth_fw_offload_buffer_setup(struct prueth_emac *emac)
        }
 
        bpool_cfg = emac->dram.va + BUFFER_POOL_0_ADDR_OFFSET;
-       /* workaround for f/w bug. bpool 0 needs to be initialized */
-       for (i = 0; i <  PRUETH_NUM_BUF_POOLS; i++) {
+
+       /* Configure buffer pools for forwarding buffers
+        * - used by firmware to store packets to be forwarded to other port
+        * - 8 total pools per slice
+        */
+       for (i = 0; i <  PRUETH_NUM_FWD_BUF_POOLS_PER_SLICE; i++) {
                writel(addr, &bpool_cfg[i].addr);
-               writel(PRUETH_EMAC_BUF_POOL_SIZE, &bpool_cfg[i].len);
-               addr += PRUETH_EMAC_BUF_POOL_SIZE;
+               writel(PRUETH_SW_FWD_BUF_POOL_SIZE, &bpool_cfg[i].len);
+               addr += PRUETH_SW_FWD_BUF_POOL_SIZE;
        }
 
-       if (!slice)
-               addr += PRUETH_NUM_BUF_POOLS * PRUETH_EMAC_BUF_POOL_SIZE;
-       else
-               addr += PRUETH_SW_NUM_BUF_POOLS_HOST * PRUETH_SW_BUF_POOL_SIZE_HOST;
-
-       for (i = PRUETH_NUM_BUF_POOLS;
-            i < 2 * PRUETH_SW_NUM_BUF_POOLS_HOST + PRUETH_NUM_BUF_POOLS;
-            i++) {
-               /* The driver only uses first 4 queues per PRU so only initialize them */
-               if (i % PRUETH_SW_NUM_BUF_POOLS_HOST < PRUETH_SW_NUM_BUF_POOLS_PER_PRU) {
-                       writel(addr, &bpool_cfg[i].addr);
-                       writel(PRUETH_SW_BUF_POOL_SIZE_HOST, &bpool_cfg[i].len);
-                       addr += PRUETH_SW_BUF_POOL_SIZE_HOST;
+       /* Configure buffer pools for Local Injection buffers
+        *  - used by firmware to store packets received from host core
+        *  - 16 total pools per slice
+        */
+       for (i = 0; i < PRUETH_NUM_LI_BUF_POOLS_PER_SLICE; i++) {
+               int cfg_idx = i + PRUETH_NUM_FWD_BUF_POOLS_PER_SLICE;
+
+               /* The driver only uses first 4 queues per PRU,
+                * so only initialize buffer for them
+                */
+               if ((i % PRUETH_NUM_LI_BUF_POOLS_PER_PORT_PER_SLICE)
+                        < PRUETH_SW_USED_LI_BUF_POOLS_PER_PORT_PER_SLICE) {
+                       writel(addr, &bpool_cfg[cfg_idx].addr);
+                       writel(PRUETH_SW_LI_BUF_POOL_SIZE,
+                              &bpool_cfg[cfg_idx].len);
+                       addr += PRUETH_SW_LI_BUF_POOL_SIZE;
                } else {
-                       writel(0, &bpool_cfg[i].addr);
-                       writel(0, &bpool_cfg[i].len);
+                       writel(0, &bpool_cfg[cfg_idx].addr);
+                       writel(0, &bpool_cfg[cfg_idx].len);
                }
        }
 
-       if (!slice)
-               addr += PRUETH_SW_NUM_BUF_POOLS_HOST * PRUETH_SW_BUF_POOL_SIZE_HOST;
-       else
-               addr += PRUETH_EMAC_RX_CTX_BUF_SIZE;
+       /* Express RX buffer queue
+        *  - used by firmware to store express packets to be transmitted
+        *    to the host core
+        */
+       rxq_ctx = emac->dram.va + HOST_RX_Q_EXP_CONTEXT_OFFSET;
+       for (i = 0; i < 3; i++)
+               writel(addr, &rxq_ctx->start[i]);
+
+       addr += PRUETH_SW_HOST_EXP_BUF_POOL_SIZE;
+       writel(addr, &rxq_ctx->end);
 
+       /* Pre-emptible RX buffer queue
+        *  - used by firmware to store preemptible packets to be transmitted
+        *    to the host core
+        */
        rxq_ctx = emac->dram.va + HOST_RX_Q_PRE_CONTEXT_OFFSET;
        for (i = 0; i < 3; i++)
                writel(addr, &rxq_ctx->start[i]);
 
-       addr += PRUETH_EMAC_RX_CTX_BUF_SIZE;
-       writel(addr - SZ_2K, &rxq_ctx->end);
+       addr += PRUETH_SW_HOST_PRE_BUF_POOL_SIZE;
+       writel(addr, &rxq_ctx->end);
+
+       /* Set pointer for default dropped packet write
+        *  - used by firmware to temporarily store packet to be dropped
+        */
+       rxq_ctx = emac->dram.va + DEFAULT_MSMC_Q_OFFSET;
+       writel(addr, &rxq_ctx->start[0]);
 
        return 0;
 }
@@ -347,13 +374,13 @@ static int prueth_emac_buffer_setup(struct prueth_emac *emac)
        u32 addr;
        int i;
 
-       /* Layout to have 64KB aligned buffer pool
-        * |BPOOL0|BPOOL1|RX_CTX0|RX_CTX1|
-        */
-
        addr = lower_32_bits(prueth->msmcram.pa);
-       if (slice)
-               addr += PRUETH_NUM_BUF_POOLS * PRUETH_EMAC_BUF_POOL_SIZE;
+       if (slice) {
+               if (prueth->pdata.banked_ms_ram)
+                       addr += MSMC_RAM_BANK_SIZE;
+               else
+                       addr += PRUETH_EMAC_TOTAL_BUF_SIZE_PER_SLICE;
+       }
 
        if (addr % SZ_64K) {
                dev_warn(prueth->dev, "buffer pool needs to be 64KB aligned\n");
@@ -361,39 +388,66 @@ static int prueth_emac_buffer_setup(struct prueth_emac *emac)
        }
 
        bpool_cfg = emac->dram.va + BUFFER_POOL_0_ADDR_OFFSET;
-       /* workaround for f/w bug. bpool 0 needs to be initilalized */
-       writel(addr, &bpool_cfg[0].addr);
-       writel(0, &bpool_cfg[0].len);
 
-       for (i = PRUETH_EMAC_BUF_POOL_START;
-            i < PRUETH_EMAC_BUF_POOL_START + PRUETH_NUM_BUF_POOLS;
-            i++) {
-               writel(addr, &bpool_cfg[i].addr);
-               writel(PRUETH_EMAC_BUF_POOL_SIZE, &bpool_cfg[i].len);
-               addr += PRUETH_EMAC_BUF_POOL_SIZE;
+       /* Configure buffer pools for forwarding buffers
+        *  - in mac mode - no forwarding so initialize all pools to 0
+        *  - 8 total pools per slice
+        */
+       for (i = 0; i <  PRUETH_NUM_FWD_BUF_POOLS_PER_SLICE; i++) {
+               writel(0, &bpool_cfg[i].addr);
+               writel(0, &bpool_cfg[i].len);
        }
 
-       if (!slice)
-               addr += PRUETH_NUM_BUF_POOLS * PRUETH_EMAC_BUF_POOL_SIZE;
-       else
-               addr += PRUETH_EMAC_RX_CTX_BUF_SIZE * 2;
+       /* Configure buffer pools for Local Injection buffers
+        *  - used by firmware to store packets received from host core
+        *  - 16 total pools per slice
+        */
+       bpool_cfg = emac->dram.va + BUFFER_POOL_0_ADDR_OFFSET;
+       for (i = 0; i < PRUETH_NUM_LI_BUF_POOLS_PER_SLICE; i++) {
+               int cfg_idx = i + PRUETH_NUM_FWD_BUF_POOLS_PER_SLICE;
+
+               /* In EMAC mode, only first 4 buffers are used,
+                * as 1 slice needs to handle only 1 port
+                */
+               if (i < PRUETH_EMAC_USED_LI_BUF_POOLS_PER_PORT_PER_SLICE) {
+                       writel(addr, &bpool_cfg[cfg_idx].addr);
+                       writel(PRUETH_EMAC_LI_BUF_POOL_SIZE,
+                              &bpool_cfg[cfg_idx].len);
+                       addr += PRUETH_EMAC_LI_BUF_POOL_SIZE;
+               } else {
+                       writel(0, &bpool_cfg[cfg_idx].addr);
+                       writel(0, &bpool_cfg[cfg_idx].len);
+               }
+       }
 
-       /* Pre-emptible RX buffer queue */
-       rxq_ctx = emac->dram.va + HOST_RX_Q_PRE_CONTEXT_OFFSET;
+       /* Express RX buffer queue
+        *  - used by firmware to store express packets to be transmitted
+        *    to host core
+        */
+       rxq_ctx = emac->dram.va + HOST_RX_Q_EXP_CONTEXT_OFFSET;
        for (i = 0; i < 3; i++)
                writel(addr, &rxq_ctx->start[i]);
 
-       addr += PRUETH_EMAC_RX_CTX_BUF_SIZE;
+       addr += PRUETH_EMAC_HOST_EXP_BUF_POOL_SIZE;
        writel(addr, &rxq_ctx->end);
 
-       /* Express RX buffer queue */
-       rxq_ctx = emac->dram.va + HOST_RX_Q_EXP_CONTEXT_OFFSET;
+       /* Pre-emptible RX buffer queue
+        *  - used by firmware to store preemptible packets to be transmitted
+        *    to host core
+        */
+       rxq_ctx = emac->dram.va + HOST_RX_Q_PRE_CONTEXT_OFFSET;
        for (i = 0; i < 3; i++)
                writel(addr, &rxq_ctx->start[i]);
 
-       addr += PRUETH_EMAC_RX_CTX_BUF_SIZE;
+       addr += PRUETH_EMAC_HOST_PRE_BUF_POOL_SIZE;
        writel(addr, &rxq_ctx->end);
 
+       /* Set pointer for default dropped packet write
+        *  - used by firmware to temporarily store packet to be dropped
+        */
+       rxq_ctx = emac->dram.va + DEFAULT_MSMC_Q_OFFSET;
+       writel(addr, &rxq_ctx->start[0]);
+
        return 0;
 }
 
index c884e9fa099e6fb33836c7818ff0dbce0514f82e..60d69744ffae280597d614a586874b42df3d5f19 100644 (file)
@@ -26,21 +26,71 @@ struct icssg_flow_cfg {
 #define PRUETH_MAX_RX_FLOWS    1       /* excluding default flow */
 #define PRUETH_RX_FLOW_DATA    0
 
-#define PRUETH_EMAC_BUF_POOL_SIZE      SZ_8K
-#define PRUETH_EMAC_POOLS_PER_SLICE    24
-#define PRUETH_EMAC_BUF_POOL_START     8
-#define PRUETH_NUM_BUF_POOLS   8
-#define PRUETH_EMAC_RX_CTX_BUF_SIZE    SZ_16K  /* per slice */
-#define MSMC_RAM_SIZE  \
-       (2 * (PRUETH_EMAC_BUF_POOL_SIZE * PRUETH_NUM_BUF_POOLS + \
-        PRUETH_EMAC_RX_CTX_BUF_SIZE * 2))
-
-#define PRUETH_SW_BUF_POOL_SIZE_HOST   SZ_4K
-#define PRUETH_SW_NUM_BUF_POOLS_HOST   8
-#define PRUETH_SW_NUM_BUF_POOLS_PER_PRU 4
-#define MSMC_RAM_SIZE_SWITCH_MODE \
-       (MSMC_RAM_SIZE + \
-       (2 * PRUETH_SW_BUF_POOL_SIZE_HOST * PRUETH_SW_NUM_BUF_POOLS_HOST))
+/* Defines for forwarding path buffer pools:
+ *   - used by firmware to store packets to be forwarded to other port
+ *   - 8 total pools per slice
+ *   - only used in switch mode (as no forwarding in mac mode)
+ */
+#define PRUETH_NUM_FWD_BUF_POOLS_PER_SLICE                     8
+#define PRUETH_SW_FWD_BUF_POOL_SIZE                            (SZ_8K)
+
+/* Defines for local injection path buffer pools:
+ *   - used by firmware to store packets received from host core
+ *   - 16 total pools per slice
+ *   - 8 pools per port per slice and each slice handles both ports
+ *   - only 4 out of 8 pools used per port (as only 4 real QoS levels in ICSSG)
+ *   - switch mode: 8 total pools used
+ *   - mac mode:    4 total pools used
+ */
+#define PRUETH_NUM_LI_BUF_POOLS_PER_SLICE                      16
+#define PRUETH_NUM_LI_BUF_POOLS_PER_PORT_PER_SLICE             8
+#define PRUETH_SW_LI_BUF_POOL_SIZE                             SZ_4K
+#define PRUETH_SW_USED_LI_BUF_POOLS_PER_SLICE                  8
+#define PRUETH_SW_USED_LI_BUF_POOLS_PER_PORT_PER_SLICE         4
+#define PRUETH_EMAC_LI_BUF_POOL_SIZE                           SZ_8K
+#define PRUETH_EMAC_USED_LI_BUF_POOLS_PER_SLICE                        4
+#define PRUETH_EMAC_USED_LI_BUF_POOLS_PER_PORT_PER_SLICE       4
+
+/* Defines for host egress path - express and preemptible buffers
+ *   - used by firmware to store express and preemptible packets
+ *     to be transmitted to host core
+ *   - used by both mac/switch modes
+ */
+#define PRUETH_SW_HOST_EXP_BUF_POOL_SIZE       SZ_16K
+#define PRUETH_SW_HOST_PRE_BUF_POOL_SIZE       (SZ_16K - SZ_2K)
+#define PRUETH_EMAC_HOST_EXP_BUF_POOL_SIZE     PRUETH_SW_HOST_EXP_BUF_POOL_SIZE
+#define PRUETH_EMAC_HOST_PRE_BUF_POOL_SIZE     PRUETH_SW_HOST_PRE_BUF_POOL_SIZE
+
+/* Buffer used by firmware to temporarily store packet to be dropped */
+#define PRUETH_SW_DROP_PKT_BUF_SIZE            SZ_2K
+#define PRUETH_EMAC_DROP_PKT_BUF_SIZE          PRUETH_SW_DROP_PKT_BUF_SIZE
+
+/* Total switch mode memory usage for buffers per slice */
+#define PRUETH_SW_TOTAL_BUF_SIZE_PER_SLICE \
+       (PRUETH_SW_FWD_BUF_POOL_SIZE * PRUETH_NUM_FWD_BUF_POOLS_PER_SLICE + \
+        PRUETH_SW_LI_BUF_POOL_SIZE * PRUETH_SW_USED_LI_BUF_POOLS_PER_SLICE + \
+        PRUETH_SW_HOST_EXP_BUF_POOL_SIZE + \
+        PRUETH_SW_HOST_PRE_BUF_POOL_SIZE + \
+        PRUETH_SW_DROP_PKT_BUF_SIZE)
+
+/* Total switch mode memory usage for all buffers */
+#define PRUETH_SW_TOTAL_BUF_SIZE \
+       (2 * PRUETH_SW_TOTAL_BUF_SIZE_PER_SLICE)
+
+/* Total mac mode memory usage for buffers per slice */
+#define PRUETH_EMAC_TOTAL_BUF_SIZE_PER_SLICE \
+       (PRUETH_EMAC_LI_BUF_POOL_SIZE * \
+        PRUETH_EMAC_USED_LI_BUF_POOLS_PER_SLICE + \
+        PRUETH_EMAC_HOST_EXP_BUF_POOL_SIZE + \
+        PRUETH_EMAC_HOST_PRE_BUF_POOL_SIZE + \
+        PRUETH_EMAC_DROP_PKT_BUF_SIZE)
+
+/* Total mac mode memory usage for all buffers */
+#define PRUETH_EMAC_TOTAL_BUF_SIZE \
+       (2 * PRUETH_EMAC_TOTAL_BUF_SIZE_PER_SLICE)
+
+/* Size of 1 bank of MSMC/OC_SRAM memory */
+#define MSMC_RAM_BANK_SIZE                     SZ_256K
 
 #define PRUETH_SWITCH_FDB_MASK ((SIZE_OF_FDB / NUMBER_OF_FDB_BUCKET_ENTRIES) - 1)
 
index 86fc1278127c74e83a640dc6467f5455c250c659..2f5c4335dec388225cd69e6c4414b8e06153d090 100644 (file)
@@ -1764,10 +1764,15 @@ static int prueth_probe(struct platform_device *pdev)
                goto put_mem;
        }
 
-       msmc_ram_size = MSMC_RAM_SIZE;
        prueth->is_switchmode_supported = prueth->pdata.switch_mode;
-       if (prueth->is_switchmode_supported)
-               msmc_ram_size = MSMC_RAM_SIZE_SWITCH_MODE;
+       if (prueth->pdata.banked_ms_ram) {
+               /* Reserve 2 MSMC RAM banks for buffers to avoid arbitration */
+               msmc_ram_size = (2 * MSMC_RAM_BANK_SIZE);
+       } else {
+               msmc_ram_size = PRUETH_EMAC_TOTAL_BUF_SIZE;
+               if (prueth->is_switchmode_supported)
+                       msmc_ram_size = PRUETH_SW_TOTAL_BUF_SIZE;
+       }
 
        /* NOTE: FW bug needs buffer base to be 64KB aligned */
        prueth->msmcram.va =
@@ -1924,7 +1929,8 @@ put_iep0:
 
 free_pool:
        gen_pool_free(prueth->sram_pool,
-                     (unsigned long)prueth->msmcram.va, msmc_ram_size);
+                     (unsigned long)prueth->msmcram.va,
+                     prueth->msmcram.size);
 
 put_mem:
        pruss_release_mem_region(prueth->pruss, &prueth->shram);
@@ -1976,8 +1982,8 @@ static void prueth_remove(struct platform_device *pdev)
        icss_iep_put(prueth->iep0);
 
        gen_pool_free(prueth->sram_pool,
-                     (unsigned long)prueth->msmcram.va,
-                     MSMC_RAM_SIZE);
+               (unsigned long)prueth->msmcram.va,
+               prueth->msmcram.size);
 
        pruss_release_mem_region(prueth->pruss, &prueth->shram);
 
@@ -1994,12 +2000,14 @@ static const struct prueth_pdata am654_icssg_pdata = {
        .fdqring_mode = K3_RINGACC_RING_MODE_MESSAGE,
        .quirk_10m_link_issue = 1,
        .switch_mode = 1,
+       .banked_ms_ram = 0,
 };
 
 static const struct prueth_pdata am64x_icssg_pdata = {
        .fdqring_mode = K3_RINGACC_RING_MODE_RING,
        .quirk_10m_link_issue = 1,
        .switch_mode = 1,
+       .banked_ms_ram = 1,
 };
 
 static const struct of_device_id prueth_dt_match[] = {
index 23c465f1ce7ff4403a41501b25575e605a56b16a..3bb9fd8c3804d11deafe0756258672a40d3c2673 100644 (file)
@@ -251,11 +251,13 @@ struct prueth_emac {
  * @fdqring_mode: Free desc queue mode
  * @quirk_10m_link_issue: 10M link detect errata
  * @switch_mode: switch firmware support
+ * @banked_ms_ram: banked memory support
  */
 struct prueth_pdata {
        enum k3_ring_mode fdqring_mode;
        u32     quirk_10m_link_issue:1;
        u32     switch_mode:1;
+       u32     banked_ms_ram:1;
 };
 
 struct icssg_firmwares {
index 490a9cc06fb05aff27b2966b6f3b5dcbdf6a9d86..7e053b8af3ece301cf8d6ea23a86e529a8da95b3 100644 (file)
 /* Used to notify the FW of the current link speed */
 #define PORT_LINK_SPEED_OFFSET                             0x00A8
 
+/* 2k memory pointer reserved for default writes by PRU0*/
+#define DEFAULT_MSMC_Q_OFFSET                              0x00AC
+
 /* TAS gate mask for windows list0 */
 #define TAS_GATE_MASK_LIST0                                0x0100