Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Allan, Bruce W and committed by
David S. Miller
b32607dd 9e67030a

+90 -67
+7 -67
drivers/net/phy/phy.c
··· 1035 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 1039 * phy_init_eee - init and check the EEE feature 1100 1040 * @phydev: target phy_device struct ··· 1072 1132 if (eee_cap < 0) 1073 1133 return eee_cap; 1074 1134 1075 - cap = phy_eee_to_supported(eee_cap); 1135 + cap = mmd_eee_cap_to_ethtool_sup_t(eee_cap); 1076 1136 if (!cap) 1077 1137 goto eee_exit; 1078 1138 ··· 1089 1149 if (eee_adv < 0) 1090 1150 return eee_adv; 1091 1151 1092 - adv = phy_eee_to_adv(eee_adv); 1093 - lp = phy_eee_to_adv(eee_lp); 1152 + adv = mmd_eee_adv_to_ethtool_adv_t(eee_adv); 1153 + lp = mmd_eee_adv_to_ethtool_adv_t(eee_lp); 1094 1154 idx = phy_find_setting(phydev->speed, phydev->duplex); 1095 1155 if ((lp & adv & settings[idx].setting)) 1096 1156 goto eee_exit; ··· 1150 1210 MDIO_MMD_PCS, phydev->addr); 1151 1211 if (val < 0) 1152 1212 return val; 1153 - data->supported = phy_eee_to_supported(val); 1213 + data->supported = mmd_eee_cap_to_ethtool_sup_t(val); 1154 1214 1155 1215 /* Get advertisement EEE */ 1156 1216 val = phy_read_mmd_indirect(phydev->bus, MDIO_AN_EEE_ADV, 1157 1217 MDIO_MMD_AN, phydev->addr); 1158 1218 if (val < 0) 1159 1219 return val; 1160 - data->advertised = phy_eee_to_adv(val); 1220 + data->advertised = mmd_eee_adv_to_ethtool_adv_t(val); 1161 1221 1162 1222 /* Get LP advertisement EEE */ 1163 1223 val = phy_read_mmd_indirect(phydev->bus, MDIO_AN_EEE_LPABLE, 1164 1224 MDIO_MMD_AN, phydev->addr); 1165 1225 if (val < 0) 1166 1226 return val; 1167 - data->lp_advertised = phy_eee_to_adv(val); 1227 + data->lp_advertised = mmd_eee_adv_to_ethtool_adv_t(val); 1168 1228 1169 1229 return 0; 1170 1230 } ··· 1181 1241 { 1182 1242 int val; 1183 1243 1184 - val = phy_adv_to_eee(data->advertised); 1244 + val = ethtool_adv_to_mmd_eee_adv_t(data->advertised); 1185 1245 phy_write_mmd_indirect(phydev->bus, MDIO_AN_EEE_ADV, MDIO_MMD_AN, 1186 1246 phydev->addr, val); 1187 1247
+83
include/linux/mdio.h
··· 377 377 extern int mdio_mii_ioctl(const struct mdio_if_info *mdio, 378 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) 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 + */ 443 + static 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 463 #endif /* __KERNEL__ */ 381 464 #endif /* __LINUX_MDIO_H__ */