LCOV - code coverage report
Current view: top level - drivers/net/phy - phy.c (source / functions) Hit Total Coverage
Test: gcov_data_raspi2_real_modules_combined.info Lines: 0 363 0.0 %
Date: 2020-09-30 20:25:40 Functions: 0 39 0.0 %
Branches: 0 287 0.0 %

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

Generated by: LCOV version 1.14