uboot/drivers/net/phy/mv88e61xx.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2015
   3 * Elecsys Corporation <www.elecsyscorp.com>
   4 * Kevin Smith <kevin.smith@elecsyscorp.com>
   5 *
   6 * Original driver:
   7 * (C) Copyright 2009
   8 * Marvell Semiconductor <www.marvell.com>
   9 * Prafulla Wadaskar <prafulla@marvell.com>
  10 *
  11 * SPDX-License-Identifier:     GPL-2.0+
  12 */
  13
  14/*
  15 * PHY driver for mv88e61xx ethernet switches.
  16 *
  17 * This driver configures the mv88e61xx for basic use as a PHY.  The switch
  18 * supports a VLAN configuration that determines how traffic will be routed
  19 * between the ports.  This driver uses a simple configuration that routes
  20 * traffic from each PHY port only to the CPU port, and from the CPU port to
  21 * any PHY port.
  22 *
  23 * The configuration determines which PHY ports to activate using the
  24 * CONFIG_MV88E61XX_PHY_PORTS bitmask.  Setting bit 0 will activate port 0, bit
  25 * 1 activates port 1, etc.  Do not set the bit for the port the CPU is
  26 * connected to unless it is connected over a PHY interface (not MII).
  27 *
  28 * This driver was written for and tested on the mv88e6176 with an SGMII
  29 * connection.  Other configurations should be supported, but some additions or
  30 * changes may be required.
  31 */
  32
  33#include <common.h>
  34
  35#include <bitfield.h>
  36#include <errno.h>
  37#include <malloc.h>
  38#include <miiphy.h>
  39#include <netdev.h>
  40
  41#define PHY_AUTONEGOTIATE_TIMEOUT       5000
  42
  43#define PORT_COUNT                      11
  44#define PORT_MASK                       ((1 << PORT_COUNT) - 1)
  45
  46/* Device addresses */
  47#define DEVADDR_PHY(p)                  (p)
  48#define DEVADDR_PORT(p)                 (0x10 + (p))
  49#define DEVADDR_SERDES                  0x0F
  50#define DEVADDR_GLOBAL_1                0x1B
  51#define DEVADDR_GLOBAL_2                0x1C
  52
  53/* SMI indirection registers for multichip addressing mode */
  54#define SMI_CMD_REG                     0x00
  55#define SMI_DATA_REG                    0x01
  56
  57/* Global registers */
  58#define GLOBAL1_STATUS                  0x00
  59#define GLOBAL1_CTRL                    0x04
  60#define GLOBAL1_MON_CTRL                0x1A
  61
  62/* Global 2 registers */
  63#define GLOBAL2_REG_PHY_CMD             0x18
  64#define GLOBAL2_REG_PHY_DATA            0x19
  65
  66/* Port registers */
  67#define PORT_REG_STATUS                 0x00
  68#define PORT_REG_PHYS_CTRL              0x01
  69#define PORT_REG_SWITCH_ID              0x03
  70#define PORT_REG_CTRL                   0x04
  71#define PORT_REG_VLAN_MAP               0x06
  72#define PORT_REG_VLAN_ID                0x07
  73
  74/* Phy registers */
  75#define PHY_REG_CTRL1                   0x10
  76#define PHY_REG_STATUS1                 0x11
  77#define PHY_REG_PAGE                    0x16
  78
  79/* Serdes registers */
  80#define SERDES_REG_CTRL_1               0x10
  81
  82/* Phy page numbers */
  83#define PHY_PAGE_COPPER                 0
  84#define PHY_PAGE_SERDES                 1
  85
  86/* Register fields */
  87#define GLOBAL1_CTRL_SWRESET            BIT(15)
  88
  89#define GLOBAL1_MON_CTRL_CPUDEST_SHIFT  4
  90#define GLOBAL1_MON_CTRL_CPUDEST_WIDTH  4
  91
  92#define PORT_REG_STATUS_LINK            BIT(11)
  93#define PORT_REG_STATUS_DUPLEX          BIT(10)
  94
  95#define PORT_REG_STATUS_SPEED_SHIFT     8
  96#define PORT_REG_STATUS_SPEED_WIDTH     2
  97#define PORT_REG_STATUS_SPEED_10        0
  98#define PORT_REG_STATUS_SPEED_100       1
  99#define PORT_REG_STATUS_SPEED_1000      2
 100
 101#define PORT_REG_STATUS_CMODE_MASK              0xF
 102#define PORT_REG_STATUS_CMODE_100BASE_X         0x8
 103#define PORT_REG_STATUS_CMODE_1000BASE_X        0x9
 104#define PORT_REG_STATUS_CMODE_SGMII             0xa
 105
 106#define PORT_REG_PHYS_CTRL_PCS_AN_EN    BIT(10)
 107#define PORT_REG_PHYS_CTRL_PCS_AN_RST   BIT(9)
 108#define PORT_REG_PHYS_CTRL_FC_VALUE     BIT(7)
 109#define PORT_REG_PHYS_CTRL_FC_FORCE     BIT(6)
 110#define PORT_REG_PHYS_CTRL_LINK_VALUE   BIT(5)
 111#define PORT_REG_PHYS_CTRL_LINK_FORCE   BIT(4)
 112#define PORT_REG_PHYS_CTRL_DUPLEX_VALUE BIT(3)
 113#define PORT_REG_PHYS_CTRL_DUPLEX_FORCE BIT(2)
 114#define PORT_REG_PHYS_CTRL_SPD1000      BIT(1)
 115#define PORT_REG_PHYS_CTRL_SPD_MASK     (BIT(1) | BIT(0))
 116
 117#define PORT_REG_CTRL_PSTATE_SHIFT      0
 118#define PORT_REG_CTRL_PSTATE_WIDTH      2
 119
 120#define PORT_REG_VLAN_ID_DEF_VID_SHIFT  0
 121#define PORT_REG_VLAN_ID_DEF_VID_WIDTH  12
 122
 123#define PORT_REG_VLAN_MAP_TABLE_SHIFT   0
 124#define PORT_REG_VLAN_MAP_TABLE_WIDTH   11
 125
 126#define SERDES_REG_CTRL_1_FORCE_LINK    BIT(10)
 127
 128#define PHY_REG_CTRL1_ENERGY_DET_SHIFT  8
 129#define PHY_REG_CTRL1_ENERGY_DET_WIDTH  2
 130
 131/* Field values */
 132#define PORT_REG_CTRL_PSTATE_DISABLED   0
 133#define PORT_REG_CTRL_PSTATE_FORWARD    3
 134
 135#define PHY_REG_CTRL1_ENERGY_DET_OFF    0
 136#define PHY_REG_CTRL1_ENERGY_DET_SENSE_ONLY     2
 137#define PHY_REG_CTRL1_ENERGY_DET_SENSE_XMIT     3
 138
 139/* PHY Status Register */
 140#define PHY_REG_STATUS1_SPEED           0xc000
 141#define PHY_REG_STATUS1_GBIT            0x8000
 142#define PHY_REG_STATUS1_100             0x4000
 143#define PHY_REG_STATUS1_DUPLEX          0x2000
 144#define PHY_REG_STATUS1_SPDDONE         0x0800
 145#define PHY_REG_STATUS1_LINK            0x0400
 146#define PHY_REG_STATUS1_ENERGY          0x0010
 147
 148/*
 149 * Macros for building commands for indirect addressing modes.  These are valid
 150 * for both the indirect multichip addressing mode and the PHY indirection
 151 * required for the writes to any PHY register.
 152 */
 153#define SMI_BUSY                        BIT(15)
 154#define SMI_CMD_CLAUSE_22               BIT(12)
 155#define SMI_CMD_CLAUSE_22_OP_READ       (2 << 10)
 156#define SMI_CMD_CLAUSE_22_OP_WRITE      (1 << 10)
 157
 158#define SMI_CMD_READ                    (SMI_BUSY | SMI_CMD_CLAUSE_22 | \
 159                                         SMI_CMD_CLAUSE_22_OP_READ)
 160#define SMI_CMD_WRITE                   (SMI_BUSY | SMI_CMD_CLAUSE_22 | \
 161                                         SMI_CMD_CLAUSE_22_OP_WRITE)
 162
 163#define SMI_CMD_ADDR_SHIFT              5
 164#define SMI_CMD_ADDR_WIDTH              5
 165#define SMI_CMD_REG_SHIFT               0
 166#define SMI_CMD_REG_WIDTH               5
 167
 168/* Check for required macros */
 169#ifndef CONFIG_MV88E61XX_PHY_PORTS
 170#error Define CONFIG_MV88E61XX_PHY_PORTS to indicate which physical ports \
 171        to activate
 172#endif
 173#ifndef CONFIG_MV88E61XX_CPU_PORT
 174#error Define CONFIG_MV88E61XX_CPU_PORT to the port the CPU is attached to
 175#endif
 176
 177/*
 178 *  These are ports without PHYs that may be wired directly
 179 * to other serdes interfaces
 180 */
 181#ifndef CONFIG_MV88E61XX_FIXED_PORTS
 182#define CONFIG_MV88E61XX_FIXED_PORTS 0
 183#endif
 184
 185/* ID register values for different switch models */
 186#define PORT_SWITCH_ID_6096             0x0980
 187#define PORT_SWITCH_ID_6097             0x0990
 188#define PORT_SWITCH_ID_6172             0x1720
 189#define PORT_SWITCH_ID_6176             0x1760
 190#define PORT_SWITCH_ID_6240             0x2400
 191#define PORT_SWITCH_ID_6352             0x3520
 192
 193struct mv88e61xx_phy_priv {
 194        struct mii_dev *mdio_bus;
 195        int smi_addr;
 196        int id;
 197};
 198
 199static inline int smi_cmd(int cmd, int addr, int reg)
 200{
 201        cmd = bitfield_replace(cmd, SMI_CMD_ADDR_SHIFT, SMI_CMD_ADDR_WIDTH,
 202                               addr);
 203        cmd = bitfield_replace(cmd, SMI_CMD_REG_SHIFT, SMI_CMD_REG_WIDTH, reg);
 204        return cmd;
 205}
 206
 207static inline int smi_cmd_read(int addr, int reg)
 208{
 209        return smi_cmd(SMI_CMD_READ, addr, reg);
 210}
 211
 212static inline int smi_cmd_write(int addr, int reg)
 213{
 214        return smi_cmd(SMI_CMD_WRITE, addr, reg);
 215}
 216
 217__weak int mv88e61xx_hw_reset(struct phy_device *phydev)
 218{
 219        return 0;
 220}
 221
 222/* Wait for the current SMI indirect command to complete */
 223static int mv88e61xx_smi_wait(struct mii_dev *bus, int smi_addr)
 224{
 225        int val;
 226        u32 timeout = 100;
 227
 228        do {
 229                val = bus->read(bus, smi_addr, MDIO_DEVAD_NONE, SMI_CMD_REG);
 230                if (val >= 0 && (val & SMI_BUSY) == 0)
 231                        return 0;
 232
 233                mdelay(1);
 234        } while (--timeout);
 235
 236        puts("SMI busy timeout\n");
 237        return -ETIMEDOUT;
 238}
 239
 240/*
 241 * The mv88e61xx has three types of addresses: the smi bus address, the device
 242 * address, and the register address.  The smi bus address distinguishes it on
 243 * the smi bus from other PHYs or switches.  The device address determines
 244 * which on-chip register set you are reading/writing (the various PHYs, their
 245 * associated ports, or global configuration registers).  The register address
 246 * is the offset of the register you are reading/writing.
 247 *
 248 * When the mv88e61xx is hardware configured to have address zero, it behaves in
 249 * single-chip addressing mode, where it responds to all SMI addresses, using
 250 * the smi address as its device address.  This obviously only works when this
 251 * is the only chip on the SMI bus.  This allows the driver to access device
 252 * registers without using indirection.  When the chip is configured to a
 253 * non-zero address, it only responds to that SMI address and requires indirect
 254 * writes to access the different device addresses.
 255 */
 256static int mv88e61xx_reg_read(struct phy_device *phydev, int dev, int reg)
 257{
 258        struct mv88e61xx_phy_priv *priv = phydev->priv;
 259        struct mii_dev *mdio_bus = priv->mdio_bus;
 260        int smi_addr = priv->smi_addr;
 261        int res;
 262
 263        /* In single-chip mode, the device can be addressed directly */
 264        if (smi_addr == 0)
 265                return mdio_bus->read(mdio_bus, dev, MDIO_DEVAD_NONE, reg);
 266
 267        /* Wait for the bus to become free */
 268        res = mv88e61xx_smi_wait(mdio_bus, smi_addr);
 269        if (res < 0)
 270                return res;
 271
 272        /* Issue the read command */
 273        res = mdio_bus->write(mdio_bus, smi_addr, MDIO_DEVAD_NONE, SMI_CMD_REG,
 274                         smi_cmd_read(dev, reg));
 275        if (res < 0)
 276                return res;
 277
 278        /* Wait for the read command to complete */
 279        res = mv88e61xx_smi_wait(mdio_bus, smi_addr);
 280        if (res < 0)
 281                return res;
 282
 283        /* Read the data */
 284        res = mdio_bus->read(mdio_bus, smi_addr, MDIO_DEVAD_NONE, SMI_DATA_REG);
 285        if (res < 0)
 286                return res;
 287
 288        return bitfield_extract(res, 0, 16);
 289}
 290
 291/* See the comment above mv88e61xx_reg_read */
 292static int mv88e61xx_reg_write(struct phy_device *phydev, int dev, int reg,
 293                               u16 val)
 294{
 295        struct mv88e61xx_phy_priv *priv = phydev->priv;
 296        struct mii_dev *mdio_bus = priv->mdio_bus;
 297        int smi_addr = priv->smi_addr;
 298        int res;
 299
 300        /* In single-chip mode, the device can be addressed directly */
 301        if (smi_addr == 0) {
 302                return mdio_bus->write(mdio_bus, dev, MDIO_DEVAD_NONE, reg,
 303                                val);
 304        }
 305
 306        /* Wait for the bus to become free */
 307        res = mv88e61xx_smi_wait(mdio_bus, smi_addr);
 308        if (res < 0)
 309                return res;
 310
 311        /* Set the data to write */
 312        res = mdio_bus->write(mdio_bus, smi_addr, MDIO_DEVAD_NONE,
 313                                SMI_DATA_REG, val);
 314        if (res < 0)
 315                return res;
 316
 317        /* Issue the write command */
 318        res = mdio_bus->write(mdio_bus, smi_addr, MDIO_DEVAD_NONE, SMI_CMD_REG,
 319                                smi_cmd_write(dev, reg));
 320        if (res < 0)
 321                return res;
 322
 323        /* Wait for the write command to complete */
 324        res = mv88e61xx_smi_wait(mdio_bus, smi_addr);
 325        if (res < 0)
 326                return res;
 327
 328        return 0;
 329}
 330
 331static int mv88e61xx_phy_wait(struct phy_device *phydev)
 332{
 333        int val;
 334        u32 timeout = 100;
 335
 336        do {
 337                val = mv88e61xx_reg_read(phydev, DEVADDR_GLOBAL_2,
 338                                         GLOBAL2_REG_PHY_CMD);
 339                if (val >= 0 && (val & SMI_BUSY) == 0)
 340                        return 0;
 341
 342                mdelay(1);
 343        } while (--timeout);
 344
 345        return -ETIMEDOUT;
 346}
 347
 348static int mv88e61xx_phy_read_indirect(struct mii_dev *smi_wrapper, int dev,
 349                int devad, int reg)
 350{
 351        struct phy_device *phydev;
 352        int res;
 353
 354        phydev = (struct phy_device *)smi_wrapper->priv;
 355
 356        /* Issue command to read */
 357        res = mv88e61xx_reg_write(phydev, DEVADDR_GLOBAL_2,
 358                                  GLOBAL2_REG_PHY_CMD,
 359                                  smi_cmd_read(dev, reg));
 360
 361        /* Wait for data to be read */
 362        res = mv88e61xx_phy_wait(phydev);
 363        if (res < 0)
 364                return res;
 365
 366        /* Read retrieved data */
 367        return mv88e61xx_reg_read(phydev, DEVADDR_GLOBAL_2,
 368                                  GLOBAL2_REG_PHY_DATA);
 369}
 370
 371static int mv88e61xx_phy_write_indirect(struct mii_dev *smi_wrapper, int dev,
 372                int devad, int reg, u16 data)
 373{
 374        struct phy_device *phydev;
 375        int res;
 376
 377        phydev = (struct phy_device *)smi_wrapper->priv;
 378
 379        /* Set the data to write */
 380        res = mv88e61xx_reg_write(phydev, DEVADDR_GLOBAL_2,
 381                                  GLOBAL2_REG_PHY_DATA, data);
 382        if (res < 0)
 383                return res;
 384        /* Issue the write command */
 385        res = mv88e61xx_reg_write(phydev, DEVADDR_GLOBAL_2,
 386                                  GLOBAL2_REG_PHY_CMD,
 387                                  smi_cmd_write(dev, reg));
 388        if (res < 0)
 389                return res;
 390
 391        /* Wait for command to complete */
 392        return mv88e61xx_phy_wait(phydev);
 393}
 394
 395/* Wrapper function to make calls to phy_read_indirect simpler */
 396static int mv88e61xx_phy_read(struct phy_device *phydev, int phy, int reg)
 397{
 398        return mv88e61xx_phy_read_indirect(phydev->bus, DEVADDR_PHY(phy),
 399                                           MDIO_DEVAD_NONE, reg);
 400}
 401
 402/* Wrapper function to make calls to phy_read_indirect simpler */
 403static int mv88e61xx_phy_write(struct phy_device *phydev, int phy,
 404                int reg, u16 val)
 405{
 406        return mv88e61xx_phy_write_indirect(phydev->bus, DEVADDR_PHY(phy),
 407                                            MDIO_DEVAD_NONE, reg, val);
 408}
 409
 410static int mv88e61xx_port_read(struct phy_device *phydev, u8 port, u8 reg)
 411{
 412        return mv88e61xx_reg_read(phydev, DEVADDR_PORT(port), reg);
 413}
 414
 415static int mv88e61xx_port_write(struct phy_device *phydev, u8 port, u8 reg,
 416                                                                u16 val)
 417{
 418        return mv88e61xx_reg_write(phydev, DEVADDR_PORT(port), reg, val);
 419}
 420
 421static int mv88e61xx_set_page(struct phy_device *phydev, u8 phy, u8 page)
 422{
 423        return mv88e61xx_phy_write(phydev, phy, PHY_REG_PAGE, page);
 424}
 425
 426static int mv88e61xx_get_switch_id(struct phy_device *phydev)
 427{
 428        int res;
 429
 430        res = mv88e61xx_port_read(phydev, 0, PORT_REG_SWITCH_ID);
 431        if (res < 0)
 432                return res;
 433        return res & 0xfff0;
 434}
 435
 436static bool mv88e61xx_6352_family(struct phy_device *phydev)
 437{
 438        struct mv88e61xx_phy_priv *priv = phydev->priv;
 439
 440        switch (priv->id) {
 441        case PORT_SWITCH_ID_6172:
 442        case PORT_SWITCH_ID_6176:
 443        case PORT_SWITCH_ID_6240:
 444        case PORT_SWITCH_ID_6352:
 445                return true;
 446        }
 447        return false;
 448}
 449
 450static int mv88e61xx_get_cmode(struct phy_device *phydev, u8 port)
 451{
 452        int res;
 453
 454        res = mv88e61xx_port_read(phydev, port, PORT_REG_STATUS);
 455        if (res < 0)
 456                return res;
 457        return res & PORT_REG_STATUS_CMODE_MASK;
 458}
 459
 460static int mv88e61xx_parse_status(struct phy_device *phydev)
 461{
 462        unsigned int speed;
 463        unsigned int mii_reg;
 464
 465        mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, PHY_REG_STATUS1);
 466
 467        if ((mii_reg & PHY_REG_STATUS1_LINK) &&
 468            !(mii_reg & PHY_REG_STATUS1_SPDDONE)) {
 469                int i = 0;
 470
 471                puts("Waiting for PHY realtime link");
 472                while (!(mii_reg & PHY_REG_STATUS1_SPDDONE)) {
 473                        /* Timeout reached ? */
 474                        if (i > PHY_AUTONEGOTIATE_TIMEOUT) {
 475                                puts(" TIMEOUT !\n");
 476                                phydev->link = 0;
 477                                break;
 478                        }
 479
 480                        if ((i++ % 1000) == 0)
 481                                putc('.');
 482                        udelay(1000);
 483                        mii_reg = phy_read(phydev, MDIO_DEVAD_NONE,
 484                                        PHY_REG_STATUS1);
 485                }
 486                puts(" done\n");
 487                udelay(500000); /* another 500 ms (results in faster booting) */
 488        } else {
 489                if (mii_reg & PHY_REG_STATUS1_LINK)
 490                        phydev->link = 1;
 491                else
 492                        phydev->link = 0;
 493        }
 494
 495        if (mii_reg & PHY_REG_STATUS1_DUPLEX)
 496                phydev->duplex = DUPLEX_FULL;
 497        else
 498                phydev->duplex = DUPLEX_HALF;
 499
 500        speed = mii_reg & PHY_REG_STATUS1_SPEED;
 501
 502        switch (speed) {
 503        case PHY_REG_STATUS1_GBIT:
 504                phydev->speed = SPEED_1000;
 505                break;
 506        case PHY_REG_STATUS1_100:
 507                phydev->speed = SPEED_100;
 508                break;
 509        default:
 510                phydev->speed = SPEED_10;
 511                break;
 512        }
 513
 514        return 0;
 515}
 516
 517static int mv88e61xx_switch_reset(struct phy_device *phydev)
 518{
 519        int time;
 520        int val;
 521        u8 port;
 522
 523        /* Disable all ports */
 524        for (port = 0; port < PORT_COUNT; port++) {
 525                val = mv88e61xx_port_read(phydev, port, PORT_REG_CTRL);
 526                if (val < 0)
 527                        return val;
 528                val = bitfield_replace(val, PORT_REG_CTRL_PSTATE_SHIFT,
 529                                       PORT_REG_CTRL_PSTATE_WIDTH,
 530                                       PORT_REG_CTRL_PSTATE_DISABLED);
 531                val = mv88e61xx_port_write(phydev, port, PORT_REG_CTRL, val);
 532                if (val < 0)
 533                        return val;
 534        }
 535
 536        /* Wait 2 ms for queues to drain */
 537        udelay(2000);
 538
 539        /* Reset switch */
 540        val = mv88e61xx_reg_read(phydev, DEVADDR_GLOBAL_1, GLOBAL1_CTRL);
 541        if (val < 0)
 542                return val;
 543        val |= GLOBAL1_CTRL_SWRESET;
 544        val = mv88e61xx_reg_write(phydev, DEVADDR_GLOBAL_1,
 545                                     GLOBAL1_CTRL, val);
 546        if (val < 0)
 547                return val;
 548
 549        /* Wait up to 1 second for switch reset complete */
 550        for (time = 1000; time; time--) {
 551                val = mv88e61xx_reg_read(phydev, DEVADDR_GLOBAL_1,
 552                                            GLOBAL1_CTRL);
 553                if (val >= 0 && ((val & GLOBAL1_CTRL_SWRESET) == 0))
 554                        break;
 555                udelay(1000);
 556        }
 557        if (!time)
 558                return -ETIMEDOUT;
 559
 560        return 0;
 561}
 562
 563static int mv88e61xx_serdes_init(struct phy_device *phydev)
 564{
 565        int val;
 566
 567        val = mv88e61xx_set_page(phydev, DEVADDR_SERDES, PHY_PAGE_SERDES);
 568        if (val < 0)
 569                return val;
 570
 571        /* Power up serdes module */
 572        val = mv88e61xx_phy_read(phydev, DEVADDR_SERDES, MII_BMCR);
 573        if (val < 0)
 574                return val;
 575        val &= ~(BMCR_PDOWN);
 576        val = mv88e61xx_phy_write(phydev, DEVADDR_SERDES, MII_BMCR, val);
 577        if (val < 0)
 578                return val;
 579
 580        return 0;
 581}
 582
 583static int mv88e61xx_port_enable(struct phy_device *phydev, u8 port)
 584{
 585        int val;
 586
 587        val = mv88e61xx_port_read(phydev, port, PORT_REG_CTRL);
 588        if (val < 0)
 589                return val;
 590        val = bitfield_replace(val, PORT_REG_CTRL_PSTATE_SHIFT,
 591                               PORT_REG_CTRL_PSTATE_WIDTH,
 592                               PORT_REG_CTRL_PSTATE_FORWARD);
 593        val = mv88e61xx_port_write(phydev, port, PORT_REG_CTRL, val);
 594        if (val < 0)
 595                return val;
 596
 597        return 0;
 598}
 599
 600static int mv88e61xx_port_set_vlan(struct phy_device *phydev, u8 port,
 601                                                        u16 mask)
 602{
 603        int val;
 604
 605        /* Set VID to port number plus one */
 606        val = mv88e61xx_port_read(phydev, port, PORT_REG_VLAN_ID);
 607        if (val < 0)
 608                return val;
 609        val = bitfield_replace(val, PORT_REG_VLAN_ID_DEF_VID_SHIFT,
 610                               PORT_REG_VLAN_ID_DEF_VID_WIDTH,
 611                               port + 1);
 612        val = mv88e61xx_port_write(phydev, port, PORT_REG_VLAN_ID, val);
 613        if (val < 0)
 614                return val;
 615
 616        /* Set VID mask */
 617        val = mv88e61xx_port_read(phydev, port, PORT_REG_VLAN_MAP);
 618        if (val < 0)
 619                return val;
 620        val = bitfield_replace(val, PORT_REG_VLAN_MAP_TABLE_SHIFT,
 621                               PORT_REG_VLAN_MAP_TABLE_WIDTH,
 622                               mask);
 623        val = mv88e61xx_port_write(phydev, port, PORT_REG_VLAN_MAP, val);
 624        if (val < 0)
 625                return val;
 626
 627        return 0;
 628}
 629
 630static int mv88e61xx_read_port_config(struct phy_device *phydev, u8 port)
 631{
 632        int res;
 633        int val;
 634        bool forced = false;
 635
 636        val = mv88e61xx_port_read(phydev, port, PORT_REG_STATUS);
 637        if (val < 0)
 638                return val;
 639        if (!(val & PORT_REG_STATUS_LINK)) {
 640                /* Temporarily force link to read port configuration */
 641                u32 timeout = 100;
 642                forced = true;
 643
 644                val = mv88e61xx_port_read(phydev, port, PORT_REG_PHYS_CTRL);
 645                if (val < 0)
 646                        return val;
 647                val |= (PORT_REG_PHYS_CTRL_LINK_FORCE |
 648                                PORT_REG_PHYS_CTRL_LINK_VALUE);
 649                val = mv88e61xx_port_write(phydev, port, PORT_REG_PHYS_CTRL,
 650                                           val);
 651                if (val < 0)
 652                        return val;
 653
 654                /* Wait for status register to reflect forced link */
 655                do {
 656                        val = mv88e61xx_port_read(phydev, port,
 657                                                  PORT_REG_STATUS);
 658                        if (val < 0) {
 659                                res = -EIO;
 660                                goto unforce;
 661                        }
 662                        if (val & PORT_REG_STATUS_LINK)
 663                                break;
 664                } while (--timeout);
 665
 666                if (timeout == 0) {
 667                        res = -ETIMEDOUT;
 668                        goto unforce;
 669                }
 670        }
 671
 672        if (val & PORT_REG_STATUS_DUPLEX)
 673                phydev->duplex = DUPLEX_FULL;
 674        else
 675                phydev->duplex = DUPLEX_HALF;
 676
 677        val = bitfield_extract(val, PORT_REG_STATUS_SPEED_SHIFT,
 678                               PORT_REG_STATUS_SPEED_WIDTH);
 679        switch (val) {
 680        case PORT_REG_STATUS_SPEED_1000:
 681                phydev->speed = SPEED_1000;
 682                break;
 683        case PORT_REG_STATUS_SPEED_100:
 684                phydev->speed = SPEED_100;
 685                break;
 686        default:
 687                phydev->speed = SPEED_10;
 688                break;
 689        }
 690
 691        res = 0;
 692
 693unforce:
 694        if (forced) {
 695                val = mv88e61xx_port_read(phydev, port, PORT_REG_PHYS_CTRL);
 696                if (val < 0)
 697                        return val;
 698                val &= ~(PORT_REG_PHYS_CTRL_LINK_FORCE |
 699                                PORT_REG_PHYS_CTRL_LINK_VALUE);
 700                val = mv88e61xx_port_write(phydev, port, PORT_REG_PHYS_CTRL,
 701                                           val);
 702                if (val < 0)
 703                        return val;
 704        }
 705
 706        return res;
 707}
 708
 709static int mv88e61xx_set_cpu_port(struct phy_device *phydev)
 710{
 711        int val;
 712
 713        /* Set CPUDest */
 714        val = mv88e61xx_reg_read(phydev, DEVADDR_GLOBAL_1, GLOBAL1_MON_CTRL);
 715        if (val < 0)
 716                return val;
 717        val = bitfield_replace(val, GLOBAL1_MON_CTRL_CPUDEST_SHIFT,
 718                               GLOBAL1_MON_CTRL_CPUDEST_WIDTH,
 719                               CONFIG_MV88E61XX_CPU_PORT);
 720        val = mv88e61xx_reg_write(phydev, DEVADDR_GLOBAL_1,
 721                                     GLOBAL1_MON_CTRL, val);
 722        if (val < 0)
 723                return val;
 724
 725        /* Allow CPU to route to any port */
 726        val = PORT_MASK & ~(1 << CONFIG_MV88E61XX_CPU_PORT);
 727        val = mv88e61xx_port_set_vlan(phydev, CONFIG_MV88E61XX_CPU_PORT, val);
 728        if (val < 0)
 729                return val;
 730
 731        /* Enable CPU port */
 732        val = mv88e61xx_port_enable(phydev, CONFIG_MV88E61XX_CPU_PORT);
 733        if (val < 0)
 734                return val;
 735
 736        val = mv88e61xx_read_port_config(phydev, CONFIG_MV88E61XX_CPU_PORT);
 737        if (val < 0)
 738                return val;
 739
 740        /* If CPU is connected to serdes, initialize serdes */
 741        if (mv88e61xx_6352_family(phydev)) {
 742                val = mv88e61xx_get_cmode(phydev, CONFIG_MV88E61XX_CPU_PORT);
 743                if (val < 0)
 744                        return val;
 745                if (val == PORT_REG_STATUS_CMODE_100BASE_X ||
 746                    val == PORT_REG_STATUS_CMODE_1000BASE_X ||
 747                    val == PORT_REG_STATUS_CMODE_SGMII) {
 748                        val = mv88e61xx_serdes_init(phydev);
 749                        if (val < 0)
 750                                return val;
 751                }
 752        }
 753
 754        return 0;
 755}
 756
 757static int mv88e61xx_switch_init(struct phy_device *phydev)
 758{
 759        static int init;
 760        int res;
 761
 762        if (init)
 763                return 0;
 764
 765        res = mv88e61xx_switch_reset(phydev);
 766        if (res < 0)
 767                return res;
 768
 769        res = mv88e61xx_set_cpu_port(phydev);
 770        if (res < 0)
 771                return res;
 772
 773        init = 1;
 774
 775        return 0;
 776}
 777
 778static int mv88e61xx_phy_enable(struct phy_device *phydev, u8 phy)
 779{
 780        int val;
 781
 782        val = mv88e61xx_phy_read(phydev, phy, MII_BMCR);
 783        if (val < 0)
 784                return val;
 785        val &= ~(BMCR_PDOWN);
 786        val = mv88e61xx_phy_write(phydev, phy, MII_BMCR, val);
 787        if (val < 0)
 788                return val;
 789
 790        return 0;
 791}
 792
 793static int mv88e61xx_phy_setup(struct phy_device *phydev, u8 phy)
 794{
 795        int val;
 796
 797        /*
 798         * Enable energy-detect sensing on PHY, used to determine when a PHY
 799         * port is physically connected
 800         */
 801        val = mv88e61xx_phy_read(phydev, phy, PHY_REG_CTRL1);
 802        if (val < 0)
 803                return val;
 804        val = bitfield_replace(val, PHY_REG_CTRL1_ENERGY_DET_SHIFT,
 805                               PHY_REG_CTRL1_ENERGY_DET_WIDTH,
 806                               PHY_REG_CTRL1_ENERGY_DET_SENSE_XMIT);
 807        val = mv88e61xx_phy_write(phydev, phy, PHY_REG_CTRL1, val);
 808        if (val < 0)
 809                return val;
 810
 811        return 0;
 812}
 813
 814static int mv88e61xx_fixed_port_setup(struct phy_device *phydev, u8 port)
 815{
 816        int val;
 817
 818        val = mv88e61xx_port_read(phydev, port, PORT_REG_PHYS_CTRL);
 819        if (val < 0)
 820                return val;
 821
 822        val &= ~(PORT_REG_PHYS_CTRL_SPD_MASK |
 823                 PORT_REG_PHYS_CTRL_FC_VALUE);
 824        val |= PORT_REG_PHYS_CTRL_PCS_AN_EN |
 825               PORT_REG_PHYS_CTRL_PCS_AN_RST |
 826               PORT_REG_PHYS_CTRL_FC_FORCE |
 827               PORT_REG_PHYS_CTRL_DUPLEX_VALUE |
 828               PORT_REG_PHYS_CTRL_DUPLEX_FORCE |
 829               PORT_REG_PHYS_CTRL_SPD1000;
 830
 831        return mv88e61xx_port_write(phydev, port, PORT_REG_PHYS_CTRL,
 832                                   val);
 833}
 834
 835static int mv88e61xx_phy_config_port(struct phy_device *phydev, u8 phy)
 836{
 837        int val;
 838
 839        val = mv88e61xx_port_enable(phydev, phy);
 840        if (val < 0)
 841                return val;
 842
 843        val = mv88e61xx_port_set_vlan(phydev, phy,
 844                        1 << CONFIG_MV88E61XX_CPU_PORT);
 845        if (val < 0)
 846                return val;
 847
 848        return 0;
 849}
 850
 851static int mv88e61xx_probe(struct phy_device *phydev)
 852{
 853        struct mii_dev *smi_wrapper;
 854        struct mv88e61xx_phy_priv *priv;
 855        int res;
 856
 857        res = mv88e61xx_hw_reset(phydev);
 858        if (res < 0)
 859                return res;
 860
 861        priv = malloc(sizeof(*priv));
 862        if (!priv)
 863                return -ENOMEM;
 864
 865        memset(priv, 0, sizeof(*priv));
 866
 867        /*
 868         * This device requires indirect reads/writes to the PHY registers
 869         * which the generic PHY code can't handle.  Make a wrapper MII device
 870         * to handle reads/writes
 871         */
 872        smi_wrapper = mdio_alloc();
 873        if (!smi_wrapper) {
 874                free(priv);
 875                return -ENOMEM;
 876        }
 877
 878        /*
 879         * Store the mdio bus in the private data, as we are going to replace
 880         * the bus with the wrapper bus
 881         */
 882        priv->mdio_bus = phydev->bus;
 883
 884        /*
 885         * Store the smi bus address in private data.  This lets us use the
 886         * phydev addr field for device address instead, as the genphy code
 887         * expects.
 888         */
 889        priv->smi_addr = phydev->addr;
 890
 891        /*
 892         * Store the phy_device in the wrapper mii device. This lets us get it
 893         * back when genphy functions call phy_read/phy_write.
 894         */
 895        smi_wrapper->priv = phydev;
 896        strncpy(smi_wrapper->name, "indirect mii", sizeof(smi_wrapper->name));
 897        smi_wrapper->read = mv88e61xx_phy_read_indirect;
 898        smi_wrapper->write = mv88e61xx_phy_write_indirect;
 899
 900        /* Replace the bus with the wrapper device */
 901        phydev->bus = smi_wrapper;
 902
 903        phydev->priv = priv;
 904
 905        priv->id = mv88e61xx_get_switch_id(phydev);
 906
 907        return 0;
 908}
 909
 910static int mv88e61xx_phy_config(struct phy_device *phydev)
 911{
 912        int res;
 913        int i;
 914        int ret = -1;
 915
 916        res = mv88e61xx_switch_init(phydev);
 917        if (res < 0)
 918                return res;
 919
 920        for (i = 0; i < PORT_COUNT; i++) {
 921                if ((1 << i) & CONFIG_MV88E61XX_PHY_PORTS) {
 922                        phydev->addr = i;
 923
 924                        res = mv88e61xx_phy_enable(phydev, i);
 925                        if (res < 0) {
 926                                printf("Error enabling PHY %i\n", i);
 927                                continue;
 928                        }
 929                        res = mv88e61xx_phy_setup(phydev, i);
 930                        if (res < 0) {
 931                                printf("Error setting up PHY %i\n", i);
 932                                continue;
 933                        }
 934                        res = mv88e61xx_phy_config_port(phydev, i);
 935                        if (res < 0) {
 936                                printf("Error configuring PHY %i\n", i);
 937                                continue;
 938                        }
 939
 940                        res = genphy_config_aneg(phydev);
 941                        if (res < 0) {
 942                                printf("Error setting PHY %i autoneg\n", i);
 943                                continue;
 944                        }
 945                        res = phy_reset(phydev);
 946                        if (res < 0) {
 947                                printf("Error resetting PHY %i\n", i);
 948                                continue;
 949                        }
 950
 951                        /* Return success if any PHY succeeds */
 952                        ret = 0;
 953                } else if ((1 << i) & CONFIG_MV88E61XX_FIXED_PORTS) {
 954                        res = mv88e61xx_fixed_port_setup(phydev, i);
 955                        if (res < 0) {
 956                                printf("Error configuring port %i\n", i);
 957                                continue;
 958                        }
 959                }
 960        }
 961
 962        return ret;
 963}
 964
 965static int mv88e61xx_phy_is_connected(struct phy_device *phydev)
 966{
 967        int val;
 968
 969        val = mv88e61xx_phy_read(phydev, phydev->addr, PHY_REG_STATUS1);
 970        if (val < 0)
 971                return 0;
 972
 973        /*
 974         * After reset, the energy detect signal remains high for a few seconds
 975         * regardless of whether a cable is connected.  This function will
 976         * return false positives during this time.
 977         */
 978        return (val & PHY_REG_STATUS1_ENERGY) == 0;
 979}
 980
 981static int mv88e61xx_phy_startup(struct phy_device *phydev)
 982{
 983        int i;
 984        int link = 0;
 985        int res;
 986        int speed = phydev->speed;
 987        int duplex = phydev->duplex;
 988
 989        for (i = 0; i < PORT_COUNT; i++) {
 990                if ((1 << i) & CONFIG_MV88E61XX_PHY_PORTS) {
 991                        phydev->addr = i;
 992                        if (!mv88e61xx_phy_is_connected(phydev))
 993                                continue;
 994                        res = genphy_update_link(phydev);
 995                        if (res < 0)
 996                                continue;
 997                        res = mv88e61xx_parse_status(phydev);
 998                        if (res < 0)
 999                                continue;
1000                        link = (link || phydev->link);
1001                }
1002        }
1003        phydev->link = link;
1004
1005        /* Restore CPU interface speed and duplex after it was changed for
1006         * other ports */
1007        phydev->speed = speed;
1008        phydev->duplex = duplex;
1009
1010        return 0;
1011}
1012
1013static struct phy_driver mv88e61xx_driver = {
1014        .name = "Marvell MV88E61xx",
1015        .uid = 0x01410eb1,
1016        .mask = 0xfffffff0,
1017        .features = PHY_GBIT_FEATURES,
1018        .probe = mv88e61xx_probe,
1019        .config = mv88e61xx_phy_config,
1020        .startup = mv88e61xx_phy_startup,
1021        .shutdown = &genphy_shutdown,
1022};
1023
1024static struct phy_driver mv88e609x_driver = {
1025        .name = "Marvell MV88E609x",
1026        .uid = 0x1410c89,
1027        .mask = 0xfffffff0,
1028        .features = PHY_GBIT_FEATURES,
1029        .probe = mv88e61xx_probe,
1030        .config = mv88e61xx_phy_config,
1031        .startup = mv88e61xx_phy_startup,
1032        .shutdown = &genphy_shutdown,
1033};
1034
1035int phy_mv88e61xx_init(void)
1036{
1037        phy_register(&mv88e61xx_driver);
1038        phy_register(&mv88e609x_driver);
1039
1040        return 0;
1041}
1042
1043/*
1044 * Overload weak get_phy_id definition since we need non-standard functions
1045 * to read PHY registers
1046 */
1047int get_phy_id(struct mii_dev *bus, int smi_addr, int devad, u32 *phy_id)
1048{
1049        struct phy_device temp_phy;
1050        struct mv88e61xx_phy_priv temp_priv;
1051        struct mii_dev temp_mii;
1052        int val;
1053
1054        /*
1055         * Buid temporary data structures that the chip reading code needs to
1056         * read the ID
1057         */
1058        temp_priv.mdio_bus = bus;
1059        temp_priv.smi_addr = smi_addr;
1060        temp_phy.priv = &temp_priv;
1061        temp_mii.priv = &temp_phy;
1062
1063        val = mv88e61xx_phy_read_indirect(&temp_mii, 0, devad, MII_PHYSID1);
1064        if (val < 0)
1065                return -EIO;
1066
1067        *phy_id = val << 16;
1068
1069        val = mv88e61xx_phy_read_indirect(&temp_mii, 0, devad, MII_PHYSID2);
1070        if (val < 0)
1071                return -EIO;
1072
1073        *phy_id |= (val & 0xffff);
1074
1075        return 0;
1076}
1077