LCOV - code coverage report
Current view: top level - drivers/net/phy - phy.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 74 454 16.3 %
Date: 2022-04-01 14:35:51 Functions: 5 40 12.5 %
Branches: 26 280 9.3 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0+
       2                 :            : /* Framework for configuring and reading PHY devices
       3                 :            :  * Based on code in sungem_phy.c and gianfar_phy.c
       4                 :            :  *
       5                 :            :  * Author: Andy Fleming
       6                 :            :  *
       7                 :            :  * Copyright (c) 2004 Freescale Semiconductor, Inc.
       8                 :            :  * Copyright (c) 2006, 2007  Maciej W. Rozycki
       9                 :            :  */
      10                 :            : 
      11                 :            : #include <linux/kernel.h>
      12                 :            : #include <linux/string.h>
      13                 :            : #include <linux/errno.h>
      14                 :            : #include <linux/unistd.h>
      15                 :            : #include <linux/interrupt.h>
      16                 :            : #include <linux/delay.h>
      17                 :            : #include <linux/netdevice.h>
      18                 :            : #include <linux/etherdevice.h>
      19                 :            : #include <linux/skbuff.h>
      20                 :            : #include <linux/mm.h>
      21                 :            : #include <linux/module.h>
      22                 :            : #include <linux/mii.h>
      23                 :            : #include <linux/ethtool.h>
      24                 :            : #include <linux/phy.h>
      25                 :            : #include <linux/phy_led_triggers.h>
      26                 :            : #include <linux/sfp.h>
      27                 :            : #include <linux/workqueue.h>
      28                 :            : #include <linux/mdio.h>
      29                 :            : #include <linux/io.h>
      30                 :            : #include <linux/uaccess.h>
      31                 :            : #include <linux/atomic.h>
      32                 :            : 
      33                 :            : #define PHY_STATE_TIME  HZ
      34                 :            : 
      35                 :            : #define PHY_STATE_STR(_state)                   \
      36                 :            :         case PHY_##_state:                      \
      37                 :            :                 return __stringify(_state);     \
      38                 :            : 
      39                 :          0 : static const char *phy_state_to_str(enum phy_state st)
      40                 :            : {
      41                 :          0 :         switch (st) {
      42                 :            :         PHY_STATE_STR(DOWN)
      43                 :            :         PHY_STATE_STR(READY)
      44                 :            :         PHY_STATE_STR(UP)
      45                 :            :         PHY_STATE_STR(RUNNING)
      46                 :            :         PHY_STATE_STR(NOLINK)
      47                 :            :         PHY_STATE_STR(HALTED)
      48                 :            :         }
      49                 :            : 
      50                 :            :         return NULL;
      51                 :            : }
      52                 :            : 
      53                 :          0 : static void phy_link_up(struct phy_device *phydev)
      54                 :            : {
      55                 :          0 :         phydev->phy_link_change(phydev, true, true);
      56                 :          0 :         phy_led_trigger_change_speed(phydev);
      57                 :          0 : }
      58                 :            : 
      59                 :         21 : static void phy_link_down(struct phy_device *phydev, bool do_carrier)
      60                 :            : {
      61                 :         21 :         phydev->phy_link_change(phydev, false, do_carrier);
      62                 :         21 :         phy_led_trigger_change_speed(phydev);
      63                 :         21 : }
      64                 :            : 
      65                 :          0 : static const char *phy_pause_str(struct phy_device *phydev)
      66                 :            : {
      67                 :          0 :         bool local_pause, local_asym_pause;
      68                 :            : 
      69         [ #  # ]:          0 :         if (phydev->autoneg == AUTONEG_DISABLE)
      70                 :          0 :                 goto no_pause;
      71                 :            : 
      72                 :          0 :         local_pause = linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT,
      73                 :          0 :                                         phydev->advertising);
      74                 :          0 :         local_asym_pause = linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
      75                 :            :                                              phydev->advertising);
      76                 :            : 
      77   [ #  #  #  # ]:          0 :         if (local_pause && phydev->pause)
      78                 :            :                 return "rx/tx";
      79                 :            : 
      80   [ #  #  #  # ]:          0 :         if (local_asym_pause && phydev->asym_pause) {
      81         [ #  # ]:          0 :                 if (local_pause)
      82                 :            :                         return "rx";
      83         [ #  # ]:          0 :                 if (phydev->pause)
      84                 :          0 :                         return "tx";
      85                 :            :         }
      86                 :            : 
      87                 :          0 : no_pause:
      88                 :            :         return "off";
      89                 :            : }
      90                 :            : 
      91                 :            : /**
      92                 :            :  * phy_print_status - Convenience function to print out the current phy status
      93                 :            :  * @phydev: the phy_device struct
      94                 :            :  */
      95                 :          0 : void phy_print_status(struct phy_device *phydev)
      96                 :            : {
      97         [ #  # ]:          0 :         if (phydev->link) {
      98                 :          0 :                 netdev_info(phydev->attached_dev,
      99                 :            :                         "Link is Up - %s/%s - flow control %s\n",
     100                 :            :                         phy_speed_to_str(phydev->speed),
     101                 :          0 :                         phy_duplex_to_str(phydev->duplex),
     102                 :            :                         phy_pause_str(phydev));
     103                 :            :         } else  {
     104                 :          0 :                 netdev_info(phydev->attached_dev, "Link is Down\n");
     105                 :            :         }
     106                 :          0 : }
     107                 :            : EXPORT_SYMBOL(phy_print_status);
     108                 :            : 
     109                 :            : /**
     110                 :            :  * phy_clear_interrupt - Ack the phy device's interrupt
     111                 :            :  * @phydev: the phy_device struct
     112                 :            :  *
     113                 :            :  * If the @phydev driver has an ack_interrupt function, call it to
     114                 :            :  * ack and clear the phy device's interrupt.
     115                 :            :  *
     116                 :            :  * Returns 0 on success or < 0 on error.
     117                 :            :  */
     118                 :          0 : static int phy_clear_interrupt(struct phy_device *phydev)
     119                 :            : {
     120         [ #  # ]:          0 :         if (phydev->drv->ack_interrupt)
     121                 :          0 :                 return phydev->drv->ack_interrupt(phydev);
     122                 :            : 
     123                 :            :         return 0;
     124                 :            : }
     125                 :            : 
     126                 :            : /**
     127                 :            :  * phy_config_interrupt - configure the PHY device for the requested interrupts
     128                 :            :  * @phydev: the phy_device struct
     129                 :            :  * @interrupts: interrupt flags to configure for this @phydev
     130                 :            :  *
     131                 :            :  * Returns 0 on success or < 0 on error.
     132                 :            :  */
     133                 :          0 : static int phy_config_interrupt(struct phy_device *phydev, bool interrupts)
     134                 :            : {
     135                 :          0 :         phydev->interrupts = interrupts ? 1 : 0;
     136                 :          0 :         if (phydev->drv->config_intr)
     137                 :          0 :                 return phydev->drv->config_intr(phydev);
     138                 :            : 
     139                 :            :         return 0;
     140                 :            : }
     141                 :            : 
     142                 :            : /**
     143                 :            :  * phy_restart_aneg - restart auto-negotiation
     144                 :            :  * @phydev: target phy_device struct
     145                 :            :  *
     146                 :            :  * Restart the autonegotiation on @phydev.  Returns >= 0 on success or
     147                 :            :  * negative errno on error.
     148                 :            :  */
     149                 :          0 : int phy_restart_aneg(struct phy_device *phydev)
     150                 :            : {
     151                 :          0 :         int ret;
     152                 :            : 
     153   [ #  #  #  # ]:          0 :         if (phydev->is_c45 && !(phydev->c45_ids.devices_in_package & BIT(0)))
     154                 :          0 :                 ret = genphy_c45_restart_aneg(phydev);
     155                 :            :         else
     156                 :          0 :                 ret = genphy_restart_aneg(phydev);
     157                 :            : 
     158                 :          0 :         return ret;
     159                 :            : }
     160                 :            : EXPORT_SYMBOL_GPL(phy_restart_aneg);
     161                 :            : 
     162                 :            : /**
     163                 :            :  * phy_aneg_done - return auto-negotiation status
     164                 :            :  * @phydev: target phy_device struct
     165                 :            :  *
     166                 :            :  * Description: Return the auto-negotiation status from this @phydev
     167                 :            :  * Returns > 0 on success or < 0 on error. 0 means that auto-negotiation
     168                 :            :  * is still pending.
     169                 :            :  */
     170                 :          0 : int phy_aneg_done(struct phy_device *phydev)
     171                 :            : {
     172   [ #  #  #  # ]:          0 :         if (phydev->drv && phydev->drv->aneg_done)
     173                 :          0 :                 return phydev->drv->aneg_done(phydev);
     174         [ #  # ]:          0 :         else if (phydev->is_c45)
     175                 :          0 :                 return genphy_c45_aneg_done(phydev);
     176                 :            :         else
     177                 :          0 :                 return genphy_aneg_done(phydev);
     178                 :            : }
     179                 :            : EXPORT_SYMBOL(phy_aneg_done);
     180                 :            : 
     181                 :            : /**
     182                 :            :  * phy_find_valid - find a PHY setting that matches the requested parameters
     183                 :            :  * @speed: desired speed
     184                 :            :  * @duplex: desired duplex
     185                 :            :  * @supported: mask of supported link modes
     186                 :            :  *
     187                 :            :  * Locate a supported phy setting that is, in priority order:
     188                 :            :  * - an exact match for the specified speed and duplex mode
     189                 :            :  * - a match for the specified speed, or slower speed
     190                 :            :  * - the slowest supported speed
     191                 :            :  * Returns the matched phy_setting entry, or %NULL if no supported phy
     192                 :            :  * settings were found.
     193                 :            :  */
     194                 :            : static const struct phy_setting *
     195                 :          0 : phy_find_valid(int speed, int duplex, unsigned long *supported)
     196                 :            : {
     197                 :          0 :         return phy_lookup_setting(speed, duplex, supported, false);
     198                 :            : }
     199                 :            : 
     200                 :            : /**
     201                 :            :  * phy_supported_speeds - return all speeds currently supported by a phy device
     202                 :            :  * @phy: The phy device to return supported speeds of.
     203                 :            :  * @speeds: buffer to store supported speeds in.
     204                 :            :  * @size:   size of speeds buffer.
     205                 :            :  *
     206                 :            :  * Description: Returns the number of supported speeds, and fills the speeds
     207                 :            :  * buffer with the supported speeds. If speeds buffer is too small to contain
     208                 :            :  * all currently supported speeds, will return as many speeds as can fit.
     209                 :            :  */
     210                 :          0 : unsigned int phy_supported_speeds(struct phy_device *phy,
     211                 :            :                                   unsigned int *speeds,
     212                 :            :                                   unsigned int size)
     213                 :            : {
     214                 :          0 :         return phy_speeds(speeds, size, phy->supported);
     215                 :            : }
     216                 :            : 
     217                 :            : /**
     218                 :            :  * phy_check_valid - check if there is a valid PHY setting which matches
     219                 :            :  *                   speed, duplex, and feature mask
     220                 :            :  * @speed: speed to match
     221                 :            :  * @duplex: duplex to match
     222                 :            :  * @features: A mask of the valid settings
     223                 :            :  *
     224                 :            :  * Description: Returns true if there is a valid setting, false otherwise.
     225                 :            :  */
     226                 :          0 : static inline bool phy_check_valid(int speed, int duplex,
     227                 :            :                                    unsigned long *features)
     228                 :            : {
     229                 :          0 :         return !!phy_lookup_setting(speed, duplex, features, true);
     230                 :            : }
     231                 :            : 
     232                 :            : /**
     233                 :            :  * phy_sanitize_settings - make sure the PHY is set to supported speed and duplex
     234                 :            :  * @phydev: the target phy_device struct
     235                 :            :  *
     236                 :            :  * Description: Make sure the PHY is set to supported speeds and
     237                 :            :  *   duplexes.  Drop down by one in this order:  1000/FULL,
     238                 :            :  *   1000/HALF, 100/FULL, 100/HALF, 10/FULL, 10/HALF.
     239                 :            :  */
     240                 :          0 : static void phy_sanitize_settings(struct phy_device *phydev)
     241                 :            : {
     242                 :          0 :         const struct phy_setting *setting;
     243                 :            : 
     244                 :          0 :         setting = phy_find_valid(phydev->speed, phydev->duplex,
     245                 :          0 :                                  phydev->supported);
     246         [ #  # ]:          0 :         if (setting) {
     247                 :          0 :                 phydev->speed = setting->speed;
     248                 :          0 :                 phydev->duplex = setting->duplex;
     249                 :            :         } else {
     250                 :            :                 /* We failed to find anything (no supported speeds?) */
     251                 :          0 :                 phydev->speed = SPEED_UNKNOWN;
     252                 :          0 :                 phydev->duplex = DUPLEX_UNKNOWN;
     253                 :            :         }
     254                 :          0 : }
     255                 :            : 
     256                 :          0 : int phy_ethtool_ksettings_set(struct phy_device *phydev,
     257                 :            :                               const struct ethtool_link_ksettings *cmd)
     258                 :            : {
     259                 :          0 :         __ETHTOOL_DECLARE_LINK_MODE_MASK(advertising);
     260                 :          0 :         u8 autoneg = cmd->base.autoneg;
     261                 :          0 :         u8 duplex = cmd->base.duplex;
     262                 :          0 :         u32 speed = cmd->base.speed;
     263                 :            : 
     264         [ #  # ]:          0 :         if (cmd->base.phy_address != phydev->mdio.addr)
     265                 :            :                 return -EINVAL;
     266                 :            : 
     267                 :          0 :         linkmode_copy(advertising, cmd->link_modes.advertising);
     268                 :            : 
     269                 :            :         /* We make sure that we don't pass unsupported values in to the PHY */
     270                 :          0 :         linkmode_and(advertising, advertising, phydev->supported);
     271                 :            : 
     272                 :            :         /* Verify the settings we care about. */
     273         [ #  # ]:          0 :         if (autoneg != AUTONEG_ENABLE && autoneg != AUTONEG_DISABLE)
     274                 :            :                 return -EINVAL;
     275                 :            : 
     276   [ #  #  #  # ]:          0 :         if (autoneg == AUTONEG_ENABLE && linkmode_empty(advertising))
     277                 :            :                 return -EINVAL;
     278                 :            : 
     279         [ #  # ]:          0 :         if (autoneg == AUTONEG_DISABLE &&
     280                 :          0 :             ((speed != SPEED_1000 &&
     281   [ #  #  #  # ]:          0 :               speed != SPEED_100 &&
     282         [ #  # ]:          0 :               speed != SPEED_10) ||
     283                 :            :              (duplex != DUPLEX_HALF &&
     284                 :            :               duplex != DUPLEX_FULL)))
     285                 :            :                 return -EINVAL;
     286                 :            : 
     287                 :          0 :         phydev->autoneg = autoneg;
     288                 :            : 
     289                 :          0 :         phydev->speed = speed;
     290                 :            : 
     291                 :          0 :         linkmode_copy(phydev->advertising, advertising);
     292                 :            : 
     293                 :          0 :         linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
     294                 :          0 :                          phydev->advertising, autoneg == AUTONEG_ENABLE);
     295                 :            : 
     296                 :          0 :         phydev->duplex = duplex;
     297                 :            : 
     298                 :          0 :         phydev->mdix_ctrl = cmd->base.eth_tp_mdix_ctrl;
     299                 :            : 
     300                 :            :         /* Restart the PHY */
     301                 :          0 :         phy_start_aneg(phydev);
     302                 :            : 
     303                 :          0 :         return 0;
     304                 :            : }
     305                 :            : EXPORT_SYMBOL(phy_ethtool_ksettings_set);
     306                 :            : 
     307                 :          0 : void phy_ethtool_ksettings_get(struct phy_device *phydev,
     308                 :            :                                struct ethtool_link_ksettings *cmd)
     309                 :            : {
     310         [ #  # ]:          0 :         linkmode_copy(cmd->link_modes.supported, phydev->supported);
     311                 :          0 :         linkmode_copy(cmd->link_modes.advertising, phydev->advertising);
     312                 :          0 :         linkmode_copy(cmd->link_modes.lp_advertising, phydev->lp_advertising);
     313                 :            : 
     314                 :          0 :         cmd->base.speed = phydev->speed;
     315                 :          0 :         cmd->base.duplex = phydev->duplex;
     316         [ #  # ]:          0 :         if (phydev->interface == PHY_INTERFACE_MODE_MOCA)
     317                 :          0 :                 cmd->base.port = PORT_BNC;
     318                 :            :         else
     319                 :          0 :                 cmd->base.port = PORT_MII;
     320                 :          0 :         cmd->base.transceiver = phy_is_internal(phydev) ?
     321                 :          0 :                                 XCVR_INTERNAL : XCVR_EXTERNAL;
     322                 :          0 :         cmd->base.phy_address = phydev->mdio.addr;
     323                 :          0 :         cmd->base.autoneg = phydev->autoneg;
     324                 :          0 :         cmd->base.eth_tp_mdix_ctrl = phydev->mdix_ctrl;
     325                 :          0 :         cmd->base.eth_tp_mdix = phydev->mdix;
     326                 :          0 : }
     327                 :            : EXPORT_SYMBOL(phy_ethtool_ksettings_get);
     328                 :            : 
     329                 :            : /**
     330                 :            :  * phy_mii_ioctl - generic PHY MII ioctl interface
     331                 :            :  * @phydev: the phy_device struct
     332                 :            :  * @ifr: &struct ifreq for socket ioctl's
     333                 :            :  * @cmd: ioctl cmd to execute
     334                 :            :  *
     335                 :            :  * Note that this function is currently incompatible with the
     336                 :            :  * PHYCONTROL layer.  It changes registers without regard to
     337                 :            :  * current state.  Use at own risk.
     338                 :            :  */
     339                 :          0 : int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd)
     340                 :            : {
     341   [ #  #  #  #  :          0 :         struct mii_ioctl_data *mii_data = if_mii(ifr);
                      # ]
     342                 :          0 :         u16 val = mii_data->val_in;
     343                 :          0 :         bool change_autoneg = false;
     344                 :          0 :         int prtad, devad;
     345                 :            : 
     346   [ #  #  #  #  :          0 :         switch (cmd) {
                      # ]
     347                 :          0 :         case SIOCGMIIPHY:
     348                 :          0 :                 mii_data->phy_id = phydev->mdio.addr;
     349                 :            :                 /* fall through */
     350                 :            : 
     351                 :          0 :         case SIOCGMIIREG:
     352         [ #  # ]:          0 :                 if (mdio_phy_id_is_c45(mii_data->phy_id)) {
     353                 :          0 :                         prtad = mdio_phy_id_prtad(mii_data->phy_id);
     354                 :          0 :                         devad = mdio_phy_id_devad(mii_data->phy_id);
     355                 :          0 :                         devad = MII_ADDR_C45 | devad << 16 | mii_data->reg_num;
     356                 :            :                 } else {
     357                 :          0 :                         prtad = mii_data->phy_id;
     358                 :          0 :                         devad = mii_data->reg_num;
     359                 :            :                 }
     360                 :          0 :                 mii_data->val_out = mdiobus_read(phydev->mdio.bus, prtad,
     361                 :            :                                                  devad);
     362                 :          0 :                 return 0;
     363                 :            : 
     364                 :          0 :         case SIOCSMIIREG:
     365         [ #  # ]:          0 :                 if (mdio_phy_id_is_c45(mii_data->phy_id)) {
     366                 :          0 :                         prtad = mdio_phy_id_prtad(mii_data->phy_id);
     367                 :          0 :                         devad = mdio_phy_id_devad(mii_data->phy_id);
     368                 :          0 :                         devad = MII_ADDR_C45 | devad << 16 | mii_data->reg_num;
     369                 :            :                 } else {
     370                 :          0 :                         prtad = mii_data->phy_id;
     371                 :          0 :                         devad = mii_data->reg_num;
     372                 :            :                 }
     373         [ #  # ]:          0 :                 if (prtad == phydev->mdio.addr) {
     374   [ #  #  #  # ]:          0 :                         switch (devad) {
     375                 :          0 :                         case MII_BMCR:
     376         [ #  # ]:          0 :                                 if ((val & (BMCR_RESET | BMCR_ANENABLE)) == 0) {
     377         [ #  # ]:          0 :                                         if (phydev->autoneg == AUTONEG_ENABLE)
     378                 :          0 :                                                 change_autoneg = true;
     379                 :          0 :                                         phydev->autoneg = AUTONEG_DISABLE;
     380         [ #  # ]:          0 :                                         if (val & BMCR_FULLDPLX)
     381                 :          0 :                                                 phydev->duplex = DUPLEX_FULL;
     382                 :            :                                         else
     383                 :          0 :                                                 phydev->duplex = DUPLEX_HALF;
     384         [ #  # ]:          0 :                                         if (val & BMCR_SPEED1000)
     385                 :          0 :                                                 phydev->speed = SPEED_1000;
     386         [ #  # ]:          0 :                                         else if (val & BMCR_SPEED100)
     387                 :          0 :                                                 phydev->speed = SPEED_100;
     388                 :          0 :                                         else phydev->speed = SPEED_10;
     389                 :            :                                 }
     390                 :            :                                 else {
     391         [ #  # ]:          0 :                                         if (phydev->autoneg == AUTONEG_DISABLE)
     392                 :          0 :                                                 change_autoneg = true;
     393                 :          0 :                                         phydev->autoneg = AUTONEG_ENABLE;
     394                 :            :                                 }
     395                 :            :                                 break;
     396                 :          0 :                         case MII_ADVERTISE:
     397                 :          0 :                                 mii_adv_mod_linkmode_adv_t(phydev->advertising,
     398                 :            :                                                            val);
     399                 :          0 :                                 change_autoneg = true;
     400                 :          0 :                                 break;
     401                 :          0 :                         case MII_CTRL1000:
     402                 :          0 :                                 mii_ctrl1000_mod_linkmode_adv_t(phydev->advertising,
     403                 :            :                                                                 val);
     404                 :          0 :                                 change_autoneg = true;
     405                 :          0 :                                 break;
     406                 :            :                         default:
     407                 :            :                                 /* do nothing */
     408                 :            :                                 break;
     409                 :            :                         }
     410                 :          0 :                 }
     411                 :            : 
     412                 :          0 :                 mdiobus_write(phydev->mdio.bus, prtad, devad, val);
     413                 :            : 
     414         [ #  # ]:          0 :                 if (prtad == phydev->mdio.addr &&
     415         [ #  # ]:          0 :                     devad == MII_BMCR &&
     416                 :            :                     val & BMCR_RESET)
     417                 :          0 :                         return phy_init_hw(phydev);
     418                 :            : 
     419         [ #  # ]:          0 :                 if (change_autoneg)
     420                 :          0 :                         return phy_start_aneg(phydev);
     421                 :            : 
     422                 :            :                 return 0;
     423                 :            : 
     424                 :          0 :         case SIOCSHWTSTAMP:
     425   [ #  #  #  # ]:          0 :                 if (phydev->mii_ts && phydev->mii_ts->hwtstamp)
     426                 :          0 :                         return phydev->mii_ts->hwtstamp(phydev->mii_ts, ifr);
     427                 :            :                 /* fall through */
     428                 :            : 
     429                 :            :         default:
     430                 :            :                 return -EOPNOTSUPP;
     431                 :            :         }
     432                 :            : }
     433                 :            : EXPORT_SYMBOL(phy_mii_ioctl);
     434                 :            : 
     435                 :            : /**
     436                 :            :  * phy_do_ioctl - generic ndo_do_ioctl implementation
     437                 :            :  * @dev: the net_device struct
     438                 :            :  * @ifr: &struct ifreq for socket ioctl's
     439                 :            :  * @cmd: ioctl cmd to execute
     440                 :            :  */
     441                 :          0 : int phy_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
     442                 :            : {
     443         [ #  # ]:          0 :         if (!dev->phydev)
     444                 :            :                 return -ENODEV;
     445                 :            : 
     446                 :          0 :         return phy_mii_ioctl(dev->phydev, ifr, cmd);
     447                 :            : }
     448                 :            : EXPORT_SYMBOL(phy_do_ioctl);
     449                 :            : 
     450                 :            : /* same as phy_do_ioctl, but ensures that net_device is running */
     451                 :          0 : int phy_do_ioctl_running(struct net_device *dev, struct ifreq *ifr, int cmd)
     452                 :            : {
     453         [ #  # ]:          0 :         if (!netif_running(dev))
     454                 :            :                 return -ENODEV;
     455                 :            : 
     456         [ #  # ]:          0 :         return phy_do_ioctl(dev, ifr, cmd);
     457                 :            : }
     458                 :            : EXPORT_SYMBOL(phy_do_ioctl_running);
     459                 :            : 
     460                 :         84 : void phy_queue_state_machine(struct phy_device *phydev, unsigned long jiffies)
     461                 :            : {
     462                 :          0 :         mod_delayed_work(system_power_efficient_wq, &phydev->state_queue,
     463                 :            :                          jiffies);
     464                 :         63 : }
     465                 :            : EXPORT_SYMBOL(phy_queue_state_machine);
     466                 :            : 
     467                 :         21 : static void phy_trigger_machine(struct phy_device *phydev)
     468                 :            : {
     469                 :         21 :         phy_queue_state_machine(phydev, 0);
     470                 :          0 : }
     471                 :            : 
     472                 :         21 : static int phy_config_aneg(struct phy_device *phydev)
     473                 :            : {
     474         [ -  + ]:         21 :         if (phydev->drv->config_aneg)
     475                 :          0 :                 return phydev->drv->config_aneg(phydev);
     476                 :            : 
     477                 :            :         /* Clause 45 PHYs that don't implement Clause 22 registers are not
     478                 :            :          * allowed to call genphy_config_aneg()
     479                 :            :          */
     480   [ -  +  -  - ]:         21 :         if (phydev->is_c45 && !(phydev->c45_ids.devices_in_package & BIT(0)))
     481                 :          0 :                 return genphy_c45_config_aneg(phydev);
     482                 :            : 
     483                 :         21 :         return genphy_config_aneg(phydev);
     484                 :            : }
     485                 :            : 
     486                 :            : /**
     487                 :            :  * phy_check_link_status - check link status and set state accordingly
     488                 :            :  * @phydev: the phy_device struct
     489                 :            :  *
     490                 :            :  * Description: Check for link and whether autoneg was triggered / is running
     491                 :            :  * and set state accordingly
     492                 :            :  */
     493                 :         63 : static int phy_check_link_status(struct phy_device *phydev)
     494                 :            : {
     495                 :         63 :         int err;
     496                 :            : 
     497         [ -  + ]:         63 :         WARN_ON(!mutex_is_locked(&phydev->lock));
     498                 :            : 
     499                 :            :         /* Keep previous state if loopback is enabled because some PHYs
     500                 :            :          * report that Link is Down when loopback is enabled.
     501                 :            :          */
     502         [ +  - ]:         63 :         if (phydev->loopback_enabled)
     503                 :            :                 return 0;
     504                 :            : 
     505                 :         63 :         err = phy_read_status(phydev);
     506         [ +  - ]:         63 :         if (err)
     507                 :            :                 return err;
     508                 :            : 
     509   [ -  +  -  - ]:         63 :         if (phydev->link && phydev->state != PHY_RUNNING) {
     510                 :          0 :                 phydev->state = PHY_RUNNING;
     511                 :          0 :                 phy_link_up(phydev);
     512   [ +  -  +  + ]:         63 :         } else if (!phydev->link && phydev->state != PHY_NOLINK) {
     513                 :         21 :                 phydev->state = PHY_NOLINK;
     514                 :         21 :                 phy_link_down(phydev, true);
     515                 :            :         }
     516                 :            : 
     517                 :            :         return 0;
     518                 :            : }
     519                 :            : 
     520                 :            : /**
     521                 :            :  * phy_start_aneg - start auto-negotiation for this PHY device
     522                 :            :  * @phydev: the phy_device struct
     523                 :            :  *
     524                 :            :  * Description: Sanitizes the settings (if we're not autonegotiating
     525                 :            :  *   them), and then calls the driver's config_aneg function.
     526                 :            :  *   If the PHYCONTROL Layer is operating, we change the state to
     527                 :            :  *   reflect the beginning of Auto-negotiation or forcing.
     528                 :            :  */
     529                 :         21 : int phy_start_aneg(struct phy_device *phydev)
     530                 :            : {
     531                 :         21 :         int err;
     532                 :            : 
     533         [ +  - ]:         21 :         if (!phydev->drv)
     534                 :            :                 return -EIO;
     535                 :            : 
     536                 :         21 :         mutex_lock(&phydev->lock);
     537                 :            : 
     538         [ -  + ]:         21 :         if (AUTONEG_DISABLE == phydev->autoneg)
     539                 :          0 :                 phy_sanitize_settings(phydev);
     540                 :            : 
     541                 :         21 :         err = phy_config_aneg(phydev);
     542         [ -  + ]:         21 :         if (err < 0)
     543                 :          0 :                 goto out_unlock;
     544                 :            : 
     545         [ -  + ]:         21 :         if (phy_is_started(phydev))
     546                 :         21 :                 err = phy_check_link_status(phydev);
     547                 :          0 : out_unlock:
     548                 :         21 :         mutex_unlock(&phydev->lock);
     549                 :            : 
     550                 :         21 :         return err;
     551                 :            : }
     552                 :            : EXPORT_SYMBOL(phy_start_aneg);
     553                 :            : 
     554                 :          0 : static int phy_poll_aneg_done(struct phy_device *phydev)
     555                 :            : {
     556                 :          0 :         unsigned int retries = 100;
     557                 :          0 :         int ret;
     558                 :            : 
     559                 :          0 :         do {
     560                 :          0 :                 msleep(100);
     561                 :          0 :                 ret = phy_aneg_done(phydev);
     562   [ #  #  #  # ]:          0 :         } while (!ret && --retries);
     563                 :            : 
     564         [ #  # ]:          0 :         if (!ret)
     565                 :            :                 return -ETIMEDOUT;
     566                 :            : 
     567                 :          0 :         return ret < 0 ? ret : 0;
     568                 :            : }
     569                 :            : 
     570                 :            : /**
     571                 :            :  * phy_speed_down - set speed to lowest speed supported by both link partners
     572                 :            :  * @phydev: the phy_device struct
     573                 :            :  * @sync: perform action synchronously
     574                 :            :  *
     575                 :            :  * Description: Typically used to save energy when waiting for a WoL packet
     576                 :            :  *
     577                 :            :  * WARNING: Setting sync to false may cause the system being unable to suspend
     578                 :            :  * in case the PHY generates an interrupt when finishing the autonegotiation.
     579                 :            :  * This interrupt may wake up the system immediately after suspend.
     580                 :            :  * Therefore use sync = false only if you're sure it's safe with the respective
     581                 :            :  * network chip.
     582                 :            :  */
     583                 :          0 : int phy_speed_down(struct phy_device *phydev, bool sync)
     584                 :            : {
     585                 :          0 :         __ETHTOOL_DECLARE_LINK_MODE_MASK(adv_tmp);
     586                 :          0 :         int ret;
     587                 :            : 
     588         [ #  # ]:          0 :         if (phydev->autoneg != AUTONEG_ENABLE)
     589                 :            :                 return 0;
     590                 :            : 
     591                 :          0 :         linkmode_copy(adv_tmp, phydev->advertising);
     592                 :            : 
     593                 :          0 :         ret = phy_speed_down_core(phydev);
     594         [ #  # ]:          0 :         if (ret)
     595                 :            :                 return ret;
     596                 :            : 
     597                 :          0 :         linkmode_copy(phydev->adv_old, adv_tmp);
     598                 :            : 
     599         [ #  # ]:          0 :         if (linkmode_equal(phydev->advertising, adv_tmp))
     600                 :            :                 return 0;
     601                 :            : 
     602                 :          0 :         ret = phy_config_aneg(phydev);
     603         [ #  # ]:          0 :         if (ret)
     604                 :            :                 return ret;
     605                 :            : 
     606         [ #  # ]:          0 :         return sync ? phy_poll_aneg_done(phydev) : 0;
     607                 :            : }
     608                 :            : EXPORT_SYMBOL_GPL(phy_speed_down);
     609                 :            : 
     610                 :            : /**
     611                 :            :  * phy_speed_up - (re)set advertised speeds to all supported speeds
     612                 :            :  * @phydev: the phy_device struct
     613                 :            :  *
     614                 :            :  * Description: Used to revert the effect of phy_speed_down
     615                 :            :  */
     616                 :          0 : int phy_speed_up(struct phy_device *phydev)
     617                 :            : {
     618                 :          0 :         __ETHTOOL_DECLARE_LINK_MODE_MASK(adv_tmp);
     619                 :            : 
     620         [ #  # ]:          0 :         if (phydev->autoneg != AUTONEG_ENABLE)
     621                 :            :                 return 0;
     622                 :            : 
     623         [ #  # ]:          0 :         if (linkmode_empty(phydev->adv_old))
     624                 :            :                 return 0;
     625                 :            : 
     626                 :          0 :         linkmode_copy(adv_tmp, phydev->advertising);
     627                 :          0 :         linkmode_copy(phydev->advertising, phydev->adv_old);
     628                 :          0 :         linkmode_zero(phydev->adv_old);
     629                 :            : 
     630         [ #  # ]:          0 :         if (linkmode_equal(phydev->advertising, adv_tmp))
     631                 :            :                 return 0;
     632                 :            : 
     633                 :          0 :         return phy_config_aneg(phydev);
     634                 :            : }
     635                 :            : EXPORT_SYMBOL_GPL(phy_speed_up);
     636                 :            : 
     637                 :            : /**
     638                 :            :  * phy_start_machine - start PHY state machine tracking
     639                 :            :  * @phydev: the phy_device struct
     640                 :            :  *
     641                 :            :  * Description: The PHY infrastructure can run a state machine
     642                 :            :  *   which tracks whether the PHY is starting up, negotiating,
     643                 :            :  *   etc.  This function starts the delayed workqueue which tracks
     644                 :            :  *   the state of the PHY. If you want to maintain your own state machine,
     645                 :            :  *   do not call this function.
     646                 :            :  */
     647                 :         21 : void phy_start_machine(struct phy_device *phydev)
     648                 :            : {
     649                 :          0 :         phy_trigger_machine(phydev);
     650                 :         21 : }
     651                 :            : EXPORT_SYMBOL_GPL(phy_start_machine);
     652                 :            : 
     653                 :            : /**
     654                 :            :  * phy_stop_machine - stop the PHY state machine tracking
     655                 :            :  * @phydev: target phy_device struct
     656                 :            :  *
     657                 :            :  * Description: Stops the state machine delayed workqueue, sets the
     658                 :            :  *   state to UP (unless it wasn't up yet). This function must be
     659                 :            :  *   called BEFORE phy_detach.
     660                 :            :  */
     661                 :          0 : void phy_stop_machine(struct phy_device *phydev)
     662                 :            : {
     663                 :          0 :         cancel_delayed_work_sync(&phydev->state_queue);
     664                 :            : 
     665                 :          0 :         mutex_lock(&phydev->lock);
     666         [ #  # ]:          0 :         if (phy_is_started(phydev))
     667                 :          0 :                 phydev->state = PHY_UP;
     668                 :          0 :         mutex_unlock(&phydev->lock);
     669                 :          0 : }
     670                 :            : 
     671                 :            : /**
     672                 :            :  * phy_error - enter HALTED state for this PHY device
     673                 :            :  * @phydev: target phy_device struct
     674                 :            :  *
     675                 :            :  * Moves the PHY to the HALTED state in response to a read
     676                 :            :  * or write error, and tells the controller the link is down.
     677                 :            :  * Must not be called from interrupt context, or while the
     678                 :            :  * phydev->lock is held.
     679                 :            :  */
     680                 :          0 : static void phy_error(struct phy_device *phydev)
     681                 :            : {
     682                 :          0 :         WARN_ON(1);
     683                 :            : 
     684                 :          0 :         mutex_lock(&phydev->lock);
     685                 :          0 :         phydev->state = PHY_HALTED;
     686                 :          0 :         mutex_unlock(&phydev->lock);
     687                 :            : 
     688                 :          0 :         phy_trigger_machine(phydev);
     689                 :          0 : }
     690                 :            : 
     691                 :            : /**
     692                 :            :  * phy_disable_interrupts - Disable the PHY interrupts from the PHY side
     693                 :            :  * @phydev: target phy_device struct
     694                 :            :  */
     695                 :          0 : static int phy_disable_interrupts(struct phy_device *phydev)
     696                 :            : {
     697                 :          0 :         int err;
     698                 :            : 
     699                 :            :         /* Disable PHY interrupts */
     700         [ #  # ]:          0 :         err = phy_config_interrupt(phydev, PHY_INTERRUPT_DISABLED);
     701         [ #  # ]:          0 :         if (err)
     702                 :            :                 return err;
     703                 :            : 
     704                 :            :         /* Clear the interrupt */
     705         [ #  # ]:          0 :         return phy_clear_interrupt(phydev);
     706                 :            : }
     707                 :            : 
     708                 :            : /**
     709                 :            :  * phy_interrupt - PHY interrupt handler
     710                 :            :  * @irq: interrupt line
     711                 :            :  * @phy_dat: phy_device pointer
     712                 :            :  *
     713                 :            :  * Description: Handle PHY interrupt
     714                 :            :  */
     715                 :          0 : static irqreturn_t phy_interrupt(int irq, void *phy_dat)
     716                 :            : {
     717                 :          0 :         struct phy_device *phydev = phy_dat;
     718                 :            : 
     719   [ #  #  #  # ]:          0 :         if (phydev->drv->did_interrupt && !phydev->drv->did_interrupt(phydev))
     720                 :            :                 return IRQ_NONE;
     721                 :            : 
     722         [ #  # ]:          0 :         if (phydev->drv->handle_interrupt) {
     723         [ #  # ]:          0 :                 if (phydev->drv->handle_interrupt(phydev))
     724                 :          0 :                         goto phy_err;
     725                 :            :         } else {
     726                 :            :                 /* reschedule state queue work to run as soon as possible */
     727                 :          0 :                 phy_trigger_machine(phydev);
     728                 :            :         }
     729                 :            : 
     730                 :            :         /* did_interrupt() may have cleared the interrupt already */
     731   [ #  #  #  # ]:          0 :         if (!phydev->drv->did_interrupt && phy_clear_interrupt(phydev))
     732                 :          0 :                 goto phy_err;
     733                 :            :         return IRQ_HANDLED;
     734                 :            : 
     735                 :          0 : phy_err:
     736                 :          0 :         phy_error(phydev);
     737                 :          0 :         return IRQ_NONE;
     738                 :            : }
     739                 :            : 
     740                 :            : /**
     741                 :            :  * phy_enable_interrupts - Enable the interrupts from the PHY side
     742                 :            :  * @phydev: target phy_device struct
     743                 :            :  */
     744                 :          0 : static int phy_enable_interrupts(struct phy_device *phydev)
     745                 :            : {
     746         [ #  # ]:          0 :         int err = phy_clear_interrupt(phydev);
     747                 :            : 
     748         [ #  # ]:          0 :         if (err < 0)
     749                 :            :                 return err;
     750                 :            : 
     751         [ #  # ]:          0 :         return phy_config_interrupt(phydev, PHY_INTERRUPT_ENABLED);
     752                 :            : }
     753                 :            : 
     754                 :            : /**
     755                 :            :  * phy_request_interrupt - request and enable interrupt for a PHY device
     756                 :            :  * @phydev: target phy_device struct
     757                 :            :  *
     758                 :            :  * Description: Request and enable the interrupt for the given PHY.
     759                 :            :  *   If this fails, then we set irq to PHY_POLL.
     760                 :            :  *   This should only be called with a valid IRQ number.
     761                 :            :  */
     762                 :          0 : void phy_request_interrupt(struct phy_device *phydev)
     763                 :            : {
     764                 :          0 :         int err;
     765                 :            : 
     766         [ #  # ]:          0 :         err = request_threaded_irq(phydev->irq, NULL, phy_interrupt,
     767                 :            :                                    IRQF_ONESHOT | IRQF_SHARED,
     768                 :            :                                    phydev_name(phydev), phydev);
     769         [ #  # ]:          0 :         if (err) {
     770                 :          0 :                 phydev_warn(phydev, "Error %d requesting IRQ %d, falling back to polling\n",
     771                 :            :                             err, phydev->irq);
     772                 :          0 :                 phydev->irq = PHY_POLL;
     773                 :            :         } else {
     774         [ #  # ]:          0 :                 if (phy_enable_interrupts(phydev)) {
     775                 :          0 :                         phydev_warn(phydev, "Can't enable interrupt, falling back to polling\n");
     776                 :          0 :                         phy_free_interrupt(phydev);
     777                 :          0 :                         phydev->irq = PHY_POLL;
     778                 :            :                 }
     779                 :            :         }
     780                 :          0 : }
     781                 :            : EXPORT_SYMBOL(phy_request_interrupt);
     782                 :            : 
     783                 :            : /**
     784                 :            :  * phy_free_interrupt - disable and free interrupt for a PHY device
     785                 :            :  * @phydev: target phy_device struct
     786                 :            :  *
     787                 :            :  * Description: Disable and free the interrupt for the given PHY.
     788                 :            :  *   This should only be called with a valid IRQ number.
     789                 :            :  */
     790                 :          0 : void phy_free_interrupt(struct phy_device *phydev)
     791                 :            : {
     792                 :          0 :         phy_disable_interrupts(phydev);
     793                 :          0 :         free_irq(phydev->irq, phydev);
     794                 :          0 : }
     795                 :            : EXPORT_SYMBOL(phy_free_interrupt);
     796                 :            : 
     797                 :            : /**
     798                 :            :  * phy_stop - Bring down the PHY link, and stop checking the status
     799                 :            :  * @phydev: target phy_device struct
     800                 :            :  */
     801                 :          0 : void phy_stop(struct phy_device *phydev)
     802                 :            : {
     803         [ #  # ]:          0 :         if (!phy_is_started(phydev)) {
     804                 :          0 :                 WARN(1, "called from state %s\n",
     805                 :            :                      phy_state_to_str(phydev->state));
     806                 :          0 :                 return;
     807                 :            :         }
     808                 :            : 
     809                 :          0 :         mutex_lock(&phydev->lock);
     810                 :            : 
     811                 :          0 :         if (phydev->sfp_bus)
     812                 :            :                 sfp_upstream_stop(phydev->sfp_bus);
     813                 :            : 
     814                 :          0 :         phydev->state = PHY_HALTED;
     815                 :            : 
     816                 :          0 :         mutex_unlock(&phydev->lock);
     817                 :            : 
     818                 :          0 :         phy_state_machine(&phydev->state_queue.work);
     819                 :          0 :         phy_stop_machine(phydev);
     820                 :            : 
     821                 :            :         /* Cannot call flush_scheduled_work() here as desired because
     822                 :            :          * of rtnl_lock(), but PHY_HALTED shall guarantee irq handler
     823                 :            :          * will not reenable interrupts.
     824                 :            :          */
     825                 :            : }
     826                 :            : EXPORT_SYMBOL(phy_stop);
     827                 :            : 
     828                 :            : /**
     829                 :            :  * phy_start - start or restart a PHY device
     830                 :            :  * @phydev: target phy_device struct
     831                 :            :  *
     832                 :            :  * Description: Indicates the attached device's readiness to
     833                 :            :  *   handle PHY-related work.  Used during startup to start the
     834                 :            :  *   PHY, and after a call to phy_stop() to resume operation.
     835                 :            :  *   Also used to indicate the MDIO bus has cleared an error
     836                 :            :  *   condition.
     837                 :            :  */
     838                 :         21 : void phy_start(struct phy_device *phydev)
     839                 :            : {
     840                 :         21 :         mutex_lock(&phydev->lock);
     841                 :            : 
     842         [ -  + ]:         21 :         if (phydev->state != PHY_READY && phydev->state != PHY_HALTED) {
     843         [ #  # ]:          0 :                 WARN(1, "called from state %s\n",
     844                 :            :                      phy_state_to_str(phydev->state));
     845                 :          0 :                 goto out;
     846                 :            :         }
     847                 :            : 
     848                 :         21 :         if (phydev->sfp_bus)
     849                 :            :                 sfp_upstream_start(phydev->sfp_bus);
     850                 :            : 
     851                 :            :         /* if phy was suspended, bring the physical link up again */
     852                 :         21 :         __phy_resume(phydev);
     853                 :            : 
     854                 :         21 :         phydev->state = PHY_UP;
     855                 :            : 
     856                 :         21 :         phy_start_machine(phydev);
     857                 :         21 : out:
     858                 :         21 :         mutex_unlock(&phydev->lock);
     859                 :         21 : }
     860                 :            : EXPORT_SYMBOL(phy_start);
     861                 :            : 
     862                 :            : /**
     863                 :            :  * phy_state_machine - Handle the state machine
     864                 :            :  * @work: work_struct that describes the work to be done
     865                 :            :  */
     866                 :         63 : void phy_state_machine(struct work_struct *work)
     867                 :            : {
     868                 :         63 :         struct delayed_work *dwork = to_delayed_work(work);
     869                 :         63 :         struct phy_device *phydev =
     870                 :         63 :                         container_of(dwork, struct phy_device, state_queue);
     871                 :         63 :         bool needs_aneg = false, do_suspend = false;
     872                 :         63 :         enum phy_state old_state;
     873                 :         63 :         int err = 0;
     874                 :            : 
     875                 :         63 :         mutex_lock(&phydev->lock);
     876                 :            : 
     877                 :         63 :         old_state = phydev->state;
     878                 :            : 
     879   [ +  +  -  - ]:         63 :         switch (phydev->state) {
     880                 :            :         case PHY_DOWN:
     881                 :            :         case PHY_READY:
     882                 :            :                 break;
     883                 :         21 :         case PHY_UP:
     884                 :         21 :                 needs_aneg = true;
     885                 :            : 
     886                 :         21 :                 break;
     887                 :         42 :         case PHY_NOLINK:
     888                 :            :         case PHY_RUNNING:
     889                 :         42 :                 err = phy_check_link_status(phydev);
     890                 :         42 :                 break;
     891                 :          0 :         case PHY_HALTED:
     892         [ #  # ]:          0 :                 if (phydev->link) {
     893                 :          0 :                         phydev->link = 0;
     894                 :          0 :                         phy_link_down(phydev, true);
     895                 :            :                 }
     896                 :            :                 do_suspend = true;
     897                 :            :                 break;
     898                 :            :         }
     899                 :            : 
     900                 :         63 :         mutex_unlock(&phydev->lock);
     901                 :            : 
     902         [ +  + ]:         63 :         if (needs_aneg)
     903                 :         21 :                 err = phy_start_aneg(phydev);
     904         [ -  + ]:         42 :         else if (do_suspend)
     905                 :          0 :                 phy_suspend(phydev);
     906                 :            : 
     907         [ -  + ]:         63 :         if (err < 0)
     908                 :          0 :                 phy_error(phydev);
     909                 :            : 
     910         [ +  + ]:         63 :         if (old_state != phydev->state) {
     911                 :         21 :                 phydev_dbg(phydev, "PHY state change %s -> %s\n",
     912                 :            :                            phy_state_to_str(old_state),
     913                 :            :                            phy_state_to_str(phydev->state));
     914   [ +  -  -  + ]:         21 :                 if (phydev->drv && phydev->drv->link_change_notify)
     915                 :          0 :                         phydev->drv->link_change_notify(phydev);
     916                 :            :         }
     917                 :            : 
     918                 :            :         /* Only re-schedule a PHY state machine change if we are polling the
     919                 :            :          * PHY, if PHY_IGNORE_INTERRUPT is set, then we will be moving
     920                 :            :          * between states from phy_mac_interrupt().
     921                 :            :          *
     922                 :            :          * In state PHY_HALTED the PHY gets suspended, so rescheduling the
     923                 :            :          * state machine would be pointless and possibly error prone when
     924                 :            :          * called from phy_disconnect() synchronously.
     925                 :            :          */
     926                 :         63 :         mutex_lock(&phydev->lock);
     927   [ +  -  +  - ]:         63 :         if (phy_polling_mode(phydev) && phy_is_started(phydev))
     928                 :         63 :                 phy_queue_state_machine(phydev, PHY_STATE_TIME);
     929                 :         63 :         mutex_unlock(&phydev->lock);
     930                 :         63 : }
     931                 :            : 
     932                 :            : /**
     933                 :            :  * phy_mac_interrupt - MAC says the link has changed
     934                 :            :  * @phydev: phy_device struct with changed link
     935                 :            :  *
     936                 :            :  * The MAC layer is able to indicate there has been a change in the PHY link
     937                 :            :  * status. Trigger the state machine and work a work queue.
     938                 :            :  */
     939                 :          0 : void phy_mac_interrupt(struct phy_device *phydev)
     940                 :            : {
     941                 :            :         /* Trigger a state machine change */
     942                 :          0 :         phy_trigger_machine(phydev);
     943                 :          0 : }
     944                 :            : EXPORT_SYMBOL(phy_mac_interrupt);
     945                 :            : 
     946                 :          0 : static void mmd_eee_adv_to_linkmode(unsigned long *advertising, u16 eee_adv)
     947                 :            : {
     948         [ #  # ]:          0 :         linkmode_zero(advertising);
     949                 :            : 
     950         [ #  # ]:          0 :         if (eee_adv & MDIO_EEE_100TX)
     951                 :          0 :                 linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
     952                 :            :                                  advertising);
     953         [ #  # ]:          0 :         if (eee_adv & MDIO_EEE_1000T)
     954                 :          0 :                 linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
     955                 :            :                                  advertising);
     956         [ #  # ]:          0 :         if (eee_adv & MDIO_EEE_10GT)
     957                 :          0 :                 linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
     958                 :            :                                  advertising);
     959         [ #  # ]:          0 :         if (eee_adv & MDIO_EEE_1000KX)
     960                 :          0 :                 linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
     961                 :            :                                  advertising);
     962         [ #  # ]:          0 :         if (eee_adv & MDIO_EEE_10GKX4)
     963                 :          0 :                 linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
     964                 :            :                                  advertising);
     965         [ #  # ]:          0 :         if (eee_adv & MDIO_EEE_10GKR)
     966                 :          0 :                 linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
     967                 :            :                                  advertising);
     968                 :          0 : }
     969                 :            : 
     970                 :            : /**
     971                 :            :  * phy_init_eee - init and check the EEE feature
     972                 :            :  * @phydev: target phy_device struct
     973                 :            :  * @clk_stop_enable: PHY may stop the clock during LPI
     974                 :            :  *
     975                 :            :  * Description: it checks if the Energy-Efficient Ethernet (EEE)
     976                 :            :  * is supported by looking at the MMD registers 3.20 and 7.60/61
     977                 :            :  * and it programs the MMD register 3.0 setting the "Clock stop enable"
     978                 :            :  * bit if required.
     979                 :            :  */
     980                 :          0 : int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable)
     981                 :            : {
     982         [ #  # ]:          0 :         if (!phydev->drv)
     983                 :            :                 return -EIO;
     984                 :            : 
     985                 :            :         /* According to 802.3az,the EEE is supported only in full duplex-mode.
     986                 :            :          */
     987         [ #  # ]:          0 :         if (phydev->duplex == DUPLEX_FULL) {
     988                 :          0 :                 __ETHTOOL_DECLARE_LINK_MODE_MASK(common);
     989                 :          0 :                 __ETHTOOL_DECLARE_LINK_MODE_MASK(lp);
     990                 :          0 :                 __ETHTOOL_DECLARE_LINK_MODE_MASK(adv);
     991                 :          0 :                 int eee_lp, eee_cap, eee_adv;
     992                 :          0 :                 int status;
     993                 :          0 :                 u32 cap;
     994                 :            : 
     995                 :            :                 /* Read phy status to properly get the right settings */
     996                 :          0 :                 status = phy_read_status(phydev);
     997         [ #  # ]:          0 :                 if (status)
     998                 :          0 :                         return status;
     999                 :            : 
    1000                 :            :                 /* First check if the EEE ability is supported */
    1001                 :          0 :                 eee_cap = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE);
    1002         [ #  # ]:          0 :                 if (eee_cap <= 0)
    1003                 :          0 :                         goto eee_exit_err;
    1004                 :            : 
    1005                 :          0 :                 cap = mmd_eee_cap_to_ethtool_sup_t(eee_cap);
    1006         [ #  # ]:          0 :                 if (!cap)
    1007                 :          0 :                         goto eee_exit_err;
    1008                 :            : 
    1009                 :            :                 /* Check which link settings negotiated and verify it in
    1010                 :            :                  * the EEE advertising registers.
    1011                 :            :                  */
    1012                 :          0 :                 eee_lp = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_LPABLE);
    1013         [ #  # ]:          0 :                 if (eee_lp <= 0)
    1014                 :          0 :                         goto eee_exit_err;
    1015                 :            : 
    1016                 :          0 :                 eee_adv = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV);
    1017         [ #  # ]:          0 :                 if (eee_adv <= 0)
    1018                 :          0 :                         goto eee_exit_err;
    1019                 :            : 
    1020                 :          0 :                 mmd_eee_adv_to_linkmode(adv, eee_adv);
    1021                 :          0 :                 mmd_eee_adv_to_linkmode(lp, eee_lp);
    1022                 :          0 :                 linkmode_and(common, adv, lp);
    1023                 :            : 
    1024         [ #  # ]:          0 :                 if (!phy_check_valid(phydev->speed, phydev->duplex, common))
    1025                 :          0 :                         goto eee_exit_err;
    1026                 :            : 
    1027         [ #  # ]:          0 :                 if (clk_stop_enable)
    1028                 :            :                         /* Configure the PHY to stop receiving xMII
    1029                 :            :                          * clock while it is signaling LPI.
    1030                 :            :                          */
    1031                 :          0 :                         phy_set_bits_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1,
    1032                 :            :                                          MDIO_PCS_CTRL1_CLKSTOP_EN);
    1033                 :            : 
    1034                 :          0 :                 return 0; /* EEE supported */
    1035                 :            :         }
    1036                 :          0 : eee_exit_err:
    1037                 :            :         return -EPROTONOSUPPORT;
    1038                 :            : }
    1039                 :            : EXPORT_SYMBOL(phy_init_eee);
    1040                 :            : 
    1041                 :            : /**
    1042                 :            :  * phy_get_eee_err - report the EEE wake error count
    1043                 :            :  * @phydev: target phy_device struct
    1044                 :            :  *
    1045                 :            :  * Description: it is to report the number of time where the PHY
    1046                 :            :  * failed to complete its normal wake sequence.
    1047                 :            :  */
    1048                 :          0 : int phy_get_eee_err(struct phy_device *phydev)
    1049                 :            : {
    1050         [ #  # ]:          0 :         if (!phydev->drv)
    1051                 :            :                 return -EIO;
    1052                 :            : 
    1053                 :          0 :         return phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_EEE_WK_ERR);
    1054                 :            : }
    1055                 :            : EXPORT_SYMBOL(phy_get_eee_err);
    1056                 :            : 
    1057                 :            : /**
    1058                 :            :  * phy_ethtool_get_eee - get EEE supported and status
    1059                 :            :  * @phydev: target phy_device struct
    1060                 :            :  * @data: ethtool_eee data
    1061                 :            :  *
    1062                 :            :  * Description: it reportes the Supported/Advertisement/LP Advertisement
    1063                 :            :  * capabilities.
    1064                 :            :  */
    1065                 :          0 : int phy_ethtool_get_eee(struct phy_device *phydev, struct ethtool_eee *data)
    1066                 :            : {
    1067                 :          0 :         int val;
    1068                 :            : 
    1069         [ #  # ]:          0 :         if (!phydev->drv)
    1070                 :            :                 return -EIO;
    1071                 :            : 
    1072                 :            :         /* Get Supported EEE */
    1073                 :          0 :         val = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE);
    1074         [ #  # ]:          0 :         if (val < 0)
    1075                 :            :                 return val;
    1076                 :          0 :         data->supported = mmd_eee_cap_to_ethtool_sup_t(val);
    1077                 :            : 
    1078                 :            :         /* Get advertisement EEE */
    1079                 :          0 :         val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV);
    1080         [ #  # ]:          0 :         if (val < 0)
    1081                 :            :                 return val;
    1082                 :          0 :         data->advertised = mmd_eee_adv_to_ethtool_adv_t(val);
    1083                 :          0 :         data->eee_enabled = !!data->advertised;
    1084                 :            : 
    1085                 :            :         /* Get LP advertisement EEE */
    1086                 :          0 :         val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_LPABLE);
    1087         [ #  # ]:          0 :         if (val < 0)
    1088                 :            :                 return val;
    1089                 :          0 :         data->lp_advertised = mmd_eee_adv_to_ethtool_adv_t(val);
    1090                 :            : 
    1091                 :          0 :         data->eee_active = !!(data->advertised & data->lp_advertised);
    1092                 :            : 
    1093                 :          0 :         return 0;
    1094                 :            : }
    1095                 :            : EXPORT_SYMBOL(phy_ethtool_get_eee);
    1096                 :            : 
    1097                 :            : /**
    1098                 :            :  * phy_ethtool_set_eee - set EEE supported and status
    1099                 :            :  * @phydev: target phy_device struct
    1100                 :            :  * @data: ethtool_eee data
    1101                 :            :  *
    1102                 :            :  * Description: it is to program the Advertisement EEE register.
    1103                 :            :  */
    1104                 :          0 : int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_eee *data)
    1105                 :            : {
    1106                 :          0 :         int cap, old_adv, adv = 0, ret;
    1107                 :            : 
    1108         [ #  # ]:          0 :         if (!phydev->drv)
    1109                 :            :                 return -EIO;
    1110                 :            : 
    1111                 :            :         /* Get Supported EEE */
    1112                 :          0 :         cap = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE);
    1113         [ #  # ]:          0 :         if (cap < 0)
    1114                 :            :                 return cap;
    1115                 :            : 
    1116                 :          0 :         old_adv = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV);
    1117         [ #  # ]:          0 :         if (old_adv < 0)
    1118                 :            :                 return old_adv;
    1119                 :            : 
    1120         [ #  # ]:          0 :         if (data->eee_enabled) {
    1121         [ #  # ]:          0 :                 adv = !data->advertised ? cap :
    1122                 :          0 :                       ethtool_adv_to_mmd_eee_adv_t(data->advertised) & cap;
    1123                 :            :                 /* Mask prohibited EEE modes */
    1124                 :          0 :                 adv &= ~phydev->eee_broken_modes;
    1125                 :            :         }
    1126                 :            : 
    1127         [ #  # ]:          0 :         if (old_adv != adv) {
    1128                 :          0 :                 ret = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, adv);
    1129         [ #  # ]:          0 :                 if (ret < 0)
    1130                 :            :                         return ret;
    1131                 :            : 
    1132                 :            :                 /* Restart autonegotiation so the new modes get sent to the
    1133                 :            :                  * link partner.
    1134                 :            :                  */
    1135                 :          0 :                 ret = phy_restart_aneg(phydev);
    1136                 :          0 :                 if (ret < 0)
    1137                 :            :                         return ret;
    1138                 :            :         }
    1139                 :            : 
    1140                 :            :         return 0;
    1141                 :            : }
    1142                 :            : EXPORT_SYMBOL(phy_ethtool_set_eee);
    1143                 :            : 
    1144                 :          0 : int phy_ethtool_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol)
    1145                 :            : {
    1146   [ #  #  #  # ]:          0 :         if (phydev->drv && phydev->drv->set_wol)
    1147                 :          0 :                 return phydev->drv->set_wol(phydev, wol);
    1148                 :            : 
    1149                 :            :         return -EOPNOTSUPP;
    1150                 :            : }
    1151                 :            : EXPORT_SYMBOL(phy_ethtool_set_wol);
    1152                 :            : 
    1153                 :          0 : void phy_ethtool_get_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol)
    1154                 :            : {
    1155   [ #  #  #  # ]:          0 :         if (phydev->drv && phydev->drv->get_wol)
    1156                 :          0 :                 phydev->drv->get_wol(phydev, wol);
    1157                 :          0 : }
    1158                 :            : EXPORT_SYMBOL(phy_ethtool_get_wol);
    1159                 :            : 
    1160                 :          0 : int phy_ethtool_get_link_ksettings(struct net_device *ndev,
    1161                 :            :                                    struct ethtool_link_ksettings *cmd)
    1162                 :            : {
    1163                 :          0 :         struct phy_device *phydev = ndev->phydev;
    1164                 :            : 
    1165         [ #  # ]:          0 :         if (!phydev)
    1166                 :            :                 return -ENODEV;
    1167                 :            : 
    1168                 :          0 :         phy_ethtool_ksettings_get(phydev, cmd);
    1169                 :            : 
    1170                 :          0 :         return 0;
    1171                 :            : }
    1172                 :            : EXPORT_SYMBOL(phy_ethtool_get_link_ksettings);
    1173                 :            : 
    1174                 :          0 : int phy_ethtool_set_link_ksettings(struct net_device *ndev,
    1175                 :            :                                    const struct ethtool_link_ksettings *cmd)
    1176                 :            : {
    1177                 :          0 :         struct phy_device *phydev = ndev->phydev;
    1178                 :            : 
    1179         [ #  # ]:          0 :         if (!phydev)
    1180                 :            :                 return -ENODEV;
    1181                 :            : 
    1182                 :          0 :         return phy_ethtool_ksettings_set(phydev, cmd);
    1183                 :            : }
    1184                 :            : EXPORT_SYMBOL(phy_ethtool_set_link_ksettings);
    1185                 :            : 
    1186                 :          0 : int phy_ethtool_nway_reset(struct net_device *ndev)
    1187                 :            : {
    1188                 :          0 :         struct phy_device *phydev = ndev->phydev;
    1189                 :            : 
    1190         [ #  # ]:          0 :         if (!phydev)
    1191                 :            :                 return -ENODEV;
    1192                 :            : 
    1193         [ #  # ]:          0 :         if (!phydev->drv)
    1194                 :            :                 return -EIO;
    1195                 :            : 
    1196                 :          0 :         return phy_restart_aneg(phydev);
    1197                 :            : }
    1198                 :            : EXPORT_SYMBOL(phy_ethtool_nway_reset);

Generated by: LCOV version 1.14