linux/drivers/net/usb/zaurus.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * Copyright (C) 2002 Pavel Machek <pavel@ucw.cz>
   4 * Copyright (C) 2002-2005 by David Brownell
   5 */
   6
   7// #define      DEBUG                   // error path messages, extra info
   8// #define      VERBOSE                 // more; success messages
   9
  10#include <linux/module.h>
  11#include <linux/netdevice.h>
  12#include <linux/ethtool.h>
  13#include <linux/workqueue.h>
  14#include <linux/mii.h>
  15#include <linux/crc32.h>
  16#include <linux/usb.h>
  17#include <linux/usb/cdc.h>
  18#include <linux/usb/usbnet.h>
  19
  20
  21/*
  22 * All known Zaurii lie about their standards conformance.  At least
  23 * the earliest SA-1100 models lie by saying they support CDC Ethernet.
  24 * Some later models (especially PXA-25x and PXA-27x based ones) lie
  25 * and say they support CDC MDLM (for access to cell phone modems).
  26 *
  27 * There are non-Zaurus products that use these same protocols too.
  28 *
  29 * The annoying thing is that at the same time Sharp was developing
  30 * that annoying standards-breaking software, the Linux community had
  31 * a simple "CDC Subset" working reliably on the same SA-1100 hardware.
  32 * That is, the same functionality but not violating standards.
  33 *
  34 * The CDC Ethernet nonconformance points are troublesome to hosts
  35 * with a true CDC Ethernet implementation:
  36 *   - Framing appends a CRC, which the spec says drivers "must not" do;
  37 *   - Transfers data in altsetting zero, instead of altsetting 1;
  38 *   - All these peripherals use the same ethernet address.
  39 *
  40 * The CDC MDLM nonconformance is less immediately troublesome, since all
  41 * MDLM implementations are quasi-proprietary anyway.
  42 */
  43
  44static struct sk_buff *
  45zaurus_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
  46{
  47        int                     padlen;
  48        struct sk_buff          *skb2;
  49
  50        padlen = 2;
  51        if (!skb_cloned(skb)) {
  52                int     tailroom = skb_tailroom(skb);
  53                if ((padlen + 4) <= tailroom)
  54                        goto done;
  55        }
  56        skb2 = skb_copy_expand(skb, 0, 4 + padlen, flags);
  57        dev_kfree_skb_any(skb);
  58        skb = skb2;
  59        if (skb) {
  60                u32             fcs;
  61done:
  62                fcs = crc32_le(~0, skb->data, skb->len);
  63                fcs = ~fcs;
  64
  65                skb_put_u8(skb, fcs & 0xff);
  66                skb_put_u8(skb, (fcs >> 8) & 0xff);
  67                skb_put_u8(skb, (fcs >> 16) & 0xff);
  68                skb_put_u8(skb, (fcs >> 24) & 0xff);
  69        }
  70        return skb;
  71}
  72
  73static int zaurus_bind(struct usbnet *dev, struct usb_interface *intf)
  74{
  75        /* Belcarra's funky framing has other options; mostly
  76         * TRAILERS (!) with 4 bytes CRC, and maybe 2 pad bytes.
  77         */
  78        dev->net->hard_header_len += 6;
  79        dev->rx_urb_size = dev->net->hard_header_len + dev->net->mtu;
  80        return usbnet_generic_cdc_bind(dev, intf);
  81}
  82
  83/* PDA style devices are always connected if present */
  84static int always_connected (struct usbnet *dev)
  85{
  86        return 0;
  87}
  88
  89static const struct driver_info zaurus_sl5x00_info = {
  90        .description =  "Sharp Zaurus SL-5x00",
  91        .flags =        FLAG_POINTTOPOINT | FLAG_FRAMING_Z,
  92        .check_connect = always_connected,
  93        .bind =         zaurus_bind,
  94        .unbind =       usbnet_cdc_unbind,
  95        .tx_fixup =     zaurus_tx_fixup,
  96};
  97#define ZAURUS_STRONGARM_INFO   ((unsigned long)&zaurus_sl5x00_info)
  98
  99static const struct driver_info zaurus_pxa_info = {
 100        .description =  "Sharp Zaurus, PXA-2xx based",
 101        .flags =        FLAG_POINTTOPOINT | FLAG_FRAMING_Z,
 102        .check_connect = always_connected,
 103        .bind =         zaurus_bind,
 104        .unbind =       usbnet_cdc_unbind,
 105        .tx_fixup =     zaurus_tx_fixup,
 106};
 107#define ZAURUS_PXA_INFO         ((unsigned long)&zaurus_pxa_info)
 108
 109static const struct driver_info olympus_mxl_info = {
 110        .description =  "Olympus R1000",
 111        .flags =        FLAG_POINTTOPOINT | FLAG_FRAMING_Z,
 112        .check_connect = always_connected,
 113        .bind =         zaurus_bind,
 114        .unbind =       usbnet_cdc_unbind,
 115        .tx_fixup =     zaurus_tx_fixup,
 116};
 117#define OLYMPUS_MXL_INFO        ((unsigned long)&olympus_mxl_info)
 118
 119
 120/* Some more recent products using Lineo/Belcarra code will wrongly claim
 121 * CDC MDLM conformance.  They aren't conformant:  data endpoints live
 122 * in the control interface, there's no data interface, and it's not used
 123 * to talk to a cell phone radio.  But at least we can detect these two
 124 * pseudo-classes, rather than growing this product list with entries for
 125 * each new nonconformant product (sigh).
 126 */
 127static const u8 safe_guid[16] = {
 128        0x5d, 0x34, 0xcf, 0x66, 0x11, 0x18, 0x11, 0xd6,
 129        0xa2, 0x1a, 0x00, 0x01, 0x02, 0xca, 0x9a, 0x7f,
 130};
 131static const u8 blan_guid[16] = {
 132        0x74, 0xf0, 0x3d, 0xbd, 0x1e, 0xc1, 0x44, 0x70,
 133        0xa3, 0x67, 0x71, 0x34, 0xc9, 0xf5, 0x54, 0x37,
 134};
 135
 136static int blan_mdlm_bind(struct usbnet *dev, struct usb_interface *intf)
 137{
 138        u8                              *buf = intf->cur_altsetting->extra;
 139        int                             len = intf->cur_altsetting->extralen;
 140        struct usb_cdc_mdlm_desc        *desc = NULL;
 141        struct usb_cdc_mdlm_detail_desc *detail = NULL;
 142
 143        while (len > 3) {
 144                if (buf [1] != USB_DT_CS_INTERFACE)
 145                        goto next_desc;
 146
 147                /* use bDescriptorSubType, and just verify that we get a
 148                 * "BLAN" (or "SAFE") descriptor.
 149                 */
 150                switch (buf [2]) {
 151                case USB_CDC_MDLM_TYPE:
 152                        if (desc) {
 153                                dev_dbg(&intf->dev, "extra MDLM\n");
 154                                goto bad_desc;
 155                        }
 156                        desc = (void *) buf;
 157                        if (desc->bLength != sizeof *desc) {
 158                                dev_dbg(&intf->dev, "MDLM len %u\n",
 159                                        desc->bLength);
 160                                goto bad_desc;
 161                        }
 162                        /* expect bcdVersion 1.0, ignore */
 163                        if (memcmp(&desc->bGUID, blan_guid, 16) &&
 164                            memcmp(&desc->bGUID, safe_guid, 16)) {
 165                                /* hey, this one might _really_ be MDLM! */
 166                                dev_dbg(&intf->dev, "MDLM guid\n");
 167                                goto bad_desc;
 168                        }
 169                        break;
 170                case USB_CDC_MDLM_DETAIL_TYPE:
 171                        if (detail) {
 172                                dev_dbg(&intf->dev, "extra MDLM detail\n");
 173                                goto bad_desc;
 174                        }
 175                        detail = (void *) buf;
 176                        switch (detail->bGuidDescriptorType) {
 177                        case 0:                 /* "SAFE" */
 178                                if (detail->bLength != (sizeof *detail + 2))
 179                                        goto bad_detail;
 180                                break;
 181                        case 1:                 /* "BLAN" */
 182                                if (detail->bLength != (sizeof *detail + 3))
 183                                        goto bad_detail;
 184                                break;
 185                        default:
 186                                goto bad_detail;
 187                        }
 188
 189                        /* assuming we either noticed BLAN already, or will
 190                         * find it soon, there are some data bytes here:
 191                         *  - bmNetworkCapabilities (unused)
 192                         *  - bmDataCapabilities (bits, see below)
 193                         *  - bPad (ignored, for PADAFTER -- BLAN-only)
 194                         * bits are:
 195                         *  - 0x01 -- Zaurus framing (add CRC)
 196                         *  - 0x02 -- PADBEFORE (CRC includes some padding)
 197                         *  - 0x04 -- PADAFTER (some padding after CRC)
 198                         *  - 0x08 -- "fermat" packet mangling (for hw bugs)
 199                         * the PADBEFORE appears not to matter; we interop
 200                         * with devices that use it and those that don't.
 201                         */
 202                        if ((detail->bDetailData[1] & ~0x02) != 0x01) {
 203                                /* bmDataCapabilities == 0 would be fine too,
 204                                 * but framing is minidriver-coupled for now.
 205                                 */
 206bad_detail:
 207                                dev_dbg(&intf->dev,
 208                                                "bad MDLM detail, %d %d %d\n",
 209                                                detail->bLength,
 210                                                detail->bDetailData[0],
 211                                                detail->bDetailData[2]);
 212                                goto bad_desc;
 213                        }
 214
 215                        /* same extra framing as for non-BLAN mode */
 216                        dev->net->hard_header_len += 6;
 217                        dev->rx_urb_size = dev->net->hard_header_len
 218                                        + dev->net->mtu;
 219                        break;
 220                }
 221next_desc:
 222                len -= buf [0]; /* bLength */
 223                buf += buf [0];
 224        }
 225
 226        if (!desc || !detail) {
 227                dev_dbg(&intf->dev, "missing cdc mdlm %s%sdescriptor\n",
 228                        desc ? "" : "func ",
 229                        detail ? "" : "detail ");
 230                goto bad_desc;
 231        }
 232
 233        /* There's probably a CDC Ethernet descriptor there, but we can't
 234         * rely on the Ethernet address it provides since not all vendors
 235         * bother to make it unique.  Likewise there's no point in tracking
 236         * of the CDC event notifications.
 237         */
 238        return usbnet_get_endpoints(dev, intf);
 239
 240bad_desc:
 241        dev_info(&dev->udev->dev, "unsupported MDLM descriptors\n");
 242        return -ENODEV;
 243}
 244
 245static const struct driver_info bogus_mdlm_info = {
 246        .description =  "pseudo-MDLM (BLAN) device",
 247        .flags =        FLAG_POINTTOPOINT | FLAG_FRAMING_Z,
 248        .check_connect = always_connected,
 249        .tx_fixup =     zaurus_tx_fixup,
 250        .bind =         blan_mdlm_bind,
 251};
 252
 253static const struct usb_device_id       products [] = {
 254#define ZAURUS_MASTER_INTERFACE \
 255        .bInterfaceClass        = USB_CLASS_COMM, \
 256        .bInterfaceSubClass     = USB_CDC_SUBCLASS_ETHERNET, \
 257        .bInterfaceProtocol     = USB_CDC_PROTO_NONE
 258
 259/* SA-1100 based Sharp Zaurus ("collie"), or compatible. */
 260{
 261        .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
 262                          | USB_DEVICE_ID_MATCH_DEVICE,
 263        .idVendor               = 0x04DD,
 264        .idProduct              = 0x8004,
 265        ZAURUS_MASTER_INTERFACE,
 266        .driver_info = ZAURUS_STRONGARM_INFO,
 267},
 268
 269/* PXA-2xx based models are also lying-about-cdc.  If you add any
 270 * more devices that claim to be CDC Ethernet, make sure they get
 271 * added to the blacklist in cdc_ether too.
 272 *
 273 * NOTE:  OpenZaurus versions with 2.6 kernels won't use these entries,
 274 * unlike the older ones with 2.4 "embedix" kernels.
 275 */
 276{
 277        .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
 278                          | USB_DEVICE_ID_MATCH_DEVICE,
 279        .idVendor               = 0x04DD,
 280        .idProduct              = 0x8005,       /* A-300 */
 281        ZAURUS_MASTER_INTERFACE,
 282        .driver_info = ZAURUS_PXA_INFO,
 283}, {
 284        .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
 285                          | USB_DEVICE_ID_MATCH_DEVICE,
 286        .idVendor               = 0x04DD,
 287        .idProduct              = 0x8006,       /* B-500/SL-5600 */
 288        ZAURUS_MASTER_INTERFACE,
 289        .driver_info = ZAURUS_PXA_INFO,
 290}, {
 291        .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
 292                  | USB_DEVICE_ID_MATCH_DEVICE,
 293        .idVendor               = 0x04DD,
 294        .idProduct              = 0x8007,       /* C-700 */
 295        ZAURUS_MASTER_INTERFACE,
 296        .driver_info = ZAURUS_PXA_INFO,
 297}, {
 298        .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
 299                 | USB_DEVICE_ID_MATCH_DEVICE,
 300        .idVendor               = 0x04DD,
 301        .idProduct              = 0x9031,       /* C-750 C-760 */
 302        ZAURUS_MASTER_INTERFACE,
 303        .driver_info = ZAURUS_PXA_INFO,
 304}, {
 305        /* C-750/C-760/C-860/SL-C3000 PDA in MDLM mode */
 306        USB_DEVICE_AND_INTERFACE_INFO(0x04DD, 0x9031, USB_CLASS_COMM,
 307                        USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
 308        .driver_info = (unsigned long) &bogus_mdlm_info,
 309}, {
 310        .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
 311                 | USB_DEVICE_ID_MATCH_DEVICE,
 312        .idVendor               = 0x04DD,
 313        .idProduct              = 0x9032,       /* SL-6000 */
 314        ZAURUS_MASTER_INTERFACE,
 315        .driver_info = ZAURUS_PXA_INFO,
 316}, {
 317        .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
 318                 | USB_DEVICE_ID_MATCH_DEVICE,
 319        .idVendor               = 0x04DD,
 320        /* reported with some C860 units */
 321        .idProduct              = 0x9050,       /* C-860 */
 322        ZAURUS_MASTER_INTERFACE,
 323        .driver_info = ZAURUS_PXA_INFO,
 324},
 325{
 326        /* Motorola Rokr E6 */
 327        USB_DEVICE_AND_INTERFACE_INFO(0x22b8, 0x6027, USB_CLASS_COMM,
 328                        USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
 329        .driver_info = (unsigned long) &bogus_mdlm_info,
 330}, {
 331        /* Motorola MOTOMAGX phones */
 332        USB_DEVICE_AND_INTERFACE_INFO(0x22b8, 0x6425, USB_CLASS_COMM,
 333                        USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
 334        .driver_info = (unsigned long) &bogus_mdlm_info,
 335},
 336
 337/* Olympus has some models with a Zaurus-compatible option.
 338 * R-1000 uses a FreeScale i.MXL cpu (ARMv4T)
 339 */
 340{
 341        .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
 342                 | USB_DEVICE_ID_MATCH_DEVICE,
 343        .idVendor               = 0x07B4,
 344        .idProduct              = 0x0F02,       /* R-1000 */
 345        ZAURUS_MASTER_INTERFACE,
 346        .driver_info = OLYMPUS_MXL_INFO,
 347},
 348
 349/* Logitech Harmony 900 - uses the pseudo-MDLM (BLAN) driver */
 350{
 351        USB_DEVICE_AND_INTERFACE_INFO(0x046d, 0xc11f, USB_CLASS_COMM,
 352                        USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
 353        .driver_info = (unsigned long) &bogus_mdlm_info,
 354},
 355        { },            // END
 356};
 357MODULE_DEVICE_TABLE(usb, products);
 358
 359static struct usb_driver zaurus_driver = {
 360        .name =         "zaurus",
 361        .id_table =     products,
 362        .probe =        usbnet_probe,
 363        .disconnect =   usbnet_disconnect,
 364        .suspend =      usbnet_suspend,
 365        .resume =       usbnet_resume,
 366        .disable_hub_initiated_lpm = 1,
 367};
 368
 369module_usb_driver(zaurus_driver);
 370
 371MODULE_AUTHOR("Pavel Machek, David Brownell");
 372MODULE_DESCRIPTION("Sharp Zaurus PDA, and compatible products");
 373MODULE_LICENSE("GPL");
 374