Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

net: airoha: Rework the code flow in airoha_remove() and in airoha_probe() error path

As suggested by Simon in [0], rework the code flow in airoha_remove()
and in the airoha_probe() error path in order to rely on a more common
approach un-registering configured net-devices first and destroying the
hw resources at the end of the code.
Introduce airoha_qdma_cleanup routine to release QDMA resources.

[0] https://lore.kernel.org/netdev/20251214-airoha-fix-dev-registration-v1-1-860e027ad4c6@kernel.org/

Suggested-by: Simon Horman <horms@kernel.org>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260321-airoha-remove-rework-v2-1-16c7bade5fe5@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

authored by

Lorenzo Bianconi and committed by
Paolo Abeni
b1c803d5 a4b908c8

+44 -32
+44 -32
drivers/net/ethernet/airoha/airoha_eth.c
··· 1368 1368 return airoha_qdma_hw_init(qdma); 1369 1369 } 1370 1370 1371 + static void airoha_qdma_cleanup(struct airoha_qdma *qdma) 1372 + { 1373 + int i; 1374 + 1375 + for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { 1376 + if (!qdma->q_rx[i].ndesc) 1377 + continue; 1378 + 1379 + netif_napi_del(&qdma->q_rx[i].napi); 1380 + airoha_qdma_cleanup_rx_queue(&qdma->q_rx[i]); 1381 + if (qdma->q_rx[i].page_pool) { 1382 + page_pool_destroy(qdma->q_rx[i].page_pool); 1383 + qdma->q_rx[i].page_pool = NULL; 1384 + } 1385 + } 1386 + 1387 + for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) 1388 + netif_napi_del(&qdma->q_tx_irq[i].napi); 1389 + 1390 + for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { 1391 + if (!qdma->q_tx[i].ndesc) 1392 + continue; 1393 + 1394 + airoha_qdma_cleanup_tx_queue(&qdma->q_tx[i]); 1395 + } 1396 + } 1397 + 1371 1398 static int airoha_hw_init(struct platform_device *pdev, 1372 1399 struct airoha_eth *eth) 1373 1400 { ··· 1422 1395 for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) { 1423 1396 err = airoha_qdma_init(pdev, eth, &eth->qdma[i]); 1424 1397 if (err) 1425 - return err; 1398 + goto error; 1426 1399 } 1427 1400 1428 1401 err = airoha_ppe_init(eth); 1429 1402 if (err) 1430 - return err; 1403 + goto error; 1431 1404 1432 1405 set_bit(DEV_STATE_INITIALIZED, &eth->state); 1433 1406 1434 1407 return 0; 1408 + error: 1409 + for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) 1410 + airoha_qdma_cleanup(&eth->qdma[i]); 1411 + 1412 + return err; 1435 1413 } 1436 1414 1437 - static void airoha_hw_cleanup(struct airoha_qdma *qdma) 1415 + static void airoha_hw_cleanup(struct airoha_eth *eth) 1438 1416 { 1439 1417 int i; 1440 1418 1441 - for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { 1442 - if (!qdma->q_rx[i].ndesc) 1443 - continue; 1444 - 1445 - netif_napi_del(&qdma->q_rx[i].napi); 1446 - airoha_qdma_cleanup_rx_queue(&qdma->q_rx[i]); 1447 - if (qdma->q_rx[i].page_pool) 1448 - page_pool_destroy(qdma->q_rx[i].page_pool); 1449 - } 1450 - 1451 - for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) 1452 - netif_napi_del(&qdma->q_tx_irq[i].napi); 1453 - 1454 - for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { 1455 - if (!qdma->q_tx[i].ndesc) 1456 - continue; 1457 - 1458 - airoha_qdma_cleanup_tx_queue(&qdma->q_tx[i]); 1459 - } 1419 + for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) 1420 + airoha_qdma_cleanup(&eth->qdma[i]); 1421 + airoha_ppe_deinit(eth); 1460 1422 } 1461 1423 1462 1424 static void airoha_qdma_start_napi(struct airoha_qdma *qdma) ··· 3028 3012 3029 3013 err = airoha_hw_init(pdev, eth); 3030 3014 if (err) 3031 - goto error_hw_cleanup; 3015 + goto error_netdev_free; 3032 3016 3033 3017 for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) 3034 3018 airoha_qdma_start_napi(&eth->qdma[i]); ··· 3056 3040 error_napi_stop: 3057 3041 for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) 3058 3042 airoha_qdma_stop_napi(&eth->qdma[i]); 3059 - airoha_ppe_deinit(eth); 3060 - error_hw_cleanup: 3061 - for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) 3062 - airoha_hw_cleanup(&eth->qdma[i]); 3063 3043 3064 3044 for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { 3065 3045 struct airoha_gdm_port *port = eth->ports[i]; ··· 3067 3055 unregister_netdev(port->dev); 3068 3056 airoha_metadata_dst_free(port); 3069 3057 } 3058 + airoha_hw_cleanup(eth); 3059 + error_netdev_free: 3070 3060 free_netdev(eth->napi_dev); 3071 3061 platform_set_drvdata(pdev, NULL); 3072 3062 ··· 3080 3066 struct airoha_eth *eth = platform_get_drvdata(pdev); 3081 3067 int i; 3082 3068 3083 - for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) { 3069 + for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) 3084 3070 airoha_qdma_stop_napi(&eth->qdma[i]); 3085 - airoha_hw_cleanup(&eth->qdma[i]); 3086 - } 3087 3071 3088 3072 for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { 3089 3073 struct airoha_gdm_port *port = eth->ports[i]; ··· 3092 3080 unregister_netdev(port->dev); 3093 3081 airoha_metadata_dst_free(port); 3094 3082 } 3095 - free_netdev(eth->napi_dev); 3083 + airoha_hw_cleanup(eth); 3096 3084 3097 - airoha_ppe_deinit(eth); 3085 + free_netdev(eth->napi_dev); 3098 3086 platform_set_drvdata(pdev, NULL); 3099 3087 } 3100 3088