From c1d8e2c49ad1eaabc4c471888bcc609f0e70aaa9 Mon Sep 17 00:00:00 2001
From: Grygorii Strashko <grygorii.strashko@ti.com>
Date: Fri, 8 Apr 2022 12:21:32 +0300
Subject: [PATCH] net: ethernet: ti: icssg_prueth: fix devlink port register
 sequence

When udevd is configured to rename interfaces according to persistent
naming rules and if a network interface has phys_port_name in sysfs, its
contents will be appended to the interface name. However, register_netdev
creates device in sysfs and if devlink_port_register is called after that,
there is a timeframe in which udevd may read an empty phys_port_name value.
The consequence is that the interface will lose this suffix and its name
will not be really persistent.

The solution is to register the port before registering a netdev.

Fixes: 3f7a788ef4c3 ("net: ethernet: ti: icssg_prueth: Add support for ICSSG switch firmware on AM654 PG2.0")
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
---
 drivers/net/ethernet/ti/icssg_prueth.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c
index 10ec9ebef867..fd15611f2013 100644
--- a/drivers/net/ethernet/ti/icssg_prueth.c
+++ b/drivers/net/ethernet/ti/icssg_prueth.c
@@ -2719,7 +2719,6 @@ static int prueth_register_devlink(struct prueth *prueth)
 				emac->port_id, ret);
 			goto dl_port_unreg;
 		}
-		devlink_port_type_eth_set(dl_port, emac->ndev);
 	}
 
 	return ret;
@@ -2944,6 +2943,10 @@ static int prueth_probe(struct platform_device *pdev)
 			prueth->emac[PRUETH_MAC1]->iep = prueth->iep0;
 	}
 
+	ret = prueth_register_devlink(prueth);
+	if (ret)
+		goto netdev_exit;
+
 	/* register the network devices */
 	if (eth0_node) {
 		ret = register_netdev(prueth->emac[PRUETH_MAC0]->ndev);
@@ -2952,6 +2955,8 @@ static int prueth_probe(struct platform_device *pdev)
 			goto netdev_exit;
 		}
 
+		devlink_port_type_eth_set(&prueth->emac[PRUETH_MAC0]->devlink_port,
+					  prueth->emac[PRUETH_MAC0]->ndev);
 		prueth->registered_netdevs[PRUETH_MAC0] = prueth->emac[PRUETH_MAC0]->ndev;
 	}
 
@@ -2961,14 +2966,12 @@ static int prueth_probe(struct platform_device *pdev)
 			dev_err(dev, "can't register netdev for port MII1");
 			goto netdev_unregister;
 		}
+		devlink_port_type_eth_set(&prueth->emac[PRUETH_MAC1]->devlink_port,
+					  prueth->emac[PRUETH_MAC1]->ndev);
 
 		prueth->registered_netdevs[PRUETH_MAC1] = prueth->emac[PRUETH_MAC1]->ndev;
 	}
 
-	ret = prueth_register_devlink(prueth);
-	if (ret)
-		goto netdev_unregister;
-
 	if (prueth->is_switchmode_supported) {
 		ret = prueth_register_notifiers(prueth);
 		if (ret)
@@ -3045,13 +3048,13 @@ static int prueth_remove(struct platform_device *pdev)
 	int i;
 
 	prueth_unregister_notifiers(prueth);
-	prueth_unregister_devlink(prueth);
 
 	for (i = 0; i < PRUETH_NUM_MACS; i++) {
 		if (!prueth->registered_netdevs[i])
 			continue;
 		unregister_netdev(prueth->registered_netdevs[i]);
 	}
+	prueth_unregister_devlink(prueth);
 
 	for (i = 0; i < PRUETH_NUM_MACS; i++) {
 		eth_node = prueth->eth_node[i];
