Skip to content

Commit ebd7bf6

Browse files
rogerqdavem330
authored andcommitted
net: ethernet: ti: am65-cpsw: Fix error handling in am65_cpsw_nuss_common_open()
k3_udma_glue_enable_rx/tx_chn returns error code on failure. Bail out on error while enabling TX/RX channel. In the error path, clean up the RX descriptors and SKBs. Get rid of kmemleak_not_leak() as it seems unnecessary now. Fixes: 93a7653 ("net: ethernet: ti: introduce am65x/j721e gigabit eth subsystem driver") Signed-off-by: Roger Quadros <rogerq@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent be397ea commit ebd7bf6

File tree

1 file changed

+39
-9
lines changed

1 file changed

+39
-9
lines changed

drivers/net/ethernet/ti/am65-cpsw-nuss.c

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,7 @@ static void am65_cpsw_nuss_tx_cleanup(void *data, dma_addr_t desc_dma)
443443
static int am65_cpsw_nuss_common_open(struct am65_cpsw_common *common)
444444
{
445445
struct am65_cpsw_host *host_p = am65_common_get_host(common);
446-
int port_idx, i, ret;
446+
int port_idx, i, ret, tx;
447447
struct sk_buff *skb;
448448
u32 val, port_mask;
449449

@@ -510,8 +510,12 @@ static int am65_cpsw_nuss_common_open(struct am65_cpsw_common *common)
510510
AM65_CPSW_MAX_PACKET_SIZE,
511511
GFP_KERNEL);
512512
if (!skb) {
513+
ret = -ENOMEM;
513514
dev_err(common->dev, "cannot allocate skb\n");
514-
return -ENOMEM;
515+
if (i)
516+
goto fail_rx;
517+
518+
return ret;
515519
}
516520

517521
ret = am65_cpsw_nuss_rx_push(common, skb);
@@ -520,17 +524,28 @@ static int am65_cpsw_nuss_common_open(struct am65_cpsw_common *common)
520524
"cannot submit skb to channel rx, error %d\n",
521525
ret);
522526
kfree_skb(skb);
527+
if (i)
528+
goto fail_rx;
529+
523530
return ret;
524531
}
525-
kmemleak_not_leak(skb);
526532
}
527-
k3_udma_glue_enable_rx_chn(common->rx_chns.rx_chn);
528533

529-
for (i = 0; i < common->tx_ch_num; i++) {
530-
ret = k3_udma_glue_enable_tx_chn(common->tx_chns[i].tx_chn);
531-
if (ret)
532-
return ret;
533-
napi_enable(&common->tx_chns[i].napi_tx);
534+
ret = k3_udma_glue_enable_rx_chn(common->rx_chns.rx_chn);
535+
if (ret) {
536+
dev_err(common->dev, "couldn't enable rx chn: %d\n", ret);
537+
goto fail_rx;
538+
}
539+
540+
for (tx = 0; tx < common->tx_ch_num; tx++) {
541+
ret = k3_udma_glue_enable_tx_chn(common->tx_chns[tx].tx_chn);
542+
if (ret) {
543+
dev_err(common->dev, "couldn't enable tx chn %d: %d\n",
544+
tx, ret);
545+
tx--;
546+
goto fail_tx;
547+
}
548+
napi_enable(&common->tx_chns[tx].napi_tx);
534549
}
535550

536551
napi_enable(&common->napi_rx);
@@ -541,6 +556,21 @@ static int am65_cpsw_nuss_common_open(struct am65_cpsw_common *common)
541556

542557
dev_dbg(common->dev, "cpsw_nuss started\n");
543558
return 0;
559+
560+
fail_tx:
561+
while (tx >= 0) {
562+
napi_disable(&common->tx_chns[tx].napi_tx);
563+
k3_udma_glue_disable_tx_chn(common->tx_chns[tx].tx_chn);
564+
tx--;
565+
}
566+
567+
k3_udma_glue_disable_rx_chn(common->rx_chns.rx_chn);
568+
569+
fail_rx:
570+
k3_udma_glue_reset_rx_chn(common->rx_chns.rx_chn, 0,
571+
&common->rx_chns,
572+
am65_cpsw_nuss_rx_cleanup, 0);
573+
return ret;
544574
}
545575

546576
static int am65_cpsw_nuss_common_stop(struct am65_cpsw_common *common)

0 commit comments

Comments
 (0)