1 From: Russell King <rmk+kernel@arm.linux.org.uk>
2 Date: Thu, 24 Sep 2015 11:01:13 +0100
3 Subject: [PATCH] phylink: add hooks for SFP support
5 Add support to phylink for SFP, which needs to control and configure
6 the ethernet MAC link state. Specifically, SFP needs to:
8 1. set the negotiation mode between SGMII and 1000base-X
9 2. attach and detach the module PHY
10 3. prevent the link coming up when errors are reported
12 In the absence of a PHY, we also need to set the ethtool port type
13 according to the module plugged in.
15 Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
16 Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
18 - rework phylink_set_link_*(), combining into a single function.
21 --- a/drivers/net/phy/phylink.c
22 +++ b/drivers/net/phy/phylink.c
24 #include <linux/ethtool.h>
25 #include <linux/export.h>
26 #include <linux/gpio/consumer.h>
27 +#include <linux/list.h>
28 #include <linux/netdevice.h>
30 #include <linux/of_mdio.h>
32 (ADVERTISED_TP | ADVERTISED_MII | ADVERTISED_FIBRE | \
33 ADVERTISED_BNC | ADVERTISED_AUI | ADVERTISED_Backplane)
35 +static LIST_HEAD(phylinks);
36 +static DEFINE_MUTEX(phylink_mutex);
39 PHYLINK_DISABLE_STOPPED,
40 + PHYLINK_DISABLE_LINK,
44 + struct list_head node;
45 struct net_device *netdev;
46 const struct phylink_mac_ops *ops;
47 struct mutex config_mutex;
48 @@ -375,12 +381,20 @@ struct phylink *phylink_create(struct ne
49 phylink_init_advert(pl, pl->link_an_mode, pl->supported,
50 pl->link_config.advertising);
52 + mutex_lock(&phylink_mutex);
53 + list_add_tail(&pl->node, &phylinks);
54 + mutex_unlock(&phylink_mutex);
58 EXPORT_SYMBOL_GPL(phylink_create);
60 void phylink_destroy(struct phylink *pl)
62 + mutex_lock(&phylink_mutex);
63 + list_del(&pl->node);
64 + mutex_unlock(&phylink_mutex);
66 cancel_work_sync(&pl->resolve);
69 @@ -900,4 +914,93 @@ int phylink_mii_ioctl(struct phylink *pl
71 EXPORT_SYMBOL_GPL(phylink_mii_ioctl);
75 +void phylink_disable(struct phylink *pl)
77 + set_bit(PHYLINK_DISABLE_LINK, &pl->phylink_disable_state);
78 + flush_work(&pl->resolve);
80 + netif_carrier_off(pl->netdev);
82 +EXPORT_SYMBOL_GPL(phylink_disable);
84 +void phylink_enable(struct phylink *pl)
86 + clear_bit(PHYLINK_DISABLE_LINK, &pl->phylink_disable_state);
87 + phylink_run_resolve(pl);
89 +EXPORT_SYMBOL_GPL(phylink_enable);
91 +int phylink_set_link(struct phylink *pl, unsigned int mode, u8 port,
92 + const unsigned long *support)
94 + __ETHTOOL_DECLARE_LINK_MODE_MASK(mask);
97 + netdev_dbg(pl->netdev, "requesting link mode %s with support %*pb\n",
98 + phylink_an_mode_str(mode),
99 + __ETHTOOL_LINK_MODE_MASK_NBITS, support);
101 + if (mode == MLO_AN_FIXED)
104 + linkmode_copy(mask, support);
106 + /* Ignore errors if we're expecting a PHY to attach later */
107 + ret = phylink_validate_support(pl, mode, mask);
108 + if (ret && mode != MLO_AN_PHY)
111 + mutex_lock(&pl->config_mutex);
112 + if (mode == MLO_AN_8023Z && pl->phydev) {
115 + bool changed = !bitmap_equal(pl->supported, mask,
116 + __ETHTOOL_LINK_MODE_MASK_NBITS);
118 + linkmode_copy(pl->supported, mask);
120 + phylink_init_advert(pl, mode, mask,
121 + pl->link_config.advertising);
124 + if (pl->link_an_mode != mode) {
125 + pl->link_an_mode = mode;
129 + netdev_info(pl->netdev, "switched to %s link mode\n",
130 + phylink_an_mode_str(mode));
133 + pl->link_port = port;
135 + if (changed && !test_bit(PHYLINK_DISABLE_STOPPED,
136 + &pl->phylink_disable_state))
137 + phylink_mac_config(pl, &pl->link_config);
139 + mutex_unlock(&pl->config_mutex);
143 +EXPORT_SYMBOL_GPL(phylink_set_link);
145 +struct phylink *phylink_lookup_by_netdev(struct net_device *ndev)
147 + struct phylink *pl, *found = NULL;
149 + mutex_lock(&phylink_mutex);
150 + list_for_each_entry(pl, &phylinks, node)
151 + if (pl->netdev == ndev) {
156 + mutex_unlock(&phylink_mutex);
160 +EXPORT_SYMBOL_GPL(phylink_lookup_by_netdev);
162 MODULE_LICENSE("GPL");
163 --- a/include/linux/phylink.h
164 +++ b/include/linux/phylink.h
165 @@ -88,6 +88,12 @@ int phylink_ethtool_ksettings_set(struct
166 const struct ethtool_link_ksettings *);
167 int phylink_mii_ioctl(struct phylink *, struct ifreq *, int);
169 +int phylink_set_link(struct phylink *pl, unsigned int mode, u8 port,
170 + const unsigned long *support);
171 +void phylink_disable(struct phylink *pl);
172 +void phylink_enable(struct phylink *pl);
173 +struct phylink *phylink_lookup_by_netdev(struct net_device *ndev);
175 #define phylink_zero(bm) \
176 bitmap_zero(bm, __ETHTOOL_LINK_MODE_MASK_NBITS)
177 #define __phylink_do_bit(op, bm, mode) \