tools: mkimage: provide dtc path during build
[openwrt/staging/dedeckeh.git] / target / linux / mvebu / patches-4.9 / 416-phylink-add-hooks-for-SFP-support.patch
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
4
5 Add support to phylink for SFP, which needs to control and configure
6 the ethernet MAC link state. Specifically, SFP needs to:
7
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
11
12 In the absence of a PHY, we also need to set the ethtool port type
13 according to the module plugged in.
14
15 Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
16 Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
17
18 - rework phylink_set_link_*(), combining into a single function.
19 ---
20
21 --- a/drivers/net/phy/phylink.c
22 +++ b/drivers/net/phy/phylink.c
23 @@ -11,6 +11,7 @@
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>
29 #include <linux/of.h>
30 #include <linux/of_mdio.h>
31 @@ -29,11 +30,16 @@
32 (ADVERTISED_TP | ADVERTISED_MII | ADVERTISED_FIBRE | \
33 ADVERTISED_BNC | ADVERTISED_AUI | ADVERTISED_Backplane)
34
35 +static LIST_HEAD(phylinks);
36 +static DEFINE_MUTEX(phylink_mutex);
37 +
38 enum {
39 PHYLINK_DISABLE_STOPPED,
40 + PHYLINK_DISABLE_LINK,
41 };
42
43 struct phylink {
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);
51
52 + mutex_lock(&phylink_mutex);
53 + list_add_tail(&pl->node, &phylinks);
54 + mutex_unlock(&phylink_mutex);
55 +
56 return pl;
57 }
58 EXPORT_SYMBOL_GPL(phylink_create);
59
60 void phylink_destroy(struct phylink *pl)
61 {
62 + mutex_lock(&phylink_mutex);
63 + list_del(&pl->node);
64 + mutex_unlock(&phylink_mutex);
65 +
66 cancel_work_sync(&pl->resolve);
67 kfree(pl);
68 }
69 @@ -900,4 +914,93 @@ int phylink_mii_ioctl(struct phylink *pl
70 }
71 EXPORT_SYMBOL_GPL(phylink_mii_ioctl);
72
73 +
74 +
75 +void phylink_disable(struct phylink *pl)
76 +{
77 + set_bit(PHYLINK_DISABLE_LINK, &pl->phylink_disable_state);
78 + flush_work(&pl->resolve);
79 +
80 + netif_carrier_off(pl->netdev);
81 +}
82 +EXPORT_SYMBOL_GPL(phylink_disable);
83 +
84 +void phylink_enable(struct phylink *pl)
85 +{
86 + clear_bit(PHYLINK_DISABLE_LINK, &pl->phylink_disable_state);
87 + phylink_run_resolve(pl);
88 +}
89 +EXPORT_SYMBOL_GPL(phylink_enable);
90 +
91 +int phylink_set_link(struct phylink *pl, unsigned int mode, u8 port,
92 + const unsigned long *support)
93 +{
94 + __ETHTOOL_DECLARE_LINK_MODE_MASK(mask);
95 + int ret = 0;
96 +
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);
100 +
101 + if (mode == MLO_AN_FIXED)
102 + return -EINVAL;
103 +
104 + linkmode_copy(mask, support);
105 +
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)
109 + return ret;
110 +
111 + mutex_lock(&pl->config_mutex);
112 + if (mode == MLO_AN_8023Z && pl->phydev) {
113 + ret = -EINVAL;
114 + } else {
115 + bool changed = !bitmap_equal(pl->supported, mask,
116 + __ETHTOOL_LINK_MODE_MASK_NBITS);
117 + if (changed) {
118 + linkmode_copy(pl->supported, mask);
119 +
120 + phylink_init_advert(pl, mode, mask,
121 + pl->link_config.advertising);
122 + }
123 +
124 + if (pl->link_an_mode != mode) {
125 + pl->link_an_mode = mode;
126 +
127 + changed = true;
128 +
129 + netdev_info(pl->netdev, "switched to %s link mode\n",
130 + phylink_an_mode_str(mode));
131 + }
132 +
133 + pl->link_port = port;
134 +
135 + if (changed && !test_bit(PHYLINK_DISABLE_STOPPED,
136 + &pl->phylink_disable_state))
137 + phylink_mac_config(pl, &pl->link_config);
138 + }
139 + mutex_unlock(&pl->config_mutex);
140 +
141 + return ret;
142 +}
143 +EXPORT_SYMBOL_GPL(phylink_set_link);
144 +
145 +struct phylink *phylink_lookup_by_netdev(struct net_device *ndev)
146 +{
147 + struct phylink *pl, *found = NULL;
148 +
149 + mutex_lock(&phylink_mutex);
150 + list_for_each_entry(pl, &phylinks, node)
151 + if (pl->netdev == ndev) {
152 + found = pl;
153 + break;
154 + }
155 +
156 + mutex_unlock(&phylink_mutex);
157 +
158 + return found;
159 +}
160 +EXPORT_SYMBOL_GPL(phylink_lookup_by_netdev);
161 +
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);
168
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);
174 +
175 #define phylink_zero(bm) \
176 bitmap_zero(bm, __ETHTOOL_LINK_MODE_MASK_NBITS)
177 #define __phylink_do_bit(op, bm, mode) \