* [PATCH 01/11] phy: add phy_interface_mode_is_8023z() helper
2017-12-01 10:23 ` [PATCH net-next 00/11] SFP/phylink updates Russell King - ARM Linux
@ 2017-12-01 10:24 ` Russell King
2017-12-01 17:20 ` Florian Fainelli
2017-12-01 10:24 ` [PATCH 02/11] phylink: merge SGMII and 802.3z handling Russell King
` (12 subsequent siblings)
13 siblings, 1 reply; 28+ messages in thread
From: Russell King @ 2017-12-01 10:24 UTC (permalink / raw)
To: Andrew Lunn, Florian Fainelli, Jonathan Corbet; +Cc: linux-doc, netdev
Add and use phy_interface_mode_is_8023z() helper to identify the
interface modes that use 802.3z negotiation. Use it in phylink's
phylink_mac_an_restart().
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
drivers/net/phy/phylink.c | 3 +--
include/linux/phy.h | 14 ++++++++++++++
2 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 5dc9668dde34..a02d67689d6e 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -320,8 +320,7 @@ static void phylink_mac_config(struct phylink *pl,
static void phylink_mac_an_restart(struct phylink *pl)
{
if (pl->link_config.an_enabled &&
- (pl->link_config.interface == PHY_INTERFACE_MODE_1000BASEX ||
- pl->link_config.interface == PHY_INTERFACE_MODE_2500BASEX))
+ phy_interface_mode_is_8023z(pl->link_config.interface))
pl->ops->mac_an_restart(pl->netdev);
}
diff --git a/include/linux/phy.h b/include/linux/phy.h
index dc82a07cb4fd..71d777fe6c3d 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -763,6 +763,20 @@ static inline bool phy_interface_mode_is_rgmii(phy_interface_t mode)
};
/**
+ * phy_interface_mode_is_8023z() - does the phy interface mode use 802.3z
+ * negotiation
+ * @mode: one of &enum phy_interface_t
+ *
+ * Returns true if the phy interface mode uses the 16-bit negotiation
+ * word as defined in 802.3z. (See 802.3-2015 37.2.1 Config_Reg encoding)
+ */
+static inline bool phy_interface_mode_is_8023z(phy_interface_t mode)
+{
+ return mode == PHY_INTERFACE_MODE_1000BASEX ||
+ mode == PHY_INTERFACE_MODE_2500BASEX;
+}
+
+/**
* phy_interface_is_rgmii - Convenience function for testing if a PHY interface
* is RGMII (all variants)
* @phydev: the phy_device struct
--
2.7.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 02/11] phylink: merge SGMII and 802.3z handling
2017-12-01 10:23 ` [PATCH net-next 00/11] SFP/phylink updates Russell King - ARM Linux
2017-12-01 10:24 ` [PATCH 01/11] phy: add phy_interface_mode_is_8023z() helper Russell King
@ 2017-12-01 10:24 ` Russell King
2017-12-01 17:21 ` Florian Fainelli
2017-12-01 10:24 ` [PATCH 03/11] phylink: get rid of separate Cisco SGMII and 802.3z modes Russell King
` (11 subsequent siblings)
13 siblings, 1 reply; 28+ messages in thread
From: Russell King @ 2017-12-01 10:24 UTC (permalink / raw)
To: Andrew Lunn, Florian Fainelli, Jonathan Corbet; +Cc: linux-doc, netdev
The code handling SGMII and 802.3z is essentially the same, except that
we assume 802.3z has no PHY. Re-organise the code such that these cases
are merged, and exclude 802.3z mode from having a PHY attached. This
results in the same link handling behaviour as before.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
drivers/net/phy/phylink.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index a02d67689d6e..d7006fdc8f71 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -423,6 +423,7 @@ static void phylink_resolve(struct work_struct *w)
break;
case MLO_AN_SGMII:
+ case MLO_AN_8023Z:
phylink_get_mac_state(pl, &link_state);
if (pl->phydev) {
bool changed = false;
@@ -448,10 +449,6 @@ static void phylink_resolve(struct work_struct *w)
}
}
break;
-
- case MLO_AN_8023Z:
- phylink_get_mac_state(pl, &link_state);
- break;
}
}
@@ -656,6 +653,10 @@ int phylink_connect_phy(struct phylink *pl, struct phy_device *phy)
{
int ret;
+ if (WARN_ON(pl->link_an_mode == MLO_AN_FIXED ||
+ pl->link_an_mode == MLO_AN_8023Z))
+ return -EINVAL;
+
ret = phy_attach_direct(pl->netdev, phy, 0, pl->link_interface);
if (ret)
return ret;
@@ -674,8 +675,9 @@ int phylink_of_phy_connect(struct phylink *pl, struct device_node *dn)
struct phy_device *phy_dev;
int ret;
- /* Fixed links are handled without needing a PHY */
- if (pl->link_an_mode == MLO_AN_FIXED)
+ /* Fixed links and 802.3z are handled without needing a PHY */
+ if (pl->link_an_mode == MLO_AN_FIXED ||
+ pl->link_an_mode == MLO_AN_8023Z)
return 0;
phy_node = of_parse_phandle(dn, "phy-handle", 0);
@@ -850,13 +852,13 @@ int phylink_ethtool_ksettings_get(struct phylink *pl,
break;
case MLO_AN_SGMII:
+ case MLO_AN_8023Z:
/* If there is a phy attached, then use the reported
* settings from the phy with no modification.
*/
if (pl->phydev)
break;
- case MLO_AN_8023Z:
phylink_get_mac_state(pl, &link_state);
/* The MAC is reporting the link results from its own PCS
--
2.7.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: [PATCH 02/11] phylink: merge SGMII and 802.3z handling
2017-12-01 10:24 ` [PATCH 02/11] phylink: merge SGMII and 802.3z handling Russell King
@ 2017-12-01 17:21 ` Florian Fainelli
0 siblings, 0 replies; 28+ messages in thread
From: Florian Fainelli @ 2017-12-01 17:21 UTC (permalink / raw)
To: Russell King, Andrew Lunn, Jonathan Corbet; +Cc: linux-doc, netdev
On 12/01/2017 02:24 AM, Russell King wrote:
> The code handling SGMII and 802.3z is essentially the same, except that
> we assume 802.3z has no PHY. Re-organise the code such that these cases
> are merged, and exclude 802.3z mode from having a PHY attached. This
> results in the same link handling behaviour as before.
>
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
--
Florian
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH 03/11] phylink: get rid of separate Cisco SGMII and 802.3z modes
2017-12-01 10:23 ` [PATCH net-next 00/11] SFP/phylink updates Russell King - ARM Linux
2017-12-01 10:24 ` [PATCH 01/11] phy: add phy_interface_mode_is_8023z() helper Russell King
2017-12-01 10:24 ` [PATCH 02/11] phylink: merge SGMII and 802.3z handling Russell King
@ 2017-12-01 10:24 ` Russell King
2017-12-01 17:22 ` Florian Fainelli
2017-12-01 10:24 ` [PATCH 04/11] phylink: add support for 2500baseX and 10GbaseKR Russell King
` (10 subsequent siblings)
13 siblings, 1 reply; 28+ messages in thread
From: Russell King @ 2017-12-01 10:24 UTC (permalink / raw)
To: Andrew Lunn, Florian Fainelli, Jonathan Corbet; +Cc: linux-doc, netdev
Since the handling of SGMII and 802.3z is now the same, combine the
MLO_AN_xxx constants into a single MLO_AN_INBAND, and use the PHY
interface mode to distinguish between Cisco SGMII and 802.3z.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
drivers/net/phy/phylink.c | 39 ++++++++++++++-------------------------
include/linux/phylink.h | 19 +++++++------------
2 files changed, 21 insertions(+), 37 deletions(-)
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index d7006fdc8f71..34ecdb892f57 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -117,8 +117,7 @@ static const char *phylink_an_mode_str(unsigned int mode)
static const char *modestr[] = {
[MLO_AN_PHY] = "phy",
[MLO_AN_FIXED] = "fixed",
- [MLO_AN_SGMII] = "SGMII",
- [MLO_AN_8023Z] = "802.3z",
+ [MLO_AN_INBAND] = "inband",
};
return mode < ARRAY_SIZE(modestr) ? modestr[mode] : "unknown";
@@ -244,6 +243,7 @@ static int phylink_parse_mode(struct phylink *pl, struct device_node *np)
phylink_set(pl->supported, Asym_Pause);
phylink_set(pl->supported, Pause);
pl->link_config.an_enabled = true;
+ pl->link_an_mode = MLO_AN_INBAND;
switch (pl->link_config.interface) {
case PHY_INTERFACE_MODE_SGMII:
@@ -253,17 +253,14 @@ static int phylink_parse_mode(struct phylink *pl, struct device_node *np)
phylink_set(pl->supported, 100baseT_Full);
phylink_set(pl->supported, 1000baseT_Half);
phylink_set(pl->supported, 1000baseT_Full);
- pl->link_an_mode = MLO_AN_SGMII;
break;
case PHY_INTERFACE_MODE_1000BASEX:
phylink_set(pl->supported, 1000baseX_Full);
- pl->link_an_mode = MLO_AN_8023Z;
break;
case PHY_INTERFACE_MODE_2500BASEX:
phylink_set(pl->supported, 2500baseX_Full);
- pl->link_an_mode = MLO_AN_8023Z;
break;
case PHY_INTERFACE_MODE_10GKR:
@@ -280,7 +277,6 @@ static int phylink_parse_mode(struct phylink *pl, struct device_node *np)
phylink_set(pl->supported, 10000baseLR_Full);
phylink_set(pl->supported, 10000baseLRM_Full);
phylink_set(pl->supported, 10000baseER_Full);
- pl->link_an_mode = MLO_AN_SGMII;
break;
default:
@@ -422,8 +418,7 @@ static void phylink_resolve(struct work_struct *w)
phylink_mac_config(pl, &link_state);
break;
- case MLO_AN_SGMII:
- case MLO_AN_8023Z:
+ case MLO_AN_INBAND:
phylink_get_mac_state(pl, &link_state);
if (pl->phydev) {
bool changed = false;
@@ -654,7 +649,8 @@ int phylink_connect_phy(struct phylink *pl, struct phy_device *phy)
int ret;
if (WARN_ON(pl->link_an_mode == MLO_AN_FIXED ||
- pl->link_an_mode == MLO_AN_8023Z))
+ (pl->link_an_mode == MLO_AN_INBAND &&
+ phy_interface_mode_is_8023z(pl->link_interface))))
return -EINVAL;
ret = phy_attach_direct(pl->netdev, phy, 0, pl->link_interface);
@@ -677,7 +673,8 @@ int phylink_of_phy_connect(struct phylink *pl, struct device_node *dn)
/* Fixed links and 802.3z are handled without needing a PHY */
if (pl->link_an_mode == MLO_AN_FIXED ||
- pl->link_an_mode == MLO_AN_8023Z)
+ (pl->link_an_mode == MLO_AN_INBAND &&
+ phy_interface_mode_is_8023z(pl->link_interface)))
return 0;
phy_node = of_parse_phandle(dn, "phy-handle", 0);
@@ -851,8 +848,7 @@ int phylink_ethtool_ksettings_get(struct phylink *pl,
phylink_get_ksettings(&link_state, kset);
break;
- case MLO_AN_SGMII:
- case MLO_AN_8023Z:
+ case MLO_AN_INBAND:
/* If there is a phy attached, then use the reported
* settings from the phy with no modification.
*/
@@ -1029,8 +1025,7 @@ int phylink_ethtool_set_pauseparam(struct phylink *pl,
phylink_mac_config(pl, config);
break;
- case MLO_AN_SGMII:
- case MLO_AN_8023Z:
+ case MLO_AN_INBAND:
phylink_mac_config(pl, config);
phylink_mac_an_restart(pl);
break;
@@ -1247,9 +1242,7 @@ static int phylink_mii_read(struct phylink *pl, unsigned int phy_id,
case MLO_AN_PHY:
return -EOPNOTSUPP;
- case MLO_AN_SGMII:
- /* No phy, fall through to 8023z method */
- case MLO_AN_8023Z:
+ case MLO_AN_INBAND:
if (phy_id == 0) {
val = phylink_get_mac_state(pl, &state);
if (val < 0)
@@ -1274,9 +1267,7 @@ static int phylink_mii_write(struct phylink *pl, unsigned int phy_id,
case MLO_AN_PHY:
return -EOPNOTSUPP;
- case MLO_AN_SGMII:
- /* No phy, fall through to 8023z method */
- case MLO_AN_8023Z:
+ case MLO_AN_INBAND:
break;
}
@@ -1291,7 +1282,7 @@ int phylink_mii_ioctl(struct phylink *pl, struct ifreq *ifr, int cmd)
WARN_ON(!lockdep_rtnl_is_held());
if (pl->phydev) {
- /* PHYs only exist for MLO_AN_PHY and MLO_AN_SGMII */
+ /* PHYs only exist for MLO_AN_PHY and SGMII */
switch (cmd) {
case SIOCGMIIPHY:
mii->phy_id = pl->phydev->mdio.addr;
@@ -1360,10 +1351,8 @@ static int phylink_sfp_module_insert(void *upstream,
switch (iface) {
case PHY_INTERFACE_MODE_SGMII:
- mode = MLO_AN_SGMII;
- break;
case PHY_INTERFACE_MODE_1000BASEX:
- mode = MLO_AN_8023Z;
+ mode = MLO_AN_INBAND;
break;
default:
return -EINVAL;
@@ -1390,7 +1379,7 @@ static int phylink_sfp_module_insert(void *upstream,
phylink_an_mode_str(mode), phy_modes(config.interface),
__ETHTOOL_LINK_MODE_MASK_NBITS, support);
- if (mode == MLO_AN_8023Z && pl->phydev)
+ if (phy_interface_mode_is_8023z(iface) && pl->phydev)
return -EINVAL;
changed = !bitmap_equal(pl->supported, support,
diff --git a/include/linux/phylink.h b/include/linux/phylink.h
index af67edd4ae38..cab22ad3bd6f 100644
--- a/include/linux/phylink.h
+++ b/include/linux/phylink.h
@@ -20,13 +20,12 @@ enum {
MLO_AN_PHY = 0, /* Conventional PHY */
MLO_AN_FIXED, /* Fixed-link mode */
- MLO_AN_SGMII, /* Cisco SGMII protocol */
- MLO_AN_8023Z, /* 1000base-X protocol */
+ MLO_AN_INBAND, /* In-band protocol */
};
static inline bool phylink_autoneg_inband(unsigned int mode)
{
- return mode == MLO_AN_SGMII || mode == MLO_AN_8023Z;
+ return mode == MLO_AN_INBAND;
}
struct phylink_link_state {
@@ -69,7 +68,7 @@ struct phylink_mac_ops {
/**
* mac_config: configure the MAC for the selected mode and state
* @ndev: net_device structure for the MAC
- * @mode: one of MLO_AN_FIXED, MLO_AN_PHY, MLO_AN_8023Z, MLO_AN_SGMII
+ * @mode: one of MLO_AN_FIXED, MLO_AN_PHY, MLO_AN_INBAND
* @state: state structure
*
* The action performed depends on the currently selected mode:
@@ -77,14 +76,10 @@ struct phylink_mac_ops {
* %MLO_AN_FIXED, %MLO_AN_PHY:
* set the specified speed, duplex, pause mode, and phy interface
* mode in the provided @state.
- * %MLO_AN_8023Z:
- * place the link in 1000base-X mode, advertising the parameters
- * given in advertising in @state.
- * %MLO_AN_SGMII:
- * place the link in Cisco SGMII mode - there is no advertisment
- * to make as the PHY communicates the speed and duplex to the
- * MAC over the in-band control word. Configuration of the pause
- * mode is as per MLO_AN_PHY since this is not included.
+ * %MLO_AN_INBAND:
+ * place the link in an inband negotiation mode (such as
+ * 1000base-X or Cisco SGMII mode depending on the phy interface
+ * mode), advertising the parameters given in advertising in @state.
*/
void (*mac_config)(struct net_device *ndev, unsigned int mode,
const struct phylink_link_state *state);
--
2.7.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 04/11] phylink: add support for 2500baseX and 10GbaseKR
2017-12-01 10:23 ` [PATCH net-next 00/11] SFP/phylink updates Russell King - ARM Linux
` (2 preceding siblings ...)
2017-12-01 10:24 ` [PATCH 03/11] phylink: get rid of separate Cisco SGMII and 802.3z modes Russell King
@ 2017-12-01 10:24 ` Russell King
2017-12-01 17:22 ` Florian Fainelli
2017-12-01 10:24 ` [PATCH 05/11] phylink: remove phylink_init_eee() Russell King
` (9 subsequent siblings)
13 siblings, 1 reply; 28+ messages in thread
From: Russell King @ 2017-12-01 10:24 UTC (permalink / raw)
To: Andrew Lunn, Florian Fainelli, Jonathan Corbet; +Cc: linux-doc, netdev
Add support for handling the faster 2.5G and 10G link modes when used
with SFP modules.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
drivers/net/phy/phylink.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 34ecdb892f57..06c6ad0603ac 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -1352,6 +1352,8 @@ static int phylink_sfp_module_insert(void *upstream,
switch (iface) {
case PHY_INTERFACE_MODE_SGMII:
case PHY_INTERFACE_MODE_1000BASEX:
+ case PHY_INTERFACE_MODE_2500BASEX:
+ case PHY_INTERFACE_MODE_10GKR:
mode = MLO_AN_INBAND;
break;
default:
--
2.7.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 05/11] phylink: remove phylink_init_eee()
2017-12-01 10:23 ` [PATCH net-next 00/11] SFP/phylink updates Russell King - ARM Linux
` (3 preceding siblings ...)
2017-12-01 10:24 ` [PATCH 04/11] phylink: add support for 2500baseX and 10GbaseKR Russell King
@ 2017-12-01 10:24 ` Russell King
2017-12-01 17:23 ` Florian Fainelli
2017-12-01 10:24 ` [PATCH 06/11] phylink: restart 802.3z negotiation when starting net device Russell King
` (8 subsequent siblings)
13 siblings, 1 reply; 28+ messages in thread
From: Russell King @ 2017-12-01 10:24 UTC (permalink / raw)
To: Andrew Lunn, Florian Fainelli, Jonathan Corbet; +Cc: linux-doc, netdev
phylink_init_eee() serves no purpose, remove it.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
drivers/net/phy/phylink.c | 13 -------------
include/linux/phylink.h | 1 -
2 files changed, 14 deletions(-)
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 06c6ad0603ac..560486463930 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -1064,19 +1064,6 @@ int phylink_ethtool_get_module_eeprom(struct phylink *pl,
}
EXPORT_SYMBOL_GPL(phylink_ethtool_get_module_eeprom);
-int phylink_init_eee(struct phylink *pl, bool clk_stop_enable)
-{
- int ret = -EPROTONOSUPPORT;
-
- WARN_ON(!lockdep_rtnl_is_held());
-
- if (pl->phydev)
- ret = phy_init_eee(pl->phydev, clk_stop_enable);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(phylink_init_eee);
-
int phylink_get_eee_err(struct phylink *pl)
{
int ret = 0;
diff --git a/include/linux/phylink.h b/include/linux/phylink.h
index cab22ad3bd6f..4d0f42da9078 100644
--- a/include/linux/phylink.h
+++ b/include/linux/phylink.h
@@ -123,7 +123,6 @@ int phylink_ethtool_set_pauseparam(struct phylink *,
int phylink_ethtool_get_module_info(struct phylink *, struct ethtool_modinfo *);
int phylink_ethtool_get_module_eeprom(struct phylink *,
struct ethtool_eeprom *, u8 *);
-int phylink_init_eee(struct phylink *, bool);
int phylink_get_eee_err(struct phylink *);
int phylink_ethtool_get_eee(struct phylink *, struct ethtool_eee *);
int phylink_ethtool_set_eee(struct phylink *, struct ethtool_eee *);
--
2.7.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 06/11] phylink: restart 802.3z negotiation when starting net device
2017-12-01 10:23 ` [PATCH net-next 00/11] SFP/phylink updates Russell King - ARM Linux
` (4 preceding siblings ...)
2017-12-01 10:24 ` [PATCH 05/11] phylink: remove phylink_init_eee() Russell King
@ 2017-12-01 10:24 ` Russell King
2017-12-01 17:24 ` Florian Fainelli
2017-12-01 10:24 ` [PATCH 07/11] phylink: add documentation for kernel APIs Russell King
` (7 subsequent siblings)
13 siblings, 1 reply; 28+ messages in thread
From: Russell King @ 2017-12-01 10:24 UTC (permalink / raw)
To: Andrew Lunn, Florian Fainelli, Jonathan Corbet; +Cc: linux-doc, netdev
Restart 802.3z negotiation when the net device is brought up to ensure
that the link partner has our current link modes.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
drivers/net/phy/phylink.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 560486463930..40563c8d7352 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -751,6 +751,12 @@ void phylink_start(struct phylink *pl)
phylink_resolve_flow(pl, &pl->link_config);
phylink_mac_config(pl, &pl->link_config);
+ /* Restart autonegotiation if using 802.3z to ensure that the link
+ * parameters are properly negotiated. This is necessary for DSA
+ * switches using 802.3z negotiation to ensure they see our modes.
+ */
+ phylink_mac_an_restart(pl);
+
clear_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state);
phylink_run_resolve(pl);
--
2.7.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 07/11] phylink: add documentation for kernel APIs
2017-12-01 10:23 ` [PATCH net-next 00/11] SFP/phylink updates Russell King - ARM Linux
` (5 preceding siblings ...)
2017-12-01 10:24 ` [PATCH 06/11] phylink: restart 802.3z negotiation when starting net device Russell King
@ 2017-12-01 10:24 ` Russell King
2017-12-01 17:28 ` Florian Fainelli
2017-12-01 10:24 ` [PATCH 08/11] sfp: " Russell King
` (6 subsequent siblings)
13 siblings, 1 reply; 28+ messages in thread
From: Russell King @ 2017-12-01 10:24 UTC (permalink / raw)
To: Andrew Lunn, Florian Fainelli, Jonathan Corbet; +Cc: linux-doc, netdev
Add kernel-doc documentation for phylink kernel APIs, and link it into
the networking kapi documentation under "Network device support".
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
Documentation/networking/kapi.rst | 12 +++
drivers/net/phy/phylink.c | 182 +++++++++++++++++++++++++++++++++++++
include/linux/phylink.h | 183 ++++++++++++++++++++++++++++----------
3 files changed, 329 insertions(+), 48 deletions(-)
diff --git a/Documentation/networking/kapi.rst b/Documentation/networking/kapi.rst
index 580289f345da..df4141b72f24 100644
--- a/Documentation/networking/kapi.rst
+++ b/Documentation/networking/kapi.rst
@@ -145,3 +145,15 @@ PHY Support
.. kernel-doc:: drivers/net/phy/mdio_bus.c
:internal:
+
+PHYLINK
+-------
+
+ PHYLINK interfaces traditional network drivers with PHYLIB, fixed-links,
+ and SFF modules (eg, hot-pluggable SFP) that may contain PHYs. PHYLINK
+ provides management of the link state and link modes.
+
+.. kernel-doc:: include/linux/phylink.h
+ :internal:
+
+.. kernel-doc:: drivers/net/phy/phylink.c
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 40563c8d7352..5a1bd48eb6d7 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -36,7 +36,11 @@ enum {
PHYLINK_DISABLE_LINK,
};
+/**
+ * struct phylink - internal data type for phylink
+ */
struct phylink {
+ /* private: */
struct net_device *netdev;
const struct phylink_mac_ops *ops;
@@ -87,6 +91,13 @@ static inline bool linkmode_empty(const unsigned long *src)
return bitmap_empty(src, __ETHTOOL_LINK_MODE_MASK_NBITS);
}
+/**
+ * phylink_set_port_modes() - set the port type modes in the ethtool mask
+ * @mask: ethtool link mode mask
+ *
+ * Sets all the port type modes in the ethtool mask. MAC drivers should
+ * use this in their 'validate' callback.
+ */
void phylink_set_port_modes(unsigned long *mask)
{
phylink_set(mask, TP);
@@ -496,6 +507,19 @@ static int phylink_register_sfp(struct phylink *pl, struct device_node *np)
return 0;
}
+/**
+ * phylink_create() - create a phylink instance
+ * @ndev: a pointer to the &struct net_device
+ * @np: a pointer to a &struct device_node describing the network interface
+ * @iface: the desired link mode defined by &typedef phy_interface_t
+ * @ops: a pointer to a &struct phylink_mac_ops for the MAC.
+ *
+ * Create a new phylink instance, and parse the link parameters found in @np.
+ * This will parse in-band modes, fixed-link or SFP configuration.
+ *
+ * Returns a pointer to a &struct phylink, or an error-pointer value. Users
+ * must use IS_ERR() to check for errors from this function.
+ */
struct phylink *phylink_create(struct net_device *ndev, struct device_node *np,
phy_interface_t iface,
const struct phylink_mac_ops *ops)
@@ -548,6 +572,13 @@ struct phylink *phylink_create(struct net_device *ndev, struct device_node *np,
}
EXPORT_SYMBOL_GPL(phylink_create);
+/**
+ * phylink_destroy() - cleanup and destroy the phylink instance
+ * @pl: a pointer to a &struct phylink returned from phylink_create()
+ *
+ * Destroy a phylink instance. Any PHY that has been attached must have been
+ * cleaned up via phylink_disconnect_phy() prior to calling this function.
+ */
void phylink_destroy(struct phylink *pl)
{
if (pl->sfp_bus)
@@ -644,6 +675,21 @@ static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy)
return 0;
}
+/**
+ * phylink_connect_phy() - connect a PHY to the phylink instance
+ * @pl: a pointer to a &struct phylink returned from phylink_create()
+ * @phy: a pointer to a &struct phy_device.
+ *
+ * Connect @phy to the phylink instance specified by @pl by calling
+ * phy_attach_direct(). Configure the @phy according to the MAC driver's
+ * capabilities, start the PHYLIB state machine and enable any interrupts
+ * that the PHY supports.
+ *
+ * This updates the phylink's ethtool supported and advertising link mode
+ * masks.
+ *
+ * Returns 0 on success or a negative errno.
+ */
int phylink_connect_phy(struct phylink *pl, struct phy_device *phy)
{
int ret;
@@ -665,6 +711,17 @@ int phylink_connect_phy(struct phylink *pl, struct phy_device *phy)
}
EXPORT_SYMBOL_GPL(phylink_connect_phy);
+/**
+ * phylink_of_phy_connect() - connect the PHY specified in the DT mode.
+ * @pl: a pointer to a &struct phylink returned from phylink_create()
+ * @dn: a pointer to a &struct device_node.
+ *
+ * Connect the phy specified in the device node @dn to the phylink instance
+ * specified by @pl. Actions specified in phylink_connect_phy() will be
+ * performed.
+ *
+ * Returns 0 on success or a negative errno.
+ */
int phylink_of_phy_connect(struct phylink *pl, struct device_node *dn)
{
struct device_node *phy_node;
@@ -706,6 +763,13 @@ int phylink_of_phy_connect(struct phylink *pl, struct device_node *dn)
}
EXPORT_SYMBOL_GPL(phylink_of_phy_connect);
+/**
+ * phylink_disconnect_phy() - disconnect any PHY attached to the phylink
+ * instance.
+ * @pl: a pointer to a &struct phylink returned from phylink_create()
+ *
+ * Disconnect any current PHY from the phylink instance described by @pl.
+ */
void phylink_disconnect_phy(struct phylink *pl)
{
struct phy_device *phy;
@@ -727,6 +791,14 @@ void phylink_disconnect_phy(struct phylink *pl)
}
EXPORT_SYMBOL_GPL(phylink_disconnect_phy);
+/**
+ * phylink_mac_change() - notify phylink of a change in MAC state
+ * @pl: a pointer to a &struct phylink returned from phylink_create()
+ * @up: indicates whether the link is currently up.
+ *
+ * The MAC driver should call this driver when the state of its link
+ * changes (eg, link failure, new negotiation results, etc.)
+ */
void phylink_mac_change(struct phylink *pl, bool up)
{
if (!up)
@@ -736,6 +808,14 @@ void phylink_mac_change(struct phylink *pl, bool up)
}
EXPORT_SYMBOL_GPL(phylink_mac_change);
+/**
+ * phylink_start() - start a phylink instance
+ * @pl: a pointer to a &struct phylink returned from phylink_create()
+ *
+ * Start the phylink instance specified by @pl, configuring the MAC for the
+ * desired link mode(s) and negotiation style. This should be called from the
+ * network device driver's &struct net_device_ops ndo_open() method.
+ */
void phylink_start(struct phylink *pl)
{
WARN_ON(!lockdep_rtnl_is_held());
@@ -767,6 +847,15 @@ void phylink_start(struct phylink *pl)
}
EXPORT_SYMBOL_GPL(phylink_start);
+/**
+ * phylink_stop() - stop a phylink instance
+ * @pl: a pointer to a &struct phylink returned from phylink_create()
+ *
+ * Stop the phylink instance specified by @pl. This should be called from the
+ * network device driver's &struct net_device_ops ndo_stop() method. The
+ * network device's carrier state should not be changed prior to calling this
+ * function.
+ */
void phylink_stop(struct phylink *pl)
{
WARN_ON(!lockdep_rtnl_is_held());
@@ -782,6 +871,15 @@ void phylink_stop(struct phylink *pl)
}
EXPORT_SYMBOL_GPL(phylink_stop);
+/**
+ * phylink_ethtool_get_wol() - get the wake on lan parameters for the PHY
+ * @pl: a pointer to a &struct phylink returned from phylink_create()
+ * @wol: a pointer to &struct ethtool_wolinfo to hold the read parameters
+ *
+ * Read the wake on lan parameters from the PHY attached to the phylink
+ * instance specified by @pl. If no PHY is currently attached, report no
+ * support for wake on lan.
+ */
void phylink_ethtool_get_wol(struct phylink *pl, struct ethtool_wolinfo *wol)
{
WARN_ON(!lockdep_rtnl_is_held());
@@ -794,6 +892,17 @@ void phylink_ethtool_get_wol(struct phylink *pl, struct ethtool_wolinfo *wol)
}
EXPORT_SYMBOL_GPL(phylink_ethtool_get_wol);
+/**
+ * phylink_ethtool_set_wol() - set wake on lan parameters
+ * @pl: a pointer to a &struct phylink returned from phylink_create()
+ * @wol: a pointer to &struct ethtool_wolinfo for the desired parameters
+ *
+ * Set the wake on lan parameters for the PHY attached to the phylink
+ * instance specified by @pl. If no PHY is attached, returns %EOPNOTSUPP
+ * error.
+ *
+ * Returns zero on success or negative errno code.
+ */
int phylink_ethtool_set_wol(struct phylink *pl, struct ethtool_wolinfo *wol)
{
int ret = -EOPNOTSUPP;
@@ -829,6 +938,15 @@ static void phylink_get_ksettings(const struct phylink_link_state *state,
AUTONEG_DISABLE;
}
+/**
+ * phylink_ethtool_ksettings_get() - get the current link settings
+ * @pl: a pointer to a &struct phylink returned from phylink_create()
+ * @kset: a pointer to a &struct ethtool_link_ksettings to hold link settings
+ *
+ * Read the current link settings for the phylink instance specified by @pl.
+ * This will be the link settings read from the MAC, PHY or fixed link
+ * settings depending on the current negotiation mode.
+ */
int phylink_ethtool_ksettings_get(struct phylink *pl,
struct ethtool_link_ksettings *kset)
{
@@ -875,6 +993,11 @@ int phylink_ethtool_ksettings_get(struct phylink *pl,
}
EXPORT_SYMBOL_GPL(phylink_ethtool_ksettings_get);
+/**
+ * phylink_ethtool_ksettings_set() - set the link settings
+ * @pl: a pointer to a &struct phylink returned from phylink_create()
+ * @kset: a pointer to a &struct ethtool_link_ksettings for the desired modes
+ */
int phylink_ethtool_ksettings_set(struct phylink *pl,
const struct ethtool_link_ksettings *kset)
{
@@ -968,6 +1091,17 @@ int phylink_ethtool_ksettings_set(struct phylink *pl,
}
EXPORT_SYMBOL_GPL(phylink_ethtool_ksettings_set);
+/**
+ * phylink_ethtool_nway_reset() - restart negotiation
+ * @pl: a pointer to a &struct phylink returned from phylink_create()
+ *
+ * Restart negotiation for the phylink instance specified by @pl. This will
+ * cause any attached phy to restart negotiation with the link partner, and
+ * if the MAC is in a BaseX mode, the MAC will also be requested to restart
+ * negotiation.
+ *
+ * Returns zero on success, or negative error code.
+ */
int phylink_ethtool_nway_reset(struct phylink *pl)
{
int ret = 0;
@@ -982,6 +1116,11 @@ int phylink_ethtool_nway_reset(struct phylink *pl)
}
EXPORT_SYMBOL_GPL(phylink_ethtool_nway_reset);
+/**
+ * phylink_ethtool_get_pauseparam() - get the current pause parameters
+ * @pl: a pointer to a &struct phylink returned from phylink_create()
+ * @pause: a pointer to a &struct ethtool_pauseparam
+ */
void phylink_ethtool_get_pauseparam(struct phylink *pl,
struct ethtool_pauseparam *pause)
{
@@ -993,6 +1132,11 @@ void phylink_ethtool_get_pauseparam(struct phylink *pl,
}
EXPORT_SYMBOL_GPL(phylink_ethtool_get_pauseparam);
+/**
+ * phylink_ethtool_set_pauseparam() - set the current pause parameters
+ * @pl: a pointer to a &struct phylink returned from phylink_create()
+ * @pause: a pointer to a &struct ethtool_pauseparam
+ */
int phylink_ethtool_set_pauseparam(struct phylink *pl,
struct ethtool_pauseparam *pause)
{
@@ -1070,6 +1214,16 @@ int phylink_ethtool_get_module_eeprom(struct phylink *pl,
}
EXPORT_SYMBOL_GPL(phylink_ethtool_get_module_eeprom);
+/**
+ * phylink_ethtool_get_eee_err() - read the energy efficient ethernet error
+ * counter
+ * @pl: a pointer to a &struct phylink returned from phylink_create().
+ *
+ * Read the Energy Efficient Ethernet error counter from the PHY associated
+ * with the phylink instance specified by @pl.
+ *
+ * Returns positive error counter value, or negative error code.
+ */
int phylink_get_eee_err(struct phylink *pl)
{
int ret = 0;
@@ -1083,6 +1237,11 @@ int phylink_get_eee_err(struct phylink *pl)
}
EXPORT_SYMBOL_GPL(phylink_get_eee_err);
+/**
+ * phylink_ethtool_get_eee() - read the energy efficient ethernet parameters
+ * @pl: a pointer to a &struct phylink returned from phylink_create()
+ * @eee: a pointer to a &struct ethtool_eee for the read parameters
+ */
int phylink_ethtool_get_eee(struct phylink *pl, struct ethtool_eee *eee)
{
int ret = -EOPNOTSUPP;
@@ -1096,6 +1255,11 @@ int phylink_ethtool_get_eee(struct phylink *pl, struct ethtool_eee *eee)
}
EXPORT_SYMBOL_GPL(phylink_ethtool_get_eee);
+/**
+ * phylink_ethtool_set_eee() - set the energy efficient ethernet parameters
+ * @pl: a pointer to a &struct phylink returned from phylink_create()
+ * @eee: a pointer to a &struct ethtool_eee for the desired parameters
+ */
int phylink_ethtool_set_eee(struct phylink *pl, struct ethtool_eee *eee)
{
int ret = -EOPNOTSUPP;
@@ -1267,6 +1431,24 @@ static int phylink_mii_write(struct phylink *pl, unsigned int phy_id,
return 0;
}
+/**
+ * phylink_mii_ioctl() - generic mii ioctl interface
+ * @pl: a pointer to a &struct phylink returned from phylink_create()
+ * @ifr: a pointer to a &struct ifreq for socket ioctls
+ * @cmd: ioctl cmd to execute
+ *
+ * Perform the specified MII ioctl on the PHY attached to the phylink instance
+ * specified by @pl. If no PHY is attached, emulate the presence of the PHY.
+ *
+ * Returns: zero on success or negative error code.
+ *
+ * %SIOCGMIIPHY:
+ * read register from the current PHY.
+ * %SIOCGMIIREG:
+ * read register from the specified PHY.
+ * %SIOCSMIIREG:
+ * set a register on the specified PHY.
+ */
int phylink_mii_ioctl(struct phylink *pl, struct ifreq *ifr, int cmd)
{
struct mii_ioctl_data *mii = if_mii(ifr);
diff --git a/include/linux/phylink.h b/include/linux/phylink.h
index 4d0f42da9078..30e9d0070377 100644
--- a/include/linux/phylink.h
+++ b/include/linux/phylink.h
@@ -28,10 +28,23 @@ static inline bool phylink_autoneg_inband(unsigned int mode)
return mode == MLO_AN_INBAND;
}
+/**
+ * struct phylink_link_state - link state structure
+ * @advertising: ethtool bitmask containing advertised link modes
+ * @lp_advertising: ethtool bitmask containing link partner advertised link
+ * modes
+ * @interface: link &typedef phy_interface_t mode
+ * @speed: link speed, one of the SPEED_* constants.
+ * @duplex: link duplex mode, one of DUPLEX_* constants.
+ * @pause: link pause state, described by MLO_PAUSE_* constants.
+ * @link: true if the link is up.
+ * @an_enabled: true if autonegotiation is enabled/desired.
+ * @an_complete: true if autonegotiation has completed.
+ */
struct phylink_link_state {
__ETHTOOL_DECLARE_LINK_MODE_MASK(advertising);
__ETHTOOL_DECLARE_LINK_MODE_MASK(lp_advertising);
- phy_interface_t interface; /* PHY_INTERFACE_xxx */
+ phy_interface_t interface;
int speed;
int duplex;
int pause;
@@ -40,61 +53,135 @@ struct phylink_link_state {
unsigned int an_complete:1;
};
+/**
+ * struct phylink_mac_ops - MAC operations structure.
+ * @validate: Validate and update the link configuration.
+ * @mac_link_state: Read the current link state from the hardware.
+ * @mac_config: configure the MAC for the selected mode and state.
+ * @mac_an_restart: restart 802.3z BaseX autonegotiation.
+ * @mac_link_down: take the link down.
+ * @mac_link_up: allow the link to come up.
+ *
+ * The individual methods are described more fully below.
+ */
struct phylink_mac_ops {
- /**
- * validate: validate and update the link configuration
- * @ndev: net_device structure associated with MAC
- * @config: configuration to validate
- *
- * Update the %config->supported and %config->advertised masks
- * clearing bits that can not be supported.
- *
- * Note: the PHY may be able to transform from one connection
- * technology to another, so, eg, don't clear 1000BaseX just
- * because the MAC is unable to support it. This is more about
- * clearing unsupported speeds and duplex settings.
- *
- * If the %config->interface mode is %PHY_INTERFACE_MODE_1000BASEX
- * or %PHY_INTERFACE_MODE_2500BASEX, select the appropriate mode
- * based on %config->advertised and/or %config->speed.
- */
void (*validate)(struct net_device *ndev, unsigned long *supported,
struct phylink_link_state *state);
-
- /* Read the current link state from the hardware */
- int (*mac_link_state)(struct net_device *, struct phylink_link_state *);
-
- /* Configure the MAC */
- /**
- * mac_config: configure the MAC for the selected mode and state
- * @ndev: net_device structure for the MAC
- * @mode: one of MLO_AN_FIXED, MLO_AN_PHY, MLO_AN_INBAND
- * @state: state structure
- *
- * The action performed depends on the currently selected mode:
- *
- * %MLO_AN_FIXED, %MLO_AN_PHY:
- * set the specified speed, duplex, pause mode, and phy interface
- * mode in the provided @state.
- * %MLO_AN_INBAND:
- * place the link in an inband negotiation mode (such as
- * 1000base-X or Cisco SGMII mode depending on the phy interface
- * mode), advertising the parameters given in advertising in @state.
- */
+ int (*mac_link_state)(struct net_device *ndev,
+ struct phylink_link_state *state);
void (*mac_config)(struct net_device *ndev, unsigned int mode,
const struct phylink_link_state *state);
-
- /**
- * mac_an_restart: restart 802.3z BaseX autonegotiation
- * @ndev: net_device structure for the MAC
- */
void (*mac_an_restart)(struct net_device *ndev);
-
- void (*mac_link_down)(struct net_device *, unsigned int mode);
- void (*mac_link_up)(struct net_device *, unsigned int mode,
- struct phy_device *);
+ void (*mac_link_down)(struct net_device *ndev, unsigned int mode);
+ void (*mac_link_up)(struct net_device *ndev, unsigned int mode,
+ struct phy_device *phy);
};
+#if 0 /* For kernel-doc purposes only. */
+/**
+ * validate - Validate and update the link configuration
+ * @ndev: a pointer to a &struct net_device for the MAC.
+ * @supported: ethtool bitmask for supported link modes.
+ * @state: a pointer to a &struct phylink_link_state.
+ *
+ * Clear bits in the @supported and @state->advertising masks that
+ * are not supportable by the MAC.
+ *
+ * Note that the PHY may be able to transform from one connection
+ * technology to another, so, eg, don't clear 1000BaseX just
+ * because the MAC is unable to BaseX mode. This is more about
+ * clearing unsupported speeds and duplex settings.
+ *
+ * If the @state->interface mode is %PHY_INTERFACE_MODE_1000BASEX
+ * or %PHY_INTERFACE_MODE_2500BASEX, select the appropriate mode
+ * based on @state->advertising and/or @state->speed and update
+ * @state->interface accordingly.
+ */
+void validate(struct net_device *ndev, unsigned long *supported,
+ struct phylink_link_state *state);
+
+/**
+ * mac_link_state() - Read the current link state from the hardware
+ * @ndev: a pointer to a &struct net_device for the MAC.
+ * @state: a pointer to a &struct phylink_link_state.
+ *
+ * Read the current link state from the MAC, reporting the current
+ * speed in @state->speed, duplex mode in @state->duplex, pause mode
+ * in @state->pause using the %MLO_PAUSE_RX and %MLO_PAUSE_TX bits,
+ * negotiation completion state in @state->an_complete, and link
+ * up state in @state->link.
+ */
+int mac_link_state(struct net_device *ndev,
+ struct phylink_link_state *state);
+
+/**
+ * mac_config() - configure the MAC for the selected mode and state
+ * @ndev: a pointer to a &struct net_device for the MAC.
+ * @mode: one of %MLO_AN_FIXED, %MLO_AN_PHY, %MLO_AN_INBAND.
+ * @state: a pointer to a &struct phylink_link_state.
+ *
+ * The action performed depends on the currently selected mode:
+ *
+ * %MLO_AN_FIXED, %MLO_AN_PHY:
+ * Configure the specified @state->speed, @state->duplex and
+ * @state->pause (%MLO_PAUSE_TX / %MLO_PAUSE_RX) mode.
+ *
+ * %MLO_AN_INBAND:
+ * place the link in an inband negotiation mode (such as 802.3z
+ * 1000base-X or Cisco SGMII mode depending on the @state->interface
+ * mode). In both cases, link state management (whether the link
+ * is up or not) is performed by the MAC, and reported via the
+ * mac_link_state() callback. Changes in link state must be made
+ * by calling phylink_mac_change().
+ *
+ * If in 802.3z mode, the link speed is fixed, dependent on the
+ * @state->interface. Duplex is negotiated, and pause is advertised
+ * according to @state->an_enabled, @state->pause and
+ * @state->advertising flags. Beware of MACs which only support full
+ * duplex at gigabit and higher speeds.
+ *
+ * If in Cisco SGMII mode, the link speed and duplex mode are passed
+ * in the serial bitstream 16-bit configuration word, and the MAC
+ * should be configured to read these bits and acknowledge the
+ * configuration word. Nothing is advertised by the MAC. The MAC is
+ * responsible for reading the configuration word and configuring
+ * itself accordingly.
+ */
+void mac_config(struct net_device *ndev, unsigned int mode,
+ const struct phylink_link_state *state);
+
+/**
+ * mac_an_restart() - restart 802.3z BaseX autonegotiation
+ * @ndev: a pointer to a &struct net_device for the MAC.
+ */
+void mac_an_restart(struct net_device *ndev);
+
+/**
+ * mac_link_down() - take the link down
+ * @ndev: a pointer to a &struct net_device for the MAC.
+ * @mode: link autonegotiation mode
+ *
+ * If @mode is not an in-band negotiation mode (as defined by
+ * phylink_autoneg_inband()), force the link down and disable any
+ * Energy Efficient Ethernet MAC configuration.
+ */
+void mac_link_down(struct net_device *ndev, unsigned int mode);
+
+/**
+ * mac_link_up() - allow the link to come up
+ * @ndev: a pointer to a &struct net_device for the MAC.
+ * @mode: link autonegotiation mode
+ * @phy: any attached phy
+ *
+ * If @mode is not an in-band negotiation mode (as defined by
+ * phylink_autoneg_inband()), allow the link to come up. If @phy
+ * is non-%NULL, configure Energy Efficient Ethernet by calling
+ * phy_init_eee() and perform appropriate MAC configuration for EEE.
+ */
+void mac_link_up(struct net_device *ndev, unsigned int mode,
+ struct phy_device *phy);
+#endif
+
struct phylink *phylink_create(struct net_device *, struct device_node *,
phy_interface_t iface, const struct phylink_mac_ops *ops);
void phylink_destroy(struct phylink *);
--
2.7.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 08/11] sfp: add documentation for kernel APIs
2017-12-01 10:23 ` [PATCH net-next 00/11] SFP/phylink updates Russell King - ARM Linux
` (6 preceding siblings ...)
2017-12-01 10:24 ` [PATCH 07/11] phylink: add documentation for kernel APIs Russell King
@ 2017-12-01 10:24 ` Russell King
2017-12-01 17:28 ` Florian Fainelli
2017-12-01 10:24 ` [PATCH 09/11] sfp: fix sparse warning Russell King
` (5 subsequent siblings)
13 siblings, 1 reply; 28+ messages in thread
From: Russell King @ 2017-12-01 10:24 UTC (permalink / raw)
To: Andrew Lunn, Florian Fainelli, Jonathan Corbet; +Cc: linux-doc, netdev
Add kernel-doc documentation for sfp kernel APIs, and link it into the
networking kapi documentation under "Network device support".
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
Documentation/networking/kapi.rst | 12 +++++
drivers/net/phy/sfp-bus.c | 104 ++++++++++++++++++++++++++++++++++++++
include/linux/sfp.h | 50 +++++++++++++-----
3 files changed, 152 insertions(+), 14 deletions(-)
diff --git a/Documentation/networking/kapi.rst b/Documentation/networking/kapi.rst
index df4141b72f24..f03ae64be8bc 100644
--- a/Documentation/networking/kapi.rst
+++ b/Documentation/networking/kapi.rst
@@ -157,3 +157,15 @@ PHYLINK
:internal:
.. kernel-doc:: drivers/net/phy/phylink.c
+
+SFP support
+-----------
+
+.. kernel-doc:: drivers/net/phy/sfp-bus.c
+ :internal:
+
+.. kernel-doc:: include/linux/sfp.h
+ :internal:
+
+.. kernel-doc:: drivers/net/phy/sfp-bus.c
+ :export:
diff --git a/drivers/net/phy/sfp-bus.c b/drivers/net/phy/sfp-bus.c
index 8a1b1f4c1b7c..2b8c256156a2 100644
--- a/drivers/net/phy/sfp-bus.c
+++ b/drivers/net/phy/sfp-bus.c
@@ -8,7 +8,11 @@
#include "sfp.h"
+/**
+ * struct sfp_bus - internal representation of a sfp bus
+ */
struct sfp_bus {
+ /* private: */
struct kref kref;
struct list_head node;
struct device_node *device_node;
@@ -26,6 +30,20 @@ struct sfp_bus {
bool started;
};
+/**
+ * sfp_parse_port() - Parse the EEPROM base ID, setting the port type
+ * @bus: a pointer to the &struct sfp_bus structure for the sfp module
+ * @id: a pointer to the module's &struct sfp_eeprom_id
+ * @support: optional pointer to an array of unsigned long for the
+ * ethtool support mask
+ *
+ * Parse the EEPROM identification given in @id, and return one of
+ * %PORT_TP, %PORT_FIBRE or %PORT_OTHER. If @support is non-%NULL,
+ * also set the ethtool %ETHTOOL_LINK_MODE_xxx_BIT corresponding with
+ * the connector type.
+ *
+ * If the port type is not known, returns %PORT_OTHER.
+ */
int sfp_parse_port(struct sfp_bus *bus, const struct sfp_eeprom_id *id,
unsigned long *support)
{
@@ -78,6 +96,24 @@ int sfp_parse_port(struct sfp_bus *bus, const struct sfp_eeprom_id *id,
}
EXPORT_SYMBOL_GPL(sfp_parse_port);
+/**
+ * sfp_parse_interface() - Parse the phy_interface_t
+ * @bus: a pointer to the &struct sfp_bus structure for the sfp module
+ * @id: a pointer to the module's &struct sfp_eeprom_id
+ *
+ * Derive the phy_interface_t mode for the information found in the
+ * module's identifying EEPROM. There is no standard or defined way
+ * to derive this information, so we use some heuristics.
+ *
+ * If the encoding is 64b66b, then the module must be >= 10G, so
+ * return %PHY_INTERFACE_MODE_10GKR.
+ *
+ * If it's 8b10b, then it's 1G or slower. If it's definitely a fibre
+ * module, return %PHY_INTERFACE_MODE_1000BASEX mode, otherwise return
+ * %PHY_INTERFACE_MODE_SGMII mode.
+ *
+ * If the encoding is not known, return %PHY_INTERFACE_MODE_NA.
+ */
phy_interface_t sfp_parse_interface(struct sfp_bus *bus,
const struct sfp_eeprom_id *id)
{
@@ -117,6 +153,15 @@ phy_interface_t sfp_parse_interface(struct sfp_bus *bus,
}
EXPORT_SYMBOL_GPL(sfp_parse_interface);
+/**
+ * sfp_parse_support() - Parse the eeprom id for supported link modes
+ * @bus: a pointer to the &struct sfp_bus structure for the sfp module
+ * @id: a pointer to the module's &struct sfp_eeprom_id
+ * @support: pointer to an array of unsigned long for the ethtool support mask
+ *
+ * Parse the EEPROM identification information and derive the supported
+ * ethtool link modes for the module.
+ */
void sfp_parse_support(struct sfp_bus *bus, const struct sfp_eeprom_id *id,
unsigned long *support)
{
@@ -293,6 +338,16 @@ static void sfp_unregister_bus(struct sfp_bus *bus)
bus->registered = false;
}
+/**
+ * sfp_get_module_info() - Get the ethtool_modinfo for a SFP module
+ * @bus: a pointer to the &struct sfp_bus structure for the sfp module
+ * @modinfo: a &struct ethtool_modinfo
+ *
+ * Fill in the type and eeprom_len parameters in @modinfo for a module on
+ * the sfp bus specified by @bus.
+ *
+ * Returns 0 on success or a negative errno number.
+ */
int sfp_get_module_info(struct sfp_bus *bus, struct ethtool_modinfo *modinfo)
{
if (!bus->registered)
@@ -301,6 +356,17 @@ int sfp_get_module_info(struct sfp_bus *bus, struct ethtool_modinfo *modinfo)
}
EXPORT_SYMBOL_GPL(sfp_get_module_info);
+/**
+ * sfp_get_module_eeprom() - Read the SFP module EEPROM
+ * @bus: a pointer to the &struct sfp_bus structure for the sfp module
+ * @ee: a &struct ethtool_eeprom
+ * @data: buffer to contain the EEPROM data (must be at least @ee->len bytes)
+ *
+ * Read the EEPROM as specified by the supplied @ee. See the documentation
+ * for &struct ethtool_eeprom for the region to be read.
+ *
+ * Returns 0 on success or a negative errno number.
+ */
int sfp_get_module_eeprom(struct sfp_bus *bus, struct ethtool_eeprom *ee,
u8 *data)
{
@@ -310,6 +376,15 @@ int sfp_get_module_eeprom(struct sfp_bus *bus, struct ethtool_eeprom *ee,
}
EXPORT_SYMBOL_GPL(sfp_get_module_eeprom);
+/**
+ * sfp_upstream_start() - Inform the SFP that the network device is up
+ * @bus: a pointer to the &struct sfp_bus structure for the sfp module
+ *
+ * Inform the SFP socket that the network device is now up, so that the
+ * module can be enabled by allowing TX_DISABLE to be deasserted. This
+ * should be called from the network device driver's &struct net_device_ops
+ * ndo_open() method.
+ */
void sfp_upstream_start(struct sfp_bus *bus)
{
if (bus->registered)
@@ -318,6 +393,15 @@ void sfp_upstream_start(struct sfp_bus *bus)
}
EXPORT_SYMBOL_GPL(sfp_upstream_start);
+/**
+ * sfp_upstream_stop() - Inform the SFP that the network device is down
+ * @bus: a pointer to the &struct sfp_bus structure for the sfp module
+ *
+ * Inform the SFP socket that the network device is now up, so that the
+ * module can be disabled by asserting TX_DISABLE, disabling the laser
+ * in optical modules. This should be called from the network device
+ * driver's &struct net_device_ops ndo_stop() method.
+ */
void sfp_upstream_stop(struct sfp_bus *bus)
{
if (bus->registered)
@@ -326,6 +410,19 @@ void sfp_upstream_stop(struct sfp_bus *bus)
}
EXPORT_SYMBOL_GPL(sfp_upstream_stop);
+/**
+ * sfp_register_upstream() - Register the neighbouring device
+ * @np: device node for the SFP bus
+ * @ndev: network device associated with the interface
+ * @upstream: the upstream private data
+ * @ops: the upstream's &struct sfp_upstream_ops
+ *
+ * Register the upstream device (eg, PHY) with the SFP bus. MAC drivers
+ * should use phylink, which will call this function for them. Returns
+ * a pointer to the allocated &struct sfp_bus.
+ *
+ * On error, returns %NULL.
+ */
struct sfp_bus *sfp_register_upstream(struct device_node *np,
struct net_device *ndev, void *upstream,
const struct sfp_upstream_ops *ops)
@@ -353,6 +450,13 @@ struct sfp_bus *sfp_register_upstream(struct device_node *np,
}
EXPORT_SYMBOL_GPL(sfp_register_upstream);
+/**
+ * sfp_unregister_upstream() - Unregister sfp bus
+ * @bus: a pointer to the &struct sfp_bus structure for the sfp module
+ *
+ * Unregister a previously registered upstream connection for the SFP
+ * module. @bus is returned from sfp_register_upstream().
+ */
void sfp_unregister_upstream(struct sfp_bus *bus)
{
rtnl_lock();
diff --git a/include/linux/sfp.h b/include/linux/sfp.h
index 4a906f560817..b6089fe72378 100644
--- a/include/linux/sfp.h
+++ b/include/linux/sfp.h
@@ -3,7 +3,7 @@
#include <linux/phy.h>
-struct __packed sfp_eeprom_base {
+struct sfp_eeprom_base {
u8 phys_id;
u8 phys_ext_id;
u8 connector;
@@ -166,12 +166,12 @@ struct __packed sfp_eeprom_base {
union {
__be16 optical_wavelength;
u8 cable_spec;
- };
+ } __packed;
u8 reserved62;
u8 cc_base;
-};
+} __packed;
-struct __packed sfp_eeprom_ext {
+struct sfp_eeprom_ext {
__be16 options;
u8 br_max;
u8 br_min;
@@ -181,12 +181,21 @@ struct __packed sfp_eeprom_ext {
u8 enhopts;
u8 sff8472_compliance;
u8 cc_ext;
-};
-
-struct __packed sfp_eeprom_id {
+} __packed;
+
+/**
+ * struct sfp_eeprom_id - raw SFP module identification information
+ * @base: base SFP module identification structure
+ * @ext: extended SFP module identification structure
+ *
+ * See the SFF-8472 specification and related documents for the definition
+ * of these structure members. This can be obtained from
+ * ftp://ftp.seagate.com/sff
+ */
+struct sfp_eeprom_id {
struct sfp_eeprom_base base;
struct sfp_eeprom_ext ext;
-};
+} __packed;
/* SFP EEPROM registers */
enum {
@@ -353,13 +362,26 @@ struct ethtool_modinfo;
struct net_device;
struct sfp_bus;
+/**
+ * struct sfp_upstream_ops - upstream operations structure
+ * @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.
+ * @link_down: called when the link is non-operational for whatever
+ * reason.
+ * @link_up: called when the link is operational.
+ * @connect_phy: called when an I2C accessible PHY has been detected
+ * on the module.
+ * @disconnect_phy: called when a module with an I2C accessible PHY has
+ * been removed.
+ */
struct sfp_upstream_ops {
- int (*module_insert)(void *, const struct sfp_eeprom_id *id);
- void (*module_remove)(void *);
- void (*link_down)(void *);
- void (*link_up)(void *);
- int (*connect_phy)(void *, struct phy_device *);
- void (*disconnect_phy)(void *);
+ int (*module_insert)(void *priv, const struct sfp_eeprom_id *id);
+ void (*module_remove)(void *priv);
+ void (*link_down)(void *priv);
+ void (*link_up)(void *priv);
+ int (*connect_phy)(void *priv, struct phy_device *);
+ void (*disconnect_phy)(void *priv);
};
#if IS_ENABLED(CONFIG_SFP)
--
2.7.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: [PATCH 08/11] sfp: add documentation for kernel APIs
2017-12-01 10:24 ` [PATCH 08/11] sfp: " Russell King
@ 2017-12-01 17:28 ` Florian Fainelli
0 siblings, 0 replies; 28+ messages in thread
From: Florian Fainelli @ 2017-12-01 17:28 UTC (permalink / raw)
To: Russell King, Andrew Lunn, Jonathan Corbet; +Cc: linux-doc, netdev
On 12/01/2017 02:24 AM, Russell King wrote:
> Add kernel-doc documentation for sfp kernel APIs, and link it into the
> networking kapi documentation under "Network device support".
>
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
--
Florian
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH 09/11] sfp: fix sparse warning
2017-12-01 10:23 ` [PATCH net-next 00/11] SFP/phylink updates Russell King - ARM Linux
` (7 preceding siblings ...)
2017-12-01 10:24 ` [PATCH 08/11] sfp: " Russell King
@ 2017-12-01 10:24 ` Russell King
2017-12-01 18:17 ` Florian Fainelli
2017-12-01 10:25 ` [PATCH 10/11] sfp: convert to fwnode Russell King
` (4 subsequent siblings)
13 siblings, 1 reply; 28+ messages in thread
From: Russell King @ 2017-12-01 10:24 UTC (permalink / raw)
To: Andrew Lunn, Florian Fainelli, Jonathan Corbet; +Cc: linux-doc, netdev
drivers/net/phy/sfp-bus.c:298:13: warning: context imbalance in 'sfp_bus_release' - wrong count at exit
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
drivers/net/phy/sfp-bus.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/phy/sfp-bus.c b/drivers/net/phy/sfp-bus.c
index 2b8c256156a2..a28859022ddb 100644
--- a/drivers/net/phy/sfp-bus.c
+++ b/drivers/net/phy/sfp-bus.c
@@ -291,7 +291,7 @@ static struct sfp_bus *sfp_bus_get(struct device_node *np)
return found;
}
-static void sfp_bus_release(struct kref *kref) __releases(sfp_mutex)
+static void sfp_bus_release(struct kref *kref)
{
struct sfp_bus *bus = container_of(kref, struct sfp_bus, kref);
--
2.7.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 10/11] sfp: convert to fwnode
2017-12-01 10:23 ` [PATCH net-next 00/11] SFP/phylink updates Russell King - ARM Linux
` (8 preceding siblings ...)
2017-12-01 10:24 ` [PATCH 09/11] sfp: fix sparse warning Russell King
@ 2017-12-01 10:25 ` Russell King
2017-12-01 18:18 ` Florian Fainelli
2017-12-01 10:25 ` [PATCH 11/11] phylink: " Russell King
` (3 subsequent siblings)
13 siblings, 1 reply; 28+ messages in thread
From: Russell King @ 2017-12-01 10:25 UTC (permalink / raw)
To: Andrew Lunn, Florian Fainelli, Jonathan Corbet; +Cc: linux-doc, netdev
Convert sfp-bus to use fwnode rather than device_node internally, so
we can support more than just device tree firmware.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
drivers/net/phy/phylink.c | 3 ++-
drivers/net/phy/sfp-bus.c | 14 +++++++-------
include/linux/sfp.h | 7 ++++---
3 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 5a1bd48eb6d7..bca142a4863c 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -499,7 +499,8 @@ static int phylink_register_sfp(struct phylink *pl, struct device_node *np)
if (!sfp_np)
return 0;
- pl->sfp_bus = sfp_register_upstream(sfp_np, pl->netdev, pl,
+ pl->sfp_bus = sfp_register_upstream(of_fwnode_handle(sfp_np),
+ pl->netdev, pl,
&sfp_phylink_ops);
if (!pl->sfp_bus)
return -ENOMEM;
diff --git a/drivers/net/phy/sfp-bus.c b/drivers/net/phy/sfp-bus.c
index a28859022ddb..1356dba0d9d3 100644
--- a/drivers/net/phy/sfp-bus.c
+++ b/drivers/net/phy/sfp-bus.c
@@ -15,7 +15,7 @@ struct sfp_bus {
/* private: */
struct kref kref;
struct list_head node;
- struct device_node *device_node;
+ struct fwnode_handle *fwnode;
const struct sfp_socket_ops *socket_ops;
struct device *sfp_dev;
@@ -260,7 +260,7 @@ static const struct sfp_upstream_ops *sfp_get_upstream_ops(struct sfp_bus *bus)
return bus->registered ? bus->upstream_ops : NULL;
}
-static struct sfp_bus *sfp_bus_get(struct device_node *np)
+static struct sfp_bus *sfp_bus_get(struct fwnode_handle *fwnode)
{
struct sfp_bus *sfp, *new, *found = NULL;
@@ -269,7 +269,7 @@ static struct sfp_bus *sfp_bus_get(struct device_node *np)
mutex_lock(&sfp_mutex);
list_for_each_entry(sfp, &sfp_buses, node) {
- if (sfp->device_node == np) {
+ if (sfp->fwnode == fwnode) {
kref_get(&sfp->kref);
found = sfp;
break;
@@ -278,7 +278,7 @@ static struct sfp_bus *sfp_bus_get(struct device_node *np)
if (!found && new) {
kref_init(&new->kref);
- new->device_node = np;
+ new->fwnode = fwnode;
list_add(&new->node, &sfp_buses);
found = new;
new = NULL;
@@ -423,11 +423,11 @@ EXPORT_SYMBOL_GPL(sfp_upstream_stop);
*
* On error, returns %NULL.
*/
-struct sfp_bus *sfp_register_upstream(struct device_node *np,
+struct sfp_bus *sfp_register_upstream(struct fwnode_handle *fwnode,
struct net_device *ndev, void *upstream,
const struct sfp_upstream_ops *ops)
{
- struct sfp_bus *bus = sfp_bus_get(np);
+ struct sfp_bus *bus = sfp_bus_get(fwnode);
int ret = 0;
if (bus) {
@@ -537,7 +537,7 @@ EXPORT_SYMBOL_GPL(sfp_module_remove);
struct sfp_bus *sfp_register_socket(struct device *dev, struct sfp *sfp,
const struct sfp_socket_ops *ops)
{
- struct sfp_bus *bus = sfp_bus_get(dev->of_node);
+ struct sfp_bus *bus = sfp_bus_get(dev->fwnode);
int ret = 0;
if (bus) {
diff --git a/include/linux/sfp.h b/include/linux/sfp.h
index b6089fe72378..47ea32d3e816 100644
--- a/include/linux/sfp.h
+++ b/include/linux/sfp.h
@@ -356,7 +356,7 @@ enum {
SFP_PAGE = 0x7f,
};
-struct device_node;
+struct fwnode_handle;
struct ethtool_eeprom;
struct ethtool_modinfo;
struct net_device;
@@ -397,7 +397,7 @@ int sfp_get_module_eeprom(struct sfp_bus *bus, struct ethtool_eeprom *ee,
u8 *data);
void sfp_upstream_start(struct sfp_bus *bus);
void sfp_upstream_stop(struct sfp_bus *bus);
-struct sfp_bus *sfp_register_upstream(struct device_node *np,
+struct sfp_bus *sfp_register_upstream(struct fwnode_handle *fwnode,
struct net_device *ndev, void *upstream,
const struct sfp_upstream_ops *ops);
void sfp_unregister_upstream(struct sfp_bus *bus);
@@ -441,7 +441,8 @@ static inline void sfp_upstream_stop(struct sfp_bus *bus)
{
}
-static inline struct sfp_bus *sfp_register_upstream(struct device_node *np,
+static inline struct sfp_bus *sfp_register_upstream(
+ struct fwnode_handle *fwnode,
struct net_device *ndev, void *upstream,
const struct sfp_upstream_ops *ops)
{
--
2.7.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 11/11] phylink: convert to fwnode
2017-12-01 10:23 ` [PATCH net-next 00/11] SFP/phylink updates Russell King - ARM Linux
` (9 preceding siblings ...)
2017-12-01 10:25 ` [PATCH 10/11] sfp: convert to fwnode Russell King
@ 2017-12-01 10:25 ` Russell King
2017-12-01 18:19 ` Florian Fainelli
2017-12-01 10:29 ` [PATCH net-next 00/11] SFP/phylink updates Russell King - ARM Linux
` (2 subsequent siblings)
13 siblings, 1 reply; 28+ messages in thread
From: Russell King @ 2017-12-01 10:25 UTC (permalink / raw)
To: Andrew Lunn, Florian Fainelli, Jonathan Corbet; +Cc: linux-doc, netdev
Convert phylink to fwnode, switching phylink_create() from taking a
device_node to taking a fwnode_handle. This will allow other firmware
systems to take advantage of sfp/phylink support.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
drivers/net/phy/phylink.c | 91 +++++++++++++++++++++++++++--------------------
include/linux/phylink.h | 3 +-
2 files changed, 55 insertions(+), 39 deletions(-)
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index bca142a4863c..2bfb548d3dff 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -142,59 +142,64 @@ static int phylink_validate(struct phylink *pl, unsigned long *supported,
return phylink_is_empty_linkmode(supported) ? -EINVAL : 0;
}
-static int phylink_parse_fixedlink(struct phylink *pl, struct device_node *np)
+static int phylink_parse_fixedlink(struct phylink *pl,
+ struct fwnode_handle *fwnode)
{
- struct device_node *fixed_node;
+ struct fwnode_handle *fixed_node;
const struct phy_setting *s;
struct gpio_desc *desc;
- const __be32 *fixed_prop;
u32 speed;
- int ret, len;
+ int ret;
- fixed_node = of_get_child_by_name(np, "fixed-link");
+ fixed_node = fwnode_get_named_child_node(fwnode, "fixed-link");
if (fixed_node) {
- ret = of_property_read_u32(fixed_node, "speed", &speed);
+ ret = fwnode_property_read_u32(fixed_node, "speed", &speed);
pl->link_config.speed = speed;
pl->link_config.duplex = DUPLEX_HALF;
- if (of_property_read_bool(fixed_node, "full-duplex"))
+ if (fwnode_property_read_bool(fixed_node, "full-duplex"))
pl->link_config.duplex = DUPLEX_FULL;
/* We treat the "pause" and "asym-pause" terminology as
* defining the link partner's ability. */
- if (of_property_read_bool(fixed_node, "pause"))
+ if (fwnode_property_read_bool(fixed_node, "pause"))
pl->link_config.pause |= MLO_PAUSE_SYM;
- if (of_property_read_bool(fixed_node, "asym-pause"))
+ if (fwnode_property_read_bool(fixed_node, "asym-pause"))
pl->link_config.pause |= MLO_PAUSE_ASYM;
if (ret == 0) {
- desc = fwnode_get_named_gpiod(&fixed_node->fwnode,
- "link-gpios", 0,
- GPIOD_IN, "?");
+ desc = fwnode_get_named_gpiod(fixed_node, "link-gpios",
+ 0, GPIOD_IN, "?");
if (!IS_ERR(desc))
pl->link_gpio = desc;
else if (desc == ERR_PTR(-EPROBE_DEFER))
ret = -EPROBE_DEFER;
}
- of_node_put(fixed_node);
+ fwnode_handle_put(fixed_node);
if (ret)
return ret;
} else {
- fixed_prop = of_get_property(np, "fixed-link", &len);
- if (!fixed_prop) {
+ u32 prop[5];
+
+ ret = fwnode_property_read_u32_array(fwnode, "fixed-link",
+ NULL, 0);
+ if (ret != ARRAY_SIZE(prop)) {
netdev_err(pl->netdev, "broken fixed-link?\n");
return -EINVAL;
}
- if (len == 5 * sizeof(*fixed_prop)) {
- pl->link_config.duplex = be32_to_cpu(fixed_prop[1]) ?
+
+ ret = fwnode_property_read_u32_array(fwnode, "fixed-link",
+ prop, ARRAY_SIZE(prop));
+ if (!ret) {
+ pl->link_config.duplex = prop[1] ?
DUPLEX_FULL : DUPLEX_HALF;
- pl->link_config.speed = be32_to_cpu(fixed_prop[2]);
- if (be32_to_cpu(fixed_prop[3]))
+ pl->link_config.speed = prop[2];
+ if (prop[3])
pl->link_config.pause |= MLO_PAUSE_SYM;
- if (be32_to_cpu(fixed_prop[4]))
+ if (prop[4])
pl->link_config.pause |= MLO_PAUSE_ASYM;
}
}
@@ -230,17 +235,17 @@ static int phylink_parse_fixedlink(struct phylink *pl, struct device_node *np)
return 0;
}
-static int phylink_parse_mode(struct phylink *pl, struct device_node *np)
+static int phylink_parse_mode(struct phylink *pl, struct fwnode_handle *fwnode)
{
- struct device_node *dn;
+ struct fwnode_handle *dn;
const char *managed;
- dn = of_get_child_by_name(np, "fixed-link");
- if (dn || of_find_property(np, "fixed-link", NULL))
+ dn = fwnode_get_named_child_node(fwnode, "fixed-link");
+ if (dn || fwnode_property_present(fwnode, "fixed-link"))
pl->link_an_mode = MLO_AN_FIXED;
- of_node_put(dn);
+ fwnode_handle_put(dn);
- if (of_property_read_string(np, "managed", &managed) == 0 &&
+ if (fwnode_property_read_string(fwnode, "managed", &managed) == 0 &&
strcmp(managed, "in-band-status") == 0) {
if (pl->link_an_mode == MLO_AN_FIXED) {
netdev_err(pl->netdev,
@@ -491,16 +496,24 @@ static void phylink_run_resolve(struct phylink *pl)
static const struct sfp_upstream_ops sfp_phylink_ops;
-static int phylink_register_sfp(struct phylink *pl, struct device_node *np)
+static int phylink_register_sfp(struct phylink *pl,
+ struct fwnode_handle *fwnode)
{
- struct device_node *sfp_np;
+ struct fwnode_reference_args ref;
+ int ret;
- sfp_np = of_parse_phandle(np, "sfp", 0);
- if (!sfp_np)
- return 0;
+ ret = fwnode_property_get_reference_args(fwnode, "sfp", NULL,
+ 0, 0, &ref);
+ if (ret < 0) {
+ if (ret == -ENOENT)
+ return 0;
+
+ netdev_err(pl->netdev, "unable to parse \"sfp\" node: %d\n",
+ ret);
+ return ret;
+ }
- pl->sfp_bus = sfp_register_upstream(of_fwnode_handle(sfp_np),
- pl->netdev, pl,
+ pl->sfp_bus = sfp_register_upstream(ref.fwnode, pl->netdev, pl,
&sfp_phylink_ops);
if (!pl->sfp_bus)
return -ENOMEM;
@@ -511,7 +524,8 @@ static int phylink_register_sfp(struct phylink *pl, struct device_node *np)
/**
* phylink_create() - create a phylink instance
* @ndev: a pointer to the &struct net_device
- * @np: a pointer to a &struct device_node describing the network interface
+ * @fwnode: a pointer to a &struct fwnode_handle describing the network
+ * interface
* @iface: the desired link mode defined by &typedef phy_interface_t
* @ops: a pointer to a &struct phylink_mac_ops for the MAC.
*
@@ -521,7 +535,8 @@ static int phylink_register_sfp(struct phylink *pl, struct device_node *np)
* Returns a pointer to a &struct phylink, or an error-pointer value. Users
* must use IS_ERR() to check for errors from this function.
*/
-struct phylink *phylink_create(struct net_device *ndev, struct device_node *np,
+struct phylink *phylink_create(struct net_device *ndev,
+ struct fwnode_handle *fwnode,
phy_interface_t iface,
const struct phylink_mac_ops *ops)
{
@@ -549,21 +564,21 @@ struct phylink *phylink_create(struct net_device *ndev, struct device_node *np,
linkmode_copy(pl->link_config.advertising, pl->supported);
phylink_validate(pl, pl->supported, &pl->link_config);
- ret = phylink_parse_mode(pl, np);
+ ret = phylink_parse_mode(pl, fwnode);
if (ret < 0) {
kfree(pl);
return ERR_PTR(ret);
}
if (pl->link_an_mode == MLO_AN_FIXED) {
- ret = phylink_parse_fixedlink(pl, np);
+ ret = phylink_parse_fixedlink(pl, fwnode);
if (ret < 0) {
kfree(pl);
return ERR_PTR(ret);
}
}
- ret = phylink_register_sfp(pl, np);
+ ret = phylink_register_sfp(pl, fwnode);
if (ret < 0) {
kfree(pl);
return ERR_PTR(ret);
diff --git a/include/linux/phylink.h b/include/linux/phylink.h
index 30e9d0070377..4f0f452ff38d 100644
--- a/include/linux/phylink.h
+++ b/include/linux/phylink.h
@@ -7,6 +7,7 @@
struct device_node;
struct ethtool_cmd;
+struct fwnode_handle;
struct net_device;
enum {
@@ -182,7 +183,7 @@ void mac_link_up(struct net_device *ndev, unsigned int mode,
struct phy_device *phy);
#endif
-struct phylink *phylink_create(struct net_device *, struct device_node *,
+struct phylink *phylink_create(struct net_device *, struct fwnode_handle *,
phy_interface_t iface, const struct phylink_mac_ops *ops);
void phylink_destroy(struct phylink *);
--
2.7.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: [PATCH 11/11] phylink: convert to fwnode
2017-12-01 10:25 ` [PATCH 11/11] phylink: " Russell King
@ 2017-12-01 18:19 ` Florian Fainelli
0 siblings, 0 replies; 28+ messages in thread
From: Florian Fainelli @ 2017-12-01 18:19 UTC (permalink / raw)
To: Russell King, Andrew Lunn, Jonathan Corbet; +Cc: linux-doc, netdev
On 12/01/2017 02:25 AM, Russell King wrote:
> Convert phylink to fwnode, switching phylink_create() from taking a
> device_node to taking a fwnode_handle. This will allow other firmware
> systems to take advantage of sfp/phylink support.
>
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
--
Florian
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH net-next 00/11] SFP/phylink updates
2017-12-01 10:23 ` [PATCH net-next 00/11] SFP/phylink updates Russell King - ARM Linux
` (10 preceding siblings ...)
2017-12-01 10:25 ` [PATCH 11/11] phylink: " Russell King
@ 2017-12-01 10:29 ` Russell King - ARM Linux
2017-12-03 14:55 ` David Miller
2017-12-05 16:16 ` David Miller
13 siblings, 0 replies; 28+ messages in thread
From: Russell King - ARM Linux @ 2017-12-01 10:29 UTC (permalink / raw)
To: Andrew Lunn, Florian Fainelli; +Cc: netdev
On Fri, Dec 01, 2017 at 10:23:07AM +0000, Russell King - ARM Linux wrote:
> Hi,
>
> This series, which follows on from the fixes posted earlier, improves
> the phylink/sfp support. Changes included here are:
Sorry, just realised I sent the patches without the net-next annotation
after the [PATCH in their subject line.
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 8.8Mbps down 630kbps up
According to speedtest.net: 8.21Mbps down 510kbps up
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH net-next 00/11] SFP/phylink updates
2017-12-01 10:23 ` [PATCH net-next 00/11] SFP/phylink updates Russell King - ARM Linux
` (11 preceding siblings ...)
2017-12-01 10:29 ` [PATCH net-next 00/11] SFP/phylink updates Russell King - ARM Linux
@ 2017-12-03 14:55 ` David Miller
2017-12-05 16:16 ` David Miller
13 siblings, 0 replies; 28+ messages in thread
From: David Miller @ 2017-12-03 14:55 UTC (permalink / raw)
To: linux; +Cc: andrew, f.fainelli, netdev
From: Russell King - ARM Linux <linux@armlinux.org.uk>
Date: Fri, 1 Dec 2017 10:23:07 +0000
> This series, which follows on from the fixes posted earlier, improves
> the phylink/sfp support. Changes included here are:
Ok, I'll merge this in the next time I get 'net' into 'net-next'.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH net-next 00/11] SFP/phylink updates
2017-12-01 10:23 ` [PATCH net-next 00/11] SFP/phylink updates Russell King - ARM Linux
` (12 preceding siblings ...)
2017-12-03 14:55 ` David Miller
@ 2017-12-05 16:16 ` David Miller
13 siblings, 0 replies; 28+ messages in thread
From: David Miller @ 2017-12-05 16:16 UTC (permalink / raw)
To: linux; +Cc: andrew, f.fainelli, netdev
From: Russell King - ARM Linux <linux@armlinux.org.uk>
Date: Fri, 1 Dec 2017 10:23:07 +0000
> This series, which follows on from the fixes posted earlier, improves
> the phylink/sfp support. Changes included here are:
...
Series applied, thanks!
^ permalink raw reply [flat|nested] 28+ messages in thread