Skip to content

Commit 6007612

Browse files
HoratiuVulturPaolo Abeni
authored andcommitted
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: db8bcaa ("net: lan966x: add the basic lan966x driver") Signed-off-by: Horatiu Vultur <[email protected]> Reviewed-by: Simon Horman <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Paolo Abeni <[email protected]>
1 parent 18c40a1 commit 6007612

File tree

1 file changed

+10
-0
lines changed

1 file changed

+10
-0
lines changed

drivers/net/ethernet/microchip/lan966x/lan966x_main.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,6 +1039,16 @@ static int lan966x_reset_switch(struct lan966x *lan966x)
10391039

10401040
reset_control_reset(switch_reset);
10411041

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+
10421052
lan_wr(SYS_RESET_CFG_CORE_ENA_SET(0), lan966x, SYS_RESET_CFG);
10431053
lan_wr(SYS_RAM_INIT_RAM_INIT_SET(1), lan966x, SYS_RAM_INIT);
10441054
ret = readx_poll_timeout(lan966x_ram_init, lan966x,

0 commit comments

Comments
 (0)