LCOV - code coverage report
Current view: top level - drivers/net/phy - phy-c45.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 217 0.0 %
Date: 2022-04-01 13:59:58 Functions: 0 14 0.0 %
Branches: 0 107 0.0 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0-only
       2                 :            : /*
       3                 :            :  * Clause 45 PHY support
       4                 :            :  */
       5                 :            : #include <linux/ethtool.h>
       6                 :            : #include <linux/export.h>
       7                 :            : #include <linux/mdio.h>
       8                 :            : #include <linux/mii.h>
       9                 :            : #include <linux/phy.h>
      10                 :            : 
      11                 :            : /**
      12                 :            :  * genphy_c45_setup_forced - configures a forced speed
      13                 :            :  * @phydev: target phy_device struct
      14                 :            :  */
      15                 :          0 : int genphy_c45_pma_setup_forced(struct phy_device *phydev)
      16                 :            : {
      17                 :          0 :         int ctrl1, ctrl2, ret;
      18                 :            : 
      19                 :            :         /* Half duplex is not supported */
      20         [ #  # ]:          0 :         if (phydev->duplex != DUPLEX_FULL)
      21                 :            :                 return -EINVAL;
      22                 :            : 
      23                 :          0 :         ctrl1 = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL1);
      24         [ #  # ]:          0 :         if (ctrl1 < 0)
      25                 :            :                 return ctrl1;
      26                 :            : 
      27                 :          0 :         ctrl2 = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL2);
      28         [ #  # ]:          0 :         if (ctrl2 < 0)
      29                 :            :                 return ctrl2;
      30                 :            : 
      31                 :          0 :         ctrl1 &= ~MDIO_CTRL1_SPEEDSEL;
      32                 :            :         /*
      33                 :            :          * PMA/PMD type selection is 1.7.5:0 not 1.7.3:0.  See 45.2.1.6.1
      34                 :            :          * in 802.3-2012 and 802.3-2015.
      35                 :            :          */
      36                 :          0 :         ctrl2 &= ~(MDIO_PMA_CTRL2_TYPE | 0x30);
      37                 :            : 
      38   [ #  #  #  #  :          0 :         switch (phydev->speed) {
                #  #  # ]
      39                 :          0 :         case SPEED_10:
      40                 :          0 :                 ctrl2 |= MDIO_PMA_CTRL2_10BT;
      41                 :          0 :                 break;
      42                 :          0 :         case SPEED_100:
      43                 :          0 :                 ctrl1 |= MDIO_PMA_CTRL1_SPEED100;
      44                 :          0 :                 ctrl2 |= MDIO_PMA_CTRL2_100BTX;
      45                 :          0 :                 break;
      46                 :          0 :         case SPEED_1000:
      47                 :          0 :                 ctrl1 |= MDIO_PMA_CTRL1_SPEED1000;
      48                 :            :                 /* Assume 1000base-T */
      49                 :          0 :                 ctrl2 |= MDIO_PMA_CTRL2_1000BT;
      50                 :          0 :                 break;
      51                 :          0 :         case SPEED_2500:
      52                 :          0 :                 ctrl1 |= MDIO_CTRL1_SPEED2_5G;
      53                 :            :                 /* Assume 2.5Gbase-T */
      54                 :          0 :                 ctrl2 |= MDIO_PMA_CTRL2_2_5GBT;
      55                 :          0 :                 break;
      56                 :          0 :         case SPEED_5000:
      57                 :          0 :                 ctrl1 |= MDIO_CTRL1_SPEED5G;
      58                 :            :                 /* Assume 5Gbase-T */
      59                 :          0 :                 ctrl2 |= MDIO_PMA_CTRL2_5GBT;
      60                 :          0 :                 break;
      61                 :          0 :         case SPEED_10000:
      62                 :          0 :                 ctrl1 |= MDIO_CTRL1_SPEED10G;
      63                 :            :                 /* Assume 10Gbase-T */
      64                 :          0 :                 ctrl2 |= MDIO_PMA_CTRL2_10GBT;
      65                 :          0 :                 break;
      66                 :            :         default:
      67                 :            :                 return -EINVAL;
      68                 :            :         }
      69                 :            : 
      70                 :          0 :         ret = phy_write_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL1, ctrl1);
      71         [ #  # ]:          0 :         if (ret < 0)
      72                 :            :                 return ret;
      73                 :            : 
      74                 :          0 :         ret = phy_write_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL2, ctrl2);
      75         [ #  # ]:          0 :         if (ret < 0)
      76                 :            :                 return ret;
      77                 :            : 
      78                 :          0 :         return genphy_c45_an_disable_aneg(phydev);
      79                 :            : }
      80                 :            : EXPORT_SYMBOL_GPL(genphy_c45_pma_setup_forced);
      81                 :            : 
      82                 :            : /**
      83                 :            :  * genphy_c45_an_config_aneg - configure advertisement registers
      84                 :            :  * @phydev: target phy_device struct
      85                 :            :  *
      86                 :            :  * Configure advertisement registers based on modes set in phydev->advertising
      87                 :            :  *
      88                 :            :  * Returns negative errno code on failure, 0 if advertisement didn't change,
      89                 :            :  * or 1 if advertised modes changed.
      90                 :            :  */
      91                 :          0 : int genphy_c45_an_config_aneg(struct phy_device *phydev)
      92                 :            : {
      93                 :          0 :         int changed, ret;
      94                 :          0 :         u32 adv;
      95                 :            : 
      96                 :          0 :         linkmode_and(phydev->advertising, phydev->advertising,
      97                 :          0 :                      phydev->supported);
      98                 :            : 
      99                 :          0 :         changed = genphy_config_eee_advert(phydev);
     100                 :            : 
     101                 :          0 :         adv = linkmode_adv_to_mii_adv_t(phydev->advertising);
     102                 :            : 
     103                 :          0 :         ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE,
     104                 :            :                                      ADVERTISE_ALL | ADVERTISE_100BASE4 |
     105                 :            :                                      ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM,
     106                 :            :                                      adv);
     107         [ #  # ]:          0 :         if (ret < 0)
     108                 :            :                 return ret;
     109         [ #  # ]:          0 :         if (ret > 0)
     110                 :          0 :                 changed = 1;
     111                 :            : 
     112                 :          0 :         adv = linkmode_adv_to_mii_10gbt_adv_t(phydev->advertising);
     113                 :            : 
     114                 :          0 :         ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
     115                 :            :                                      MDIO_AN_10GBT_CTRL_ADV10G |
     116                 :            :                                      MDIO_AN_10GBT_CTRL_ADV5G |
     117                 :            :                                      MDIO_AN_10GBT_CTRL_ADV2_5G, adv);
     118         [ #  # ]:          0 :         if (ret < 0)
     119                 :            :                 return ret;
     120         [ #  # ]:          0 :         if (ret > 0)
     121                 :          0 :                 changed = 1;
     122                 :            : 
     123                 :            :         return changed;
     124                 :            : }
     125                 :            : EXPORT_SYMBOL_GPL(genphy_c45_an_config_aneg);
     126                 :            : 
     127                 :            : /**
     128                 :            :  * genphy_c45_an_disable_aneg - disable auto-negotiation
     129                 :            :  * @phydev: target phy_device struct
     130                 :            :  *
     131                 :            :  * Disable auto-negotiation in the Clause 45 PHY. The link parameters
     132                 :            :  * parameters are controlled through the PMA/PMD MMD registers.
     133                 :            :  *
     134                 :            :  * Returns zero on success, negative errno code on failure.
     135                 :            :  */
     136                 :          0 : int genphy_c45_an_disable_aneg(struct phy_device *phydev)
     137                 :            : {
     138                 :            : 
     139                 :          0 :         return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1,
     140                 :            :                                   MDIO_AN_CTRL1_ENABLE | MDIO_AN_CTRL1_RESTART);
     141                 :            : }
     142                 :            : EXPORT_SYMBOL_GPL(genphy_c45_an_disable_aneg);
     143                 :            : 
     144                 :            : /**
     145                 :            :  * genphy_c45_restart_aneg - Enable and restart auto-negotiation
     146                 :            :  * @phydev: target phy_device struct
     147                 :            :  *
     148                 :            :  * This assumes that the auto-negotiation MMD is present.
     149                 :            :  *
     150                 :            :  * Enable and restart auto-negotiation.
     151                 :            :  */
     152                 :          0 : int genphy_c45_restart_aneg(struct phy_device *phydev)
     153                 :            : {
     154                 :          0 :         return phy_set_bits_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1,
     155                 :            :                                 MDIO_AN_CTRL1_ENABLE | MDIO_AN_CTRL1_RESTART);
     156                 :            : }
     157                 :            : EXPORT_SYMBOL_GPL(genphy_c45_restart_aneg);
     158                 :            : 
     159                 :            : /**
     160                 :            :  * genphy_c45_check_and_restart_aneg - Enable and restart auto-negotiation
     161                 :            :  * @phydev: target phy_device struct
     162                 :            :  * @restart: whether aneg restart is requested
     163                 :            :  *
     164                 :            :  * This assumes that the auto-negotiation MMD is present.
     165                 :            :  *
     166                 :            :  * Check, and restart auto-negotiation if needed.
     167                 :            :  */
     168                 :          0 : int genphy_c45_check_and_restart_aneg(struct phy_device *phydev, bool restart)
     169                 :            : {
     170                 :          0 :         int ret;
     171                 :            : 
     172         [ #  # ]:          0 :         if (!restart) {
     173                 :            :                 /* Configure and restart aneg if it wasn't set before */
     174                 :          0 :                 ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1);
     175         [ #  # ]:          0 :                 if (ret < 0)
     176                 :            :                         return ret;
     177                 :            : 
     178         [ #  # ]:          0 :                 if (!(ret & MDIO_AN_CTRL1_ENABLE))
     179                 :            :                         restart = true;
     180                 :            :         }
     181                 :            : 
     182         [ #  # ]:          0 :         if (restart)
     183                 :          0 :                 return genphy_c45_restart_aneg(phydev);
     184                 :            : 
     185                 :            :         return 0;
     186                 :            : }
     187                 :            : EXPORT_SYMBOL_GPL(genphy_c45_check_and_restart_aneg);
     188                 :            : 
     189                 :            : /**
     190                 :            :  * genphy_c45_aneg_done - return auto-negotiation complete status
     191                 :            :  * @phydev: target phy_device struct
     192                 :            :  *
     193                 :            :  * This assumes that the auto-negotiation MMD is present.
     194                 :            :  *
     195                 :            :  * Reads the status register from the auto-negotiation MMD, returning:
     196                 :            :  * - positive if auto-negotiation is complete
     197                 :            :  * - negative errno code on error
     198                 :            :  * - zero otherwise
     199                 :            :  */
     200                 :          0 : int genphy_c45_aneg_done(struct phy_device *phydev)
     201                 :            : {
     202                 :          0 :         int val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1);
     203                 :            : 
     204         [ #  # ]:          0 :         return val < 0 ? val : val & MDIO_AN_STAT1_COMPLETE ? 1 : 0;
     205                 :            : }
     206                 :            : EXPORT_SYMBOL_GPL(genphy_c45_aneg_done);
     207                 :            : 
     208                 :            : /**
     209                 :            :  * genphy_c45_read_link - read the overall link status from the MMDs
     210                 :            :  * @phydev: target phy_device struct
     211                 :            :  *
     212                 :            :  * Read the link status from the specified MMDs, and if they all indicate
     213                 :            :  * that the link is up, set phydev->link to 1.  If an error is encountered,
     214                 :            :  * a negative errno will be returned, otherwise zero.
     215                 :            :  */
     216                 :          0 : int genphy_c45_read_link(struct phy_device *phydev)
     217                 :            : {
     218                 :          0 :         u32 mmd_mask = MDIO_DEVS_PMAPMD;
     219                 :          0 :         int val, devad;
     220                 :          0 :         bool link = true;
     221                 :            : 
     222         [ #  # ]:          0 :         if (phydev->c45_ids.devices_in_package & MDIO_DEVS_AN) {
     223                 :          0 :                 val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1);
     224         [ #  # ]:          0 :                 if (val < 0)
     225                 :            :                         return val;
     226                 :            : 
     227                 :            :                 /* Autoneg is being started, therefore disregard current
     228                 :            :                  * link status and report link as down.
     229                 :            :                  */
     230         [ #  # ]:          0 :                 if (val & MDIO_AN_CTRL1_RESTART) {
     231                 :          0 :                         phydev->link = 0;
     232                 :          0 :                         return 0;
     233                 :            :                 }
     234                 :            :         }
     235                 :            : 
     236         [ #  # ]:          0 :         while (mmd_mask && link) {
     237         [ #  # ]:          0 :                 devad = __ffs(mmd_mask);
     238                 :            :                 mmd_mask &= ~BIT(devad);
     239                 :            : 
     240                 :            :                 /* The link state is latched low so that momentary link
     241                 :            :                  * drops can be detected. Do not double-read the status
     242                 :            :                  * in polling mode to detect such short link drops.
     243                 :            :                  */
     244         [ #  # ]:          0 :                 if (!phy_polling_mode(phydev)) {
     245                 :          0 :                         val = phy_read_mmd(phydev, devad, MDIO_STAT1);
     246         [ #  # ]:          0 :                         if (val < 0)
     247                 :          0 :                                 return val;
     248         [ #  # ]:          0 :                         else if (val & MDIO_STAT1_LSTATUS)
     249                 :          0 :                                 continue;
     250                 :            :                 }
     251                 :            : 
     252                 :          0 :                 val = phy_read_mmd(phydev, devad, MDIO_STAT1);
     253         [ #  # ]:          0 :                 if (val < 0)
     254                 :          0 :                         return val;
     255                 :            : 
     256         [ #  # ]:          0 :                 if (!(val & MDIO_STAT1_LSTATUS))
     257                 :          0 :                         link = false;
     258                 :            :         }
     259                 :            : 
     260                 :          0 :         phydev->link = link;
     261                 :            : 
     262                 :          0 :         return 0;
     263                 :            : }
     264                 :            : EXPORT_SYMBOL_GPL(genphy_c45_read_link);
     265                 :            : 
     266                 :            : /**
     267                 :            :  * genphy_c45_read_lpa - read the link partner advertisement and pause
     268                 :            :  * @phydev: target phy_device struct
     269                 :            :  *
     270                 :            :  * Read the Clause 45 defined base (7.19) and 10G (7.33) status registers,
     271                 :            :  * filling in the link partner advertisement, pause and asym_pause members
     272                 :            :  * in @phydev.  This assumes that the auto-negotiation MMD is present, and
     273                 :            :  * the backplane bit (7.48.0) is clear.  Clause 45 PHY drivers are expected
     274                 :            :  * to fill in the remainder of the link partner advert from vendor registers.
     275                 :            :  */
     276                 :          0 : int genphy_c45_read_lpa(struct phy_device *phydev)
     277                 :            : {
     278                 :          0 :         int val;
     279                 :            : 
     280                 :          0 :         val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1);
     281         [ #  # ]:          0 :         if (val < 0)
     282                 :            :                 return val;
     283                 :            : 
     284         [ #  # ]:          0 :         if (!(val & MDIO_AN_STAT1_COMPLETE)) {
     285                 :          0 :                 linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
     286                 :          0 :                                    phydev->lp_advertising);
     287                 :          0 :                 mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, 0);
     288                 :          0 :                 mii_adv_mod_linkmode_adv_t(phydev->lp_advertising, 0);
     289                 :          0 :                 phydev->pause = 0;
     290                 :          0 :                 phydev->asym_pause = 0;
     291                 :            : 
     292                 :          0 :                 return 0;
     293                 :            :         }
     294                 :            : 
     295                 :          0 :         linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->lp_advertising,
     296                 :            :                          val & MDIO_AN_STAT1_LPABLE);
     297                 :            : 
     298                 :            :         /* Read the link partner's base page advertisement */
     299                 :          0 :         val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_LPA);
     300         [ #  # ]:          0 :         if (val < 0)
     301                 :            :                 return val;
     302                 :            : 
     303                 :          0 :         mii_adv_mod_linkmode_adv_t(phydev->lp_advertising, val);
     304                 :          0 :         phydev->pause = val & LPA_PAUSE_CAP ? 1 : 0;
     305                 :          0 :         phydev->asym_pause = val & LPA_PAUSE_ASYM ? 1 : 0;
     306                 :            : 
     307                 :            :         /* Read the link partner's 10G advertisement */
     308                 :          0 :         val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_STAT);
     309         [ #  # ]:          0 :         if (val < 0)
     310                 :            :                 return val;
     311                 :            : 
     312                 :          0 :         mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, val);
     313                 :            : 
     314                 :          0 :         return 0;
     315                 :            : }
     316                 :            : EXPORT_SYMBOL_GPL(genphy_c45_read_lpa);
     317                 :            : 
     318                 :            : /**
     319                 :            :  * genphy_c45_read_pma - read link speed etc from PMA
     320                 :            :  * @phydev: target phy_device struct
     321                 :            :  */
     322                 :          0 : int genphy_c45_read_pma(struct phy_device *phydev)
     323                 :            : {
     324                 :          0 :         int val;
     325                 :            : 
     326                 :          0 :         linkmode_zero(phydev->lp_advertising);
     327                 :            : 
     328                 :          0 :         val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL1);
     329         [ #  # ]:          0 :         if (val < 0)
     330                 :            :                 return val;
     331                 :            : 
     332   [ #  #  #  #  :          0 :         switch (val & MDIO_CTRL1_SPEEDSEL) {
                #  #  # ]
     333                 :          0 :         case 0:
     334                 :          0 :                 phydev->speed = SPEED_10;
     335                 :          0 :                 break;
     336                 :          0 :         case MDIO_PMA_CTRL1_SPEED100:
     337                 :          0 :                 phydev->speed = SPEED_100;
     338                 :          0 :                 break;
     339                 :          0 :         case MDIO_PMA_CTRL1_SPEED1000:
     340                 :          0 :                 phydev->speed = SPEED_1000;
     341                 :          0 :                 break;
     342                 :          0 :         case MDIO_CTRL1_SPEED2_5G:
     343                 :          0 :                 phydev->speed = SPEED_2500;
     344                 :          0 :                 break;
     345                 :          0 :         case MDIO_CTRL1_SPEED5G:
     346                 :          0 :                 phydev->speed = SPEED_5000;
     347                 :          0 :                 break;
     348                 :          0 :         case MDIO_CTRL1_SPEED10G:
     349                 :          0 :                 phydev->speed = SPEED_10000;
     350                 :          0 :                 break;
     351                 :          0 :         default:
     352                 :          0 :                 phydev->speed = SPEED_UNKNOWN;
     353                 :          0 :                 break;
     354                 :            :         }
     355                 :            : 
     356                 :          0 :         phydev->duplex = DUPLEX_FULL;
     357                 :            : 
     358                 :          0 :         return 0;
     359                 :            : }
     360                 :            : EXPORT_SYMBOL_GPL(genphy_c45_read_pma);
     361                 :            : 
     362                 :            : /**
     363                 :            :  * genphy_c45_read_mdix - read mdix status from PMA
     364                 :            :  * @phydev: target phy_device struct
     365                 :            :  */
     366                 :          0 : int genphy_c45_read_mdix(struct phy_device *phydev)
     367                 :            : {
     368                 :          0 :         int val;
     369                 :            : 
     370         [ #  # ]:          0 :         if (phydev->speed == SPEED_10000) {
     371                 :          0 :                 val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD,
     372                 :            :                                    MDIO_PMA_10GBT_SWAPPOL);
     373         [ #  # ]:          0 :                 if (val < 0)
     374                 :            :                         return val;
     375                 :            : 
     376      [ #  #  # ]:          0 :                 switch (val) {
     377                 :          0 :                 case MDIO_PMA_10GBT_SWAPPOL_ABNX | MDIO_PMA_10GBT_SWAPPOL_CDNX:
     378                 :          0 :                         phydev->mdix = ETH_TP_MDI;
     379                 :          0 :                         break;
     380                 :            : 
     381                 :          0 :                 case 0:
     382                 :          0 :                         phydev->mdix = ETH_TP_MDI_X;
     383                 :          0 :                         break;
     384                 :            : 
     385                 :          0 :                 default:
     386                 :          0 :                         phydev->mdix = ETH_TP_MDI_INVALID;
     387                 :          0 :                         break;
     388                 :            :                 }
     389                 :          0 :         }
     390                 :            : 
     391                 :            :         return 0;
     392                 :            : }
     393                 :            : EXPORT_SYMBOL_GPL(genphy_c45_read_mdix);
     394                 :            : 
     395                 :            : /**
     396                 :            :  * genphy_c45_pma_read_abilities - read supported link modes from PMA
     397                 :            :  * @phydev: target phy_device struct
     398                 :            :  *
     399                 :            :  * Read the supported link modes from the PMA Status 2 (1.8) register. If bit
     400                 :            :  * 1.8.9 is set, the list of supported modes is build using the values in the
     401                 :            :  * PMA Extended Abilities (1.11) register, indicating 1000BASET an 10G related
     402                 :            :  * modes. If bit 1.11.14 is set, then the list is also extended with the modes
     403                 :            :  * in the 2.5G/5G PMA Extended register (1.21), indicating if 2.5GBASET and
     404                 :            :  * 5GBASET are supported.
     405                 :            :  */
     406                 :          0 : int genphy_c45_pma_read_abilities(struct phy_device *phydev)
     407                 :            : {
     408                 :          0 :         int val;
     409                 :            : 
     410                 :          0 :         linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported);
     411         [ #  # ]:          0 :         if (phydev->c45_ids.devices_in_package & MDIO_DEVS_AN) {
     412                 :          0 :                 val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1);
     413         [ #  # ]:          0 :                 if (val < 0)
     414                 :            :                         return val;
     415                 :            : 
     416         [ #  # ]:          0 :                 if (val & MDIO_AN_STAT1_ABLE)
     417                 :          0 :                         linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
     418                 :            :                                          phydev->supported);
     419                 :            :         }
     420                 :            : 
     421                 :          0 :         val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_STAT2);
     422         [ #  # ]:          0 :         if (val < 0)
     423                 :            :                 return val;
     424                 :            : 
     425                 :          0 :         linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseSR_Full_BIT,
     426                 :            :                          phydev->supported,
     427                 :            :                          val & MDIO_PMA_STAT2_10GBSR);
     428                 :            : 
     429                 :          0 :         linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseLR_Full_BIT,
     430                 :            :                          phydev->supported,
     431                 :            :                          val & MDIO_PMA_STAT2_10GBLR);
     432                 :            : 
     433                 :          0 :         linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseER_Full_BIT,
     434                 :            :                          phydev->supported,
     435                 :            :                          val & MDIO_PMA_STAT2_10GBER);
     436                 :            : 
     437         [ #  # ]:          0 :         if (val & MDIO_PMA_STAT2_EXTABLE) {
     438                 :          0 :                 val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_EXTABLE);
     439         [ #  # ]:          0 :                 if (val < 0)
     440                 :            :                         return val;
     441                 :            : 
     442                 :          0 :                 linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT,
     443                 :            :                                  phydev->supported,
     444                 :            :                                  val & MDIO_PMA_EXTABLE_10GBLRM);
     445                 :          0 :                 linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
     446                 :            :                                  phydev->supported,
     447                 :            :                                  val & MDIO_PMA_EXTABLE_10GBT);
     448                 :          0 :                 linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
     449                 :            :                                  phydev->supported,
     450                 :            :                                  val & MDIO_PMA_EXTABLE_10GBKX4);
     451                 :          0 :                 linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
     452                 :            :                                  phydev->supported,
     453                 :            :                                  val & MDIO_PMA_EXTABLE_10GBKR);
     454                 :          0 :                 linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
     455                 :            :                                  phydev->supported,
     456                 :            :                                  val & MDIO_PMA_EXTABLE_1000BT);
     457                 :          0 :                 linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
     458                 :            :                                  phydev->supported,
     459                 :            :                                  val & MDIO_PMA_EXTABLE_1000BKX);
     460                 :            : 
     461                 :          0 :                 linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
     462                 :            :                                  phydev->supported,
     463                 :            :                                  val & MDIO_PMA_EXTABLE_100BTX);
     464                 :          0 :                 linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT,
     465                 :            :                                  phydev->supported,
     466                 :            :                                  val & MDIO_PMA_EXTABLE_100BTX);
     467                 :            : 
     468                 :          0 :                 linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT,
     469                 :            :                                  phydev->supported,
     470                 :            :                                  val & MDIO_PMA_EXTABLE_10BT);
     471                 :          0 :                 linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT,
     472                 :            :                                  phydev->supported,
     473                 :            :                                  val & MDIO_PMA_EXTABLE_10BT);
     474                 :            : 
     475         [ #  # ]:          0 :                 if (val & MDIO_PMA_EXTABLE_NBT) {
     476                 :          0 :                         val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD,
     477                 :            :                                            MDIO_PMA_NG_EXTABLE);
     478         [ #  # ]:          0 :                         if (val < 0)
     479                 :            :                                 return val;
     480                 :            : 
     481                 :          0 :                         linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
     482                 :            :                                          phydev->supported,
     483                 :            :                                          val & MDIO_PMA_NG_EXTABLE_2_5GBT);
     484                 :            : 
     485                 :          0 :                         linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
     486                 :            :                                          phydev->supported,
     487                 :            :                                          val & MDIO_PMA_NG_EXTABLE_5GBT);
     488                 :            :                 }
     489                 :            :         }
     490                 :            : 
     491                 :            :         return 0;
     492                 :            : }
     493                 :            : EXPORT_SYMBOL_GPL(genphy_c45_pma_read_abilities);
     494                 :            : 
     495                 :            : /**
     496                 :            :  * genphy_c45_read_status - read PHY status
     497                 :            :  * @phydev: target phy_device struct
     498                 :            :  *
     499                 :            :  * Reads status from PHY and sets phy_device members accordingly.
     500                 :            :  */
     501                 :          0 : int genphy_c45_read_status(struct phy_device *phydev)
     502                 :            : {
     503                 :          0 :         int ret;
     504                 :            : 
     505                 :          0 :         ret = genphy_c45_read_link(phydev);
     506         [ #  # ]:          0 :         if (ret)
     507                 :            :                 return ret;
     508                 :            : 
     509                 :          0 :         phydev->speed = SPEED_UNKNOWN;
     510                 :          0 :         phydev->duplex = DUPLEX_UNKNOWN;
     511                 :          0 :         phydev->pause = 0;
     512                 :          0 :         phydev->asym_pause = 0;
     513                 :            : 
     514         [ #  # ]:          0 :         if (phydev->autoneg == AUTONEG_ENABLE) {
     515                 :          0 :                 ret = genphy_c45_read_lpa(phydev);
     516         [ #  # ]:          0 :                 if (ret)
     517                 :            :                         return ret;
     518                 :            : 
     519                 :          0 :                 phy_resolve_aneg_linkmode(phydev);
     520                 :            :         } else {
     521                 :          0 :                 ret = genphy_c45_read_pma(phydev);
     522                 :            :         }
     523                 :            : 
     524                 :            :         return ret;
     525                 :            : }
     526                 :            : EXPORT_SYMBOL_GPL(genphy_c45_read_status);
     527                 :            : 
     528                 :            : /**
     529                 :            :  * genphy_c45_config_aneg - restart auto-negotiation or forced setup
     530                 :            :  * @phydev: target phy_device struct
     531                 :            :  *
     532                 :            :  * Description: If auto-negotiation is enabled, we configure the
     533                 :            :  *   advertising, and then restart auto-negotiation.  If it is not
     534                 :            :  *   enabled, then we force a configuration.
     535                 :            :  */
     536                 :          0 : int genphy_c45_config_aneg(struct phy_device *phydev)
     537                 :            : {
     538                 :          0 :         bool changed = false;
     539                 :          0 :         int ret;
     540                 :            : 
     541         [ #  # ]:          0 :         if (phydev->autoneg == AUTONEG_DISABLE)
     542                 :          0 :                 return genphy_c45_pma_setup_forced(phydev);
     543                 :            : 
     544                 :          0 :         ret = genphy_c45_an_config_aneg(phydev);
     545         [ #  # ]:          0 :         if (ret < 0)
     546                 :            :                 return ret;
     547         [ #  # ]:          0 :         if (ret > 0)
     548                 :          0 :                 changed = true;
     549                 :            : 
     550                 :          0 :         return genphy_c45_check_and_restart_aneg(phydev, changed);
     551                 :            : }
     552                 :            : EXPORT_SYMBOL_GPL(genphy_c45_config_aneg);
     553                 :            : 
     554                 :            : /* The gen10g_* functions are the old Clause 45 stub */
     555                 :            : 
     556                 :          0 : int gen10g_config_aneg(struct phy_device *phydev)
     557                 :            : {
     558                 :          0 :         return 0;
     559                 :            : }
     560                 :            : EXPORT_SYMBOL_GPL(gen10g_config_aneg);
     561                 :            : 
     562                 :            : struct phy_driver genphy_c45_driver = {
     563                 :            :         .phy_id         = 0xffffffff,
     564                 :            :         .phy_id_mask    = 0xffffffff,
     565                 :            :         .name           = "Generic Clause 45 PHY",
     566                 :            :         .soft_reset     = genphy_no_soft_reset,
     567                 :            :         .read_status    = genphy_c45_read_status,
     568                 :            : };

Generated by: LCOV version 1.14