Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Driver for the Texas Instruments DP83TC811 PHY
0004  *
0005  * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
0006  *
0007  */
0008 
0009 #include <linux/ethtool.h>
0010 #include <linux/etherdevice.h>
0011 #include <linux/kernel.h>
0012 #include <linux/mii.h>
0013 #include <linux/module.h>
0014 #include <linux/of.h>
0015 #include <linux/phy.h>
0016 #include <linux/netdevice.h>
0017 
0018 #define DP83TC811_PHY_ID    0x2000a253
0019 #define DP83811_DEVADDR     0x1f
0020 
0021 #define MII_DP83811_SGMII_CTRL  0x09
0022 #define MII_DP83811_INT_STAT1   0x12
0023 #define MII_DP83811_INT_STAT2   0x13
0024 #define MII_DP83811_INT_STAT3   0x18
0025 #define MII_DP83811_RESET_CTRL  0x1f
0026 
0027 #define DP83811_HW_RESET    BIT(15)
0028 #define DP83811_SW_RESET    BIT(14)
0029 
0030 /* INT_STAT1 bits */
0031 #define DP83811_RX_ERR_HF_INT_EN    BIT(0)
0032 #define DP83811_MS_TRAINING_INT_EN  BIT(1)
0033 #define DP83811_ANEG_COMPLETE_INT_EN    BIT(2)
0034 #define DP83811_ESD_EVENT_INT_EN    BIT(3)
0035 #define DP83811_WOL_INT_EN      BIT(4)
0036 #define DP83811_LINK_STAT_INT_EN    BIT(5)
0037 #define DP83811_ENERGY_DET_INT_EN   BIT(6)
0038 #define DP83811_LINK_QUAL_INT_EN    BIT(7)
0039 
0040 /* INT_STAT2 bits */
0041 #define DP83811_JABBER_DET_INT_EN   BIT(0)
0042 #define DP83811_POLARITY_INT_EN     BIT(1)
0043 #define DP83811_SLEEP_MODE_INT_EN   BIT(2)
0044 #define DP83811_OVERTEMP_INT_EN     BIT(3)
0045 #define DP83811_OVERVOLTAGE_INT_EN  BIT(6)
0046 #define DP83811_UNDERVOLTAGE_INT_EN BIT(7)
0047 
0048 /* INT_STAT3 bits */
0049 #define DP83811_LPS_INT_EN  BIT(0)
0050 #define DP83811_NO_FRAME_INT_EN BIT(3)
0051 #define DP83811_POR_DONE_INT_EN BIT(4)
0052 
0053 #define MII_DP83811_RXSOP1  0x04a5
0054 #define MII_DP83811_RXSOP2  0x04a6
0055 #define MII_DP83811_RXSOP3  0x04a7
0056 
0057 /* WoL Registers */
0058 #define MII_DP83811_WOL_CFG 0x04a0
0059 #define MII_DP83811_WOL_STAT    0x04a1
0060 #define MII_DP83811_WOL_DA1 0x04a2
0061 #define MII_DP83811_WOL_DA2 0x04a3
0062 #define MII_DP83811_WOL_DA3 0x04a4
0063 
0064 /* WoL bits */
0065 #define DP83811_WOL_MAGIC_EN    BIT(0)
0066 #define DP83811_WOL_SECURE_ON   BIT(5)
0067 #define DP83811_WOL_EN      BIT(7)
0068 #define DP83811_WOL_INDICATION_SEL BIT(8)
0069 #define DP83811_WOL_CLR_INDICATION BIT(11)
0070 
0071 /* SGMII CTRL bits */
0072 #define DP83811_TDR_AUTO        BIT(8)
0073 #define DP83811_SGMII_EN        BIT(12)
0074 #define DP83811_SGMII_AUTO_NEG_EN   BIT(13)
0075 #define DP83811_SGMII_TX_ERR_DIS    BIT(14)
0076 #define DP83811_SGMII_SOFT_RESET    BIT(15)
0077 
0078 static int dp83811_ack_interrupt(struct phy_device *phydev)
0079 {
0080     int err;
0081 
0082     err = phy_read(phydev, MII_DP83811_INT_STAT1);
0083     if (err < 0)
0084         return err;
0085 
0086     err = phy_read(phydev, MII_DP83811_INT_STAT2);
0087     if (err < 0)
0088         return err;
0089 
0090     err = phy_read(phydev, MII_DP83811_INT_STAT3);
0091     if (err < 0)
0092         return err;
0093 
0094     return 0;
0095 }
0096 
0097 static int dp83811_set_wol(struct phy_device *phydev,
0098                struct ethtool_wolinfo *wol)
0099 {
0100     struct net_device *ndev = phydev->attached_dev;
0101     const u8 *mac;
0102     u16 value;
0103 
0104     if (wol->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE)) {
0105         mac = (const u8 *)ndev->dev_addr;
0106 
0107         if (!is_valid_ether_addr(mac))
0108             return -EINVAL;
0109 
0110         /* MAC addresses start with byte 5, but stored in mac[0].
0111          * 811 PHYs store bytes 4|5, 2|3, 0|1
0112          */
0113         phy_write_mmd(phydev, DP83811_DEVADDR, MII_DP83811_WOL_DA1,
0114                   (mac[1] << 8) | mac[0]);
0115         phy_write_mmd(phydev, DP83811_DEVADDR, MII_DP83811_WOL_DA2,
0116                   (mac[3] << 8) | mac[2]);
0117         phy_write_mmd(phydev, DP83811_DEVADDR, MII_DP83811_WOL_DA3,
0118                   (mac[5] << 8) | mac[4]);
0119 
0120         value = phy_read_mmd(phydev, DP83811_DEVADDR,
0121                      MII_DP83811_WOL_CFG);
0122         if (wol->wolopts & WAKE_MAGIC)
0123             value |= DP83811_WOL_MAGIC_EN;
0124         else
0125             value &= ~DP83811_WOL_MAGIC_EN;
0126 
0127         if (wol->wolopts & WAKE_MAGICSECURE) {
0128             phy_write_mmd(phydev, DP83811_DEVADDR,
0129                       MII_DP83811_RXSOP1,
0130                       (wol->sopass[1] << 8) | wol->sopass[0]);
0131             phy_write_mmd(phydev, DP83811_DEVADDR,
0132                       MII_DP83811_RXSOP2,
0133                       (wol->sopass[3] << 8) | wol->sopass[2]);
0134             phy_write_mmd(phydev, DP83811_DEVADDR,
0135                       MII_DP83811_RXSOP3,
0136                       (wol->sopass[5] << 8) | wol->sopass[4]);
0137             value |= DP83811_WOL_SECURE_ON;
0138         } else {
0139             value &= ~DP83811_WOL_SECURE_ON;
0140         }
0141 
0142         /* Clear any pending WoL interrupt */
0143         phy_read(phydev, MII_DP83811_INT_STAT1);
0144 
0145         value |= DP83811_WOL_EN | DP83811_WOL_INDICATION_SEL |
0146              DP83811_WOL_CLR_INDICATION;
0147 
0148         return phy_write_mmd(phydev, DP83811_DEVADDR,
0149                      MII_DP83811_WOL_CFG, value);
0150     } else {
0151         return phy_clear_bits_mmd(phydev, DP83811_DEVADDR,
0152                       MII_DP83811_WOL_CFG, DP83811_WOL_EN);
0153     }
0154 
0155 }
0156 
0157 static void dp83811_get_wol(struct phy_device *phydev,
0158                 struct ethtool_wolinfo *wol)
0159 {
0160     u16 sopass_val;
0161     int value;
0162 
0163     wol->supported = (WAKE_MAGIC | WAKE_MAGICSECURE);
0164     wol->wolopts = 0;
0165 
0166     value = phy_read_mmd(phydev, DP83811_DEVADDR, MII_DP83811_WOL_CFG);
0167 
0168     if (value & DP83811_WOL_MAGIC_EN)
0169         wol->wolopts |= WAKE_MAGIC;
0170 
0171     if (value & DP83811_WOL_SECURE_ON) {
0172         sopass_val = phy_read_mmd(phydev, DP83811_DEVADDR,
0173                       MII_DP83811_RXSOP1);
0174         wol->sopass[0] = (sopass_val & 0xff);
0175         wol->sopass[1] = (sopass_val >> 8);
0176 
0177         sopass_val = phy_read_mmd(phydev, DP83811_DEVADDR,
0178                       MII_DP83811_RXSOP2);
0179         wol->sopass[2] = (sopass_val & 0xff);
0180         wol->sopass[3] = (sopass_val >> 8);
0181 
0182         sopass_val = phy_read_mmd(phydev, DP83811_DEVADDR,
0183                       MII_DP83811_RXSOP3);
0184         wol->sopass[4] = (sopass_val & 0xff);
0185         wol->sopass[5] = (sopass_val >> 8);
0186 
0187         wol->wolopts |= WAKE_MAGICSECURE;
0188     }
0189 
0190     /* WoL is not enabled so set wolopts to 0 */
0191     if (!(value & DP83811_WOL_EN))
0192         wol->wolopts = 0;
0193 }
0194 
0195 static int dp83811_config_intr(struct phy_device *phydev)
0196 {
0197     int misr_status, err;
0198 
0199     if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
0200         err = dp83811_ack_interrupt(phydev);
0201         if (err)
0202             return err;
0203 
0204         misr_status = phy_read(phydev, MII_DP83811_INT_STAT1);
0205         if (misr_status < 0)
0206             return misr_status;
0207 
0208         misr_status |= (DP83811_RX_ERR_HF_INT_EN |
0209                 DP83811_MS_TRAINING_INT_EN |
0210                 DP83811_ANEG_COMPLETE_INT_EN |
0211                 DP83811_ESD_EVENT_INT_EN |
0212                 DP83811_WOL_INT_EN |
0213                 DP83811_LINK_STAT_INT_EN |
0214                 DP83811_ENERGY_DET_INT_EN |
0215                 DP83811_LINK_QUAL_INT_EN);
0216 
0217         err = phy_write(phydev, MII_DP83811_INT_STAT1, misr_status);
0218         if (err < 0)
0219             return err;
0220 
0221         misr_status = phy_read(phydev, MII_DP83811_INT_STAT2);
0222         if (misr_status < 0)
0223             return misr_status;
0224 
0225         misr_status |= (DP83811_JABBER_DET_INT_EN |
0226                 DP83811_POLARITY_INT_EN |
0227                 DP83811_SLEEP_MODE_INT_EN |
0228                 DP83811_OVERTEMP_INT_EN |
0229                 DP83811_OVERVOLTAGE_INT_EN |
0230                 DP83811_UNDERVOLTAGE_INT_EN);
0231 
0232         err = phy_write(phydev, MII_DP83811_INT_STAT2, misr_status);
0233         if (err < 0)
0234             return err;
0235 
0236         misr_status = phy_read(phydev, MII_DP83811_INT_STAT3);
0237         if (misr_status < 0)
0238             return misr_status;
0239 
0240         misr_status |= (DP83811_LPS_INT_EN |
0241                 DP83811_NO_FRAME_INT_EN |
0242                 DP83811_POR_DONE_INT_EN);
0243 
0244         err = phy_write(phydev, MII_DP83811_INT_STAT3, misr_status);
0245 
0246     } else {
0247         err = phy_write(phydev, MII_DP83811_INT_STAT1, 0);
0248         if (err < 0)
0249             return err;
0250 
0251         err = phy_write(phydev, MII_DP83811_INT_STAT2, 0);
0252         if (err < 0)
0253             return err;
0254 
0255         err = phy_write(phydev, MII_DP83811_INT_STAT3, 0);
0256         if (err < 0)
0257             return err;
0258 
0259         err = dp83811_ack_interrupt(phydev);
0260     }
0261 
0262     return err;
0263 }
0264 
0265 static irqreturn_t dp83811_handle_interrupt(struct phy_device *phydev)
0266 {
0267     bool trigger_machine = false;
0268     int irq_status;
0269 
0270     /* The INT_STAT registers 1, 2 and 3 are holding the interrupt status
0271      * in the upper half (15:8), while the lower half (7:0) is used for
0272      * controlling the interrupt enable state of those individual interrupt
0273      * sources. To determine the possible interrupt sources, just read the
0274      * INT_STAT* register and use it directly to know which interrupts have
0275      * been enabled previously or not.
0276      */
0277     irq_status = phy_read(phydev, MII_DP83811_INT_STAT1);
0278     if (irq_status < 0) {
0279         phy_error(phydev);
0280         return IRQ_NONE;
0281     }
0282     if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
0283         trigger_machine = true;
0284 
0285     irq_status = phy_read(phydev, MII_DP83811_INT_STAT2);
0286     if (irq_status < 0) {
0287         phy_error(phydev);
0288         return IRQ_NONE;
0289     }
0290     if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
0291         trigger_machine = true;
0292 
0293     irq_status = phy_read(phydev, MII_DP83811_INT_STAT3);
0294     if (irq_status < 0) {
0295         phy_error(phydev);
0296         return IRQ_NONE;
0297     }
0298     if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
0299         trigger_machine = true;
0300 
0301     if (!trigger_machine)
0302         return IRQ_NONE;
0303 
0304     phy_trigger_machine(phydev);
0305 
0306     return IRQ_HANDLED;
0307 }
0308 
0309 static int dp83811_config_aneg(struct phy_device *phydev)
0310 {
0311     int value, err;
0312 
0313     if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
0314         value = phy_read(phydev, MII_DP83811_SGMII_CTRL);
0315         if (phydev->autoneg == AUTONEG_ENABLE) {
0316             err = phy_write(phydev, MII_DP83811_SGMII_CTRL,
0317                     (DP83811_SGMII_AUTO_NEG_EN | value));
0318             if (err < 0)
0319                 return err;
0320         } else {
0321             err = phy_write(phydev, MII_DP83811_SGMII_CTRL,
0322                     (~DP83811_SGMII_AUTO_NEG_EN & value));
0323             if (err < 0)
0324                 return err;
0325         }
0326     }
0327 
0328     return genphy_config_aneg(phydev);
0329 }
0330 
0331 static int dp83811_config_init(struct phy_device *phydev)
0332 {
0333     int value, err;
0334 
0335     value = phy_read(phydev, MII_DP83811_SGMII_CTRL);
0336     if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
0337         err = phy_write(phydev, MII_DP83811_SGMII_CTRL,
0338                     (DP83811_SGMII_EN | value));
0339     } else {
0340         err = phy_write(phydev, MII_DP83811_SGMII_CTRL,
0341                 (~DP83811_SGMII_EN & value));
0342     }
0343 
0344     if (err < 0)
0345 
0346         return err;
0347 
0348     value = DP83811_WOL_MAGIC_EN | DP83811_WOL_SECURE_ON | DP83811_WOL_EN;
0349 
0350     return phy_clear_bits_mmd(phydev, DP83811_DEVADDR, MII_DP83811_WOL_CFG,
0351                   value);
0352 }
0353 
0354 static int dp83811_phy_reset(struct phy_device *phydev)
0355 {
0356     int err;
0357 
0358     err = phy_write(phydev, MII_DP83811_RESET_CTRL, DP83811_HW_RESET);
0359     if (err < 0)
0360         return err;
0361 
0362     return 0;
0363 }
0364 
0365 static int dp83811_suspend(struct phy_device *phydev)
0366 {
0367     int value;
0368 
0369     value = phy_read_mmd(phydev, DP83811_DEVADDR, MII_DP83811_WOL_CFG);
0370 
0371     if (!(value & DP83811_WOL_EN))
0372         genphy_suspend(phydev);
0373 
0374     return 0;
0375 }
0376 
0377 static int dp83811_resume(struct phy_device *phydev)
0378 {
0379     genphy_resume(phydev);
0380 
0381     phy_set_bits_mmd(phydev, DP83811_DEVADDR, MII_DP83811_WOL_CFG,
0382              DP83811_WOL_CLR_INDICATION);
0383 
0384     return 0;
0385 }
0386 
0387 static struct phy_driver dp83811_driver[] = {
0388     {
0389         .phy_id = DP83TC811_PHY_ID,
0390         .phy_id_mask = 0xfffffff0,
0391         .name = "TI DP83TC811",
0392         /* PHY_BASIC_FEATURES */
0393         .config_init = dp83811_config_init,
0394         .config_aneg = dp83811_config_aneg,
0395         .soft_reset = dp83811_phy_reset,
0396         .get_wol = dp83811_get_wol,
0397         .set_wol = dp83811_set_wol,
0398         .config_intr = dp83811_config_intr,
0399         .handle_interrupt = dp83811_handle_interrupt,
0400         .suspend = dp83811_suspend,
0401         .resume = dp83811_resume,
0402      },
0403 };
0404 module_phy_driver(dp83811_driver);
0405 
0406 static struct mdio_device_id __maybe_unused dp83811_tbl[] = {
0407     { DP83TC811_PHY_ID, 0xfffffff0 },
0408     { },
0409 };
0410 MODULE_DEVICE_TABLE(mdio, dp83811_tbl);
0411 
0412 MODULE_DESCRIPTION("Texas Instruments DP83TC811 PHY driver");
0413 MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com");
0414 MODULE_LICENSE("GPL");