File Index
Files and directories
Sign in
FILE

mscc_main.c

File preview with syntax highlighting.

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