2bf9ea6a31
Signed-off-by: Felix Fietkau <nbd@nbd.name> Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
142 lines
4 KiB
Diff
142 lines
4 KiB
Diff
From: Russell King <rmk+kernel@armlinux.org.uk>
|
|
Date: Thu, 5 Jan 2017 16:32:14 +0000
|
|
Subject: [PATCH] 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>
|
|
---
|
|
|
|
--- a/drivers/net/phy/phy.c
|
|
+++ b/drivers/net/phy/phy.c
|
|
@@ -175,7 +175,7 @@ static inline int phy_aneg_done(struct p
|
|
struct phy_setting {
|
|
int speed;
|
|
int duplex;
|
|
- u32 setting;
|
|
+ int bit;
|
|
};
|
|
|
|
/* A mapping of all SUPPORTED settings to speed/duplex. This table
|
|
@@ -185,57 +185,57 @@ static const struct phy_setting settings
|
|
{
|
|
.speed = SPEED_10000,
|
|
.duplex = DUPLEX_FULL,
|
|
- .setting = SUPPORTED_10000baseKR_Full,
|
|
+ .bit = ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
|
|
},
|
|
{
|
|
.speed = SPEED_10000,
|
|
.duplex = DUPLEX_FULL,
|
|
- .setting = SUPPORTED_10000baseKX4_Full,
|
|
+ .bit = ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
|
|
},
|
|
{
|
|
.speed = SPEED_10000,
|
|
.duplex = DUPLEX_FULL,
|
|
- .setting = SUPPORTED_10000baseT_Full,
|
|
+ .bit = ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
|
|
},
|
|
{
|
|
.speed = SPEED_2500,
|
|
.duplex = DUPLEX_FULL,
|
|
- .setting = SUPPORTED_2500baseX_Full,
|
|
+ .bit = ETHTOOL_LINK_MODE_2500baseX_Full_BIT,
|
|
},
|
|
{
|
|
.speed = SPEED_1000,
|
|
.duplex = DUPLEX_FULL,
|
|
- .setting = SUPPORTED_1000baseKX_Full,
|
|
+ .bit = ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
|
|
},
|
|
{
|
|
.speed = SPEED_1000,
|
|
.duplex = DUPLEX_FULL,
|
|
- .setting = SUPPORTED_1000baseT_Full,
|
|
+ .bit = ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
|
|
},
|
|
{
|
|
.speed = SPEED_1000,
|
|
.duplex = DUPLEX_HALF,
|
|
- .setting = SUPPORTED_1000baseT_Half,
|
|
+ .bit = ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
|
|
},
|
|
{
|
|
.speed = SPEED_100,
|
|
.duplex = DUPLEX_FULL,
|
|
- .setting = SUPPORTED_100baseT_Full,
|
|
+ .bit = ETHTOOL_LINK_MODE_100baseT_Full_BIT,
|
|
},
|
|
{
|
|
.speed = SPEED_100,
|
|
.duplex = DUPLEX_HALF,
|
|
- .setting = SUPPORTED_100baseT_Half,
|
|
+ .bit = ETHTOOL_LINK_MODE_100baseT_Half_BIT,
|
|
},
|
|
{
|
|
.speed = SPEED_10,
|
|
.duplex = DUPLEX_FULL,
|
|
- .setting = SUPPORTED_10baseT_Full,
|
|
+ .bit = ETHTOOL_LINK_MODE_10baseT_Full_BIT,
|
|
},
|
|
{
|
|
.speed = SPEED_10,
|
|
.duplex = DUPLEX_HALF,
|
|
- .setting = SUPPORTED_10baseT_Half,
|
|
+ .bit = ETHTOOL_LINK_MODE_10baseT_Half_BIT,
|
|
},
|
|
};
|
|
|
|
@@ -243,7 +243,8 @@ static const struct phy_setting settings
|
|
* phy_lookup_setting - lookup a PHY setting
|
|
* @speed: speed to match
|
|
* @duplex: duplex to match
|
|
- * @feature: allowed link modes
|
|
+ * @mask: allowed link modes
|
|
+ * @maxbit: bit size of link modes
|
|
* @exact: an exact match is required
|
|
*
|
|
* Search the settings array for a setting that matches the speed and
|
|
@@ -257,13 +258,14 @@ static const struct phy_setting settings
|
|
* they all fail, %NULL will be returned.
|
|
*/
|
|
static const struct phy_setting *
|
|
-phy_lookup_setting(int speed, int duplex, u32 features, bool exact)
|
|
+phy_lookup_setting(int speed, int duplex, const unsigned long *mask,
|
|
+ size_t maxbit, bool exact)
|
|
{
|
|
const struct phy_setting *p, *match = NULL, *last = NULL;
|
|
int i;
|
|
|
|
for (i = 0, p = settings; i < ARRAY_SIZE(settings); i++, p++) {
|
|
- if (p->setting & features) {
|
|
+ if (p->bit < maxbit && test_bit(p->bit, mask)) {
|
|
last = p;
|
|
if (p->speed == speed && p->duplex == duplex) {
|
|
/* Exact match for speed and duplex */
|
|
@@ -302,7 +304,9 @@ phy_lookup_setting(int speed, int duplex
|
|
static const struct phy_setting *
|
|
phy_find_valid(int speed, int duplex, u32 supported)
|
|
{
|
|
- return phy_lookup_setting(speed, duplex, supported, false);
|
|
+ unsigned long mask = supported;
|
|
+
|
|
+ return phy_lookup_setting(speed, duplex, &mask, BITS_PER_LONG, false);
|
|
}
|
|
|
|
/**
|
|
@@ -316,7 +320,9 @@ phy_find_valid(int speed, int duplex, u3
|
|
*/
|
|
static inline bool phy_check_valid(int speed, int duplex, u32 features)
|
|
{
|
|
- return !!phy_lookup_setting(speed, duplex, features, true);
|
|
+ unsigned long mask = features;
|
|
+
|
|
+ return !!phy_lookup_setting(speed, duplex, &mask, BITS_PER_LONG, true);
|
|
}
|
|
|
|
/**
|