68 lines
2.0 KiB
Diff
68 lines
2.0 KiB
Diff
|
From 0836d9fb41ed90090ef4af0d7abe784ee7706f80 Mon Sep 17 00:00:00 2001
|
||
|
From: Russell King <rmk+kernel@armlinux.org.uk>
|
||
|
Date: Fri, 14 Apr 2017 14:21:25 +0100
|
||
|
Subject: [PATCH 636/660] net: phy: marvell10g: add SFP+ support
|
||
|
|
||
|
Add support for SFP+ cages to the Marvell 10G PHY driver. This is
|
||
|
slightly complicated by the way phylib works in that we need to use
|
||
|
a multi-step process to attach the SFP bus, and we also need to track
|
||
|
the phylink state machine to know when the module's transmit disable
|
||
|
signal should change state.
|
||
|
|
||
|
With appropriate DT changes, this allows the SFP+ canges on the
|
||
|
Macchiatobin platform to be functional.
|
||
|
|
||
|
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
|
||
|
---
|
||
|
drivers/net/phy/marvell10g.c | 25 ++++++++++++++++++++++++-
|
||
|
1 file changed, 24 insertions(+), 1 deletion(-)
|
||
|
|
||
|
--- a/drivers/net/phy/marvell10g.c
|
||
|
+++ b/drivers/net/phy/marvell10g.c
|
||
|
@@ -25,6 +25,7 @@
|
||
|
#include <linux/hwmon.h>
|
||
|
#include <linux/marvell_phy.h>
|
||
|
#include <linux/phy.h>
|
||
|
+#include <linux/sfp.h>
|
||
|
|
||
|
enum {
|
||
|
MV_PMA_BOOT = 0xc050,
|
||
|
@@ -219,6 +220,28 @@ static int mv3310_hwmon_probe(struct phy
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
+static int mv3310_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
|
||
|
+{
|
||
|
+ struct phy_device *phydev = upstream;
|
||
|
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(support) = { 0, };
|
||
|
+ phy_interface_t iface;
|
||
|
+
|
||
|
+ sfp_parse_support(phydev->sfp_bus, id, support);
|
||
|
+ iface = sfp_select_interface(phydev->sfp_bus, id, support);
|
||
|
+
|
||
|
+ if (iface != PHY_INTERFACE_MODE_10GKR) {
|
||
|
+ dev_err(&phydev->mdio.dev, "incompatible SFP module inserted\n");
|
||
|
+ return -EINVAL;
|
||
|
+ }
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static const struct sfp_upstream_ops mv3310_sfp_ops = {
|
||
|
+ .attach = phy_sfp_attach,
|
||
|
+ .detach = phy_sfp_detach,
|
||
|
+ .module_insert = mv3310_sfp_insert,
|
||
|
+};
|
||
|
+
|
||
|
static int mv3310_probe(struct phy_device *phydev)
|
||
|
{
|
||
|
struct mv3310_priv *priv;
|
||
|
@@ -249,7 +272,7 @@ static int mv3310_probe(struct phy_devic
|
||
|
if (ret)
|
||
|
return ret;
|
||
|
|
||
|
- return 0;
|
||
|
+ return phy_sfp_probe(phydev, &mv3310_sfp_ops);
|
||
|
}
|
||
|
|
||
|
static int mv3310_suspend(struct phy_device *phydev)
|