Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Clause 45 PHY support
0004  */
0005 #include <linux/ethtool.h>
0006 #include <linux/export.h>
0007 #include <linux/mdio.h>
0008 #include <linux/mii.h>
0009 #include <linux/phy.h>
0010 
0011 /**
0012  * genphy_c45_baset1_able - checks if the PMA has BASE-T1 extended abilities
0013  * @phydev: target phy_device struct
0014  */
0015 static bool genphy_c45_baset1_able(struct phy_device *phydev)
0016 {
0017     int val;
0018 
0019     if (phydev->pma_extable == -ENODATA) {
0020         val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_EXTABLE);
0021         if (val < 0)
0022             return false;
0023 
0024         phydev->pma_extable = val;
0025     }
0026 
0027     return !!(phydev->pma_extable & MDIO_PMA_EXTABLE_BT1);
0028 }
0029 
0030 /**
0031  * genphy_c45_pma_can_sleep - checks if the PMA have sleep support
0032  * @phydev: target phy_device struct
0033  */
0034 static bool genphy_c45_pma_can_sleep(struct phy_device *phydev)
0035 {
0036     int stat1;
0037 
0038     stat1 = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_STAT1);
0039     if (stat1 < 0)
0040         return false;
0041 
0042     return !!(stat1 & MDIO_STAT1_LPOWERABLE);
0043 }
0044 
0045 /**
0046  * genphy_c45_pma_resume - wakes up the PMA module
0047  * @phydev: target phy_device struct
0048  */
0049 int genphy_c45_pma_resume(struct phy_device *phydev)
0050 {
0051     if (!genphy_c45_pma_can_sleep(phydev))
0052         return -EOPNOTSUPP;
0053 
0054     return phy_clear_bits_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL1,
0055                   MDIO_CTRL1_LPOWER);
0056 }
0057 EXPORT_SYMBOL_GPL(genphy_c45_pma_resume);
0058 
0059 /**
0060  * genphy_c45_pma_suspend - suspends the PMA module
0061  * @phydev: target phy_device struct
0062  */
0063 int genphy_c45_pma_suspend(struct phy_device *phydev)
0064 {
0065     if (!genphy_c45_pma_can_sleep(phydev))
0066         return -EOPNOTSUPP;
0067 
0068     return phy_set_bits_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL1,
0069                 MDIO_CTRL1_LPOWER);
0070 }
0071 EXPORT_SYMBOL_GPL(genphy_c45_pma_suspend);
0072 
0073 /**
0074  * genphy_c45_pma_baset1_setup_master_slave - configures forced master/slave
0075  * role of BaseT1 devices.
0076  * @phydev: target phy_device struct
0077  */
0078 int genphy_c45_pma_baset1_setup_master_slave(struct phy_device *phydev)
0079 {
0080     int ctl = 0;
0081 
0082     switch (phydev->master_slave_set) {
0083     case MASTER_SLAVE_CFG_MASTER_PREFERRED:
0084     case MASTER_SLAVE_CFG_MASTER_FORCE:
0085         ctl = MDIO_PMA_PMD_BT1_CTRL_CFG_MST;
0086         break;
0087     case MASTER_SLAVE_CFG_SLAVE_FORCE:
0088     case MASTER_SLAVE_CFG_SLAVE_PREFERRED:
0089         break;
0090     case MASTER_SLAVE_CFG_UNKNOWN:
0091     case MASTER_SLAVE_CFG_UNSUPPORTED:
0092         return 0;
0093     default:
0094         phydev_warn(phydev, "Unsupported Master/Slave mode\n");
0095         return -EOPNOTSUPP;
0096     }
0097 
0098     return phy_modify_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_PMD_BT1_CTRL,
0099                  MDIO_PMA_PMD_BT1_CTRL_CFG_MST, ctl);
0100 }
0101 EXPORT_SYMBOL_GPL(genphy_c45_pma_baset1_setup_master_slave);
0102 
0103 /**
0104  * genphy_c45_pma_setup_forced - configures a forced speed
0105  * @phydev: target phy_device struct
0106  */
0107 int genphy_c45_pma_setup_forced(struct phy_device *phydev)
0108 {
0109     int ctrl1, ctrl2, ret;
0110 
0111     /* Half duplex is not supported */
0112     if (phydev->duplex != DUPLEX_FULL)
0113         return -EINVAL;
0114 
0115     ctrl1 = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL1);
0116     if (ctrl1 < 0)
0117         return ctrl1;
0118 
0119     ctrl2 = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL2);
0120     if (ctrl2 < 0)
0121         return ctrl2;
0122 
0123     ctrl1 &= ~MDIO_CTRL1_SPEEDSEL;
0124     /*
0125      * PMA/PMD type selection is 1.7.5:0 not 1.7.3:0.  See 45.2.1.6.1
0126      * in 802.3-2012 and 802.3-2015.
0127      */
0128     ctrl2 &= ~(MDIO_PMA_CTRL2_TYPE | 0x30);
0129 
0130     switch (phydev->speed) {
0131     case SPEED_10:
0132         if (genphy_c45_baset1_able(phydev))
0133             ctrl2 |= MDIO_PMA_CTRL2_BASET1;
0134         else
0135             ctrl2 |= MDIO_PMA_CTRL2_10BT;
0136         break;
0137     case SPEED_100:
0138         ctrl1 |= MDIO_PMA_CTRL1_SPEED100;
0139         ctrl2 |= MDIO_PMA_CTRL2_100BTX;
0140         break;
0141     case SPEED_1000:
0142         ctrl1 |= MDIO_PMA_CTRL1_SPEED1000;
0143         /* Assume 1000base-T */
0144         ctrl2 |= MDIO_PMA_CTRL2_1000BT;
0145         break;
0146     case SPEED_2500:
0147         ctrl1 |= MDIO_CTRL1_SPEED2_5G;
0148         /* Assume 2.5Gbase-T */
0149         ctrl2 |= MDIO_PMA_CTRL2_2_5GBT;
0150         break;
0151     case SPEED_5000:
0152         ctrl1 |= MDIO_CTRL1_SPEED5G;
0153         /* Assume 5Gbase-T */
0154         ctrl2 |= MDIO_PMA_CTRL2_5GBT;
0155         break;
0156     case SPEED_10000:
0157         ctrl1 |= MDIO_CTRL1_SPEED10G;
0158         /* Assume 10Gbase-T */
0159         ctrl2 |= MDIO_PMA_CTRL2_10GBT;
0160         break;
0161     default:
0162         return -EINVAL;
0163     }
0164 
0165     ret = phy_write_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL1, ctrl1);
0166     if (ret < 0)
0167         return ret;
0168 
0169     ret = phy_write_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL2, ctrl2);
0170     if (ret < 0)
0171         return ret;
0172 
0173     if (genphy_c45_baset1_able(phydev)) {
0174         ret = genphy_c45_pma_baset1_setup_master_slave(phydev);
0175         if (ret < 0)
0176             return ret;
0177     }
0178 
0179     return genphy_c45_an_disable_aneg(phydev);
0180 }
0181 EXPORT_SYMBOL_GPL(genphy_c45_pma_setup_forced);
0182 
0183 /* Sets master/slave preference and supported technologies.
0184  * The preference is set in the BIT(4) of BASE-T1 AN
0185  * advertisement register 7.515 and whether the status
0186  * is forced or not, it is set in the BIT(12) of BASE-T1
0187  * AN advertisement register 7.514.
0188  * Sets 10BASE-T1L Ability BIT(14) in BASE-T1 autonegotiation
0189  * advertisement register [31:16] if supported.
0190  */
0191 static int genphy_c45_baset1_an_config_aneg(struct phy_device *phydev)
0192 {
0193     u16 adv_l_mask, adv_l = 0;
0194     u16 adv_m_mask, adv_m = 0;
0195     int changed = 0;
0196     int ret;
0197 
0198     adv_l_mask = MDIO_AN_T1_ADV_L_FORCE_MS | MDIO_AN_T1_ADV_L_PAUSE_CAP |
0199         MDIO_AN_T1_ADV_L_PAUSE_ASYM;
0200     adv_m_mask = MDIO_AN_T1_ADV_M_MST | MDIO_AN_T1_ADV_M_B10L;
0201 
0202     switch (phydev->master_slave_set) {
0203     case MASTER_SLAVE_CFG_MASTER_FORCE:
0204         adv_m |= MDIO_AN_T1_ADV_M_MST;
0205         fallthrough;
0206     case MASTER_SLAVE_CFG_SLAVE_FORCE:
0207         adv_l |= MDIO_AN_T1_ADV_L_FORCE_MS;
0208         break;
0209     case MASTER_SLAVE_CFG_MASTER_PREFERRED:
0210         adv_m |= MDIO_AN_T1_ADV_M_MST;
0211         fallthrough;
0212     case MASTER_SLAVE_CFG_SLAVE_PREFERRED:
0213         break;
0214     case MASTER_SLAVE_CFG_UNKNOWN:
0215     case MASTER_SLAVE_CFG_UNSUPPORTED:
0216         /* if master/slave role is not specified, do not overwrite it */
0217         adv_l_mask &= ~MDIO_AN_T1_ADV_L_FORCE_MS;
0218         adv_m_mask &= ~MDIO_AN_T1_ADV_M_MST;
0219         break;
0220     default:
0221         phydev_warn(phydev, "Unsupported Master/Slave mode\n");
0222         return -EOPNOTSUPP;
0223     }
0224 
0225     adv_l |= linkmode_adv_to_mii_t1_adv_l_t(phydev->advertising);
0226 
0227     ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_T1_ADV_L,
0228                      adv_l_mask, adv_l);
0229     if (ret < 0)
0230         return ret;
0231     if (ret > 0)
0232         changed = 1;
0233 
0234     adv_m |= linkmode_adv_to_mii_t1_adv_m_t(phydev->advertising);
0235 
0236     ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_T1_ADV_M,
0237                      adv_m_mask, adv_m);
0238     if (ret < 0)
0239         return ret;
0240     if (ret > 0)
0241         changed = 1;
0242 
0243     return changed;
0244 }
0245 
0246 /**
0247  * genphy_c45_an_config_aneg - configure advertisement registers
0248  * @phydev: target phy_device struct
0249  *
0250  * Configure advertisement registers based on modes set in phydev->advertising
0251  *
0252  * Returns negative errno code on failure, 0 if advertisement didn't change,
0253  * or 1 if advertised modes changed.
0254  */
0255 int genphy_c45_an_config_aneg(struct phy_device *phydev)
0256 {
0257     int changed, ret;
0258     u32 adv;
0259 
0260     linkmode_and(phydev->advertising, phydev->advertising,
0261              phydev->supported);
0262 
0263     changed = genphy_config_eee_advert(phydev);
0264 
0265     if (genphy_c45_baset1_able(phydev))
0266         return genphy_c45_baset1_an_config_aneg(phydev);
0267 
0268     adv = linkmode_adv_to_mii_adv_t(phydev->advertising);
0269 
0270     ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE,
0271                      ADVERTISE_ALL | ADVERTISE_100BASE4 |
0272                      ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM,
0273                      adv);
0274     if (ret < 0)
0275         return ret;
0276     if (ret > 0)
0277         changed = 1;
0278 
0279     adv = linkmode_adv_to_mii_10gbt_adv_t(phydev->advertising);
0280 
0281     ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
0282                      MDIO_AN_10GBT_CTRL_ADV10G |
0283                      MDIO_AN_10GBT_CTRL_ADV5G |
0284                      MDIO_AN_10GBT_CTRL_ADV2_5G, adv);
0285     if (ret < 0)
0286         return ret;
0287     if (ret > 0)
0288         changed = 1;
0289 
0290     return changed;
0291 }
0292 EXPORT_SYMBOL_GPL(genphy_c45_an_config_aneg);
0293 
0294 /**
0295  * genphy_c45_an_disable_aneg - disable auto-negotiation
0296  * @phydev: target phy_device struct
0297  *
0298  * Disable auto-negotiation in the Clause 45 PHY. The link parameters
0299  * are controlled through the PMA/PMD MMD registers.
0300  *
0301  * Returns zero on success, negative errno code on failure.
0302  */
0303 int genphy_c45_an_disable_aneg(struct phy_device *phydev)
0304 {
0305     u16 reg = MDIO_CTRL1;
0306 
0307     if (genphy_c45_baset1_able(phydev))
0308         reg = MDIO_AN_T1_CTRL;
0309 
0310     return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg,
0311                   MDIO_AN_CTRL1_ENABLE | MDIO_AN_CTRL1_RESTART);
0312 }
0313 EXPORT_SYMBOL_GPL(genphy_c45_an_disable_aneg);
0314 
0315 /**
0316  * genphy_c45_restart_aneg - Enable and restart auto-negotiation
0317  * @phydev: target phy_device struct
0318  *
0319  * This assumes that the auto-negotiation MMD is present.
0320  *
0321  * Enable and restart auto-negotiation.
0322  */
0323 int genphy_c45_restart_aneg(struct phy_device *phydev)
0324 {
0325     u16 reg = MDIO_CTRL1;
0326 
0327     if (genphy_c45_baset1_able(phydev))
0328         reg = MDIO_AN_T1_CTRL;
0329 
0330     return phy_set_bits_mmd(phydev, MDIO_MMD_AN, reg,
0331                 MDIO_AN_CTRL1_ENABLE | MDIO_AN_CTRL1_RESTART);
0332 }
0333 EXPORT_SYMBOL_GPL(genphy_c45_restart_aneg);
0334 
0335 /**
0336  * genphy_c45_check_and_restart_aneg - Enable and restart auto-negotiation
0337  * @phydev: target phy_device struct
0338  * @restart: whether aneg restart is requested
0339  *
0340  * This assumes that the auto-negotiation MMD is present.
0341  *
0342  * Check, and restart auto-negotiation if needed.
0343  */
0344 int genphy_c45_check_and_restart_aneg(struct phy_device *phydev, bool restart)
0345 {
0346     u16 reg = MDIO_CTRL1;
0347     int ret;
0348 
0349     if (genphy_c45_baset1_able(phydev))
0350         reg = MDIO_AN_T1_CTRL;
0351 
0352     if (!restart) {
0353         /* Configure and restart aneg if it wasn't set before */
0354         ret = phy_read_mmd(phydev, MDIO_MMD_AN, reg);
0355         if (ret < 0)
0356             return ret;
0357 
0358         if (!(ret & MDIO_AN_CTRL1_ENABLE))
0359             restart = true;
0360     }
0361 
0362     if (restart)
0363         return genphy_c45_restart_aneg(phydev);
0364 
0365     return 0;
0366 }
0367 EXPORT_SYMBOL_GPL(genphy_c45_check_and_restart_aneg);
0368 
0369 /**
0370  * genphy_c45_aneg_done - return auto-negotiation complete status
0371  * @phydev: target phy_device struct
0372  *
0373  * This assumes that the auto-negotiation MMD is present.
0374  *
0375  * Reads the status register from the auto-negotiation MMD, returning:
0376  * - positive if auto-negotiation is complete
0377  * - negative errno code on error
0378  * - zero otherwise
0379  */
0380 int genphy_c45_aneg_done(struct phy_device *phydev)
0381 {
0382     int reg = MDIO_STAT1;
0383     int val;
0384 
0385     if (genphy_c45_baset1_able(phydev))
0386         reg = MDIO_AN_T1_STAT;
0387 
0388     val = phy_read_mmd(phydev, MDIO_MMD_AN, reg);
0389 
0390     return val < 0 ? val : val & MDIO_AN_STAT1_COMPLETE ? 1 : 0;
0391 }
0392 EXPORT_SYMBOL_GPL(genphy_c45_aneg_done);
0393 
0394 /**
0395  * genphy_c45_read_link - read the overall link status from the MMDs
0396  * @phydev: target phy_device struct
0397  *
0398  * Read the link status from the specified MMDs, and if they all indicate
0399  * that the link is up, set phydev->link to 1.  If an error is encountered,
0400  * a negative errno will be returned, otherwise zero.
0401  */
0402 int genphy_c45_read_link(struct phy_device *phydev)
0403 {
0404     u32 mmd_mask = MDIO_DEVS_PMAPMD;
0405     int val, devad;
0406     bool link = true;
0407 
0408     if (phydev->c45_ids.mmds_present & MDIO_DEVS_AN) {
0409         val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1);
0410         if (val < 0)
0411             return val;
0412 
0413         /* Autoneg is being started, therefore disregard current
0414          * link status and report link as down.
0415          */
0416         if (val & MDIO_AN_CTRL1_RESTART) {
0417             phydev->link = 0;
0418             return 0;
0419         }
0420     }
0421 
0422     while (mmd_mask && link) {
0423         devad = __ffs(mmd_mask);
0424         mmd_mask &= ~BIT(devad);
0425 
0426         /* The link state is latched low so that momentary link
0427          * drops can be detected. Do not double-read the status
0428          * in polling mode to detect such short link drops except
0429          * the link was already down.
0430          */
0431         if (!phy_polling_mode(phydev) || !phydev->link) {
0432             val = phy_read_mmd(phydev, devad, MDIO_STAT1);
0433             if (val < 0)
0434                 return val;
0435             else if (val & MDIO_STAT1_LSTATUS)
0436                 continue;
0437         }
0438 
0439         val = phy_read_mmd(phydev, devad, MDIO_STAT1);
0440         if (val < 0)
0441             return val;
0442 
0443         if (!(val & MDIO_STAT1_LSTATUS))
0444             link = false;
0445     }
0446 
0447     phydev->link = link;
0448 
0449     return 0;
0450 }
0451 EXPORT_SYMBOL_GPL(genphy_c45_read_link);
0452 
0453 /* Read the Clause 45 defined BASE-T1 AN (7.513) status register to check
0454  * if autoneg is complete. If so read the BASE-T1 Autonegotiation
0455  * Advertisement registers filling in the link partner advertisement,
0456  * pause and asym_pause members in phydev.
0457  */
0458 static int genphy_c45_baset1_read_lpa(struct phy_device *phydev)
0459 {
0460     int val;
0461 
0462     val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_T1_STAT);
0463     if (val < 0)
0464         return val;
0465 
0466     if (!(val & MDIO_AN_STAT1_COMPLETE)) {
0467         linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->lp_advertising);
0468         mii_t1_adv_l_mod_linkmode_t(phydev->lp_advertising, 0);
0469         mii_t1_adv_m_mod_linkmode_t(phydev->lp_advertising, 0);
0470 
0471         phydev->pause = 0;
0472         phydev->asym_pause = 0;
0473 
0474         return 0;
0475     }
0476 
0477     linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->lp_advertising, 1);
0478 
0479     val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_T1_LP_L);
0480     if (val < 0)
0481         return val;
0482 
0483     mii_t1_adv_l_mod_linkmode_t(phydev->lp_advertising, val);
0484     phydev->pause = val & MDIO_AN_T1_ADV_L_PAUSE_CAP ? 1 : 0;
0485     phydev->asym_pause = val & MDIO_AN_T1_ADV_L_PAUSE_ASYM ? 1 : 0;
0486 
0487     val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_T1_LP_M);
0488     if (val < 0)
0489         return val;
0490 
0491     mii_t1_adv_m_mod_linkmode_t(phydev->lp_advertising, val);
0492 
0493     return 0;
0494 }
0495 
0496 /**
0497  * genphy_c45_read_lpa - read the link partner advertisement and pause
0498  * @phydev: target phy_device struct
0499  *
0500  * Read the Clause 45 defined base (7.19) and 10G (7.33) status registers,
0501  * filling in the link partner advertisement, pause and asym_pause members
0502  * in @phydev.  This assumes that the auto-negotiation MMD is present, and
0503  * the backplane bit (7.48.0) is clear.  Clause 45 PHY drivers are expected
0504  * to fill in the remainder of the link partner advert from vendor registers.
0505  */
0506 int genphy_c45_read_lpa(struct phy_device *phydev)
0507 {
0508     int val;
0509 
0510     if (genphy_c45_baset1_able(phydev))
0511         return genphy_c45_baset1_read_lpa(phydev);
0512 
0513     val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1);
0514     if (val < 0)
0515         return val;
0516 
0517     if (!(val & MDIO_AN_STAT1_COMPLETE)) {
0518         linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
0519                    phydev->lp_advertising);
0520         mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, 0);
0521         mii_adv_mod_linkmode_adv_t(phydev->lp_advertising, 0);
0522         phydev->pause = 0;
0523         phydev->asym_pause = 0;
0524 
0525         return 0;
0526     }
0527 
0528     linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->lp_advertising,
0529              val & MDIO_AN_STAT1_LPABLE);
0530 
0531     /* Read the link partner's base page advertisement */
0532     val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_LPA);
0533     if (val < 0)
0534         return val;
0535 
0536     mii_adv_mod_linkmode_adv_t(phydev->lp_advertising, val);
0537     phydev->pause = val & LPA_PAUSE_CAP ? 1 : 0;
0538     phydev->asym_pause = val & LPA_PAUSE_ASYM ? 1 : 0;
0539 
0540     /* Read the link partner's 10G advertisement */
0541     val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_STAT);
0542     if (val < 0)
0543         return val;
0544 
0545     mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, val);
0546 
0547     return 0;
0548 }
0549 EXPORT_SYMBOL_GPL(genphy_c45_read_lpa);
0550 
0551 /**
0552  * genphy_c45_pma_baset1_read_master_slave - read forced master/slave
0553  * configuration
0554  * @phydev: target phy_device struct
0555  */
0556 int genphy_c45_pma_baset1_read_master_slave(struct phy_device *phydev)
0557 {
0558     int val;
0559 
0560     phydev->master_slave_state = MASTER_SLAVE_STATE_UNKNOWN;
0561     phydev->master_slave_get = MASTER_SLAVE_CFG_UNKNOWN;
0562 
0563     val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_PMD_BT1_CTRL);
0564     if (val < 0)
0565         return val;
0566 
0567     if (val & MDIO_PMA_PMD_BT1_CTRL_CFG_MST) {
0568         phydev->master_slave_get = MASTER_SLAVE_CFG_MASTER_FORCE;
0569         phydev->master_slave_state = MASTER_SLAVE_STATE_MASTER;
0570     } else {
0571         phydev->master_slave_get = MASTER_SLAVE_CFG_SLAVE_FORCE;
0572         phydev->master_slave_state = MASTER_SLAVE_STATE_SLAVE;
0573     }
0574 
0575     return 0;
0576 }
0577 EXPORT_SYMBOL_GPL(genphy_c45_pma_baset1_read_master_slave);
0578 
0579 /**
0580  * genphy_c45_read_pma - read link speed etc from PMA
0581  * @phydev: target phy_device struct
0582  */
0583 int genphy_c45_read_pma(struct phy_device *phydev)
0584 {
0585     int val;
0586 
0587     linkmode_zero(phydev->lp_advertising);
0588 
0589     val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL1);
0590     if (val < 0)
0591         return val;
0592 
0593     switch (val & MDIO_CTRL1_SPEEDSEL) {
0594     case 0:
0595         phydev->speed = SPEED_10;
0596         break;
0597     case MDIO_PMA_CTRL1_SPEED100:
0598         phydev->speed = SPEED_100;
0599         break;
0600     case MDIO_PMA_CTRL1_SPEED1000:
0601         phydev->speed = SPEED_1000;
0602         break;
0603     case MDIO_CTRL1_SPEED2_5G:
0604         phydev->speed = SPEED_2500;
0605         break;
0606     case MDIO_CTRL1_SPEED5G:
0607         phydev->speed = SPEED_5000;
0608         break;
0609     case MDIO_CTRL1_SPEED10G:
0610         phydev->speed = SPEED_10000;
0611         break;
0612     default:
0613         phydev->speed = SPEED_UNKNOWN;
0614         break;
0615     }
0616 
0617     phydev->duplex = DUPLEX_FULL;
0618 
0619     if (genphy_c45_baset1_able(phydev)) {
0620         val = genphy_c45_pma_baset1_read_master_slave(phydev);
0621         if (val < 0)
0622             return val;
0623     }
0624 
0625     return 0;
0626 }
0627 EXPORT_SYMBOL_GPL(genphy_c45_read_pma);
0628 
0629 /**
0630  * genphy_c45_read_mdix - read mdix status from PMA
0631  * @phydev: target phy_device struct
0632  */
0633 int genphy_c45_read_mdix(struct phy_device *phydev)
0634 {
0635     int val;
0636 
0637     if (phydev->speed == SPEED_10000) {
0638         val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD,
0639                    MDIO_PMA_10GBT_SWAPPOL);
0640         if (val < 0)
0641             return val;
0642 
0643         switch (val) {
0644         case MDIO_PMA_10GBT_SWAPPOL_ABNX | MDIO_PMA_10GBT_SWAPPOL_CDNX:
0645             phydev->mdix = ETH_TP_MDI;
0646             break;
0647 
0648         case 0:
0649             phydev->mdix = ETH_TP_MDI_X;
0650             break;
0651 
0652         default:
0653             phydev->mdix = ETH_TP_MDI_INVALID;
0654             break;
0655         }
0656     }
0657 
0658     return 0;
0659 }
0660 EXPORT_SYMBOL_GPL(genphy_c45_read_mdix);
0661 
0662 /**
0663  * genphy_c45_pma_read_abilities - read supported link modes from PMA
0664  * @phydev: target phy_device struct
0665  *
0666  * Read the supported link modes from the PMA Status 2 (1.8) register. If bit
0667  * 1.8.9 is set, the list of supported modes is build using the values in the
0668  * PMA Extended Abilities (1.11) register, indicating 1000BASET an 10G related
0669  * modes. If bit 1.11.14 is set, then the list is also extended with the modes
0670  * in the 2.5G/5G PMA Extended register (1.21), indicating if 2.5GBASET and
0671  * 5GBASET are supported.
0672  */
0673 int genphy_c45_pma_read_abilities(struct phy_device *phydev)
0674 {
0675     int val;
0676 
0677     linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported);
0678     if (phydev->c45_ids.mmds_present & MDIO_DEVS_AN) {
0679         val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1);
0680         if (val < 0)
0681             return val;
0682 
0683         if (val & MDIO_AN_STAT1_ABLE)
0684             linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
0685                      phydev->supported);
0686     }
0687 
0688     val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_STAT2);
0689     if (val < 0)
0690         return val;
0691 
0692     linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseSR_Full_BIT,
0693              phydev->supported,
0694              val & MDIO_PMA_STAT2_10GBSR);
0695 
0696     linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseLR_Full_BIT,
0697              phydev->supported,
0698              val & MDIO_PMA_STAT2_10GBLR);
0699 
0700     linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseER_Full_BIT,
0701              phydev->supported,
0702              val & MDIO_PMA_STAT2_10GBER);
0703 
0704     if (val & MDIO_PMA_STAT2_EXTABLE) {
0705         val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_EXTABLE);
0706         if (val < 0)
0707             return val;
0708 
0709         linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT,
0710                  phydev->supported,
0711                  val & MDIO_PMA_EXTABLE_10GBLRM);
0712         linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
0713                  phydev->supported,
0714                  val & MDIO_PMA_EXTABLE_10GBT);
0715         linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
0716                  phydev->supported,
0717                  val & MDIO_PMA_EXTABLE_10GBKX4);
0718         linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
0719                  phydev->supported,
0720                  val & MDIO_PMA_EXTABLE_10GBKR);
0721         linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
0722                  phydev->supported,
0723                  val & MDIO_PMA_EXTABLE_1000BT);
0724         linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
0725                  phydev->supported,
0726                  val & MDIO_PMA_EXTABLE_1000BKX);
0727 
0728         linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
0729                  phydev->supported,
0730                  val & MDIO_PMA_EXTABLE_100BTX);
0731         linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT,
0732                  phydev->supported,
0733                  val & MDIO_PMA_EXTABLE_100BTX);
0734 
0735         linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT,
0736                  phydev->supported,
0737                  val & MDIO_PMA_EXTABLE_10BT);
0738         linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT,
0739                  phydev->supported,
0740                  val & MDIO_PMA_EXTABLE_10BT);
0741 
0742         if (val & MDIO_PMA_EXTABLE_NBT) {
0743             val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD,
0744                        MDIO_PMA_NG_EXTABLE);
0745             if (val < 0)
0746                 return val;
0747 
0748             linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
0749                      phydev->supported,
0750                      val & MDIO_PMA_NG_EXTABLE_2_5GBT);
0751 
0752             linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
0753                      phydev->supported,
0754                      val & MDIO_PMA_NG_EXTABLE_5GBT);
0755         }
0756 
0757         if (val & MDIO_PMA_EXTABLE_BT1) {
0758             val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_PMD_BT1);
0759             if (val < 0)
0760                 return val;
0761 
0762             linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT1L_Full_BIT,
0763                      phydev->supported,
0764                      val & MDIO_PMA_PMD_BT1_B10L_ABLE);
0765 
0766             val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_T1_STAT);
0767             if (val < 0)
0768                 return val;
0769 
0770             linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
0771                      phydev->supported,
0772                      val & MDIO_AN_STAT1_ABLE);
0773         }
0774     }
0775 
0776     return 0;
0777 }
0778 EXPORT_SYMBOL_GPL(genphy_c45_pma_read_abilities);
0779 
0780 /* Read master/slave preference from registers.
0781  * The preference is read from the BIT(4) of BASE-T1 AN
0782  * advertisement register 7.515 and whether the preference
0783  * is forced or not, it is read from BASE-T1 AN advertisement
0784  * register 7.514.
0785  */
0786 int genphy_c45_baset1_read_status(struct phy_device *phydev)
0787 {
0788     int ret;
0789     int cfg;
0790 
0791     phydev->master_slave_get = MASTER_SLAVE_CFG_UNKNOWN;
0792     phydev->master_slave_state = MASTER_SLAVE_STATE_UNKNOWN;
0793 
0794     ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_T1_ADV_L);
0795     if (ret < 0)
0796         return ret;
0797 
0798     cfg = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_T1_ADV_M);
0799     if (cfg < 0)
0800         return cfg;
0801 
0802     if (ret & MDIO_AN_T1_ADV_L_FORCE_MS) {
0803         if (cfg & MDIO_AN_T1_ADV_M_MST)
0804             phydev->master_slave_get = MASTER_SLAVE_CFG_MASTER_FORCE;
0805         else
0806             phydev->master_slave_get = MASTER_SLAVE_CFG_SLAVE_FORCE;
0807     } else {
0808         if (cfg & MDIO_AN_T1_ADV_M_MST)
0809             phydev->master_slave_get = MASTER_SLAVE_CFG_MASTER_PREFERRED;
0810         else
0811             phydev->master_slave_get = MASTER_SLAVE_CFG_SLAVE_PREFERRED;
0812     }
0813 
0814     return 0;
0815 }
0816 EXPORT_SYMBOL_GPL(genphy_c45_baset1_read_status);
0817 
0818 /**
0819  * genphy_c45_read_status - read PHY status
0820  * @phydev: target phy_device struct
0821  *
0822  * Reads status from PHY and sets phy_device members accordingly.
0823  */
0824 int genphy_c45_read_status(struct phy_device *phydev)
0825 {
0826     int ret;
0827 
0828     ret = genphy_c45_read_link(phydev);
0829     if (ret)
0830         return ret;
0831 
0832     phydev->speed = SPEED_UNKNOWN;
0833     phydev->duplex = DUPLEX_UNKNOWN;
0834     phydev->pause = 0;
0835     phydev->asym_pause = 0;
0836 
0837     if (phydev->autoneg == AUTONEG_ENABLE) {
0838         ret = genphy_c45_read_lpa(phydev);
0839         if (ret)
0840             return ret;
0841 
0842         if (genphy_c45_baset1_able(phydev)) {
0843             ret = genphy_c45_baset1_read_status(phydev);
0844             if (ret < 0)
0845                 return ret;
0846         }
0847 
0848         phy_resolve_aneg_linkmode(phydev);
0849     } else {
0850         ret = genphy_c45_read_pma(phydev);
0851     }
0852 
0853     return ret;
0854 }
0855 EXPORT_SYMBOL_GPL(genphy_c45_read_status);
0856 
0857 /**
0858  * genphy_c45_config_aneg - restart auto-negotiation or forced setup
0859  * @phydev: target phy_device struct
0860  *
0861  * Description: If auto-negotiation is enabled, we configure the
0862  *   advertising, and then restart auto-negotiation.  If it is not
0863  *   enabled, then we force a configuration.
0864  */
0865 int genphy_c45_config_aneg(struct phy_device *phydev)
0866 {
0867     bool changed = false;
0868     int ret;
0869 
0870     if (phydev->autoneg == AUTONEG_DISABLE)
0871         return genphy_c45_pma_setup_forced(phydev);
0872 
0873     ret = genphy_c45_an_config_aneg(phydev);
0874     if (ret < 0)
0875         return ret;
0876     if (ret > 0)
0877         changed = true;
0878 
0879     return genphy_c45_check_and_restart_aneg(phydev, changed);
0880 }
0881 EXPORT_SYMBOL_GPL(genphy_c45_config_aneg);
0882 
0883 /* The gen10g_* functions are the old Clause 45 stub */
0884 
0885 int gen10g_config_aneg(struct phy_device *phydev)
0886 {
0887     return 0;
0888 }
0889 EXPORT_SYMBOL_GPL(gen10g_config_aneg);
0890 
0891 int genphy_c45_loopback(struct phy_device *phydev, bool enable)
0892 {
0893     return phy_modify_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1,
0894                   MDIO_PCS_CTRL1_LOOPBACK,
0895                   enable ? MDIO_PCS_CTRL1_LOOPBACK : 0);
0896 }
0897 EXPORT_SYMBOL_GPL(genphy_c45_loopback);
0898 
0899 /**
0900  * genphy_c45_fast_retrain - configure fast retrain registers
0901  * @phydev: target phy_device struct
0902  * @enable: enable fast retrain or not
0903  *
0904  * Description: If fast-retrain is enabled, we configure PHY as
0905  *   advertising fast retrain capable and THP Bypass Request, then
0906  *   enable fast retrain. If it is not enabled, we configure fast
0907  *   retrain disabled.
0908  */
0909 int genphy_c45_fast_retrain(struct phy_device *phydev, bool enable)
0910 {
0911     int ret;
0912 
0913     if (!enable)
0914         return phy_clear_bits_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_FSRT_CSR,
0915                 MDIO_PMA_10GBR_FSRT_ENABLE);
0916 
0917     if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported)) {
0918         ret = phy_set_bits_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
0919                 MDIO_AN_10GBT_CTRL_ADVFSRT2_5G);
0920         if (ret)
0921             return ret;
0922 
0923         ret = phy_set_bits_mmd(phydev, MDIO_MMD_AN, MDIO_AN_CTRL2,
0924                 MDIO_AN_THP_BP2_5GT);
0925         if (ret)
0926             return ret;
0927     }
0928 
0929     return phy_set_bits_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_FSRT_CSR,
0930             MDIO_PMA_10GBR_FSRT_ENABLE);
0931 }
0932 EXPORT_SYMBOL_GPL(genphy_c45_fast_retrain);
0933 
0934 struct phy_driver genphy_c45_driver = {
0935     .phy_id         = 0xffffffff,
0936     .phy_id_mask    = 0xffffffff,
0937     .name           = "Generic Clause 45 PHY",
0938     .read_status    = genphy_c45_read_status,
0939 };