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: Move net_devs registration in a dedicated routine

Since airoha_probe() is not executed under rtnl lock, there is small race
where a given device is configured by user-space while the remaining ones
are not completely loaded from the dts yet. This condition will allow a
hw device misconfiguration since there are some conditions (e.g. GDM2 check
in airoha_dev_init()) that require all device are properly loaded from the
device tree. Fix the issue moving net_devices registration at the end of
the airoha_probe routine.

Fixes: 9cd451d414f6e ("net: airoha: Add loopback support for GDM2")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20251214-airoha-fix-dev-registration-v1-1-860e027ad4c6@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

authored by

Lorenzo Bianconi and committed by
Paolo Abeni
5e7365b5 35ddf66c

+26 -13
+26 -13
drivers/net/ethernet/airoha/airoha_eth.c
··· 2924 2924 port->id = id; 2925 2925 eth->ports[p] = port; 2926 2926 2927 - err = airoha_metadata_dst_alloc(port); 2928 - if (err) 2929 - return err; 2927 + return airoha_metadata_dst_alloc(port); 2928 + } 2930 2929 2931 - err = register_netdev(dev); 2932 - if (err) 2933 - goto free_metadata_dst; 2930 + static int airoha_register_gdm_devices(struct airoha_eth *eth) 2931 + { 2932 + int i; 2933 + 2934 + for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { 2935 + struct airoha_gdm_port *port = eth->ports[i]; 2936 + int err; 2937 + 2938 + if (!port) 2939 + continue; 2940 + 2941 + err = register_netdev(port->dev); 2942 + if (err) 2943 + return err; 2944 + } 2934 2945 2935 2946 return 0; 2936 - 2937 - free_metadata_dst: 2938 - airoha_metadata_dst_free(port); 2939 - return err; 2940 2947 } 2941 2948 2942 2949 static int airoha_probe(struct platform_device *pdev) ··· 3034 3027 } 3035 3028 } 3036 3029 3030 + err = airoha_register_gdm_devices(eth); 3031 + if (err) 3032 + goto error_napi_stop; 3033 + 3037 3034 return 0; 3038 3035 3039 3036 error_napi_stop: ··· 3051 3040 for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { 3052 3041 struct airoha_gdm_port *port = eth->ports[i]; 3053 3042 3054 - if (port && port->dev->reg_state == NETREG_REGISTERED) { 3043 + if (!port) 3044 + continue; 3045 + 3046 + if (port->dev->reg_state == NETREG_REGISTERED) 3055 3047 unregister_netdev(port->dev); 3056 - airoha_metadata_dst_free(port); 3057 - } 3048 + airoha_metadata_dst_free(port); 3058 3049 } 3059 3050 free_netdev(eth->napi_dev); 3060 3051 platform_set_drvdata(pdev, NULL);