LCOV - code coverage report
Current view: top level - drivers/net - mii.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 161 0.0 %
Date: 2014-04-07 Functions: 0 9 0.0 %
Branches: 0 121 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            : 
       3                 :            :         mii.c: MII interface library
       4                 :            : 
       5                 :            :         Maintained by Jeff Garzik <jgarzik@pobox.com>
       6                 :            :         Copyright 2001,2002 Jeff Garzik
       7                 :            : 
       8                 :            :         Various code came from myson803.c and other files by
       9                 :            :         Donald Becker.  Copyright:
      10                 :            : 
      11                 :            :                 Written 1998-2002 by Donald Becker.
      12                 :            : 
      13                 :            :                 This software may be used and distributed according
      14                 :            :                 to the terms of the GNU General Public License (GPL),
      15                 :            :                 incorporated herein by reference.  Drivers based on
      16                 :            :                 or derived from this code fall under the GPL and must
      17                 :            :                 retain the authorship, copyright and license notice.
      18                 :            :                 This file is not a complete program and may only be
      19                 :            :                 used when the entire operating system is licensed
      20                 :            :                 under the GPL.
      21                 :            : 
      22                 :            :                 The author may be reached as becker@scyld.com, or C/O
      23                 :            :                 Scyld Computing Corporation
      24                 :            :                 410 Severn Ave., Suite 210
      25                 :            :                 Annapolis MD 21403
      26                 :            : 
      27                 :            : 
      28                 :            :  */
      29                 :            : 
      30                 :            : #include <linux/kernel.h>
      31                 :            : #include <linux/module.h>
      32                 :            : #include <linux/netdevice.h>
      33                 :            : #include <linux/ethtool.h>
      34                 :            : #include <linux/mii.h>
      35                 :            : 
      36                 :          0 : static u32 mii_get_an(struct mii_if_info *mii, u16 addr)
      37                 :            : {
      38                 :            :         int advert;
      39                 :            : 
      40                 :          0 :         advert = mii->mdio_read(mii->dev, mii->phy_id, addr);
      41                 :            : 
      42                 :          0 :         return mii_lpa_to_ethtool_lpa_t(advert);
      43                 :            : }
      44                 :            : 
      45                 :            : /**
      46                 :            :  * mii_ethtool_gset - get settings that are specified in @ecmd
      47                 :            :  * @mii: MII interface
      48                 :            :  * @ecmd: requested ethtool_cmd
      49                 :            :  *
      50                 :            :  * The @ecmd parameter is expected to have been cleared before calling
      51                 :            :  * mii_ethtool_gset().
      52                 :            :  *
      53                 :            :  * Returns 0 for success, negative on error.
      54                 :            :  */
      55                 :          0 : int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
      56                 :            : {
      57                 :          0 :         struct net_device *dev = mii->dev;
      58                 :            :         u16 bmcr, bmsr, ctrl1000 = 0, stat1000 = 0;
      59                 :            :         u32 nego;
      60                 :            : 
      61                 :          0 :         ecmd->supported =
      62                 :            :             (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
      63                 :            :              SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
      64                 :            :              SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII);
      65         [ #  # ]:          0 :         if (mii->supports_gmii)
      66                 :          0 :                 ecmd->supported |= SUPPORTED_1000baseT_Half |
      67                 :            :                         SUPPORTED_1000baseT_Full;
      68                 :            : 
      69                 :            :         /* only supports twisted-pair */
      70                 :          0 :         ecmd->port = PORT_MII;
      71                 :            : 
      72                 :            :         /* only supports internal transceiver */
      73                 :          0 :         ecmd->transceiver = XCVR_INTERNAL;
      74                 :            : 
      75                 :            :         /* this isn't fully supported at higher layers */
      76                 :          0 :         ecmd->phy_address = mii->phy_id;
      77                 :          0 :         ecmd->mdio_support = ETH_MDIO_SUPPORTS_C22;
      78                 :            : 
      79                 :          0 :         ecmd->advertising = ADVERTISED_TP | ADVERTISED_MII;
      80                 :            : 
      81                 :          0 :         bmcr = mii->mdio_read(dev, mii->phy_id, MII_BMCR);
      82                 :          0 :         bmsr = mii->mdio_read(dev, mii->phy_id, MII_BMSR);
      83         [ #  # ]:          0 :         if (mii->supports_gmii) {
      84                 :          0 :                 ctrl1000 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000);
      85                 :          0 :                 stat1000 = mii->mdio_read(dev, mii->phy_id, MII_STAT1000);
      86                 :            :         }
      87         [ #  # ]:          0 :         if (bmcr & BMCR_ANENABLE) {
      88                 :          0 :                 ecmd->advertising |= ADVERTISED_Autoneg;
      89                 :          0 :                 ecmd->autoneg = AUTONEG_ENABLE;
      90                 :            : 
      91                 :          0 :                 ecmd->advertising |= mii_get_an(mii, MII_ADVERTISE);
      92         [ #  # ]:          0 :                 if (mii->supports_gmii)
      93                 :          0 :                         ecmd->advertising |=
      94                 :            :                                         mii_ctrl1000_to_ethtool_adv_t(ctrl1000);
      95                 :            : 
      96         [ #  # ]:          0 :                 if (bmsr & BMSR_ANEGCOMPLETE) {
      97                 :          0 :                         ecmd->lp_advertising = mii_get_an(mii, MII_LPA);
      98                 :          0 :                         ecmd->lp_advertising |=
      99                 :            :                                         mii_stat1000_to_ethtool_lpa_t(stat1000);
     100                 :            :                 } else {
     101                 :          0 :                         ecmd->lp_advertising = 0;
     102                 :            :                 }
     103                 :            : 
     104                 :          0 :                 nego = ecmd->advertising & ecmd->lp_advertising;
     105                 :            : 
     106         [ #  # ]:          0 :                 if (nego & (ADVERTISED_1000baseT_Full |
     107                 :            :                             ADVERTISED_1000baseT_Half)) {
     108                 :            :                         ethtool_cmd_speed_set(ecmd, SPEED_1000);
     109                 :          0 :                         ecmd->duplex = !!(nego & ADVERTISED_1000baseT_Full);
     110         [ #  # ]:          0 :                 } else if (nego & (ADVERTISED_100baseT_Full |
     111                 :            :                                    ADVERTISED_100baseT_Half)) {
     112                 :            :                         ethtool_cmd_speed_set(ecmd, SPEED_100);
     113                 :          0 :                         ecmd->duplex = !!(nego & ADVERTISED_100baseT_Full);
     114                 :            :                 } else {
     115                 :            :                         ethtool_cmd_speed_set(ecmd, SPEED_10);
     116                 :          0 :                         ecmd->duplex = !!(nego & ADVERTISED_10baseT_Full);
     117                 :            :                 }
     118                 :            :         } else {
     119                 :          0 :                 ecmd->autoneg = AUTONEG_DISABLE;
     120                 :            : 
     121 [ #  # ][ #  # ]:          0 :                 ethtool_cmd_speed_set(ecmd,
     122                 :          0 :                                       ((bmcr & BMCR_SPEED1000 &&
     123                 :            :                                         (bmcr & BMCR_SPEED100) == 0) ?
     124                 :            :                                        SPEED_1000 :
     125                 :          0 :                                        ((bmcr & BMCR_SPEED100) ?
     126                 :            :                                         SPEED_100 : SPEED_10)));
     127                 :          0 :                 ecmd->duplex = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : DUPLEX_HALF;
     128                 :            :         }
     129                 :            : 
     130                 :          0 :         mii->full_duplex = ecmd->duplex;
     131                 :            : 
     132                 :            :         /* ignore maxtxpkt, maxrxpkt for now */
     133                 :            : 
     134                 :          0 :         return 0;
     135                 :            : }
     136                 :            : 
     137                 :            : /**
     138                 :            :  * mii_ethtool_sset - set settings that are specified in @ecmd
     139                 :            :  * @mii: MII interface
     140                 :            :  * @ecmd: requested ethtool_cmd
     141                 :            :  *
     142                 :            :  * Returns 0 for success, negative on error.
     143                 :            :  */
     144                 :          0 : int mii_ethtool_sset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
     145                 :            : {
     146                 :          0 :         struct net_device *dev = mii->dev;
     147                 :            :         u32 speed = ethtool_cmd_speed(ecmd);
     148                 :            : 
     149         [ #  # ]:          0 :         if (speed != SPEED_10 &&
     150         [ #  # ]:          0 :             speed != SPEED_100 &&
     151                 :            :             speed != SPEED_1000)
     152                 :            :                 return -EINVAL;
     153         [ #  # ]:          0 :         if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL)
     154                 :            :                 return -EINVAL;
     155         [ #  # ]:          0 :         if (ecmd->port != PORT_MII)
     156                 :            :                 return -EINVAL;
     157         [ #  # ]:          0 :         if (ecmd->transceiver != XCVR_INTERNAL)
     158                 :            :                 return -EINVAL;
     159         [ #  # ]:          0 :         if (ecmd->phy_address != mii->phy_id)
     160                 :            :                 return -EINVAL;
     161         [ #  # ]:          0 :         if (ecmd->autoneg != AUTONEG_DISABLE && ecmd->autoneg != AUTONEG_ENABLE)
     162                 :            :                 return -EINVAL;
     163 [ #  # ][ #  # ]:          0 :         if ((speed == SPEED_1000) && (!mii->supports_gmii))
     164                 :            :                 return -EINVAL;
     165                 :            : 
     166                 :            :         /* ignore supported, maxtxpkt, maxrxpkt */
     167                 :            : 
     168         [ #  # ]:          0 :         if (ecmd->autoneg == AUTONEG_ENABLE) {
     169                 :            :                 u32 bmcr, advert, tmp;
     170                 :            :                 u32 advert2 = 0, tmp2 = 0;
     171                 :            : 
     172         [ #  # ]:          0 :                 if ((ecmd->advertising & (ADVERTISED_10baseT_Half |
     173                 :            :                                           ADVERTISED_10baseT_Full |
     174                 :            :                                           ADVERTISED_100baseT_Half |
     175                 :            :                                           ADVERTISED_100baseT_Full |
     176                 :            :                                           ADVERTISED_1000baseT_Half |
     177                 :            :                                           ADVERTISED_1000baseT_Full)) == 0)
     178                 :            :                         return -EINVAL;
     179                 :            : 
     180                 :            :                 /* advertise only what has been requested */
     181                 :          0 :                 advert = mii->mdio_read(dev, mii->phy_id, MII_ADVERTISE);
     182                 :          0 :                 tmp = advert & ~(ADVERTISE_ALL | ADVERTISE_100BASE4);
     183         [ #  # ]:          0 :                 if (mii->supports_gmii) {
     184                 :          0 :                         advert2 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000);
     185                 :          0 :                         tmp2 = advert2 & ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL);
     186                 :            :                 }
     187                 :          0 :                 tmp |= ethtool_adv_to_mii_adv_t(ecmd->advertising);
     188                 :            : 
     189         [ #  # ]:          0 :                 if (mii->supports_gmii)
     190                 :          0 :                         tmp2 |=
     191                 :            :                               ethtool_adv_to_mii_ctrl1000_t(ecmd->advertising);
     192         [ #  # ]:          0 :                 if (advert != tmp) {
     193                 :          0 :                         mii->mdio_write(dev, mii->phy_id, MII_ADVERTISE, tmp);
     194                 :          0 :                         mii->advertising = tmp;
     195                 :            :                 }
     196 [ #  # ][ #  # ]:          0 :                 if ((mii->supports_gmii) && (advert2 != tmp2))
     197                 :          0 :                         mii->mdio_write(dev, mii->phy_id, MII_CTRL1000, tmp2);
     198                 :            : 
     199                 :            :                 /* turn on autonegotiation, and force a renegotiate */
     200                 :          0 :                 bmcr = mii->mdio_read(dev, mii->phy_id, MII_BMCR);
     201                 :          0 :                 bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART);
     202                 :          0 :                 mii->mdio_write(dev, mii->phy_id, MII_BMCR, bmcr);
     203                 :            : 
     204                 :          0 :                 mii->force_media = 0;
     205                 :            :         } else {
     206                 :            :                 u32 bmcr, tmp;
     207                 :            : 
     208                 :            :                 /* turn off auto negotiation, set speed and duplexity */
     209                 :          0 :                 bmcr = mii->mdio_read(dev, mii->phy_id, MII_BMCR);
     210                 :          0 :                 tmp = bmcr & ~(BMCR_ANENABLE | BMCR_SPEED100 |
     211                 :            :                                BMCR_SPEED1000 | BMCR_FULLDPLX);
     212         [ #  # ]:          0 :                 if (speed == SPEED_1000)
     213                 :          0 :                         tmp |= BMCR_SPEED1000;
     214         [ #  # ]:          0 :                 else if (speed == SPEED_100)
     215                 :          0 :                         tmp |= BMCR_SPEED100;
     216         [ #  # ]:          0 :                 if (ecmd->duplex == DUPLEX_FULL) {
     217                 :          0 :                         tmp |= BMCR_FULLDPLX;
     218                 :          0 :                         mii->full_duplex = 1;
     219                 :            :                 } else
     220                 :          0 :                         mii->full_duplex = 0;
     221         [ #  # ]:          0 :                 if (bmcr != tmp)
     222                 :          0 :                         mii->mdio_write(dev, mii->phy_id, MII_BMCR, tmp);
     223                 :            : 
     224                 :          0 :                 mii->force_media = 1;
     225                 :            :         }
     226                 :            :         return 0;
     227                 :            : }
     228                 :            : 
     229                 :            : /**
     230                 :            :  * mii_check_gmii_support - check if the MII supports Gb interfaces
     231                 :            :  * @mii: the MII interface
     232                 :            :  */
     233                 :          0 : int mii_check_gmii_support(struct mii_if_info *mii)
     234                 :            : {
     235                 :            :         int reg;
     236                 :            : 
     237                 :          0 :         reg = mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR);
     238         [ #  # ]:          0 :         if (reg & BMSR_ESTATEN) {
     239                 :          0 :                 reg = mii->mdio_read(mii->dev, mii->phy_id, MII_ESTATUS);
     240         [ #  # ]:          0 :                 if (reg & (ESTATUS_1000_TFULL | ESTATUS_1000_THALF))
     241                 :            :                         return 1;
     242                 :            :         }
     243                 :            : 
     244                 :            :         return 0;
     245                 :            : }
     246                 :            : 
     247                 :            : /**
     248                 :            :  * mii_link_ok - is link status up/ok
     249                 :            :  * @mii: the MII interface
     250                 :            :  *
     251                 :            :  * Returns 1 if the MII reports link status up/ok, 0 otherwise.
     252                 :            :  */
     253                 :          0 : int mii_link_ok (struct mii_if_info *mii)
     254                 :            : {
     255                 :            :         /* first, a dummy read, needed to latch some MII phys */
     256                 :          0 :         mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR);
     257         [ #  # ]:          0 :         if (mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR) & BMSR_LSTATUS)
     258                 :            :                 return 1;
     259                 :          0 :         return 0;
     260                 :            : }
     261                 :            : 
     262                 :            : /**
     263                 :            :  * mii_nway_restart - restart NWay (autonegotiation) for this interface
     264                 :            :  * @mii: the MII interface
     265                 :            :  *
     266                 :            :  * Returns 0 on success, negative on error.
     267                 :            :  */
     268                 :          0 : int mii_nway_restart (struct mii_if_info *mii)
     269                 :            : {
     270                 :            :         int bmcr;
     271                 :            :         int r = -EINVAL;
     272                 :            : 
     273                 :            :         /* if autoneg is off, it's an error */
     274                 :          0 :         bmcr = mii->mdio_read(mii->dev, mii->phy_id, MII_BMCR);
     275                 :            : 
     276         [ #  # ]:          0 :         if (bmcr & BMCR_ANENABLE) {
     277                 :          0 :                 bmcr |= BMCR_ANRESTART;
     278                 :          0 :                 mii->mdio_write(mii->dev, mii->phy_id, MII_BMCR, bmcr);
     279                 :            :                 r = 0;
     280                 :            :         }
     281                 :            : 
     282                 :          0 :         return r;
     283                 :            : }
     284                 :            : 
     285                 :            : /**
     286                 :            :  * mii_check_link - check MII link status
     287                 :            :  * @mii: MII interface
     288                 :            :  *
     289                 :            :  * If the link status changed (previous != current), call
     290                 :            :  * netif_carrier_on() if current link status is Up or call
     291                 :            :  * netif_carrier_off() if current link status is Down.
     292                 :            :  */
     293                 :          0 : void mii_check_link (struct mii_if_info *mii)
     294                 :            : {
     295                 :          0 :         int cur_link = mii_link_ok(mii);
     296                 :          0 :         int prev_link = netif_carrier_ok(mii->dev);
     297                 :            : 
     298         [ #  # ]:          0 :         if (cur_link && !prev_link)
     299                 :          0 :                 netif_carrier_on(mii->dev);
     300         [ #  # ]:          0 :         else if (prev_link && !cur_link)
     301                 :          0 :                 netif_carrier_off(mii->dev);
     302                 :          0 : }
     303                 :            : 
     304                 :            : /**
     305                 :            :  * mii_check_media - check the MII interface for a duplex change
     306                 :            :  * @mii: the MII interface
     307                 :            :  * @ok_to_print: OK to print link up/down messages
     308                 :            :  * @init_media: OK to save duplex mode in @mii
     309                 :            :  *
     310                 :            :  * Returns 1 if the duplex mode changed, 0 if not.
     311                 :            :  * If the media type is forced, always returns 0.
     312                 :            :  */
     313                 :          0 : unsigned int mii_check_media (struct mii_if_info *mii,
     314                 :            :                               unsigned int ok_to_print,
     315                 :            :                               unsigned int init_media)
     316                 :            : {
     317                 :            :         unsigned int old_carrier, new_carrier;
     318                 :            :         int advertise, lpa, media, duplex;
     319                 :            :         int lpa2 = 0;
     320                 :            : 
     321                 :            :         /* if forced media, go no further */
     322         [ #  # ]:          0 :         if (mii->force_media)
     323                 :            :                 return 0; /* duplex did not change */
     324                 :            : 
     325                 :            :         /* check current and old link status */
     326                 :          0 :         old_carrier = netif_carrier_ok(mii->dev) ? 1 : 0;
     327                 :          0 :         new_carrier = (unsigned int) mii_link_ok(mii);
     328                 :            : 
     329                 :            :         /* if carrier state did not change, this is a "bounce",
     330                 :            :          * just exit as everything is already set correctly
     331                 :            :          */
     332         [ #  # ]:          0 :         if ((!init_media) && (old_carrier == new_carrier))
     333                 :            :                 return 0; /* duplex did not change */
     334                 :            : 
     335                 :            :         /* no carrier, nothing much to do */
     336         [ #  # ]:          0 :         if (!new_carrier) {
     337                 :          0 :                 netif_carrier_off(mii->dev);
     338         [ #  # ]:          0 :                 if (ok_to_print)
     339                 :          0 :                         netdev_info(mii->dev, "link down\n");
     340                 :            :                 return 0; /* duplex did not change */
     341                 :            :         }
     342                 :            : 
     343                 :            :         /*
     344                 :            :          * we have carrier, see who's on the other end
     345                 :            :          */
     346                 :          0 :         netif_carrier_on(mii->dev);
     347                 :            : 
     348                 :            :         /* get MII advertise and LPA values */
     349 [ #  # ][ #  # ]:          0 :         if ((!init_media) && (mii->advertising))
     350                 :            :                 advertise = mii->advertising;
     351                 :            :         else {
     352                 :          0 :                 advertise = mii->mdio_read(mii->dev, mii->phy_id, MII_ADVERTISE);
     353                 :          0 :                 mii->advertising = advertise;
     354                 :            :         }
     355                 :          0 :         lpa = mii->mdio_read(mii->dev, mii->phy_id, MII_LPA);
     356         [ #  # ]:          0 :         if (mii->supports_gmii)
     357                 :          0 :                 lpa2 = mii->mdio_read(mii->dev, mii->phy_id, MII_STAT1000);
     358                 :            : 
     359                 :            :         /* figure out media and duplex from advertise and LPA values */
     360                 :          0 :         media = mii_nway_result(lpa & advertise);
     361                 :          0 :         duplex = (media & ADVERTISE_FULL) ? 1 : 0;
     362         [ #  # ]:          0 :         if (lpa2 & LPA_1000FULL)
     363                 :            :                 duplex = 1;
     364                 :            : 
     365         [ #  # ]:          0 :         if (ok_to_print)
     366 [ #  # ][ #  # ]:          0 :                 netdev_info(mii->dev, "link up, %uMbps, %s-duplex, lpa 0x%04X\n",
     367                 :          0 :                             lpa2 & (LPA_1000FULL | LPA_1000HALF) ? 1000 :
     368                 :          0 :                             media & (ADVERTISE_100FULL | ADVERTISE_100HALF) ?
     369         [ #  # ]:          0 :                             100 : 10,
     370                 :            :                             duplex ? "full" : "half",
     371                 :            :                             lpa);
     372                 :            : 
     373 [ #  # ][ #  # ]:          0 :         if ((init_media) || (mii->full_duplex != duplex)) {
     374                 :          0 :                 mii->full_duplex = duplex;
     375                 :          0 :                 return 1; /* duplex changed */
     376                 :            :         }
     377                 :            : 
     378                 :            :         return 0; /* duplex did not change */
     379                 :            : }
     380                 :            : 
     381                 :            : /**
     382                 :            :  * generic_mii_ioctl - main MII ioctl interface
     383                 :            :  * @mii_if: the MII interface
     384                 :            :  * @mii_data: MII ioctl data structure
     385                 :            :  * @cmd: MII ioctl command
     386                 :            :  * @duplex_chg_out: pointer to @duplex_changed status if there was no
     387                 :            :  *      ioctl error
     388                 :            :  *
     389                 :            :  * Returns 0 on success, negative on error.
     390                 :            :  */
     391                 :          0 : int generic_mii_ioctl(struct mii_if_info *mii_if,
     392                 :            :                       struct mii_ioctl_data *mii_data, int cmd,
     393                 :            :                       unsigned int *duplex_chg_out)
     394                 :            : {
     395                 :            :         int rc = 0;
     396                 :            :         unsigned int duplex_changed = 0;
     397                 :            : 
     398         [ #  # ]:          0 :         if (duplex_chg_out)
     399                 :          0 :                 *duplex_chg_out = 0;
     400                 :            : 
     401                 :          0 :         mii_data->phy_id &= mii_if->phy_id_mask;
     402                 :          0 :         mii_data->reg_num &= mii_if->reg_num_mask;
     403                 :            : 
     404   [ #  #  #  # ]:          0 :         switch(cmd) {
     405                 :            :         case SIOCGMIIPHY:
     406                 :          0 :                 mii_data->phy_id = mii_if->phy_id;
     407                 :            :                 /* fall through */
     408                 :            : 
     409                 :            :         case SIOCGMIIREG:
     410                 :          0 :                 mii_data->val_out =
     411                 :          0 :                         mii_if->mdio_read(mii_if->dev, mii_data->phy_id,
     412                 :            :                                           mii_data->reg_num);
     413                 :          0 :                 break;
     414                 :            : 
     415                 :            :         case SIOCSMIIREG: {
     416                 :          0 :                 u16 val = mii_data->val_in;
     417                 :            : 
     418         [ #  # ]:          0 :                 if (mii_data->phy_id == mii_if->phy_id) {
     419      [ #  #  # ]:          0 :                         switch(mii_data->reg_num) {
     420                 :            :                         case MII_BMCR: {
     421                 :            :                                 unsigned int new_duplex = 0;
     422         [ #  # ]:          0 :                                 if (val & (BMCR_RESET|BMCR_ANENABLE))
     423                 :          0 :                                         mii_if->force_media = 0;
     424                 :            :                                 else
     425                 :          0 :                                         mii_if->force_media = 1;
     426 [ #  # ][ #  # ]:          0 :                                 if (mii_if->force_media &&
     427                 :          0 :                                     (val & BMCR_FULLDPLX))
     428                 :            :                                         new_duplex = 1;
     429         [ #  # ]:          0 :                                 if (mii_if->full_duplex != new_duplex) {
     430                 :            :                                         duplex_changed = 1;
     431                 :          0 :                                         mii_if->full_duplex = new_duplex;
     432                 :            :                                 }
     433                 :            :                                 break;
     434                 :            :                         }
     435                 :            :                         case MII_ADVERTISE:
     436                 :          0 :                                 mii_if->advertising = val;
     437                 :          0 :                                 break;
     438                 :            :                         default:
     439                 :            :                                 /* do nothing */
     440                 :            :                                 break;
     441                 :            :                         }
     442                 :            :                 }
     443                 :            : 
     444                 :          0 :                 mii_if->mdio_write(mii_if->dev, mii_data->phy_id,
     445                 :          0 :                                    mii_data->reg_num, val);
     446                 :          0 :                 break;
     447                 :            :         }
     448                 :            : 
     449                 :            :         default:
     450                 :            :                 rc = -EOPNOTSUPP;
     451                 :            :                 break;
     452                 :            :         }
     453                 :            : 
     454 [ #  # ][ #  # ]:          0 :         if ((rc == 0) && (duplex_chg_out) && (duplex_changed))
     455                 :          0 :                 *duplex_chg_out = 1;
     456                 :            : 
     457                 :          0 :         return rc;
     458                 :            : }
     459                 :            : 
     460                 :            : MODULE_AUTHOR ("Jeff Garzik <jgarzik@pobox.com>");
     461                 :            : MODULE_DESCRIPTION ("MII hardware support library");
     462                 :            : MODULE_LICENSE("GPL");
     463                 :            : 
     464                 :            : EXPORT_SYMBOL(mii_link_ok);
     465                 :            : EXPORT_SYMBOL(mii_nway_restart);
     466                 :            : EXPORT_SYMBOL(mii_ethtool_gset);
     467                 :            : EXPORT_SYMBOL(mii_ethtool_sset);
     468                 :            : EXPORT_SYMBOL(mii_check_link);
     469                 :            : EXPORT_SYMBOL(mii_check_media);
     470                 :            : EXPORT_SYMBOL(mii_check_gmii_support);
     471                 :            : EXPORT_SYMBOL(generic_mii_ioctl);
     472                 :            : 

Generated by: LCOV version 1.9