Skip to content

Commit c3ecbe7

Browse files
Russell Kingdavem330
authored andcommitted
net: phy: allow settings table to support more than 32 link modes
Allow the phy settings table to support more than 32 link modes by switching to the ethtool link mode bit number representation, rather than storing the mask. This will allow phylink and other ethtool code to share the settings table to look up settings. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 21e27f2 commit c3ecbe7

File tree

1 file changed

+26
-18
lines changed

1 file changed

+26
-18
lines changed

drivers/net/phy/phy.c

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ EXPORT_SYMBOL(phy_aneg_done);
199199
struct phy_setting {
200200
int speed;
201201
int duplex;
202-
u32 setting;
202+
int bit;
203203
};
204204

205205
/* A mapping of all SUPPORTED settings to speed/duplex. This table
@@ -209,65 +209,66 @@ static const struct phy_setting settings[] = {
209209
{
210210
.speed = SPEED_10000,
211211
.duplex = DUPLEX_FULL,
212-
.setting = SUPPORTED_10000baseKR_Full,
212+
.bit = ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
213213
},
214214
{
215215
.speed = SPEED_10000,
216216
.duplex = DUPLEX_FULL,
217-
.setting = SUPPORTED_10000baseKX4_Full,
217+
.bit = ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
218218
},
219219
{
220220
.speed = SPEED_10000,
221221
.duplex = DUPLEX_FULL,
222-
.setting = SUPPORTED_10000baseT_Full,
222+
.bit = ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
223223
},
224224
{
225225
.speed = SPEED_2500,
226226
.duplex = DUPLEX_FULL,
227-
.setting = SUPPORTED_2500baseX_Full,
227+
.bit = ETHTOOL_LINK_MODE_2500baseX_Full_BIT,
228228
},
229229
{
230230
.speed = SPEED_1000,
231231
.duplex = DUPLEX_FULL,
232-
.setting = SUPPORTED_1000baseKX_Full,
232+
.bit = ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
233233
},
234234
{
235235
.speed = SPEED_1000,
236236
.duplex = DUPLEX_FULL,
237-
.setting = SUPPORTED_1000baseT_Full,
237+
.bit = ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
238238
},
239239
{
240240
.speed = SPEED_1000,
241241
.duplex = DUPLEX_HALF,
242-
.setting = SUPPORTED_1000baseT_Half,
242+
.bit = ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
243243
},
244244
{
245245
.speed = SPEED_100,
246246
.duplex = DUPLEX_FULL,
247-
.setting = SUPPORTED_100baseT_Full,
247+
.bit = ETHTOOL_LINK_MODE_100baseT_Full_BIT,
248248
},
249249
{
250250
.speed = SPEED_100,
251251
.duplex = DUPLEX_HALF,
252-
.setting = SUPPORTED_100baseT_Half,
252+
.bit = ETHTOOL_LINK_MODE_100baseT_Half_BIT,
253253
},
254254
{
255255
.speed = SPEED_10,
256256
.duplex = DUPLEX_FULL,
257-
.setting = SUPPORTED_10baseT_Full,
257+
.bit = ETHTOOL_LINK_MODE_10baseT_Full_BIT,
258258
},
259259
{
260260
.speed = SPEED_10,
261261
.duplex = DUPLEX_HALF,
262-
.setting = SUPPORTED_10baseT_Half,
262+
.bit = ETHTOOL_LINK_MODE_10baseT_Half_BIT,
263263
},
264264
};
265265

266266
/**
267267
* phy_lookup_setting - lookup a PHY setting
268268
* @speed: speed to match
269269
* @duplex: duplex to match
270-
* @features: allowed link modes
270+
* @mask: allowed link modes
271+
* @maxbit: bit size of link modes
271272
* @exact: an exact match is required
272273
*
273274
* Search the settings array for a setting that matches the speed and
@@ -281,13 +282,14 @@ static const struct phy_setting settings[] = {
281282
* they all fail, %NULL will be returned.
282283
*/
283284
static const struct phy_setting *
284-
phy_lookup_setting(int speed, int duplex, u32 features, bool exact)
285+
phy_lookup_setting(int speed, int duplex, const unsigned long *mask,
286+
size_t maxbit, bool exact)
285287
{
286288
const struct phy_setting *p, *match = NULL, *last = NULL;
287289
int i;
288290

289291
for (i = 0, p = settings; i < ARRAY_SIZE(settings); i++, p++) {
290-
if (p->setting & features) {
292+
if (p->bit < maxbit && test_bit(p->bit, mask)) {
291293
last = p;
292294
if (p->speed == speed && p->duplex == duplex) {
293295
/* Exact match for speed and duplex */
@@ -326,7 +328,9 @@ phy_lookup_setting(int speed, int duplex, u32 features, bool exact)
326328
static const struct phy_setting *
327329
phy_find_valid(int speed, int duplex, u32 supported)
328330
{
329-
return phy_lookup_setting(speed, duplex, supported, false);
331+
unsigned long mask = supported;
332+
333+
return phy_lookup_setting(speed, duplex, &mask, BITS_PER_LONG, false);
330334
}
331335

332336
/**
@@ -343,12 +347,14 @@ unsigned int phy_supported_speeds(struct phy_device *phy,
343347
unsigned int *speeds,
344348
unsigned int size)
345349
{
350+
unsigned long supported = phy->supported;
346351
unsigned int count = 0;
347352
unsigned int idx = 0;
348353

349354
for (idx = 0; idx < ARRAY_SIZE(settings) && count < size; idx++)
350355
/* Assumes settings are grouped by speed */
351-
if ((settings[idx].setting & phy->supported) &&
356+
if (settings[idx].bit < BITS_PER_LONG &&
357+
!test_bit(settings[idx].bit, &supported) &&
352358
(count == 0 || speeds[count - 1] != settings[idx].speed))
353359
speeds[count++] = settings[idx].speed;
354360

@@ -366,7 +372,9 @@ unsigned int phy_supported_speeds(struct phy_device *phy,
366372
*/
367373
static inline bool phy_check_valid(int speed, int duplex, u32 features)
368374
{
369-
return !!phy_lookup_setting(speed, duplex, features, true);
375+
unsigned long mask = features;
376+
377+
return !!phy_lookup_setting(speed, duplex, &mask, BITS_PER_LONG, true);
370378
}
371379

372380
/**

0 commit comments

Comments
 (0)