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.

lan966x: Fix unloading/loading of the driver

It was noticing that after a while when unloading/loading the driver and
sending traffic through the switch, it would stop working. It would stop
forwarding any traffic and the only way to get out of this was to do a
power cycle of the board. The root cause seems to be that the switch
core is initialized twice. Apparently initializing twice the switch core
disturbs the pointers in the queue systems in the HW, so after a while
it would stop sending the traffic.
Unfortunetly, it is not possible to use a reset of the switch here,
because the reset line is connected to multiple devices like MDIO,
SGPIO, FAN, etc. So then all the devices will get reseted when the
network driver will be loaded.
So the fix is to check if the core is initialized already and if that is
the case don't initialize it again.

Fixes: db8bcaad5393 ("net: lan966x: add the basic lan966x driver")
Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
Reviewed-by: Simon Horman <simon.horman@corigine.com>
Link: https://lore.kernel.org/r/20230522120038.3749026-1-horatiu.vultur@microchip.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

authored by

Horatiu Vultur and committed by
Paolo Abeni
60076124 18c40a1c

+10
+10
drivers/net/ethernet/microchip/lan966x/lan966x_main.c
··· 1039 1039 1040 1040 reset_control_reset(switch_reset); 1041 1041 1042 + /* Don't reinitialize the switch core, if it is already initialized. In 1043 + * case it is initialized twice, some pointers inside the queue system 1044 + * in HW will get corrupted and then after a while the queue system gets 1045 + * full and no traffic is passing through the switch. The issue is seen 1046 + * when loading and unloading the driver and sending traffic through the 1047 + * switch. 1048 + */ 1049 + if (lan_rd(lan966x, SYS_RESET_CFG) & SYS_RESET_CFG_CORE_ENA) 1050 + return 0; 1051 + 1042 1052 lan_wr(SYS_RESET_CFG_CORE_ENA_SET(0), lan966x, SYS_RESET_CFG); 1043 1053 lan_wr(SYS_RAM_INIT_RAM_INIT_SET(1), lan966x, SYS_RAM_INIT); 1044 1054 ret = readx_poll_timeout(lan966x_ram_init, lan966x,