Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
0002 /*
0003  * Driver for Microsemi VSC85xx PHYs
0004  *
0005  * Author: Nagaraju Lakkaraju
0006  * License: Dual MIT/GPL
0007  * Copyright (c) 2016 Microsemi Corporation
0008  */
0009 
0010 #include <linux/firmware.h>
0011 #include <linux/jiffies.h>
0012 #include <linux/kernel.h>
0013 #include <linux/module.h>
0014 #include <linux/mdio.h>
0015 #include <linux/mii.h>
0016 #include <linux/phy.h>
0017 #include <linux/of.h>
0018 #include <linux/netdevice.h>
0019 #include <dt-bindings/net/mscc-phy-vsc8531.h>
0020 #include "mscc_serdes.h"
0021 #include "mscc.h"
0022 
0023 static const struct vsc85xx_hw_stat vsc85xx_hw_stats[] = {
0024     {
0025         .string = "phy_receive_errors",
0026         .reg    = MSCC_PHY_ERR_RX_CNT,
0027         .page   = MSCC_PHY_PAGE_STANDARD,
0028         .mask   = ERR_CNT_MASK,
0029     }, {
0030         .string = "phy_false_carrier",
0031         .reg    = MSCC_PHY_ERR_FALSE_CARRIER_CNT,
0032         .page   = MSCC_PHY_PAGE_STANDARD,
0033         .mask   = ERR_CNT_MASK,
0034     }, {
0035         .string = "phy_cu_media_link_disconnect",
0036         .reg    = MSCC_PHY_ERR_LINK_DISCONNECT_CNT,
0037         .page   = MSCC_PHY_PAGE_STANDARD,
0038         .mask   = ERR_CNT_MASK,
0039     }, {
0040         .string = "phy_cu_media_crc_good_count",
0041         .reg    = MSCC_PHY_CU_MEDIA_CRC_VALID_CNT,
0042         .page   = MSCC_PHY_PAGE_EXTENDED,
0043         .mask   = VALID_CRC_CNT_CRC_MASK,
0044     }, {
0045         .string = "phy_cu_media_crc_error_count",
0046         .reg    = MSCC_PHY_EXT_PHY_CNTL_4,
0047         .page   = MSCC_PHY_PAGE_EXTENDED,
0048         .mask   = ERR_CNT_MASK,
0049     },
0050 };
0051 
0052 static const struct vsc85xx_hw_stat vsc8584_hw_stats[] = {
0053     {
0054         .string = "phy_receive_errors",
0055         .reg    = MSCC_PHY_ERR_RX_CNT,
0056         .page   = MSCC_PHY_PAGE_STANDARD,
0057         .mask   = ERR_CNT_MASK,
0058     }, {
0059         .string = "phy_false_carrier",
0060         .reg    = MSCC_PHY_ERR_FALSE_CARRIER_CNT,
0061         .page   = MSCC_PHY_PAGE_STANDARD,
0062         .mask   = ERR_CNT_MASK,
0063     }, {
0064         .string = "phy_cu_media_link_disconnect",
0065         .reg    = MSCC_PHY_ERR_LINK_DISCONNECT_CNT,
0066         .page   = MSCC_PHY_PAGE_STANDARD,
0067         .mask   = ERR_CNT_MASK,
0068     }, {
0069         .string = "phy_cu_media_crc_good_count",
0070         .reg    = MSCC_PHY_CU_MEDIA_CRC_VALID_CNT,
0071         .page   = MSCC_PHY_PAGE_EXTENDED,
0072         .mask   = VALID_CRC_CNT_CRC_MASK,
0073     }, {
0074         .string = "phy_cu_media_crc_error_count",
0075         .reg    = MSCC_PHY_EXT_PHY_CNTL_4,
0076         .page   = MSCC_PHY_PAGE_EXTENDED,
0077         .mask   = ERR_CNT_MASK,
0078     }, {
0079         .string = "phy_serdes_tx_good_pkt_count",
0080         .reg    = MSCC_PHY_SERDES_TX_VALID_CNT,
0081         .page   = MSCC_PHY_PAGE_EXTENDED_3,
0082         .mask   = VALID_CRC_CNT_CRC_MASK,
0083     }, {
0084         .string = "phy_serdes_tx_bad_crc_count",
0085         .reg    = MSCC_PHY_SERDES_TX_CRC_ERR_CNT,
0086         .page   = MSCC_PHY_PAGE_EXTENDED_3,
0087         .mask   = ERR_CNT_MASK,
0088     }, {
0089         .string = "phy_serdes_rx_good_pkt_count",
0090         .reg    = MSCC_PHY_SERDES_RX_VALID_CNT,
0091         .page   = MSCC_PHY_PAGE_EXTENDED_3,
0092         .mask   = VALID_CRC_CNT_CRC_MASK,
0093     }, {
0094         .string = "phy_serdes_rx_bad_crc_count",
0095         .reg    = MSCC_PHY_SERDES_RX_CRC_ERR_CNT,
0096         .page   = MSCC_PHY_PAGE_EXTENDED_3,
0097         .mask   = ERR_CNT_MASK,
0098     },
0099 };
0100 
0101 #if IS_ENABLED(CONFIG_OF_MDIO)
0102 static const struct vsc8531_edge_rate_table edge_table[] = {
0103     {MSCC_VDDMAC_3300, { 0, 2,  4,  7, 10, 17, 29, 53} },
0104     {MSCC_VDDMAC_2500, { 0, 3,  6, 10, 14, 23, 37, 63} },
0105     {MSCC_VDDMAC_1800, { 0, 5,  9, 16, 23, 35, 52, 76} },
0106     {MSCC_VDDMAC_1500, { 0, 6, 14, 21, 29, 42, 58, 77} },
0107 };
0108 #endif
0109 
0110 static int vsc85xx_phy_read_page(struct phy_device *phydev)
0111 {
0112     return __phy_read(phydev, MSCC_EXT_PAGE_ACCESS);
0113 }
0114 
0115 static int vsc85xx_phy_write_page(struct phy_device *phydev, int page)
0116 {
0117     return __phy_write(phydev, MSCC_EXT_PAGE_ACCESS, page);
0118 }
0119 
0120 static int vsc85xx_get_sset_count(struct phy_device *phydev)
0121 {
0122     struct vsc8531_private *priv = phydev->priv;
0123 
0124     if (!priv)
0125         return 0;
0126 
0127     return priv->nstats;
0128 }
0129 
0130 static void vsc85xx_get_strings(struct phy_device *phydev, u8 *data)
0131 {
0132     struct vsc8531_private *priv = phydev->priv;
0133     int i;
0134 
0135     if (!priv)
0136         return;
0137 
0138     for (i = 0; i < priv->nstats; i++)
0139         strlcpy(data + i * ETH_GSTRING_LEN, priv->hw_stats[i].string,
0140             ETH_GSTRING_LEN);
0141 }
0142 
0143 static u64 vsc85xx_get_stat(struct phy_device *phydev, int i)
0144 {
0145     struct vsc8531_private *priv = phydev->priv;
0146     int val;
0147 
0148     val = phy_read_paged(phydev, priv->hw_stats[i].page,
0149                  priv->hw_stats[i].reg);
0150     if (val < 0)
0151         return U64_MAX;
0152 
0153     val = val & priv->hw_stats[i].mask;
0154     priv->stats[i] += val;
0155 
0156     return priv->stats[i];
0157 }
0158 
0159 static void vsc85xx_get_stats(struct phy_device *phydev,
0160                   struct ethtool_stats *stats, u64 *data)
0161 {
0162     struct vsc8531_private *priv = phydev->priv;
0163     int i;
0164 
0165     if (!priv)
0166         return;
0167 
0168     for (i = 0; i < priv->nstats; i++)
0169         data[i] = vsc85xx_get_stat(phydev, i);
0170 }
0171 
0172 static int vsc85xx_led_cntl_set(struct phy_device *phydev,
0173                 u8 led_num,
0174                 u8 mode)
0175 {
0176     int rc;
0177     u16 reg_val;
0178 
0179     mutex_lock(&phydev->lock);
0180     reg_val = phy_read(phydev, MSCC_PHY_LED_MODE_SEL);
0181     reg_val &= ~LED_MODE_SEL_MASK(led_num);
0182     reg_val |= LED_MODE_SEL(led_num, (u16)mode);
0183     rc = phy_write(phydev, MSCC_PHY_LED_MODE_SEL, reg_val);
0184     mutex_unlock(&phydev->lock);
0185 
0186     return rc;
0187 }
0188 
0189 static int vsc85xx_mdix_get(struct phy_device *phydev, u8 *mdix)
0190 {
0191     u16 reg_val;
0192 
0193     reg_val = phy_read(phydev, MSCC_PHY_DEV_AUX_CNTL);
0194     if (reg_val & HP_AUTO_MDIX_X_OVER_IND_MASK)
0195         *mdix = ETH_TP_MDI_X;
0196     else
0197         *mdix = ETH_TP_MDI;
0198 
0199     return 0;
0200 }
0201 
0202 static int vsc85xx_mdix_set(struct phy_device *phydev, u8 mdix)
0203 {
0204     int rc;
0205     u16 reg_val;
0206 
0207     reg_val = phy_read(phydev, MSCC_PHY_BYPASS_CONTROL);
0208     if (mdix == ETH_TP_MDI || mdix == ETH_TP_MDI_X) {
0209         reg_val |= (DISABLE_PAIR_SWAP_CORR_MASK |
0210                 DISABLE_POLARITY_CORR_MASK  |
0211                 DISABLE_HP_AUTO_MDIX_MASK);
0212     } else {
0213         reg_val &= ~(DISABLE_PAIR_SWAP_CORR_MASK |
0214                  DISABLE_POLARITY_CORR_MASK  |
0215                  DISABLE_HP_AUTO_MDIX_MASK);
0216     }
0217     rc = phy_write(phydev, MSCC_PHY_BYPASS_CONTROL, reg_val);
0218     if (rc)
0219         return rc;
0220 
0221     reg_val = 0;
0222 
0223     if (mdix == ETH_TP_MDI)
0224         reg_val = FORCE_MDI_CROSSOVER_MDI;
0225     else if (mdix == ETH_TP_MDI_X)
0226         reg_val = FORCE_MDI_CROSSOVER_MDIX;
0227 
0228     rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED,
0229                   MSCC_PHY_EXT_MODE_CNTL, FORCE_MDI_CROSSOVER_MASK,
0230                   reg_val);
0231     if (rc < 0)
0232         return rc;
0233 
0234     return genphy_restart_aneg(phydev);
0235 }
0236 
0237 static int vsc85xx_downshift_get(struct phy_device *phydev, u8 *count)
0238 {
0239     int reg_val;
0240 
0241     reg_val = phy_read_paged(phydev, MSCC_PHY_PAGE_EXTENDED,
0242                  MSCC_PHY_ACTIPHY_CNTL);
0243     if (reg_val < 0)
0244         return reg_val;
0245 
0246     reg_val &= DOWNSHIFT_CNTL_MASK;
0247     if (!(reg_val & DOWNSHIFT_EN))
0248         *count = DOWNSHIFT_DEV_DISABLE;
0249     else
0250         *count = ((reg_val & ~DOWNSHIFT_EN) >> DOWNSHIFT_CNTL_POS) + 2;
0251 
0252     return 0;
0253 }
0254 
0255 static int vsc85xx_downshift_set(struct phy_device *phydev, u8 count)
0256 {
0257     if (count == DOWNSHIFT_DEV_DEFAULT_COUNT) {
0258         /* Default downshift count 3 (i.e. Bit3:2 = 0b01) */
0259         count = ((1 << DOWNSHIFT_CNTL_POS) | DOWNSHIFT_EN);
0260     } else if (count > DOWNSHIFT_COUNT_MAX || count == 1) {
0261         phydev_err(phydev, "Downshift count should be 2,3,4 or 5\n");
0262         return -ERANGE;
0263     } else if (count) {
0264         /* Downshift count is either 2,3,4 or 5 */
0265         count = (((count - 2) << DOWNSHIFT_CNTL_POS) | DOWNSHIFT_EN);
0266     }
0267 
0268     return phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED,
0269                 MSCC_PHY_ACTIPHY_CNTL, DOWNSHIFT_CNTL_MASK,
0270                 count);
0271 }
0272 
0273 static int vsc85xx_wol_set(struct phy_device *phydev,
0274                struct ethtool_wolinfo *wol)
0275 {
0276     const u8 *mac_addr = phydev->attached_dev->dev_addr;
0277     int rc;
0278     u16 reg_val;
0279     u8  i;
0280     u16 pwd[3] = {0, 0, 0};
0281     struct ethtool_wolinfo *wol_conf = wol;
0282 
0283     mutex_lock(&phydev->lock);
0284     rc = phy_select_page(phydev, MSCC_PHY_PAGE_EXTENDED_2);
0285     if (rc < 0) {
0286         rc = phy_restore_page(phydev, rc, rc);
0287         goto out_unlock;
0288     }
0289 
0290     if (wol->wolopts & WAKE_MAGIC) {
0291         /* Store the device address for the magic packet */
0292         for (i = 0; i < ARRAY_SIZE(pwd); i++)
0293             pwd[i] = mac_addr[5 - (i * 2 + 1)] << 8 |
0294                  mac_addr[5 - i * 2];
0295         __phy_write(phydev, MSCC_PHY_WOL_LOWER_MAC_ADDR, pwd[0]);
0296         __phy_write(phydev, MSCC_PHY_WOL_MID_MAC_ADDR, pwd[1]);
0297         __phy_write(phydev, MSCC_PHY_WOL_UPPER_MAC_ADDR, pwd[2]);
0298     } else {
0299         __phy_write(phydev, MSCC_PHY_WOL_LOWER_MAC_ADDR, 0);
0300         __phy_write(phydev, MSCC_PHY_WOL_MID_MAC_ADDR, 0);
0301         __phy_write(phydev, MSCC_PHY_WOL_UPPER_MAC_ADDR, 0);
0302     }
0303 
0304     if (wol_conf->wolopts & WAKE_MAGICSECURE) {
0305         for (i = 0; i < ARRAY_SIZE(pwd); i++)
0306             pwd[i] = wol_conf->sopass[5 - (i * 2 + 1)] << 8 |
0307                  wol_conf->sopass[5 - i * 2];
0308         __phy_write(phydev, MSCC_PHY_WOL_LOWER_PASSWD, pwd[0]);
0309         __phy_write(phydev, MSCC_PHY_WOL_MID_PASSWD, pwd[1]);
0310         __phy_write(phydev, MSCC_PHY_WOL_UPPER_PASSWD, pwd[2]);
0311     } else {
0312         __phy_write(phydev, MSCC_PHY_WOL_LOWER_PASSWD, 0);
0313         __phy_write(phydev, MSCC_PHY_WOL_MID_PASSWD, 0);
0314         __phy_write(phydev, MSCC_PHY_WOL_UPPER_PASSWD, 0);
0315     }
0316 
0317     reg_val = __phy_read(phydev, MSCC_PHY_WOL_MAC_CONTROL);
0318     if (wol_conf->wolopts & WAKE_MAGICSECURE)
0319         reg_val |= SECURE_ON_ENABLE;
0320     else
0321         reg_val &= ~SECURE_ON_ENABLE;
0322     __phy_write(phydev, MSCC_PHY_WOL_MAC_CONTROL, reg_val);
0323 
0324     rc = phy_restore_page(phydev, rc, rc > 0 ? 0 : rc);
0325     if (rc < 0)
0326         goto out_unlock;
0327 
0328     if (wol->wolopts & WAKE_MAGIC) {
0329         /* Enable the WOL interrupt */
0330         reg_val = phy_read(phydev, MII_VSC85XX_INT_MASK);
0331         reg_val |= MII_VSC85XX_INT_MASK_WOL;
0332         rc = phy_write(phydev, MII_VSC85XX_INT_MASK, reg_val);
0333         if (rc)
0334             goto out_unlock;
0335     } else {
0336         /* Disable the WOL interrupt */
0337         reg_val = phy_read(phydev, MII_VSC85XX_INT_MASK);
0338         reg_val &= (~MII_VSC85XX_INT_MASK_WOL);
0339         rc = phy_write(phydev, MII_VSC85XX_INT_MASK, reg_val);
0340         if (rc)
0341             goto out_unlock;
0342     }
0343     /* Clear WOL iterrupt status */
0344     reg_val = phy_read(phydev, MII_VSC85XX_INT_STATUS);
0345 
0346 out_unlock:
0347     mutex_unlock(&phydev->lock);
0348 
0349     return rc;
0350 }
0351 
0352 static void vsc85xx_wol_get(struct phy_device *phydev,
0353                 struct ethtool_wolinfo *wol)
0354 {
0355     int rc;
0356     u16 reg_val;
0357     u8  i;
0358     u16 pwd[3] = {0, 0, 0};
0359     struct ethtool_wolinfo *wol_conf = wol;
0360 
0361     mutex_lock(&phydev->lock);
0362     rc = phy_select_page(phydev, MSCC_PHY_PAGE_EXTENDED_2);
0363     if (rc < 0)
0364         goto out_unlock;
0365 
0366     reg_val = __phy_read(phydev, MSCC_PHY_WOL_MAC_CONTROL);
0367     if (reg_val & SECURE_ON_ENABLE)
0368         wol_conf->wolopts |= WAKE_MAGICSECURE;
0369     if (wol_conf->wolopts & WAKE_MAGICSECURE) {
0370         pwd[0] = __phy_read(phydev, MSCC_PHY_WOL_LOWER_PASSWD);
0371         pwd[1] = __phy_read(phydev, MSCC_PHY_WOL_MID_PASSWD);
0372         pwd[2] = __phy_read(phydev, MSCC_PHY_WOL_UPPER_PASSWD);
0373         for (i = 0; i < ARRAY_SIZE(pwd); i++) {
0374             wol_conf->sopass[5 - i * 2] = pwd[i] & 0x00ff;
0375             wol_conf->sopass[5 - (i * 2 + 1)] = (pwd[i] & 0xff00)
0376                                 >> 8;
0377         }
0378     }
0379 
0380 out_unlock:
0381     phy_restore_page(phydev, rc, rc > 0 ? 0 : rc);
0382     mutex_unlock(&phydev->lock);
0383 }
0384 
0385 #if IS_ENABLED(CONFIG_OF_MDIO)
0386 static int vsc85xx_edge_rate_magic_get(struct phy_device *phydev)
0387 {
0388     u32 vdd, sd;
0389     int i, j;
0390     struct device *dev = &phydev->mdio.dev;
0391     struct device_node *of_node = dev->of_node;
0392     u8 sd_array_size = ARRAY_SIZE(edge_table[0].slowdown);
0393 
0394     if (!of_node)
0395         return -ENODEV;
0396 
0397     if (of_property_read_u32(of_node, "vsc8531,vddmac", &vdd))
0398         vdd = MSCC_VDDMAC_3300;
0399 
0400     if (of_property_read_u32(of_node, "vsc8531,edge-slowdown", &sd))
0401         sd = 0;
0402 
0403     for (i = 0; i < ARRAY_SIZE(edge_table); i++)
0404         if (edge_table[i].vddmac == vdd)
0405             for (j = 0; j < sd_array_size; j++)
0406                 if (edge_table[i].slowdown[j] == sd)
0407                     return (sd_array_size - j - 1);
0408 
0409     return -EINVAL;
0410 }
0411 
0412 static int vsc85xx_dt_led_mode_get(struct phy_device *phydev,
0413                    char *led,
0414                    u32 default_mode)
0415 {
0416     struct vsc8531_private *priv = phydev->priv;
0417     struct device *dev = &phydev->mdio.dev;
0418     struct device_node *of_node = dev->of_node;
0419     u32 led_mode;
0420     int err;
0421 
0422     if (!of_node)
0423         return -ENODEV;
0424 
0425     led_mode = default_mode;
0426     err = of_property_read_u32(of_node, led, &led_mode);
0427     if (!err && !(BIT(led_mode) & priv->supp_led_modes)) {
0428         phydev_err(phydev, "DT %s invalid\n", led);
0429         return -EINVAL;
0430     }
0431 
0432     return led_mode;
0433 }
0434 
0435 #else
0436 static int vsc85xx_edge_rate_magic_get(struct phy_device *phydev)
0437 {
0438     return 0;
0439 }
0440 
0441 static int vsc85xx_dt_led_mode_get(struct phy_device *phydev,
0442                    char *led,
0443                    u8 default_mode)
0444 {
0445     return default_mode;
0446 }
0447 #endif /* CONFIG_OF_MDIO */
0448 
0449 static int vsc85xx_dt_led_modes_get(struct phy_device *phydev,
0450                     u32 *default_mode)
0451 {
0452     struct vsc8531_private *priv = phydev->priv;
0453     char led_dt_prop[28];
0454     int i, ret;
0455 
0456     for (i = 0; i < priv->nleds; i++) {
0457         ret = sprintf(led_dt_prop, "vsc8531,led-%d-mode", i);
0458         if (ret < 0)
0459             return ret;
0460 
0461         ret = vsc85xx_dt_led_mode_get(phydev, led_dt_prop,
0462                           default_mode[i]);
0463         if (ret < 0)
0464             return ret;
0465         priv->leds_mode[i] = ret;
0466     }
0467 
0468     return 0;
0469 }
0470 
0471 static int vsc85xx_edge_rate_cntl_set(struct phy_device *phydev, u8 edge_rate)
0472 {
0473     int rc;
0474 
0475     mutex_lock(&phydev->lock);
0476     rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2,
0477                   MSCC_PHY_WOL_MAC_CONTROL, EDGE_RATE_CNTL_MASK,
0478                   edge_rate << EDGE_RATE_CNTL_POS);
0479     mutex_unlock(&phydev->lock);
0480 
0481     return rc;
0482 }
0483 
0484 static int vsc85xx_mac_if_set(struct phy_device *phydev,
0485                   phy_interface_t interface)
0486 {
0487     int rc;
0488     u16 reg_val;
0489 
0490     mutex_lock(&phydev->lock);
0491     reg_val = phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_1);
0492     reg_val &= ~(MAC_IF_SELECTION_MASK);
0493     switch (interface) {
0494     case PHY_INTERFACE_MODE_RGMII_TXID:
0495     case PHY_INTERFACE_MODE_RGMII_RXID:
0496     case PHY_INTERFACE_MODE_RGMII_ID:
0497     case PHY_INTERFACE_MODE_RGMII:
0498         reg_val |= (MAC_IF_SELECTION_RGMII << MAC_IF_SELECTION_POS);
0499         break;
0500     case PHY_INTERFACE_MODE_RMII:
0501         reg_val |= (MAC_IF_SELECTION_RMII << MAC_IF_SELECTION_POS);
0502         break;
0503     case PHY_INTERFACE_MODE_MII:
0504     case PHY_INTERFACE_MODE_GMII:
0505         reg_val |= (MAC_IF_SELECTION_GMII << MAC_IF_SELECTION_POS);
0506         break;
0507     default:
0508         rc = -EINVAL;
0509         goto out_unlock;
0510     }
0511     rc = phy_write(phydev, MSCC_PHY_EXT_PHY_CNTL_1, reg_val);
0512     if (rc)
0513         goto out_unlock;
0514 
0515     rc = genphy_soft_reset(phydev);
0516 
0517 out_unlock:
0518     mutex_unlock(&phydev->lock);
0519 
0520     return rc;
0521 }
0522 
0523 /* Set the RGMII RX and TX clock skews individually, according to the PHY
0524  * interface type, to:
0525  *  * 0.2 ns (their default, and lowest, hardware value) if delays should
0526  *    not be enabled
0527  *  * 2.0 ns (which causes the data to be sampled at exactly half way between
0528  *    clock transitions at 1000 Mbps) if delays should be enabled
0529  */
0530 static int vsc85xx_rgmii_set_skews(struct phy_device *phydev, u32 rgmii_cntl,
0531                    u16 rgmii_rx_delay_mask,
0532                    u16 rgmii_tx_delay_mask)
0533 {
0534     u16 rgmii_rx_delay_pos = ffs(rgmii_rx_delay_mask) - 1;
0535     u16 rgmii_tx_delay_pos = ffs(rgmii_tx_delay_mask) - 1;
0536     u16 reg_val = 0;
0537     int rc;
0538 
0539     mutex_lock(&phydev->lock);
0540 
0541     if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID ||
0542         phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
0543         reg_val |= RGMII_CLK_DELAY_2_0_NS << rgmii_rx_delay_pos;
0544     if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID ||
0545         phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
0546         reg_val |= RGMII_CLK_DELAY_2_0_NS << rgmii_tx_delay_pos;
0547 
0548     rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2,
0549                   rgmii_cntl,
0550                   rgmii_rx_delay_mask | rgmii_tx_delay_mask,
0551                   reg_val);
0552 
0553     mutex_unlock(&phydev->lock);
0554 
0555     return rc;
0556 }
0557 
0558 static int vsc85xx_default_config(struct phy_device *phydev)
0559 {
0560     int rc;
0561 
0562     phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
0563 
0564     if (phy_interface_mode_is_rgmii(phydev->interface)) {
0565         rc = vsc85xx_rgmii_set_skews(phydev, VSC8502_RGMII_CNTL,
0566                          VSC8502_RGMII_RX_DELAY_MASK,
0567                          VSC8502_RGMII_TX_DELAY_MASK);
0568         if (rc)
0569             return rc;
0570     }
0571 
0572     return 0;
0573 }
0574 
0575 static int vsc85xx_get_tunable(struct phy_device *phydev,
0576                    struct ethtool_tunable *tuna, void *data)
0577 {
0578     switch (tuna->id) {
0579     case ETHTOOL_PHY_DOWNSHIFT:
0580         return vsc85xx_downshift_get(phydev, (u8 *)data);
0581     default:
0582         return -EINVAL;
0583     }
0584 }
0585 
0586 static int vsc85xx_set_tunable(struct phy_device *phydev,
0587                    struct ethtool_tunable *tuna,
0588                    const void *data)
0589 {
0590     switch (tuna->id) {
0591     case ETHTOOL_PHY_DOWNSHIFT:
0592         return vsc85xx_downshift_set(phydev, *(u8 *)data);
0593     default:
0594         return -EINVAL;
0595     }
0596 }
0597 
0598 /* mdiobus lock should be locked when using this function */
0599 static void vsc85xx_tr_write(struct phy_device *phydev, u16 addr, u32 val)
0600 {
0601     __phy_write(phydev, MSCC_PHY_TR_MSB, val >> 16);
0602     __phy_write(phydev, MSCC_PHY_TR_LSB, val & GENMASK(15, 0));
0603     __phy_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(addr));
0604 }
0605 
0606 static int vsc8531_pre_init_seq_set(struct phy_device *phydev)
0607 {
0608     int rc;
0609     static const struct reg_val init_seq[] = {
0610         {0x0f90, 0x00688980},
0611         {0x0696, 0x00000003},
0612         {0x07fa, 0x0050100f},
0613         {0x1686, 0x00000004},
0614     };
0615     unsigned int i;
0616     int oldpage;
0617 
0618     rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_STANDARD,
0619                   MSCC_PHY_EXT_CNTL_STATUS, SMI_BROADCAST_WR_EN,
0620                   SMI_BROADCAST_WR_EN);
0621     if (rc < 0)
0622         return rc;
0623     rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_TEST,
0624                   MSCC_PHY_TEST_PAGE_24, 0, 0x0400);
0625     if (rc < 0)
0626         return rc;
0627     rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_TEST,
0628                   MSCC_PHY_TEST_PAGE_5, 0x0a00, 0x0e00);
0629     if (rc < 0)
0630         return rc;
0631     rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_TEST,
0632                   MSCC_PHY_TEST_PAGE_8, TR_CLK_DISABLE, TR_CLK_DISABLE);
0633     if (rc < 0)
0634         return rc;
0635 
0636     mutex_lock(&phydev->lock);
0637     oldpage = phy_select_page(phydev, MSCC_PHY_PAGE_TR);
0638     if (oldpage < 0)
0639         goto out_unlock;
0640 
0641     for (i = 0; i < ARRAY_SIZE(init_seq); i++)
0642         vsc85xx_tr_write(phydev, init_seq[i].reg, init_seq[i].val);
0643 
0644 out_unlock:
0645     oldpage = phy_restore_page(phydev, oldpage, oldpage);
0646     mutex_unlock(&phydev->lock);
0647 
0648     return oldpage;
0649 }
0650 
0651 static int vsc85xx_eee_init_seq_set(struct phy_device *phydev)
0652 {
0653     static const struct reg_val init_eee[] = {
0654         {0x0f82, 0x0012b00a},
0655         {0x1686, 0x00000004},
0656         {0x168c, 0x00d2c46f},
0657         {0x17a2, 0x00000620},
0658         {0x16a0, 0x00eeffdd},
0659         {0x16a6, 0x00071448},
0660         {0x16a4, 0x0013132f},
0661         {0x16a8, 0x00000000},
0662         {0x0ffc, 0x00c0a028},
0663         {0x0fe8, 0x0091b06c},
0664         {0x0fea, 0x00041600},
0665         {0x0f80, 0x00000af4},
0666         {0x0fec, 0x00901809},
0667         {0x0fee, 0x0000a6a1},
0668         {0x0ffe, 0x00b01007},
0669         {0x16b0, 0x00eeff00},
0670         {0x16b2, 0x00007000},
0671         {0x16b4, 0x00000814},
0672     };
0673     unsigned int i;
0674     int oldpage;
0675 
0676     mutex_lock(&phydev->lock);
0677     oldpage = phy_select_page(phydev, MSCC_PHY_PAGE_TR);
0678     if (oldpage < 0)
0679         goto out_unlock;
0680 
0681     for (i = 0; i < ARRAY_SIZE(init_eee); i++)
0682         vsc85xx_tr_write(phydev, init_eee[i].reg, init_eee[i].val);
0683 
0684 out_unlock:
0685     oldpage = phy_restore_page(phydev, oldpage, oldpage);
0686     mutex_unlock(&phydev->lock);
0687 
0688     return oldpage;
0689 }
0690 
0691 /* phydev->bus->mdio_lock should be locked when using this function */
0692 int phy_base_write(struct phy_device *phydev, u32 regnum, u16 val)
0693 {
0694     if (unlikely(!mutex_is_locked(&phydev->mdio.bus->mdio_lock))) {
0695         dev_err(&phydev->mdio.dev, "MDIO bus lock not held!\n");
0696         dump_stack();
0697     }
0698 
0699     return __phy_package_write(phydev, regnum, val);
0700 }
0701 
0702 /* phydev->bus->mdio_lock should be locked when using this function */
0703 int phy_base_read(struct phy_device *phydev, u32 regnum)
0704 {
0705     if (unlikely(!mutex_is_locked(&phydev->mdio.bus->mdio_lock))) {
0706         dev_err(&phydev->mdio.dev, "MDIO bus lock not held!\n");
0707         dump_stack();
0708     }
0709 
0710     return __phy_package_read(phydev, regnum);
0711 }
0712 
0713 u32 vsc85xx_csr_read(struct phy_device *phydev,
0714              enum csr_target target, u32 reg)
0715 {
0716     unsigned long deadline;
0717     u32 val, val_l, val_h;
0718 
0719     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_CSR_CNTL);
0720 
0721     /* CSR registers are grouped under different Target IDs.
0722      * 6-bit Target_ID is split between MSCC_EXT_PAGE_CSR_CNTL_20 and
0723      * MSCC_EXT_PAGE_CSR_CNTL_19 registers.
0724      * Target_ID[5:2] maps to bits[3:0] of MSCC_EXT_PAGE_CSR_CNTL_20
0725      * and Target_ID[1:0] maps to bits[13:12] of MSCC_EXT_PAGE_CSR_CNTL_19.
0726      */
0727 
0728     /* Setup the Target ID */
0729     phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_20,
0730                MSCC_PHY_CSR_CNTL_20_TARGET(target >> 2));
0731 
0732     if ((target >> 2 == 0x1) || (target >> 2 == 0x3))
0733         /* non-MACsec access */
0734         target &= 0x3;
0735     else
0736         target = 0;
0737 
0738     /* Trigger CSR Action - Read into the CSR's */
0739     phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_19,
0740                MSCC_PHY_CSR_CNTL_19_CMD | MSCC_PHY_CSR_CNTL_19_READ |
0741                MSCC_PHY_CSR_CNTL_19_REG_ADDR(reg) |
0742                MSCC_PHY_CSR_CNTL_19_TARGET(target));
0743 
0744     /* Wait for register access*/
0745     deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
0746     do {
0747         usleep_range(500, 1000);
0748         val = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_19);
0749     } while (time_before(jiffies, deadline) &&
0750         !(val & MSCC_PHY_CSR_CNTL_19_CMD));
0751 
0752     if (!(val & MSCC_PHY_CSR_CNTL_19_CMD))
0753         return 0xffffffff;
0754 
0755     /* Read the Least Significant Word (LSW) (17) */
0756     val_l = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_17);
0757 
0758     /* Read the Most Significant Word (MSW) (18) */
0759     val_h = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_18);
0760 
0761     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
0762                MSCC_PHY_PAGE_STANDARD);
0763 
0764     return (val_h << 16) | val_l;
0765 }
0766 
0767 int vsc85xx_csr_write(struct phy_device *phydev,
0768               enum csr_target target, u32 reg, u32 val)
0769 {
0770     unsigned long deadline;
0771 
0772     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_CSR_CNTL);
0773 
0774     /* CSR registers are grouped under different Target IDs.
0775      * 6-bit Target_ID is split between MSCC_EXT_PAGE_CSR_CNTL_20 and
0776      * MSCC_EXT_PAGE_CSR_CNTL_19 registers.
0777      * Target_ID[5:2] maps to bits[3:0] of MSCC_EXT_PAGE_CSR_CNTL_20
0778      * and Target_ID[1:0] maps to bits[13:12] of MSCC_EXT_PAGE_CSR_CNTL_19.
0779      */
0780 
0781     /* Setup the Target ID */
0782     phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_20,
0783                MSCC_PHY_CSR_CNTL_20_TARGET(target >> 2));
0784 
0785     /* Write the Least Significant Word (LSW) (17) */
0786     phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_17, (u16)val);
0787 
0788     /* Write the Most Significant Word (MSW) (18) */
0789     phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_18, (u16)(val >> 16));
0790 
0791     if ((target >> 2 == 0x1) || (target >> 2 == 0x3))
0792         /* non-MACsec access */
0793         target &= 0x3;
0794     else
0795         target = 0;
0796 
0797     /* Trigger CSR Action - Write into the CSR's */
0798     phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_19,
0799                MSCC_PHY_CSR_CNTL_19_CMD |
0800                MSCC_PHY_CSR_CNTL_19_REG_ADDR(reg) |
0801                MSCC_PHY_CSR_CNTL_19_TARGET(target));
0802 
0803     /* Wait for register access */
0804     deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
0805     do {
0806         usleep_range(500, 1000);
0807         val = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_19);
0808     } while (time_before(jiffies, deadline) &&
0809          !(val & MSCC_PHY_CSR_CNTL_19_CMD));
0810 
0811     if (!(val & MSCC_PHY_CSR_CNTL_19_CMD))
0812         return -ETIMEDOUT;
0813 
0814     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
0815                MSCC_PHY_PAGE_STANDARD);
0816 
0817     return 0;
0818 }
0819 
0820 /* bus->mdio_lock should be locked when using this function */
0821 static void vsc8584_csr_write(struct phy_device *phydev, u16 addr, u32 val)
0822 {
0823     phy_base_write(phydev, MSCC_PHY_TR_MSB, val >> 16);
0824     phy_base_write(phydev, MSCC_PHY_TR_LSB, val & GENMASK(15, 0));
0825     phy_base_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(addr));
0826 }
0827 
0828 /* bus->mdio_lock should be locked when using this function */
0829 int vsc8584_cmd(struct phy_device *phydev, u16 val)
0830 {
0831     unsigned long deadline;
0832     u16 reg_val;
0833 
0834     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
0835                MSCC_PHY_PAGE_EXTENDED_GPIO);
0836 
0837     phy_base_write(phydev, MSCC_PHY_PROC_CMD, PROC_CMD_NCOMPLETED | val);
0838 
0839     deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
0840     do {
0841         reg_val = phy_base_read(phydev, MSCC_PHY_PROC_CMD);
0842     } while (time_before(jiffies, deadline) &&
0843          (reg_val & PROC_CMD_NCOMPLETED) &&
0844          !(reg_val & PROC_CMD_FAILED));
0845 
0846     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
0847 
0848     if (reg_val & PROC_CMD_FAILED)
0849         return -EIO;
0850 
0851     if (reg_val & PROC_CMD_NCOMPLETED)
0852         return -ETIMEDOUT;
0853 
0854     return 0;
0855 }
0856 
0857 /* bus->mdio_lock should be locked when using this function */
0858 static int vsc8584_micro_deassert_reset(struct phy_device *phydev,
0859                     bool patch_en)
0860 {
0861     u32 enable, release;
0862 
0863     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
0864                MSCC_PHY_PAGE_EXTENDED_GPIO);
0865 
0866     enable = RUN_FROM_INT_ROM | MICRO_CLK_EN | DW8051_CLK_EN;
0867     release = MICRO_NSOFT_RESET | RUN_FROM_INT_ROM | DW8051_CLK_EN |
0868         MICRO_CLK_EN;
0869 
0870     if (patch_en) {
0871         enable |= MICRO_PATCH_EN;
0872         release |= MICRO_PATCH_EN;
0873 
0874         /* Clear all patches */
0875         phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_RAM);
0876     }
0877 
0878     /* Enable 8051 Micro clock; CLEAR/SET patch present; disable PRAM clock
0879      * override and addr. auto-incr; operate at 125 MHz
0880      */
0881     phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, enable);
0882     /* Release 8051 Micro SW reset */
0883     phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, release);
0884 
0885     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
0886 
0887     return 0;
0888 }
0889 
0890 /* bus->mdio_lock should be locked when using this function */
0891 static int vsc8584_micro_assert_reset(struct phy_device *phydev)
0892 {
0893     int ret;
0894     u16 reg;
0895 
0896     ret = vsc8584_cmd(phydev, PROC_CMD_NOP);
0897     if (ret)
0898         return ret;
0899 
0900     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
0901                MSCC_PHY_PAGE_EXTENDED_GPIO);
0902 
0903     reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
0904     reg &= ~EN_PATCH_RAM_TRAP_ADDR(4);
0905     phy_base_write(phydev, MSCC_INT_MEM_CNTL, reg);
0906 
0907     phy_base_write(phydev, MSCC_TRAP_ROM_ADDR(4), 0x005b);
0908     phy_base_write(phydev, MSCC_PATCH_RAM_ADDR(4), 0x005b);
0909 
0910     reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
0911     reg |= EN_PATCH_RAM_TRAP_ADDR(4);
0912     phy_base_write(phydev, MSCC_INT_MEM_CNTL, reg);
0913 
0914     phy_base_write(phydev, MSCC_PHY_PROC_CMD, PROC_CMD_NOP);
0915 
0916     reg = phy_base_read(phydev, MSCC_DW8051_CNTL_STATUS);
0917     reg &= ~MICRO_NSOFT_RESET;
0918     phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, reg);
0919 
0920     phy_base_write(phydev, MSCC_PHY_PROC_CMD, PROC_CMD_MCB_ACCESS_MAC_CONF |
0921                PROC_CMD_SGMII_PORT(0) | PROC_CMD_NO_MAC_CONF |
0922                PROC_CMD_READ);
0923 
0924     reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
0925     reg &= ~EN_PATCH_RAM_TRAP_ADDR(4);
0926     phy_base_write(phydev, MSCC_INT_MEM_CNTL, reg);
0927 
0928     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
0929 
0930     return 0;
0931 }
0932 
0933 /* bus->mdio_lock should be locked when using this function */
0934 static int vsc8584_get_fw_crc(struct phy_device *phydev, u16 start, u16 size,
0935                   u16 *crc)
0936 {
0937     int ret;
0938 
0939     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
0940 
0941     phy_base_write(phydev, MSCC_PHY_VERIPHY_CNTL_2, start);
0942     phy_base_write(phydev, MSCC_PHY_VERIPHY_CNTL_3, size);
0943 
0944     /* Start Micro command */
0945     ret = vsc8584_cmd(phydev, PROC_CMD_CRC16);
0946     if (ret)
0947         goto out;
0948 
0949     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
0950 
0951     *crc = phy_base_read(phydev, MSCC_PHY_VERIPHY_CNTL_2);
0952 
0953 out:
0954     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
0955 
0956     return ret;
0957 }
0958 
0959 /* bus->mdio_lock should be locked when using this function */
0960 static int vsc8584_patch_fw(struct phy_device *phydev,
0961                 const struct firmware *fw)
0962 {
0963     int i, ret;
0964 
0965     ret = vsc8584_micro_assert_reset(phydev);
0966     if (ret) {
0967         dev_err(&phydev->mdio.dev,
0968             "%s: failed to assert reset of micro\n", __func__);
0969         return ret;
0970     }
0971 
0972     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
0973                MSCC_PHY_PAGE_EXTENDED_GPIO);
0974 
0975     /* Hold 8051 Micro in SW Reset, Enable auto incr address and patch clock
0976      * Disable the 8051 Micro clock
0977      */
0978     phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, RUN_FROM_INT_ROM |
0979                AUTOINC_ADDR | PATCH_RAM_CLK | MICRO_CLK_EN |
0980                MICRO_CLK_DIVIDE(2));
0981     phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_PRAM | INT_MEM_WRITE_EN |
0982                INT_MEM_DATA(2));
0983     phy_base_write(phydev, MSCC_INT_MEM_ADDR, 0x0000);
0984 
0985     for (i = 0; i < fw->size; i++)
0986         phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_PRAM |
0987                    INT_MEM_WRITE_EN | fw->data[i]);
0988 
0989     /* Clear internal memory access */
0990     phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_RAM);
0991 
0992     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
0993 
0994     return 0;
0995 }
0996 
0997 /* bus->mdio_lock should be locked when using this function */
0998 static bool vsc8574_is_serdes_init(struct phy_device *phydev)
0999 {
1000     u16 reg;
1001     bool ret;
1002 
1003     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1004                MSCC_PHY_PAGE_EXTENDED_GPIO);
1005 
1006     reg = phy_base_read(phydev, MSCC_TRAP_ROM_ADDR(1));
1007     if (reg != 0x3eb7) {
1008         ret = false;
1009         goto out;
1010     }
1011 
1012     reg = phy_base_read(phydev, MSCC_PATCH_RAM_ADDR(1));
1013     if (reg != 0x4012) {
1014         ret = false;
1015         goto out;
1016     }
1017 
1018     reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
1019     if (reg != EN_PATCH_RAM_TRAP_ADDR(1)) {
1020         ret = false;
1021         goto out;
1022     }
1023 
1024     reg = phy_base_read(phydev, MSCC_DW8051_CNTL_STATUS);
1025     if ((MICRO_NSOFT_RESET | RUN_FROM_INT_ROM |  DW8051_CLK_EN |
1026          MICRO_CLK_EN) != (reg & MSCC_DW8051_VLD_MASK)) {
1027         ret = false;
1028         goto out;
1029     }
1030 
1031     ret = true;
1032 out:
1033     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1034 
1035     return ret;
1036 }
1037 
1038 /* bus->mdio_lock should be locked when using this function */
1039 static int vsc8574_config_pre_init(struct phy_device *phydev)
1040 {
1041     static const struct reg_val pre_init1[] = {
1042         {0x0fae, 0x000401bd},
1043         {0x0fac, 0x000f000f},
1044         {0x17a0, 0x00a0f147},
1045         {0x0fe4, 0x00052f54},
1046         {0x1792, 0x0027303d},
1047         {0x07fe, 0x00000704},
1048         {0x0fe0, 0x00060150},
1049         {0x0f82, 0x0012b00a},
1050         {0x0f80, 0x00000d74},
1051         {0x02e0, 0x00000012},
1052         {0x03a2, 0x00050208},
1053         {0x03b2, 0x00009186},
1054         {0x0fb0, 0x000e3700},
1055         {0x1688, 0x00049f81},
1056         {0x0fd2, 0x0000ffff},
1057         {0x168a, 0x00039fa2},
1058         {0x1690, 0x0020640b},
1059         {0x0258, 0x00002220},
1060         {0x025a, 0x00002a20},
1061         {0x025c, 0x00003060},
1062         {0x025e, 0x00003fa0},
1063         {0x03a6, 0x0000e0f0},
1064         {0x0f92, 0x00001489},
1065         {0x16a2, 0x00007000},
1066         {0x16a6, 0x00071448},
1067         {0x16a0, 0x00eeffdd},
1068         {0x0fe8, 0x0091b06c},
1069         {0x0fea, 0x00041600},
1070         {0x16b0, 0x00eeff00},
1071         {0x16b2, 0x00007000},
1072         {0x16b4, 0x00000814},
1073         {0x0f90, 0x00688980},
1074         {0x03a4, 0x0000d8f0},
1075         {0x0fc0, 0x00000400},
1076         {0x07fa, 0x0050100f},
1077         {0x0796, 0x00000003},
1078         {0x07f8, 0x00c3ff98},
1079         {0x0fa4, 0x0018292a},
1080         {0x168c, 0x00d2c46f},
1081         {0x17a2, 0x00000620},
1082         {0x16a4, 0x0013132f},
1083         {0x16a8, 0x00000000},
1084         {0x0ffc, 0x00c0a028},
1085         {0x0fec, 0x00901c09},
1086         {0x0fee, 0x0004a6a1},
1087         {0x0ffe, 0x00b01807},
1088     };
1089     static const struct reg_val pre_init2[] = {
1090         {0x0486, 0x0008a518},
1091         {0x0488, 0x006dc696},
1092         {0x048a, 0x00000912},
1093         {0x048e, 0x00000db6},
1094         {0x049c, 0x00596596},
1095         {0x049e, 0x00000514},
1096         {0x04a2, 0x00410280},
1097         {0x04a4, 0x00000000},
1098         {0x04a6, 0x00000000},
1099         {0x04a8, 0x00000000},
1100         {0x04aa, 0x00000000},
1101         {0x04ae, 0x007df7dd},
1102         {0x04b0, 0x006d95d4},
1103         {0x04b2, 0x00492410},
1104     };
1105     struct device *dev = &phydev->mdio.dev;
1106     const struct firmware *fw;
1107     unsigned int i;
1108     u16 crc, reg;
1109     bool serdes_init;
1110     int ret;
1111 
1112     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1113 
1114     /* all writes below are broadcasted to all PHYs in the same package */
1115     reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
1116     reg |= SMI_BROADCAST_WR_EN;
1117     phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
1118 
1119     phy_base_write(phydev, MII_VSC85XX_INT_MASK, 0);
1120 
1121     /* The below register writes are tweaking analog and electrical
1122      * configuration that were determined through characterization by PHY
1123      * engineers. These don't mean anything more than "these are the best
1124      * values".
1125      */
1126     phy_base_write(phydev, MSCC_PHY_EXT_PHY_CNTL_2, 0x0040);
1127 
1128     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
1129 
1130     phy_base_write(phydev, MSCC_PHY_TEST_PAGE_20, 0x4320);
1131     phy_base_write(phydev, MSCC_PHY_TEST_PAGE_24, 0x0c00);
1132     phy_base_write(phydev, MSCC_PHY_TEST_PAGE_9, 0x18ca);
1133     phy_base_write(phydev, MSCC_PHY_TEST_PAGE_5, 0x1b20);
1134 
1135     reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
1136     reg |= TR_CLK_DISABLE;
1137     phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
1138 
1139     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
1140 
1141     for (i = 0; i < ARRAY_SIZE(pre_init1); i++)
1142         vsc8584_csr_write(phydev, pre_init1[i].reg, pre_init1[i].val);
1143 
1144     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED_2);
1145 
1146     phy_base_write(phydev, MSCC_PHY_CU_PMD_TX_CNTL, 0x028e);
1147 
1148     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
1149 
1150     for (i = 0; i < ARRAY_SIZE(pre_init2); i++)
1151         vsc8584_csr_write(phydev, pre_init2[i].reg, pre_init2[i].val);
1152 
1153     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
1154 
1155     reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
1156     reg &= ~TR_CLK_DISABLE;
1157     phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
1158 
1159     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1160 
1161     /* end of write broadcasting */
1162     reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
1163     reg &= ~SMI_BROADCAST_WR_EN;
1164     phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
1165 
1166     ret = request_firmware(&fw, MSCC_VSC8574_REVB_INT8051_FW, dev);
1167     if (ret) {
1168         dev_err(dev, "failed to load firmware %s, ret: %d\n",
1169             MSCC_VSC8574_REVB_INT8051_FW, ret);
1170         return ret;
1171     }
1172 
1173     /* Add one byte to size for the one added by the patch_fw function */
1174     ret = vsc8584_get_fw_crc(phydev,
1175                  MSCC_VSC8574_REVB_INT8051_FW_START_ADDR,
1176                  fw->size + 1, &crc);
1177     if (ret)
1178         goto out;
1179 
1180     if (crc == MSCC_VSC8574_REVB_INT8051_FW_CRC) {
1181         serdes_init = vsc8574_is_serdes_init(phydev);
1182 
1183         if (!serdes_init) {
1184             ret = vsc8584_micro_assert_reset(phydev);
1185             if (ret) {
1186                 dev_err(dev,
1187                     "%s: failed to assert reset of micro\n",
1188                     __func__);
1189                 goto out;
1190             }
1191         }
1192     } else {
1193         dev_dbg(dev, "FW CRC is not the expected one, patching FW\n");
1194 
1195         serdes_init = false;
1196 
1197         if (vsc8584_patch_fw(phydev, fw))
1198             dev_warn(dev,
1199                  "failed to patch FW, expect non-optimal device\n");
1200     }
1201 
1202     if (!serdes_init) {
1203         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1204                    MSCC_PHY_PAGE_EXTENDED_GPIO);
1205 
1206         phy_base_write(phydev, MSCC_TRAP_ROM_ADDR(1), 0x3eb7);
1207         phy_base_write(phydev, MSCC_PATCH_RAM_ADDR(1), 0x4012);
1208         phy_base_write(phydev, MSCC_INT_MEM_CNTL,
1209                    EN_PATCH_RAM_TRAP_ADDR(1));
1210 
1211         vsc8584_micro_deassert_reset(phydev, false);
1212 
1213         /* Add one byte to size for the one added by the patch_fw
1214          * function
1215          */
1216         ret = vsc8584_get_fw_crc(phydev,
1217                      MSCC_VSC8574_REVB_INT8051_FW_START_ADDR,
1218                      fw->size + 1, &crc);
1219         if (ret)
1220             goto out;
1221 
1222         if (crc != MSCC_VSC8574_REVB_INT8051_FW_CRC)
1223             dev_warn(dev,
1224                  "FW CRC after patching is not the expected one, expect non-optimal device\n");
1225     }
1226 
1227     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1228                MSCC_PHY_PAGE_EXTENDED_GPIO);
1229 
1230     ret = vsc8584_cmd(phydev, PROC_CMD_1588_DEFAULT_INIT |
1231               PROC_CMD_PHY_INIT);
1232 
1233 out:
1234     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1235 
1236     release_firmware(fw);
1237 
1238     return ret;
1239 }
1240 
1241 /* Access LCPLL Cfg_2 */
1242 static void vsc8584_pll5g_cfg2_wr(struct phy_device *phydev,
1243                   bool disable_fsm)
1244 {
1245     u32 rd_dat;
1246 
1247     rd_dat = vsc85xx_csr_read(phydev, MACRO_CTRL, PHY_S6G_PLL5G_CFG2);
1248     rd_dat &= ~BIT(PHY_S6G_CFG2_FSM_DIS);
1249     rd_dat |= (disable_fsm << PHY_S6G_CFG2_FSM_DIS);
1250     vsc85xx_csr_write(phydev, MACRO_CTRL, PHY_S6G_PLL5G_CFG2, rd_dat);
1251 }
1252 
1253 /* trigger a read to the spcified MCB */
1254 static int vsc8584_mcb_rd_trig(struct phy_device *phydev,
1255                    u32 mcb_reg_addr, u8 mcb_slave_num)
1256 {
1257     u32 rd_dat = 0;
1258 
1259     /* read MCB */
1260     vsc85xx_csr_write(phydev, MACRO_CTRL, mcb_reg_addr,
1261               (0x40000000 | (1L << mcb_slave_num)));
1262 
1263     return read_poll_timeout(vsc85xx_csr_read, rd_dat,
1264                  !(rd_dat & 0x40000000),
1265                  4000, 200000, 0,
1266                  phydev, MACRO_CTRL, mcb_reg_addr);
1267 }
1268 
1269 /* trigger a write to the spcified MCB */
1270 static int vsc8584_mcb_wr_trig(struct phy_device *phydev,
1271                    u32 mcb_reg_addr,
1272                    u8 mcb_slave_num)
1273 {
1274     u32 rd_dat = 0;
1275 
1276     /* write back MCB */
1277     vsc85xx_csr_write(phydev, MACRO_CTRL, mcb_reg_addr,
1278               (0x80000000 | (1L << mcb_slave_num)));
1279 
1280     return read_poll_timeout(vsc85xx_csr_read, rd_dat,
1281                  !(rd_dat & 0x80000000),
1282                  4000, 200000, 0,
1283                  phydev, MACRO_CTRL, mcb_reg_addr);
1284 }
1285 
1286 /* Sequence to Reset LCPLL for the VIPER and ELISE PHY */
1287 static int vsc8584_pll5g_reset(struct phy_device *phydev)
1288 {
1289     bool dis_fsm;
1290     int ret = 0;
1291 
1292     ret = vsc8584_mcb_rd_trig(phydev, 0x11, 0);
1293     if (ret < 0)
1294         goto done;
1295     dis_fsm = 1;
1296 
1297     /* Reset LCPLL */
1298     vsc8584_pll5g_cfg2_wr(phydev, dis_fsm);
1299 
1300     /* write back LCPLL MCB */
1301     ret = vsc8584_mcb_wr_trig(phydev, 0x11, 0);
1302     if (ret < 0)
1303         goto done;
1304 
1305     /* 10 mSec sleep while LCPLL is hold in reset */
1306     usleep_range(10000, 20000);
1307 
1308     /* read LCPLL MCB into CSRs */
1309     ret = vsc8584_mcb_rd_trig(phydev, 0x11, 0);
1310     if (ret < 0)
1311         goto done;
1312     dis_fsm = 0;
1313 
1314     /* Release the Reset of LCPLL */
1315     vsc8584_pll5g_cfg2_wr(phydev, dis_fsm);
1316 
1317     /* write back LCPLL MCB */
1318     ret = vsc8584_mcb_wr_trig(phydev, 0x11, 0);
1319     if (ret < 0)
1320         goto done;
1321 
1322     usleep_range(110000, 200000);
1323 done:
1324     return ret;
1325 }
1326 
1327 /* bus->mdio_lock should be locked when using this function */
1328 static int vsc8584_config_pre_init(struct phy_device *phydev)
1329 {
1330     static const struct reg_val pre_init1[] = {
1331         {0x07fa, 0x0050100f},
1332         {0x1688, 0x00049f81},
1333         {0x0f90, 0x00688980},
1334         {0x03a4, 0x0000d8f0},
1335         {0x0fc0, 0x00000400},
1336         {0x0f82, 0x0012b002},
1337         {0x1686, 0x00000004},
1338         {0x168c, 0x00d2c46f},
1339         {0x17a2, 0x00000620},
1340         {0x16a0, 0x00eeffdd},
1341         {0x16a6, 0x00071448},
1342         {0x16a4, 0x0013132f},
1343         {0x16a8, 0x00000000},
1344         {0x0ffc, 0x00c0a028},
1345         {0x0fe8, 0x0091b06c},
1346         {0x0fea, 0x00041600},
1347         {0x0f80, 0x00fffaff},
1348         {0x0fec, 0x00901809},
1349         {0x0ffe, 0x00b01007},
1350         {0x16b0, 0x00eeff00},
1351         {0x16b2, 0x00007000},
1352         {0x16b4, 0x00000814},
1353     };
1354     static const struct reg_val pre_init2[] = {
1355         {0x0486, 0x0008a518},
1356         {0x0488, 0x006dc696},
1357         {0x048a, 0x00000912},
1358     };
1359     const struct firmware *fw;
1360     struct device *dev = &phydev->mdio.dev;
1361     unsigned int i;
1362     u16 crc, reg;
1363     int ret;
1364 
1365     ret = vsc8584_pll5g_reset(phydev);
1366     if (ret < 0) {
1367         dev_err(dev, "failed LCPLL reset, ret: %d\n", ret);
1368         return ret;
1369     }
1370 
1371     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1372 
1373     /* all writes below are broadcasted to all PHYs in the same package */
1374     reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
1375     reg |= SMI_BROADCAST_WR_EN;
1376     phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
1377 
1378     phy_base_write(phydev, MII_VSC85XX_INT_MASK, 0);
1379 
1380     reg = phy_base_read(phydev,  MSCC_PHY_BYPASS_CONTROL);
1381     reg |= PARALLEL_DET_IGNORE_ADVERTISED;
1382     phy_base_write(phydev, MSCC_PHY_BYPASS_CONTROL, reg);
1383 
1384     /* The below register writes are tweaking analog and electrical
1385      * configuration that were determined through characterization by PHY
1386      * engineers. These don't mean anything more than "these are the best
1387      * values".
1388      */
1389     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED_3);
1390 
1391     phy_base_write(phydev, MSCC_PHY_SERDES_TX_CRC_ERR_CNT, 0x2000);
1392 
1393     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
1394 
1395     phy_base_write(phydev, MSCC_PHY_TEST_PAGE_5, 0x1f20);
1396 
1397     reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
1398     reg |= TR_CLK_DISABLE;
1399     phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
1400 
1401     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
1402 
1403     phy_base_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(0x2fa4));
1404 
1405     reg = phy_base_read(phydev, MSCC_PHY_TR_MSB);
1406     reg &= ~0x007f;
1407     reg |= 0x0019;
1408     phy_base_write(phydev, MSCC_PHY_TR_MSB, reg);
1409 
1410     phy_base_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(0x0fa4));
1411 
1412     for (i = 0; i < ARRAY_SIZE(pre_init1); i++)
1413         vsc8584_csr_write(phydev, pre_init1[i].reg, pre_init1[i].val);
1414 
1415     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED_2);
1416 
1417     phy_base_write(phydev, MSCC_PHY_CU_PMD_TX_CNTL, 0x028e);
1418 
1419     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
1420 
1421     for (i = 0; i < ARRAY_SIZE(pre_init2); i++)
1422         vsc8584_csr_write(phydev, pre_init2[i].reg, pre_init2[i].val);
1423 
1424     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
1425 
1426     reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
1427     reg &= ~TR_CLK_DISABLE;
1428     phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
1429 
1430     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1431 
1432     /* end of write broadcasting */
1433     reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
1434     reg &= ~SMI_BROADCAST_WR_EN;
1435     phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
1436 
1437     ret = request_firmware(&fw, MSCC_VSC8584_REVB_INT8051_FW, dev);
1438     if (ret) {
1439         dev_err(dev, "failed to load firmware %s, ret: %d\n",
1440             MSCC_VSC8584_REVB_INT8051_FW, ret);
1441         return ret;
1442     }
1443 
1444     /* Add one byte to size for the one added by the patch_fw function */
1445     ret = vsc8584_get_fw_crc(phydev,
1446                  MSCC_VSC8584_REVB_INT8051_FW_START_ADDR,
1447                  fw->size + 1, &crc);
1448     if (ret)
1449         goto out;
1450 
1451     if (crc != MSCC_VSC8584_REVB_INT8051_FW_CRC) {
1452         dev_dbg(dev, "FW CRC is not the expected one, patching FW\n");
1453         if (vsc8584_patch_fw(phydev, fw))
1454             dev_warn(dev,
1455                  "failed to patch FW, expect non-optimal device\n");
1456     }
1457 
1458     vsc8584_micro_deassert_reset(phydev, false);
1459 
1460     /* Add one byte to size for the one added by the patch_fw function */
1461     ret = vsc8584_get_fw_crc(phydev,
1462                  MSCC_VSC8584_REVB_INT8051_FW_START_ADDR,
1463                  fw->size + 1, &crc);
1464     if (ret)
1465         goto out;
1466 
1467     if (crc != MSCC_VSC8584_REVB_INT8051_FW_CRC)
1468         dev_warn(dev,
1469              "FW CRC after patching is not the expected one, expect non-optimal device\n");
1470 
1471     ret = vsc8584_micro_assert_reset(phydev);
1472     if (ret)
1473         goto out;
1474 
1475     /* Write patch vector 0, to skip IB cal polling  */
1476     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED_GPIO);
1477     reg = MSCC_ROM_TRAP_SERDES_6G_CFG; /* ROM address to trap, for patch vector 0 */
1478     ret = phy_base_write(phydev, MSCC_TRAP_ROM_ADDR(1), reg);
1479     if (ret)
1480         goto out;
1481 
1482     reg = MSCC_RAM_TRAP_SERDES_6G_CFG; /* RAM address to jump to, when patch vector 0 enabled */
1483     ret = phy_base_write(phydev, MSCC_PATCH_RAM_ADDR(1), reg);
1484     if (ret)
1485         goto out;
1486 
1487     reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
1488     reg |= PATCH_VEC_ZERO_EN; /* bit 8, enable patch vector 0 */
1489     ret = phy_base_write(phydev, MSCC_INT_MEM_CNTL, reg);
1490     if (ret)
1491         goto out;
1492 
1493     vsc8584_micro_deassert_reset(phydev, true);
1494 
1495 out:
1496     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1497 
1498     release_firmware(fw);
1499 
1500     return ret;
1501 }
1502 
1503 static void vsc8584_get_base_addr(struct phy_device *phydev)
1504 {
1505     struct vsc8531_private *vsc8531 = phydev->priv;
1506     u16 val, addr;
1507 
1508     phy_lock_mdio_bus(phydev);
1509     __phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
1510 
1511     addr = __phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_4);
1512     addr >>= PHY_CNTL_4_ADDR_POS;
1513 
1514     val = __phy_read(phydev, MSCC_PHY_ACTIPHY_CNTL);
1515 
1516     __phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1517     phy_unlock_mdio_bus(phydev);
1518 
1519     /* In the package, there are two pairs of PHYs (PHY0 + PHY2 and
1520      * PHY1 + PHY3). The first PHY of each pair (PHY0 and PHY1) is
1521      * the base PHY for timestamping operations.
1522      */
1523     vsc8531->ts_base_addr = phydev->mdio.addr;
1524     vsc8531->ts_base_phy = addr;
1525 
1526     if (val & PHY_ADDR_REVERSED) {
1527         vsc8531->base_addr = phydev->mdio.addr + addr;
1528         if (addr > 1) {
1529             vsc8531->ts_base_addr += 2;
1530             vsc8531->ts_base_phy += 2;
1531         }
1532     } else {
1533         vsc8531->base_addr = phydev->mdio.addr - addr;
1534         if (addr > 1) {
1535             vsc8531->ts_base_addr -= 2;
1536             vsc8531->ts_base_phy -= 2;
1537         }
1538     }
1539 
1540     vsc8531->addr = addr;
1541 }
1542 
1543 static void vsc85xx_coma_mode_release(struct phy_device *phydev)
1544 {
1545     /* The coma mode (pin or reg) provides an optional feature that
1546      * may be used to control when the PHYs become active.
1547      * Alternatively the COMA_MODE pin may be connected low
1548      * so that the PHYs are fully active once out of reset.
1549      */
1550 
1551     /* Enable output (mode=0) and write zero to it */
1552     vsc85xx_phy_write_page(phydev, MSCC_PHY_PAGE_EXTENDED_GPIO);
1553     __phy_modify(phydev, MSCC_PHY_GPIO_CONTROL_2,
1554              MSCC_PHY_COMA_MODE | MSCC_PHY_COMA_OUTPUT, 0);
1555     vsc85xx_phy_write_page(phydev, MSCC_PHY_PAGE_STANDARD);
1556 }
1557 
1558 static int vsc8584_config_host_serdes(struct phy_device *phydev)
1559 {
1560     struct vsc8531_private *vsc8531 = phydev->priv;
1561     int ret;
1562     u16 val;
1563 
1564     ret = phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1565                  MSCC_PHY_PAGE_EXTENDED_GPIO);
1566     if (ret)
1567         return ret;
1568 
1569     val = phy_base_read(phydev, MSCC_PHY_MAC_CFG_FASTLINK);
1570     val &= ~MAC_CFG_MASK;
1571     if (phydev->interface == PHY_INTERFACE_MODE_QSGMII) {
1572         val |= MAC_CFG_QSGMII;
1573     } else if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
1574         val |= MAC_CFG_SGMII;
1575     } else {
1576         ret = -EINVAL;
1577         return ret;
1578     }
1579 
1580     ret = phy_base_write(phydev, MSCC_PHY_MAC_CFG_FASTLINK, val);
1581     if (ret)
1582         return ret;
1583 
1584     ret = phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1585                  MSCC_PHY_PAGE_STANDARD);
1586     if (ret)
1587         return ret;
1588 
1589     val = PROC_CMD_MCB_ACCESS_MAC_CONF | PROC_CMD_RST_CONF_PORT |
1590         PROC_CMD_READ_MOD_WRITE_PORT;
1591     if (phydev->interface == PHY_INTERFACE_MODE_QSGMII)
1592         val |= PROC_CMD_QSGMII_MAC;
1593     else
1594         val |= PROC_CMD_SGMII_MAC;
1595 
1596     ret = vsc8584_cmd(phydev, val);
1597     if (ret)
1598         return ret;
1599 
1600     usleep_range(10000, 20000);
1601 
1602     /* Disable SerDes for 100Base-FX */
1603     ret = vsc8584_cmd(phydev, PROC_CMD_FIBER_MEDIA_CONF |
1604               PROC_CMD_FIBER_PORT(vsc8531->addr) |
1605               PROC_CMD_FIBER_DISABLE |
1606               PROC_CMD_READ_MOD_WRITE_PORT |
1607               PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_100BASE_FX);
1608     if (ret)
1609         return ret;
1610 
1611     /* Disable SerDes for 1000Base-X */
1612     ret = vsc8584_cmd(phydev, PROC_CMD_FIBER_MEDIA_CONF |
1613               PROC_CMD_FIBER_PORT(vsc8531->addr) |
1614               PROC_CMD_FIBER_DISABLE |
1615               PROC_CMD_READ_MOD_WRITE_PORT |
1616               PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_1000BASE_X);
1617     if (ret)
1618         return ret;
1619 
1620     return vsc85xx_sd6g_config_v2(phydev);
1621 }
1622 
1623 static int vsc8574_config_host_serdes(struct phy_device *phydev)
1624 {
1625     struct vsc8531_private *vsc8531 = phydev->priv;
1626     int ret;
1627     u16 val;
1628 
1629     ret = phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1630                  MSCC_PHY_PAGE_EXTENDED_GPIO);
1631     if (ret)
1632         return ret;
1633 
1634     val = phy_base_read(phydev, MSCC_PHY_MAC_CFG_FASTLINK);
1635     val &= ~MAC_CFG_MASK;
1636     if (phydev->interface == PHY_INTERFACE_MODE_QSGMII) {
1637         val |= MAC_CFG_QSGMII;
1638     } else if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
1639         val |= MAC_CFG_SGMII;
1640     } else if (phy_interface_is_rgmii(phydev)) {
1641         val |= MAC_CFG_RGMII;
1642     } else {
1643         ret = -EINVAL;
1644         return ret;
1645     }
1646 
1647     ret = phy_base_write(phydev, MSCC_PHY_MAC_CFG_FASTLINK, val);
1648     if (ret)
1649         return ret;
1650 
1651     ret = phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1652                  MSCC_PHY_PAGE_STANDARD);
1653     if (ret)
1654         return ret;
1655 
1656     if (!phy_interface_is_rgmii(phydev)) {
1657         val = PROC_CMD_MCB_ACCESS_MAC_CONF | PROC_CMD_RST_CONF_PORT |
1658             PROC_CMD_READ_MOD_WRITE_PORT;
1659         if (phydev->interface == PHY_INTERFACE_MODE_QSGMII)
1660             val |= PROC_CMD_QSGMII_MAC;
1661         else
1662             val |= PROC_CMD_SGMII_MAC;
1663 
1664         ret = vsc8584_cmd(phydev, val);
1665         if (ret)
1666             return ret;
1667 
1668         usleep_range(10000, 20000);
1669     }
1670 
1671     /* Disable SerDes for 100Base-FX */
1672     ret = vsc8584_cmd(phydev, PROC_CMD_FIBER_MEDIA_CONF |
1673               PROC_CMD_FIBER_PORT(vsc8531->addr) |
1674               PROC_CMD_FIBER_DISABLE |
1675               PROC_CMD_READ_MOD_WRITE_PORT |
1676               PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_100BASE_FX);
1677     if (ret)
1678         return ret;
1679 
1680     /* Disable SerDes for 1000Base-X */
1681     return vsc8584_cmd(phydev, PROC_CMD_FIBER_MEDIA_CONF |
1682                PROC_CMD_FIBER_PORT(vsc8531->addr) |
1683                PROC_CMD_FIBER_DISABLE |
1684                PROC_CMD_READ_MOD_WRITE_PORT |
1685                PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_1000BASE_X);
1686 }
1687 
1688 static int vsc8584_config_init(struct phy_device *phydev)
1689 {
1690     struct vsc8531_private *vsc8531 = phydev->priv;
1691     int ret, i;
1692     u16 val;
1693 
1694     phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
1695 
1696     phy_lock_mdio_bus(phydev);
1697 
1698     /* Some parts of the init sequence are identical for every PHY in the
1699      * package. Some parts are modifying the GPIO register bank which is a
1700      * set of registers that are affecting all PHYs, a few resetting the
1701      * microprocessor common to all PHYs. The CRC check responsible of the
1702      * checking the firmware within the 8051 microprocessor can only be
1703      * accessed via the PHY whose internal address in the package is 0.
1704      * All PHYs' interrupts mask register has to be zeroed before enabling
1705      * any PHY's interrupt in this register.
1706      * For all these reasons, we need to do the init sequence once and only
1707      * once whatever is the first PHY in the package that is initialized and
1708      * do the correct init sequence for all PHYs that are package-critical
1709      * in this pre-init function.
1710      */
1711     if (phy_package_init_once(phydev)) {
1712         /* The following switch statement assumes that the lowest
1713          * nibble of the phy_id_mask is always 0. This works because
1714          * the lowest nibble of the PHY_ID's below are also 0.
1715          */
1716         WARN_ON(phydev->drv->phy_id_mask & 0xf);
1717 
1718         switch (phydev->phy_id & phydev->drv->phy_id_mask) {
1719         case PHY_ID_VSC8504:
1720         case PHY_ID_VSC8552:
1721         case PHY_ID_VSC8572:
1722         case PHY_ID_VSC8574:
1723             ret = vsc8574_config_pre_init(phydev);
1724             if (ret)
1725                 goto err;
1726             ret = vsc8574_config_host_serdes(phydev);
1727             if (ret)
1728                 goto err;
1729             break;
1730         case PHY_ID_VSC856X:
1731         case PHY_ID_VSC8575:
1732         case PHY_ID_VSC8582:
1733         case PHY_ID_VSC8584:
1734             ret = vsc8584_config_pre_init(phydev);
1735             if (ret)
1736                 goto err;
1737             ret = vsc8584_config_host_serdes(phydev);
1738             if (ret)
1739                 goto err;
1740             vsc85xx_coma_mode_release(phydev);
1741             break;
1742         default:
1743             ret = -EINVAL;
1744             break;
1745         }
1746 
1747         if (ret)
1748             goto err;
1749     }
1750 
1751     phy_unlock_mdio_bus(phydev);
1752 
1753     ret = vsc8584_macsec_init(phydev);
1754     if (ret)
1755         return ret;
1756 
1757     ret = vsc8584_ptp_init(phydev);
1758     if (ret)
1759         return ret;
1760 
1761     val = phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_1);
1762     val &= ~(MEDIA_OP_MODE_MASK | VSC8584_MAC_IF_SELECTION_MASK);
1763     val |= (MEDIA_OP_MODE_COPPER << MEDIA_OP_MODE_POS) |
1764            (VSC8584_MAC_IF_SELECTION_SGMII << VSC8584_MAC_IF_SELECTION_POS);
1765     ret = phy_write(phydev, MSCC_PHY_EXT_PHY_CNTL_1, val);
1766     if (ret)
1767         return ret;
1768 
1769     if (phy_interface_is_rgmii(phydev)) {
1770         ret = vsc85xx_rgmii_set_skews(phydev, VSC8572_RGMII_CNTL,
1771                           VSC8572_RGMII_RX_DELAY_MASK,
1772                           VSC8572_RGMII_TX_DELAY_MASK);
1773         if (ret)
1774             return ret;
1775     }
1776 
1777     ret = genphy_soft_reset(phydev);
1778     if (ret)
1779         return ret;
1780 
1781     for (i = 0; i < vsc8531->nleds; i++) {
1782         ret = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]);
1783         if (ret)
1784             return ret;
1785     }
1786 
1787     return 0;
1788 
1789 err:
1790     phy_unlock_mdio_bus(phydev);
1791     return ret;
1792 }
1793 
1794 static irqreturn_t vsc8584_handle_interrupt(struct phy_device *phydev)
1795 {
1796     irqreturn_t ret;
1797     int irq_status;
1798 
1799     irq_status = phy_read(phydev, MII_VSC85XX_INT_STATUS);
1800     if (irq_status < 0)
1801         return IRQ_NONE;
1802 
1803     /* Timestamping IRQ does not set a bit in the global INT_STATUS, so
1804      * irq_status would be 0.
1805      */
1806     ret = vsc8584_handle_ts_interrupt(phydev);
1807     if (!(irq_status & MII_VSC85XX_INT_MASK_MASK))
1808         return ret;
1809 
1810     if (irq_status & MII_VSC85XX_INT_MASK_EXT)
1811         vsc8584_handle_macsec_interrupt(phydev);
1812 
1813     if (irq_status & MII_VSC85XX_INT_MASK_LINK_CHG)
1814         phy_trigger_machine(phydev);
1815 
1816     return IRQ_HANDLED;
1817 }
1818 
1819 static int vsc85xx_config_init(struct phy_device *phydev)
1820 {
1821     int rc, i, phy_id;
1822     struct vsc8531_private *vsc8531 = phydev->priv;
1823 
1824     rc = vsc85xx_default_config(phydev);
1825     if (rc)
1826         return rc;
1827 
1828     rc = vsc85xx_mac_if_set(phydev, phydev->interface);
1829     if (rc)
1830         return rc;
1831 
1832     rc = vsc85xx_edge_rate_cntl_set(phydev, vsc8531->rate_magic);
1833     if (rc)
1834         return rc;
1835 
1836     phy_id = phydev->drv->phy_id & phydev->drv->phy_id_mask;
1837     if (PHY_ID_VSC8531 == phy_id || PHY_ID_VSC8541 == phy_id ||
1838         PHY_ID_VSC8530 == phy_id || PHY_ID_VSC8540 == phy_id) {
1839         rc = vsc8531_pre_init_seq_set(phydev);
1840         if (rc)
1841             return rc;
1842     }
1843 
1844     rc = vsc85xx_eee_init_seq_set(phydev);
1845     if (rc)
1846         return rc;
1847 
1848     for (i = 0; i < vsc8531->nleds; i++) {
1849         rc = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]);
1850         if (rc)
1851             return rc;
1852     }
1853 
1854     return 0;
1855 }
1856 
1857 static int __phy_write_mcb_s6g(struct phy_device *phydev, u32 reg, u8 mcb,
1858                    u32 op)
1859 {
1860     unsigned long deadline;
1861     u32 val;
1862     int ret;
1863 
1864     ret = vsc85xx_csr_write(phydev, PHY_MCB_TARGET, reg,
1865                 op | (1 << mcb));
1866     if (ret)
1867         return -EINVAL;
1868 
1869     deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
1870     do {
1871         usleep_range(500, 1000);
1872         val = vsc85xx_csr_read(phydev, PHY_MCB_TARGET, reg);
1873 
1874         if (val == 0xffffffff)
1875             return -EIO;
1876 
1877     } while (time_before(jiffies, deadline) && (val & op));
1878 
1879     if (val & op)
1880         return -ETIMEDOUT;
1881 
1882     return 0;
1883 }
1884 
1885 /* Trigger a read to the specified MCB */
1886 int phy_update_mcb_s6g(struct phy_device *phydev, u32 reg, u8 mcb)
1887 {
1888     return __phy_write_mcb_s6g(phydev, reg, mcb, PHY_MCB_S6G_READ);
1889 }
1890 
1891 /* Trigger a write to the specified MCB */
1892 int phy_commit_mcb_s6g(struct phy_device *phydev, u32 reg, u8 mcb)
1893 {
1894     return __phy_write_mcb_s6g(phydev, reg, mcb, PHY_MCB_S6G_WRITE);
1895 }
1896 
1897 static int vsc8514_config_host_serdes(struct phy_device *phydev)
1898 {
1899     int ret;
1900     u16 val;
1901 
1902     ret = phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1903                  MSCC_PHY_PAGE_EXTENDED_GPIO);
1904     if (ret)
1905         return ret;
1906 
1907     val = phy_base_read(phydev, MSCC_PHY_MAC_CFG_FASTLINK);
1908     val &= ~MAC_CFG_MASK;
1909     val |= MAC_CFG_QSGMII;
1910     ret = phy_base_write(phydev, MSCC_PHY_MAC_CFG_FASTLINK, val);
1911     if (ret)
1912         return ret;
1913 
1914     ret = phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1915                  MSCC_PHY_PAGE_STANDARD);
1916     if (ret)
1917         return ret;
1918 
1919     ret = vsc8584_cmd(phydev, PROC_CMD_NOP);
1920     if (ret)
1921         return ret;
1922 
1923     ret = vsc8584_cmd(phydev,
1924               PROC_CMD_MCB_ACCESS_MAC_CONF |
1925               PROC_CMD_RST_CONF_PORT |
1926               PROC_CMD_READ_MOD_WRITE_PORT | PROC_CMD_QSGMII_MAC);
1927     if (ret) {
1928         dev_err(&phydev->mdio.dev, "%s: QSGMII error: %d\n",
1929             __func__, ret);
1930         return ret;
1931     }
1932 
1933     /* Apply 6G SerDes FOJI Algorithm
1934      *  Initial condition requirement:
1935      *  1. hold 8051 in reset
1936      *  2. disable patch vector 0, in order to allow IB cal poll during FoJi
1937      *  3. deassert 8051 reset after change patch vector status
1938      *  4. proceed with FoJi (vsc85xx_sd6g_config_v2)
1939      */
1940     vsc8584_micro_assert_reset(phydev);
1941     val = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
1942     /* clear bit 8, to disable patch vector 0 */
1943     val &= ~PATCH_VEC_ZERO_EN;
1944     ret = phy_base_write(phydev, MSCC_INT_MEM_CNTL, val);
1945     /* Enable 8051 clock, don't set patch present, disable PRAM clock override */
1946     vsc8584_micro_deassert_reset(phydev, false);
1947 
1948     return vsc85xx_sd6g_config_v2(phydev);
1949 }
1950 
1951 static int vsc8514_config_pre_init(struct phy_device *phydev)
1952 {
1953     /* These are the settings to override the silicon default
1954      * values to handle hardware performance of PHY. They
1955      * are set at Power-On state and remain until PHY Reset.
1956      */
1957     static const struct reg_val pre_init1[] = {
1958         {0x0f90, 0x00688980},
1959         {0x0786, 0x00000003},
1960         {0x07fa, 0x0050100f},
1961         {0x0f82, 0x0012b002},
1962         {0x1686, 0x00000004},
1963         {0x168c, 0x00d2c46f},
1964         {0x17a2, 0x00000620},
1965         {0x16a0, 0x00eeffdd},
1966         {0x16a6, 0x00071448},
1967         {0x16a4, 0x0013132f},
1968         {0x16a8, 0x00000000},
1969         {0x0ffc, 0x00c0a028},
1970         {0x0fe8, 0x0091b06c},
1971         {0x0fea, 0x00041600},
1972         {0x0f80, 0x00fffaff},
1973         {0x0fec, 0x00901809},
1974         {0x0ffe, 0x00b01007},
1975         {0x16b0, 0x00eeff00},
1976         {0x16b2, 0x00007000},
1977         {0x16b4, 0x00000814},
1978     };
1979     struct device *dev = &phydev->mdio.dev;
1980     unsigned int i;
1981     u16 reg;
1982     int ret;
1983 
1984     ret = vsc8584_pll5g_reset(phydev);
1985     if (ret < 0) {
1986         dev_err(dev, "failed LCPLL reset, ret: %d\n", ret);
1987         return ret;
1988     }
1989 
1990     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1991 
1992     /* all writes below are broadcasted to all PHYs in the same package */
1993     reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
1994     reg |= SMI_BROADCAST_WR_EN;
1995     phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
1996 
1997     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
1998 
1999     reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
2000     reg |= BIT(15);
2001     phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
2002 
2003     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
2004 
2005     for (i = 0; i < ARRAY_SIZE(pre_init1); i++)
2006         vsc8584_csr_write(phydev, pre_init1[i].reg, pre_init1[i].val);
2007 
2008     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
2009 
2010     reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
2011     reg &= ~BIT(15);
2012     phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
2013 
2014     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
2015 
2016     reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
2017     reg &= ~SMI_BROADCAST_WR_EN;
2018     phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
2019 
2020     /* Add pre-patching commands to:
2021      * 1. enable 8051 clock, operate 8051 clock at 125 MHz
2022      * instead of HW default 62.5MHz
2023      * 2. write patch vector 0, to skip IB cal polling executed
2024      * as part of the 0x80E0 ROM command
2025      */
2026     vsc8584_micro_deassert_reset(phydev, false);
2027 
2028     vsc8584_micro_assert_reset(phydev);
2029     phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
2030                MSCC_PHY_PAGE_EXTENDED_GPIO);
2031     /* ROM address to trap, for patch vector 0 */
2032     reg = MSCC_ROM_TRAP_SERDES_6G_CFG;
2033     ret = phy_base_write(phydev, MSCC_TRAP_ROM_ADDR(1), reg);
2034     if (ret)
2035         goto err;
2036     /* RAM address to jump to, when patch vector 0 enabled */
2037     reg = MSCC_RAM_TRAP_SERDES_6G_CFG;
2038     ret = phy_base_write(phydev, MSCC_PATCH_RAM_ADDR(1), reg);
2039     if (ret)
2040         goto err;
2041     reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
2042     reg |= PATCH_VEC_ZERO_EN; /* bit 8, enable patch vector 0 */
2043     ret = phy_base_write(phydev, MSCC_INT_MEM_CNTL, reg);
2044     if (ret)
2045         goto err;
2046 
2047     /* Enable 8051 clock, don't set patch present
2048      * yet, disable PRAM clock override
2049      */
2050     vsc8584_micro_deassert_reset(phydev, false);
2051     return ret;
2052  err:
2053     /* restore 8051 and bail w error */
2054     vsc8584_micro_deassert_reset(phydev, false);
2055     return ret;
2056 }
2057 
2058 static int vsc8514_config_init(struct phy_device *phydev)
2059 {
2060     struct vsc8531_private *vsc8531 = phydev->priv;
2061     int ret, i;
2062 
2063     phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
2064 
2065     phy_lock_mdio_bus(phydev);
2066 
2067     /* Some parts of the init sequence are identical for every PHY in the
2068      * package. Some parts are modifying the GPIO register bank which is a
2069      * set of registers that are affecting all PHYs, a few resetting the
2070      * microprocessor common to all PHYs.
2071      * All PHYs' interrupts mask register has to be zeroed before enabling
2072      * any PHY's interrupt in this register.
2073      * For all these reasons, we need to do the init sequence once and only
2074      * once whatever is the first PHY in the package that is initialized and
2075      * do the correct init sequence for all PHYs that are package-critical
2076      * in this pre-init function.
2077      */
2078     if (phy_package_init_once(phydev)) {
2079         ret = vsc8514_config_pre_init(phydev);
2080         if (ret)
2081             goto err;
2082         ret = vsc8514_config_host_serdes(phydev);
2083         if (ret)
2084             goto err;
2085         vsc85xx_coma_mode_release(phydev);
2086     }
2087 
2088     phy_unlock_mdio_bus(phydev);
2089 
2090     ret = phy_modify(phydev, MSCC_PHY_EXT_PHY_CNTL_1, MEDIA_OP_MODE_MASK,
2091              MEDIA_OP_MODE_COPPER << MEDIA_OP_MODE_POS);
2092 
2093     if (ret)
2094         return ret;
2095 
2096     ret = genphy_soft_reset(phydev);
2097 
2098     if (ret)
2099         return ret;
2100 
2101     for (i = 0; i < vsc8531->nleds; i++) {
2102         ret = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]);
2103         if (ret)
2104             return ret;
2105     }
2106 
2107     return ret;
2108 
2109 err:
2110     phy_unlock_mdio_bus(phydev);
2111     return ret;
2112 }
2113 
2114 static int vsc85xx_ack_interrupt(struct phy_device *phydev)
2115 {
2116     int rc = 0;
2117 
2118     if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
2119         rc = phy_read(phydev, MII_VSC85XX_INT_STATUS);
2120 
2121     return (rc < 0) ? rc : 0;
2122 }
2123 
2124 static int vsc85xx_config_intr(struct phy_device *phydev)
2125 {
2126     int rc;
2127 
2128     if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
2129         rc = vsc85xx_ack_interrupt(phydev);
2130         if (rc)
2131             return rc;
2132 
2133         vsc8584_config_macsec_intr(phydev);
2134         vsc8584_config_ts_intr(phydev);
2135 
2136         rc = phy_write(phydev, MII_VSC85XX_INT_MASK,
2137                    MII_VSC85XX_INT_MASK_MASK);
2138     } else {
2139         rc = phy_write(phydev, MII_VSC85XX_INT_MASK, 0);
2140         if (rc < 0)
2141             return rc;
2142         rc = phy_read(phydev, MII_VSC85XX_INT_STATUS);
2143         if (rc < 0)
2144             return rc;
2145 
2146         rc = vsc85xx_ack_interrupt(phydev);
2147     }
2148 
2149     return rc;
2150 }
2151 
2152 static irqreturn_t vsc85xx_handle_interrupt(struct phy_device *phydev)
2153 {
2154     int irq_status;
2155 
2156     irq_status = phy_read(phydev, MII_VSC85XX_INT_STATUS);
2157     if (irq_status < 0) {
2158         phy_error(phydev);
2159         return IRQ_NONE;
2160     }
2161 
2162     if (!(irq_status & MII_VSC85XX_INT_MASK_MASK))
2163         return IRQ_NONE;
2164 
2165     phy_trigger_machine(phydev);
2166 
2167     return IRQ_HANDLED;
2168 }
2169 
2170 static int vsc85xx_config_aneg(struct phy_device *phydev)
2171 {
2172     int rc;
2173 
2174     rc = vsc85xx_mdix_set(phydev, phydev->mdix_ctrl);
2175     if (rc < 0)
2176         return rc;
2177 
2178     return genphy_config_aneg(phydev);
2179 }
2180 
2181 static int vsc85xx_read_status(struct phy_device *phydev)
2182 {
2183     int rc;
2184 
2185     rc = vsc85xx_mdix_get(phydev, &phydev->mdix);
2186     if (rc < 0)
2187         return rc;
2188 
2189     return genphy_read_status(phydev);
2190 }
2191 
2192 static int vsc8514_probe(struct phy_device *phydev)
2193 {
2194     struct vsc8531_private *vsc8531;
2195     u32 default_mode[4] = {VSC8531_LINK_1000_ACTIVITY,
2196        VSC8531_LINK_100_ACTIVITY, VSC8531_LINK_ACTIVITY,
2197        VSC8531_DUPLEX_COLLISION};
2198 
2199     vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
2200     if (!vsc8531)
2201         return -ENOMEM;
2202 
2203     phydev->priv = vsc8531;
2204 
2205     vsc8584_get_base_addr(phydev);
2206     devm_phy_package_join(&phydev->mdio.dev, phydev,
2207                   vsc8531->base_addr, 0);
2208 
2209     vsc8531->nleds = 4;
2210     vsc8531->supp_led_modes = VSC85XX_SUPP_LED_MODES;
2211     vsc8531->hw_stats = vsc85xx_hw_stats;
2212     vsc8531->nstats = ARRAY_SIZE(vsc85xx_hw_stats);
2213     vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats,
2214                       sizeof(u64), GFP_KERNEL);
2215     if (!vsc8531->stats)
2216         return -ENOMEM;
2217 
2218     return vsc85xx_dt_led_modes_get(phydev, default_mode);
2219 }
2220 
2221 static int vsc8574_probe(struct phy_device *phydev)
2222 {
2223     struct vsc8531_private *vsc8531;
2224     u32 default_mode[4] = {VSC8531_LINK_1000_ACTIVITY,
2225        VSC8531_LINK_100_ACTIVITY, VSC8531_LINK_ACTIVITY,
2226        VSC8531_DUPLEX_COLLISION};
2227 
2228     vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
2229     if (!vsc8531)
2230         return -ENOMEM;
2231 
2232     phydev->priv = vsc8531;
2233 
2234     vsc8584_get_base_addr(phydev);
2235     devm_phy_package_join(&phydev->mdio.dev, phydev,
2236                   vsc8531->base_addr, 0);
2237 
2238     vsc8531->nleds = 4;
2239     vsc8531->supp_led_modes = VSC8584_SUPP_LED_MODES;
2240     vsc8531->hw_stats = vsc8584_hw_stats;
2241     vsc8531->nstats = ARRAY_SIZE(vsc8584_hw_stats);
2242     vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats,
2243                       sizeof(u64), GFP_KERNEL);
2244     if (!vsc8531->stats)
2245         return -ENOMEM;
2246 
2247     return vsc85xx_dt_led_modes_get(phydev, default_mode);
2248 }
2249 
2250 static int vsc8584_probe(struct phy_device *phydev)
2251 {
2252     struct vsc8531_private *vsc8531;
2253     u32 default_mode[4] = {VSC8531_LINK_1000_ACTIVITY,
2254        VSC8531_LINK_100_ACTIVITY, VSC8531_LINK_ACTIVITY,
2255        VSC8531_DUPLEX_COLLISION};
2256     int ret;
2257 
2258     if ((phydev->phy_id & MSCC_DEV_REV_MASK) != VSC8584_REVB) {
2259         dev_err(&phydev->mdio.dev, "Only VSC8584 revB is supported.\n");
2260         return -ENOTSUPP;
2261     }
2262 
2263     vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
2264     if (!vsc8531)
2265         return -ENOMEM;
2266 
2267     phydev->priv = vsc8531;
2268 
2269     vsc8584_get_base_addr(phydev);
2270     devm_phy_package_join(&phydev->mdio.dev, phydev, vsc8531->base_addr,
2271                   sizeof(struct vsc85xx_shared_private));
2272 
2273     vsc8531->nleds = 4;
2274     vsc8531->supp_led_modes = VSC8584_SUPP_LED_MODES;
2275     vsc8531->hw_stats = vsc8584_hw_stats;
2276     vsc8531->nstats = ARRAY_SIZE(vsc8584_hw_stats);
2277     vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats,
2278                       sizeof(u64), GFP_KERNEL);
2279     if (!vsc8531->stats)
2280         return -ENOMEM;
2281 
2282     if (phy_package_probe_once(phydev)) {
2283         ret = vsc8584_ptp_probe_once(phydev);
2284         if (ret)
2285             return ret;
2286     }
2287 
2288     ret = vsc8584_ptp_probe(phydev);
2289     if (ret)
2290         return ret;
2291 
2292     return vsc85xx_dt_led_modes_get(phydev, default_mode);
2293 }
2294 
2295 static int vsc85xx_probe(struct phy_device *phydev)
2296 {
2297     struct vsc8531_private *vsc8531;
2298     int rate_magic;
2299     u32 default_mode[2] = {VSC8531_LINK_1000_ACTIVITY,
2300        VSC8531_LINK_100_ACTIVITY};
2301 
2302     rate_magic = vsc85xx_edge_rate_magic_get(phydev);
2303     if (rate_magic < 0)
2304         return rate_magic;
2305 
2306     vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
2307     if (!vsc8531)
2308         return -ENOMEM;
2309 
2310     phydev->priv = vsc8531;
2311 
2312     vsc8531->rate_magic = rate_magic;
2313     vsc8531->nleds = 2;
2314     vsc8531->supp_led_modes = VSC85XX_SUPP_LED_MODES;
2315     vsc8531->hw_stats = vsc85xx_hw_stats;
2316     vsc8531->nstats = ARRAY_SIZE(vsc85xx_hw_stats);
2317     vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats,
2318                       sizeof(u64), GFP_KERNEL);
2319     if (!vsc8531->stats)
2320         return -ENOMEM;
2321 
2322     return vsc85xx_dt_led_modes_get(phydev, default_mode);
2323 }
2324 
2325 /* Microsemi VSC85xx PHYs */
2326 static struct phy_driver vsc85xx_driver[] = {
2327 {
2328     .phy_id     = PHY_ID_VSC8502,
2329     .name       = "Microsemi GE VSC8502 SyncE",
2330     .phy_id_mask    = 0xfffffff0,
2331     /* PHY_BASIC_FEATURES */
2332     .soft_reset = &genphy_soft_reset,
2333     .config_init    = &vsc85xx_config_init,
2334     .config_aneg    = &vsc85xx_config_aneg,
2335     .read_status    = &vsc85xx_read_status,
2336     .handle_interrupt = vsc85xx_handle_interrupt,
2337     .config_intr    = &vsc85xx_config_intr,
2338     .suspend    = &genphy_suspend,
2339     .resume     = &genphy_resume,
2340     .probe      = &vsc85xx_probe,
2341     .set_wol    = &vsc85xx_wol_set,
2342     .get_wol    = &vsc85xx_wol_get,
2343     .get_tunable    = &vsc85xx_get_tunable,
2344     .set_tunable    = &vsc85xx_set_tunable,
2345     .read_page  = &vsc85xx_phy_read_page,
2346     .write_page = &vsc85xx_phy_write_page,
2347     .get_sset_count = &vsc85xx_get_sset_count,
2348     .get_strings    = &vsc85xx_get_strings,
2349     .get_stats      = &vsc85xx_get_stats,
2350 },
2351 {
2352     .phy_id     = PHY_ID_VSC8504,
2353     .name       = "Microsemi GE VSC8504 SyncE",
2354     .phy_id_mask    = 0xfffffff0,
2355     /* PHY_GBIT_FEATURES */
2356     .soft_reset = &genphy_soft_reset,
2357     .config_init    = &vsc8584_config_init,
2358     .config_aneg    = &vsc85xx_config_aneg,
2359     .aneg_done  = &genphy_aneg_done,
2360     .read_status    = &vsc85xx_read_status,
2361     .handle_interrupt = vsc85xx_handle_interrupt,
2362     .config_intr    = &vsc85xx_config_intr,
2363     .suspend    = &genphy_suspend,
2364     .resume     = &genphy_resume,
2365     .probe      = &vsc8574_probe,
2366     .set_wol    = &vsc85xx_wol_set,
2367     .get_wol    = &vsc85xx_wol_get,
2368     .get_tunable    = &vsc85xx_get_tunable,
2369     .set_tunable    = &vsc85xx_set_tunable,
2370     .read_page  = &vsc85xx_phy_read_page,
2371     .write_page = &vsc85xx_phy_write_page,
2372     .get_sset_count = &vsc85xx_get_sset_count,
2373     .get_strings    = &vsc85xx_get_strings,
2374     .get_stats      = &vsc85xx_get_stats,
2375 },
2376 {
2377     .phy_id     = PHY_ID_VSC8514,
2378     .name       = "Microsemi GE VSC8514 SyncE",
2379     .phy_id_mask    = 0xfffffff0,
2380     .soft_reset = &genphy_soft_reset,
2381     .config_init    = &vsc8514_config_init,
2382     .config_aneg    = &vsc85xx_config_aneg,
2383     .read_status    = &vsc85xx_read_status,
2384     .handle_interrupt = vsc85xx_handle_interrupt,
2385     .config_intr    = &vsc85xx_config_intr,
2386     .suspend    = &genphy_suspend,
2387     .resume     = &genphy_resume,
2388     .probe      = &vsc8514_probe,
2389     .set_wol    = &vsc85xx_wol_set,
2390     .get_wol    = &vsc85xx_wol_get,
2391     .get_tunable    = &vsc85xx_get_tunable,
2392     .set_tunable    = &vsc85xx_set_tunable,
2393     .read_page      = &vsc85xx_phy_read_page,
2394     .write_page     = &vsc85xx_phy_write_page,
2395     .get_sset_count = &vsc85xx_get_sset_count,
2396     .get_strings    = &vsc85xx_get_strings,
2397     .get_stats      = &vsc85xx_get_stats,
2398 },
2399 {
2400     .phy_id     = PHY_ID_VSC8530,
2401     .name       = "Microsemi FE VSC8530",
2402     .phy_id_mask    = 0xfffffff0,
2403     /* PHY_BASIC_FEATURES */
2404     .soft_reset = &genphy_soft_reset,
2405     .config_init    = &vsc85xx_config_init,
2406     .config_aneg    = &vsc85xx_config_aneg,
2407     .read_status    = &vsc85xx_read_status,
2408     .handle_interrupt = vsc85xx_handle_interrupt,
2409     .config_intr    = &vsc85xx_config_intr,
2410     .suspend    = &genphy_suspend,
2411     .resume     = &genphy_resume,
2412     .probe      = &vsc85xx_probe,
2413     .set_wol    = &vsc85xx_wol_set,
2414     .get_wol    = &vsc85xx_wol_get,
2415     .get_tunable    = &vsc85xx_get_tunable,
2416     .set_tunable    = &vsc85xx_set_tunable,
2417     .read_page  = &vsc85xx_phy_read_page,
2418     .write_page = &vsc85xx_phy_write_page,
2419     .get_sset_count = &vsc85xx_get_sset_count,
2420     .get_strings    = &vsc85xx_get_strings,
2421     .get_stats      = &vsc85xx_get_stats,
2422 },
2423 {
2424     .phy_id     = PHY_ID_VSC8531,
2425     .name       = "Microsemi VSC8531",
2426     .phy_id_mask    = 0xfffffff0,
2427     /* PHY_GBIT_FEATURES */
2428     .soft_reset = &genphy_soft_reset,
2429     .config_init    = &vsc85xx_config_init,
2430     .config_aneg    = &vsc85xx_config_aneg,
2431     .read_status    = &vsc85xx_read_status,
2432     .handle_interrupt = vsc85xx_handle_interrupt,
2433     .config_intr    = &vsc85xx_config_intr,
2434     .suspend    = &genphy_suspend,
2435     .resume     = &genphy_resume,
2436     .probe      = &vsc85xx_probe,
2437     .set_wol    = &vsc85xx_wol_set,
2438     .get_wol    = &vsc85xx_wol_get,
2439     .get_tunable    = &vsc85xx_get_tunable,
2440     .set_tunable    = &vsc85xx_set_tunable,
2441     .read_page  = &vsc85xx_phy_read_page,
2442     .write_page = &vsc85xx_phy_write_page,
2443     .get_sset_count = &vsc85xx_get_sset_count,
2444     .get_strings    = &vsc85xx_get_strings,
2445     .get_stats      = &vsc85xx_get_stats,
2446 },
2447 {
2448     .phy_id     = PHY_ID_VSC8540,
2449     .name       = "Microsemi FE VSC8540 SyncE",
2450     .phy_id_mask    = 0xfffffff0,
2451     /* PHY_BASIC_FEATURES */
2452     .soft_reset = &genphy_soft_reset,
2453     .config_init    = &vsc85xx_config_init,
2454     .config_aneg    = &vsc85xx_config_aneg,
2455     .read_status    = &vsc85xx_read_status,
2456     .handle_interrupt = vsc85xx_handle_interrupt,
2457     .config_intr    = &vsc85xx_config_intr,
2458     .suspend    = &genphy_suspend,
2459     .resume     = &genphy_resume,
2460     .probe      = &vsc85xx_probe,
2461     .set_wol    = &vsc85xx_wol_set,
2462     .get_wol    = &vsc85xx_wol_get,
2463     .get_tunable    = &vsc85xx_get_tunable,
2464     .set_tunable    = &vsc85xx_set_tunable,
2465     .read_page  = &vsc85xx_phy_read_page,
2466     .write_page = &vsc85xx_phy_write_page,
2467     .get_sset_count = &vsc85xx_get_sset_count,
2468     .get_strings    = &vsc85xx_get_strings,
2469     .get_stats      = &vsc85xx_get_stats,
2470 },
2471 {
2472     .phy_id     = PHY_ID_VSC8541,
2473     .name       = "Microsemi VSC8541 SyncE",
2474     .phy_id_mask    = 0xfffffff0,
2475     /* PHY_GBIT_FEATURES */
2476     .soft_reset = &genphy_soft_reset,
2477     .config_init    = &vsc85xx_config_init,
2478     .config_aneg    = &vsc85xx_config_aneg,
2479     .read_status    = &vsc85xx_read_status,
2480     .handle_interrupt = vsc85xx_handle_interrupt,
2481     .config_intr    = &vsc85xx_config_intr,
2482     .suspend    = &genphy_suspend,
2483     .resume     = &genphy_resume,
2484     .probe      = &vsc85xx_probe,
2485     .set_wol    = &vsc85xx_wol_set,
2486     .get_wol    = &vsc85xx_wol_get,
2487     .get_tunable    = &vsc85xx_get_tunable,
2488     .set_tunable    = &vsc85xx_set_tunable,
2489     .read_page  = &vsc85xx_phy_read_page,
2490     .write_page = &vsc85xx_phy_write_page,
2491     .get_sset_count = &vsc85xx_get_sset_count,
2492     .get_strings    = &vsc85xx_get_strings,
2493     .get_stats      = &vsc85xx_get_stats,
2494 },
2495 {
2496     .phy_id     = PHY_ID_VSC8552,
2497     .name       = "Microsemi GE VSC8552 SyncE",
2498     .phy_id_mask    = 0xfffffff0,
2499     /* PHY_GBIT_FEATURES */
2500     .soft_reset = &genphy_soft_reset,
2501     .config_init    = &vsc8584_config_init,
2502     .config_aneg    = &vsc85xx_config_aneg,
2503     .read_status    = &vsc85xx_read_status,
2504     .handle_interrupt = vsc85xx_handle_interrupt,
2505     .config_intr    = &vsc85xx_config_intr,
2506     .suspend    = &genphy_suspend,
2507     .resume     = &genphy_resume,
2508     .probe      = &vsc8574_probe,
2509     .set_wol    = &vsc85xx_wol_set,
2510     .get_wol    = &vsc85xx_wol_get,
2511     .get_tunable    = &vsc85xx_get_tunable,
2512     .set_tunable    = &vsc85xx_set_tunable,
2513     .read_page  = &vsc85xx_phy_read_page,
2514     .write_page = &vsc85xx_phy_write_page,
2515     .get_sset_count = &vsc85xx_get_sset_count,
2516     .get_strings    = &vsc85xx_get_strings,
2517     .get_stats      = &vsc85xx_get_stats,
2518 },
2519 {
2520     .phy_id     = PHY_ID_VSC856X,
2521     .name       = "Microsemi GE VSC856X SyncE",
2522     .phy_id_mask    = 0xfffffff0,
2523     /* PHY_GBIT_FEATURES */
2524     .soft_reset = &genphy_soft_reset,
2525     .config_init    = &vsc8584_config_init,
2526     .config_aneg    = &vsc85xx_config_aneg,
2527     .read_status    = &vsc85xx_read_status,
2528     .handle_interrupt = vsc85xx_handle_interrupt,
2529     .config_intr    = &vsc85xx_config_intr,
2530     .suspend    = &genphy_suspend,
2531     .resume     = &genphy_resume,
2532     .probe      = &vsc8584_probe,
2533     .get_tunable    = &vsc85xx_get_tunable,
2534     .set_tunable    = &vsc85xx_set_tunable,
2535     .read_page  = &vsc85xx_phy_read_page,
2536     .write_page = &vsc85xx_phy_write_page,
2537     .get_sset_count = &vsc85xx_get_sset_count,
2538     .get_strings    = &vsc85xx_get_strings,
2539     .get_stats      = &vsc85xx_get_stats,
2540 },
2541 {
2542     .phy_id     = PHY_ID_VSC8572,
2543     .name       = "Microsemi GE VSC8572 SyncE",
2544     .phy_id_mask    = 0xfffffff0,
2545     /* PHY_GBIT_FEATURES */
2546     .soft_reset = &genphy_soft_reset,
2547     .config_init    = &vsc8584_config_init,
2548     .config_aneg    = &vsc85xx_config_aneg,
2549     .aneg_done  = &genphy_aneg_done,
2550     .read_status    = &vsc85xx_read_status,
2551     .handle_interrupt = &vsc8584_handle_interrupt,
2552     .config_intr    = &vsc85xx_config_intr,
2553     .suspend    = &genphy_suspend,
2554     .resume     = &genphy_resume,
2555     .probe      = &vsc8574_probe,
2556     .set_wol    = &vsc85xx_wol_set,
2557     .get_wol    = &vsc85xx_wol_get,
2558     .get_tunable    = &vsc85xx_get_tunable,
2559     .set_tunable    = &vsc85xx_set_tunable,
2560     .read_page  = &vsc85xx_phy_read_page,
2561     .write_page = &vsc85xx_phy_write_page,
2562     .get_sset_count = &vsc85xx_get_sset_count,
2563     .get_strings    = &vsc85xx_get_strings,
2564     .get_stats      = &vsc85xx_get_stats,
2565 },
2566 {
2567     .phy_id     = PHY_ID_VSC8574,
2568     .name       = "Microsemi GE VSC8574 SyncE",
2569     .phy_id_mask    = 0xfffffff0,
2570     /* PHY_GBIT_FEATURES */
2571     .soft_reset = &genphy_soft_reset,
2572     .config_init    = &vsc8584_config_init,
2573     .config_aneg    = &vsc85xx_config_aneg,
2574     .aneg_done  = &genphy_aneg_done,
2575     .read_status    = &vsc85xx_read_status,
2576     .handle_interrupt = vsc85xx_handle_interrupt,
2577     .config_intr    = &vsc85xx_config_intr,
2578     .suspend    = &genphy_suspend,
2579     .resume     = &genphy_resume,
2580     .probe      = &vsc8574_probe,
2581     .set_wol    = &vsc85xx_wol_set,
2582     .get_wol    = &vsc85xx_wol_get,
2583     .get_tunable    = &vsc85xx_get_tunable,
2584     .set_tunable    = &vsc85xx_set_tunable,
2585     .read_page  = &vsc85xx_phy_read_page,
2586     .write_page = &vsc85xx_phy_write_page,
2587     .get_sset_count = &vsc85xx_get_sset_count,
2588     .get_strings    = &vsc85xx_get_strings,
2589     .get_stats      = &vsc85xx_get_stats,
2590 },
2591 {
2592     .phy_id     = PHY_ID_VSC8575,
2593     .name       = "Microsemi GE VSC8575 SyncE",
2594     .phy_id_mask    = 0xfffffff0,
2595     /* PHY_GBIT_FEATURES */
2596     .soft_reset = &genphy_soft_reset,
2597     .config_init    = &vsc8584_config_init,
2598     .config_aneg    = &vsc85xx_config_aneg,
2599     .aneg_done  = &genphy_aneg_done,
2600     .read_status    = &vsc85xx_read_status,
2601     .handle_interrupt = &vsc8584_handle_interrupt,
2602     .config_intr    = &vsc85xx_config_intr,
2603     .suspend    = &genphy_suspend,
2604     .resume     = &genphy_resume,
2605     .probe      = &vsc8584_probe,
2606     .get_tunable    = &vsc85xx_get_tunable,
2607     .set_tunable    = &vsc85xx_set_tunable,
2608     .read_page  = &vsc85xx_phy_read_page,
2609     .write_page = &vsc85xx_phy_write_page,
2610     .get_sset_count = &vsc85xx_get_sset_count,
2611     .get_strings    = &vsc85xx_get_strings,
2612     .get_stats      = &vsc85xx_get_stats,
2613 },
2614 {
2615     .phy_id     = PHY_ID_VSC8582,
2616     .name       = "Microsemi GE VSC8582 SyncE",
2617     .phy_id_mask    = 0xfffffff0,
2618     /* PHY_GBIT_FEATURES */
2619     .soft_reset = &genphy_soft_reset,
2620     .config_init    = &vsc8584_config_init,
2621     .config_aneg    = &vsc85xx_config_aneg,
2622     .aneg_done  = &genphy_aneg_done,
2623     .read_status    = &vsc85xx_read_status,
2624     .handle_interrupt = &vsc8584_handle_interrupt,
2625     .config_intr    = &vsc85xx_config_intr,
2626     .suspend    = &genphy_suspend,
2627     .resume     = &genphy_resume,
2628     .probe      = &vsc8584_probe,
2629     .get_tunable    = &vsc85xx_get_tunable,
2630     .set_tunable    = &vsc85xx_set_tunable,
2631     .read_page  = &vsc85xx_phy_read_page,
2632     .write_page = &vsc85xx_phy_write_page,
2633     .get_sset_count = &vsc85xx_get_sset_count,
2634     .get_strings    = &vsc85xx_get_strings,
2635     .get_stats      = &vsc85xx_get_stats,
2636 },
2637 {
2638     .phy_id     = PHY_ID_VSC8584,
2639     .name       = "Microsemi GE VSC8584 SyncE",
2640     .phy_id_mask    = 0xfffffff0,
2641     /* PHY_GBIT_FEATURES */
2642     .soft_reset = &genphy_soft_reset,
2643     .config_init    = &vsc8584_config_init,
2644     .config_aneg    = &vsc85xx_config_aneg,
2645     .aneg_done  = &genphy_aneg_done,
2646     .read_status    = &vsc85xx_read_status,
2647     .handle_interrupt = &vsc8584_handle_interrupt,
2648     .config_intr    = &vsc85xx_config_intr,
2649     .suspend    = &genphy_suspend,
2650     .resume     = &genphy_resume,
2651     .probe      = &vsc8584_probe,
2652     .get_tunable    = &vsc85xx_get_tunable,
2653     .set_tunable    = &vsc85xx_set_tunable,
2654     .read_page  = &vsc85xx_phy_read_page,
2655     .write_page = &vsc85xx_phy_write_page,
2656     .get_sset_count = &vsc85xx_get_sset_count,
2657     .get_strings    = &vsc85xx_get_strings,
2658     .get_stats      = &vsc85xx_get_stats,
2659     .link_change_notify = &vsc85xx_link_change_notify,
2660 }
2661 
2662 };
2663 
2664 module_phy_driver(vsc85xx_driver);
2665 
2666 static struct mdio_device_id __maybe_unused vsc85xx_tbl[] = {
2667     { PHY_ID_VSC8504, 0xfffffff0, },
2668     { PHY_ID_VSC8514, 0xfffffff0, },
2669     { PHY_ID_VSC8530, 0xfffffff0, },
2670     { PHY_ID_VSC8531, 0xfffffff0, },
2671     { PHY_ID_VSC8540, 0xfffffff0, },
2672     { PHY_ID_VSC8541, 0xfffffff0, },
2673     { PHY_ID_VSC8552, 0xfffffff0, },
2674     { PHY_ID_VSC856X, 0xfffffff0, },
2675     { PHY_ID_VSC8572, 0xfffffff0, },
2676     { PHY_ID_VSC8574, 0xfffffff0, },
2677     { PHY_ID_VSC8575, 0xfffffff0, },
2678     { PHY_ID_VSC8582, 0xfffffff0, },
2679     { PHY_ID_VSC8584, 0xfffffff0, },
2680     { }
2681 };
2682 
2683 MODULE_DEVICE_TABLE(mdio, vsc85xx_tbl);
2684 
2685 MODULE_DESCRIPTION("Microsemi VSC85xx PHY driver");
2686 MODULE_AUTHOR("Nagaraju Lakkaraju");
2687 MODULE_LICENSE("Dual MIT/GPL");
2688 
2689 MODULE_FIRMWARE(MSCC_VSC8584_REVB_INT8051_FW);
2690 MODULE_FIRMWARE(MSCC_VSC8574_REVB_INT8051_FW);