summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPrashant Rahul <prashantrahul23@gmail.com>2026-07-02 12:36:17 +0530
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-07-07 11:25:28 +0200
commit4bcc688a11da4d6dda2c704f5ff74b43875f785c (patch)
tree12b5adc47b2bc6e6132ddf493e42b8310604a1a8
parent53113fbfb93166179370b8cd0d579e417a2739fd (diff)
downloadlinux-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.c36
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)