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