root/drivers/net/phy/dp83867.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dp83867_ack_interrupt
  2. dp83867_config_intr
  3. dp83867_config_port_mirroring
  4. dp83867_of_init
  5. dp83867_of_init
  6. dp83867_probe
  7. dp83867_config_init
  8. dp83867_phy_reset

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Driver for the Texas Instruments DP83867 PHY
   4  *
   5  * Copyright (C) 2015 Texas Instruments Inc.
   6  */
   7 
   8 #include <linux/ethtool.h>
   9 #include <linux/kernel.h>
  10 #include <linux/mii.h>
  11 #include <linux/module.h>
  12 #include <linux/of.h>
  13 #include <linux/phy.h>
  14 #include <linux/delay.h>
  15 
  16 #include <dt-bindings/net/ti-dp83867.h>
  17 
  18 #define DP83867_PHY_ID          0x2000a231
  19 #define DP83867_DEVADDR         0x1f
  20 
  21 #define MII_DP83867_PHYCTRL     0x10
  22 #define MII_DP83867_MICR        0x12
  23 #define MII_DP83867_ISR         0x13
  24 #define DP83867_CTRL            0x1f
  25 #define DP83867_CFG3            0x1e
  26 
  27 /* Extended Registers */
  28 #define DP83867_FLD_THR_CFG     0x002e
  29 #define DP83867_CFG4            0x0031
  30 #define DP83867_CFG4_SGMII_ANEG_MASK (BIT(5) | BIT(6))
  31 #define DP83867_CFG4_SGMII_ANEG_TIMER_11MS   (3 << 5)
  32 #define DP83867_CFG4_SGMII_ANEG_TIMER_800US  (2 << 5)
  33 #define DP83867_CFG4_SGMII_ANEG_TIMER_2US    (1 << 5)
  34 #define DP83867_CFG4_SGMII_ANEG_TIMER_16MS   (0 << 5)
  35 
  36 #define DP83867_RGMIICTL        0x0032
  37 #define DP83867_STRAP_STS1      0x006E
  38 #define DP83867_STRAP_STS2      0x006f
  39 #define DP83867_RGMIIDCTL       0x0086
  40 #define DP83867_IO_MUX_CFG      0x0170
  41 #define DP83867_SGMIICTL        0x00D3
  42 #define DP83867_10M_SGMII_CFG   0x016F
  43 #define DP83867_10M_SGMII_RATE_ADAPT_MASK BIT(7)
  44 
  45 #define DP83867_SW_RESET        BIT(15)
  46 #define DP83867_SW_RESTART      BIT(14)
  47 
  48 /* MICR Interrupt bits */
  49 #define MII_DP83867_MICR_AN_ERR_INT_EN          BIT(15)
  50 #define MII_DP83867_MICR_SPEED_CHNG_INT_EN      BIT(14)
  51 #define MII_DP83867_MICR_DUP_MODE_CHNG_INT_EN   BIT(13)
  52 #define MII_DP83867_MICR_PAGE_RXD_INT_EN        BIT(12)
  53 #define MII_DP83867_MICR_AUTONEG_COMP_INT_EN    BIT(11)
  54 #define MII_DP83867_MICR_LINK_STS_CHNG_INT_EN   BIT(10)
  55 #define MII_DP83867_MICR_FALSE_CARRIER_INT_EN   BIT(8)
  56 #define MII_DP83867_MICR_SLEEP_MODE_CHNG_INT_EN BIT(4)
  57 #define MII_DP83867_MICR_WOL_INT_EN             BIT(3)
  58 #define MII_DP83867_MICR_XGMII_ERR_INT_EN       BIT(2)
  59 #define MII_DP83867_MICR_POL_CHNG_INT_EN        BIT(1)
  60 #define MII_DP83867_MICR_JABBER_INT_EN          BIT(0)
  61 
  62 /* RGMIICTL bits */
  63 #define DP83867_RGMII_TX_CLK_DELAY_EN           BIT(1)
  64 #define DP83867_RGMII_RX_CLK_DELAY_EN           BIT(0)
  65 
  66 /* SGMIICTL bits */
  67 #define DP83867_SGMII_TYPE              BIT(14)
  68 
  69 /* STRAP_STS1 bits */
  70 #define DP83867_STRAP_STS1_RESERVED             BIT(11)
  71 
  72 /* STRAP_STS2 bits */
  73 #define DP83867_STRAP_STS2_CLK_SKEW_TX_MASK     GENMASK(6, 4)
  74 #define DP83867_STRAP_STS2_CLK_SKEW_TX_SHIFT    4
  75 #define DP83867_STRAP_STS2_CLK_SKEW_RX_MASK     GENMASK(2, 0)
  76 #define DP83867_STRAP_STS2_CLK_SKEW_RX_SHIFT    0
  77 #define DP83867_STRAP_STS2_CLK_SKEW_NONE        BIT(2)
  78 #define DP83867_STRAP_STS2_STRAP_FLD            BIT(10)
  79 
  80 /* PHY CTRL bits */
  81 #define DP83867_PHYCR_FIFO_DEPTH_SHIFT          14
  82 #define DP83867_PHYCR_FIFO_DEPTH_MAX            0x03
  83 #define DP83867_PHYCR_FIFO_DEPTH_MASK           GENMASK(15, 14)
  84 #define DP83867_PHYCR_RESERVED_MASK             BIT(11)
  85 #define DP83867_PHYCR_FORCE_LINK_GOOD           BIT(10)
  86 
  87 /* RGMIIDCTL bits */
  88 #define DP83867_RGMII_TX_CLK_DELAY_MAX          0xf
  89 #define DP83867_RGMII_TX_CLK_DELAY_SHIFT        4
  90 #define DP83867_RGMII_RX_CLK_DELAY_MAX          0xf
  91 #define DP83867_RGMII_RX_CLK_DELAY_SHIFT        0
  92 
  93 /* IO_MUX_CFG bits */
  94 #define DP83867_IO_MUX_CFG_IO_IMPEDANCE_MASK    0x1f
  95 #define DP83867_IO_MUX_CFG_IO_IMPEDANCE_MAX     0x0
  96 #define DP83867_IO_MUX_CFG_IO_IMPEDANCE_MIN     0x1f
  97 #define DP83867_IO_MUX_CFG_CLK_O_DISABLE        BIT(6)
  98 #define DP83867_IO_MUX_CFG_CLK_O_SEL_MASK       (0x1f << 8)
  99 #define DP83867_IO_MUX_CFG_CLK_O_SEL_SHIFT      8
 100 
 101 /* CFG3 bits */
 102 #define DP83867_CFG3_INT_OE                     BIT(7)
 103 #define DP83867_CFG3_ROBUST_AUTO_MDIX           BIT(9)
 104 
 105 /* CFG4 bits */
 106 #define DP83867_CFG4_PORT_MIRROR_EN              BIT(0)
 107 
 108 /* FLD_THR_CFG */
 109 #define DP83867_FLD_THR_CFG_ENERGY_LOST_THR_MASK        0x7
 110 
 111 enum {
 112         DP83867_PORT_MIRROING_KEEP,
 113         DP83867_PORT_MIRROING_EN,
 114         DP83867_PORT_MIRROING_DIS,
 115 };
 116 
 117 struct dp83867_private {
 118         u32 rx_id_delay;
 119         u32 tx_id_delay;
 120         u32 fifo_depth;
 121         int io_impedance;
 122         int port_mirroring;
 123         bool rxctrl_strap_quirk;
 124         bool set_clk_output;
 125         u32 clk_output_sel;
 126         bool sgmii_ref_clk_en;
 127 };
 128 
 129 static int dp83867_ack_interrupt(struct phy_device *phydev)
 130 {
 131         int err = phy_read(phydev, MII_DP83867_ISR);
 132 
 133         if (err < 0)
 134                 return err;
 135 
 136         return 0;
 137 }
 138 
 139 static int dp83867_config_intr(struct phy_device *phydev)
 140 {
 141         int micr_status;
 142 
 143         if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
 144                 micr_status = phy_read(phydev, MII_DP83867_MICR);
 145                 if (micr_status < 0)
 146                         return micr_status;
 147 
 148                 micr_status |=
 149                         (MII_DP83867_MICR_AN_ERR_INT_EN |
 150                         MII_DP83867_MICR_SPEED_CHNG_INT_EN |
 151                         MII_DP83867_MICR_AUTONEG_COMP_INT_EN |
 152                         MII_DP83867_MICR_LINK_STS_CHNG_INT_EN |
 153                         MII_DP83867_MICR_DUP_MODE_CHNG_INT_EN |
 154                         MII_DP83867_MICR_SLEEP_MODE_CHNG_INT_EN);
 155 
 156                 return phy_write(phydev, MII_DP83867_MICR, micr_status);
 157         }
 158 
 159         micr_status = 0x0;
 160         return phy_write(phydev, MII_DP83867_MICR, micr_status);
 161 }
 162 
 163 static int dp83867_config_port_mirroring(struct phy_device *phydev)
 164 {
 165         struct dp83867_private *dp83867 =
 166                 (struct dp83867_private *)phydev->priv;
 167 
 168         if (dp83867->port_mirroring == DP83867_PORT_MIRROING_EN)
 169                 phy_set_bits_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4,
 170                                  DP83867_CFG4_PORT_MIRROR_EN);
 171         else
 172                 phy_clear_bits_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4,
 173                                    DP83867_CFG4_PORT_MIRROR_EN);
 174         return 0;
 175 }
 176 
 177 #ifdef CONFIG_OF_MDIO
 178 static int dp83867_of_init(struct phy_device *phydev)
 179 {
 180         struct dp83867_private *dp83867 = phydev->priv;
 181         struct device *dev = &phydev->mdio.dev;
 182         struct device_node *of_node = dev->of_node;
 183         int ret;
 184 
 185         if (!of_node)
 186                 return -ENODEV;
 187 
 188         /* Optional configuration */
 189         ret = of_property_read_u32(of_node, "ti,clk-output-sel",
 190                                    &dp83867->clk_output_sel);
 191         /* If not set, keep default */
 192         if (!ret) {
 193                 dp83867->set_clk_output = true;
 194                 /* Valid values are 0 to DP83867_CLK_O_SEL_REF_CLK or
 195                  * DP83867_CLK_O_SEL_OFF.
 196                  */
 197                 if (dp83867->clk_output_sel > DP83867_CLK_O_SEL_REF_CLK &&
 198                     dp83867->clk_output_sel != DP83867_CLK_O_SEL_OFF) {
 199                         phydev_err(phydev, "ti,clk-output-sel value %u out of range\n",
 200                                    dp83867->clk_output_sel);
 201                         return -EINVAL;
 202                 }
 203         }
 204 
 205         if (of_property_read_bool(of_node, "ti,max-output-impedance"))
 206                 dp83867->io_impedance = DP83867_IO_MUX_CFG_IO_IMPEDANCE_MAX;
 207         else if (of_property_read_bool(of_node, "ti,min-output-impedance"))
 208                 dp83867->io_impedance = DP83867_IO_MUX_CFG_IO_IMPEDANCE_MIN;
 209         else
 210                 dp83867->io_impedance = -1; /* leave at default */
 211 
 212         dp83867->rxctrl_strap_quirk = of_property_read_bool(of_node,
 213                                         "ti,dp83867-rxctrl-strap-quirk");
 214 
 215         dp83867->sgmii_ref_clk_en = of_property_read_bool(of_node,
 216                                         "ti,sgmii-ref-clock-output-enable");
 217 
 218         /* Existing behavior was to use default pin strapping delay in rgmii
 219          * mode, but rgmii should have meant no delay.  Warn existing users.
 220          */
 221         if (phydev->interface == PHY_INTERFACE_MODE_RGMII) {
 222                 const u16 val = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_STRAP_STS2);
 223                 const u16 txskew = (val & DP83867_STRAP_STS2_CLK_SKEW_TX_MASK) >>
 224                                    DP83867_STRAP_STS2_CLK_SKEW_TX_SHIFT;
 225                 const u16 rxskew = (val & DP83867_STRAP_STS2_CLK_SKEW_RX_MASK) >>
 226                                    DP83867_STRAP_STS2_CLK_SKEW_RX_SHIFT;
 227 
 228                 if (txskew != DP83867_STRAP_STS2_CLK_SKEW_NONE ||
 229                     rxskew != DP83867_STRAP_STS2_CLK_SKEW_NONE)
 230                         phydev_warn(phydev,
 231                                     "PHY has delays via pin strapping, but phy-mode = 'rgmii'\n"
 232                                     "Should be 'rgmii-id' to use internal delays\n");
 233         }
 234 
 235         /* RX delay *must* be specified if internal delay of RX is used. */
 236         if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
 237             phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
 238                 ret = of_property_read_u32(of_node, "ti,rx-internal-delay",
 239                                            &dp83867->rx_id_delay);
 240                 if (ret) {
 241                         phydev_err(phydev, "ti,rx-internal-delay must be specified\n");
 242                         return ret;
 243                 }
 244                 if (dp83867->rx_id_delay > DP83867_RGMII_RX_CLK_DELAY_MAX) {
 245                         phydev_err(phydev,
 246                                    "ti,rx-internal-delay value of %u out of range\n",
 247                                    dp83867->rx_id_delay);
 248                         return -EINVAL;
 249                 }
 250         }
 251 
 252         /* TX delay *must* be specified if internal delay of RX is used. */
 253         if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
 254             phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
 255                 ret = of_property_read_u32(of_node, "ti,tx-internal-delay",
 256                                            &dp83867->tx_id_delay);
 257                 if (ret) {
 258                         phydev_err(phydev, "ti,tx-internal-delay must be specified\n");
 259                         return ret;
 260                 }
 261                 if (dp83867->tx_id_delay > DP83867_RGMII_TX_CLK_DELAY_MAX) {
 262                         phydev_err(phydev,
 263                                    "ti,tx-internal-delay value of %u out of range\n",
 264                                    dp83867->tx_id_delay);
 265                         return -EINVAL;
 266                 }
 267         }
 268 
 269         if (of_property_read_bool(of_node, "enet-phy-lane-swap"))
 270                 dp83867->port_mirroring = DP83867_PORT_MIRROING_EN;
 271 
 272         if (of_property_read_bool(of_node, "enet-phy-lane-no-swap"))
 273                 dp83867->port_mirroring = DP83867_PORT_MIRROING_DIS;
 274 
 275         ret = of_property_read_u32(of_node, "ti,fifo-depth",
 276                                    &dp83867->fifo_depth);
 277         if (ret) {
 278                 phydev_err(phydev,
 279                            "ti,fifo-depth property is required\n");
 280                 return ret;
 281         }
 282         if (dp83867->fifo_depth > DP83867_PHYCR_FIFO_DEPTH_MAX) {
 283                 phydev_err(phydev,
 284                            "ti,fifo-depth value %u out of range\n",
 285                            dp83867->fifo_depth);
 286                 return -EINVAL;
 287         }
 288         return 0;
 289 }
 290 #else
 291 static int dp83867_of_init(struct phy_device *phydev)
 292 {
 293         return 0;
 294 }
 295 #endif /* CONFIG_OF_MDIO */
 296 
 297 static int dp83867_probe(struct phy_device *phydev)
 298 {
 299         struct dp83867_private *dp83867;
 300 
 301         dp83867 = devm_kzalloc(&phydev->mdio.dev, sizeof(*dp83867),
 302                                GFP_KERNEL);
 303         if (!dp83867)
 304                 return -ENOMEM;
 305 
 306         phydev->priv = dp83867;
 307 
 308         return 0;
 309 }
 310 
 311 static int dp83867_config_init(struct phy_device *phydev)
 312 {
 313         struct dp83867_private *dp83867 = phydev->priv;
 314         int ret, val, bs;
 315         u16 delay;
 316 
 317         ret = dp83867_of_init(phydev);
 318         if (ret)
 319                 return ret;
 320 
 321         /* RX_DV/RX_CTRL strapped in mode 1 or mode 2 workaround */
 322         if (dp83867->rxctrl_strap_quirk)
 323                 phy_clear_bits_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4,
 324                                    BIT(7));
 325 
 326         bs = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_STRAP_STS2);
 327         if (bs & DP83867_STRAP_STS2_STRAP_FLD) {
 328                 /* When using strap to enable FLD, the ENERGY_LOST_FLD_THR will
 329                  * be set to 0x2. This may causes the PHY link to be unstable -
 330                  * the default value 0x1 need to be restored.
 331                  */
 332                 ret = phy_modify_mmd(phydev, DP83867_DEVADDR,
 333                                      DP83867_FLD_THR_CFG,
 334                                      DP83867_FLD_THR_CFG_ENERGY_LOST_THR_MASK,
 335                                      0x1);
 336                 if (ret)
 337                         return ret;
 338         }
 339 
 340         if (phy_interface_is_rgmii(phydev)) {
 341                 val = phy_read(phydev, MII_DP83867_PHYCTRL);
 342                 if (val < 0)
 343                         return val;
 344                 val &= ~DP83867_PHYCR_FIFO_DEPTH_MASK;
 345                 val |= (dp83867->fifo_depth << DP83867_PHYCR_FIFO_DEPTH_SHIFT);
 346 
 347                 /* The code below checks if "port mirroring" N/A MODE4 has been
 348                  * enabled during power on bootstrap.
 349                  *
 350                  * Such N/A mode enabled by mistake can put PHY IC in some
 351                  * internal testing mode and disable RGMII transmission.
 352                  *
 353                  * In this particular case one needs to check STRAP_STS1
 354                  * register's bit 11 (marked as RESERVED).
 355                  */
 356 
 357                 bs = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_STRAP_STS1);
 358                 if (bs & DP83867_STRAP_STS1_RESERVED)
 359                         val &= ~DP83867_PHYCR_RESERVED_MASK;
 360 
 361                 ret = phy_write(phydev, MII_DP83867_PHYCTRL, val);
 362                 if (ret)
 363                         return ret;
 364 
 365                 /* If rgmii mode with no internal delay is selected, we do NOT use
 366                  * aligned mode as one might expect.  Instead we use the PHY's default
 367                  * based on pin strapping.  And the "mode 0" default is to *use*
 368                  * internal delay with a value of 7 (2.00 ns).
 369                  *
 370                  * Set up RGMII delays
 371                  */
 372                 val = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_RGMIICTL);
 373 
 374                 val &= ~(DP83867_RGMII_TX_CLK_DELAY_EN | DP83867_RGMII_RX_CLK_DELAY_EN);
 375                 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
 376                         val |= (DP83867_RGMII_TX_CLK_DELAY_EN | DP83867_RGMII_RX_CLK_DELAY_EN);
 377 
 378                 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
 379                         val |= DP83867_RGMII_TX_CLK_DELAY_EN;
 380 
 381                 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
 382                         val |= DP83867_RGMII_RX_CLK_DELAY_EN;
 383 
 384                 phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RGMIICTL, val);
 385 
 386                 delay = (dp83867->rx_id_delay |
 387                         (dp83867->tx_id_delay << DP83867_RGMII_TX_CLK_DELAY_SHIFT));
 388 
 389                 phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RGMIIDCTL,
 390                               delay);
 391         }
 392 
 393         /* If specified, set io impedance */
 394         if (dp83867->io_impedance >= 0)
 395                 phy_modify_mmd(phydev, DP83867_DEVADDR, DP83867_IO_MUX_CFG,
 396                                DP83867_IO_MUX_CFG_IO_IMPEDANCE_MASK,
 397                                dp83867->io_impedance);
 398 
 399         if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
 400                 /* For support SPEED_10 in SGMII mode
 401                  * DP83867_10M_SGMII_RATE_ADAPT bit
 402                  * has to be cleared by software. That
 403                  * does not affect SPEED_100 and
 404                  * SPEED_1000.
 405                  */
 406                 ret = phy_modify_mmd(phydev, DP83867_DEVADDR,
 407                                      DP83867_10M_SGMII_CFG,
 408                                      DP83867_10M_SGMII_RATE_ADAPT_MASK,
 409                                      0);
 410                 if (ret)
 411                         return ret;
 412 
 413                 /* After reset SGMII Autoneg timer is set to 2us (bits 6 and 5
 414                  * are 01). That is not enough to finalize autoneg on some
 415                  * devices. Increase this timer duration to maximum 16ms.
 416                  */
 417                 ret = phy_modify_mmd(phydev, DP83867_DEVADDR,
 418                                      DP83867_CFG4,
 419                                      DP83867_CFG4_SGMII_ANEG_MASK,
 420                                      DP83867_CFG4_SGMII_ANEG_TIMER_16MS);
 421 
 422                 if (ret)
 423                         return ret;
 424 
 425                 val = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_SGMIICTL);
 426                 /* SGMII type is set to 4-wire mode by default.
 427                  * If we place appropriate property in dts (see above)
 428                  * switch on 6-wire mode.
 429                  */
 430                 if (dp83867->sgmii_ref_clk_en)
 431                         val |= DP83867_SGMII_TYPE;
 432                 else
 433                         val &= ~DP83867_SGMII_TYPE;
 434                 phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_SGMIICTL, val);
 435         }
 436 
 437         val = phy_read(phydev, DP83867_CFG3);
 438         /* Enable Interrupt output INT_OE in CFG3 register */
 439         if (phy_interrupt_is_valid(phydev))
 440                 val |= DP83867_CFG3_INT_OE;
 441 
 442         val |= DP83867_CFG3_ROBUST_AUTO_MDIX;
 443         phy_write(phydev, DP83867_CFG3, val);
 444 
 445         if (dp83867->port_mirroring != DP83867_PORT_MIRROING_KEEP)
 446                 dp83867_config_port_mirroring(phydev);
 447 
 448         /* Clock output selection if muxing property is set */
 449         if (dp83867->set_clk_output) {
 450                 u16 mask = DP83867_IO_MUX_CFG_CLK_O_DISABLE;
 451 
 452                 if (dp83867->clk_output_sel == DP83867_CLK_O_SEL_OFF) {
 453                         val = DP83867_IO_MUX_CFG_CLK_O_DISABLE;
 454                 } else {
 455                         mask |= DP83867_IO_MUX_CFG_CLK_O_SEL_MASK;
 456                         val = dp83867->clk_output_sel <<
 457                               DP83867_IO_MUX_CFG_CLK_O_SEL_SHIFT;
 458                 }
 459 
 460                 phy_modify_mmd(phydev, DP83867_DEVADDR, DP83867_IO_MUX_CFG,
 461                                mask, val);
 462         }
 463 
 464         return 0;
 465 }
 466 
 467 static int dp83867_phy_reset(struct phy_device *phydev)
 468 {
 469         int err;
 470 
 471         err = phy_write(phydev, DP83867_CTRL, DP83867_SW_RESET);
 472         if (err < 0)
 473                 return err;
 474 
 475         usleep_range(10, 20);
 476 
 477         /* After reset FORCE_LINK_GOOD bit is set. Although the
 478          * default value should be unset. Disable FORCE_LINK_GOOD
 479          * for the phy to work properly.
 480          */
 481         return phy_modify(phydev, MII_DP83867_PHYCTRL,
 482                          DP83867_PHYCR_FORCE_LINK_GOOD, 0);
 483 }
 484 
 485 static struct phy_driver dp83867_driver[] = {
 486         {
 487                 .phy_id         = DP83867_PHY_ID,
 488                 .phy_id_mask    = 0xfffffff0,
 489                 .name           = "TI DP83867",
 490                 /* PHY_GBIT_FEATURES */
 491 
 492                 .probe          = dp83867_probe,
 493                 .config_init    = dp83867_config_init,
 494                 .soft_reset     = dp83867_phy_reset,
 495 
 496                 /* IRQ related */
 497                 .ack_interrupt  = dp83867_ack_interrupt,
 498                 .config_intr    = dp83867_config_intr,
 499 
 500                 .suspend        = genphy_suspend,
 501                 .resume         = genphy_resume,
 502         },
 503 };
 504 module_phy_driver(dp83867_driver);
 505 
 506 static struct mdio_device_id __maybe_unused dp83867_tbl[] = {
 507         { DP83867_PHY_ID, 0xfffffff0 },
 508         { }
 509 };
 510 
 511 MODULE_DEVICE_TABLE(mdio, dp83867_tbl);
 512 
 513 MODULE_DESCRIPTION("Texas Instruments DP83867 PHY driver");
 514 MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com");
 515 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */