Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.4.
   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 const int vsc85xx_internal_delay[] = {200, 800, 1100, 1700, 2000, 2300,
 111					     2600, 3400};
 112
 113static int vsc85xx_phy_read_page(struct phy_device *phydev)
 114{
 115	return __phy_read(phydev, MSCC_EXT_PAGE_ACCESS);
 116}
 117
 118static int vsc85xx_phy_write_page(struct phy_device *phydev, int page)
 119{
 120	return __phy_write(phydev, MSCC_EXT_PAGE_ACCESS, page);
 121}
 122
 123static int vsc85xx_get_sset_count(struct phy_device *phydev)
 124{
 125	struct vsc8531_private *priv = phydev->priv;
 126
 127	if (!priv)
 128		return 0;
 129
 130	return priv->nstats;
 131}
 132
 133static void vsc85xx_get_strings(struct phy_device *phydev, u8 *data)
 134{
 135	struct vsc8531_private *priv = phydev->priv;
 136	int i;
 137
 138	if (!priv)
 139		return;
 140
 141	for (i = 0; i < priv->nstats; i++)
 142		ethtool_puts(&data, priv->hw_stats[i].string);
 143}
 144
 145static u64 vsc85xx_get_stat(struct phy_device *phydev, int i)
 146{
 147	struct vsc8531_private *priv = phydev->priv;
 148	int val;
 149
 150	val = phy_read_paged(phydev, priv->hw_stats[i].page,
 151			     priv->hw_stats[i].reg);
 152	if (val < 0)
 153		return U64_MAX;
 154
 155	val = val & priv->hw_stats[i].mask;
 156	priv->stats[i] += val;
 157
 158	return priv->stats[i];
 159}
 160
 161static void vsc85xx_get_stats(struct phy_device *phydev,
 162			      struct ethtool_stats *stats, u64 *data)
 163{
 164	struct vsc8531_private *priv = phydev->priv;
 165	int i;
 166
 167	if (!priv)
 168		return;
 169
 170	for (i = 0; i < priv->nstats; i++)
 171		data[i] = vsc85xx_get_stat(phydev, i);
 172}
 173
 174static int vsc85xx_led_cntl_set(struct phy_device *phydev,
 175				u8 led_num,
 176				u8 mode)
 177{
 178	int rc;
 179	u16 reg_val;
 180
 181	mutex_lock(&phydev->lock);
 182	reg_val = phy_read(phydev, MSCC_PHY_LED_MODE_SEL);
 183	reg_val &= ~LED_MODE_SEL_MASK(led_num);
 184	reg_val |= LED_MODE_SEL(led_num, (u16)mode);
 185	rc = phy_write(phydev, MSCC_PHY_LED_MODE_SEL, reg_val);
 186	mutex_unlock(&phydev->lock);
 187
 188	return rc;
 189}
 190
 191static int vsc85xx_mdix_get(struct phy_device *phydev, u8 *mdix)
 192{
 193	u16 reg_val;
 194
 195	reg_val = phy_read(phydev, MSCC_PHY_DEV_AUX_CNTL);
 196	if (reg_val & HP_AUTO_MDIX_X_OVER_IND_MASK)
 197		*mdix = ETH_TP_MDI_X;
 198	else
 199		*mdix = ETH_TP_MDI;
 200
 201	return 0;
 202}
 203
 204static int vsc85xx_mdix_set(struct phy_device *phydev, u8 mdix)
 205{
 206	int rc;
 207	u16 reg_val;
 208
 209	reg_val = phy_read(phydev, MSCC_PHY_BYPASS_CONTROL);
 210	if (mdix == ETH_TP_MDI || mdix == ETH_TP_MDI_X) {
 211		reg_val |= (DISABLE_PAIR_SWAP_CORR_MASK |
 212			    DISABLE_POLARITY_CORR_MASK  |
 213			    DISABLE_HP_AUTO_MDIX_MASK);
 214	} else {
 215		reg_val &= ~(DISABLE_PAIR_SWAP_CORR_MASK |
 216			     DISABLE_POLARITY_CORR_MASK  |
 217			     DISABLE_HP_AUTO_MDIX_MASK);
 218	}
 219	rc = phy_write(phydev, MSCC_PHY_BYPASS_CONTROL, reg_val);
 220	if (rc)
 221		return rc;
 222
 223	reg_val = 0;
 224
 225	if (mdix == ETH_TP_MDI)
 226		reg_val = FORCE_MDI_CROSSOVER_MDI;
 227	else if (mdix == ETH_TP_MDI_X)
 228		reg_val = FORCE_MDI_CROSSOVER_MDIX;
 229
 230	rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED,
 231			      MSCC_PHY_EXT_MODE_CNTL, FORCE_MDI_CROSSOVER_MASK,
 232			      reg_val);
 233	if (rc < 0)
 234		return rc;
 235
 236	return genphy_restart_aneg(phydev);
 237}
 238
 239static int vsc85xx_downshift_get(struct phy_device *phydev, u8 *count)
 240{
 241	int reg_val;
 242
 243	reg_val = phy_read_paged(phydev, MSCC_PHY_PAGE_EXTENDED,
 244				 MSCC_PHY_ACTIPHY_CNTL);
 245	if (reg_val < 0)
 246		return reg_val;
 247
 248	reg_val &= DOWNSHIFT_CNTL_MASK;
 249	if (!(reg_val & DOWNSHIFT_EN))
 250		*count = DOWNSHIFT_DEV_DISABLE;
 251	else
 252		*count = ((reg_val & ~DOWNSHIFT_EN) >> DOWNSHIFT_CNTL_POS) + 2;
 253
 254	return 0;
 255}
 256
 257static int vsc85xx_downshift_set(struct phy_device *phydev, u8 count)
 258{
 259	if (count == DOWNSHIFT_DEV_DEFAULT_COUNT) {
 260		/* Default downshift count 3 (i.e. Bit3:2 = 0b01) */
 261		count = ((1 << DOWNSHIFT_CNTL_POS) | DOWNSHIFT_EN);
 262	} else if (count > DOWNSHIFT_COUNT_MAX || count == 1) {
 263		phydev_err(phydev, "Downshift count should be 2,3,4 or 5\n");
 264		return -ERANGE;
 265	} else if (count) {
 266		/* Downshift count is either 2,3,4 or 5 */
 267		count = (((count - 2) << DOWNSHIFT_CNTL_POS) | DOWNSHIFT_EN);
 268	}
 269
 270	return phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED,
 271				MSCC_PHY_ACTIPHY_CNTL, DOWNSHIFT_CNTL_MASK,
 272				count);
 273}
 274
 275static int vsc85xx_wol_set(struct phy_device *phydev,
 276			   struct ethtool_wolinfo *wol)
 277{
 278	const u8 *mac_addr = phydev->attached_dev->dev_addr;
 279	int rc;
 280	u16 reg_val;
 281	u8  i;
 282	u16 pwd[3] = {0, 0, 0};
 283	struct ethtool_wolinfo *wol_conf = wol;
 284
 285	rc = phy_select_page(phydev, MSCC_PHY_PAGE_EXTENDED_2);
 286	if (rc < 0)
 287		return phy_restore_page(phydev, rc, rc);
 288
 289	if (wol->wolopts & WAKE_MAGIC) {
 290		/* Store the device address for the magic packet */
 291		for (i = 0; i < ARRAY_SIZE(pwd); i++)
 292			pwd[i] = mac_addr[5 - (i * 2 + 1)] << 8 |
 293				 mac_addr[5 - i * 2];
 294		__phy_write(phydev, MSCC_PHY_WOL_LOWER_MAC_ADDR, pwd[0]);
 295		__phy_write(phydev, MSCC_PHY_WOL_MID_MAC_ADDR, pwd[1]);
 296		__phy_write(phydev, MSCC_PHY_WOL_UPPER_MAC_ADDR, pwd[2]);
 297	} else {
 298		__phy_write(phydev, MSCC_PHY_WOL_LOWER_MAC_ADDR, 0);
 299		__phy_write(phydev, MSCC_PHY_WOL_MID_MAC_ADDR, 0);
 300		__phy_write(phydev, MSCC_PHY_WOL_UPPER_MAC_ADDR, 0);
 301	}
 302
 303	if (wol_conf->wolopts & WAKE_MAGICSECURE) {
 304		for (i = 0; i < ARRAY_SIZE(pwd); i++)
 305			pwd[i] = wol_conf->sopass[5 - (i * 2 + 1)] << 8 |
 306				 wol_conf->sopass[5 - i * 2];
 307		__phy_write(phydev, MSCC_PHY_WOL_LOWER_PASSWD, pwd[0]);
 308		__phy_write(phydev, MSCC_PHY_WOL_MID_PASSWD, pwd[1]);
 309		__phy_write(phydev, MSCC_PHY_WOL_UPPER_PASSWD, pwd[2]);
 310	} else {
 311		__phy_write(phydev, MSCC_PHY_WOL_LOWER_PASSWD, 0);
 312		__phy_write(phydev, MSCC_PHY_WOL_MID_PASSWD, 0);
 313		__phy_write(phydev, MSCC_PHY_WOL_UPPER_PASSWD, 0);
 314	}
 315
 316	reg_val = __phy_read(phydev, MSCC_PHY_WOL_MAC_CONTROL);
 317	if (wol_conf->wolopts & WAKE_MAGICSECURE)
 318		reg_val |= SECURE_ON_ENABLE;
 319	else
 320		reg_val &= ~SECURE_ON_ENABLE;
 321	__phy_write(phydev, MSCC_PHY_WOL_MAC_CONTROL, reg_val);
 322
 323	rc = phy_restore_page(phydev, rc, rc > 0 ? 0 : rc);
 324	if (rc < 0)
 325		return rc;
 326
 327	if (wol->wolopts & WAKE_MAGIC) {
 328		/* Enable the WOL interrupt */
 329		reg_val = phy_read(phydev, MII_VSC85XX_INT_MASK);
 330		reg_val |= MII_VSC85XX_INT_MASK_WOL;
 331		rc = phy_write(phydev, MII_VSC85XX_INT_MASK, reg_val);
 332		if (rc)
 333			return rc;
 334	} else {
 335		/* Disable the WOL interrupt */
 336		reg_val = phy_read(phydev, MII_VSC85XX_INT_MASK);
 337		reg_val &= (~MII_VSC85XX_INT_MASK_WOL);
 338		rc = phy_write(phydev, MII_VSC85XX_INT_MASK, reg_val);
 339		if (rc)
 340			return rc;
 341	}
 342	/* Clear WOL iterrupt status */
 343	reg_val = phy_read(phydev, MII_VSC85XX_INT_STATUS);
 344
 345	return 0;
 346}
 347
 348static void vsc85xx_wol_get(struct phy_device *phydev,
 349			    struct ethtool_wolinfo *wol)
 350{
 351	int rc;
 352	u16 reg_val;
 353	u8  i;
 354	u16 pwd[3] = {0, 0, 0};
 355	struct ethtool_wolinfo *wol_conf = wol;
 356
 357	rc = phy_select_page(phydev, MSCC_PHY_PAGE_EXTENDED_2);
 358	if (rc < 0)
 359		goto out_restore_page;
 360
 361	reg_val = __phy_read(phydev, MSCC_PHY_WOL_MAC_CONTROL);
 362	if (reg_val & SECURE_ON_ENABLE)
 363		wol_conf->wolopts |= WAKE_MAGICSECURE;
 364	if (wol_conf->wolopts & WAKE_MAGICSECURE) {
 365		pwd[0] = __phy_read(phydev, MSCC_PHY_WOL_LOWER_PASSWD);
 366		pwd[1] = __phy_read(phydev, MSCC_PHY_WOL_MID_PASSWD);
 367		pwd[2] = __phy_read(phydev, MSCC_PHY_WOL_UPPER_PASSWD);
 368		for (i = 0; i < ARRAY_SIZE(pwd); i++) {
 369			wol_conf->sopass[5 - i * 2] = pwd[i] & 0x00ff;
 370			wol_conf->sopass[5 - (i * 2 + 1)] = (pwd[i] & 0xff00)
 371							    >> 8;
 372		}
 373	}
 374
 375out_restore_page:
 376	phy_restore_page(phydev, rc, rc > 0 ? 0 : rc);
 377}
 378
 379#if IS_ENABLED(CONFIG_OF_MDIO)
 380static int vsc85xx_edge_rate_magic_get(struct phy_device *phydev)
 381{
 382	u32 vdd, sd;
 383	int i, j;
 384	struct device *dev = &phydev->mdio.dev;
 385	struct device_node *of_node = dev->of_node;
 386	u8 sd_array_size = ARRAY_SIZE(edge_table[0].slowdown);
 387
 388	if (!of_node)
 389		return -ENODEV;
 390
 391	if (of_property_read_u32(of_node, "vsc8531,vddmac", &vdd))
 392		vdd = MSCC_VDDMAC_3300;
 393
 394	if (of_property_read_u32(of_node, "vsc8531,edge-slowdown", &sd))
 395		sd = 0;
 396
 397	for (i = 0; i < ARRAY_SIZE(edge_table); i++)
 398		if (edge_table[i].vddmac == vdd)
 399			for (j = 0; j < sd_array_size; j++)
 400				if (edge_table[i].slowdown[j] == sd)
 401					return (sd_array_size - j - 1);
 402
 403	return -EINVAL;
 404}
 405
 406static int vsc85xx_dt_led_mode_get(struct phy_device *phydev,
 407				   char *led,
 408				   u32 default_mode)
 409{
 410	struct vsc8531_private *priv = phydev->priv;
 411	struct device *dev = &phydev->mdio.dev;
 412	struct device_node *of_node = dev->of_node;
 413	u32 led_mode;
 414	int err;
 415
 416	if (!of_node)
 417		return -ENODEV;
 418
 419	led_mode = default_mode;
 420	err = of_property_read_u32(of_node, led, &led_mode);
 421	if (!err && !(BIT(led_mode) & priv->supp_led_modes)) {
 422		phydev_err(phydev, "DT %s invalid\n", led);
 423		return -EINVAL;
 424	}
 425
 426	return led_mode;
 427}
 428
 429#else
 430static int vsc85xx_edge_rate_magic_get(struct phy_device *phydev)
 431{
 432	return 0;
 433}
 434
 435static int vsc85xx_dt_led_mode_get(struct phy_device *phydev,
 436				   char *led,
 437				   u8 default_mode)
 438{
 439	return default_mode;
 440}
 441#endif /* CONFIG_OF_MDIO */
 442
 443static int vsc85xx_dt_led_modes_get(struct phy_device *phydev,
 444				    u32 *default_mode)
 445{
 446	struct vsc8531_private *priv = phydev->priv;
 447	char led_dt_prop[28];
 448	int i, ret;
 449
 450	for (i = 0; i < priv->nleds; i++) {
 451		ret = sprintf(led_dt_prop, "vsc8531,led-%d-mode", i);
 452		if (ret < 0)
 453			return ret;
 454
 455		ret = vsc85xx_dt_led_mode_get(phydev, led_dt_prop,
 456					      default_mode[i]);
 457		if (ret < 0)
 458			return ret;
 459		priv->leds_mode[i] = ret;
 460	}
 461
 462	return 0;
 463}
 464
 465static int vsc85xx_edge_rate_cntl_set(struct phy_device *phydev, u8 edge_rate)
 466{
 467	int rc;
 468
 469	mutex_lock(&phydev->lock);
 470	rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2,
 471			      MSCC_PHY_WOL_MAC_CONTROL, EDGE_RATE_CNTL_MASK,
 472			      edge_rate << EDGE_RATE_CNTL_POS);
 473	mutex_unlock(&phydev->lock);
 474
 475	return rc;
 476}
 477
 478static int vsc85xx_mac_if_set(struct phy_device *phydev,
 479			      phy_interface_t interface)
 480{
 481	int rc;
 482	u16 reg_val;
 483
 484	mutex_lock(&phydev->lock);
 485	reg_val = phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_1);
 486	reg_val &= ~(MAC_IF_SELECTION_MASK);
 487	switch (interface) {
 488	case PHY_INTERFACE_MODE_RGMII_TXID:
 489	case PHY_INTERFACE_MODE_RGMII_RXID:
 490	case PHY_INTERFACE_MODE_RGMII_ID:
 491	case PHY_INTERFACE_MODE_RGMII:
 492		reg_val |= (MAC_IF_SELECTION_RGMII << MAC_IF_SELECTION_POS);
 493		break;
 494	case PHY_INTERFACE_MODE_RMII:
 495		reg_val |= (MAC_IF_SELECTION_RMII << MAC_IF_SELECTION_POS);
 496		break;
 497	case PHY_INTERFACE_MODE_MII:
 498	case PHY_INTERFACE_MODE_GMII:
 499		reg_val |= (MAC_IF_SELECTION_GMII << MAC_IF_SELECTION_POS);
 500		break;
 501	default:
 502		rc = -EINVAL;
 503		goto out_unlock;
 504	}
 505	rc = phy_write(phydev, MSCC_PHY_EXT_PHY_CNTL_1, reg_val);
 506	if (rc)
 507		goto out_unlock;
 508
 509	rc = genphy_soft_reset(phydev);
 510
 511out_unlock:
 512	mutex_unlock(&phydev->lock);
 513
 514	return rc;
 515}
 516
 517/* Set the RGMII RX and TX clock skews individually, according to the PHY
 518 * interface type, to:
 519 *  * 0.2 ns (their default, and lowest, hardware value) if delays should
 520 *    not be enabled
 521 *  * 2.0 ns (which causes the data to be sampled at exactly half way between
 522 *    clock transitions at 1000 Mbps) if delays should be enabled
 523 */
 524static int vsc85xx_update_rgmii_cntl(struct phy_device *phydev, u32 rgmii_cntl,
 525				     u16 rgmii_rx_delay_mask,
 526				     u16 rgmii_tx_delay_mask)
 527{
 528	u16 rgmii_rx_delay_pos = ffs(rgmii_rx_delay_mask) - 1;
 529	u16 rgmii_tx_delay_pos = ffs(rgmii_tx_delay_mask) - 1;
 530	int delay_size = ARRAY_SIZE(vsc85xx_internal_delay);
 531	struct device *dev = &phydev->mdio.dev;
 532	u16 reg_val = 0;
 533	u16 mask = 0;
 534	s32 rx_delay;
 535	s32 tx_delay;
 536	int rc = 0;
 537
 538	/* For traffic to pass, the VSC8502 family needs the RX_CLK disable bit
 539	 * to be unset for all PHY modes, so do that as part of the paged
 540	 * register modification.
 541	 * For some family members (like VSC8530/31/40/41) this bit is reserved
 542	 * and read-only, and the RX clock is enabled by default.
 543	 */
 544	if (rgmii_cntl == VSC8502_RGMII_CNTL)
 545		mask |= VSC8502_RGMII_RX_CLK_DISABLE;
 546
 547	if (phy_interface_is_rgmii(phydev))
 548		mask |= rgmii_rx_delay_mask | rgmii_tx_delay_mask;
 549
 550	rx_delay = phy_get_internal_delay(phydev, dev, vsc85xx_internal_delay,
 551					  delay_size, true);
 552	if (rx_delay < 0) {
 553		if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID ||
 554		    phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
 555			rx_delay = RGMII_CLK_DELAY_2_0_NS;
 556		else
 557			rx_delay = RGMII_CLK_DELAY_0_2_NS;
 558	}
 559
 560	tx_delay = phy_get_internal_delay(phydev, dev, vsc85xx_internal_delay,
 561					  delay_size, false);
 562	if (tx_delay < 0) {
 563		if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID ||
 564		    phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
 565			tx_delay = RGMII_CLK_DELAY_2_0_NS;
 566		else
 567			tx_delay = RGMII_CLK_DELAY_0_2_NS;
 568	}
 569
 570	reg_val |= rx_delay << rgmii_rx_delay_pos;
 571	reg_val |= tx_delay << rgmii_tx_delay_pos;
 572
 573	if (mask)
 574		rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2,
 575				      rgmii_cntl, mask, reg_val);
 576
 577	return rc;
 578}
 579
 580static int vsc85xx_default_config(struct phy_device *phydev)
 581{
 582	phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
 583
 584	return vsc85xx_update_rgmii_cntl(phydev, VSC8502_RGMII_CNTL,
 585					 VSC8502_RGMII_RX_DELAY_MASK,
 586					 VSC8502_RGMII_TX_DELAY_MASK);
 587}
 588
 589static int vsc85xx_get_tunable(struct phy_device *phydev,
 590			       struct ethtool_tunable *tuna, void *data)
 591{
 592	switch (tuna->id) {
 593	case ETHTOOL_PHY_DOWNSHIFT:
 594		return vsc85xx_downshift_get(phydev, (u8 *)data);
 595	default:
 596		return -EINVAL;
 597	}
 598}
 599
 600static int vsc85xx_set_tunable(struct phy_device *phydev,
 601			       struct ethtool_tunable *tuna,
 602			       const void *data)
 603{
 604	switch (tuna->id) {
 605	case ETHTOOL_PHY_DOWNSHIFT:
 606		return vsc85xx_downshift_set(phydev, *(u8 *)data);
 607	default:
 608		return -EINVAL;
 609	}
 610}
 611
 612/* mdiobus lock should be locked when using this function */
 613static void vsc85xx_tr_write(struct phy_device *phydev, u16 addr, u32 val)
 614{
 615	__phy_write(phydev, MSCC_PHY_TR_MSB, val >> 16);
 616	__phy_write(phydev, MSCC_PHY_TR_LSB, val & GENMASK(15, 0));
 617	__phy_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(addr));
 618}
 619
 620static int vsc8531_pre_init_seq_set(struct phy_device *phydev)
 621{
 622	int rc;
 623	static const struct reg_val init_seq[] = {
 624		{0x0f90, 0x00688980},
 625		{0x0696, 0x00000003},
 626		{0x07fa, 0x0050100f},
 627		{0x1686, 0x00000004},
 628	};
 629	unsigned int i;
 630	int oldpage;
 631
 632	rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_STANDARD,
 633			      MSCC_PHY_EXT_CNTL_STATUS, SMI_BROADCAST_WR_EN,
 634			      SMI_BROADCAST_WR_EN);
 635	if (rc < 0)
 636		return rc;
 637	rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_TEST,
 638			      MSCC_PHY_TEST_PAGE_24, 0, 0x0400);
 639	if (rc < 0)
 640		return rc;
 641	rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_TEST,
 642			      MSCC_PHY_TEST_PAGE_5, 0x0a00, 0x0e00);
 643	if (rc < 0)
 644		return rc;
 645	rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_TEST,
 646			      MSCC_PHY_TEST_PAGE_8, TR_CLK_DISABLE, TR_CLK_DISABLE);
 647	if (rc < 0)
 648		return rc;
 649
 650	mutex_lock(&phydev->lock);
 651	oldpage = phy_select_page(phydev, MSCC_PHY_PAGE_TR);
 652	if (oldpage < 0)
 653		goto out_unlock;
 654
 655	for (i = 0; i < ARRAY_SIZE(init_seq); i++)
 656		vsc85xx_tr_write(phydev, init_seq[i].reg, init_seq[i].val);
 657
 658out_unlock:
 659	oldpage = phy_restore_page(phydev, oldpage, oldpage);
 660	mutex_unlock(&phydev->lock);
 661
 662	return oldpage;
 663}
 664
 665static int vsc85xx_eee_init_seq_set(struct phy_device *phydev)
 666{
 667	static const struct reg_val init_eee[] = {
 668		{0x0f82, 0x0012b00a},
 669		{0x1686, 0x00000004},
 670		{0x168c, 0x00d2c46f},
 671		{0x17a2, 0x00000620},
 672		{0x16a0, 0x00eeffdd},
 673		{0x16a6, 0x00071448},
 674		{0x16a4, 0x0013132f},
 675		{0x16a8, 0x00000000},
 676		{0x0ffc, 0x00c0a028},
 677		{0x0fe8, 0x0091b06c},
 678		{0x0fea, 0x00041600},
 679		{0x0f80, 0x00000af4},
 680		{0x0fec, 0x00901809},
 681		{0x0fee, 0x0000a6a1},
 682		{0x0ffe, 0x00b01007},
 683		{0x16b0, 0x00eeff00},
 684		{0x16b2, 0x00007000},
 685		{0x16b4, 0x00000814},
 686	};
 687	unsigned int i;
 688	int oldpage;
 689
 690	mutex_lock(&phydev->lock);
 691	oldpage = phy_select_page(phydev, MSCC_PHY_PAGE_TR);
 692	if (oldpage < 0)
 693		goto out_unlock;
 694
 695	for (i = 0; i < ARRAY_SIZE(init_eee); i++)
 696		vsc85xx_tr_write(phydev, init_eee[i].reg, init_eee[i].val);
 697
 698out_unlock:
 699	oldpage = phy_restore_page(phydev, oldpage, oldpage);
 700	mutex_unlock(&phydev->lock);
 701
 702	return oldpage;
 703}
 704
 705/* phydev->bus->mdio_lock should be locked when using this function */
 706int phy_base_write(struct phy_device *phydev, u32 regnum, u16 val)
 707{
 708	if (unlikely(!mutex_is_locked(&phydev->mdio.bus->mdio_lock))) {
 709		dev_err(&phydev->mdio.dev, "MDIO bus lock not held!\n");
 710		dump_stack();
 711	}
 712
 713	return __phy_package_write(phydev, VSC88XX_BASE_ADDR, regnum, val);
 714}
 715
 716/* phydev->bus->mdio_lock should be locked when using this function */
 717int phy_base_read(struct phy_device *phydev, u32 regnum)
 718{
 719	if (unlikely(!mutex_is_locked(&phydev->mdio.bus->mdio_lock))) {
 720		dev_err(&phydev->mdio.dev, "MDIO bus lock not held!\n");
 721		dump_stack();
 722	}
 723
 724	return __phy_package_read(phydev, VSC88XX_BASE_ADDR, regnum);
 725}
 726
 727u32 vsc85xx_csr_read(struct phy_device *phydev,
 728		     enum csr_target target, u32 reg)
 729{
 730	unsigned long deadline;
 731	u32 val, val_l, val_h;
 732
 733	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_CSR_CNTL);
 734
 735	/* CSR registers are grouped under different Target IDs.
 736	 * 6-bit Target_ID is split between MSCC_EXT_PAGE_CSR_CNTL_20 and
 737	 * MSCC_EXT_PAGE_CSR_CNTL_19 registers.
 738	 * Target_ID[5:2] maps to bits[3:0] of MSCC_EXT_PAGE_CSR_CNTL_20
 739	 * and Target_ID[1:0] maps to bits[13:12] of MSCC_EXT_PAGE_CSR_CNTL_19.
 740	 */
 741
 742	/* Setup the Target ID */
 743	phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_20,
 744		       MSCC_PHY_CSR_CNTL_20_TARGET(target >> 2));
 745
 746	if ((target >> 2 == 0x1) || (target >> 2 == 0x3))
 747		/* non-MACsec access */
 748		target &= 0x3;
 749	else
 750		target = 0;
 751
 752	/* Trigger CSR Action - Read into the CSR's */
 753	phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_19,
 754		       MSCC_PHY_CSR_CNTL_19_CMD | MSCC_PHY_CSR_CNTL_19_READ |
 755		       MSCC_PHY_CSR_CNTL_19_REG_ADDR(reg) |
 756		       MSCC_PHY_CSR_CNTL_19_TARGET(target));
 757
 758	/* Wait for register access*/
 759	deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
 760	do {
 761		usleep_range(500, 1000);
 762		val = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_19);
 763	} while (time_before(jiffies, deadline) &&
 764		!(val & MSCC_PHY_CSR_CNTL_19_CMD));
 765
 766	if (!(val & MSCC_PHY_CSR_CNTL_19_CMD))
 767		return 0xffffffff;
 768
 769	/* Read the Least Significant Word (LSW) (17) */
 770	val_l = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_17);
 771
 772	/* Read the Most Significant Word (MSW) (18) */
 773	val_h = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_18);
 774
 775	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
 776		       MSCC_PHY_PAGE_STANDARD);
 777
 778	return (val_h << 16) | val_l;
 779}
 780
 781int vsc85xx_csr_write(struct phy_device *phydev,
 782		      enum csr_target target, u32 reg, u32 val)
 783{
 784	unsigned long deadline;
 785
 786	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_CSR_CNTL);
 787
 788	/* CSR registers are grouped under different Target IDs.
 789	 * 6-bit Target_ID is split between MSCC_EXT_PAGE_CSR_CNTL_20 and
 790	 * MSCC_EXT_PAGE_CSR_CNTL_19 registers.
 791	 * Target_ID[5:2] maps to bits[3:0] of MSCC_EXT_PAGE_CSR_CNTL_20
 792	 * and Target_ID[1:0] maps to bits[13:12] of MSCC_EXT_PAGE_CSR_CNTL_19.
 793	 */
 794
 795	/* Setup the Target ID */
 796	phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_20,
 797		       MSCC_PHY_CSR_CNTL_20_TARGET(target >> 2));
 798
 799	/* Write the Least Significant Word (LSW) (17) */
 800	phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_17, (u16)val);
 801
 802	/* Write the Most Significant Word (MSW) (18) */
 803	phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_18, (u16)(val >> 16));
 804
 805	if ((target >> 2 == 0x1) || (target >> 2 == 0x3))
 806		/* non-MACsec access */
 807		target &= 0x3;
 808	else
 809		target = 0;
 810
 811	/* Trigger CSR Action - Write into the CSR's */
 812	phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_19,
 813		       MSCC_PHY_CSR_CNTL_19_CMD |
 814		       MSCC_PHY_CSR_CNTL_19_REG_ADDR(reg) |
 815		       MSCC_PHY_CSR_CNTL_19_TARGET(target));
 816
 817	/* Wait for register access */
 818	deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
 819	do {
 820		usleep_range(500, 1000);
 821		val = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_19);
 822	} while (time_before(jiffies, deadline) &&
 823		 !(val & MSCC_PHY_CSR_CNTL_19_CMD));
 824
 825	if (!(val & MSCC_PHY_CSR_CNTL_19_CMD))
 826		return -ETIMEDOUT;
 827
 828	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
 829		       MSCC_PHY_PAGE_STANDARD);
 830
 831	return 0;
 832}
 833
 834/* bus->mdio_lock should be locked when using this function */
 835static void vsc8584_csr_write(struct phy_device *phydev, u16 addr, u32 val)
 836{
 837	phy_base_write(phydev, MSCC_PHY_TR_MSB, val >> 16);
 838	phy_base_write(phydev, MSCC_PHY_TR_LSB, val & GENMASK(15, 0));
 839	phy_base_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(addr));
 840}
 841
 842/* bus->mdio_lock should be locked when using this function */
 843int vsc8584_cmd(struct phy_device *phydev, u16 val)
 844{
 845	unsigned long deadline;
 846	u16 reg_val;
 847
 848	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
 849		       MSCC_PHY_PAGE_EXTENDED_GPIO);
 850
 851	phy_base_write(phydev, MSCC_PHY_PROC_CMD, PROC_CMD_NCOMPLETED | val);
 852
 853	deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
 854	do {
 855		reg_val = phy_base_read(phydev, MSCC_PHY_PROC_CMD);
 856	} while (time_before(jiffies, deadline) &&
 857		 (reg_val & PROC_CMD_NCOMPLETED) &&
 858		 !(reg_val & PROC_CMD_FAILED));
 859
 860	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
 861
 862	if (reg_val & PROC_CMD_FAILED)
 863		return -EIO;
 864
 865	if (reg_val & PROC_CMD_NCOMPLETED)
 866		return -ETIMEDOUT;
 867
 868	return 0;
 869}
 870
 871/* bus->mdio_lock should be locked when using this function */
 872static int vsc8584_micro_deassert_reset(struct phy_device *phydev,
 873					bool patch_en)
 874{
 875	u32 enable, release;
 876
 877	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
 878		       MSCC_PHY_PAGE_EXTENDED_GPIO);
 879
 880	enable = RUN_FROM_INT_ROM | MICRO_CLK_EN | DW8051_CLK_EN;
 881	release = MICRO_NSOFT_RESET | RUN_FROM_INT_ROM | DW8051_CLK_EN |
 882		MICRO_CLK_EN;
 883
 884	if (patch_en) {
 885		enable |= MICRO_PATCH_EN;
 886		release |= MICRO_PATCH_EN;
 887
 888		/* Clear all patches */
 889		phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_RAM);
 890	}
 891
 892	/* Enable 8051 Micro clock; CLEAR/SET patch present; disable PRAM clock
 893	 * override and addr. auto-incr; operate at 125 MHz
 894	 */
 895	phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, enable);
 896	/* Release 8051 Micro SW reset */
 897	phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, release);
 898
 899	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
 900
 901	return 0;
 902}
 903
 904/* bus->mdio_lock should be locked when using this function */
 905static int vsc8584_micro_assert_reset(struct phy_device *phydev)
 906{
 907	int ret;
 908	u16 reg;
 909
 910	ret = vsc8584_cmd(phydev, PROC_CMD_NOP);
 911	if (ret)
 912		return ret;
 913
 914	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
 915		       MSCC_PHY_PAGE_EXTENDED_GPIO);
 916
 917	reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
 918	reg &= ~EN_PATCH_RAM_TRAP_ADDR(4);
 919	phy_base_write(phydev, MSCC_INT_MEM_CNTL, reg);
 920
 921	phy_base_write(phydev, MSCC_TRAP_ROM_ADDR(4), 0x005b);
 922	phy_base_write(phydev, MSCC_PATCH_RAM_ADDR(4), 0x005b);
 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_PHY_PROC_CMD, PROC_CMD_NOP);
 929
 930	reg = phy_base_read(phydev, MSCC_DW8051_CNTL_STATUS);
 931	reg &= ~MICRO_NSOFT_RESET;
 932	phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, reg);
 933
 934	phy_base_write(phydev, MSCC_PHY_PROC_CMD, PROC_CMD_MCB_ACCESS_MAC_CONF |
 935		       PROC_CMD_SGMII_PORT(0) | PROC_CMD_NO_MAC_CONF |
 936		       PROC_CMD_READ);
 937
 938	reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
 939	reg &= ~EN_PATCH_RAM_TRAP_ADDR(4);
 940	phy_base_write(phydev, MSCC_INT_MEM_CNTL, reg);
 941
 942	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
 943
 944	return 0;
 945}
 946
 947/* bus->mdio_lock should be locked when using this function */
 948static int vsc8584_get_fw_crc(struct phy_device *phydev, u16 start, u16 size,
 949			      u16 *crc)
 950{
 951	int ret;
 952
 953	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
 954
 955	phy_base_write(phydev, MSCC_PHY_VERIPHY_CNTL_2, start);
 956	phy_base_write(phydev, MSCC_PHY_VERIPHY_CNTL_3, size);
 957
 958	/* Start Micro command */
 959	ret = vsc8584_cmd(phydev, PROC_CMD_CRC16);
 960	if (ret)
 961		goto out;
 962
 963	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
 964
 965	*crc = phy_base_read(phydev, MSCC_PHY_VERIPHY_CNTL_2);
 966
 967out:
 968	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
 969
 970	return ret;
 971}
 972
 973/* bus->mdio_lock should be locked when using this function */
 974static int vsc8584_patch_fw(struct phy_device *phydev,
 975			    const struct firmware *fw)
 976{
 977	int i, ret;
 978
 979	ret = vsc8584_micro_assert_reset(phydev);
 980	if (ret) {
 981		dev_err(&phydev->mdio.dev,
 982			"%s: failed to assert reset of micro\n", __func__);
 983		return ret;
 984	}
 985
 986	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
 987		       MSCC_PHY_PAGE_EXTENDED_GPIO);
 988
 989	/* Hold 8051 Micro in SW Reset, Enable auto incr address and patch clock
 990	 * Disable the 8051 Micro clock
 991	 */
 992	phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, RUN_FROM_INT_ROM |
 993		       AUTOINC_ADDR | PATCH_RAM_CLK | MICRO_CLK_EN |
 994		       MICRO_CLK_DIVIDE(2));
 995	phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_PRAM | INT_MEM_WRITE_EN |
 996		       INT_MEM_DATA(2));
 997	phy_base_write(phydev, MSCC_INT_MEM_ADDR, 0x0000);
 998
 999	for (i = 0; i < fw->size; i++)
1000		phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_PRAM |
1001			       INT_MEM_WRITE_EN | fw->data[i]);
1002
1003	/* Clear internal memory access */
1004	phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_RAM);
1005
1006	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1007
1008	return 0;
1009}
1010
1011/* bus->mdio_lock should be locked when using this function */
1012static bool vsc8574_is_serdes_init(struct phy_device *phydev)
1013{
1014	u16 reg;
1015	bool ret;
1016
1017	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1018		       MSCC_PHY_PAGE_EXTENDED_GPIO);
1019
1020	reg = phy_base_read(phydev, MSCC_TRAP_ROM_ADDR(1));
1021	if (reg != 0x3eb7) {
1022		ret = false;
1023		goto out;
1024	}
1025
1026	reg = phy_base_read(phydev, MSCC_PATCH_RAM_ADDR(1));
1027	if (reg != 0x4012) {
1028		ret = false;
1029		goto out;
1030	}
1031
1032	reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
1033	if (reg != EN_PATCH_RAM_TRAP_ADDR(1)) {
1034		ret = false;
1035		goto out;
1036	}
1037
1038	reg = phy_base_read(phydev, MSCC_DW8051_CNTL_STATUS);
1039	if ((MICRO_NSOFT_RESET | RUN_FROM_INT_ROM |  DW8051_CLK_EN |
1040	     MICRO_CLK_EN) != (reg & MSCC_DW8051_VLD_MASK)) {
1041		ret = false;
1042		goto out;
1043	}
1044
1045	ret = true;
1046out:
1047	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1048
1049	return ret;
1050}
1051
1052/* bus->mdio_lock should be locked when using this function */
1053static int vsc8574_config_pre_init(struct phy_device *phydev)
1054{
1055	static const struct reg_val pre_init1[] = {
1056		{0x0fae, 0x000401bd},
1057		{0x0fac, 0x000f000f},
1058		{0x17a0, 0x00a0f147},
1059		{0x0fe4, 0x00052f54},
1060		{0x1792, 0x0027303d},
1061		{0x07fe, 0x00000704},
1062		{0x0fe0, 0x00060150},
1063		{0x0f82, 0x0012b00a},
1064		{0x0f80, 0x00000d74},
1065		{0x02e0, 0x00000012},
1066		{0x03a2, 0x00050208},
1067		{0x03b2, 0x00009186},
1068		{0x0fb0, 0x000e3700},
1069		{0x1688, 0x00049f81},
1070		{0x0fd2, 0x0000ffff},
1071		{0x168a, 0x00039fa2},
1072		{0x1690, 0x0020640b},
1073		{0x0258, 0x00002220},
1074		{0x025a, 0x00002a20},
1075		{0x025c, 0x00003060},
1076		{0x025e, 0x00003fa0},
1077		{0x03a6, 0x0000e0f0},
1078		{0x0f92, 0x00001489},
1079		{0x16a2, 0x00007000},
1080		{0x16a6, 0x00071448},
1081		{0x16a0, 0x00eeffdd},
1082		{0x0fe8, 0x0091b06c},
1083		{0x0fea, 0x00041600},
1084		{0x16b0, 0x00eeff00},
1085		{0x16b2, 0x00007000},
1086		{0x16b4, 0x00000814},
1087		{0x0f90, 0x00688980},
1088		{0x03a4, 0x0000d8f0},
1089		{0x0fc0, 0x00000400},
1090		{0x07fa, 0x0050100f},
1091		{0x0796, 0x00000003},
1092		{0x07f8, 0x00c3ff98},
1093		{0x0fa4, 0x0018292a},
1094		{0x168c, 0x00d2c46f},
1095		{0x17a2, 0x00000620},
1096		{0x16a4, 0x0013132f},
1097		{0x16a8, 0x00000000},
1098		{0x0ffc, 0x00c0a028},
1099		{0x0fec, 0x00901c09},
1100		{0x0fee, 0x0004a6a1},
1101		{0x0ffe, 0x00b01807},
1102	};
1103	static const struct reg_val pre_init2[] = {
1104		{0x0486, 0x0008a518},
1105		{0x0488, 0x006dc696},
1106		{0x048a, 0x00000912},
1107		{0x048e, 0x00000db6},
1108		{0x049c, 0x00596596},
1109		{0x049e, 0x00000514},
1110		{0x04a2, 0x00410280},
1111		{0x04a4, 0x00000000},
1112		{0x04a6, 0x00000000},
1113		{0x04a8, 0x00000000},
1114		{0x04aa, 0x00000000},
1115		{0x04ae, 0x007df7dd},
1116		{0x04b0, 0x006d95d4},
1117		{0x04b2, 0x00492410},
1118	};
1119	struct device *dev = &phydev->mdio.dev;
1120	const struct firmware *fw;
1121	unsigned int i;
1122	u16 crc, reg;
1123	bool serdes_init;
1124	int ret;
1125
1126	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1127
1128	/* all writes below are broadcasted to all PHYs in the same package */
1129	reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
1130	reg |= SMI_BROADCAST_WR_EN;
1131	phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
1132
1133	phy_base_write(phydev, MII_VSC85XX_INT_MASK, 0);
1134
1135	/* The below register writes are tweaking analog and electrical
1136	 * configuration that were determined through characterization by PHY
1137	 * engineers. These don't mean anything more than "these are the best
1138	 * values".
1139	 */
1140	phy_base_write(phydev, MSCC_PHY_EXT_PHY_CNTL_2, 0x0040);
1141
1142	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
1143
1144	phy_base_write(phydev, MSCC_PHY_TEST_PAGE_20, 0x4320);
1145	phy_base_write(phydev, MSCC_PHY_TEST_PAGE_24, 0x0c00);
1146	phy_base_write(phydev, MSCC_PHY_TEST_PAGE_9, 0x18ca);
1147	phy_base_write(phydev, MSCC_PHY_TEST_PAGE_5, 0x1b20);
1148
1149	reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
1150	reg |= TR_CLK_DISABLE;
1151	phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
1152
1153	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
1154
1155	for (i = 0; i < ARRAY_SIZE(pre_init1); i++)
1156		vsc8584_csr_write(phydev, pre_init1[i].reg, pre_init1[i].val);
1157
1158	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED_2);
1159
1160	phy_base_write(phydev, MSCC_PHY_CU_PMD_TX_CNTL, 0x028e);
1161
1162	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
1163
1164	for (i = 0; i < ARRAY_SIZE(pre_init2); i++)
1165		vsc8584_csr_write(phydev, pre_init2[i].reg, pre_init2[i].val);
1166
1167	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
1168
1169	reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
1170	reg &= ~TR_CLK_DISABLE;
1171	phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
1172
1173	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1174
1175	/* end of write broadcasting */
1176	reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
1177	reg &= ~SMI_BROADCAST_WR_EN;
1178	phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
1179
1180	ret = request_firmware(&fw, MSCC_VSC8574_REVB_INT8051_FW, dev);
1181	if (ret) {
1182		dev_err(dev, "failed to load firmware %s, ret: %d\n",
1183			MSCC_VSC8574_REVB_INT8051_FW, ret);
1184		return ret;
1185	}
1186
1187	/* Add one byte to size for the one added by the patch_fw function */
1188	ret = vsc8584_get_fw_crc(phydev,
1189				 MSCC_VSC8574_REVB_INT8051_FW_START_ADDR,
1190				 fw->size + 1, &crc);
1191	if (ret)
1192		goto out;
1193
1194	if (crc == MSCC_VSC8574_REVB_INT8051_FW_CRC) {
1195		serdes_init = vsc8574_is_serdes_init(phydev);
1196
1197		if (!serdes_init) {
1198			ret = vsc8584_micro_assert_reset(phydev);
1199			if (ret) {
1200				dev_err(dev,
1201					"%s: failed to assert reset of micro\n",
1202					__func__);
1203				goto out;
1204			}
1205		}
1206	} else {
1207		dev_dbg(dev, "FW CRC is not the expected one, patching FW\n");
1208
1209		serdes_init = false;
1210
1211		if (vsc8584_patch_fw(phydev, fw))
1212			dev_warn(dev,
1213				 "failed to patch FW, expect non-optimal device\n");
1214	}
1215
1216	if (!serdes_init) {
1217		phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1218			       MSCC_PHY_PAGE_EXTENDED_GPIO);
1219
1220		phy_base_write(phydev, MSCC_TRAP_ROM_ADDR(1), 0x3eb7);
1221		phy_base_write(phydev, MSCC_PATCH_RAM_ADDR(1), 0x4012);
1222		phy_base_write(phydev, MSCC_INT_MEM_CNTL,
1223			       EN_PATCH_RAM_TRAP_ADDR(1));
1224
1225		vsc8584_micro_deassert_reset(phydev, false);
1226
1227		/* Add one byte to size for the one added by the patch_fw
1228		 * function
1229		 */
1230		ret = vsc8584_get_fw_crc(phydev,
1231					 MSCC_VSC8574_REVB_INT8051_FW_START_ADDR,
1232					 fw->size + 1, &crc);
1233		if (ret)
1234			goto out;
1235
1236		if (crc != MSCC_VSC8574_REVB_INT8051_FW_CRC)
1237			dev_warn(dev,
1238				 "FW CRC after patching is not the expected one, expect non-optimal device\n");
1239	}
1240
1241	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1242		       MSCC_PHY_PAGE_EXTENDED_GPIO);
1243
1244	ret = vsc8584_cmd(phydev, PROC_CMD_1588_DEFAULT_INIT |
1245			  PROC_CMD_PHY_INIT);
1246
1247out:
1248	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1249
1250	release_firmware(fw);
1251
1252	return ret;
1253}
1254
1255/* Access LCPLL Cfg_2 */
1256static void vsc8584_pll5g_cfg2_wr(struct phy_device *phydev,
1257				  bool disable_fsm)
1258{
1259	u32 rd_dat;
1260
1261	rd_dat = vsc85xx_csr_read(phydev, MACRO_CTRL, PHY_S6G_PLL5G_CFG2);
1262	rd_dat &= ~BIT(PHY_S6G_CFG2_FSM_DIS);
1263	rd_dat |= (disable_fsm << PHY_S6G_CFG2_FSM_DIS);
1264	vsc85xx_csr_write(phydev, MACRO_CTRL, PHY_S6G_PLL5G_CFG2, rd_dat);
1265}
1266
1267/* trigger a read to the spcified MCB */
1268static int vsc8584_mcb_rd_trig(struct phy_device *phydev,
1269			       u32 mcb_reg_addr, u8 mcb_slave_num)
1270{
1271	u32 rd_dat = 0;
1272
1273	/* read MCB */
1274	vsc85xx_csr_write(phydev, MACRO_CTRL, mcb_reg_addr,
1275			  (0x40000000 | (1L << mcb_slave_num)));
1276
1277	return read_poll_timeout(vsc85xx_csr_read, rd_dat,
1278				 !(rd_dat & 0x40000000),
1279				 4000, 200000, 0,
1280				 phydev, MACRO_CTRL, mcb_reg_addr);
1281}
1282
1283/* trigger a write to the spcified MCB */
1284static int vsc8584_mcb_wr_trig(struct phy_device *phydev,
1285			       u32 mcb_reg_addr,
1286			       u8 mcb_slave_num)
1287{
1288	u32 rd_dat = 0;
1289
1290	/* write back MCB */
1291	vsc85xx_csr_write(phydev, MACRO_CTRL, mcb_reg_addr,
1292			  (0x80000000 | (1L << mcb_slave_num)));
1293
1294	return read_poll_timeout(vsc85xx_csr_read, rd_dat,
1295				 !(rd_dat & 0x80000000),
1296				 4000, 200000, 0,
1297				 phydev, MACRO_CTRL, mcb_reg_addr);
1298}
1299
1300/* Sequence to Reset LCPLL for the VIPER and ELISE PHY */
1301static int vsc8584_pll5g_reset(struct phy_device *phydev)
1302{
1303	bool dis_fsm;
1304	int ret = 0;
1305
1306	ret = vsc8584_mcb_rd_trig(phydev, 0x11, 0);
1307	if (ret < 0)
1308		goto done;
1309	dis_fsm = 1;
1310
1311	/* Reset LCPLL */
1312	vsc8584_pll5g_cfg2_wr(phydev, dis_fsm);
1313
1314	/* write back LCPLL MCB */
1315	ret = vsc8584_mcb_wr_trig(phydev, 0x11, 0);
1316	if (ret < 0)
1317		goto done;
1318
1319	/* 10 mSec sleep while LCPLL is hold in reset */
1320	usleep_range(10000, 20000);
1321
1322	/* read LCPLL MCB into CSRs */
1323	ret = vsc8584_mcb_rd_trig(phydev, 0x11, 0);
1324	if (ret < 0)
1325		goto done;
1326	dis_fsm = 0;
1327
1328	/* Release the Reset of LCPLL */
1329	vsc8584_pll5g_cfg2_wr(phydev, dis_fsm);
1330
1331	/* write back LCPLL MCB */
1332	ret = vsc8584_mcb_wr_trig(phydev, 0x11, 0);
1333	if (ret < 0)
1334		goto done;
1335
1336	usleep_range(110000, 200000);
1337done:
1338	return ret;
1339}
1340
1341/* bus->mdio_lock should be locked when using this function */
1342static int vsc8584_config_pre_init(struct phy_device *phydev)
1343{
1344	static const struct reg_val pre_init1[] = {
1345		{0x07fa, 0x0050100f},
1346		{0x1688, 0x00049f81},
1347		{0x0f90, 0x00688980},
1348		{0x03a4, 0x0000d8f0},
1349		{0x0fc0, 0x00000400},
1350		{0x0f82, 0x0012b002},
1351		{0x1686, 0x00000004},
1352		{0x168c, 0x00d2c46f},
1353		{0x17a2, 0x00000620},
1354		{0x16a0, 0x00eeffdd},
1355		{0x16a6, 0x00071448},
1356		{0x16a4, 0x0013132f},
1357		{0x16a8, 0x00000000},
1358		{0x0ffc, 0x00c0a028},
1359		{0x0fe8, 0x0091b06c},
1360		{0x0fea, 0x00041600},
1361		{0x0f80, 0x00fffaff},
1362		{0x0fec, 0x00901809},
1363		{0x0ffe, 0x00b01007},
1364		{0x16b0, 0x00eeff00},
1365		{0x16b2, 0x00007000},
1366		{0x16b4, 0x00000814},
1367	};
1368	static const struct reg_val pre_init2[] = {
1369		{0x0486, 0x0008a518},
1370		{0x0488, 0x006dc696},
1371		{0x048a, 0x00000912},
1372	};
1373	const struct firmware *fw;
1374	struct device *dev = &phydev->mdio.dev;
1375	unsigned int i;
1376	u16 crc, reg;
1377	int ret;
1378
1379	ret = vsc8584_pll5g_reset(phydev);
1380	if (ret < 0) {
1381		dev_err(dev, "failed LCPLL reset, ret: %d\n", ret);
1382		return ret;
1383	}
1384
1385	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1386
1387	/* all writes below are broadcasted to all PHYs in the same package */
1388	reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
1389	reg |= SMI_BROADCAST_WR_EN;
1390	phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
1391
1392	phy_base_write(phydev, MII_VSC85XX_INT_MASK, 0);
1393
1394	reg = phy_base_read(phydev,  MSCC_PHY_BYPASS_CONTROL);
1395	reg |= PARALLEL_DET_IGNORE_ADVERTISED;
1396	phy_base_write(phydev, MSCC_PHY_BYPASS_CONTROL, reg);
1397
1398	/* The below register writes are tweaking analog and electrical
1399	 * configuration that were determined through characterization by PHY
1400	 * engineers. These don't mean anything more than "these are the best
1401	 * values".
1402	 */
1403	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED_3);
1404
1405	phy_base_write(phydev, MSCC_PHY_SERDES_TX_CRC_ERR_CNT, 0x2000);
1406
1407	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
1408
1409	phy_base_write(phydev, MSCC_PHY_TEST_PAGE_5, 0x1f20);
1410
1411	reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
1412	reg |= TR_CLK_DISABLE;
1413	phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
1414
1415	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
1416
1417	phy_base_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(0x2fa4));
1418
1419	reg = phy_base_read(phydev, MSCC_PHY_TR_MSB);
1420	reg &= ~0x007f;
1421	reg |= 0x0019;
1422	phy_base_write(phydev, MSCC_PHY_TR_MSB, reg);
1423
1424	phy_base_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(0x0fa4));
1425
1426	for (i = 0; i < ARRAY_SIZE(pre_init1); i++)
1427		vsc8584_csr_write(phydev, pre_init1[i].reg, pre_init1[i].val);
1428
1429	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED_2);
1430
1431	phy_base_write(phydev, MSCC_PHY_CU_PMD_TX_CNTL, 0x028e);
1432
1433	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
1434
1435	for (i = 0; i < ARRAY_SIZE(pre_init2); i++)
1436		vsc8584_csr_write(phydev, pre_init2[i].reg, pre_init2[i].val);
1437
1438	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
1439
1440	reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
1441	reg &= ~TR_CLK_DISABLE;
1442	phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
1443
1444	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1445
1446	/* end of write broadcasting */
1447	reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
1448	reg &= ~SMI_BROADCAST_WR_EN;
1449	phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
1450
1451	ret = request_firmware(&fw, MSCC_VSC8584_REVB_INT8051_FW, dev);
1452	if (ret) {
1453		dev_err(dev, "failed to load firmware %s, ret: %d\n",
1454			MSCC_VSC8584_REVB_INT8051_FW, ret);
1455		return ret;
1456	}
1457
1458	/* Add one byte to size for the one added by the patch_fw function */
1459	ret = vsc8584_get_fw_crc(phydev,
1460				 MSCC_VSC8584_REVB_INT8051_FW_START_ADDR,
1461				 fw->size + 1, &crc);
1462	if (ret)
1463		goto out;
1464
1465	if (crc != MSCC_VSC8584_REVB_INT8051_FW_CRC) {
1466		dev_dbg(dev, "FW CRC is not the expected one, patching FW\n");
1467		if (vsc8584_patch_fw(phydev, fw))
1468			dev_warn(dev,
1469				 "failed to patch FW, expect non-optimal device\n");
1470	}
1471
1472	vsc8584_micro_deassert_reset(phydev, false);
1473
1474	/* Add one byte to size for the one added by the patch_fw function */
1475	ret = vsc8584_get_fw_crc(phydev,
1476				 MSCC_VSC8584_REVB_INT8051_FW_START_ADDR,
1477				 fw->size + 1, &crc);
1478	if (ret)
1479		goto out;
1480
1481	if (crc != MSCC_VSC8584_REVB_INT8051_FW_CRC)
1482		dev_warn(dev,
1483			 "FW CRC after patching is not the expected one, expect non-optimal device\n");
1484
1485	ret = vsc8584_micro_assert_reset(phydev);
1486	if (ret)
1487		goto out;
1488
1489	/* Write patch vector 0, to skip IB cal polling  */
1490	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED_GPIO);
1491	reg = MSCC_ROM_TRAP_SERDES_6G_CFG; /* ROM address to trap, for patch vector 0 */
1492	ret = phy_base_write(phydev, MSCC_TRAP_ROM_ADDR(1), reg);
1493	if (ret)
1494		goto out;
1495
1496	reg = MSCC_RAM_TRAP_SERDES_6G_CFG; /* RAM address to jump to, when patch vector 0 enabled */
1497	ret = phy_base_write(phydev, MSCC_PATCH_RAM_ADDR(1), reg);
1498	if (ret)
1499		goto out;
1500
1501	reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
1502	reg |= PATCH_VEC_ZERO_EN; /* bit 8, enable patch vector 0 */
1503	ret = phy_base_write(phydev, MSCC_INT_MEM_CNTL, reg);
1504	if (ret)
1505		goto out;
1506
1507	vsc8584_micro_deassert_reset(phydev, true);
1508
1509out:
1510	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1511
1512	release_firmware(fw);
1513
1514	return ret;
1515}
1516
1517static void vsc8584_get_base_addr(struct phy_device *phydev)
1518{
1519	struct vsc8531_private *vsc8531 = phydev->priv;
1520	u16 val, addr;
1521
1522	phy_lock_mdio_bus(phydev);
1523	__phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
1524
1525	addr = __phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_4);
1526	addr >>= PHY_CNTL_4_ADDR_POS;
1527
1528	val = __phy_read(phydev, MSCC_PHY_ACTIPHY_CNTL);
1529
1530	__phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1531	phy_unlock_mdio_bus(phydev);
1532
1533	/* In the package, there are two pairs of PHYs (PHY0 + PHY2 and
1534	 * PHY1 + PHY3). The first PHY of each pair (PHY0 and PHY1) is
1535	 * the base PHY for timestamping operations.
1536	 */
1537	vsc8531->ts_base_addr = phydev->mdio.addr;
1538	vsc8531->ts_base_phy = addr;
1539
1540	if (val & PHY_ADDR_REVERSED) {
1541		vsc8531->base_addr = phydev->mdio.addr + addr;
1542		if (addr > 1) {
1543			vsc8531->ts_base_addr += 2;
1544			vsc8531->ts_base_phy += 2;
1545		}
1546	} else {
1547		vsc8531->base_addr = phydev->mdio.addr - addr;
1548		if (addr > 1) {
1549			vsc8531->ts_base_addr -= 2;
1550			vsc8531->ts_base_phy -= 2;
1551		}
1552	}
1553
1554	vsc8531->addr = addr;
1555}
1556
1557static void vsc85xx_coma_mode_release(struct phy_device *phydev)
1558{
1559	/* The coma mode (pin or reg) provides an optional feature that
1560	 * may be used to control when the PHYs become active.
1561	 * Alternatively the COMA_MODE pin may be connected low
1562	 * so that the PHYs are fully active once out of reset.
1563	 */
1564
1565	/* Enable output (mode=0) and write zero to it */
1566	vsc85xx_phy_write_page(phydev, MSCC_PHY_PAGE_EXTENDED_GPIO);
1567	__phy_modify(phydev, MSCC_PHY_GPIO_CONTROL_2,
1568		     MSCC_PHY_COMA_MODE | MSCC_PHY_COMA_OUTPUT, 0);
1569	vsc85xx_phy_write_page(phydev, MSCC_PHY_PAGE_STANDARD);
1570}
1571
1572static int vsc8584_config_host_serdes(struct phy_device *phydev)
1573{
1574	struct vsc8531_private *vsc8531 = phydev->priv;
1575	int ret;
1576	u16 val;
1577
1578	ret = phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1579			     MSCC_PHY_PAGE_EXTENDED_GPIO);
1580	if (ret)
1581		return ret;
1582
1583	val = phy_base_read(phydev, MSCC_PHY_MAC_CFG_FASTLINK);
1584	val &= ~MAC_CFG_MASK;
1585	if (phydev->interface == PHY_INTERFACE_MODE_QSGMII) {
1586		val |= MAC_CFG_QSGMII;
1587	} else if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
1588		val |= MAC_CFG_SGMII;
1589	} else {
1590		ret = -EINVAL;
1591		return ret;
1592	}
1593
1594	ret = phy_base_write(phydev, MSCC_PHY_MAC_CFG_FASTLINK, val);
1595	if (ret)
1596		return ret;
1597
1598	ret = phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1599			     MSCC_PHY_PAGE_STANDARD);
1600	if (ret)
1601		return ret;
1602
1603	val = PROC_CMD_MCB_ACCESS_MAC_CONF | PROC_CMD_RST_CONF_PORT |
1604		PROC_CMD_READ_MOD_WRITE_PORT;
1605	if (phydev->interface == PHY_INTERFACE_MODE_QSGMII)
1606		val |= PROC_CMD_QSGMII_MAC;
1607	else
1608		val |= PROC_CMD_SGMII_MAC;
1609
1610	ret = vsc8584_cmd(phydev, val);
1611	if (ret)
1612		return ret;
1613
1614	usleep_range(10000, 20000);
1615
1616	/* Disable SerDes for 100Base-FX */
1617	ret = vsc8584_cmd(phydev, PROC_CMD_FIBER_MEDIA_CONF |
1618			  PROC_CMD_FIBER_PORT(vsc8531->addr) |
1619			  PROC_CMD_FIBER_DISABLE |
1620			  PROC_CMD_READ_MOD_WRITE_PORT |
1621			  PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_100BASE_FX);
1622	if (ret)
1623		return ret;
1624
1625	/* Disable SerDes for 1000Base-X */
1626	ret = vsc8584_cmd(phydev, PROC_CMD_FIBER_MEDIA_CONF |
1627			  PROC_CMD_FIBER_PORT(vsc8531->addr) |
1628			  PROC_CMD_FIBER_DISABLE |
1629			  PROC_CMD_READ_MOD_WRITE_PORT |
1630			  PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_1000BASE_X);
1631	if (ret)
1632		return ret;
1633
1634	return vsc85xx_sd6g_config_v2(phydev);
1635}
1636
1637static int vsc8574_config_host_serdes(struct phy_device *phydev)
1638{
1639	struct vsc8531_private *vsc8531 = phydev->priv;
1640	int ret;
1641	u16 val;
1642
1643	ret = phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1644			     MSCC_PHY_PAGE_EXTENDED_GPIO);
1645	if (ret)
1646		return ret;
1647
1648	val = phy_base_read(phydev, MSCC_PHY_MAC_CFG_FASTLINK);
1649	val &= ~MAC_CFG_MASK;
1650	if (phydev->interface == PHY_INTERFACE_MODE_QSGMII) {
1651		val |= MAC_CFG_QSGMII;
1652	} else if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
1653		val |= MAC_CFG_SGMII;
1654	} else if (phy_interface_is_rgmii(phydev)) {
1655		val |= MAC_CFG_RGMII;
1656	} else {
1657		ret = -EINVAL;
1658		return ret;
1659	}
1660
1661	ret = phy_base_write(phydev, MSCC_PHY_MAC_CFG_FASTLINK, val);
1662	if (ret)
1663		return ret;
1664
1665	ret = phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1666			     MSCC_PHY_PAGE_STANDARD);
1667	if (ret)
1668		return ret;
1669
1670	if (!phy_interface_is_rgmii(phydev)) {
1671		val = PROC_CMD_MCB_ACCESS_MAC_CONF | PROC_CMD_RST_CONF_PORT |
1672			PROC_CMD_READ_MOD_WRITE_PORT;
1673		if (phydev->interface == PHY_INTERFACE_MODE_QSGMII)
1674			val |= PROC_CMD_QSGMII_MAC;
1675		else
1676			val |= PROC_CMD_SGMII_MAC;
1677
1678		ret = vsc8584_cmd(phydev, val);
1679		if (ret)
1680			return ret;
1681
1682		usleep_range(10000, 20000);
1683	}
1684
1685	/* Disable SerDes for 100Base-FX */
1686	ret = vsc8584_cmd(phydev, PROC_CMD_FIBER_MEDIA_CONF |
1687			  PROC_CMD_FIBER_PORT(vsc8531->addr) |
1688			  PROC_CMD_FIBER_DISABLE |
1689			  PROC_CMD_READ_MOD_WRITE_PORT |
1690			  PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_100BASE_FX);
1691	if (ret)
1692		return ret;
1693
1694	/* Disable SerDes for 1000Base-X */
1695	return vsc8584_cmd(phydev, PROC_CMD_FIBER_MEDIA_CONF |
1696			   PROC_CMD_FIBER_PORT(vsc8531->addr) |
1697			   PROC_CMD_FIBER_DISABLE |
1698			   PROC_CMD_READ_MOD_WRITE_PORT |
1699			   PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_1000BASE_X);
1700}
1701
1702static int vsc8584_config_init(struct phy_device *phydev)
1703{
1704	struct vsc8531_private *vsc8531 = phydev->priv;
1705	int ret, i;
1706	u16 val;
1707
1708	phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
1709
1710	phy_lock_mdio_bus(phydev);
1711
1712	/* Some parts of the init sequence are identical for every PHY in the
1713	 * package. Some parts are modifying the GPIO register bank which is a
1714	 * set of registers that are affecting all PHYs, a few resetting the
1715	 * microprocessor common to all PHYs. The CRC check responsible of the
1716	 * checking the firmware within the 8051 microprocessor can only be
1717	 * accessed via the PHY whose internal address in the package is 0.
1718	 * All PHYs' interrupts mask register has to be zeroed before enabling
1719	 * any PHY's interrupt in this register.
1720	 * For all these reasons, we need to do the init sequence once and only
1721	 * once whatever is the first PHY in the package that is initialized and
1722	 * do the correct init sequence for all PHYs that are package-critical
1723	 * in this pre-init function.
1724	 */
1725	if (phy_package_init_once(phydev)) {
1726		/* The following switch statement assumes that the lowest
1727		 * nibble of the phy_id_mask is always 0. This works because
1728		 * the lowest nibble of the PHY_ID's below are also 0.
1729		 */
1730		WARN_ON(phydev->drv->phy_id_mask & 0xf);
1731
1732		switch (phydev->phy_id & phydev->drv->phy_id_mask) {
1733		case PHY_ID_VSC8504:
1734		case PHY_ID_VSC8552:
1735		case PHY_ID_VSC8572:
1736		case PHY_ID_VSC8574:
1737			ret = vsc8574_config_pre_init(phydev);
1738			if (ret)
1739				goto err;
1740			ret = vsc8574_config_host_serdes(phydev);
1741			if (ret)
1742				goto err;
1743			break;
1744		case PHY_ID_VSC856X:
1745		case PHY_ID_VSC8575:
1746		case PHY_ID_VSC8582:
1747		case PHY_ID_VSC8584:
1748			ret = vsc8584_config_pre_init(phydev);
1749			if (ret)
1750				goto err;
1751			ret = vsc8584_config_host_serdes(phydev);
1752			if (ret)
1753				goto err;
1754			vsc85xx_coma_mode_release(phydev);
1755			break;
1756		default:
1757			ret = -EINVAL;
1758			break;
1759		}
1760
1761		if (ret)
1762			goto err;
1763	}
1764
1765	phy_unlock_mdio_bus(phydev);
1766
1767	ret = vsc8584_macsec_init(phydev);
1768	if (ret)
1769		return ret;
1770
1771	ret = vsc8584_ptp_init(phydev);
1772	if (ret)
1773		return ret;
1774
1775	val = phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_1);
1776	val &= ~(MEDIA_OP_MODE_MASK | VSC8584_MAC_IF_SELECTION_MASK);
1777	val |= (MEDIA_OP_MODE_COPPER << MEDIA_OP_MODE_POS) |
1778	       (VSC8584_MAC_IF_SELECTION_SGMII << VSC8584_MAC_IF_SELECTION_POS);
1779	ret = phy_write(phydev, MSCC_PHY_EXT_PHY_CNTL_1, val);
1780	if (ret)
1781		return ret;
1782
1783	ret = vsc85xx_update_rgmii_cntl(phydev, VSC8572_RGMII_CNTL,
1784					VSC8572_RGMII_RX_DELAY_MASK,
1785					VSC8572_RGMII_TX_DELAY_MASK);
1786	if (ret)
1787		return ret;
1788
1789	ret = genphy_soft_reset(phydev);
1790	if (ret)
1791		return ret;
1792
1793	for (i = 0; i < vsc8531->nleds; i++) {
1794		ret = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]);
1795		if (ret)
1796			return ret;
1797	}
1798
1799	return 0;
1800
1801err:
1802	phy_unlock_mdio_bus(phydev);
1803	return ret;
1804}
1805
1806static irqreturn_t vsc8584_handle_interrupt(struct phy_device *phydev)
1807{
1808	irqreturn_t ret;
1809	int irq_status;
1810
1811	irq_status = phy_read(phydev, MII_VSC85XX_INT_STATUS);
1812	if (irq_status < 0)
1813		return IRQ_NONE;
1814
1815	/* Timestamping IRQ does not set a bit in the global INT_STATUS, so
1816	 * irq_status would be 0.
1817	 */
1818	ret = vsc8584_handle_ts_interrupt(phydev);
1819	if (!(irq_status & MII_VSC85XX_INT_MASK_MASK))
1820		return ret;
1821
1822	if (irq_status & MII_VSC85XX_INT_MASK_EXT)
1823		vsc8584_handle_macsec_interrupt(phydev);
1824
1825	if (irq_status & MII_VSC85XX_INT_MASK_LINK_CHG)
1826		phy_trigger_machine(phydev);
1827
1828	return IRQ_HANDLED;
1829}
1830
1831static int vsc85xx_config_init(struct phy_device *phydev)
1832{
1833	int rc, i, phy_id;
1834	struct vsc8531_private *vsc8531 = phydev->priv;
1835
1836	rc = vsc85xx_default_config(phydev);
1837	if (rc)
1838		return rc;
1839
1840	rc = vsc85xx_mac_if_set(phydev, phydev->interface);
1841	if (rc)
1842		return rc;
1843
1844	rc = vsc85xx_edge_rate_cntl_set(phydev, vsc8531->rate_magic);
1845	if (rc)
1846		return rc;
1847
1848	phy_id = phydev->drv->phy_id & phydev->drv->phy_id_mask;
1849	if (PHY_ID_VSC8531 == phy_id || PHY_ID_VSC8541 == phy_id ||
1850	    PHY_ID_VSC8530 == phy_id || PHY_ID_VSC8540 == phy_id) {
1851		rc = vsc8531_pre_init_seq_set(phydev);
1852		if (rc)
1853			return rc;
1854	}
1855
1856	rc = vsc85xx_eee_init_seq_set(phydev);
1857	if (rc)
1858		return rc;
1859
1860	for (i = 0; i < vsc8531->nleds; i++) {
1861		rc = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]);
1862		if (rc)
1863			return rc;
1864	}
1865
1866	return 0;
1867}
1868
1869static int __phy_write_mcb_s6g(struct phy_device *phydev, u32 reg, u8 mcb,
1870			       u32 op)
1871{
1872	unsigned long deadline;
1873	u32 val;
1874	int ret;
1875
1876	ret = vsc85xx_csr_write(phydev, PHY_MCB_TARGET, reg,
1877				op | (1 << mcb));
1878	if (ret)
1879		return -EINVAL;
1880
1881	deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
1882	do {
1883		usleep_range(500, 1000);
1884		val = vsc85xx_csr_read(phydev, PHY_MCB_TARGET, reg);
1885
1886		if (val == 0xffffffff)
1887			return -EIO;
1888
1889	} while (time_before(jiffies, deadline) && (val & op));
1890
1891	if (val & op)
1892		return -ETIMEDOUT;
1893
1894	return 0;
1895}
1896
1897/* Trigger a read to the specified MCB */
1898int phy_update_mcb_s6g(struct phy_device *phydev, u32 reg, u8 mcb)
1899{
1900	return __phy_write_mcb_s6g(phydev, reg, mcb, PHY_MCB_S6G_READ);
1901}
1902
1903/* Trigger a write to the specified MCB */
1904int phy_commit_mcb_s6g(struct phy_device *phydev, u32 reg, u8 mcb)
1905{
1906	return __phy_write_mcb_s6g(phydev, reg, mcb, PHY_MCB_S6G_WRITE);
1907}
1908
1909static int vsc8514_config_host_serdes(struct phy_device *phydev)
1910{
1911	int ret;
1912	u16 val;
1913
1914	ret = phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1915			     MSCC_PHY_PAGE_EXTENDED_GPIO);
1916	if (ret)
1917		return ret;
1918
1919	val = phy_base_read(phydev, MSCC_PHY_MAC_CFG_FASTLINK);
1920	val &= ~MAC_CFG_MASK;
1921	val |= MAC_CFG_QSGMII;
1922	ret = phy_base_write(phydev, MSCC_PHY_MAC_CFG_FASTLINK, val);
1923	if (ret)
1924		return ret;
1925
1926	ret = phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1927			     MSCC_PHY_PAGE_STANDARD);
1928	if (ret)
1929		return ret;
1930
1931	ret = vsc8584_cmd(phydev, PROC_CMD_NOP);
1932	if (ret)
1933		return ret;
1934
1935	ret = vsc8584_cmd(phydev,
1936			  PROC_CMD_MCB_ACCESS_MAC_CONF |
1937			  PROC_CMD_RST_CONF_PORT |
1938			  PROC_CMD_READ_MOD_WRITE_PORT | PROC_CMD_QSGMII_MAC);
1939	if (ret) {
1940		dev_err(&phydev->mdio.dev, "%s: QSGMII error: %d\n",
1941			__func__, ret);
1942		return ret;
1943	}
1944
1945	/* Apply 6G SerDes FOJI Algorithm
1946	 *  Initial condition requirement:
1947	 *  1. hold 8051 in reset
1948	 *  2. disable patch vector 0, in order to allow IB cal poll during FoJi
1949	 *  3. deassert 8051 reset after change patch vector status
1950	 *  4. proceed with FoJi (vsc85xx_sd6g_config_v2)
1951	 */
1952	vsc8584_micro_assert_reset(phydev);
1953	val = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
1954	/* clear bit 8, to disable patch vector 0 */
1955	val &= ~PATCH_VEC_ZERO_EN;
1956	ret = phy_base_write(phydev, MSCC_INT_MEM_CNTL, val);
1957	/* Enable 8051 clock, don't set patch present, disable PRAM clock override */
1958	vsc8584_micro_deassert_reset(phydev, false);
1959
1960	return vsc85xx_sd6g_config_v2(phydev);
1961}
1962
1963static int vsc8514_config_pre_init(struct phy_device *phydev)
1964{
1965	/* These are the settings to override the silicon default
1966	 * values to handle hardware performance of PHY. They
1967	 * are set at Power-On state and remain until PHY Reset.
1968	 */
1969	static const struct reg_val pre_init1[] = {
1970		{0x0f90, 0x00688980},
1971		{0x0786, 0x00000003},
1972		{0x07fa, 0x0050100f},
1973		{0x0f82, 0x0012b002},
1974		{0x1686, 0x00000004},
1975		{0x168c, 0x00d2c46f},
1976		{0x17a2, 0x00000620},
1977		{0x16a0, 0x00eeffdd},
1978		{0x16a6, 0x00071448},
1979		{0x16a4, 0x0013132f},
1980		{0x16a8, 0x00000000},
1981		{0x0ffc, 0x00c0a028},
1982		{0x0fe8, 0x0091b06c},
1983		{0x0fea, 0x00041600},
1984		{0x0f80, 0x00fffaff},
1985		{0x0fec, 0x00901809},
1986		{0x0ffe, 0x00b01007},
1987		{0x16b0, 0x00eeff00},
1988		{0x16b2, 0x00007000},
1989		{0x16b4, 0x00000814},
1990	};
1991	struct device *dev = &phydev->mdio.dev;
1992	unsigned int i;
1993	u16 reg;
1994	int ret;
1995
1996	ret = vsc8584_pll5g_reset(phydev);
1997	if (ret < 0) {
1998		dev_err(dev, "failed LCPLL reset, ret: %d\n", ret);
1999		return ret;
2000	}
2001
2002	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
2003
2004	/* all writes below are broadcasted to all PHYs in the same package */
2005	reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
2006	reg |= SMI_BROADCAST_WR_EN;
2007	phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
2008
2009	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
2010
2011	reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
2012	reg |= BIT(15);
2013	phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
2014
2015	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
2016
2017	for (i = 0; i < ARRAY_SIZE(pre_init1); i++)
2018		vsc8584_csr_write(phydev, pre_init1[i].reg, pre_init1[i].val);
2019
2020	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
2021
2022	reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
2023	reg &= ~BIT(15);
2024	phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
2025
2026	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
2027
2028	reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
2029	reg &= ~SMI_BROADCAST_WR_EN;
2030	phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
2031
2032	/* Add pre-patching commands to:
2033	 * 1. enable 8051 clock, operate 8051 clock at 125 MHz
2034	 * instead of HW default 62.5MHz
2035	 * 2. write patch vector 0, to skip IB cal polling executed
2036	 * as part of the 0x80E0 ROM command
2037	 */
2038	vsc8584_micro_deassert_reset(phydev, false);
2039
2040	vsc8584_micro_assert_reset(phydev);
2041	phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
2042		       MSCC_PHY_PAGE_EXTENDED_GPIO);
2043	/* ROM address to trap, for patch vector 0 */
2044	reg = MSCC_ROM_TRAP_SERDES_6G_CFG;
2045	ret = phy_base_write(phydev, MSCC_TRAP_ROM_ADDR(1), reg);
2046	if (ret)
2047		goto err;
2048	/* RAM address to jump to, when patch vector 0 enabled */
2049	reg = MSCC_RAM_TRAP_SERDES_6G_CFG;
2050	ret = phy_base_write(phydev, MSCC_PATCH_RAM_ADDR(1), reg);
2051	if (ret)
2052		goto err;
2053	reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
2054	reg |= PATCH_VEC_ZERO_EN; /* bit 8, enable patch vector 0 */
2055	ret = phy_base_write(phydev, MSCC_INT_MEM_CNTL, reg);
2056	if (ret)
2057		goto err;
2058
2059	/* Enable 8051 clock, don't set patch present
2060	 * yet, disable PRAM clock override
2061	 */
2062	vsc8584_micro_deassert_reset(phydev, false);
2063	return ret;
2064 err:
2065	/* restore 8051 and bail w error */
2066	vsc8584_micro_deassert_reset(phydev, false);
2067	return ret;
2068}
2069
2070static int vsc8514_config_init(struct phy_device *phydev)
2071{
2072	struct vsc8531_private *vsc8531 = phydev->priv;
2073	int ret, i;
2074
2075	phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
2076
2077	phy_lock_mdio_bus(phydev);
2078
2079	/* Some parts of the init sequence are identical for every PHY in the
2080	 * package. Some parts are modifying the GPIO register bank which is a
2081	 * set of registers that are affecting all PHYs, a few resetting the
2082	 * microprocessor common to all PHYs.
2083	 * All PHYs' interrupts mask register has to be zeroed before enabling
2084	 * any PHY's interrupt in this register.
2085	 * For all these reasons, we need to do the init sequence once and only
2086	 * once whatever is the first PHY in the package that is initialized and
2087	 * do the correct init sequence for all PHYs that are package-critical
2088	 * in this pre-init function.
2089	 */
2090	if (phy_package_init_once(phydev)) {
2091		ret = vsc8514_config_pre_init(phydev);
2092		if (ret)
2093			goto err;
2094		ret = vsc8514_config_host_serdes(phydev);
2095		if (ret)
2096			goto err;
2097		vsc85xx_coma_mode_release(phydev);
2098	}
2099
2100	phy_unlock_mdio_bus(phydev);
2101
2102	ret = phy_modify(phydev, MSCC_PHY_EXT_PHY_CNTL_1, MEDIA_OP_MODE_MASK,
2103			 MEDIA_OP_MODE_COPPER << MEDIA_OP_MODE_POS);
2104
2105	if (ret)
2106		return ret;
2107
2108	ret = genphy_soft_reset(phydev);
2109
2110	if (ret)
2111		return ret;
2112
2113	for (i = 0; i < vsc8531->nleds; i++) {
2114		ret = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]);
2115		if (ret)
2116			return ret;
2117	}
2118
2119	return ret;
2120
2121err:
2122	phy_unlock_mdio_bus(phydev);
2123	return ret;
2124}
2125
2126static int vsc85xx_ack_interrupt(struct phy_device *phydev)
2127{
2128	int rc = 0;
2129
2130	if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
2131		rc = phy_read(phydev, MII_VSC85XX_INT_STATUS);
2132
2133	return (rc < 0) ? rc : 0;
2134}
2135
2136static int vsc85xx_config_intr(struct phy_device *phydev)
2137{
2138	int rc;
2139
2140	if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
2141		rc = vsc85xx_ack_interrupt(phydev);
2142		if (rc)
2143			return rc;
2144
2145		vsc8584_config_macsec_intr(phydev);
2146		vsc8584_config_ts_intr(phydev);
2147
2148		rc = phy_write(phydev, MII_VSC85XX_INT_MASK,
2149			       MII_VSC85XX_INT_MASK_MASK);
2150	} else {
2151		rc = phy_write(phydev, MII_VSC85XX_INT_MASK, 0);
2152		if (rc < 0)
2153			return rc;
2154		rc = phy_read(phydev, MII_VSC85XX_INT_STATUS);
2155		if (rc < 0)
2156			return rc;
2157
2158		rc = vsc85xx_ack_interrupt(phydev);
2159	}
2160
2161	return rc;
2162}
2163
2164static irqreturn_t vsc85xx_handle_interrupt(struct phy_device *phydev)
2165{
2166	int irq_status;
2167
2168	irq_status = phy_read(phydev, MII_VSC85XX_INT_STATUS);
2169	if (irq_status < 0) {
2170		phy_error(phydev);
2171		return IRQ_NONE;
2172	}
2173
2174	if (!(irq_status & MII_VSC85XX_INT_MASK_MASK))
2175		return IRQ_NONE;
2176
2177	phy_trigger_machine(phydev);
2178
2179	return IRQ_HANDLED;
2180}
2181
2182static int vsc85xx_config_aneg(struct phy_device *phydev)
2183{
2184	int rc;
2185
2186	rc = vsc85xx_mdix_set(phydev, phydev->mdix_ctrl);
2187	if (rc < 0)
2188		return rc;
2189
2190	return genphy_config_aneg(phydev);
2191}
2192
2193static int vsc85xx_read_status(struct phy_device *phydev)
2194{
2195	int rc;
2196
2197	rc = vsc85xx_mdix_get(phydev, &phydev->mdix);
2198	if (rc < 0)
2199		return rc;
2200
2201	return genphy_read_status(phydev);
2202}
2203
2204static int vsc8514_probe(struct phy_device *phydev)
2205{
2206	struct vsc8531_private *vsc8531;
2207	u32 default_mode[4] = {VSC8531_LINK_1000_ACTIVITY,
2208	   VSC8531_LINK_100_ACTIVITY, VSC8531_LINK_ACTIVITY,
2209	   VSC8531_DUPLEX_COLLISION};
2210
2211	vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
2212	if (!vsc8531)
2213		return -ENOMEM;
2214
2215	phydev->priv = vsc8531;
2216
2217	vsc8584_get_base_addr(phydev);
2218	devm_phy_package_join(&phydev->mdio.dev, phydev,
2219			      vsc8531->base_addr, 0);
2220
2221	vsc8531->nleds = 4;
2222	vsc8531->supp_led_modes = VSC85XX_SUPP_LED_MODES;
2223	vsc8531->hw_stats = vsc85xx_hw_stats;
2224	vsc8531->nstats = ARRAY_SIZE(vsc85xx_hw_stats);
2225	vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats,
2226				      sizeof(u64), GFP_KERNEL);
2227	if (!vsc8531->stats)
2228		return -ENOMEM;
2229
2230	return vsc85xx_dt_led_modes_get(phydev, default_mode);
2231}
2232
2233static int vsc8574_probe(struct phy_device *phydev)
2234{
2235	struct vsc8531_private *vsc8531;
2236	u32 default_mode[4] = {VSC8531_LINK_1000_ACTIVITY,
2237	   VSC8531_LINK_100_ACTIVITY, VSC8531_LINK_ACTIVITY,
2238	   VSC8531_DUPLEX_COLLISION};
2239
2240	vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
2241	if (!vsc8531)
2242		return -ENOMEM;
2243
2244	phydev->priv = vsc8531;
2245
2246	vsc8584_get_base_addr(phydev);
2247	devm_phy_package_join(&phydev->mdio.dev, phydev,
2248			      vsc8531->base_addr, 0);
2249
2250	vsc8531->nleds = 4;
2251	vsc8531->supp_led_modes = VSC8584_SUPP_LED_MODES;
2252	vsc8531->hw_stats = vsc8584_hw_stats;
2253	vsc8531->nstats = ARRAY_SIZE(vsc8584_hw_stats);
2254	vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats,
2255				      sizeof(u64), GFP_KERNEL);
2256	if (!vsc8531->stats)
2257		return -ENOMEM;
2258
2259	return vsc85xx_dt_led_modes_get(phydev, default_mode);
2260}
2261
2262static int vsc8584_probe(struct phy_device *phydev)
2263{
2264	struct vsc8531_private *vsc8531;
2265	u32 default_mode[4] = {VSC8531_LINK_1000_ACTIVITY,
2266	   VSC8531_LINK_100_ACTIVITY, VSC8531_LINK_ACTIVITY,
2267	   VSC8531_DUPLEX_COLLISION};
2268	int ret;
2269
2270	if ((phydev->phy_id & MSCC_DEV_REV_MASK) != VSC8584_REVB) {
2271		dev_err(&phydev->mdio.dev, "Only VSC8584 revB is supported.\n");
2272		return -ENOTSUPP;
2273	}
2274
2275	vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
2276	if (!vsc8531)
2277		return -ENOMEM;
2278
2279	phydev->priv = vsc8531;
2280
2281	vsc8584_get_base_addr(phydev);
2282	devm_phy_package_join(&phydev->mdio.dev, phydev, vsc8531->base_addr,
2283			      sizeof(struct vsc85xx_shared_private));
2284
2285	vsc8531->nleds = 4;
2286	vsc8531->supp_led_modes = VSC8584_SUPP_LED_MODES;
2287	vsc8531->hw_stats = vsc8584_hw_stats;
2288	vsc8531->nstats = ARRAY_SIZE(vsc8584_hw_stats);
2289	vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats,
2290				      sizeof(u64), GFP_KERNEL);
2291	if (!vsc8531->stats)
2292		return -ENOMEM;
2293
2294	if (phy_package_probe_once(phydev)) {
2295		ret = vsc8584_ptp_probe_once(phydev);
2296		if (ret)
2297			return ret;
2298	}
2299
2300	ret = vsc8584_ptp_probe(phydev);
2301	if (ret)
2302		return ret;
2303
2304	return vsc85xx_dt_led_modes_get(phydev, default_mode);
2305}
2306
2307static int vsc85xx_probe(struct phy_device *phydev)
2308{
2309	struct vsc8531_private *vsc8531;
2310	int rate_magic;
2311	u32 default_mode[2] = {VSC8531_LINK_1000_ACTIVITY,
2312	   VSC8531_LINK_100_ACTIVITY};
2313
2314	rate_magic = vsc85xx_edge_rate_magic_get(phydev);
2315	if (rate_magic < 0)
2316		return rate_magic;
2317
2318	vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
2319	if (!vsc8531)
2320		return -ENOMEM;
2321
2322	phydev->priv = vsc8531;
2323
2324	vsc8531->rate_magic = rate_magic;
2325	vsc8531->nleds = 2;
2326	vsc8531->supp_led_modes = VSC85XX_SUPP_LED_MODES;
2327	vsc8531->hw_stats = vsc85xx_hw_stats;
2328	vsc8531->nstats = ARRAY_SIZE(vsc85xx_hw_stats);
2329	vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats,
2330				      sizeof(u64), GFP_KERNEL);
2331	if (!vsc8531->stats)
2332		return -ENOMEM;
2333
2334	return vsc85xx_dt_led_modes_get(phydev, default_mode);
2335}
2336
2337/* Microsemi VSC85xx PHYs */
2338static struct phy_driver vsc85xx_driver[] = {
2339{
2340	.phy_id		= PHY_ID_VSC8501,
2341	.name		= "Microsemi GE VSC8501 SyncE",
2342	.phy_id_mask	= 0xfffffff0,
2343	/* PHY_BASIC_FEATURES */
2344	.soft_reset	= &genphy_soft_reset,
2345	.config_init	= &vsc85xx_config_init,
2346	.config_aneg    = &vsc85xx_config_aneg,
2347	.read_status	= &vsc85xx_read_status,
2348	.handle_interrupt = vsc85xx_handle_interrupt,
2349	.config_intr	= &vsc85xx_config_intr,
2350	.suspend	= &genphy_suspend,
2351	.resume		= &genphy_resume,
2352	.probe		= &vsc85xx_probe,
2353	.set_wol	= &vsc85xx_wol_set,
2354	.get_wol	= &vsc85xx_wol_get,
2355	.get_tunable	= &vsc85xx_get_tunable,
2356	.set_tunable	= &vsc85xx_set_tunable,
2357	.read_page	= &vsc85xx_phy_read_page,
2358	.write_page	= &vsc85xx_phy_write_page,
2359	.get_sset_count = &vsc85xx_get_sset_count,
2360	.get_strings    = &vsc85xx_get_strings,
2361	.get_stats      = &vsc85xx_get_stats,
2362},
2363{
2364	.phy_id		= PHY_ID_VSC8502,
2365	.name		= "Microsemi GE VSC8502 SyncE",
2366	.phy_id_mask	= 0xfffffff0,
2367	/* PHY_BASIC_FEATURES */
2368	.soft_reset	= &genphy_soft_reset,
2369	.config_init	= &vsc85xx_config_init,
2370	.config_aneg    = &vsc85xx_config_aneg,
2371	.read_status	= &vsc85xx_read_status,
2372	.handle_interrupt = vsc85xx_handle_interrupt,
2373	.config_intr	= &vsc85xx_config_intr,
2374	.suspend	= &genphy_suspend,
2375	.resume		= &genphy_resume,
2376	.probe		= &vsc85xx_probe,
2377	.set_wol	= &vsc85xx_wol_set,
2378	.get_wol	= &vsc85xx_wol_get,
2379	.get_tunable	= &vsc85xx_get_tunable,
2380	.set_tunable	= &vsc85xx_set_tunable,
2381	.read_page	= &vsc85xx_phy_read_page,
2382	.write_page	= &vsc85xx_phy_write_page,
2383	.get_sset_count = &vsc85xx_get_sset_count,
2384	.get_strings    = &vsc85xx_get_strings,
2385	.get_stats      = &vsc85xx_get_stats,
2386},
2387{
2388	.phy_id		= PHY_ID_VSC8504,
2389	.name		= "Microsemi GE VSC8504 SyncE",
2390	.phy_id_mask	= 0xfffffff0,
2391	/* PHY_GBIT_FEATURES */
2392	.soft_reset	= &genphy_soft_reset,
2393	.config_init    = &vsc8584_config_init,
2394	.config_aneg    = &vsc85xx_config_aneg,
2395	.aneg_done	= &genphy_aneg_done,
2396	.read_status	= &vsc85xx_read_status,
2397	.handle_interrupt = vsc85xx_handle_interrupt,
2398	.config_intr    = &vsc85xx_config_intr,
2399	.suspend	= &genphy_suspend,
2400	.resume		= &genphy_resume,
2401	.probe		= &vsc8574_probe,
2402	.set_wol	= &vsc85xx_wol_set,
2403	.get_wol	= &vsc85xx_wol_get,
2404	.get_tunable	= &vsc85xx_get_tunable,
2405	.set_tunable	= &vsc85xx_set_tunable,
2406	.read_page	= &vsc85xx_phy_read_page,
2407	.write_page	= &vsc85xx_phy_write_page,
2408	.get_sset_count = &vsc85xx_get_sset_count,
2409	.get_strings    = &vsc85xx_get_strings,
2410	.get_stats      = &vsc85xx_get_stats,
2411},
2412{
2413	.phy_id		= PHY_ID_VSC8514,
2414	.name		= "Microsemi GE VSC8514 SyncE",
2415	.phy_id_mask	= 0xfffffff0,
2416	.soft_reset	= &genphy_soft_reset,
2417	.config_init    = &vsc8514_config_init,
2418	.config_aneg    = &vsc85xx_config_aneg,
2419	.read_status	= &vsc85xx_read_status,
2420	.handle_interrupt = vsc85xx_handle_interrupt,
2421	.config_intr    = &vsc85xx_config_intr,
2422	.suspend	= &genphy_suspend,
2423	.resume		= &genphy_resume,
2424	.probe		= &vsc8514_probe,
2425	.set_wol	= &vsc85xx_wol_set,
2426	.get_wol	= &vsc85xx_wol_get,
2427	.get_tunable	= &vsc85xx_get_tunable,
2428	.set_tunable	= &vsc85xx_set_tunable,
2429	.read_page      = &vsc85xx_phy_read_page,
2430	.write_page     = &vsc85xx_phy_write_page,
2431	.get_sset_count = &vsc85xx_get_sset_count,
2432	.get_strings    = &vsc85xx_get_strings,
2433	.get_stats      = &vsc85xx_get_stats,
2434},
2435{
2436	.phy_id		= PHY_ID_VSC8530,
2437	.name		= "Microsemi FE VSC8530",
2438	.phy_id_mask	= 0xfffffff0,
2439	/* PHY_BASIC_FEATURES */
2440	.soft_reset	= &genphy_soft_reset,
2441	.config_init	= &vsc85xx_config_init,
2442	.config_aneg    = &vsc85xx_config_aneg,
2443	.read_status	= &vsc85xx_read_status,
2444	.handle_interrupt = vsc85xx_handle_interrupt,
2445	.config_intr	= &vsc85xx_config_intr,
2446	.suspend	= &genphy_suspend,
2447	.resume		= &genphy_resume,
2448	.probe		= &vsc85xx_probe,
2449	.set_wol	= &vsc85xx_wol_set,
2450	.get_wol	= &vsc85xx_wol_get,
2451	.get_tunable	= &vsc85xx_get_tunable,
2452	.set_tunable	= &vsc85xx_set_tunable,
2453	.read_page	= &vsc85xx_phy_read_page,
2454	.write_page	= &vsc85xx_phy_write_page,
2455	.get_sset_count = &vsc85xx_get_sset_count,
2456	.get_strings    = &vsc85xx_get_strings,
2457	.get_stats      = &vsc85xx_get_stats,
2458},
2459{
2460	.phy_id		= PHY_ID_VSC8531,
2461	.name		= "Microsemi VSC8531",
2462	.phy_id_mask    = 0xfffffff0,
2463	/* PHY_GBIT_FEATURES */
2464	.soft_reset	= &genphy_soft_reset,
2465	.config_init    = &vsc85xx_config_init,
2466	.config_aneg    = &vsc85xx_config_aneg,
2467	.read_status	= &vsc85xx_read_status,
2468	.handle_interrupt = vsc85xx_handle_interrupt,
2469	.config_intr    = &vsc85xx_config_intr,
2470	.suspend	= &genphy_suspend,
2471	.resume		= &genphy_resume,
2472	.probe		= &vsc85xx_probe,
2473	.set_wol	= &vsc85xx_wol_set,
2474	.get_wol	= &vsc85xx_wol_get,
2475	.get_tunable	= &vsc85xx_get_tunable,
2476	.set_tunable	= &vsc85xx_set_tunable,
2477	.read_page	= &vsc85xx_phy_read_page,
2478	.write_page	= &vsc85xx_phy_write_page,
2479	.get_sset_count = &vsc85xx_get_sset_count,
2480	.get_strings    = &vsc85xx_get_strings,
2481	.get_stats      = &vsc85xx_get_stats,
2482},
2483{
2484	.phy_id		= PHY_ID_VSC8540,
2485	.name		= "Microsemi FE VSC8540 SyncE",
2486	.phy_id_mask	= 0xfffffff0,
2487	/* PHY_BASIC_FEATURES */
2488	.soft_reset	= &genphy_soft_reset,
2489	.config_init	= &vsc85xx_config_init,
2490	.config_aneg	= &vsc85xx_config_aneg,
2491	.read_status	= &vsc85xx_read_status,
2492	.handle_interrupt = vsc85xx_handle_interrupt,
2493	.config_intr	= &vsc85xx_config_intr,
2494	.suspend	= &genphy_suspend,
2495	.resume		= &genphy_resume,
2496	.probe		= &vsc85xx_probe,
2497	.set_wol	= &vsc85xx_wol_set,
2498	.get_wol	= &vsc85xx_wol_get,
2499	.get_tunable	= &vsc85xx_get_tunable,
2500	.set_tunable	= &vsc85xx_set_tunable,
2501	.read_page	= &vsc85xx_phy_read_page,
2502	.write_page	= &vsc85xx_phy_write_page,
2503	.get_sset_count = &vsc85xx_get_sset_count,
2504	.get_strings    = &vsc85xx_get_strings,
2505	.get_stats      = &vsc85xx_get_stats,
2506},
2507{
2508	.phy_id		= PHY_ID_VSC8541,
2509	.name		= "Microsemi VSC8541 SyncE",
2510	.phy_id_mask    = 0xfffffff0,
2511	/* PHY_GBIT_FEATURES */
2512	.soft_reset	= &genphy_soft_reset,
2513	.config_init    = &vsc85xx_config_init,
2514	.config_aneg    = &vsc85xx_config_aneg,
2515	.read_status	= &vsc85xx_read_status,
2516	.handle_interrupt = vsc85xx_handle_interrupt,
2517	.config_intr    = &vsc85xx_config_intr,
2518	.suspend	= &genphy_suspend,
2519	.resume		= &genphy_resume,
2520	.probe		= &vsc85xx_probe,
2521	.set_wol	= &vsc85xx_wol_set,
2522	.get_wol	= &vsc85xx_wol_get,
2523	.get_tunable	= &vsc85xx_get_tunable,
2524	.set_tunable	= &vsc85xx_set_tunable,
2525	.read_page	= &vsc85xx_phy_read_page,
2526	.write_page	= &vsc85xx_phy_write_page,
2527	.get_sset_count = &vsc85xx_get_sset_count,
2528	.get_strings    = &vsc85xx_get_strings,
2529	.get_stats      = &vsc85xx_get_stats,
2530},
2531{
2532	.phy_id		= PHY_ID_VSC8552,
2533	.name		= "Microsemi GE VSC8552 SyncE",
2534	.phy_id_mask	= 0xfffffff0,
2535	/* PHY_GBIT_FEATURES */
2536	.soft_reset	= &genphy_soft_reset,
2537	.config_init    = &vsc8584_config_init,
2538	.config_aneg    = &vsc85xx_config_aneg,
2539	.read_status	= &vsc85xx_read_status,
2540	.handle_interrupt = vsc85xx_handle_interrupt,
2541	.config_intr    = &vsc85xx_config_intr,
2542	.suspend	= &genphy_suspend,
2543	.resume		= &genphy_resume,
2544	.probe		= &vsc8574_probe,
2545	.set_wol	= &vsc85xx_wol_set,
2546	.get_wol	= &vsc85xx_wol_get,
2547	.get_tunable	= &vsc85xx_get_tunable,
2548	.set_tunable	= &vsc85xx_set_tunable,
2549	.read_page	= &vsc85xx_phy_read_page,
2550	.write_page	= &vsc85xx_phy_write_page,
2551	.get_sset_count = &vsc85xx_get_sset_count,
2552	.get_strings    = &vsc85xx_get_strings,
2553	.get_stats      = &vsc85xx_get_stats,
2554},
2555{
2556	.phy_id		= PHY_ID_VSC856X,
2557	.name		= "Microsemi GE VSC856X SyncE",
2558	.phy_id_mask	= 0xfffffff0,
2559	/* PHY_GBIT_FEATURES */
2560	.soft_reset	= &genphy_soft_reset,
2561	.config_init    = &vsc8584_config_init,
2562	.config_aneg    = &vsc85xx_config_aneg,
2563	.read_status	= &vsc85xx_read_status,
2564	.handle_interrupt = vsc85xx_handle_interrupt,
2565	.config_intr    = &vsc85xx_config_intr,
2566	.suspend	= &genphy_suspend,
2567	.resume		= &genphy_resume,
2568	.probe		= &vsc8584_probe,
2569	.get_tunable	= &vsc85xx_get_tunable,
2570	.set_tunable	= &vsc85xx_set_tunable,
2571	.read_page	= &vsc85xx_phy_read_page,
2572	.write_page	= &vsc85xx_phy_write_page,
2573	.get_sset_count = &vsc85xx_get_sset_count,
2574	.get_strings    = &vsc85xx_get_strings,
2575	.get_stats      = &vsc85xx_get_stats,
2576},
2577{
2578	.phy_id		= PHY_ID_VSC8572,
2579	.name		= "Microsemi GE VSC8572 SyncE",
2580	.phy_id_mask	= 0xfffffff0,
2581	/* PHY_GBIT_FEATURES */
2582	.soft_reset	= &genphy_soft_reset,
2583	.config_init    = &vsc8584_config_init,
2584	.config_aneg    = &vsc85xx_config_aneg,
2585	.aneg_done	= &genphy_aneg_done,
2586	.read_status	= &vsc85xx_read_status,
2587	.handle_interrupt = &vsc8584_handle_interrupt,
2588	.config_intr    = &vsc85xx_config_intr,
2589	.suspend	= &genphy_suspend,
2590	.resume		= &genphy_resume,
2591	.probe		= &vsc8574_probe,
2592	.set_wol	= &vsc85xx_wol_set,
2593	.get_wol	= &vsc85xx_wol_get,
2594	.get_tunable	= &vsc85xx_get_tunable,
2595	.set_tunable	= &vsc85xx_set_tunable,
2596	.read_page	= &vsc85xx_phy_read_page,
2597	.write_page	= &vsc85xx_phy_write_page,
2598	.get_sset_count = &vsc85xx_get_sset_count,
2599	.get_strings    = &vsc85xx_get_strings,
2600	.get_stats      = &vsc85xx_get_stats,
2601},
2602{
2603	.phy_id		= PHY_ID_VSC8574,
2604	.name		= "Microsemi GE VSC8574 SyncE",
2605	.phy_id_mask	= 0xfffffff0,
2606	/* PHY_GBIT_FEATURES */
2607	.soft_reset	= &genphy_soft_reset,
2608	.config_init    = &vsc8584_config_init,
2609	.config_aneg    = &vsc85xx_config_aneg,
2610	.aneg_done	= &genphy_aneg_done,
2611	.read_status	= &vsc85xx_read_status,
2612	.handle_interrupt = vsc85xx_handle_interrupt,
2613	.config_intr    = &vsc85xx_config_intr,
2614	.suspend	= &genphy_suspend,
2615	.resume		= &genphy_resume,
2616	.probe		= &vsc8574_probe,
2617	.set_wol	= &vsc85xx_wol_set,
2618	.get_wol	= &vsc85xx_wol_get,
2619	.get_tunable	= &vsc85xx_get_tunable,
2620	.set_tunable	= &vsc85xx_set_tunable,
2621	.read_page	= &vsc85xx_phy_read_page,
2622	.write_page	= &vsc85xx_phy_write_page,
2623	.get_sset_count = &vsc85xx_get_sset_count,
2624	.get_strings    = &vsc85xx_get_strings,
2625	.get_stats      = &vsc85xx_get_stats,
2626},
2627{
2628	.phy_id		= PHY_ID_VSC8575,
2629	.name		= "Microsemi GE VSC8575 SyncE",
2630	.phy_id_mask	= 0xfffffff0,
2631	/* PHY_GBIT_FEATURES */
2632	.soft_reset	= &genphy_soft_reset,
2633	.config_init    = &vsc8584_config_init,
2634	.config_aneg    = &vsc85xx_config_aneg,
2635	.aneg_done	= &genphy_aneg_done,
2636	.read_status	= &vsc85xx_read_status,
2637	.handle_interrupt = &vsc8584_handle_interrupt,
2638	.config_intr    = &vsc85xx_config_intr,
2639	.suspend	= &genphy_suspend,
2640	.resume		= &genphy_resume,
2641	.probe		= &vsc8584_probe,
2642	.get_tunable	= &vsc85xx_get_tunable,
2643	.set_tunable	= &vsc85xx_set_tunable,
2644	.read_page	= &vsc85xx_phy_read_page,
2645	.write_page	= &vsc85xx_phy_write_page,
2646	.get_sset_count = &vsc85xx_get_sset_count,
2647	.get_strings    = &vsc85xx_get_strings,
2648	.get_stats      = &vsc85xx_get_stats,
2649},
2650{
2651	.phy_id		= PHY_ID_VSC8582,
2652	.name		= "Microsemi GE VSC8582 SyncE",
2653	.phy_id_mask	= 0xfffffff0,
2654	/* PHY_GBIT_FEATURES */
2655	.soft_reset	= &genphy_soft_reset,
2656	.config_init    = &vsc8584_config_init,
2657	.config_aneg    = &vsc85xx_config_aneg,
2658	.aneg_done	= &genphy_aneg_done,
2659	.read_status	= &vsc85xx_read_status,
2660	.handle_interrupt = &vsc8584_handle_interrupt,
2661	.config_intr    = &vsc85xx_config_intr,
2662	.suspend	= &genphy_suspend,
2663	.resume		= &genphy_resume,
2664	.probe		= &vsc8584_probe,
2665	.get_tunable	= &vsc85xx_get_tunable,
2666	.set_tunable	= &vsc85xx_set_tunable,
2667	.read_page	= &vsc85xx_phy_read_page,
2668	.write_page	= &vsc85xx_phy_write_page,
2669	.get_sset_count = &vsc85xx_get_sset_count,
2670	.get_strings    = &vsc85xx_get_strings,
2671	.get_stats      = &vsc85xx_get_stats,
2672},
2673{
2674	.phy_id		= PHY_ID_VSC8584,
2675	.name		= "Microsemi GE VSC8584 SyncE",
2676	.phy_id_mask	= 0xfffffff0,
2677	/* PHY_GBIT_FEATURES */
2678	.soft_reset	= &genphy_soft_reset,
2679	.config_init    = &vsc8584_config_init,
2680	.config_aneg    = &vsc85xx_config_aneg,
2681	.aneg_done	= &genphy_aneg_done,
2682	.read_status	= &vsc85xx_read_status,
2683	.handle_interrupt = &vsc8584_handle_interrupt,
2684	.config_intr    = &vsc85xx_config_intr,
2685	.suspend	= &genphy_suspend,
2686	.resume		= &genphy_resume,
2687	.probe		= &vsc8584_probe,
2688	.get_tunable	= &vsc85xx_get_tunable,
2689	.set_tunable	= &vsc85xx_set_tunable,
2690	.read_page	= &vsc85xx_phy_read_page,
2691	.write_page	= &vsc85xx_phy_write_page,
2692	.get_sset_count = &vsc85xx_get_sset_count,
2693	.get_strings    = &vsc85xx_get_strings,
2694	.get_stats      = &vsc85xx_get_stats,
2695	.link_change_notify = &vsc85xx_link_change_notify,
2696}
2697
2698};
2699
2700module_phy_driver(vsc85xx_driver);
2701
2702static struct mdio_device_id __maybe_unused vsc85xx_tbl[] = {
2703	{ PHY_ID_MATCH_VENDOR(PHY_VENDOR_MSCC) },
2704	{ }
2705};
2706
2707MODULE_DEVICE_TABLE(mdio, vsc85xx_tbl);
2708
2709MODULE_DESCRIPTION("Microsemi VSC85xx PHY driver");
2710MODULE_AUTHOR("Nagaraju Lakkaraju");
2711MODULE_LICENSE("Dual MIT/GPL");
2712
2713MODULE_FIRMWARE(MSCC_VSC8584_REVB_INT8051_FW);
2714MODULE_FIRMWARE(MSCC_VSC8574_REVB_INT8051_FW);