Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Driver for the Texas Instruments DP83822, DP83825 and DP83826 PHYs.
0003  *
0004  * Copyright (C) 2017 Texas Instruments Inc.
0005  */
0006 
0007 #include <linux/ethtool.h>
0008 #include <linux/etherdevice.h>
0009 #include <linux/kernel.h>
0010 #include <linux/mii.h>
0011 #include <linux/module.h>
0012 #include <linux/of.h>
0013 #include <linux/phy.h>
0014 #include <linux/netdevice.h>
0015 
0016 #define DP83822_PHY_ID          0x2000a240
0017 #define DP83825S_PHY_ID     0x2000a140
0018 #define DP83825I_PHY_ID     0x2000a150
0019 #define DP83825CM_PHY_ID    0x2000a160
0020 #define DP83825CS_PHY_ID    0x2000a170
0021 #define DP83826C_PHY_ID     0x2000a130
0022 #define DP83826NC_PHY_ID    0x2000a110
0023 
0024 #define DP83822_DEVADDR     0x1f
0025 
0026 #define MII_DP83822_CTRL_2  0x0a
0027 #define MII_DP83822_PHYSTS  0x10
0028 #define MII_DP83822_PHYSCR  0x11
0029 #define MII_DP83822_MISR1   0x12
0030 #define MII_DP83822_MISR2   0x13
0031 #define MII_DP83822_FCSCR   0x14
0032 #define MII_DP83822_RCSR    0x17
0033 #define MII_DP83822_RESET_CTRL  0x1f
0034 #define MII_DP83822_GENCFG  0x465
0035 #define MII_DP83822_SOR1    0x467
0036 
0037 /* GENCFG */
0038 #define DP83822_SIG_DET_LOW BIT(0)
0039 
0040 /* Control Register 2 bits */
0041 #define DP83822_FX_ENABLE   BIT(14)
0042 
0043 #define DP83822_HW_RESET    BIT(15)
0044 #define DP83822_SW_RESET    BIT(14)
0045 
0046 /* PHY STS bits */
0047 #define DP83822_PHYSTS_DUPLEX           BIT(2)
0048 #define DP83822_PHYSTS_10           BIT(1)
0049 #define DP83822_PHYSTS_LINK         BIT(0)
0050 
0051 /* PHYSCR Register Fields */
0052 #define DP83822_PHYSCR_INT_OE       BIT(0) /* Interrupt Output Enable */
0053 #define DP83822_PHYSCR_INTEN        BIT(1) /* Interrupt Enable */
0054 
0055 /* MISR1 bits */
0056 #define DP83822_RX_ERR_HF_INT_EN    BIT(0)
0057 #define DP83822_FALSE_CARRIER_HF_INT_EN BIT(1)
0058 #define DP83822_ANEG_COMPLETE_INT_EN    BIT(2)
0059 #define DP83822_DUP_MODE_CHANGE_INT_EN  BIT(3)
0060 #define DP83822_SPEED_CHANGED_INT_EN    BIT(4)
0061 #define DP83822_LINK_STAT_INT_EN    BIT(5)
0062 #define DP83822_ENERGY_DET_INT_EN   BIT(6)
0063 #define DP83822_LINK_QUAL_INT_EN    BIT(7)
0064 
0065 /* MISR2 bits */
0066 #define DP83822_JABBER_DET_INT_EN   BIT(0)
0067 #define DP83822_WOL_PKT_INT_EN      BIT(1)
0068 #define DP83822_SLEEP_MODE_INT_EN   BIT(2)
0069 #define DP83822_MDI_XOVER_INT_EN    BIT(3)
0070 #define DP83822_LB_FIFO_INT_EN      BIT(4)
0071 #define DP83822_PAGE_RX_INT_EN      BIT(5)
0072 #define DP83822_ANEG_ERR_INT_EN     BIT(6)
0073 #define DP83822_EEE_ERROR_CHANGE_INT_EN BIT(7)
0074 
0075 /* INT_STAT1 bits */
0076 #define DP83822_WOL_INT_EN  BIT(4)
0077 #define DP83822_WOL_INT_STAT    BIT(12)
0078 
0079 #define MII_DP83822_RXSOP1  0x04a5
0080 #define MII_DP83822_RXSOP2  0x04a6
0081 #define MII_DP83822_RXSOP3  0x04a7
0082 
0083 /* WoL Registers */
0084 #define MII_DP83822_WOL_CFG 0x04a0
0085 #define MII_DP83822_WOL_STAT    0x04a1
0086 #define MII_DP83822_WOL_DA1 0x04a2
0087 #define MII_DP83822_WOL_DA2 0x04a3
0088 #define MII_DP83822_WOL_DA3 0x04a4
0089 
0090 /* WoL bits */
0091 #define DP83822_WOL_MAGIC_EN    BIT(0)
0092 #define DP83822_WOL_SECURE_ON   BIT(5)
0093 #define DP83822_WOL_EN      BIT(7)
0094 #define DP83822_WOL_INDICATION_SEL BIT(8)
0095 #define DP83822_WOL_CLR_INDICATION BIT(11)
0096 
0097 /* RCSR bits */
0098 #define DP83822_RGMII_MODE_EN   BIT(9)
0099 #define DP83822_RX_CLK_SHIFT    BIT(12)
0100 #define DP83822_TX_CLK_SHIFT    BIT(11)
0101 
0102 /* SOR1 mode */
0103 #define DP83822_STRAP_MODE1 0
0104 #define DP83822_STRAP_MODE2 BIT(0)
0105 #define DP83822_STRAP_MODE3 BIT(1)
0106 #define DP83822_STRAP_MODE4 GENMASK(1, 0)
0107 
0108 #define DP83822_COL_STRAP_MASK  GENMASK(11, 10)
0109 #define DP83822_COL_SHIFT   10
0110 #define DP83822_RX_ER_STR_MASK  GENMASK(9, 8)
0111 #define DP83822_RX_ER_SHIFT 8
0112 
0113 #define MII_DP83822_FIBER_ADVERTISE    (ADVERTISED_TP | ADVERTISED_MII | \
0114                     ADVERTISED_FIBRE | \
0115                     ADVERTISED_Pause | ADVERTISED_Asym_Pause)
0116 
0117 struct dp83822_private {
0118     bool fx_signal_det_low;
0119     int fx_enabled;
0120     u16 fx_sd_enable;
0121 };
0122 
0123 static int dp83822_set_wol(struct phy_device *phydev,
0124                struct ethtool_wolinfo *wol)
0125 {
0126     struct net_device *ndev = phydev->attached_dev;
0127     u16 value;
0128     const u8 *mac;
0129 
0130     if (wol->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE)) {
0131         mac = (const u8 *)ndev->dev_addr;
0132 
0133         if (!is_valid_ether_addr(mac))
0134             return -EINVAL;
0135 
0136         /* MAC addresses start with byte 5, but stored in mac[0].
0137          * 822 PHYs store bytes 4|5, 2|3, 0|1
0138          */
0139         phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_DA1,
0140                   (mac[1] << 8) | mac[0]);
0141         phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_DA2,
0142                   (mac[3] << 8) | mac[2]);
0143         phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_DA3,
0144                   (mac[5] << 8) | mac[4]);
0145 
0146         value = phy_read_mmd(phydev, DP83822_DEVADDR,
0147                      MII_DP83822_WOL_CFG);
0148         if (wol->wolopts & WAKE_MAGIC)
0149             value |= DP83822_WOL_MAGIC_EN;
0150         else
0151             value &= ~DP83822_WOL_MAGIC_EN;
0152 
0153         if (wol->wolopts & WAKE_MAGICSECURE) {
0154             phy_write_mmd(phydev, DP83822_DEVADDR,
0155                       MII_DP83822_RXSOP1,
0156                       (wol->sopass[1] << 8) | wol->sopass[0]);
0157             phy_write_mmd(phydev, DP83822_DEVADDR,
0158                       MII_DP83822_RXSOP2,
0159                       (wol->sopass[3] << 8) | wol->sopass[2]);
0160             phy_write_mmd(phydev, DP83822_DEVADDR,
0161                       MII_DP83822_RXSOP3,
0162                       (wol->sopass[5] << 8) | wol->sopass[4]);
0163             value |= DP83822_WOL_SECURE_ON;
0164         } else {
0165             value &= ~DP83822_WOL_SECURE_ON;
0166         }
0167 
0168         /* Clear any pending WoL interrupt */
0169         phy_read(phydev, MII_DP83822_MISR2);
0170 
0171         value |= DP83822_WOL_EN | DP83822_WOL_INDICATION_SEL |
0172              DP83822_WOL_CLR_INDICATION;
0173 
0174         return phy_write_mmd(phydev, DP83822_DEVADDR,
0175                      MII_DP83822_WOL_CFG, value);
0176     } else {
0177         return phy_clear_bits_mmd(phydev, DP83822_DEVADDR,
0178                       MII_DP83822_WOL_CFG, DP83822_WOL_EN);
0179     }
0180 }
0181 
0182 static void dp83822_get_wol(struct phy_device *phydev,
0183                 struct ethtool_wolinfo *wol)
0184 {
0185     int value;
0186     u16 sopass_val;
0187 
0188     wol->supported = (WAKE_MAGIC | WAKE_MAGICSECURE);
0189     wol->wolopts = 0;
0190 
0191     value = phy_read_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG);
0192 
0193     if (value & DP83822_WOL_MAGIC_EN)
0194         wol->wolopts |= WAKE_MAGIC;
0195 
0196     if (value & DP83822_WOL_SECURE_ON) {
0197         sopass_val = phy_read_mmd(phydev, DP83822_DEVADDR,
0198                       MII_DP83822_RXSOP1);
0199         wol->sopass[0] = (sopass_val & 0xff);
0200         wol->sopass[1] = (sopass_val >> 8);
0201 
0202         sopass_val = phy_read_mmd(phydev, DP83822_DEVADDR,
0203                       MII_DP83822_RXSOP2);
0204         wol->sopass[2] = (sopass_val & 0xff);
0205         wol->sopass[3] = (sopass_val >> 8);
0206 
0207         sopass_val = phy_read_mmd(phydev, DP83822_DEVADDR,
0208                       MII_DP83822_RXSOP3);
0209         wol->sopass[4] = (sopass_val & 0xff);
0210         wol->sopass[5] = (sopass_val >> 8);
0211 
0212         wol->wolopts |= WAKE_MAGICSECURE;
0213     }
0214 
0215     /* WoL is not enabled so set wolopts to 0 */
0216     if (!(value & DP83822_WOL_EN))
0217         wol->wolopts = 0;
0218 }
0219 
0220 static int dp83822_config_intr(struct phy_device *phydev)
0221 {
0222     struct dp83822_private *dp83822 = phydev->priv;
0223     int misr_status;
0224     int physcr_status;
0225     int err;
0226 
0227     if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
0228         misr_status = phy_read(phydev, MII_DP83822_MISR1);
0229         if (misr_status < 0)
0230             return misr_status;
0231 
0232         misr_status |= (DP83822_LINK_STAT_INT_EN |
0233                 DP83822_ENERGY_DET_INT_EN |
0234                 DP83822_LINK_QUAL_INT_EN);
0235 
0236         if (!dp83822->fx_enabled)
0237             misr_status |= DP83822_ANEG_COMPLETE_INT_EN |
0238                        DP83822_DUP_MODE_CHANGE_INT_EN |
0239                        DP83822_SPEED_CHANGED_INT_EN;
0240 
0241 
0242         err = phy_write(phydev, MII_DP83822_MISR1, misr_status);
0243         if (err < 0)
0244             return err;
0245 
0246         misr_status = phy_read(phydev, MII_DP83822_MISR2);
0247         if (misr_status < 0)
0248             return misr_status;
0249 
0250         misr_status |= (DP83822_JABBER_DET_INT_EN |
0251                 DP83822_SLEEP_MODE_INT_EN |
0252                 DP83822_LB_FIFO_INT_EN |
0253                 DP83822_PAGE_RX_INT_EN |
0254                 DP83822_EEE_ERROR_CHANGE_INT_EN);
0255 
0256         if (!dp83822->fx_enabled)
0257             misr_status |= DP83822_MDI_XOVER_INT_EN |
0258                        DP83822_ANEG_ERR_INT_EN |
0259                        DP83822_WOL_PKT_INT_EN;
0260 
0261         err = phy_write(phydev, MII_DP83822_MISR2, misr_status);
0262         if (err < 0)
0263             return err;
0264 
0265         physcr_status = phy_read(phydev, MII_DP83822_PHYSCR);
0266         if (physcr_status < 0)
0267             return physcr_status;
0268 
0269         physcr_status |= DP83822_PHYSCR_INT_OE | DP83822_PHYSCR_INTEN;
0270 
0271     } else {
0272         err = phy_write(phydev, MII_DP83822_MISR1, 0);
0273         if (err < 0)
0274             return err;
0275 
0276         err = phy_write(phydev, MII_DP83822_MISR2, 0);
0277         if (err < 0)
0278             return err;
0279 
0280         physcr_status = phy_read(phydev, MII_DP83822_PHYSCR);
0281         if (physcr_status < 0)
0282             return physcr_status;
0283 
0284         physcr_status &= ~DP83822_PHYSCR_INTEN;
0285     }
0286 
0287     return phy_write(phydev, MII_DP83822_PHYSCR, physcr_status);
0288 }
0289 
0290 static irqreturn_t dp83822_handle_interrupt(struct phy_device *phydev)
0291 {
0292     bool trigger_machine = false;
0293     int irq_status;
0294 
0295     /* The MISR1 and MISR2 registers are holding the interrupt status in
0296      * the upper half (15:8), while the lower half (7:0) is used for
0297      * controlling the interrupt enable state of those individual interrupt
0298      * sources. To determine the possible interrupt sources, just read the
0299      * MISR* register and use it directly to know which interrupts have
0300      * been enabled previously or not.
0301      */
0302     irq_status = phy_read(phydev, MII_DP83822_MISR1);
0303     if (irq_status < 0) {
0304         phy_error(phydev);
0305         return IRQ_NONE;
0306     }
0307     if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
0308         trigger_machine = true;
0309 
0310     irq_status = phy_read(phydev, MII_DP83822_MISR2);
0311     if (irq_status < 0) {
0312         phy_error(phydev);
0313         return IRQ_NONE;
0314     }
0315     if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
0316         trigger_machine = true;
0317 
0318     if (!trigger_machine)
0319         return IRQ_NONE;
0320 
0321     phy_trigger_machine(phydev);
0322 
0323     return IRQ_HANDLED;
0324 }
0325 
0326 static int dp8382x_disable_wol(struct phy_device *phydev)
0327 {
0328     return phy_clear_bits_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG,
0329                   DP83822_WOL_EN | DP83822_WOL_MAGIC_EN |
0330                   DP83822_WOL_SECURE_ON);
0331 }
0332 
0333 static int dp83822_read_status(struct phy_device *phydev)
0334 {
0335     struct dp83822_private *dp83822 = phydev->priv;
0336     int status = phy_read(phydev, MII_DP83822_PHYSTS);
0337     int ctrl2;
0338     int ret;
0339 
0340     if (dp83822->fx_enabled) {
0341         if (status & DP83822_PHYSTS_LINK) {
0342             phydev->speed = SPEED_UNKNOWN;
0343             phydev->duplex = DUPLEX_UNKNOWN;
0344         } else {
0345             ctrl2 = phy_read(phydev, MII_DP83822_CTRL_2);
0346             if (ctrl2 < 0)
0347                 return ctrl2;
0348 
0349             if (!(ctrl2 & DP83822_FX_ENABLE)) {
0350                 ret = phy_write(phydev, MII_DP83822_CTRL_2,
0351                         DP83822_FX_ENABLE | ctrl2);
0352                 if (ret < 0)
0353                     return ret;
0354             }
0355         }
0356     }
0357 
0358     ret = genphy_read_status(phydev);
0359     if (ret)
0360         return ret;
0361 
0362     if (status < 0)
0363         return status;
0364 
0365     if (status & DP83822_PHYSTS_DUPLEX)
0366         phydev->duplex = DUPLEX_FULL;
0367     else
0368         phydev->duplex = DUPLEX_HALF;
0369 
0370     if (status & DP83822_PHYSTS_10)
0371         phydev->speed = SPEED_10;
0372     else
0373         phydev->speed = SPEED_100;
0374 
0375     return 0;
0376 }
0377 
0378 static int dp83822_config_init(struct phy_device *phydev)
0379 {
0380     struct dp83822_private *dp83822 = phydev->priv;
0381     struct device *dev = &phydev->mdio.dev;
0382     int rgmii_delay;
0383     s32 rx_int_delay;
0384     s32 tx_int_delay;
0385     int err = 0;
0386     int bmcr;
0387 
0388     if (phy_interface_is_rgmii(phydev)) {
0389         rx_int_delay = phy_get_internal_delay(phydev, dev, NULL, 0,
0390                               true);
0391 
0392         if (rx_int_delay <= 0)
0393             rgmii_delay = 0;
0394         else
0395             rgmii_delay = DP83822_RX_CLK_SHIFT;
0396 
0397         tx_int_delay = phy_get_internal_delay(phydev, dev, NULL, 0,
0398                               false);
0399         if (tx_int_delay <= 0)
0400             rgmii_delay &= ~DP83822_TX_CLK_SHIFT;
0401         else
0402             rgmii_delay |= DP83822_TX_CLK_SHIFT;
0403 
0404         if (rgmii_delay) {
0405             err = phy_set_bits_mmd(phydev, DP83822_DEVADDR,
0406                            MII_DP83822_RCSR, rgmii_delay);
0407             if (err)
0408                 return err;
0409         }
0410 
0411         phy_set_bits_mmd(phydev, DP83822_DEVADDR,
0412                     MII_DP83822_RCSR, DP83822_RGMII_MODE_EN);
0413     } else {
0414         phy_clear_bits_mmd(phydev, DP83822_DEVADDR,
0415                     MII_DP83822_RCSR, DP83822_RGMII_MODE_EN);
0416     }
0417 
0418     if (dp83822->fx_enabled) {
0419         err = phy_modify(phydev, MII_DP83822_CTRL_2,
0420                  DP83822_FX_ENABLE, 1);
0421         if (err < 0)
0422             return err;
0423 
0424         /* Only allow advertising what this PHY supports */
0425         linkmode_and(phydev->advertising, phydev->advertising,
0426                  phydev->supported);
0427 
0428         linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
0429                  phydev->supported);
0430         linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
0431                  phydev->advertising);
0432         linkmode_set_bit(ETHTOOL_LINK_MODE_100baseFX_Full_BIT,
0433                  phydev->supported);
0434         linkmode_set_bit(ETHTOOL_LINK_MODE_100baseFX_Half_BIT,
0435                  phydev->supported);
0436         linkmode_set_bit(ETHTOOL_LINK_MODE_100baseFX_Full_BIT,
0437                  phydev->advertising);
0438         linkmode_set_bit(ETHTOOL_LINK_MODE_100baseFX_Half_BIT,
0439                  phydev->advertising);
0440 
0441         /* Auto neg is not supported in fiber mode */
0442         bmcr = phy_read(phydev, MII_BMCR);
0443         if (bmcr < 0)
0444             return bmcr;
0445 
0446         if (bmcr & BMCR_ANENABLE) {
0447             err =  phy_modify(phydev, MII_BMCR, BMCR_ANENABLE, 0);
0448             if (err < 0)
0449                 return err;
0450         }
0451         phydev->autoneg = AUTONEG_DISABLE;
0452         linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
0453                    phydev->supported);
0454         linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
0455                    phydev->advertising);
0456 
0457         /* Setup fiber advertisement */
0458         err = phy_modify_changed(phydev, MII_ADVERTISE,
0459                      MII_DP83822_FIBER_ADVERTISE,
0460                      MII_DP83822_FIBER_ADVERTISE);
0461 
0462         if (err < 0)
0463             return err;
0464 
0465         if (dp83822->fx_signal_det_low) {
0466             err = phy_set_bits_mmd(phydev, DP83822_DEVADDR,
0467                            MII_DP83822_GENCFG,
0468                            DP83822_SIG_DET_LOW);
0469             if (err)
0470                 return err;
0471         }
0472     }
0473     return dp8382x_disable_wol(phydev);
0474 }
0475 
0476 static int dp8382x_config_init(struct phy_device *phydev)
0477 {
0478     return dp8382x_disable_wol(phydev);
0479 }
0480 
0481 static int dp83822_phy_reset(struct phy_device *phydev)
0482 {
0483     int err;
0484 
0485     err = phy_write(phydev, MII_DP83822_RESET_CTRL, DP83822_SW_RESET);
0486     if (err < 0)
0487         return err;
0488 
0489     return phydev->drv->config_init(phydev);
0490 }
0491 
0492 #ifdef CONFIG_OF_MDIO
0493 static int dp83822_of_init(struct phy_device *phydev)
0494 {
0495     struct dp83822_private *dp83822 = phydev->priv;
0496     struct device *dev = &phydev->mdio.dev;
0497 
0498     /* Signal detection for the PHY is only enabled if the FX_EN and the
0499      * SD_EN pins are strapped. Signal detection can only enabled if FX_EN
0500      * is strapped otherwise signal detection is disabled for the PHY.
0501      */
0502     if (dp83822->fx_enabled && dp83822->fx_sd_enable)
0503         dp83822->fx_signal_det_low = device_property_present(dev,
0504                                      "ti,link-loss-low");
0505     if (!dp83822->fx_enabled)
0506         dp83822->fx_enabled = device_property_present(dev,
0507                                   "ti,fiber-mode");
0508 
0509     return 0;
0510 }
0511 #else
0512 static int dp83822_of_init(struct phy_device *phydev)
0513 {
0514     return 0;
0515 }
0516 #endif /* CONFIG_OF_MDIO */
0517 
0518 static int dp83822_read_straps(struct phy_device *phydev)
0519 {
0520     struct dp83822_private *dp83822 = phydev->priv;
0521     int fx_enabled, fx_sd_enable;
0522     int val;
0523 
0524     val = phy_read_mmd(phydev, DP83822_DEVADDR, MII_DP83822_SOR1);
0525     if (val < 0)
0526         return val;
0527 
0528     fx_enabled = (val & DP83822_COL_STRAP_MASK) >> DP83822_COL_SHIFT;
0529     if (fx_enabled == DP83822_STRAP_MODE2 ||
0530         fx_enabled == DP83822_STRAP_MODE3)
0531         dp83822->fx_enabled = 1;
0532 
0533     if (dp83822->fx_enabled) {
0534         fx_sd_enable = (val & DP83822_RX_ER_STR_MASK) >> DP83822_RX_ER_SHIFT;
0535         if (fx_sd_enable == DP83822_STRAP_MODE3 ||
0536             fx_sd_enable == DP83822_STRAP_MODE4)
0537             dp83822->fx_sd_enable = 1;
0538     }
0539 
0540     return 0;
0541 }
0542 
0543 static int dp83822_probe(struct phy_device *phydev)
0544 {
0545     struct dp83822_private *dp83822;
0546     int ret;
0547 
0548     dp83822 = devm_kzalloc(&phydev->mdio.dev, sizeof(*dp83822),
0549                    GFP_KERNEL);
0550     if (!dp83822)
0551         return -ENOMEM;
0552 
0553     phydev->priv = dp83822;
0554 
0555     ret = dp83822_read_straps(phydev);
0556     if (ret)
0557         return ret;
0558 
0559     dp83822_of_init(phydev);
0560 
0561     if (dp83822->fx_enabled)
0562         phydev->port = PORT_FIBRE;
0563 
0564     return 0;
0565 }
0566 
0567 static int dp83822_suspend(struct phy_device *phydev)
0568 {
0569     int value;
0570 
0571     value = phy_read_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG);
0572 
0573     if (!(value & DP83822_WOL_EN))
0574         genphy_suspend(phydev);
0575 
0576     return 0;
0577 }
0578 
0579 static int dp83822_resume(struct phy_device *phydev)
0580 {
0581     int value;
0582 
0583     genphy_resume(phydev);
0584 
0585     value = phy_read_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG);
0586 
0587     phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG, value |
0588               DP83822_WOL_CLR_INDICATION);
0589 
0590     return 0;
0591 }
0592 
0593 #define DP83822_PHY_DRIVER(_id, _name)              \
0594     {                           \
0595         PHY_ID_MATCH_MODEL(_id),            \
0596         .name       = (_name),          \
0597         /* PHY_BASIC_FEATURES */            \
0598         .probe          = dp83822_probe,        \
0599         .soft_reset = dp83822_phy_reset,        \
0600         .config_init    = dp83822_config_init,      \
0601         .read_status    = dp83822_read_status,      \
0602         .get_wol = dp83822_get_wol,         \
0603         .set_wol = dp83822_set_wol,         \
0604         .config_intr = dp83822_config_intr,     \
0605         .handle_interrupt = dp83822_handle_interrupt,   \
0606         .suspend = dp83822_suspend,         \
0607         .resume = dp83822_resume,           \
0608     }
0609 
0610 #define DP8382X_PHY_DRIVER(_id, _name)              \
0611     {                           \
0612         PHY_ID_MATCH_MODEL(_id),            \
0613         .name       = (_name),          \
0614         /* PHY_BASIC_FEATURES */            \
0615         .soft_reset = dp83822_phy_reset,        \
0616         .config_init    = dp8382x_config_init,      \
0617         .get_wol = dp83822_get_wol,         \
0618         .set_wol = dp83822_set_wol,         \
0619         .config_intr = dp83822_config_intr,     \
0620         .handle_interrupt = dp83822_handle_interrupt,   \
0621         .suspend = dp83822_suspend,         \
0622         .resume = dp83822_resume,           \
0623     }
0624 
0625 static struct phy_driver dp83822_driver[] = {
0626     DP83822_PHY_DRIVER(DP83822_PHY_ID, "TI DP83822"),
0627     DP8382X_PHY_DRIVER(DP83825I_PHY_ID, "TI DP83825I"),
0628     DP8382X_PHY_DRIVER(DP83826C_PHY_ID, "TI DP83826C"),
0629     DP8382X_PHY_DRIVER(DP83826NC_PHY_ID, "TI DP83826NC"),
0630     DP8382X_PHY_DRIVER(DP83825S_PHY_ID, "TI DP83825S"),
0631     DP8382X_PHY_DRIVER(DP83825CM_PHY_ID, "TI DP83825M"),
0632     DP8382X_PHY_DRIVER(DP83825CS_PHY_ID, "TI DP83825CS"),
0633 };
0634 module_phy_driver(dp83822_driver);
0635 
0636 static struct mdio_device_id __maybe_unused dp83822_tbl[] = {
0637     { DP83822_PHY_ID, 0xfffffff0 },
0638     { DP83825I_PHY_ID, 0xfffffff0 },
0639     { DP83826C_PHY_ID, 0xfffffff0 },
0640     { DP83826NC_PHY_ID, 0xfffffff0 },
0641     { DP83825S_PHY_ID, 0xfffffff0 },
0642     { DP83825CM_PHY_ID, 0xfffffff0 },
0643     { DP83825CS_PHY_ID, 0xfffffff0 },
0644     { },
0645 };
0646 MODULE_DEVICE_TABLE(mdio, dp83822_tbl);
0647 
0648 MODULE_DESCRIPTION("Texas Instruments DP83822 PHY driver");
0649 MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com");
0650 MODULE_LICENSE("GPL v2");