]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
net: airoha: Fix error path in airoha_probe()
authorLorenzo Bianconi <lorenzo@kernel.org>
Mon, 16 Dec 2024 17:47:33 +0000 (18:47 +0100)
committerJakub Kicinski <kuba@kernel.org>
Fri, 20 Dec 2024 03:08:28 +0000 (19:08 -0800)
Do not run napi_disable() if airoha_hw_init() fails since Tx/Rx napi
has not been started yet. In order to fix the issue, introduce
airoha_qdma_stop_napi routine and remove napi_disable in
airoha_hw_cleanup().

Fixes: 23020f049327 ("net: airoha: Introduce ethernet support for EN7581 SoC")
Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20241216-airoha_probe-error-path-fix-v2-1-6b10e04e9a5c@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/mediatek/airoha_eth.c

index 6c683a12d5aa52dd9d966df123509075a989c0b3..d8bfc21a5b194478e18201ee3beca7494c223e24 100644 (file)
@@ -2138,17 +2138,14 @@ static void airoha_hw_cleanup(struct airoha_qdma *qdma)
                if (!qdma->q_rx[i].ndesc)
                        continue;
 
-               napi_disable(&qdma->q_rx[i].napi);
                netif_napi_del(&qdma->q_rx[i].napi);
                airoha_qdma_cleanup_rx_queue(&qdma->q_rx[i]);
                if (qdma->q_rx[i].page_pool)
                        page_pool_destroy(qdma->q_rx[i].page_pool);
        }
 
-       for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) {
-               napi_disable(&qdma->q_tx_irq[i].napi);
+       for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++)
                netif_napi_del(&qdma->q_tx_irq[i].napi);
-       }
 
        for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) {
                if (!qdma->q_tx[i].ndesc)
@@ -2173,6 +2170,21 @@ static void airoha_qdma_start_napi(struct airoha_qdma *qdma)
        }
 }
 
+static void airoha_qdma_stop_napi(struct airoha_qdma *qdma)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++)
+               napi_disable(&qdma->q_tx_irq[i].napi);
+
+       for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
+               if (!qdma->q_rx[i].ndesc)
+                       continue;
+
+               napi_disable(&qdma->q_rx[i].napi);
+       }
+}
+
 static void airoha_update_hw_stats(struct airoha_gdm_port *port)
 {
        struct airoha_eth *eth = port->qdma->eth;
@@ -2738,7 +2750,7 @@ static int airoha_probe(struct platform_device *pdev)
 
        err = airoha_hw_init(pdev, eth);
        if (err)
-               goto error;
+               goto error_hw_cleanup;
 
        for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
                airoha_qdma_start_napi(&eth->qdma[i]);
@@ -2753,13 +2765,16 @@ static int airoha_probe(struct platform_device *pdev)
                err = airoha_alloc_gdm_port(eth, np);
                if (err) {
                        of_node_put(np);
-                       goto error;
+                       goto error_napi_stop;
                }
        }
 
        return 0;
 
-error:
+error_napi_stop:
+       for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
+               airoha_qdma_stop_napi(&eth->qdma[i]);
+error_hw_cleanup:
        for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
                airoha_hw_cleanup(&eth->qdma[i]);
 
@@ -2780,8 +2795,10 @@ static void airoha_remove(struct platform_device *pdev)
        struct airoha_eth *eth = platform_get_drvdata(pdev);
        int i;
 
-       for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
+       for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) {
+               airoha_qdma_stop_napi(&eth->qdma[i]);
                airoha_hw_cleanup(&eth->qdma[i]);
+       }
 
        for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
                struct airoha_gdm_port *port = eth->ports[i];