diff options
Diffstat (limited to 'drivers/net/usb/usbnet.c')
-rw-r--r-- | drivers/net/usb/usbnet.c | 66 |
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); } |