[][kernel][common][eth][Update firmware download feature for Aquantia PHY driver]

[Description]
Refactor firmware download feature for Aquantia PHY driver.
    - Add duplicate phydev check in the gangload mode.
    - Add phy_start to re-configure PHY setting after downloading.
    - Revise PHY reset sequence.

If without this patch, PHY might lose Flow Control setting
that cause Flow Control mismatch.

[Release-log]


Change-Id: I714ea9de7864857934cce656ca3a32facb6f7976
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/6896901
diff --git a/target/linux/mediatek/patches-5.4/751-net-phy-aquantia-add-firmware-download.patch b/target/linux/mediatek/patches-5.4/751-net-phy-aquantia-add-firmware-download.patch
index 1ed206c..b31b40d 100644
--- a/target/linux/mediatek/patches-5.4/751-net-phy-aquantia-add-firmware-download.patch
+++ b/target/linux/mediatek/patches-5.4/751-net-phy-aquantia-add-firmware-download.patch
@@ -142,7 +142,7 @@
 index 0000000..7aeec86
 --- /dev/null
 +++ b/drivers/net/phy/aquantia_firmware.c
-@@ -0,0 +1,995 @@
+@@ -0,0 +1,1023 @@
 +// SPDX-License-Identifier: GPL-2.0
 +/* FW download driver for Aquantia PHY
 + */
@@ -977,11 +977,22 @@
 +	int j;
 +
 +	for (j = 0; j < num_phydevs; j++) {
++		/* stall the uP */
++		val = phy_read_mmd(phydevs[j], MDIO_MMD_VEND1, VEND1_CONTROL2);
++		val |= VEND1_CONTROL2_UP_RUNSTALL_OVERRIDE;
++		val |= VEND1_CONTROL2_UP_RUNSTALL;
++		phy_write_mmd(phydevs[j], MDIO_MMD_VEND1, VEND1_CONTROL2, val);
++
 +		/* disable the S/W reset to the Global MMD registers */
 +		val = phy_read_mmd(phydevs[j], MDIO_MMD_VEND1, VEND1_RESET_CONTROL);
 +		val |= VEND1_RESET_CONTROL_MMD_RESET_DISABLE;
 +		phy_write_mmd(phydevs[j], MDIO_MMD_VEND1, VEND1_RESET_CONTROL, val);
 +
++		/* de-assert Global S/W reset */
++		val = phy_read_mmd(phydevs[j], MDIO_MMD_VEND1, VEND1_STD_CONTROL1);
++		val &= ~VEND1_STD_CONTROL1_SOFT_RESET;
++		phy_write_mmd(phydevs[j], MDIO_MMD_VEND1, VEND1_STD_CONTROL1, val);
++
 +		/* assert Global S/W reset */
 +		val = phy_read_mmd(phydevs[j], MDIO_MMD_VEND1, VEND1_STD_CONTROL1);
 +		val |= VEND1_STD_CONTROL1_SOFT_RESET;
@@ -1018,6 +1029,11 @@
 +	if (!fw)
 +		return;
 +
++	for (i = 0; i < MAX_GANGLOAD_DEVICES; i++) {
++		if (phy_is_started(phydevs[i]))
++			phy_stop(phydevs[i]);
++	}
++
 +retry:
 +	memset(result, 0, sizeof(result));
 +
@@ -1042,9 +1058,13 @@
 +		if (result[i] == 0) {
 +			priv = phydevs[i]->priv;
 +			priv->fw_initialized = true;
++
 +#ifdef CONFIG_AQUANTIA_PHY_MDI_SWAP
 +			aqr107_config_mdi(phydevs[i]);
 +#endif
++
++			if (!phy_is_started(phydevs[i]))
++				phy_start(phydevs[i]);
 +		}
 +	}
 +
@@ -1104,6 +1124,7 @@
 +{
 +	struct aqr107_priv *priv = phydev->priv;
 +	struct device *dev = &phydev->mdio.dev;
++	int i;
 +
 +	if (priv->fw_initialized == true)
 +		return 0;
@@ -1122,6 +1143,13 @@
 +		wake_up_process(gangload_kthread);
 +	}
 +
++	for (i = 0; i < gangload; i++) {
++		if (gangload_phydevs[i] == phydev) {
++			dev_err(dev, "Detect duplicate gangload phydev\n");
++			return -EINVAL;
++		}
++	}
++
 +	gangload_phydevs[gangload] = phydev;
 +	gangload++;
 +