mtd: fix build with GCC 14
[openwrt/openwrt.git] / target / linux / generic / backport-5.15 / 778-v5.18-02-net-phy-at803x-support-downstream-SFP-cage.patch
1 From dc4d5fcc5d365c9f70ea3f5c09bdf70e988fad50 Mon Sep 17 00:00:00 2001
2 From: Robert Hancock <robert.hancock@calian.com>
3 Date: Tue, 25 Jan 2022 10:54:10 -0600
4 Subject: [PATCH] net: phy: at803x: Support downstream SFP cage
5
6 Add support for downstream SFP cages for AR8031 and AR8033. This is
7 primarily intended for fiber modules or direct-attach cables, however
8 copper modules which work in 1000Base-X mode may also function. Such
9 modules are allowed with a warning.
10
11 Signed-off-by: Robert Hancock <robert.hancock@calian.com>
12 Signed-off-by: David S. Miller <davem@davemloft.net>
13 ---
14 drivers/net/phy/at803x.c | 56 ++++++++++++++++++++++++++++++++++++++++
15 1 file changed, 56 insertions(+)
16
17 --- a/drivers/net/phy/at803x.c
18 +++ b/drivers/net/phy/at803x.c
19 @@ -19,6 +19,8 @@
20 #include <linux/regulator/of_regulator.h>
21 #include <linux/regulator/driver.h>
22 #include <linux/regulator/consumer.h>
23 +#include <linux/phylink.h>
24 +#include <linux/sfp.h>
25 #include <dt-bindings/net/qca-ar803x.h>
26
27 #define AT803X_SPECIFIC_FUNCTION_CONTROL 0x10
28 @@ -555,6 +557,55 @@ static int at8031_register_regulators(st
29 return 0;
30 }
31
32 +static int at803x_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
33 +{
34 + struct phy_device *phydev = upstream;
35 + __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_support);
36 + __ETHTOOL_DECLARE_LINK_MODE_MASK(sfp_support);
37 + phy_interface_t iface;
38 +
39 + linkmode_zero(phy_support);
40 + phylink_set(phy_support, 1000baseX_Full);
41 + phylink_set(phy_support, 1000baseT_Full);
42 + phylink_set(phy_support, Autoneg);
43 + phylink_set(phy_support, Pause);
44 + phylink_set(phy_support, Asym_Pause);
45 +
46 + linkmode_zero(sfp_support);
47 + sfp_parse_support(phydev->sfp_bus, id, sfp_support);
48 + /* Some modules support 10G modes as well as others we support.
49 + * Mask out non-supported modes so the correct interface is picked.
50 + */
51 + linkmode_and(sfp_support, phy_support, sfp_support);
52 +
53 + if (linkmode_empty(sfp_support)) {
54 + dev_err(&phydev->mdio.dev, "incompatible SFP module inserted\n");
55 + return -EINVAL;
56 + }
57 +
58 + iface = sfp_select_interface(phydev->sfp_bus, sfp_support);
59 +
60 + /* Only 1000Base-X is supported by AR8031/8033 as the downstream SerDes
61 + * interface for use with SFP modules.
62 + * However, some copper modules detected as having a preferred SGMII
63 + * interface do default to and function in 1000Base-X mode, so just
64 + * print a warning and allow such modules, as they may have some chance
65 + * of working.
66 + */
67 + if (iface == PHY_INTERFACE_MODE_SGMII)
68 + dev_warn(&phydev->mdio.dev, "module may not function if 1000Base-X not supported\n");
69 + else if (iface != PHY_INTERFACE_MODE_1000BASEX)
70 + return -EINVAL;
71 +
72 + return 0;
73 +}
74 +
75 +static const struct sfp_upstream_ops at803x_sfp_ops = {
76 + .attach = phy_sfp_attach,
77 + .detach = phy_sfp_detach,
78 + .module_insert = at803x_sfp_insert,
79 +};
80 +
81 static int at803x_parse_dt(struct phy_device *phydev)
82 {
83 struct device_node *node = phydev->mdio.dev.of_node;
84 @@ -662,6 +713,11 @@ static int at803x_parse_dt(struct phy_de
85 phydev_err(phydev, "failed to get VDDIO regulator\n");
86 return PTR_ERR(priv->vddio);
87 }
88 +
89 + /* Only AR8031/8033 support 1000Base-X for SFP modules */
90 + ret = phy_sfp_probe(phydev, &at803x_sfp_ops);
91 + if (ret < 0)
92 + return ret;
93 }
94
95 return 0;