diff options
| author | Allan, Bruce W <bruce.w.allan@intel.com> | 2012-08-20 00:55:29 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2012-08-23 01:58:27 -0400 |
| commit | b32607dd47d456b99f0a16f1c37bc8a0975ffb19 (patch) | |
| tree | 74be66275dc26089b3a2c7b73b83d08198cff551 | |
| parent | 9e67030af367ab524d0856af9e992de241eca3c7 (diff) | |
mdio: translation of MMD EEE registers to/from ethtool settings
The helper functions which translate IEEE MDIO Manageable Device (MMD)
Energy-Efficient Ethernet (EEE) registers 3.20, 7.60 and 7.61 to and from
the comparable ethtool supported/advertised settings will be needed by
drivers other than those in PHYLIB (e.g. e1000e in a follow-on patch).
In the same fashion as similar translation functions in linux/mii.h, move
these functions from the PHYLIB core to the linux/mdio.h header file so the
code will not have to be duplicated in each driver needing MMD-to-ethtool
(and vice-versa) translations. The function and some variable names have
been renamed to be more descriptive.
Not tested on the only hardware that currently calls the related functions,
stmmac, because I don't have access to any. Has been compile tested and
the translations have been tested on a locally modified version of e1000e.
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Cc: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | drivers/net/phy/phy.c | 74 | ||||
| -rw-r--r-- | include/linux/mdio.h | 83 |
2 files changed, 90 insertions, 67 deletions
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 7ca2ff97c368..ef9ea9248223 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c | |||
| @@ -1035,66 +1035,6 @@ static void phy_write_mmd_indirect(struct mii_bus *bus, int prtad, int devad, | |||
| 1035 | bus->write(bus, addr, MII_MMD_DATA, data); | 1035 | bus->write(bus, addr, MII_MMD_DATA, data); |
| 1036 | } | 1036 | } |
| 1037 | 1037 | ||
| 1038 | static u32 phy_eee_to_adv(u16 eee_adv) | ||
| 1039 | { | ||
| 1040 | u32 adv = 0; | ||
| 1041 | |||
| 1042 | if (eee_adv & MDIO_EEE_100TX) | ||
| 1043 | adv |= ADVERTISED_100baseT_Full; | ||
| 1044 | if (eee_adv & MDIO_EEE_1000T) | ||
| 1045 | adv |= ADVERTISED_1000baseT_Full; | ||
| 1046 | if (eee_adv & MDIO_EEE_10GT) | ||
| 1047 | adv |= ADVERTISED_10000baseT_Full; | ||
| 1048 | if (eee_adv & MDIO_EEE_1000KX) | ||
| 1049 | adv |= ADVERTISED_1000baseKX_Full; | ||
| 1050 | if (eee_adv & MDIO_EEE_10GKX4) | ||
| 1051 | adv |= ADVERTISED_10000baseKX4_Full; | ||
| 1052 | if (eee_adv & MDIO_EEE_10GKR) | ||
| 1053 | adv |= ADVERTISED_10000baseKR_Full; | ||
| 1054 | |||
| 1055 | return adv; | ||
| 1056 | } | ||
| 1057 | |||
| 1058 | static u32 phy_eee_to_supported(u16 eee_caported) | ||
| 1059 | { | ||
| 1060 | u32 supported = 0; | ||
| 1061 | |||
| 1062 | if (eee_caported & MDIO_EEE_100TX) | ||
| 1063 | supported |= SUPPORTED_100baseT_Full; | ||
| 1064 | if (eee_caported & MDIO_EEE_1000T) | ||
| 1065 | supported |= SUPPORTED_1000baseT_Full; | ||
| 1066 | if (eee_caported & MDIO_EEE_10GT) | ||
| 1067 | supported |= SUPPORTED_10000baseT_Full; | ||
| 1068 | if (eee_caported & MDIO_EEE_1000KX) | ||
| 1069 | supported |= SUPPORTED_1000baseKX_Full; | ||
| 1070 | if (eee_caported & MDIO_EEE_10GKX4) | ||
| 1071 | supported |= SUPPORTED_10000baseKX4_Full; | ||
| 1072 | if (eee_caported & MDIO_EEE_10GKR) | ||
| 1073 | supported |= SUPPORTED_10000baseKR_Full; | ||
| 1074 | |||
| 1075 | return supported; | ||
| 1076 | } | ||
| 1077 | |||
| 1078 | static u16 phy_adv_to_eee(u32 adv) | ||
| 1079 | { | ||
| 1080 | u16 reg = 0; | ||
| 1081 | |||
| 1082 | if (adv & ADVERTISED_100baseT_Full) | ||
| 1083 | reg |= MDIO_EEE_100TX; | ||
| 1084 | if (adv & ADVERTISED_1000baseT_Full) | ||
| 1085 | reg |= MDIO_EEE_1000T; | ||
| 1086 | if (adv & ADVERTISED_10000baseT_Full) | ||
| 1087 | reg |= MDIO_EEE_10GT; | ||
| 1088 | if (adv & ADVERTISED_1000baseKX_Full) | ||
| 1089 | reg |= MDIO_EEE_1000KX; | ||
| 1090 | if (adv & ADVERTISED_10000baseKX4_Full) | ||
| 1091 | reg |= MDIO_EEE_10GKX4; | ||
| 1092 | if (adv & ADVERTISED_10000baseKR_Full) | ||
| 1093 | reg |= MDIO_EEE_10GKR; | ||
| 1094 | |||
| 1095 | return reg; | ||
| 1096 | } | ||
| 1097 | |||
| 1098 | /** | 1038 | /** |
| 1099 | * phy_init_eee - init and check the EEE feature | 1039 | * phy_init_eee - init and check the EEE feature |
| 1100 | * @phydev: target phy_device struct | 1040 | * @phydev: target phy_device struct |
| @@ -1132,7 +1072,7 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable) | |||
| 1132 | if (eee_cap < 0) | 1072 | if (eee_cap < 0) |
| 1133 | return eee_cap; | 1073 | return eee_cap; |
| 1134 | 1074 | ||
| 1135 | cap = phy_eee_to_supported(eee_cap); | 1075 | cap = mmd_eee_cap_to_ethtool_sup_t(eee_cap); |
| 1136 | if (!cap) | 1076 | if (!cap) |
| 1137 | goto eee_exit; | 1077 | goto eee_exit; |
| 1138 | 1078 | ||
| @@ -1149,8 +1089,8 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable) | |||
| 1149 | if (eee_adv < 0) | 1089 | if (eee_adv < 0) |
| 1150 | return eee_adv; | 1090 | return eee_adv; |
| 1151 | 1091 | ||
| 1152 | adv = phy_eee_to_adv(eee_adv); | 1092 | adv = mmd_eee_adv_to_ethtool_adv_t(eee_adv); |
| 1153 | lp = phy_eee_to_adv(eee_lp); | 1093 | lp = mmd_eee_adv_to_ethtool_adv_t(eee_lp); |
| 1154 | idx = phy_find_setting(phydev->speed, phydev->duplex); | 1094 | idx = phy_find_setting(phydev->speed, phydev->duplex); |
| 1155 | if ((lp & adv & settings[idx].setting)) | 1095 | if ((lp & adv & settings[idx].setting)) |
| 1156 | goto eee_exit; | 1096 | goto eee_exit; |
| @@ -1210,21 +1150,21 @@ int phy_ethtool_get_eee(struct phy_device *phydev, struct ethtool_eee *data) | |||
| 1210 | MDIO_MMD_PCS, phydev->addr); | 1150 | MDIO_MMD_PCS, phydev->addr); |
| 1211 | if (val < 0) | 1151 | if (val < 0) |
| 1212 | return val; | 1152 | return val; |
| 1213 | data->supported = phy_eee_to_supported(val); | 1153 | data->supported = mmd_eee_cap_to_ethtool_sup_t(val); |
| 1214 | 1154 | ||
| 1215 | /* Get advertisement EEE */ | 1155 | /* Get advertisement EEE */ |
| 1216 | val = phy_read_mmd_indirect(phydev->bus, MDIO_AN_EEE_ADV, | 1156 | val = phy_read_mmd_indirect(phydev->bus, MDIO_AN_EEE_ADV, |
| 1217 | MDIO_MMD_AN, phydev->addr); | 1157 | MDIO_MMD_AN, phydev->addr); |
| 1218 | if (val < 0) | 1158 | if (val < 0) |
| 1219 | return val; | 1159 | return val; |
| 1220 | data->advertised = phy_eee_to_adv(val); | 1160 | data->advertised = mmd_eee_adv_to_ethtool_adv_t(val); |
| 1221 | 1161 | ||
| 1222 | /* Get LP advertisement EEE */ | 1162 | /* Get LP advertisement EEE */ |
| 1223 | val = phy_read_mmd_indirect(phydev->bus, MDIO_AN_EEE_LPABLE, | 1163 | val = phy_read_mmd_indirect(phydev->bus, MDIO_AN_EEE_LPABLE, |
| 1224 | MDIO_MMD_AN, phydev->addr); | 1164 | MDIO_MMD_AN, phydev->addr); |
| 1225 | if (val < 0) | 1165 | if (val < 0) |
| 1226 | return val; | 1166 | return val; |
| 1227 | data->lp_advertised = phy_eee_to_adv(val); | 1167 | data->lp_advertised = mmd_eee_adv_to_ethtool_adv_t(val); |
| 1228 | 1168 | ||
| 1229 | return 0; | 1169 | return 0; |
| 1230 | } | 1170 | } |
| @@ -1241,7 +1181,7 @@ int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_eee *data) | |||
| 1241 | { | 1181 | { |
| 1242 | int val; | 1182 | int val; |
| 1243 | 1183 | ||
| 1244 | val = phy_adv_to_eee(data->advertised); | 1184 | val = ethtool_adv_to_mmd_eee_adv_t(data->advertised); |
| 1245 | phy_write_mmd_indirect(phydev->bus, MDIO_AN_EEE_ADV, MDIO_MMD_AN, | 1185 | phy_write_mmd_indirect(phydev->bus, MDIO_AN_EEE_ADV, MDIO_MMD_AN, |
| 1246 | phydev->addr, val); | 1186 | phydev->addr, val); |
| 1247 | 1187 | ||
diff --git a/include/linux/mdio.h b/include/linux/mdio.h index 7cccafe50e7b..6c406845f7e2 100644 --- a/include/linux/mdio.h +++ b/include/linux/mdio.h | |||
| @@ -377,5 +377,88 @@ static inline void mdio45_ethtool_gset(const struct mdio_if_info *mdio, | |||
| 377 | extern int mdio_mii_ioctl(const struct mdio_if_info *mdio, | 377 | extern int mdio_mii_ioctl(const struct mdio_if_info *mdio, |
| 378 | struct mii_ioctl_data *mii_data, int cmd); | 378 | struct mii_ioctl_data *mii_data, int cmd); |
| 379 | 379 | ||
| 380 | /** | ||
| 381 | * mmd_eee_cap_to_ethtool_sup_t | ||
| 382 | * @eee_cap: value of the MMD EEE Capability register | ||
| 383 | * | ||
| 384 | * A small helper function that translates MMD EEE Capability (3.20) bits | ||
| 385 | * to ethtool supported settings. | ||
| 386 | */ | ||
| 387 | static inline u32 mmd_eee_cap_to_ethtool_sup_t(u16 eee_cap) | ||
| 388 | { | ||
| 389 | u32 supported = 0; | ||
| 390 | |||
| 391 | if (eee_cap & MDIO_EEE_100TX) | ||
| 392 | supported |= SUPPORTED_100baseT_Full; | ||
| 393 | if (eee_cap & MDIO_EEE_1000T) | ||
| 394 | supported |= SUPPORTED_1000baseT_Full; | ||
| 395 | if (eee_cap & MDIO_EEE_10GT) | ||
| 396 | supported |= SUPPORTED_10000baseT_Full; | ||
| 397 | if (eee_cap & MDIO_EEE_1000KX) | ||
| 398 | supported |= SUPPORTED_1000baseKX_Full; | ||
| 399 | if (eee_cap & MDIO_EEE_10GKX4) | ||
| 400 | supported |= SUPPORTED_10000baseKX4_Full; | ||
| 401 | if (eee_cap & MDIO_EEE_10GKR) | ||
| 402 | supported |= SUPPORTED_10000baseKR_Full; | ||
| 403 | |||
| 404 | return supported; | ||
| 405 | } | ||
| 406 | |||
| 407 | /** | ||
| 408 | * mmd_eee_adv_to_ethtool_adv_t | ||
| 409 | * @eee_adv: value of the MMD EEE Advertisement/Link Partner Ability registers | ||
| 410 | * | ||
| 411 | * A small helper function that translates the MMD EEE Advertisment (7.60) | ||
| 412 | * and MMD EEE Link Partner Ability (7.61) bits to ethtool advertisement | ||
| 413 | * settings. | ||
| 414 | */ | ||
| 415 | static inline u32 mmd_eee_adv_to_ethtool_adv_t(u16 eee_adv) | ||
| 416 | { | ||
| 417 | u32 adv = 0; | ||
| 418 | |||
| 419 | if (eee_adv & MDIO_EEE_100TX) | ||
| 420 | adv |= ADVERTISED_100baseT_Full; | ||
| 421 | if (eee_adv & MDIO_EEE_1000T) | ||
| 422 | adv |= ADVERTISED_1000baseT_Full; | ||
| 423 | if (eee_adv & MDIO_EEE_10GT) | ||
