Subject: [PATCH 2/3] staging: octeon: avoid needless device allocation

From: Ladislav Michl <[email-masked]>
Date: Thu, 13 Apr 2023 16:14:04 +0200

From: Ladislav Michl <[email-masked]>

Etherdev is allocated and then tested for valid interface,
then it is immediately freed after port is found unsupported.
Move that decision out of the port loop.

Signed-off-by: Ladislav Michl <[email-masked]>
---
 drivers/staging/octeon/ethernet.c | 114 +++++++++++++++---------------
 1 file changed, 58 insertions(+), 56 deletions(-)

diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c
index 949ef51bf896..466d43a71d34 100644
--- a/drivers/staging/octeon/ethernet.c
+++ b/drivers/staging/octeon/ethernet.c
@@ -799,18 +799,63 @@ static int cvm_oct_probe(struct platform_device *pdev)
 
 	num_interfaces = cvmx_helper_get_number_of_interfaces();
 	for (interface = 0; interface < num_interfaces; interface++) {
+		int num_ports, port_index;
+		const struct net_device_ops *ops;
+		const char *name;
+		phy_interface_t phy_mode = PHY_INTERFACE_MODE_NA;
 		cvmx_helper_interface_mode_t imode =
-		    cvmx_helper_interface_get_mode(interface);
-		int num_ports = cvmx_helper_ports_on_interface(interface);
-		int port_index;
+			cvmx_helper_interface_get_mode(interface);
+
+		switch (imode) {
+		case CVMX_HELPER_INTERFACE_MODE_NPI:
+			ops = &cvm_oct_npi_netdev_ops;
+			name = "npi%d";
+			break;
+
+		case CVMX_HELPER_INTERFACE_MODE_XAUI:
+			ops = &cvm_oct_xaui_netdev_ops;
+			name = "xaui%d";
+			break;
+
+		case CVMX_HELPER_INTERFACE_MODE_LOOP:
+			ops = &cvm_oct_npi_netdev_ops;
+			name = "loop%d";
+			break;
+
+		case CVMX_HELPER_INTERFACE_MODE_SGMII:
+			ops = &cvm_oct_sgmii_netdev_ops;
+			name = "eth%d";
+			phy_mode = PHY_INTERFACE_MODE_SGMII;
+			break;
+
+		case CVMX_HELPER_INTERFACE_MODE_SPI:
+			ops = &cvm_oct_spi_netdev_ops;
+			name = "spi%d";
+			break;
+
+		case CVMX_HELPER_INTERFACE_MODE_GMII:
+			ops = &cvm_oct_rgmii_netdev_ops;
+			name = "eth%d";
+			phy_mode = PHY_INTERFACE_MODE_GMII;
+			break;
 
+		case CVMX_HELPER_INTERFACE_MODE_RGMII:
+			ops = &cvm_oct_rgmii_netdev_ops;
+			name = "eth%d";
+			break;
+
+		default:
+			continue;
+		}
+
+		num_ports = cvmx_helper_ports_on_interface(interface);
 		for (port_index = 0,
 		     port = cvmx_helper_get_ipd_port(interface, 0);
 		     port < cvmx_helper_get_ipd_port(interface, num_ports);
 		     port_index++, port++) {
 			struct octeon_ethernet *priv;
 			struct net_device *dev =
-			    alloc_etherdev(sizeof(struct octeon_ethernet));
+				alloc_etherdev(sizeof(struct octeon_ethernet));
 			if (!dev) {
 				pr_err("Failed to allocate ethernet device for port %d\n",
 				       port);
@@ -830,7 +875,12 @@ static int cvm_oct_probe(struct platform_device *pdev)
 			priv->port = port;
 			priv->queue = cvmx_pko_get_base_queue(priv->port);
 			priv->fau = fau - cvmx_pko_get_num_queues(port) * 4;
-			priv->phy_mode = PHY_INTERFACE_MODE_NA;
+			priv->phy_mode = phy_mode;
+			if (imode == CVMX_HELPER_INTERFACE_MODE_RGMII)
+				cvm_set_rgmii_delay(priv, interface,
+						    port_index);
+			dev->netdev_ops = ops;
+			strscpy(dev->name, name, sizeof(dev->name));
 			for (qos = 0; qos < 16; qos++)
 				skb_queue_head_init(&priv->tx_free_list[qos]);
 			for (qos = 0; qos < cvmx_pko_get_num_queues(port);
@@ -839,64 +889,16 @@ static int cvm_oct_probe(struct platform_device *pdev)
 			dev->min_mtu = VLAN_ETH_ZLEN - mtu_overhead;
 			dev->max_mtu = OCTEON_MAX_MTU - mtu_overhead;
 
-			switch (priv->imode) {
-			/* These types don't support ports to IPD/PKO */
-			case CVMX_HELPER_INTERFACE_MODE_DISABLED:
-			case CVMX_HELPER_INTERFACE_MODE_PCIE:
-			case CVMX_HELPER_INTERFACE_MODE_PICMG:
-				break;
-
-			case CVMX_HELPER_INTERFACE_MODE_NPI:
-				dev->netdev_ops = &cvm_oct_npi_netdev_ops;
-				strscpy(dev->name, "npi%d", sizeof(dev->name));
-				break;
-
-			case CVMX_HELPER_INTERFACE_MODE_XAUI:
-				dev->netdev_ops = &cvm_oct_xaui_netdev_ops;
-				strscpy(dev->name, "xaui%d", sizeof(dev->name));
-				break;
-
-			case CVMX_HELPER_INTERFACE_MODE_LOOP:
-				dev->netdev_ops = &cvm_oct_npi_netdev_ops;
-				strscpy(dev->name, "loop%d", sizeof(dev->name));
-				break;
-
-			case CVMX_HELPER_INTERFACE_MODE_SGMII:
-				priv->phy_mode = PHY_INTERFACE_MODE_SGMII;
-				dev->netdev_ops = &cvm_oct_sgmii_netdev_ops;
-				strscpy(dev->name, "eth%d", sizeof(dev->name));
-				break;
-
-			case CVMX_HELPER_INTERFACE_MODE_SPI:
-				dev->netdev_ops = &cvm_oct_spi_netdev_ops;
-				strscpy(dev->name, "spi%d", sizeof(dev->name));
-				break;
-
-			case CVMX_HELPER_INTERFACE_MODE_GMII:
-				priv->phy_mode = PHY_INTERFACE_MODE_GMII;
-				dev->netdev_ops = &cvm_oct_rgmii_netdev_ops;
-				strscpy(dev->name, "eth%d", sizeof(dev->name));
-				break;
-
-			case CVMX_HELPER_INTERFACE_MODE_RGMII:
-				dev->netdev_ops = &cvm_oct_rgmii_netdev_ops;
-				strscpy(dev->name, "eth%d", sizeof(dev->name));
-				cvm_set_rgmii_delay(priv, interface,
-						    port_index);
-				break;
-			}
-
 			if (priv->of_node && of_phy_is_fixed_link(priv->of_node)) {
 				if (of_phy_register_fixed_link(priv->of_node)) {
 					netdev_err(dev, "Failed to register fixed link for interface %d, port %d\n",
 						   interface, priv->port);
-					dev->netdev_ops = NULL;
+					free_netdev(dev);
+					continue;
 				}
 			}
 
-			if (!dev->netdev_ops) {
-				free_netdev(dev);
-			} else if (register_netdev(dev) < 0) {
+			if (register_netdev(dev) < 0) {
 				pr_err("Failed to register ethernet device for interface %d, port %d\n",
 				       interface, priv->port);
 				free_netdev(dev);
-- 
2.32.0