0001
0002
0003
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
0013
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
0032
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
0047
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
0061
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
0075
0076
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
0105
0106
0107 int genphy_c45_pma_setup_forced(struct phy_device *phydev)
0108 {
0109 int ctrl1, ctrl2, ret;
0110
0111
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
0126
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
0144 ctrl2 |= MDIO_PMA_CTRL2_1000BT;
0145 break;
0146 case SPEED_2500:
0147 ctrl1 |= MDIO_CTRL1_SPEED2_5G;
0148
0149 ctrl2 |= MDIO_PMA_CTRL2_2_5GBT;
0150 break;
0151 case SPEED_5000:
0152 ctrl1 |= MDIO_CTRL1_SPEED5G;
0153
0154 ctrl2 |= MDIO_PMA_CTRL2_5GBT;
0155 break;
0156 case SPEED_10000:
0157 ctrl1 |= MDIO_CTRL1_SPEED10G;
0158
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
0184
0185
0186
0187
0188
0189
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
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
0248
0249
0250
0251
0252
0253
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
0296
0297
0298
0299
0300
0301
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
0317
0318
0319
0320
0321
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
0337
0338
0339
0340
0341
0342
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
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
0371
0372
0373
0374
0375
0376
0377
0378
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
0396
0397
0398
0399
0400
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
0414
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
0427
0428
0429
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
0454
0455
0456
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
0498
0499
0500
0501
0502
0503
0504
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
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
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
0553
0554
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
0581
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
0631
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
0664
0665
0666
0667
0668
0669
0670
0671
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
0781
0782
0783
0784
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
0820
0821
0822
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
0859
0860
0861
0862
0863
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
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
0901
0902
0903
0904
0905
0906
0907
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 };