root/drivers/net/phy/at803x.c

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

DEFINITIONS

This source file includes following definitions.
  1. at803x_debug_reg_read
  2. at803x_debug_reg_mask
  3. at803x_enable_rx_delay
  4. at803x_enable_tx_delay
  5. at803x_disable_rx_delay
  6. at803x_disable_tx_delay
  7. at803x_context_save
  8. at803x_context_restore
  9. at803x_set_wol
  10. at803x_get_wol
  11. at803x_suspend
  12. at803x_resume
  13. at803x_probe
  14. at803x_config_init
  15. at803x_ack_interrupt
  16. at803x_config_intr
  17. at803x_link_change_notify
  18. at803x_aneg_done
  19. at803x_read_status

   1 // SPDX-License-Identifier: GPL-2.0+
   2 /*
   3  * drivers/net/phy/at803x.c
   4  *
   5  * Driver for Atheros 803x PHY
   6  *
   7  * Author: Matus Ujhelyi <ujhelyi.m@gmail.com>
   8  */
   9 
  10 #include <linux/phy.h>
  11 #include <linux/module.h>
  12 #include <linux/string.h>
  13 #include <linux/netdevice.h>
  14 #include <linux/etherdevice.h>
  15 #include <linux/of_gpio.h>
  16 #include <linux/gpio/consumer.h>
  17 
  18 #define AT803X_SPECIFIC_STATUS                  0x11
  19 #define AT803X_SS_SPEED_MASK                    (3 << 14)
  20 #define AT803X_SS_SPEED_1000                    (2 << 14)
  21 #define AT803X_SS_SPEED_100                     (1 << 14)
  22 #define AT803X_SS_SPEED_10                      (0 << 14)
  23 #define AT803X_SS_DUPLEX                        BIT(13)
  24 #define AT803X_SS_SPEED_DUPLEX_RESOLVED         BIT(11)
  25 #define AT803X_SS_MDIX                          BIT(6)
  26 
  27 #define AT803X_INTR_ENABLE                      0x12
  28 #define AT803X_INTR_ENABLE_AUTONEG_ERR          BIT(15)
  29 #define AT803X_INTR_ENABLE_SPEED_CHANGED        BIT(14)
  30 #define AT803X_INTR_ENABLE_DUPLEX_CHANGED       BIT(13)
  31 #define AT803X_INTR_ENABLE_PAGE_RECEIVED        BIT(12)
  32 #define AT803X_INTR_ENABLE_LINK_FAIL            BIT(11)
  33 #define AT803X_INTR_ENABLE_LINK_SUCCESS         BIT(10)
  34 #define AT803X_INTR_ENABLE_WIRESPEED_DOWNGRADE  BIT(5)
  35 #define AT803X_INTR_ENABLE_POLARITY_CHANGED     BIT(1)
  36 #define AT803X_INTR_ENABLE_WOL                  BIT(0)
  37 
  38 #define AT803X_INTR_STATUS                      0x13
  39 
  40 #define AT803X_SMART_SPEED                      0x14
  41 #define AT803X_LED_CONTROL                      0x18
  42 
  43 #define AT803X_DEVICE_ADDR                      0x03
  44 #define AT803X_LOC_MAC_ADDR_0_15_OFFSET         0x804C
  45 #define AT803X_LOC_MAC_ADDR_16_31_OFFSET        0x804B
  46 #define AT803X_LOC_MAC_ADDR_32_47_OFFSET        0x804A
  47 #define AT803X_REG_CHIP_CONFIG                  0x1f
  48 #define AT803X_BT_BX_REG_SEL                    0x8000
  49 
  50 #define AT803X_DEBUG_ADDR                       0x1D
  51 #define AT803X_DEBUG_DATA                       0x1E
  52 
  53 #define AT803X_MODE_CFG_MASK                    0x0F
  54 #define AT803X_MODE_CFG_SGMII                   0x01
  55 
  56 #define AT803X_PSSR                     0x11    /*PHY-Specific Status Register*/
  57 #define AT803X_PSSR_MR_AN_COMPLETE      0x0200
  58 
  59 #define AT803X_DEBUG_REG_0                      0x00
  60 #define AT803X_DEBUG_RX_CLK_DLY_EN              BIT(15)
  61 
  62 #define AT803X_DEBUG_REG_5                      0x05
  63 #define AT803X_DEBUG_TX_CLK_DLY_EN              BIT(8)
  64 
  65 #define ATH8030_PHY_ID 0x004dd076
  66 #define ATH8031_PHY_ID 0x004dd074
  67 #define ATH8035_PHY_ID 0x004dd072
  68 #define AT803X_PHY_ID_MASK                      0xffffffef
  69 
  70 MODULE_DESCRIPTION("Atheros 803x PHY driver");
  71 MODULE_AUTHOR("Matus Ujhelyi");
  72 MODULE_LICENSE("GPL");
  73 
  74 struct at803x_priv {
  75         bool phy_reset:1;
  76 };
  77 
  78 struct at803x_context {
  79         u16 bmcr;
  80         u16 advertise;
  81         u16 control1000;
  82         u16 int_enable;
  83         u16 smart_speed;
  84         u16 led_control;
  85 };
  86 
  87 static int at803x_debug_reg_read(struct phy_device *phydev, u16 reg)
  88 {
  89         int ret;
  90 
  91         ret = phy_write(phydev, AT803X_DEBUG_ADDR, reg);
  92         if (ret < 0)
  93                 return ret;
  94 
  95         return phy_read(phydev, AT803X_DEBUG_DATA);
  96 }
  97 
  98 static int at803x_debug_reg_mask(struct phy_device *phydev, u16 reg,
  99                                  u16 clear, u16 set)
 100 {
 101         u16 val;
 102         int ret;
 103 
 104         ret = at803x_debug_reg_read(phydev, reg);
 105         if (ret < 0)
 106                 return ret;
 107 
 108         val = ret & 0xffff;
 109         val &= ~clear;
 110         val |= set;
 111 
 112         return phy_write(phydev, AT803X_DEBUG_DATA, val);
 113 }
 114 
 115 static int at803x_enable_rx_delay(struct phy_device *phydev)
 116 {
 117         return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0, 0,
 118                                      AT803X_DEBUG_RX_CLK_DLY_EN);
 119 }
 120 
 121 static int at803x_enable_tx_delay(struct phy_device *phydev)
 122 {
 123         return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_5, 0,
 124                                      AT803X_DEBUG_TX_CLK_DLY_EN);
 125 }
 126 
 127 static int at803x_disable_rx_delay(struct phy_device *phydev)
 128 {
 129         return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
 130                                      AT803X_DEBUG_RX_CLK_DLY_EN, 0);
 131 }
 132 
 133 static int at803x_disable_tx_delay(struct phy_device *phydev)
 134 {
 135         return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_5,
 136                                      AT803X_DEBUG_TX_CLK_DLY_EN, 0);
 137 }
 138 
 139 /* save relevant PHY registers to private copy */
 140 static void at803x_context_save(struct phy_device *phydev,
 141                                 struct at803x_context *context)
 142 {
 143         context->bmcr = phy_read(phydev, MII_BMCR);
 144         context->advertise = phy_read(phydev, MII_ADVERTISE);
 145         context->control1000 = phy_read(phydev, MII_CTRL1000);
 146         context->int_enable = phy_read(phydev, AT803X_INTR_ENABLE);
 147         context->smart_speed = phy_read(phydev, AT803X_SMART_SPEED);
 148         context->led_control = phy_read(phydev, AT803X_LED_CONTROL);
 149 }
 150 
 151 /* restore relevant PHY registers from private copy */
 152 static void at803x_context_restore(struct phy_device *phydev,
 153                                    const struct at803x_context *context)
 154 {
 155         phy_write(phydev, MII_BMCR, context->bmcr);
 156         phy_write(phydev, MII_ADVERTISE, context->advertise);
 157         phy_write(phydev, MII_CTRL1000, context->control1000);
 158         phy_write(phydev, AT803X_INTR_ENABLE, context->int_enable);
 159         phy_write(phydev, AT803X_SMART_SPEED, context->smart_speed);
 160         phy_write(phydev, AT803X_LED_CONTROL, context->led_control);
 161 }
 162 
 163 static int at803x_set_wol(struct phy_device *phydev,
 164                           struct ethtool_wolinfo *wol)
 165 {
 166         struct net_device *ndev = phydev->attached_dev;
 167         const u8 *mac;
 168         int ret;
 169         u32 value;
 170         unsigned int i, offsets[] = {
 171                 AT803X_LOC_MAC_ADDR_32_47_OFFSET,
 172                 AT803X_LOC_MAC_ADDR_16_31_OFFSET,
 173                 AT803X_LOC_MAC_ADDR_0_15_OFFSET,
 174         };
 175 
 176         if (!ndev)
 177                 return -ENODEV;
 178 
 179         if (wol->wolopts & WAKE_MAGIC) {
 180                 mac = (const u8 *) ndev->dev_addr;
 181 
 182                 if (!is_valid_ether_addr(mac))
 183                         return -EINVAL;
 184 
 185                 for (i = 0; i < 3; i++)
 186                         phy_write_mmd(phydev, AT803X_DEVICE_ADDR, offsets[i],
 187                                       mac[(i * 2) + 1] | (mac[(i * 2)] << 8));
 188 
 189                 value = phy_read(phydev, AT803X_INTR_ENABLE);
 190                 value |= AT803X_INTR_ENABLE_WOL;
 191                 ret = phy_write(phydev, AT803X_INTR_ENABLE, value);
 192                 if (ret)
 193                         return ret;
 194                 value = phy_read(phydev, AT803X_INTR_STATUS);
 195         } else {
 196                 value = phy_read(phydev, AT803X_INTR_ENABLE);
 197                 value &= (~AT803X_INTR_ENABLE_WOL);
 198                 ret = phy_write(phydev, AT803X_INTR_ENABLE, value);
 199                 if (ret)
 200                         return ret;
 201                 value = phy_read(phydev, AT803X_INTR_STATUS);
 202         }
 203 
 204         return ret;
 205 }
 206 
 207 static void at803x_get_wol(struct phy_device *phydev,
 208                            struct ethtool_wolinfo *wol)
 209 {
 210         u32 value;
 211 
 212         wol->supported = WAKE_MAGIC;
 213         wol->wolopts = 0;
 214 
 215         value = phy_read(phydev, AT803X_INTR_ENABLE);
 216         if (value & AT803X_INTR_ENABLE_WOL)
 217                 wol->wolopts |= WAKE_MAGIC;
 218 }
 219 
 220 static int at803x_suspend(struct phy_device *phydev)
 221 {
 222         int value;
 223         int wol_enabled;
 224 
 225         value = phy_read(phydev, AT803X_INTR_ENABLE);
 226         wol_enabled = value & AT803X_INTR_ENABLE_WOL;
 227 
 228         if (wol_enabled)
 229                 value = BMCR_ISOLATE;
 230         else
 231                 value = BMCR_PDOWN;
 232 
 233         phy_modify(phydev, MII_BMCR, 0, value);
 234 
 235         return 0;
 236 }
 237 
 238 static int at803x_resume(struct phy_device *phydev)
 239 {
 240         return phy_modify(phydev, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE, 0);
 241 }
 242 
 243 static int at803x_probe(struct phy_device *phydev)
 244 {
 245         struct device *dev = &phydev->mdio.dev;
 246         struct at803x_priv *priv;
 247 
 248         priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 249         if (!priv)
 250                 return -ENOMEM;
 251 
 252         phydev->priv = priv;
 253 
 254         return 0;
 255 }
 256 
 257 static int at803x_config_init(struct phy_device *phydev)
 258 {
 259         int ret;
 260 
 261         /* The RX and TX delay default is:
 262          *   after HW reset: RX delay enabled and TX delay disabled
 263          *   after SW reset: RX delay enabled, while TX delay retains the
 264          *   value before reset.
 265          */
 266         if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
 267             phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
 268                 ret = at803x_enable_rx_delay(phydev);
 269         else
 270                 ret = at803x_disable_rx_delay(phydev);
 271         if (ret < 0)
 272                 return ret;
 273 
 274         if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
 275             phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
 276                 ret = at803x_enable_tx_delay(phydev);
 277         else
 278                 ret = at803x_disable_tx_delay(phydev);
 279 
 280         return ret;
 281 }
 282 
 283 static int at803x_ack_interrupt(struct phy_device *phydev)
 284 {
 285         int err;
 286 
 287         err = phy_read(phydev, AT803X_INTR_STATUS);
 288 
 289         return (err < 0) ? err : 0;
 290 }
 291 
 292 static int at803x_config_intr(struct phy_device *phydev)
 293 {
 294         int err;
 295         int value;
 296 
 297         value = phy_read(phydev, AT803X_INTR_ENABLE);
 298 
 299         if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
 300                 value |= AT803X_INTR_ENABLE_AUTONEG_ERR;
 301                 value |= AT803X_INTR_ENABLE_SPEED_CHANGED;
 302                 value |= AT803X_INTR_ENABLE_DUPLEX_CHANGED;
 303                 value |= AT803X_INTR_ENABLE_LINK_FAIL;
 304                 value |= AT803X_INTR_ENABLE_LINK_SUCCESS;
 305 
 306                 err = phy_write(phydev, AT803X_INTR_ENABLE, value);
 307         }
 308         else
 309                 err = phy_write(phydev, AT803X_INTR_ENABLE, 0);
 310 
 311         return err;
 312 }
 313 
 314 static void at803x_link_change_notify(struct phy_device *phydev)
 315 {
 316         /*
 317          * Conduct a hardware reset for AT8030 every time a link loss is
 318          * signalled. This is necessary to circumvent a hardware bug that
 319          * occurs when the cable is unplugged while TX packets are pending
 320          * in the FIFO. In such cases, the FIFO enters an error mode it
 321          * cannot recover from by software.
 322          */
 323         if (phydev->state == PHY_NOLINK && phydev->mdio.reset_gpio) {
 324                 struct at803x_context context;
 325 
 326                 at803x_context_save(phydev, &context);
 327 
 328                 phy_device_reset(phydev, 1);
 329                 msleep(1);
 330                 phy_device_reset(phydev, 0);
 331                 msleep(1);
 332 
 333                 at803x_context_restore(phydev, &context);
 334 
 335                 phydev_dbg(phydev, "%s(): phy was reset\n", __func__);
 336         }
 337 }
 338 
 339 static int at803x_aneg_done(struct phy_device *phydev)
 340 {
 341         int ccr;
 342 
 343         int aneg_done = genphy_aneg_done(phydev);
 344         if (aneg_done != BMSR_ANEGCOMPLETE)
 345                 return aneg_done;
 346 
 347         /*
 348          * in SGMII mode, if copper side autoneg is successful,
 349          * also check SGMII side autoneg result
 350          */
 351         ccr = phy_read(phydev, AT803X_REG_CHIP_CONFIG);
 352         if ((ccr & AT803X_MODE_CFG_MASK) != AT803X_MODE_CFG_SGMII)
 353                 return aneg_done;
 354 
 355         /* switch to SGMII/fiber page */
 356         phy_write(phydev, AT803X_REG_CHIP_CONFIG, ccr & ~AT803X_BT_BX_REG_SEL);
 357 
 358         /* check if the SGMII link is OK. */
 359         if (!(phy_read(phydev, AT803X_PSSR) & AT803X_PSSR_MR_AN_COMPLETE)) {
 360                 phydev_warn(phydev, "803x_aneg_done: SGMII link is not ok\n");
 361                 aneg_done = 0;
 362         }
 363         /* switch back to copper page */
 364         phy_write(phydev, AT803X_REG_CHIP_CONFIG, ccr | AT803X_BT_BX_REG_SEL);
 365 
 366         return aneg_done;
 367 }
 368 
 369 static int at803x_read_status(struct phy_device *phydev)
 370 {
 371         int ss, err, old_link = phydev->link;
 372 
 373         /* Update the link, but return if there was an error */
 374         err = genphy_update_link(phydev);
 375         if (err)
 376                 return err;
 377 
 378         /* why bother the PHY if nothing can have changed */
 379         if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link)
 380                 return 0;
 381 
 382         phydev->speed = SPEED_UNKNOWN;
 383         phydev->duplex = DUPLEX_UNKNOWN;
 384         phydev->pause = 0;
 385         phydev->asym_pause = 0;
 386 
 387         err = genphy_read_lpa(phydev);
 388         if (err < 0)
 389                 return err;
 390 
 391         /* Read the AT8035 PHY-Specific Status register, which indicates the
 392          * speed and duplex that the PHY is actually using, irrespective of
 393          * whether we are in autoneg mode or not.
 394          */
 395         ss = phy_read(phydev, AT803X_SPECIFIC_STATUS);
 396         if (ss < 0)
 397                 return ss;
 398 
 399         if (ss & AT803X_SS_SPEED_DUPLEX_RESOLVED) {
 400                 switch (ss & AT803X_SS_SPEED_MASK) {
 401                 case AT803X_SS_SPEED_10:
 402                         phydev->speed = SPEED_10;
 403                         break;
 404                 case AT803X_SS_SPEED_100:
 405                         phydev->speed = SPEED_100;
 406                         break;
 407                 case AT803X_SS_SPEED_1000:
 408                         phydev->speed = SPEED_1000;
 409                         break;
 410                 }
 411                 if (ss & AT803X_SS_DUPLEX)
 412                         phydev->duplex = DUPLEX_FULL;
 413                 else
 414                         phydev->duplex = DUPLEX_HALF;
 415                 if (ss & AT803X_SS_MDIX)
 416                         phydev->mdix = ETH_TP_MDI_X;
 417                 else
 418                         phydev->mdix = ETH_TP_MDI;
 419         }
 420 
 421         if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete)
 422                 phy_resolve_aneg_pause(phydev);
 423 
 424         return 0;
 425 }
 426 
 427 static struct phy_driver at803x_driver[] = {
 428 {
 429         /* ATHEROS 8035 */
 430         .phy_id                 = ATH8035_PHY_ID,
 431         .name                   = "Atheros 8035 ethernet",
 432         .phy_id_mask            = AT803X_PHY_ID_MASK,
 433         .probe                  = at803x_probe,
 434         .config_init            = at803x_config_init,
 435         .set_wol                = at803x_set_wol,
 436         .get_wol                = at803x_get_wol,
 437         .suspend                = at803x_suspend,
 438         .resume                 = at803x_resume,
 439         /* PHY_GBIT_FEATURES */
 440         .read_status            = at803x_read_status,
 441         .ack_interrupt          = at803x_ack_interrupt,
 442         .config_intr            = at803x_config_intr,
 443 }, {
 444         /* ATHEROS 8030 */
 445         .phy_id                 = ATH8030_PHY_ID,
 446         .name                   = "Atheros 8030 ethernet",
 447         .phy_id_mask            = AT803X_PHY_ID_MASK,
 448         .probe                  = at803x_probe,
 449         .config_init            = at803x_config_init,
 450         .link_change_notify     = at803x_link_change_notify,
 451         .set_wol                = at803x_set_wol,
 452         .get_wol                = at803x_get_wol,
 453         .suspend                = at803x_suspend,
 454         .resume                 = at803x_resume,
 455         /* PHY_BASIC_FEATURES */
 456         .ack_interrupt          = at803x_ack_interrupt,
 457         .config_intr            = at803x_config_intr,
 458 }, {
 459         /* ATHEROS 8031 */
 460         .phy_id                 = ATH8031_PHY_ID,
 461         .name                   = "Atheros 8031 ethernet",
 462         .phy_id_mask            = AT803X_PHY_ID_MASK,
 463         .probe                  = at803x_probe,
 464         .config_init            = at803x_config_init,
 465         .set_wol                = at803x_set_wol,
 466         .get_wol                = at803x_get_wol,
 467         .suspend                = at803x_suspend,
 468         .resume                 = at803x_resume,
 469         /* PHY_GBIT_FEATURES */
 470         .read_status            = at803x_read_status,
 471         .aneg_done              = at803x_aneg_done,
 472         .ack_interrupt          = &at803x_ack_interrupt,
 473         .config_intr            = &at803x_config_intr,
 474 } };
 475 
 476 module_phy_driver(at803x_driver);
 477 
 478 static struct mdio_device_id __maybe_unused atheros_tbl[] = {
 479         { ATH8030_PHY_ID, AT803X_PHY_ID_MASK },
 480         { ATH8031_PHY_ID, AT803X_PHY_ID_MASK },
 481         { ATH8035_PHY_ID, AT803X_PHY_ID_MASK },
 482         { }
 483 };
 484 
 485 MODULE_DEVICE_TABLE(mdio, atheros_tbl);

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