From: Russell King <rmk+kernel@armlinux.org.uk>
To: Andrew Lunn <andrew@lunn.ch>,
Florian Fainelli <f.fainelli@gmail.com>,
Heiner Kallweit <hkallweit1@gmail.com>
Cc: "David S. Miller" <davem@davemloft.net>, netdev@vger.kernel.org
Subject: [PATCH net-next 1/2] net: phy: add core phylib sfp support
Date: Sun, 10 Nov 2019 14:23:05 +0000 [thread overview]
Message-ID: <E1iTo7N-0005Sj-Nk@rmk-PC.armlinux.org.uk> (raw)
In-Reply-To: <20191110142226.GB25745@shell.armlinux.org.uk>
Add core phylib help for supporting SFP sockets on PHYs. This provides
a mechanism to inform the SFP layer about PHY up/down events, and also
unregister the SFP bus when the PHY is going away.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
drivers/net/phy/phy.c | 7 ++++
drivers/net/phy/phy_device.c | 66 ++++++++++++++++++++++++++++++++++++
include/linux/phy.h | 11 ++++++
3 files changed, 84 insertions(+)
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 0a314cf45408..cb9ab24ee898 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -23,6 +23,7 @@
#include <linux/ethtool.h>
#include <linux/phy.h>
#include <linux/phy_led_triggers.h>
+#include <linux/sfp.h>
#include <linux/workqueue.h>
#include <linux/mdio.h>
#include <linux/io.h>
@@ -866,6 +867,9 @@ void phy_stop(struct phy_device *phydev)
mutex_lock(&phydev->lock);
+ if (phydev->sfp_bus)
+ sfp_upstream_stop(phydev->sfp_bus);
+
phydev->state = PHY_HALTED;
mutex_unlock(&phydev->lock);
@@ -900,6 +904,9 @@ void phy_start(struct phy_device *phydev)
goto out;
}
+ if (phydev->sfp_bus)
+ sfp_upstream_start(phydev->sfp_bus);
+
/* if phy was suspended, bring the physical link up again */
__phy_resume(phydev);
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 9ddfb8b0ce04..ff47ec245100 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -27,6 +27,7 @@
#include <linux/bitmap.h>
#include <linux/phy.h>
#include <linux/phy_led_triggers.h>
+#include <linux/sfp.h>
#include <linux/mdio.h>
#include <linux/io.h>
#include <linux/uaccess.h>
@@ -1174,6 +1175,65 @@ phy_standalone_show(struct device *dev, struct device_attribute *attr,
}
static DEVICE_ATTR_RO(phy_standalone);
+/**
+ * phy_sfp_attach - attach the SFP bus to the PHY upstream network device
+ * @upstream: pointer to the phy device
+ * @bus: sfp bus representing cage being attached
+ *
+ * This is used to fill in the sfp_upstream_ops .attach member.
+ */
+void phy_sfp_attach(void *upstream, struct sfp_bus *bus)
+{
+ struct phy_device *phydev = upstream;
+
+ if (phydev->attached_dev)
+ phydev->attached_dev->sfp_bus = bus;
+ phydev->sfp_bus_attached = true;
+}
+EXPORT_SYMBOL(phy_sfp_attach);
+
+/**
+ * phy_sfp_detach - detach the SFP bus from the PHY upstream network device
+ * @upstream: pointer to the phy device
+ * @bus: sfp bus representing cage being attached
+ *
+ * This is used to fill in the sfp_upstream_ops .detach member.
+ */
+void phy_sfp_detach(void *upstream, struct sfp_bus *bus)
+{
+ struct phy_device *phydev = upstream;
+
+ if (phydev->attached_dev)
+ phydev->attached_dev->sfp_bus = NULL;
+ phydev->sfp_bus_attached = false;
+}
+EXPORT_SYMBOL(phy_sfp_detach);
+
+/**
+ * phy_sfp_probe - probe for a SFP cage attached to this PHY device
+ * @phydev: Pointer to phy_device
+ * @ops: SFP's upstream operations
+ */
+int phy_sfp_probe(struct phy_device *phydev,
+ const struct sfp_upstream_ops *ops)
+{
+ struct sfp_bus *bus;
+ int ret;
+
+ if (phydev->mdio.dev.fwnode) {
+ bus = sfp_bus_find_fwnode(phydev->mdio.dev.fwnode);
+ if (IS_ERR(bus))
+ return PTR_ERR(bus);
+
+ phydev->sfp_bus = bus;
+
+ ret = sfp_bus_add_upstream(bus, phydev, ops);
+ sfp_bus_put(bus);
+ }
+ return 0;
+}
+EXPORT_SYMBOL(phy_sfp_probe);
+
/**
* phy_attach_direct - attach a network device to a given PHY device pointer
* @dev: network device to attach
@@ -1249,6 +1309,9 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
if (dev) {
phydev->attached_dev = dev;
dev->phydev = phydev;
+
+ if (phydev->sfp_bus_attached)
+ dev->sfp_bus = phydev->sfp_bus;
}
/* Some Ethernet drivers try to connect to a PHY device before
@@ -2333,6 +2396,9 @@ static int phy_remove(struct device *dev)
phydev->state = PHY_DOWN;
mutex_unlock(&phydev->lock);
+ sfp_bus_del_upstream(phydev->sfp_bus);
+ phydev->sfp_bus = NULL;
+
if (phydev->drv && phydev->drv->remove) {
phydev->drv->remove(phydev);
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 1f9a141ccfb4..9753d9f28d73 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -203,6 +203,8 @@ static inline const char *phy_modes(phy_interface_t interface)
struct device;
struct phylink;
+struct sfp_bus;
+struct sfp_upstream_ops;
struct sk_buff;
/*
@@ -342,6 +344,8 @@ struct phy_c45_device_ids {
* dev_flags: Device-specific flags used by the PHY driver.
* irq: IRQ number of the PHY's interrupt (-1 if none)
* phy_timer: The timer for handling the state machine
+ * sfp_bus_attached: flag indicating whether the SFP bus has been attached
+ * sfp_bus: SFP bus attached to this PHY's fiber port
* attached_dev: The attached enet driver's device instance ptr
* adjust_link: Callback for the enet controller to respond to
* changes in the link state.
@@ -430,6 +434,9 @@ struct phy_device {
struct mutex lock;
+ /* This may be modified under the rtnl lock */
+ bool sfp_bus_attached;
+ struct sfp_bus *sfp_bus;
struct phylink *phylink;
struct net_device *attached_dev;
@@ -1015,6 +1022,10 @@ int phy_suspend(struct phy_device *phydev);
int phy_resume(struct phy_device *phydev);
int __phy_resume(struct phy_device *phydev);
int phy_loopback(struct phy_device *phydev, bool enable);
+void phy_sfp_attach(void *upstream, struct sfp_bus *bus);
+void phy_sfp_detach(void *upstream, struct sfp_bus *bus);
+int phy_sfp_probe(struct phy_device *phydev,
+ const struct sfp_upstream_ops *ops);
struct phy_device *phy_attach(struct net_device *dev, const char *bus_id,
phy_interface_t interface);
struct phy_device *phy_find_first(struct mii_bus *bus);
--
2.20.1
next prev parent reply other threads:[~2019-11-10 14:23 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-11-10 14:22 [PATCH net-next 0/2] Add support for SFPs behind PHYs Russell King - ARM Linux admin
2019-11-10 14:23 ` Russell King [this message]
2019-11-10 16:13 ` [PATCH net-next 1/2] net: phy: add core phylib sfp support Andrew Lunn
2019-11-10 16:40 ` Russell King - ARM Linux admin
2019-11-10 17:00 ` Andrew Lunn
2019-11-10 17:08 ` Russell King - ARM Linux admin
2019-11-10 17:22 ` Andrew Lunn
2019-11-11 14:01 ` Russell King - ARM Linux admin
2019-11-11 14:54 ` Russell King - ARM Linux admin
2019-11-11 15:01 ` Rob Herring
2019-11-11 15:07 ` Russell King - ARM Linux admin
2019-11-11 15:44 ` Rob Herring
2019-11-11 15:52 ` Russell King - ARM Linux admin
2019-11-10 14:23 ` [PATCH net-next 2/2] net: phy: marvell10g: add SFP+ support Russell King
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=E1iTo7N-0005Sj-Nk@rmk-PC.armlinux.org.uk \
--to=rmk+kernel@armlinux.org.uk \
--cc=andrew@lunn.ch \
--cc=davem@davemloft.net \
--cc=f.fainelli@gmail.com \
--cc=hkallweit1@gmail.com \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).