Linux Audio

Check our new training course

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