1 From: Russell King <rmk+kernel@armlinux.org.uk>
2 Date: Thu, 5 Jan 2017 16:47:39 +0000
3 Subject: [PATCH] net: phy: move phy_lookup_setting() and guts of
4 phy_supported_speeds() to phy-core
6 phy_lookup_setting() provides useful functionality in ethtool code
7 outside phylib. Move it to phy-core and allow it to be re-used (eg,
8 in phylink) rather than duplicated elsewhere. Note that this supports
9 the larger linkmode space.
11 As we move the phy settings table, we also need to move the guts of
12 phy_supported_speeds() as well.
14 Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
17 --- a/drivers/net/phy/phy.c
18 +++ b/drivers/net/phy/phy.c
19 @@ -149,125 +149,6 @@ static inline int phy_aneg_done(struct p
20 return genphy_aneg_done(phydev);
23 -/* A structure for mapping a particular speed and duplex
24 - * combination to a particular SUPPORTED and ADVERTISED value
32 -/* A mapping of all SUPPORTED settings to speed/duplex. This table
33 - * must be grouped by speed and sorted in descending match priority
34 - * - iow, descending speed. */
35 -static const struct phy_setting settings[] = {
37 - .speed = SPEED_10000,
38 - .duplex = DUPLEX_FULL,
39 - .bit = ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
42 - .speed = SPEED_10000,
43 - .duplex = DUPLEX_FULL,
44 - .bit = ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
47 - .speed = SPEED_10000,
48 - .duplex = DUPLEX_FULL,
49 - .bit = ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
52 - .speed = SPEED_2500,
53 - .duplex = DUPLEX_FULL,
54 - .bit = ETHTOOL_LINK_MODE_2500baseX_Full_BIT,
57 - .speed = SPEED_1000,
58 - .duplex = DUPLEX_FULL,
59 - .bit = ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
62 - .speed = SPEED_1000,
63 - .duplex = DUPLEX_FULL,
64 - .bit = ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
67 - .speed = SPEED_1000,
68 - .duplex = DUPLEX_HALF,
69 - .bit = ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
73 - .duplex = DUPLEX_FULL,
74 - .bit = ETHTOOL_LINK_MODE_100baseT_Full_BIT,
78 - .duplex = DUPLEX_HALF,
79 - .bit = ETHTOOL_LINK_MODE_100baseT_Half_BIT,
83 - .duplex = DUPLEX_FULL,
84 - .bit = ETHTOOL_LINK_MODE_10baseT_Full_BIT,
88 - .duplex = DUPLEX_HALF,
89 - .bit = ETHTOOL_LINK_MODE_10baseT_Half_BIT,
94 - * phy_lookup_setting - lookup a PHY setting
95 - * @speed: speed to match
96 - * @duplex: duplex to match
97 - * @mask: allowed link modes
98 - * @maxbit: bit size of link modes
99 - * @exact: an exact match is required
101 - * Search the settings array for a setting that matches the speed and
102 - * duplex, and which is supported.
104 - * If @exact is unset, either an exact match or %NULL for no match will
107 - * If @exact is set, an exact match, the fastest supported setting at
108 - * or below the specified speed, the slowest supported setting, or if
109 - * they all fail, %NULL will be returned.
111 -static const struct phy_setting *
112 -phy_lookup_setting(int speed, int duplex, const unsigned long *mask,
113 - size_t maxbit, bool exact)
115 - const struct phy_setting *p, *match = NULL, *last = NULL;
118 - for (i = 0, p = settings; i < ARRAY_SIZE(settings); i++, p++) {
119 - if (p->bit < maxbit && test_bit(p->bit, mask)) {
121 - if (p->speed == speed && p->duplex == duplex) {
122 - /* Exact match for speed and duplex */
125 - } else if (!exact) {
126 - if (!match && p->speed <= speed)
130 - if (p->speed < speed)
136 - if (!match && !exact)
143 * phy_find_valid - find a PHY setting that matches the requested parameters
144 * @speed: desired speed
145 @@ -290,6 +171,25 @@ phy_find_valid(int speed, int duplex, u3
149 + * phy_supported_speeds - return all speeds currently supported by a phy device
150 + * @phy: The phy device to return supported speeds of.
151 + * @speeds: buffer to store supported speeds in.
152 + * @size: size of speeds buffer.
154 + * Description: Returns the number of supported speeds, and fills the speeds
155 + * buffer with the supported speeds. If speeds buffer is too small to contain
156 + * all currently supported speeds, will return as many speeds as can fit.
158 +unsigned int phy_supported_speeds(struct phy_device *phy,
159 + unsigned int *speeds,
162 + unsigned long supported = phy->supported;
164 + return phy_speeds(speeds, size, &supported, BITS_PER_LONG);
168 * phy_check_valid - check if there is a valid PHY setting which matches
169 * speed, duplex, and feature mask
170 * @speed: speed to match
171 --- a/drivers/net/phy/phy-core.c
172 +++ b/drivers/net/phy/phy-core.c
173 @@ -42,6 +42,132 @@ const char *phy_duplex_to_str(unsigned i
175 EXPORT_SYMBOL_GPL(phy_duplex_to_str);
177 +/* A mapping of all SUPPORTED settings to speed/duplex. This table
178 + * must be grouped by speed and sorted in descending match priority
179 + * - iow, descending speed. */
180 +static const struct phy_setting settings[] = {
182 + .speed = SPEED_10000,
183 + .duplex = DUPLEX_FULL,
184 + .bit = ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
187 + .speed = SPEED_10000,
188 + .duplex = DUPLEX_FULL,
189 + .bit = ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
192 + .speed = SPEED_10000,
193 + .duplex = DUPLEX_FULL,
194 + .bit = ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
197 + .speed = SPEED_2500,
198 + .duplex = DUPLEX_FULL,
199 + .bit = ETHTOOL_LINK_MODE_2500baseX_Full_BIT,
202 + .speed = SPEED_1000,
203 + .duplex = DUPLEX_FULL,
204 + .bit = ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
207 + .speed = SPEED_1000,
208 + .duplex = DUPLEX_FULL,
209 + .bit = ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
212 + .speed = SPEED_1000,
213 + .duplex = DUPLEX_HALF,
214 + .bit = ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
217 + .speed = SPEED_100,
218 + .duplex = DUPLEX_FULL,
219 + .bit = ETHTOOL_LINK_MODE_100baseT_Full_BIT,
222 + .speed = SPEED_100,
223 + .duplex = DUPLEX_HALF,
224 + .bit = ETHTOOL_LINK_MODE_100baseT_Half_BIT,
228 + .duplex = DUPLEX_FULL,
229 + .bit = ETHTOOL_LINK_MODE_10baseT_Full_BIT,
233 + .duplex = DUPLEX_HALF,
234 + .bit = ETHTOOL_LINK_MODE_10baseT_Half_BIT,
239 + * phy_lookup_setting - lookup a PHY setting
240 + * @speed: speed to match
241 + * @duplex: duplex to match
242 + * @mask: allowed link modes
243 + * @maxbit: bit size of link modes
244 + * @exact: an exact match is required
246 + * Search the settings array for a setting that matches the speed and
247 + * duplex, and which is supported.
249 + * If @exact is unset, either an exact match or %NULL for no match will
252 + * If @exact is set, an exact match, the fastest supported setting at
253 + * or below the specified speed, the slowest supported setting, or if
254 + * they all fail, %NULL will be returned.
256 +const struct phy_setting *
257 +phy_lookup_setting(int speed, int duplex, const unsigned long *mask,
258 + size_t maxbit, bool exact)
260 + const struct phy_setting *p, *match = NULL, *last = NULL;
263 + for (i = 0, p = settings; i < ARRAY_SIZE(settings); i++, p++) {
264 + if (p->bit < maxbit && test_bit(p->bit, mask)) {
266 + if (p->speed == speed && p->duplex == duplex) {
267 + /* Exact match for speed and duplex */
270 + } else if (!exact) {
271 + if (!match && p->speed <= speed)
275 + if (p->speed < speed)
281 + if (!match && !exact)
286 +EXPORT_SYMBOL_GPL(phy_lookup_setting);
288 +size_t phy_speeds(unsigned int *speeds, size_t size,
289 + unsigned long *mask, size_t maxbit)
294 + for (i = 0, count = 0; i < ARRAY_SIZE(settings) && count < size; i++)
295 + if (settings[i].bit < maxbit &&
296 + test_bit(settings[i].bit, mask) &&
297 + (count == 0 || speeds[count - 1] != settings[i].speed))
298 + speeds[count++] = settings[i].speed;
303 static inline void mmd_phy_indirect(struct mii_bus *bus, int prtad, int devad,
306 --- a/include/linux/phy.h
307 +++ b/include/linux/phy.h
308 @@ -644,6 +644,21 @@ struct phy_fixup {
309 const char *phy_speed_to_str(int speed);
310 const char *phy_duplex_to_str(unsigned int duplex);
312 +/* A structure for mapping a particular speed and duplex
313 + * combination to a particular SUPPORTED and ADVERTISED value
315 +struct phy_setting {
321 +const struct phy_setting *
322 +phy_lookup_setting(int speed, int duplex, const unsigned long *mask,
323 + size_t maxbit, bool exact);
324 +size_t phy_speeds(unsigned int *speeds, size_t size,
325 + unsigned long *mask, size_t maxbit);
328 * phy_read_mmd - Convenience function for reading a register
329 * from an MMD on a given PHY.