File Index
Files and directories
Sign in
FILE

marvell.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/phy/marvell.c C
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * drivers/net/phy/marvell.c
   4 *
   5 * Driver for Marvell PHYs
   6 *
   7 * Author: Andy Fleming
   8 *
   9 * Copyright (c) 2004 Freescale Semiconductor, Inc.
  10 *
  11 * Copyright (c) 2013 Michael Stapelberg <michael@stapelberg.de>
  12 */
  13#include <linux/kernel.h>
  14#include <linux/string.h>
  15#include <linux/ctype.h>
  16#include <linux/errno.h>
  17#include <linux/unistd.h>
  18#include <linux/hwmon.h>
  19#include <linux/interrupt.h>
  20#include <linux/init.h>
  21#include <linux/delay.h>
  22#include <linux/netdevice.h>
  23#include <linux/etherdevice.h>
  24#include <linux/skbuff.h>
  25#include <linux/spinlock.h>
  26#include <linux/mm.h>
  27#include <linux/module.h>
  28#include <linux/mii.h>
  29#include <linux/ethtool.h>
  30#include <linux/ethtool_netlink.h>
  31#include <linux/phy.h>
  32#include <linux/marvell_phy.h>
  33#include <linux/bitfield.h>
  34#include <linux/of.h>
  35#include <linux/sfp.h>
  36
  37#include <linux/io.h>
  38#include <asm/irq.h>
  39#include <linux/uaccess.h>
  40
  41#define MII_MARVELL_PHY_PAGE		22
  42#define MII_MARVELL_COPPER_PAGE		0x00
  43#define MII_MARVELL_FIBER_PAGE		0x01
  44#define MII_MARVELL_MSCR_PAGE		0x02
  45#define MII_MARVELL_LED_PAGE		0x03
  46#define MII_MARVELL_VCT5_PAGE		0x05
  47#define MII_MARVELL_MISC_TEST_PAGE	0x06
  48#define MII_MARVELL_VCT7_PAGE		0x07
  49#define MII_MARVELL_WOL_PAGE		0x11
  50#define MII_MARVELL_MODE_PAGE		0x12
  51
  52#define MII_M1011_IEVENT		0x13
  53#define MII_M1011_IEVENT_CLEAR		0x0000
  54
  55#define MII_M1011_IMASK			0x12
  56#define MII_M1011_IMASK_INIT		0x6400
  57#define MII_M1011_IMASK_CLEAR		0x0000
  58
  59#define MII_M1011_PHY_SCR			0x10
  60#define MII_M1011_PHY_SCR_DOWNSHIFT_EN		BIT(11)
  61#define MII_M1011_PHY_SCR_DOWNSHIFT_MASK	GENMASK(14, 12)
  62#define MII_M1011_PHY_SCR_DOWNSHIFT_MAX		8
  63#define MII_M1011_PHY_SCR_MDI			(0x0 << 5)
  64#define MII_M1011_PHY_SCR_MDI_X			(0x1 << 5)
  65#define MII_M1011_PHY_SCR_AUTO_CROSS		(0x3 << 5)
  66
  67#define MII_M1011_PHY_SSR			0x11
  68#define MII_M1011_PHY_SSR_DOWNSHIFT		BIT(5)
  69
  70#define MII_M1111_PHY_LED_CONTROL	0x18
  71#define MII_M1111_PHY_LED_DIRECT	0x4100
  72#define MII_M1111_PHY_LED_COMBINE	0x411c
  73#define MII_M1111_PHY_EXT_CR		0x14
  74#define MII_M1111_PHY_EXT_CR_DOWNSHIFT_MASK	GENMASK(11, 9)
  75#define MII_M1111_PHY_EXT_CR_DOWNSHIFT_MAX	8
  76#define MII_M1111_PHY_EXT_CR_DOWNSHIFT_EN	BIT(8)
  77#define MII_M1111_RGMII_RX_DELAY	BIT(7)
  78#define MII_M1111_RGMII_TX_DELAY	BIT(1)
  79#define MII_M1111_PHY_EXT_SR		0x1b
  80
  81#define MII_M1111_HWCFG_MODE_MASK		0xf
  82#define MII_M1111_HWCFG_MODE_FIBER_RGMII	0x3
  83#define MII_M1111_HWCFG_MODE_SGMII_NO_CLK	0x4
  84#define MII_M1111_HWCFG_MODE_RTBI		0x7
  85#define MII_M1111_HWCFG_MODE_COPPER_1000X_AN	0x8
  86#define MII_M1111_HWCFG_MODE_COPPER_RTBI	0x9
  87#define MII_M1111_HWCFG_MODE_COPPER_RGMII	0xb
  88#define MII_M1111_HWCFG_MODE_COPPER_1000X_NOAN	0xc
  89#define MII_M1111_HWCFG_SERIAL_AN_BYPASS	BIT(12)
  90#define MII_M1111_HWCFG_FIBER_COPPER_RES	BIT(13)
  91#define MII_M1111_HWCFG_FIBER_COPPER_AUTO	BIT(15)
  92
  93#define MII_88E1121_PHY_MSCR_REG	21
  94#define MII_88E1121_PHY_MSCR_RX_DELAY	BIT(5)
  95#define MII_88E1121_PHY_MSCR_TX_DELAY	BIT(4)
  96#define MII_88E1121_PHY_MSCR_DELAY_MASK	(BIT(5) | BIT(4))
  97
  98#define MII_88E1121_MISC_TEST				0x1a
  99#define MII_88E1510_MISC_TEST_TEMP_THRESHOLD_MASK	0x1f00
 100#define MII_88E1510_MISC_TEST_TEMP_THRESHOLD_SHIFT	8
 101#define MII_88E1510_MISC_TEST_TEMP_IRQ_EN		BIT(7)
 102#define MII_88E1510_MISC_TEST_TEMP_IRQ			BIT(6)
 103#define MII_88E1121_MISC_TEST_TEMP_SENSOR_EN		BIT(5)
 104#define MII_88E1121_MISC_TEST_TEMP_MASK			0x1f
 105
 106#define MII_88E1510_TEMP_SENSOR		0x1b
 107#define MII_88E1510_TEMP_SENSOR_MASK	0xff
 108
 109#define MII_88E1540_COPPER_CTRL3	0x1a
 110#define MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_MASK	GENMASK(11, 10)
 111#define MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_00MS	0
 112#define MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_10MS	1
 113#define MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_20MS	2
 114#define MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_40MS	3
 115#define MII_88E1540_COPPER_CTRL3_FAST_LINK_DOWN		BIT(9)
 116
 117#define MII_88E6390_MISC_TEST		0x1b
 118#define MII_88E6390_MISC_TEST_TEMP_SENSOR_ENABLE_SAMPLE_1S	(0x0 << 14)
 119#define MII_88E6390_MISC_TEST_TEMP_SENSOR_ENABLE		(0x1 << 14)
 120#define MII_88E6390_MISC_TEST_TEMP_SENSOR_ENABLE_ONESHOT	(0x2 << 14)
 121#define MII_88E6390_MISC_TEST_TEMP_SENSOR_DISABLE		(0x3 << 14)
 122#define MII_88E6390_MISC_TEST_TEMP_SENSOR_MASK			(0x3 << 14)
 123#define MII_88E6393_MISC_TEST_SAMPLES_2048	(0x0 << 11)
 124#define MII_88E6393_MISC_TEST_SAMPLES_4096	(0x1 << 11)
 125#define MII_88E6393_MISC_TEST_SAMPLES_8192	(0x2 << 11)
 126#define MII_88E6393_MISC_TEST_SAMPLES_16384	(0x3 << 11)
 127#define MII_88E6393_MISC_TEST_SAMPLES_MASK	(0x3 << 11)
 128#define MII_88E6393_MISC_TEST_RATE_2_3MS	(0x5 << 8)
 129#define MII_88E6393_MISC_TEST_RATE_6_4MS	(0x6 << 8)
 130#define MII_88E6393_MISC_TEST_RATE_11_9MS	(0x7 << 8)
 131#define MII_88E6393_MISC_TEST_RATE_MASK		(0x7 << 8)
 132
 133#define MII_88E6390_TEMP_SENSOR		0x1c
 134#define MII_88E6393_TEMP_SENSOR_THRESHOLD_MASK	0xff00
 135#define MII_88E6393_TEMP_SENSOR_THRESHOLD_SHIFT	8
 136#define MII_88E6390_TEMP_SENSOR_MASK		0xff
 137#define MII_88E6390_TEMP_SENSOR_SAMPLES		10
 138
 139#define MII_88E1318S_PHY_MSCR1_REG	16
 140#define MII_88E1318S_PHY_MSCR1_PAD_ODD	BIT(6)
 141
 142/* Copper Specific Interrupt Enable Register */
 143#define MII_88E1318S_PHY_CSIER				0x12
 144/* WOL Event Interrupt Enable */
 145#define MII_88E1318S_PHY_CSIER_WOL_EIE			BIT(7)
 146
 147#define MII_88E1318S_PHY_LED_FUNC		0x10
 148#define MII_88E1318S_PHY_LED_FUNC_OFF		(0x8)
 149#define MII_88E1318S_PHY_LED_FUNC_ON		(0x9)
 150#define MII_88E1318S_PHY_LED_FUNC_HI_Z		(0xa)
 151#define MII_88E1318S_PHY_LED_FUNC_BLINK		(0xb)
 152#define MII_88E1318S_PHY_LED_TCR		0x12
 153#define MII_88E1318S_PHY_LED_TCR_FORCE_INT	BIT(15)
 154#define MII_88E1318S_PHY_LED_TCR_INTn_ENABLE	BIT(7)
 155#define MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW	BIT(11)
 156
 157/* Magic Packet MAC address registers */
 158#define MII_88E1318S_PHY_MAGIC_PACKET_WORD2		0x17
 159#define MII_88E1318S_PHY_MAGIC_PACKET_WORD1		0x18
 160#define MII_88E1318S_PHY_MAGIC_PACKET_WORD0		0x19
 161
 162#define MII_88E1318S_PHY_WOL_CTRL				0x10
 163#define MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS		BIT(12)
 164#define MII_88E1318S_PHY_WOL_CTRL_LINK_UP_ENABLE		BIT(13)
 165#define MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE	BIT(14)
 166
 167#define MII_PHY_LED_CTRL	        16
 168#define MII_88E1121_PHY_LED_DEF		0x0030
 169#define MII_88E1510_PHY_LED_DEF		0x1177
 170#define MII_88E1510_PHY_LED0_LINK_LED1_ACTIVE	0x1040
 171
 172#define MII_M1011_PHY_STATUS		0x11
 173#define MII_M1011_PHY_STATUS_1000	0x8000
 174#define MII_M1011_PHY_STATUS_100	0x4000
 175#define MII_M1011_PHY_STATUS_SPD_MASK	0xc000
 176#define MII_M1011_PHY_STATUS_FULLDUPLEX	0x2000
 177#define MII_M1011_PHY_STATUS_RESOLVED	0x0800
 178#define MII_M1011_PHY_STATUS_LINK	0x0400
 179#define MII_M1011_PHY_STATUS_MDIX	BIT(6)
 180
 181#define MII_88E3016_PHY_SPEC_CTRL	0x10
 182#define MII_88E3016_DISABLE_SCRAMBLER	0x0200
 183#define MII_88E3016_AUTO_MDIX_CROSSOVER	0x0030
 184
 185#define MII_88E1510_GEN_CTRL_REG_1		0x14
 186#define MII_88E1510_GEN_CTRL_REG_1_MODE_MASK	0x7
 187#define MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII	0x0	/* RGMII to copper */
 188#define MII_88E1510_GEN_CTRL_REG_1_MODE_SGMII	0x1	/* SGMII to copper */
 189/* RGMII to 1000BASE-X */
 190#define MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII_1000X	0x2
 191/* RGMII to 100BASE-FX */
 192#define MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII_100FX	0x3
 193/* RGMII to SGMII */
 194#define MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII_SGMII	0x4
 195#define MII_88E1510_GEN_CTRL_REG_1_RESET	0x8000	/* Soft reset */
 196
 197#define MII_88E1510_MSCR_2		0x15
 198
 199#define MII_VCT5_TX_RX_MDI0_COUPLING	0x10
 200#define MII_VCT5_TX_RX_MDI1_COUPLING	0x11
 201#define MII_VCT5_TX_RX_MDI2_COUPLING	0x12
 202#define MII_VCT5_TX_RX_MDI3_COUPLING	0x13
 203#define MII_VCT5_TX_RX_AMPLITUDE_MASK	0x7f00
 204#define MII_VCT5_TX_RX_AMPLITUDE_SHIFT	8
 205#define MII_VCT5_TX_RX_COUPLING_POSITIVE_REFLECTION	BIT(15)
 206
 207#define MII_VCT5_CTRL				0x17
 208#define MII_VCT5_CTRL_ENABLE				BIT(15)
 209#define MII_VCT5_CTRL_COMPLETE				BIT(14)
 210#define MII_VCT5_CTRL_TX_SAME_CHANNEL			(0x0 << 11)
 211#define MII_VCT5_CTRL_TX0_CHANNEL			(0x4 << 11)
 212#define MII_VCT5_CTRL_TX1_CHANNEL			(0x5 << 11)
 213#define MII_VCT5_CTRL_TX2_CHANNEL			(0x6 << 11)
 214#define MII_VCT5_CTRL_TX3_CHANNEL			(0x7 << 11)
 215#define MII_VCT5_CTRL_SAMPLES_2				(0x0 << 8)
 216#define MII_VCT5_CTRL_SAMPLES_4				(0x1 << 8)
 217#define MII_VCT5_CTRL_SAMPLES_8				(0x2 << 8)
 218#define MII_VCT5_CTRL_SAMPLES_16			(0x3 << 8)
 219#define MII_VCT5_CTRL_SAMPLES_32			(0x4 << 8)
 220#define MII_VCT5_CTRL_SAMPLES_64			(0x5 << 8)
 221#define MII_VCT5_CTRL_SAMPLES_128			(0x6 << 8)
 222#define MII_VCT5_CTRL_SAMPLES_DEFAULT			(0x6 << 8)
 223#define MII_VCT5_CTRL_SAMPLES_256			(0x7 << 8)
 224#define MII_VCT5_CTRL_SAMPLES_SHIFT			8
 225#define MII_VCT5_CTRL_MODE_MAXIMUM_PEEK			(0x0 << 6)
 226#define MII_VCT5_CTRL_MODE_FIRST_LAST_PEEK		(0x1 << 6)
 227#define MII_VCT5_CTRL_MODE_OFFSET			(0x2 << 6)
 228#define MII_VCT5_CTRL_SAMPLE_POINT			(0x3 << 6)
 229#define MII_VCT5_CTRL_PEEK_HYST_DEFAULT			3
 230
 231#define MII_VCT5_SAMPLE_POINT_DISTANCE		0x18
 232#define MII_VCT5_SAMPLE_POINT_DISTANCE_MAX	511
 233#define MII_VCT5_TX_PULSE_CTRL			0x1c
 234#define MII_VCT5_TX_PULSE_CTRL_DONT_WAIT_LINK_DOWN	BIT(12)
 235#define MII_VCT5_TX_PULSE_CTRL_PULSE_WIDTH_128nS	(0x0 << 10)
 236#define MII_VCT5_TX_PULSE_CTRL_PULSE_WIDTH_96nS		(0x1 << 10)
 237#define MII_VCT5_TX_PULSE_CTRL_PULSE_WIDTH_64nS		(0x2 << 10)
 238#define MII_VCT5_TX_PULSE_CTRL_PULSE_WIDTH_32nS		(0x3 << 10)
 239#define MII_VCT5_TX_PULSE_CTRL_PULSE_WIDTH_SHIFT	10
 240#define MII_VCT5_TX_PULSE_CTRL_PULSE_AMPLITUDE_1000mV	(0x0 << 8)
 241#define MII_VCT5_TX_PULSE_CTRL_PULSE_AMPLITUDE_750mV	(0x1 << 8)
 242#define MII_VCT5_TX_PULSE_CTRL_PULSE_AMPLITUDE_500mV	(0x2 << 8)
 243#define MII_VCT5_TX_PULSE_CTRL_PULSE_AMPLITUDE_250mV	(0x3 << 8)
 244#define MII_VCT5_TX_PULSE_CTRL_PULSE_AMPLITUDE_SHIFT	8
 245#define MII_VCT5_TX_PULSE_CTRL_MAX_AMP			BIT(7)
 246#define MII_VCT5_TX_PULSE_CTRL_GT_140m_46_86mV		(0x6 << 0)
 247
 248/* For TDR measurements less than 11 meters, a short pulse should be
 249 * used.
 250 */
 251#define TDR_SHORT_CABLE_LENGTH	11
 252
 253#define MII_VCT7_PAIR_0_DISTANCE	0x10
 254#define MII_VCT7_PAIR_1_DISTANCE	0x11
 255#define MII_VCT7_PAIR_2_DISTANCE	0x12
 256#define MII_VCT7_PAIR_3_DISTANCE	0x13
 257
 258#define MII_VCT7_RESULTS	0x14
 259#define MII_VCT7_RESULTS_PAIR3_MASK	0xf000
 260#define MII_VCT7_RESULTS_PAIR2_MASK	0x0f00
 261#define MII_VCT7_RESULTS_PAIR1_MASK	0x00f0
 262#define MII_VCT7_RESULTS_PAIR0_MASK	0x000f
 263#define MII_VCT7_RESULTS_PAIR3_SHIFT	12
 264#define MII_VCT7_RESULTS_PAIR2_SHIFT	8
 265#define MII_VCT7_RESULTS_PAIR1_SHIFT	4
 266#define MII_VCT7_RESULTS_PAIR0_SHIFT	0
 267#define MII_VCT7_RESULTS_INVALID	0
 268#define MII_VCT7_RESULTS_OK		1
 269#define MII_VCT7_RESULTS_OPEN		2
 270#define MII_VCT7_RESULTS_SAME_SHORT	3
 271#define MII_VCT7_RESULTS_CROSS_SHORT	4
 272#define MII_VCT7_RESULTS_BUSY		9
 273
 274#define MII_VCT7_CTRL		0x15
 275#define MII_VCT7_CTRL_RUN_NOW			BIT(15)
 276#define MII_VCT7_CTRL_RUN_ANEG			BIT(14)
 277#define MII_VCT7_CTRL_DISABLE_CROSS		BIT(13)
 278#define MII_VCT7_CTRL_RUN_AFTER_BREAK_LINK	BIT(12)
 279#define MII_VCT7_CTRL_IN_PROGRESS		BIT(11)
 280#define MII_VCT7_CTRL_METERS			BIT(10)
 281#define MII_VCT7_CTRL_CENTIMETERS		0
 282
 283#define MII_VCT_TXPINS			0x1A
 284#define MII_VCT_RXPINS			0x1B
 285#define MII_VCT_SR			0x1C
 286#define MII_VCT_TXPINS_ENVCT		BIT(15)
 287#define MII_VCT_TXRXPINS_VCTTST		GENMASK(14, 13)
 288#define MII_VCT_TXRXPINS_VCTTST_SHIFT	13
 289#define MII_VCT_TXRXPINS_VCTTST_OK	0
 290#define MII_VCT_TXRXPINS_VCTTST_SHORT	1
 291#define MII_VCT_TXRXPINS_VCTTST_OPEN	2
 292#define MII_VCT_TXRXPINS_VCTTST_FAIL	3
 293#define MII_VCT_TXRXPINS_AMPRFLN	GENMASK(12, 8)
 294#define MII_VCT_TXRXPINS_AMPRFLN_SHIFT	8
 295#define MII_VCT_TXRXPINS_DISTRFLN	GENMASK(7, 0)
 296#define MII_VCT_TXRXPINS_DISTRFLN_MAX	0xff
 297
 298#define M88E3082_PAIR_A		BIT(0)
 299#define M88E3082_PAIR_B		BIT(1)
 300
 301#define LPA_PAUSE_FIBER		0x180
 302#define LPA_PAUSE_ASYM_FIBER	0x100
 303
 304#define NB_FIBER_STATS	1
 305#define NB_STAT_MAX	3
 306
 307MODULE_DESCRIPTION("Marvell PHY driver");
 308MODULE_AUTHOR("Andy Fleming");
 309MODULE_LICENSE("GPL");
 310
 311struct marvell_hw_stat {
 312	const char *string;
 313	u8 page;
 314	u8 reg;
 315	u8 bits;
 316};
 317
 318static const struct marvell_hw_stat marvell_hw_stats[] = {
 319	{ "phy_receive_errors_copper", 0, 21, 16},
 320	{ "phy_idle_errors", 0, 10, 8 },
 321	{ "phy_receive_errors_fiber", 1, 21, 16},
 322};
 323
 324static_assert(ARRAY_SIZE(marvell_hw_stats) <= NB_STAT_MAX);
 325
 326/* "simple" stat list + corresponding marvell_get_*_simple functions are used
 327 * on PHYs without a page register
 328 */
 329struct marvell_hw_stat_simple {
 330	const char *string;
 331	u8 reg;
 332	u8 bits;
 333};
 334
 335static const struct marvell_hw_stat_simple marvell_hw_stats_simple[] = {
 336	{ "phy_receive_errors", 21, 16},
 337};
 338
 339static_assert(ARRAY_SIZE(marvell_hw_stats_simple) <= NB_STAT_MAX);
 340
 341enum {
 342	M88E3082_VCT_OFF,
 343	M88E3082_VCT_PHASE1,
 344	M88E3082_VCT_PHASE2,
 345};
 346
 347struct marvell_priv {
 348	u64 stats[NB_STAT_MAX];
 349	char *hwmon_name;
 350	struct device *hwmon_dev;
 351	bool cable_test_tdr;
 352	u32 first;
 353	u32 last;
 354	u32 step;
 355	s8 pair;
 356	u8 vct_phase;
 357};
 358
 359static int marvell_read_page(struct phy_device *phydev)
 360{
 361	return __phy_read(phydev, MII_MARVELL_PHY_PAGE);
 362}
 363
 364static int marvell_write_page(struct phy_device *phydev, int page)
 365{
 366	return __phy_write(phydev, MII_MARVELL_PHY_PAGE, page);
 367}
 368
 369static int marvell_set_page(struct phy_device *phydev, int page)
 370{
 371	return phy_write(phydev, MII_MARVELL_PHY_PAGE, page);
 372}
 373
 374static int marvell_ack_interrupt(struct phy_device *phydev)
 375{
 376	int err;
 377
 378	/* Clear the interrupts by reading the reg */
 379	err = phy_read(phydev, MII_M1011_IEVENT);
 380
 381	if (err < 0)
 382		return err;
 383
 384	return 0;
 385}
 386
 387static int marvell_config_intr(struct phy_device *phydev)
 388{
 389	int err;
 390
 391	if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
 392		err = marvell_ack_interrupt(phydev);
 393		if (err)
 394			return err;
 395
 396		err = phy_write(phydev, MII_M1011_IMASK,
 397				MII_M1011_IMASK_INIT);
 398	} else {
 399		err = phy_write(phydev, MII_M1011_IMASK,
 400				MII_M1011_IMASK_CLEAR);
 401		if (err)
 402			return err;
 403
 404		err = marvell_ack_interrupt(phydev);
 405	}
 406
 407	return err;
 408}
 409
 410static irqreturn_t marvell_handle_interrupt(struct phy_device *phydev)
 411{
 412	int irq_status;
 413
 414	irq_status = phy_read(phydev, MII_M1011_IEVENT);
 415	if (irq_status < 0) {
 416		phy_error(phydev);
 417		return IRQ_NONE;
 418	}
 419
 420	if (!(irq_status & MII_M1011_IMASK_INIT))
 421		return IRQ_NONE;
 422
 423	phy_trigger_machine(phydev);
 424
 425	return IRQ_HANDLED;
 426}
 427
 428static int marvell_set_polarity(struct phy_device *phydev, int polarity)
 429{
 430	u16 val;
 431
 432	switch (polarity) {
 433	case ETH_TP_MDI:
 434		val = MII_M1011_PHY_SCR_MDI;
 435		break;
 436	case ETH_TP_MDI_X:
 437		val = MII_M1011_PHY_SCR_MDI_X;
 438		break;
 439	case ETH_TP_MDI_AUTO:
 440	case ETH_TP_MDI_INVALID:
 441	default:
 442		val = MII_M1011_PHY_SCR_AUTO_CROSS;
 443		break;
 444	}
 445
 446	return phy_modify_changed(phydev, MII_M1011_PHY_SCR,
 447				  MII_M1011_PHY_SCR_AUTO_CROSS, val);
 448}
 449
 450static int marvell_config_aneg(struct phy_device *phydev)
 451{
 452	int changed = 0;
 453	int err;
 454
 455	err = marvell_set_polarity(phydev, phydev->mdix_ctrl);
 456	if (err < 0)
 457		return err;
 458
 459	changed = err;
 460
 461	err = phy_write(phydev, MII_M1111_PHY_LED_CONTROL,
 462			MII_M1111_PHY_LED_DIRECT);
 463	if (err < 0)
 464		return err;
 465
 466	err = genphy_config_aneg(phydev);
 467	if (err < 0)
 468		return err;
 469
 470	if (phydev->autoneg != AUTONEG_ENABLE || changed) {
 471		/* A write to speed/duplex bits (that is performed by
 472		 * genphy_config_aneg() call above) must be followed by
 473		 * a software reset. Otherwise, the write has no effect.
 474		 */
 475		err = genphy_soft_reset(phydev);
 476		if (err < 0)
 477			return err;
 478	}
 479
 480	return 0;
 481}
 482
 483static int m88e1101_config_aneg(struct phy_device *phydev)
 484{
 485	int err;
 486
 487	/* This Marvell PHY has an errata which requires
 488	 * that certain registers get written in order
 489	 * to restart autonegotiation
 490	 */
 491	err = genphy_soft_reset(phydev);
 492	if (err < 0)
 493		return err;
 494
 495	err = phy_write(phydev, 0x1d, 0x1f);
 496	if (err < 0)
 497		return err;
 498
 499	err = phy_write(phydev, 0x1e, 0x200c);
 500	if (err < 0)
 501		return err;
 502
 503	err = phy_write(phydev, 0x1d, 0x5);
 504	if (err < 0)
 505		return err;
 506
 507	err = phy_write(phydev, 0x1e, 0);
 508	if (err < 0)
 509		return err;
 510
 511	err = phy_write(phydev, 0x1e, 0x100);
 512	if (err < 0)
 513		return err;
 514
 515	return marvell_config_aneg(phydev);
 516}
 517
 518#if IS_ENABLED(CONFIG_OF_MDIO)
 519/* Set and/or override some configuration registers based on the
 520 * marvell,reg-init property stored in the of_node for the phydev.
 521 *
 522 * marvell,reg-init = <reg-page reg mask value>,...;
 523 *
 524 * There may be one or more sets of <reg-page reg mask value>:
 525 *
 526 * reg-page: which register bank to use.
 527 * reg: the register.
 528 * mask: if non-zero, ANDed with existing register value.
 529 * value: ORed with the masked value and written to the regiser.
 530 *
 531 */
 532static int marvell_of_reg_init(struct phy_device *phydev)
 533{
 534	const __be32 *paddr;
 535	int len, i, saved_page, current_page, ret = 0;
 536
 537	if (!phydev->mdio.dev.of_node)
 538		return 0;
 539
 540	paddr = of_get_property(phydev->mdio.dev.of_node,
 541				"marvell,reg-init", &len);
 542	if (!paddr || len < (4 * sizeof(*paddr)))
 543		return 0;
 544
 545	saved_page = phy_save_page(phydev);
 546	if (saved_page < 0)
 547		goto err;
 548	current_page = saved_page;
 549
 550	len /= sizeof(*paddr);
 551	for (i = 0; i < len - 3; i += 4) {
 552		u16 page = be32_to_cpup(paddr + i);
 553		u16 reg = be32_to_cpup(paddr + i + 1);
 554		u16 mask = be32_to_cpup(paddr + i + 2);
 555		u16 val_bits = be32_to_cpup(paddr + i + 3);
 556		int val;
 557
 558		if (page != current_page) {
 559			current_page = page;
 560			ret = marvell_write_page(phydev, page);
 561			if (ret < 0)
 562				goto err;
 563		}
 564
 565		val = 0;
 566		if (mask) {
 567			val = __phy_read(phydev, reg);
 568			if (val < 0) {
 569				ret = val;
 570				goto err;
 571			}
 572			val &= mask;
 573		}
 574		val |= val_bits;
 575
 576		ret = __phy_write(phydev, reg, val);
 577		if (ret < 0)
 578			goto err;
 579	}
 580err:
 581	return phy_restore_page(phydev, saved_page, ret);
 582}
 583#else
 584static int marvell_of_reg_init(struct phy_device *phydev)
 585{
 586	return 0;
 587}
 588#endif /* CONFIG_OF_MDIO */
 589
 590static int m88e1121_config_aneg_rgmii_delays(struct phy_device *phydev)
 591{
 592	int mscr;
 593
 594	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
 595		mscr = MII_88E1121_PHY_MSCR_RX_DELAY |
 596		       MII_88E1121_PHY_MSCR_TX_DELAY;
 597	else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
 598		mscr = MII_88E1121_PHY_MSCR_RX_DELAY;
 599	else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
 600		mscr = MII_88E1121_PHY_MSCR_TX_DELAY;
 601	else
 602		mscr = 0;
 603
 604	return phy_modify_paged_changed(phydev, MII_MARVELL_MSCR_PAGE,
 605					MII_88E1121_PHY_MSCR_REG,
 606					MII_88E1121_PHY_MSCR_DELAY_MASK, mscr);
 607}
 608
 609static int m88e1121_config_aneg(struct phy_device *phydev)
 610{
 611	int changed = 0;
 612	int err = 0;
 613
 614	if (phy_interface_is_rgmii(phydev)) {
 615		err = m88e1121_config_aneg_rgmii_delays(phydev);
 616		if (err < 0)
 617			return err;
 618	}
 619
 620	changed = err;
 621
 622	err = marvell_set_polarity(phydev, phydev->mdix_ctrl);
 623	if (err < 0)
 624		return err;
 625
 626	changed |= err;
 627
 628	err = genphy_config_aneg(phydev);
 629	if (err < 0)
 630		return err;
 631
 632	if (phydev->autoneg != AUTONEG_ENABLE || changed) {
 633		/* A software reset is used to ensure a "commit" of the
 634		 * changes is done.
 635		 */
 636		err = genphy_soft_reset(phydev);
 637		if (err < 0)
 638			return err;
 639	}
 640
 641	return 0;
 642}
 643
 644static int m88e1318_config_aneg(struct phy_device *phydev)
 645{
 646	int err;
 647
 648	err = phy_modify_paged(phydev, MII_MARVELL_MSCR_PAGE,
 649			       MII_88E1318S_PHY_MSCR1_REG,
 650			       0, MII_88E1318S_PHY_MSCR1_PAD_ODD);
 651	if (err < 0)
 652		return err;
 653
 654	return m88e1121_config_aneg(phydev);
 655}
 656
 657/**
 658 * linkmode_adv_to_fiber_adv_t
 659 * @advertise: the linkmode advertisement settings
 660 *
 661 * A small helper function that translates linkmode advertisement
 662 * settings to phy autonegotiation advertisements for the MII_ADV
 663 * register for fiber link.
 664 */
 665static inline u32 linkmode_adv_to_fiber_adv_t(unsigned long *advertise)
 666{
 667	u32 result = 0;
 668
 669	if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, advertise))
 670		result |= ADVERTISE_1000XHALF;
 671	if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, advertise))
 672		result |= ADVERTISE_1000XFULL;
 673
 674	if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, advertise) &&
 675	    linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, advertise))
 676		result |= ADVERTISE_1000XPSE_ASYM;
 677	else if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, advertise))
 678		result |= ADVERTISE_1000XPAUSE;
 679
 680	return result;
 681}
 682
 683/**
 684 * marvell_config_aneg_fiber - restart auto-negotiation or write BMCR
 685 * @phydev: target phy_device struct
 686 *
 687 * Description: If auto-negotiation is enabled, we configure the
 688 *   advertising, and then restart auto-negotiation.  If it is not
 689 *   enabled, then we write the BMCR. Adapted for fiber link in
 690 *   some Marvell's devices.
 691 */
 692static int marvell_config_aneg_fiber(struct phy_device *phydev)
 693{
 694	int changed = 0;
 695	int err;
 696	u16 adv;
 697
 698	if (phydev->autoneg != AUTONEG_ENABLE)
 699		return genphy_setup_forced(phydev);
 700
 701	/* Only allow advertising what this PHY supports */
 702	linkmode_and(phydev->advertising, phydev->advertising,
 703		     phydev->supported);
 704
 705	adv = linkmode_adv_to_fiber_adv_t(phydev->advertising);
 706
 707	/* Setup fiber advertisement */
 708	err = phy_modify_changed(phydev, MII_ADVERTISE,
 709				 ADVERTISE_1000XHALF | ADVERTISE_1000XFULL |
 710				 ADVERTISE_1000XPAUSE | ADVERTISE_1000XPSE_ASYM,
 711				 adv);
 712	if (err < 0)
 713		return err;
 714	if (err > 0)
 715		changed = 1;
 716
 717	return genphy_check_and_restart_aneg(phydev, changed);
 718}
 719
 720static unsigned int m88e1111_inband_caps(struct phy_device *phydev,
 721					 phy_interface_t interface)
 722{
 723	/* In 1000base-X and SGMII modes, the inband mode can be changed
 724	 * through the Fibre page BMCR ANENABLE bit.
 725	 */
 726	if (interface == PHY_INTERFACE_MODE_1000BASEX ||
 727	    interface == PHY_INTERFACE_MODE_SGMII)
 728		return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE |
 729		       LINK_INBAND_BYPASS;
 730
 731	return 0;
 732}
 733
 734static int m88e1111_config_inband(struct phy_device *phydev, unsigned int modes)
 735{
 736	u16 extsr, bmcr;
 737	int err;
 738
 739	if (phydev->interface != PHY_INTERFACE_MODE_1000BASEX &&
 740	    phydev->interface != PHY_INTERFACE_MODE_SGMII)
 741		return -EINVAL;
 742
 743	if (modes == LINK_INBAND_BYPASS)
 744		extsr = MII_M1111_HWCFG_SERIAL_AN_BYPASS;
 745	else
 746		extsr = 0;
 747
 748	if (modes == LINK_INBAND_DISABLE)
 749		bmcr = 0;
 750	else
 751		bmcr = BMCR_ANENABLE;
 752
 753	err = phy_modify(phydev, MII_M1111_PHY_EXT_SR,
 754			 MII_M1111_HWCFG_SERIAL_AN_BYPASS, extsr);
 755	if (err < 0)
 756		return extsr;
 757
 758	return phy_modify_paged(phydev, MII_MARVELL_FIBER_PAGE, MII_BMCR,
 759				BMCR_ANENABLE, bmcr);
 760}
 761
 762static int m88e1111_config_aneg(struct phy_device *phydev)
 763{
 764	int extsr = phy_read(phydev, MII_M1111_PHY_EXT_SR);
 765	int err;
 766
 767	if (extsr < 0)
 768		return extsr;
 769
 770	/* If not using SGMII or copper 1000BaseX modes, use normal process.
 771	 * Steps below are only required for these modes.
 772	 */
 773	if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&
 774	    (extsr & MII_M1111_HWCFG_MODE_MASK) !=
 775	    MII_M1111_HWCFG_MODE_COPPER_1000X_AN)
 776		return marvell_config_aneg(phydev);
 777
 778	err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
 779	if (err < 0)
 780		goto error;
 781
 782	/* Configure the copper link first */
 783	err = marvell_config_aneg(phydev);
 784	if (err < 0)
 785		goto error;
 786
 787	/* Then the fiber link */
 788	err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE);
 789	if (err < 0)
 790		goto error;
 791
 792	if (phydev->interface == PHY_INTERFACE_MODE_SGMII)
 793		/* Do not touch the fiber advertisement if we're in copper->sgmii mode.
 794		 * Just ensure that SGMII-side autonegotiation is enabled.
 795		 * If we switched from some other mode to SGMII it may not be.
 796		 */
 797		err = genphy_check_and_restart_aneg(phydev, false);
 798	else
 799		err = marvell_config_aneg_fiber(phydev);
 800	if (err < 0)
 801		goto error;
 802
 803	return marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
 804
 805error:
 806	marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
 807	return err;
 808}
 809
 810static int m88e1510_config_aneg(struct phy_device *phydev)
 811{
 812	int err;
 813
 814	err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
 815	if (err < 0)
 816		goto error;
 817
 818	/* Configure the copper link first */
 819	err = m88e1318_config_aneg(phydev);
 820	if (err < 0)
 821		goto error;
 822
 823	/* Do not touch the fiber page if we're in copper->sgmii mode */
 824	if (phydev->interface == PHY_INTERFACE_MODE_SGMII)
 825		return 0;
 826
 827	/* Then the fiber link */
 828	err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE);
 829	if (err < 0)
 830		goto error;
 831
 832	err = marvell_config_aneg_fiber(phydev);
 833	if (err < 0)
 834		goto error;
 835
 836	return marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
 837
 838error:
 839	marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
 840	return err;
 841}
 842
 843static void marvell_config_led(struct phy_device *phydev)
 844{
 845	u16 def_config;
 846	int err;
 847
 848	switch (MARVELL_PHY_FAMILY_ID(phydev->phy_id)) {
 849	/* Default PHY LED config: LED[0] .. Link, LED[1] .. Activity */
 850	case MARVELL_PHY_FAMILY_ID(MARVELL_PHY_ID_88E1121R):
 851	case MARVELL_PHY_FAMILY_ID(MARVELL_PHY_ID_88E1318S):
 852		def_config = MII_88E1121_PHY_LED_DEF;
 853		break;
 854	/* Default PHY LED config:
 855	 * LED[0] .. 1000Mbps Link
 856	 * LED[1] .. 100Mbps Link
 857	 * LED[2] .. Blink, Activity
 858	 */
 859	case MARVELL_PHY_FAMILY_ID(MARVELL_PHY_ID_88E1510):
 860		if (phydev->dev_flags & MARVELL_PHY_LED0_LINK_LED1_ACTIVE)
 861			def_config = MII_88E1510_PHY_LED0_LINK_LED1_ACTIVE;
 862		else
 863			def_config = MII_88E1510_PHY_LED_DEF;
 864		break;
 865	default:
 866		return;
 867	}
 868
 869	err = phy_write_paged(phydev, MII_MARVELL_LED_PAGE, MII_PHY_LED_CTRL,
 870			      def_config);
 871	if (err < 0)
 872		phydev_warn(phydev, "Fail to config marvell phy LED.\n");
 873}
 874
 875static int marvell_config_init(struct phy_device *phydev)
 876{
 877	/* Set default LED */
 878	marvell_config_led(phydev);
 879
 880	/* Set registers from marvell,reg-init DT property */
 881	return marvell_of_reg_init(phydev);
 882}
 883
 884static int m88e3016_config_init(struct phy_device *phydev)
 885{
 886	int ret;
 887
 888	/* Enable Scrambler and Auto-Crossover */
 889	ret = phy_modify(phydev, MII_88E3016_PHY_SPEC_CTRL,
 890			 MII_88E3016_DISABLE_SCRAMBLER,
 891			 MII_88E3016_AUTO_MDIX_CROSSOVER);
 892	if (ret < 0)
 893		return ret;
 894
 895	return marvell_config_init(phydev);
 896}
 897
 898static int m88e1111_config_init_hwcfg_mode(struct phy_device *phydev,
 899					   u16 mode,
 900					   int fibre_copper_auto)
 901{
 902	if (fibre_copper_auto)
 903		mode |= MII_M1111_HWCFG_FIBER_COPPER_AUTO;
 904
 905	return phy_modify(phydev, MII_M1111_PHY_EXT_SR,
 906			  MII_M1111_HWCFG_MODE_MASK |
 907			  MII_M1111_HWCFG_FIBER_COPPER_AUTO |
 908			  MII_M1111_HWCFG_FIBER_COPPER_RES,
 909			  mode);
 910}
 911
 912static int m88e1111_config_init_rgmii_delays(struct phy_device *phydev)
 913{
 914	int delay;
 915
 916	switch (phydev->interface) {
 917	case PHY_INTERFACE_MODE_RGMII_ID:
 918		delay = MII_M1111_RGMII_RX_DELAY | MII_M1111_RGMII_TX_DELAY;
 919		break;
 920	case PHY_INTERFACE_MODE_RGMII_RXID:
 921		delay = MII_M1111_RGMII_RX_DELAY;
 922		break;
 923	case PHY_INTERFACE_MODE_RGMII_TXID:
 924		delay = MII_M1111_RGMII_TX_DELAY;
 925		break;
 926	default:
 927		delay = 0;
 928		break;
 929	}
 930
 931	return phy_modify(phydev, MII_M1111_PHY_EXT_CR,
 932			  MII_M1111_RGMII_RX_DELAY | MII_M1111_RGMII_TX_DELAY,
 933			  delay);
 934}
 935
 936static int m88e1111_config_init_rgmii(struct phy_device *phydev)
 937{
 938	int temp;
 939	int err;
 940
 941	err = m88e1111_config_init_rgmii_delays(phydev);
 942	if (err < 0)
 943		return err;
 944
 945	temp = phy_read(phydev, MII_M1111_PHY_EXT_SR);
 946	if (temp < 0)
 947		return temp;
 948
 949	temp &= ~(MII_M1111_HWCFG_MODE_MASK);
 950
 951	if (temp & MII_M1111_HWCFG_FIBER_COPPER_RES)
 952		temp |= MII_M1111_HWCFG_MODE_FIBER_RGMII;
 953	else
 954		temp |= MII_M1111_HWCFG_MODE_COPPER_RGMII;
 955
 956	return phy_write(phydev, MII_M1111_PHY_EXT_SR, temp);
 957}
 958
 959static int m88e1111_config_init_sgmii(struct phy_device *phydev)
 960{
 961	int err;
 962
 963	err = m88e1111_config_init_hwcfg_mode(
 964		phydev,
 965		MII_M1111_HWCFG_MODE_SGMII_NO_CLK,
 966		MII_M1111_HWCFG_FIBER_COPPER_AUTO);
 967	if (err < 0)
 968		return err;
 969
 970	/* make sure copper is selected */
 971	return marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
 972}
 973
 974static int m88e1111_config_init_rtbi(struct phy_device *phydev)
 975{
 976	int err;
 977
 978	err = m88e1111_config_init_rgmii_delays(phydev);
 979	if (err < 0)
 980		return err;
 981
 982	err = m88e1111_config_init_hwcfg_mode(
 983		phydev,
 984		MII_M1111_HWCFG_MODE_RTBI,
 985		MII_M1111_HWCFG_FIBER_COPPER_AUTO);
 986	if (err < 0)
 987		return err;
 988
 989	/* soft reset */
 990	err = genphy_soft_reset(phydev);
 991	if (err < 0)
 992		return err;
 993
 994	return m88e1111_config_init_hwcfg_mode(
 995		phydev,
 996		MII_M1111_HWCFG_MODE_RTBI,
 997		MII_M1111_HWCFG_FIBER_COPPER_AUTO);
 998}
 999
1000static int m88e1111_config_init_1000basex(struct phy_device *phydev)
1001{
1002	int extsr = phy_read(phydev, MII_M1111_PHY_EXT_SR);
1003	int err, mode;
1004
1005	if (extsr < 0)
1006		return extsr;
1007
1008	/* If using copper mode, ensure 1000BaseX auto-negotiation is enabled.
1009	 * FIXME: this does not actually enable 1000BaseX auto-negotiation if
1010	 * it was previously disabled in the Fiber BMCR!
1011	 */
1012	mode = extsr & MII_M1111_HWCFG_MODE_MASK;
1013	if (mode == MII_M1111_HWCFG_MODE_COPPER_1000X_NOAN) {
1014		err = phy_modify(phydev, MII_M1111_PHY_EXT_SR,
1015				 MII_M1111_HWCFG_MODE_MASK |
1016				 MII_M1111_HWCFG_SERIAL_AN_BYPASS,
1017				 MII_M1111_HWCFG_MODE_COPPER_1000X_AN |
1018				 MII_M1111_HWCFG_SERIAL_AN_BYPASS);
1019		if (err < 0)
1020			return err;
1021	}
1022	return 0;
1023}
1024
1025static int m88e1111_config_init(struct phy_device *phydev)
1026{
1027	int err;
1028
1029	if (phy_interface_is_rgmii(phydev)) {
1030		err = m88e1111_config_init_rgmii(phydev);
1031		if (err < 0)
1032			return err;
1033	}
1034
1035	if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
1036		err = m88e1111_config_init_sgmii(phydev);
1037		if (err < 0)
1038			return err;
1039	}
1040
1041	if (phydev->interface == PHY_INTERFACE_MODE_RTBI) {
1042		err = m88e1111_config_init_rtbi(phydev);
1043		if (err < 0)
1044			return err;
1045	}
1046
1047	if (phydev->interface == PHY_INTERFACE_MODE_1000BASEX) {
1048		err = m88e1111_config_init_1000basex(phydev);
1049		if (err < 0)
1050			return err;
1051	}
1052
1053	err = marvell_of_reg_init(phydev);
1054	if (err < 0)
1055		return err;
1056
1057	err = genphy_soft_reset(phydev);
1058	if (err < 0)
1059		return err;
1060
1061	if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
1062		/* If the HWCFG_MODE was changed from another mode (such as
1063		 * 1000BaseX) to SGMII, the state of the support bits may have
1064		 * also changed now that the PHY has been reset.
1065		 * Update the PHY abilities accordingly.
1066		 */
1067		err = genphy_read_abilities(phydev);
1068		linkmode_or(phydev->advertising, phydev->advertising,
1069			    phydev->supported);
1070	}
1071	return err;
1072}
1073
1074static int m88e1111_get_downshift(struct phy_device *phydev, u8 *data)
1075{
1076	int val, cnt, enable;
1077
1078	val = phy_read(phydev, MII_M1111_PHY_EXT_CR);
1079	if (val < 0)
1080		return val;
1081
1082	enable = FIELD_GET(MII_M1111_PHY_EXT_CR_DOWNSHIFT_EN, val);
1083	cnt = FIELD_GET(MII_M1111_PHY_EXT_CR_DOWNSHIFT_MASK, val) + 1;
1084
1085	*data = enable ? cnt : DOWNSHIFT_DEV_DISABLE;
1086
1087	return 0;
1088}
1089
1090static int m88e1111_set_downshift(struct phy_device *phydev, u8 cnt)
1091{
1092	int val, err;
1093
1094	if (cnt > MII_M1111_PHY_EXT_CR_DOWNSHIFT_MAX)
1095		return -E2BIG;
1096
1097	if (!cnt) {
1098		err = phy_clear_bits(phydev, MII_M1111_PHY_EXT_CR,
1099				     MII_M1111_PHY_EXT_CR_DOWNSHIFT_EN);
1100	} else {
1101		val = MII_M1111_PHY_EXT_CR_DOWNSHIFT_EN;
1102		val |= FIELD_PREP(MII_M1111_PHY_EXT_CR_DOWNSHIFT_MASK, cnt - 1);
1103
1104		err = phy_modify(phydev, MII_M1111_PHY_EXT_CR,
1105				 MII_M1111_PHY_EXT_CR_DOWNSHIFT_EN |
1106				 MII_M1111_PHY_EXT_CR_DOWNSHIFT_MASK,
1107				 val);
1108	}
1109
1110	if (err < 0)
1111		return err;
1112
1113	return genphy_soft_reset(phydev);
1114}
1115
1116static int m88e1111_get_tunable(struct phy_device *phydev,
1117				struct ethtool_tunable *tuna, void *data)
1118{
1119	switch (tuna->id) {
1120	case ETHTOOL_PHY_DOWNSHIFT:
1121		return m88e1111_get_downshift(phydev, data);
1122	default:
1123		return -EOPNOTSUPP;
1124	}
1125}
1126
1127static int m88e1111_set_tunable(struct phy_device *phydev,
1128				struct ethtool_tunable *tuna, const void *data)
1129{
1130	switch (tuna->id) {
1131	case ETHTOOL_PHY_DOWNSHIFT:
1132		return m88e1111_set_downshift(phydev, *(const u8 *)data);
1133	default:
1134		return -EOPNOTSUPP;
1135	}
1136}
1137
1138static int m88e1011_get_downshift(struct phy_device *phydev, u8 *data)
1139{
1140	int val, cnt, enable;
1141
1142	val = phy_read(phydev, MII_M1011_PHY_SCR);
1143	if (val < 0)
1144		return val;
1145
1146	enable = FIELD_GET(MII_M1011_PHY_SCR_DOWNSHIFT_EN, val);
1147	cnt = FIELD_GET(MII_M1011_PHY_SCR_DOWNSHIFT_MASK, val) + 1;
1148
1149	*data = enable ? cnt : DOWNSHIFT_DEV_DISABLE;
1150
1151	return 0;
1152}
1153
1154static int m88e1011_set_downshift(struct phy_device *phydev, u8 cnt)
1155{
1156	int val, err;
1157
1158	if (cnt > MII_M1011_PHY_SCR_DOWNSHIFT_MAX)
1159		return -E2BIG;
1160
1161	if (!cnt) {
1162		err = phy_clear_bits(phydev, MII_M1011_PHY_SCR,
1163				     MII_M1011_PHY_SCR_DOWNSHIFT_EN);
1164	} else {
1165		val = MII_M1011_PHY_SCR_DOWNSHIFT_EN;
1166		val |= FIELD_PREP(MII_M1011_PHY_SCR_DOWNSHIFT_MASK, cnt - 1);
1167
1168		err = phy_modify(phydev, MII_M1011_PHY_SCR,
1169				 MII_M1011_PHY_SCR_DOWNSHIFT_EN |
1170				 MII_M1011_PHY_SCR_DOWNSHIFT_MASK,
1171				 val);
1172	}
1173
1174	if (err < 0)
1175		return err;
1176
1177	return genphy_soft_reset(phydev);
1178}
1179
1180static int m88e1011_get_tunable(struct phy_device *phydev,
1181				struct ethtool_tunable *tuna, void *data)
1182{
1183	switch (tuna->id) {
1184	case ETHTOOL_PHY_DOWNSHIFT:
1185		return m88e1011_get_downshift(phydev, data);
1186	default:
1187		return -EOPNOTSUPP;
1188	}
1189}
1190
1191static int m88e1011_set_tunable(struct phy_device *phydev,
1192				struct ethtool_tunable *tuna, const void *data)
1193{
1194	switch (tuna->id) {
1195	case ETHTOOL_PHY_DOWNSHIFT:
1196		return m88e1011_set_downshift(phydev, *(const u8 *)data);
1197	default:
1198		return -EOPNOTSUPP;
1199	}
1200}
1201
1202static int m88e1112_config_init(struct phy_device *phydev)
1203{
1204	int err;
1205
1206	err = m88e1011_set_downshift(phydev, 3);
1207	if (err < 0)
1208		return err;
1209
1210	return m88e1111_config_init(phydev);
1211}
1212
1213static int m88e1111gbe_config_init(struct phy_device *phydev)
1214{
1215	int err;
1216
1217	err = m88e1111_set_downshift(phydev, 3);
1218	if (err < 0)
1219		return err;
1220
1221	return m88e1111_config_init(phydev);
1222}
1223
1224static int marvell_1011gbe_config_init(struct phy_device *phydev)
1225{
1226	int err;
1227
1228	err = m88e1011_set_downshift(phydev, 3);
1229	if (err < 0)
1230		return err;
1231
1232	return marvell_config_init(phydev);
1233}
1234static int m88e1116r_config_init(struct phy_device *phydev)
1235{
1236	int err;
1237
1238	err = genphy_soft_reset(phydev);
1239	if (err < 0)
1240		return err;
1241
1242	msleep(500);
1243
1244	err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
1245	if (err < 0)
1246		return err;
1247
1248	err = marvell_set_polarity(phydev, phydev->mdix_ctrl);
1249	if (err < 0)
1250		return err;
1251
1252	err = m88e1011_set_downshift(phydev, 8);
1253	if (err < 0)
1254		return err;
1255
1256	if (phy_interface_is_rgmii(phydev)) {
1257		err = m88e1121_config_aneg_rgmii_delays(phydev);
1258		if (err < 0)
1259			return err;
1260	}
1261
1262	err = genphy_soft_reset(phydev);
1263	if (err < 0)
1264		return err;
1265
1266	return marvell_config_init(phydev);
1267}
1268
1269static int m88e1318_config_init(struct phy_device *phydev)
1270{
1271	if (phy_interrupt_is_valid(phydev)) {
1272		int err = phy_modify_paged(
1273			phydev, MII_MARVELL_LED_PAGE,
1274			MII_88E1318S_PHY_LED_TCR,
1275			MII_88E1318S_PHY_LED_TCR_FORCE_INT,
1276			MII_88E1318S_PHY_LED_TCR_INTn_ENABLE |
1277			MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW);
1278		if (err < 0)
1279			return err;
1280	}
1281
1282	return marvell_config_init(phydev);
1283}
1284
1285static int m88e1510_config_init(struct phy_device *phydev)
1286{
1287	static const struct {
1288		u16 reg17, reg16;
1289	} errata_vals[] = {
1290		{ 0x214b, 0x2144 },
1291		{ 0x0c28, 0x2146 },
1292		{ 0xb233, 0x214d },
1293		{ 0xcc0c, 0x2159 },
1294	};
1295	int err;
1296	int i;
1297
1298	/* As per Marvell Release Notes - Alaska 88E1510/88E1518/88E1512/
1299	 * 88E1514 Rev A0, Errata Section 5.1:
1300	 * If EEE is intended to be used, the following register writes
1301	 * must be done once after every hardware reset.
1302	 */
1303	err = marvell_set_page(phydev, 0x00FF);
1304	if (err < 0)
1305		return err;
1306
1307	for (i = 0; i < ARRAY_SIZE(errata_vals); ++i) {
1308		err = phy_write(phydev, 17, errata_vals[i].reg17);
1309		if (err)
1310			return err;
1311		err = phy_write(phydev, 16, errata_vals[i].reg16);
1312		if (err)
1313			return err;
1314	}
1315
1316	err = marvell_set_page(phydev, 0x00FB);
1317	if (err < 0)
1318		return err;
1319	err = phy_write(phydev, 07, 0xC00D);
1320	if (err < 0)
1321		return err;
1322	err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
1323	if (err < 0)
1324		return err;
1325
1326	/* SGMII-to-Copper mode initialization */
1327	if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
1328		/* Select page 18 */
1329		err = marvell_set_page(phydev, 18);
1330		if (err < 0)
1331			return err;
1332
1333		/* In reg 20, write MODE[2:0] = 0x1 (SGMII to Copper) */
1334		err = phy_modify(phydev, MII_88E1510_GEN_CTRL_REG_1,
1335				 MII_88E1510_GEN_CTRL_REG_1_MODE_MASK,
1336				 MII_88E1510_GEN_CTRL_REG_1_MODE_SGMII);
1337		if (err < 0)
1338			return err;
1339
1340		/* PHY reset is necessary after changing MODE[2:0] */
1341		err = phy_set_bits(phydev, MII_88E1510_GEN_CTRL_REG_1,
1342				   MII_88E1510_GEN_CTRL_REG_1_RESET);
1343		if (err < 0)
1344			return err;
1345
1346		/* Reset page selection */
1347		err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
1348		if (err < 0)
1349			return err;
1350	}
1351	err = m88e1011_set_downshift(phydev, 3);
1352	if (err < 0)
1353		return err;
1354
1355	return m88e1318_config_init(phydev);
1356}
1357
1358static int m88e1118_config_aneg(struct phy_device *phydev)
1359{
1360	int err;
1361
1362	err = marvell_set_polarity(phydev, phydev->mdix_ctrl);
1363	if (err < 0)
1364		return err;
1365
1366	err = genphy_config_aneg(phydev);
1367	if (err < 0)
1368		return err;
1369
1370	return genphy_soft_reset(phydev);
1371}
1372
1373static int m88e1118_config_init(struct phy_device *phydev)
1374{
1375	u16 leds;
1376	int err;
1377
1378	/* Enable 1000 Mbit */
1379	err = phy_write_paged(phydev, MII_MARVELL_MSCR_PAGE,
1380			      MII_88E1121_PHY_MSCR_REG, 0x1070);
1381	if (err < 0)
1382		return err;
1383
1384	if (phy_interface_is_rgmii(phydev)) {
1385		err = m88e1121_config_aneg_rgmii_delays(phydev);
1386		if (err < 0)
1387			return err;
1388	}
1389
1390	/* Adjust LED Control */
1391	if (phydev->dev_flags & MARVELL_PHY_M1118_DNS323_LEDS)
1392		leds = 0x1100;
1393	else
1394		leds = 0x021e;
1395
1396	err = phy_write_paged(phydev, MII_MARVELL_LED_PAGE, 0x10, leds);
1397	if (err < 0)
1398		return err;
1399
1400	err = marvell_of_reg_init(phydev);
1401	if (err < 0)
1402		return err;
1403
1404	/* Reset page register */
1405	err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
1406	if (err < 0)
1407		return err;
1408
1409	return genphy_soft_reset(phydev);
1410}
1411
1412static int m88e1149_config_init(struct phy_device *phydev)
1413{
1414	int err;
1415
1416	/* Change address */
1417	err = marvell_set_page(phydev, MII_MARVELL_MSCR_PAGE);
1418	if (err < 0)
1419		return err;
1420
1421	/* Enable 1000 Mbit */
1422	err = phy_write(phydev, 0x15, 0x1048);
1423	if (err < 0)
1424		return err;
1425
1426	err = marvell_of_reg_init(phydev);
1427	if (err < 0)
1428		return err;
1429
1430	/* Reset address */
1431	err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
1432	if (err < 0)
1433		return err;
1434
1435	return genphy_soft_reset(phydev);
1436}
1437
1438static int m88e1145_config_init_rgmii(struct phy_device *phydev)
1439{
1440	int err;
1441
1442	err = m88e1111_config_init_rgmii_delays(phydev);
1443	if (err < 0)
1444		return err;
1445
1446	if (phydev->dev_flags & MARVELL_PHY_M1145_FLAGS_RESISTANCE) {
1447		err = phy_write(phydev, 0x1d, 0x0012);
1448		if (err < 0)
1449			return err;
1450
1451		err = phy_modify(phydev, 0x1e, 0x0fc0,
1452				 2 << 9 | /* 36 ohm */
1453				 2 << 6); /* 39 ohm */
1454		if (err < 0)
1455			return err;
1456
1457		err = phy_write(phydev, 0x1d, 0x3);
1458		if (err < 0)
1459			return err;
1460
1461		err = phy_write(phydev, 0x1e, 0x8000);
1462	}
1463	return err;
1464}
1465
1466static int m88e1145_config_init_sgmii(struct phy_device *phydev)
1467{
1468	return m88e1111_config_init_hwcfg_mode(
1469		phydev, MII_M1111_HWCFG_MODE_SGMII_NO_CLK,
1470		MII_M1111_HWCFG_FIBER_COPPER_AUTO);
1471}
1472
1473static int m88e1145_config_init(struct phy_device *phydev)
1474{
1475	int err;
1476
1477	/* Take care of errata E0 & E1 */
1478	err = phy_write(phydev, 0x1d, 0x001b);
1479	if (err < 0)
1480		return err;
1481
1482	err = phy_write(phydev, 0x1e, 0x418f);
1483	if (err < 0)
1484		return err;
1485
1486	err = phy_write(phydev, 0x1d, 0x0016);
1487	if (err < 0)
1488		return err;
1489
1490	err = phy_write(phydev, 0x1e, 0xa2da);
1491	if (err < 0)
1492		return err;
1493
1494	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) {
1495		err = m88e1145_config_init_rgmii(phydev);
1496		if (err < 0)
1497			return err;
1498	}
1499
1500	if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
1501		err = m88e1145_config_init_sgmii(phydev);
1502		if (err < 0)
1503			return err;
1504	}
1505	err = m88e1111_set_downshift(phydev, 3);
1506	if (err < 0)
1507		return err;
1508
1509	err = marvell_of_reg_init(phydev);
1510	if (err < 0)
1511		return err;
1512
1513	return 0;
1514}
1515
1516static int m88e1540_get_fld(struct phy_device *phydev, u8 *msecs)
1517{
1518	int val;
1519
1520	val = phy_read(phydev, MII_88E1540_COPPER_CTRL3);
1521	if (val < 0)
1522		return val;
1523
1524	if (!(val & MII_88E1540_COPPER_CTRL3_FAST_LINK_DOWN)) {
1525		*msecs = ETHTOOL_PHY_FAST_LINK_DOWN_OFF;
1526		return 0;
1527	}
1528
1529	val = FIELD_GET(MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_MASK, val);
1530
1531	switch (val) {
1532	case MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_00MS:
1533		*msecs = 0;
1534		break;
1535	case MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_10MS:
1536		*msecs = 10;
1537		break;
1538	case MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_20MS:
1539		*msecs = 20;
1540		break;
1541	case MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_40MS:
1542		*msecs = 40;
1543		break;
1544	default:
1545		return -EINVAL;
1546	}
1547
1548	return 0;
1549}
1550
1551static int m88e1540_set_fld(struct phy_device *phydev, const u8 *msecs)
1552{
1553	int val, ret;
1554
1555	if (*msecs == ETHTOOL_PHY_FAST_LINK_DOWN_OFF)
1556		return phy_clear_bits(phydev, MII_88E1540_COPPER_CTRL3,
1557				      MII_88E1540_COPPER_CTRL3_FAST_LINK_DOWN);
1558
1559	/* According to the Marvell data sheet EEE must be disabled for
1560	 * Fast Link Down detection to work properly
1561	 */
1562	if (phydev->eee_cfg.eee_enabled) {
1563		phydev_warn(phydev, "Fast Link Down detection requires EEE to be disabled!\n");
1564		return -EBUSY;
1565	}
1566
1567	if (*msecs <= 5)
1568		val = MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_00MS;
1569	else if (*msecs <= 15)
1570		val = MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_10MS;
1571	else if (*msecs <= 30)
1572		val = MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_20MS;
1573	else
1574		val = MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_40MS;
1575
1576	val = FIELD_PREP(MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_MASK, val);
1577
1578	ret = phy_modify(phydev, MII_88E1540_COPPER_CTRL3,
1579			 MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_MASK, val);
1580	if (ret)
1581		return ret;
1582
1583	return phy_set_bits(phydev, MII_88E1540_COPPER_CTRL3,
1584			    MII_88E1540_COPPER_CTRL3_FAST_LINK_DOWN);
1585}
1586
1587static int m88e1540_get_tunable(struct phy_device *phydev,
1588				struct ethtool_tunable *tuna, void *data)
1589{
1590	switch (tuna->id) {
1591	case ETHTOOL_PHY_FAST_LINK_DOWN:
1592		return m88e1540_get_fld(phydev, data);
1593	case ETHTOOL_PHY_DOWNSHIFT:
1594		return m88e1011_get_downshift(phydev, data);
1595	default:
1596		return -EOPNOTSUPP;
1597	}
1598}
1599
1600static int m88e1540_set_tunable(struct phy_device *phydev,
1601				struct ethtool_tunable *tuna, const void *data)
1602{
1603	switch (tuna->id) {
1604	case ETHTOOL_PHY_FAST_LINK_DOWN:
1605		return m88e1540_set_fld(phydev, data);
1606	case ETHTOOL_PHY_DOWNSHIFT:
1607		return m88e1011_set_downshift(phydev, *(const u8 *)data);
1608	default:
1609		return -EOPNOTSUPP;
1610	}
1611}
1612
1613/* The VOD can be out of specification on link up. Poke an
1614 * undocumented register, in an undocumented page, with a magic value
1615 * to fix this.
1616 */
1617static int m88e6390_errata(struct phy_device *phydev)
1618{
1619	int err;
1620
1621	err = phy_write(phydev, MII_BMCR,
1622			BMCR_ANENABLE | BMCR_SPEED1000 | BMCR_FULLDPLX);
1623	if (err)
1624		return err;
1625
1626	usleep_range(300, 400);
1627
1628	err = phy_write_paged(phydev, 0xf8, 0x08, 0x36);
1629	if (err)
1630		return err;
1631
1632	return genphy_soft_reset(phydev);
1633}
1634
1635static int m88e6390_config_aneg(struct phy_device *phydev)
1636{
1637	int err;
1638
1639	err = m88e6390_errata(phydev);
1640	if (err)
1641		return err;
1642
1643	return m88e1510_config_aneg(phydev);
1644}
1645
1646/**
1647 * fiber_lpa_mod_linkmode_lpa_t
1648 * @advertising: the linkmode advertisement settings
1649 * @lpa: value of the MII_LPA register for fiber link
1650 *
1651 * A small helper function that translates MII_LPA bits to linkmode LP
1652 * advertisement settings. Other bits in advertising are left
1653 * unchanged.
1654 */
1655static void fiber_lpa_mod_linkmode_lpa_t(unsigned long *advertising, u32 lpa)
1656{
1657	linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
1658			 advertising, lpa & LPA_1000XHALF);
1659
1660	linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
1661			 advertising, lpa & LPA_1000XFULL);
1662}
1663
1664static int marvell_read_status_page_an(struct phy_device *phydev,
1665				       int fiber, int status)
1666{
1667	int lpa;
1668	int err;
1669
1670	if (!(status & MII_M1011_PHY_STATUS_RESOLVED)) {
1671		phydev->link = 0;
1672		return 0;
1673	}
1674
1675	if (status & MII_M1011_PHY_STATUS_FULLDUPLEX)
1676		phydev->duplex = DUPLEX_FULL;
1677	else
1678		phydev->duplex = DUPLEX_HALF;
1679
1680	switch (status & MII_M1011_PHY_STATUS_SPD_MASK) {
1681	case MII_M1011_PHY_STATUS_1000:
1682		phydev->speed = SPEED_1000;
1683		break;
1684
1685	case MII_M1011_PHY_STATUS_100:
1686		phydev->speed = SPEED_100;
1687		break;
1688
1689	default:
1690		phydev->speed = SPEED_10;
1691		break;
1692	}
1693
1694	if (!fiber) {
1695		err = genphy_read_lpa(phydev);
1696		if (err < 0)
1697			return err;
1698
1699		phy_resolve_aneg_pause(phydev);
1700	} else {
1701		lpa = phy_read(phydev, MII_LPA);
1702		if (lpa < 0)
1703			return lpa;
1704
1705		/* The fiber link is only 1000M capable */
1706		fiber_lpa_mod_linkmode_lpa_t(phydev->lp_advertising, lpa);
1707
1708		if (phydev->duplex == DUPLEX_FULL) {
1709			if (!(lpa & LPA_PAUSE_FIBER)) {
1710				phydev->pause = 0;
1711				phydev->asym_pause = 0;
1712			} else if ((lpa & LPA_PAUSE_ASYM_FIBER)) {
1713				phydev->pause = 1;
1714				phydev->asym_pause = 1;
1715			} else {
1716				phydev->pause = 1;
1717				phydev->asym_pause = 0;
1718			}
1719		}
1720	}
1721
1722	return 0;
1723}
1724
1725/* marvell_read_status_page
1726 *
1727 * Description:
1728 *   Check the link, then figure out the current state
1729 *   by comparing what we advertise with what the link partner
1730 *   advertises.  Start by checking the gigabit possibilities,
1731 *   then move on to 10/100.
1732 */
1733static int marvell_read_status_page(struct phy_device *phydev, int page)
1734{
1735	int status;
1736	int fiber;
1737	int err;
1738
1739	status = phy_read(phydev, MII_M1011_PHY_STATUS);
1740	if (status < 0)
1741		return status;
1742
1743	/* Use the generic register for copper link status,
1744	 * and the PHY status register for fiber link status.
1745	 */
1746	if (page == MII_MARVELL_FIBER_PAGE) {
1747		phydev->link = !!(status & MII_M1011_PHY_STATUS_LINK);
1748	} else {
1749		err = genphy_update_link(phydev);
1750		if (err)
1751			return err;
1752	}
1753
1754	if (page == MII_MARVELL_FIBER_PAGE)
1755		fiber = 1;
1756	else
1757		fiber = 0;
1758
1759	linkmode_zero(phydev->lp_advertising);
1760	phydev->pause = 0;
1761	phydev->asym_pause = 0;
1762	phydev->speed = SPEED_UNKNOWN;
1763	phydev->duplex = DUPLEX_UNKNOWN;
1764	phydev->port = fiber ? PORT_FIBRE : PORT_TP;
1765
1766	if (fiber) {
1767		phydev->mdix = ETH_TP_MDI_INVALID;
1768	} else {
1769		/* The MDI-X state is set regardless of Autoneg being enabled
1770		 * and reflects forced MDI-X state as well as auto resolution
1771		 */
1772		if (status & MII_M1011_PHY_STATUS_RESOLVED)
1773			phydev->mdix = status & MII_M1011_PHY_STATUS_MDIX ?
1774				ETH_TP_MDI_X : ETH_TP_MDI;
1775		else
1776			phydev->mdix = ETH_TP_MDI_INVALID;
1777	}
1778
1779	if (phydev->autoneg == AUTONEG_ENABLE)
1780		err = marvell_read_status_page_an(phydev, fiber, status);
1781	else
1782		err = genphy_read_status_fixed(phydev);
1783
1784	return err;
1785}
1786
1787/* marvell_read_status
1788 *
1789 * Some Marvell's phys have two modes: fiber and copper.
1790 * Both need status checked.
1791 * Description:
1792 *   First, check the fiber link and status.
1793 *   If the fiber link is down, check the copper link and status which
1794 *   will be the default value if both link are down.
1795 */
1796static int marvell_read_status(struct phy_device *phydev)
1797{
1798	int err;
1799
1800	/* Check the fiber mode first */
1801	if (linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
1802			      phydev->supported) &&
1803	    phydev->interface != PHY_INTERFACE_MODE_SGMII) {
1804		err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE);
1805		if (err < 0)
1806			goto error;
1807
1808		err = marvell_read_status_page(phydev, MII_MARVELL_FIBER_PAGE);
1809		if (err < 0)
1810			goto error;
1811
1812		/* If the fiber link is up, it is the selected and
1813		 * used link. In this case, we need to stay in the
1814		 * fiber page. Please to be careful about that, avoid
1815		 * to restore Copper page in other functions which
1816		 * could break the behaviour for some fiber phy like
1817		 * 88E1512.
1818		 */
1819		if (phydev->link)
1820			return 0;
1821
1822		/* If fiber link is down, check and save copper mode state */
1823		err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
1824		if (err < 0)
1825			goto error;
1826	}
1827
1828	return marvell_read_status_page(phydev, MII_MARVELL_COPPER_PAGE);
1829
1830error:
1831	marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
1832	return err;
1833}
1834
1835/* marvell_suspend
1836 *
1837 * Some Marvell's phys have two modes: fiber and copper.
1838 * Both need to be suspended
1839 */
1840static int marvell_suspend(struct phy_device *phydev)
1841{
1842	int err;
1843
1844	/* Suspend the fiber mode first */
1845	if (linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
1846			      phydev->supported)) {
1847		err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE);
1848		if (err < 0)
1849			goto error;
1850
1851		/* With the page set, use the generic suspend */
1852		err = genphy_suspend(phydev);
1853		if (err < 0)
1854			goto error;
1855
1856		/* Then, the copper link */
1857		err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
1858		if (err < 0)
1859			goto error;
1860	}
1861
1862	/* With the page set, use the generic suspend */
1863	return genphy_suspend(phydev);
1864
1865error:
1866	marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
1867	return err;
1868}
1869
1870/* marvell_resume
1871 *
1872 * Some Marvell's phys have two modes: fiber and copper.
1873 * Both need to be resumed
1874 */
1875static int marvell_resume(struct phy_device *phydev)
1876{
1877	int err;
1878
1879	/* Resume the fiber mode first */
1880	if (linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
1881			      phydev->supported)) {
1882		err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE);
1883		if (err < 0)
1884			goto error;
1885
1886		/* With the page set, use the generic resume */
1887		err = genphy_resume(phydev);
1888		if (err < 0)
1889			goto error;
1890
1891		/* Then, the copper link */
1892		err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
1893		if (err < 0)
1894			goto error;
1895	}
1896
1897	/* With the page set, use the generic resume */
1898	return genphy_resume(phydev);
1899
1900error:
1901	marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
1902	return err;
1903}
1904
1905/* m88e1510_resume
1906 *
1907 * The 88e1510 PHY has an erratum where the phy downshift counter is not cleared
1908 * after phy being suspended(BMCR_PDOWN set) and then later resumed(BMCR_PDOWN
1909 * cleared). This can cause the link to intermittently downshift to a lower speed.
1910 *
1911 * Disabling and re-enabling the downshift feature clears the counter, allowing
1912 * the PHY to retry gigabit link negotiation up to the programmed retry count
1913 * before downshifting. This behavior has been observed on copper links.
1914 */
1915static int m88e1510_resume(struct phy_device *phydev)
1916{
1917	int err;
1918	u8 cnt = 0;
1919
1920	err = marvell_resume(phydev);
1921	if (err < 0)
1922		return err;
1923
1924	/* read downshift counter value */
1925	err = m88e1011_get_downshift(phydev, &cnt);
1926	if (err < 0)
1927		return err;
1928
1929	if (cnt) {
1930		/* downshift disabled */
1931		err = m88e1011_set_downshift(phydev, 0);
1932		if (err < 0)
1933			return err;
1934
1935		/* downshift enabled, with previous counter value */
1936		err = m88e1011_set_downshift(phydev, cnt);
1937	}
1938
1939	return err;
1940}
1941
1942static int marvell_aneg_done(struct phy_device *phydev)
1943{
1944	int retval = phy_read(phydev, MII_M1011_PHY_STATUS);
1945
1946	return (retval < 0) ? retval : (retval & MII_M1011_PHY_STATUS_RESOLVED);
1947}
1948
1949static void m88e1318_get_wol(struct phy_device *phydev,
1950			     struct ethtool_wolinfo *wol)
1951{
1952	int ret;
1953
1954	wol->supported = WAKE_MAGIC | WAKE_PHY;
1955	wol->wolopts = 0;
1956
1957	ret = phy_read_paged(phydev, MII_MARVELL_WOL_PAGE,
1958			     MII_88E1318S_PHY_WOL_CTRL);
1959	if (ret < 0)
1960		return;
1961
1962	if (ret & MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE)
1963		wol->wolopts |= WAKE_MAGIC;
1964
1965	if (ret & MII_88E1318S_PHY_WOL_CTRL_LINK_UP_ENABLE)
1966		wol->wolopts |= WAKE_PHY;
1967}
1968
1969static int m88e1318_set_wol(struct phy_device *phydev,
1970			    struct ethtool_wolinfo *wol)
1971{
1972	int err = 0, oldpage;
1973
1974	oldpage = phy_save_page(phydev);
1975	if (oldpage < 0)
1976		goto error;
1977
1978	if (wol->wolopts & (WAKE_MAGIC | WAKE_PHY)) {
1979		/* Explicitly switch to page 0x00, just to be sure */
1980		err = marvell_write_page(phydev, MII_MARVELL_COPPER_PAGE);
1981		if (err < 0)
1982			goto error;
1983
1984		/* If WOL event happened once, the LED[2] interrupt pin
1985		 * will not be cleared unless we reading the interrupt status
1986		 * register. If interrupts are in use, the normal interrupt
1987		 * handling will clear the WOL event. Clear the WOL event
1988		 * before enabling it if !phy_interrupt_is_valid()
1989		 */
1990		if (!phy_interrupt_is_valid(phydev))
1991			__phy_read(phydev, MII_M1011_IEVENT);
1992
1993		/* Enable the WOL interrupt */
1994		err = __phy_set_bits(phydev, MII_88E1318S_PHY_CSIER,
1995				     MII_88E1318S_PHY_CSIER_WOL_EIE);
1996		if (err < 0)
1997			goto error;
1998
1999		err = marvell_write_page(phydev, MII_MARVELL_LED_PAGE);
2000		if (err < 0)
2001			goto error;
2002
2003		/* Setup LED[2] as interrupt pin (active low) */
2004		err = __phy_modify(phydev, MII_88E1318S_PHY_LED_TCR,
2005				   MII_88E1318S_PHY_LED_TCR_FORCE_INT,
2006				   MII_88E1318S_PHY_LED_TCR_INTn_ENABLE |
2007				   MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW);
2008		if (err < 0)
2009			goto error;
2010	}
2011
2012	if (wol->wolopts & WAKE_MAGIC) {
2013		err = marvell_write_page(phydev, MII_MARVELL_WOL_PAGE);
2014		if (err < 0)
2015			goto error;
2016
2017		/* Store the device address for the magic packet */
2018		err = __phy_write(phydev, MII_88E1318S_PHY_MAGIC_PACKET_WORD2,
2019				((phydev->attached_dev->dev_addr[5] << 8) |
2020				 phydev->attached_dev->dev_addr[4]));
2021		if (err < 0)
2022			goto error;
2023		err = __phy_write(phydev, MII_88E1318S_PHY_MAGIC_PACKET_WORD1,
2024				((phydev->attached_dev->dev_addr[3] << 8) |
2025				 phydev->attached_dev->dev_addr[2]));
2026		if (err < 0)
2027			goto error;
2028		err = __phy_write(phydev, MII_88E1318S_PHY_MAGIC_PACKET_WORD0,
2029				((phydev->attached_dev->dev_addr[1] << 8) |
2030				 phydev->attached_dev->dev_addr[0]));
2031		if (err < 0)
2032			goto error;
2033
2034		/* Clear WOL status and enable magic packet matching */
2035		err = __phy_set_bits(phydev, MII_88E1318S_PHY_WOL_CTRL,
2036				     MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS |
2037				     MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE);
2038		if (err < 0)
2039			goto error;
2040	} else {
2041		err = marvell_write_page(phydev, MII_MARVELL_WOL_PAGE);
2042		if (err < 0)
2043			goto error;
2044
2045		/* Clear WOL status and disable magic packet matching */
2046		err = __phy_modify(phydev, MII_88E1318S_PHY_WOL_CTRL,
2047				   MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE,
2048				   MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS);
2049		if (err < 0)
2050			goto error;
2051	}
2052
2053	if (wol->wolopts & WAKE_PHY) {
2054		err = marvell_write_page(phydev, MII_MARVELL_WOL_PAGE);
2055		if (err < 0)
2056			goto error;
2057
2058		/* Clear WOL status and enable link up event */
2059		err = __phy_modify(phydev, MII_88E1318S_PHY_WOL_CTRL, 0,
2060				   MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS |
2061				   MII_88E1318S_PHY_WOL_CTRL_LINK_UP_ENABLE);
2062		if (err < 0)
2063			goto error;
2064	} else {
2065		err = marvell_write_page(phydev, MII_MARVELL_WOL_PAGE);
2066		if (err < 0)
2067			goto error;
2068
2069		/* Clear WOL status and disable link up event */
2070		err = __phy_modify(phydev, MII_88E1318S_PHY_WOL_CTRL,
2071				   MII_88E1318S_PHY_WOL_CTRL_LINK_UP_ENABLE,
2072				   MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS);
2073		if (err < 0)
2074			goto error;
2075	}
2076
2077error:
2078	return phy_restore_page(phydev, oldpage, err);
2079}
2080
2081static int marvell_get_sset_count(struct phy_device *phydev)
2082{
2083	if (linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
2084			      phydev->supported))
2085		return ARRAY_SIZE(marvell_hw_stats);
2086	else
2087		return ARRAY_SIZE(marvell_hw_stats) - NB_FIBER_STATS;
2088}
2089
2090static int marvell_get_sset_count_simple(struct phy_device *phydev)
2091{
2092	return ARRAY_SIZE(marvell_hw_stats_simple);
2093}
2094
2095static void marvell_get_strings(struct phy_device *phydev, u8 *data)
2096{
2097	int count = marvell_get_sset_count(phydev);
2098	int i;
2099
2100	for (i = 0; i < count; i++)
2101		ethtool_puts(&data, marvell_hw_stats[i].string);
2102}
2103
2104static void marvell_get_strings_simple(struct phy_device *phydev, u8 *data)
2105{
2106	int count = marvell_get_sset_count_simple(phydev);
2107	int i;
2108
2109	for (i = 0; i < count; i++)
2110		ethtool_puts(&data, marvell_hw_stats_simple[i].string);
2111}
2112
2113static u64 marvell_get_stat(struct phy_device *phydev, int i)
2114{
2115	struct marvell_hw_stat stat = marvell_hw_stats[i];
2116	struct marvell_priv *priv = phydev->priv;
2117	int val;
2118	u64 ret;
2119
2120	val = phy_read_paged(phydev, stat.page, stat.reg);
2121	if (val < 0) {
2122		ret = U64_MAX;
2123	} else {
2124		val = val & ((1 << stat.bits) - 1);
2125		priv->stats[i] += val;
2126		ret = priv->stats[i];
2127	}
2128
2129	return ret;
2130}
2131
2132static u64 marvell_get_stat_simple(struct phy_device *phydev, int i)
2133{
2134	struct marvell_hw_stat_simple stat = marvell_hw_stats_simple[i];
2135	struct marvell_priv *priv = phydev->priv;
2136	int val;
2137	u64 ret;
2138
2139	val = phy_read(phydev, stat.reg);
2140	if (val < 0) {
2141		ret = U64_MAX;
2142	} else {
2143		val = val & ((1 << stat.bits) - 1);
2144		priv->stats[i] += val;
2145		ret = priv->stats[i];
2146	}
2147
2148	return ret;
2149}
2150
2151static void marvell_get_stats(struct phy_device *phydev,
2152			      struct ethtool_stats *stats, u64 *data)
2153{
2154	int count = marvell_get_sset_count(phydev);
2155	int i;
2156
2157	for (i = 0; i < count; i++)
2158		data[i] = marvell_get_stat(phydev, i);
2159}
2160
2161static void marvell_get_stats_simple(struct phy_device *phydev,
2162				     struct ethtool_stats *stats, u64 *data)
2163{
2164	int count = marvell_get_sset_count_simple(phydev);
2165	int i;
2166
2167	for (i = 0; i < count; i++)
2168		data[i] = marvell_get_stat_simple(phydev, i);
2169}
2170
2171static int m88e1510_loopback(struct phy_device *phydev, bool enable, int speed)
2172{
2173	u16 bmcr_ctl, mscr2_ctl = 0;
2174	int err;
2175
2176	if (!enable)
2177		return genphy_loopback(phydev, enable, 0);
2178
2179	if (speed == SPEED_10 || speed == SPEED_100 || speed == SPEED_1000)
2180		phydev->speed = speed;
2181	else if (speed)
2182		return -EINVAL;
2183
2184	bmcr_ctl = mii_bmcr_encode_fixed(phydev->speed, phydev->duplex);
2185
2186	err = phy_write(phydev, MII_BMCR, bmcr_ctl);
2187	if (err < 0)
2188		return err;
2189
2190	if (phydev->speed == SPEED_1000)
2191		mscr2_ctl = BMCR_SPEED1000;
2192	else if (phydev->speed == SPEED_100)
2193		mscr2_ctl = BMCR_SPEED100;
2194
2195	err = phy_modify_paged(phydev, MII_MARVELL_MSCR_PAGE,
2196			       MII_88E1510_MSCR_2, BMCR_SPEED1000 |
2197			       BMCR_SPEED100, mscr2_ctl);
2198	if (err < 0)
2199		return err;
2200
2201	/* Need soft reset to have speed configuration takes effect */
2202	err = genphy_soft_reset(phydev);
2203	if (err < 0)
2204		return err;
2205
2206	err = phy_modify(phydev, MII_BMCR, BMCR_LOOPBACK,
2207			 BMCR_LOOPBACK);
2208
2209	if (!err) {
2210		/*
2211		 * It takes some time for PHY device to switch into loopback
2212		 * mode.
2213		 */
2214		msleep(1000);
2215	}
2216	return err;
2217}
2218
2219static int marvell_vct5_wait_complete(struct phy_device *phydev)
2220{
2221	int i;
2222	int val;
2223
2224	for (i = 0; i < 32; i++) {
2225		val = __phy_read(phydev, MII_VCT5_CTRL);
2226		if (val < 0)
2227			return val;
2228
2229		if (val & MII_VCT5_CTRL_COMPLETE)
2230			return 0;
2231	}
2232
2233	phydev_err(phydev, "Timeout while waiting for cable test to finish\n");
2234	return -ETIMEDOUT;
2235}
2236
2237static int marvell_vct5_amplitude(struct phy_device *phydev, int pair)
2238{
2239	int amplitude;
2240	int val;
2241	int reg;
2242
2243	reg = MII_VCT5_TX_RX_MDI0_COUPLING + pair;
2244	val = __phy_read(phydev, reg);
2245
2246	if (val < 0)
2247		return 0;
2248
2249	amplitude = (val & MII_VCT5_TX_RX_AMPLITUDE_MASK) >>
2250		MII_VCT5_TX_RX_AMPLITUDE_SHIFT;
2251
2252	if (!(val & MII_VCT5_TX_RX_COUPLING_POSITIVE_REFLECTION))
2253		amplitude = -amplitude;
2254
2255	return 1000 * amplitude / 128;
2256}
2257
2258static u32 marvell_vct5_distance2cm(int distance)
2259{
2260	return distance * 805 / 10;
2261}
2262
2263static u32 marvell_vct5_cm2distance(int cm)
2264{
2265	return cm * 10 / 805;
2266}
2267
2268static int marvell_vct5_amplitude_distance(struct phy_device *phydev,
2269					   int distance, int pair)
2270{
2271	u16 reg;
2272	int err;
2273	int mV;
2274	int i;
2275
2276	err = __phy_write(phydev, MII_VCT5_SAMPLE_POINT_DISTANCE,
2277			  distance);
2278	if (err)
2279		return err;
2280
2281	reg = MII_VCT5_CTRL_ENABLE |
2282		MII_VCT5_CTRL_TX_SAME_CHANNEL |
2283		MII_VCT5_CTRL_SAMPLES_DEFAULT |
2284		MII_VCT5_CTRL_SAMPLE_POINT |
2285		MII_VCT5_CTRL_PEEK_HYST_DEFAULT;
2286	err = __phy_write(phydev, MII_VCT5_CTRL, reg);
2287	if (err)
2288		return err;
2289
2290	err = marvell_vct5_wait_complete(phydev);
2291	if (err)
2292		return err;
2293
2294	for (i = 0; i < 4; i++) {
2295		if (pair != PHY_PAIR_ALL && i != pair)
2296			continue;
2297
2298		mV = marvell_vct5_amplitude(phydev, i);
2299		ethnl_cable_test_amplitude(phydev, i, mV);
2300	}
2301
2302	return 0;
2303}
2304
2305static int marvell_vct5_amplitude_graph(struct phy_device *phydev)
2306{
2307	struct marvell_priv *priv = phydev->priv;
2308	int distance;
2309	u16 width;
2310	int page;
2311	int err;
2312	u16 reg;
2313
2314	if (priv->first <= TDR_SHORT_CABLE_LENGTH)
2315		width = MII_VCT5_TX_PULSE_CTRL_PULSE_WIDTH_32nS;
2316	else
2317		width = MII_VCT5_TX_PULSE_CTRL_PULSE_WIDTH_128nS;
2318
2319	reg = MII_VCT5_TX_PULSE_CTRL_GT_140m_46_86mV |
2320		MII_VCT5_TX_PULSE_CTRL_DONT_WAIT_LINK_DOWN |
2321		MII_VCT5_TX_PULSE_CTRL_MAX_AMP | width;
2322
2323	err = phy_write_paged(phydev, MII_MARVELL_VCT5_PAGE,
2324			      MII_VCT5_TX_PULSE_CTRL, reg);
2325	if (err)
2326		return err;
2327
2328	/* Reading the TDR data is very MDIO heavy. We need to optimize
2329	 * access to keep the time to a minimum. So lock the bus once,
2330	 * and don't release it until complete. We can then avoid having
2331	 * to change the page for every access, greatly speeding things
2332	 * up.
2333	 */
2334	page = phy_select_page(phydev, MII_MARVELL_VCT5_PAGE);
2335	if (page < 0)
2336		goto restore_page;
2337
2338	for (distance = priv->first;
2339	     distance <= priv->last;
2340	     distance += priv->step) {
2341		err = marvell_vct5_amplitude_distance(phydev, distance,
2342						      priv->pair);
2343		if (err)
2344			goto restore_page;
2345
2346		if (distance > TDR_SHORT_CABLE_LENGTH &&
2347		    width == MII_VCT5_TX_PULSE_CTRL_PULSE_WIDTH_32nS) {
2348			width = MII_VCT5_TX_PULSE_CTRL_PULSE_WIDTH_128nS;
2349			reg = MII_VCT5_TX_PULSE_CTRL_GT_140m_46_86mV |
2350				MII_VCT5_TX_PULSE_CTRL_DONT_WAIT_LINK_DOWN |
2351				MII_VCT5_TX_PULSE_CTRL_MAX_AMP | width;
2352			err = __phy_write(phydev, MII_VCT5_TX_PULSE_CTRL, reg);
2353			if (err)
2354				goto restore_page;
2355		}
2356	}
2357
2358restore_page:
2359	return phy_restore_page(phydev, page, err);
2360}
2361
2362static int marvell_cable_test_start_common(struct phy_device *phydev)
2363{
2364	int bmcr, bmsr, ret;
2365
2366	/* If auto-negotiation is enabled, but not complete, the cable
2367	 * test never completes. So disable auto-neg.
2368	 */
2369	bmcr = phy_read(phydev, MII_BMCR);
2370	if (bmcr < 0)
2371		return bmcr;
2372
2373	bmsr = phy_read(phydev, MII_BMSR);
2374
2375	if (bmsr < 0)
2376		return bmsr;
2377
2378	if (bmcr & BMCR_ANENABLE) {
2379		ret =  phy_clear_bits(phydev, MII_BMCR, BMCR_ANENABLE);
2380		if (ret < 0)
2381			return ret;
2382		ret = genphy_soft_reset(phydev);
2383		if (ret < 0)
2384			return ret;
2385	}
2386
2387	/* If the link is up, allow it some time to go down */
2388	if (bmsr & BMSR_LSTATUS)
2389		msleep(1500);
2390
2391	return 0;
2392}
2393
2394static int marvell_vct7_cable_test_start(struct phy_device *phydev)
2395{
2396	struct marvell_priv *priv = phydev->priv;
2397	int ret;
2398
2399	ret = marvell_cable_test_start_common(phydev);
2400	if (ret)
2401		return ret;
2402
2403	priv->cable_test_tdr = false;
2404
2405	/* Reset the VCT5 API control to defaults, otherwise
2406	 * VCT7 does not work correctly.
2407	 */
2408	ret = phy_write_paged(phydev, MII_MARVELL_VCT5_PAGE,
2409			      MII_VCT5_CTRL,
2410			      MII_VCT5_CTRL_TX_SAME_CHANNEL |
2411			      MII_VCT5_CTRL_SAMPLES_DEFAULT |
2412			      MII_VCT5_CTRL_MODE_MAXIMUM_PEEK |
2413			      MII_VCT5_CTRL_PEEK_HYST_DEFAULT);
2414	if (ret)
2415		return ret;
2416
2417	ret = phy_write_paged(phydev, MII_MARVELL_VCT5_PAGE,
2418			      MII_VCT5_SAMPLE_POINT_DISTANCE, 0);
2419	if (ret)
2420		return ret;
2421
2422	return phy_write_paged(phydev, MII_MARVELL_VCT7_PAGE,
2423			       MII_VCT7_CTRL,
2424			       MII_VCT7_CTRL_RUN_NOW |
2425			       MII_VCT7_CTRL_CENTIMETERS);
2426}
2427
2428static int marvell_vct5_cable_test_tdr_start(struct phy_device *phydev,
2429					     const struct phy_tdr_config *cfg)
2430{
2431	struct marvell_priv *priv = phydev->priv;
2432	int ret;
2433
2434	priv->cable_test_tdr = true;
2435	priv->first = marvell_vct5_cm2distance(cfg->first);
2436	priv->last = marvell_vct5_cm2distance(cfg->last);
2437	priv->step = marvell_vct5_cm2distance(cfg->step);
2438	priv->pair = cfg->pair;
2439
2440	if (priv->first > MII_VCT5_SAMPLE_POINT_DISTANCE_MAX)
2441		return -EINVAL;
2442
2443	if (priv->last > MII_VCT5_SAMPLE_POINT_DISTANCE_MAX)
2444		return -EINVAL;
2445
2446	/* Disable  VCT7 */
2447	ret = phy_write_paged(phydev, MII_MARVELL_VCT7_PAGE,
2448			      MII_VCT7_CTRL, 0);
2449	if (ret)
2450		return ret;
2451
2452	ret = marvell_cable_test_start_common(phydev);
2453	if (ret)
2454		return ret;
2455
2456	ret = ethnl_cable_test_pulse(phydev, 1000);
2457	if (ret)
2458		return ret;
2459
2460	return ethnl_cable_test_step(phydev,
2461				     marvell_vct5_distance2cm(priv->first),
2462				     marvell_vct5_distance2cm(priv->last),
2463				     marvell_vct5_distance2cm(priv->step));
2464}
2465
2466static int marvell_vct7_distance_to_length(int distance, bool meter)
2467{
2468	if (meter)
2469		distance *= 100;
2470
2471	return distance;
2472}
2473
2474static bool marvell_vct7_distance_valid(int result)
2475{
2476	switch (result) {
2477	case MII_VCT7_RESULTS_OPEN:
2478	case MII_VCT7_RESULTS_SAME_SHORT:
2479	case MII_VCT7_RESULTS_CROSS_SHORT:
2480		return true;
2481	}
2482	return false;
2483}
2484
2485static int marvell_vct7_report_length(struct phy_device *phydev,
2486				      int pair, bool meter)
2487{
2488	int length;
2489	int ret;
2490
2491	ret = phy_read_paged(phydev, MII_MARVELL_VCT7_PAGE,
2492			     MII_VCT7_PAIR_0_DISTANCE + pair);
2493	if (ret < 0)
2494		return ret;
2495
2496	length = marvell_vct7_distance_to_length(ret, meter);
2497
2498	ethnl_cable_test_fault_length(phydev, pair, length);
2499
2500	return 0;
2501}
2502
2503static int marvell_vct7_cable_test_report_trans(int result)
2504{
2505	switch (result) {
2506	case MII_VCT7_RESULTS_OK:
2507		return ETHTOOL_A_CABLE_RESULT_CODE_OK;
2508	case MII_VCT7_RESULTS_OPEN:
2509		return ETHTOOL_A_CABLE_RESULT_CODE_OPEN;
2510	case MII_VCT7_RESULTS_SAME_SHORT:
2511		return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT;
2512	case MII_VCT7_RESULTS_CROSS_SHORT:
2513		return ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT;
2514	default:
2515		return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC;
2516	}
2517}
2518
2519static int marvell_vct7_cable_test_report(struct phy_device *phydev)
2520{
2521	int pair0, pair1, pair2, pair3;
2522	bool meter;
2523	int ret;
2524
2525	ret = phy_read_paged(phydev, MII_MARVELL_VCT7_PAGE,
2526			     MII_VCT7_RESULTS);
2527	if (ret < 0)
2528		return ret;
2529
2530	pair3 = (ret & MII_VCT7_RESULTS_PAIR3_MASK) >>
2531		MII_VCT7_RESULTS_PAIR3_SHIFT;
2532	pair2 = (ret & MII_VCT7_RESULTS_PAIR2_MASK) >>
2533		MII_VCT7_RESULTS_PAIR2_SHIFT;
2534	pair1 = (ret & MII_VCT7_RESULTS_PAIR1_MASK) >>
2535		MII_VCT7_RESULTS_PAIR1_SHIFT;
2536	pair0 = (ret & MII_VCT7_RESULTS_PAIR0_MASK) >>
2537		MII_VCT7_RESULTS_PAIR0_SHIFT;
2538
2539	ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_A,
2540				marvell_vct7_cable_test_report_trans(pair0));
2541	ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_B,
2542				marvell_vct7_cable_test_report_trans(pair1));
2543	ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_C,
2544				marvell_vct7_cable_test_report_trans(pair2));
2545	ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_D,
2546				marvell_vct7_cable_test_report_trans(pair3));
2547
2548	ret = phy_read_paged(phydev, MII_MARVELL_VCT7_PAGE, MII_VCT7_CTRL);
2549	if (ret < 0)
2550		return ret;
2551
2552	meter = ret & MII_VCT7_CTRL_METERS;
2553
2554	if (marvell_vct7_distance_valid(pair0))
2555		marvell_vct7_report_length(phydev, 0, meter);
2556	if (marvell_vct7_distance_valid(pair1))
2557		marvell_vct7_report_length(phydev, 1, meter);
2558	if (marvell_vct7_distance_valid(pair2))
2559		marvell_vct7_report_length(phydev, 2, meter);
2560	if (marvell_vct7_distance_valid(pair3))
2561		marvell_vct7_report_length(phydev, 3, meter);
2562
2563	return 0;
2564}
2565
2566static int marvell_vct7_cable_test_get_status(struct phy_device *phydev,
2567					      bool *finished)
2568{
2569	struct marvell_priv *priv = phydev->priv;
2570	int ret;
2571
2572	if (priv->cable_test_tdr) {
2573		ret = marvell_vct5_amplitude_graph(phydev);
2574		*finished = true;
2575		return ret;
2576	}
2577
2578	*finished = false;
2579
2580	ret = phy_read_paged(phydev, MII_MARVELL_VCT7_PAGE,
2581			     MII_VCT7_CTRL);
2582
2583	if (ret < 0)
2584		return ret;
2585
2586	if (!(ret & MII_VCT7_CTRL_IN_PROGRESS)) {
2587		*finished = true;
2588
2589		return marvell_vct7_cable_test_report(phydev);
2590	}
2591
2592	return 0;
2593}
2594
2595static int m88e3082_vct_cable_test_start(struct phy_device *phydev)
2596{
2597	struct marvell_priv *priv = phydev->priv;
2598	int ret;
2599
2600	/* It needs some magic workarounds described in VCT manual for this PHY.
2601	 */
2602	ret = phy_write(phydev, 29, 0x0003);
2603	if (ret < 0)
2604		return ret;
2605
2606	ret = phy_write(phydev, 30, 0x6440);
2607	if (ret < 0)
2608		return ret;
2609
2610	if (priv->vct_phase == M88E3082_VCT_PHASE1) {
2611		ret = phy_write(phydev, 29, 0x000a);
2612		if (ret < 0)
2613			return ret;
2614
2615		ret = phy_write(phydev, 30, 0x0002);
2616		if (ret < 0)
2617			return ret;
2618	}
2619
2620	ret = phy_write(phydev, MII_BMCR,
2621			BMCR_RESET | BMCR_SPEED100 | BMCR_FULLDPLX);
2622	if (ret < 0)
2623		return ret;
2624
2625	ret = phy_write(phydev, MII_VCT_TXPINS, MII_VCT_TXPINS_ENVCT);
2626	if (ret < 0)
2627		return ret;
2628
2629	ret = phy_write(phydev, 29, 0x0003);
2630	if (ret < 0)
2631		return ret;
2632
2633	ret = phy_write(phydev, 30, 0x0);
2634	if (ret < 0)
2635		return ret;
2636
2637	if (priv->vct_phase == M88E3082_VCT_OFF) {
2638		priv->vct_phase = M88E3082_VCT_PHASE1;
2639		priv->pair = 0;
2640
2641		return 0;
2642	}
2643
2644	ret = phy_write(phydev, 29, 0x000a);
2645	if (ret < 0)
2646		return ret;
2647
2648	ret = phy_write(phydev, 30, 0x0);
2649	if (ret < 0)
2650		return ret;
2651
2652	priv->vct_phase = M88E3082_VCT_PHASE2;
2653
2654	return 0;
2655}
2656
2657static int m88e3082_vct_cable_test_report_trans(int result, u8 distance)
2658{
2659	switch (result) {
2660	case MII_VCT_TXRXPINS_VCTTST_OK:
2661		if (distance == MII_VCT_TXRXPINS_DISTRFLN_MAX)
2662			return ETHTOOL_A_CABLE_RESULT_CODE_OK;
2663		return ETHTOOL_A_CABLE_RESULT_CODE_IMPEDANCE_MISMATCH;
2664	case MII_VCT_TXRXPINS_VCTTST_SHORT:
2665		return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT;
2666	case MII_VCT_TXRXPINS_VCTTST_OPEN:
2667		return ETHTOOL_A_CABLE_RESULT_CODE_OPEN;
2668	default:
2669		return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC;
2670	}
2671}
2672
2673static u32 m88e3082_vct_distrfln_2_cm(u8 distrfln)
2674{
2675	if (distrfln < 24)
2676		return 0;
2677
2678	/* Original function for meters: y = 0.7861x - 18.862 */
2679	return (7861 * distrfln - 188620) / 100;
2680}
2681
2682static int m88e3082_vct_cable_test_get_status(struct phy_device *phydev,
2683					      bool *finished)
2684{
2685	u8 tx_vcttst_res, rx_vcttst_res, tx_distrfln, rx_distrfln;
2686	struct marvell_priv *priv = phydev->priv;
2687	int ret, tx_result, rx_result;
2688	bool done_phase = true;
2689
2690	*finished = false;
2691
2692	ret = phy_read(phydev, MII_VCT_TXPINS);
2693	if (ret < 0)
2694		return ret;
2695	else if (ret & MII_VCT_TXPINS_ENVCT)
2696		return 0;
2697
2698	tx_distrfln = ret & MII_VCT_TXRXPINS_DISTRFLN;
2699	tx_vcttst_res = (ret & MII_VCT_TXRXPINS_VCTTST) >>
2700			MII_VCT_TXRXPINS_VCTTST_SHIFT;
2701
2702	ret = phy_read(phydev, MII_VCT_RXPINS);
2703	if (ret < 0)
2704		return ret;
2705
2706	rx_distrfln = ret & MII_VCT_TXRXPINS_DISTRFLN;
2707	rx_vcttst_res = (ret & MII_VCT_TXRXPINS_VCTTST) >>
2708			MII_VCT_TXRXPINS_VCTTST_SHIFT;
2709
2710	*finished = true;
2711
2712	switch (priv->vct_phase) {
2713	case M88E3082_VCT_PHASE1:
2714		tx_result = m88e3082_vct_cable_test_report_trans(tx_vcttst_res,
2715								 tx_distrfln);
2716		rx_result = m88e3082_vct_cable_test_report_trans(rx_vcttst_res,
2717								 rx_distrfln);
2718
2719		ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_A,
2720					tx_result);
2721		ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_B,
2722					rx_result);
2723
2724		if (tx_vcttst_res == MII_VCT_TXRXPINS_VCTTST_OPEN) {
2725			done_phase = false;
2726			priv->pair |= M88E3082_PAIR_A;
2727		} else if (tx_distrfln < MII_VCT_TXRXPINS_DISTRFLN_MAX) {
2728			u8 pair = ETHTOOL_A_CABLE_PAIR_A;
2729			u32 cm = m88e3082_vct_distrfln_2_cm(tx_distrfln);
2730
2731			ethnl_cable_test_fault_length(phydev, pair, cm);
2732		}
2733
2734		if (rx_vcttst_res == MII_VCT_TXRXPINS_VCTTST_OPEN) {
2735			done_phase = false;
2736			priv->pair |= M88E3082_PAIR_B;
2737		} else if (rx_distrfln < MII_VCT_TXRXPINS_DISTRFLN_MAX) {
2738			u8 pair = ETHTOOL_A_CABLE_PAIR_B;
2739			u32 cm = m88e3082_vct_distrfln_2_cm(rx_distrfln);
2740
2741			ethnl_cable_test_fault_length(phydev, pair, cm);
2742		}
2743
2744		break;
2745	case M88E3082_VCT_PHASE2:
2746		if (priv->pair & M88E3082_PAIR_A &&
2747		    tx_vcttst_res == MII_VCT_TXRXPINS_VCTTST_OPEN &&
2748		    tx_distrfln < MII_VCT_TXRXPINS_DISTRFLN_MAX) {
2749			u8 pair = ETHTOOL_A_CABLE_PAIR_A;
2750			u32 cm = m88e3082_vct_distrfln_2_cm(tx_distrfln);
2751
2752			ethnl_cable_test_fault_length(phydev, pair, cm);
2753		}
2754		if (priv->pair & M88E3082_PAIR_B &&
2755		    rx_vcttst_res == MII_VCT_TXRXPINS_VCTTST_OPEN &&
2756		    rx_distrfln < MII_VCT_TXRXPINS_DISTRFLN_MAX) {
2757			u8 pair = ETHTOOL_A_CABLE_PAIR_B;
2758			u32 cm = m88e3082_vct_distrfln_2_cm(rx_distrfln);
2759
2760			ethnl_cable_test_fault_length(phydev, pair, cm);
2761		}
2762
2763		break;
2764	default:
2765		return -EINVAL;
2766	}
2767
2768	if (!done_phase) {
2769		*finished = false;
2770		return m88e3082_vct_cable_test_start(phydev);
2771	}
2772	if (*finished)
2773		priv->vct_phase = M88E3082_VCT_OFF;
2774	return 0;
2775}
2776
2777static int m88e1111_vct_cable_test_start(struct phy_device *phydev)
2778{
2779	int ret;
2780
2781	ret = marvell_cable_test_start_common(phydev);
2782	if (ret)
2783		return ret;
2784
2785	/* It needs some magic workarounds described in VCT manual for this PHY.
2786	 */
2787	ret = phy_write(phydev, 29, 0x0018);
2788	if (ret < 0)
2789		return ret;
2790
2791	ret = phy_write(phydev, 30, 0x00c2);
2792	if (ret < 0)
2793		return ret;
2794
2795	ret = phy_write(phydev, 30, 0x00ca);
2796	if (ret < 0)
2797		return ret;
2798
2799	ret = phy_write(phydev, 30, 0x00c2);
2800	if (ret < 0)
2801		return ret;
2802
2803	ret = phy_write_paged(phydev, MII_MARVELL_COPPER_PAGE, MII_VCT_SR,
2804			      MII_VCT_TXPINS_ENVCT);
2805	if (ret < 0)
2806		return ret;
2807
2808	ret = phy_write(phydev, 29, 0x0018);
2809	if (ret < 0)
2810		return ret;
2811
2812	ret = phy_write(phydev, 30, 0x0042);
2813	if (ret < 0)
2814		return ret;
2815
2816	return 0;
2817}
2818
2819static u32 m88e1111_vct_distrfln_2_cm(u8 distrfln)
2820{
2821	if (distrfln < 36)
2822		return 0;
2823
2824	/* Original function for meters: y = 0.8018x - 28.751 */
2825	return (8018 * distrfln - 287510) / 100;
2826}
2827
2828static int m88e1111_vct_cable_test_get_status(struct phy_device *phydev,
2829					      bool *finished)
2830{
2831	u8 vcttst_res, distrfln;
2832	int ret, result;
2833
2834	*finished = false;
2835
2836	/* Each pair use one page: A-0, B-1, C-2, D-3 */
2837	for (u8 i = 0; i < 4; i++) {
2838		ret = phy_read_paged(phydev, i, MII_VCT_SR);
2839		if (ret < 0)
2840			return ret;
2841		else if (i == 0 && ret & MII_VCT_TXPINS_ENVCT)
2842			return 0;
2843
2844		distrfln = ret & MII_VCT_TXRXPINS_DISTRFLN;
2845		vcttst_res = (ret & MII_VCT_TXRXPINS_VCTTST) >>
2846			      MII_VCT_TXRXPINS_VCTTST_SHIFT;
2847
2848		result = m88e3082_vct_cable_test_report_trans(vcttst_res,
2849							      distrfln);
2850		ethnl_cable_test_result(phydev, i, result);
2851
2852		if (distrfln < MII_VCT_TXRXPINS_DISTRFLN_MAX) {
2853			u32 cm = m88e1111_vct_distrfln_2_cm(distrfln);
2854
2855			ethnl_cable_test_fault_length(phydev, i, cm);
2856		}
2857	}
2858
2859	*finished = true;
2860	return 0;
2861}
2862
2863#ifdef CONFIG_HWMON
2864struct marvell_hwmon_ops {
2865	int (*config)(struct phy_device *phydev);
2866	int (*get_temp)(struct phy_device *phydev, long *temp);
2867	int (*get_temp_critical)(struct phy_device *phydev, long *temp);
2868	int (*set_temp_critical)(struct phy_device *phydev, long temp);
2869	int (*get_temp_alarm)(struct phy_device *phydev, long *alarm);
2870};
2871
2872static const struct marvell_hwmon_ops *
2873to_marvell_hwmon_ops(const struct phy_device *phydev)
2874{
2875	return phydev->drv->driver_data;
2876}
2877
2878static int m88e1121_get_temp(struct phy_device *phydev, long *temp)
2879{
2880	int oldpage;
2881	int ret = 0;
2882	int val;
2883
2884	*temp = 0;
2885
2886	oldpage = phy_select_page(phydev, MII_MARVELL_MISC_TEST_PAGE);
2887	if (oldpage < 0)
2888		goto error;
2889
2890	/* Enable temperature sensor */
2891	ret = __phy_read(phydev, MII_88E1121_MISC_TEST);
2892	if (ret < 0)
2893		goto error;
2894
2895	ret = __phy_write(phydev, MII_88E1121_MISC_TEST,
2896			  ret | MII_88E1121_MISC_TEST_TEMP_SENSOR_EN);
2897	if (ret < 0)
2898		goto error;
2899
2900	/* Wait for temperature to stabilize */
2901	usleep_range(10000, 12000);
2902
2903	val = __phy_read(phydev, MII_88E1121_MISC_TEST);
2904	if (val < 0) {
2905		ret = val;
2906		goto error;
2907	}
2908
2909	/* Disable temperature sensor */
2910	ret = __phy_write(phydev, MII_88E1121_MISC_TEST,
2911			  ret & ~MII_88E1121_MISC_TEST_TEMP_SENSOR_EN);
2912	if (ret < 0)
2913		goto error;
2914
2915	*temp = ((val & MII_88E1121_MISC_TEST_TEMP_MASK) - 5) * 5000;
2916
2917error:
2918	return phy_restore_page(phydev, oldpage, ret);
2919}
2920
2921static int m88e1510_get_temp(struct phy_device *phydev, long *temp)
2922{
2923	int ret;
2924
2925	*temp = 0;
2926
2927	ret = phy_read_paged(phydev, MII_MARVELL_MISC_TEST_PAGE,
2928			     MII_88E1510_TEMP_SENSOR);
2929	if (ret < 0)
2930		return ret;
2931
2932	*temp = ((ret & MII_88E1510_TEMP_SENSOR_MASK) - 25) * 1000;
2933
2934	return 0;
2935}
2936
2937static int m88e1510_get_temp_critical(struct phy_device *phydev, long *temp)
2938{
2939	int ret;
2940
2941	*temp = 0;
2942
2943	ret = phy_read_paged(phydev, MII_MARVELL_MISC_TEST_PAGE,
2944			     MII_88E1121_MISC_TEST);
2945	if (ret < 0)
2946		return ret;
2947
2948	*temp = (((ret & MII_88E1510_MISC_TEST_TEMP_THRESHOLD_MASK) >>
2949		  MII_88E1510_MISC_TEST_TEMP_THRESHOLD_SHIFT) * 5) - 25;
2950	/* convert to mC */
2951	*temp *= 1000;
2952
2953	return 0;
2954}
2955
2956static int m88e1510_set_temp_critical(struct phy_device *phydev, long temp)
2957{
2958	temp = temp / 1000;
2959	temp = clamp_val(DIV_ROUND_CLOSEST(temp, 5) + 5, 0, 0x1f);
2960
2961	return phy_modify_paged(phydev, MII_MARVELL_MISC_TEST_PAGE,
2962				MII_88E1121_MISC_TEST,
2963				MII_88E1510_MISC_TEST_TEMP_THRESHOLD_MASK,
2964				temp << MII_88E1510_MISC_TEST_TEMP_THRESHOLD_SHIFT);
2965}
2966
2967static int m88e1510_get_temp_alarm(struct phy_device *phydev, long *alarm)
2968{
2969	int ret;
2970
2971	*alarm = false;
2972
2973	ret = phy_read_paged(phydev, MII_MARVELL_MISC_TEST_PAGE,
2974			     MII_88E1121_MISC_TEST);
2975	if (ret < 0)
2976		return ret;
2977
2978	*alarm = !!(ret & MII_88E1510_MISC_TEST_TEMP_IRQ);
2979
2980	return 0;
2981}
2982
2983static int m88e6390_get_temp(struct phy_device *phydev, long *temp)
2984{
2985	int sum = 0;
2986	int oldpage;
2987	int ret = 0;
2988	int i;
2989
2990	*temp = 0;
2991
2992	oldpage = phy_select_page(phydev, MII_MARVELL_MISC_TEST_PAGE);
2993	if (oldpage < 0)
2994		goto error;
2995
2996	/* Enable temperature sensor */
2997	ret = __phy_read(phydev, MII_88E6390_MISC_TEST);
2998	if (ret < 0)
2999		goto error;
3000
3001	ret &= ~MII_88E6390_MISC_TEST_TEMP_SENSOR_MASK;
3002	ret |= MII_88E6390_MISC_TEST_TEMP_SENSOR_ENABLE_SAMPLE_1S;
3003
3004	ret = __phy_write(phydev, MII_88E6390_MISC_TEST, ret);
3005	if (ret < 0)
3006		goto error;
3007
3008	/* Wait for temperature to stabilize */
3009	usleep_range(10000, 12000);
3010
3011	/* Reading the temperature sense has an errata. You need to read
3012	 * a number of times and take an average.
3013	 */
3014	for (i = 0; i < MII_88E6390_TEMP_SENSOR_SAMPLES; i++) {
3015		ret = __phy_read(phydev, MII_88E6390_TEMP_SENSOR);
3016		if (ret < 0)
3017			goto error;
3018		sum += ret & MII_88E6390_TEMP_SENSOR_MASK;
3019	}
3020
3021	sum /= MII_88E6390_TEMP_SENSOR_SAMPLES;
3022	*temp = (sum  - 75) * 1000;
3023
3024	/* Disable temperature sensor */
3025	ret = __phy_read(phydev, MII_88E6390_MISC_TEST);
3026	if (ret < 0)
3027		goto error;
3028
3029	ret = ret & ~MII_88E6390_MISC_TEST_TEMP_SENSOR_MASK;
3030	ret |= MII_88E6390_MISC_TEST_TEMP_SENSOR_DISABLE;
3031
3032	ret = __phy_write(phydev, MII_88E6390_MISC_TEST, ret);
3033
3034error:
3035	phy_restore_page(phydev, oldpage, ret);
3036
3037	return ret;
3038}
3039
3040static int m88e6393_get_temp(struct phy_device *phydev, long *temp)
3041{
3042	int err;
3043
3044	err = m88e1510_get_temp(phydev, temp);
3045
3046	/* 88E1510 measures T + 25, while the PHY on 88E6393X switch
3047	 * T + 75, so we have to subtract another 50
3048	 */
3049	*temp -= 50000;
3050
3051	return err;
3052}
3053
3054static int m88e6393_get_temp_critical(struct phy_device *phydev, long *temp)
3055{
3056	int ret;
3057
3058	*temp = 0;
3059
3060	ret = phy_read_paged(phydev, MII_MARVELL_MISC_TEST_PAGE,
3061			     MII_88E6390_TEMP_SENSOR);
3062	if (ret < 0)
3063		return ret;
3064
3065	*temp = (((ret & MII_88E6393_TEMP_SENSOR_THRESHOLD_MASK) >>
3066		  MII_88E6393_TEMP_SENSOR_THRESHOLD_SHIFT) - 75) * 1000;
3067
3068	return 0;
3069}
3070
3071static int m88e6393_set_temp_critical(struct phy_device *phydev, long temp)
3072{
3073	temp = (temp / 1000) + 75;
3074
3075	return phy_modify_paged(phydev, MII_MARVELL_MISC_TEST_PAGE,
3076				MII_88E6390_TEMP_SENSOR,
3077				MII_88E6393_TEMP_SENSOR_THRESHOLD_MASK,
3078				temp << MII_88E6393_TEMP_SENSOR_THRESHOLD_SHIFT);
3079}
3080
3081static int m88e6393_hwmon_config(struct phy_device *phydev)
3082{
3083	int err;
3084
3085	err = m88e6393_set_temp_critical(phydev, 100000);
3086	if (err)
3087		return err;
3088
3089	return phy_modify_paged(phydev, MII_MARVELL_MISC_TEST_PAGE,
3090				MII_88E6390_MISC_TEST,
3091				MII_88E6390_MISC_TEST_TEMP_SENSOR_MASK |
3092				MII_88E6393_MISC_TEST_SAMPLES_MASK |
3093				MII_88E6393_MISC_TEST_RATE_MASK,
3094				MII_88E6390_MISC_TEST_TEMP_SENSOR_ENABLE |
3095				MII_88E6393_MISC_TEST_SAMPLES_2048 |
3096				MII_88E6393_MISC_TEST_RATE_2_3MS);
3097}
3098
3099static int marvell_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
3100			      u32 attr, int channel, long *temp)
3101{
3102	struct phy_device *phydev = dev_get_drvdata(dev);
3103	const struct marvell_hwmon_ops *ops = to_marvell_hwmon_ops(phydev);
3104	int err = -EOPNOTSUPP;
3105
3106	switch (attr) {
3107	case hwmon_temp_input:
3108		if (ops->get_temp)
3109			err = ops->get_temp(phydev, temp);
3110		break;
3111	case hwmon_temp_crit:
3112		if (ops->get_temp_critical)
3113			err = ops->get_temp_critical(phydev, temp);
3114		break;
3115	case hwmon_temp_max_alarm:
3116		if (ops->get_temp_alarm)
3117			err = ops->get_temp_alarm(phydev, temp);
3118		break;
3119	}
3120
3121	return err;
3122}
3123
3124static int marvell_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
3125			       u32 attr, int channel, long temp)
3126{
3127	struct phy_device *phydev = dev_get_drvdata(dev);
3128	const struct marvell_hwmon_ops *ops = to_marvell_hwmon_ops(phydev);
3129	int err = -EOPNOTSUPP;
3130
3131	switch (attr) {
3132	case hwmon_temp_crit:
3133		if (ops->set_temp_critical)
3134			err = ops->set_temp_critical(phydev, temp);
3135		break;
3136	}
3137
3138	return err;
3139}
3140
3141static umode_t marvell_hwmon_is_visible(const void *data,
3142					enum hwmon_sensor_types type,
3143					u32 attr, int channel)
3144{
3145	const struct phy_device *phydev = data;
3146	const struct marvell_hwmon_ops *ops = to_marvell_hwmon_ops(phydev);
3147
3148	if (type != hwmon_temp)
3149		return 0;
3150
3151	switch (attr) {
3152	case hwmon_temp_input:
3153		return ops->get_temp ? 0444 : 0;
3154	case hwmon_temp_max_alarm:
3155		return ops->get_temp_alarm ? 0444 : 0;
3156	case hwmon_temp_crit:
3157		return (ops->get_temp_critical ? 0444 : 0) |
3158		       (ops->set_temp_critical ? 0200 : 0);
3159	default:
3160		return 0;
3161	}
3162}
3163
3164/* we can define HWMON_T_CRIT and HWMON_T_MAX_ALARM even though these are not
3165 * defined for all PHYs, because the hwmon code checks whether the attributes
3166 * exists via the .is_visible method
3167 */
3168static const struct hwmon_channel_info * const marvell_hwmon_info[] = {
3169	HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ),
3170	HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_CRIT | HWMON_T_MAX_ALARM),
3171	NULL
3172};
3173
3174static const struct hwmon_ops marvell_hwmon_hwmon_ops = {
3175	.is_visible = marvell_hwmon_is_visible,
3176	.read = marvell_hwmon_read,
3177	.write = marvell_hwmon_write,
3178};
3179
3180static const struct hwmon_chip_info marvell_hwmon_chip_info = {
3181	.ops = &marvell_hwmon_hwmon_ops,
3182	.info = marvell_hwmon_info,
3183};
3184
3185static int marvell_hwmon_name(struct phy_device *phydev)
3186{
3187	struct marvell_priv *priv = phydev->priv;
3188	struct device *dev = &phydev->mdio.dev;
3189	const char *devname = dev_name(dev);
3190	size_t len = strlen(devname);
3191	int i, j;
3192
3193	priv->hwmon_name = devm_kzalloc(dev, len, GFP_KERNEL);
3194	if (!priv->hwmon_name)
3195		return -ENOMEM;
3196
3197	for (i = j = 0; i < len && devname[i]; i++) {
3198		if (isalnum(devname[i]))
3199			priv->hwmon_name[j++] = devname[i];
3200	}
3201
3202	return 0;
3203}
3204
3205static int marvell_hwmon_probe(struct phy_device *phydev)
3206{
3207	const struct marvell_hwmon_ops *ops = to_marvell_hwmon_ops(phydev);
3208	struct marvell_priv *priv = phydev->priv;
3209	struct device *dev = &phydev->mdio.dev;
3210	int err;
3211
3212	if (!ops)
3213		return 0;
3214
3215	err = marvell_hwmon_name(phydev);
3216	if (err)
3217		return err;
3218
3219	priv->hwmon_dev = devm_hwmon_device_register_with_info(
3220		dev, priv->hwmon_name, phydev, &marvell_hwmon_chip_info, NULL);
3221	if (IS_ERR(priv->hwmon_dev))
3222		return PTR_ERR(priv->hwmon_dev);
3223
3224	if (ops->config)
3225		err = ops->config(phydev);
3226
3227	return err;
3228}
3229
3230static const struct marvell_hwmon_ops m88e1121_hwmon_ops = {
3231	.get_temp = m88e1121_get_temp,
3232};
3233
3234static const struct marvell_hwmon_ops m88e1510_hwmon_ops = {
3235	.get_temp = m88e1510_get_temp,
3236	.get_temp_critical = m88e1510_get_temp_critical,
3237	.set_temp_critical = m88e1510_set_temp_critical,
3238	.get_temp_alarm = m88e1510_get_temp_alarm,
3239};
3240
3241static const struct marvell_hwmon_ops m88e6390_hwmon_ops = {
3242	.get_temp = m88e6390_get_temp,
3243};
3244
3245static const struct marvell_hwmon_ops m88e6393_hwmon_ops = {
3246	.config = m88e6393_hwmon_config,
3247	.get_temp = m88e6393_get_temp,
3248	.get_temp_critical = m88e6393_get_temp_critical,
3249	.set_temp_critical = m88e6393_set_temp_critical,
3250	.get_temp_alarm = m88e1510_get_temp_alarm,
3251};
3252
3253#define DEF_MARVELL_HWMON_OPS(s) (&(s))
3254
3255#else
3256
3257#define DEF_MARVELL_HWMON_OPS(s) NULL
3258
3259static int marvell_hwmon_probe(struct phy_device *phydev)
3260{
3261	return 0;
3262}
3263#endif
3264
3265static int m88e1318_led_brightness_set(struct phy_device *phydev,
3266				       u8 index, enum led_brightness value)
3267{
3268	int reg;
3269
3270	reg = phy_read_paged(phydev, MII_MARVELL_LED_PAGE,
3271			     MII_88E1318S_PHY_LED_FUNC);
3272	if (reg < 0)
3273		return reg;
3274
3275	switch (index) {
3276	case 0:
3277	case 1:
3278	case 2:
3279		reg &= ~(0xf << (4 * index));
3280		if (value == LED_OFF)
3281			reg |= MII_88E1318S_PHY_LED_FUNC_OFF << (4 * index);
3282		else
3283			reg |= MII_88E1318S_PHY_LED_FUNC_ON << (4 * index);
3284		break;
3285	default:
3286		return -EINVAL;
3287	}
3288
3289	return phy_write_paged(phydev, MII_MARVELL_LED_PAGE,
3290			       MII_88E1318S_PHY_LED_FUNC, reg);
3291}
3292
3293static int m88e1318_led_blink_set(struct phy_device *phydev, u8 index,
3294				  unsigned long *delay_on,
3295				  unsigned long *delay_off)
3296{
3297	int reg;
3298
3299	reg = phy_read_paged(phydev, MII_MARVELL_LED_PAGE,
3300			     MII_88E1318S_PHY_LED_FUNC);
3301	if (reg < 0)
3302		return reg;
3303
3304	switch (index) {
3305	case 0:
3306	case 1:
3307	case 2:
3308		reg &= ~(0xf << (4 * index));
3309		reg |= MII_88E1318S_PHY_LED_FUNC_BLINK << (4 * index);
3310		/* Reset default is 84ms */
3311		*delay_on = 84 / 2;
3312		*delay_off = 84 / 2;
3313		break;
3314	default:
3315		return -EINVAL;
3316	}
3317
3318	return phy_write_paged(phydev, MII_MARVELL_LED_PAGE,
3319			       MII_88E1318S_PHY_LED_FUNC, reg);
3320}
3321
3322struct marvell_led_rules {
3323	int mode;
3324	unsigned long rules;
3325};
3326
3327static const struct marvell_led_rules marvell_led0[] = {
3328	{
3329		.mode = 0,
3330		.rules = BIT(TRIGGER_NETDEV_LINK),
3331	},
3332	{
3333		.mode = 1,
3334		.rules = (BIT(TRIGGER_NETDEV_LINK) |
3335			  BIT(TRIGGER_NETDEV_RX) |
3336			  BIT(TRIGGER_NETDEV_TX)),
3337	},
3338	{
3339		.mode = 3,
3340		.rules = (BIT(TRIGGER_NETDEV_RX) |
3341			  BIT(TRIGGER_NETDEV_TX)),
3342	},
3343	{
3344		.mode = 4,
3345		.rules = (BIT(TRIGGER_NETDEV_RX) |
3346			  BIT(TRIGGER_NETDEV_TX)),
3347	},
3348	{
3349		.mode = 5,
3350		.rules = BIT(TRIGGER_NETDEV_TX),
3351	},
3352	{
3353		.mode = 6,
3354		.rules = BIT(TRIGGER_NETDEV_LINK),
3355	},
3356	{
3357		.mode = 7,
3358		.rules = BIT(TRIGGER_NETDEV_LINK_1000),
3359	},
3360	{
3361		.mode = 8,
3362		.rules = 0,
3363	},
3364};
3365
3366static const struct marvell_led_rules marvell_led1[] = {
3367	{
3368		.mode = 1,
3369		.rules = (BIT(TRIGGER_NETDEV_LINK) |
3370			  BIT(TRIGGER_NETDEV_RX) |
3371			  BIT(TRIGGER_NETDEV_TX)),
3372	},
3373	{
3374		.mode = 2,
3375		.rules = (BIT(TRIGGER_NETDEV_LINK) |
3376			  BIT(TRIGGER_NETDEV_RX)),
3377	},
3378	{
3379		.mode = 3,
3380		.rules = (BIT(TRIGGER_NETDEV_RX) |
3381			  BIT(TRIGGER_NETDEV_TX)),
3382	},
3383	{
3384		.mode = 4,
3385		.rules = (BIT(TRIGGER_NETDEV_RX) |
3386			  BIT(TRIGGER_NETDEV_TX)),
3387	},
3388	{
3389		.mode = 6,
3390		.rules = (BIT(TRIGGER_NETDEV_LINK_100) |
3391			  BIT(TRIGGER_NETDEV_LINK_1000)),
3392	},
3393	{
3394		.mode = 7,
3395		.rules = BIT(TRIGGER_NETDEV_LINK_100),
3396	},
3397	{
3398		.mode = 8,
3399		.rules = 0,
3400	},
3401};
3402
3403static const struct marvell_led_rules marvell_led2[] = {
3404	{
3405		.mode = 0,
3406		.rules = BIT(TRIGGER_NETDEV_LINK),
3407	},
3408	{
3409		.mode = 1,
3410		.rules = (BIT(TRIGGER_NETDEV_LINK) |
3411			  BIT(TRIGGER_NETDEV_RX) |
3412			  BIT(TRIGGER_NETDEV_TX)),
3413	},
3414	{
3415		.mode = 3,
3416		.rules = (BIT(TRIGGER_NETDEV_RX) |
3417			  BIT(TRIGGER_NETDEV_TX)),
3418	},
3419	{
3420		.mode = 4,
3421		.rules = (BIT(TRIGGER_NETDEV_RX) |
3422			  BIT(TRIGGER_NETDEV_TX)),
3423	},
3424	{
3425		.mode = 5,
3426		.rules = BIT(TRIGGER_NETDEV_TX),
3427	},
3428	{
3429		.mode = 6,
3430		.rules = (BIT(TRIGGER_NETDEV_LINK_10) |
3431			  BIT(TRIGGER_NETDEV_LINK_1000)),
3432	},
3433	{
3434		.mode = 7,
3435		.rules = BIT(TRIGGER_NETDEV_LINK_10),
3436	},
3437	{
3438		.mode = 8,
3439		.rules = 0,
3440	},
3441};
3442
3443static int marvell_find_led_mode(unsigned long rules,
3444				 const struct marvell_led_rules *marvell_rules,
3445				 int count,
3446				 int *mode)
3447{
3448	int i;
3449
3450	for (i = 0; i < count; i++) {
3451		if (marvell_rules[i].rules == rules) {
3452			*mode = marvell_rules[i].mode;
3453			return 0;
3454		}
3455	}
3456	return -EOPNOTSUPP;
3457}
3458
3459static int marvell_get_led_mode(u8 index, unsigned long rules, int *mode)
3460{
3461	int ret;
3462
3463	switch (index) {
3464	case 0:
3465		ret = marvell_find_led_mode(rules, marvell_led0,
3466					    ARRAY_SIZE(marvell_led0), mode);
3467		break;
3468	case 1:
3469		ret = marvell_find_led_mode(rules, marvell_led1,
3470					    ARRAY_SIZE(marvell_led1), mode);
3471		break;
3472	case 2:
3473		ret = marvell_find_led_mode(rules, marvell_led2,
3474					    ARRAY_SIZE(marvell_led2), mode);
3475		break;
3476	default:
3477		ret = -EINVAL;
3478	}
3479
3480	return ret;
3481}
3482
3483static int marvell_find_led_rules(unsigned long *rules,
3484				  const struct marvell_led_rules *marvell_rules,
3485				  int count,
3486				  int mode)
3487{
3488	int i;
3489
3490	for (i = 0; i < count; i++) {
3491		if (marvell_rules[i].mode == mode) {
3492			*rules = marvell_rules[i].rules;
3493			return 0;
3494		}
3495	}
3496	return -EOPNOTSUPP;
3497}
3498
3499static int marvell_get_led_rules(u8 index, unsigned long *rules, int mode)
3500{
3501	int ret;
3502
3503	switch (index) {
3504	case 0:
3505		ret = marvell_find_led_rules(rules, marvell_led0,
3506					     ARRAY_SIZE(marvell_led0), mode);
3507		break;
3508	case 1:
3509		ret = marvell_find_led_rules(rules, marvell_led1,
3510					     ARRAY_SIZE(marvell_led1), mode);
3511		break;
3512	case 2:
3513		ret = marvell_find_led_rules(rules, marvell_led2,
3514					     ARRAY_SIZE(marvell_led2), mode);
3515		break;
3516	default:
3517		ret = -EOPNOTSUPP;
3518	}
3519
3520	return ret;
3521}
3522
3523static int m88e1318_led_hw_is_supported(struct phy_device *phydev, u8 index,
3524					unsigned long rules)
3525{
3526	int mode, ret;
3527
3528	switch (index) {
3529	case 0:
3530	case 1:
3531	case 2:
3532		ret = marvell_get_led_mode(index, rules, &mode);
3533		break;
3534	default:
3535		ret = -EINVAL;
3536	}
3537
3538	return ret;
3539}
3540
3541static int m88e1318_led_hw_control_set(struct phy_device *phydev, u8 index,
3542				       unsigned long rules)
3543{
3544	int mode, ret, reg;
3545
3546	switch (index) {
3547	case 0:
3548	case 1:
3549	case 2:
3550		ret = marvell_get_led_mode(index, rules, &mode);
3551		break;
3552	default:
3553		ret = -EINVAL;
3554	}
3555
3556	if (ret < 0)
3557		return ret;
3558
3559	reg = phy_read_paged(phydev, MII_MARVELL_LED_PAGE,
3560			     MII_88E1318S_PHY_LED_FUNC);
3561	if (reg < 0)
3562		return reg;
3563
3564	reg &= ~(0xf << (4 * index));
3565	reg |= mode << (4 * index);
3566	return phy_write_paged(phydev, MII_MARVELL_LED_PAGE,
3567			       MII_88E1318S_PHY_LED_FUNC, reg);
3568}
3569
3570static int m88e1318_led_hw_control_get(struct phy_device *phydev, u8 index,
3571				       unsigned long *rules)
3572{
3573	int mode, reg;
3574
3575	if (index > 2)
3576		return -EINVAL;
3577
3578	reg = phy_read_paged(phydev, MII_MARVELL_LED_PAGE,
3579			     MII_88E1318S_PHY_LED_FUNC);
3580	if (reg < 0)
3581		return reg;
3582
3583	mode = (reg >> (4 * index)) & 0xf;
3584
3585	return marvell_get_led_rules(index, rules, mode);
3586}
3587
3588static int marvell_probe(struct phy_device *phydev)
3589{
3590	struct marvell_priv *priv;
3591
3592	priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
3593	if (!priv)
3594		return -ENOMEM;
3595
3596	phydev->priv = priv;
3597
3598	return marvell_hwmon_probe(phydev);
3599}
3600
3601static int m88e1510_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
3602{
3603	struct phy_device *phydev = upstream;
3604	const struct sfp_module_caps *caps;
3605	phy_interface_t interface;
3606	struct device *dev;
3607	int oldpage;
3608	int ret = 0;
3609	u16 mode;
3610
3611	dev = &phydev->mdio.dev;
3612
3613	caps = sfp_get_module_caps(phydev->sfp_bus);
3614	interface = sfp_select_interface(phydev->sfp_bus, caps->link_modes);
3615
3616	dev_info(dev, "%s SFP module inserted\n", phy_modes(interface));
3617
3618	switch (interface) {
3619	case PHY_INTERFACE_MODE_1000BASEX:
3620		mode = MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII_1000X;
3621
3622		break;
3623	case PHY_INTERFACE_MODE_100BASEX:
3624		mode = MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII_100FX;
3625
3626		break;
3627	case PHY_INTERFACE_MODE_SGMII:
3628		mode = MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII_SGMII;
3629
3630		break;
3631	default:
3632		dev_err(dev, "Incompatible SFP module inserted\n");
3633
3634		return -EINVAL;
3635	}
3636
3637	oldpage = phy_select_page(phydev, MII_MARVELL_MODE_PAGE);
3638	if (oldpage < 0)
3639		goto error;
3640
3641	ret = __phy_modify(phydev, MII_88E1510_GEN_CTRL_REG_1,
3642			   MII_88E1510_GEN_CTRL_REG_1_MODE_MASK, mode);
3643	if (ret < 0)
3644		goto error;
3645
3646	ret = __phy_set_bits(phydev, MII_88E1510_GEN_CTRL_REG_1,
3647			     MII_88E1510_GEN_CTRL_REG_1_RESET);
3648
3649error:
3650	return phy_restore_page(phydev, oldpage, ret);
3651}
3652
3653static void m88e1510_sfp_remove(void *upstream)
3654{
3655	struct phy_device *phydev = upstream;
3656	int oldpage;
3657	int ret = 0;
3658
3659	oldpage = phy_select_page(phydev, MII_MARVELL_MODE_PAGE);
3660	if (oldpage < 0)
3661		goto error;
3662
3663	ret = __phy_modify(phydev, MII_88E1510_GEN_CTRL_REG_1,
3664			   MII_88E1510_GEN_CTRL_REG_1_MODE_MASK,
3665			   MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII);
3666	if (ret < 0)
3667		goto error;
3668
3669	ret = __phy_set_bits(phydev, MII_88E1510_GEN_CTRL_REG_1,
3670			     MII_88E1510_GEN_CTRL_REG_1_RESET);
3671
3672error:
3673	phy_restore_page(phydev, oldpage, ret);
3674}
3675
3676static const struct sfp_upstream_ops m88e1510_sfp_ops = {
3677	.module_insert = m88e1510_sfp_insert,
3678	.module_remove = m88e1510_sfp_remove,
3679	.attach = phy_sfp_attach,
3680	.detach = phy_sfp_detach,
3681	.connect_phy = phy_sfp_connect_phy,
3682	.disconnect_phy = phy_sfp_disconnect_phy,
3683};
3684
3685static int m88e1510_probe(struct phy_device *phydev)
3686{
3687	int err;
3688
3689	err = marvell_probe(phydev);
3690	if (err)
3691		return err;
3692
3693	return phy_sfp_probe(phydev, &m88e1510_sfp_ops);
3694}
3695
3696static struct phy_driver marvell_drivers[] = {
3697	{
3698		.phy_id = MARVELL_PHY_ID_88E1101,
3699		.phy_id_mask = MARVELL_PHY_ID_MASK,
3700		.name = "Marvell 88E1101",
3701		/* PHY_GBIT_FEATURES */
3702		.probe = marvell_probe,
3703		.config_init = marvell_config_init,
3704		.config_aneg = m88e1101_config_aneg,
3705		.config_intr = marvell_config_intr,
3706		.handle_interrupt = marvell_handle_interrupt,
3707		.resume = genphy_resume,
3708		.suspend = genphy_suspend,
3709		.read_page = marvell_read_page,
3710		.write_page = marvell_write_page,
3711		.get_sset_count = marvell_get_sset_count,
3712		.get_strings = marvell_get_strings,
3713		.get_stats = marvell_get_stats,
3714	},
3715	{
3716		.phy_id = MARVELL_PHY_ID_88E3082,
3717		.phy_id_mask = MARVELL_PHY_ID_MASK,
3718		.name = "Marvell 88E308X/88E609X Family",
3719		/* PHY_BASIC_FEATURES */
3720		.probe = marvell_probe,
3721		.config_init = marvell_config_init,
3722		.aneg_done = marvell_aneg_done,
3723		.read_status = marvell_read_status,
3724		.resume = genphy_resume,
3725		.suspend = genphy_suspend,
3726		.cable_test_start = m88e3082_vct_cable_test_start,
3727		.cable_test_get_status = m88e3082_vct_cable_test_get_status,
3728	},
3729	{
3730		.phy_id = MARVELL_PHY_ID_88E1112,
3731		.phy_id_mask = MARVELL_PHY_ID_MASK,
3732		.name = "Marvell 88E1112",
3733		/* PHY_GBIT_FEATURES */
3734		.probe = marvell_probe,
3735		.inband_caps = m88e1111_inband_caps,
3736		.config_inband = m88e1111_config_inband,
3737		.config_init = m88e1112_config_init,
3738		.config_aneg = marvell_config_aneg,
3739		.config_intr = marvell_config_intr,
3740		.handle_interrupt = marvell_handle_interrupt,
3741		.resume = genphy_resume,
3742		.suspend = genphy_suspend,
3743		.read_page = marvell_read_page,
3744		.write_page = marvell_write_page,
3745		.get_sset_count = marvell_get_sset_count,
3746		.get_strings = marvell_get_strings,
3747		.get_stats = marvell_get_stats,
3748		.get_tunable = m88e1011_get_tunable,
3749		.set_tunable = m88e1011_set_tunable,
3750	},
3751	{
3752		.phy_id = MARVELL_PHY_ID_88E1111,
3753		.phy_id_mask = MARVELL_PHY_ID_MASK,
3754		.name = "Marvell 88E1111",
3755		/* PHY_GBIT_FEATURES */
3756		.flags = PHY_POLL_CABLE_TEST,
3757		.probe = marvell_probe,
3758		.inband_caps = m88e1111_inband_caps,
3759		.config_inband = m88e1111_config_inband,
3760		.config_init = m88e1111gbe_config_init,
3761		.config_aneg = m88e1111_config_aneg,
3762		.read_status = marvell_read_status,
3763		.config_intr = marvell_config_intr,
3764		.handle_interrupt = marvell_handle_interrupt,
3765		.resume = genphy_resume,
3766		.suspend = genphy_suspend,
3767		.read_page = marvell_read_page,
3768		.write_page = marvell_write_page,
3769		.get_sset_count = marvell_get_sset_count,
3770		.get_strings = marvell_get_strings,
3771		.get_stats = marvell_get_stats,
3772		.get_tunable = m88e1111_get_tunable,
3773		.set_tunable = m88e1111_set_tunable,
3774		.cable_test_start = m88e1111_vct_cable_test_start,
3775		.cable_test_get_status = m88e1111_vct_cable_test_get_status,
3776	},
3777	{
3778		.phy_id = MARVELL_PHY_ID_88E1111_FINISAR,
3779		.phy_id_mask = MARVELL_PHY_ID_MASK,
3780		.name = "Marvell 88E1111 (Finisar)",
3781		/* PHY_GBIT_FEATURES */
3782		.probe = marvell_probe,
3783		.inband_caps = m88e1111_inband_caps,
3784		.config_inband = m88e1111_config_inband,
3785		.config_init = m88e1111gbe_config_init,
3786		.config_aneg = m88e1111_config_aneg,
3787		.read_status = marvell_read_status,
3788		.config_intr = marvell_config_intr,
3789		.handle_interrupt = marvell_handle_interrupt,
3790		.resume = genphy_resume,
3791		.suspend = genphy_suspend,
3792		.read_page = marvell_read_page,
3793		.write_page = marvell_write_page,
3794		.get_sset_count = marvell_get_sset_count,
3795		.get_strings = marvell_get_strings,
3796		.get_stats = marvell_get_stats,
3797		.get_tunable = m88e1111_get_tunable,
3798		.set_tunable = m88e1111_set_tunable,
3799	},
3800	{
3801		.phy_id = MARVELL_PHY_ID_88E1118,
3802		.phy_id_mask = MARVELL_PHY_ID_MASK,
3803		.name = "Marvell 88E1118",
3804		/* PHY_GBIT_FEATURES */
3805		.probe = marvell_probe,
3806		.config_init = m88e1118_config_init,
3807		.config_aneg = m88e1118_config_aneg,
3808		.config_intr = marvell_config_intr,
3809		.handle_interrupt = marvell_handle_interrupt,
3810		.resume = genphy_resume,
3811		.suspend = genphy_suspend,
3812		.read_page = marvell_read_page,
3813		.write_page = marvell_write_page,
3814		.get_sset_count = marvell_get_sset_count,
3815		.get_strings = marvell_get_strings,
3816		.get_stats = marvell_get_stats,
3817	},
3818	{
3819		.phy_id = MARVELL_PHY_ID_88E1121R,
3820		.phy_id_mask = MARVELL_PHY_ID_MASK,
3821		.name = "Marvell 88E1121R",
3822		.driver_data = DEF_MARVELL_HWMON_OPS(m88e1121_hwmon_ops),
3823		/* PHY_GBIT_FEATURES */
3824		.probe = marvell_probe,
3825		.config_init = marvell_1011gbe_config_init,
3826		.config_aneg = m88e1121_config_aneg,
3827		.read_status = marvell_read_status,
3828		.config_intr = marvell_config_intr,
3829		.handle_interrupt = marvell_handle_interrupt,
3830		.resume = genphy_resume,
3831		.suspend = genphy_suspend,
3832		.read_page = marvell_read_page,
3833		.write_page = marvell_write_page,
3834		.get_sset_count = marvell_get_sset_count,
3835		.get_strings = marvell_get_strings,
3836		.get_stats = marvell_get_stats,
3837		.get_tunable = m88e1011_get_tunable,
3838		.set_tunable = m88e1011_set_tunable,
3839	},
3840	{
3841		.phy_id = MARVELL_PHY_ID_88E1318S,
3842		.phy_id_mask = MARVELL_PHY_ID_MASK,
3843		.name = "Marvell 88E1318S",
3844		/* PHY_GBIT_FEATURES */
3845		.probe = marvell_probe,
3846		.config_init = m88e1318_config_init,
3847		.config_aneg = m88e1318_config_aneg,
3848		.read_status = marvell_read_status,
3849		.config_intr = marvell_config_intr,
3850		.handle_interrupt = marvell_handle_interrupt,
3851		.get_wol = m88e1318_get_wol,
3852		.set_wol = m88e1318_set_wol,
3853		.resume = genphy_resume,
3854		.suspend = genphy_suspend,
3855		.read_page = marvell_read_page,
3856		.write_page = marvell_write_page,
3857		.get_sset_count = marvell_get_sset_count,
3858		.get_strings = marvell_get_strings,
3859		.get_stats = marvell_get_stats,
3860		.led_brightness_set = m88e1318_led_brightness_set,
3861		.led_blink_set = m88e1318_led_blink_set,
3862		.led_hw_is_supported = m88e1318_led_hw_is_supported,
3863		.led_hw_control_set = m88e1318_led_hw_control_set,
3864		.led_hw_control_get = m88e1318_led_hw_control_get,
3865	},
3866	{
3867		.phy_id = MARVELL_PHY_ID_88E1145,
3868		.phy_id_mask = MARVELL_PHY_ID_MASK,
3869		.name = "Marvell 88E1145",
3870		/* PHY_GBIT_FEATURES */
3871		.flags = PHY_POLL_CABLE_TEST,
3872		.probe = marvell_probe,
3873		.config_init = m88e1145_config_init,
3874		.config_aneg = m88e1101_config_aneg,
3875		.config_intr = marvell_config_intr,
3876		.handle_interrupt = marvell_handle_interrupt,
3877		.resume = genphy_resume,
3878		.suspend = genphy_suspend,
3879		.read_page = marvell_read_page,
3880		.write_page = marvell_write_page,
3881		.get_sset_count = marvell_get_sset_count,
3882		.get_strings = marvell_get_strings,
3883		.get_stats = marvell_get_stats,
3884		.get_tunable = m88e1111_get_tunable,
3885		.set_tunable = m88e1111_set_tunable,
3886		.cable_test_start = m88e1111_vct_cable_test_start,
3887		.cable_test_get_status = m88e1111_vct_cable_test_get_status,
3888	},
3889	{
3890		.phy_id = MARVELL_PHY_ID_88E1149R,
3891		.phy_id_mask = MARVELL_PHY_ID_MASK,
3892		.name = "Marvell 88E1149R",
3893		/* PHY_GBIT_FEATURES */
3894		.probe = marvell_probe,
3895		.config_init = m88e1149_config_init,
3896		.config_aneg = m88e1118_config_aneg,
3897		.config_intr = marvell_config_intr,
3898		.handle_interrupt = marvell_handle_interrupt,
3899		.resume = genphy_resume,
3900		.suspend = genphy_suspend,
3901		.read_page = marvell_read_page,
3902		.write_page = marvell_write_page,
3903		.get_sset_count = marvell_get_sset_count,
3904		.get_strings = marvell_get_strings,
3905		.get_stats = marvell_get_stats,
3906	},
3907	{
3908		.phy_id = MARVELL_PHY_ID_88E1240,
3909		.phy_id_mask = MARVELL_PHY_ID_MASK,
3910		.name = "Marvell 88E1240",
3911		/* PHY_GBIT_FEATURES */
3912		.probe = marvell_probe,
3913		.config_init = m88e1112_config_init,
3914		.config_aneg = marvell_config_aneg,
3915		.config_intr = marvell_config_intr,
3916		.handle_interrupt = marvell_handle_interrupt,
3917		.resume = genphy_resume,
3918		.suspend = genphy_suspend,
3919		.read_page = marvell_read_page,
3920		.write_page = marvell_write_page,
3921		.get_sset_count = marvell_get_sset_count,
3922		.get_strings = marvell_get_strings,
3923		.get_stats = marvell_get_stats,
3924		.get_tunable = m88e1011_get_tunable,
3925		.set_tunable = m88e1011_set_tunable,
3926	},
3927	{
3928		.phy_id = MARVELL_PHY_ID_88E1116R,
3929		.phy_id_mask = MARVELL_PHY_ID_MASK,
3930		.name = "Marvell 88E1116R",
3931		/* PHY_GBIT_FEATURES */
3932		.probe = marvell_probe,
3933		.config_init = m88e1116r_config_init,
3934		.config_intr = marvell_config_intr,
3935		.handle_interrupt = marvell_handle_interrupt,
3936		.resume = genphy_resume,
3937		.suspend = genphy_suspend,
3938		.read_page = marvell_read_page,
3939		.write_page = marvell_write_page,
3940		.get_sset_count = marvell_get_sset_count,
3941		.get_strings = marvell_get_strings,
3942		.get_stats = marvell_get_stats,
3943		.get_tunable = m88e1011_get_tunable,
3944		.set_tunable = m88e1011_set_tunable,
3945	},
3946	{
3947		.phy_id = MARVELL_PHY_ID_88E1510,
3948		.phy_id_mask = MARVELL_PHY_ID_MASK,
3949		.name = "Marvell 88E1510",
3950		.driver_data = DEF_MARVELL_HWMON_OPS(m88e1510_hwmon_ops),
3951		.features = PHY_GBIT_FIBRE_FEATURES,
3952		.flags = PHY_POLL_CABLE_TEST,
3953		.probe = m88e1510_probe,
3954		.config_init = m88e1510_config_init,
3955		.config_aneg = m88e1510_config_aneg,
3956		.read_status = marvell_read_status,
3957		.config_intr = marvell_config_intr,
3958		.handle_interrupt = marvell_handle_interrupt,
3959		.get_wol = m88e1318_get_wol,
3960		.set_wol = m88e1318_set_wol,
3961		.resume = m88e1510_resume,
3962		.suspend = marvell_suspend,
3963		.read_page = marvell_read_page,
3964		.write_page = marvell_write_page,
3965		.get_sset_count = marvell_get_sset_count,
3966		.get_strings = marvell_get_strings,
3967		.get_stats = marvell_get_stats,
3968		.set_loopback = m88e1510_loopback,
3969		.get_tunable = m88e1011_get_tunable,
3970		.set_tunable = m88e1011_set_tunable,
3971		.cable_test_start = marvell_vct7_cable_test_start,
3972		.cable_test_tdr_start = marvell_vct5_cable_test_tdr_start,
3973		.cable_test_get_status = marvell_vct7_cable_test_get_status,
3974		.led_brightness_set = m88e1318_led_brightness_set,
3975		.led_blink_set = m88e1318_led_blink_set,
3976		.led_hw_is_supported = m88e1318_led_hw_is_supported,
3977		.led_hw_control_set = m88e1318_led_hw_control_set,
3978		.led_hw_control_get = m88e1318_led_hw_control_get,
3979	},
3980	{
3981		.phy_id = MARVELL_PHY_ID_88E1540,
3982		.phy_id_mask = MARVELL_PHY_ID_MASK,
3983		.name = "Marvell 88E1540",
3984		.driver_data = DEF_MARVELL_HWMON_OPS(m88e1510_hwmon_ops),
3985		/* PHY_GBIT_FEATURES */
3986		.flags = PHY_POLL_CABLE_TEST,
3987		.probe = marvell_probe,
3988		.config_init = marvell_1011gbe_config_init,
3989		.config_aneg = m88e1510_config_aneg,
3990		.read_status = marvell_read_status,
3991		.config_intr = marvell_config_intr,
3992		.handle_interrupt = marvell_handle_interrupt,
3993		.resume = genphy_resume,
3994		.suspend = genphy_suspend,
3995		.read_page = marvell_read_page,
3996		.write_page = marvell_write_page,
3997		.get_sset_count = marvell_get_sset_count,
3998		.get_strings = marvell_get_strings,
3999		.get_stats = marvell_get_stats,
4000		.get_tunable = m88e1540_get_tunable,
4001		.set_tunable = m88e1540_set_tunable,
4002		.cable_test_start = marvell_vct7_cable_test_start,
4003		.cable_test_tdr_start = marvell_vct5_cable_test_tdr_start,
4004		.cable_test_get_status = marvell_vct7_cable_test_get_status,
4005		.led_brightness_set = m88e1318_led_brightness_set,
4006		.led_blink_set = m88e1318_led_blink_set,
4007		.led_hw_is_supported = m88e1318_led_hw_is_supported,
4008		.led_hw_control_set = m88e1318_led_hw_control_set,
4009		.led_hw_control_get = m88e1318_led_hw_control_get,
4010	},
4011	{
4012		.phy_id = MARVELL_PHY_ID_88E1545,
4013		.phy_id_mask = MARVELL_PHY_ID_MASK,
4014		.name = "Marvell 88E1545",
4015		.driver_data = DEF_MARVELL_HWMON_OPS(m88e1510_hwmon_ops),
4016		.probe = marvell_probe,
4017		/* PHY_GBIT_FEATURES */
4018		.flags = PHY_POLL_CABLE_TEST,
4019		.config_init = marvell_1011gbe_config_init,
4020		.config_aneg = m88e1510_config_aneg,
4021		.read_status = marvell_read_status,
4022		.config_intr = marvell_config_intr,
4023		.handle_interrupt = marvell_handle_interrupt,
4024		.resume = genphy_resume,
4025		.suspend = genphy_suspend,
4026		.read_page = marvell_read_page,
4027		.write_page = marvell_write_page,
4028		.get_sset_count = marvell_get_sset_count,
4029		.get_strings = marvell_get_strings,
4030		.get_stats = marvell_get_stats,
4031		.get_tunable = m88e1540_get_tunable,
4032		.set_tunable = m88e1540_set_tunable,
4033		.cable_test_start = marvell_vct7_cable_test_start,
4034		.cable_test_tdr_start = marvell_vct5_cable_test_tdr_start,
4035		.cable_test_get_status = marvell_vct7_cable_test_get_status,
4036		.led_brightness_set = m88e1318_led_brightness_set,
4037		.led_blink_set = m88e1318_led_blink_set,
4038		.led_hw_is_supported = m88e1318_led_hw_is_supported,
4039		.led_hw_control_set = m88e1318_led_hw_control_set,
4040		.led_hw_control_get = m88e1318_led_hw_control_get,
4041	},
4042	{
4043		.phy_id = MARVELL_PHY_ID_88E3016,
4044		.phy_id_mask = MARVELL_PHY_ID_MASK,
4045		.name = "Marvell 88E3016",
4046		/* PHY_BASIC_FEATURES */
4047		.probe = marvell_probe,
4048		.config_init = m88e3016_config_init,
4049		.aneg_done = marvell_aneg_done,
4050		.read_status = marvell_read_status,
4051		.config_intr = marvell_config_intr,
4052		.handle_interrupt = marvell_handle_interrupt,
4053		.resume = genphy_resume,
4054		.suspend = genphy_suspend,
4055		.read_page = marvell_read_page,
4056		.write_page = marvell_write_page,
4057		.get_sset_count = marvell_get_sset_count,
4058		.get_strings = marvell_get_strings,
4059		.get_stats = marvell_get_stats,
4060	},
4061	{
4062		.phy_id = MARVELL_PHY_ID_88E6250_FAMILY,
4063		.phy_id_mask = MARVELL_PHY_ID_MASK,
4064		.name = "Marvell 88E6250 Family",
4065		/* PHY_BASIC_FEATURES */
4066		.probe = marvell_probe,
4067		.aneg_done = marvell_aneg_done,
4068		.config_intr = marvell_config_intr,
4069		.handle_interrupt = marvell_handle_interrupt,
4070		.resume = genphy_resume,
4071		.suspend = genphy_suspend,
4072		.get_sset_count = marvell_get_sset_count_simple,
4073		.get_strings = marvell_get_strings_simple,
4074		.get_stats = marvell_get_stats_simple,
4075	},
4076	{
4077		.phy_id = MARVELL_PHY_ID_88E6341_FAMILY,
4078		.phy_id_mask = MARVELL_PHY_ID_MASK,
4079		.name = "Marvell 88E6341 Family",
4080		.driver_data = DEF_MARVELL_HWMON_OPS(m88e1510_hwmon_ops),
4081		/* PHY_GBIT_FEATURES */
4082		.flags = PHY_POLL_CABLE_TEST,
4083		.probe = marvell_probe,
4084		.config_init = marvell_1011gbe_config_init,
4085		.config_aneg = m88e6390_config_aneg,
4086		.read_status = marvell_read_status,
4087		.config_intr = marvell_config_intr,
4088		.handle_interrupt = marvell_handle_interrupt,
4089		.resume = genphy_resume,
4090		.suspend = genphy_suspend,
4091		.read_page = marvell_read_page,
4092		.write_page = marvell_write_page,
4093		.get_sset_count = marvell_get_sset_count,
4094		.get_strings = marvell_get_strings,
4095		.get_stats = marvell_get_stats,
4096		.get_tunable = m88e1540_get_tunable,
4097		.set_tunable = m88e1540_set_tunable,
4098		.cable_test_start = marvell_vct7_cable_test_start,
4099		.cable_test_tdr_start = marvell_vct5_cable_test_tdr_start,
4100		.cable_test_get_status = marvell_vct7_cable_test_get_status,
4101	},
4102	{
4103		.phy_id = MARVELL_PHY_ID_88E6390_FAMILY,
4104		.phy_id_mask = MARVELL_PHY_ID_MASK,
4105		.name = "Marvell 88E6390 Family",
4106		.driver_data = DEF_MARVELL_HWMON_OPS(m88e6390_hwmon_ops),
4107		/* PHY_GBIT_FEATURES */
4108		.flags = PHY_POLL_CABLE_TEST,
4109		.probe = marvell_probe,
4110		.config_init = marvell_1011gbe_config_init,
4111		.config_aneg = m88e6390_config_aneg,
4112		.read_status = marvell_read_status,
4113		.config_intr = marvell_config_intr,
4114		.handle_interrupt = marvell_handle_interrupt,
4115		.resume = genphy_resume,
4116		.suspend = genphy_suspend,
4117		.read_page = marvell_read_page,
4118		.write_page = marvell_write_page,
4119		.get_sset_count = marvell_get_sset_count,
4120		.get_strings = marvell_get_strings,
4121		.get_stats = marvell_get_stats,
4122		.get_tunable = m88e1540_get_tunable,
4123		.set_tunable = m88e1540_set_tunable,
4124		.cable_test_start = marvell_vct7_cable_test_start,
4125		.cable_test_tdr_start = marvell_vct5_cable_test_tdr_start,
4126		.cable_test_get_status = marvell_vct7_cable_test_get_status,
4127	},
4128	{
4129		.phy_id = MARVELL_PHY_ID_88E6393_FAMILY,
4130		.phy_id_mask = MARVELL_PHY_ID_MASK,
4131		.name = "Marvell 88E6393 Family",
4132		.driver_data = DEF_MARVELL_HWMON_OPS(m88e6393_hwmon_ops),
4133		/* PHY_GBIT_FEATURES */
4134		.flags = PHY_POLL_CABLE_TEST,
4135		.probe = marvell_probe,
4136		.config_init = marvell_1011gbe_config_init,
4137		.config_aneg = m88e1510_config_aneg,
4138		.read_status = marvell_read_status,
4139		.config_intr = marvell_config_intr,
4140		.handle_interrupt = marvell_handle_interrupt,
4141		.resume = genphy_resume,
4142		.suspend = genphy_suspend,
4143		.read_page = marvell_read_page,
4144		.write_page = marvell_write_page,
4145		.get_sset_count = marvell_get_sset_count,
4146		.get_strings = marvell_get_strings,
4147		.get_stats = marvell_get_stats,
4148		.get_tunable = m88e1540_get_tunable,
4149		.set_tunable = m88e1540_set_tunable,
4150		.cable_test_start = marvell_vct7_cable_test_start,
4151		.cable_test_tdr_start = marvell_vct5_cable_test_tdr_start,
4152		.cable_test_get_status = marvell_vct7_cable_test_get_status,
4153	},
4154	{
4155		.phy_id = MARVELL_PHY_ID_88E1340S,
4156		.phy_id_mask = MARVELL_PHY_ID_MASK,
4157		.name = "Marvell 88E1340S",
4158		.driver_data = DEF_MARVELL_HWMON_OPS(m88e1510_hwmon_ops),
4159		.probe = marvell_probe,
4160		/* PHY_GBIT_FEATURES */
4161		.config_init = marvell_1011gbe_config_init,
4162		.config_aneg = m88e1510_config_aneg,
4163		.read_status = marvell_read_status,
4164		.config_intr = marvell_config_intr,
4165		.handle_interrupt = marvell_handle_interrupt,
4166		.resume = genphy_resume,
4167		.suspend = genphy_suspend,
4168		.read_page = marvell_read_page,
4169		.write_page = marvell_write_page,
4170		.get_sset_count = marvell_get_sset_count,
4171		.get_strings = marvell_get_strings,
4172		.get_stats = marvell_get_stats,
4173		.get_tunable = m88e1540_get_tunable,
4174		.set_tunable = m88e1540_set_tunable,
4175	},
4176	{
4177		.phy_id = MARVELL_PHY_ID_88E1548P,
4178		.phy_id_mask = MARVELL_PHY_ID_MASK,
4179		.name = "Marvell 88E1548P",
4180		.driver_data = DEF_MARVELL_HWMON_OPS(m88e1510_hwmon_ops),
4181		.probe = marvell_probe,
4182		.features = PHY_GBIT_FIBRE_FEATURES,
4183		.config_init = marvell_1011gbe_config_init,
4184		.config_aneg = m88e1510_config_aneg,
4185		.read_status = marvell_read_status,
4186		.config_intr = marvell_config_intr,
4187		.handle_interrupt = marvell_handle_interrupt,
4188		.resume = genphy_resume,
4189		.suspend = genphy_suspend,
4190		.read_page = marvell_read_page,
4191		.write_page = marvell_write_page,
4192		.get_sset_count = marvell_get_sset_count,
4193		.get_strings = marvell_get_strings,
4194		.get_stats = marvell_get_stats,
4195		.get_tunable = m88e1540_get_tunable,
4196		.set_tunable = m88e1540_set_tunable,
4197		.led_brightness_set = m88e1318_led_brightness_set,
4198		.led_blink_set = m88e1318_led_blink_set,
4199		.led_hw_is_supported = m88e1318_led_hw_is_supported,
4200		.led_hw_control_set = m88e1318_led_hw_control_set,
4201		.led_hw_control_get = m88e1318_led_hw_control_get,
4202	},
4203};
4204
4205module_phy_driver(marvell_drivers);
4206
4207static const struct mdio_device_id __maybe_unused marvell_tbl[] = {
4208	{ MARVELL_PHY_ID_88E1101, MARVELL_PHY_ID_MASK },
4209	{ MARVELL_PHY_ID_88E3082, MARVELL_PHY_ID_MASK },
4210	{ MARVELL_PHY_ID_88E1112, MARVELL_PHY_ID_MASK },
4211	{ MARVELL_PHY_ID_88E1111, MARVELL_PHY_ID_MASK },
4212	{ MARVELL_PHY_ID_88E1111_FINISAR, MARVELL_PHY_ID_MASK },
4213	{ MARVELL_PHY_ID_88E1118, MARVELL_PHY_ID_MASK },
4214	{ MARVELL_PHY_ID_88E1121R, MARVELL_PHY_ID_MASK },
4215	{ MARVELL_PHY_ID_88E1145, MARVELL_PHY_ID_MASK },
4216	{ MARVELL_PHY_ID_88E1149R, MARVELL_PHY_ID_MASK },
4217	{ MARVELL_PHY_ID_88E1240, MARVELL_PHY_ID_MASK },
4218	{ MARVELL_PHY_ID_88E1318S, MARVELL_PHY_ID_MASK },
4219	{ MARVELL_PHY_ID_88E1116R, MARVELL_PHY_ID_MASK },
4220	{ MARVELL_PHY_ID_88E1510, MARVELL_PHY_ID_MASK },
4221	{ MARVELL_PHY_ID_88E1540, MARVELL_PHY_ID_MASK },
4222	{ MARVELL_PHY_ID_88E1545, MARVELL_PHY_ID_MASK },
4223	{ MARVELL_PHY_ID_88E3016, MARVELL_PHY_ID_MASK },
4224	{ MARVELL_PHY_ID_88E6250_FAMILY, MARVELL_PHY_ID_MASK },
4225	{ MARVELL_PHY_ID_88E6341_FAMILY, MARVELL_PHY_ID_MASK },
4226	{ MARVELL_PHY_ID_88E6390_FAMILY, MARVELL_PHY_ID_MASK },
4227	{ MARVELL_PHY_ID_88E6393_FAMILY, MARVELL_PHY_ID_MASK },
4228	{ MARVELL_PHY_ID_88E1340S, MARVELL_PHY_ID_MASK },
4229	{ MARVELL_PHY_ID_88E1548P, MARVELL_PHY_ID_MASK },
4230	{ }
4231};
4232
4233MODULE_DEVICE_TABLE(mdio, marvell_tbl);
~/ Read-only file preview.