Linux Audio

Check our new training course

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