Skip to content

Commit 4a4b684

Browse files
HoratiuVulturkuba-moo
authored andcommitted
net: lan966x: Stop replacing tx dcbs and dcbs_buf when changing MTU
When a frame is sent using FDMA, the skb is mapped and then the mapped address is given to an tx dcb that is different than the last used tx dcb. Once the HW finish with this frame, it would generate an interrupt and then the dcb can be reused and memory can be freed. For each dcb there is an dcb buf that contains some meta-data(is used by PTP, is it free). There is 1 to 1 relationship between dcb and dcb_buf. The following issue was observed. That sometimes after changing the MTU to allocate new tx dcbs and dcbs_buf, two frames were not transmitted. The frames were not transmitted because when reloading the tx dcbs, it was always presuming to use the first dcb but that was not always happening. Because it could be that the last tx dcb used before changing MTU was first dcb and then when it tried to get the next dcb it would take dcb 1 instead of 0. Because it is supposed to take a different dcb than the last used one. This can be fixed simply by changing tx->last_in_use to -1 when the fdma is disabled to reload the new dcb and dcbs_buff. But there could be a different issue. For example, right after the frame is sent, the MTU is changed. Now all the dcbs and dcbs_buf will be cleared. And now get the interrupt from HW that it finished with the frame. So when we try to clear the skb, it is not possible because we lost all the dcbs_buf. The solution here is to stop replacing the tx dcbs and dcbs_buf when changing MTU because the TX doesn't care what is the MTU size, it is only the RX that needs this information. Fixes: 2ea1cba ("net: lan966x: Update FDMA to change MTU.") Signed-off-by: Horatiu Vultur <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 4fa8655 commit 4a4b684

File tree

1 file changed

+3
-21
lines changed

1 file changed

+3
-21
lines changed

drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,7 @@ static void lan966x_fdma_tx_disable(struct lan966x_tx *tx)
309309
lan966x, FDMA_CH_DB_DISCARD);
310310

311311
tx->activated = false;
312+
tx->last_in_use = -1;
312313
}
313314

314315
static void lan966x_fdma_tx_reload(struct lan966x_tx *tx)
@@ -687,17 +688,14 @@ static int lan966x_qsys_sw_status(struct lan966x *lan966x)
687688

688689
static int lan966x_fdma_reload(struct lan966x *lan966x, int new_mtu)
689690
{
690-
void *rx_dcbs, *tx_dcbs, *tx_dcbs_buf;
691-
dma_addr_t rx_dma, tx_dma;
691+
dma_addr_t rx_dma;
692+
void *rx_dcbs;
692693
u32 size;
693694
int err;
694695

695696
/* Store these for later to free them */
696697
rx_dma = lan966x->rx.dma;
697-
tx_dma = lan966x->tx.dma;
698698
rx_dcbs = lan966x->rx.dcbs;
699-
tx_dcbs = lan966x->tx.dcbs;
700-
tx_dcbs_buf = lan966x->tx.dcbs_buf;
701699

702700
napi_synchronize(&lan966x->napi);
703701
napi_disable(&lan966x->napi);
@@ -715,17 +713,6 @@ static int lan966x_fdma_reload(struct lan966x *lan966x, int new_mtu)
715713
size = ALIGN(size, PAGE_SIZE);
716714
dma_free_coherent(lan966x->dev, size, rx_dcbs, rx_dma);
717715

718-
lan966x_fdma_tx_disable(&lan966x->tx);
719-
err = lan966x_fdma_tx_alloc(&lan966x->tx);
720-
if (err)
721-
goto restore_tx;
722-
723-
size = sizeof(struct lan966x_tx_dcb) * FDMA_DCB_MAX;
724-
size = ALIGN(size, PAGE_SIZE);
725-
dma_free_coherent(lan966x->dev, size, tx_dcbs, tx_dma);
726-
727-
kfree(tx_dcbs_buf);
728-
729716
lan966x_fdma_wakeup_netdev(lan966x);
730717
napi_enable(&lan966x->napi);
731718

@@ -735,11 +722,6 @@ static int lan966x_fdma_reload(struct lan966x *lan966x, int new_mtu)
735722
lan966x->rx.dcbs = rx_dcbs;
736723
lan966x_fdma_rx_start(&lan966x->rx);
737724

738-
restore_tx:
739-
lan966x->tx.dma = tx_dma;
740-
lan966x->tx.dcbs = tx_dcbs;
741-
lan966x->tx.dcbs_buf = tx_dcbs_buf;
742-
743725
return err;
744726
}
745727

0 commit comments

Comments
 (0)