LCOV - code coverage report
Current view: top level - drivers/net/usb - cdc_subset.c (source / functions) Hit Total Coverage
Test: gcov_data_raspi2_qemu_modules_combined.info Lines: 3 14 21.4 %
Date: 2020-09-30 20:25:01 Functions: 2 6 33.3 %
Branches: 0 2 0.0 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0-or-later
       2                 :            : /*
       3                 :            :  * Simple "CDC Subset" USB Networking Links
       4                 :            :  * Copyright (C) 2000-2005 by David Brownell
       5                 :            :  */
       6                 :            : 
       7                 :            : #include <linux/module.h>
       8                 :            : #include <linux/kmod.h>
       9                 :            : #include <linux/netdevice.h>
      10                 :            : #include <linux/etherdevice.h>
      11                 :            : #include <linux/ethtool.h>
      12                 :            : #include <linux/workqueue.h>
      13                 :            : #include <linux/mii.h>
      14                 :            : #include <linux/usb.h>
      15                 :            : #include <linux/usb/usbnet.h>
      16                 :            : 
      17                 :            : 
      18                 :            : /*
      19                 :            :  * This supports simple USB network links that don't require any special
      20                 :            :  * framing or hardware control operations.  The protocol used here is a
      21                 :            :  * strict subset of CDC Ethernet, with three basic differences reflecting
      22                 :            :  * the goal that almost any hardware should run it:
      23                 :            :  *
      24                 :            :  *  - Minimal runtime control:  one interface, no altsettings, and
      25                 :            :  *    no vendor or class specific control requests.  If a device is
      26                 :            :  *    configured, it is allowed to exchange packets with the host.
      27                 :            :  *    Fancier models would mean not working on some hardware.
      28                 :            :  *
      29                 :            :  *  - Minimal manufacturing control:  no IEEE "Organizationally
      30                 :            :  *    Unique ID" required, or an EEPROMs to store one.  Each host uses
      31                 :            :  *    one random "locally assigned" Ethernet address instead, which can
      32                 :            :  *    of course be overridden using standard tools like "ifconfig".
      33                 :            :  *    (With 2^46 such addresses, same-net collisions are quite rare.)
      34                 :            :  *
      35                 :            :  *  - There is no additional framing data for USB.  Packets are written
      36                 :            :  *    exactly as in CDC Ethernet, starting with an Ethernet header and
      37                 :            :  *    terminated by a short packet.  However, the host will never send a
      38                 :            :  *    zero length packet; some systems can't handle those robustly.
      39                 :            :  *
      40                 :            :  * Anything that can transmit and receive USB bulk packets can implement
      41                 :            :  * this protocol.  That includes both smart peripherals and quite a lot
      42                 :            :  * of "host-to-host" USB cables (which embed two devices back-to-back).
      43                 :            :  *
      44                 :            :  * Note that although Linux may use many of those host-to-host links
      45                 :            :  * with this "cdc_subset" framing, that doesn't mean there may not be a
      46                 :            :  * better approach.  Handling the "other end unplugs/replugs" scenario
      47                 :            :  * well tends to require chip-specific vendor requests.  Also, Windows
      48                 :            :  * peers at the other end of host-to-host cables may expect their own
      49                 :            :  * framing to be used rather than this "cdc_subset" model.
      50                 :            :  */
      51                 :            : 
      52                 :            : #if defined(CONFIG_USB_EPSON2888) || defined(CONFIG_USB_ARMLINUX)
      53                 :            : /* PDA style devices are always connected if present */
      54                 :        248 : static int always_connected (struct usbnet *dev)
      55                 :            : {
      56                 :        248 :         return 0;
      57                 :            : }
      58                 :            : #endif
      59                 :            : 
      60                 :            : #ifdef  CONFIG_USB_ALI_M5632
      61                 :            : #define HAVE_HARDWARE
      62                 :            : 
      63                 :            : /*-------------------------------------------------------------------------
      64                 :            :  *
      65                 :            :  * ALi M5632 driver ... does high speed
      66                 :            :  *
      67                 :            :  * NOTE that the MS-Windows drivers for this chip use some funky and
      68                 :            :  * (naturally) undocumented 7-byte prefix to each packet, so this is a
      69                 :            :  * case where we don't currently interoperate.  Also, once you unplug
      70                 :            :  * one end of the cable, you need to replug the other end too ... since
      71                 :            :  * chip docs are unavailable, there's no way to reset the relevant state
      72                 :            :  * short of a power cycle.
      73                 :            :  *
      74                 :            :  *-------------------------------------------------------------------------*/
      75                 :            : 
      76                 :          0 : static void m5632_recover(struct usbnet *dev)
      77                 :            : {
      78                 :          0 :         struct usb_device       *udev = dev->udev;
      79                 :          0 :         struct usb_interface    *intf = dev->intf;
      80                 :            :         int r;
      81                 :            : 
      82                 :          0 :         r = usb_lock_device_for_reset(udev, intf);
      83         [ #  # ]:          0 :         if (r < 0)
      84                 :          0 :                 return;
      85                 :            : 
      86                 :          0 :         usb_reset_device(udev);
      87                 :            :         usb_unlock_device(udev);
      88                 :            : }
      89                 :            : 
      90                 :            : static const struct driver_info ali_m5632_info = {
      91                 :            :         .description =  "ALi M5632",
      92                 :            :         .flags       = FLAG_POINTTOPOINT,
      93                 :            :         .recover     = m5632_recover,
      94                 :            : };
      95                 :            : 
      96                 :            : #endif
      97                 :            : 
      98                 :            : #ifdef  CONFIG_USB_AN2720
      99                 :            : #define HAVE_HARDWARE
     100                 :            : 
     101                 :            : /*-------------------------------------------------------------------------
     102                 :            :  *
     103                 :            :  * AnchorChips 2720 driver ... http://www.cypress.com
     104                 :            :  *
     105                 :            :  * This doesn't seem to have a way to detect whether the peer is
     106                 :            :  * connected, or need any reset handshaking.  It's got pretty big
     107                 :            :  * internal buffers (handles most of a frame's worth of data).
     108                 :            :  * Chip data sheets don't describe any vendor control messages.
     109                 :            :  *
     110                 :            :  *-------------------------------------------------------------------------*/
     111                 :            : 
     112                 :            : static const struct driver_info an2720_info = {
     113                 :            :         .description =  "AnchorChips/Cypress 2720",
     114                 :            :         .flags       = FLAG_POINTTOPOINT,
     115                 :            :         // no reset available!
     116                 :            :         // no check_connect available!
     117                 :            : 
     118                 :            :         .in = 2, .out = 2,              // direction distinguishes these
     119                 :            : };
     120                 :            : 
     121                 :            : #endif  /* CONFIG_USB_AN2720 */
     122                 :            : 
     123                 :            : 
     124                 :            : #ifdef  CONFIG_USB_BELKIN
     125                 :            : #define HAVE_HARDWARE
     126                 :            : 
     127                 :            : /*-------------------------------------------------------------------------
     128                 :            :  *
     129                 :            :  * Belkin F5U104 ... two NetChip 2280 devices + Atmel AVR microcontroller
     130                 :            :  *
     131                 :            :  * ... also two eTEK designs, including one sold as "Advance USBNET"
     132                 :            :  *
     133                 :            :  *-------------------------------------------------------------------------*/
     134                 :            : 
     135                 :            : static const struct driver_info belkin_info = {
     136                 :            :         .description =  "Belkin, eTEK, or compatible",
     137                 :            :         .flags       = FLAG_POINTTOPOINT,
     138                 :            : };
     139                 :            : 
     140                 :            : #endif  /* CONFIG_USB_BELKIN */
     141                 :            : 
     142                 :            : 
     143                 :            : 
     144                 :            : #ifdef  CONFIG_USB_EPSON2888
     145                 :            : #define HAVE_HARDWARE
     146                 :            : 
     147                 :            : /*-------------------------------------------------------------------------
     148                 :            :  *
     149                 :            :  * EPSON USB clients
     150                 :            :  *
     151                 :            :  * This is the same idea as Linux PDAs (below) except the firmware in the
     152                 :            :  * device might not be Tux-powered.  Epson provides reference firmware that
     153                 :            :  * implements this interface.  Product developers can reuse or modify that
     154                 :            :  * code, such as by using their own product and vendor codes.
     155                 :            :  *
     156                 :            :  * Support was from Juro Bystricky <bystricky.juro@erd.epson.com>
     157                 :            :  *
     158                 :            :  *-------------------------------------------------------------------------*/
     159                 :            : 
     160                 :            : static const struct driver_info epson2888_info = {
     161                 :            :         .description =  "Epson USB Device",
     162                 :            :         .check_connect = always_connected,
     163                 :            :         .flags = FLAG_POINTTOPOINT,
     164                 :            : 
     165                 :            :         .in = 4, .out = 3,
     166                 :            : };
     167                 :            : 
     168                 :            : #endif  /* CONFIG_USB_EPSON2888 */
     169                 :            : 
     170                 :            : 
     171                 :            : /*-------------------------------------------------------------------------
     172                 :            :  *
     173                 :            :  * info from Jonathan McDowell <noodles@earth.li>
     174                 :            :  *
     175                 :            :  *-------------------------------------------------------------------------*/
     176                 :            : #ifdef CONFIG_USB_KC2190
     177                 :            : #define HAVE_HARDWARE
     178                 :            : static const struct driver_info kc2190_info = {
     179                 :            :         .description =  "KC Technology KC-190",
     180                 :            :         .flags = FLAG_POINTTOPOINT,
     181                 :            : };
     182                 :            : #endif /* CONFIG_USB_KC2190 */
     183                 :            : 
     184                 :            : 
     185                 :            : #ifdef  CONFIG_USB_ARMLINUX
     186                 :            : #define HAVE_HARDWARE
     187                 :            : 
     188                 :            : /*-------------------------------------------------------------------------
     189                 :            :  *
     190                 :            :  * Intel's SA-1100 chip integrates basic USB support, and is used
     191                 :            :  * in PDAs like some iPaqs, the Yopy, some Zaurus models, and more.
     192                 :            :  * When they run Linux, arch/arm/mach-sa1100/usb-eth.c may be used to
     193                 :            :  * network using minimal USB framing data.
     194                 :            :  *
     195                 :            :  * This describes the driver currently in standard ARM Linux kernels.
     196                 :            :  * The Zaurus uses a different driver (see later).
     197                 :            :  *
     198                 :            :  * PXA25x and PXA210 use XScale cores (ARM v5TE) with better USB support
     199                 :            :  * and different USB endpoint numbering than the SA1100 devices.  The
     200                 :            :  * mach-pxa/usb-eth.c driver re-uses the device ids from mach-sa1100
     201                 :            :  * so we rely on the endpoint descriptors.
     202                 :            :  *
     203                 :            :  *-------------------------------------------------------------------------*/
     204                 :            : 
     205                 :            : static const struct driver_info linuxdev_info = {
     206                 :            :         .description =  "Linux Device",
     207                 :            :         .check_connect = always_connected,
     208                 :            :         .flags = FLAG_POINTTOPOINT,
     209                 :            : };
     210                 :            : 
     211                 :            : static const struct driver_info yopy_info = {
     212                 :            :         .description =  "Yopy",
     213                 :            :         .check_connect = always_connected,
     214                 :            :         .flags = FLAG_POINTTOPOINT,
     215                 :            : };
     216                 :            : 
     217                 :            : static const struct driver_info blob_info = {
     218                 :            :         .description =  "Boot Loader OBject",
     219                 :            :         .check_connect = always_connected,
     220                 :            :         .flags = FLAG_POINTTOPOINT,
     221                 :            : };
     222                 :            : 
     223                 :            : #endif  /* CONFIG_USB_ARMLINUX */
     224                 :            : 
     225                 :            : 
     226                 :            : /*-------------------------------------------------------------------------*/
     227                 :            : 
     228                 :            : #ifndef HAVE_HARDWARE
     229                 :            : #warning You need to configure some hardware for this driver
     230                 :            : #endif
     231                 :            : 
     232                 :            : /*
     233                 :            :  * chip vendor names won't normally be on the cables, and
     234                 :            :  * may not be on the device.
     235                 :            :  */
     236                 :            : 
     237                 :            : static const struct usb_device_id       products [] = {
     238                 :            : 
     239                 :            : #ifdef  CONFIG_USB_ALI_M5632
     240                 :            : {
     241                 :            :         USB_DEVICE (0x0402, 0x5632),    // ALi defaults
     242                 :            :         .driver_info =  (unsigned long) &ali_m5632_info,
     243                 :            : },
     244                 :            : {
     245                 :            :         USB_DEVICE (0x182d,0x207c),     // SiteCom CN-124
     246                 :            :         .driver_info =  (unsigned long) &ali_m5632_info,
     247                 :            : },
     248                 :            : #endif
     249                 :            : 
     250                 :            : #ifdef  CONFIG_USB_AN2720
     251                 :            : {
     252                 :            :         USB_DEVICE (0x0547, 0x2720),    // AnchorChips defaults
     253                 :            :         .driver_info =  (unsigned long) &an2720_info,
     254                 :            : }, {
     255                 :            :         USB_DEVICE (0x0547, 0x2727),    // Xircom PGUNET
     256                 :            :         .driver_info =  (unsigned long) &an2720_info,
     257                 :            : },
     258                 :            : #endif
     259                 :            : 
     260                 :            : #ifdef  CONFIG_USB_BELKIN
     261                 :            : {
     262                 :            :         USB_DEVICE (0x050d, 0x0004),    // Belkin
     263                 :            :         .driver_info =  (unsigned long) &belkin_info,
     264                 :            : }, {
     265                 :            :         USB_DEVICE (0x056c, 0x8100),    // eTEK
     266                 :            :         .driver_info =  (unsigned long) &belkin_info,
     267                 :            : }, {
     268                 :            :         USB_DEVICE (0x0525, 0x9901),    // Advance USBNET (eTEK)
     269                 :            :         .driver_info =  (unsigned long) &belkin_info,
     270                 :            : },
     271                 :            : #endif
     272                 :            : 
     273                 :            : #ifdef  CONFIG_USB_EPSON2888
     274                 :            : {
     275                 :            :         USB_DEVICE (0x0525, 0x2888),    // EPSON USB client
     276                 :            :         .driver_info    = (unsigned long) &epson2888_info,
     277                 :            : },
     278                 :            : #endif
     279                 :            : 
     280                 :            : #ifdef CONFIG_USB_KC2190
     281                 :            : {
     282                 :            :         USB_DEVICE (0x050f, 0x0190),    // KC-190
     283                 :            :         .driver_info =  (unsigned long) &kc2190_info,
     284                 :            : },
     285                 :            : #endif
     286                 :            : 
     287                 :            : #ifdef  CONFIG_USB_ARMLINUX
     288                 :            : /*
     289                 :            :  * SA-1100 using standard ARM Linux kernels, or compatible.
     290                 :            :  * Often used when talking to Linux PDAs (iPaq, Yopy, etc).
     291                 :            :  * The sa-1100 "usb-eth" driver handles the basic framing.
     292                 :            :  *
     293                 :            :  * PXA25x or PXA210 ...  these use a "usb-eth" driver much like
     294                 :            :  * the sa1100 one, but hardware uses different endpoint numbers.
     295                 :            :  *
     296                 :            :  * Or the Linux "Ethernet" gadget on hardware that can't talk
     297                 :            :  * CDC Ethernet (e.g., no altsettings), in either of two modes:
     298                 :            :  *  - acting just like the old "usb-eth" firmware, though
     299                 :            :  *    the implementation is different
     300                 :            :  *  - supporting RNDIS as the first/default configuration for
     301                 :            :  *    MS-Windows interop; Linux needs to use the other config
     302                 :            :  */
     303                 :            : {
     304                 :            :         // 1183 = 0x049F, both used as hex values?
     305                 :            :         // Compaq "Itsy" vendor/product id
     306                 :            :         USB_DEVICE (0x049F, 0x505A),    // usb-eth, or compatible
     307                 :            :         .driver_info =  (unsigned long) &linuxdev_info,
     308                 :            : }, {
     309                 :            :         USB_DEVICE (0x0E7E, 0x1001),    // G.Mate "Yopy"
     310                 :            :         .driver_info =  (unsigned long) &yopy_info,
     311                 :            : }, {
     312                 :            :         USB_DEVICE (0x8086, 0x07d3),    // "blob" bootloader
     313                 :            :         .driver_info =  (unsigned long) &blob_info,
     314                 :            : }, {
     315                 :            :         USB_DEVICE (0x1286, 0x8001),    // "blob" bootloader
     316                 :            :         .driver_info =  (unsigned long) &blob_info,
     317                 :            : }, {
     318                 :            :         // Linux Ethernet/RNDIS gadget, mostly on PXA, second config
     319                 :            :         // e.g. Gumstix, current OpenZaurus, ... or anything else
     320                 :            :         // that just enables this gadget option.
     321                 :            :         USB_DEVICE (0x0525, 0xa4a2),
     322                 :            :         .driver_info =  (unsigned long) &linuxdev_info,
     323                 :            : },
     324                 :            : #endif
     325                 :            : 
     326                 :            :         { },            // END
     327                 :            : };
     328                 :            : MODULE_DEVICE_TABLE(usb, products);
     329                 :            : 
     330                 :            : /*-------------------------------------------------------------------------*/
     331                 :          0 : static int dummy_prereset(struct usb_interface *intf)
     332                 :            : {
     333                 :          0 :         return 0;
     334                 :            : }
     335                 :            : 
     336                 :          0 : static int dummy_postreset(struct usb_interface *intf)
     337                 :            : {
     338                 :          0 :         return 0;
     339                 :            : }
     340                 :            : 
     341                 :            : static struct usb_driver cdc_subset_driver = {
     342                 :            :         .name =         "cdc_subset",
     343                 :            :         .probe =        usbnet_probe,
     344                 :            :         .suspend =      usbnet_suspend,
     345                 :            :         .resume =       usbnet_resume,
     346                 :            :         .pre_reset =    dummy_prereset,
     347                 :            :         .post_reset =   dummy_postreset,
     348                 :            :         .disconnect =   usbnet_disconnect,
     349                 :            :         .id_table =     products,
     350                 :            :         .disable_hub_initiated_lpm = 1,
     351                 :            : };
     352                 :            : 
     353                 :        404 : module_usb_driver(cdc_subset_driver);
     354                 :            : 
     355                 :            : MODULE_AUTHOR("David Brownell");
     356                 :            : MODULE_DESCRIPTION("Simple 'CDC Subset' USB networking links");
     357                 :            : MODULE_LICENSE("GPL");

Generated by: LCOV version 1.14