uboot/drivers/usb/eth/lan78xx.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (c) 2017 Microchip Technology Inc. All rights reserved.
   4 */
   5
   6#include <dm.h>
   7#include <log.h>
   8#include <net.h>
   9#include <usb.h>
  10#include <linux/bitops.h>
  11#include "usb_ether.h"
  12#include "lan7x.h"
  13
  14/* LAN78xx specific register/bit defines */
  15#define LAN78XX_HW_CFG_LED1_EN          BIT(21) /* Muxed with EEDO */
  16#define LAN78XX_HW_CFG_LED0_EN          BIT(20) /* Muxed with EECLK */
  17
  18#define LAN78XX_USB_CFG0                0x080
  19#define LAN78XX_USB_CFG0_BIR            BIT(6)
  20
  21#define LAN78XX_BURST_CAP               0x090
  22
  23#define LAN78XX_BULK_IN_DLY             0x094
  24
  25#define LAN78XX_RFE_CTL                 0x0B0
  26
  27#define LAN78XX_FCT_RX_CTL              0x0C0
  28
  29#define LAN78XX_FCT_TX_CTL              0x0C4
  30
  31#define LAN78XX_FCT_RX_FIFO_END         0x0C8
  32
  33#define LAN78XX_FCT_TX_FIFO_END         0x0CC
  34
  35#define LAN78XX_FCT_FLOW                0x0D0
  36
  37#define LAN78XX_MAF_BASE                0x400
  38#define LAN78XX_MAF_HIX                 0x00
  39#define LAN78XX_MAF_LOX                 0x04
  40#define LAN78XX_MAF_HI_BEGIN            (LAN78XX_MAF_BASE + LAN78XX_MAF_HIX)
  41#define LAN78XX_MAF_LO_BEGIN            (LAN78XX_MAF_BASE + LAN78XX_MAF_LOX)
  42#define LAN78XX_MAF_HI(index)           (LAN78XX_MAF_BASE + (8 * (index)) + \
  43                                        LAN78XX_MAF_HIX)
  44#define LAN78XX_MAF_LO(index)           (LAN78XX_MAF_BASE + (8 * (index)) + \
  45                                        LAN78XX_MAF_LOX)
  46#define LAN78XX_MAF_HI_VALID            BIT(31)
  47
  48/* OTP registers */
  49#define LAN78XX_OTP_BASE_ADDR           0x00001000
  50
  51#define LAN78XX_OTP_PWR_DN              (LAN78XX_OTP_BASE_ADDR + 4 * 0x00)
  52#define LAN78XX_OTP_PWR_DN_PWRDN_N      BIT(0)
  53
  54#define LAN78XX_OTP_ADDR1               (LAN78XX_OTP_BASE_ADDR + 4 * 0x01)
  55#define LAN78XX_OTP_ADDR1_15_11         0x1F
  56
  57#define LAN78XX_OTP_ADDR2               (LAN78XX_OTP_BASE_ADDR + 4 * 0x02)
  58#define LAN78XX_OTP_ADDR2_10_3          0xFF
  59
  60#define LAN78XX_OTP_RD_DATA             (LAN78XX_OTP_BASE_ADDR + 4 * 0x06)
  61
  62#define LAN78XX_OTP_FUNC_CMD            (LAN78XX_OTP_BASE_ADDR + 4 * 0x08)
  63#define LAN78XX_OTP_FUNC_CMD_READ       BIT(0)
  64
  65#define LAN78XX_OTP_CMD_GO              (LAN78XX_OTP_BASE_ADDR + 4 * 0x0A)
  66#define LAN78XX_OTP_CMD_GO_GO           BIT(0)
  67
  68#define LAN78XX_OTP_STATUS              (LAN78XX_OTP_BASE_ADDR + 4 * 0x0C)
  69#define LAN78XX_OTP_STATUS_BUSY         BIT(0)
  70
  71#define LAN78XX_OTP_INDICATOR_1         0xF3
  72#define LAN78XX_OTP_INDICATOR_2         0xF7
  73
  74/*
  75 * Lan78xx infrastructure commands
  76 */
  77static int lan78xx_read_raw_otp(struct usb_device *udev, u32 offset,
  78                                u32 length, u8 *data)
  79{
  80        int i;
  81        int ret;
  82        u32 buf;
  83
  84        ret = lan7x_read_reg(udev, LAN78XX_OTP_PWR_DN, &buf);
  85        if (ret)
  86                return ret;
  87
  88        if (buf & LAN78XX_OTP_PWR_DN_PWRDN_N) {
  89                /* clear it and wait to be cleared */
  90                ret = lan7x_write_reg(udev, LAN78XX_OTP_PWR_DN, 0);
  91                if (ret)
  92                        return ret;
  93
  94                ret = lan7x_wait_for_bit(udev, "LAN78XX_OTP_PWR_DN_PWRDN_N",
  95                                         LAN78XX_OTP_PWR_DN,
  96                                         LAN78XX_OTP_PWR_DN_PWRDN_N,
  97                                         false, 1000, 0);
  98                if (ret)
  99                        return ret;
 100        }
 101
 102        for (i = 0; i < length; i++) {
 103                ret = lan7x_write_reg(udev, LAN78XX_OTP_ADDR1,
 104                                      ((offset + i) >> 8) &
 105                                      LAN78XX_OTP_ADDR1_15_11);
 106                if (ret)
 107                        return ret;
 108                ret = lan7x_write_reg(udev, LAN78XX_OTP_ADDR2,
 109                                      ((offset + i) & LAN78XX_OTP_ADDR2_10_3));
 110                if (ret)
 111                        return ret;
 112
 113                ret = lan7x_write_reg(udev, LAN78XX_OTP_FUNC_CMD,
 114                                      LAN78XX_OTP_FUNC_CMD_READ);
 115                if (ret)
 116                        return ret;
 117                ret = lan7x_write_reg(udev, LAN78XX_OTP_CMD_GO,
 118                                      LAN78XX_OTP_CMD_GO_GO);
 119
 120                if (ret)
 121                        return ret;
 122
 123                ret = lan7x_wait_for_bit(udev, "LAN78XX_OTP_STATUS_BUSY",
 124                                         LAN78XX_OTP_STATUS,
 125                                         LAN78XX_OTP_STATUS_BUSY,
 126                                         false, 1000, 0);
 127                if (ret)
 128                        return ret;
 129
 130                ret = lan7x_read_reg(udev, LAN78XX_OTP_RD_DATA, &buf);
 131                if (ret)
 132                        return ret;
 133
 134                data[i] = (u8)(buf & 0xFF);
 135        }
 136
 137        return 0;
 138}
 139
 140static int lan78xx_read_otp(struct usb_device *udev, u32 offset,
 141                            u32 length, u8 *data)
 142{
 143        u8 sig;
 144        int ret;
 145
 146        ret = lan78xx_read_raw_otp(udev, 0, 1, &sig);
 147
 148        if (!ret) {
 149                if (sig == LAN78XX_OTP_INDICATOR_1)
 150                        offset = offset;
 151                else if (sig == LAN78XX_OTP_INDICATOR_2)
 152                        offset += 0x100;
 153                else
 154                        return -EINVAL;
 155                ret = lan78xx_read_raw_otp(udev, offset, length, data);
 156                if (ret)
 157                        return ret;
 158        }
 159        debug("LAN78x: MAC address from OTP = %pM\n", data);
 160
 161        return ret;
 162}
 163
 164static int lan78xx_read_otp_mac(unsigned char *enetaddr,
 165                                struct usb_device *udev)
 166{
 167        int ret;
 168
 169        memset(enetaddr, 0, 6);
 170
 171        ret = lan78xx_read_otp(udev,
 172                               EEPROM_MAC_OFFSET,
 173                               ETH_ALEN,
 174                               enetaddr);
 175        if (!ret && is_valid_ethaddr(enetaddr)) {
 176                /* eeprom values are valid so use them */
 177                debug("MAC address read from OTP %pM\n", enetaddr);
 178                return 0;
 179        }
 180        debug("MAC address read from OTP invalid %pM\n", enetaddr);
 181
 182        memset(enetaddr, 0, 6);
 183        return -EINVAL;
 184}
 185
 186static int lan78xx_update_flowcontrol(struct usb_device *udev,
 187                                      struct ueth_data *dev)
 188{
 189        uint32_t flow = 0, fct_flow = 0;
 190        int ret;
 191
 192        ret = lan7x_update_flowcontrol(udev, dev, &flow, &fct_flow);
 193        if (ret)
 194                return ret;
 195
 196        ret = lan7x_write_reg(udev, LAN78XX_FCT_FLOW, fct_flow);
 197        if (ret)
 198                return ret;
 199        return lan7x_write_reg(udev, FLOW, flow);
 200}
 201
 202static int lan78xx_read_mac(unsigned char *enetaddr,
 203                            struct usb_device *udev,
 204                            struct lan7x_private *priv)
 205{
 206        u32 val;
 207        int ret;
 208        int saved = 0, done = 0;
 209
 210        /*
 211         * Depends on chip, some EEPROM pins are muxed with LED function.
 212         * disable & restore LED function to access EEPROM.
 213         */
 214        if ((priv->chipid == ID_REV_CHIP_ID_7800) ||
 215            (priv->chipid == ID_REV_CHIP_ID_7850)) {
 216                ret = lan7x_read_reg(udev, HW_CFG, &val);
 217                if (ret)
 218                        return ret;
 219                saved = val;
 220                val &= ~(LAN78XX_HW_CFG_LED1_EN | LAN78XX_HW_CFG_LED0_EN);
 221                ret = lan7x_write_reg(udev, HW_CFG, val);
 222                if (ret)
 223                        goto restore;
 224        }
 225
 226        /*
 227         * Refer to the doc/README.enetaddr and doc/README.usb for
 228         * the U-Boot MAC address policy
 229         */
 230        /* try reading mac address from EEPROM, then from OTP */
 231        ret = lan7x_read_eeprom_mac(enetaddr, udev);
 232        if (!ret)
 233                done = 1;
 234
 235restore:
 236        if ((priv->chipid == ID_REV_CHIP_ID_7800) ||
 237            (priv->chipid == ID_REV_CHIP_ID_7850)) {
 238                ret = lan7x_write_reg(udev, HW_CFG, saved);
 239                if (ret)
 240                        return ret;
 241        }
 242        /* if the EEPROM mac address is good, then exit */
 243        if (done)
 244                return 0;
 245
 246        /* try reading mac address from OTP if the device is LAN78xx */
 247        return lan78xx_read_otp_mac(enetaddr, udev);
 248}
 249
 250static int lan78xx_set_receive_filter(struct usb_device *udev)
 251{
 252        /* No multicast in u-boot for now */
 253        return lan7x_write_reg(udev, LAN78XX_RFE_CTL,
 254                               RFE_CTL_BCAST_EN | RFE_CTL_DA_PERFECT);
 255}
 256
 257/* starts the TX path */
 258static void lan78xx_start_tx_path(struct usb_device *udev)
 259{
 260        /* Enable Tx at MAC */
 261        lan7x_write_reg(udev, MAC_TX, MAC_TX_TXEN);
 262
 263        /* Enable Tx at SCSRs */
 264        lan7x_write_reg(udev, LAN78XX_FCT_TX_CTL, FCT_TX_CTL_EN);
 265}
 266
 267/* Starts the Receive path */
 268static void lan78xx_start_rx_path(struct usb_device *udev)
 269{
 270        /* Enable Rx at MAC */
 271        lan7x_write_reg(udev, MAC_RX,
 272                        LAN7X_MAC_RX_MAX_SIZE_DEFAULT |
 273                        MAC_RX_FCS_STRIP | MAC_RX_RXEN);
 274
 275        /* Enable Rx at SCSRs */
 276        lan7x_write_reg(udev, LAN78XX_FCT_RX_CTL, FCT_RX_CTL_EN);
 277}
 278
 279static int lan78xx_basic_reset(struct usb_device *udev,
 280                               struct ueth_data *dev,
 281                               struct lan7x_private *priv)
 282{
 283        int ret;
 284        u32 val;
 285
 286        ret = lan7x_basic_reset(udev, dev);
 287        if (ret)
 288                return ret;
 289
 290        /* Keep the chip ID */
 291        ret = lan7x_read_reg(udev, ID_REV, &val);
 292        if (ret)
 293                return ret;
 294        debug("LAN78xx ID_REV = 0x%08x\n", val);
 295
 296        priv->chipid = (val & ID_REV_CHIP_ID_MASK) >> 16;
 297
 298        /* Respond to the IN token with a NAK */
 299        ret = lan7x_read_reg(udev, LAN78XX_USB_CFG0, &val);
 300        if (ret)
 301                return ret;
 302        val &= ~LAN78XX_USB_CFG0_BIR;
 303        return lan7x_write_reg(udev, LAN78XX_USB_CFG0, val);
 304}
 305
 306int lan78xx_write_hwaddr(struct udevice *dev)
 307{
 308        struct usb_device *udev = dev_get_parent_priv(dev);
 309        struct eth_pdata *pdata = dev_get_plat(dev);
 310        unsigned char *enetaddr = pdata->enetaddr;
 311        u32 addr_lo = get_unaligned_le32(&enetaddr[0]);
 312        u32 addr_hi = (u32)get_unaligned_le16(&enetaddr[4]);
 313        int ret;
 314
 315        /* set hardware address */
 316        ret = lan7x_write_reg(udev, RX_ADDRL, addr_lo);
 317        if (ret)
 318                return ret;
 319
 320        ret = lan7x_write_reg(udev, RX_ADDRH, addr_hi);
 321        if (ret)
 322                return ret;
 323
 324        ret = lan7x_write_reg(udev, LAN78XX_MAF_LO(0), addr_lo);
 325        if (ret)
 326                return ret;
 327
 328        ret = lan7x_write_reg(udev, LAN78XX_MAF_HI(0),
 329                              addr_hi | LAN78XX_MAF_HI_VALID);
 330        if (ret)
 331                return ret;
 332
 333        debug("MAC addr %pM written\n", enetaddr);
 334
 335        return 0;
 336}
 337
 338static int lan78xx_eth_start(struct udevice *dev)
 339{
 340        struct usb_device *udev = dev_get_parent_priv(dev);
 341        struct lan7x_private *priv = dev_get_priv(dev);
 342
 343        int ret;
 344        u32 write_buf;
 345
 346        /* Reset and read Mac addr were done in probe() */
 347        ret = lan78xx_write_hwaddr(dev);
 348        if (ret)
 349                return ret;
 350
 351        ret = lan7x_write_reg(udev, LAN78XX_BURST_CAP, 0);
 352        if (ret)
 353                return ret;
 354
 355        ret = lan7x_write_reg(udev, LAN78XX_BULK_IN_DLY, DEFAULT_BULK_IN_DELAY);
 356        if (ret)
 357                return ret;
 358
 359        ret = lan7x_write_reg(udev, INT_STS, 0xFFFFFFFF);
 360        if (ret)
 361                return ret;
 362
 363        /* set FIFO sizes */
 364        ret = lan7x_write_reg(udev, LAN78XX_FCT_RX_FIFO_END,
 365                              (MAX_RX_FIFO_SIZE - 512) / 512);
 366        if (ret)
 367                return ret;
 368
 369        ret = lan7x_write_reg(udev, LAN78XX_FCT_TX_FIFO_END,
 370                              (MAX_TX_FIFO_SIZE - 512) / 512);
 371        if (ret)
 372                return ret;
 373
 374        /* Init Tx */
 375        ret = lan7x_write_reg(udev, FLOW, 0);
 376        if (ret)
 377                return ret;
 378
 379        /* Init Rx. Set Vlan, keep default for VLAN on 78xx */
 380        ret = lan78xx_set_receive_filter(udev);
 381        if (ret)
 382                return ret;
 383
 384        /* Init PHY, autonego, and link */
 385        ret = lan7x_eth_phylib_connect(dev, &priv->ueth);
 386        if (ret)
 387                return ret;
 388        ret = lan7x_eth_phylib_config_start(dev);
 389        if (ret)
 390                return ret;
 391
 392        /*
 393         * MAC_CR has to be set after PHY init.
 394         * MAC will auto detect the PHY speed.
 395         */
 396        ret = lan7x_read_reg(udev, MAC_CR, &write_buf);
 397        if (ret)
 398                return ret;
 399        write_buf |= MAC_CR_AUTO_DUPLEX | MAC_CR_AUTO_SPEED | MAC_CR_ADP;
 400        ret = lan7x_write_reg(udev, MAC_CR, write_buf);
 401        if (ret)
 402                return ret;
 403
 404        lan78xx_start_tx_path(udev);
 405        lan78xx_start_rx_path(udev);
 406
 407        return lan78xx_update_flowcontrol(udev, &priv->ueth);
 408}
 409
 410int lan78xx_read_rom_hwaddr(struct udevice *dev)
 411{
 412        struct usb_device *udev = dev_get_parent_priv(dev);
 413        struct eth_pdata *pdata = dev_get_plat(dev);
 414        struct lan7x_private *priv = dev_get_priv(dev);
 415        int ret;
 416
 417        ret = lan78xx_read_mac(pdata->enetaddr, udev, priv);
 418        if (ret)
 419                memset(pdata->enetaddr, 0, 6);
 420
 421        return 0;
 422}
 423
 424static int lan78xx_eth_probe(struct udevice *dev)
 425{
 426        struct usb_device *udev = dev_get_parent_priv(dev);
 427        struct lan7x_private *priv = dev_get_priv(dev);
 428        struct ueth_data *ueth = &priv->ueth;
 429        struct eth_pdata *pdata = dev_get_plat(dev);
 430        int ret;
 431
 432        /* Do a reset in order to get the MAC address from HW */
 433        if (lan78xx_basic_reset(udev, ueth, priv))
 434                return 0;
 435
 436        /* Get the MAC address */
 437        /*
 438         * We must set the eth->enetaddr from HW because the upper layer
 439         * will force to use the environmental var (usbethaddr) or random if
 440         * there is no valid MAC address in eth->enetaddr.
 441         */
 442        lan78xx_read_mac(pdata->enetaddr, udev, priv);
 443        /* Do not return 0 for not finding MAC addr in HW */
 444
 445        ret = usb_ether_register(dev, ueth, RX_URB_SIZE);
 446        if (ret)
 447                return ret;
 448
 449        /* Register phylib */
 450        return lan7x_phylib_register(dev);
 451}
 452
 453static const struct eth_ops lan78xx_eth_ops = {
 454        .start  = lan78xx_eth_start,
 455        .send   = lan7x_eth_send,
 456        .recv   = lan7x_eth_recv,
 457        .free_pkt = lan7x_free_pkt,
 458        .stop   = lan7x_eth_stop,
 459        .write_hwaddr = lan78xx_write_hwaddr,
 460        .read_rom_hwaddr = lan78xx_read_rom_hwaddr,
 461};
 462
 463U_BOOT_DRIVER(lan78xx_eth) = {
 464        .name   = "lan78xx_eth",
 465        .id     = UCLASS_ETH,
 466        .probe  = lan78xx_eth_probe,
 467        .remove = lan7x_eth_remove,
 468        .ops    = &lan78xx_eth_ops,
 469        .priv_auto      = sizeof(struct lan7x_private),
 470        .plat_auto      = sizeof(struct eth_pdata),
 471};
 472
 473static const struct usb_device_id lan78xx_eth_id_table[] = {
 474        { USB_DEVICE(0x0424, 0x7800) }, /* LAN7800 USB Ethernet */
 475        { USB_DEVICE(0x0424, 0x7850) }, /* LAN7850 USB Ethernet */
 476        { }             /* Terminating entry */
 477};
 478
 479U_BOOT_USB_DEVICE(lan78xx_eth, lan78xx_eth_id_table);
 480