sfc: Move PHY software state initialisation from init() into probe()

This prevents efx->link_advertising from being blatted during
a reset.

The phy_short_reach sysfs node is now destroyed later in the
port shutdown process, so check for STATE_RUNNING after
acquiring the rtnl_lock (just like in set_phy_flash_cfg).

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/drivers/net/sfc/mcdi_phy.c b/drivers/net/sfc/mcdi_phy.c
index 0e1bcc5..eb694af 100644
--- a/drivers/net/sfc/mcdi_phy.c
+++ b/drivers/net/sfc/mcdi_phy.c
@@ -304,31 +304,47 @@
 
 static int efx_mcdi_phy_probe(struct efx_nic *efx)
 {
-	struct efx_mcdi_phy_cfg *phy_cfg;
+	struct efx_mcdi_phy_cfg *phy_data;
+	u8 outbuf[MC_CMD_GET_LINK_OUT_LEN];
+	u32 caps;
 	int rc;
 
-	/* TODO: Move phy_data initialisation to
-	 * phy_op->probe/remove, rather than init/fini */
-	phy_cfg = kzalloc(sizeof(*phy_cfg), GFP_KERNEL);
-	if (phy_cfg == NULL) {
-		rc = -ENOMEM;
-		goto fail_alloc;
-	}
-	rc = efx_mcdi_get_phy_cfg(efx, phy_cfg);
+	/* Initialise and populate phy_data */
+	phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL);
+	if (phy_data == NULL)
+		return -ENOMEM;
+
+	rc = efx_mcdi_get_phy_cfg(efx, phy_data);
 	if (rc != 0)
 		goto fail;
 
-	efx->phy_type = phy_cfg->type;
+	/* Read initial link advertisement */
+	BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
+	rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
+			  outbuf, sizeof(outbuf), NULL);
+	if (rc)
+		goto fail;
 
-	efx->mdio_bus = phy_cfg->channel;
-	efx->mdio.prtad = phy_cfg->port;
-	efx->mdio.mmds = phy_cfg->mmd_mask & ~(1 << MC_CMD_MMD_CLAUSE22);
+	/* Fill out nic state */
+	efx->phy_data = phy_data;
+	efx->phy_type = phy_data->type;
+
+	efx->mdio_bus = phy_data->channel;
+	efx->mdio.prtad = phy_data->port;
+	efx->mdio.mmds = phy_data->mmd_mask & ~(1 << MC_CMD_MMD_CLAUSE22);
 	efx->mdio.mode_support = 0;
-	if (phy_cfg->mmd_mask & (1 << MC_CMD_MMD_CLAUSE22))
+	if (phy_data->mmd_mask & (1 << MC_CMD_MMD_CLAUSE22))
 		efx->mdio.mode_support |= MDIO_SUPPORTS_C22;
-	if (phy_cfg->mmd_mask & ~(1 << MC_CMD_MMD_CLAUSE22))
+	if (phy_data->mmd_mask & ~(1 << MC_CMD_MMD_CLAUSE22))
 		efx->mdio.mode_support |= MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22;
 
+	caps = MCDI_DWORD(outbuf, GET_LINK_OUT_CAP);
+	if (caps & (1 << MC_CMD_PHY_CAP_AN_LBN))
+		efx->link_advertising =
+			mcdi_to_ethtool_cap(phy_data->media, caps);
+	else
+		phy_data->forced_cap = caps;
+
 	/* Assert that we can map efx -> mcdi loopback modes */
 	BUILD_BUG_ON(LOOPBACK_NONE != MC_CMD_LOOPBACK_NONE);
 	BUILD_BUG_ON(LOOPBACK_DATA != MC_CMD_LOOPBACK_DATA);
@@ -365,46 +381,6 @@
 	 * but by convention we don't */
 	efx->loopback_modes &= ~(1 << LOOPBACK_NONE);
 
-	kfree(phy_cfg);
-
-	return 0;
-
-fail:
-	kfree(phy_cfg);
-fail_alloc:
-	return rc;
-}
-
-static int efx_mcdi_phy_init(struct efx_nic *efx)
-{
-	struct efx_mcdi_phy_cfg *phy_data;
-	u8 outbuf[MC_CMD_GET_LINK_OUT_LEN];
-	u32 caps;
-	int rc;
-
-	phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL);
-	if (phy_data == NULL)
-		return -ENOMEM;
-
-	rc = efx_mcdi_get_phy_cfg(efx, phy_data);
-	if (rc != 0)
-		goto fail;
-
-	efx->phy_data = phy_data;
-
-	BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
-	rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
-			  outbuf, sizeof(outbuf), NULL);
-	if (rc)
-		goto fail;
-
-	caps = MCDI_DWORD(outbuf, GET_LINK_OUT_CAP);
-	if (caps & (1 << MC_CMD_PHY_CAP_AN_LBN))
-		efx->link_advertising =
-			mcdi_to_ethtool_cap(phy_data->media, caps);
-	else
-		phy_data->forced_cap = caps;
-
 	return 0;
 
 fail:
@@ -504,7 +480,7 @@
 	return !efx_link_state_equal(&efx->link_state, &old_state);
 }
 
-static void efx_mcdi_phy_fini(struct efx_nic *efx)
+static void efx_mcdi_phy_remove(struct efx_nic *efx)
 {
 	struct efx_mcdi_phy_data *phy_data = efx->phy_data;
 
@@ -586,10 +562,11 @@
 
 struct efx_phy_operations efx_mcdi_phy_ops = {
 	.probe		= efx_mcdi_phy_probe,
-	.init 	 	= efx_mcdi_phy_init,
+	.init 	 	= efx_port_dummy_op_int,
 	.reconfigure	= efx_mcdi_phy_reconfigure,
 	.poll		= efx_mcdi_phy_poll,
-	.fini		= efx_mcdi_phy_fini,
+	.fini		= efx_port_dummy_op_void,
+	.remove		= efx_mcdi_phy_remove,
 	.get_settings	= efx_mcdi_phy_get_settings,
 	.set_settings	= efx_mcdi_phy_set_settings,
 	.run_tests	= NULL,