Linux Audio

Check our new training course

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