mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-28 09:39:00 +00:00
c6ddf8d502
Many changes were done in drivers/pinctrl/bcm/pinctrl-bcm2835.c between 5.4.171 and 5.4.179. The following 3 patches do not apply any more: * target/linux/bcm27xx/patches-5.4/950-0316-pinctrl-bcm2835-Add-support-for-BCM2711-pull-up-func.patch This was already integrated in kernel v5.4-rc1, it was never needed. * target/linux/bcm27xx/patches-5.4/950-0328-Revert-pinctrl-bcm2835-Pass-irqchip-when-adding-gpio.patch * target/linux/bcm27xx/patches-5.4/950-0362-pinctrl-bcm2835-Change-init-order-for-gpio-hogs.patch I think these were done to fix the problem which was really fixed in commit 75278f1aff5e ("pinctrl: bcm2835: Change init order for gpio hogs") from v5.4.175 target/linux/generic/backport-5.4/716-v5.5-net-sfp-move-fwnode-parsing-into-sfp-bus-layer.patch Move fwnode_device_is_available to the same position as in kernel 5.10. target/linux/layerscape/patches-5.4/302-dts-0083-arm64-ls1028a-qds-correct-bus-of-rtc.patch Applied in commit 65816c1034769e714edb70f59a33bc5472d9e55f ("arm64: dts: ls1028a-qds: move rtc node to the correct i2c bus") Compile-tested: lantiq/xrx200, bcm27xx/bcm2710 Run-tested: lantiq/xrx200 Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
132 lines
4.6 KiB
Diff
132 lines
4.6 KiB
Diff
From f9a5a54b59cb904b37bf7409a43635ab195d0214 Mon Sep 17 00:00:00 2001
|
|
From: Russell King <rmk+kernel@armlinux.org.uk>
|
|
Date: Tue, 19 Nov 2019 10:13:25 +0000
|
|
Subject: [PATCH 646/660] net: sfp: add module start/stop upstream
|
|
notifications
|
|
|
|
When dealing with some copper modules, we can't positively know the
|
|
module capabilities are until we have probed the PHY. Without the full
|
|
capabilities, we may end up failing a module that we could otherwise
|
|
drive with a restricted set of capabilities.
|
|
|
|
An example of this would be a module with a NBASE-T PHY plugged into
|
|
a host that supports phy interface modes 2500BASE-X and SGMII. The
|
|
PHY supports 10GBASE-R, 5000BASE-X, 2500BASE-X, SGMII interface modes,
|
|
which means a subset of the capabilities are compatible with the host.
|
|
|
|
However, reading the module EEPROM leads us to believe that the module
|
|
only supports ethtool link mode 10GBASE-T, which is incompatible with
|
|
the host - and thus results in the module being rejected.
|
|
|
|
This patch adds an extra notification which are triggered after the
|
|
SFP module's PHY probe, and a corresponding notification just before
|
|
the PHY is removed.
|
|
|
|
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
|
|
---
|
|
drivers/net/phy/sfp-bus.c | 21 +++++++++++++++++++++
|
|
drivers/net/phy/sfp.c | 8 ++++++++
|
|
drivers/net/phy/sfp.h | 2 ++
|
|
include/linux/sfp.h | 4 ++++
|
|
4 files changed, 35 insertions(+)
|
|
|
|
--- a/drivers/net/phy/sfp-bus.c
|
|
+++ b/drivers/net/phy/sfp-bus.c
|
|
@@ -717,6 +717,27 @@ void sfp_module_remove(struct sfp_bus *b
|
|
}
|
|
EXPORT_SYMBOL_GPL(sfp_module_remove);
|
|
|
|
+int sfp_module_start(struct sfp_bus *bus)
|
|
+{
|
|
+ const struct sfp_upstream_ops *ops = sfp_get_upstream_ops(bus);
|
|
+ int ret = 0;
|
|
+
|
|
+ if (ops && ops->module_start)
|
|
+ ret = ops->module_start(bus->upstream);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+EXPORT_SYMBOL_GPL(sfp_module_start);
|
|
+
|
|
+void sfp_module_stop(struct sfp_bus *bus)
|
|
+{
|
|
+ const struct sfp_upstream_ops *ops = sfp_get_upstream_ops(bus);
|
|
+
|
|
+ if (ops && ops->module_stop)
|
|
+ ops->module_stop(bus->upstream);
|
|
+}
|
|
+EXPORT_SYMBOL_GPL(sfp_module_stop);
|
|
+
|
|
static void sfp_socket_clear(struct sfp_bus *bus)
|
|
{
|
|
bus->sfp_dev = NULL;
|
|
--- a/drivers/net/phy/sfp.c
|
|
+++ b/drivers/net/phy/sfp.c
|
|
@@ -59,6 +59,7 @@ enum {
|
|
SFP_DEV_UP,
|
|
|
|
SFP_S_DOWN = 0,
|
|
+ SFP_S_FAIL,
|
|
SFP_S_WAIT,
|
|
SFP_S_INIT,
|
|
SFP_S_INIT_TX_FAULT,
|
|
@@ -122,6 +123,7 @@ static const char *event_to_str(unsigned
|
|
|
|
static const char * const sm_state_strings[] = {
|
|
[SFP_S_DOWN] = "down",
|
|
+ [SFP_S_FAIL] = "fail",
|
|
[SFP_S_WAIT] = "wait",
|
|
[SFP_S_INIT] = "init",
|
|
[SFP_S_INIT_TX_FAULT] = "init_tx_fault",
|
|
@@ -1918,6 +1920,8 @@ static void sfp_sm_main(struct sfp *sfp,
|
|
if (sfp->sm_state == SFP_S_LINK_UP &&
|
|
sfp->sm_dev_state == SFP_DEV_UP)
|
|
sfp_sm_link_down(sfp);
|
|
+ if (sfp->sm_state > SFP_S_INIT)
|
|
+ sfp_module_stop(sfp->sfp_bus);
|
|
if (sfp->mod_phy)
|
|
sfp_sm_phy_detach(sfp);
|
|
sfp_module_tx_disable(sfp);
|
|
@@ -1985,6 +1989,10 @@ static void sfp_sm_main(struct sfp *sfp,
|
|
* clear. Probe for the PHY and check the LOS state.
|
|
*/
|
|
sfp_sm_probe_for_phy(sfp);
|
|
+ if (sfp_module_start(sfp->sfp_bus)) {
|
|
+ sfp_sm_next(sfp, SFP_S_FAIL, 0);
|
|
+ break;
|
|
+ }
|
|
sfp_sm_link_check_los(sfp);
|
|
|
|
/* Reset the fault retry count */
|
|
--- a/drivers/net/phy/sfp.h
|
|
+++ b/drivers/net/phy/sfp.h
|
|
@@ -22,6 +22,8 @@ void sfp_link_up(struct sfp_bus *bus);
|
|
void sfp_link_down(struct sfp_bus *bus);
|
|
int sfp_module_insert(struct sfp_bus *bus, const struct sfp_eeprom_id *id);
|
|
void sfp_module_remove(struct sfp_bus *bus);
|
|
+int sfp_module_start(struct sfp_bus *bus);
|
|
+void sfp_module_stop(struct sfp_bus *bus);
|
|
int sfp_link_configure(struct sfp_bus *bus, const struct sfp_eeprom_id *id);
|
|
struct sfp_bus *sfp_register_socket(struct device *dev, struct sfp *sfp,
|
|
const struct sfp_socket_ops *ops);
|
|
--- a/include/linux/sfp.h
|
|
+++ b/include/linux/sfp.h
|
|
@@ -507,6 +507,8 @@ struct sfp_bus;
|
|
* @module_insert: called after a module has been detected to determine
|
|
* whether the module is supported for the upstream device.
|
|
* @module_remove: called after the module has been removed.
|
|
+ * @module_start: called after the PHY probe step
|
|
+ * @module_stop: called before the PHY is removed
|
|
* @link_down: called when the link is non-operational for whatever
|
|
* reason.
|
|
* @link_up: called when the link is operational.
|
|
@@ -520,6 +522,8 @@ struct sfp_upstream_ops {
|
|
void (*detach)(void *priv, struct sfp_bus *bus);
|
|
int (*module_insert)(void *priv, const struct sfp_eeprom_id *id);
|
|
void (*module_remove)(void *priv);
|
|
+ int (*module_start)(void *priv);
|
|
+ void (*module_stop)(void *priv);
|
|
void (*link_down)(void *priv);
|
|
void (*link_up)(void *priv);
|
|
int (*connect_phy)(void *priv, struct phy_device *);
|