From 341d5317c7deb0895c927132525ebaa877a8d5fb Mon Sep 17 00:00:00 2001 From: Volodymyr Babchuk Date: Thu, 23 Jun 2022 21:29:20 +0300 Subject: [PATCH] rswitch: fix netdev initialization order Register netdev at the very end of rswitch device initialization. Else, linux kernel might try to send packets before driver finishes chain and IRQ configuration. This can lead to random memory corruption and GWCA will try to access memory via un-initialized descriptors. Signed-off-by: Volodymyr Babchuk --- drivers/net/ethernet/renesas/rswitch.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/net/ethernet/renesas/rswitch.c b/drivers/net/ethernet/renesas/rswitch.c index 0fca707b36253..cad3f80764338 100644 --- a/drivers/net/ethernet/renesas/rswitch.c +++ b/drivers/net/ethernet/renesas/rswitch.c @@ -2609,7 +2609,7 @@ static void rswitch_set_mac_address(struct rswitch_device *rdev) of_node_put(ports); } -static int rswitch_ndev_register(struct rswitch_private *priv, int index) +static int rswitch_ndev_create(struct rswitch_private *priv, int index) { struct platform_device *pdev = priv->pdev; struct net_device *ndev; @@ -2650,11 +2650,6 @@ static int rswitch_ndev_register(struct rswitch_private *priv, int index) rswitch_set_mac_address(rdev); - /* Network device register */ - err = register_netdev(ndev); - if (err) - goto out_reg_netdev; - /* FIXME: it seems S4 VPF has FWPBFCSDC0/1 only so that we cannot set * CSD = 1 (rx_chain->index = 1) for FWPBFCS03. So, use index = 0 * for the RX. @@ -2676,9 +2671,6 @@ static int rswitch_ndev_register(struct rswitch_private *priv, int index) rswitch_rxdmac_free(ndev, priv); out_rxdmac: - unregister_netdev(ndev); - -out_reg_netdev: netif_napi_del(&rdev->napi); free_netdev(ndev); @@ -2833,7 +2825,7 @@ static int rswitch_init(struct rswitch_private *priv) goto out; for (i = 0; i < num_ndev; i++) { - err = rswitch_ndev_register(priv, i); + err = rswitch_ndev_create(priv, i); if (err < 0) goto out; } @@ -2852,6 +2844,14 @@ static int rswitch_init(struct rswitch_private *priv) if (err < 0) goto out; + /* Register devices so Linux network stack can access them now */ + + for (i = 0; i < num_ndev; i++) { + err = register_netdev(priv->rdev[i]->ndev); + if (err) + goto out; + } + return 0; out: