Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: 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>

authored by

Himanshu Mittal and committed by
Jakub Kicinski
6e86fb73 96e056ff

+191 -74
+108 -54
drivers/net/ethernet/ti/icssg/icssg_config.c
··· 288 288 int i; 289 289 290 290 addr = lower_32_bits(prueth->msmcram.pa); 291 - if (slice) 292 - addr += PRUETH_NUM_BUF_POOLS * PRUETH_EMAC_BUF_POOL_SIZE; 291 + if (slice) { 292 + if (prueth->pdata.banked_ms_ram) 293 + addr += MSMC_RAM_BANK_SIZE; 294 + else 295 + addr += PRUETH_SW_TOTAL_BUF_SIZE_PER_SLICE; 296 + } 293 297 294 298 if (addr % SZ_64K) { 295 299 dev_warn(prueth->dev, "buffer pool needs to be 64KB aligned\n"); ··· 301 297 } 302 298 303 299 bpool_cfg = emac->dram.va + BUFFER_POOL_0_ADDR_OFFSET; 304 - /* workaround for f/w bug. bpool 0 needs to be initialized */ 305 - for (i = 0; i < PRUETH_NUM_BUF_POOLS; i++) { 300 + 301 + /* Configure buffer pools for forwarding buffers 302 + * - used by firmware to store packets to be forwarded to other port 303 + * - 8 total pools per slice 304 + */ 305 + for (i = 0; i < PRUETH_NUM_FWD_BUF_POOLS_PER_SLICE; i++) { 306 306 writel(addr, &bpool_cfg[i].addr); 307 - writel(PRUETH_EMAC_BUF_POOL_SIZE, &bpool_cfg[i].len); 308 - addr += PRUETH_EMAC_BUF_POOL_SIZE; 307 + writel(PRUETH_SW_FWD_BUF_POOL_SIZE, &bpool_cfg[i].len); 308 + addr += PRUETH_SW_FWD_BUF_POOL_SIZE; 309 309 } 310 310 311 - if (!slice) 312 - addr += PRUETH_NUM_BUF_POOLS * PRUETH_EMAC_BUF_POOL_SIZE; 313 - else 314 - addr += PRUETH_SW_NUM_BUF_POOLS_HOST * PRUETH_SW_BUF_POOL_SIZE_HOST; 311 + /* Configure buffer pools for Local Injection buffers 312 + * - used by firmware to store packets received from host core 313 + * - 16 total pools per slice 314 + */ 315 + for (i = 0; i < PRUETH_NUM_LI_BUF_POOLS_PER_SLICE; i++) { 316 + int cfg_idx = i + PRUETH_NUM_FWD_BUF_POOLS_PER_SLICE; 315 317 316 - for (i = PRUETH_NUM_BUF_POOLS; 317 - i < 2 * PRUETH_SW_NUM_BUF_POOLS_HOST + PRUETH_NUM_BUF_POOLS; 318 - i++) { 319 - /* The driver only uses first 4 queues per PRU so only initialize them */ 320 - if (i % PRUETH_SW_NUM_BUF_POOLS_HOST < PRUETH_SW_NUM_BUF_POOLS_PER_PRU) { 321 - writel(addr, &bpool_cfg[i].addr); 322 - writel(PRUETH_SW_BUF_POOL_SIZE_HOST, &bpool_cfg[i].len); 323 - addr += PRUETH_SW_BUF_POOL_SIZE_HOST; 318 + /* The driver only uses first 4 queues per PRU, 319 + * so only initialize buffer for them 320 + */ 321 + if ((i % PRUETH_NUM_LI_BUF_POOLS_PER_PORT_PER_SLICE) 322 + < PRUETH_SW_USED_LI_BUF_POOLS_PER_PORT_PER_SLICE) { 323 + writel(addr, &bpool_cfg[cfg_idx].addr); 324 + writel(PRUETH_SW_LI_BUF_POOL_SIZE, 325 + &bpool_cfg[cfg_idx].len); 326 + addr += PRUETH_SW_LI_BUF_POOL_SIZE; 324 327 } else { 325 - writel(0, &bpool_cfg[i].addr); 326 - writel(0, &bpool_cfg[i].len); 328 + writel(0, &bpool_cfg[cfg_idx].addr); 329 + writel(0, &bpool_cfg[cfg_idx].len); 327 330 } 328 331 } 329 332 330 - if (!slice) 331 - addr += PRUETH_SW_NUM_BUF_POOLS_HOST * PRUETH_SW_BUF_POOL_SIZE_HOST; 332 - else 333 - addr += PRUETH_EMAC_RX_CTX_BUF_SIZE; 333 + /* Express RX buffer queue 334 + * - used by firmware to store express packets to be transmitted 335 + * to the host core 336 + */ 337 + rxq_ctx = emac->dram.va + HOST_RX_Q_EXP_CONTEXT_OFFSET; 338 + for (i = 0; i < 3; i++) 339 + writel(addr, &rxq_ctx->start[i]); 334 340 341 + addr += PRUETH_SW_HOST_EXP_BUF_POOL_SIZE; 342 + writel(addr, &rxq_ctx->end); 343 + 344 + /* Pre-emptible RX buffer queue 345 + * - used by firmware to store preemptible packets to be transmitted 346 + * to the host core 347 + */ 335 348 rxq_ctx = emac->dram.va + HOST_RX_Q_PRE_CONTEXT_OFFSET; 336 349 for (i = 0; i < 3; i++) 337 350 writel(addr, &rxq_ctx->start[i]); 338 351 339 - addr += PRUETH_EMAC_RX_CTX_BUF_SIZE; 340 - writel(addr - SZ_2K, &rxq_ctx->end); 352 + addr += PRUETH_SW_HOST_PRE_BUF_POOL_SIZE; 353 + writel(addr, &rxq_ctx->end); 354 + 355 + /* Set pointer for default dropped packet write 356 + * - used by firmware to temporarily store packet to be dropped 357 + */ 358 + rxq_ctx = emac->dram.va + DEFAULT_MSMC_Q_OFFSET; 359 + writel(addr, &rxq_ctx->start[0]); 341 360 342 361 return 0; 343 362 } ··· 374 347 u32 addr; 375 348 int i; 376 349 377 - /* Layout to have 64KB aligned buffer pool 378 - * |BPOOL0|BPOOL1|RX_CTX0|RX_CTX1| 379 - */ 380 - 381 350 addr = lower_32_bits(prueth->msmcram.pa); 382 - if (slice) 383 - addr += PRUETH_NUM_BUF_POOLS * PRUETH_EMAC_BUF_POOL_SIZE; 351 + if (slice) { 352 + if (prueth->pdata.banked_ms_ram) 353 + addr += MSMC_RAM_BANK_SIZE; 354 + else 355 + addr += PRUETH_EMAC_TOTAL_BUF_SIZE_PER_SLICE; 356 + } 384 357 385 358 if (addr % SZ_64K) { 386 359 dev_warn(prueth->dev, "buffer pool needs to be 64KB aligned\n"); ··· 388 361 } 389 362 390 363 bpool_cfg = emac->dram.va + BUFFER_POOL_0_ADDR_OFFSET; 391 - /* workaround for f/w bug. bpool 0 needs to be initilalized */ 392 - writel(addr, &bpool_cfg[0].addr); 393 - writel(0, &bpool_cfg[0].len); 394 364 395 - for (i = PRUETH_EMAC_BUF_POOL_START; 396 - i < PRUETH_EMAC_BUF_POOL_START + PRUETH_NUM_BUF_POOLS; 397 - i++) { 398 - writel(addr, &bpool_cfg[i].addr); 399 - writel(PRUETH_EMAC_BUF_POOL_SIZE, &bpool_cfg[i].len); 400 - addr += PRUETH_EMAC_BUF_POOL_SIZE; 365 + /* Configure buffer pools for forwarding buffers 366 + * - in mac mode - no forwarding so initialize all pools to 0 367 + * - 8 total pools per slice 368 + */ 369 + for (i = 0; i < PRUETH_NUM_FWD_BUF_POOLS_PER_SLICE; i++) { 370 + writel(0, &bpool_cfg[i].addr); 371 + writel(0, &bpool_cfg[i].len); 401 372 } 402 373 403 - if (!slice) 404 - addr += PRUETH_NUM_BUF_POOLS * PRUETH_EMAC_BUF_POOL_SIZE; 405 - else 406 - addr += PRUETH_EMAC_RX_CTX_BUF_SIZE * 2; 374 + /* Configure buffer pools for Local Injection buffers 375 + * - used by firmware to store packets received from host core 376 + * - 16 total pools per slice 377 + */ 378 + bpool_cfg = emac->dram.va + BUFFER_POOL_0_ADDR_OFFSET; 379 + for (i = 0; i < PRUETH_NUM_LI_BUF_POOLS_PER_SLICE; i++) { 380 + int cfg_idx = i + PRUETH_NUM_FWD_BUF_POOLS_PER_SLICE; 407 381 408 - /* Pre-emptible RX buffer queue */ 409 - rxq_ctx = emac->dram.va + HOST_RX_Q_PRE_CONTEXT_OFFSET; 410 - for (i = 0; i < 3; i++) 411 - writel(addr, &rxq_ctx->start[i]); 382 + /* In EMAC mode, only first 4 buffers are used, 383 + * as 1 slice needs to handle only 1 port 384 + */ 385 + if (i < PRUETH_EMAC_USED_LI_BUF_POOLS_PER_PORT_PER_SLICE) { 386 + writel(addr, &bpool_cfg[cfg_idx].addr); 387 + writel(PRUETH_EMAC_LI_BUF_POOL_SIZE, 388 + &bpool_cfg[cfg_idx].len); 389 + addr += PRUETH_EMAC_LI_BUF_POOL_SIZE; 390 + } else { 391 + writel(0, &bpool_cfg[cfg_idx].addr); 392 + writel(0, &bpool_cfg[cfg_idx].len); 393 + } 394 + } 412 395 413 - addr += PRUETH_EMAC_RX_CTX_BUF_SIZE; 414 - writel(addr, &rxq_ctx->end); 415 - 416 - /* Express RX buffer queue */ 396 + /* Express RX buffer queue 397 + * - used by firmware to store express packets to be transmitted 398 + * to host core 399 + */ 417 400 rxq_ctx = emac->dram.va + HOST_RX_Q_EXP_CONTEXT_OFFSET; 418 401 for (i = 0; i < 3; i++) 419 402 writel(addr, &rxq_ctx->start[i]); 420 403 421 - addr += PRUETH_EMAC_RX_CTX_BUF_SIZE; 404 + addr += PRUETH_EMAC_HOST_EXP_BUF_POOL_SIZE; 422 405 writel(addr, &rxq_ctx->end); 406 + 407 + /* Pre-emptible RX buffer queue 408 + * - used by firmware to store preemptible packets to be transmitted 409 + * to host core 410 + */ 411 + rxq_ctx = emac->dram.va + HOST_RX_Q_PRE_CONTEXT_OFFSET; 412 + for (i = 0; i < 3; i++) 413 + writel(addr, &rxq_ctx->start[i]); 414 + 415 + addr += PRUETH_EMAC_HOST_PRE_BUF_POOL_SIZE; 416 + writel(addr, &rxq_ctx->end); 417 + 418 + /* Set pointer for default dropped packet write 419 + * - used by firmware to temporarily store packet to be dropped 420 + */ 421 + rxq_ctx = emac->dram.va + DEFAULT_MSMC_Q_OFFSET; 422 + writel(addr, &rxq_ctx->start[0]); 423 423 424 424 return 0; 425 425 }
+64 -14
drivers/net/ethernet/ti/icssg/icssg_config.h
··· 26 26 #define PRUETH_MAX_RX_FLOWS 1 /* excluding default flow */ 27 27 #define PRUETH_RX_FLOW_DATA 0 28 28 29 - #define PRUETH_EMAC_BUF_POOL_SIZE SZ_8K 30 - #define PRUETH_EMAC_POOLS_PER_SLICE 24 31 - #define PRUETH_EMAC_BUF_POOL_START 8 32 - #define PRUETH_NUM_BUF_POOLS 8 33 - #define PRUETH_EMAC_RX_CTX_BUF_SIZE SZ_16K /* per slice */ 34 - #define MSMC_RAM_SIZE \ 35 - (2 * (PRUETH_EMAC_BUF_POOL_SIZE * PRUETH_NUM_BUF_POOLS + \ 36 - PRUETH_EMAC_RX_CTX_BUF_SIZE * 2)) 29 + /* Defines for forwarding path buffer pools: 30 + * - used by firmware to store packets to be forwarded to other port 31 + * - 8 total pools per slice 32 + * - only used in switch mode (as no forwarding in mac mode) 33 + */ 34 + #define PRUETH_NUM_FWD_BUF_POOLS_PER_SLICE 8 35 + #define PRUETH_SW_FWD_BUF_POOL_SIZE (SZ_8K) 37 36 38 - #define PRUETH_SW_BUF_POOL_SIZE_HOST SZ_4K 39 - #define PRUETH_SW_NUM_BUF_POOLS_HOST 8 40 - #define PRUETH_SW_NUM_BUF_POOLS_PER_PRU 4 41 - #define MSMC_RAM_SIZE_SWITCH_MODE \ 42 - (MSMC_RAM_SIZE + \ 43 - (2 * PRUETH_SW_BUF_POOL_SIZE_HOST * PRUETH_SW_NUM_BUF_POOLS_HOST)) 37 + /* Defines for local injection path buffer pools: 38 + * - used by firmware to store packets received from host core 39 + * - 16 total pools per slice 40 + * - 8 pools per port per slice and each slice handles both ports 41 + * - only 4 out of 8 pools used per port (as only 4 real QoS levels in ICSSG) 42 + * - switch mode: 8 total pools used 43 + * - mac mode: 4 total pools used 44 + */ 45 + #define PRUETH_NUM_LI_BUF_POOLS_PER_SLICE 16 46 + #define PRUETH_NUM_LI_BUF_POOLS_PER_PORT_PER_SLICE 8 47 + #define PRUETH_SW_LI_BUF_POOL_SIZE SZ_4K 48 + #define PRUETH_SW_USED_LI_BUF_POOLS_PER_SLICE 8 49 + #define PRUETH_SW_USED_LI_BUF_POOLS_PER_PORT_PER_SLICE 4 50 + #define PRUETH_EMAC_LI_BUF_POOL_SIZE SZ_8K 51 + #define PRUETH_EMAC_USED_LI_BUF_POOLS_PER_SLICE 4 52 + #define PRUETH_EMAC_USED_LI_BUF_POOLS_PER_PORT_PER_SLICE 4 53 + 54 + /* Defines for host egress path - express and preemptible buffers 55 + * - used by firmware to store express and preemptible packets 56 + * to be transmitted to host core 57 + * - used by both mac/switch modes 58 + */ 59 + #define PRUETH_SW_HOST_EXP_BUF_POOL_SIZE SZ_16K 60 + #define PRUETH_SW_HOST_PRE_BUF_POOL_SIZE (SZ_16K - SZ_2K) 61 + #define PRUETH_EMAC_HOST_EXP_BUF_POOL_SIZE PRUETH_SW_HOST_EXP_BUF_POOL_SIZE 62 + #define PRUETH_EMAC_HOST_PRE_BUF_POOL_SIZE PRUETH_SW_HOST_PRE_BUF_POOL_SIZE 63 + 64 + /* Buffer used by firmware to temporarily store packet to be dropped */ 65 + #define PRUETH_SW_DROP_PKT_BUF_SIZE SZ_2K 66 + #define PRUETH_EMAC_DROP_PKT_BUF_SIZE PRUETH_SW_DROP_PKT_BUF_SIZE 67 + 68 + /* Total switch mode memory usage for buffers per slice */ 69 + #define PRUETH_SW_TOTAL_BUF_SIZE_PER_SLICE \ 70 + (PRUETH_SW_FWD_BUF_POOL_SIZE * PRUETH_NUM_FWD_BUF_POOLS_PER_SLICE + \ 71 + PRUETH_SW_LI_BUF_POOL_SIZE * PRUETH_SW_USED_LI_BUF_POOLS_PER_SLICE + \ 72 + PRUETH_SW_HOST_EXP_BUF_POOL_SIZE + \ 73 + PRUETH_SW_HOST_PRE_BUF_POOL_SIZE + \ 74 + PRUETH_SW_DROP_PKT_BUF_SIZE) 75 + 76 + /* Total switch mode memory usage for all buffers */ 77 + #define PRUETH_SW_TOTAL_BUF_SIZE \ 78 + (2 * PRUETH_SW_TOTAL_BUF_SIZE_PER_SLICE) 79 + 80 + /* Total mac mode memory usage for buffers per slice */ 81 + #define PRUETH_EMAC_TOTAL_BUF_SIZE_PER_SLICE \ 82 + (PRUETH_EMAC_LI_BUF_POOL_SIZE * \ 83 + PRUETH_EMAC_USED_LI_BUF_POOLS_PER_SLICE + \ 84 + PRUETH_EMAC_HOST_EXP_BUF_POOL_SIZE + \ 85 + PRUETH_EMAC_HOST_PRE_BUF_POOL_SIZE + \ 86 + PRUETH_EMAC_DROP_PKT_BUF_SIZE) 87 + 88 + /* Total mac mode memory usage for all buffers */ 89 + #define PRUETH_EMAC_TOTAL_BUF_SIZE \ 90 + (2 * PRUETH_EMAC_TOTAL_BUF_SIZE_PER_SLICE) 91 + 92 + /* Size of 1 bank of MSMC/OC_SRAM memory */ 93 + #define MSMC_RAM_BANK_SIZE SZ_256K 44 94 45 95 #define PRUETH_SWITCH_FDB_MASK ((SIZE_OF_FDB / NUMBER_OF_FDB_BUCKET_ENTRIES) - 1) 46 96
+14 -6
drivers/net/ethernet/ti/icssg/icssg_prueth.c
··· 1764 1764 goto put_mem; 1765 1765 } 1766 1766 1767 - msmc_ram_size = MSMC_RAM_SIZE; 1768 1767 prueth->is_switchmode_supported = prueth->pdata.switch_mode; 1769 - if (prueth->is_switchmode_supported) 1770 - msmc_ram_size = MSMC_RAM_SIZE_SWITCH_MODE; 1768 + if (prueth->pdata.banked_ms_ram) { 1769 + /* Reserve 2 MSMC RAM banks for buffers to avoid arbitration */ 1770 + msmc_ram_size = (2 * MSMC_RAM_BANK_SIZE); 1771 + } else { 1772 + msmc_ram_size = PRUETH_EMAC_TOTAL_BUF_SIZE; 1773 + if (prueth->is_switchmode_supported) 1774 + msmc_ram_size = PRUETH_SW_TOTAL_BUF_SIZE; 1775 + } 1771 1776 1772 1777 /* NOTE: FW bug needs buffer base to be 64KB aligned */ 1773 1778 prueth->msmcram.va = ··· 1929 1924 1930 1925 free_pool: 1931 1926 gen_pool_free(prueth->sram_pool, 1932 - (unsigned long)prueth->msmcram.va, msmc_ram_size); 1927 + (unsigned long)prueth->msmcram.va, 1928 + prueth->msmcram.size); 1933 1929 1934 1930 put_mem: 1935 1931 pruss_release_mem_region(prueth->pruss, &prueth->shram); ··· 1982 1976 icss_iep_put(prueth->iep0); 1983 1977 1984 1978 gen_pool_free(prueth->sram_pool, 1985 - (unsigned long)prueth->msmcram.va, 1986 - MSMC_RAM_SIZE); 1979 + (unsigned long)prueth->msmcram.va, 1980 + prueth->msmcram.size); 1987 1981 1988 1982 pruss_release_mem_region(prueth->pruss, &prueth->shram); 1989 1983 ··· 2000 1994 .fdqring_mode = K3_RINGACC_RING_MODE_MESSAGE, 2001 1995 .quirk_10m_link_issue = 1, 2002 1996 .switch_mode = 1, 1997 + .banked_ms_ram = 0, 2003 1998 }; 2004 1999 2005 2000 static const struct prueth_pdata am64x_icssg_pdata = { 2006 2001 .fdqring_mode = K3_RINGACC_RING_MODE_RING, 2007 2002 .quirk_10m_link_issue = 1, 2008 2003 .switch_mode = 1, 2004 + .banked_ms_ram = 1, 2009 2005 }; 2010 2006 2011 2007 static const struct of_device_id prueth_dt_match[] = {
+2
drivers/net/ethernet/ti/icssg/icssg_prueth.h
··· 251 251 * @fdqring_mode: Free desc queue mode 252 252 * @quirk_10m_link_issue: 10M link detect errata 253 253 * @switch_mode: switch firmware support 254 + * @banked_ms_ram: banked memory support 254 255 */ 255 256 struct prueth_pdata { 256 257 enum k3_ring_mode fdqring_mode; 257 258 u32 quirk_10m_link_issue:1; 258 259 u32 switch_mode:1; 260 + u32 banked_ms_ram:1; 259 261 }; 260 262 261 263 struct icssg_firmwares {
+3
drivers/net/ethernet/ti/icssg/icssg_switch_map.h
··· 180 180 /* Used to notify the FW of the current link speed */ 181 181 #define PORT_LINK_SPEED_OFFSET 0x00A8 182 182 183 + /* 2k memory pointer reserved for default writes by PRU0*/ 184 + #define DEFAULT_MSMC_Q_OFFSET 0x00AC 185 + 183 186 /* TAS gate mask for windows list0 */ 184 187 #define TAS_GATE_MASK_LIST0 0x0100 185 188