File Index
Files and directories
Sign in
FILE

mxl-gpy.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/phy/mxl-gpy.c C
   1// SPDX-License-Identifier: GPL-2.0+
   2/* Copyright (C) 2021 Maxlinear Corporation
   3 * Copyright (C) 2020 Intel Corporation
   4 *
   5 * Drivers for Maxlinear Ethernet GPY
   6 *
   7 */
   8
   9#include <linux/module.h>
  10#include <linux/bitfield.h>
  11#include <linux/hwmon.h>
  12#include <linux/mutex.h>
  13#include <linux/phy.h>
  14#include <linux/polynomial.h>
  15#include <linux/property.h>
  16#include <linux/netdevice.h>
  17
  18/* PHY ID */
  19#define PHY_ID_GPYx15B_MASK	0xFFFFFFFC
  20#define PHY_ID_GPY21xB_MASK	0xFFFFFFF9
  21#define PHY_ID_GPY2xx		0x67C9DC00
  22#define PHY_ID_GPY115B		0x67C9DF00
  23#define PHY_ID_GPY115C		0x67C9DF10
  24#define PHY_ID_GPY211B		0x67C9DE08
  25#define PHY_ID_GPY211C		0x67C9DE10
  26#define PHY_ID_GPY212B		0x67C9DE09
  27#define PHY_ID_GPY212C		0x67C9DE20
  28#define PHY_ID_GPY215B		0x67C9DF04
  29#define PHY_ID_GPY215C		0x67C9DF20
  30#define PHY_ID_GPY241B		0x67C9DE40
  31#define PHY_ID_GPY241BM		0x67C9DE80
  32#define PHY_ID_GPY245B		0x67C9DEC0
  33#define PHY_ID_MXL86211C	0xC1335400
  34#define PHY_ID_MXL86252		0xC1335520
  35#define PHY_ID_MXL86282		0xC1335500
  36
  37#define PHY_CTL1		0x13
  38#define PHY_CTL1_MDICD		BIT(3)
  39#define PHY_CTL1_MDIAB		BIT(2)
  40#define PHY_CTL1_AMDIX		BIT(0)
  41#define PHY_MIISTAT		0x18	/* MII state */
  42#define PHY_IMASK		0x19	/* interrupt mask */
  43#define PHY_ISTAT		0x1A	/* interrupt status */
  44#define PHY_LED			0x1B	/* LEDs */
  45#define PHY_FWV			0x1E	/* firmware version */
  46
  47#define PHY_MIISTAT_SPD_MASK	GENMASK(2, 0)
  48#define PHY_MIISTAT_DPX		BIT(3)
  49#define PHY_MIISTAT_LS		BIT(10)
  50
  51#define PHY_MIISTAT_SPD_10	0
  52#define PHY_MIISTAT_SPD_100	1
  53#define PHY_MIISTAT_SPD_1000	2
  54#define PHY_MIISTAT_SPD_2500	4
  55
  56#define PHY_IMASK_WOL		BIT(15)	/* Wake-on-LAN */
  57#define PHY_IMASK_ANC		BIT(10)	/* Auto-Neg complete */
  58#define PHY_IMASK_ADSC		BIT(5)	/* Link auto-downspeed detect */
  59#define PHY_IMASK_DXMC		BIT(2)	/* Duplex mode change */
  60#define PHY_IMASK_LSPC		BIT(1)	/* Link speed change */
  61#define PHY_IMASK_LSTC		BIT(0)	/* Link state change */
  62#define PHY_IMASK_MASK		(PHY_IMASK_LSTC | \
  63				 PHY_IMASK_LSPC | \
  64				 PHY_IMASK_DXMC | \
  65				 PHY_IMASK_ADSC | \
  66				 PHY_IMASK_ANC)
  67
  68#define GPY_MAX_LEDS		4
  69#define PHY_LED_POLARITY(idx)	BIT(12 + (idx))
  70#define PHY_LED_HWCONTROL(idx)	BIT(8 + (idx))
  71#define PHY_LED_ON(idx)		BIT(idx)
  72
  73#define PHY_FWV_REL_MASK	BIT(15)
  74#define PHY_FWV_MAJOR_MASK	GENMASK(11, 8)
  75#define PHY_FWV_MINOR_MASK	GENMASK(7, 0)
  76
  77#define PHY_PMA_MGBT_POLARITY	0x82
  78#define PHY_MDI_MDI_X_MASK	GENMASK(1, 0)
  79#define PHY_MDI_MDI_X_NORMAL	0x3
  80#define PHY_MDI_MDI_X_AB	0x2
  81#define PHY_MDI_MDI_X_CD	0x1
  82#define PHY_MDI_MDI_X_CROSS	0x0
  83
  84/* LED */
  85#define VSPEC1_LED(idx)		(1 + (idx))
  86#define VSPEC1_LED_BLINKS	GENMASK(15, 12)
  87#define VSPEC1_LED_PULSE	GENMASK(11, 8)
  88#define VSPEC1_LED_CON		GENMASK(7, 4)
  89#define VSPEC1_LED_BLINKF	GENMASK(3, 0)
  90
  91#define VSPEC1_LED_LINK10	BIT(0)
  92#define VSPEC1_LED_LINK100	BIT(1)
  93#define VSPEC1_LED_LINK1000	BIT(2)
  94#define VSPEC1_LED_LINK2500	BIT(3)
  95
  96#define VSPEC1_LED_TXACT	BIT(0)
  97#define VSPEC1_LED_RXACT	BIT(1)
  98#define VSPEC1_LED_COL		BIT(2)
  99#define VSPEC1_LED_NO_CON	BIT(3)
 100
 101/* SGMII */
 102#define VSPEC1_SGMII_CTRL	0x08
 103#define VSPEC1_SGMII_CTRL_ANEN	BIT(12)		/* Aneg enable */
 104#define VSPEC1_SGMII_CTRL_ANRS	BIT(9)		/* Restart Aneg */
 105#define VSPEC1_SGMII_ANEN_ANRS	(VSPEC1_SGMII_CTRL_ANEN | \
 106				 VSPEC1_SGMII_CTRL_ANRS)
 107
 108/* Temperature sensor */
 109#define VSPEC1_TEMP_STA	0x0E
 110#define VSPEC1_TEMP_STA_DATA	GENMASK(9, 0)
 111
 112/* Mailbox */
 113#define VSPEC1_MBOX_DATA	0x5
 114#define VSPEC1_MBOX_ADDRLO	0x6
 115#define VSPEC1_MBOX_CMD		0x7
 116#define VSPEC1_MBOX_CMD_ADDRHI	GENMASK(7, 0)
 117#define VSPEC1_MBOX_CMD_RD	(0 << 8)
 118#define VSPEC1_MBOX_CMD_READY	BIT(15)
 119
 120/* WoL */
 121#define VPSPEC2_WOL_CTL		0x0E06
 122#define VPSPEC2_WOL_AD01	0x0E08
 123#define VPSPEC2_WOL_AD23	0x0E09
 124#define VPSPEC2_WOL_AD45	0x0E0A
 125#define WOL_EN			BIT(0)
 126
 127/* Internal registers, access via mbox */
 128#define REG_GPIO0_OUT		0xd3ce00
 129
 130struct gpy_priv {
 131	/* serialize mailbox acesses */
 132	struct mutex mbox_lock;
 133
 134	u8 fw_major;
 135	u8 fw_minor;
 136	u32 wolopts;
 137
 138	/* It takes 3 seconds to fully switch out of loopback mode before
 139	 * it can safely re-enter loopback mode. Record the time when
 140	 * loopback is disabled. Check and wait if necessary before loopback
 141	 * is enabled.
 142	 */
 143	u64 lb_dis_to;
 144};
 145
 146static const struct {
 147	int major;
 148	int minor;
 149} ver_need_sgmii_reaneg[] = {
 150	{7, 0x6D},
 151	{8, 0x6D},
 152	{9, 0x73},
 153};
 154
 155#if IS_ENABLED(CONFIG_HWMON)
 156/* The original translation formulae of the temperature (in degrees of Celsius)
 157 * are as follows:
 158 *
 159 *   T = -2.5761e-11*(N^4) + 9.7332e-8*(N^3) + -1.9165e-4*(N^2) +
 160 *       3.0762e-1*(N^1) + -5.2156e1
 161 *
 162 * where [-52.156, 137.961]C and N = [0, 1023].
 163 *
 164 * They must be accordingly altered to be suitable for the integer arithmetics.
 165 * The technique is called 'factor redistribution', which just makes sure the
 166 * multiplications and divisions are made so to have a result of the operations
 167 * within the integer numbers limit. In addition we need to translate the
 168 * formulae to accept millidegrees of Celsius. Here what it looks like after
 169 * the alterations:
 170 *
 171 *   T = -25761e-12*(N^4) + 97332e-9*(N^3) + -191650e-6*(N^2) +
 172 *       307620e-3*(N^1) + -52156
 173 *
 174 * where T = [-52156, 137961]mC and N = [0, 1023].
 175 */
 176static const struct polynomial poly_N_to_temp = {
 177	.terms = {
 178		{4,  -25761, 1000, 1},
 179		{3,   97332, 1000, 1},
 180		{2, -191650, 1000, 1},
 181		{1,  307620, 1000, 1},
 182		{0,  -52156,    1, 1}
 183	}
 184};
 185
 186static int gpy_hwmon_read(struct device *dev,
 187			  enum hwmon_sensor_types type,
 188			  u32 attr, int channel, long *value)
 189{
 190	struct phy_device *phydev = dev_get_drvdata(dev);
 191	int ret;
 192
 193	ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_TEMP_STA);
 194	if (ret < 0)
 195		return ret;
 196	if (!ret)
 197		return -ENODATA;
 198
 199	*value = polynomial_calc(&poly_N_to_temp,
 200				 FIELD_GET(VSPEC1_TEMP_STA_DATA, ret));
 201
 202	return 0;
 203}
 204
 205static int mxl862x2_hwmon_read(struct device *dev,
 206			       enum hwmon_sensor_types type,
 207			       u32 attr, int channel, long *value)
 208{
 209	struct phy_device *phydev = dev_get_drvdata(dev);
 210	long tmp;
 211	int ret;
 212
 213	ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_TEMP_STA);
 214	if (ret < 0)
 215		return ret;
 216	if (!ret)
 217		return -ENODATA;
 218
 219	tmp = (s16)ret;
 220	tmp *= 78125;
 221	tmp /= 10000;
 222
 223	*value = tmp;
 224
 225	return 0;
 226}
 227
 228static umode_t gpy_hwmon_is_visible(const void *data,
 229				    enum hwmon_sensor_types type,
 230				    u32 attr, int channel)
 231{
 232	return 0444;
 233}
 234
 235static const struct hwmon_channel_info * const gpy_hwmon_info[] = {
 236	HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),
 237	NULL
 238};
 239
 240static const struct hwmon_ops gpy_hwmon_hwmon_ops = {
 241	.is_visible	= gpy_hwmon_is_visible,
 242	.read		= gpy_hwmon_read,
 243};
 244
 245static const struct hwmon_ops mxl862x2_hwmon_hwmon_ops = {
 246	.is_visible	= gpy_hwmon_is_visible,
 247	.read		= mxl862x2_hwmon_read,
 248};
 249
 250static const struct hwmon_chip_info gpy_hwmon_chip_info = {
 251	.ops		= &gpy_hwmon_hwmon_ops,
 252	.info		= gpy_hwmon_info,
 253};
 254
 255static const struct hwmon_chip_info mxl862x2_hwmon_chip_info = {
 256	.ops		= &mxl862x2_hwmon_hwmon_ops,
 257	.info		= gpy_hwmon_info,
 258};
 259
 260static int gpy_hwmon_register(struct phy_device *phydev)
 261{
 262	struct device *dev = &phydev->mdio.dev;
 263	const struct hwmon_chip_info *info;
 264	struct device *hwmon_dev;
 265
 266	if (phy_id_compare_model(phydev->phy_id, PHY_ID_MXL86252) ||
 267	    phy_id_compare_model(phydev->phy_id, PHY_ID_MXL86282))
 268		info = &mxl862x2_hwmon_chip_info;
 269	else
 270		info = &gpy_hwmon_chip_info;
 271
 272	hwmon_dev = devm_hwmon_device_register_with_info(dev, NULL, phydev,
 273							 info, NULL);
 274
 275	return PTR_ERR_OR_ZERO(hwmon_dev);
 276}
 277#else
 278static int gpy_hwmon_register(struct phy_device *phydev)
 279{
 280	return 0;
 281}
 282#endif
 283
 284static int gpy_ack_interrupt(struct phy_device *phydev)
 285{
 286	int ret;
 287
 288	/* Clear all pending interrupts */
 289	ret = phy_read(phydev, PHY_ISTAT);
 290	return ret < 0 ? ret : 0;
 291}
 292
 293static int gpy_mbox_read(struct phy_device *phydev, u32 addr)
 294{
 295	struct gpy_priv *priv = phydev->priv;
 296	int val, ret;
 297	u16 cmd;
 298
 299	mutex_lock(&priv->mbox_lock);
 300
 301	ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_MBOX_ADDRLO,
 302			    addr);
 303	if (ret)
 304		goto out;
 305
 306	cmd = VSPEC1_MBOX_CMD_RD;
 307	cmd |= FIELD_PREP(VSPEC1_MBOX_CMD_ADDRHI, addr >> 16);
 308
 309	ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_MBOX_CMD, cmd);
 310	if (ret)
 311		goto out;
 312
 313	/* The mbox read is used in the interrupt workaround. It was observed
 314	 * that a read might take up to 2.5ms. This is also the time for which
 315	 * the interrupt line is stuck low. To be on the safe side, poll the
 316	 * ready bit for 10ms.
 317	 */
 318	ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
 319					VSPEC1_MBOX_CMD, val,
 320					(val & VSPEC1_MBOX_CMD_READY),
 321					500, 10000, false);
 322	if (ret)
 323		goto out;
 324
 325	ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_MBOX_DATA);
 326
 327out:
 328	mutex_unlock(&priv->mbox_lock);
 329	return ret;
 330}
 331
 332static int gpy_config_init(struct phy_device *phydev)
 333{
 334	/* Nothing to configure. Configuration Requirement Placeholder */
 335	return 0;
 336}
 337
 338static int gpy21x_config_init(struct phy_device *phydev)
 339{
 340	__set_bit(PHY_INTERFACE_MODE_2500BASEX, phydev->possible_interfaces);
 341	__set_bit(PHY_INTERFACE_MODE_SGMII, phydev->possible_interfaces);
 342
 343	return gpy_config_init(phydev);
 344}
 345
 346static int gpy_probe(struct phy_device *phydev)
 347{
 348	struct device *dev = &phydev->mdio.dev;
 349	struct gpy_priv *priv;
 350	int fw_version;
 351	int ret;
 352
 353	if (!phydev->is_c45) {
 354		ret = phy_get_c45_ids(phydev);
 355		if (ret < 0)
 356			return ret;
 357	}
 358
 359	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 360	if (!priv)
 361		return -ENOMEM;
 362	phydev->priv = priv;
 363	mutex_init(&priv->mbox_lock);
 364
 365	if (!device_property_present(dev, "maxlinear,use-broken-interrupts"))
 366		phydev->dev_flags |= PHY_F_NO_IRQ;
 367
 368	fw_version = phy_read(phydev, PHY_FWV);
 369	if (fw_version < 0)
 370		return fw_version;
 371	priv->fw_major = FIELD_GET(PHY_FWV_MAJOR_MASK, fw_version);
 372	priv->fw_minor = FIELD_GET(PHY_FWV_MINOR_MASK, fw_version);
 373
 374	ret = gpy_hwmon_register(phydev);
 375	if (ret)
 376		return ret;
 377
 378	/* Show GPY PHY FW version in dmesg */
 379	phydev_info(phydev, "Firmware Version: %d.%d (0x%04X%s)\n",
 380		    priv->fw_major, priv->fw_minor, fw_version,
 381		    fw_version & PHY_FWV_REL_MASK ? "" : " test version");
 382
 383	return 0;
 384}
 385
 386static bool gpy_sgmii_need_reaneg(struct phy_device *phydev)
 387{
 388	struct gpy_priv *priv = phydev->priv;
 389	size_t i;
 390
 391	for (i = 0; i < ARRAY_SIZE(ver_need_sgmii_reaneg); i++) {
 392		if (priv->fw_major != ver_need_sgmii_reaneg[i].major)
 393			continue;
 394		if (priv->fw_minor < ver_need_sgmii_reaneg[i].minor)
 395			return true;
 396		break;
 397	}
 398
 399	return false;
 400}
 401
 402static bool gpy_2500basex_chk(struct phy_device *phydev)
 403{
 404	int ret;
 405
 406	ret = phy_read(phydev, PHY_MIISTAT);
 407	if (ret < 0) {
 408		phydev_err(phydev, "Error: MDIO register access failed: %d\n",
 409			   ret);
 410		return false;
 411	}
 412
 413	if (!(ret & PHY_MIISTAT_LS) ||
 414	    FIELD_GET(PHY_MIISTAT_SPD_MASK, ret) != PHY_MIISTAT_SPD_2500)
 415		return false;
 416
 417	phydev->speed = SPEED_2500;
 418	phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
 419	phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL,
 420		       VSPEC1_SGMII_CTRL_ANEN, 0);
 421	return true;
 422}
 423
 424static bool gpy_sgmii_aneg_en(struct phy_device *phydev)
 425{
 426	int ret;
 427
 428	ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL);
 429	if (ret < 0) {
 430		phydev_err(phydev, "Error: MMD register access failed: %d\n",
 431			   ret);
 432		return true;
 433	}
 434
 435	return (ret & VSPEC1_SGMII_CTRL_ANEN) ? true : false;
 436}
 437
 438static int gpy_config_mdix(struct phy_device *phydev, u8 ctrl)
 439{
 440	int ret;
 441	u16 val;
 442
 443	switch (ctrl) {
 444	case ETH_TP_MDI_AUTO:
 445		val = PHY_CTL1_AMDIX;
 446		break;
 447	case ETH_TP_MDI_X:
 448		val = (PHY_CTL1_MDIAB | PHY_CTL1_MDICD);
 449		break;
 450	case ETH_TP_MDI:
 451		val = 0;
 452		break;
 453	default:
 454		return 0;
 455	}
 456
 457	ret =  phy_modify(phydev, PHY_CTL1, PHY_CTL1_AMDIX | PHY_CTL1_MDIAB |
 458			  PHY_CTL1_MDICD, val);
 459	if (ret < 0)
 460		return ret;
 461
 462	return genphy_c45_restart_aneg(phydev);
 463}
 464
 465static int gpy_config_aneg(struct phy_device *phydev)
 466{
 467	bool changed = false;
 468	u32 adv;
 469	int ret;
 470
 471	if (phydev->autoneg == AUTONEG_DISABLE) {
 472		/* Configure half duplex with genphy_setup_forced,
 473		 * because genphy_c45_pma_setup_forced does not support.
 474		 */
 475		return phydev->duplex != DUPLEX_FULL
 476			? genphy_setup_forced(phydev)
 477			: genphy_c45_pma_setup_forced(phydev);
 478	}
 479
 480	ret = gpy_config_mdix(phydev,  phydev->mdix_ctrl);
 481	if (ret < 0)
 482		return ret;
 483
 484	ret = genphy_c45_an_config_aneg(phydev);
 485	if (ret < 0)
 486		return ret;
 487	if (ret > 0)
 488		changed = true;
 489
 490	adv = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising);
 491	ret = phy_modify_changed(phydev, MII_CTRL1000,
 492				 ADVERTISE_1000FULL | ADVERTISE_1000HALF,
 493				 adv);
 494	if (ret < 0)
 495		return ret;
 496	if (ret > 0)
 497		changed = true;
 498
 499	ret = genphy_c45_check_and_restart_aneg(phydev, changed);
 500	if (ret < 0)
 501		return ret;
 502
 503	if (phydev->interface == PHY_INTERFACE_MODE_USXGMII ||
 504	    phydev->interface == PHY_INTERFACE_MODE_INTERNAL)
 505		return 0;
 506
 507	/* No need to trigger re-ANEG if link speed is 2.5G or SGMII ANEG is
 508	 * disabled.
 509	 */
 510	if (!gpy_sgmii_need_reaneg(phydev) || gpy_2500basex_chk(phydev) ||
 511	    !gpy_sgmii_aneg_en(phydev))
 512		return 0;
 513
 514	/* There is a design constraint in GPY2xx device where SGMII AN is
 515	 * only triggered when there is change of speed. If, PHY link
 516	 * partner`s speed is still same even after PHY TPI is down and up
 517	 * again, SGMII AN is not triggered and hence no new in-band message
 518	 * from GPY to MAC side SGMII.
 519	 * This could cause an issue during power up, when PHY is up prior to
 520	 * MAC. At this condition, once MAC side SGMII is up, MAC side SGMII
 521	 * wouldn`t receive new in-band message from GPY with correct link
 522	 * status, speed and duplex info.
 523	 *
 524	 * 1) If PHY is already up and TPI link status is still down (such as
 525	 *    hard reboot), TPI link status is polled for 4 seconds before
 526	 *    retriggerring SGMII AN.
 527	 * 2) If PHY is already up and TPI link status is also up (such as soft
 528	 *    reboot), polling of TPI link status is not needed and SGMII AN is
 529	 *    immediately retriggered.
 530	 * 3) Other conditions such as PHY is down, speed change etc, skip
 531	 *    retriggering SGMII AN. Note: in case of speed change, GPY FW will
 532	 *    initiate SGMII AN.
 533	 */
 534
 535	if (phydev->state != PHY_UP)
 536		return 0;
 537
 538	ret = phy_read_poll_timeout(phydev, MII_BMSR, ret, ret & BMSR_LSTATUS,
 539				    20000, 4000000, false);
 540	if (ret == -ETIMEDOUT)
 541		return 0;
 542	else if (ret < 0)
 543		return ret;
 544
 545	/* Trigger SGMII AN. */
 546	return phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL,
 547			      VSPEC1_SGMII_CTRL_ANRS, VSPEC1_SGMII_CTRL_ANRS);
 548}
 549
 550static int gpy_update_mdix(struct phy_device *phydev)
 551{
 552	int ret;
 553
 554	ret = phy_read(phydev, PHY_CTL1);
 555	if (ret < 0)
 556		return ret;
 557
 558	if (ret & PHY_CTL1_AMDIX)
 559		phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
 560	else
 561		if (ret & PHY_CTL1_MDICD || ret & PHY_CTL1_MDIAB)
 562			phydev->mdix_ctrl = ETH_TP_MDI_X;
 563		else
 564			phydev->mdix_ctrl = ETH_TP_MDI;
 565
 566	ret = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, PHY_PMA_MGBT_POLARITY);
 567	if (ret < 0)
 568		return ret;
 569
 570	if ((ret & PHY_MDI_MDI_X_MASK) < PHY_MDI_MDI_X_NORMAL)
 571		phydev->mdix = ETH_TP_MDI_X;
 572	else
 573		phydev->mdix = ETH_TP_MDI;
 574
 575	return 0;
 576}
 577
 578static int gpy_update_interface(struct phy_device *phydev)
 579{
 580	int ret;
 581
 582	/* Interface mode is fixed for USXGMII and integrated PHY */
 583	if (phydev->interface == PHY_INTERFACE_MODE_USXGMII ||
 584	    phydev->interface == PHY_INTERFACE_MODE_INTERNAL)
 585		return 0;
 586
 587	/* Automatically switch SERDES interface between SGMII and 2500-BaseX
 588	 * according to speed. Disable ANEG in 2500-BaseX mode.
 589	 */
 590	switch (phydev->speed) {
 591	case SPEED_2500:
 592		phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
 593		ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL,
 594				     VSPEC1_SGMII_CTRL_ANEN, 0);
 595		if (ret < 0) {
 596			phydev_err(phydev,
 597				   "Error: Disable of SGMII ANEG failed: %d\n",
 598				   ret);
 599			return ret;
 600		}
 601		break;
 602	case SPEED_1000:
 603	case SPEED_100:
 604	case SPEED_10:
 605		phydev->interface = PHY_INTERFACE_MODE_SGMII;
 606		if (gpy_sgmii_aneg_en(phydev))
 607			break;
 608		/* Enable and restart SGMII ANEG for 10/100/1000Mbps link speed
 609		 * if ANEG is disabled (in 2500-BaseX mode).
 610		 */
 611		ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL,
 612				     VSPEC1_SGMII_ANEN_ANRS,
 613				     VSPEC1_SGMII_ANEN_ANRS);
 614		if (ret < 0) {
 615			phydev_err(phydev,
 616				   "Error: Enable of SGMII ANEG failed: %d\n",
 617				   ret);
 618			return ret;
 619		}
 620		break;
 621	}
 622
 623	return 0;
 624}
 625
 626static int gpy_read_status(struct phy_device *phydev)
 627{
 628	int ret;
 629
 630	ret = genphy_update_link(phydev);
 631	if (ret)
 632		return ret;
 633
 634	phydev->speed = SPEED_UNKNOWN;
 635	phydev->duplex = DUPLEX_UNKNOWN;
 636	phydev->pause = 0;
 637	phydev->asym_pause = 0;
 638
 639	if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) {
 640		ret = genphy_c45_read_lpa(phydev);
 641		if (ret < 0)
 642			return ret;
 643
 644		/* Read the link partner's 1G advertisement */
 645		ret = phy_read(phydev, MII_STAT1000);
 646		if (ret < 0)
 647			return ret;
 648		mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, ret);
 649	} else if (phydev->autoneg == AUTONEG_DISABLE) {
 650		linkmode_zero(phydev->lp_advertising);
 651	}
 652
 653	ret = phy_read(phydev, PHY_MIISTAT);
 654	if (ret < 0)
 655		return ret;
 656
 657	phydev->link = (ret & PHY_MIISTAT_LS) ? 1 : 0;
 658	phydev->duplex = (ret & PHY_MIISTAT_DPX) ? DUPLEX_FULL : DUPLEX_HALF;
 659	switch (FIELD_GET(PHY_MIISTAT_SPD_MASK, ret)) {
 660	case PHY_MIISTAT_SPD_10:
 661		phydev->speed = SPEED_10;
 662		break;
 663	case PHY_MIISTAT_SPD_100:
 664		phydev->speed = SPEED_100;
 665		break;
 666	case PHY_MIISTAT_SPD_1000:
 667		phydev->speed = SPEED_1000;
 668		break;
 669	case PHY_MIISTAT_SPD_2500:
 670		phydev->speed = SPEED_2500;
 671		break;
 672	}
 673
 674	if (phydev->link) {
 675		ret = gpy_update_interface(phydev);
 676		if (ret < 0)
 677			return ret;
 678
 679		if (phydev->speed == SPEED_2500 || phydev->speed == SPEED_1000) {
 680			ret = genphy_read_master_slave(phydev);
 681			if (ret < 0)
 682				return ret;
 683		}
 684
 685		ret = gpy_update_mdix(phydev);
 686		if (ret < 0)
 687			return ret;
 688	}
 689
 690	return 0;
 691}
 692
 693static int gpy_config_intr(struct phy_device *phydev)
 694{
 695	struct gpy_priv *priv = phydev->priv;
 696	u16 mask = 0;
 697	int ret;
 698
 699	ret = gpy_ack_interrupt(phydev);
 700	if (ret)
 701		return ret;
 702
 703	if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
 704		mask = PHY_IMASK_MASK;
 705
 706	if (priv->wolopts & WAKE_MAGIC)
 707		mask |= PHY_IMASK_WOL;
 708
 709	if (priv->wolopts & WAKE_PHY)
 710		mask |= PHY_IMASK_LSTC;
 711
 712	return phy_write(phydev, PHY_IMASK, mask);
 713}
 714
 715static irqreturn_t gpy_handle_interrupt(struct phy_device *phydev)
 716{
 717	int reg;
 718
 719	reg = phy_read(phydev, PHY_ISTAT);
 720	if (reg < 0) {
 721		phy_error(phydev);
 722		return IRQ_NONE;
 723	}
 724
 725	if (!(reg & PHY_IMASK_MASK))
 726		return IRQ_NONE;
 727
 728	/* The PHY might leave the interrupt line asserted even after PHY_ISTAT
 729	 * is read. To avoid interrupt storms, delay the interrupt handling as
 730	 * long as the PHY drives the interrupt line. An internal bus read will
 731	 * stall as long as the interrupt line is asserted, thus just read a
 732	 * random register here.
 733	 * Because we cannot access the internal bus at all while the interrupt
 734	 * is driven by the PHY, there is no way to make the interrupt line
 735	 * unstuck (e.g. by changing the pinmux to GPIO input) during that time
 736	 * frame. Therefore, polling is the best we can do and won't do any more
 737	 * harm.
 738	 * It was observed that this bug happens on link state and link speed
 739	 * changes independent of the firmware version.
 740	 */
 741	if (reg & (PHY_IMASK_LSTC | PHY_IMASK_LSPC)) {
 742		reg = gpy_mbox_read(phydev, REG_GPIO0_OUT);
 743		if (reg < 0) {
 744			phy_error(phydev);
 745			return IRQ_NONE;
 746		}
 747	}
 748
 749	phy_trigger_machine(phydev);
 750
 751	return IRQ_HANDLED;
 752}
 753
 754static int gpy_set_wol(struct phy_device *phydev,
 755		       struct ethtool_wolinfo *wol)
 756{
 757	struct net_device *attach_dev = phydev->attached_dev;
 758	struct gpy_priv *priv = phydev->priv;
 759	int ret;
 760
 761	if (wol->wolopts & WAKE_MAGIC) {
 762		/* MAC address - Byte0:Byte1:Byte2:Byte3:Byte4:Byte5
 763		 * VPSPEC2_WOL_AD45 = Byte0:Byte1
 764		 * VPSPEC2_WOL_AD23 = Byte2:Byte3
 765		 * VPSPEC2_WOL_AD01 = Byte4:Byte5
 766		 */
 767		ret = phy_set_bits_mmd(phydev, MDIO_MMD_VEND2,
 768				       VPSPEC2_WOL_AD45,
 769				       ((attach_dev->dev_addr[0] << 8) |
 770				       attach_dev->dev_addr[1]));
 771		if (ret < 0)
 772			return ret;
 773
 774		ret = phy_set_bits_mmd(phydev, MDIO_MMD_VEND2,
 775				       VPSPEC2_WOL_AD23,
 776				       ((attach_dev->dev_addr[2] << 8) |
 777				       attach_dev->dev_addr[3]));
 778		if (ret < 0)
 779			return ret;
 780
 781		ret = phy_set_bits_mmd(phydev, MDIO_MMD_VEND2,
 782				       VPSPEC2_WOL_AD01,
 783				       ((attach_dev->dev_addr[4] << 8) |
 784				       attach_dev->dev_addr[5]));
 785		if (ret < 0)
 786			return ret;
 787
 788		/* Enable the WOL interrupt */
 789		ret = phy_write(phydev, PHY_IMASK, PHY_IMASK_WOL);
 790		if (ret < 0)
 791			return ret;
 792
 793		/* Enable magic packet matching */
 794		ret = phy_set_bits_mmd(phydev, MDIO_MMD_VEND2,
 795				       VPSPEC2_WOL_CTL,
 796				       WOL_EN);
 797		if (ret < 0)
 798			return ret;
 799
 800		/* Clear the interrupt status register.
 801		 * Only WoL is enabled so clear all.
 802		 */
 803		ret = phy_read(phydev, PHY_ISTAT);
 804		if (ret < 0)
 805			return ret;
 806
 807		priv->wolopts |= WAKE_MAGIC;
 808	} else {
 809		/* Disable magic packet matching */
 810		ret = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2,
 811					 VPSPEC2_WOL_CTL,
 812					 WOL_EN);
 813		if (ret < 0)
 814			return ret;
 815
 816		/* Disable the WOL interrupt */
 817		ret = phy_clear_bits(phydev, PHY_IMASK, PHY_IMASK_WOL);
 818		if (ret < 0)
 819			return ret;
 820
 821		priv->wolopts &= ~WAKE_MAGIC;
 822	}
 823
 824	if (wol->wolopts & WAKE_PHY) {
 825		/* Enable the link state change interrupt */
 826		ret = phy_set_bits(phydev, PHY_IMASK, PHY_IMASK_LSTC);
 827		if (ret < 0)
 828			return ret;
 829
 830		/* Clear the interrupt status register */
 831		ret = phy_read(phydev, PHY_ISTAT);
 832		if (ret < 0)
 833			return ret;
 834
 835		if (ret & (PHY_IMASK_MASK & ~PHY_IMASK_LSTC))
 836			phy_trigger_machine(phydev);
 837
 838		priv->wolopts |= WAKE_PHY;
 839		return 0;
 840	}
 841
 842	priv->wolopts &= ~WAKE_PHY;
 843	/* Disable the link state change interrupt */
 844	return phy_clear_bits(phydev, PHY_IMASK, PHY_IMASK_LSTC);
 845}
 846
 847static void gpy_get_wol(struct phy_device *phydev,
 848			struct ethtool_wolinfo *wol)
 849{
 850	struct gpy_priv *priv = phydev->priv;
 851
 852	wol->supported = WAKE_MAGIC | WAKE_PHY;
 853	wol->wolopts = priv->wolopts;
 854}
 855
 856static int gpy_loopback(struct phy_device *phydev, bool enable, int speed)
 857{
 858	struct gpy_priv *priv = phydev->priv;
 859	u16 set = 0;
 860	int ret;
 861
 862	if (enable) {
 863		u64 now = get_jiffies_64();
 864
 865		if (speed)
 866			return -EOPNOTSUPP;
 867
 868		/* wait until 3 seconds from last disable */
 869		if (time_before64(now, priv->lb_dis_to))
 870			msleep(jiffies64_to_msecs(priv->lb_dis_to - now));
 871
 872		set = BMCR_LOOPBACK;
 873	}
 874
 875	ret = phy_modify(phydev, MII_BMCR, BMCR_LOOPBACK, set);
 876	if (ret <= 0)
 877		return ret;
 878
 879	if (enable) {
 880		/* It takes some time for PHY device to switch into
 881		 * loopback mode.
 882		 */
 883		msleep(100);
 884	} else {
 885		priv->lb_dis_to = get_jiffies_64() + HZ * 3;
 886	}
 887
 888	return 0;
 889}
 890
 891static int gpy115_loopback(struct phy_device *phydev, bool enable, int speed)
 892{
 893	struct gpy_priv *priv = phydev->priv;
 894
 895	if (enable)
 896		return gpy_loopback(phydev, enable, speed);
 897
 898	if (priv->fw_minor > 0x76)
 899		return gpy_loopback(phydev, 0, 0);
 900
 901	return genphy_soft_reset(phydev);
 902}
 903
 904static int gpy_led_brightness_set(struct phy_device *phydev,
 905				  u8 index, enum led_brightness value)
 906{
 907	int ret;
 908
 909	if (index >= GPY_MAX_LEDS)
 910		return -EINVAL;
 911
 912	/* clear HWCONTROL and set manual LED state */
 913	ret = phy_modify(phydev, PHY_LED,
 914			 ((value == LED_OFF) ? PHY_LED_HWCONTROL(index) : 0) |
 915			 PHY_LED_ON(index),
 916			 (value == LED_OFF) ? 0 : PHY_LED_ON(index));
 917	if (ret)
 918		return ret;
 919
 920	/* ToDo: set PWM brightness */
 921
 922	/* clear HW LED setup */
 923	if (value == LED_OFF)
 924		return phy_write_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_LED(index), 0);
 925	else
 926		return 0;
 927}
 928
 929static const unsigned long supported_triggers = (BIT(TRIGGER_NETDEV_LINK) |
 930						 BIT(TRIGGER_NETDEV_LINK_10) |
 931						 BIT(TRIGGER_NETDEV_LINK_100) |
 932						 BIT(TRIGGER_NETDEV_LINK_1000) |
 933						 BIT(TRIGGER_NETDEV_LINK_2500) |
 934						 BIT(TRIGGER_NETDEV_RX) |
 935						 BIT(TRIGGER_NETDEV_TX));
 936
 937static int gpy_led_hw_is_supported(struct phy_device *phydev, u8 index,
 938				   unsigned long rules)
 939{
 940	if (index >= GPY_MAX_LEDS)
 941		return -EINVAL;
 942
 943	/* All combinations of the supported triggers are allowed */
 944	if (rules & ~supported_triggers)
 945		return -EOPNOTSUPP;
 946
 947	return 0;
 948}
 949
 950static int gpy_led_hw_control_get(struct phy_device *phydev, u8 index,
 951				  unsigned long *rules)
 952{
 953	int val;
 954
 955	if (index >= GPY_MAX_LEDS)
 956		return -EINVAL;
 957
 958	val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_LED(index));
 959	if (val < 0)
 960		return val;
 961
 962	if (FIELD_GET(VSPEC1_LED_CON, val) & VSPEC1_LED_LINK10)
 963		*rules |= BIT(TRIGGER_NETDEV_LINK_10);
 964
 965	if (FIELD_GET(VSPEC1_LED_CON, val) & VSPEC1_LED_LINK100)
 966		*rules |= BIT(TRIGGER_NETDEV_LINK_100);
 967
 968	if (FIELD_GET(VSPEC1_LED_CON, val) & VSPEC1_LED_LINK1000)
 969		*rules |= BIT(TRIGGER_NETDEV_LINK_1000);
 970
 971	if (FIELD_GET(VSPEC1_LED_CON, val) & VSPEC1_LED_LINK2500)
 972		*rules |= BIT(TRIGGER_NETDEV_LINK_2500);
 973
 974	if (FIELD_GET(VSPEC1_LED_CON, val) == (VSPEC1_LED_LINK10 |
 975					       VSPEC1_LED_LINK100 |
 976					       VSPEC1_LED_LINK1000 |
 977					       VSPEC1_LED_LINK2500))
 978		*rules |= BIT(TRIGGER_NETDEV_LINK);
 979
 980	if (FIELD_GET(VSPEC1_LED_PULSE, val) & VSPEC1_LED_TXACT)
 981		*rules |= BIT(TRIGGER_NETDEV_TX);
 982
 983	if (FIELD_GET(VSPEC1_LED_PULSE, val) & VSPEC1_LED_RXACT)
 984		*rules |= BIT(TRIGGER_NETDEV_RX);
 985
 986	return 0;
 987}
 988
 989static int gpy_led_hw_control_set(struct phy_device *phydev, u8 index,
 990				  unsigned long rules)
 991{
 992	u16 val = 0;
 993	int ret;
 994
 995	if (index >= GPY_MAX_LEDS)
 996		return -EINVAL;
 997
 998	if (rules & BIT(TRIGGER_NETDEV_LINK) ||
 999	    rules & BIT(TRIGGER_NETDEV_LINK_10))
1000		val |= FIELD_PREP(VSPEC1_LED_CON, VSPEC1_LED_LINK10);
1001
1002	if (rules & BIT(TRIGGER_NETDEV_LINK) ||
1003	    rules & BIT(TRIGGER_NETDEV_LINK_100))
1004		val |= FIELD_PREP(VSPEC1_LED_CON, VSPEC1_LED_LINK100);
1005
1006	if (rules & BIT(TRIGGER_NETDEV_LINK) ||
1007	    rules & BIT(TRIGGER_NETDEV_LINK_1000))
1008		val |= FIELD_PREP(VSPEC1_LED_CON, VSPEC1_LED_LINK1000);
1009
1010	if (rules & BIT(TRIGGER_NETDEV_LINK) ||
1011	    rules & BIT(TRIGGER_NETDEV_LINK_2500))
1012		val |= FIELD_PREP(VSPEC1_LED_CON, VSPEC1_LED_LINK2500);
1013
1014	if (rules & BIT(TRIGGER_NETDEV_TX))
1015		val |= FIELD_PREP(VSPEC1_LED_PULSE, VSPEC1_LED_TXACT);
1016
1017	if (rules & BIT(TRIGGER_NETDEV_RX))
1018		val |= FIELD_PREP(VSPEC1_LED_PULSE, VSPEC1_LED_RXACT);
1019
1020	/* allow RX/TX pulse without link indication */
1021	if ((rules & BIT(TRIGGER_NETDEV_TX) || rules & BIT(TRIGGER_NETDEV_RX)) &&
1022	    !(val & VSPEC1_LED_CON))
1023		val |= FIELD_PREP(VSPEC1_LED_PULSE, VSPEC1_LED_NO_CON) | VSPEC1_LED_CON;
1024
1025	ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_LED(index), val);
1026	if (ret)
1027		return ret;
1028
1029	return phy_set_bits(phydev, PHY_LED, PHY_LED_HWCONTROL(index));
1030}
1031
1032static int gpy_led_polarity_set(struct phy_device *phydev, int index,
1033				unsigned long modes)
1034{
1035	bool force_active_low = false, force_active_high = false;
1036	u32 mode;
1037
1038	if (index >= GPY_MAX_LEDS)
1039		return -EINVAL;
1040
1041	for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) {
1042		switch (mode) {
1043		case PHY_LED_ACTIVE_LOW:
1044			force_active_low = true;
1045			break;
1046		case PHY_LED_ACTIVE_HIGH:
1047			force_active_high = true;
1048			break;
1049		default:
1050			return -EINVAL;
1051		}
1052	}
1053
1054	if (force_active_low)
1055		return phy_set_bits(phydev, PHY_LED, PHY_LED_POLARITY(index));
1056
1057	if (force_active_high)
1058		return phy_clear_bits(phydev, PHY_LED, PHY_LED_POLARITY(index));
1059
1060	return -EINVAL;
1061}
1062
1063static struct phy_driver gpy_drivers[] = {
1064	{
1065		PHY_ID_MATCH_MODEL(PHY_ID_GPY2xx),
1066		.name		= "Maxlinear Ethernet GPY2xx",
1067		.get_features	= genphy_c45_pma_read_abilities,
1068		.config_init	= gpy_config_init,
1069		.probe		= gpy_probe,
1070		.suspend	= genphy_suspend,
1071		.resume		= genphy_resume,
1072		.config_aneg	= gpy_config_aneg,
1073		.aneg_done	= genphy_c45_aneg_done,
1074		.read_status	= gpy_read_status,
1075		.config_intr	= gpy_config_intr,
1076		.handle_interrupt = gpy_handle_interrupt,
1077		.set_wol	= gpy_set_wol,
1078		.get_wol	= gpy_get_wol,
1079		.set_loopback	= gpy_loopback,
1080		.led_brightness_set = gpy_led_brightness_set,
1081		.led_hw_is_supported = gpy_led_hw_is_supported,
1082		.led_hw_control_get = gpy_led_hw_control_get,
1083		.led_hw_control_set = gpy_led_hw_control_set,
1084		.led_polarity_set = gpy_led_polarity_set,
1085	},
1086	{
1087		.phy_id		= PHY_ID_GPY115B,
1088		.phy_id_mask	= PHY_ID_GPYx15B_MASK,
1089		.name		= "Maxlinear Ethernet GPY115B",
1090		.get_features	= genphy_c45_pma_read_abilities,
1091		.config_init	= gpy_config_init,
1092		.probe		= gpy_probe,
1093		.suspend	= genphy_suspend,
1094		.resume		= genphy_resume,
1095		.config_aneg	= gpy_config_aneg,
1096		.aneg_done	= genphy_c45_aneg_done,
1097		.read_status	= gpy_read_status,
1098		.config_intr	= gpy_config_intr,
1099		.handle_interrupt = gpy_handle_interrupt,
1100		.set_wol	= gpy_set_wol,
1101		.get_wol	= gpy_get_wol,
1102		.set_loopback	= gpy115_loopback,
1103		.led_brightness_set = gpy_led_brightness_set,
1104		.led_hw_is_supported = gpy_led_hw_is_supported,
1105		.led_hw_control_get = gpy_led_hw_control_get,
1106		.led_hw_control_set = gpy_led_hw_control_set,
1107		.led_polarity_set = gpy_led_polarity_set,
1108	},
1109	{
1110		PHY_ID_MATCH_MODEL(PHY_ID_GPY115C),
1111		.name		= "Maxlinear Ethernet GPY115C",
1112		.get_features	= genphy_c45_pma_read_abilities,
1113		.config_init	= gpy_config_init,
1114		.probe		= gpy_probe,
1115		.suspend	= genphy_suspend,
1116		.resume		= genphy_resume,
1117		.config_aneg	= gpy_config_aneg,
1118		.aneg_done	= genphy_c45_aneg_done,
1119		.read_status	= gpy_read_status,
1120		.config_intr	= gpy_config_intr,
1121		.handle_interrupt = gpy_handle_interrupt,
1122		.set_wol	= gpy_set_wol,
1123		.get_wol	= gpy_get_wol,
1124		.set_loopback	= gpy115_loopback,
1125		.led_brightness_set = gpy_led_brightness_set,
1126		.led_hw_is_supported = gpy_led_hw_is_supported,
1127		.led_hw_control_get = gpy_led_hw_control_get,
1128		.led_hw_control_set = gpy_led_hw_control_set,
1129		.led_polarity_set = gpy_led_polarity_set,
1130	},
1131	{
1132		.phy_id		= PHY_ID_GPY211B,
1133		.phy_id_mask	= PHY_ID_GPY21xB_MASK,
1134		.name		= "Maxlinear Ethernet GPY211B",
1135		.get_features	= genphy_c45_pma_read_abilities,
1136		.config_init	= gpy21x_config_init,
1137		.probe		= gpy_probe,
1138		.suspend	= genphy_suspend,
1139		.resume		= genphy_resume,
1140		.config_aneg	= gpy_config_aneg,
1141		.aneg_done	= genphy_c45_aneg_done,
1142		.read_status	= gpy_read_status,
1143		.config_intr	= gpy_config_intr,
1144		.handle_interrupt = gpy_handle_interrupt,
1145		.set_wol	= gpy_set_wol,
1146		.get_wol	= gpy_get_wol,
1147		.set_loopback	= gpy_loopback,
1148		.led_brightness_set = gpy_led_brightness_set,
1149		.led_hw_is_supported = gpy_led_hw_is_supported,
1150		.led_hw_control_get = gpy_led_hw_control_get,
1151		.led_hw_control_set = gpy_led_hw_control_set,
1152		.led_polarity_set = gpy_led_polarity_set,
1153	},
1154	{
1155		PHY_ID_MATCH_MODEL(PHY_ID_GPY211C),
1156		.name		= "Maxlinear Ethernet GPY211C",
1157		.get_features	= genphy_c45_pma_read_abilities,
1158		.config_init	= gpy21x_config_init,
1159		.probe		= gpy_probe,
1160		.suspend	= genphy_suspend,
1161		.resume		= genphy_resume,
1162		.config_aneg	= gpy_config_aneg,
1163		.aneg_done	= genphy_c45_aneg_done,
1164		.read_status	= gpy_read_status,
1165		.config_intr	= gpy_config_intr,
1166		.handle_interrupt = gpy_handle_interrupt,
1167		.set_wol	= gpy_set_wol,
1168		.get_wol	= gpy_get_wol,
1169		.set_loopback	= gpy_loopback,
1170		.led_brightness_set = gpy_led_brightness_set,
1171		.led_hw_is_supported = gpy_led_hw_is_supported,
1172		.led_hw_control_get = gpy_led_hw_control_get,
1173		.led_hw_control_set = gpy_led_hw_control_set,
1174		.led_polarity_set = gpy_led_polarity_set,
1175	},
1176	{
1177		.phy_id		= PHY_ID_GPY212B,
1178		.phy_id_mask	= PHY_ID_GPY21xB_MASK,
1179		.name		= "Maxlinear Ethernet GPY212B",
1180		.get_features	= genphy_c45_pma_read_abilities,
1181		.config_init	= gpy21x_config_init,
1182		.probe		= gpy_probe,
1183		.suspend	= genphy_suspend,
1184		.resume		= genphy_resume,
1185		.config_aneg	= gpy_config_aneg,
1186		.aneg_done	= genphy_c45_aneg_done,
1187		.read_status	= gpy_read_status,
1188		.config_intr	= gpy_config_intr,
1189		.handle_interrupt = gpy_handle_interrupt,
1190		.set_wol	= gpy_set_wol,
1191		.get_wol	= gpy_get_wol,
1192		.set_loopback	= gpy_loopback,
1193		.led_brightness_set = gpy_led_brightness_set,
1194		.led_hw_is_supported = gpy_led_hw_is_supported,
1195		.led_hw_control_get = gpy_led_hw_control_get,
1196		.led_hw_control_set = gpy_led_hw_control_set,
1197		.led_polarity_set = gpy_led_polarity_set,
1198	},
1199	{
1200		PHY_ID_MATCH_MODEL(PHY_ID_GPY212C),
1201		.name		= "Maxlinear Ethernet GPY212C",
1202		.get_features	= genphy_c45_pma_read_abilities,
1203		.config_init	= gpy21x_config_init,
1204		.probe		= gpy_probe,
1205		.suspend	= genphy_suspend,
1206		.resume		= genphy_resume,
1207		.config_aneg	= gpy_config_aneg,
1208		.aneg_done	= genphy_c45_aneg_done,
1209		.read_status	= gpy_read_status,
1210		.config_intr	= gpy_config_intr,
1211		.handle_interrupt = gpy_handle_interrupt,
1212		.set_wol	= gpy_set_wol,
1213		.get_wol	= gpy_get_wol,
1214		.set_loopback	= gpy_loopback,
1215		.led_brightness_set = gpy_led_brightness_set,
1216		.led_hw_is_supported = gpy_led_hw_is_supported,
1217		.led_hw_control_get = gpy_led_hw_control_get,
1218		.led_hw_control_set = gpy_led_hw_control_set,
1219		.led_polarity_set = gpy_led_polarity_set,
1220	},
1221	{
1222		.phy_id		= PHY_ID_GPY215B,
1223		.phy_id_mask	= PHY_ID_GPYx15B_MASK,
1224		.name		= "Maxlinear Ethernet GPY215B",
1225		.get_features	= genphy_c45_pma_read_abilities,
1226		.config_init	= gpy21x_config_init,
1227		.probe		= gpy_probe,
1228		.suspend	= genphy_suspend,
1229		.resume		= genphy_resume,
1230		.config_aneg	= gpy_config_aneg,
1231		.aneg_done	= genphy_c45_aneg_done,
1232		.read_status	= gpy_read_status,
1233		.config_intr	= gpy_config_intr,
1234		.handle_interrupt = gpy_handle_interrupt,
1235		.set_wol	= gpy_set_wol,
1236		.get_wol	= gpy_get_wol,
1237		.set_loopback	= gpy_loopback,
1238		.led_brightness_set = gpy_led_brightness_set,
1239		.led_hw_is_supported = gpy_led_hw_is_supported,
1240		.led_hw_control_get = gpy_led_hw_control_get,
1241		.led_hw_control_set = gpy_led_hw_control_set,
1242		.led_polarity_set = gpy_led_polarity_set,
1243	},
1244	{
1245		PHY_ID_MATCH_MODEL(PHY_ID_GPY215C),
1246		.name		= "Maxlinear Ethernet GPY215C",
1247		.get_features	= genphy_c45_pma_read_abilities,
1248		.config_init	= gpy21x_config_init,
1249		.probe		= gpy_probe,
1250		.suspend	= genphy_suspend,
1251		.resume		= genphy_resume,
1252		.config_aneg	= gpy_config_aneg,
1253		.aneg_done	= genphy_c45_aneg_done,
1254		.read_status	= gpy_read_status,
1255		.config_intr	= gpy_config_intr,
1256		.handle_interrupt = gpy_handle_interrupt,
1257		.set_wol	= gpy_set_wol,
1258		.get_wol	= gpy_get_wol,
1259		.set_loopback	= gpy_loopback,
1260		.led_brightness_set = gpy_led_brightness_set,
1261		.led_hw_is_supported = gpy_led_hw_is_supported,
1262		.led_hw_control_get = gpy_led_hw_control_get,
1263		.led_hw_control_set = gpy_led_hw_control_set,
1264		.led_polarity_set = gpy_led_polarity_set,
1265	},
1266	{
1267		PHY_ID_MATCH_MODEL(PHY_ID_GPY241B),
1268		.name		= "Maxlinear Ethernet GPY241B",
1269		.get_features	= genphy_c45_pma_read_abilities,
1270		.config_init	= gpy_config_init,
1271		.probe		= gpy_probe,
1272		.suspend	= genphy_suspend,
1273		.resume		= genphy_resume,
1274		.config_aneg	= gpy_config_aneg,
1275		.aneg_done	= genphy_c45_aneg_done,
1276		.read_status	= gpy_read_status,
1277		.config_intr	= gpy_config_intr,
1278		.handle_interrupt = gpy_handle_interrupt,
1279		.set_wol	= gpy_set_wol,
1280		.get_wol	= gpy_get_wol,
1281		.set_loopback	= gpy_loopback,
1282	},
1283	{
1284		PHY_ID_MATCH_MODEL(PHY_ID_GPY241BM),
1285		.name		= "Maxlinear Ethernet GPY241BM",
1286		.get_features	= genphy_c45_pma_read_abilities,
1287		.config_init	= gpy_config_init,
1288		.probe		= gpy_probe,
1289		.suspend	= genphy_suspend,
1290		.resume		= genphy_resume,
1291		.config_aneg	= gpy_config_aneg,
1292		.aneg_done	= genphy_c45_aneg_done,
1293		.read_status	= gpy_read_status,
1294		.config_intr	= gpy_config_intr,
1295		.handle_interrupt = gpy_handle_interrupt,
1296		.set_wol	= gpy_set_wol,
1297		.get_wol	= gpy_get_wol,
1298		.set_loopback	= gpy_loopback,
1299	},
1300	{
1301		PHY_ID_MATCH_MODEL(PHY_ID_GPY245B),
1302		.name		= "Maxlinear Ethernet GPY245B",
1303		.get_features	= genphy_c45_pma_read_abilities,
1304		.config_init	= gpy_config_init,
1305		.probe		= gpy_probe,
1306		.suspend	= genphy_suspend,
1307		.resume		= genphy_resume,
1308		.config_aneg	= gpy_config_aneg,
1309		.aneg_done	= genphy_c45_aneg_done,
1310		.read_status	= gpy_read_status,
1311		.config_intr	= gpy_config_intr,
1312		.handle_interrupt = gpy_handle_interrupt,
1313		.set_wol	= gpy_set_wol,
1314		.get_wol	= gpy_get_wol,
1315		.set_loopback	= gpy_loopback,
1316	},
1317	{
1318		PHY_ID_MATCH_MODEL(PHY_ID_MXL86211C),
1319		.name		= "Maxlinear Ethernet MxL86211C",
1320		.get_features	= genphy_c45_pma_read_abilities,
1321		.config_init	= gpy_config_init,
1322		.probe		= gpy_probe,
1323		.suspend	= genphy_suspend,
1324		.resume		= genphy_resume,
1325		.config_aneg	= gpy_config_aneg,
1326		.aneg_done	= genphy_c45_aneg_done,
1327		.read_status	= gpy_read_status,
1328		.config_intr	= gpy_config_intr,
1329		.handle_interrupt = gpy_handle_interrupt,
1330		.set_wol	= gpy_set_wol,
1331		.get_wol	= gpy_get_wol,
1332		.set_loopback	= gpy_loopback,
1333		.led_brightness_set = gpy_led_brightness_set,
1334		.led_hw_is_supported = gpy_led_hw_is_supported,
1335		.led_hw_control_get = gpy_led_hw_control_get,
1336		.led_hw_control_set = gpy_led_hw_control_set,
1337		.led_polarity_set = gpy_led_polarity_set,
1338	},
1339	{
1340		PHY_ID_MATCH_MODEL(PHY_ID_MXL86252),
1341		.name		= "MaxLinear Ethernet MxL86252",
1342		.get_features	= genphy_c45_pma_read_abilities,
1343		.config_init	= gpy_config_init,
1344		.probe		= gpy_probe,
1345		.suspend	= genphy_suspend,
1346		.resume		= genphy_resume,
1347		.config_aneg	= gpy_config_aneg,
1348		.aneg_done	= genphy_c45_aneg_done,
1349		.read_status	= gpy_read_status,
1350		.config_intr	= gpy_config_intr,
1351		.handle_interrupt = gpy_handle_interrupt,
1352		.set_wol	= gpy_set_wol,
1353		.get_wol	= gpy_get_wol,
1354		.set_loopback	= gpy_loopback,
1355		.led_brightness_set = gpy_led_brightness_set,
1356		.led_hw_is_supported = gpy_led_hw_is_supported,
1357		.led_hw_control_get = gpy_led_hw_control_get,
1358		.led_hw_control_set = gpy_led_hw_control_set,
1359		.led_polarity_set = gpy_led_polarity_set,
1360	},
1361	{
1362		PHY_ID_MATCH_MODEL(PHY_ID_MXL86282),
1363		.name		= "MaxLinear Ethernet MxL86282",
1364		.get_features	= genphy_c45_pma_read_abilities,
1365		.config_init	= gpy_config_init,
1366		.probe		= gpy_probe,
1367		.suspend	= genphy_suspend,
1368		.resume		= genphy_resume,
1369		.config_aneg	= gpy_config_aneg,
1370		.aneg_done	= genphy_c45_aneg_done,
1371		.read_status	= gpy_read_status,
1372		.config_intr	= gpy_config_intr,
1373		.handle_interrupt = gpy_handle_interrupt,
1374		.set_wol	= gpy_set_wol,
1375		.get_wol	= gpy_get_wol,
1376		.set_loopback	= gpy_loopback,
1377		.led_brightness_set = gpy_led_brightness_set,
1378		.led_hw_is_supported = gpy_led_hw_is_supported,
1379		.led_hw_control_get = gpy_led_hw_control_get,
1380		.led_hw_control_set = gpy_led_hw_control_set,
1381		.led_polarity_set = gpy_led_polarity_set,
1382	},
1383};
1384module_phy_driver(gpy_drivers);
1385
1386static const struct mdio_device_id __maybe_unused gpy_tbl[] = {
1387	{PHY_ID_MATCH_MODEL(PHY_ID_GPY2xx)},
1388	{PHY_ID_GPY115B, PHY_ID_GPYx15B_MASK},
1389	{PHY_ID_MATCH_MODEL(PHY_ID_GPY115C)},
1390	{PHY_ID_GPY211B, PHY_ID_GPY21xB_MASK},
1391	{PHY_ID_MATCH_MODEL(PHY_ID_GPY211C)},
1392	{PHY_ID_GPY212B, PHY_ID_GPY21xB_MASK},
1393	{PHY_ID_MATCH_MODEL(PHY_ID_GPY212C)},
1394	{PHY_ID_GPY215B, PHY_ID_GPYx15B_MASK},
1395	{PHY_ID_MATCH_MODEL(PHY_ID_GPY215C)},
1396	{PHY_ID_MATCH_MODEL(PHY_ID_GPY241B)},
1397	{PHY_ID_MATCH_MODEL(PHY_ID_GPY241BM)},
1398	{PHY_ID_MATCH_MODEL(PHY_ID_GPY245B)},
1399	{PHY_ID_MATCH_MODEL(PHY_ID_MXL86211C)},
1400	{PHY_ID_MATCH_MODEL(PHY_ID_MXL86252)},
1401	{PHY_ID_MATCH_MODEL(PHY_ID_MXL86282)},
1402	{ }
1403};
1404MODULE_DEVICE_TABLE(mdio, gpy_tbl);
1405
1406MODULE_DESCRIPTION("Maxlinear Ethernet GPY Driver");
1407MODULE_AUTHOR("Xu Liang");
1408MODULE_LICENSE("GPL");
~/ Read-only file preview.