summaryrefslogtreecommitdiffstats
path: root/drivers/net/usb/usbnet.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/usb/usbnet.c')
-rw-r--r--drivers/net/usb/usbnet.c66
1 files changed, 46 insertions, 20 deletions
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 60e67ff1a2..3c3da3171b 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -1,10 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0-only
#include <common.h>
-#include <usb/usb.h>
-#include <usb/usbnet.h>
+#include <linux/usb/usb.h>
+#include <linux/usb/usbnet.h>
#include <asm/byteorder.h>
#include <errno.h>
#include <malloc.h>
#include <linux/phy.h>
+#include <dma.h>
/* handles CDC Ethernet and many other network "bulk data" interfaces */
int usbnet_get_endpoints(struct usbnet *dev)
@@ -77,8 +79,6 @@ int usbnet_get_endpoints(struct usbnet *dev)
}
EXPORT_SYMBOL(usbnet_get_endpoints);
-char tx_buffer[4096];
-
static int usbnet_send(struct eth_device *edev, void *eth_data, int data_length)
{
struct usbnet *dev = edev->priv;
@@ -91,30 +91,30 @@ static int usbnet_send(struct eth_device *edev, void *eth_data, int data_length)
* win32 driver (usually) and/or hardware quirks
*/
if(info->tx_fixup) {
- if(info->tx_fixup(dev, eth_data, data_length, tx_buffer, &len)) {
+ if(info->tx_fixup(dev, eth_data, data_length, dev->tx_buf, &len)) {
dev_dbg(&edev->dev, "can't tx_fixup packet");
return 0;
}
} else {
len = data_length;
- memmove(tx_buffer, (void*) eth_data, len);
+ memmove(dev->tx_buf, (void*) eth_data, len);
}
/* don't assume the hardware handles USB_ZERO_PACKET
* NOTE: strictly conforming cdc-ether devices should expect
* the ZLP here, but ignore the one-byte packet.
*/
- if ((len % dev->maxpacket) == 0)
- tx_buffer[len++] = 0;
+ if ((len % dev->maxpacket) == 0) {
+ *(unsigned char *)(dev->tx_buf + len) = 0;
+ len++;
+ }
- ret = usb_bulk_msg(dev->udev, dev->out, tx_buffer, len, &alen, 1000);
+ ret = usb_bulk_msg(dev->udev, dev->out, dev->tx_buf, len, &alen, 1000);
dev_dbg(&edev->dev, "%s: ret: %d len: %d alen: %d\n", __func__, ret, len, alen);
return ret;
}
-static char rx_buf[4096];
-
static int usbnet_recv(struct eth_device *edev)
{
struct usbnet *dev = (struct usbnet*) edev->priv;
@@ -125,15 +125,15 @@ static int usbnet_recv(struct eth_device *edev)
len = dev->rx_urb_size;
- ret = usb_bulk_msg(dev->udev, dev->in, rx_buf, len, &alen, 100);
+ ret = usb_bulk_msg(dev->udev, dev->in, dev->rx_buf, len, &alen, 2);
if (ret)
return ret;
if (alen) {
if (info->rx_fixup)
- return info->rx_fixup(dev, rx_buf, alen);
+ return info->rx_fixup(dev, dev->rx_buf, alen);
else
- net_receive(edev, rx_buf, alen);
+ net_receive(edev, dev->rx_buf, alen);
}
return 0;
@@ -159,13 +159,22 @@ static int usbnet_init(struct eth_device *edev)
return 0;
}
+static void usbnet_adjust_link(struct eth_device *edev)
+{
+ struct usbnet *dev = (struct usbnet*)edev->priv;
+ struct driver_info *info = dev->driver_info;
+
+ if (info->link_reset)
+ info->link_reset(dev);
+}
+
static int usbnet_open(struct eth_device *edev)
{
struct usbnet *dev = (struct usbnet*)edev->priv;
dev_dbg(&edev->dev, "%s\n",__func__);
- return phy_device_connect(edev, &dev->miibus, dev->phy_addr, NULL,
+ return phy_device_connect(edev, &dev->miibus, dev->phy_addr, usbnet_adjust_link,
0, PHY_INTERFACE_MODE_NA);
}
@@ -190,11 +199,11 @@ int usbnet_probe(struct usb_device *usbdev, const struct usb_device_id *prod)
edev = &undev->edev;
undev->udev = usbdev;
- edev->open = usbnet_open,
- edev->init = usbnet_init,
- edev->send = usbnet_send,
- edev->recv = usbnet_recv,
- edev->halt = usbnet_halt,
+ edev->open = usbnet_open;
+ edev->init = usbnet_init;
+ edev->send = usbnet_send;
+ edev->recv = usbnet_recv;
+ edev->halt = usbnet_halt;
edev->priv = undev;
edev->parent = &usbdev->dev;
@@ -211,8 +220,23 @@ int usbnet_probe(struct usb_device *usbdev, const struct usb_device_id *prod)
undev->rx_urb_size = 1514; /* FIXME: What to put here? */
undev->maxpacket = usb_maxpacket(undev->udev, undev->out);
+ undev->rx_buf = dma_alloc(undev->rx_urb_size);
+ if (!undev->rx_buf) {
+ status = -ENOMEM;
+ goto out1;
+ }
+
+ undev->tx_buf = dma_alloc(4096);
+ if (!undev->tx_buf) {
+ status = -ENOMEM;
+ goto out1;
+ }
+
eth_register(edev);
+ slice_depends_on(eth_device_slice(edev), usb_device_slice(usbdev));
+ slice_depends_on(mdiobus_slice(&undev->miibus), usb_device_slice(usbdev));
+
return 0;
out1:
dev_dbg(&edev->dev, "err: %d\n", status);
@@ -231,5 +255,7 @@ void usbnet_disconnect(struct usb_device *usbdev)
eth_unregister(edev);
+ free(undev->rx_buf);
+ free(undev->tx_buf);
free(undev);
}