LCOV - code coverage report
Current view: top level - drivers/net/phy - phy.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 17 305 5.6 %
Date: 2014-04-16 Functions: 1 26 3.8 %
Branches: 9 233 3.9 %

           Branch data     Line data    Source code
       1                 :            : /* Framework for configuring and reading PHY devices
       2                 :            :  * Based on code in sungem_phy.c and gianfar_phy.c
       3                 :            :  *
       4                 :            :  * Author: Andy Fleming
       5                 :            :  *
       6                 :            :  * Copyright (c) 2004 Freescale Semiconductor, Inc.
       7                 :            :  * Copyright (c) 2006, 2007  Maciej W. Rozycki
       8                 :            :  *
       9                 :            :  * This program is free software; you can redistribute  it and/or modify it
      10                 :            :  * under  the terms of  the GNU General  Public License as published by the
      11                 :            :  * Free Software Foundation;  either version 2 of the  License, or (at your
      12                 :            :  * option) any later version.
      13                 :            :  *
      14                 :            :  */
      15                 :            : 
      16                 :            : #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
      17                 :            : 
      18                 :            : #include <linux/kernel.h>
      19                 :            : #include <linux/string.h>
      20                 :            : #include <linux/errno.h>
      21                 :            : #include <linux/unistd.h>
      22                 :            : #include <linux/interrupt.h>
      23                 :            : #include <linux/delay.h>
      24                 :            : #include <linux/netdevice.h>
      25                 :            : #include <linux/etherdevice.h>
      26                 :            : #include <linux/skbuff.h>
      27                 :            : #include <linux/mm.h>
      28                 :            : #include <linux/module.h>
      29                 :            : #include <linux/mii.h>
      30                 :            : #include <linux/ethtool.h>
      31                 :            : #include <linux/phy.h>
      32                 :            : #include <linux/timer.h>
      33                 :            : #include <linux/workqueue.h>
      34                 :            : #include <linux/mdio.h>
      35                 :            : #include <linux/io.h>
      36                 :            : #include <linux/uaccess.h>
      37                 :            : #include <linux/atomic.h>
      38                 :            : 
      39                 :            : #include <asm/irq.h>
      40                 :            : 
      41                 :            : /**
      42                 :            :  * phy_print_status - Convenience function to print out the current phy status
      43                 :            :  * @phydev: the phy_device struct
      44                 :            :  */
      45                 :          0 : void phy_print_status(struct phy_device *phydev)
      46                 :            : {
      47         [ #  # ]:          0 :         if (phydev->link) {
      48         [ #  # ]:          0 :                 pr_info("%s - Link is Up - %d/%s\n",
      49                 :            :                         dev_name(&phydev->dev),
      50                 :            :                         phydev->speed,
      51                 :            :                         DUPLEX_FULL == phydev->duplex ? "Full" : "Half");
      52                 :            :         } else  {
      53                 :          0 :                 pr_info("%s - Link is Down\n", dev_name(&phydev->dev));
      54                 :            :         }
      55                 :          0 : }
      56                 :            : EXPORT_SYMBOL(phy_print_status);
      57                 :            : 
      58                 :            : /**
      59                 :            :  * phy_clear_interrupt - Ack the phy device's interrupt
      60                 :            :  * @phydev: the phy_device struct
      61                 :            :  *
      62                 :            :  * If the @phydev driver has an ack_interrupt function, call it to
      63                 :            :  * ack and clear the phy device's interrupt.
      64                 :            :  *
      65                 :            :  * Returns 0 on success on < 0 on error.
      66                 :            :  */
      67                 :            : static int phy_clear_interrupt(struct phy_device *phydev)
      68                 :            : {
      69 [ #  # ][ #  # ]:          0 :         if (phydev->drv->ack_interrupt)
         [ #  # ][ #  # ]
      70                 :          0 :                 return phydev->drv->ack_interrupt(phydev);
      71                 :            : 
      72                 :            :         return 0;
      73                 :            : }
      74                 :            : 
      75                 :            : /**
      76                 :            :  * phy_config_interrupt - configure the PHY device for the requested interrupts
      77                 :            :  * @phydev: the phy_device struct
      78                 :            :  * @interrupts: interrupt flags to configure for this @phydev
      79                 :            :  *
      80                 :            :  * Returns 0 on success on < 0 on error.
      81                 :            :  */
      82                 :            : static int phy_config_interrupt(struct phy_device *phydev, u32 interrupts)
      83                 :            : {
      84                 :          0 :         phydev->interrupts = interrupts;
      85 [ #  # ][ #  # ]:          0 :         if (phydev->drv->config_intr)
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      86                 :          0 :                 return phydev->drv->config_intr(phydev);
      87                 :            : 
      88                 :            :         return 0;
      89                 :            : }
      90                 :            : 
      91                 :            : 
      92                 :            : /**
      93                 :            :  * phy_aneg_done - return auto-negotiation status
      94                 :            :  * @phydev: target phy_device struct
      95                 :            :  *
      96                 :            :  * Description: Reads the status register and returns 0 either if
      97                 :            :  *   auto-negotiation is incomplete, or if there was an error.
      98                 :            :  *   Returns BMSR_ANEGCOMPLETE if auto-negotiation is done.
      99                 :            :  */
     100                 :          0 : static inline int phy_aneg_done(struct phy_device *phydev)
     101                 :            : {
     102                 :            :         int retval = phy_read(phydev, MII_BMSR);
     103                 :            : 
     104 [ #  # ][ #  # ]:          0 :         return (retval < 0) ? retval : (retval & BMSR_ANEGCOMPLETE);
     105                 :            : }
     106                 :            : 
     107                 :            : /* A structure for mapping a particular speed and duplex
     108                 :            :  * combination to a particular SUPPORTED and ADVERTISED value
     109                 :            :  */
     110                 :            : struct phy_setting {
     111                 :            :         int speed;
     112                 :            :         int duplex;
     113                 :            :         u32 setting;
     114                 :            : };
     115                 :            : 
     116                 :            : /* A mapping of all SUPPORTED settings to speed/duplex */
     117                 :            : static const struct phy_setting settings[] = {
     118                 :            :         {
     119                 :            :                 .speed = 10000,
     120                 :            :                 .duplex = DUPLEX_FULL,
     121                 :            :                 .setting = SUPPORTED_10000baseT_Full,
     122                 :            :         },
     123                 :            :         {
     124                 :            :                 .speed = SPEED_1000,
     125                 :            :                 .duplex = DUPLEX_FULL,
     126                 :            :                 .setting = SUPPORTED_1000baseT_Full,
     127                 :            :         },
     128                 :            :         {
     129                 :            :                 .speed = SPEED_1000,
     130                 :            :                 .duplex = DUPLEX_HALF,
     131                 :            :                 .setting = SUPPORTED_1000baseT_Half,
     132                 :            :         },
     133                 :            :         {
     134                 :            :                 .speed = SPEED_100,
     135                 :            :                 .duplex = DUPLEX_FULL,
     136                 :            :                 .setting = SUPPORTED_100baseT_Full,
     137                 :            :         },
     138                 :            :         {
     139                 :            :                 .speed = SPEED_100,
     140                 :            :                 .duplex = DUPLEX_HALF,
     141                 :            :                 .setting = SUPPORTED_100baseT_Half,
     142                 :            :         },
     143                 :            :         {
     144                 :            :                 .speed = SPEED_10,
     145                 :            :                 .duplex = DUPLEX_FULL,
     146                 :            :                 .setting = SUPPORTED_10baseT_Full,
     147                 :            :         },
     148                 :            :         {
     149                 :            :                 .speed = SPEED_10,
     150                 :            :                 .duplex = DUPLEX_HALF,
     151                 :            :                 .setting = SUPPORTED_10baseT_Half,
     152                 :            :         },
     153                 :            : };
     154                 :            : 
     155                 :            : #define MAX_NUM_SETTINGS ARRAY_SIZE(settings)
     156                 :            : 
     157                 :            : /**
     158                 :            :  * phy_find_setting - find a PHY settings array entry that matches speed & duplex
     159                 :            :  * @speed: speed to match
     160                 :            :  * @duplex: duplex to match
     161                 :            :  *
     162                 :            :  * Description: Searches the settings array for the setting which
     163                 :            :  *   matches the desired speed and duplex, and returns the index
     164                 :            :  *   of that setting.  Returns the index of the last setting if
     165                 :            :  *   none of the others match.
     166                 :            :  */
     167                 :            : static inline unsigned int phy_find_setting(int speed, int duplex)
     168                 :            : {
     169                 :            :         unsigned int idx = 0;
     170                 :            : 
     171 [ #  # ][ #  # ]:          0 :         while (idx < ARRAY_SIZE(settings) &&
         [ #  # ][ #  # ]
     172 [ #  # ][ #  # ]:          0 :                (settings[idx].speed != speed || settings[idx].duplex != duplex))
     173                 :          0 :                 idx++;
     174                 :            : 
     175                 :          0 :         return idx < MAX_NUM_SETTINGS ? idx : MAX_NUM_SETTINGS - 1;
     176                 :            : }
     177                 :            : 
     178                 :            : /**
     179                 :            :  * phy_find_valid - find a PHY setting that matches the requested features mask
     180                 :            :  * @idx: The first index in settings[] to search
     181                 :            :  * @features: A mask of the valid settings
     182                 :            :  *
     183                 :            :  * Description: Returns the index of the first valid setting less
     184                 :            :  *   than or equal to the one pointed to by idx, as determined by
     185                 :            :  *   the mask in features.  Returns the index of the last setting
     186                 :            :  *   if nothing else matches.
     187                 :            :  */
     188                 :            : static inline unsigned int phy_find_valid(unsigned int idx, u32 features)
     189                 :            : {
     190 [ #  # ][ #  # ]:          0 :         while (idx < MAX_NUM_SETTINGS && !(settings[idx].setting & features))
     191                 :          0 :                 idx++;
     192                 :            : 
     193                 :          0 :         return idx < MAX_NUM_SETTINGS ? idx : MAX_NUM_SETTINGS - 1;
     194                 :            : }
     195                 :            : 
     196                 :            : /**
     197                 :            :  * phy_sanitize_settings - make sure the PHY is set to supported speed and duplex
     198                 :            :  * @phydev: the target phy_device struct
     199                 :            :  *
     200                 :            :  * Description: Make sure the PHY is set to supported speeds and
     201                 :            :  *   duplexes.  Drop down by one in this order:  1000/FULL,
     202                 :            :  *   1000/HALF, 100/FULL, 100/HALF, 10/FULL, 10/HALF.
     203                 :            :  */
     204                 :          0 : static void phy_sanitize_settings(struct phy_device *phydev)
     205                 :            : {
     206                 :          0 :         u32 features = phydev->supported;
     207                 :            :         unsigned int idx;
     208                 :            : 
     209                 :            :         /* Sanitize settings based on PHY capabilities */
     210         [ #  # ]:          0 :         if ((features & SUPPORTED_Autoneg) == 0)
     211                 :          0 :                 phydev->autoneg = AUTONEG_DISABLE;
     212                 :            : 
     213                 :          0 :         idx = phy_find_valid(phy_find_setting(phydev->speed, phydev->duplex),
     214                 :            :                         features);
     215                 :            : 
     216                 :          0 :         phydev->speed = settings[idx].speed;
     217                 :          0 :         phydev->duplex = settings[idx].duplex;
     218                 :          0 : }
     219                 :            : 
     220                 :            : /**
     221                 :            :  * phy_ethtool_sset - generic ethtool sset function, handles all the details
     222                 :            :  * @phydev: target phy_device struct
     223                 :            :  * @cmd: ethtool_cmd
     224                 :            :  *
     225                 :            :  * A few notes about parameter checking:
     226                 :            :  * - We don't set port or transceiver, so we don't care what they
     227                 :            :  *   were set to.
     228                 :            :  * - phy_start_aneg() will make sure forced settings are sane, and
     229                 :            :  *   choose the next best ones from the ones selected, so we don't
     230                 :            :  *   care if ethtool tries to give us bad values.
     231                 :            :  */
     232                 :          0 : int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd)
     233                 :            : {
     234                 :            :         u32 speed = ethtool_cmd_speed(cmd);
     235                 :            : 
     236         [ #  # ]:          0 :         if (cmd->phy_address != phydev->addr)
     237                 :            :                 return -EINVAL;
     238                 :            : 
     239                 :            :         /* We make sure that we don't pass unsupported values in to the PHY */
     240                 :          0 :         cmd->advertising &= phydev->supported;
     241                 :            : 
     242                 :            :         /* Verify the settings we care about. */
     243         [ #  # ]:          0 :         if (cmd->autoneg != AUTONEG_ENABLE && cmd->autoneg != AUTONEG_DISABLE)
     244                 :            :                 return -EINVAL;
     245                 :            : 
     246 [ #  # ][ #  # ]:          0 :         if (cmd->autoneg == AUTONEG_ENABLE && cmd->advertising == 0)
     247                 :            :                 return -EINVAL;
     248                 :            : 
     249 [ #  # ][ #  # ]:          0 :         if (cmd->autoneg == AUTONEG_DISABLE &&
     250                 :          0 :             ((speed != SPEED_1000 &&
     251         [ #  # ]:          0 :               speed != SPEED_100 &&
     252         [ #  # ]:          0 :               speed != SPEED_10) ||
     253                 :          0 :              (cmd->duplex != DUPLEX_HALF &&
     254                 :            :               cmd->duplex != DUPLEX_FULL)))
     255                 :            :                 return -EINVAL;
     256                 :            : 
     257                 :          0 :         phydev->autoneg = cmd->autoneg;
     258                 :            : 
     259                 :          0 :         phydev->speed = speed;
     260                 :            : 
     261                 :          0 :         phydev->advertising = cmd->advertising;
     262                 :            : 
     263         [ #  # ]:          0 :         if (AUTONEG_ENABLE == cmd->autoneg)
     264                 :          0 :                 phydev->advertising |= ADVERTISED_Autoneg;
     265                 :            :         else
     266                 :          0 :                 phydev->advertising &= ~ADVERTISED_Autoneg;
     267                 :            : 
     268                 :          0 :         phydev->duplex = cmd->duplex;
     269                 :            : 
     270                 :            :         /* Restart the PHY */
     271                 :          0 :         phy_start_aneg(phydev);
     272                 :            : 
     273                 :          0 :         return 0;
     274                 :            : }
     275                 :            : EXPORT_SYMBOL(phy_ethtool_sset);
     276                 :            : 
     277                 :          0 : int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd)
     278                 :            : {
     279                 :          0 :         cmd->supported = phydev->supported;
     280                 :            : 
     281                 :          0 :         cmd->advertising = phydev->advertising;
     282                 :          0 :         cmd->lp_advertising = phydev->lp_advertising;
     283                 :            : 
     284                 :          0 :         ethtool_cmd_speed_set(cmd, phydev->speed);
     285                 :          0 :         cmd->duplex = phydev->duplex;
     286                 :          0 :         cmd->port = PORT_MII;
     287                 :          0 :         cmd->phy_address = phydev->addr;
     288         [ #  # ]:          0 :         cmd->transceiver = phy_is_internal(phydev) ?
     289                 :            :                 XCVR_INTERNAL : XCVR_EXTERNAL;
     290                 :          0 :         cmd->autoneg = phydev->autoneg;
     291                 :            : 
     292                 :          0 :         return 0;
     293                 :            : }
     294                 :            : EXPORT_SYMBOL(phy_ethtool_gset);
     295                 :            : 
     296                 :            : /**
     297                 :            :  * phy_mii_ioctl - generic PHY MII ioctl interface
     298                 :            :  * @phydev: the phy_device struct
     299                 :            :  * @ifr: &struct ifreq for socket ioctl's
     300                 :            :  * @cmd: ioctl cmd to execute
     301                 :            :  *
     302                 :            :  * Note that this function is currently incompatible with the
     303                 :            :  * PHYCONTROL layer.  It changes registers without regard to
     304                 :            :  * current state.  Use at own risk.
     305                 :            :  */
     306                 :          0 : int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd)
     307                 :            : {
     308                 :            :         struct mii_ioctl_data *mii_data = if_mii(ifr);
     309                 :          0 :         u16 val = mii_data->val_in;
     310                 :            : 
     311   [ #  #  #  #  :          0 :         switch (cmd) {
                      # ]
     312                 :            :         case SIOCGMIIPHY:
     313                 :          0 :                 mii_data->phy_id = phydev->addr;
     314                 :            :                 /* fall through */
     315                 :            : 
     316                 :            :         case SIOCGMIIREG:
     317                 :          0 :                 mii_data->val_out = mdiobus_read(phydev->bus, mii_data->phy_id,
     318                 :          0 :                                                  mii_data->reg_num);
     319                 :          0 :                 return 0;
     320                 :            : 
     321                 :            :         case SIOCSMIIREG:
     322         [ #  # ]:          0 :                 if (mii_data->phy_id == phydev->addr) {
     323      [ #  #  # ]:          0 :                         switch (mii_data->reg_num) {
     324                 :            :                         case MII_BMCR:
     325         [ #  # ]:          0 :                                 if ((val & (BMCR_RESET | BMCR_ANENABLE)) == 0)
     326                 :          0 :                                         phydev->autoneg = AUTONEG_DISABLE;
     327                 :            :                                 else
     328                 :          0 :                                         phydev->autoneg = AUTONEG_ENABLE;
     329 [ #  # ][ #  # ]:          0 :                                 if (!phydev->autoneg && (val & BMCR_FULLDPLX))
     330                 :          0 :                                         phydev->duplex = DUPLEX_FULL;
     331                 :            :                                 else
     332                 :          0 :                                         phydev->duplex = DUPLEX_HALF;
     333 [ #  # ][ #  # ]:          0 :                                 if (!phydev->autoneg && (val & BMCR_SPEED1000))
     334                 :          0 :                                         phydev->speed = SPEED_1000;
     335 [ #  # ][ #  # ]:          0 :                                 else if (!phydev->autoneg &&
     336                 :          0 :                                          (val & BMCR_SPEED100))
     337                 :          0 :                                         phydev->speed = SPEED_100;
     338                 :            :                                 break;
     339                 :            :                         case MII_ADVERTISE:
     340                 :          0 :                                 phydev->advertising = val;
     341                 :          0 :                                 break;
     342                 :            :                         default:
     343                 :            :                                 /* do nothing */
     344                 :            :                                 break;
     345                 :            :                         }
     346                 :            :                 }
     347                 :            : 
     348                 :          0 :                 mdiobus_write(phydev->bus, mii_data->phy_id,
     349                 :          0 :                               mii_data->reg_num, val);
     350                 :            : 
     351 [ #  # ][ #  # ]:          0 :                 if (mii_data->reg_num == MII_BMCR &&
     352                 :            :                     val & BMCR_RESET)
     353                 :          0 :                         return phy_init_hw(phydev);
     354                 :            :                 return 0;
     355                 :            : 
     356                 :            :         case SIOCSHWTSTAMP:
     357         [ #  # ]:          0 :                 if (phydev->drv->hwtstamp)
     358                 :          0 :                         return phydev->drv->hwtstamp(phydev, ifr);
     359                 :            :                 /* fall through */
     360                 :            : 
     361                 :            :         default:
     362                 :            :                 return -EOPNOTSUPP;
     363                 :            :         }
     364                 :            : }
     365                 :            : EXPORT_SYMBOL(phy_mii_ioctl);
     366                 :            : 
     367                 :            : /**
     368                 :            :  * phy_start_aneg - start auto-negotiation for this PHY device
     369                 :            :  * @phydev: the phy_device struct
     370                 :            :  *
     371                 :            :  * Description: Sanitizes the settings (if we're not autonegotiating
     372                 :            :  *   them), and then calls the driver's config_aneg function.
     373                 :            :  *   If the PHYCONTROL Layer is operating, we change the state to
     374                 :            :  *   reflect the beginning of Auto-negotiation or forcing.
     375                 :            :  */
     376                 :          0 : int phy_start_aneg(struct phy_device *phydev)
     377                 :            : {
     378                 :            :         int err;
     379                 :            : 
     380                 :          0 :         mutex_lock(&phydev->lock);
     381                 :            : 
     382         [ #  # ]:          0 :         if (AUTONEG_DISABLE == phydev->autoneg)
     383                 :          0 :                 phy_sanitize_settings(phydev);
     384                 :            : 
     385                 :          0 :         err = phydev->drv->config_aneg(phydev);
     386         [ #  # ]:          0 :         if (err < 0)
     387                 :            :                 goto out_unlock;
     388                 :            : 
     389         [ #  # ]:          0 :         if (phydev->state != PHY_HALTED) {
     390         [ #  # ]:          0 :                 if (AUTONEG_ENABLE == phydev->autoneg) {
     391                 :          0 :                         phydev->state = PHY_AN;
     392                 :          0 :                         phydev->link_timeout = PHY_AN_TIMEOUT;
     393                 :            :                 } else {
     394                 :          0 :                         phydev->state = PHY_FORCING;
     395                 :          0 :                         phydev->link_timeout = PHY_FORCE_TIMEOUT;
     396                 :            :                 }
     397                 :            :         }
     398                 :            : 
     399                 :            : out_unlock:
     400                 :          0 :         mutex_unlock(&phydev->lock);
     401                 :          0 :         return err;
     402                 :            : }
     403                 :            : EXPORT_SYMBOL(phy_start_aneg);
     404                 :            : 
     405                 :            : /**
     406                 :            :  * phy_start_machine - start PHY state machine tracking
     407                 :            :  * @phydev: the phy_device struct
     408                 :            :  *
     409                 :            :  * Description: The PHY infrastructure can run a state machine
     410                 :            :  *   which tracks whether the PHY is starting up, negotiating,
     411                 :            :  *   etc.  This function starts the timer which tracks the state
     412                 :            :  *   of the PHY.  If you want to maintain your own state machine,
     413                 :            :  *   do not call this function.
     414                 :            :  */
     415                 :          0 : void phy_start_machine(struct phy_device *phydev)
     416                 :            : {
     417                 :          0 :         queue_delayed_work(system_power_efficient_wq, &phydev->state_queue, HZ);
     418                 :          0 : }
     419                 :            : 
     420                 :            : /**
     421                 :            :  * phy_stop_machine - stop the PHY state machine tracking
     422                 :            :  * @phydev: target phy_device struct
     423                 :            :  *
     424                 :            :  * Description: Stops the state machine timer, sets the state to UP
     425                 :            :  *   (unless it wasn't up yet). This function must be called BEFORE
     426                 :            :  *   phy_detach.
     427                 :            :  */
     428                 :          0 : void phy_stop_machine(struct phy_device *phydev)
     429                 :            : {
     430                 :          0 :         cancel_delayed_work_sync(&phydev->state_queue);
     431                 :            : 
     432                 :          0 :         mutex_lock(&phydev->lock);
     433         [ #  # ]:          0 :         if (phydev->state > PHY_UP)
     434                 :          0 :                 phydev->state = PHY_UP;
     435                 :          0 :         mutex_unlock(&phydev->lock);
     436                 :          0 : }
     437                 :            : 
     438                 :            : /**
     439                 :            :  * phy_error - enter HALTED state for this PHY device
     440                 :            :  * @phydev: target phy_device struct
     441                 :            :  *
     442                 :            :  * Moves the PHY to the HALTED state in response to a read
     443                 :            :  * or write error, and tells the controller the link is down.
     444                 :            :  * Must not be called from interrupt context, or while the
     445                 :            :  * phydev->lock is held.
     446                 :            :  */
     447                 :            : static void phy_error(struct phy_device *phydev)
     448                 :            : {
     449                 :          0 :         mutex_lock(&phydev->lock);
     450                 :          0 :         phydev->state = PHY_HALTED;
     451                 :          0 :         mutex_unlock(&phydev->lock);
     452                 :            : }
     453                 :            : 
     454                 :            : /**
     455                 :            :  * phy_interrupt - PHY interrupt handler
     456                 :            :  * @irq: interrupt line
     457                 :            :  * @phy_dat: phy_device pointer
     458                 :            :  *
     459                 :            :  * Description: When a PHY interrupt occurs, the handler disables
     460                 :            :  * interrupts, and schedules a work task to clear the interrupt.
     461                 :            :  */
     462                 :          0 : static irqreturn_t phy_interrupt(int irq, void *phy_dat)
     463                 :            : {
     464                 :            :         struct phy_device *phydev = phy_dat;
     465                 :            : 
     466         [ #  # ]:          0 :         if (PHY_HALTED == phydev->state)
     467                 :            :                 return IRQ_NONE;                /* It can't be ours.  */
     468                 :            : 
     469                 :            :         /* The MDIO bus is not allowed to be written in interrupt
     470                 :            :          * context, so we need to disable the irq here.  A work
     471                 :            :          * queue will write the PHY to disable and clear the
     472                 :            :          * interrupt, and then reenable the irq line.
     473                 :            :          */
     474                 :          0 :         disable_irq_nosync(irq);
     475                 :          0 :         atomic_inc(&phydev->irq_disable);
     476                 :            : 
     477                 :          0 :         queue_work(system_power_efficient_wq, &phydev->phy_queue);
     478                 :            : 
     479                 :          0 :         return IRQ_HANDLED;
     480                 :            : }
     481                 :            : 
     482                 :            : /**
     483                 :            :  * phy_enable_interrupts - Enable the interrupts from the PHY side
     484                 :            :  * @phydev: target phy_device struct
     485                 :            :  */
     486                 :          0 : static int phy_enable_interrupts(struct phy_device *phydev)
     487                 :            : {
     488                 :            :         int err = phy_clear_interrupt(phydev);
     489                 :            : 
     490         [ #  # ]:          0 :         if (err < 0)
     491                 :            :                 return err;
     492                 :            : 
     493                 :          0 :         return phy_config_interrupt(phydev, PHY_INTERRUPT_ENABLED);
     494                 :            : }
     495                 :            : 
     496                 :            : /**
     497                 :            :  * phy_disable_interrupts - Disable the PHY interrupts from the PHY side
     498                 :            :  * @phydev: target phy_device struct
     499                 :            :  */
     500                 :          0 : static int phy_disable_interrupts(struct phy_device *phydev)
     501                 :            : {
     502                 :            :         int err;
     503                 :            : 
     504                 :            :         /* Disable PHY interrupts */
     505                 :            :         err = phy_config_interrupt(phydev, PHY_INTERRUPT_DISABLED);
     506         [ #  # ]:          0 :         if (err)
     507                 :            :                 goto phy_err;
     508                 :            : 
     509                 :            :         /* Clear the interrupt */
     510                 :            :         err = phy_clear_interrupt(phydev);
     511         [ #  # ]:          0 :         if (err)
     512                 :            :                 goto phy_err;
     513                 :            : 
     514                 :            :         return 0;
     515                 :            : 
     516                 :            : phy_err:
     517                 :            :         phy_error(phydev);
     518                 :            : 
     519                 :          0 :         return err;
     520                 :            : }
     521                 :            : 
     522                 :            : /**
     523                 :            :  * phy_start_interrupts - request and enable interrupts for a PHY device
     524                 :            :  * @phydev: target phy_device struct
     525                 :            :  *
     526                 :            :  * Description: Request the interrupt for the given PHY.
     527                 :            :  *   If this fails, then we set irq to PHY_POLL.
     528                 :            :  *   Otherwise, we enable the interrupts in the PHY.
     529                 :            :  *   This should only be called with a valid IRQ number.
     530                 :            :  *   Returns 0 on success or < 0 on error.
     531                 :            :  */
     532                 :          0 : int phy_start_interrupts(struct phy_device *phydev)
     533                 :            : {
     534                 :          0 :         atomic_set(&phydev->irq_disable, 0);
     535         [ #  # ]:          0 :         if (request_irq(phydev->irq, phy_interrupt, 0, "phy_interrupt",
     536                 :            :                         phydev) < 0) {
     537                 :          0 :                 pr_warn("%s: Can't get IRQ %d (PHY)\n",
     538                 :            :                         phydev->bus->name, phydev->irq);
     539                 :          0 :                 phydev->irq = PHY_POLL;
     540                 :          0 :                 return 0;
     541                 :            :         }
     542                 :            : 
     543                 :          0 :         return phy_enable_interrupts(phydev);
     544                 :            : }
     545                 :            : EXPORT_SYMBOL(phy_start_interrupts);
     546                 :            : 
     547                 :            : /**
     548                 :            :  * phy_stop_interrupts - disable interrupts from a PHY device
     549                 :            :  * @phydev: target phy_device struct
     550                 :            :  */
     551                 :          0 : int phy_stop_interrupts(struct phy_device *phydev)
     552                 :            : {
     553                 :          0 :         int err = phy_disable_interrupts(phydev);
     554                 :            : 
     555         [ #  # ]:          0 :         if (err)
     556                 :            :                 phy_error(phydev);
     557                 :            : 
     558                 :          0 :         free_irq(phydev->irq, phydev);
     559                 :            : 
     560                 :            :         /* Cannot call flush_scheduled_work() here as desired because
     561                 :            :          * of rtnl_lock(), but we do not really care about what would
     562                 :            :          * be done, except from enable_irq(), so cancel any work
     563                 :            :          * possibly pending and take care of the matter below.
     564                 :            :          */
     565                 :          0 :         cancel_work_sync(&phydev->phy_queue);
     566                 :            :         /* If work indeed has been cancelled, disable_irq() will have
     567                 :            :          * been left unbalanced from phy_interrupt() and enable_irq()
     568                 :            :          * has to be called so that other devices on the line work.
     569                 :            :          */
     570         [ #  # ]:          0 :         while (atomic_dec_return(&phydev->irq_disable) >= 0)
     571                 :          0 :                 enable_irq(phydev->irq);
     572                 :            : 
     573                 :          0 :         return err;
     574                 :            : }
     575                 :            : EXPORT_SYMBOL(phy_stop_interrupts);
     576                 :            : 
     577                 :            : /**
     578                 :            :  * phy_change - Scheduled by the phy_interrupt/timer to handle PHY changes
     579                 :            :  * @work: work_struct that describes the work to be done
     580                 :            :  */
     581                 :          0 : void phy_change(struct work_struct *work)
     582                 :            : {
     583                 :          0 :         struct phy_device *phydev =
     584                 :            :                 container_of(work, struct phy_device, phy_queue);
     585                 :            : 
     586   [ #  #  #  # ]:          0 :         if (phydev->drv->did_interrupt &&
     587                 :          0 :             !phydev->drv->did_interrupt(phydev))
     588                 :            :                 goto ignore;
     589                 :            : 
     590         [ #  # ]:          0 :         if (phy_disable_interrupts(phydev))
     591                 :            :                 goto phy_err;
     592                 :            : 
     593                 :          0 :         mutex_lock(&phydev->lock);
     594         [ #  # ]:          0 :         if ((PHY_RUNNING == phydev->state) || (PHY_NOLINK == phydev->state))
     595                 :          0 :                 phydev->state = PHY_CHANGELINK;
     596                 :          0 :         mutex_unlock(&phydev->lock);
     597                 :            : 
     598                 :          0 :         atomic_dec(&phydev->irq_disable);
     599                 :          0 :         enable_irq(phydev->irq);
     600                 :            : 
     601                 :            :         /* Reenable interrupts */
     602 [ #  # ][ #  # ]:          0 :         if (PHY_HALTED != phydev->state &&
     603                 :            :             phy_config_interrupt(phydev, PHY_INTERRUPT_ENABLED))
     604                 :            :                 goto irq_enable_err;
     605                 :            : 
     606                 :            :         /* reschedule state queue work to run as soon as possible */
     607                 :          0 :         cancel_delayed_work_sync(&phydev->state_queue);
     608                 :          0 :         queue_delayed_work(system_power_efficient_wq, &phydev->state_queue, 0);
     609                 :            :         return;
     610                 :            : 
     611                 :            : ignore:
     612                 :          0 :         atomic_dec(&phydev->irq_disable);
     613                 :          0 :         enable_irq(phydev->irq);
     614                 :          0 :         return;
     615                 :            : 
     616                 :            : irq_enable_err:
     617                 :          0 :         disable_irq(phydev->irq);
     618                 :            :         atomic_inc(&phydev->irq_disable);
     619                 :            : phy_err:
     620                 :            :         phy_error(phydev);
     621                 :            : }
     622                 :            : 
     623                 :            : /**
     624                 :            :  * phy_stop - Bring down the PHY link, and stop checking the status
     625                 :            :  * @phydev: target phy_device struct
     626                 :            :  */
     627                 :          0 : void phy_stop(struct phy_device *phydev)
     628                 :            : {
     629                 :          0 :         mutex_lock(&phydev->lock);
     630                 :            : 
     631         [ #  # ]:          0 :         if (PHY_HALTED == phydev->state)
     632                 :            :                 goto out_unlock;
     633                 :            : 
     634         [ #  # ]:          0 :         if (phy_interrupt_is_valid(phydev)) {
     635                 :            :                 /* Disable PHY Interrupts */
     636                 :            :                 phy_config_interrupt(phydev, PHY_INTERRUPT_DISABLED);
     637                 :            : 
     638                 :            :                 /* Clear any pending interrupts */
     639                 :            :                 phy_clear_interrupt(phydev);
     640                 :            :         }
     641                 :            : 
     642                 :          0 :         phydev->state = PHY_HALTED;
     643                 :            : 
     644                 :            : out_unlock:
     645                 :          0 :         mutex_unlock(&phydev->lock);
     646                 :            : 
     647                 :            :         /* Cannot call flush_scheduled_work() here as desired because
     648                 :            :          * of rtnl_lock(), but PHY_HALTED shall guarantee phy_change()
     649                 :            :          * will not reenable interrupts.
     650                 :            :          */
     651                 :          0 : }
     652                 :            : EXPORT_SYMBOL(phy_stop);
     653                 :            : 
     654                 :            : /**
     655                 :            :  * phy_start - start or restart a PHY device
     656                 :            :  * @phydev: target phy_device struct
     657                 :            :  *
     658                 :            :  * Description: Indicates the attached device's readiness to
     659                 :            :  *   handle PHY-related work.  Used during startup to start the
     660                 :            :  *   PHY, and after a call to phy_stop() to resume operation.
     661                 :            :  *   Also used to indicate the MDIO bus has cleared an error
     662                 :            :  *   condition.
     663                 :            :  */
     664                 :          0 : void phy_start(struct phy_device *phydev)
     665                 :            : {
     666                 :          0 :         mutex_lock(&phydev->lock);
     667                 :            : 
     668   [ #  #  #  # ]:          0 :         switch (phydev->state) {
     669                 :            :         case PHY_STARTING:
     670                 :          0 :                 phydev->state = PHY_PENDING;
     671                 :          0 :                 break;
     672                 :            :         case PHY_READY:
     673                 :          0 :                 phydev->state = PHY_UP;
     674                 :          0 :                 break;
     675                 :            :         case PHY_HALTED:
     676                 :          0 :                 phydev->state = PHY_RESUMING;
     677                 :            :         default:
     678                 :            :                 break;
     679                 :            :         }
     680                 :          0 :         mutex_unlock(&phydev->lock);
     681                 :          0 : }
     682                 :            : EXPORT_SYMBOL(phy_start);
     683                 :            : 
     684                 :            : /**
     685                 :            :  * phy_state_machine - Handle the state machine
     686                 :            :  * @work: work_struct that describes the work to be done
     687                 :            :  */
     688                 :          0 : void phy_state_machine(struct work_struct *work)
     689                 :            : {
     690                 :            :         struct delayed_work *dwork = to_delayed_work(work);
     691                 :      65866 :         struct phy_device *phydev =
     692                 :            :                         container_of(dwork, struct phy_device, state_queue);
     693                 :            :         int needs_aneg = 0, do_suspend = 0;
     694                 :            :         int err = 0;
     695                 :            : 
     696                 :      32933 :         mutex_lock(&phydev->lock);
     697                 :            : 
     698   [ -  -  -  -  :      32933 :         switch (phydev->state) {
             +  +  -  -  
                      - ]
     699                 :            :         case PHY_DOWN:
     700                 :            :         case PHY_STARTING:
     701                 :            :         case PHY_READY:
     702                 :            :         case PHY_PENDING:
     703                 :            :                 break;
     704                 :            :         case PHY_UP:
     705                 :            :                 needs_aneg = 1;
     706                 :            : 
     707                 :          0 :                 phydev->link_timeout = PHY_AN_TIMEOUT;
     708                 :            : 
     709                 :          0 :                 break;
     710                 :            :         case PHY_AN:
     711                 :            :                 err = phy_read_status(phydev);
     712         [ #  # ]:          0 :                 if (err < 0)
     713                 :            :                         break;
     714                 :            : 
     715                 :            :                 /* If the link is down, give up on negotiation for now */
     716         [ #  # ]:          0 :                 if (!phydev->link) {
     717                 :          0 :                         phydev->state = PHY_NOLINK;
     718                 :          0 :                         netif_carrier_off(phydev->attached_dev);
     719                 :          0 :                         phydev->adjust_link(phydev->attached_dev);
     720                 :          0 :                         break;
     721                 :            :                 }
     722                 :            : 
     723                 :            :                 /* Check if negotiation is done.  Break if there's an error */
     724                 :            :                 err = phy_aneg_done(phydev);
     725         [ #  # ]:          0 :                 if (err < 0)
     726                 :            :                         break;
     727                 :            : 
     728                 :            :                 /* If AN is done, we're running */
     729         [ #  # ]:          0 :                 if (err > 0) {
     730                 :          0 :                         phydev->state = PHY_RUNNING;
     731                 :          0 :                         netif_carrier_on(phydev->attached_dev);
     732                 :          0 :                         phydev->adjust_link(phydev->attached_dev);
     733                 :            : 
     734         [ #  # ]:          0 :                 } else if (0 == phydev->link_timeout--) {
     735                 :            :                         needs_aneg = 1;
     736                 :            :                         /* If we have the magic_aneg bit, we try again */
     737                 :            :                         if (phydev->drv->flags & PHY_HAS_MAGICANEG)
     738                 :            :                                 break;
     739                 :            :                 }
     740                 :            :                 break;
     741                 :            :         case PHY_NOLINK:
     742                 :            :                 err = phy_read_status(phydev);
     743         [ #  # ]:          0 :                 if (err)
     744                 :            :                         break;
     745                 :            : 
     746         [ #  # ]:          0 :                 if (phydev->link) {
     747                 :          0 :                         phydev->state = PHY_RUNNING;
     748                 :          0 :                         netif_carrier_on(phydev->attached_dev);
     749                 :          0 :                         phydev->adjust_link(phydev->attached_dev);
     750                 :            :                 }
     751                 :            :                 break;
     752                 :            :         case PHY_FORCING:
     753                 :          0 :                 err = genphy_update_link(phydev);
     754         [ #  # ]:          0 :                 if (err)
     755                 :            :                         break;
     756                 :            : 
     757         [ #  # ]:          0 :                 if (phydev->link) {
     758                 :          0 :                         phydev->state = PHY_RUNNING;
     759                 :          0 :                         netif_carrier_on(phydev->attached_dev);
     760                 :            :                 } else {
     761         [ #  # ]:          0 :                         if (0 == phydev->link_timeout--)
     762                 :            :                                 needs_aneg = 1;
     763                 :            :                 }
     764                 :            : 
     765                 :          0 :                 phydev->adjust_link(phydev->attached_dev);
     766                 :          0 :                 break;
     767                 :            :         case PHY_RUNNING:
     768                 :            :                 /* Only register a CHANGE if we are
     769                 :            :                  * polling or ignoring interrupts
     770                 :            :                  */
     771         [ +  - ]:      16466 :                 if (!phy_interrupt_is_valid(phydev))
     772                 :      16466 :                         phydev->state = PHY_CHANGELINK;
     773                 :            :                 break;
     774                 :            :         case PHY_CHANGELINK:
     775                 :            :                 err = phy_read_status(phydev);
     776         [ +  - ]:      16467 :                 if (err)
     777                 :            :                         break;
     778                 :            : 
     779         [ +  - ]:      16467 :                 if (phydev->link) {
     780                 :      16467 :                         phydev->state = PHY_RUNNING;
     781                 :      16467 :                         netif_carrier_on(phydev->attached_dev);
     782                 :            :                 } else {
     783                 :          0 :                         phydev->state = PHY_NOLINK;
     784                 :          0 :                         netif_carrier_off(phydev->attached_dev);
     785                 :            :                 }
     786                 :            : 
     787                 :      16467 :                 phydev->adjust_link(phydev->attached_dev);
     788                 :            : 
     789         [ -  + ]:      16467 :                 if (phy_interrupt_is_valid(phydev))
     790                 :            :                         err = phy_config_interrupt(phydev,
     791                 :            :                                                    PHY_INTERRUPT_ENABLED);
     792                 :            :                 break;
     793                 :            :         case PHY_HALTED:
     794         [ #  # ]:          0 :                 if (phydev->link) {
     795                 :          0 :                         phydev->link = 0;
     796                 :          0 :                         netif_carrier_off(phydev->attached_dev);
     797                 :          0 :                         phydev->adjust_link(phydev->attached_dev);
     798                 :            :                         do_suspend = 1;
     799                 :            :                 }
     800                 :            :                 break;
     801                 :            :         case PHY_RESUMING:
     802                 :            :                 err = phy_clear_interrupt(phydev);
     803         [ #  # ]:          0 :                 if (err)
     804                 :            :                         break;
     805                 :            : 
     806                 :            :                 err = phy_config_interrupt(phydev, PHY_INTERRUPT_ENABLED);
     807         [ #  # ]:          0 :                 if (err)
     808                 :            :                         break;
     809                 :            : 
     810         [ #  # ]:          0 :                 if (AUTONEG_ENABLE == phydev->autoneg) {
     811                 :            :                         err = phy_aneg_done(phydev);
     812         [ #  # ]:          0 :                         if (err < 0)
     813                 :            :                                 break;
     814                 :            : 
     815                 :            :                         /* err > 0 if AN is done.
     816                 :            :                          * Otherwise, it's 0, and we're  still waiting for AN
     817                 :            :                          */
     818         [ #  # ]:          0 :                         if (err > 0) {
     819                 :            :                                 err = phy_read_status(phydev);
     820         [ #  # ]:          0 :                                 if (err)
     821                 :            :                                         break;
     822                 :            : 
     823         [ #  # ]:          0 :                                 if (phydev->link) {
     824                 :          0 :                                         phydev->state = PHY_RUNNING;
     825                 :          0 :                                         netif_carrier_on(phydev->attached_dev);
     826                 :            :                                 } else  {
     827                 :          0 :                                         phydev->state = PHY_NOLINK;
     828                 :            :                                 }
     829                 :          0 :                                 phydev->adjust_link(phydev->attached_dev);
     830                 :            :                         } else {
     831                 :          0 :                                 phydev->state = PHY_AN;
     832                 :          0 :                                 phydev->link_timeout = PHY_AN_TIMEOUT;
     833                 :            :                         }
     834                 :            :                 } else {
     835                 :            :                         err = phy_read_status(phydev);
     836         [ #  # ]:          0 :                         if (err)
     837                 :            :                                 break;
     838                 :            : 
     839         [ #  # ]:          0 :                         if (phydev->link) {
     840                 :          0 :                                 phydev->state = PHY_RUNNING;
     841                 :          0 :                                 netif_carrier_on(phydev->attached_dev);
     842                 :            :                         } else  {
     843                 :          0 :                                 phydev->state = PHY_NOLINK;
     844                 :            :                         }
     845                 :          0 :                         phydev->adjust_link(phydev->attached_dev);
     846                 :            :                 }
     847                 :            :                 break;
     848                 :            :         }
     849                 :            : 
     850                 :      32933 :         mutex_unlock(&phydev->lock);
     851                 :            : 
     852         [ -  + ]:      32933 :         if (needs_aneg)
     853                 :          0 :                 err = phy_start_aneg(phydev);
     854                 :            : 
     855         [ -  + ]:      32933 :         if (do_suspend)
     856                 :          0 :                 phy_suspend(phydev);
     857                 :            : 
     858         [ -  + ]:      32933 :         if (err < 0)
     859                 :            :                 phy_error(phydev);
     860                 :            : 
     861                 :      32933 :         queue_delayed_work(system_power_efficient_wq, &phydev->state_queue,
     862                 :            :                            PHY_STATE_TIME * HZ);
     863                 :      32933 : }
     864                 :            : 
     865                 :          0 : void phy_mac_interrupt(struct phy_device *phydev, int new_link)
     866                 :            : {
     867                 :          0 :         cancel_work_sync(&phydev->phy_queue);
     868                 :          0 :         phydev->link = new_link;
     869                 :            :         schedule_work(&phydev->phy_queue);
     870                 :          0 : }
     871                 :            : EXPORT_SYMBOL(phy_mac_interrupt);
     872                 :            : 
     873                 :            : static inline void mmd_phy_indirect(struct mii_bus *bus, int prtad, int devad,
     874                 :            :                                     int addr)
     875                 :            : {
     876                 :            :         /* Write the desired MMD Devad */
     877                 :          0 :         bus->write(bus, addr, MII_MMD_CTRL, devad);
     878                 :            : 
     879                 :            :         /* Write the desired MMD register address */
     880                 :          0 :         bus->write(bus, addr, MII_MMD_DATA, prtad);
     881                 :            : 
     882                 :            :         /* Select the Function : DATA with no post increment */
     883                 :          0 :         bus->write(bus, addr, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR));
     884                 :            : }
     885                 :            : 
     886                 :            : /**
     887                 :            :  * phy_read_mmd_indirect - reads data from the MMD registers
     888                 :            :  * @bus: the target MII bus
     889                 :            :  * @prtad: MMD Address
     890                 :            :  * @devad: MMD DEVAD
     891                 :            :  * @addr: PHY address on the MII bus
     892                 :            :  *
     893                 :            :  * Description: it reads data from the MMD registers (clause 22 to access to
     894                 :            :  * clause 45) of the specified phy address.
     895                 :            :  * To read these register we have:
     896                 :            :  * 1) Write reg 13 // DEVAD
     897                 :            :  * 2) Write reg 14 // MMD Address
     898                 :            :  * 3) Write reg 13 // MMD Data Command for MMD DEVAD
     899                 :            :  * 3) Read  reg 14 // Read MMD data
     900                 :            :  */
     901                 :          0 : static int phy_read_mmd_indirect(struct mii_bus *bus, int prtad, int devad,
     902                 :            :                                  int addr)
     903                 :            : {
     904                 :            :         mmd_phy_indirect(bus, prtad, devad, addr);
     905                 :            : 
     906                 :            :         /* Read the content of the MMD's selected register */
     907                 :          0 :         return bus->read(bus, addr, MII_MMD_DATA);
     908                 :            : }
     909                 :            : 
     910                 :            : /**
     911                 :            :  * phy_write_mmd_indirect - writes data to the MMD registers
     912                 :            :  * @bus: the target MII bus
     913                 :            :  * @prtad: MMD Address
     914                 :            :  * @devad: MMD DEVAD
     915                 :            :  * @addr: PHY address on the MII bus
     916                 :            :  * @data: data to write in the MMD register
     917                 :            :  *
     918                 :            :  * Description: Write data from the MMD registers of the specified
     919                 :            :  * phy address.
     920                 :            :  * To write these register we have:
     921                 :            :  * 1) Write reg 13 // DEVAD
     922                 :            :  * 2) Write reg 14 // MMD Address
     923                 :            :  * 3) Write reg 13 // MMD Data Command for MMD DEVAD
     924                 :            :  * 3) Write reg 14 // Write MMD data
     925                 :            :  */
     926                 :          0 : static void phy_write_mmd_indirect(struct mii_bus *bus, int prtad, int devad,
     927                 :            :                                    int addr, u32 data)
     928                 :            : {
     929                 :            :         mmd_phy_indirect(bus, prtad, devad, addr);
     930                 :            : 
     931                 :            :         /* Write the data into MMD's selected register */
     932                 :          0 :         bus->write(bus, addr, MII_MMD_DATA, data);
     933                 :          0 : }
     934                 :            : 
     935                 :            : /**
     936                 :            :  * phy_init_eee - init and check the EEE feature
     937                 :            :  * @phydev: target phy_device struct
     938                 :            :  * @clk_stop_enable: PHY may stop the clock during LPI
     939                 :            :  *
     940                 :            :  * Description: it checks if the Energy-Efficient Ethernet (EEE)
     941                 :            :  * is supported by looking at the MMD registers 3.20 and 7.60/61
     942                 :            :  * and it programs the MMD register 3.0 setting the "Clock stop enable"
     943                 :            :  * bit if required.
     944                 :            :  */
     945                 :          0 : int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable)
     946                 :            : {
     947                 :            :         /* According to 802.3az,the EEE is supported only in full duplex-mode.
     948                 :            :          * Also EEE feature is active when core is operating with MII, GMII
     949                 :            :          * or RGMII.
     950                 :            :          */
     951 [ #  # ][ #  # ]:          0 :         if ((phydev->duplex == DUPLEX_FULL) &&
     952                 :          0 :             ((phydev->interface == PHY_INTERFACE_MODE_MII) ||
     953                 :          0 :             (phydev->interface == PHY_INTERFACE_MODE_GMII) ||
     954                 :            :             (phydev->interface == PHY_INTERFACE_MODE_RGMII))) {
     955                 :            :                 int eee_lp, eee_cap, eee_adv;
     956                 :            :                 u32 lp, cap, adv;
     957                 :            :                 int status;
     958                 :            :                 unsigned int idx;
     959                 :            : 
     960                 :            :                 /* Read phy status to properly get the right settings */
     961                 :            :                 status = phy_read_status(phydev);
     962         [ #  # ]:          0 :                 if (status)
     963                 :            :                         return status;
     964                 :            : 
     965                 :            :                 /* First check if the EEE ability is supported */
     966                 :          0 :                 eee_cap = phy_read_mmd_indirect(phydev->bus, MDIO_PCS_EEE_ABLE,
     967                 :            :                                                 MDIO_MMD_PCS, phydev->addr);
     968         [ #  # ]:          0 :                 if (eee_cap < 0)
     969                 :            :                         return eee_cap;
     970                 :            : 
     971                 :          0 :                 cap = mmd_eee_cap_to_ethtool_sup_t(eee_cap);
     972         [ #  # ]:          0 :                 if (!cap)
     973                 :            :                         return -EPROTONOSUPPORT;
     974                 :            : 
     975                 :            :                 /* Check which link settings negotiated and verify it in
     976                 :            :                  * the EEE advertising registers.
     977                 :            :                  */
     978                 :          0 :                 eee_lp = phy_read_mmd_indirect(phydev->bus, MDIO_AN_EEE_LPABLE,
     979                 :            :                                                MDIO_MMD_AN, phydev->addr);
     980         [ #  # ]:          0 :                 if (eee_lp < 0)
     981                 :            :                         return eee_lp;
     982                 :            : 
     983                 :          0 :                 eee_adv = phy_read_mmd_indirect(phydev->bus, MDIO_AN_EEE_ADV,
     984                 :            :                                                 MDIO_MMD_AN, phydev->addr);
     985         [ #  # ]:          0 :                 if (eee_adv < 0)
     986                 :            :                         return eee_adv;
     987                 :            : 
     988                 :          0 :                 adv = mmd_eee_adv_to_ethtool_adv_t(eee_adv);
     989                 :          0 :                 lp = mmd_eee_adv_to_ethtool_adv_t(eee_lp);
     990                 :          0 :                 idx = phy_find_setting(phydev->speed, phydev->duplex);
     991         [ #  # ]:          0 :                 if (!(lp & adv & settings[idx].setting))
     992                 :            :                         return -EPROTONOSUPPORT;
     993                 :            : 
     994         [ #  # ]:          0 :                 if (clk_stop_enable) {
     995                 :            :                         /* Configure the PHY to stop receiving xMII
     996                 :            :                          * clock while it is signaling LPI.
     997                 :            :                          */
     998                 :          0 :                         int val = phy_read_mmd_indirect(phydev->bus, MDIO_CTRL1,
     999                 :            :                                                         MDIO_MMD_PCS,
    1000                 :            :                                                         phydev->addr);
    1001         [ #  # ]:          0 :                         if (val < 0)
    1002                 :            :                                 return val;
    1003                 :            : 
    1004                 :          0 :                         val |= MDIO_PCS_CTRL1_CLKSTOP_EN;
    1005                 :          0 :                         phy_write_mmd_indirect(phydev->bus, MDIO_CTRL1,
    1006                 :            :                                                MDIO_MMD_PCS, phydev->addr, val);
    1007                 :            :                 }
    1008                 :            : 
    1009                 :            :                 return 0; /* EEE supported */
    1010                 :            :         }
    1011                 :            : 
    1012                 :            :         return -EPROTONOSUPPORT;
    1013                 :            : }
    1014                 :            : EXPORT_SYMBOL(phy_init_eee);
    1015                 :            : 
    1016                 :            : /**
    1017                 :            :  * phy_get_eee_err - report the EEE wake error count
    1018                 :            :  * @phydev: target phy_device struct
    1019                 :            :  *
    1020                 :            :  * Description: it is to report the number of time where the PHY
    1021                 :            :  * failed to complete its normal wake sequence.
    1022                 :            :  */
    1023                 :          0 : int phy_get_eee_err(struct phy_device *phydev)
    1024                 :            : {
    1025                 :          0 :         return phy_read_mmd_indirect(phydev->bus, MDIO_PCS_EEE_WK_ERR,
    1026                 :            :                                      MDIO_MMD_PCS, phydev->addr);
    1027                 :            : }
    1028                 :            : EXPORT_SYMBOL(phy_get_eee_err);
    1029                 :            : 
    1030                 :            : /**
    1031                 :            :  * phy_ethtool_get_eee - get EEE supported and status
    1032                 :            :  * @phydev: target phy_device struct
    1033                 :            :  * @data: ethtool_eee data
    1034                 :            :  *
    1035                 :            :  * Description: it reportes the Supported/Advertisement/LP Advertisement
    1036                 :            :  * capabilities.
    1037                 :            :  */
    1038                 :          0 : int phy_ethtool_get_eee(struct phy_device *phydev, struct ethtool_eee *data)
    1039                 :            : {
    1040                 :            :         int val;
    1041                 :            : 
    1042                 :            :         /* Get Supported EEE */
    1043                 :          0 :         val = phy_read_mmd_indirect(phydev->bus, MDIO_PCS_EEE_ABLE,
    1044                 :            :                                     MDIO_MMD_PCS, phydev->addr);
    1045         [ #  # ]:          0 :         if (val < 0)
    1046                 :            :                 return val;
    1047                 :          0 :         data->supported = mmd_eee_cap_to_ethtool_sup_t(val);
    1048                 :            : 
    1049                 :            :         /* Get advertisement EEE */
    1050                 :          0 :         val = phy_read_mmd_indirect(phydev->bus, MDIO_AN_EEE_ADV,
    1051                 :            :                                     MDIO_MMD_AN, phydev->addr);
    1052         [ #  # ]:          0 :         if (val < 0)
    1053                 :            :                 return val;
    1054                 :          0 :         data->advertised = mmd_eee_adv_to_ethtool_adv_t(val);
    1055                 :            : 
    1056                 :            :         /* Get LP advertisement EEE */
    1057                 :          0 :         val = phy_read_mmd_indirect(phydev->bus, MDIO_AN_EEE_LPABLE,
    1058                 :            :                                     MDIO_MMD_AN, phydev->addr);
    1059         [ #  # ]:          0 :         if (val < 0)
    1060                 :            :                 return val;
    1061                 :          0 :         data->lp_advertised = mmd_eee_adv_to_ethtool_adv_t(val);
    1062                 :            : 
    1063                 :          0 :         return 0;
    1064                 :            : }
    1065                 :            : EXPORT_SYMBOL(phy_ethtool_get_eee);
    1066                 :            : 
    1067                 :            : /**
    1068                 :            :  * phy_ethtool_set_eee - set EEE supported and status
    1069                 :            :  * @phydev: target phy_device struct
    1070                 :            :  * @data: ethtool_eee data
    1071                 :            :  *
    1072                 :            :  * Description: it is to program the Advertisement EEE register.
    1073                 :            :  */
    1074                 :          0 : int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_eee *data)
    1075                 :            : {
    1076                 :          0 :         int val = ethtool_adv_to_mmd_eee_adv_t(data->advertised);
    1077                 :            : 
    1078                 :          0 :         phy_write_mmd_indirect(phydev->bus, MDIO_AN_EEE_ADV, MDIO_MMD_AN,
    1079                 :            :                                phydev->addr, val);
    1080                 :            : 
    1081                 :          0 :         return 0;
    1082                 :            : }
    1083                 :            : EXPORT_SYMBOL(phy_ethtool_set_eee);
    1084                 :            : 
    1085                 :          0 : int phy_ethtool_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol)
    1086                 :            : {
    1087         [ #  # ]:          0 :         if (phydev->drv->set_wol)
    1088                 :          0 :                 return phydev->drv->set_wol(phydev, wol);
    1089                 :            : 
    1090                 :            :         return -EOPNOTSUPP;
    1091                 :            : }
    1092                 :            : EXPORT_SYMBOL(phy_ethtool_set_wol);
    1093                 :            : 
    1094                 :          0 : void phy_ethtool_get_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol)
    1095                 :            : {
    1096         [ #  # ]:          0 :         if (phydev->drv->get_wol)
    1097                 :          0 :                 phydev->drv->get_wol(phydev, wol);
    1098                 :          0 : }
    1099                 :            : EXPORT_SYMBOL(phy_ethtool_get_wol);

Generated by: LCOV version 1.9