Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  *  Driver for Analog Devices Industrial Ethernet PHYs
0004  *
0005  * Copyright 2019 Analog Devices Inc.
0006  */
0007 #include <linux/kernel.h>
0008 #include <linux/bitfield.h>
0009 #include <linux/delay.h>
0010 #include <linux/errno.h>
0011 #include <linux/ethtool_netlink.h>
0012 #include <linux/init.h>
0013 #include <linux/module.h>
0014 #include <linux/mii.h>
0015 #include <linux/phy.h>
0016 #include <linux/property.h>
0017 
0018 #define PHY_ID_ADIN1200             0x0283bc20
0019 #define PHY_ID_ADIN1300             0x0283bc30
0020 
0021 #define ADIN1300_MII_EXT_REG_PTR        0x0010
0022 #define ADIN1300_MII_EXT_REG_DATA       0x0011
0023 
0024 #define ADIN1300_PHY_CTRL1          0x0012
0025 #define   ADIN1300_AUTO_MDI_EN          BIT(10)
0026 #define   ADIN1300_MAN_MDIX_EN          BIT(9)
0027 #define   ADIN1300_DIAG_CLK_EN          BIT(2)
0028 
0029 #define ADIN1300_RX_ERR_CNT         0x0014
0030 
0031 #define ADIN1300_PHY_CTRL_STATUS2       0x0015
0032 #define   ADIN1300_NRG_PD_EN            BIT(3)
0033 #define   ADIN1300_NRG_PD_TX_EN         BIT(2)
0034 #define   ADIN1300_NRG_PD_STATUS        BIT(1)
0035 
0036 #define ADIN1300_PHY_CTRL2          0x0016
0037 #define   ADIN1300_DOWNSPEED_AN_100_EN      BIT(11)
0038 #define   ADIN1300_DOWNSPEED_AN_10_EN       BIT(10)
0039 #define   ADIN1300_GROUP_MDIO_EN        BIT(6)
0040 #define   ADIN1300_DOWNSPEEDS_EN    \
0041     (ADIN1300_DOWNSPEED_AN_100_EN | ADIN1300_DOWNSPEED_AN_10_EN)
0042 
0043 #define ADIN1300_PHY_CTRL3          0x0017
0044 #define   ADIN1300_LINKING_EN           BIT(13)
0045 #define   ADIN1300_DOWNSPEED_RETRIES_MSK    GENMASK(12, 10)
0046 
0047 #define ADIN1300_INT_MASK_REG           0x0018
0048 #define   ADIN1300_INT_MDIO_SYNC_EN     BIT(9)
0049 #define   ADIN1300_INT_ANEG_STAT_CHNG_EN    BIT(8)
0050 #define   ADIN1300_INT_ANEG_PAGE_RX_EN      BIT(6)
0051 #define   ADIN1300_INT_IDLE_ERR_CNT_EN      BIT(5)
0052 #define   ADIN1300_INT_MAC_FIFO_OU_EN       BIT(4)
0053 #define   ADIN1300_INT_RX_STAT_CHNG_EN      BIT(3)
0054 #define   ADIN1300_INT_LINK_STAT_CHNG_EN    BIT(2)
0055 #define   ADIN1300_INT_SPEED_CHNG_EN        BIT(1)
0056 #define   ADIN1300_INT_HW_IRQ_EN        BIT(0)
0057 #define ADIN1300_INT_MASK_EN    \
0058     (ADIN1300_INT_LINK_STAT_CHNG_EN | ADIN1300_INT_HW_IRQ_EN)
0059 #define ADIN1300_INT_STATUS_REG         0x0019
0060 
0061 #define ADIN1300_PHY_STATUS1            0x001a
0062 #define   ADIN1300_PAIR_01_SWAP         BIT(11)
0063 
0064 /* EEE register addresses, accessible via Clause 22 access using
0065  * ADIN1300_MII_EXT_REG_PTR & ADIN1300_MII_EXT_REG_DATA.
0066  * The bit-fields are the same as specified by IEEE for EEE.
0067  */
0068 #define ADIN1300_EEE_CAP_REG            0x8000
0069 #define ADIN1300_EEE_ADV_REG            0x8001
0070 #define ADIN1300_EEE_LPABLE_REG         0x8002
0071 #define ADIN1300_CLOCK_STOP_REG         0x9400
0072 #define ADIN1300_LPI_WAKE_ERR_CNT_REG       0xa000
0073 
0074 #define ADIN1300_CDIAG_RUN          0xba1b
0075 #define   ADIN1300_CDIAG_RUN_EN         BIT(0)
0076 
0077 /*
0078  * The XSIM3/2/1 and XSHRT3/2/1 are actually relative.
0079  * For CDIAG_DTLD_RSLTS(0) it's ADIN1300_CDIAG_RSLT_XSIM3/2/1
0080  * For CDIAG_DTLD_RSLTS(1) it's ADIN1300_CDIAG_RSLT_XSIM3/2/0
0081  * For CDIAG_DTLD_RSLTS(2) it's ADIN1300_CDIAG_RSLT_XSIM3/1/0
0082  * For CDIAG_DTLD_RSLTS(3) it's ADIN1300_CDIAG_RSLT_XSIM2/1/0
0083  */
0084 #define ADIN1300_CDIAG_DTLD_RSLTS(x)        (0xba1d + (x))
0085 #define   ADIN1300_CDIAG_RSLT_BUSY      BIT(10)
0086 #define   ADIN1300_CDIAG_RSLT_XSIM3     BIT(9)
0087 #define   ADIN1300_CDIAG_RSLT_XSIM2     BIT(8)
0088 #define   ADIN1300_CDIAG_RSLT_XSIM1     BIT(7)
0089 #define   ADIN1300_CDIAG_RSLT_SIM       BIT(6)
0090 #define   ADIN1300_CDIAG_RSLT_XSHRT3        BIT(5)
0091 #define   ADIN1300_CDIAG_RSLT_XSHRT2        BIT(4)
0092 #define   ADIN1300_CDIAG_RSLT_XSHRT1        BIT(3)
0093 #define   ADIN1300_CDIAG_RSLT_SHRT      BIT(2)
0094 #define   ADIN1300_CDIAG_RSLT_OPEN      BIT(1)
0095 #define   ADIN1300_CDIAG_RSLT_GOOD      BIT(0)
0096 
0097 #define ADIN1300_CDIAG_FLT_DIST(x)      (0xba21 + (x))
0098 
0099 #define ADIN1300_GE_SOFT_RESET_REG      0xff0c
0100 #define   ADIN1300_GE_SOFT_RESET        BIT(0)
0101 
0102 #define ADIN1300_GE_CLK_CFG_REG         0xff1f
0103 #define   ADIN1300_GE_CLK_CFG_MASK      GENMASK(5, 0)
0104 #define   ADIN1300_GE_CLK_CFG_RCVR_125      BIT(5)
0105 #define   ADIN1300_GE_CLK_CFG_FREE_125      BIT(4)
0106 #define   ADIN1300_GE_CLK_CFG_REF_EN        BIT(3)
0107 #define   ADIN1300_GE_CLK_CFG_HRT_RCVR      BIT(2)
0108 #define   ADIN1300_GE_CLK_CFG_HRT_FREE      BIT(1)
0109 #define   ADIN1300_GE_CLK_CFG_25        BIT(0)
0110 
0111 #define ADIN1300_GE_RGMII_CFG_REG       0xff23
0112 #define   ADIN1300_GE_RGMII_RX_MSK      GENMASK(8, 6)
0113 #define   ADIN1300_GE_RGMII_RX_SEL(x)       \
0114         FIELD_PREP(ADIN1300_GE_RGMII_RX_MSK, x)
0115 #define   ADIN1300_GE_RGMII_GTX_MSK     GENMASK(5, 3)
0116 #define   ADIN1300_GE_RGMII_GTX_SEL(x)      \
0117         FIELD_PREP(ADIN1300_GE_RGMII_GTX_MSK, x)
0118 #define   ADIN1300_GE_RGMII_RXID_EN     BIT(2)
0119 #define   ADIN1300_GE_RGMII_TXID_EN     BIT(1)
0120 #define   ADIN1300_GE_RGMII_EN          BIT(0)
0121 
0122 /* RGMII internal delay settings for rx and tx for ADIN1300 */
0123 #define ADIN1300_RGMII_1_60_NS          0x0001
0124 #define ADIN1300_RGMII_1_80_NS          0x0002
0125 #define ADIN1300_RGMII_2_00_NS          0x0000
0126 #define ADIN1300_RGMII_2_20_NS          0x0006
0127 #define ADIN1300_RGMII_2_40_NS          0x0007
0128 
0129 #define ADIN1300_GE_RMII_CFG_REG        0xff24
0130 #define   ADIN1300_GE_RMII_FIFO_DEPTH_MSK   GENMASK(6, 4)
0131 #define   ADIN1300_GE_RMII_FIFO_DEPTH_SEL(x)    \
0132         FIELD_PREP(ADIN1300_GE_RMII_FIFO_DEPTH_MSK, x)
0133 #define   ADIN1300_GE_RMII_EN           BIT(0)
0134 
0135 /* RMII fifo depth values */
0136 #define ADIN1300_RMII_4_BITS            0x0000
0137 #define ADIN1300_RMII_8_BITS            0x0001
0138 #define ADIN1300_RMII_12_BITS           0x0002
0139 #define ADIN1300_RMII_16_BITS           0x0003
0140 #define ADIN1300_RMII_20_BITS           0x0004
0141 #define ADIN1300_RMII_24_BITS           0x0005
0142 
0143 /**
0144  * struct adin_cfg_reg_map - map a config value to aregister value
0145  * @cfg:    value in device configuration
0146  * @reg:    value in the register
0147  */
0148 struct adin_cfg_reg_map {
0149     int cfg;
0150     int reg;
0151 };
0152 
0153 static const struct adin_cfg_reg_map adin_rgmii_delays[] = {
0154     { 1600, ADIN1300_RGMII_1_60_NS },
0155     { 1800, ADIN1300_RGMII_1_80_NS },
0156     { 2000, ADIN1300_RGMII_2_00_NS },
0157     { 2200, ADIN1300_RGMII_2_20_NS },
0158     { 2400, ADIN1300_RGMII_2_40_NS },
0159     { },
0160 };
0161 
0162 static const struct adin_cfg_reg_map adin_rmii_fifo_depths[] = {
0163     { 4,  ADIN1300_RMII_4_BITS },
0164     { 8,  ADIN1300_RMII_8_BITS },
0165     { 12, ADIN1300_RMII_12_BITS },
0166     { 16, ADIN1300_RMII_16_BITS },
0167     { 20, ADIN1300_RMII_20_BITS },
0168     { 24, ADIN1300_RMII_24_BITS },
0169     { },
0170 };
0171 
0172 /**
0173  * struct adin_clause45_mmd_map - map to convert Clause 45 regs to Clause 22
0174  * @devad:      device address used in Clause 45 access
0175  * @cl45_regnum:    register address defined by Clause 45
0176  * @adin_regnum:    equivalent register address accessible via Clause 22
0177  */
0178 struct adin_clause45_mmd_map {
0179     int devad;
0180     u16 cl45_regnum;
0181     u16 adin_regnum;
0182 };
0183 
0184 static const struct adin_clause45_mmd_map adin_clause45_mmd_map[] = {
0185     { MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE,  ADIN1300_EEE_CAP_REG },
0186     { MDIO_MMD_AN,  MDIO_AN_EEE_LPABLE, ADIN1300_EEE_LPABLE_REG },
0187     { MDIO_MMD_AN,  MDIO_AN_EEE_ADV,    ADIN1300_EEE_ADV_REG },
0188     { MDIO_MMD_PCS, MDIO_CTRL1,     ADIN1300_CLOCK_STOP_REG },
0189     { MDIO_MMD_PCS, MDIO_PCS_EEE_WK_ERR,    ADIN1300_LPI_WAKE_ERR_CNT_REG },
0190 };
0191 
0192 struct adin_hw_stat {
0193     const char *string;
0194     u16 reg1;
0195     u16 reg2;
0196 };
0197 
0198 static const struct adin_hw_stat adin_hw_stats[] = {
0199     { "total_frames_checked_count",     0x940A, 0x940B }, /* hi + lo */
0200     { "length_error_frames_count",      0x940C },
0201     { "alignment_error_frames_count",   0x940D },
0202     { "symbol_error_count",         0x940E },
0203     { "oversized_frames_count",     0x940F },
0204     { "undersized_frames_count",        0x9410 },
0205     { "odd_nibble_frames_count",        0x9411 },
0206     { "odd_preamble_packet_count",      0x9412 },
0207     { "dribble_bits_frames_count",      0x9413 },
0208     { "false_carrier_events_count",     0x9414 },
0209 };
0210 
0211 /**
0212  * struct adin_priv - ADIN PHY driver private data
0213  * @stats:      statistic counters for the PHY
0214  */
0215 struct adin_priv {
0216     u64         stats[ARRAY_SIZE(adin_hw_stats)];
0217 };
0218 
0219 static int adin_lookup_reg_value(const struct adin_cfg_reg_map *tbl, int cfg)
0220 {
0221     size_t i;
0222 
0223     for (i = 0; tbl[i].cfg; i++) {
0224         if (tbl[i].cfg == cfg)
0225             return tbl[i].reg;
0226     }
0227 
0228     return -EINVAL;
0229 }
0230 
0231 static u32 adin_get_reg_value(struct phy_device *phydev,
0232                   const char *prop_name,
0233                   const struct adin_cfg_reg_map *tbl,
0234                   u32 dflt)
0235 {
0236     struct device *dev = &phydev->mdio.dev;
0237     u32 val;
0238     int rc;
0239 
0240     if (device_property_read_u32(dev, prop_name, &val))
0241         return dflt;
0242 
0243     rc = adin_lookup_reg_value(tbl, val);
0244     if (rc < 0) {
0245         phydev_warn(phydev,
0246                 "Unsupported value %u for %s using default (%u)\n",
0247                 val, prop_name, dflt);
0248         return dflt;
0249     }
0250 
0251     return rc;
0252 }
0253 
0254 static int adin_config_rgmii_mode(struct phy_device *phydev)
0255 {
0256     u32 val;
0257     int reg;
0258 
0259     if (!phy_interface_is_rgmii(phydev))
0260         return phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
0261                       ADIN1300_GE_RGMII_CFG_REG,
0262                       ADIN1300_GE_RGMII_EN);
0263 
0264     reg = phy_read_mmd(phydev, MDIO_MMD_VEND1, ADIN1300_GE_RGMII_CFG_REG);
0265     if (reg < 0)
0266         return reg;
0267 
0268     reg |= ADIN1300_GE_RGMII_EN;
0269 
0270     if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
0271         phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
0272         reg |= ADIN1300_GE_RGMII_RXID_EN;
0273 
0274         val = adin_get_reg_value(phydev, "adi,rx-internal-delay-ps",
0275                      adin_rgmii_delays,
0276                      ADIN1300_RGMII_2_00_NS);
0277         reg &= ~ADIN1300_GE_RGMII_RX_MSK;
0278         reg |= ADIN1300_GE_RGMII_RX_SEL(val);
0279     } else {
0280         reg &= ~ADIN1300_GE_RGMII_RXID_EN;
0281     }
0282 
0283     if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
0284         phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
0285         reg |= ADIN1300_GE_RGMII_TXID_EN;
0286 
0287         val = adin_get_reg_value(phydev, "adi,tx-internal-delay-ps",
0288                      adin_rgmii_delays,
0289                      ADIN1300_RGMII_2_00_NS);
0290         reg &= ~ADIN1300_GE_RGMII_GTX_MSK;
0291         reg |= ADIN1300_GE_RGMII_GTX_SEL(val);
0292     } else {
0293         reg &= ~ADIN1300_GE_RGMII_TXID_EN;
0294     }
0295 
0296     return phy_write_mmd(phydev, MDIO_MMD_VEND1,
0297                  ADIN1300_GE_RGMII_CFG_REG, reg);
0298 }
0299 
0300 static int adin_config_rmii_mode(struct phy_device *phydev)
0301 {
0302     u32 val;
0303     int reg;
0304 
0305     if (phydev->interface != PHY_INTERFACE_MODE_RMII)
0306         return phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
0307                       ADIN1300_GE_RMII_CFG_REG,
0308                       ADIN1300_GE_RMII_EN);
0309 
0310     reg = phy_read_mmd(phydev, MDIO_MMD_VEND1, ADIN1300_GE_RMII_CFG_REG);
0311     if (reg < 0)
0312         return reg;
0313 
0314     reg |= ADIN1300_GE_RMII_EN;
0315 
0316     val = adin_get_reg_value(phydev, "adi,fifo-depth-bits",
0317                  adin_rmii_fifo_depths,
0318                  ADIN1300_RMII_8_BITS);
0319 
0320     reg &= ~ADIN1300_GE_RMII_FIFO_DEPTH_MSK;
0321     reg |= ADIN1300_GE_RMII_FIFO_DEPTH_SEL(val);
0322 
0323     return phy_write_mmd(phydev, MDIO_MMD_VEND1,
0324                  ADIN1300_GE_RMII_CFG_REG, reg);
0325 }
0326 
0327 static int adin_get_downshift(struct phy_device *phydev, u8 *data)
0328 {
0329     int val, cnt, enable;
0330 
0331     val = phy_read(phydev, ADIN1300_PHY_CTRL2);
0332     if (val < 0)
0333         return val;
0334 
0335     cnt = phy_read(phydev, ADIN1300_PHY_CTRL3);
0336     if (cnt < 0)
0337         return cnt;
0338 
0339     enable = FIELD_GET(ADIN1300_DOWNSPEEDS_EN, val);
0340     cnt = FIELD_GET(ADIN1300_DOWNSPEED_RETRIES_MSK, cnt);
0341 
0342     *data = (enable && cnt) ? cnt : DOWNSHIFT_DEV_DISABLE;
0343 
0344     return 0;
0345 }
0346 
0347 static int adin_set_downshift(struct phy_device *phydev, u8 cnt)
0348 {
0349     u16 val;
0350     int rc;
0351 
0352     if (cnt == DOWNSHIFT_DEV_DISABLE)
0353         return phy_clear_bits(phydev, ADIN1300_PHY_CTRL2,
0354                       ADIN1300_DOWNSPEEDS_EN);
0355 
0356     if (cnt > 7)
0357         return -E2BIG;
0358 
0359     val = FIELD_PREP(ADIN1300_DOWNSPEED_RETRIES_MSK, cnt);
0360 
0361     rc = phy_modify(phydev, ADIN1300_PHY_CTRL3,
0362             ADIN1300_DOWNSPEED_RETRIES_MSK,
0363             val);
0364     if (rc < 0)
0365         return rc;
0366 
0367     return phy_set_bits(phydev, ADIN1300_PHY_CTRL2,
0368                 ADIN1300_DOWNSPEEDS_EN);
0369 }
0370 
0371 static int adin_get_edpd(struct phy_device *phydev, u16 *tx_interval)
0372 {
0373     int val;
0374 
0375     val = phy_read(phydev, ADIN1300_PHY_CTRL_STATUS2);
0376     if (val < 0)
0377         return val;
0378 
0379     if (ADIN1300_NRG_PD_EN & val) {
0380         if (val & ADIN1300_NRG_PD_TX_EN)
0381             /* default is 1 second */
0382             *tx_interval = ETHTOOL_PHY_EDPD_DFLT_TX_MSECS;
0383         else
0384             *tx_interval = ETHTOOL_PHY_EDPD_NO_TX;
0385     } else {
0386         *tx_interval = ETHTOOL_PHY_EDPD_DISABLE;
0387     }
0388 
0389     return 0;
0390 }
0391 
0392 static int adin_set_edpd(struct phy_device *phydev, u16 tx_interval)
0393 {
0394     u16 val;
0395 
0396     if (tx_interval == ETHTOOL_PHY_EDPD_DISABLE)
0397         return phy_clear_bits(phydev, ADIN1300_PHY_CTRL_STATUS2,
0398                 (ADIN1300_NRG_PD_EN | ADIN1300_NRG_PD_TX_EN));
0399 
0400     val = ADIN1300_NRG_PD_EN;
0401 
0402     switch (tx_interval) {
0403     case 1000: /* 1 second */
0404         fallthrough;
0405     case ETHTOOL_PHY_EDPD_DFLT_TX_MSECS:
0406         val |= ADIN1300_NRG_PD_TX_EN;
0407         fallthrough;
0408     case ETHTOOL_PHY_EDPD_NO_TX:
0409         break;
0410     default:
0411         return -EINVAL;
0412     }
0413 
0414     return phy_modify(phydev, ADIN1300_PHY_CTRL_STATUS2,
0415               (ADIN1300_NRG_PD_EN | ADIN1300_NRG_PD_TX_EN),
0416               val);
0417 }
0418 
0419 static int adin_get_tunable(struct phy_device *phydev,
0420                 struct ethtool_tunable *tuna, void *data)
0421 {
0422     switch (tuna->id) {
0423     case ETHTOOL_PHY_DOWNSHIFT:
0424         return adin_get_downshift(phydev, data);
0425     case ETHTOOL_PHY_EDPD:
0426         return adin_get_edpd(phydev, data);
0427     default:
0428         return -EOPNOTSUPP;
0429     }
0430 }
0431 
0432 static int adin_set_tunable(struct phy_device *phydev,
0433                 struct ethtool_tunable *tuna, const void *data)
0434 {
0435     switch (tuna->id) {
0436     case ETHTOOL_PHY_DOWNSHIFT:
0437         return adin_set_downshift(phydev, *(const u8 *)data);
0438     case ETHTOOL_PHY_EDPD:
0439         return adin_set_edpd(phydev, *(const u16 *)data);
0440     default:
0441         return -EOPNOTSUPP;
0442     }
0443 }
0444 
0445 static int adin_config_clk_out(struct phy_device *phydev)
0446 {
0447     struct device *dev = &phydev->mdio.dev;
0448     const char *val = NULL;
0449     u8 sel = 0;
0450 
0451     device_property_read_string(dev, "adi,phy-output-clock", &val);
0452     if (!val) {
0453         /* property not present, do not enable GP_CLK pin */
0454     } else if (strcmp(val, "25mhz-reference") == 0) {
0455         sel |= ADIN1300_GE_CLK_CFG_25;
0456     } else if (strcmp(val, "125mhz-free-running") == 0) {
0457         sel |= ADIN1300_GE_CLK_CFG_FREE_125;
0458     } else if (strcmp(val, "adaptive-free-running") == 0) {
0459         sel |= ADIN1300_GE_CLK_CFG_HRT_FREE;
0460     } else {
0461         phydev_err(phydev, "invalid adi,phy-output-clock\n");
0462         return -EINVAL;
0463     }
0464 
0465     if (device_property_read_bool(dev, "adi,phy-output-reference-clock"))
0466         sel |= ADIN1300_GE_CLK_CFG_REF_EN;
0467 
0468     return phy_modify_mmd(phydev, MDIO_MMD_VEND1, ADIN1300_GE_CLK_CFG_REG,
0469                   ADIN1300_GE_CLK_CFG_MASK, sel);
0470 }
0471 
0472 static int adin_config_init(struct phy_device *phydev)
0473 {
0474     int rc;
0475 
0476     phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
0477 
0478     rc = adin_config_rgmii_mode(phydev);
0479     if (rc < 0)
0480         return rc;
0481 
0482     rc = adin_config_rmii_mode(phydev);
0483     if (rc < 0)
0484         return rc;
0485 
0486     rc = adin_set_downshift(phydev, 4);
0487     if (rc < 0)
0488         return rc;
0489 
0490     rc = adin_set_edpd(phydev, ETHTOOL_PHY_EDPD_DFLT_TX_MSECS);
0491     if (rc < 0)
0492         return rc;
0493 
0494     rc = adin_config_clk_out(phydev);
0495     if (rc < 0)
0496         return rc;
0497 
0498     phydev_dbg(phydev, "PHY is using mode '%s'\n",
0499            phy_modes(phydev->interface));
0500 
0501     return 0;
0502 }
0503 
0504 static int adin_phy_ack_intr(struct phy_device *phydev)
0505 {
0506     /* Clear pending interrupts */
0507     int rc = phy_read(phydev, ADIN1300_INT_STATUS_REG);
0508 
0509     return rc < 0 ? rc : 0;
0510 }
0511 
0512 static int adin_phy_config_intr(struct phy_device *phydev)
0513 {
0514     int err;
0515 
0516     if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
0517         err = adin_phy_ack_intr(phydev);
0518         if (err)
0519             return err;
0520 
0521         err = phy_set_bits(phydev, ADIN1300_INT_MASK_REG,
0522                    ADIN1300_INT_MASK_EN);
0523     } else {
0524         err = phy_clear_bits(phydev, ADIN1300_INT_MASK_REG,
0525                      ADIN1300_INT_MASK_EN);
0526         if (err)
0527             return err;
0528 
0529         err = adin_phy_ack_intr(phydev);
0530     }
0531 
0532     return err;
0533 }
0534 
0535 static irqreturn_t adin_phy_handle_interrupt(struct phy_device *phydev)
0536 {
0537     int irq_status;
0538 
0539     irq_status = phy_read(phydev, ADIN1300_INT_STATUS_REG);
0540     if (irq_status < 0) {
0541         phy_error(phydev);
0542         return IRQ_NONE;
0543     }
0544 
0545     if (!(irq_status & ADIN1300_INT_LINK_STAT_CHNG_EN))
0546         return IRQ_NONE;
0547 
0548     phy_trigger_machine(phydev);
0549 
0550     return IRQ_HANDLED;
0551 }
0552 
0553 static int adin_cl45_to_adin_reg(struct phy_device *phydev, int devad,
0554                  u16 cl45_regnum)
0555 {
0556     const struct adin_clause45_mmd_map *m;
0557     int i;
0558 
0559     if (devad == MDIO_MMD_VEND1)
0560         return cl45_regnum;
0561 
0562     for (i = 0; i < ARRAY_SIZE(adin_clause45_mmd_map); i++) {
0563         m = &adin_clause45_mmd_map[i];
0564         if (m->devad == devad && m->cl45_regnum == cl45_regnum)
0565             return m->adin_regnum;
0566     }
0567 
0568     phydev_err(phydev,
0569            "No translation available for devad: %d reg: %04x\n",
0570            devad, cl45_regnum);
0571 
0572     return -EINVAL;
0573 }
0574 
0575 static int adin_read_mmd(struct phy_device *phydev, int devad, u16 regnum)
0576 {
0577     struct mii_bus *bus = phydev->mdio.bus;
0578     int phy_addr = phydev->mdio.addr;
0579     int adin_regnum;
0580     int err;
0581 
0582     adin_regnum = adin_cl45_to_adin_reg(phydev, devad, regnum);
0583     if (adin_regnum < 0)
0584         return adin_regnum;
0585 
0586     err = __mdiobus_write(bus, phy_addr, ADIN1300_MII_EXT_REG_PTR,
0587                   adin_regnum);
0588     if (err)
0589         return err;
0590 
0591     return __mdiobus_read(bus, phy_addr, ADIN1300_MII_EXT_REG_DATA);
0592 }
0593 
0594 static int adin_write_mmd(struct phy_device *phydev, int devad, u16 regnum,
0595               u16 val)
0596 {
0597     struct mii_bus *bus = phydev->mdio.bus;
0598     int phy_addr = phydev->mdio.addr;
0599     int adin_regnum;
0600     int err;
0601 
0602     adin_regnum = adin_cl45_to_adin_reg(phydev, devad, regnum);
0603     if (adin_regnum < 0)
0604         return adin_regnum;
0605 
0606     err = __mdiobus_write(bus, phy_addr, ADIN1300_MII_EXT_REG_PTR,
0607                   adin_regnum);
0608     if (err)
0609         return err;
0610 
0611     return __mdiobus_write(bus, phy_addr, ADIN1300_MII_EXT_REG_DATA, val);
0612 }
0613 
0614 static int adin_config_mdix(struct phy_device *phydev)
0615 {
0616     bool auto_en, mdix_en;
0617     int reg;
0618 
0619     mdix_en = false;
0620     auto_en = false;
0621     switch (phydev->mdix_ctrl) {
0622     case ETH_TP_MDI:
0623         break;
0624     case ETH_TP_MDI_X:
0625         mdix_en = true;
0626         break;
0627     case ETH_TP_MDI_AUTO:
0628         auto_en = true;
0629         break;
0630     default:
0631         return -EINVAL;
0632     }
0633 
0634     reg = phy_read(phydev, ADIN1300_PHY_CTRL1);
0635     if (reg < 0)
0636         return reg;
0637 
0638     if (mdix_en)
0639         reg |= ADIN1300_MAN_MDIX_EN;
0640     else
0641         reg &= ~ADIN1300_MAN_MDIX_EN;
0642 
0643     if (auto_en)
0644         reg |= ADIN1300_AUTO_MDI_EN;
0645     else
0646         reg &= ~ADIN1300_AUTO_MDI_EN;
0647 
0648     return phy_write(phydev, ADIN1300_PHY_CTRL1, reg);
0649 }
0650 
0651 static int adin_config_aneg(struct phy_device *phydev)
0652 {
0653     int ret;
0654 
0655     ret = phy_clear_bits(phydev, ADIN1300_PHY_CTRL1, ADIN1300_DIAG_CLK_EN);
0656     if (ret < 0)
0657         return ret;
0658 
0659     ret = phy_set_bits(phydev, ADIN1300_PHY_CTRL3, ADIN1300_LINKING_EN);
0660     if (ret < 0)
0661         return ret;
0662 
0663     ret = adin_config_mdix(phydev);
0664     if (ret)
0665         return ret;
0666 
0667     return genphy_config_aneg(phydev);
0668 }
0669 
0670 static int adin_mdix_update(struct phy_device *phydev)
0671 {
0672     bool auto_en, mdix_en;
0673     bool swapped;
0674     int reg;
0675 
0676     reg = phy_read(phydev, ADIN1300_PHY_CTRL1);
0677     if (reg < 0)
0678         return reg;
0679 
0680     auto_en = !!(reg & ADIN1300_AUTO_MDI_EN);
0681     mdix_en = !!(reg & ADIN1300_MAN_MDIX_EN);
0682 
0683     /* If MDI/MDIX is forced, just read it from the control reg */
0684     if (!auto_en) {
0685         if (mdix_en)
0686             phydev->mdix = ETH_TP_MDI_X;
0687         else
0688             phydev->mdix = ETH_TP_MDI;
0689         return 0;
0690     }
0691 
0692     /**
0693      * Otherwise, we need to deduce it from the PHY status2 reg.
0694      * When Auto-MDI is enabled, the ADIN1300_MAN_MDIX_EN bit implies
0695      * a preference for MDIX when it is set.
0696      */
0697     reg = phy_read(phydev, ADIN1300_PHY_STATUS1);
0698     if (reg < 0)
0699         return reg;
0700 
0701     swapped = !!(reg & ADIN1300_PAIR_01_SWAP);
0702 
0703     if (mdix_en != swapped)
0704         phydev->mdix = ETH_TP_MDI_X;
0705     else
0706         phydev->mdix = ETH_TP_MDI;
0707 
0708     return 0;
0709 }
0710 
0711 static int adin_read_status(struct phy_device *phydev)
0712 {
0713     int ret;
0714 
0715     ret = adin_mdix_update(phydev);
0716     if (ret < 0)
0717         return ret;
0718 
0719     return genphy_read_status(phydev);
0720 }
0721 
0722 static int adin_soft_reset(struct phy_device *phydev)
0723 {
0724     int rc;
0725 
0726     /* The reset bit is self-clearing, set it and wait */
0727     rc = phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
0728                   ADIN1300_GE_SOFT_RESET_REG,
0729                   ADIN1300_GE_SOFT_RESET);
0730     if (rc < 0)
0731         return rc;
0732 
0733     msleep(20);
0734 
0735     /* If we get a read error something may be wrong */
0736     rc = phy_read_mmd(phydev, MDIO_MMD_VEND1,
0737               ADIN1300_GE_SOFT_RESET_REG);
0738 
0739     return rc < 0 ? rc : 0;
0740 }
0741 
0742 static int adin_get_sset_count(struct phy_device *phydev)
0743 {
0744     return ARRAY_SIZE(adin_hw_stats);
0745 }
0746 
0747 static void adin_get_strings(struct phy_device *phydev, u8 *data)
0748 {
0749     int i;
0750 
0751     for (i = 0; i < ARRAY_SIZE(adin_hw_stats); i++) {
0752         strlcpy(&data[i * ETH_GSTRING_LEN],
0753             adin_hw_stats[i].string, ETH_GSTRING_LEN);
0754     }
0755 }
0756 
0757 static int adin_read_mmd_stat_regs(struct phy_device *phydev,
0758                    const struct adin_hw_stat *stat,
0759                    u32 *val)
0760 {
0761     int ret;
0762 
0763     ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, stat->reg1);
0764     if (ret < 0)
0765         return ret;
0766 
0767     *val = (ret & 0xffff);
0768 
0769     if (stat->reg2 == 0)
0770         return 0;
0771 
0772     ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, stat->reg2);
0773     if (ret < 0)
0774         return ret;
0775 
0776     *val <<= 16;
0777     *val |= (ret & 0xffff);
0778 
0779     return 0;
0780 }
0781 
0782 static u64 adin_get_stat(struct phy_device *phydev, int i)
0783 {
0784     const struct adin_hw_stat *stat = &adin_hw_stats[i];
0785     struct adin_priv *priv = phydev->priv;
0786     u32 val;
0787     int ret;
0788 
0789     if (stat->reg1 > 0x1f) {
0790         ret = adin_read_mmd_stat_regs(phydev, stat, &val);
0791         if (ret < 0)
0792             return (u64)(~0);
0793     } else {
0794         ret = phy_read(phydev, stat->reg1);
0795         if (ret < 0)
0796             return (u64)(~0);
0797         val = (ret & 0xffff);
0798     }
0799 
0800     priv->stats[i] += val;
0801 
0802     return priv->stats[i];
0803 }
0804 
0805 static void adin_get_stats(struct phy_device *phydev,
0806                struct ethtool_stats *stats, u64 *data)
0807 {
0808     int i, rc;
0809 
0810     /* latch copies of all the frame-checker counters */
0811     rc = phy_read(phydev, ADIN1300_RX_ERR_CNT);
0812     if (rc < 0)
0813         return;
0814 
0815     for (i = 0; i < ARRAY_SIZE(adin_hw_stats); i++)
0816         data[i] = adin_get_stat(phydev, i);
0817 }
0818 
0819 static int adin_probe(struct phy_device *phydev)
0820 {
0821     struct device *dev = &phydev->mdio.dev;
0822     struct adin_priv *priv;
0823 
0824     priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
0825     if (!priv)
0826         return -ENOMEM;
0827 
0828     phydev->priv = priv;
0829 
0830     return 0;
0831 }
0832 
0833 static int adin_cable_test_start(struct phy_device *phydev)
0834 {
0835     int ret;
0836 
0837     ret = phy_clear_bits(phydev, ADIN1300_PHY_CTRL3, ADIN1300_LINKING_EN);
0838     if (ret < 0)
0839         return ret;
0840 
0841     ret = phy_clear_bits(phydev, ADIN1300_PHY_CTRL1, ADIN1300_DIAG_CLK_EN);
0842     if (ret < 0)
0843         return ret;
0844 
0845     /* wait a bit for the clock to stabilize */
0846     msleep(50);
0847 
0848     return phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, ADIN1300_CDIAG_RUN,
0849                 ADIN1300_CDIAG_RUN_EN);
0850 }
0851 
0852 static int adin_cable_test_report_trans(int result)
0853 {
0854     int mask;
0855 
0856     if (result & ADIN1300_CDIAG_RSLT_GOOD)
0857         return ETHTOOL_A_CABLE_RESULT_CODE_OK;
0858     if (result & ADIN1300_CDIAG_RSLT_OPEN)
0859         return ETHTOOL_A_CABLE_RESULT_CODE_OPEN;
0860 
0861     /* short with other pairs */
0862     mask = ADIN1300_CDIAG_RSLT_XSHRT3 |
0863            ADIN1300_CDIAG_RSLT_XSHRT2 |
0864            ADIN1300_CDIAG_RSLT_XSHRT1;
0865     if (result & mask)
0866         return ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT;
0867 
0868     if (result & ADIN1300_CDIAG_RSLT_SHRT)
0869         return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT;
0870 
0871     return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC;
0872 }
0873 
0874 static int adin_cable_test_report_pair(struct phy_device *phydev,
0875                        unsigned int pair)
0876 {
0877     int fault_rslt;
0878     int ret;
0879 
0880     ret = phy_read_mmd(phydev, MDIO_MMD_VEND1,
0881                ADIN1300_CDIAG_DTLD_RSLTS(pair));
0882     if (ret < 0)
0883         return ret;
0884 
0885     fault_rslt = adin_cable_test_report_trans(ret);
0886 
0887     ret = ethnl_cable_test_result(phydev, pair, fault_rslt);
0888     if (ret < 0)
0889         return ret;
0890 
0891     ret = phy_read_mmd(phydev, MDIO_MMD_VEND1,
0892                ADIN1300_CDIAG_FLT_DIST(pair));
0893     if (ret < 0)
0894         return ret;
0895 
0896     switch (fault_rslt) {
0897     case ETHTOOL_A_CABLE_RESULT_CODE_OPEN:
0898     case ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT:
0899     case ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT:
0900         return ethnl_cable_test_fault_length(phydev, pair, ret * 100);
0901     default:
0902         return  0;
0903     }
0904 }
0905 
0906 static int adin_cable_test_report(struct phy_device *phydev)
0907 {
0908     unsigned int pair;
0909     int ret;
0910 
0911     for (pair = ETHTOOL_A_CABLE_PAIR_A; pair <= ETHTOOL_A_CABLE_PAIR_D; pair++) {
0912         ret = adin_cable_test_report_pair(phydev, pair);
0913         if (ret < 0)
0914             return ret;
0915     }
0916 
0917     return 0;
0918 }
0919 
0920 static int adin_cable_test_get_status(struct phy_device *phydev,
0921                       bool *finished)
0922 {
0923     int ret;
0924 
0925     *finished = false;
0926 
0927     ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, ADIN1300_CDIAG_RUN);
0928     if (ret < 0)
0929         return ret;
0930 
0931     if (ret & ADIN1300_CDIAG_RUN_EN)
0932         return 0;
0933 
0934     *finished = true;
0935 
0936     return adin_cable_test_report(phydev);
0937 }
0938 
0939 static struct phy_driver adin_driver[] = {
0940     {
0941         PHY_ID_MATCH_MODEL(PHY_ID_ADIN1200),
0942         .name       = "ADIN1200",
0943         .flags      = PHY_POLL_CABLE_TEST,
0944         .probe      = adin_probe,
0945         .config_init    = adin_config_init,
0946         .soft_reset = adin_soft_reset,
0947         .config_aneg    = adin_config_aneg,
0948         .read_status    = adin_read_status,
0949         .get_tunable    = adin_get_tunable,
0950         .set_tunable    = adin_set_tunable,
0951         .config_intr    = adin_phy_config_intr,
0952         .handle_interrupt = adin_phy_handle_interrupt,
0953         .get_sset_count = adin_get_sset_count,
0954         .get_strings    = adin_get_strings,
0955         .get_stats  = adin_get_stats,
0956         .resume     = genphy_resume,
0957         .suspend    = genphy_suspend,
0958         .read_mmd   = adin_read_mmd,
0959         .write_mmd  = adin_write_mmd,
0960         .cable_test_start   = adin_cable_test_start,
0961         .cable_test_get_status  = adin_cable_test_get_status,
0962     },
0963     {
0964         PHY_ID_MATCH_MODEL(PHY_ID_ADIN1300),
0965         .name       = "ADIN1300",
0966         .flags      = PHY_POLL_CABLE_TEST,
0967         .probe      = adin_probe,
0968         .config_init    = adin_config_init,
0969         .soft_reset = adin_soft_reset,
0970         .config_aneg    = adin_config_aneg,
0971         .read_status    = adin_read_status,
0972         .get_tunable    = adin_get_tunable,
0973         .set_tunable    = adin_set_tunable,
0974         .config_intr    = adin_phy_config_intr,
0975         .handle_interrupt = adin_phy_handle_interrupt,
0976         .get_sset_count = adin_get_sset_count,
0977         .get_strings    = adin_get_strings,
0978         .get_stats  = adin_get_stats,
0979         .resume     = genphy_resume,
0980         .suspend    = genphy_suspend,
0981         .read_mmd   = adin_read_mmd,
0982         .write_mmd  = adin_write_mmd,
0983         .cable_test_start   = adin_cable_test_start,
0984         .cable_test_get_status  = adin_cable_test_get_status,
0985     },
0986 };
0987 
0988 module_phy_driver(adin_driver);
0989 
0990 static struct mdio_device_id __maybe_unused adin_tbl[] = {
0991     { PHY_ID_MATCH_MODEL(PHY_ID_ADIN1200) },
0992     { PHY_ID_MATCH_MODEL(PHY_ID_ADIN1300) },
0993     { }
0994 };
0995 
0996 MODULE_DEVICE_TABLE(mdio, adin_tbl);
0997 MODULE_DESCRIPTION("Analog Devices Industrial Ethernet PHY driver");
0998 MODULE_LICENSE("GPL");