0001
0002
0003
0004
0005
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
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
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
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
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
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
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
0111
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
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
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
0271
0272
0273
0274
0275
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
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");