uboot/drivers/net/phy/aquantia.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Aquantia PHY drivers
   4 *
   5 * Copyright 2014 Freescale Semiconductor, Inc.
   6 */
   7#include <config.h>
   8#include <common.h>
   9#include <dm.h>
  10#include <phy.h>
  11#include <u-boot/crc.h>
  12#include <malloc.h>
  13#include <asm/byteorder.h>
  14#include <fs.h>
  15
  16#define AQUNTIA_10G_CTL         0x20
  17#define AQUNTIA_VENDOR_P1       0xc400
  18
  19#define AQUNTIA_SPEED_LSB_MASK  0x2000
  20#define AQUNTIA_SPEED_MSB_MASK  0x40
  21
  22/* registers in MDIO_MMD_VEND1 region */
  23#define GLOBAL_FIRMWARE_ID 0x20
  24#define GLOBAL_FAULT 0xc850
  25#define GLOBAL_RSTATUS_1 0xc885
  26
  27#define GLOBAL_STANDARD_CONTROL 0x0
  28#define SOFT_RESET BIT(15)
  29#define LOW_POWER BIT(11)
  30
  31#define MAILBOX_CONTROL 0x0200
  32#define MAILBOX_EXECUTE BIT(15)
  33#define MAILBOX_WRITE BIT(14)
  34#define MAILBOX_RESET_CRC BIT(12)
  35#define MAILBOX_BUSY BIT(8)
  36
  37#define MAILBOX_CRC 0x0201
  38
  39#define MAILBOX_ADDR_MSW 0x0202
  40#define MAILBOX_ADDR_LSW 0x0203
  41
  42#define MAILBOX_DATA_MSW 0x0204
  43#define MAILBOX_DATA_LSW 0x0205
  44
  45#define UP_CONTROL 0xc001
  46#define UP_RESET BIT(15)
  47#define UP_RUN_STALL_OVERRIDE BIT(6)
  48#define UP_RUN_STALL BIT(0)
  49
  50/* addresses of memory segments in the phy */
  51#define DRAM_BASE_ADDR 0x3FFE0000
  52#define IRAM_BASE_ADDR 0x40000000
  53
  54/* firmware image format constants */
  55#define VERSION_STRING_SIZE 0x40
  56#define VERSION_STRING_OFFSET 0x0200
  57#define HEADER_OFFSET 0x300
  58
  59#pragma pack(1)
  60struct fw_header {
  61        u8 padding[4];
  62        u8 iram_offset[3];
  63        u8 iram_size[3];
  64        u8 dram_offset[3];
  65        u8 dram_size[3];
  66};
  67
  68#pragma pack()
  69
  70#if defined(CONFIG_PHY_AQUANTIA_UPLOAD_FW)
  71static int aquantia_read_fw(u8 **fw_addr, size_t *fw_length)
  72{
  73        loff_t length, read;
  74        int ret;
  75        void *addr = NULL;
  76
  77        *fw_addr = NULL;
  78        *fw_length = 0;
  79        debug("Loading Acquantia microcode from %s %s\n",
  80              CONFIG_PHY_AQUANTIA_FW_PART, CONFIG_PHY_AQUANTIA_FW_NAME);
  81        ret = fs_set_blk_dev("mmc", CONFIG_PHY_AQUANTIA_FW_PART, FS_TYPE_ANY);
  82        if (ret < 0)
  83                goto cleanup;
  84
  85        ret = fs_size(CONFIG_PHY_AQUANTIA_FW_NAME, &length);
  86        if (ret < 0)
  87                goto cleanup;
  88
  89        addr = malloc(length);
  90        if (!addr) {
  91                ret = -ENOMEM;
  92                goto cleanup;
  93        }
  94
  95        ret = fs_set_blk_dev("mmc", CONFIG_PHY_AQUANTIA_FW_PART, FS_TYPE_ANY);
  96        if (ret < 0)
  97                goto cleanup;
  98
  99        ret = fs_read(CONFIG_PHY_AQUANTIA_FW_NAME, (ulong)addr, 0, length,
 100                      &read);
 101        if (ret < 0)
 102                goto cleanup;
 103
 104        *fw_addr = addr;
 105        *fw_length = length;
 106        debug("Found Acquantia microcode.\n");
 107
 108cleanup:
 109        if (ret < 0) {
 110                printf("loading firmware file %s %s failed with error %d\n",
 111                       CONFIG_PHY_AQUANTIA_FW_PART,
 112                       CONFIG_PHY_AQUANTIA_FW_NAME, ret);
 113                free(addr);
 114        }
 115        return ret;
 116}
 117
 118/* load data into the phy's memory */
 119static int aquantia_load_memory(struct phy_device *phydev, u32 addr,
 120                                const u8 *data, size_t len)
 121{
 122        size_t pos;
 123        u16 crc = 0, up_crc;
 124
 125        phy_write(phydev, MDIO_MMD_VEND1, MAILBOX_CONTROL, MAILBOX_RESET_CRC);
 126        phy_write(phydev, MDIO_MMD_VEND1, MAILBOX_ADDR_MSW, addr >> 16);
 127        phy_write(phydev, MDIO_MMD_VEND1, MAILBOX_ADDR_LSW, addr & 0xfffc);
 128
 129        for (pos = 0; pos < len; pos += min(sizeof(u32), len - pos)) {
 130                u32 word = 0;
 131
 132                memcpy(&word, &data[pos], min(sizeof(u32), len - pos));
 133
 134                phy_write(phydev, MDIO_MMD_VEND1, MAILBOX_DATA_MSW,
 135                          (word >> 16));
 136                phy_write(phydev, MDIO_MMD_VEND1, MAILBOX_DATA_LSW,
 137                          word & 0xffff);
 138
 139                phy_write(phydev, MDIO_MMD_VEND1, MAILBOX_CONTROL,
 140                          MAILBOX_EXECUTE | MAILBOX_WRITE);
 141
 142                /* keep a big endian CRC to match the phy processor */
 143                word = cpu_to_be32(word);
 144                crc = crc16_ccitt(crc, (u8 *)&word, sizeof(word));
 145        }
 146
 147        up_crc = phy_read(phydev, MDIO_MMD_VEND1, MAILBOX_CRC);
 148        if (crc != up_crc) {
 149                printf("%s crc mismatch: calculated 0x%04hx phy 0x%04hx\n",
 150                       phydev->dev->name, crc, up_crc);
 151                return -EINVAL;
 152        }
 153        return 0;
 154}
 155
 156static u32 unpack_u24(const u8 *data)
 157{
 158        return (data[2] << 16) + (data[1] << 8) + data[0];
 159}
 160
 161static int aquantia_upload_firmware(struct phy_device *phydev)
 162{
 163        int ret;
 164        u8 *addr = NULL;
 165        size_t fw_length = 0;
 166        u16 calculated_crc, read_crc;
 167        char version[VERSION_STRING_SIZE];
 168        u32 primary_offset, iram_offset, iram_size, dram_offset, dram_size;
 169        const struct fw_header *header;
 170
 171        ret = aquantia_read_fw(&addr, &fw_length);
 172        if (ret != 0)
 173                return ret;
 174
 175        read_crc = (addr[fw_length - 2] << 8)  | addr[fw_length - 1];
 176        calculated_crc = crc16_ccitt(0, addr, fw_length - 2);
 177        if (read_crc != calculated_crc) {
 178                printf("%s bad firmware crc: file 0x%04x calculated 0x%04x\n",
 179                       phydev->dev->name, read_crc, calculated_crc);
 180                ret = -EINVAL;
 181                goto done;
 182        }
 183
 184        /* Find the DRAM and IRAM sections within the firmware file. */
 185        primary_offset = ((addr[9] & 0xf) << 8 | addr[8]) << 12;
 186
 187        header = (struct fw_header *)&addr[primary_offset + HEADER_OFFSET];
 188
 189        iram_offset = primary_offset + unpack_u24(header->iram_offset);
 190        iram_size = unpack_u24(header->iram_size);
 191
 192        dram_offset = primary_offset + unpack_u24(header->dram_offset);
 193        dram_size = unpack_u24(header->dram_size);
 194
 195        debug("primary %d iram offset=%d size=%d dram offset=%d size=%d\n",
 196              primary_offset, iram_offset, iram_size, dram_offset, dram_size);
 197
 198        strlcpy(version, (char *)&addr[dram_offset + VERSION_STRING_OFFSET],
 199                VERSION_STRING_SIZE);
 200        printf("%s loading firmare version '%s'\n", phydev->dev->name, version);
 201
 202        /* stall the microcprocessor */
 203        phy_write(phydev, MDIO_MMD_VEND1, UP_CONTROL,
 204                  UP_RUN_STALL | UP_RUN_STALL_OVERRIDE);
 205
 206        debug("loading dram 0x%08x from offset=%d size=%d\n",
 207              DRAM_BASE_ADDR, dram_offset, dram_size);
 208        ret = aquantia_load_memory(phydev, DRAM_BASE_ADDR, &addr[dram_offset],
 209                                   dram_size);
 210        if (ret != 0)
 211                goto done;
 212
 213        debug("loading iram 0x%08x from offset=%d size=%d\n",
 214              IRAM_BASE_ADDR, iram_offset, iram_size);
 215        ret = aquantia_load_memory(phydev, IRAM_BASE_ADDR, &addr[iram_offset],
 216                                   iram_size);
 217        if (ret != 0)
 218                goto done;
 219
 220        /* make sure soft reset and low power mode are clear */
 221        phy_write(phydev, MDIO_MMD_VEND1, GLOBAL_STANDARD_CONTROL, 0);
 222
 223        /* Release the microprocessor. UP_RESET must be held for 100 usec. */
 224        phy_write(phydev, MDIO_MMD_VEND1, UP_CONTROL,
 225                  UP_RUN_STALL | UP_RUN_STALL_OVERRIDE | UP_RESET);
 226
 227        udelay(100);
 228
 229        phy_write(phydev, MDIO_MMD_VEND1, UP_CONTROL, UP_RUN_STALL_OVERRIDE);
 230
 231        printf("%s firmare loading done.\n", phydev->dev->name);
 232done:
 233        free(addr);
 234        return ret;
 235}
 236#else
 237static int aquantia_upload_firmware(struct phy_device *phydev)
 238{
 239        printf("ERROR %s firmware loading disabled.\n", phydev->dev->name);
 240        return -1;
 241}
 242#endif
 243
 244int aquantia_config(struct phy_device *phydev)
 245{
 246        u32 val, id, rstatus, fault;
 247
 248        id = phy_read(phydev, MDIO_MMD_VEND1, GLOBAL_FIRMWARE_ID);
 249        rstatus = phy_read(phydev, MDIO_MMD_VEND1, GLOBAL_RSTATUS_1);
 250        fault = phy_read(phydev, MDIO_MMD_VEND1, GLOBAL_FAULT);
 251
 252        if (id != 0)
 253                printf("%s running firmware version %X.%X.%X\n",
 254                       phydev->dev->name, (id >> 8), id & 0xff,
 255                       (rstatus >> 4) & 0xf);
 256
 257        if (fault != 0)
 258                printf("%s fault 0x%04x detected\n", phydev->dev->name, fault);
 259
 260        if (id == 0 || fault != 0) {
 261                int ret;
 262
 263                ret = aquantia_upload_firmware(phydev);
 264                if (ret != 0)
 265                        return ret;
 266        }
 267
 268        val = phy_read(phydev, MDIO_MMD_PMAPMD, MII_BMCR);
 269
 270        if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
 271                /* 1000BASE-T mode */
 272                phydev->advertising = SUPPORTED_1000baseT_Full;
 273                phydev->supported = phydev->advertising;
 274
 275                val = (val & ~AQUNTIA_SPEED_LSB_MASK) | AQUNTIA_SPEED_MSB_MASK;
 276                phy_write(phydev, MDIO_MMD_PMAPMD, MII_BMCR, val);
 277        } else if (phydev->interface == PHY_INTERFACE_MODE_XGMII) {
 278                /* 10GBASE-T mode */
 279                phydev->advertising = SUPPORTED_10000baseT_Full;
 280                phydev->supported = phydev->advertising;
 281
 282                if (!(val & AQUNTIA_SPEED_LSB_MASK) ||
 283                    !(val & AQUNTIA_SPEED_MSB_MASK))
 284                        phy_write(phydev, MDIO_MMD_PMAPMD, MII_BMCR,
 285                                  AQUNTIA_SPEED_LSB_MASK |
 286                                  AQUNTIA_SPEED_MSB_MASK);
 287        } else if (phydev->interface == PHY_INTERFACE_MODE_SGMII_2500) {
 288                /* 2.5GBASE-T mode */
 289                phydev->advertising = SUPPORTED_1000baseT_Full;
 290                phydev->supported = phydev->advertising;
 291
 292                phy_write(phydev, MDIO_MMD_AN, AQUNTIA_10G_CTL, 1);
 293                phy_write(phydev, MDIO_MMD_AN, AQUNTIA_VENDOR_P1, 0x9440);
 294        } else if (phydev->interface == PHY_INTERFACE_MODE_MII) {
 295                /* 100BASE-TX mode */
 296                phydev->advertising = SUPPORTED_100baseT_Full;
 297                phydev->supported = phydev->advertising;
 298
 299                val = (val & ~AQUNTIA_SPEED_MSB_MASK) | AQUNTIA_SPEED_LSB_MASK;
 300                phy_write(phydev, MDIO_MMD_PMAPMD, MII_BMCR, val);
 301        }
 302        return 0;
 303}
 304
 305int aquantia_startup(struct phy_device *phydev)
 306{
 307        u32 reg, speed;
 308        int i = 0;
 309
 310        phydev->duplex = DUPLEX_FULL;
 311
 312        /* if the AN is still in progress, wait till timeout. */
 313        phy_read(phydev, MDIO_MMD_AN, MDIO_STAT1);
 314        reg = phy_read(phydev, MDIO_MMD_AN, MDIO_STAT1);
 315        if (!(reg & MDIO_AN_STAT1_COMPLETE)) {
 316                printf("%s Waiting for PHY auto negotiation to complete",
 317                       phydev->dev->name);
 318                do {
 319                        udelay(1000);
 320                        reg = phy_read(phydev, MDIO_MMD_AN, MDIO_STAT1);
 321                        if ((i++ % 500) == 0)
 322                                printf(".");
 323                } while (!(reg & MDIO_AN_STAT1_COMPLETE) &&
 324                         i < (4 * PHY_ANEG_TIMEOUT));
 325
 326                if (i > PHY_ANEG_TIMEOUT)
 327                        printf(" TIMEOUT !\n");
 328        }
 329
 330        /* Read twice because link state is latched and a
 331         * read moves the current state into the register */
 332        phy_read(phydev, MDIO_MMD_AN, MDIO_STAT1);
 333        reg = phy_read(phydev, MDIO_MMD_AN, MDIO_STAT1);
 334        if (reg < 0 || !(reg & MDIO_STAT1_LSTATUS))
 335                phydev->link = 0;
 336        else
 337                phydev->link = 1;
 338
 339        speed = phy_read(phydev, MDIO_MMD_PMAPMD, MII_BMCR);
 340        if (speed & AQUNTIA_SPEED_MSB_MASK) {
 341                if (speed & AQUNTIA_SPEED_LSB_MASK)
 342                        phydev->speed = SPEED_10000;
 343                else
 344                        phydev->speed = SPEED_1000;
 345        } else {
 346                if (speed & AQUNTIA_SPEED_LSB_MASK)
 347                        phydev->speed = SPEED_100;
 348                else
 349                        phydev->speed = SPEED_10;
 350        }
 351
 352        return 0;
 353}
 354
 355struct phy_driver aq1202_driver = {
 356        .name = "Aquantia AQ1202",
 357        .uid = 0x3a1b445,
 358        .mask = 0xfffffff0,
 359        .features = PHY_10G_FEATURES,
 360        .mmds = (MDIO_MMD_PMAPMD | MDIO_MMD_PCS|
 361                        MDIO_MMD_PHYXS | MDIO_MMD_AN |
 362                        MDIO_MMD_VEND1),
 363        .config = &aquantia_config,
 364        .startup = &aquantia_startup,
 365        .shutdown = &gen10g_shutdown,
 366};
 367
 368struct phy_driver aq2104_driver = {
 369        .name = "Aquantia AQ2104",
 370        .uid = 0x3a1b460,
 371        .mask = 0xfffffff0,
 372        .features = PHY_10G_FEATURES,
 373        .mmds = (MDIO_MMD_PMAPMD | MDIO_MMD_PCS|
 374                        MDIO_MMD_PHYXS | MDIO_MMD_AN |
 375                        MDIO_MMD_VEND1),
 376        .config = &aquantia_config,
 377        .startup = &aquantia_startup,
 378        .shutdown = &gen10g_shutdown,
 379};
 380
 381struct phy_driver aqr105_driver = {
 382        .name = "Aquantia AQR105",
 383        .uid = 0x3a1b4a2,
 384        .mask = 0xfffffff0,
 385        .features = PHY_10G_FEATURES,
 386        .mmds = (MDIO_MMD_PMAPMD | MDIO_MMD_PCS|
 387                        MDIO_MMD_PHYXS | MDIO_MMD_AN |
 388                        MDIO_MMD_VEND1),
 389        .config = &aquantia_config,
 390        .startup = &aquantia_startup,
 391        .shutdown = &gen10g_shutdown,
 392};
 393
 394struct phy_driver aqr106_driver = {
 395        .name = "Aquantia AQR106",
 396        .uid = 0x3a1b4d0,
 397        .mask = 0xfffffff0,
 398        .features = PHY_10G_FEATURES,
 399        .mmds = (MDIO_MMD_PMAPMD | MDIO_MMD_PCS|
 400                        MDIO_MMD_PHYXS | MDIO_MMD_AN |
 401                        MDIO_MMD_VEND1),
 402        .config = &aquantia_config,
 403        .startup = &aquantia_startup,
 404        .shutdown = &gen10g_shutdown,
 405};
 406
 407struct phy_driver aqr107_driver = {
 408        .name = "Aquantia AQR107",
 409        .uid = 0x3a1b4e0,
 410        .mask = 0xfffffff0,
 411        .features = PHY_10G_FEATURES,
 412        .mmds = (MDIO_MMD_PMAPMD | MDIO_MMD_PCS|
 413                        MDIO_MMD_PHYXS | MDIO_MMD_AN |
 414                        MDIO_MMD_VEND1),
 415        .config = &aquantia_config,
 416        .startup = &aquantia_startup,
 417        .shutdown = &gen10g_shutdown,
 418};
 419
 420struct phy_driver aqr405_driver = {
 421        .name = "Aquantia AQR405",
 422        .uid = 0x3a1b4b2,
 423        .mask = 0xfffffff0,
 424        .features = PHY_10G_FEATURES,
 425        .mmds = (MDIO_MMD_PMAPMD | MDIO_MMD_PCS|
 426                 MDIO_MMD_PHYXS | MDIO_MMD_AN |
 427                 MDIO_MMD_VEND1),
 428        .config = &aquantia_config,
 429        .startup = &aquantia_startup,
 430        .shutdown = &gen10g_shutdown,
 431};
 432
 433int phy_aquantia_init(void)
 434{
 435        phy_register(&aq1202_driver);
 436        phy_register(&aq2104_driver);
 437        phy_register(&aqr105_driver);
 438        phy_register(&aqr106_driver);
 439        phy_register(&aqr107_driver);
 440        phy_register(&aqr405_driver);
 441
 442        return 0;
 443}
 444