aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAllan, Bruce W <bruce.w.allan@intel.com>2012-08-20 00:55:29 -0400
committerDavid S. Miller <davem@davemloft.net>2012-08-23 01:58:27 -0400
commitb32607dd47d456b99f0a16f1c37bc8a0975ffb19 (patch)
tree74be66275dc26089b3a2c7b73b83d08198cff551
parent9e67030af367ab524d0856af9e992de241eca3c7 (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.c74
-rw-r--r--include/linux/mdio.h83
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
1038static 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
1058static 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
1078static 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,
377extern int mdio_mii_ioctl(const struct mdio_if_info *mdio, 377extern 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 */
387static 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 */
415static 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)
424 adv |= ADVERTISED_10000baseT_Full;
425 if (eee_adv & MDIO_EEE_1000KX)
426 adv |= ADVERTISED_1000baseKX_Full;
427 if (eee_adv & MDIO_EEE_10GKX4)
428 adv |= ADVERTISED_10000baseKX4_Full;
429 if (eee_adv & MDIO_EEE_10GKR)
430 adv |= ADVERTISED_10000baseKR_Full;
431
432 return adv;
433}
434
435/**
436 * ethtool_adv_to_mmd_eee_adv_t
437 * @adv: the ethtool advertisement settings
438 *
439 * A small helper function that translates ethtool advertisement settings
440 * to EEE advertisements for the MMD EEE Advertisement (7.60) and
441 * MMD EEE Link Partner Ability (7.61) registers.
442 */
443static inline u16 ethtool_adv_to_mmd_eee_adv_t(u32 adv)
444{
445 u16 reg = 0;
446
447 if (adv & ADVERTISED_100baseT_Full)
448 reg |= MDIO_EEE_100TX;
449 if (adv & ADVERTISED_1000baseT_Full)
450 reg |= MDIO_EEE_1000T;
451 if (adv & ADVERTISED_10000baseT_Full)
452 reg |= MDIO_EEE_10GT;
453 if (adv & ADVERTISED_1000baseKX_Full)
454 reg |= MDIO_EEE_1000KX;
455 if (adv & ADVERTISED_10000baseKX4_Full)
456 reg |= MDIO_EEE_10GKX4;
457 if (adv & ADVERTISED_10000baseKR_Full)
458 reg |= MDIO_EEE_10GKR;
459
460 return reg;
461}
462
380#endif /* __KERNEL__ */ 463#endif /* __KERNEL__ */
381#endif /* __LINUX_MDIO_H__ */ 464#endif /* __LINUX_MDIO_H__ */