blob: 40a666a3f2ab5bc00592e6fd0a1d53d5a2ddd310 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001From 0836d9fb41ed90090ef4af0d7abe784ee7706f80 Mon Sep 17 00:00:00 2001
2From: Russell King <rmk+kernel@armlinux.org.uk>
3Date: Fri, 14 Apr 2017 14:21:25 +0100
4Subject: [PATCH 636/660] net: phy: marvell10g: add SFP+ support
5
6Add support for SFP+ cages to the Marvell 10G PHY driver. This is
7slightly complicated by the way phylib works in that we need to use
8a multi-step process to attach the SFP bus, and we also need to track
9the phylink state machine to know when the module's transmit disable
10signal should change state.
11
12With appropriate DT changes, this allows the SFP+ canges on the
13Macchiatobin platform to be functional.
14
15Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
16---
17 drivers/net/phy/marvell10g.c | 25 ++++++++++++++++++++++++-
18 1 file changed, 24 insertions(+), 1 deletion(-)
19
20--- a/drivers/net/phy/marvell10g.c
21+++ b/drivers/net/phy/marvell10g.c
22@@ -26,6 +26,7 @@
23 #include <linux/hwmon.h>
24 #include <linux/marvell_phy.h>
25 #include <linux/phy.h>
26+#include <linux/sfp.h>
27
28 #define MV_PHY_ALASKA_NBT_QUIRK_MASK 0xfffffffe
29 #define MV_PHY_ALASKA_NBT_QUIRK_REV (MARVELL_PHY_ID_88X3310 | 0xa)
30@@ -206,6 +207,28 @@ static int mv3310_hwmon_probe(struct phy
31 }
32 #endif
33
34+static int mv3310_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
35+{
36+ struct phy_device *phydev = upstream;
37+ __ETHTOOL_DECLARE_LINK_MODE_MASK(support) = { 0, };
38+ phy_interface_t iface;
39+
40+ sfp_parse_support(phydev->sfp_bus, id, support);
41+ iface = sfp_select_interface(phydev->sfp_bus, id, support);
42+
43+ if (iface != PHY_INTERFACE_MODE_10GKR) {
44+ dev_err(&phydev->mdio.dev, "incompatible SFP module inserted\n");
45+ return -EINVAL;
46+ }
47+ return 0;
48+}
49+
50+static const struct sfp_upstream_ops mv3310_sfp_ops = {
51+ .attach = phy_sfp_attach,
52+ .detach = phy_sfp_detach,
53+ .module_insert = mv3310_sfp_insert,
54+};
55+
56 static int mv3310_probe(struct phy_device *phydev)
57 {
58 struct mv3310_priv *priv;
59@@ -236,7 +259,7 @@ static int mv3310_probe(struct phy_devic
60 if (ret)
61 return ret;
62
63- return 0;
64+ return phy_sfp_probe(phydev, &mv3310_sfp_ops);
65 }
66
67 static int mv3310_suspend(struct phy_device *phydev)