Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * Copyright (C) 2015 Microchip Technology
0004  */
0005 #include <linux/kernel.h>
0006 #include <linux/module.h>
0007 #include <linux/mii.h>
0008 #include <linux/ethtool.h>
0009 #include <linux/phy.h>
0010 #include <linux/microchipphy.h>
0011 #include <linux/delay.h>
0012 #include <linux/of.h>
0013 #include <dt-bindings/net/microchip-lan78xx.h>
0014 
0015 #define DRIVER_AUTHOR   "WOOJUNG HUH <woojung.huh@microchip.com>"
0016 #define DRIVER_DESC "Microchip LAN88XX PHY driver"
0017 
0018 struct lan88xx_priv {
0019     int chip_id;
0020     int chip_rev;
0021     __u32   wolopts;
0022 };
0023 
0024 static int lan88xx_read_page(struct phy_device *phydev)
0025 {
0026     return __phy_read(phydev, LAN88XX_EXT_PAGE_ACCESS);
0027 }
0028 
0029 static int lan88xx_write_page(struct phy_device *phydev, int page)
0030 {
0031     return __phy_write(phydev, LAN88XX_EXT_PAGE_ACCESS, page);
0032 }
0033 
0034 static int lan88xx_phy_config_intr(struct phy_device *phydev)
0035 {
0036     int rc;
0037 
0038     if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
0039         /* unmask all source and clear them before enable */
0040         rc = phy_write(phydev, LAN88XX_INT_MASK, 0x7FFF);
0041         rc = phy_read(phydev, LAN88XX_INT_STS);
0042         rc = phy_write(phydev, LAN88XX_INT_MASK,
0043                    LAN88XX_INT_MASK_MDINTPIN_EN_ |
0044                    LAN88XX_INT_MASK_LINK_CHANGE_);
0045     } else {
0046         rc = phy_write(phydev, LAN88XX_INT_MASK, 0);
0047         if (rc)
0048             return rc;
0049 
0050         /* Ack interrupts after they have been disabled */
0051         rc = phy_read(phydev, LAN88XX_INT_STS);
0052     }
0053 
0054     return rc < 0 ? rc : 0;
0055 }
0056 
0057 static irqreturn_t lan88xx_handle_interrupt(struct phy_device *phydev)
0058 {
0059     int irq_status;
0060 
0061     irq_status = phy_read(phydev, LAN88XX_INT_STS);
0062     if (irq_status < 0) {
0063         phy_error(phydev);
0064         return IRQ_NONE;
0065     }
0066 
0067     if (!(irq_status & LAN88XX_INT_STS_LINK_CHANGE_))
0068         return IRQ_NONE;
0069 
0070     phy_trigger_machine(phydev);
0071 
0072     return IRQ_HANDLED;
0073 }
0074 
0075 static int lan88xx_suspend(struct phy_device *phydev)
0076 {
0077     struct lan88xx_priv *priv = phydev->priv;
0078 
0079     /* do not power down PHY when WOL is enabled */
0080     if (!priv->wolopts)
0081         genphy_suspend(phydev);
0082 
0083     return 0;
0084 }
0085 
0086 static int lan88xx_TR_reg_set(struct phy_device *phydev, u16 regaddr,
0087                   u32 data)
0088 {
0089     int val, save_page, ret = 0;
0090     u16 buf;
0091 
0092     /* Save current page */
0093     save_page = phy_save_page(phydev);
0094     if (save_page < 0) {
0095         phydev_warn(phydev, "Failed to get current page\n");
0096         goto err;
0097     }
0098 
0099     /* Switch to TR page */
0100     lan88xx_write_page(phydev, LAN88XX_EXT_PAGE_ACCESS_TR);
0101 
0102     ret = __phy_write(phydev, LAN88XX_EXT_PAGE_TR_LOW_DATA,
0103               (data & 0xFFFF));
0104     if (ret < 0) {
0105         phydev_warn(phydev, "Failed to write TR low data\n");
0106         goto err;
0107     }
0108 
0109     ret = __phy_write(phydev, LAN88XX_EXT_PAGE_TR_HIGH_DATA,
0110               (data & 0x00FF0000) >> 16);
0111     if (ret < 0) {
0112         phydev_warn(phydev, "Failed to write TR high data\n");
0113         goto err;
0114     }
0115 
0116     /* Config control bits [15:13] of register */
0117     buf = (regaddr & ~(0x3 << 13));/* Clr [14:13] to write data in reg */
0118     buf |= 0x8000; /* Set [15] to Packet transmit */
0119 
0120     ret = __phy_write(phydev, LAN88XX_EXT_PAGE_TR_CR, buf);
0121     if (ret < 0) {
0122         phydev_warn(phydev, "Failed to write data in reg\n");
0123         goto err;
0124     }
0125 
0126     usleep_range(1000, 2000);/* Wait for Data to be written */
0127     val = __phy_read(phydev, LAN88XX_EXT_PAGE_TR_CR);
0128     if (!(val & 0x8000))
0129         phydev_warn(phydev, "TR Register[0x%X] configuration failed\n",
0130                 regaddr);
0131 err:
0132     return phy_restore_page(phydev, save_page, ret);
0133 }
0134 
0135 static void lan88xx_config_TR_regs(struct phy_device *phydev)
0136 {
0137     int err;
0138 
0139     /* Get access to Channel 0x1, Node 0xF , Register 0x01.
0140      * Write 24-bit value 0x12B00A to register. Setting MrvlTrFix1000Kf,
0141      * MrvlTrFix1000Kp, MasterEnableTR bits.
0142      */
0143     err = lan88xx_TR_reg_set(phydev, 0x0F82, 0x12B00A);
0144     if (err < 0)
0145         phydev_warn(phydev, "Failed to Set Register[0x0F82]\n");
0146 
0147     /* Get access to Channel b'10, Node b'1101, Register 0x06.
0148      * Write 24-bit value 0xD2C46F to register. Setting SSTrKf1000Slv,
0149      * SSTrKp1000Mas bits.
0150      */
0151     err = lan88xx_TR_reg_set(phydev, 0x168C, 0xD2C46F);
0152     if (err < 0)
0153         phydev_warn(phydev, "Failed to Set Register[0x168C]\n");
0154 
0155     /* Get access to Channel b'10, Node b'1111, Register 0x11.
0156      * Write 24-bit value 0x620 to register. Setting rem_upd_done_thresh
0157      * bits
0158      */
0159     err = lan88xx_TR_reg_set(phydev, 0x17A2, 0x620);
0160     if (err < 0)
0161         phydev_warn(phydev, "Failed to Set Register[0x17A2]\n");
0162 
0163     /* Get access to Channel b'10, Node b'1101, Register 0x10.
0164      * Write 24-bit value 0xEEFFDD to register. Setting
0165      * eee_TrKp1Long_1000, eee_TrKp2Long_1000, eee_TrKp3Long_1000,
0166      * eee_TrKp1Short_1000,eee_TrKp2Short_1000, eee_TrKp3Short_1000 bits.
0167      */
0168     err = lan88xx_TR_reg_set(phydev, 0x16A0, 0xEEFFDD);
0169     if (err < 0)
0170         phydev_warn(phydev, "Failed to Set Register[0x16A0]\n");
0171 
0172     /* Get access to Channel b'10, Node b'1101, Register 0x13.
0173      * Write 24-bit value 0x071448 to register. Setting
0174      * slv_lpi_tr_tmr_val1, slv_lpi_tr_tmr_val2 bits.
0175      */
0176     err = lan88xx_TR_reg_set(phydev, 0x16A6, 0x071448);
0177     if (err < 0)
0178         phydev_warn(phydev, "Failed to Set Register[0x16A6]\n");
0179 
0180     /* Get access to Channel b'10, Node b'1101, Register 0x12.
0181      * Write 24-bit value 0x13132F to register. Setting
0182      * slv_sigdet_timer_val1, slv_sigdet_timer_val2 bits.
0183      */
0184     err = lan88xx_TR_reg_set(phydev, 0x16A4, 0x13132F);
0185     if (err < 0)
0186         phydev_warn(phydev, "Failed to Set Register[0x16A4]\n");
0187 
0188     /* Get access to Channel b'10, Node b'1101, Register 0x14.
0189      * Write 24-bit value 0x0 to register. Setting eee_3level_delay,
0190      * eee_TrKf_freeze_delay bits.
0191      */
0192     err = lan88xx_TR_reg_set(phydev, 0x16A8, 0x0);
0193     if (err < 0)
0194         phydev_warn(phydev, "Failed to Set Register[0x16A8]\n");
0195 
0196     /* Get access to Channel b'01, Node b'1111, Register 0x34.
0197      * Write 24-bit value 0x91B06C to register. Setting
0198      * FastMseSearchThreshLong1000, FastMseSearchThreshShort1000,
0199      * FastMseSearchUpdGain1000 bits.
0200      */
0201     err = lan88xx_TR_reg_set(phydev, 0x0FE8, 0x91B06C);
0202     if (err < 0)
0203         phydev_warn(phydev, "Failed to Set Register[0x0FE8]\n");
0204 
0205     /* Get access to Channel b'01, Node b'1111, Register 0x3E.
0206      * Write 24-bit value 0xC0A028 to register. Setting
0207      * FastMseKp2ThreshLong1000, FastMseKp2ThreshShort1000,
0208      * FastMseKp2UpdGain1000, FastMseKp2ExitEn1000 bits.
0209      */
0210     err = lan88xx_TR_reg_set(phydev, 0x0FFC, 0xC0A028);
0211     if (err < 0)
0212         phydev_warn(phydev, "Failed to Set Register[0x0FFC]\n");
0213 
0214     /* Get access to Channel b'01, Node b'1111, Register 0x35.
0215      * Write 24-bit value 0x041600 to register. Setting
0216      * FastMseSearchPhShNum1000, FastMseSearchClksPerPh1000,
0217      * FastMsePhChangeDelay1000 bits.
0218      */
0219     err = lan88xx_TR_reg_set(phydev, 0x0FEA, 0x041600);
0220     if (err < 0)
0221         phydev_warn(phydev, "Failed to Set Register[0x0FEA]\n");
0222 
0223     /* Get access to Channel b'10, Node b'1101, Register 0x03.
0224      * Write 24-bit value 0x000004 to register. Setting TrFreeze bits.
0225      */
0226     err = lan88xx_TR_reg_set(phydev, 0x1686, 0x000004);
0227     if (err < 0)
0228         phydev_warn(phydev, "Failed to Set Register[0x1686]\n");
0229 }
0230 
0231 static int lan88xx_probe(struct phy_device *phydev)
0232 {
0233     struct device *dev = &phydev->mdio.dev;
0234     struct lan88xx_priv *priv;
0235     u32 led_modes[4];
0236     int len;
0237 
0238     priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
0239     if (!priv)
0240         return -ENOMEM;
0241 
0242     priv->wolopts = 0;
0243 
0244     len = of_property_read_variable_u32_array(dev->of_node,
0245                           "microchip,led-modes",
0246                           led_modes,
0247                           0,
0248                           ARRAY_SIZE(led_modes));
0249     if (len >= 0) {
0250         u32 reg = 0;
0251         int i;
0252 
0253         for (i = 0; i < len; i++) {
0254             if (led_modes[i] > 15)
0255                 return -EINVAL;
0256             reg |= led_modes[i] << (i * 4);
0257         }
0258         for (; i < ARRAY_SIZE(led_modes); i++)
0259             reg |= LAN78XX_FORCE_LED_OFF << (i * 4);
0260         (void)phy_write(phydev, LAN78XX_PHY_LED_MODE_SELECT, reg);
0261     } else if (len == -EOVERFLOW) {
0262         return -EINVAL;
0263     }
0264 
0265     /* these values can be used to identify internal PHY */
0266     priv->chip_id = phy_read_mmd(phydev, 3, LAN88XX_MMD3_CHIP_ID);
0267     priv->chip_rev = phy_read_mmd(phydev, 3, LAN88XX_MMD3_CHIP_REV);
0268 
0269     phydev->priv = priv;
0270 
0271     return 0;
0272 }
0273 
0274 static void lan88xx_remove(struct phy_device *phydev)
0275 {
0276     struct device *dev = &phydev->mdio.dev;
0277     struct lan88xx_priv *priv = phydev->priv;
0278 
0279     if (priv)
0280         devm_kfree(dev, priv);
0281 }
0282 
0283 static int lan88xx_set_wol(struct phy_device *phydev,
0284                struct ethtool_wolinfo *wol)
0285 {
0286     struct lan88xx_priv *priv = phydev->priv;
0287 
0288     priv->wolopts = wol->wolopts;
0289 
0290     return 0;
0291 }
0292 
0293 static void lan88xx_set_mdix(struct phy_device *phydev)
0294 {
0295     int buf;
0296     int val;
0297 
0298     switch (phydev->mdix_ctrl) {
0299     case ETH_TP_MDI:
0300         val = LAN88XX_EXT_MODE_CTRL_MDI_;
0301         break;
0302     case ETH_TP_MDI_X:
0303         val = LAN88XX_EXT_MODE_CTRL_MDI_X_;
0304         break;
0305     case ETH_TP_MDI_AUTO:
0306         val = LAN88XX_EXT_MODE_CTRL_AUTO_MDIX_;
0307         break;
0308     default:
0309         return;
0310     }
0311 
0312     phy_write(phydev, LAN88XX_EXT_PAGE_ACCESS, LAN88XX_EXT_PAGE_SPACE_1);
0313     buf = phy_read(phydev, LAN88XX_EXT_MODE_CTRL);
0314     buf &= ~LAN88XX_EXT_MODE_CTRL_MDIX_MASK_;
0315     buf |= val;
0316     phy_write(phydev, LAN88XX_EXT_MODE_CTRL, buf);
0317     phy_write(phydev, LAN88XX_EXT_PAGE_ACCESS, LAN88XX_EXT_PAGE_SPACE_0);
0318 }
0319 
0320 static int lan88xx_config_init(struct phy_device *phydev)
0321 {
0322     int val;
0323 
0324     /*Zerodetect delay enable */
0325     val = phy_read_mmd(phydev, MDIO_MMD_PCS,
0326                PHY_ARDENNES_MMD_DEV_3_PHY_CFG);
0327     val |= PHY_ARDENNES_MMD_DEV_3_PHY_CFG_ZD_DLY_EN_;
0328 
0329     phy_write_mmd(phydev, MDIO_MMD_PCS, PHY_ARDENNES_MMD_DEV_3_PHY_CFG,
0330               val);
0331 
0332     /* Config DSP registers */
0333     lan88xx_config_TR_regs(phydev);
0334 
0335     return 0;
0336 }
0337 
0338 static int lan88xx_config_aneg(struct phy_device *phydev)
0339 {
0340     lan88xx_set_mdix(phydev);
0341 
0342     return genphy_config_aneg(phydev);
0343 }
0344 
0345 static struct phy_driver microchip_phy_driver[] = {
0346 {
0347     .phy_id     = 0x0007c132,
0348     /* This mask (0xfffffff2) is to differentiate from
0349      * LAN8742 (phy_id 0x0007c130 and 0x0007c131)
0350      * and allows future phy_id revisions.
0351      */
0352     .phy_id_mask    = 0xfffffff2,
0353     .name       = "Microchip LAN88xx",
0354 
0355     /* PHY_GBIT_FEATURES */
0356 
0357     .probe      = lan88xx_probe,
0358     .remove     = lan88xx_remove,
0359 
0360     .config_init    = lan88xx_config_init,
0361     .config_aneg    = lan88xx_config_aneg,
0362 
0363     .config_intr    = lan88xx_phy_config_intr,
0364     .handle_interrupt = lan88xx_handle_interrupt,
0365 
0366     .suspend    = lan88xx_suspend,
0367     .resume     = genphy_resume,
0368     .set_wol    = lan88xx_set_wol,
0369     .read_page  = lan88xx_read_page,
0370     .write_page = lan88xx_write_page,
0371 } };
0372 
0373 module_phy_driver(microchip_phy_driver);
0374 
0375 static struct mdio_device_id __maybe_unused microchip_tbl[] = {
0376     { 0x0007c132, 0xfffffff2 },
0377     { }
0378 };
0379 
0380 MODULE_DEVICE_TABLE(mdio, microchip_tbl);
0381 
0382 MODULE_AUTHOR(DRIVER_AUTHOR);
0383 MODULE_DESCRIPTION(DRIVER_DESC);
0384 MODULE_LICENSE("GPL");