net: ti: icssg-prueth: Fix buffer allocation for ICSSG

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: abd5576b9c ("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>
This commit is contained in:
Himanshu Mittal 2025-07-17 15:12:20 +05:30 committed by Jakub Kicinski
parent 96e056ffba
commit 6e86fb73de
5 changed files with 191 additions and 74 deletions

View file

@ -288,8 +288,12 @@ static int prueth_fw_offload_buffer_setup(struct prueth_emac *emac)
int i; int i;
addr = lower_32_bits(prueth->msmcram.pa); addr = lower_32_bits(prueth->msmcram.pa);
if (slice) if (slice) {
addr += PRUETH_NUM_BUF_POOLS * PRUETH_EMAC_BUF_POOL_SIZE; if (prueth->pdata.banked_ms_ram)
addr += MSMC_RAM_BANK_SIZE;
else
addr += PRUETH_SW_TOTAL_BUF_SIZE_PER_SLICE;
}
if (addr % SZ_64K) { if (addr % SZ_64K) {
dev_warn(prueth->dev, "buffer pool needs to be 64KB aligned\n"); 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; 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(addr, &bpool_cfg[i].addr);
writel(PRUETH_EMAC_BUF_POOL_SIZE, &bpool_cfg[i].len); writel(PRUETH_SW_FWD_BUF_POOL_SIZE, &bpool_cfg[i].len);
addr += PRUETH_EMAC_BUF_POOL_SIZE; addr += PRUETH_SW_FWD_BUF_POOL_SIZE;
} }
if (!slice) /* Configure buffer pools for Local Injection buffers
addr += PRUETH_NUM_BUF_POOLS * PRUETH_EMAC_BUF_POOL_SIZE; * - used by firmware to store packets received from host core
else * - 16 total pools per slice
addr += PRUETH_SW_NUM_BUF_POOLS_HOST * PRUETH_SW_BUF_POOL_SIZE_HOST; */
for (i = 0; i < PRUETH_NUM_LI_BUF_POOLS_PER_SLICE; i++) {
int cfg_idx = i + PRUETH_NUM_FWD_BUF_POOLS_PER_SLICE;
for (i = PRUETH_NUM_BUF_POOLS; /* The driver only uses first 4 queues per PRU,
i < 2 * PRUETH_SW_NUM_BUF_POOLS_HOST + PRUETH_NUM_BUF_POOLS; * so only initialize buffer for them
i++) { */
/* The driver only uses first 4 queues per PRU so only initialize them */ if ((i % PRUETH_NUM_LI_BUF_POOLS_PER_PORT_PER_SLICE)
if (i % PRUETH_SW_NUM_BUF_POOLS_HOST < PRUETH_SW_NUM_BUF_POOLS_PER_PRU) { < PRUETH_SW_USED_LI_BUF_POOLS_PER_PORT_PER_SLICE) {
writel(addr, &bpool_cfg[i].addr); writel(addr, &bpool_cfg[cfg_idx].addr);
writel(PRUETH_SW_BUF_POOL_SIZE_HOST, &bpool_cfg[i].len); writel(PRUETH_SW_LI_BUF_POOL_SIZE,
addr += PRUETH_SW_BUF_POOL_SIZE_HOST; &bpool_cfg[cfg_idx].len);
addr += PRUETH_SW_LI_BUF_POOL_SIZE;
} else { } else {
writel(0, &bpool_cfg[i].addr); writel(0, &bpool_cfg[cfg_idx].addr);
writel(0, &bpool_cfg[i].len); writel(0, &bpool_cfg[cfg_idx].len);
} }
} }
if (!slice) /* Express RX buffer queue
addr += PRUETH_SW_NUM_BUF_POOLS_HOST * PRUETH_SW_BUF_POOL_SIZE_HOST; * - used by firmware to store express packets to be transmitted
else * to the host core
addr += PRUETH_EMAC_RX_CTX_BUF_SIZE; */
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; rxq_ctx = emac->dram.va + HOST_RX_Q_PRE_CONTEXT_OFFSET;
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
writel(addr, &rxq_ctx->start[i]); writel(addr, &rxq_ctx->start[i]);
addr += PRUETH_EMAC_RX_CTX_BUF_SIZE; addr += PRUETH_SW_HOST_PRE_BUF_POOL_SIZE;
writel(addr - SZ_2K, &rxq_ctx->end); 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; return 0;
} }
@ -347,13 +374,13 @@ static int prueth_emac_buffer_setup(struct prueth_emac *emac)
u32 addr; u32 addr;
int i; int i;
/* Layout to have 64KB aligned buffer pool
* |BPOOL0|BPOOL1|RX_CTX0|RX_CTX1|
*/
addr = lower_32_bits(prueth->msmcram.pa); addr = lower_32_bits(prueth->msmcram.pa);
if (slice) if (slice) {
addr += PRUETH_NUM_BUF_POOLS * PRUETH_EMAC_BUF_POOL_SIZE; if (prueth->pdata.banked_ms_ram)
addr += MSMC_RAM_BANK_SIZE;
else
addr += PRUETH_EMAC_TOTAL_BUF_SIZE_PER_SLICE;
}
if (addr % SZ_64K) { if (addr % SZ_64K) {
dev_warn(prueth->dev, "buffer pool needs to be 64KB aligned\n"); 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; 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; /* Configure buffer pools for forwarding buffers
i < PRUETH_EMAC_BUF_POOL_START + PRUETH_NUM_BUF_POOLS; * - in mac mode - no forwarding so initialize all pools to 0
i++) { * - 8 total pools per slice
writel(addr, &bpool_cfg[i].addr); */
writel(PRUETH_EMAC_BUF_POOL_SIZE, &bpool_cfg[i].len); for (i = 0; i < PRUETH_NUM_FWD_BUF_POOLS_PER_SLICE; i++) {
addr += PRUETH_EMAC_BUF_POOL_SIZE; writel(0, &bpool_cfg[i].addr);
writel(0, &bpool_cfg[i].len);
} }
if (!slice) /* Configure buffer pools for Local Injection buffers
addr += PRUETH_NUM_BUF_POOLS * PRUETH_EMAC_BUF_POOL_SIZE; * - used by firmware to store packets received from host core
else * - 16 total pools per slice
addr += PRUETH_EMAC_RX_CTX_BUF_SIZE * 2; */
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;
/* Pre-emptible RX buffer queue */ /* In EMAC mode, only first 4 buffers are used,
rxq_ctx = emac->dram.va + HOST_RX_Q_PRE_CONTEXT_OFFSET; * as 1 slice needs to handle only 1 port
for (i = 0; i < 3; i++) */
writel(addr, &rxq_ctx->start[i]); 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);
}
}
addr += PRUETH_EMAC_RX_CTX_BUF_SIZE; /* Express RX buffer queue
writel(addr, &rxq_ctx->end); * - used by firmware to store express packets to be transmitted
* to host core
/* Express RX buffer queue */ */
rxq_ctx = emac->dram.va + HOST_RX_Q_EXP_CONTEXT_OFFSET; rxq_ctx = emac->dram.va + HOST_RX_Q_EXP_CONTEXT_OFFSET;
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
writel(addr, &rxq_ctx->start[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); writel(addr, &rxq_ctx->end);
/* 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_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; return 0;
} }

View file

@ -26,21 +26,71 @@ struct icssg_flow_cfg {
#define PRUETH_MAX_RX_FLOWS 1 /* excluding default flow */ #define PRUETH_MAX_RX_FLOWS 1 /* excluding default flow */
#define PRUETH_RX_FLOW_DATA 0 #define PRUETH_RX_FLOW_DATA 0
#define PRUETH_EMAC_BUF_POOL_SIZE SZ_8K /* Defines for forwarding path buffer pools:
#define PRUETH_EMAC_POOLS_PER_SLICE 24 * - used by firmware to store packets to be forwarded to other port
#define PRUETH_EMAC_BUF_POOL_START 8 * - 8 total pools per slice
#define PRUETH_NUM_BUF_POOLS 8 * - only used in switch mode (as no forwarding in mac mode)
#define PRUETH_EMAC_RX_CTX_BUF_SIZE SZ_16K /* per slice */ */
#define MSMC_RAM_SIZE \ #define PRUETH_NUM_FWD_BUF_POOLS_PER_SLICE 8
(2 * (PRUETH_EMAC_BUF_POOL_SIZE * PRUETH_NUM_BUF_POOLS + \ #define PRUETH_SW_FWD_BUF_POOL_SIZE (SZ_8K)
PRUETH_EMAC_RX_CTX_BUF_SIZE * 2))
#define PRUETH_SW_BUF_POOL_SIZE_HOST SZ_4K /* Defines for local injection path buffer pools:
#define PRUETH_SW_NUM_BUF_POOLS_HOST 8 * - used by firmware to store packets received from host core
#define PRUETH_SW_NUM_BUF_POOLS_PER_PRU 4 * - 16 total pools per slice
#define MSMC_RAM_SIZE_SWITCH_MODE \ * - 8 pools per port per slice and each slice handles both ports
(MSMC_RAM_SIZE + \ * - only 4 out of 8 pools used per port (as only 4 real QoS levels in ICSSG)
(2 * PRUETH_SW_BUF_POOL_SIZE_HOST * PRUETH_SW_NUM_BUF_POOLS_HOST)) * - 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) #define PRUETH_SWITCH_FDB_MASK ((SIZE_OF_FDB / NUMBER_OF_FDB_BUCKET_ENTRIES) - 1)

View file

@ -1764,10 +1764,15 @@ static int prueth_probe(struct platform_device *pdev)
goto put_mem; goto put_mem;
} }
msmc_ram_size = MSMC_RAM_SIZE;
prueth->is_switchmode_supported = prueth->pdata.switch_mode; prueth->is_switchmode_supported = prueth->pdata.switch_mode;
if (prueth->is_switchmode_supported) if (prueth->pdata.banked_ms_ram) {
msmc_ram_size = MSMC_RAM_SIZE_SWITCH_MODE; /* 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 */ /* NOTE: FW bug needs buffer base to be 64KB aligned */
prueth->msmcram.va = prueth->msmcram.va =
@ -1924,7 +1929,8 @@ put_iep0:
free_pool: free_pool:
gen_pool_free(prueth->sram_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: put_mem:
pruss_release_mem_region(prueth->pruss, &prueth->shram); 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); icss_iep_put(prueth->iep0);
gen_pool_free(prueth->sram_pool, gen_pool_free(prueth->sram_pool,
(unsigned long)prueth->msmcram.va, (unsigned long)prueth->msmcram.va,
MSMC_RAM_SIZE); prueth->msmcram.size);
pruss_release_mem_region(prueth->pruss, &prueth->shram); 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, .fdqring_mode = K3_RINGACC_RING_MODE_MESSAGE,
.quirk_10m_link_issue = 1, .quirk_10m_link_issue = 1,
.switch_mode = 1, .switch_mode = 1,
.banked_ms_ram = 0,
}; };
static const struct prueth_pdata am64x_icssg_pdata = { static const struct prueth_pdata am64x_icssg_pdata = {
.fdqring_mode = K3_RINGACC_RING_MODE_RING, .fdqring_mode = K3_RINGACC_RING_MODE_RING,
.quirk_10m_link_issue = 1, .quirk_10m_link_issue = 1,
.switch_mode = 1, .switch_mode = 1,
.banked_ms_ram = 1,
}; };
static const struct of_device_id prueth_dt_match[] = { static const struct of_device_id prueth_dt_match[] = {

View file

@ -251,11 +251,13 @@ struct prueth_emac {
* @fdqring_mode: Free desc queue mode * @fdqring_mode: Free desc queue mode
* @quirk_10m_link_issue: 10M link detect errata * @quirk_10m_link_issue: 10M link detect errata
* @switch_mode: switch firmware support * @switch_mode: switch firmware support
* @banked_ms_ram: banked memory support
*/ */
struct prueth_pdata { struct prueth_pdata {
enum k3_ring_mode fdqring_mode; enum k3_ring_mode fdqring_mode;
u32 quirk_10m_link_issue:1; u32 quirk_10m_link_issue:1;
u32 switch_mode:1; u32 switch_mode:1;
u32 banked_ms_ram:1;
}; };
struct icssg_firmwares { struct icssg_firmwares {

View file

@ -180,6 +180,9 @@
/* Used to notify the FW of the current link speed */ /* Used to notify the FW of the current link speed */
#define PORT_LINK_SPEED_OFFSET 0x00A8 #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 */ /* TAS gate mask for windows list0 */
#define TAS_GATE_MASK_LIST0 0x0100 #define TAS_GATE_MASK_LIST0 0x0100