Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * Core PHY library, taken from phy.c
0004  */
0005 #include <linux/export.h>
0006 #include <linux/phy.h>
0007 #include <linux/of.h>
0008 
0009 /**
0010  * phy_speed_to_str - Return a string representing the PHY link speed
0011  *
0012  * @speed: Speed of the link
0013  */
0014 const char *phy_speed_to_str(int speed)
0015 {
0016     BUILD_BUG_ON_MSG(__ETHTOOL_LINK_MODE_MASK_NBITS != 93,
0017         "Enum ethtool_link_mode_bit_indices and phylib are out of sync. "
0018         "If a speed or mode has been added please update phy_speed_to_str "
0019         "and the PHY settings array.\n");
0020 
0021     switch (speed) {
0022     case SPEED_10:
0023         return "10Mbps";
0024     case SPEED_100:
0025         return "100Mbps";
0026     case SPEED_1000:
0027         return "1Gbps";
0028     case SPEED_2500:
0029         return "2.5Gbps";
0030     case SPEED_5000:
0031         return "5Gbps";
0032     case SPEED_10000:
0033         return "10Gbps";
0034     case SPEED_14000:
0035         return "14Gbps";
0036     case SPEED_20000:
0037         return "20Gbps";
0038     case SPEED_25000:
0039         return "25Gbps";
0040     case SPEED_40000:
0041         return "40Gbps";
0042     case SPEED_50000:
0043         return "50Gbps";
0044     case SPEED_56000:
0045         return "56Gbps";
0046     case SPEED_100000:
0047         return "100Gbps";
0048     case SPEED_200000:
0049         return "200Gbps";
0050     case SPEED_400000:
0051         return "400Gbps";
0052     case SPEED_UNKNOWN:
0053         return "Unknown";
0054     default:
0055         return "Unsupported (update phy-core.c)";
0056     }
0057 }
0058 EXPORT_SYMBOL_GPL(phy_speed_to_str);
0059 
0060 /**
0061  * phy_duplex_to_str - Return string describing the duplex
0062  *
0063  * @duplex: Duplex setting to describe
0064  */
0065 const char *phy_duplex_to_str(unsigned int duplex)
0066 {
0067     if (duplex == DUPLEX_HALF)
0068         return "Half";
0069     if (duplex == DUPLEX_FULL)
0070         return "Full";
0071     if (duplex == DUPLEX_UNKNOWN)
0072         return "Unknown";
0073     return "Unsupported (update phy-core.c)";
0074 }
0075 EXPORT_SYMBOL_GPL(phy_duplex_to_str);
0076 
0077 /* A mapping of all SUPPORTED settings to speed/duplex.  This table
0078  * must be grouped by speed and sorted in descending match priority
0079  * - iow, descending speed.
0080  */
0081 
0082 #define PHY_SETTING(s, d, b) { .speed = SPEED_ ## s, .duplex = DUPLEX_ ## d, \
0083                    .bit = ETHTOOL_LINK_MODE_ ## b ## _BIT}
0084 
0085 static const struct phy_setting settings[] = {
0086     /* 400G */
0087     PHY_SETTING( 400000, FULL, 400000baseCR8_Full       ),
0088     PHY_SETTING( 400000, FULL, 400000baseKR8_Full       ),
0089     PHY_SETTING( 400000, FULL, 400000baseLR8_ER8_FR8_Full   ),
0090     PHY_SETTING( 400000, FULL, 400000baseDR8_Full       ),
0091     PHY_SETTING( 400000, FULL, 400000baseSR8_Full       ),
0092     PHY_SETTING( 400000, FULL, 400000baseCR4_Full       ),
0093     PHY_SETTING( 400000, FULL, 400000baseKR4_Full       ),
0094     PHY_SETTING( 400000, FULL, 400000baseLR4_ER4_FR4_Full   ),
0095     PHY_SETTING( 400000, FULL, 400000baseDR4_Full       ),
0096     PHY_SETTING( 400000, FULL, 400000baseSR4_Full       ),
0097     /* 200G */
0098     PHY_SETTING( 200000, FULL, 200000baseCR4_Full       ),
0099     PHY_SETTING( 200000, FULL, 200000baseKR4_Full       ),
0100     PHY_SETTING( 200000, FULL, 200000baseLR4_ER4_FR4_Full   ),
0101     PHY_SETTING( 200000, FULL, 200000baseDR4_Full       ),
0102     PHY_SETTING( 200000, FULL, 200000baseSR4_Full       ),
0103     PHY_SETTING( 200000, FULL, 200000baseCR2_Full       ),
0104     PHY_SETTING( 200000, FULL, 200000baseKR2_Full       ),
0105     PHY_SETTING( 200000, FULL, 200000baseLR2_ER2_FR2_Full   ),
0106     PHY_SETTING( 200000, FULL, 200000baseDR2_Full       ),
0107     PHY_SETTING( 200000, FULL, 200000baseSR2_Full       ),
0108     /* 100G */
0109     PHY_SETTING( 100000, FULL, 100000baseCR4_Full       ),
0110     PHY_SETTING( 100000, FULL, 100000baseKR4_Full       ),
0111     PHY_SETTING( 100000, FULL, 100000baseLR4_ER4_Full   ),
0112     PHY_SETTING( 100000, FULL, 100000baseSR4_Full       ),
0113     PHY_SETTING( 100000, FULL, 100000baseCR2_Full       ),
0114     PHY_SETTING( 100000, FULL, 100000baseKR2_Full       ),
0115     PHY_SETTING( 100000, FULL, 100000baseLR2_ER2_FR2_Full   ),
0116     PHY_SETTING( 100000, FULL, 100000baseDR2_Full       ),
0117     PHY_SETTING( 100000, FULL, 100000baseSR2_Full       ),
0118     PHY_SETTING( 100000, FULL, 100000baseCR_Full        ),
0119     PHY_SETTING( 100000, FULL, 100000baseKR_Full        ),
0120     PHY_SETTING( 100000, FULL, 100000baseLR_ER_FR_Full  ),
0121     PHY_SETTING( 100000, FULL, 100000baseDR_Full        ),
0122     PHY_SETTING( 100000, FULL, 100000baseSR_Full        ),
0123     /* 56G */
0124     PHY_SETTING(  56000, FULL,  56000baseCR4_Full       ),
0125     PHY_SETTING(  56000, FULL,  56000baseKR4_Full       ),
0126     PHY_SETTING(  56000, FULL,  56000baseLR4_Full       ),
0127     PHY_SETTING(  56000, FULL,  56000baseSR4_Full       ),
0128     /* 50G */
0129     PHY_SETTING(  50000, FULL,  50000baseCR2_Full       ),
0130     PHY_SETTING(  50000, FULL,  50000baseKR2_Full       ),
0131     PHY_SETTING(  50000, FULL,  50000baseSR2_Full       ),
0132     PHY_SETTING(  50000, FULL,  50000baseCR_Full        ),
0133     PHY_SETTING(  50000, FULL,  50000baseKR_Full        ),
0134     PHY_SETTING(  50000, FULL,  50000baseLR_ER_FR_Full  ),
0135     PHY_SETTING(  50000, FULL,  50000baseDR_Full        ),
0136     PHY_SETTING(  50000, FULL,  50000baseSR_Full        ),
0137     /* 40G */
0138     PHY_SETTING(  40000, FULL,  40000baseCR4_Full       ),
0139     PHY_SETTING(  40000, FULL,  40000baseKR4_Full       ),
0140     PHY_SETTING(  40000, FULL,  40000baseLR4_Full       ),
0141     PHY_SETTING(  40000, FULL,  40000baseSR4_Full       ),
0142     /* 25G */
0143     PHY_SETTING(  25000, FULL,  25000baseCR_Full        ),
0144     PHY_SETTING(  25000, FULL,  25000baseKR_Full        ),
0145     PHY_SETTING(  25000, FULL,  25000baseSR_Full        ),
0146     /* 20G */
0147     PHY_SETTING(  20000, FULL,  20000baseKR2_Full       ),
0148     PHY_SETTING(  20000, FULL,  20000baseMLD2_Full      ),
0149     /* 10G */
0150     PHY_SETTING(  10000, FULL,  10000baseCR_Full        ),
0151     PHY_SETTING(  10000, FULL,  10000baseER_Full        ),
0152     PHY_SETTING(  10000, FULL,  10000baseKR_Full        ),
0153     PHY_SETTING(  10000, FULL,  10000baseKX4_Full       ),
0154     PHY_SETTING(  10000, FULL,  10000baseLR_Full        ),
0155     PHY_SETTING(  10000, FULL,  10000baseLRM_Full       ),
0156     PHY_SETTING(  10000, FULL,  10000baseR_FEC      ),
0157     PHY_SETTING(  10000, FULL,  10000baseSR_Full        ),
0158     PHY_SETTING(  10000, FULL,  10000baseT_Full     ),
0159     /* 5G */
0160     PHY_SETTING(   5000, FULL,   5000baseT_Full     ),
0161     /* 2.5G */
0162     PHY_SETTING(   2500, FULL,   2500baseT_Full     ),
0163     PHY_SETTING(   2500, FULL,   2500baseX_Full     ),
0164     /* 1G */
0165     PHY_SETTING(   1000, FULL,   1000baseT_Full     ),
0166     PHY_SETTING(   1000, HALF,   1000baseT_Half     ),
0167     PHY_SETTING(   1000, FULL,   1000baseT1_Full        ),
0168     PHY_SETTING(   1000, FULL,   1000baseX_Full     ),
0169     PHY_SETTING(   1000, FULL,   1000baseKX_Full        ),
0170     /* 100M */
0171     PHY_SETTING(    100, FULL,    100baseT_Full     ),
0172     PHY_SETTING(    100, FULL,    100baseT1_Full        ),
0173     PHY_SETTING(    100, HALF,    100baseT_Half     ),
0174     PHY_SETTING(    100, HALF,    100baseFX_Half        ),
0175     PHY_SETTING(    100, FULL,    100baseFX_Full        ),
0176     /* 10M */
0177     PHY_SETTING(     10, FULL,     10baseT_Full     ),
0178     PHY_SETTING(     10, HALF,     10baseT_Half     ),
0179     PHY_SETTING(     10, FULL,     10baseT1L_Full       ),
0180 };
0181 #undef PHY_SETTING
0182 
0183 /**
0184  * phy_lookup_setting - lookup a PHY setting
0185  * @speed: speed to match
0186  * @duplex: duplex to match
0187  * @mask: allowed link modes
0188  * @exact: an exact match is required
0189  *
0190  * Search the settings array for a setting that matches the speed and
0191  * duplex, and which is supported.
0192  *
0193  * If @exact is unset, either an exact match or %NULL for no match will
0194  * be returned.
0195  *
0196  * If @exact is set, an exact match, the fastest supported setting at
0197  * or below the specified speed, the slowest supported setting, or if
0198  * they all fail, %NULL will be returned.
0199  */
0200 const struct phy_setting *
0201 phy_lookup_setting(int speed, int duplex, const unsigned long *mask, bool exact)
0202 {
0203     const struct phy_setting *p, *match = NULL, *last = NULL;
0204     int i;
0205 
0206     for (i = 0, p = settings; i < ARRAY_SIZE(settings); i++, p++) {
0207         if (p->bit < __ETHTOOL_LINK_MODE_MASK_NBITS &&
0208             test_bit(p->bit, mask)) {
0209             last = p;
0210             if (p->speed == speed && p->duplex == duplex) {
0211                 /* Exact match for speed and duplex */
0212                 match = p;
0213                 break;
0214             } else if (!exact) {
0215                 if (!match && p->speed <= speed)
0216                     /* Candidate */
0217                     match = p;
0218 
0219                 if (p->speed < speed)
0220                     break;
0221             }
0222         }
0223     }
0224 
0225     if (!match && !exact)
0226         match = last;
0227 
0228     return match;
0229 }
0230 EXPORT_SYMBOL_GPL(phy_lookup_setting);
0231 
0232 size_t phy_speeds(unsigned int *speeds, size_t size,
0233           unsigned long *mask)
0234 {
0235     size_t count;
0236     int i;
0237 
0238     for (i = 0, count = 0; i < ARRAY_SIZE(settings) && count < size; i++)
0239         if (settings[i].bit < __ETHTOOL_LINK_MODE_MASK_NBITS &&
0240             test_bit(settings[i].bit, mask) &&
0241             (count == 0 || speeds[count - 1] != settings[i].speed))
0242             speeds[count++] = settings[i].speed;
0243 
0244     return count;
0245 }
0246 
0247 static void __set_linkmode_max_speed(u32 max_speed, unsigned long *addr)
0248 {
0249     const struct phy_setting *p;
0250     int i;
0251 
0252     for (i = 0, p = settings; i < ARRAY_SIZE(settings); i++, p++) {
0253         if (p->speed > max_speed)
0254             linkmode_clear_bit(p->bit, addr);
0255         else
0256             break;
0257     }
0258 }
0259 
0260 static void __set_phy_supported(struct phy_device *phydev, u32 max_speed)
0261 {
0262     __set_linkmode_max_speed(max_speed, phydev->supported);
0263 }
0264 
0265 /**
0266  * phy_set_max_speed - Set the maximum speed the PHY should support
0267  *
0268  * @phydev: The phy_device struct
0269  * @max_speed: Maximum speed
0270  *
0271  * The PHY might be more capable than the MAC. For example a Fast Ethernet
0272  * is connected to a 1G PHY. This function allows the MAC to indicate its
0273  * maximum speed, and so limit what the PHY will advertise.
0274  */
0275 void phy_set_max_speed(struct phy_device *phydev, u32 max_speed)
0276 {
0277     __set_phy_supported(phydev, max_speed);
0278 
0279     phy_advertise_supported(phydev);
0280 }
0281 EXPORT_SYMBOL(phy_set_max_speed);
0282 
0283 void of_set_phy_supported(struct phy_device *phydev)
0284 {
0285     struct device_node *node = phydev->mdio.dev.of_node;
0286     u32 max_speed;
0287 
0288     if (!IS_ENABLED(CONFIG_OF_MDIO))
0289         return;
0290 
0291     if (!node)
0292         return;
0293 
0294     if (!of_property_read_u32(node, "max-speed", &max_speed))
0295         __set_phy_supported(phydev, max_speed);
0296 }
0297 
0298 void of_set_phy_eee_broken(struct phy_device *phydev)
0299 {
0300     struct device_node *node = phydev->mdio.dev.of_node;
0301     u32 broken = 0;
0302 
0303     if (!IS_ENABLED(CONFIG_OF_MDIO))
0304         return;
0305 
0306     if (!node)
0307         return;
0308 
0309     if (of_property_read_bool(node, "eee-broken-100tx"))
0310         broken |= MDIO_EEE_100TX;
0311     if (of_property_read_bool(node, "eee-broken-1000t"))
0312         broken |= MDIO_EEE_1000T;
0313     if (of_property_read_bool(node, "eee-broken-10gt"))
0314         broken |= MDIO_EEE_10GT;
0315     if (of_property_read_bool(node, "eee-broken-1000kx"))
0316         broken |= MDIO_EEE_1000KX;
0317     if (of_property_read_bool(node, "eee-broken-10gkx4"))
0318         broken |= MDIO_EEE_10GKX4;
0319     if (of_property_read_bool(node, "eee-broken-10gkr"))
0320         broken |= MDIO_EEE_10GKR;
0321 
0322     phydev->eee_broken_modes = broken;
0323 }
0324 
0325 /**
0326  * phy_resolve_aneg_pause - Determine pause autoneg results
0327  *
0328  * @phydev: The phy_device struct
0329  *
0330  * Once autoneg has completed the local pause settings can be
0331  * resolved.  Determine if pause and asymmetric pause should be used
0332  * by the MAC.
0333  */
0334 
0335 void phy_resolve_aneg_pause(struct phy_device *phydev)
0336 {
0337     if (phydev->duplex == DUPLEX_FULL) {
0338         phydev->pause = linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT,
0339                           phydev->lp_advertising);
0340         phydev->asym_pause = linkmode_test_bit(
0341             ETHTOOL_LINK_MODE_Asym_Pause_BIT,
0342             phydev->lp_advertising);
0343     }
0344 }
0345 EXPORT_SYMBOL_GPL(phy_resolve_aneg_pause);
0346 
0347 /**
0348  * phy_resolve_aneg_linkmode - resolve the advertisements into PHY settings
0349  * @phydev: The phy_device struct
0350  *
0351  * Resolve our and the link partner advertisements into their corresponding
0352  * speed and duplex. If full duplex was negotiated, extract the pause mode
0353  * from the link partner mask.
0354  */
0355 void phy_resolve_aneg_linkmode(struct phy_device *phydev)
0356 {
0357     __ETHTOOL_DECLARE_LINK_MODE_MASK(common);
0358     int i;
0359 
0360     linkmode_and(common, phydev->lp_advertising, phydev->advertising);
0361 
0362     for (i = 0; i < ARRAY_SIZE(settings); i++)
0363         if (test_bit(settings[i].bit, common)) {
0364             phydev->speed = settings[i].speed;
0365             phydev->duplex = settings[i].duplex;
0366             break;
0367         }
0368 
0369     phy_resolve_aneg_pause(phydev);
0370 }
0371 EXPORT_SYMBOL_GPL(phy_resolve_aneg_linkmode);
0372 
0373 /**
0374  * phy_check_downshift - check whether downshift occurred
0375  * @phydev: The phy_device struct
0376  *
0377  * Check whether a downshift to a lower speed occurred. If this should be the
0378  * case warn the user.
0379  * Prerequisite for detecting downshift is that PHY driver implements the
0380  * read_status callback and sets phydev->speed to the actual link speed.
0381  */
0382 void phy_check_downshift(struct phy_device *phydev)
0383 {
0384     __ETHTOOL_DECLARE_LINK_MODE_MASK(common);
0385     int i, speed = SPEED_UNKNOWN;
0386 
0387     phydev->downshifted_rate = 0;
0388 
0389     if (phydev->autoneg == AUTONEG_DISABLE ||
0390         phydev->speed == SPEED_UNKNOWN)
0391         return;
0392 
0393     linkmode_and(common, phydev->lp_advertising, phydev->advertising);
0394 
0395     for (i = 0; i < ARRAY_SIZE(settings); i++)
0396         if (test_bit(settings[i].bit, common)) {
0397             speed = settings[i].speed;
0398             break;
0399         }
0400 
0401     if (speed == SPEED_UNKNOWN || phydev->speed >= speed)
0402         return;
0403 
0404     phydev_warn(phydev, "Downshift occurred from negotiated speed %s to actual speed %s, check cabling!\n",
0405             phy_speed_to_str(speed), phy_speed_to_str(phydev->speed));
0406 
0407     phydev->downshifted_rate = 1;
0408 }
0409 EXPORT_SYMBOL_GPL(phy_check_downshift);
0410 
0411 static int phy_resolve_min_speed(struct phy_device *phydev, bool fdx_only)
0412 {
0413     __ETHTOOL_DECLARE_LINK_MODE_MASK(common);
0414     int i = ARRAY_SIZE(settings);
0415 
0416     linkmode_and(common, phydev->lp_advertising, phydev->advertising);
0417 
0418     while (--i >= 0) {
0419         if (test_bit(settings[i].bit, common)) {
0420             if (fdx_only && settings[i].duplex != DUPLEX_FULL)
0421                 continue;
0422             return settings[i].speed;
0423         }
0424     }
0425 
0426     return SPEED_UNKNOWN;
0427 }
0428 
0429 int phy_speed_down_core(struct phy_device *phydev)
0430 {
0431     int min_common_speed = phy_resolve_min_speed(phydev, true);
0432 
0433     if (min_common_speed == SPEED_UNKNOWN)
0434         return -EINVAL;
0435 
0436     __set_linkmode_max_speed(min_common_speed, phydev->advertising);
0437 
0438     return 0;
0439 }
0440 
0441 static void mmd_phy_indirect(struct mii_bus *bus, int phy_addr, int devad,
0442                  u16 regnum)
0443 {
0444     /* Write the desired MMD Devad */
0445     __mdiobus_write(bus, phy_addr, MII_MMD_CTRL, devad);
0446 
0447     /* Write the desired MMD register address */
0448     __mdiobus_write(bus, phy_addr, MII_MMD_DATA, regnum);
0449 
0450     /* Select the Function : DATA with no post increment */
0451     __mdiobus_write(bus, phy_addr, MII_MMD_CTRL,
0452             devad | MII_MMD_CTRL_NOINCR);
0453 }
0454 
0455 /**
0456  * __phy_read_mmd - Convenience function for reading a register
0457  * from an MMD on a given PHY.
0458  * @phydev: The phy_device struct
0459  * @devad: The MMD to read from (0..31)
0460  * @regnum: The register on the MMD to read (0..65535)
0461  *
0462  * Same rules as for __phy_read();
0463  */
0464 int __phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum)
0465 {
0466     int val;
0467 
0468     if (regnum > (u16)~0 || devad > 32)
0469         return -EINVAL;
0470 
0471     if (phydev->drv && phydev->drv->read_mmd) {
0472         val = phydev->drv->read_mmd(phydev, devad, regnum);
0473     } else if (phydev->is_c45) {
0474         val = __mdiobus_c45_read(phydev->mdio.bus, phydev->mdio.addr,
0475                      devad, regnum);
0476     } else {
0477         struct mii_bus *bus = phydev->mdio.bus;
0478         int phy_addr = phydev->mdio.addr;
0479 
0480         mmd_phy_indirect(bus, phy_addr, devad, regnum);
0481 
0482         /* Read the content of the MMD's selected register */
0483         val = __mdiobus_read(bus, phy_addr, MII_MMD_DATA);
0484     }
0485     return val;
0486 }
0487 EXPORT_SYMBOL(__phy_read_mmd);
0488 
0489 /**
0490  * phy_read_mmd - Convenience function for reading a register
0491  * from an MMD on a given PHY.
0492  * @phydev: The phy_device struct
0493  * @devad: The MMD to read from
0494  * @regnum: The register on the MMD to read
0495  *
0496  * Same rules as for phy_read();
0497  */
0498 int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum)
0499 {
0500     int ret;
0501 
0502     phy_lock_mdio_bus(phydev);
0503     ret = __phy_read_mmd(phydev, devad, regnum);
0504     phy_unlock_mdio_bus(phydev);
0505 
0506     return ret;
0507 }
0508 EXPORT_SYMBOL(phy_read_mmd);
0509 
0510 /**
0511  * __phy_write_mmd - Convenience function for writing a register
0512  * on an MMD on a given PHY.
0513  * @phydev: The phy_device struct
0514  * @devad: The MMD to read from
0515  * @regnum: The register on the MMD to read
0516  * @val: value to write to @regnum
0517  *
0518  * Same rules as for __phy_write();
0519  */
0520 int __phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val)
0521 {
0522     int ret;
0523 
0524     if (regnum > (u16)~0 || devad > 32)
0525         return -EINVAL;
0526 
0527     if (phydev->drv && phydev->drv->write_mmd) {
0528         ret = phydev->drv->write_mmd(phydev, devad, regnum, val);
0529     } else if (phydev->is_c45) {
0530         ret = __mdiobus_c45_write(phydev->mdio.bus, phydev->mdio.addr,
0531                       devad, regnum, val);
0532     } else {
0533         struct mii_bus *bus = phydev->mdio.bus;
0534         int phy_addr = phydev->mdio.addr;
0535 
0536         mmd_phy_indirect(bus, phy_addr, devad, regnum);
0537 
0538         /* Write the data into MMD's selected register */
0539         __mdiobus_write(bus, phy_addr, MII_MMD_DATA, val);
0540 
0541         ret = 0;
0542     }
0543     return ret;
0544 }
0545 EXPORT_SYMBOL(__phy_write_mmd);
0546 
0547 /**
0548  * phy_write_mmd - Convenience function for writing a register
0549  * on an MMD on a given PHY.
0550  * @phydev: The phy_device struct
0551  * @devad: The MMD to read from
0552  * @regnum: The register on the MMD to read
0553  * @val: value to write to @regnum
0554  *
0555  * Same rules as for phy_write();
0556  */
0557 int phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val)
0558 {
0559     int ret;
0560 
0561     phy_lock_mdio_bus(phydev);
0562     ret = __phy_write_mmd(phydev, devad, regnum, val);
0563     phy_unlock_mdio_bus(phydev);
0564 
0565     return ret;
0566 }
0567 EXPORT_SYMBOL(phy_write_mmd);
0568 
0569 /**
0570  * phy_modify_changed - Function for modifying a PHY register
0571  * @phydev: the phy_device struct
0572  * @regnum: register number to modify
0573  * @mask: bit mask of bits to clear
0574  * @set: new value of bits set in mask to write to @regnum
0575  *
0576  * NOTE: MUST NOT be called from interrupt context,
0577  * because the bus read/write functions may wait for an interrupt
0578  * to conclude the operation.
0579  *
0580  * Returns negative errno, 0 if there was no change, and 1 in case of change
0581  */
0582 int phy_modify_changed(struct phy_device *phydev, u32 regnum, u16 mask, u16 set)
0583 {
0584     int ret;
0585 
0586     phy_lock_mdio_bus(phydev);
0587     ret = __phy_modify_changed(phydev, regnum, mask, set);
0588     phy_unlock_mdio_bus(phydev);
0589 
0590     return ret;
0591 }
0592 EXPORT_SYMBOL_GPL(phy_modify_changed);
0593 
0594 /**
0595  * __phy_modify - Convenience function for modifying a PHY register
0596  * @phydev: the phy_device struct
0597  * @regnum: register number to modify
0598  * @mask: bit mask of bits to clear
0599  * @set: new value of bits set in mask to write to @regnum
0600  *
0601  * NOTE: MUST NOT be called from interrupt context,
0602  * because the bus read/write functions may wait for an interrupt
0603  * to conclude the operation.
0604  */
0605 int __phy_modify(struct phy_device *phydev, u32 regnum, u16 mask, u16 set)
0606 {
0607     int ret;
0608 
0609     ret = __phy_modify_changed(phydev, regnum, mask, set);
0610 
0611     return ret < 0 ? ret : 0;
0612 }
0613 EXPORT_SYMBOL_GPL(__phy_modify);
0614 
0615 /**
0616  * phy_modify - Convenience function for modifying a given PHY register
0617  * @phydev: the phy_device struct
0618  * @regnum: register number to write
0619  * @mask: bit mask of bits to clear
0620  * @set: new value of bits set in mask to write to @regnum
0621  *
0622  * NOTE: MUST NOT be called from interrupt context,
0623  * because the bus read/write functions may wait for an interrupt
0624  * to conclude the operation.
0625  */
0626 int phy_modify(struct phy_device *phydev, u32 regnum, u16 mask, u16 set)
0627 {
0628     int ret;
0629 
0630     phy_lock_mdio_bus(phydev);
0631     ret = __phy_modify(phydev, regnum, mask, set);
0632     phy_unlock_mdio_bus(phydev);
0633 
0634     return ret;
0635 }
0636 EXPORT_SYMBOL_GPL(phy_modify);
0637 
0638 /**
0639  * __phy_modify_mmd_changed - Function for modifying a register on MMD
0640  * @phydev: the phy_device struct
0641  * @devad: the MMD containing register to modify
0642  * @regnum: register number to modify
0643  * @mask: bit mask of bits to clear
0644  * @set: new value of bits set in mask to write to @regnum
0645  *
0646  * Unlocked helper function which allows a MMD register to be modified as
0647  * new register value = (old register value & ~mask) | set
0648  *
0649  * Returns negative errno, 0 if there was no change, and 1 in case of change
0650  */
0651 int __phy_modify_mmd_changed(struct phy_device *phydev, int devad, u32 regnum,
0652                  u16 mask, u16 set)
0653 {
0654     int new, ret;
0655 
0656     ret = __phy_read_mmd(phydev, devad, regnum);
0657     if (ret < 0)
0658         return ret;
0659 
0660     new = (ret & ~mask) | set;
0661     if (new == ret)
0662         return 0;
0663 
0664     ret = __phy_write_mmd(phydev, devad, regnum, new);
0665 
0666     return ret < 0 ? ret : 1;
0667 }
0668 EXPORT_SYMBOL_GPL(__phy_modify_mmd_changed);
0669 
0670 /**
0671  * phy_modify_mmd_changed - Function for modifying a register on MMD
0672  * @phydev: the phy_device struct
0673  * @devad: the MMD containing register to modify
0674  * @regnum: register number to modify
0675  * @mask: bit mask of bits to clear
0676  * @set: new value of bits set in mask to write to @regnum
0677  *
0678  * NOTE: MUST NOT be called from interrupt context,
0679  * because the bus read/write functions may wait for an interrupt
0680  * to conclude the operation.
0681  *
0682  * Returns negative errno, 0 if there was no change, and 1 in case of change
0683  */
0684 int phy_modify_mmd_changed(struct phy_device *phydev, int devad, u32 regnum,
0685                u16 mask, u16 set)
0686 {
0687     int ret;
0688 
0689     phy_lock_mdio_bus(phydev);
0690     ret = __phy_modify_mmd_changed(phydev, devad, regnum, mask, set);
0691     phy_unlock_mdio_bus(phydev);
0692 
0693     return ret;
0694 }
0695 EXPORT_SYMBOL_GPL(phy_modify_mmd_changed);
0696 
0697 /**
0698  * __phy_modify_mmd - Convenience function for modifying a register on MMD
0699  * @phydev: the phy_device struct
0700  * @devad: the MMD containing register to modify
0701  * @regnum: register number to modify
0702  * @mask: bit mask of bits to clear
0703  * @set: new value of bits set in mask to write to @regnum
0704  *
0705  * NOTE: MUST NOT be called from interrupt context,
0706  * because the bus read/write functions may wait for an interrupt
0707  * to conclude the operation.
0708  */
0709 int __phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum,
0710              u16 mask, u16 set)
0711 {
0712     int ret;
0713 
0714     ret = __phy_modify_mmd_changed(phydev, devad, regnum, mask, set);
0715 
0716     return ret < 0 ? ret : 0;
0717 }
0718 EXPORT_SYMBOL_GPL(__phy_modify_mmd);
0719 
0720 /**
0721  * phy_modify_mmd - Convenience function for modifying a register on MMD
0722  * @phydev: the phy_device struct
0723  * @devad: the MMD containing register to modify
0724  * @regnum: register number to modify
0725  * @mask: bit mask of bits to clear
0726  * @set: new value of bits set in mask to write to @regnum
0727  *
0728  * NOTE: MUST NOT be called from interrupt context,
0729  * because the bus read/write functions may wait for an interrupt
0730  * to conclude the operation.
0731  */
0732 int phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum,
0733            u16 mask, u16 set)
0734 {
0735     int ret;
0736 
0737     phy_lock_mdio_bus(phydev);
0738     ret = __phy_modify_mmd(phydev, devad, regnum, mask, set);
0739     phy_unlock_mdio_bus(phydev);
0740 
0741     return ret;
0742 }
0743 EXPORT_SYMBOL_GPL(phy_modify_mmd);
0744 
0745 static int __phy_read_page(struct phy_device *phydev)
0746 {
0747     if (WARN_ONCE(!phydev->drv->read_page, "read_page callback not available, PHY driver not loaded?\n"))
0748         return -EOPNOTSUPP;
0749 
0750     return phydev->drv->read_page(phydev);
0751 }
0752 
0753 static int __phy_write_page(struct phy_device *phydev, int page)
0754 {
0755     if (WARN_ONCE(!phydev->drv->write_page, "write_page callback not available, PHY driver not loaded?\n"))
0756         return -EOPNOTSUPP;
0757 
0758     return phydev->drv->write_page(phydev, page);
0759 }
0760 
0761 /**
0762  * phy_save_page() - take the bus lock and save the current page
0763  * @phydev: a pointer to a &struct phy_device
0764  *
0765  * Take the MDIO bus lock, and return the current page number. On error,
0766  * returns a negative errno. phy_restore_page() must always be called
0767  * after this, irrespective of success or failure of this call.
0768  */
0769 int phy_save_page(struct phy_device *phydev)
0770 {
0771     phy_lock_mdio_bus(phydev);
0772     return __phy_read_page(phydev);
0773 }
0774 EXPORT_SYMBOL_GPL(phy_save_page);
0775 
0776 /**
0777  * phy_select_page() - take the bus lock, save the current page, and set a page
0778  * @phydev: a pointer to a &struct phy_device
0779  * @page: desired page
0780  *
0781  * Take the MDIO bus lock to protect against concurrent access, save the
0782  * current PHY page, and set the current page.  On error, returns a
0783  * negative errno, otherwise returns the previous page number.
0784  * phy_restore_page() must always be called after this, irrespective
0785  * of success or failure of this call.
0786  */
0787 int phy_select_page(struct phy_device *phydev, int page)
0788 {
0789     int ret, oldpage;
0790 
0791     oldpage = ret = phy_save_page(phydev);
0792     if (ret < 0)
0793         return ret;
0794 
0795     if (oldpage != page) {
0796         ret = __phy_write_page(phydev, page);
0797         if (ret < 0)
0798             return ret;
0799     }
0800 
0801     return oldpage;
0802 }
0803 EXPORT_SYMBOL_GPL(phy_select_page);
0804 
0805 /**
0806  * phy_restore_page() - restore the page register and release the bus lock
0807  * @phydev: a pointer to a &struct phy_device
0808  * @oldpage: the old page, return value from phy_save_page() or phy_select_page()
0809  * @ret: operation's return code
0810  *
0811  * Release the MDIO bus lock, restoring @oldpage if it is a valid page.
0812  * This function propagates the earliest error code from the group of
0813  * operations.
0814  *
0815  * Returns:
0816  *   @oldpage if it was a negative value, otherwise
0817  *   @ret if it was a negative errno value, otherwise
0818  *   phy_write_page()'s negative value if it were in error, otherwise
0819  *   @ret.
0820  */
0821 int phy_restore_page(struct phy_device *phydev, int oldpage, int ret)
0822 {
0823     int r;
0824 
0825     if (oldpage >= 0) {
0826         r = __phy_write_page(phydev, oldpage);
0827 
0828         /* Propagate the operation return code if the page write
0829          * was successful.
0830          */
0831         if (ret >= 0 && r < 0)
0832             ret = r;
0833     } else {
0834         /* Propagate the phy page selection error code */
0835         ret = oldpage;
0836     }
0837 
0838     phy_unlock_mdio_bus(phydev);
0839 
0840     return ret;
0841 }
0842 EXPORT_SYMBOL_GPL(phy_restore_page);
0843 
0844 /**
0845  * phy_read_paged() - Convenience function for reading a paged register
0846  * @phydev: a pointer to a &struct phy_device
0847  * @page: the page for the phy
0848  * @regnum: register number
0849  *
0850  * Same rules as for phy_read().
0851  */
0852 int phy_read_paged(struct phy_device *phydev, int page, u32 regnum)
0853 {
0854     int ret = 0, oldpage;
0855 
0856     oldpage = phy_select_page(phydev, page);
0857     if (oldpage >= 0)
0858         ret = __phy_read(phydev, regnum);
0859 
0860     return phy_restore_page(phydev, oldpage, ret);
0861 }
0862 EXPORT_SYMBOL(phy_read_paged);
0863 
0864 /**
0865  * phy_write_paged() - Convenience function for writing a paged register
0866  * @phydev: a pointer to a &struct phy_device
0867  * @page: the page for the phy
0868  * @regnum: register number
0869  * @val: value to write
0870  *
0871  * Same rules as for phy_write().
0872  */
0873 int phy_write_paged(struct phy_device *phydev, int page, u32 regnum, u16 val)
0874 {
0875     int ret = 0, oldpage;
0876 
0877     oldpage = phy_select_page(phydev, page);
0878     if (oldpage >= 0)
0879         ret = __phy_write(phydev, regnum, val);
0880 
0881     return phy_restore_page(phydev, oldpage, ret);
0882 }
0883 EXPORT_SYMBOL(phy_write_paged);
0884 
0885 /**
0886  * phy_modify_paged_changed() - Function for modifying a paged register
0887  * @phydev: a pointer to a &struct phy_device
0888  * @page: the page for the phy
0889  * @regnum: register number
0890  * @mask: bit mask of bits to clear
0891  * @set: bit mask of bits to set
0892  *
0893  * Returns negative errno, 0 if there was no change, and 1 in case of change
0894  */
0895 int phy_modify_paged_changed(struct phy_device *phydev, int page, u32 regnum,
0896                  u16 mask, u16 set)
0897 {
0898     int ret = 0, oldpage;
0899 
0900     oldpage = phy_select_page(phydev, page);
0901     if (oldpage >= 0)
0902         ret = __phy_modify_changed(phydev, regnum, mask, set);
0903 
0904     return phy_restore_page(phydev, oldpage, ret);
0905 }
0906 EXPORT_SYMBOL(phy_modify_paged_changed);
0907 
0908 /**
0909  * phy_modify_paged() - Convenience function for modifying a paged register
0910  * @phydev: a pointer to a &struct phy_device
0911  * @page: the page for the phy
0912  * @regnum: register number
0913  * @mask: bit mask of bits to clear
0914  * @set: bit mask of bits to set
0915  *
0916  * Same rules as for phy_read() and phy_write().
0917  */
0918 int phy_modify_paged(struct phy_device *phydev, int page, u32 regnum,
0919              u16 mask, u16 set)
0920 {
0921     int ret = phy_modify_paged_changed(phydev, page, regnum, mask, set);
0922 
0923     return ret < 0 ? ret : 0;
0924 }
0925 EXPORT_SYMBOL(phy_modify_paged);