cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

intel-xway.c (15747B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 * Copyright (C) 2012 Daniel Schwierzeck <daniel.schwierzeck@googlemail.com>
      4 * Copyright (C) 2016 Hauke Mehrtens <hauke@hauke-m.de>
      5 */
      6
      7#include <linux/mdio.h>
      8#include <linux/module.h>
      9#include <linux/phy.h>
     10#include <linux/of.h>
     11#include <linux/bitfield.h>
     12
     13#define XWAY_MDIO_MIICTRL		0x17	/* mii control */
     14#define XWAY_MDIO_IMASK			0x19	/* interrupt mask */
     15#define XWAY_MDIO_ISTAT			0x1A	/* interrupt status */
     16#define XWAY_MDIO_LED			0x1B	/* led control */
     17
     18#define XWAY_MDIO_MIICTRL_RXSKEW_MASK	GENMASK(14, 12)
     19#define XWAY_MDIO_MIICTRL_TXSKEW_MASK	GENMASK(10, 8)
     20
     21/* bit 15:12 are reserved */
     22#define XWAY_MDIO_LED_LED3_EN		BIT(11)	/* Enable the integrated function of LED3 */
     23#define XWAY_MDIO_LED_LED2_EN		BIT(10)	/* Enable the integrated function of LED2 */
     24#define XWAY_MDIO_LED_LED1_EN		BIT(9)	/* Enable the integrated function of LED1 */
     25#define XWAY_MDIO_LED_LED0_EN		BIT(8)	/* Enable the integrated function of LED0 */
     26/* bit 7:4 are reserved */
     27#define XWAY_MDIO_LED_LED3_DA		BIT(3)	/* Direct Access to LED3 */
     28#define XWAY_MDIO_LED_LED2_DA		BIT(2)	/* Direct Access to LED2 */
     29#define XWAY_MDIO_LED_LED1_DA		BIT(1)	/* Direct Access to LED1 */
     30#define XWAY_MDIO_LED_LED0_DA		BIT(0)	/* Direct Access to LED0 */
     31
     32#define XWAY_MDIO_INIT_WOL		BIT(15)	/* Wake-On-LAN */
     33#define XWAY_MDIO_INIT_MSRE		BIT(14)
     34#define XWAY_MDIO_INIT_NPRX		BIT(13)
     35#define XWAY_MDIO_INIT_NPTX		BIT(12)
     36#define XWAY_MDIO_INIT_ANE		BIT(11)	/* Auto-Neg error */
     37#define XWAY_MDIO_INIT_ANC		BIT(10)	/* Auto-Neg complete */
     38#define XWAY_MDIO_INIT_ADSC		BIT(5)	/* Link auto-downspeed detect */
     39#define XWAY_MDIO_INIT_MPIPC		BIT(4)
     40#define XWAY_MDIO_INIT_MDIXC		BIT(3)
     41#define XWAY_MDIO_INIT_DXMC		BIT(2)	/* Duplex mode change */
     42#define XWAY_MDIO_INIT_LSPC		BIT(1)	/* Link speed change */
     43#define XWAY_MDIO_INIT_LSTC		BIT(0)	/* Link state change */
     44#define XWAY_MDIO_INIT_MASK		(XWAY_MDIO_INIT_LSTC | \
     45					 XWAY_MDIO_INIT_ADSC)
     46
     47#define ADVERTISED_MPD			BIT(10)	/* Multi-port device */
     48
     49/* LED Configuration */
     50#define XWAY_MMD_LEDCH			0x01E0
     51/* Inverse of SCAN Function */
     52#define  XWAY_MMD_LEDCH_NACS_NONE	0x0000
     53#define  XWAY_MMD_LEDCH_NACS_LINK	0x0001
     54#define  XWAY_MMD_LEDCH_NACS_PDOWN	0x0002
     55#define  XWAY_MMD_LEDCH_NACS_EEE	0x0003
     56#define  XWAY_MMD_LEDCH_NACS_ANEG	0x0004
     57#define  XWAY_MMD_LEDCH_NACS_ABIST	0x0005
     58#define  XWAY_MMD_LEDCH_NACS_CDIAG	0x0006
     59#define  XWAY_MMD_LEDCH_NACS_TEST	0x0007
     60/* Slow Blink Frequency */
     61#define  XWAY_MMD_LEDCH_SBF_F02HZ	0x0000
     62#define  XWAY_MMD_LEDCH_SBF_F04HZ	0x0010
     63#define  XWAY_MMD_LEDCH_SBF_F08HZ	0x0020
     64#define  XWAY_MMD_LEDCH_SBF_F16HZ	0x0030
     65/* Fast Blink Frequency */
     66#define  XWAY_MMD_LEDCH_FBF_F02HZ	0x0000
     67#define  XWAY_MMD_LEDCH_FBF_F04HZ	0x0040
     68#define  XWAY_MMD_LEDCH_FBF_F08HZ	0x0080
     69#define  XWAY_MMD_LEDCH_FBF_F16HZ	0x00C0
     70/* LED Configuration */
     71#define XWAY_MMD_LEDCL			0x01E1
     72/* Complex Blinking Configuration */
     73#define  XWAY_MMD_LEDCH_CBLINK_NONE	0x0000
     74#define  XWAY_MMD_LEDCH_CBLINK_LINK	0x0001
     75#define  XWAY_MMD_LEDCH_CBLINK_PDOWN	0x0002
     76#define  XWAY_MMD_LEDCH_CBLINK_EEE	0x0003
     77#define  XWAY_MMD_LEDCH_CBLINK_ANEG	0x0004
     78#define  XWAY_MMD_LEDCH_CBLINK_ABIST	0x0005
     79#define  XWAY_MMD_LEDCH_CBLINK_CDIAG	0x0006
     80#define  XWAY_MMD_LEDCH_CBLINK_TEST	0x0007
     81/* Complex SCAN Configuration */
     82#define  XWAY_MMD_LEDCH_SCAN_NONE	0x0000
     83#define  XWAY_MMD_LEDCH_SCAN_LINK	0x0010
     84#define  XWAY_MMD_LEDCH_SCAN_PDOWN	0x0020
     85#define  XWAY_MMD_LEDCH_SCAN_EEE	0x0030
     86#define  XWAY_MMD_LEDCH_SCAN_ANEG	0x0040
     87#define  XWAY_MMD_LEDCH_SCAN_ABIST	0x0050
     88#define  XWAY_MMD_LEDCH_SCAN_CDIAG	0x0060
     89#define  XWAY_MMD_LEDCH_SCAN_TEST	0x0070
     90/* Configuration for LED Pin x */
     91#define XWAY_MMD_LED0H			0x01E2
     92/* Fast Blinking Configuration */
     93#define  XWAY_MMD_LEDxH_BLINKF_MASK	0x000F
     94#define  XWAY_MMD_LEDxH_BLINKF_NONE	0x0000
     95#define  XWAY_MMD_LEDxH_BLINKF_LINK10	0x0001
     96#define  XWAY_MMD_LEDxH_BLINKF_LINK100	0x0002
     97#define  XWAY_MMD_LEDxH_BLINKF_LINK10X	0x0003
     98#define  XWAY_MMD_LEDxH_BLINKF_LINK1000	0x0004
     99#define  XWAY_MMD_LEDxH_BLINKF_LINK10_0	0x0005
    100#define  XWAY_MMD_LEDxH_BLINKF_LINK100X	0x0006
    101#define  XWAY_MMD_LEDxH_BLINKF_LINK10XX	0x0007
    102#define  XWAY_MMD_LEDxH_BLINKF_PDOWN	0x0008
    103#define  XWAY_MMD_LEDxH_BLINKF_EEE	0x0009
    104#define  XWAY_MMD_LEDxH_BLINKF_ANEG	0x000A
    105#define  XWAY_MMD_LEDxH_BLINKF_ABIST	0x000B
    106#define  XWAY_MMD_LEDxH_BLINKF_CDIAG	0x000C
    107/* Constant On Configuration */
    108#define  XWAY_MMD_LEDxH_CON_MASK	0x00F0
    109#define  XWAY_MMD_LEDxH_CON_NONE	0x0000
    110#define  XWAY_MMD_LEDxH_CON_LINK10	0x0010
    111#define  XWAY_MMD_LEDxH_CON_LINK100	0x0020
    112#define  XWAY_MMD_LEDxH_CON_LINK10X	0x0030
    113#define  XWAY_MMD_LEDxH_CON_LINK1000	0x0040
    114#define  XWAY_MMD_LEDxH_CON_LINK10_0	0x0050
    115#define  XWAY_MMD_LEDxH_CON_LINK100X	0x0060
    116#define  XWAY_MMD_LEDxH_CON_LINK10XX	0x0070
    117#define  XWAY_MMD_LEDxH_CON_PDOWN	0x0080
    118#define  XWAY_MMD_LEDxH_CON_EEE		0x0090
    119#define  XWAY_MMD_LEDxH_CON_ANEG	0x00A0
    120#define  XWAY_MMD_LEDxH_CON_ABIST	0x00B0
    121#define  XWAY_MMD_LEDxH_CON_CDIAG	0x00C0
    122#define  XWAY_MMD_LEDxH_CON_COPPER	0x00D0
    123#define  XWAY_MMD_LEDxH_CON_FIBER	0x00E0
    124/* Configuration for LED Pin x */
    125#define XWAY_MMD_LED0L			0x01E3
    126/* Pulsing Configuration */
    127#define  XWAY_MMD_LEDxL_PULSE_MASK	0x000F
    128#define  XWAY_MMD_LEDxL_PULSE_NONE	0x0000
    129#define  XWAY_MMD_LEDxL_PULSE_TXACT	0x0001
    130#define  XWAY_MMD_LEDxL_PULSE_RXACT	0x0002
    131#define  XWAY_MMD_LEDxL_PULSE_COL	0x0004
    132/* Slow Blinking Configuration */
    133#define  XWAY_MMD_LEDxL_BLINKS_MASK	0x00F0
    134#define  XWAY_MMD_LEDxL_BLINKS_NONE	0x0000
    135#define  XWAY_MMD_LEDxL_BLINKS_LINK10	0x0010
    136#define  XWAY_MMD_LEDxL_BLINKS_LINK100	0x0020
    137#define  XWAY_MMD_LEDxL_BLINKS_LINK10X	0x0030
    138#define  XWAY_MMD_LEDxL_BLINKS_LINK1000	0x0040
    139#define  XWAY_MMD_LEDxL_BLINKS_LINK10_0	0x0050
    140#define  XWAY_MMD_LEDxL_BLINKS_LINK100X	0x0060
    141#define  XWAY_MMD_LEDxL_BLINKS_LINK10XX	0x0070
    142#define  XWAY_MMD_LEDxL_BLINKS_PDOWN	0x0080
    143#define  XWAY_MMD_LEDxL_BLINKS_EEE	0x0090
    144#define  XWAY_MMD_LEDxL_BLINKS_ANEG	0x00A0
    145#define  XWAY_MMD_LEDxL_BLINKS_ABIST	0x00B0
    146#define  XWAY_MMD_LEDxL_BLINKS_CDIAG	0x00C0
    147#define XWAY_MMD_LED1H			0x01E4
    148#define XWAY_MMD_LED1L			0x01E5
    149#define XWAY_MMD_LED2H			0x01E6
    150#define XWAY_MMD_LED2L			0x01E7
    151#define XWAY_MMD_LED3H			0x01E8
    152#define XWAY_MMD_LED3L			0x01E9
    153
    154#define PHY_ID_PHY11G_1_3		0x030260D1
    155#define PHY_ID_PHY22F_1_3		0x030260E1
    156#define PHY_ID_PHY11G_1_4		0xD565A400
    157#define PHY_ID_PHY22F_1_4		0xD565A410
    158#define PHY_ID_PHY11G_1_5		0xD565A401
    159#define PHY_ID_PHY22F_1_5		0xD565A411
    160#define PHY_ID_PHY11G_VR9_1_1		0xD565A408
    161#define PHY_ID_PHY22F_VR9_1_1		0xD565A418
    162#define PHY_ID_PHY11G_VR9_1_2		0xD565A409
    163#define PHY_ID_PHY22F_VR9_1_2		0xD565A419
    164
    165static const int xway_internal_delay[] = {0, 500, 1000, 1500, 2000, 2500,
    166					 3000, 3500};
    167
    168static int xway_gphy_rgmii_init(struct phy_device *phydev)
    169{
    170	struct device *dev = &phydev->mdio.dev;
    171	unsigned int delay_size = ARRAY_SIZE(xway_internal_delay);
    172	s32 int_delay;
    173	int val = 0;
    174
    175	if (!phy_interface_is_rgmii(phydev))
    176		return 0;
    177
    178	/* Existing behavior was to use default pin strapping delay in rgmii
    179	 * mode, but rgmii should have meant no delay.  Warn existing users,
    180	 * but do not change anything at the moment.
    181	 */
    182	if (phydev->interface == PHY_INTERFACE_MODE_RGMII) {
    183		u16 txskew, rxskew;
    184
    185		val = phy_read(phydev, XWAY_MDIO_MIICTRL);
    186		if (val < 0)
    187			return val;
    188
    189		txskew = FIELD_GET(XWAY_MDIO_MIICTRL_TXSKEW_MASK, val);
    190		rxskew = FIELD_GET(XWAY_MDIO_MIICTRL_RXSKEW_MASK, val);
    191
    192		if (txskew > 0 || rxskew > 0)
    193			phydev_warn(phydev,
    194				    "PHY has delays (e.g. via pin strapping), but phy-mode = 'rgmii'\n"
    195				    "Should be 'rgmii-id' to use internal delays txskew:%d ps rxskew:%d ps\n",
    196				    xway_internal_delay[txskew],
    197				    xway_internal_delay[rxskew]);
    198		return 0;
    199	}
    200
    201	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
    202	    phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
    203		int_delay = phy_get_internal_delay(phydev, dev,
    204						   xway_internal_delay,
    205						   delay_size, true);
    206
    207		/* if rx-internal-delay-ps is missing, use default of 2.0 ns */
    208		if (int_delay < 0)
    209			int_delay = 4; /* 2000 ps */
    210
    211		val |= FIELD_PREP(XWAY_MDIO_MIICTRL_RXSKEW_MASK, int_delay);
    212	}
    213
    214	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
    215	    phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
    216		int_delay = phy_get_internal_delay(phydev, dev,
    217						   xway_internal_delay,
    218						   delay_size, false);
    219
    220		/* if tx-internal-delay-ps is missing, use default of 2.0 ns */
    221		if (int_delay < 0)
    222			int_delay = 4; /* 2000 ps */
    223
    224		val |= FIELD_PREP(XWAY_MDIO_MIICTRL_TXSKEW_MASK, int_delay);
    225	}
    226
    227	return phy_modify(phydev, XWAY_MDIO_MIICTRL,
    228			  XWAY_MDIO_MIICTRL_RXSKEW_MASK |
    229			  XWAY_MDIO_MIICTRL_TXSKEW_MASK, val);
    230}
    231
    232static int xway_gphy_config_init(struct phy_device *phydev)
    233{
    234	int err;
    235	u32 ledxh;
    236	u32 ledxl;
    237
    238	/* Mask all interrupts */
    239	err = phy_write(phydev, XWAY_MDIO_IMASK, 0);
    240	if (err)
    241		return err;
    242
    243	/* Clear all pending interrupts */
    244	phy_read(phydev, XWAY_MDIO_ISTAT);
    245
    246	/* Ensure that integrated led function is enabled for all leds */
    247	err = phy_write(phydev, XWAY_MDIO_LED,
    248			XWAY_MDIO_LED_LED0_EN |
    249			XWAY_MDIO_LED_LED1_EN |
    250			XWAY_MDIO_LED_LED2_EN |
    251			XWAY_MDIO_LED_LED3_EN);
    252	if (err)
    253		return err;
    254
    255	phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LEDCH,
    256		      XWAY_MMD_LEDCH_NACS_NONE |
    257		      XWAY_MMD_LEDCH_SBF_F02HZ |
    258		      XWAY_MMD_LEDCH_FBF_F16HZ);
    259	phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LEDCL,
    260		      XWAY_MMD_LEDCH_CBLINK_NONE |
    261		      XWAY_MMD_LEDCH_SCAN_NONE);
    262
    263	/**
    264	 * In most cases only one LED is connected to this phy, so
    265	 * configure them all to constant on and pulse mode. LED3 is
    266	 * only available in some packages, leave it in its reset
    267	 * configuration.
    268	 */
    269	ledxh = XWAY_MMD_LEDxH_BLINKF_NONE | XWAY_MMD_LEDxH_CON_LINK10XX;
    270	ledxl = XWAY_MMD_LEDxL_PULSE_TXACT | XWAY_MMD_LEDxL_PULSE_RXACT |
    271		XWAY_MMD_LEDxL_BLINKS_NONE;
    272	phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED0H, ledxh);
    273	phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED0L, ledxl);
    274	phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED1H, ledxh);
    275	phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED1L, ledxl);
    276	phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED2H, ledxh);
    277	phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED2L, ledxl);
    278
    279	err = xway_gphy_rgmii_init(phydev);
    280	if (err)
    281		return err;
    282
    283	return 0;
    284}
    285
    286static int xway_gphy14_config_aneg(struct phy_device *phydev)
    287{
    288	int reg, err;
    289
    290	/* Advertise as multi-port device, see IEEE802.3-2002 40.5.1.1 */
    291	/* This is a workaround for an errata in rev < 1.5 devices */
    292	reg = phy_read(phydev, MII_CTRL1000);
    293	reg |= ADVERTISED_MPD;
    294	err = phy_write(phydev, MII_CTRL1000, reg);
    295	if (err)
    296		return err;
    297
    298	return genphy_config_aneg(phydev);
    299}
    300
    301static int xway_gphy_ack_interrupt(struct phy_device *phydev)
    302{
    303	int reg;
    304
    305	reg = phy_read(phydev, XWAY_MDIO_ISTAT);
    306	return (reg < 0) ? reg : 0;
    307}
    308
    309static int xway_gphy_config_intr(struct phy_device *phydev)
    310{
    311	u16 mask = 0;
    312	int err;
    313
    314	if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
    315		err = xway_gphy_ack_interrupt(phydev);
    316		if (err)
    317			return err;
    318
    319		mask = XWAY_MDIO_INIT_MASK;
    320		err = phy_write(phydev, XWAY_MDIO_IMASK, mask);
    321	} else {
    322		err = phy_write(phydev, XWAY_MDIO_IMASK, mask);
    323		if (err)
    324			return err;
    325
    326		err = xway_gphy_ack_interrupt(phydev);
    327	}
    328
    329	return err;
    330}
    331
    332static irqreturn_t xway_gphy_handle_interrupt(struct phy_device *phydev)
    333{
    334	int irq_status;
    335
    336	irq_status = phy_read(phydev, XWAY_MDIO_ISTAT);
    337	if (irq_status < 0) {
    338		phy_error(phydev);
    339		return IRQ_NONE;
    340	}
    341
    342	if (!(irq_status & XWAY_MDIO_INIT_MASK))
    343		return IRQ_NONE;
    344
    345	phy_trigger_machine(phydev);
    346
    347	return IRQ_HANDLED;
    348}
    349
    350static struct phy_driver xway_gphy[] = {
    351	{
    352		.phy_id		= PHY_ID_PHY11G_1_3,
    353		.phy_id_mask	= 0xffffffff,
    354		.name		= "Intel XWAY PHY11G (PEF 7071/PEF 7072) v1.3",
    355		/* PHY_GBIT_FEATURES */
    356		.config_init	= xway_gphy_config_init,
    357		.config_aneg	= xway_gphy14_config_aneg,
    358		.handle_interrupt = xway_gphy_handle_interrupt,
    359		.config_intr	= xway_gphy_config_intr,
    360		.suspend	= genphy_suspend,
    361		.resume		= genphy_resume,
    362	}, {
    363		.phy_id		= PHY_ID_PHY22F_1_3,
    364		.phy_id_mask	= 0xffffffff,
    365		.name		= "Intel XWAY PHY22F (PEF 7061) v1.3",
    366		/* PHY_BASIC_FEATURES */
    367		.config_init	= xway_gphy_config_init,
    368		.config_aneg	= xway_gphy14_config_aneg,
    369		.handle_interrupt = xway_gphy_handle_interrupt,
    370		.config_intr	= xway_gphy_config_intr,
    371		.suspend	= genphy_suspend,
    372		.resume		= genphy_resume,
    373	}, {
    374		.phy_id		= PHY_ID_PHY11G_1_4,
    375		.phy_id_mask	= 0xffffffff,
    376		.name		= "Intel XWAY PHY11G (PEF 7071/PEF 7072) v1.4",
    377		/* PHY_GBIT_FEATURES */
    378		.config_init	= xway_gphy_config_init,
    379		.config_aneg	= xway_gphy14_config_aneg,
    380		.handle_interrupt = xway_gphy_handle_interrupt,
    381		.config_intr	= xway_gphy_config_intr,
    382		.suspend	= genphy_suspend,
    383		.resume		= genphy_resume,
    384	}, {
    385		.phy_id		= PHY_ID_PHY22F_1_4,
    386		.phy_id_mask	= 0xffffffff,
    387		.name		= "Intel XWAY PHY22F (PEF 7061) v1.4",
    388		/* PHY_BASIC_FEATURES */
    389		.config_init	= xway_gphy_config_init,
    390		.config_aneg	= xway_gphy14_config_aneg,
    391		.handle_interrupt = xway_gphy_handle_interrupt,
    392		.config_intr	= xway_gphy_config_intr,
    393		.suspend	= genphy_suspend,
    394		.resume		= genphy_resume,
    395	}, {
    396		.phy_id		= PHY_ID_PHY11G_1_5,
    397		.phy_id_mask	= 0xffffffff,
    398		.name		= "Intel XWAY PHY11G (PEF 7071/PEF 7072) v1.5 / v1.6",
    399		/* PHY_GBIT_FEATURES */
    400		.config_init	= xway_gphy_config_init,
    401		.handle_interrupt = xway_gphy_handle_interrupt,
    402		.config_intr	= xway_gphy_config_intr,
    403		.suspend	= genphy_suspend,
    404		.resume		= genphy_resume,
    405	}, {
    406		.phy_id		= PHY_ID_PHY22F_1_5,
    407		.phy_id_mask	= 0xffffffff,
    408		.name		= "Intel XWAY PHY22F (PEF 7061) v1.5 / v1.6",
    409		/* PHY_BASIC_FEATURES */
    410		.config_init	= xway_gphy_config_init,
    411		.handle_interrupt = xway_gphy_handle_interrupt,
    412		.config_intr	= xway_gphy_config_intr,
    413		.suspend	= genphy_suspend,
    414		.resume		= genphy_resume,
    415	}, {
    416		.phy_id		= PHY_ID_PHY11G_VR9_1_1,
    417		.phy_id_mask	= 0xffffffff,
    418		.name		= "Intel XWAY PHY11G (xRX v1.1 integrated)",
    419		/* PHY_GBIT_FEATURES */
    420		.config_init	= xway_gphy_config_init,
    421		.handle_interrupt = xway_gphy_handle_interrupt,
    422		.config_intr	= xway_gphy_config_intr,
    423		.suspend	= genphy_suspend,
    424		.resume		= genphy_resume,
    425	}, {
    426		.phy_id		= PHY_ID_PHY22F_VR9_1_1,
    427		.phy_id_mask	= 0xffffffff,
    428		.name		= "Intel XWAY PHY22F (xRX v1.1 integrated)",
    429		/* PHY_BASIC_FEATURES */
    430		.config_init	= xway_gphy_config_init,
    431		.handle_interrupt = xway_gphy_handle_interrupt,
    432		.config_intr	= xway_gphy_config_intr,
    433		.suspend	= genphy_suspend,
    434		.resume		= genphy_resume,
    435	}, {
    436		.phy_id		= PHY_ID_PHY11G_VR9_1_2,
    437		.phy_id_mask	= 0xffffffff,
    438		.name		= "Intel XWAY PHY11G (xRX v1.2 integrated)",
    439		/* PHY_GBIT_FEATURES */
    440		.config_init	= xway_gphy_config_init,
    441		.handle_interrupt = xway_gphy_handle_interrupt,
    442		.config_intr	= xway_gphy_config_intr,
    443		.suspend	= genphy_suspend,
    444		.resume		= genphy_resume,
    445	}, {
    446		.phy_id		= PHY_ID_PHY22F_VR9_1_2,
    447		.phy_id_mask	= 0xffffffff,
    448		.name		= "Intel XWAY PHY22F (xRX v1.2 integrated)",
    449		/* PHY_BASIC_FEATURES */
    450		.config_init	= xway_gphy_config_init,
    451		.handle_interrupt = xway_gphy_handle_interrupt,
    452		.config_intr	= xway_gphy_config_intr,
    453		.suspend	= genphy_suspend,
    454		.resume		= genphy_resume,
    455	},
    456};
    457module_phy_driver(xway_gphy);
    458
    459static struct mdio_device_id __maybe_unused xway_gphy_tbl[] = {
    460	{ PHY_ID_PHY11G_1_3, 0xffffffff },
    461	{ PHY_ID_PHY22F_1_3, 0xffffffff },
    462	{ PHY_ID_PHY11G_1_4, 0xffffffff },
    463	{ PHY_ID_PHY22F_1_4, 0xffffffff },
    464	{ PHY_ID_PHY11G_1_5, 0xffffffff },
    465	{ PHY_ID_PHY22F_1_5, 0xffffffff },
    466	{ PHY_ID_PHY11G_VR9_1_1, 0xffffffff },
    467	{ PHY_ID_PHY22F_VR9_1_1, 0xffffffff },
    468	{ PHY_ID_PHY11G_VR9_1_2, 0xffffffff },
    469	{ PHY_ID_PHY22F_VR9_1_2, 0xffffffff },
    470	{ }
    471};
    472MODULE_DEVICE_TABLE(mdio, xway_gphy_tbl);
    473
    474MODULE_DESCRIPTION("Intel XWAY PHY driver");
    475MODULE_LICENSE("GPL");