[][CRITICAL][kernel][common][eth][Add automatic firmware selection for Aquantia PHY]

[Description]
Add automatic firmware selection for Aquantia PHY.

Due to the latest information provided by Marvell, different
Aquantia PHYs require different firmware, so we must choose
which firmware to load by checking the PHY ID.

Without this patch, the currently supported Aquantia AQR113C
and CUX3410 models will encounter unexpected issues, such as
failures in test mode control and power level testing.

[Release-log]
N/A


Change-Id: Ic060d176d103ad1b43609cfc83b67f27981166c0
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/9053143
diff --git a/21.02/files/target/linux/mediatek/mt7988/base-files/lib/firmware/AQR-G4_v5.7.0-AQR_EVB_Generic_X3410_StdCfg_MDISwap_USX_ID46316_VER2140.cld b/21.02/files/target/linux/mediatek/mt7988/base-files/lib/firmware/AQR-G4_v5.7.0-AQR_EVB_Generic_X3410_StdCfg_MDISwap_USX_ID46316_VER2148.cld
similarity index 99%
rename from 21.02/files/target/linux/mediatek/mt7988/base-files/lib/firmware/AQR-G4_v5.7.0-AQR_EVB_Generic_X3410_StdCfg_MDISwap_USX_ID46316_VER2140.cld
rename to 21.02/files/target/linux/mediatek/mt7988/base-files/lib/firmware/AQR-G4_v5.7.0-AQR_EVB_Generic_X3410_StdCfg_MDISwap_USX_ID46316_VER2148.cld
index 1baac15..c856456 100644
--- a/21.02/files/target/linux/mediatek/mt7988/base-files/lib/firmware/AQR-G4_v5.7.0-AQR_EVB_Generic_X3410_StdCfg_MDISwap_USX_ID46316_VER2140.cld
+++ b/21.02/files/target/linux/mediatek/mt7988/base-files/lib/firmware/AQR-G4_v5.7.0-AQR_EVB_Generic_X3410_StdCfg_MDISwap_USX_ID46316_VER2148.cld
Binary files differ
diff --git a/21.02/files/target/linux/mediatek/mt7988/config-5.4 b/21.02/files/target/linux/mediatek/mt7988/config-5.4
index 1976c16..747c9d2 100644
--- a/21.02/files/target/linux/mediatek/mt7988/config-5.4
+++ b/21.02/files/target/linux/mediatek/mt7988/config-5.4
@@ -8,7 +8,9 @@
 CONFIG_AQUANTIA_PHY_FW_DOWNLOAD=y
 CONFIG_AQUANTIA_PHY_FW_DOWNLOAD_GANG=y
 # CONFIG_AQUANTIA_PHY_FW_DOWNLOAD_SINGLE is not set
-CONFIG_AQUANTIA_PHY_FW_FILE="AQR-G4_v5.7.0-AQR_EVB_Generic_X3410_StdCfg_MDISwap_USX_ID46316_VER2140.cld"
+CONFIG_AQUANTIA_PHY_FW_FILE="Rhe-05.06-Candidate7-AQR_Mediatek_23B_StartOff_ID45623_VER36657.cld"
+CONFIG_AQUANTIA_PHY_FW_FILE_AQR113C="Rhe-05.06-Candidate9-AQR_Mediatek_23B_P5_ID45824_LCLVER1.cld"
+CONFIG_AQUANTIA_PHY_FW_FILE_CUX3410="AQR-G4_v5.7.0-AQR_EVB_Generic_X3410_StdCfg_MDISwap_USX_ID46316_VER2148.cld"
 CONFIG_AQUANTIA_PHY_MIB=y
 CONFIG_ARCH_CLOCKSOURCE_DATA=y
 CONFIG_ARCH_DMA_ADDR_T_64BIT=y
diff --git a/21.02/files/target/linux/mediatek/patches-5.4/999-2741-net-phy-aquantia-add-automatic-firmware-selection.patch b/21.02/files/target/linux/mediatek/patches-5.4/999-2741-net-phy-aquantia-add-automatic-firmware-selection.patch
new file mode 100644
index 0000000..f4969c8
--- /dev/null
+++ b/21.02/files/target/linux/mediatek/patches-5.4/999-2741-net-phy-aquantia-add-automatic-firmware-selection.patch
@@ -0,0 +1,178 @@
+diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
+index 3c2ea9f..e5a8b70 100644
+--- a/drivers/net/phy/Kconfig
++++ b/drivers/net/phy/Kconfig
+@@ -412,11 +412,25 @@ choice
+ endchoice
+ 
+ config AQUANTIA_PHY_FW_FILE
+-	string "FW File"
++	string "Default PHY FW File"
+ 	depends on AQUANTIA_PHY
+ 	default "Rhe-05.06-Candidate7-AQR_Mediatek_23B_StartOff_ID45623_VER36657.cld"
+ 	---help---
+-	  Currently supports the Aquantia AQR113c
++	  This is the default FW.
++
++config AQUANTIA_PHY_FW_FILE_AQR113C
++	string "AQR113C PHY FW File"
++	depends on AQUANTIA_PHY
++	default "Rhe-05.06-Candidate7-AQR_Mediatek_23B_StartOff_ID45623_VER36657.cld"
++	---help---
++	  This FW is for AQR113C
++
++config AQUANTIA_PHY_FW_FILE_CUX3410
++	string "CUX3410 PHY FW File"
++	depends on AQUANTIA_PHY
++	default "AQR-G4_v5.7.0-AQR_EVB_Generic_X3410_StdCfg_MDISwap_USX_ID46316_VER2148.cld"
++	---help---
++	  This FW is for CUX3410
+ 
+ config AQUANTIA_PHY_MIB
+ 	tristate "MIB Read Enable"
+diff --git a/drivers/net/phy/aquantia.h b/drivers/net/phy/aquantia.h
+index 03d6744..d7e6786 100644
+--- a/drivers/net/phy/aquantia.h
++++ b/drivers/net/phy/aquantia.h
+@@ -9,6 +9,16 @@
+ #include <linux/device.h>
+ #include <linux/phy.h>
+ 
++#define PHY_ID_AQ1202	0x03a1b445
++#define PHY_ID_AQ2104	0x03a1b460
++#define PHY_ID_AQR105	0x03a1b4a2
++#define PHY_ID_AQR106	0x03a1b4d0
++#define PHY_ID_AQR107	0x03a1b4e0
++#define PHY_ID_AQCS109	0x03a1b5c2
++#define PHY_ID_AQR405	0x03a1b4b0
++#define PHY_ID_AQR113C	0x31c31c12
++#define PHY_ID_CUX3410	0x31c31dd3
++
+ #define MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT		4
+ 
+ #define PMAPMD_RSVD_VEND_PROV				0xe400
+diff --git a/drivers/net/phy/aquantia_firmware.c b/drivers/net/phy/aquantia_firmware.c
+index f37bee1..55a9a29 100644
+--- a/drivers/net/phy/aquantia_firmware.c
++++ b/drivers/net/phy/aquantia_firmware.c
+@@ -19,6 +19,8 @@
+ #endif
+ 
+ #define AQR_FIRMWARE					CONFIG_AQUANTIA_PHY_FW_FILE
++#define AQR113C_FIRMWARE				CONFIG_AQUANTIA_PHY_FW_FILE_AQR113C
++#define CUX3410_FIRMWARE				CONFIG_AQUANTIA_PHY_FW_FILE_CUX3410
+ 
+ /* Vendor specific 1, MDIO_MMD_VEND1 */
+ #define VEND1_STD_CONTROL1				0x0000
+@@ -923,6 +925,18 @@ int aqr_firmware_heartbeat_thread(void *data)
+ 	return ret;
+ }
+ 
++static char* aqr_firmware_name_get(u32 phy_id)
++{
++	switch (phy_id) {
++		case PHY_ID_AQR113C:
++			return AQR113C_FIRMWARE;
++		case PHY_ID_CUX3410:
++			return CUX3410_FIRMWARE;
++		default:
++			return AQR_FIRMWARE;
++	}
++}
++
+ static void aqr_firmware_download_cb(const struct firmware *fw, void *context)
+ {
+ 	struct phy_device **phydevs = context;
+@@ -931,6 +945,8 @@ static void aqr_firmware_download_cb(const struct firmware *fw, void *context)
+ 	struct aqr107_priv *priv = phydevs[0]->priv;
+ 	int result[MAX_GANGLOAD_DEVICES];
+ 	int i, num_phydevs = 0, ret = 0;
++	u32 phy_id = phydevs[0]->drv->phy_id;
++	char *firmware_name = aqr_firmware_name_get(phy_id);
+ 
+ 	if (!fw)
+ 		return;
+@@ -957,7 +973,7 @@ retry:
+ 
+ 			dev = &phydevs[i]->mdio.dev;
+ 			dev_err(dev, "failed to download firmware %s, ret: %d\n",
+-				AQR_FIRMWARE, ret);
++				firmware_name, ret);
+ 			goto retry;
+ 		}
+ 	}
+@@ -1005,6 +1021,8 @@ static int aqr_firmware_download_single(struct phy_device *phydev, bool force_re
+ 	struct device *dev = &phydev->mdio.dev;
+ 	const struct firmware *fw;
+ 	int ret = 0;
++	u32 phy_id = phydev->drv->phy_id;
++	char *firmware_name = aqr_firmware_name_get(phy_id);
+ 
+ 	if (priv->fw_initialized == true && force_reload == false)
+ 		return 0;
+@@ -1016,10 +1034,10 @@ static int aqr_firmware_download_single(struct phy_device *phydev, bool force_re
+ 	priv->fw_dl_mode = FW_DL_SINGLE;
+ 	priv->heartbeat = -1;
+ 
+-	ret = request_firmware(&fw, AQR_FIRMWARE, dev);
++	ret = request_firmware(&fw, firmware_name, dev);
+ 	if (ret) {
+ 		dev_err(dev, "failed to request firmware %s, ret: %d\n",
+-			AQR_FIRMWARE, ret);
++			firmware_name, ret);
+ 	}
+ 
+ 	aqr_firmware_download_cb(fw, priv->phydevs);
+@@ -1032,6 +1050,8 @@ static int aqr_firmware_gandload_thread(void *data)
+ 	struct phy_device **phydevs = data;
+ 	struct device *dev = &phydevs[0]->mdio.dev;
+ 	int ret = 0;
++	u32 phy_id = phydevs[0]->drv->phy_id;
++	char *firmware_name = aqr_firmware_name_get(phy_id);
+ 
+ 	for (;;) {
+ 		if (kthread_should_stop())
+@@ -1040,11 +1060,11 @@ static int aqr_firmware_gandload_thread(void *data)
+ 		/* either maximum gangload phy devices or timeout is reached */
+ 		if (gangload == MAX_GANGLOAD_DEVICES ||
+ 		    time_after(jiffies, gangload_timeout)) {
+-			ret = request_firmware_nowait(THIS_MODULE, true, AQR_FIRMWARE, dev,
++			ret = request_firmware_nowait(THIS_MODULE, true, firmware_name, dev,
+ 						      GFP_KERNEL, phydevs, aqr_firmware_download_cb);
+ 			if (ret) {
+ 				dev_err(dev, "failed to request firmware %s, ret: %d\n",
+-					AQR_FIRMWARE, ret);
++					firmware_name, ret);
+ 			}
+ 			break;
+ 		}
+diff --git a/drivers/net/phy/aquantia_main.c b/drivers/net/phy/aquantia_main.c
+index f445ef9..208fc7d 100644
+--- a/drivers/net/phy/aquantia_main.c
++++ b/drivers/net/phy/aquantia_main.c
+@@ -17,16 +17,6 @@
+ 
+ #include "aquantia.h"
+ 
+-#define PHY_ID_AQ1202	0x03a1b445
+-#define PHY_ID_AQ2104	0x03a1b460
+-#define PHY_ID_AQR105	0x03a1b4a2
+-#define PHY_ID_AQR106	0x03a1b4d0
+-#define PHY_ID_AQR107	0x03a1b4e0
+-#define PHY_ID_AQCS109	0x03a1b5c2
+-#define PHY_ID_AQR405	0x03a1b4b0
+-#define PHY_ID_AQR113C	0x31c31c12
+-#define PHY_ID_CUX3410	0x31c31dd3
+-
+ #define MDIO_PHYXS_VEND_IF_STATUS		0xe812
+ #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK	GENMASK(7, 3)
+ #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR	0
+@@ -489,7 +479,7 @@ void aqr107_chip_info(struct phy_device *phydev)
+ 	build_id = FIELD_GET(VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID, val);
+ 	prov_id = FIELD_GET(VEND1_GLOBAL_RSVD_STAT1_PROV_ID, val);
+ 
+-	phydev_dbg(phydev, "FW %u.%u, Build %u, Provisioning %u\n",
++	phydev_info(phydev, "FW %u.%u, Build %u, Provisioning %u\n",
+ 		   fw_major, fw_minor, build_id, prov_id);
+ }
+