Merge tag 'ti-v2020.07-rc3' of https://gitlab.denx.de/u-boot/custodians/u-boot-ti
[oweals/u-boot.git] / drivers / usb / eth / smsc95xx.c
index 1dcd088b8dfc4772ff2d621774aa04767fc13eff..d3532df141fa246fbbe2f747edac073beaef5e39 100644 (file)
@@ -1,18 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Copyright (c) 2015 Google, Inc
  * Copyright (c) 2011 The Chromium OS Authors.
  * Copyright (C) 2009 NVIDIA, Corporation
  * Copyright (C) 2007-2008 SMSC (Steve Glendinning)
- *
- * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
 #include <dm.h>
 #include <errno.h>
+#include <log.h>
 #include <malloc.h>
+#include <memalign.h>
+#include <net.h>
 #include <usb.h>
 #include <asm/unaligned.h>
+#include <linux/delay.h>
 #include <linux/mii.h>
 #include "usb_ether.h"
 
 /* Some extra defines */
 #define HS_USB_PKT_SIZE                        512
 #define FS_USB_PKT_SIZE                        64
-#define DEFAULT_HS_BURST_CAP_SIZE      (16 * 1024 + 5 * HS_USB_PKT_SIZE)
-#define DEFAULT_FS_BURST_CAP_SIZE      (6 * 1024 + 33 * FS_USB_PKT_SIZE)
+/* 5/33 is lower limit for BURST_CAP to work */
+#define DEFAULT_HS_BURST_CAP_SIZE      (5 * HS_USB_PKT_SIZE)
+#define DEFAULT_FS_BURST_CAP_SIZE      (33 * FS_USB_PKT_SIZE)
 #define DEFAULT_BULK_IN_DELAY          0x00002000
 #define MAX_SINGLE_PACKET_SIZE         2048
 #define EEPROM_MAC_OFFSET              0x01
 #define USB_BULK_SEND_TIMEOUT 5000
 #define USB_BULK_RECV_TIMEOUT 5000
 
-#define RX_URB_SIZE 2048
+#define RX_URB_SIZE DEFAULT_HS_BURST_CAP_SIZE
 #define PHY_CONNECT_TIMEOUT 5000
 
 #define TURBO_MODE
@@ -186,10 +190,10 @@ static int smsc95xx_read_reg(struct usb_device *udev, u32 index, u32 *data)
        len = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
                              USB_VENDOR_REQUEST_READ_REGISTER,
                              USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-                             0, index, tmpbuf, sizeof(data),
+                             0, index, tmpbuf, sizeof(*data),
                              USB_CTRL_GET_TIMEOUT);
        *data = tmpbuf[0];
-       if (len != sizeof(data)) {
+       if (len != sizeof(*data)) {
                debug("smsc95xx_read_reg failed: index=%d, len=%d",
                      index, len);
                return -EIO;
@@ -389,8 +393,8 @@ static int smsc95xx_write_hwaddr_common(struct usb_device *udev,
                                        struct smsc95xx_private *priv,
                                        unsigned char *enetaddr)
 {
-       u32 addr_lo = __get_unaligned_le32(&enetaddr[0]);
-       u32 addr_hi = __get_unaligned_le16(&enetaddr[4]);
+       u32 addr_lo = get_unaligned_le32(&enetaddr[0]);
+       u32 addr_hi = get_unaligned_le16(&enetaddr[4]);
        int ret;
 
        /* set hardware address */
@@ -517,9 +521,11 @@ static int smsc95xx_init_common(struct usb_device *udev, struct ueth_data *dev,
                debug("timeout waiting for PHY Reset\n");
                return -ETIMEDOUT;
        }
+#ifndef CONFIG_DM_ETH
        if (!priv->have_hwaddr && smsc95xx_init_mac_address(enetaddr, udev) ==
                        0)
                priv->have_hwaddr = 1;
+#endif
        if (!priv->have_hwaddr) {
                puts("Error: SMSC95xx: No MAC address set - set usbethaddr\n");
                return -EADDRNOTAVAIL;
@@ -528,22 +534,6 @@ static int smsc95xx_init_common(struct usb_device *udev, struct ueth_data *dev,
        if (ret < 0)
                return ret;
 
-       ret = smsc95xx_read_reg(udev, HW_CFG, &read_buf);
-       if (ret < 0)
-               return ret;
-       debug("Read Value from HW_CFG : 0x%08x\n", read_buf);
-
-       read_buf |= HW_CFG_BIR_;
-       ret = smsc95xx_write_reg(udev, HW_CFG, read_buf);
-       if (ret < 0)
-               return ret;
-
-       ret = smsc95xx_read_reg(udev, HW_CFG, &read_buf);
-       if (ret < 0)
-               return ret;
-       debug("Read Value from HW_CFG after writing "
-               "HW_CFG_BIR_: 0x%08x\n", read_buf);
-
 #ifdef TURBO_MODE
        if (dev->pusb_dev->speed == USB_SPEED_HIGH) {
                burst_cap = DEFAULT_HS_BURST_CAP_SIZE / HS_USB_PKT_SIZE;
@@ -694,7 +684,8 @@ static int smsc95xx_send_common(struct ueth_data *dev, void *packet, int length)
        ALLOC_CACHE_ALIGN_BUFFER(unsigned char, msg,
                                 PKTSIZE + sizeof(tx_cmd_a) + sizeof(tx_cmd_b));
 
-       debug("** %s(), len %d, buf %#x\n", __func__, length, (int)msg);
+       debug("** %s(), len %d, buf %#x\n", __func__, length,
+             (unsigned int)(ulong)msg);
        if (length > PKTSIZE)
                return -ENOSPC;
 
@@ -715,8 +706,8 @@ static int smsc95xx_send_common(struct ueth_data *dev, void *packet, int length)
                                &actual_len,
                                USB_BULK_SEND_TIMEOUT);
        debug("Tx: len = %u, actual = %u, err = %d\n",
-             length + sizeof(tx_cmd_a) + sizeof(tx_cmd_b),
-             actual_len, err);
+             (unsigned int)(length + sizeof(tx_cmd_a) + sizeof(tx_cmd_b)),
+             (unsigned int)actual_len, err);
 
        return err;
 }
@@ -798,7 +789,7 @@ static int smsc95xx_recv(struct eth_device *eth)
                /* Adjust for next iteration */
                actual_len -= sizeof(packet_len) + packet_len;
                buf_ptr += sizeof(packet_len) + packet_len;
-               cur_buf_align = (int)buf_ptr - (int)recv_buf;
+               cur_buf_align = (ulong)buf_ptr - (ulong)recv_buf;
 
                if (cur_buf_align & 0x03) {
                        int align = 4 - (cur_buf_align & 0x03);
@@ -944,7 +935,7 @@ int smsc95xx_eth_get_info(struct usb_device *dev, struct ueth_data *ss,
 #ifdef CONFIG_DM_ETH
 static int smsc95xx_eth_start(struct udevice *dev)
 {
-       struct usb_device *udev = dev_get_parentdata(dev);
+       struct usb_device *udev = dev_get_parent_priv(dev);
        struct smsc95xx_private *priv = dev_get_priv(dev);
        struct eth_pdata *pdata = dev_get_platdata(dev);
 
@@ -1009,7 +1000,7 @@ int smsc95xx_eth_recv(struct udevice *dev, int flags, uchar **packetp)
        }
 
        *packetp = ptr + sizeof(packet_len);
-       return packet_len;
+       return packet_len - 4;
 
 err:
        usb_ether_advance_rxbuf(ueth, -1);
@@ -1020,7 +1011,7 @@ static int smsc95xx_free_pkt(struct udevice *dev, uchar *packet, int packet_len)
 {
        struct smsc95xx_private *priv = dev_get_priv(dev);
 
-       packet_len = ALIGN(packet_len, 4);
+       packet_len = ALIGN(packet_len + sizeof(u32), 4);
        usb_ether_advance_rxbuf(&priv->ueth, sizeof(u32) + packet_len);
 
        return 0;
@@ -1028,13 +1019,26 @@ static int smsc95xx_free_pkt(struct udevice *dev, uchar *packet, int packet_len)
 
 int smsc95xx_write_hwaddr(struct udevice *dev)
 {
-       struct usb_device *udev = dev_get_parentdata(dev);
+       struct usb_device *udev = dev_get_parent_priv(dev);
        struct eth_pdata *pdata = dev_get_platdata(dev);
        struct smsc95xx_private *priv = dev_get_priv(dev);
 
        return smsc95xx_write_hwaddr_common(udev, priv, pdata->enetaddr);
 }
 
+int smsc95xx_read_rom_hwaddr(struct udevice *dev)
+{
+       struct usb_device *udev = dev_get_parent_priv(dev);
+       struct eth_pdata *pdata = dev_get_platdata(dev);
+       int ret;
+
+       ret = smsc95xx_init_mac_address(pdata->enetaddr, udev);
+       if (ret)
+               memset(pdata->enetaddr, 0, 6);
+
+       return 0;
+}
+
 static int smsc95xx_eth_probe(struct udevice *dev)
 {
        struct smsc95xx_private *priv = dev_get_priv(dev);
@@ -1050,6 +1054,7 @@ static const struct eth_ops smsc95xx_eth_ops = {
        .free_pkt = smsc95xx_free_pkt,
        .stop   = smsc95xx_eth_stop,
        .write_hwaddr = smsc95xx_write_hwaddr,
+       .read_rom_hwaddr = smsc95xx_read_rom_hwaddr,
 };
 
 U_BOOT_DRIVER(smsc95xx_eth) = {