[openwrt/openwrt] generic: 5.15: replace ramips AR8033 fiber patch with 5.18 patches

LEDE Commits lede-commits at lists.infradead.org
Sat Apr 22 16:54:49 PDT 2023


ansuel pushed a commit to openwrt/openwrt.git, branch master:
https://git.openwrt.org/e1242fc3390aa8b50d7685ce49f5b35f15d5b424

commit e1242fc3390aa8b50d7685ce49f5b35f15d5b424
Author: Daniel Kestrel <kestrel1974 at t-online.de>
AuthorDate: Fri Mar 17 08:22:06 2023 +0100

    generic: 5.15: replace ramips AR8033 fiber patch with 5.18 patches
    
    A patch was added in kernel 5.4 to support the fiber operation of
    AR8033 with ramips devices. In kernel 5.18 similar enhancements
    were added to the kernel. Those patches are required for other
    fiber based devices but when added, build fails for ramips targets.
    This commit removes the ramips patch and adds the kernel 5.18 ones.
    
    Signed-off-by: Daniel Kestrel <kestrel1974 at t-online.de>
    [ split commit,refresh patch and improve commit message ]
    Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
---
 ...v5.18-01-net-phy-at803x-add-fiber-support.patch | 193 +++++++++++++++++++++
 ...et-phy-at803x-support-downstream-SFP-cage.patch |  95 ++++++++++
 ...ix-NULL-pointer-dereference-on-AR9331-PHY.patch |  56 ++++++
 ...03x-fix-error-return-code-in-at803x_probe.patch |  31 ++++
 target/linux/ramips/patches-5.15/710-at803x.patch  | 184 --------------------
 5 files changed, 375 insertions(+), 184 deletions(-)

diff --git a/target/linux/generic/backport-5.15/778-v5.18-01-net-phy-at803x-add-fiber-support.patch b/target/linux/generic/backport-5.15/778-v5.18-01-net-phy-at803x-add-fiber-support.patch
new file mode 100644
index 0000000000..7cb21ed00d
--- /dev/null
+++ b/target/linux/generic/backport-5.15/778-v5.18-01-net-phy-at803x-add-fiber-support.patch
@@ -0,0 +1,193 @@
+From 3265f421887847db9ae2c01a00645e33608556d8 Mon Sep 17 00:00:00 2001
+From: Robert Hancock <robert.hancock at calian.com>
+Date: Tue, 25 Jan 2022 10:54:09 -0600
+Subject: [PATCH] net: phy: at803x: add fiber support
+
+Previously this driver always forced the copper page to be selected,
+however for AR8031 in 100Base-FX or 1000Base-X modes, the fiber page
+needs to be selected. Set the appropriate mode based on the hardware
+mode_cfg strap selection.
+
+Enable the appropriate interrupt bits to detect fiber-side link up
+or down events.
+
+Update config_aneg and read_status methods to use the appropriate
+Clause 37 calls when fiber mode is in use.
+
+Signed-off-by: Robert Hancock <robert.hancock at calian.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/phy/at803x.c | 76 +++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 67 insertions(+), 9 deletions(-)
+
+--- a/drivers/net/phy/at803x.c
++++ b/drivers/net/phy/at803x.c
+@@ -48,6 +48,8 @@
+ #define AT803X_INTR_ENABLE_PAGE_RECEIVED	BIT(12)
+ #define AT803X_INTR_ENABLE_LINK_FAIL		BIT(11)
+ #define AT803X_INTR_ENABLE_LINK_SUCCESS		BIT(10)
++#define AT803X_INTR_ENABLE_LINK_FAIL_BX		BIT(8)
++#define AT803X_INTR_ENABLE_LINK_SUCCESS_BX	BIT(7)
+ #define AT803X_INTR_ENABLE_WIRESPEED_DOWNGRADE	BIT(5)
+ #define AT803X_INTR_ENABLE_POLARITY_CHANGED	BIT(1)
+ #define AT803X_INTR_ENABLE_WOL			BIT(0)
+@@ -82,6 +84,17 @@
+ 
+ #define AT803X_MODE_CFG_MASK			0x0F
+ #define AT803X_MODE_CFG_SGMII			0x01
++#define AT803X_MODE_CFG_BASET_RGMII		0x00
++#define AT803X_MODE_CFG_BASET_SGMII		0x01
++#define AT803X_MODE_CFG_BX1000_RGMII_50OHM	0x02
++#define AT803X_MODE_CFG_BX1000_RGMII_75OHM	0x03
++#define AT803X_MODE_CFG_BX1000_CONV_50OHM	0x04
++#define AT803X_MODE_CFG_BX1000_CONV_75OHM	0x05
++#define AT803X_MODE_CFG_FX100_RGMII_50OHM	0x06
++#define AT803X_MODE_CFG_FX100_CONV_50OHM	0x07
++#define AT803X_MODE_CFG_RGMII_AUTO_MDET		0x0B
++#define AT803X_MODE_CFG_FX100_RGMII_75OHM	0x0E
++#define AT803X_MODE_CFG_FX100_CONV_75OHM	0x0F
+ 
+ #define AT803X_PSSR				0x11	/*PHY-Specific Status Register*/
+ #define AT803X_PSSR_MR_AN_COMPLETE		0x0200
+@@ -199,6 +212,8 @@ struct at803x_priv {
+ 	u16 clk_25m_mask;
+ 	u8 smarteee_lpi_tw_1g;
+ 	u8 smarteee_lpi_tw_100m;
++	bool is_fiber;
++	bool is_1000basex;
+ 	struct regulator_dev *vddio_rdev;
+ 	struct regulator_dev *vddh_rdev;
+ 	struct regulator *vddio;
+@@ -674,7 +689,33 @@ static int at803x_probe(struct phy_devic
+ 			return ret;
+ 	}
+ 
++	if (phydev->drv->phy_id == ATH8031_PHY_ID) {
++		int ccr = phy_read(phydev, AT803X_REG_CHIP_CONFIG);
++		int mode_cfg;
++
++		if (ccr < 0)
++			goto err;
++		mode_cfg = ccr & AT803X_MODE_CFG_MASK;
++
++		switch (mode_cfg) {
++		case AT803X_MODE_CFG_BX1000_RGMII_50OHM:
++		case AT803X_MODE_CFG_BX1000_RGMII_75OHM:
++			priv->is_1000basex = true;
++			fallthrough;
++		case AT803X_MODE_CFG_FX100_RGMII_50OHM:
++		case AT803X_MODE_CFG_FX100_RGMII_75OHM:
++			priv->is_fiber = true;
++			break;
++		}
++	}
++
+ 	return 0;
++
++err:
++	if (priv->vddio)
++		regulator_disable(priv->vddio);
++
++	return ret;
+ }
+ 
+ static void at803x_remove(struct phy_device *phydev)
+@@ -687,6 +728,7 @@ static void at803x_remove(struct phy_dev
+ 
+ static int at803x_get_features(struct phy_device *phydev)
+ {
++	struct at803x_priv *priv = phydev->priv;
+ 	int err;
+ 
+ 	err = genphy_read_abilities(phydev);
+@@ -704,12 +746,13 @@ static int at803x_get_features(struct ph
+ 	 * As a result of that, ESTATUS_1000_XFULL is set
+ 	 * to 1 even when operating in copper TP mode.
+ 	 *
+-	 * Remove this mode from the supported link modes,
+-	 * as this driver currently only supports copper
+-	 * operation.
++	 * Remove this mode from the supported link modes
++	 * when not operating in 1000BaseX mode.
+ 	 */
+-	linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
+-			   phydev->supported);
++	if (!priv->is_1000basex)
++		linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
++				   phydev->supported);
++
+ 	return 0;
+ }
+ 
+@@ -773,15 +816,18 @@ static int at8031_pll_config(struct phy_
+ 
+ static int at803x_config_init(struct phy_device *phydev)
+ {
++	struct at803x_priv *priv = phydev->priv;
+ 	int ret;
+ 
+ 	if (phydev->drv->phy_id == ATH8031_PHY_ID) {
+ 		/* Some bootloaders leave the fiber page selected.
+-		 * Switch to the copper page, as otherwise we read
+-		 * the PHY capabilities from the fiber side.
++		 * Switch to the appropriate page (fiber or copper), as otherwise we
++		 * read the PHY capabilities from the wrong page.
+ 		 */
+ 		phy_lock_mdio_bus(phydev);
+-		ret = at803x_write_page(phydev, AT803X_PAGE_COPPER);
++		ret = at803x_write_page(phydev,
++					priv->is_fiber ? AT803X_PAGE_FIBER :
++							 AT803X_PAGE_COPPER);
+ 		phy_unlock_mdio_bus(phydev);
+ 		if (ret)
+ 			return ret;
+@@ -840,6 +886,7 @@ static int at803x_ack_interrupt(struct p
+ 
+ static int at803x_config_intr(struct phy_device *phydev)
+ {
++	struct at803x_priv *priv = phydev->priv;
+ 	int err;
+ 	int value;
+ 
+@@ -856,6 +903,10 @@ static int at803x_config_intr(struct phy
+ 		value |= AT803X_INTR_ENABLE_DUPLEX_CHANGED;
+ 		value |= AT803X_INTR_ENABLE_LINK_FAIL;
+ 		value |= AT803X_INTR_ENABLE_LINK_SUCCESS;
++		if (priv->is_fiber) {
++			value |= AT803X_INTR_ENABLE_LINK_FAIL_BX;
++			value |= AT803X_INTR_ENABLE_LINK_SUCCESS_BX;
++		}
+ 
+ 		err = phy_write(phydev, AT803X_INTR_ENABLE, value);
+ 	} else {
+@@ -923,8 +974,12 @@ static void at803x_link_change_notify(st
+ 
+ static int at803x_read_status(struct phy_device *phydev)
+ {
++	struct at803x_priv *priv = phydev->priv;
+ 	int ss, err, old_link = phydev->link;
+ 
++	if (priv->is_1000basex)
++		return genphy_c37_read_status(phydev);
++
+ 	/* Update the link, but return if there was an error */
+ 	err = genphy_update_link(phydev);
+ 	if (err)
+@@ -1023,6 +1078,7 @@ static int at803x_config_mdix(struct phy
+ 
+ static int at803x_config_aneg(struct phy_device *phydev)
+ {
++	struct at803x_priv *priv = phydev->priv;
+ 	int ret;
+ 
+ 	ret = at803x_config_mdix(phydev, phydev->mdix_ctrl);
+@@ -1039,6 +1095,9 @@ static int at803x_config_aneg(struct phy
+ 			return ret;
+ 	}
+ 
++	if (priv->is_1000basex)
++		return genphy_c37_config_aneg(phydev);
++
+ 	return genphy_config_aneg(phydev);
+ }
+ 
diff --git a/target/linux/generic/backport-5.15/778-v5.18-02-net-phy-at803x-support-downstream-SFP-cage.patch b/target/linux/generic/backport-5.15/778-v5.18-02-net-phy-at803x-support-downstream-SFP-cage.patch
new file mode 100644
index 0000000000..8393cb32e8
--- /dev/null
+++ b/target/linux/generic/backport-5.15/778-v5.18-02-net-phy-at803x-support-downstream-SFP-cage.patch
@@ -0,0 +1,95 @@
+From dc4d5fcc5d365c9f70ea3f5c09bdf70e988fad50 Mon Sep 17 00:00:00 2001
+From: Robert Hancock <robert.hancock at calian.com>
+Date: Tue, 25 Jan 2022 10:54:10 -0600
+Subject: [PATCH] net: phy: at803x: Support downstream SFP cage
+
+Add support for downstream SFP cages for AR8031 and AR8033. This is
+primarily intended for fiber modules or direct-attach cables, however
+copper modules which work in 1000Base-X mode may also function. Such
+modules are allowed with a warning.
+
+Signed-off-by: Robert Hancock <robert.hancock at calian.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/phy/at803x.c | 56 ++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 56 insertions(+)
+
+--- a/drivers/net/phy/at803x.c
++++ b/drivers/net/phy/at803x.c
+@@ -19,6 +19,8 @@
+ #include <linux/regulator/of_regulator.h>
+ #include <linux/regulator/driver.h>
+ #include <linux/regulator/consumer.h>
++#include <linux/phylink.h>
++#include <linux/sfp.h>
+ #include <dt-bindings/net/qca-ar803x.h>
+ 
+ #define AT803X_SPECIFIC_FUNCTION_CONTROL	0x10
+@@ -555,6 +557,55 @@ static int at8031_register_regulators(st
+ 	return 0;
+ }
+ 
++static int at803x_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
++{
++	struct phy_device *phydev = upstream;
++	__ETHTOOL_DECLARE_LINK_MODE_MASK(phy_support);
++	__ETHTOOL_DECLARE_LINK_MODE_MASK(sfp_support);
++	phy_interface_t iface;
++
++	linkmode_zero(phy_support);
++	phylink_set(phy_support, 1000baseX_Full);
++	phylink_set(phy_support, 1000baseT_Full);
++	phylink_set(phy_support, Autoneg);
++	phylink_set(phy_support, Pause);
++	phylink_set(phy_support, Asym_Pause);
++
++	linkmode_zero(sfp_support);
++	sfp_parse_support(phydev->sfp_bus, id, sfp_support);
++	/* Some modules support 10G modes as well as others we support.
++	 * Mask out non-supported modes so the correct interface is picked.
++	 */
++	linkmode_and(sfp_support, phy_support, sfp_support);
++
++	if (linkmode_empty(sfp_support)) {
++		dev_err(&phydev->mdio.dev, "incompatible SFP module inserted\n");
++		return -EINVAL;
++	}
++
++	iface = sfp_select_interface(phydev->sfp_bus, sfp_support);
++
++	/* Only 1000Base-X is supported by AR8031/8033 as the downstream SerDes
++	 * interface for use with SFP modules.
++	 * However, some copper modules detected as having a preferred SGMII
++	 * interface do default to and function in 1000Base-X mode, so just
++	 * print a warning and allow such modules, as they may have some chance
++	 * of working.
++	 */
++	if (iface == PHY_INTERFACE_MODE_SGMII)
++		dev_warn(&phydev->mdio.dev, "module may not function if 1000Base-X not supported\n");
++	else if (iface != PHY_INTERFACE_MODE_1000BASEX)
++		return -EINVAL;
++
++	return 0;
++}
++
++static const struct sfp_upstream_ops at803x_sfp_ops = {
++	.attach = phy_sfp_attach,
++	.detach = phy_sfp_detach,
++	.module_insert = at803x_sfp_insert,
++};
++
+ static int at803x_parse_dt(struct phy_device *phydev)
+ {
+ 	struct device_node *node = phydev->mdio.dev.of_node;
+@@ -662,6 +713,11 @@ static int at803x_parse_dt(struct phy_de
+ 			phydev_err(phydev, "failed to get VDDIO regulator\n");
+ 			return PTR_ERR(priv->vddio);
+ 		}
++
++		/* Only AR8031/8033 support 1000Base-X for SFP modules */
++		ret = phy_sfp_probe(phydev, &at803x_sfp_ops);
++		if (ret < 0)
++			return ret;
+ 	}
+ 
+ 	return 0;
diff --git a/target/linux/generic/backport-5.15/778-v5.18-03-net-phy-at803x-fix-NULL-pointer-dereference-on-AR9331-PHY.patch b/target/linux/generic/backport-5.15/778-v5.18-03-net-phy-at803x-fix-NULL-pointer-dereference-on-AR9331-PHY.patch
new file mode 100644
index 0000000000..de8951db10
--- /dev/null
+++ b/target/linux/generic/backport-5.15/778-v5.18-03-net-phy-at803x-fix-NULL-pointer-dereference-on-AR9331-PHY.patch
@@ -0,0 +1,56 @@
+From 9926de7315be3d606cc011a305ad9adb9e8e14c9 Mon Sep 17 00:00:00 2001
+From: Oleksij Rempel <o.rempel at pengutronix.de>
+Date: Sat, 18 Jun 2022 14:23:33 +0200
+Subject: [PATCH] net: phy: at803x: fix NULL pointer dereference on AR9331 PHY
+
+Latest kernel will explode on the PHY interrupt config, since it depends
+now on allocated priv. So, run probe to allocate priv to fix it.
+
+ ar9331_switch ethernet.1:10 lan0 (uninitialized): PHY [!ahb!ethernet at 1a000000!mdio!switch at 10:00] driver [Qualcomm Atheros AR9331 built-in PHY] (irq=13)
+ CPU 0 Unable to handle kernel paging request at virtual address 0000000a, epc == 8050e8a8, ra == 80504b34
+         ...
+ Call Trace:
+ [<8050e8a8>] at803x_config_intr+0x5c/0xd0
+ [<80504b34>] phy_request_interrupt+0xa8/0xd0
+ [<8050289c>] phylink_bringup_phy+0x2d8/0x3ac
+ [<80502b68>] phylink_fwnode_phy_connect+0x118/0x130
+ [<8074d8ec>] dsa_slave_create+0x270/0x420
+ [<80743b04>] dsa_port_setup+0x12c/0x148
+ [<8074580c>] dsa_register_switch+0xaf0/0xcc0
+ [<80511344>] ar9331_sw_probe+0x370/0x388
+ [<8050cb78>] mdio_probe+0x44/0x70
+ [<804df300>] really_probe+0x200/0x424
+ [<804df7b4>] __driver_probe_device+0x290/0x298
+ [<804df810>] driver_probe_device+0x54/0xe4
+ [<804dfd50>] __device_attach_driver+0xe4/0x130
+ [<804dcb00>] bus_for_each_drv+0xb4/0xd8
+ [<804dfac4>] __device_attach+0x104/0x1a4
+ [<804ddd24>] bus_probe_device+0x48/0xc4
+ [<804deb44>] deferred_probe_work_func+0xf0/0x10c
+ [<800a0ffc>] process_one_work+0x314/0x4d4
+ [<800a17fc>] worker_thread+0x2a4/0x354
+ [<800a9a54>] kthread+0x134/0x13c
+ [<8006306c>] ret_from_kernel_thread+0x14/0x1c
+
+Same Issue would affect some other PHYs (QCA8081, QCA9561), so fix it
+too.
+
+Fixes: 3265f4218878 ("net: phy: at803x: add fiber support")
+Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
+Reviewed-by: Andrew Lunn <andrew at lunn.ch>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/phy/at803x.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/net/phy/at803x.c
++++ b/drivers/net/phy/at803x.c
+@@ -1594,6 +1594,8 @@ static struct phy_driver at803x_driver[]
+ 	/* ATHEROS AR9331 */
+ 	PHY_ID_MATCH_EXACT(ATH9331_PHY_ID),
+ 	.name			= "Qualcomm Atheros AR9331 built-in PHY",
++	.probe			= at803x_probe,
++	.remove			= at803x_remove,
+ 	.suspend		= at803x_suspend,
+ 	.resume			= at803x_resume,
+ 	.flags			= PHY_POLL_CABLE_TEST,
diff --git a/target/linux/generic/backport-5.15/778-v5.18-04-net-phy-at803x-fix-error-return-code-in-at803x_probe.patch b/target/linux/generic/backport-5.15/778-v5.18-04-net-phy-at803x-fix-error-return-code-in-at803x_probe.patch
new file mode 100644
index 0000000000..cdae5b4ca4
--- /dev/null
+++ b/target/linux/generic/backport-5.15/778-v5.18-04-net-phy-at803x-fix-error-return-code-in-at803x_probe.patch
@@ -0,0 +1,31 @@
+From 1f0dd412e34e177621769866bef347f0b22364df Mon Sep 17 00:00:00 2001
+From: Wei Yongjun <weiyongjun1 at huawei.com>
+Date: Fri, 18 Nov 2022 10:36:35 +0000
+Subject: [PATCH] net: phy: at803x: fix error return code in at803x_probe()
+
+Fix to return a negative error code from the ccr read error handling
+case instead of 0, as done elsewhere in this function.
+
+Fixes: 3265f4218878 ("net: phy: at803x: add fiber support")
+Signed-off-by: Wei Yongjun <weiyongjun1 at huawei.com>
+Reviewed-by: Andrew Lunn <andrew at lunn.ch>
+Link: https://lore.kernel.org/r/20221118103635.254256-1-weiyongjun@huaweicloud.com
+Signed-off-by: Jakub Kicinski <kuba at kernel.org>
+---
+ drivers/net/phy/at803x.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/phy/at803x.c
++++ b/drivers/net/phy/at803x.c
+@@ -749,8 +749,10 @@ static int at803x_probe(struct phy_devic
+ 		int ccr = phy_read(phydev, AT803X_REG_CHIP_CONFIG);
+ 		int mode_cfg;
+ 
+-		if (ccr < 0)
++		if (ccr < 0) {
++			ret = ccr;
+ 			goto err;
++		}
+ 		mode_cfg = ccr & AT803X_MODE_CFG_MASK;
+ 
+ 		switch (mode_cfg) {
diff --git a/target/linux/ramips/patches-5.15/710-at803x.patch b/target/linux/ramips/patches-5.15/710-at803x.patch
deleted file mode 100644
index 2f43e67e3f..0000000000
--- a/target/linux/ramips/patches-5.15/710-at803x.patch
+++ /dev/null
@@ -1,184 +0,0 @@
-From 924453aa9d2324e5611f8e2b71df746d8f0c79f1 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= <opensource at vdorst.com>
-Date: Fri, 13 Nov 2020 16:11:32 +0100
-Subject: [PATCH] net: phy: at803x: add support for SFP module in
- RGMII-to-x-base mode
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Signed-off-by: René van Dorst <opensource at vdorst.com>
----
- drivers/net/phy/at803x.c | 91 ++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 91 insertions(+)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -20,6 +20,8 @@
- #include <linux/regulator/driver.h>
- #include <linux/regulator/consumer.h>
- #include <dt-bindings/net/qca-ar803x.h>
-+#include <linux/sfp.h>
-+#include <linux/phylink.h>
- 
- #define AT803X_SPECIFIC_FUNCTION_CONTROL	0x10
- #define AT803X_SFC_ASSERT_CRS			BIT(11)
-@@ -82,9 +84,18 @@
- 
- #define AT803X_MODE_CFG_MASK			0x0F
- #define AT803X_MODE_CFG_SGMII			0x01
-+#define AT803X_MODE_CFG_BX1000_RGMII_50		0x02
-+#define AT803X_MODE_CFG_BX1000_RGMII_75		0x03
-+#define AT803X_MODE_FIBER			0x01
-+#define AT803X_MODE_COPPER			0x00
- 
- #define AT803X_PSSR				0x11	/*PHY-Specific Status Register*/
- #define AT803X_PSSR_MR_AN_COMPLETE		0x0200
-+#define	 PSSR_LINK			BIT(10)
-+#define	 PSSR_SYNC_STATUS		BIT(8)
-+#define	 PSSR_DUPLEX			BIT(13)
-+#define	 PSSR_SPEED_1000		BIT(15)
-+#define	 PSSR_SPEED_100			BIT(14)
- 
- #define AT803X_DEBUG_ANALOG_TEST_CTRL		0x00
- #define QCA8327_DEBUG_MANU_CTRL_EN		BIT(2)
-@@ -652,12 +663,75 @@ static int at803x_parse_dt(struct phy_de
- 	return 0;
- }
- 
-+static int at803x_mode(struct phy_device *phydev)
-+{
-+	int mode;
-+
-+	mode = phy_read(phydev, AT803X_REG_CHIP_CONFIG) & AT803X_MODE_CFG_MASK;
-+
-+	if (mode == AT803X_MODE_CFG_BX1000_RGMII_50 ||
-+	    mode == AT803X_MODE_CFG_BX1000_RGMII_75)
-+		return AT803X_MODE_FIBER;
-+	return AT803X_MODE_COPPER;
-+}
-+
-+static int at803x_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
-+{
-+	__ETHTOOL_DECLARE_LINK_MODE_MASK(at803x_support) = { 0, };
-+	__ETHTOOL_DECLARE_LINK_MODE_MASK(support) = { 0, };
-+	struct phy_device *phydev = upstream;
-+	phy_interface_t iface;
-+
-+	phylink_set(at803x_support, 1000baseX_Full);
-+	/* AT803x only support 1000baseX but SGMII works fine when module runs
-+	 * at 1Gbit.
-+	 */
-+	phylink_set(at803x_support, 1000baseT_Full);
-+
-+	sfp_parse_support(phydev->sfp_bus, id, support);
-+
-+	// Limit to interfaces that both sides support
-+	linkmode_and(support, support, at803x_support);
-+
-+	if (linkmode_empty(support))
-+		goto unsupported_mode;
-+
-+	iface = sfp_select_interface(phydev->sfp_bus, support);
-+
-+	if (iface != PHY_INTERFACE_MODE_SGMII &&
-+	    iface != PHY_INTERFACE_MODE_1000BASEX)
-+		goto unsupported_mode;
-+
-+	dev_info(&phydev->mdio.dev, "SFP interface %s", phy_modes(iface));
-+
-+	return 0;
-+
-+unsupported_mode:
-+	dev_info(&phydev->mdio.dev, "incompatible SFP module inserted;"
-+		 "Only SGMII at 1Gbit/1000BASEX are supported!\n");
-+	return -EINVAL;
-+}
-+
-+static const struct sfp_upstream_ops at803x_sfp_ops = {
-+	.attach = phy_sfp_attach,
-+	.detach = phy_sfp_detach,
-+	.module_insert = at803x_sfp_insert,
-+};
-+
-+
- static int at803x_probe(struct phy_device *phydev)
- {
- 	struct device *dev = &phydev->mdio.dev;
- 	struct at803x_priv *priv;
- 	int ret;
- 
-+
-+	if (at803x_mode(phydev) == AT803X_MODE_FIBER) {
-+		ret = phy_sfp_probe(phydev, &at803x_sfp_ops);
-+		if (ret < 0)
-+			return ret;
-+	}
-+
- 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
- 	if (!priv)
- 		return -ENOMEM;
-@@ -693,6 +767,7 @@ static int at803x_get_features(struct ph
- 	if (err)
- 		return err;
- 
-+#if 0
- 	if (phydev->drv->phy_id != ATH8031_PHY_ID)
- 		return 0;
- 
-@@ -710,6 +785,7 @@ static int at803x_get_features(struct ph
- 	 */
- 	linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
- 			   phydev->supported);
-+#endif
- 	return 0;
- }
- 
-@@ -775,6 +851,7 @@ static int at803x_config_init(struct phy
- {
- 	int ret;
- 
-+#if 0
- 	if (phydev->drv->phy_id == ATH8031_PHY_ID) {
- 		/* Some bootloaders leave the fiber page selected.
- 		 * Switch to the copper page, as otherwise we read
-@@ -790,6 +867,7 @@ static int at803x_config_init(struct phy
- 		if (ret < 0)
- 			return ret;
- 	}
-+#endif
- 
- 	/* The RX and TX delay default is:
- 	 *   after HW reset: RX delay enabled and TX delay disabled
-@@ -925,6 +1003,10 @@ static int at803x_read_status(struct phy
- {
- 	int ss, err, old_link = phydev->link;
- 
-+	/* Handle (Fiber) SGMII to RGMII mode */
-+	if (at803x_mode(phydev) == AT803X_MODE_FIBER)
-+		return genphy_c37_read_status(phydev);
-+
- 	/* Update the link, but return if there was an error */
- 	err = genphy_update_link(phydev);
- 	if (err)
-@@ -1025,6 +1107,12 @@ static int at803x_config_aneg(struct phy
- {
- 	int ret;
- 
-+	/* Handle (Fiber) SerDes to RGMII mode */
-+	if (at803x_mode(phydev) == AT803X_MODE_FIBER) {
-+		pr_warn("%s: fiber\n", __func__);
-+		return genphy_c37_config_aneg(phydev);
-+	}
-+
- 	ret = at803x_config_mdix(phydev, phydev->mdix_ctrl);
- 	if (ret < 0)
- 		return ret;
-@@ -1437,6 +1525,7 @@ static struct phy_driver at803x_driver[]
- 	/* Qualcomm Atheros AR8031/AR8033 */
- 	PHY_ID_MATCH_EXACT(ATH8031_PHY_ID),
- 	.name			= "Qualcomm Atheros AR8031/AR8033",
-+	.config_aneg		= at803x_config_aneg,
- 	.flags			= PHY_POLL_CABLE_TEST,
- 	.probe			= at803x_probe,
- 	.remove			= at803x_remove,




More information about the lede-commits mailing list