diff options
| author | Prashant Rahul <prashantrahul23@gmail.com> | 2026-07-02 12:36:17 +0530 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2026-07-07 11:25:28 +0200 |
| commit | 4bcc688a11da4d6dda2c704f5ff74b43875f785c (patch) | |
| tree | 12b5adc47b2bc6e6132ddf493e42b8310604a1a8 | |
| parent | 53113fbfb93166179370b8cd0d579e417a2739fd (diff) | |
| download | linux-4bcc688a11da4d6dda2c704f5ff74b43875f785c.tar.gz linux-4bcc688a11da4d6dda2c704f5ff74b43875f785c.zip | |
staging: octeon: handle rx/tx initialization failures in probe
Check return value of rx/tx initialization functions and abort probing
if either one fails.
Add error handling labels to deallocate resources before returning the
error.
Signed-off-by: Prashant Rahul <prashantrahul23@gmail.com>
Tested-by: Klara Modin <klarasomdin@gmail.com>
Link: https://patch.msgid.link/20260702-staging-driver-octeon-panic-v2-4-2c2b6ae086dd@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
| -rw-r--r-- | drivers/staging/octeon/ethernet.c | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c index 56ea84818753..42ec4b8324a8 100644 --- a/drivers/staging/octeon/ethernet.c +++ b/drivers/staging/octeon/ethernet.c @@ -688,6 +688,7 @@ static int cvm_oct_probe(struct platform_device *pdev) { int num_interfaces; int interface; + int ret = 0; int fau = FAU_NUM_PACKET_BUFFERS_TO_FREE; int qos; struct device_node *pip; @@ -934,8 +935,13 @@ static int cvm_oct_probe(struct platform_device *pdev) } } - cvm_oct_tx_initialize(pdev); - cvm_oct_rx_initialize(pdev); + ret = cvm_oct_tx_initialize(pdev); + if (ret) + goto err_tx; + + ret = cvm_oct_rx_initialize(pdev); + if (ret) + goto err_rx; /* * 150 uS: about 10 1500-byte packets at 1GE. @@ -945,6 +951,32 @@ static int cvm_oct_probe(struct platform_device *pdev) schedule_delayed_work(&plat->rx_refill_work, HZ); return 0; + +err_rx: + cvm_oct_tx_shutdown(); +err_tx: + cvmx_ipd_disable(); + + atomic_inc_return(&cvm_oct_poll_queue_stopping); + + /* Free the ethernet devices */ + for (int port = 0; port < TOTAL_NUMBER_OF_PORTS; port++) + cvm_oct_remove_device(port); + + cvmx_pko_shutdown(); + + cvmx_ipd_free_ptr(); + + /* Free the HW pools */ + cvm_oct_mem_empty_fpa(pdev, CVMX_FPA_PACKET_POOL, CVMX_FPA_PACKET_POOL_SIZE, + num_packet_buffers); + cvm_oct_mem_empty_fpa(pdev, CVMX_FPA_WQE_POOL, CVMX_FPA_WQE_POOL_SIZE, + num_packet_buffers); + if (CVMX_FPA_OUTPUT_BUFFER_POOL != CVMX_FPA_PACKET_POOL) + cvm_oct_mem_empty_fpa(pdev, CVMX_FPA_OUTPUT_BUFFER_POOL, + CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE, 128); + + return ret; } static void cvm_oct_remove(struct platform_device *pdev) |
