]> git.sur5r.net Git - u-boot/blobdiff - drivers/usb/gadget/ether.c
Merge branch 'master' of git://git.denx.de/u-boot-arm
[u-boot] / drivers / usb / gadget / ether.c
index 7e6491d0aa4d834fbe6f3767db82ce7c6afc12fb..ba442d5ed529bb04a88a41e630477b4a46b32d46 100644 (file)
@@ -5,26 +5,13 @@
  * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger
  * Copyright (C) 2008 Nokia Corporation
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
 #include <asm/errno.h>
 #include <linux/netdevice.h>
 #include <linux/usb/ch9.h>
-#include <usbdescriptors.h>
 #include <linux/usb/cdc.h>
 #include <linux/usb/gadget.h>
 #include <net.h>
 
 #define atomic_read
 extern struct platform_data brd;
-#define spin_lock(x)
-#define spin_unlock(x)
 
 
 unsigned packet_received, packet_sent;
 
-#undef DEV_CONFIG_CDC
-#undef DEV_CONFIG_SUBSET
-
-#if !defined(CONFIG_USB_ETH_CDC) && !defined(CONFIG_USB_ETH_SUBSET)
-# define DEV_CONFIG_CDC                1       /* preserve default behavior */
-#endif
-
-#if defined(CONFIG_USB_ETH_CDC)
-# define DEV_CONFIG_CDC                1
-#endif
-
-#if defined(CONFIG_USB_ETH_SUBSET)
-# define DEV_CONFIG_SUBSET     1
-#endif
-
-#define GFP_ATOMIC ((gfp_t) 0)
-#define GFP_KERNEL ((gfp_t) 0)
-
 /*
  * Ethernet gadget driver -- with CDC and non-CDC options
  * Builds on hardware support for a full duplex link.
@@ -174,9 +141,9 @@ static struct usb_gadget_driver eth_driver;
 /* "main" config is either CDC, or its simple subset */
 static inline int is_cdc(struct eth_dev *dev)
 {
-#if    !defined(DEV_CONFIG_SUBSET)
+#if    !defined(CONFIG_USB_ETH_SUBSET)
        return 1;               /* only cdc possible */
-#elif  !defined(DEV_CONFIG_CDC)
+#elif  !defined(CONFIG_USB_ETH_CDC)
        return 0;               /* only subset possible */
 #else
        return dev->cdc;        /* depends on what hardware we found */
@@ -420,7 +387,7 @@ rndis_config = {
  * get those drivers from MCCI, or bundled with various products.
  */
 
-#ifdef DEV_CONFIG_CDC
+#ifdef CONFIG_USB_ETH_CDC
 static struct usb_interface_descriptor
 control_intf = {
        .bLength =              sizeof control_intf,
@@ -459,7 +426,7 @@ static const struct usb_cdc_header_desc header_desc = {
        .bcdCDC =               __constant_cpu_to_le16(0x0110),
 };
 
-#if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)
+#if defined(CONFIG_USB_ETH_CDC) || defined(CONFIG_USB_ETH_RNDIS)
 
 static const struct usb_cdc_union_desc union_desc = {
        .bLength =              sizeof union_desc,
@@ -493,7 +460,7 @@ static const struct usb_cdc_acm_descriptor acm_descriptor = {
 
 #endif
 
-#ifndef DEV_CONFIG_CDC
+#ifndef CONFIG_USB_ETH_CDC
 
 /*
  * "SAFE" loosely follows CDC WMC MDLM, violating the spec in various
@@ -543,7 +510,7 @@ static const struct usb_cdc_ether_desc ether_desc = {
        .bNumberPowerFilters =  0,
 };
 
-#if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)
+#if defined(CONFIG_USB_ETH_CDC) || defined(CONFIG_USB_ETH_RNDIS)
 
 /*
  * include the status endpoint if we can, even where it's optional.
@@ -575,7 +542,7 @@ fs_status_desc = {
 };
 #endif
 
-#ifdef DEV_CONFIG_CDC
+#ifdef CONFIG_USB_ETH_CDC
 
 /* the default data interface has no endpoints ... */
 
@@ -630,7 +597,7 @@ rndis_data_intf = {
 
 #endif
 
-#ifdef DEV_CONFIG_SUBSET
+#ifdef CONFIG_USB_ETH_SUBSET
 
 /*
  * "Simple" CDC-subset option is a simple vendor-neutral model that most
@@ -663,6 +630,7 @@ fs_source_desc = {
 
        .bEndpointAddress =     USB_DIR_IN,
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       __constant_cpu_to_le16(64),
 };
 
 static struct usb_endpoint_descriptor
@@ -672,11 +640,12 @@ fs_sink_desc = {
 
        .bEndpointAddress =     USB_DIR_OUT,
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       __constant_cpu_to_le16(64),
 };
 
 static const struct usb_descriptor_header *fs_eth_function[11] = {
        (struct usb_descriptor_header *) &otg_descriptor,
-#ifdef DEV_CONFIG_CDC
+#ifdef CONFIG_USB_ETH_CDC
        /* "cdc" mode descriptors */
        (struct usb_descriptor_header *) &control_intf,
        (struct usb_descriptor_header *) &header_desc,
@@ -690,12 +659,12 @@ static const struct usb_descriptor_header *fs_eth_function[11] = {
        (struct usb_descriptor_header *) &fs_source_desc,
        (struct usb_descriptor_header *) &fs_sink_desc,
        NULL,
-#endif /* DEV_CONFIG_CDC */
+#endif /* CONFIG_USB_ETH_CDC */
 };
 
 static inline void fs_subset_descriptors(void)
 {
-#ifdef DEV_CONFIG_SUBSET
+#ifdef CONFIG_USB_ETH_SUBSET
        /* behavior is "CDC Subset"; extra descriptors say "SAFE" */
        fs_eth_function[1] = (struct usb_descriptor_header *) &subset_data_intf;
        fs_eth_function[2] = (struct usb_descriptor_header *) &header_desc;
@@ -733,7 +702,7 @@ static const struct usb_descriptor_header *fs_rndis_function[] = {
  * descriptors, unless they only run at full speed.
  */
 
-#if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)
+#if defined(CONFIG_USB_ETH_CDC) || defined(CONFIG_USB_ETH_RNDIS)
 static struct usb_endpoint_descriptor
 hs_status_desc = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
@@ -743,7 +712,7 @@ hs_status_desc = {
        .wMaxPacketSize =       __constant_cpu_to_le16(STATUS_BYTECOUNT),
        .bInterval =            LOG2_STATUS_INTERVAL_MSEC + 4,
 };
-#endif /* DEV_CONFIG_CDC */
+#endif /* CONFIG_USB_ETH_CDC */
 
 static struct usb_endpoint_descriptor
 hs_source_desc = {
@@ -776,7 +745,7 @@ dev_qualifier = {
 
 static const struct usb_descriptor_header *hs_eth_function[11] = {
        (struct usb_descriptor_header *) &otg_descriptor,
-#ifdef DEV_CONFIG_CDC
+#ifdef CONFIG_USB_ETH_CDC
        /* "cdc" mode descriptors */
        (struct usb_descriptor_header *) &control_intf,
        (struct usb_descriptor_header *) &header_desc,
@@ -790,12 +759,12 @@ static const struct usb_descriptor_header *hs_eth_function[11] = {
        (struct usb_descriptor_header *) &hs_source_desc,
        (struct usb_descriptor_header *) &hs_sink_desc,
        NULL,
-#endif /* DEV_CONFIG_CDC */
+#endif /* CONFIG_USB_ETH_CDC */
 };
 
 static inline void hs_subset_descriptors(void)
 {
-#ifdef DEV_CONFIG_SUBSET
+#ifdef CONFIG_USB_ETH_SUBSET
        /* behavior is "CDC Subset"; extra descriptors say "SAFE" */
        hs_eth_function[1] = (struct usb_descriptor_header *) &subset_data_intf;
        hs_eth_function[2] = (struct usb_descriptor_header *) &header_desc;
@@ -857,11 +826,11 @@ static struct usb_string          strings[] = {
        { STRING_SERIALNUMBER,  serial_number, },
        { STRING_DATA,          "Ethernet Data", },
        { STRING_ETHADDR,       ethaddr, },
-#ifdef DEV_CONFIG_CDC
+#ifdef CONFIG_USB_ETH_CDC
        { STRING_CDC,           "CDC Ethernet", },
        { STRING_CONTROL,       "CDC Communications Control", },
 #endif
-#ifdef DEV_CONFIG_SUBSET
+#ifdef CONFIG_USB_ETH_SUBSET
        { STRING_SUBSET,        "CDC Ethernet Subset", },
 #endif
 #ifdef CONFIG_USB_ETH_RNDIS
@@ -877,34 +846,11 @@ static struct usb_gadget_strings  stringtab = {
 };
 
 /*============================================================================*/
-static u8 control_req[USB_BUFSIZ];
-#if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)
-static u8 status_req[STATUS_BYTECOUNT] __attribute__ ((aligned(4)));
-#endif
-
-
-/**
- * strlcpy - Copy a %NUL terminated string into a sized buffer
- * @dest: Where to copy the string to
- * @src: Where to copy the string from
- * @size: size of destination buffer
- *
- * Compatible with *BSD: the result is always a valid
- * NUL-terminated string that fits in the buffer (unless,
- * of course, the buffer size is zero). It does not pad
- * out the result like strncpy() does.
- */
-size_t strlcpy(char *dest, const char *src, size_t size)
-{
-       size_t ret = strlen(src);
+DEFINE_CACHE_ALIGN_BUFFER(u8, control_req, USB_BUFSIZ);
 
-       if (size) {
-               size_t len = (ret >= size) ? size - 1 : ret;
-               memcpy(dest, src, len);
-               dest[len] = '\0';
-       }
-       return ret;
-}
+#if defined(CONFIG_USB_ETH_CDC) || defined(CONFIG_USB_ETH_RNDIS)
+DEFINE_CACHE_ALIGN_BUFFER(u8, status_req, STATUS_BYTECOUNT);
+#endif
 
 /*============================================================================*/
 
@@ -967,7 +913,7 @@ set_ether_config(struct eth_dev *dev, gfp_t gfp_flags)
        int                                     result = 0;
        struct usb_gadget                       *gadget = dev->gadget;
 
-#if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)
+#if defined(CONFIG_USB_ETH_CDC) || defined(CONFIG_USB_ETH_RNDIS)
        /* status endpoint used for RNDIS and (optionally) CDC */
        if (!subset_active(dev) && dev->status_ep) {
                dev->status = ep_desc(gadget, &hs_status_desc,
@@ -1148,7 +1094,7 @@ static int eth_set_config(struct eth_dev *dev, unsigned number,
 
 /*-------------------------------------------------------------------------*/
 
-#ifdef DEV_CONFIG_CDC
+#ifdef CONFIG_USB_ETH_CDC
 
 /*
  * The interrupt endpoint is used in CDC networking models (Ethernet, ATM)
@@ -1379,7 +1325,7 @@ eth_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
                        goto done_set_intf;
                }
 
-#ifdef DEV_CONFIG_CDC
+#ifdef CONFIG_USB_ETH_CDC
                switch (wIndex) {
                case 0:         /* control/master intf */
                        if (wValue != 0)
@@ -1421,7 +1367,7 @@ eth_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
                 * all non-PXA hardware talks real CDC ...
                 */
                debug("set_interface ignored!\n");
-#endif /* DEV_CONFIG_CDC */
+#endif /* CONFIG_USB_ETH_CDC */
 
 done_set_intf:
                break;
@@ -1444,7 +1390,7 @@ done_set_intf:
                value = min(wLength, (u16) 1);
                break;
 
-#ifdef DEV_CONFIG_CDC
+#ifdef CONFIG_USB_ETH_CDC
        case USB_CDC_SET_ETHERNET_PACKET_FILTER:
                /*
                 * see 6.2.30: no data, wIndex = interface,
@@ -1468,7 +1414,7 @@ done_set_intf:
         * case USB_CDC_GET_ETHERNET_STATISTIC:
         */
 
-#endif /* DEV_CONFIG_CDC */
+#endif /* CONFIG_USB_ETH_CDC */
 
 #ifdef CONFIG_USB_ETH_RNDIS
        /*
@@ -1561,6 +1507,8 @@ static int rx_submit(struct eth_dev *dev, struct usb_request *req,
         */
 
        debug("%s\n", __func__);
+       if (!req)
+               return -EINVAL;
 
        size = (ETHER_HDR_SIZE + dev->mtu + RX_EXTRA);
        size += dev->out_ep->maxpacket - 1;
@@ -1993,8 +1941,8 @@ static int is_eth_addr_valid(char *str)
                        p = q;
                }
 
-               if (i == 6) /* it looks ok */
-                       return 1;
+               /* Now check the contents. */
+               return is_valid_ether_addr(ea);
        }
        return 0;
 }
@@ -2039,7 +1987,7 @@ static int eth_bind(struct usb_gadget *gadget)
        u8                      tmp[7];
 
        /* these flags are only ever cleared; compiler take note */
-#ifndef        DEV_CONFIG_CDC
+#ifndef        CONFIG_USB_ETH_CDC
        cdc = 0;
 #endif
 #ifndef        CONFIG_USB_ETH_RNDIS
@@ -2151,7 +2099,7 @@ autoconf_fail:
                goto autoconf_fail;
        out_ep->driver_data = out_ep;   /* claim */
 
-#if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)
+#if defined(CONFIG_USB_ETH_CDC) || defined(CONFIG_USB_ETH_RNDIS)
        /*
         * CDC Ethernet control interface doesn't require a status endpoint.
         * Since some hosts expect one, try to allocate one anyway.
@@ -2163,7 +2111,7 @@ autoconf_fail:
                } else if (rndis) {
                        error("can't run RNDIS on %s", gadget->name);
                        return -ENODEV;
-#ifdef DEV_CONFIG_CDC
+#ifdef CONFIG_USB_ETH_CDC
                } else if (cdc) {
                        control_intf.bNumEndpoints = 0;
                        /* FIXME remove endpoint from descriptor list */
@@ -2206,7 +2154,7 @@ autoconf_fail:
                                fs_source_desc.bEndpointAddress;
                hs_sink_desc.bEndpointAddress =
                                fs_sink_desc.bEndpointAddress;
-#if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)
+#if defined(CONFIG_USB_ETH_CDC) || defined(CONFIG_USB_ETH_RNDIS)
                if (status_ep)
                        hs_status_desc.bEndpointAddress =
                                        fs_status_desc.bEndpointAddress;
@@ -2275,7 +2223,7 @@ autoconf_fail:
        dev->req->complete = eth_setup_complete;
 
        /* ... and maybe likewise for status transfer */
-#if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)
+#if defined(CONFIG_USB_ETH_CDC) || defined(CONFIG_USB_ETH_RNDIS)
        if (dev->status_ep) {
                dev->stat_req = usb_ep_alloc_request(dev->status_ep,
                                                        GFP_KERNEL);