root/drivers/net/phy/intel-xway.c

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

DEFINITIONS

This source file includes following definitions.
  1. xway_gphy_config_init
  2. xway_gphy14_config_aneg
  3. xway_gphy_ack_interrupt
  4. xway_gphy_did_interrupt
  5. xway_gphy_config_intr

   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 
  12 #define XWAY_MDIO_IMASK                 0x19    /* interrupt mask */
  13 #define XWAY_MDIO_ISTAT                 0x1A    /* interrupt status */
  14 
  15 #define XWAY_MDIO_INIT_WOL              BIT(15) /* Wake-On-LAN */
  16 #define XWAY_MDIO_INIT_MSRE             BIT(14)
  17 #define XWAY_MDIO_INIT_NPRX             BIT(13)
  18 #define XWAY_MDIO_INIT_NPTX             BIT(12)
  19 #define XWAY_MDIO_INIT_ANE              BIT(11) /* Auto-Neg error */
  20 #define XWAY_MDIO_INIT_ANC              BIT(10) /* Auto-Neg complete */
  21 #define XWAY_MDIO_INIT_ADSC             BIT(5)  /* Link auto-downspeed detect */
  22 #define XWAY_MDIO_INIT_MPIPC            BIT(4)
  23 #define XWAY_MDIO_INIT_MDIXC            BIT(3)
  24 #define XWAY_MDIO_INIT_DXMC             BIT(2)  /* Duplex mode change */
  25 #define XWAY_MDIO_INIT_LSPC             BIT(1)  /* Link speed change */
  26 #define XWAY_MDIO_INIT_LSTC             BIT(0)  /* Link state change */
  27 #define XWAY_MDIO_INIT_MASK             (XWAY_MDIO_INIT_LSTC | \
  28                                          XWAY_MDIO_INIT_ADSC)
  29 
  30 #define ADVERTISED_MPD                  BIT(10) /* Multi-port device */
  31 
  32 /* LED Configuration */
  33 #define XWAY_MMD_LEDCH                  0x01E0
  34 /* Inverse of SCAN Function */
  35 #define  XWAY_MMD_LEDCH_NACS_NONE       0x0000
  36 #define  XWAY_MMD_LEDCH_NACS_LINK       0x0001
  37 #define  XWAY_MMD_LEDCH_NACS_PDOWN      0x0002
  38 #define  XWAY_MMD_LEDCH_NACS_EEE        0x0003
  39 #define  XWAY_MMD_LEDCH_NACS_ANEG       0x0004
  40 #define  XWAY_MMD_LEDCH_NACS_ABIST      0x0005
  41 #define  XWAY_MMD_LEDCH_NACS_CDIAG      0x0006
  42 #define  XWAY_MMD_LEDCH_NACS_TEST       0x0007
  43 /* Slow Blink Frequency */
  44 #define  XWAY_MMD_LEDCH_SBF_F02HZ       0x0000
  45 #define  XWAY_MMD_LEDCH_SBF_F04HZ       0x0010
  46 #define  XWAY_MMD_LEDCH_SBF_F08HZ       0x0020
  47 #define  XWAY_MMD_LEDCH_SBF_F16HZ       0x0030
  48 /* Fast Blink Frequency */
  49 #define  XWAY_MMD_LEDCH_FBF_F02HZ       0x0000
  50 #define  XWAY_MMD_LEDCH_FBF_F04HZ       0x0040
  51 #define  XWAY_MMD_LEDCH_FBF_F08HZ       0x0080
  52 #define  XWAY_MMD_LEDCH_FBF_F16HZ       0x00C0
  53 /* LED Configuration */
  54 #define XWAY_MMD_LEDCL                  0x01E1
  55 /* Complex Blinking Configuration */
  56 #define  XWAY_MMD_LEDCH_CBLINK_NONE     0x0000
  57 #define  XWAY_MMD_LEDCH_CBLINK_LINK     0x0001
  58 #define  XWAY_MMD_LEDCH_CBLINK_PDOWN    0x0002
  59 #define  XWAY_MMD_LEDCH_CBLINK_EEE      0x0003
  60 #define  XWAY_MMD_LEDCH_CBLINK_ANEG     0x0004
  61 #define  XWAY_MMD_LEDCH_CBLINK_ABIST    0x0005
  62 #define  XWAY_MMD_LEDCH_CBLINK_CDIAG    0x0006
  63 #define  XWAY_MMD_LEDCH_CBLINK_TEST     0x0007
  64 /* Complex SCAN Configuration */
  65 #define  XWAY_MMD_LEDCH_SCAN_NONE       0x0000
  66 #define  XWAY_MMD_LEDCH_SCAN_LINK       0x0010
  67 #define  XWAY_MMD_LEDCH_SCAN_PDOWN      0x0020
  68 #define  XWAY_MMD_LEDCH_SCAN_EEE        0x0030
  69 #define  XWAY_MMD_LEDCH_SCAN_ANEG       0x0040
  70 #define  XWAY_MMD_LEDCH_SCAN_ABIST      0x0050
  71 #define  XWAY_MMD_LEDCH_SCAN_CDIAG      0x0060
  72 #define  XWAY_MMD_LEDCH_SCAN_TEST       0x0070
  73 /* Configuration for LED Pin x */
  74 #define XWAY_MMD_LED0H                  0x01E2
  75 /* Fast Blinking Configuration */
  76 #define  XWAY_MMD_LEDxH_BLINKF_MASK     0x000F
  77 #define  XWAY_MMD_LEDxH_BLINKF_NONE     0x0000
  78 #define  XWAY_MMD_LEDxH_BLINKF_LINK10   0x0001
  79 #define  XWAY_MMD_LEDxH_BLINKF_LINK100  0x0002
  80 #define  XWAY_MMD_LEDxH_BLINKF_LINK10X  0x0003
  81 #define  XWAY_MMD_LEDxH_BLINKF_LINK1000 0x0004
  82 #define  XWAY_MMD_LEDxH_BLINKF_LINK10_0 0x0005
  83 #define  XWAY_MMD_LEDxH_BLINKF_LINK100X 0x0006
  84 #define  XWAY_MMD_LEDxH_BLINKF_LINK10XX 0x0007
  85 #define  XWAY_MMD_LEDxH_BLINKF_PDOWN    0x0008
  86 #define  XWAY_MMD_LEDxH_BLINKF_EEE      0x0009
  87 #define  XWAY_MMD_LEDxH_BLINKF_ANEG     0x000A
  88 #define  XWAY_MMD_LEDxH_BLINKF_ABIST    0x000B
  89 #define  XWAY_MMD_LEDxH_BLINKF_CDIAG    0x000C
  90 /* Constant On Configuration */
  91 #define  XWAY_MMD_LEDxH_CON_MASK        0x00F0
  92 #define  XWAY_MMD_LEDxH_CON_NONE        0x0000
  93 #define  XWAY_MMD_LEDxH_CON_LINK10      0x0010
  94 #define  XWAY_MMD_LEDxH_CON_LINK100     0x0020
  95 #define  XWAY_MMD_LEDxH_CON_LINK10X     0x0030
  96 #define  XWAY_MMD_LEDxH_CON_LINK1000    0x0040
  97 #define  XWAY_MMD_LEDxH_CON_LINK10_0    0x0050
  98 #define  XWAY_MMD_LEDxH_CON_LINK100X    0x0060
  99 #define  XWAY_MMD_LEDxH_CON_LINK10XX    0x0070
 100 #define  XWAY_MMD_LEDxH_CON_PDOWN       0x0080
 101 #define  XWAY_MMD_LEDxH_CON_EEE         0x0090
 102 #define  XWAY_MMD_LEDxH_CON_ANEG        0x00A0
 103 #define  XWAY_MMD_LEDxH_CON_ABIST       0x00B0
 104 #define  XWAY_MMD_LEDxH_CON_CDIAG       0x00C0
 105 #define  XWAY_MMD_LEDxH_CON_COPPER      0x00D0
 106 #define  XWAY_MMD_LEDxH_CON_FIBER       0x00E0
 107 /* Configuration for LED Pin x */
 108 #define XWAY_MMD_LED0L                  0x01E3
 109 /* Pulsing Configuration */
 110 #define  XWAY_MMD_LEDxL_PULSE_MASK      0x000F
 111 #define  XWAY_MMD_LEDxL_PULSE_NONE      0x0000
 112 #define  XWAY_MMD_LEDxL_PULSE_TXACT     0x0001
 113 #define  XWAY_MMD_LEDxL_PULSE_RXACT     0x0002
 114 #define  XWAY_MMD_LEDxL_PULSE_COL       0x0004
 115 /* Slow Blinking Configuration */
 116 #define  XWAY_MMD_LEDxL_BLINKS_MASK     0x00F0
 117 #define  XWAY_MMD_LEDxL_BLINKS_NONE     0x0000
 118 #define  XWAY_MMD_LEDxL_BLINKS_LINK10   0x0010
 119 #define  XWAY_MMD_LEDxL_BLINKS_LINK100  0x0020
 120 #define  XWAY_MMD_LEDxL_BLINKS_LINK10X  0x0030
 121 #define  XWAY_MMD_LEDxL_BLINKS_LINK1000 0x0040
 122 #define  XWAY_MMD_LEDxL_BLINKS_LINK10_0 0x0050
 123 #define  XWAY_MMD_LEDxL_BLINKS_LINK100X 0x0060
 124 #define  XWAY_MMD_LEDxL_BLINKS_LINK10XX 0x0070
 125 #define  XWAY_MMD_LEDxL_BLINKS_PDOWN    0x0080
 126 #define  XWAY_MMD_LEDxL_BLINKS_EEE      0x0090
 127 #define  XWAY_MMD_LEDxL_BLINKS_ANEG     0x00A0
 128 #define  XWAY_MMD_LEDxL_BLINKS_ABIST    0x00B0
 129 #define  XWAY_MMD_LEDxL_BLINKS_CDIAG    0x00C0
 130 #define XWAY_MMD_LED1H                  0x01E4
 131 #define XWAY_MMD_LED1L                  0x01E5
 132 #define XWAY_MMD_LED2H                  0x01E6
 133 #define XWAY_MMD_LED2L                  0x01E7
 134 #define XWAY_MMD_LED3H                  0x01E8
 135 #define XWAY_MMD_LED3L                  0x01E9
 136 
 137 #define PHY_ID_PHY11G_1_3               0x030260D1
 138 #define PHY_ID_PHY22F_1_3               0x030260E1
 139 #define PHY_ID_PHY11G_1_4               0xD565A400
 140 #define PHY_ID_PHY22F_1_4               0xD565A410
 141 #define PHY_ID_PHY11G_1_5               0xD565A401
 142 #define PHY_ID_PHY22F_1_5               0xD565A411
 143 #define PHY_ID_PHY11G_VR9_1_1           0xD565A408
 144 #define PHY_ID_PHY22F_VR9_1_1           0xD565A418
 145 #define PHY_ID_PHY11G_VR9_1_2           0xD565A409
 146 #define PHY_ID_PHY22F_VR9_1_2           0xD565A419
 147 
 148 static int xway_gphy_config_init(struct phy_device *phydev)
 149 {
 150         int err;
 151         u32 ledxh;
 152         u32 ledxl;
 153 
 154         /* Mask all interrupts */
 155         err = phy_write(phydev, XWAY_MDIO_IMASK, 0);
 156         if (err)
 157                 return err;
 158 
 159         /* Clear all pending interrupts */
 160         phy_read(phydev, XWAY_MDIO_ISTAT);
 161 
 162         phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LEDCH,
 163                       XWAY_MMD_LEDCH_NACS_NONE |
 164                       XWAY_MMD_LEDCH_SBF_F02HZ |
 165                       XWAY_MMD_LEDCH_FBF_F16HZ);
 166         phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LEDCL,
 167                       XWAY_MMD_LEDCH_CBLINK_NONE |
 168                       XWAY_MMD_LEDCH_SCAN_NONE);
 169 
 170         /**
 171          * In most cases only one LED is connected to this phy, so
 172          * configure them all to constant on and pulse mode. LED3 is
 173          * only available in some packages, leave it in its reset
 174          * configuration.
 175          */
 176         ledxh = XWAY_MMD_LEDxH_BLINKF_NONE | XWAY_MMD_LEDxH_CON_LINK10XX;
 177         ledxl = XWAY_MMD_LEDxL_PULSE_TXACT | XWAY_MMD_LEDxL_PULSE_RXACT |
 178                 XWAY_MMD_LEDxL_BLINKS_NONE;
 179         phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED0H, ledxh);
 180         phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED0L, ledxl);
 181         phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED1H, ledxh);
 182         phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED1L, ledxl);
 183         phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED2H, ledxh);
 184         phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED2L, ledxl);
 185 
 186         return 0;
 187 }
 188 
 189 static int xway_gphy14_config_aneg(struct phy_device *phydev)
 190 {
 191         int reg, err;
 192 
 193         /* Advertise as multi-port device, see IEEE802.3-2002 40.5.1.1 */
 194         /* This is a workaround for an errata in rev < 1.5 devices */
 195         reg = phy_read(phydev, MII_CTRL1000);
 196         reg |= ADVERTISED_MPD;
 197         err = phy_write(phydev, MII_CTRL1000, reg);
 198         if (err)
 199                 return err;
 200 
 201         return genphy_config_aneg(phydev);
 202 }
 203 
 204 static int xway_gphy_ack_interrupt(struct phy_device *phydev)
 205 {
 206         int reg;
 207 
 208         reg = phy_read(phydev, XWAY_MDIO_ISTAT);
 209         return (reg < 0) ? reg : 0;
 210 }
 211 
 212 static int xway_gphy_did_interrupt(struct phy_device *phydev)
 213 {
 214         int reg;
 215 
 216         reg = phy_read(phydev, XWAY_MDIO_ISTAT);
 217         return reg & XWAY_MDIO_INIT_MASK;
 218 }
 219 
 220 static int xway_gphy_config_intr(struct phy_device *phydev)
 221 {
 222         u16 mask = 0;
 223 
 224         if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
 225                 mask = XWAY_MDIO_INIT_MASK;
 226 
 227         return phy_write(phydev, XWAY_MDIO_IMASK, mask);
 228 }
 229 
 230 static struct phy_driver xway_gphy[] = {
 231         {
 232                 .phy_id         = PHY_ID_PHY11G_1_3,
 233                 .phy_id_mask    = 0xffffffff,
 234                 .name           = "Intel XWAY PHY11G (PEF 7071/PEF 7072) v1.3",
 235                 /* PHY_GBIT_FEATURES */
 236                 .config_init    = xway_gphy_config_init,
 237                 .config_aneg    = xway_gphy14_config_aneg,
 238                 .ack_interrupt  = xway_gphy_ack_interrupt,
 239                 .did_interrupt  = xway_gphy_did_interrupt,
 240                 .config_intr    = xway_gphy_config_intr,
 241                 .suspend        = genphy_suspend,
 242                 .resume         = genphy_resume,
 243         }, {
 244                 .phy_id         = PHY_ID_PHY22F_1_3,
 245                 .phy_id_mask    = 0xffffffff,
 246                 .name           = "Intel XWAY PHY22F (PEF 7061) v1.3",
 247                 /* PHY_BASIC_FEATURES */
 248                 .config_init    = xway_gphy_config_init,
 249                 .config_aneg    = xway_gphy14_config_aneg,
 250                 .ack_interrupt  = xway_gphy_ack_interrupt,
 251                 .did_interrupt  = xway_gphy_did_interrupt,
 252                 .config_intr    = xway_gphy_config_intr,
 253                 .suspend        = genphy_suspend,
 254                 .resume         = genphy_resume,
 255         }, {
 256                 .phy_id         = PHY_ID_PHY11G_1_4,
 257                 .phy_id_mask    = 0xffffffff,
 258                 .name           = "Intel XWAY PHY11G (PEF 7071/PEF 7072) v1.4",
 259                 /* PHY_GBIT_FEATURES */
 260                 .config_init    = xway_gphy_config_init,
 261                 .config_aneg    = xway_gphy14_config_aneg,
 262                 .ack_interrupt  = xway_gphy_ack_interrupt,
 263                 .did_interrupt  = xway_gphy_did_interrupt,
 264                 .config_intr    = xway_gphy_config_intr,
 265                 .suspend        = genphy_suspend,
 266                 .resume         = genphy_resume,
 267         }, {
 268                 .phy_id         = PHY_ID_PHY22F_1_4,
 269                 .phy_id_mask    = 0xffffffff,
 270                 .name           = "Intel XWAY PHY22F (PEF 7061) v1.4",
 271                 /* PHY_BASIC_FEATURES */
 272                 .config_init    = xway_gphy_config_init,
 273                 .config_aneg    = xway_gphy14_config_aneg,
 274                 .ack_interrupt  = xway_gphy_ack_interrupt,
 275                 .did_interrupt  = xway_gphy_did_interrupt,
 276                 .config_intr    = xway_gphy_config_intr,
 277                 .suspend        = genphy_suspend,
 278                 .resume         = genphy_resume,
 279         }, {
 280                 .phy_id         = PHY_ID_PHY11G_1_5,
 281                 .phy_id_mask    = 0xffffffff,
 282                 .name           = "Intel XWAY PHY11G (PEF 7071/PEF 7072) v1.5 / v1.6",
 283                 /* PHY_GBIT_FEATURES */
 284                 .config_init    = xway_gphy_config_init,
 285                 .ack_interrupt  = xway_gphy_ack_interrupt,
 286                 .did_interrupt  = xway_gphy_did_interrupt,
 287                 .config_intr    = xway_gphy_config_intr,
 288                 .suspend        = genphy_suspend,
 289                 .resume         = genphy_resume,
 290         }, {
 291                 .phy_id         = PHY_ID_PHY22F_1_5,
 292                 .phy_id_mask    = 0xffffffff,
 293                 .name           = "Intel XWAY PHY22F (PEF 7061) v1.5 / v1.6",
 294                 /* PHY_BASIC_FEATURES */
 295                 .config_init    = xway_gphy_config_init,
 296                 .ack_interrupt  = xway_gphy_ack_interrupt,
 297                 .did_interrupt  = xway_gphy_did_interrupt,
 298                 .config_intr    = xway_gphy_config_intr,
 299                 .suspend        = genphy_suspend,
 300                 .resume         = genphy_resume,
 301         }, {
 302                 .phy_id         = PHY_ID_PHY11G_VR9_1_1,
 303                 .phy_id_mask    = 0xffffffff,
 304                 .name           = "Intel XWAY PHY11G (xRX v1.1 integrated)",
 305                 /* PHY_GBIT_FEATURES */
 306                 .config_init    = xway_gphy_config_init,
 307                 .ack_interrupt  = xway_gphy_ack_interrupt,
 308                 .did_interrupt  = xway_gphy_did_interrupt,
 309                 .config_intr    = xway_gphy_config_intr,
 310                 .suspend        = genphy_suspend,
 311                 .resume         = genphy_resume,
 312         }, {
 313                 .phy_id         = PHY_ID_PHY22F_VR9_1_1,
 314                 .phy_id_mask    = 0xffffffff,
 315                 .name           = "Intel XWAY PHY22F (xRX v1.1 integrated)",
 316                 /* PHY_BASIC_FEATURES */
 317                 .config_init    = xway_gphy_config_init,
 318                 .ack_interrupt  = xway_gphy_ack_interrupt,
 319                 .did_interrupt  = xway_gphy_did_interrupt,
 320                 .config_intr    = xway_gphy_config_intr,
 321                 .suspend        = genphy_suspend,
 322                 .resume         = genphy_resume,
 323         }, {
 324                 .phy_id         = PHY_ID_PHY11G_VR9_1_2,
 325                 .phy_id_mask    = 0xffffffff,
 326                 .name           = "Intel XWAY PHY11G (xRX v1.2 integrated)",
 327                 /* PHY_GBIT_FEATURES */
 328                 .config_init    = xway_gphy_config_init,
 329                 .ack_interrupt  = xway_gphy_ack_interrupt,
 330                 .did_interrupt  = xway_gphy_did_interrupt,
 331                 .config_intr    = xway_gphy_config_intr,
 332                 .suspend        = genphy_suspend,
 333                 .resume         = genphy_resume,
 334         }, {
 335                 .phy_id         = PHY_ID_PHY22F_VR9_1_2,
 336                 .phy_id_mask    = 0xffffffff,
 337                 .name           = "Intel XWAY PHY22F (xRX v1.2 integrated)",
 338                 /* PHY_BASIC_FEATURES */
 339                 .config_init    = xway_gphy_config_init,
 340                 .ack_interrupt  = xway_gphy_ack_interrupt,
 341                 .did_interrupt  = xway_gphy_did_interrupt,
 342                 .config_intr    = xway_gphy_config_intr,
 343                 .suspend        = genphy_suspend,
 344                 .resume         = genphy_resume,
 345         },
 346 };
 347 module_phy_driver(xway_gphy);
 348 
 349 static struct mdio_device_id __maybe_unused xway_gphy_tbl[] = {
 350         { PHY_ID_PHY11G_1_3, 0xffffffff },
 351         { PHY_ID_PHY22F_1_3, 0xffffffff },
 352         { PHY_ID_PHY11G_1_4, 0xffffffff },
 353         { PHY_ID_PHY22F_1_4, 0xffffffff },
 354         { PHY_ID_PHY11G_1_5, 0xffffffff },
 355         { PHY_ID_PHY22F_1_5, 0xffffffff },
 356         { PHY_ID_PHY11G_VR9_1_1, 0xffffffff },
 357         { PHY_ID_PHY22F_VR9_1_1, 0xffffffff },
 358         { PHY_ID_PHY11G_VR9_1_2, 0xffffffff },
 359         { PHY_ID_PHY22F_VR9_1_2, 0xffffffff },
 360         { }
 361 };
 362 MODULE_DEVICE_TABLE(mdio, xway_gphy_tbl);
 363 
 364 MODULE_DESCRIPTION("Intel XWAY PHY driver");
 365 MODULE_LICENSE("GPL");

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