1152 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * Core PHY library, taken from phy.c4 */5#include <linux/export.h>6#include <linux/phy.h>7#include <linux/of.h>8 9/**10 * phy_speed_to_str - Return a string representing the PHY link speed11 *12 * @speed: Speed of the link13 */14const char *phy_speed_to_str(int speed)15{16 BUILD_BUG_ON_MSG(__ETHTOOL_LINK_MODE_MASK_NBITS != 103,17 "Enum ethtool_link_mode_bit_indices and phylib are out of sync. "18 "If a speed or mode has been added please update phy_speed_to_str "19 "and the PHY settings array.\n");20 21 switch (speed) {22 case SPEED_10:23 return "10Mbps";24 case SPEED_100:25 return "100Mbps";26 case SPEED_1000:27 return "1Gbps";28 case SPEED_2500:29 return "2.5Gbps";30 case SPEED_5000:31 return "5Gbps";32 case SPEED_10000:33 return "10Gbps";34 case SPEED_14000:35 return "14Gbps";36 case SPEED_20000:37 return "20Gbps";38 case SPEED_25000:39 return "25Gbps";40 case SPEED_40000:41 return "40Gbps";42 case SPEED_50000:43 return "50Gbps";44 case SPEED_56000:45 return "56Gbps";46 case SPEED_100000:47 return "100Gbps";48 case SPEED_200000:49 return "200Gbps";50 case SPEED_400000:51 return "400Gbps";52 case SPEED_800000:53 return "800Gbps";54 case SPEED_UNKNOWN:55 return "Unknown";56 default:57 return "Unsupported (update phy-core.c)";58 }59}60EXPORT_SYMBOL_GPL(phy_speed_to_str);61 62/**63 * phy_duplex_to_str - Return string describing the duplex64 *65 * @duplex: Duplex setting to describe66 */67const char *phy_duplex_to_str(unsigned int duplex)68{69 if (duplex == DUPLEX_HALF)70 return "Half";71 if (duplex == DUPLEX_FULL)72 return "Full";73 if (duplex == DUPLEX_UNKNOWN)74 return "Unknown";75 return "Unsupported (update phy-core.c)";76}77EXPORT_SYMBOL_GPL(phy_duplex_to_str);78 79/**80 * phy_rate_matching_to_str - Return a string describing the rate matching81 *82 * @rate_matching: Type of rate matching to describe83 */84const char *phy_rate_matching_to_str(int rate_matching)85{86 switch (rate_matching) {87 case RATE_MATCH_NONE:88 return "none";89 case RATE_MATCH_PAUSE:90 return "pause";91 case RATE_MATCH_CRS:92 return "crs";93 case RATE_MATCH_OPEN_LOOP:94 return "open-loop";95 }96 return "Unsupported (update phy-core.c)";97}98EXPORT_SYMBOL_GPL(phy_rate_matching_to_str);99 100/**101 * phy_interface_num_ports - Return the number of links that can be carried by102 * a given MAC-PHY physical link. Returns 0 if this is103 * unknown, the number of links else.104 *105 * @interface: The interface mode we want to get the number of ports106 */107int phy_interface_num_ports(phy_interface_t interface)108{109 switch (interface) {110 case PHY_INTERFACE_MODE_NA:111 return 0;112 case PHY_INTERFACE_MODE_INTERNAL:113 case PHY_INTERFACE_MODE_MII:114 case PHY_INTERFACE_MODE_GMII:115 case PHY_INTERFACE_MODE_TBI:116 case PHY_INTERFACE_MODE_REVMII:117 case PHY_INTERFACE_MODE_RMII:118 case PHY_INTERFACE_MODE_REVRMII:119 case PHY_INTERFACE_MODE_RGMII:120 case PHY_INTERFACE_MODE_RGMII_ID:121 case PHY_INTERFACE_MODE_RGMII_RXID:122 case PHY_INTERFACE_MODE_RGMII_TXID:123 case PHY_INTERFACE_MODE_RTBI:124 case PHY_INTERFACE_MODE_XGMII:125 case PHY_INTERFACE_MODE_XLGMII:126 case PHY_INTERFACE_MODE_MOCA:127 case PHY_INTERFACE_MODE_TRGMII:128 case PHY_INTERFACE_MODE_USXGMII:129 case PHY_INTERFACE_MODE_SGMII:130 case PHY_INTERFACE_MODE_SMII:131 case PHY_INTERFACE_MODE_1000BASEX:132 case PHY_INTERFACE_MODE_2500BASEX:133 case PHY_INTERFACE_MODE_5GBASER:134 case PHY_INTERFACE_MODE_10GBASER:135 case PHY_INTERFACE_MODE_25GBASER:136 case PHY_INTERFACE_MODE_10GKR:137 case PHY_INTERFACE_MODE_100BASEX:138 case PHY_INTERFACE_MODE_RXAUI:139 case PHY_INTERFACE_MODE_XAUI:140 case PHY_INTERFACE_MODE_1000BASEKX:141 return 1;142 case PHY_INTERFACE_MODE_QSGMII:143 case PHY_INTERFACE_MODE_QUSGMII:144 case PHY_INTERFACE_MODE_10G_QXGMII:145 return 4;146 case PHY_INTERFACE_MODE_PSGMII:147 return 5;148 case PHY_INTERFACE_MODE_MAX:149 WARN_ONCE(1, "PHY_INTERFACE_MODE_MAX isn't a valid interface mode");150 return 0;151 }152 return 0;153}154EXPORT_SYMBOL_GPL(phy_interface_num_ports);155 156/* A mapping of all SUPPORTED settings to speed/duplex. This table157 * must be grouped by speed and sorted in descending match priority158 * - iow, descending speed.159 */160 161#define PHY_SETTING(s, d, b) { .speed = SPEED_ ## s, .duplex = DUPLEX_ ## d, \162 .bit = ETHTOOL_LINK_MODE_ ## b ## _BIT}163 164static const struct phy_setting settings[] = {165 /* 800G */166 PHY_SETTING( 800000, FULL, 800000baseCR8_Full ),167 PHY_SETTING( 800000, FULL, 800000baseKR8_Full ),168 PHY_SETTING( 800000, FULL, 800000baseDR8_Full ),169 PHY_SETTING( 800000, FULL, 800000baseDR8_2_Full ),170 PHY_SETTING( 800000, FULL, 800000baseSR8_Full ),171 PHY_SETTING( 800000, FULL, 800000baseVR8_Full ),172 /* 400G */173 PHY_SETTING( 400000, FULL, 400000baseCR8_Full ),174 PHY_SETTING( 400000, FULL, 400000baseKR8_Full ),175 PHY_SETTING( 400000, FULL, 400000baseLR8_ER8_FR8_Full ),176 PHY_SETTING( 400000, FULL, 400000baseDR8_Full ),177 PHY_SETTING( 400000, FULL, 400000baseSR8_Full ),178 PHY_SETTING( 400000, FULL, 400000baseCR4_Full ),179 PHY_SETTING( 400000, FULL, 400000baseKR4_Full ),180 PHY_SETTING( 400000, FULL, 400000baseLR4_ER4_FR4_Full ),181 PHY_SETTING( 400000, FULL, 400000baseDR4_Full ),182 PHY_SETTING( 400000, FULL, 400000baseSR4_Full ),183 /* 200G */184 PHY_SETTING( 200000, FULL, 200000baseCR4_Full ),185 PHY_SETTING( 200000, FULL, 200000baseKR4_Full ),186 PHY_SETTING( 200000, FULL, 200000baseLR4_ER4_FR4_Full ),187 PHY_SETTING( 200000, FULL, 200000baseDR4_Full ),188 PHY_SETTING( 200000, FULL, 200000baseSR4_Full ),189 PHY_SETTING( 200000, FULL, 200000baseCR2_Full ),190 PHY_SETTING( 200000, FULL, 200000baseKR2_Full ),191 PHY_SETTING( 200000, FULL, 200000baseLR2_ER2_FR2_Full ),192 PHY_SETTING( 200000, FULL, 200000baseDR2_Full ),193 PHY_SETTING( 200000, FULL, 200000baseSR2_Full ),194 /* 100G */195 PHY_SETTING( 100000, FULL, 100000baseCR4_Full ),196 PHY_SETTING( 100000, FULL, 100000baseKR4_Full ),197 PHY_SETTING( 100000, FULL, 100000baseLR4_ER4_Full ),198 PHY_SETTING( 100000, FULL, 100000baseSR4_Full ),199 PHY_SETTING( 100000, FULL, 100000baseCR2_Full ),200 PHY_SETTING( 100000, FULL, 100000baseKR2_Full ),201 PHY_SETTING( 100000, FULL, 100000baseLR2_ER2_FR2_Full ),202 PHY_SETTING( 100000, FULL, 100000baseDR2_Full ),203 PHY_SETTING( 100000, FULL, 100000baseSR2_Full ),204 PHY_SETTING( 100000, FULL, 100000baseCR_Full ),205 PHY_SETTING( 100000, FULL, 100000baseKR_Full ),206 PHY_SETTING( 100000, FULL, 100000baseLR_ER_FR_Full ),207 PHY_SETTING( 100000, FULL, 100000baseDR_Full ),208 PHY_SETTING( 100000, FULL, 100000baseSR_Full ),209 /* 56G */210 PHY_SETTING( 56000, FULL, 56000baseCR4_Full ),211 PHY_SETTING( 56000, FULL, 56000baseKR4_Full ),212 PHY_SETTING( 56000, FULL, 56000baseLR4_Full ),213 PHY_SETTING( 56000, FULL, 56000baseSR4_Full ),214 /* 50G */215 PHY_SETTING( 50000, FULL, 50000baseCR2_Full ),216 PHY_SETTING( 50000, FULL, 50000baseKR2_Full ),217 PHY_SETTING( 50000, FULL, 50000baseSR2_Full ),218 PHY_SETTING( 50000, FULL, 50000baseCR_Full ),219 PHY_SETTING( 50000, FULL, 50000baseKR_Full ),220 PHY_SETTING( 50000, FULL, 50000baseLR_ER_FR_Full ),221 PHY_SETTING( 50000, FULL, 50000baseDR_Full ),222 PHY_SETTING( 50000, FULL, 50000baseSR_Full ),223 /* 40G */224 PHY_SETTING( 40000, FULL, 40000baseCR4_Full ),225 PHY_SETTING( 40000, FULL, 40000baseKR4_Full ),226 PHY_SETTING( 40000, FULL, 40000baseLR4_Full ),227 PHY_SETTING( 40000, FULL, 40000baseSR4_Full ),228 /* 25G */229 PHY_SETTING( 25000, FULL, 25000baseCR_Full ),230 PHY_SETTING( 25000, FULL, 25000baseKR_Full ),231 PHY_SETTING( 25000, FULL, 25000baseSR_Full ),232 /* 20G */233 PHY_SETTING( 20000, FULL, 20000baseKR2_Full ),234 PHY_SETTING( 20000, FULL, 20000baseMLD2_Full ),235 /* 10G */236 PHY_SETTING( 10000, FULL, 10000baseCR_Full ),237 PHY_SETTING( 10000, FULL, 10000baseER_Full ),238 PHY_SETTING( 10000, FULL, 10000baseKR_Full ),239 PHY_SETTING( 10000, FULL, 10000baseKX4_Full ),240 PHY_SETTING( 10000, FULL, 10000baseLR_Full ),241 PHY_SETTING( 10000, FULL, 10000baseLRM_Full ),242 PHY_SETTING( 10000, FULL, 10000baseR_FEC ),243 PHY_SETTING( 10000, FULL, 10000baseSR_Full ),244 PHY_SETTING( 10000, FULL, 10000baseT_Full ),245 /* 5G */246 PHY_SETTING( 5000, FULL, 5000baseT_Full ),247 /* 2.5G */248 PHY_SETTING( 2500, FULL, 2500baseT_Full ),249 PHY_SETTING( 2500, FULL, 2500baseX_Full ),250 /* 1G */251 PHY_SETTING( 1000, FULL, 1000baseT_Full ),252 PHY_SETTING( 1000, HALF, 1000baseT_Half ),253 PHY_SETTING( 1000, FULL, 1000baseT1_Full ),254 PHY_SETTING( 1000, FULL, 1000baseX_Full ),255 PHY_SETTING( 1000, FULL, 1000baseKX_Full ),256 /* 100M */257 PHY_SETTING( 100, FULL, 100baseT_Full ),258 PHY_SETTING( 100, FULL, 100baseT1_Full ),259 PHY_SETTING( 100, HALF, 100baseT_Half ),260 PHY_SETTING( 100, HALF, 100baseFX_Half ),261 PHY_SETTING( 100, FULL, 100baseFX_Full ),262 /* 10M */263 PHY_SETTING( 10, FULL, 10baseT_Full ),264 PHY_SETTING( 10, HALF, 10baseT_Half ),265 PHY_SETTING( 10, FULL, 10baseT1L_Full ),266 PHY_SETTING( 10, FULL, 10baseT1S_Full ),267 PHY_SETTING( 10, HALF, 10baseT1S_Half ),268 PHY_SETTING( 10, HALF, 10baseT1S_P2MP_Half ),269 PHY_SETTING( 10, FULL, 10baseT1BRR_Full ),270};271#undef PHY_SETTING272 273/**274 * phy_lookup_setting - lookup a PHY setting275 * @speed: speed to match276 * @duplex: duplex to match277 * @mask: allowed link modes278 * @exact: an exact match is required279 *280 * Search the settings array for a setting that matches the speed and281 * duplex, and which is supported.282 *283 * If @exact is unset, either an exact match or %NULL for no match will284 * be returned.285 *286 * If @exact is set, an exact match, the fastest supported setting at287 * or below the specified speed, the slowest supported setting, or if288 * they all fail, %NULL will be returned.289 */290const struct phy_setting *291phy_lookup_setting(int speed, int duplex, const unsigned long *mask, bool exact)292{293 const struct phy_setting *p, *match = NULL, *last = NULL;294 int i;295 296 for (i = 0, p = settings; i < ARRAY_SIZE(settings); i++, p++) {297 if (p->bit < __ETHTOOL_LINK_MODE_MASK_NBITS &&298 test_bit(p->bit, mask)) {299 last = p;300 if (p->speed == speed && p->duplex == duplex) {301 /* Exact match for speed and duplex */302 match = p;303 break;304 } else if (!exact) {305 if (!match && p->speed <= speed)306 /* Candidate */307 match = p;308 309 if (p->speed < speed)310 break;311 }312 }313 }314 315 if (!match && !exact)316 match = last;317 318 return match;319}320EXPORT_SYMBOL_GPL(phy_lookup_setting);321 322size_t phy_speeds(unsigned int *speeds, size_t size,323 unsigned long *mask)324{325 size_t count;326 int i;327 328 for (i = 0, count = 0; i < ARRAY_SIZE(settings) && count < size; i++)329 if (settings[i].bit < __ETHTOOL_LINK_MODE_MASK_NBITS &&330 test_bit(settings[i].bit, mask) &&331 (count == 0 || speeds[count - 1] != settings[i].speed))332 speeds[count++] = settings[i].speed;333 334 return count;335}336 337static void __set_linkmode_max_speed(u32 max_speed, unsigned long *addr)338{339 const struct phy_setting *p;340 int i;341 342 for (i = 0, p = settings; i < ARRAY_SIZE(settings); i++, p++) {343 if (p->speed > max_speed)344 linkmode_clear_bit(p->bit, addr);345 else346 break;347 }348}349 350static void __set_phy_supported(struct phy_device *phydev, u32 max_speed)351{352 __set_linkmode_max_speed(max_speed, phydev->supported);353}354 355/**356 * phy_set_max_speed - Set the maximum speed the PHY should support357 *358 * @phydev: The phy_device struct359 * @max_speed: Maximum speed360 *361 * The PHY might be more capable than the MAC. For example a Fast Ethernet362 * is connected to a 1G PHY. This function allows the MAC to indicate its363 * maximum speed, and so limit what the PHY will advertise.364 */365void phy_set_max_speed(struct phy_device *phydev, u32 max_speed)366{367 __set_phy_supported(phydev, max_speed);368 369 phy_advertise_supported(phydev);370}371EXPORT_SYMBOL(phy_set_max_speed);372 373void of_set_phy_supported(struct phy_device *phydev)374{375 struct device_node *node = phydev->mdio.dev.of_node;376 u32 max_speed;377 378 if (!IS_ENABLED(CONFIG_OF_MDIO))379 return;380 381 if (!node)382 return;383 384 if (!of_property_read_u32(node, "max-speed", &max_speed))385 __set_phy_supported(phydev, max_speed);386}387 388void of_set_phy_eee_broken(struct phy_device *phydev)389{390 struct device_node *node = phydev->mdio.dev.of_node;391 u32 broken = 0;392 393 if (!IS_ENABLED(CONFIG_OF_MDIO))394 return;395 396 if (!node)397 return;398 399 if (of_property_read_bool(node, "eee-broken-100tx"))400 broken |= MDIO_EEE_100TX;401 if (of_property_read_bool(node, "eee-broken-1000t"))402 broken |= MDIO_EEE_1000T;403 if (of_property_read_bool(node, "eee-broken-10gt"))404 broken |= MDIO_EEE_10GT;405 if (of_property_read_bool(node, "eee-broken-1000kx"))406 broken |= MDIO_EEE_1000KX;407 if (of_property_read_bool(node, "eee-broken-10gkx4"))408 broken |= MDIO_EEE_10GKX4;409 if (of_property_read_bool(node, "eee-broken-10gkr"))410 broken |= MDIO_EEE_10GKR;411 412 phydev->eee_broken_modes = broken;413}414 415/**416 * phy_resolve_aneg_pause - Determine pause autoneg results417 *418 * @phydev: The phy_device struct419 *420 * Once autoneg has completed the local pause settings can be421 * resolved. Determine if pause and asymmetric pause should be used422 * by the MAC.423 */424 425void phy_resolve_aneg_pause(struct phy_device *phydev)426{427 if (phydev->duplex == DUPLEX_FULL) {428 phydev->pause = linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT,429 phydev->lp_advertising);430 phydev->asym_pause = linkmode_test_bit(431 ETHTOOL_LINK_MODE_Asym_Pause_BIT,432 phydev->lp_advertising);433 }434}435EXPORT_SYMBOL_GPL(phy_resolve_aneg_pause);436 437/**438 * phy_resolve_aneg_linkmode - resolve the advertisements into PHY settings439 * @phydev: The phy_device struct440 *441 * Resolve our and the link partner advertisements into their corresponding442 * speed and duplex. If full duplex was negotiated, extract the pause mode443 * from the link partner mask.444 */445void phy_resolve_aneg_linkmode(struct phy_device *phydev)446{447 __ETHTOOL_DECLARE_LINK_MODE_MASK(common);448 int i;449 450 linkmode_and(common, phydev->lp_advertising, phydev->advertising);451 452 for (i = 0; i < ARRAY_SIZE(settings); i++)453 if (test_bit(settings[i].bit, common)) {454 phydev->speed = settings[i].speed;455 phydev->duplex = settings[i].duplex;456 break;457 }458 459 phy_resolve_aneg_pause(phydev);460}461EXPORT_SYMBOL_GPL(phy_resolve_aneg_linkmode);462 463/**464 * phy_check_downshift - check whether downshift occurred465 * @phydev: The phy_device struct466 *467 * Check whether a downshift to a lower speed occurred. If this should be the468 * case warn the user.469 * Prerequisite for detecting downshift is that PHY driver implements the470 * read_status callback and sets phydev->speed to the actual link speed.471 */472void phy_check_downshift(struct phy_device *phydev)473{474 __ETHTOOL_DECLARE_LINK_MODE_MASK(common);475 int i, speed = SPEED_UNKNOWN;476 477 phydev->downshifted_rate = 0;478 479 if (phydev->autoneg == AUTONEG_DISABLE ||480 phydev->speed == SPEED_UNKNOWN)481 return;482 483 linkmode_and(common, phydev->lp_advertising, phydev->advertising);484 485 for (i = 0; i < ARRAY_SIZE(settings); i++)486 if (test_bit(settings[i].bit, common)) {487 speed = settings[i].speed;488 break;489 }490 491 if (speed == SPEED_UNKNOWN || phydev->speed >= speed)492 return;493 494 phydev_warn(phydev, "Downshift occurred from negotiated speed %s to actual speed %s, check cabling!\n",495 phy_speed_to_str(speed), phy_speed_to_str(phydev->speed));496 497 phydev->downshifted_rate = 1;498}499EXPORT_SYMBOL_GPL(phy_check_downshift);500 501static int phy_resolve_min_speed(struct phy_device *phydev, bool fdx_only)502{503 __ETHTOOL_DECLARE_LINK_MODE_MASK(common);504 int i = ARRAY_SIZE(settings);505 506 linkmode_and(common, phydev->lp_advertising, phydev->advertising);507 508 while (--i >= 0) {509 if (test_bit(settings[i].bit, common)) {510 if (fdx_only && settings[i].duplex != DUPLEX_FULL)511 continue;512 return settings[i].speed;513 }514 }515 516 return SPEED_UNKNOWN;517}518 519int phy_speed_down_core(struct phy_device *phydev)520{521 int min_common_speed = phy_resolve_min_speed(phydev, true);522 523 if (min_common_speed == SPEED_UNKNOWN)524 return -EINVAL;525 526 __set_linkmode_max_speed(min_common_speed, phydev->advertising);527 528 return 0;529}530 531static void mmd_phy_indirect(struct mii_bus *bus, int phy_addr, int devad,532 u16 regnum)533{534 /* Write the desired MMD Devad */535 __mdiobus_write(bus, phy_addr, MII_MMD_CTRL, devad);536 537 /* Write the desired MMD register address */538 __mdiobus_write(bus, phy_addr, MII_MMD_DATA, regnum);539 540 /* Select the Function : DATA with no post increment */541 __mdiobus_write(bus, phy_addr, MII_MMD_CTRL,542 devad | MII_MMD_CTRL_NOINCR);543}544 545static int mmd_phy_read(struct mii_bus *bus, int phy_addr, bool is_c45,546 int devad, u32 regnum)547{548 if (is_c45)549 return __mdiobus_c45_read(bus, phy_addr, devad, regnum);550 551 mmd_phy_indirect(bus, phy_addr, devad, regnum);552 /* Read the content of the MMD's selected register */553 return __mdiobus_read(bus, phy_addr, MII_MMD_DATA);554}555 556static int mmd_phy_write(struct mii_bus *bus, int phy_addr, bool is_c45,557 int devad, u32 regnum, u16 val)558{559 if (is_c45)560 return __mdiobus_c45_write(bus, phy_addr, devad, regnum, val);561 562 mmd_phy_indirect(bus, phy_addr, devad, regnum);563 /* Write the data into MMD's selected register */564 return __mdiobus_write(bus, phy_addr, MII_MMD_DATA, val);565}566 567/**568 * __phy_read_mmd - Convenience function for reading a register569 * from an MMD on a given PHY.570 * @phydev: The phy_device struct571 * @devad: The MMD to read from (0..31)572 * @regnum: The register on the MMD to read (0..65535)573 *574 * Same rules as for __phy_read();575 */576int __phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum)577{578 if (regnum > (u16)~0 || devad > 32)579 return -EINVAL;580 581 if (phydev->drv && phydev->drv->read_mmd)582 return phydev->drv->read_mmd(phydev, devad, regnum);583 584 return mmd_phy_read(phydev->mdio.bus, phydev->mdio.addr,585 phydev->is_c45, devad, regnum);586}587EXPORT_SYMBOL(__phy_read_mmd);588 589/**590 * phy_read_mmd - Convenience function for reading a register591 * from an MMD on a given PHY.592 * @phydev: The phy_device struct593 * @devad: The MMD to read from594 * @regnum: The register on the MMD to read595 *596 * Same rules as for phy_read();597 */598int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum)599{600 int ret;601 602 phy_lock_mdio_bus(phydev);603 ret = __phy_read_mmd(phydev, devad, regnum);604 phy_unlock_mdio_bus(phydev);605 606 return ret;607}608EXPORT_SYMBOL(phy_read_mmd);609 610/**611 * __phy_write_mmd - Convenience function for writing a register612 * on an MMD on a given PHY.613 * @phydev: The phy_device struct614 * @devad: The MMD to read from615 * @regnum: The register on the MMD to read616 * @val: value to write to @regnum617 *618 * Same rules as for __phy_write();619 */620int __phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val)621{622 if (regnum > (u16)~0 || devad > 32)623 return -EINVAL;624 625 if (phydev->drv && phydev->drv->write_mmd)626 return phydev->drv->write_mmd(phydev, devad, regnum, val);627 628 return mmd_phy_write(phydev->mdio.bus, phydev->mdio.addr,629 phydev->is_c45, devad, regnum, val);630}631EXPORT_SYMBOL(__phy_write_mmd);632 633/**634 * phy_write_mmd - Convenience function for writing a register635 * on an MMD on a given PHY.636 * @phydev: The phy_device struct637 * @devad: The MMD to read from638 * @regnum: The register on the MMD to read639 * @val: value to write to @regnum640 *641 * Same rules as for phy_write();642 */643int phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val)644{645 int ret;646 647 phy_lock_mdio_bus(phydev);648 ret = __phy_write_mmd(phydev, devad, regnum, val);649 phy_unlock_mdio_bus(phydev);650 651 return ret;652}653EXPORT_SYMBOL(phy_write_mmd);654 655/**656 * __phy_package_read_mmd - read MMD reg relative to PHY package base addr657 * @phydev: The phy_device struct658 * @addr_offset: The offset to be added to PHY package base_addr659 * @devad: The MMD to read from660 * @regnum: The register on the MMD to read661 *662 * Convenience helper for reading a register of an MMD on a given PHY663 * using the PHY package base address. The base address is added to664 * the addr_offset value.665 *666 * Same calling rules as for __phy_read();667 *668 * NOTE: It's assumed that the entire PHY package is either C22 or C45.669 */670int __phy_package_read_mmd(struct phy_device *phydev,671 unsigned int addr_offset, int devad,672 u32 regnum)673{674 int addr = phy_package_address(phydev, addr_offset);675 676 if (addr < 0)677 return addr;678 679 if (regnum > (u16)~0 || devad > 32)680 return -EINVAL;681 682 return mmd_phy_read(phydev->mdio.bus, addr, phydev->is_c45, devad,683 regnum);684}685EXPORT_SYMBOL(__phy_package_read_mmd);686 687/**688 * phy_package_read_mmd - read MMD reg relative to PHY package base addr689 * @phydev: The phy_device struct690 * @addr_offset: The offset to be added to PHY package base_addr691 * @devad: The MMD to read from692 * @regnum: The register on the MMD to read693 *694 * Convenience helper for reading a register of an MMD on a given PHY695 * using the PHY package base address. The base address is added to696 * the addr_offset value.697 *698 * Same calling rules as for phy_read();699 *700 * NOTE: It's assumed that the entire PHY package is either C22 or C45.701 */702int phy_package_read_mmd(struct phy_device *phydev,703 unsigned int addr_offset, int devad,704 u32 regnum)705{706 int addr = phy_package_address(phydev, addr_offset);707 int val;708 709 if (addr < 0)710 return addr;711 712 if (regnum > (u16)~0 || devad > 32)713 return -EINVAL;714 715 phy_lock_mdio_bus(phydev);716 val = mmd_phy_read(phydev->mdio.bus, addr, phydev->is_c45, devad,717 regnum);718 phy_unlock_mdio_bus(phydev);719 720 return val;721}722EXPORT_SYMBOL(phy_package_read_mmd);723 724/**725 * __phy_package_write_mmd - write MMD reg relative to PHY package base addr726 * @phydev: The phy_device struct727 * @addr_offset: The offset to be added to PHY package base_addr728 * @devad: The MMD to write to729 * @regnum: The register on the MMD to write730 * @val: value to write to @regnum731 *732 * Convenience helper for writing a register of an MMD on a given PHY733 * using the PHY package base address. The base address is added to734 * the addr_offset value.735 *736 * Same calling rules as for __phy_write();737 *738 * NOTE: It's assumed that the entire PHY package is either C22 or C45.739 */740int __phy_package_write_mmd(struct phy_device *phydev,741 unsigned int addr_offset, int devad,742 u32 regnum, u16 val)743{744 int addr = phy_package_address(phydev, addr_offset);745 746 if (addr < 0)747 return addr;748 749 if (regnum > (u16)~0 || devad > 32)750 return -EINVAL;751 752 return mmd_phy_write(phydev->mdio.bus, addr, phydev->is_c45, devad,753 regnum, val);754}755EXPORT_SYMBOL(__phy_package_write_mmd);756 757/**758 * phy_package_write_mmd - write MMD reg relative to PHY package base addr759 * @phydev: The phy_device struct760 * @addr_offset: The offset to be added to PHY package base_addr761 * @devad: The MMD to write to762 * @regnum: The register on the MMD to write763 * @val: value to write to @regnum764 *765 * Convenience helper for writing a register of an MMD on a given PHY766 * using the PHY package base address. The base address is added to767 * the addr_offset value.768 *769 * Same calling rules as for phy_write();770 *771 * NOTE: It's assumed that the entire PHY package is either C22 or C45.772 */773int phy_package_write_mmd(struct phy_device *phydev,774 unsigned int addr_offset, int devad,775 u32 regnum, u16 val)776{777 int addr = phy_package_address(phydev, addr_offset);778 int ret;779 780 if (addr < 0)781 return addr;782 783 if (regnum > (u16)~0 || devad > 32)784 return -EINVAL;785 786 phy_lock_mdio_bus(phydev);787 ret = mmd_phy_write(phydev->mdio.bus, addr, phydev->is_c45, devad,788 regnum, val);789 phy_unlock_mdio_bus(phydev);790 791 return ret;792}793EXPORT_SYMBOL(phy_package_write_mmd);794 795/**796 * phy_modify_changed - Function for modifying a PHY register797 * @phydev: the phy_device struct798 * @regnum: register number to modify799 * @mask: bit mask of bits to clear800 * @set: new value of bits set in mask to write to @regnum801 *802 * NOTE: MUST NOT be called from interrupt context,803 * because the bus read/write functions may wait for an interrupt804 * to conclude the operation.805 *806 * Returns negative errno, 0 if there was no change, and 1 in case of change807 */808int phy_modify_changed(struct phy_device *phydev, u32 regnum, u16 mask, u16 set)809{810 int ret;811 812 phy_lock_mdio_bus(phydev);813 ret = __phy_modify_changed(phydev, regnum, mask, set);814 phy_unlock_mdio_bus(phydev);815 816 return ret;817}818EXPORT_SYMBOL_GPL(phy_modify_changed);819 820/**821 * __phy_modify - Convenience function for modifying a PHY register822 * @phydev: the phy_device struct823 * @regnum: register number to modify824 * @mask: bit mask of bits to clear825 * @set: new value of bits set in mask to write to @regnum826 *827 * NOTE: MUST NOT be called from interrupt context,828 * because the bus read/write functions may wait for an interrupt829 * to conclude the operation.830 */831int __phy_modify(struct phy_device *phydev, u32 regnum, u16 mask, u16 set)832{833 int ret;834 835 ret = __phy_modify_changed(phydev, regnum, mask, set);836 837 return ret < 0 ? ret : 0;838}839EXPORT_SYMBOL_GPL(__phy_modify);840 841/**842 * phy_modify - Convenience function for modifying a given PHY register843 * @phydev: the phy_device struct844 * @regnum: register number to write845 * @mask: bit mask of bits to clear846 * @set: new value of bits set in mask to write to @regnum847 *848 * NOTE: MUST NOT be called from interrupt context,849 * because the bus read/write functions may wait for an interrupt850 * to conclude the operation.851 */852int phy_modify(struct phy_device *phydev, u32 regnum, u16 mask, u16 set)853{854 int ret;855 856 phy_lock_mdio_bus(phydev);857 ret = __phy_modify(phydev, regnum, mask, set);858 phy_unlock_mdio_bus(phydev);859 860 return ret;861}862EXPORT_SYMBOL_GPL(phy_modify);863 864/**865 * __phy_modify_mmd_changed - Function for modifying a register on MMD866 * @phydev: the phy_device struct867 * @devad: the MMD containing register to modify868 * @regnum: register number to modify869 * @mask: bit mask of bits to clear870 * @set: new value of bits set in mask to write to @regnum871 *872 * Unlocked helper function which allows a MMD register to be modified as873 * new register value = (old register value & ~mask) | set874 *875 * Returns negative errno, 0 if there was no change, and 1 in case of change876 */877int __phy_modify_mmd_changed(struct phy_device *phydev, int devad, u32 regnum,878 u16 mask, u16 set)879{880 int new, ret;881 882 ret = __phy_read_mmd(phydev, devad, regnum);883 if (ret < 0)884 return ret;885 886 new = (ret & ~mask) | set;887 if (new == ret)888 return 0;889 890 ret = __phy_write_mmd(phydev, devad, regnum, new);891 892 return ret < 0 ? ret : 1;893}894EXPORT_SYMBOL_GPL(__phy_modify_mmd_changed);895 896/**897 * phy_modify_mmd_changed - Function for modifying a register on MMD898 * @phydev: the phy_device struct899 * @devad: the MMD containing register to modify900 * @regnum: register number to modify901 * @mask: bit mask of bits to clear902 * @set: new value of bits set in mask to write to @regnum903 *904 * NOTE: MUST NOT be called from interrupt context,905 * because the bus read/write functions may wait for an interrupt906 * to conclude the operation.907 *908 * Returns negative errno, 0 if there was no change, and 1 in case of change909 */910int phy_modify_mmd_changed(struct phy_device *phydev, int devad, u32 regnum,911 u16 mask, u16 set)912{913 int ret;914 915 phy_lock_mdio_bus(phydev);916 ret = __phy_modify_mmd_changed(phydev, devad, regnum, mask, set);917 phy_unlock_mdio_bus(phydev);918 919 return ret;920}921EXPORT_SYMBOL_GPL(phy_modify_mmd_changed);922 923/**924 * __phy_modify_mmd - Convenience function for modifying a register on MMD925 * @phydev: the phy_device struct926 * @devad: the MMD containing register to modify927 * @regnum: register number to modify928 * @mask: bit mask of bits to clear929 * @set: new value of bits set in mask to write to @regnum930 *931 * NOTE: MUST NOT be called from interrupt context,932 * because the bus read/write functions may wait for an interrupt933 * to conclude the operation.934 */935int __phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum,936 u16 mask, u16 set)937{938 int ret;939 940 ret = __phy_modify_mmd_changed(phydev, devad, regnum, mask, set);941 942 return ret < 0 ? ret : 0;943}944EXPORT_SYMBOL_GPL(__phy_modify_mmd);945 946/**947 * phy_modify_mmd - Convenience function for modifying a register on MMD948 * @phydev: the phy_device struct949 * @devad: the MMD containing register to modify950 * @regnum: register number to modify951 * @mask: bit mask of bits to clear952 * @set: new value of bits set in mask to write to @regnum953 *954 * NOTE: MUST NOT be called from interrupt context,955 * because the bus read/write functions may wait for an interrupt956 * to conclude the operation.957 */958int phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum,959 u16 mask, u16 set)960{961 int ret;962 963 phy_lock_mdio_bus(phydev);964 ret = __phy_modify_mmd(phydev, devad, regnum, mask, set);965 phy_unlock_mdio_bus(phydev);966 967 return ret;968}969EXPORT_SYMBOL_GPL(phy_modify_mmd);970 971static int __phy_read_page(struct phy_device *phydev)972{973 if (WARN_ONCE(!phydev->drv->read_page, "read_page callback not available, PHY driver not loaded?\n"))974 return -EOPNOTSUPP;975 976 return phydev->drv->read_page(phydev);977}978 979static int __phy_write_page(struct phy_device *phydev, int page)980{981 if (WARN_ONCE(!phydev->drv->write_page, "write_page callback not available, PHY driver not loaded?\n"))982 return -EOPNOTSUPP;983 984 return phydev->drv->write_page(phydev, page);985}986 987/**988 * phy_save_page() - take the bus lock and save the current page989 * @phydev: a pointer to a &struct phy_device990 *991 * Take the MDIO bus lock, and return the current page number. On error,992 * returns a negative errno. phy_restore_page() must always be called993 * after this, irrespective of success or failure of this call.994 */995int phy_save_page(struct phy_device *phydev)996{997 phy_lock_mdio_bus(phydev);998 return __phy_read_page(phydev);999}1000EXPORT_SYMBOL_GPL(phy_save_page);1001 1002/**1003 * phy_select_page() - take the bus lock, save the current page, and set a page1004 * @phydev: a pointer to a &struct phy_device1005 * @page: desired page1006 *1007 * Take the MDIO bus lock to protect against concurrent access, save the1008 * current PHY page, and set the current page. On error, returns a1009 * negative errno, otherwise returns the previous page number.1010 * phy_restore_page() must always be called after this, irrespective1011 * of success or failure of this call.1012 */1013int phy_select_page(struct phy_device *phydev, int page)1014{1015 int ret, oldpage;1016 1017 oldpage = ret = phy_save_page(phydev);1018 if (ret < 0)1019 return ret;1020 1021 if (oldpage != page) {1022 ret = __phy_write_page(phydev, page);1023 if (ret < 0)1024 return ret;1025 }1026 1027 return oldpage;1028}1029EXPORT_SYMBOL_GPL(phy_select_page);1030 1031/**1032 * phy_restore_page() - restore the page register and release the bus lock1033 * @phydev: a pointer to a &struct phy_device1034 * @oldpage: the old page, return value from phy_save_page() or phy_select_page()1035 * @ret: operation's return code1036 *1037 * Release the MDIO bus lock, restoring @oldpage if it is a valid page.1038 * This function propagates the earliest error code from the group of1039 * operations.1040 *1041 * Returns:1042 * @oldpage if it was a negative value, otherwise1043 * @ret if it was a negative errno value, otherwise1044 * phy_write_page()'s negative value if it were in error, otherwise1045 * @ret.1046 */1047int phy_restore_page(struct phy_device *phydev, int oldpage, int ret)1048{1049 int r;1050 1051 if (oldpage >= 0) {1052 r = __phy_write_page(phydev, oldpage);1053 1054 /* Propagate the operation return code if the page write1055 * was successful.1056 */1057 if (ret >= 0 && r < 0)1058 ret = r;1059 } else {1060 /* Propagate the phy page selection error code */1061 ret = oldpage;1062 }1063 1064 phy_unlock_mdio_bus(phydev);1065 1066 return ret;1067}1068EXPORT_SYMBOL_GPL(phy_restore_page);1069 1070/**1071 * phy_read_paged() - Convenience function for reading a paged register1072 * @phydev: a pointer to a &struct phy_device1073 * @page: the page for the phy1074 * @regnum: register number1075 *1076 * Same rules as for phy_read().1077 */1078int phy_read_paged(struct phy_device *phydev, int page, u32 regnum)1079{1080 int ret = 0, oldpage;1081 1082 oldpage = phy_select_page(phydev, page);1083 if (oldpage >= 0)1084 ret = __phy_read(phydev, regnum);1085 1086 return phy_restore_page(phydev, oldpage, ret);1087}1088EXPORT_SYMBOL(phy_read_paged);1089 1090/**1091 * phy_write_paged() - Convenience function for writing a paged register1092 * @phydev: a pointer to a &struct phy_device1093 * @page: the page for the phy1094 * @regnum: register number1095 * @val: value to write1096 *1097 * Same rules as for phy_write().1098 */1099int phy_write_paged(struct phy_device *phydev, int page, u32 regnum, u16 val)1100{1101 int ret = 0, oldpage;1102 1103 oldpage = phy_select_page(phydev, page);1104 if (oldpage >= 0)1105 ret = __phy_write(phydev, regnum, val);1106 1107 return phy_restore_page(phydev, oldpage, ret);1108}1109EXPORT_SYMBOL(phy_write_paged);1110 1111/**1112 * phy_modify_paged_changed() - Function for modifying a paged register1113 * @phydev: a pointer to a &struct phy_device1114 * @page: the page for the phy1115 * @regnum: register number1116 * @mask: bit mask of bits to clear1117 * @set: bit mask of bits to set1118 *1119 * Returns negative errno, 0 if there was no change, and 1 in case of change1120 */1121int phy_modify_paged_changed(struct phy_device *phydev, int page, u32 regnum,1122 u16 mask, u16 set)1123{1124 int ret = 0, oldpage;1125 1126 oldpage = phy_select_page(phydev, page);1127 if (oldpage >= 0)1128 ret = __phy_modify_changed(phydev, regnum, mask, set);1129 1130 return phy_restore_page(phydev, oldpage, ret);1131}1132EXPORT_SYMBOL(phy_modify_paged_changed);1133 1134/**1135 * phy_modify_paged() - Convenience function for modifying a paged register1136 * @phydev: a pointer to a &struct phy_device1137 * @page: the page for the phy1138 * @regnum: register number1139 * @mask: bit mask of bits to clear1140 * @set: bit mask of bits to set1141 *1142 * Same rules as for phy_read() and phy_write().1143 */1144int phy_modify_paged(struct phy_device *phydev, int page, u32 regnum,1145 u16 mask, u16 set)1146{1147 int ret = phy_modify_paged_changed(phydev, page, regnum, mask, set);1148 1149 return ret < 0 ? ret : 0;1150}1151EXPORT_SYMBOL(phy_modify_paged);1152