Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * Copyright (C) 2012 Daniel Schwierzeck <daniel.schwierzeck@googlemail.com>
0004  * Copyright (C) 2016 Hauke Mehrtens <hauke@hauke-m.de>
0005  */
0006 
0007 #include <linux/mdio.h>
0008 #include <linux/module.h>
0009 #include <linux/phy.h>
0010 #include <linux/of.h>
0011 #include <linux/bitfield.h>
0012 
0013 #define XWAY_MDIO_MIICTRL       0x17    /* mii control */
0014 #define XWAY_MDIO_IMASK         0x19    /* interrupt mask */
0015 #define XWAY_MDIO_ISTAT         0x1A    /* interrupt status */
0016 #define XWAY_MDIO_LED           0x1B    /* led control */
0017 
0018 #define XWAY_MDIO_MIICTRL_RXSKEW_MASK   GENMASK(14, 12)
0019 #define XWAY_MDIO_MIICTRL_TXSKEW_MASK   GENMASK(10, 8)
0020 
0021 /* bit 15:12 are reserved */
0022 #define XWAY_MDIO_LED_LED3_EN       BIT(11) /* Enable the integrated function of LED3 */
0023 #define XWAY_MDIO_LED_LED2_EN       BIT(10) /* Enable the integrated function of LED2 */
0024 #define XWAY_MDIO_LED_LED1_EN       BIT(9)  /* Enable the integrated function of LED1 */
0025 #define XWAY_MDIO_LED_LED0_EN       BIT(8)  /* Enable the integrated function of LED0 */
0026 /* bit 7:4 are reserved */
0027 #define XWAY_MDIO_LED_LED3_DA       BIT(3)  /* Direct Access to LED3 */
0028 #define XWAY_MDIO_LED_LED2_DA       BIT(2)  /* Direct Access to LED2 */
0029 #define XWAY_MDIO_LED_LED1_DA       BIT(1)  /* Direct Access to LED1 */
0030 #define XWAY_MDIO_LED_LED0_DA       BIT(0)  /* Direct Access to LED0 */
0031 
0032 #define XWAY_MDIO_INIT_WOL      BIT(15) /* Wake-On-LAN */
0033 #define XWAY_MDIO_INIT_MSRE     BIT(14)
0034 #define XWAY_MDIO_INIT_NPRX     BIT(13)
0035 #define XWAY_MDIO_INIT_NPTX     BIT(12)
0036 #define XWAY_MDIO_INIT_ANE      BIT(11) /* Auto-Neg error */
0037 #define XWAY_MDIO_INIT_ANC      BIT(10) /* Auto-Neg complete */
0038 #define XWAY_MDIO_INIT_ADSC     BIT(5)  /* Link auto-downspeed detect */
0039 #define XWAY_MDIO_INIT_MPIPC        BIT(4)
0040 #define XWAY_MDIO_INIT_MDIXC        BIT(3)
0041 #define XWAY_MDIO_INIT_DXMC     BIT(2)  /* Duplex mode change */
0042 #define XWAY_MDIO_INIT_LSPC     BIT(1)  /* Link speed change */
0043 #define XWAY_MDIO_INIT_LSTC     BIT(0)  /* Link state change */
0044 #define XWAY_MDIO_INIT_MASK     (XWAY_MDIO_INIT_LSTC | \
0045                      XWAY_MDIO_INIT_ADSC)
0046 
0047 #define ADVERTISED_MPD          BIT(10) /* Multi-port device */
0048 
0049 /* LED Configuration */
0050 #define XWAY_MMD_LEDCH          0x01E0
0051 /* Inverse of SCAN Function */
0052 #define  XWAY_MMD_LEDCH_NACS_NONE   0x0000
0053 #define  XWAY_MMD_LEDCH_NACS_LINK   0x0001
0054 #define  XWAY_MMD_LEDCH_NACS_PDOWN  0x0002
0055 #define  XWAY_MMD_LEDCH_NACS_EEE    0x0003
0056 #define  XWAY_MMD_LEDCH_NACS_ANEG   0x0004
0057 #define  XWAY_MMD_LEDCH_NACS_ABIST  0x0005
0058 #define  XWAY_MMD_LEDCH_NACS_CDIAG  0x0006
0059 #define  XWAY_MMD_LEDCH_NACS_TEST   0x0007
0060 /* Slow Blink Frequency */
0061 #define  XWAY_MMD_LEDCH_SBF_F02HZ   0x0000
0062 #define  XWAY_MMD_LEDCH_SBF_F04HZ   0x0010
0063 #define  XWAY_MMD_LEDCH_SBF_F08HZ   0x0020
0064 #define  XWAY_MMD_LEDCH_SBF_F16HZ   0x0030
0065 /* Fast Blink Frequency */
0066 #define  XWAY_MMD_LEDCH_FBF_F02HZ   0x0000
0067 #define  XWAY_MMD_LEDCH_FBF_F04HZ   0x0040
0068 #define  XWAY_MMD_LEDCH_FBF_F08HZ   0x0080
0069 #define  XWAY_MMD_LEDCH_FBF_F16HZ   0x00C0
0070 /* LED Configuration */
0071 #define XWAY_MMD_LEDCL          0x01E1
0072 /* Complex Blinking Configuration */
0073 #define  XWAY_MMD_LEDCH_CBLINK_NONE 0x0000
0074 #define  XWAY_MMD_LEDCH_CBLINK_LINK 0x0001
0075 #define  XWAY_MMD_LEDCH_CBLINK_PDOWN    0x0002
0076 #define  XWAY_MMD_LEDCH_CBLINK_EEE  0x0003
0077 #define  XWAY_MMD_LEDCH_CBLINK_ANEG 0x0004
0078 #define  XWAY_MMD_LEDCH_CBLINK_ABIST    0x0005
0079 #define  XWAY_MMD_LEDCH_CBLINK_CDIAG    0x0006
0080 #define  XWAY_MMD_LEDCH_CBLINK_TEST 0x0007
0081 /* Complex SCAN Configuration */
0082 #define  XWAY_MMD_LEDCH_SCAN_NONE   0x0000
0083 #define  XWAY_MMD_LEDCH_SCAN_LINK   0x0010
0084 #define  XWAY_MMD_LEDCH_SCAN_PDOWN  0x0020
0085 #define  XWAY_MMD_LEDCH_SCAN_EEE    0x0030
0086 #define  XWAY_MMD_LEDCH_SCAN_ANEG   0x0040
0087 #define  XWAY_MMD_LEDCH_SCAN_ABIST  0x0050
0088 #define  XWAY_MMD_LEDCH_SCAN_CDIAG  0x0060
0089 #define  XWAY_MMD_LEDCH_SCAN_TEST   0x0070
0090 /* Configuration for LED Pin x */
0091 #define XWAY_MMD_LED0H          0x01E2
0092 /* Fast Blinking Configuration */
0093 #define  XWAY_MMD_LEDxH_BLINKF_MASK 0x000F
0094 #define  XWAY_MMD_LEDxH_BLINKF_NONE 0x0000
0095 #define  XWAY_MMD_LEDxH_BLINKF_LINK10   0x0001
0096 #define  XWAY_MMD_LEDxH_BLINKF_LINK100  0x0002
0097 #define  XWAY_MMD_LEDxH_BLINKF_LINK10X  0x0003
0098 #define  XWAY_MMD_LEDxH_BLINKF_LINK1000 0x0004
0099 #define  XWAY_MMD_LEDxH_BLINKF_LINK10_0 0x0005
0100 #define  XWAY_MMD_LEDxH_BLINKF_LINK100X 0x0006
0101 #define  XWAY_MMD_LEDxH_BLINKF_LINK10XX 0x0007
0102 #define  XWAY_MMD_LEDxH_BLINKF_PDOWN    0x0008
0103 #define  XWAY_MMD_LEDxH_BLINKF_EEE  0x0009
0104 #define  XWAY_MMD_LEDxH_BLINKF_ANEG 0x000A
0105 #define  XWAY_MMD_LEDxH_BLINKF_ABIST    0x000B
0106 #define  XWAY_MMD_LEDxH_BLINKF_CDIAG    0x000C
0107 /* Constant On Configuration */
0108 #define  XWAY_MMD_LEDxH_CON_MASK    0x00F0
0109 #define  XWAY_MMD_LEDxH_CON_NONE    0x0000
0110 #define  XWAY_MMD_LEDxH_CON_LINK10  0x0010
0111 #define  XWAY_MMD_LEDxH_CON_LINK100 0x0020
0112 #define  XWAY_MMD_LEDxH_CON_LINK10X 0x0030
0113 #define  XWAY_MMD_LEDxH_CON_LINK1000    0x0040
0114 #define  XWAY_MMD_LEDxH_CON_LINK10_0    0x0050
0115 #define  XWAY_MMD_LEDxH_CON_LINK100X    0x0060
0116 #define  XWAY_MMD_LEDxH_CON_LINK10XX    0x0070
0117 #define  XWAY_MMD_LEDxH_CON_PDOWN   0x0080
0118 #define  XWAY_MMD_LEDxH_CON_EEE     0x0090
0119 #define  XWAY_MMD_LEDxH_CON_ANEG    0x00A0
0120 #define  XWAY_MMD_LEDxH_CON_ABIST   0x00B0
0121 #define  XWAY_MMD_LEDxH_CON_CDIAG   0x00C0
0122 #define  XWAY_MMD_LEDxH_CON_COPPER  0x00D0
0123 #define  XWAY_MMD_LEDxH_CON_FIBER   0x00E0
0124 /* Configuration for LED Pin x */
0125 #define XWAY_MMD_LED0L          0x01E3
0126 /* Pulsing Configuration */
0127 #define  XWAY_MMD_LEDxL_PULSE_MASK  0x000F
0128 #define  XWAY_MMD_LEDxL_PULSE_NONE  0x0000
0129 #define  XWAY_MMD_LEDxL_PULSE_TXACT 0x0001
0130 #define  XWAY_MMD_LEDxL_PULSE_RXACT 0x0002
0131 #define  XWAY_MMD_LEDxL_PULSE_COL   0x0004
0132 /* Slow Blinking Configuration */
0133 #define  XWAY_MMD_LEDxL_BLINKS_MASK 0x00F0
0134 #define  XWAY_MMD_LEDxL_BLINKS_NONE 0x0000
0135 #define  XWAY_MMD_LEDxL_BLINKS_LINK10   0x0010
0136 #define  XWAY_MMD_LEDxL_BLINKS_LINK100  0x0020
0137 #define  XWAY_MMD_LEDxL_BLINKS_LINK10X  0x0030
0138 #define  XWAY_MMD_LEDxL_BLINKS_LINK1000 0x0040
0139 #define  XWAY_MMD_LEDxL_BLINKS_LINK10_0 0x0050
0140 #define  XWAY_MMD_LEDxL_BLINKS_LINK100X 0x0060
0141 #define  XWAY_MMD_LEDxL_BLINKS_LINK10XX 0x0070
0142 #define  XWAY_MMD_LEDxL_BLINKS_PDOWN    0x0080
0143 #define  XWAY_MMD_LEDxL_BLINKS_EEE  0x0090
0144 #define  XWAY_MMD_LEDxL_BLINKS_ANEG 0x00A0
0145 #define  XWAY_MMD_LEDxL_BLINKS_ABIST    0x00B0
0146 #define  XWAY_MMD_LEDxL_BLINKS_CDIAG    0x00C0
0147 #define XWAY_MMD_LED1H          0x01E4
0148 #define XWAY_MMD_LED1L          0x01E5
0149 #define XWAY_MMD_LED2H          0x01E6
0150 #define XWAY_MMD_LED2L          0x01E7
0151 #define XWAY_MMD_LED3H          0x01E8
0152 #define XWAY_MMD_LED3L          0x01E9
0153 
0154 #define PHY_ID_PHY11G_1_3       0x030260D1
0155 #define PHY_ID_PHY22F_1_3       0x030260E1
0156 #define PHY_ID_PHY11G_1_4       0xD565A400
0157 #define PHY_ID_PHY22F_1_4       0xD565A410
0158 #define PHY_ID_PHY11G_1_5       0xD565A401
0159 #define PHY_ID_PHY22F_1_5       0xD565A411
0160 #define PHY_ID_PHY11G_VR9_1_1       0xD565A408
0161 #define PHY_ID_PHY22F_VR9_1_1       0xD565A418
0162 #define PHY_ID_PHY11G_VR9_1_2       0xD565A409
0163 #define PHY_ID_PHY22F_VR9_1_2       0xD565A419
0164 
0165 static const int xway_internal_delay[] = {0, 500, 1000, 1500, 2000, 2500,
0166                      3000, 3500};
0167 
0168 static int xway_gphy_rgmii_init(struct phy_device *phydev)
0169 {
0170     struct device *dev = &phydev->mdio.dev;
0171     unsigned int delay_size = ARRAY_SIZE(xway_internal_delay);
0172     s32 int_delay;
0173     int val = 0;
0174 
0175     if (!phy_interface_is_rgmii(phydev))
0176         return 0;
0177 
0178     /* Existing behavior was to use default pin strapping delay in rgmii
0179      * mode, but rgmii should have meant no delay.  Warn existing users,
0180      * but do not change anything at the moment.
0181      */
0182     if (phydev->interface == PHY_INTERFACE_MODE_RGMII) {
0183         u16 txskew, rxskew;
0184 
0185         val = phy_read(phydev, XWAY_MDIO_MIICTRL);
0186         if (val < 0)
0187             return val;
0188 
0189         txskew = FIELD_GET(XWAY_MDIO_MIICTRL_TXSKEW_MASK, val);
0190         rxskew = FIELD_GET(XWAY_MDIO_MIICTRL_RXSKEW_MASK, val);
0191 
0192         if (txskew > 0 || rxskew > 0)
0193             phydev_warn(phydev,
0194                     "PHY has delays (e.g. via pin strapping), but phy-mode = 'rgmii'\n"
0195                     "Should be 'rgmii-id' to use internal delays txskew:%d ps rxskew:%d ps\n",
0196                     xway_internal_delay[txskew],
0197                     xway_internal_delay[rxskew]);
0198         return 0;
0199     }
0200 
0201     if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
0202         phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
0203         int_delay = phy_get_internal_delay(phydev, dev,
0204                            xway_internal_delay,
0205                            delay_size, true);
0206 
0207         /* if rx-internal-delay-ps is missing, use default of 2.0 ns */
0208         if (int_delay < 0)
0209             int_delay = 4; /* 2000 ps */
0210 
0211         val |= FIELD_PREP(XWAY_MDIO_MIICTRL_RXSKEW_MASK, int_delay);
0212     }
0213 
0214     if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
0215         phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
0216         int_delay = phy_get_internal_delay(phydev, dev,
0217                            xway_internal_delay,
0218                            delay_size, false);
0219 
0220         /* if tx-internal-delay-ps is missing, use default of 2.0 ns */
0221         if (int_delay < 0)
0222             int_delay = 4; /* 2000 ps */
0223 
0224         val |= FIELD_PREP(XWAY_MDIO_MIICTRL_TXSKEW_MASK, int_delay);
0225     }
0226 
0227     return phy_modify(phydev, XWAY_MDIO_MIICTRL,
0228               XWAY_MDIO_MIICTRL_RXSKEW_MASK |
0229               XWAY_MDIO_MIICTRL_TXSKEW_MASK, val);
0230 }
0231 
0232 static int xway_gphy_config_init(struct phy_device *phydev)
0233 {
0234     int err;
0235     u32 ledxh;
0236     u32 ledxl;
0237 
0238     /* Mask all interrupts */
0239     err = phy_write(phydev, XWAY_MDIO_IMASK, 0);
0240     if (err)
0241         return err;
0242 
0243     /* Clear all pending interrupts */
0244     phy_read(phydev, XWAY_MDIO_ISTAT);
0245 
0246     /* Ensure that integrated led function is enabled for all leds */
0247     err = phy_write(phydev, XWAY_MDIO_LED,
0248             XWAY_MDIO_LED_LED0_EN |
0249             XWAY_MDIO_LED_LED1_EN |
0250             XWAY_MDIO_LED_LED2_EN |
0251             XWAY_MDIO_LED_LED3_EN);
0252     if (err)
0253         return err;
0254 
0255     phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LEDCH,
0256               XWAY_MMD_LEDCH_NACS_NONE |
0257               XWAY_MMD_LEDCH_SBF_F02HZ |
0258               XWAY_MMD_LEDCH_FBF_F16HZ);
0259     phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LEDCL,
0260               XWAY_MMD_LEDCH_CBLINK_NONE |
0261               XWAY_MMD_LEDCH_SCAN_NONE);
0262 
0263     /**
0264      * In most cases only one LED is connected to this phy, so
0265      * configure them all to constant on and pulse mode. LED3 is
0266      * only available in some packages, leave it in its reset
0267      * configuration.
0268      */
0269     ledxh = XWAY_MMD_LEDxH_BLINKF_NONE | XWAY_MMD_LEDxH_CON_LINK10XX;
0270     ledxl = XWAY_MMD_LEDxL_PULSE_TXACT | XWAY_MMD_LEDxL_PULSE_RXACT |
0271         XWAY_MMD_LEDxL_BLINKS_NONE;
0272     phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED0H, ledxh);
0273     phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED0L, ledxl);
0274     phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED1H, ledxh);
0275     phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED1L, ledxl);
0276     phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED2H, ledxh);
0277     phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED2L, ledxl);
0278 
0279     err = xway_gphy_rgmii_init(phydev);
0280     if (err)
0281         return err;
0282 
0283     return 0;
0284 }
0285 
0286 static int xway_gphy14_config_aneg(struct phy_device *phydev)
0287 {
0288     int reg, err;
0289 
0290     /* Advertise as multi-port device, see IEEE802.3-2002 40.5.1.1 */
0291     /* This is a workaround for an errata in rev < 1.5 devices */
0292     reg = phy_read(phydev, MII_CTRL1000);
0293     reg |= ADVERTISED_MPD;
0294     err = phy_write(phydev, MII_CTRL1000, reg);
0295     if (err)
0296         return err;
0297 
0298     return genphy_config_aneg(phydev);
0299 }
0300 
0301 static int xway_gphy_ack_interrupt(struct phy_device *phydev)
0302 {
0303     int reg;
0304 
0305     reg = phy_read(phydev, XWAY_MDIO_ISTAT);
0306     return (reg < 0) ? reg : 0;
0307 }
0308 
0309 static int xway_gphy_config_intr(struct phy_device *phydev)
0310 {
0311     u16 mask = 0;
0312     int err;
0313 
0314     if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
0315         err = xway_gphy_ack_interrupt(phydev);
0316         if (err)
0317             return err;
0318 
0319         mask = XWAY_MDIO_INIT_MASK;
0320         err = phy_write(phydev, XWAY_MDIO_IMASK, mask);
0321     } else {
0322         err = phy_write(phydev, XWAY_MDIO_IMASK, mask);
0323         if (err)
0324             return err;
0325 
0326         err = xway_gphy_ack_interrupt(phydev);
0327     }
0328 
0329     return err;
0330 }
0331 
0332 static irqreturn_t xway_gphy_handle_interrupt(struct phy_device *phydev)
0333 {
0334     int irq_status;
0335 
0336     irq_status = phy_read(phydev, XWAY_MDIO_ISTAT);
0337     if (irq_status < 0) {
0338         phy_error(phydev);
0339         return IRQ_NONE;
0340     }
0341 
0342     if (!(irq_status & XWAY_MDIO_INIT_MASK))
0343         return IRQ_NONE;
0344 
0345     phy_trigger_machine(phydev);
0346 
0347     return IRQ_HANDLED;
0348 }
0349 
0350 static struct phy_driver xway_gphy[] = {
0351     {
0352         .phy_id     = PHY_ID_PHY11G_1_3,
0353         .phy_id_mask    = 0xffffffff,
0354         .name       = "Intel XWAY PHY11G (PEF 7071/PEF 7072) v1.3",
0355         /* PHY_GBIT_FEATURES */
0356         .config_init    = xway_gphy_config_init,
0357         .config_aneg    = xway_gphy14_config_aneg,
0358         .handle_interrupt = xway_gphy_handle_interrupt,
0359         .config_intr    = xway_gphy_config_intr,
0360         .suspend    = genphy_suspend,
0361         .resume     = genphy_resume,
0362     }, {
0363         .phy_id     = PHY_ID_PHY22F_1_3,
0364         .phy_id_mask    = 0xffffffff,
0365         .name       = "Intel XWAY PHY22F (PEF 7061) v1.3",
0366         /* PHY_BASIC_FEATURES */
0367         .config_init    = xway_gphy_config_init,
0368         .config_aneg    = xway_gphy14_config_aneg,
0369         .handle_interrupt = xway_gphy_handle_interrupt,
0370         .config_intr    = xway_gphy_config_intr,
0371         .suspend    = genphy_suspend,
0372         .resume     = genphy_resume,
0373     }, {
0374         .phy_id     = PHY_ID_PHY11G_1_4,
0375         .phy_id_mask    = 0xffffffff,
0376         .name       = "Intel XWAY PHY11G (PEF 7071/PEF 7072) v1.4",
0377         /* PHY_GBIT_FEATURES */
0378         .config_init    = xway_gphy_config_init,
0379         .config_aneg    = xway_gphy14_config_aneg,
0380         .handle_interrupt = xway_gphy_handle_interrupt,
0381         .config_intr    = xway_gphy_config_intr,
0382         .suspend    = genphy_suspend,
0383         .resume     = genphy_resume,
0384     }, {
0385         .phy_id     = PHY_ID_PHY22F_1_4,
0386         .phy_id_mask    = 0xffffffff,
0387         .name       = "Intel XWAY PHY22F (PEF 7061) v1.4",
0388         /* PHY_BASIC_FEATURES */
0389         .config_init    = xway_gphy_config_init,
0390         .config_aneg    = xway_gphy14_config_aneg,
0391         .handle_interrupt = xway_gphy_handle_interrupt,
0392         .config_intr    = xway_gphy_config_intr,
0393         .suspend    = genphy_suspend,
0394         .resume     = genphy_resume,
0395     }, {
0396         .phy_id     = PHY_ID_PHY11G_1_5,
0397         .phy_id_mask    = 0xffffffff,
0398         .name       = "Intel XWAY PHY11G (PEF 7071/PEF 7072) v1.5 / v1.6",
0399         /* PHY_GBIT_FEATURES */
0400         .config_init    = xway_gphy_config_init,
0401         .handle_interrupt = xway_gphy_handle_interrupt,
0402         .config_intr    = xway_gphy_config_intr,
0403         .suspend    = genphy_suspend,
0404         .resume     = genphy_resume,
0405     }, {
0406         .phy_id     = PHY_ID_PHY22F_1_5,
0407         .phy_id_mask    = 0xffffffff,
0408         .name       = "Intel XWAY PHY22F (PEF 7061) v1.5 / v1.6",
0409         /* PHY_BASIC_FEATURES */
0410         .config_init    = xway_gphy_config_init,
0411         .handle_interrupt = xway_gphy_handle_interrupt,
0412         .config_intr    = xway_gphy_config_intr,
0413         .suspend    = genphy_suspend,
0414         .resume     = genphy_resume,
0415     }, {
0416         .phy_id     = PHY_ID_PHY11G_VR9_1_1,
0417         .phy_id_mask    = 0xffffffff,
0418         .name       = "Intel XWAY PHY11G (xRX v1.1 integrated)",
0419         /* PHY_GBIT_FEATURES */
0420         .config_init    = xway_gphy_config_init,
0421         .handle_interrupt = xway_gphy_handle_interrupt,
0422         .config_intr    = xway_gphy_config_intr,
0423         .suspend    = genphy_suspend,
0424         .resume     = genphy_resume,
0425     }, {
0426         .phy_id     = PHY_ID_PHY22F_VR9_1_1,
0427         .phy_id_mask    = 0xffffffff,
0428         .name       = "Intel XWAY PHY22F (xRX v1.1 integrated)",
0429         /* PHY_BASIC_FEATURES */
0430         .config_init    = xway_gphy_config_init,
0431         .handle_interrupt = xway_gphy_handle_interrupt,
0432         .config_intr    = xway_gphy_config_intr,
0433         .suspend    = genphy_suspend,
0434         .resume     = genphy_resume,
0435     }, {
0436         .phy_id     = PHY_ID_PHY11G_VR9_1_2,
0437         .phy_id_mask    = 0xffffffff,
0438         .name       = "Intel XWAY PHY11G (xRX v1.2 integrated)",
0439         /* PHY_GBIT_FEATURES */
0440         .config_init    = xway_gphy_config_init,
0441         .handle_interrupt = xway_gphy_handle_interrupt,
0442         .config_intr    = xway_gphy_config_intr,
0443         .suspend    = genphy_suspend,
0444         .resume     = genphy_resume,
0445     }, {
0446         .phy_id     = PHY_ID_PHY22F_VR9_1_2,
0447         .phy_id_mask    = 0xffffffff,
0448         .name       = "Intel XWAY PHY22F (xRX v1.2 integrated)",
0449         /* PHY_BASIC_FEATURES */
0450         .config_init    = xway_gphy_config_init,
0451         .handle_interrupt = xway_gphy_handle_interrupt,
0452         .config_intr    = xway_gphy_config_intr,
0453         .suspend    = genphy_suspend,
0454         .resume     = genphy_resume,
0455     },
0456 };
0457 module_phy_driver(xway_gphy);
0458 
0459 static struct mdio_device_id __maybe_unused xway_gphy_tbl[] = {
0460     { PHY_ID_PHY11G_1_3, 0xffffffff },
0461     { PHY_ID_PHY22F_1_3, 0xffffffff },
0462     { PHY_ID_PHY11G_1_4, 0xffffffff },
0463     { PHY_ID_PHY22F_1_4, 0xffffffff },
0464     { PHY_ID_PHY11G_1_5, 0xffffffff },
0465     { PHY_ID_PHY22F_1_5, 0xffffffff },
0466     { PHY_ID_PHY11G_VR9_1_1, 0xffffffff },
0467     { PHY_ID_PHY22F_VR9_1_1, 0xffffffff },
0468     { PHY_ID_PHY11G_VR9_1_2, 0xffffffff },
0469     { PHY_ID_PHY22F_VR9_1_2, 0xffffffff },
0470     { }
0471 };
0472 MODULE_DEVICE_TABLE(mdio, xway_gphy_tbl);
0473 
0474 MODULE_DESCRIPTION("Intel XWAY PHY driver");
0475 MODULE_LICENSE("GPL");