cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mscc_main.c (74182B)


      1// SPDX-License-Identifier: (GPL-2.0 OR MIT)
      2/*
      3 * Driver for Microsemi VSC85xx PHYs
      4 *
      5 * Author: Nagaraju Lakkaraju
      6 * License: Dual MIT/GPL
      7 * Copyright (c) 2016 Microsemi Corporation
      8 */
      9
     10#include <linux/firmware.h>
     11#include <linux/jiffies.h>
     12#include <linux/kernel.h>
     13#include <linux/module.h>
     14#include <linux/mdio.h>
     15#include <linux/mii.h>
     16#include <linux/phy.h>
     17#include <linux/of.h>
     18#include <linux/netdevice.h>
     19#include <dt-bindings/net/mscc-phy-vsc8531.h>
     20#include "mscc_serdes.h"
     21#include "mscc.h"
     22
     23static const struct vsc85xx_hw_stat vsc85xx_hw_stats[] = {
     24	{
     25		.string	= "phy_receive_errors",
     26		.reg	= MSCC_PHY_ERR_RX_CNT,
     27		.page	= MSCC_PHY_PAGE_STANDARD,
     28		.mask	= ERR_CNT_MASK,
     29	}, {
     30		.string	= "phy_false_carrier",
     31		.reg	= MSCC_PHY_ERR_FALSE_CARRIER_CNT,
     32		.page	= MSCC_PHY_PAGE_STANDARD,
     33		.mask	= ERR_CNT_MASK,
     34	}, {
     35		.string	= "phy_cu_media_link_disconnect",
     36		.reg	= MSCC_PHY_ERR_LINK_DISCONNECT_CNT,
     37		.page	= MSCC_PHY_PAGE_STANDARD,
     38		.mask	= ERR_CNT_MASK,
     39	}, {
     40		.string	= "phy_cu_media_crc_good_count",
     41		.reg	= MSCC_PHY_CU_MEDIA_CRC_VALID_CNT,
     42		.page	= MSCC_PHY_PAGE_EXTENDED,
     43		.mask	= VALID_CRC_CNT_CRC_MASK,
     44	}, {
     45		.string	= "phy_cu_media_crc_error_count",
     46		.reg	= MSCC_PHY_EXT_PHY_CNTL_4,
     47		.page	= MSCC_PHY_PAGE_EXTENDED,
     48		.mask	= ERR_CNT_MASK,
     49	},
     50};
     51
     52static const struct vsc85xx_hw_stat vsc8584_hw_stats[] = {
     53	{
     54		.string	= "phy_receive_errors",
     55		.reg	= MSCC_PHY_ERR_RX_CNT,
     56		.page	= MSCC_PHY_PAGE_STANDARD,
     57		.mask	= ERR_CNT_MASK,
     58	}, {
     59		.string	= "phy_false_carrier",
     60		.reg	= MSCC_PHY_ERR_FALSE_CARRIER_CNT,
     61		.page	= MSCC_PHY_PAGE_STANDARD,
     62		.mask	= ERR_CNT_MASK,
     63	}, {
     64		.string	= "phy_cu_media_link_disconnect",
     65		.reg	= MSCC_PHY_ERR_LINK_DISCONNECT_CNT,
     66		.page	= MSCC_PHY_PAGE_STANDARD,
     67		.mask	= ERR_CNT_MASK,
     68	}, {
     69		.string	= "phy_cu_media_crc_good_count",
     70		.reg	= MSCC_PHY_CU_MEDIA_CRC_VALID_CNT,
     71		.page	= MSCC_PHY_PAGE_EXTENDED,
     72		.mask	= VALID_CRC_CNT_CRC_MASK,
     73	}, {
     74		.string	= "phy_cu_media_crc_error_count",
     75		.reg	= MSCC_PHY_EXT_PHY_CNTL_4,
     76		.page	= MSCC_PHY_PAGE_EXTENDED,
     77		.mask	= ERR_CNT_MASK,
     78	}, {
     79		.string	= "phy_serdes_tx_good_pkt_count",
     80		.reg	= MSCC_PHY_SERDES_TX_VALID_CNT,
     81		.page	= MSCC_PHY_PAGE_EXTENDED_3,
     82		.mask	= VALID_CRC_CNT_CRC_MASK,
     83	}, {
     84		.string	= "phy_serdes_tx_bad_crc_count",
     85		.reg	= MSCC_PHY_SERDES_TX_CRC_ERR_CNT,
     86		.page	= MSCC_PHY_PAGE_EXTENDED_3,
     87		.mask	= ERR_CNT_MASK,
     88	}, {
     89		.string	= "phy_serdes_rx_good_pkt_count",
     90		.reg	= MSCC_PHY_SERDES_RX_VALID_CNT,
     91		.page	= MSCC_PHY_PAGE_EXTENDED_3,
     92		.mask	= VALID_CRC_CNT_CRC_MASK,
     93	}, {
     94		.string	= "phy_serdes_rx_bad_crc_count",
     95		.reg	= MSCC_PHY_SERDES_RX_CRC_ERR_CNT,
     96		.page	= MSCC_PHY_PAGE_EXTENDED_3,
     97		.mask	= ERR_CNT_MASK,
     98	},
     99};
    100
    101#if IS_ENABLED(CONFIG_OF_MDIO)
    102static const struct vsc8531_edge_rate_table edge_table[] = {
    103	{MSCC_VDDMAC_3300, { 0, 2,  4,  7, 10, 17, 29, 53} },
    104	{MSCC_VDDMAC_2500, { 0, 3,  6, 10, 14, 23, 37, 63} },
    105	{MSCC_VDDMAC_1800, { 0, 5,  9, 16, 23, 35, 52, 76} },
    106	{MSCC_VDDMAC_1500, { 0, 6, 14, 21, 29, 42, 58, 77} },
    107};
    108#endif
    109
    110static int vsc85xx_phy_read_page(struct phy_device *phydev)
    111{
    112	return __phy_read(phydev, MSCC_EXT_PAGE_ACCESS);
    113}
    114
    115static int vsc85xx_phy_write_page(struct phy_device *phydev, int page)
    116{
    117	return __phy_write(phydev, MSCC_EXT_PAGE_ACCESS, page);
    118}
    119
    120static int vsc85xx_get_sset_count(struct phy_device *phydev)
    121{
    122	struct vsc8531_private *priv = phydev->priv;
    123
    124	if (!priv)
    125		return 0;
    126
    127	return priv->nstats;
    128}
    129
    130static void vsc85xx_get_strings(struct phy_device *phydev, u8 *data)
    131{
    132	struct vsc8531_private *priv = phydev->priv;
    133	int i;
    134
    135	if (!priv)
    136		return;
    137
    138	for (i = 0; i < priv->nstats; i++)
    139		strlcpy(data + i * ETH_GSTRING_LEN, priv->hw_stats[i].string,
    140			ETH_GSTRING_LEN);
    141}
    142
    143static u64 vsc85xx_get_stat(struct phy_device *phydev, int i)
    144{
    145	struct vsc8531_private *priv = phydev->priv;
    146	int val;
    147
    148	val = phy_read_paged(phydev, priv->hw_stats[i].page,
    149			     priv->hw_stats[i].reg);
    150	if (val < 0)
    151		return U64_MAX;
    152
    153	val = val & priv->hw_stats[i].mask;
    154	priv->stats[i] += val;
    155
    156	return priv->stats[i];
    157}
    158
    159static void vsc85xx_get_stats(struct phy_device *phydev,
    160			      struct ethtool_stats *stats, u64 *data)
    161{
    162	struct vsc8531_private *priv = phydev->priv;
    163	int i;
    164
    165	if (!priv)
    166		return;
    167
    168	for (i = 0; i < priv->nstats; i++)
    169		data[i] = vsc85xx_get_stat(phydev, i);
    170}
    171
    172static int vsc85xx_led_cntl_set(struct phy_device *phydev,
    173				u8 led_num,
    174				u8 mode)
    175{
    176	int rc;
    177	u16 reg_val;
    178
    179	mutex_lock(&phydev->lock);
    180	reg_val = phy_read(phydev, MSCC_PHY_LED_MODE_SEL);
    181	reg_val &= ~LED_MODE_SEL_MASK(led_num);
    182	reg_val |= LED_MODE_SEL(led_num, (u16)mode);
    183	rc = phy_write(phydev, MSCC_PHY_LED_MODE_SEL, reg_val);
    184	mutex_unlock(&phydev->lock);
    185
    186	return rc;
    187}
    188
    189static int vsc85xx_mdix_get(struct phy_device *phydev, u8 *mdix)
    190{
    191	u16 reg_val;
    192
    193	reg_val = phy_read(phydev, MSCC_PHY_DEV_AUX_CNTL);
    194	if (reg_val & HP_AUTO_MDIX_X_OVER_IND_MASK)
    195		*mdix = ETH_TP_MDI_X;
    196	else
    197		*mdix = ETH_TP_MDI;
    198
    199	return 0;
    200}
    201
    202static int vsc85xx_mdix_set(struct phy_device *phydev, u8 mdix)
    203{
    204	int rc;
    205	u16 reg_val;
    206
    207	reg_val = phy_read(phydev, MSCC_PHY_BYPASS_CONTROL);
    208	if (mdix == ETH_TP_MDI || mdix == ETH_TP_MDI_X) {
    209		reg_val |= (DISABLE_PAIR_SWAP_CORR_MASK |
    210			    DISABLE_POLARITY_CORR_MASK  |
    211			    DISABLE_HP_AUTO_MDIX_MASK);
    212	} else {
    213		reg_val &= ~(DISABLE_PAIR_SWAP_CORR_MASK |
    214			     DISABLE_POLARITY_CORR_MASK  |
    215			     DISABLE_HP_AUTO_MDIX_MASK);
    216	}
    217	rc = phy_write(phydev, MSCC_PHY_BYPASS_CONTROL, reg_val);
    218	if (rc)
    219		return rc;
    220
    221	reg_val = 0;
    222
    223	if (mdix == ETH_TP_MDI)
    224		reg_val = FORCE_MDI_CROSSOVER_MDI;
    225	else if (mdix == ETH_TP_MDI_X)
    226		reg_val = FORCE_MDI_CROSSOVER_MDIX;
    227
    228	rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED,
    229			      MSCC_PHY_EXT_MODE_CNTL, FORCE_MDI_CROSSOVER_MASK,
    230			      reg_val);
    231	if (rc < 0)
    232		return rc;
    233
    234	return genphy_restart_aneg(phydev);
    235}
    236
    237static int vsc85xx_downshift_get(struct phy_device *phydev, u8 *count)
    238{
    239	int reg_val;
    240
    241	reg_val = phy_read_paged(phydev, MSCC_PHY_PAGE_EXTENDED,
    242				 MSCC_PHY_ACTIPHY_CNTL);
    243	if (reg_val < 0)
    244		return reg_val;
    245
    246	reg_val &= DOWNSHIFT_CNTL_MASK;
    247	if (!(reg_val & DOWNSHIFT_EN))
    248		*count = DOWNSHIFT_DEV_DISABLE;
    249	else
    250		*count = ((reg_val & ~DOWNSHIFT_EN) >> DOWNSHIFT_CNTL_POS) + 2;
    251
    252	return 0;
    253}
    254
    255static int vsc85xx_downshift_set(struct phy_device *phydev, u8 count)
    256{
    257	if (count == DOWNSHIFT_DEV_DEFAULT_COUNT) {
    258		/* Default downshift count 3 (i.e. Bit3:2 = 0b01) */
    259		count = ((1 << DOWNSHIFT_CNTL_POS) | DOWNSHIFT_EN);
    260	} else if (count > DOWNSHIFT_COUNT_MAX || count == 1) {
    261		phydev_err(phydev, "Downshift count should be 2,3,4 or 5\n");
    262		return -ERANGE;
    263	} else if (count) {
    264		/* Downshift count is either 2,3,4 or 5 */
    265		count = (((count - 2) << DOWNSHIFT_CNTL_POS) | DOWNSHIFT_EN);
    266	}
    267
    268	return phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED,
    269				MSCC_PHY_ACTIPHY_CNTL, DOWNSHIFT_CNTL_MASK,
    270				count);
    271}
    272
    273static int vsc85xx_wol_set(struct phy_device *phydev,
    274			   struct ethtool_wolinfo *wol)
    275{
    276	const u8 *mac_addr = phydev->attached_dev->dev_addr;
    277	int rc;
    278	u16 reg_val;
    279	u8  i;
    280	u16 pwd[3] = {0, 0, 0};
    281	struct ethtool_wolinfo *wol_conf = wol;
    282
    283	mutex_lock(&phydev->lock);
    284	rc = phy_select_page(phydev, MSCC_PHY_PAGE_EXTENDED_2);
    285	if (rc < 0) {
    286		rc = phy_restore_page(phydev, rc, rc);
    287		goto out_unlock;
    288	}
    289
    290	if (wol->wolopts & WAKE_MAGIC) {
    291		/* Store the device address for the magic packet */
    292		for (i = 0; i < ARRAY_SIZE(pwd); i++)
    293			pwd[i] = mac_addr[5 - (i * 2 + 1)] << 8 |
    294				 mac_addr[5 - i * 2];
    295		__phy_write(phydev, MSCC_PHY_WOL_LOWER_MAC_ADDR, pwd[0]);
    296		__phy_write(phydev, MSCC_PHY_WOL_MID_MAC_ADDR, pwd[1]);
    297		__phy_write(phydev, MSCC_PHY_WOL_UPPER_MAC_ADDR, pwd[2]);
    298	} else {
    299		__phy_write(phydev, MSCC_PHY_WOL_LOWER_MAC_ADDR, 0);
    300		__phy_write(phydev, MSCC_PHY_WOL_MID_MAC_ADDR, 0);
    301		__phy_write(phydev, MSCC_PHY_WOL_UPPER_MAC_ADDR, 0);
    302	}
    303
    304	if (wol_conf->wolopts & WAKE_MAGICSECURE) {
    305		for (i = 0; i < ARRAY_SIZE(pwd); i++)
    306			pwd[i] = wol_conf->sopass[5 - (i * 2 + 1)] << 8 |
    307				 wol_conf->sopass[5 - i * 2];
    308		__phy_write(phydev, MSCC_PHY_WOL_LOWER_PASSWD, pwd[0]);
    309		__phy_write(phydev, MSCC_PHY_WOL_MID_PASSWD, pwd[1]);
    310		__phy_write(phydev, MSCC_PHY_WOL_UPPER_PASSWD, pwd[2]);
    311	} else {
    312		__phy_write(phydev, MSCC_PHY_WOL_LOWER_PASSWD, 0);
    313		__phy_write(phydev, MSCC_PHY_WOL_MID_PASSWD, 0);
    314		__phy_write(phydev, MSCC_PHY_WOL_UPPER_PASSWD, 0);
    315	}
    316
    317	reg_val = __phy_read(phydev, MSCC_PHY_WOL_MAC_CONTROL);
    318	if (wol_conf->wolopts & WAKE_MAGICSECURE)
    319		reg_val |= SECURE_ON_ENABLE;
    320	else
    321		reg_val &= ~SECURE_ON_ENABLE;
    322	__phy_write(phydev, MSCC_PHY_WOL_MAC_CONTROL, reg_val);
    323
    324	rc = phy_restore_page(phydev, rc, rc > 0 ? 0 : rc);
    325	if (rc < 0)
    326		goto out_unlock;
    327
    328	if (wol->wolopts & WAKE_MAGIC) {
    329		/* Enable the WOL interrupt */
    330		reg_val = phy_read(phydev, MII_VSC85XX_INT_MASK);
    331		reg_val |= MII_VSC85XX_INT_MASK_WOL;
    332		rc = phy_write(phydev, MII_VSC85XX_INT_MASK, reg_val);
    333		if (rc)
    334			goto out_unlock;
    335	} else {
    336		/* Disable the WOL interrupt */
    337		reg_val = phy_read(phydev, MII_VSC85XX_INT_MASK);
    338		reg_val &= (~MII_VSC85XX_INT_MASK_WOL);
    339		rc = phy_write(phydev, MII_VSC85XX_INT_MASK, reg_val);
    340		if (rc)
    341			goto out_unlock;
    342	}
    343	/* Clear WOL iterrupt status */
    344	reg_val = phy_read(phydev, MII_VSC85XX_INT_STATUS);
    345
    346out_unlock:
    347	mutex_unlock(&phydev->lock);
    348
    349	return rc;
    350}
    351
    352static void vsc85xx_wol_get(struct phy_device *phydev,
    353			    struct ethtool_wolinfo *wol)
    354{
    355	int rc;
    356	u16 reg_val;
    357	u8  i;
    358	u16 pwd[3] = {0, 0, 0};
    359	struct ethtool_wolinfo *wol_conf = wol;
    360
    361	mutex_lock(&phydev->lock);
    362	rc = phy_select_page(phydev, MSCC_PHY_PAGE_EXTENDED_2);
    363	if (rc < 0)
    364		goto out_unlock;
    365
    366	reg_val = __phy_read(phydev, MSCC_PHY_WOL_MAC_CONTROL);
    367	if (reg_val & SECURE_ON_ENABLE)
    368		wol_conf->wolopts |= WAKE_MAGICSECURE;
    369	if (wol_conf->wolopts & WAKE_MAGICSECURE) {
    370		pwd[0] = __phy_read(phydev, MSCC_PHY_WOL_LOWER_PASSWD);
    371		pwd[1] = __phy_read(phydev, MSCC_PHY_WOL_MID_PASSWD);
    372		pwd[2] = __phy_read(phydev, MSCC_PHY_WOL_UPPER_PASSWD);
    373		for (i = 0; i < ARRAY_SIZE(pwd); i++) {
    374			wol_conf->sopass[5 - i * 2] = pwd[i] & 0x00ff;
    375			wol_conf->sopass[5 - (i * 2 + 1)] = (pwd[i] & 0xff00)
    376							    >> 8;
    377		}
    378	}
    379
    380out_unlock:
    381	phy_restore_page(phydev, rc, rc > 0 ? 0 : rc);
    382	mutex_unlock(&phydev->lock);
    383}
    384
    385#if IS_ENABLED(CONFIG_OF_MDIO)
    386static int vsc85xx_edge_rate_magic_get(struct phy_device *phydev)
    387{
    388	u32 vdd, sd;
    389	int i, j;
    390	struct device *dev = &phydev->mdio.dev;
    391	struct device_node *of_node = dev->of_node;
    392	u8 sd_array_size = ARRAY_SIZE(edge_table[0].slowdown);
    393
    394	if (!of_node)
    395		return -ENODEV;
    396
    397	if (of_property_read_u32(of_node, "vsc8531,vddmac", &vdd))
    398		vdd = MSCC_VDDMAC_3300;
    399
    400	if (of_property_read_u32(of_node, "vsc8531,edge-slowdown", &sd))
    401		sd = 0;
    402
    403	for (i = 0; i < ARRAY_SIZE(edge_table); i++)
    404		if (edge_table[i].vddmac == vdd)
    405			for (j = 0; j < sd_array_size; j++)
    406				if (edge_table[i].slowdown[j] == sd)
    407					return (sd_array_size - j - 1);
    408
    409	return -EINVAL;
    410}
    411
    412static int vsc85xx_dt_led_mode_get(struct phy_device *phydev,
    413				   char *led,
    414				   u32 default_mode)
    415{
    416	struct vsc8531_private *priv = phydev->priv;
    417	struct device *dev = &phydev->mdio.dev;
    418	struct device_node *of_node = dev->of_node;
    419	u32 led_mode;
    420	int err;
    421
    422	if (!of_node)
    423		return -ENODEV;
    424
    425	led_mode = default_mode;
    426	err = of_property_read_u32(of_node, led, &led_mode);
    427	if (!err && !(BIT(led_mode) & priv->supp_led_modes)) {
    428		phydev_err(phydev, "DT %s invalid\n", led);
    429		return -EINVAL;
    430	}
    431
    432	return led_mode;
    433}
    434
    435#else
    436static int vsc85xx_edge_rate_magic_get(struct phy_device *phydev)
    437{
    438	return 0;
    439}
    440
    441static int vsc85xx_dt_led_mode_get(struct phy_device *phydev,
    442				   char *led,
    443				   u8 default_mode)
    444{
    445	return default_mode;
    446}
    447#endif /* CONFIG_OF_MDIO */
    448
    449static int vsc85xx_dt_led_modes_get(struct phy_device *phydev,
    450				    u32 *default_mode)
    451{
    452	struct vsc8531_private *priv = phydev->priv;
    453	char led_dt_prop[28];
    454	int i, ret;
    455
    456	for (i = 0; i < priv->nleds; i++) {
    457		ret = sprintf(led_dt_prop, "vsc8531,led-%d-mode", i);
    458		if (ret < 0)
    459			return ret;
    460
    461		ret = vsc85xx_dt_led_mode_get(phydev, led_dt_prop,
    462					      default_mode[i]);
    463		if (ret < 0)
    464			return ret;
    465		priv->leds_mode[i] = ret;
    466	}
    467
    468	return 0;
    469}
    470
    471static int vsc85xx_edge_rate_cntl_set(struct phy_device *phydev, u8 edge_rate)
    472{
    473	int rc;
    474
    475	mutex_lock(&phydev->lock);
    476	rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2,
    477			      MSCC_PHY_WOL_MAC_CONTROL, EDGE_RATE_CNTL_MASK,
    478			      edge_rate << EDGE_RATE_CNTL_POS);
    479	mutex_unlock(&phydev->lock);
    480
    481	return rc;
    482}
    483
    484static int vsc85xx_mac_if_set(struct phy_device *phydev,
    485			      phy_interface_t interface)
    486{
    487	int rc;
    488	u16 reg_val;
    489
    490	mutex_lock(&phydev->lock);
    491	reg_val = phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_1);
    492	reg_val &= ~(MAC_IF_SELECTION_MASK);
    493	switch (interface) {
    494	case PHY_INTERFACE_MODE_RGMII_TXID:
    495	case PHY_INTERFACE_MODE_RGMII_RXID:
    496	case PHY_INTERFACE_MODE_RGMII_ID:
    497	case PHY_INTERFACE_MODE_RGMII:
    498		reg_val |= (MAC_IF_SELECTION_RGMII << MAC_IF_SELECTION_POS);
    499		break;
    500	case PHY_INTERFACE_MODE_RMII:
    501		reg_val |= (MAC_IF_SELECTION_RMII << MAC_IF_SELECTION_POS);
    502		break;
    503	case PHY_INTERFACE_MODE_MII:
    504	case PHY_INTERFACE_MODE_GMII:
    505		reg_val |= (MAC_IF_SELECTION_GMII << MAC_IF_SELECTION_POS);
    506		break;
    507	default:
    508		rc = -EINVAL;
    509		goto out_unlock;
    510	}
    511	rc = phy_write(phydev, MSCC_PHY_EXT_PHY_CNTL_1, reg_val);
    512	if (rc)
    513		goto out_unlock;
    514
    515	rc = genphy_soft_reset(phydev);
    516
    517out_unlock:
    518	mutex_unlock(&phydev->lock);
    519
    520	return rc;
    521}
    522
    523/* Set the RGMII RX and TX clock skews individually, according to the PHY
    524 * interface type, to:
    525 *  * 0.2 ns (their default, and lowest, hardware value) if delays should
    526 *    not be enabled
    527 *  * 2.0 ns (which causes the data to be sampled at exactly half way between
    528 *    clock transitions at 1000 Mbps) if delays should be enabled
    529 */
    530static int vsc85xx_rgmii_set_skews(struct phy_device *phydev, u32 rgmii_cntl,
    531				   u16 rgmii_rx_delay_mask,
    532				   u16 rgmii_tx_delay_mask)
    533{
    534	u16 rgmii_rx_delay_pos = ffs(rgmii_rx_delay_mask) - 1;
    535	u16 rgmii_tx_delay_pos = ffs(rgmii_tx_delay_mask) - 1;
    536	u16 reg_val = 0;
    537	int rc;
    538
    539	mutex_lock(&phydev->lock);
    540
    541	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID ||
    542	    phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
    543		reg_val |= RGMII_CLK_DELAY_2_0_NS << rgmii_rx_delay_pos;
    544	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID ||
    545	    phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
    546		reg_val |= RGMII_CLK_DELAY_2_0_NS << rgmii_tx_delay_pos;
    547
    548	rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2,
    549			      rgmii_cntl,
    550			      rgmii_rx_delay_mask | rgmii_tx_delay_mask,
    551			      reg_val);
    552
    553	mutex_unlock(&phydev->lock);
    554
    555	return rc;
    556}
    557
    558static int vsc85xx_default_config(struct phy_device *phydev)
    559{
    560	int rc;
    561
    562	phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
    563
    564	if (phy_interface_mode_is_rgmii(phydev->interface)) {
    565		rc = vsc85xx_rgmii_set_skews(phydev, VSC8502_RGMII_CNTL,
    566					     VSC8502_RGMII_RX_DELAY_MASK,
    567					     VSC8502_RGMII_TX_DELAY_MASK);
    568		if (rc)
    569			return rc;
    570	}
    571
    572	return 0;
    573}
    574
    575static int vsc85xx_get_tunable(struct phy_device *phydev,
    576			       struct ethtool_tunable *tuna, void *data)
    577{
    578	switch (tuna->id) {
    579	case ETHTOOL_PHY_DOWNSHIFT:
    580		return vsc85xx_downshift_get(phydev, (u8 *)data);
    581	default:
    582		return -EINVAL;
    583	}
    584}
    585
    586static int vsc85xx_set_tunable(struct phy_device *phydev,
    587			       struct ethtool_tunable *tuna,
    588			       const void *data)
    589{
    590	switch (tuna->id) {
    591	case ETHTOOL_PHY_DOWNSHIFT:
    592		return vsc85xx_downshift_set(phydev, *(u8 *)data);
    593	default:
    594		return -EINVAL;
    595	}
    596}
    597
    598/* mdiobus lock should be locked when using this function */
    599static void vsc85xx_tr_write(struct phy_device *phydev, u16 addr, u32 val)
    600{
    601	__phy_write(phydev, MSCC_PHY_TR_MSB, val >> 16);
    602	__phy_write(phydev, MSCC_PHY_TR_LSB, val & GENMASK(15, 0));
    603	__phy_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(addr));
    604}
    605
    606static int vsc8531_pre_init_seq_set(struct phy_device *phydev)
    607{
    608	int rc;
    609	static const struct reg_val init_seq[] = {
    610		{0x0f90, 0x00688980},
    611		{0x0696, 0x00000003},
    612		{0x07fa, 0x0050100f},
    613		{0x1686, 0x00000004},
    614	};
    615	unsigned int i;
    616	int oldpage;
    617
    618	rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_STANDARD,
    619			      MSCC_PHY_EXT_CNTL_STATUS, SMI_BROADCAST_WR_EN,
    620			      SMI_BROADCAST_WR_EN);
    621	if (rc < 0)
    622		return rc;
    623	rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_TEST,
    624			      MSCC_PHY_TEST_PAGE_24, 0, 0x0400);
    625	if (rc < 0)
    626		return rc;
    627	rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_TEST,
    628			      MSCC_PHY_TEST_PAGE_5, 0x0a00, 0x0e00);
    629	if (rc < 0)
    630		return rc;
    631	rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_TEST,
    632			      MSCC_PHY_TEST_PAGE_8, TR_CLK_DISABLE, TR_CLK_DISABLE);
    633	if (rc < 0)
    634		return rc;
    635
    636	mutex_lock(&phydev->lock);
    637	oldpage = phy_select_page(phydev, MSCC_PHY_PAGE_TR);
    638	if (oldpage < 0)
    639		goto out_unlock;
    640
    641	for (i = 0; i < ARRAY_SIZE(init_seq); i++)
    642		vsc85xx_tr_write(phydev, init_seq[i].reg, init_seq[i].val);
    643
    644out_unlock:
    645	oldpage = phy_restore_page(phydev, oldpage, oldpage);
    646	mutex_unlock(&phydev->lock);
    647
    648	return oldpage;
    649}
    650
    651static int vsc85xx_eee_init_seq_set(struct phy_device *phydev)
    652{
    653	static const struct reg_val init_eee[] = {
    654		{0x0f82, 0x0012b00a},
    655		{0x1686, 0x00000004},
    656		{0x168c, 0x00d2c46f},
    657		{0x17a2, 0x00000620},
    658		{0x16a0, 0x00eeffdd},
    659		{0x16a6, 0x00071448},
    660		{0x16a4, 0x0013132f},
    661		{0x16a8, 0x00000000},
    662		{0x0ffc, 0x00c0a028},
    663		{0x0fe8, 0x0091b06c},
    664		{0x0fea, 0x00041600},
    665		{0x0f80, 0x00000af4},
    666		{0x0fec, 0x00901809},
    667		{0x0fee, 0x0000a6a1},
    668		{0x0ffe, 0x00b01007},
    669		{0x16b0, 0x00eeff00},
    670		{0x16b2, 0x00007000},
    671		{0x16b4, 0x00000814},
    672	};
    673	unsigned int i;
    674	int oldpage;
    675
    676	mutex_lock(&phydev->lock);
    677	oldpage = phy_select_page(phydev, MSCC_PHY_PAGE_TR);
    678	if (oldpage < 0)
    679		goto out_unlock;
    680
    681	for (i = 0; i < ARRAY_SIZE(init_eee); i++)
    682		vsc85xx_tr_write(phydev, init_eee[i].reg, init_eee[i].val);
    683
    684out_unlock:
    685	oldpage = phy_restore_page(phydev, oldpage, oldpage);
    686	mutex_unlock(&phydev->lock);
    687
    688	return oldpage;
    689}
    690
    691/* phydev->bus->mdio_lock should be locked when using this function */
    692int phy_base_write(struct phy_device *phydev, u32 regnum, u16 val)
    693{
    694	if (unlikely(!mutex_is_locked(&phydev->mdio.bus->mdio_lock))) {
    695		dev_err(&phydev->mdio.dev, "MDIO bus lock not held!\n");
    696		dump_stack();
    697	}
    698
    699	return __phy_package_write(phydev, regnum, val);
    700}
    701
    702/* phydev->bus->mdio_lock should be locked when using this function */
    703int phy_base_read(struct phy_device *phydev, u32 regnum)
    704{
    705	if (unlikely(!mutex_is_locked(&phydev->mdio.bus->mdio_lock))) {
    706		dev_err(&phydev->mdio.dev, "MDIO bus lock not held!\n");
    707		dump_stack();
    708	}
    709
    710	return __phy_package_read(phydev, regnum);
    711}
    712
    713u32 vsc85xx_csr_read(struct phy_device *phydev,
    714		     enum csr_target target, u32 reg)
    715{
    716	unsigned long deadline;
    717	u32 val, val_l, val_h;
    718
    719	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_CSR_CNTL);
    720
    721	/* CSR registers are grouped under different Target IDs.
    722	 * 6-bit Target_ID is split between MSCC_EXT_PAGE_CSR_CNTL_20 and
    723	 * MSCC_EXT_PAGE_CSR_CNTL_19 registers.
    724	 * Target_ID[5:2] maps to bits[3:0] of MSCC_EXT_PAGE_CSR_CNTL_20
    725	 * and Target_ID[1:0] maps to bits[13:12] of MSCC_EXT_PAGE_CSR_CNTL_19.
    726	 */
    727
    728	/* Setup the Target ID */
    729	phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_20,
    730		       MSCC_PHY_CSR_CNTL_20_TARGET(target >> 2));
    731
    732	if ((target >> 2 == 0x1) || (target >> 2 == 0x3))
    733		/* non-MACsec access */
    734		target &= 0x3;
    735	else
    736		target = 0;
    737
    738	/* Trigger CSR Action - Read into the CSR's */
    739	phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_19,
    740		       MSCC_PHY_CSR_CNTL_19_CMD | MSCC_PHY_CSR_CNTL_19_READ |
    741		       MSCC_PHY_CSR_CNTL_19_REG_ADDR(reg) |
    742		       MSCC_PHY_CSR_CNTL_19_TARGET(target));
    743
    744	/* Wait for register access*/
    745	deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
    746	do {
    747		usleep_range(500, 1000);
    748		val = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_19);
    749	} while (time_before(jiffies, deadline) &&
    750		!(val & MSCC_PHY_CSR_CNTL_19_CMD));
    751
    752	if (!(val & MSCC_PHY_CSR_CNTL_19_CMD))
    753		return 0xffffffff;
    754
    755	/* Read the Least Significant Word (LSW) (17) */
    756	val_l = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_17);
    757
    758	/* Read the Most Significant Word (MSW) (18) */
    759	val_h = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_18);
    760
    761	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
    762		       MSCC_PHY_PAGE_STANDARD);
    763
    764	return (val_h << 16) | val_l;
    765}
    766
    767int vsc85xx_csr_write(struct phy_device *phydev,
    768		      enum csr_target target, u32 reg, u32 val)
    769{
    770	unsigned long deadline;
    771
    772	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_CSR_CNTL);
    773
    774	/* CSR registers are grouped under different Target IDs.
    775	 * 6-bit Target_ID is split between MSCC_EXT_PAGE_CSR_CNTL_20 and
    776	 * MSCC_EXT_PAGE_CSR_CNTL_19 registers.
    777	 * Target_ID[5:2] maps to bits[3:0] of MSCC_EXT_PAGE_CSR_CNTL_20
    778	 * and Target_ID[1:0] maps to bits[13:12] of MSCC_EXT_PAGE_CSR_CNTL_19.
    779	 */
    780
    781	/* Setup the Target ID */
    782	phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_20,
    783		       MSCC_PHY_CSR_CNTL_20_TARGET(target >> 2));
    784
    785	/* Write the Least Significant Word (LSW) (17) */
    786	phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_17, (u16)val);
    787
    788	/* Write the Most Significant Word (MSW) (18) */
    789	phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_18, (u16)(val >> 16));
    790
    791	if ((target >> 2 == 0x1) || (target >> 2 == 0x3))
    792		/* non-MACsec access */
    793		target &= 0x3;
    794	else
    795		target = 0;
    796
    797	/* Trigger CSR Action - Write into the CSR's */
    798	phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_19,
    799		       MSCC_PHY_CSR_CNTL_19_CMD |
    800		       MSCC_PHY_CSR_CNTL_19_REG_ADDR(reg) |
    801		       MSCC_PHY_CSR_CNTL_19_TARGET(target));
    802
    803	/* Wait for register access */
    804	deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
    805	do {
    806		usleep_range(500, 1000);
    807		val = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_19);
    808	} while (time_before(jiffies, deadline) &&
    809		 !(val & MSCC_PHY_CSR_CNTL_19_CMD));
    810
    811	if (!(val & MSCC_PHY_CSR_CNTL_19_CMD))
    812		return -ETIMEDOUT;
    813
    814	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
    815		       MSCC_PHY_PAGE_STANDARD);
    816
    817	return 0;
    818}
    819
    820/* bus->mdio_lock should be locked when using this function */
    821static void vsc8584_csr_write(struct phy_device *phydev, u16 addr, u32 val)
    822{
    823	phy_base_write(phydev, MSCC_PHY_TR_MSB, val >> 16);
    824	phy_base_write(phydev, MSCC_PHY_TR_LSB, val & GENMASK(15, 0));
    825	phy_base_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(addr));
    826}
    827
    828/* bus->mdio_lock should be locked when using this function */
    829int vsc8584_cmd(struct phy_device *phydev, u16 val)
    830{
    831	unsigned long deadline;
    832	u16 reg_val;
    833
    834	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
    835		       MSCC_PHY_PAGE_EXTENDED_GPIO);
    836
    837	phy_base_write(phydev, MSCC_PHY_PROC_CMD, PROC_CMD_NCOMPLETED | val);
    838
    839	deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
    840	do {
    841		reg_val = phy_base_read(phydev, MSCC_PHY_PROC_CMD);
    842	} while (time_before(jiffies, deadline) &&
    843		 (reg_val & PROC_CMD_NCOMPLETED) &&
    844		 !(reg_val & PROC_CMD_FAILED));
    845
    846	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
    847
    848	if (reg_val & PROC_CMD_FAILED)
    849		return -EIO;
    850
    851	if (reg_val & PROC_CMD_NCOMPLETED)
    852		return -ETIMEDOUT;
    853
    854	return 0;
    855}
    856
    857/* bus->mdio_lock should be locked when using this function */
    858static int vsc8584_micro_deassert_reset(struct phy_device *phydev,
    859					bool patch_en)
    860{
    861	u32 enable, release;
    862
    863	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
    864		       MSCC_PHY_PAGE_EXTENDED_GPIO);
    865
    866	enable = RUN_FROM_INT_ROM | MICRO_CLK_EN | DW8051_CLK_EN;
    867	release = MICRO_NSOFT_RESET | RUN_FROM_INT_ROM | DW8051_CLK_EN |
    868		MICRO_CLK_EN;
    869
    870	if (patch_en) {
    871		enable |= MICRO_PATCH_EN;
    872		release |= MICRO_PATCH_EN;
    873
    874		/* Clear all patches */
    875		phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_RAM);
    876	}
    877
    878	/* Enable 8051 Micro clock; CLEAR/SET patch present; disable PRAM clock
    879	 * override and addr. auto-incr; operate at 125 MHz
    880	 */
    881	phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, enable);
    882	/* Release 8051 Micro SW reset */
    883	phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, release);
    884
    885	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
    886
    887	return 0;
    888}
    889
    890/* bus->mdio_lock should be locked when using this function */
    891static int vsc8584_micro_assert_reset(struct phy_device *phydev)
    892{
    893	int ret;
    894	u16 reg;
    895
    896	ret = vsc8584_cmd(phydev, PROC_CMD_NOP);
    897	if (ret)
    898		return ret;
    899
    900	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
    901		       MSCC_PHY_PAGE_EXTENDED_GPIO);
    902
    903	reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
    904	reg &= ~EN_PATCH_RAM_TRAP_ADDR(4);
    905	phy_base_write(phydev, MSCC_INT_MEM_CNTL, reg);
    906
    907	phy_base_write(phydev, MSCC_TRAP_ROM_ADDR(4), 0x005b);
    908	phy_base_write(phydev, MSCC_PATCH_RAM_ADDR(4), 0x005b);
    909
    910	reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
    911	reg |= EN_PATCH_RAM_TRAP_ADDR(4);
    912	phy_base_write(phydev, MSCC_INT_MEM_CNTL, reg);
    913
    914	phy_base_write(phydev, MSCC_PHY_PROC_CMD, PROC_CMD_NOP);
    915
    916	reg = phy_base_read(phydev, MSCC_DW8051_CNTL_STATUS);
    917	reg &= ~MICRO_NSOFT_RESET;
    918	phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, reg);
    919
    920	phy_base_write(phydev, MSCC_PHY_PROC_CMD, PROC_CMD_MCB_ACCESS_MAC_CONF |
    921		       PROC_CMD_SGMII_PORT(0) | PROC_CMD_NO_MAC_CONF |
    922		       PROC_CMD_READ);
    923
    924	reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
    925	reg &= ~EN_PATCH_RAM_TRAP_ADDR(4);
    926	phy_base_write(phydev, MSCC_INT_MEM_CNTL, reg);
    927
    928	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
    929
    930	return 0;
    931}
    932
    933/* bus->mdio_lock should be locked when using this function */
    934static int vsc8584_get_fw_crc(struct phy_device *phydev, u16 start, u16 size,
    935			      u16 *crc)
    936{
    937	int ret;
    938
    939	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
    940
    941	phy_base_write(phydev, MSCC_PHY_VERIPHY_CNTL_2, start);
    942	phy_base_write(phydev, MSCC_PHY_VERIPHY_CNTL_3, size);
    943
    944	/* Start Micro command */
    945	ret = vsc8584_cmd(phydev, PROC_CMD_CRC16);
    946	if (ret)
    947		goto out;
    948
    949	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
    950
    951	*crc = phy_base_read(phydev, MSCC_PHY_VERIPHY_CNTL_2);
    952
    953out:
    954	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
    955
    956	return ret;
    957}
    958
    959/* bus->mdio_lock should be locked when using this function */
    960static int vsc8584_patch_fw(struct phy_device *phydev,
    961			    const struct firmware *fw)
    962{
    963	int i, ret;
    964
    965	ret = vsc8584_micro_assert_reset(phydev);
    966	if (ret) {
    967		dev_err(&phydev->mdio.dev,
    968			"%s: failed to assert reset of micro\n", __func__);
    969		return ret;
    970	}
    971
    972	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
    973		       MSCC_PHY_PAGE_EXTENDED_GPIO);
    974
    975	/* Hold 8051 Micro in SW Reset, Enable auto incr address and patch clock
    976	 * Disable the 8051 Micro clock
    977	 */
    978	phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, RUN_FROM_INT_ROM |
    979		       AUTOINC_ADDR | PATCH_RAM_CLK | MICRO_CLK_EN |
    980		       MICRO_CLK_DIVIDE(2));
    981	phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_PRAM | INT_MEM_WRITE_EN |
    982		       INT_MEM_DATA(2));
    983	phy_base_write(phydev, MSCC_INT_MEM_ADDR, 0x0000);
    984
    985	for (i = 0; i < fw->size; i++)
    986		phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_PRAM |
    987			       INT_MEM_WRITE_EN | fw->data[i]);
    988
    989	/* Clear internal memory access */
    990	phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_RAM);
    991
    992	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
    993
    994	return 0;
    995}
    996
    997/* bus->mdio_lock should be locked when using this function */
    998static bool vsc8574_is_serdes_init(struct phy_device *phydev)
    999{
   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;
   1032out:
   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 */
   1039static 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
   1233out:
   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 */
   1242static 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 */
   1254static 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 */
   1270static 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 */
   1287static 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);
   1323done:
   1324	return ret;
   1325}
   1326
   1327/* bus->mdio_lock should be locked when using this function */
   1328static 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
   1495out:
   1496	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
   1497
   1498	release_firmware(fw);
   1499
   1500	return ret;
   1501}
   1502
   1503static 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
   1543static 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
   1558static 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
   1623static 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
   1688static 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
   1789err:
   1790	phy_unlock_mdio_bus(phydev);
   1791	return ret;
   1792}
   1793
   1794static 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
   1819static 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
   1857static 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 */
   1886int 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 */
   1892int 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
   1897static 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
   1951static 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
   2058static 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
   2109err:
   2110	phy_unlock_mdio_bus(phydev);
   2111	return ret;
   2112}
   2113
   2114static 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
   2124static 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
   2152static 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
   2170static 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
   2181static 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
   2192static 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
   2221static 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
   2250static 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
   2295static 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 */
   2326static 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
   2664module_phy_driver(vsc85xx_driver);
   2665
   2666static 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
   2683MODULE_DEVICE_TABLE(mdio, vsc85xx_tbl);
   2684
   2685MODULE_DESCRIPTION("Microsemi VSC85xx PHY driver");
   2686MODULE_AUTHOR("Nagaraju Lakkaraju");
   2687MODULE_LICENSE("Dual MIT/GPL");
   2688
   2689MODULE_FIRMWARE(MSCC_VSC8584_REVB_INT8051_FW);
   2690MODULE_FIRMWARE(MSCC_VSC8574_REVB_INT8051_FW);