root/drivers/net/usb/net1080.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. nc_vendor_read
  2. nc_register_read
  3. nc_vendor_write
  4. nc_register_write
  5. nc_dump_registers
  6. nc_dump_usbctl
  7. nc_dump_status
  8. net1080_reset
  9. net1080_check_connect
  10. nc_ensure_sync
  11. net1080_rx_fixup
  12. net1080_tx_fixup
  13. net1080_bind

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Net1080 based USB host-to-host cables
   4  * Copyright (C) 2000-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/etherdevice.h>
  13 #include <linux/ethtool.h>
  14 #include <linux/workqueue.h>
  15 #include <linux/mii.h>
  16 #include <linux/usb.h>
  17 #include <linux/usb/usbnet.h>
  18 #include <linux/slab.h>
  19 
  20 #include <asm/unaligned.h>
  21 
  22 
  23 /*
  24  * Netchip 1080 driver ... http://www.netchip.com
  25  * (Sept 2004:  End-of-life announcement has been sent.)
  26  * Used in (some) LapLink cables
  27  */
  28 
  29 #define frame_errors    data[1]
  30 
  31 /*
  32  * NetChip framing of ethernet packets, supporting additional error
  33  * checks for links that may drop bulk packets from inside messages.
  34  * Odd USB length == always short read for last usb packet.
  35  *      - nc_header
  36  *      - Ethernet header (14 bytes)
  37  *      - payload
  38  *      - (optional padding byte, if needed so length becomes odd)
  39  *      - nc_trailer
  40  *
  41  * This framing is to be avoided for non-NetChip devices.
  42  */
  43 
  44 struct nc_header {              // packed:
  45         __le16  hdr_len;                // sizeof nc_header (LE, all)
  46         __le16  packet_len;             // payload size (including ethhdr)
  47         __le16  packet_id;              // detects dropped packets
  48 #define MIN_HEADER      6
  49 
  50         // all else is optional, and must start with:
  51         // __le16       vendorId;       // from usb-if
  52         // __le16       productId;
  53 } __packed;
  54 
  55 #define PAD_BYTE        ((unsigned char)0xAC)
  56 
  57 struct nc_trailer {
  58         __le16  packet_id;
  59 } __packed;
  60 
  61 // packets may use FLAG_FRAMING_NC and optional pad
  62 #define FRAMED_SIZE(mtu) (sizeof (struct nc_header) \
  63                                 + sizeof (struct ethhdr) \
  64                                 + (mtu) \
  65                                 + 1 \
  66                                 + sizeof (struct nc_trailer))
  67 
  68 #define MIN_FRAMED      FRAMED_SIZE(0)
  69 
  70 /* packets _could_ be up to 64KB... */
  71 #define NC_MAX_PACKET   32767
  72 
  73 
  74 /*
  75  * Zero means no timeout; else, how long a 64 byte bulk packet may be queued
  76  * before the hardware drops it.  If that's done, the driver will need to
  77  * frame network packets to guard against the dropped USB packets.  The win32
  78  * driver sets this for both sides of the link.
  79  */
  80 #define NC_READ_TTL_MS  ((u8)255)       // ms
  81 
  82 /*
  83  * We ignore most registers and EEPROM contents.
  84  */
  85 #define REG_USBCTL      ((u8)0x04)
  86 #define REG_TTL         ((u8)0x10)
  87 #define REG_STATUS      ((u8)0x11)
  88 
  89 /*
  90  * Vendor specific requests to read/write data
  91  */
  92 #define REQUEST_REGISTER        ((u8)0x10)
  93 #define REQUEST_EEPROM          ((u8)0x11)
  94 
  95 static int
  96 nc_vendor_read(struct usbnet *dev, u8 req, u8 regnum, u16 *retval_ptr)
  97 {
  98         int status = usbnet_read_cmd(dev, req,
  99                                      USB_DIR_IN | USB_TYPE_VENDOR |
 100                                      USB_RECIP_DEVICE,
 101                                      0, regnum, retval_ptr,
 102                                      sizeof *retval_ptr);
 103         if (status > 0)
 104                 status = 0;
 105         if (!status)
 106                 le16_to_cpus(retval_ptr);
 107         return status;
 108 }
 109 
 110 static inline int
 111 nc_register_read(struct usbnet *dev, u8 regnum, u16 *retval_ptr)
 112 {
 113         return nc_vendor_read(dev, REQUEST_REGISTER, regnum, retval_ptr);
 114 }
 115 
 116 // no retval ... can become async, usable in_interrupt()
 117 static void
 118 nc_vendor_write(struct usbnet *dev, u8 req, u8 regnum, u16 value)
 119 {
 120         usbnet_write_cmd(dev, req,
 121                          USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 122                          value, regnum, NULL, 0);
 123 }
 124 
 125 static inline void
 126 nc_register_write(struct usbnet *dev, u8 regnum, u16 value)
 127 {
 128         nc_vendor_write(dev, REQUEST_REGISTER, regnum, value);
 129 }
 130 
 131 
 132 #if 0
 133 static void nc_dump_registers(struct usbnet *dev)
 134 {
 135         u8      reg;
 136         u16     *vp = kmalloc(sizeof (u16));
 137 
 138         if (!vp)
 139                 return;
 140 
 141         netdev_dbg(dev->net, "registers:\n");
 142         for (reg = 0; reg < 0x20; reg++) {
 143                 int retval;
 144 
 145                 // reading some registers is trouble
 146                 if (reg >= 0x08 && reg <= 0xf)
 147                         continue;
 148                 if (reg >= 0x12 && reg <= 0x1e)
 149                         continue;
 150 
 151                 retval = nc_register_read(dev, reg, vp);
 152                 if (retval < 0)
 153                         netdev_dbg(dev->net, "reg [0x%x] ==> error %d\n",
 154                                    reg, retval);
 155                 else
 156                         netdev_dbg(dev->net, "reg [0x%x] = 0x%x\n", reg, *vp);
 157         }
 158         kfree(vp);
 159 }
 160 #endif
 161 
 162 
 163 /*-------------------------------------------------------------------------*/
 164 
 165 /*
 166  * Control register
 167  */
 168 
 169 #define USBCTL_WRITABLE_MASK    0x1f0f
 170 // bits 15-13 reserved, r/o
 171 #define USBCTL_ENABLE_LANG      (1 << 12)
 172 #define USBCTL_ENABLE_MFGR      (1 << 11)
 173 #define USBCTL_ENABLE_PROD      (1 << 10)
 174 #define USBCTL_ENABLE_SERIAL    (1 << 9)
 175 #define USBCTL_ENABLE_DEFAULTS  (1 << 8)
 176 // bits 7-4 reserved, r/o
 177 #define USBCTL_FLUSH_OTHER      (1 << 3)
 178 #define USBCTL_FLUSH_THIS       (1 << 2)
 179 #define USBCTL_DISCONN_OTHER    (1 << 1)
 180 #define USBCTL_DISCONN_THIS     (1 << 0)
 181 
 182 static inline void nc_dump_usbctl(struct usbnet *dev, u16 usbctl)
 183 {
 184         netif_dbg(dev, link, dev->net,
 185                   "net1080 %s-%s usbctl 0x%x:%s%s%s%s%s; this%s%s; other%s%s; r/o 0x%x\n",
 186                   dev->udev->bus->bus_name, dev->udev->devpath,
 187                   usbctl,
 188                   (usbctl & USBCTL_ENABLE_LANG) ? " lang" : "",
 189                   (usbctl & USBCTL_ENABLE_MFGR) ? " mfgr" : "",
 190                   (usbctl & USBCTL_ENABLE_PROD) ? " prod" : "",
 191                   (usbctl & USBCTL_ENABLE_SERIAL) ? " serial" : "",
 192                   (usbctl & USBCTL_ENABLE_DEFAULTS) ? " defaults" : "",
 193 
 194                   (usbctl & USBCTL_FLUSH_THIS) ? " FLUSH" : "",
 195                   (usbctl & USBCTL_DISCONN_THIS) ? " DIS" : "",
 196 
 197                   (usbctl & USBCTL_FLUSH_OTHER) ? " FLUSH" : "",
 198                   (usbctl & USBCTL_DISCONN_OTHER) ? " DIS" : "",
 199 
 200                   usbctl & ~USBCTL_WRITABLE_MASK);
 201 }
 202 
 203 /*-------------------------------------------------------------------------*/
 204 
 205 /*
 206  * Status register
 207  */
 208 
 209 #define STATUS_PORT_A           (1 << 15)
 210 
 211 #define STATUS_CONN_OTHER       (1 << 14)
 212 #define STATUS_SUSPEND_OTHER    (1 << 13)
 213 #define STATUS_MAILBOX_OTHER    (1 << 12)
 214 #define STATUS_PACKETS_OTHER(n) (((n) >> 8) & 0x03)
 215 
 216 #define STATUS_CONN_THIS        (1 << 6)
 217 #define STATUS_SUSPEND_THIS     (1 << 5)
 218 #define STATUS_MAILBOX_THIS     (1 << 4)
 219 #define STATUS_PACKETS_THIS(n)  (((n) >> 0) & 0x03)
 220 
 221 #define STATUS_UNSPEC_MASK      0x0c8c
 222 #define STATUS_NOISE_MASK       ((u16)~(0x0303|STATUS_UNSPEC_MASK))
 223 
 224 
 225 static inline void nc_dump_status(struct usbnet *dev, u16 status)
 226 {
 227         netif_dbg(dev, link, dev->net,
 228                   "net1080 %s-%s status 0x%x: this (%c) PKT=%d%s%s%s; other PKT=%d%s%s%s; unspec 0x%x\n",
 229                   dev->udev->bus->bus_name, dev->udev->devpath,
 230                   status,
 231 
 232                   // XXX the packet counts don't seem right
 233                   // (1 at reset, not 0); maybe UNSPEC too
 234 
 235                   (status & STATUS_PORT_A) ? 'A' : 'B',
 236                   STATUS_PACKETS_THIS(status),
 237                   (status & STATUS_CONN_THIS) ? " CON" : "",
 238                   (status & STATUS_SUSPEND_THIS) ? " SUS" : "",
 239                   (status & STATUS_MAILBOX_THIS) ? " MBOX" : "",
 240 
 241                   STATUS_PACKETS_OTHER(status),
 242                   (status & STATUS_CONN_OTHER) ? " CON" : "",
 243                   (status & STATUS_SUSPEND_OTHER) ? " SUS" : "",
 244                   (status & STATUS_MAILBOX_OTHER) ? " MBOX" : "",
 245 
 246                   status & STATUS_UNSPEC_MASK);
 247 }
 248 
 249 /*-------------------------------------------------------------------------*/
 250 
 251 /*
 252  * TTL register
 253  */
 254 
 255 #define TTL_OTHER(ttl)  (0x00ff & (ttl >> 8))
 256 #define MK_TTL(this,other)      ((u16)(((other)<<8)|(0x00ff&(this))))
 257 
 258 /*-------------------------------------------------------------------------*/
 259 
 260 static int net1080_reset(struct usbnet *dev)
 261 {
 262         u16             usbctl, status, ttl;
 263         u16             vp;
 264         int             retval;
 265 
 266         // nc_dump_registers(dev);
 267 
 268         if ((retval = nc_register_read(dev, REG_STATUS, &vp)) < 0) {
 269                 netdev_dbg(dev->net, "can't read %s-%s status: %d\n",
 270                            dev->udev->bus->bus_name, dev->udev->devpath, retval);
 271                 goto done;
 272         }
 273         status = vp;
 274         nc_dump_status(dev, status);
 275 
 276         if ((retval = nc_register_read(dev, REG_USBCTL, &vp)) < 0) {
 277                 netdev_dbg(dev->net, "can't read USBCTL, %d\n", retval);
 278                 goto done;
 279         }
 280         usbctl = vp;
 281         nc_dump_usbctl(dev, usbctl);
 282 
 283         nc_register_write(dev, REG_USBCTL,
 284                         USBCTL_FLUSH_THIS | USBCTL_FLUSH_OTHER);
 285 
 286         if ((retval = nc_register_read(dev, REG_TTL, &vp)) < 0) {
 287                 netdev_dbg(dev->net, "can't read TTL, %d\n", retval);
 288                 goto done;
 289         }
 290         ttl = vp;
 291 
 292         nc_register_write(dev, REG_TTL,
 293                         MK_TTL(NC_READ_TTL_MS, TTL_OTHER(ttl)) );
 294         netdev_dbg(dev->net, "assigned TTL, %d ms\n", NC_READ_TTL_MS);
 295 
 296         netif_info(dev, link, dev->net, "port %c, peer %sconnected\n",
 297                    (status & STATUS_PORT_A) ? 'A' : 'B',
 298                    (status & STATUS_CONN_OTHER) ? "" : "dis");
 299         retval = 0;
 300 
 301 done:
 302         return retval;
 303 }
 304 
 305 static int net1080_check_connect(struct usbnet *dev)
 306 {
 307         int                     retval;
 308         u16                     status;
 309         u16                     vp;
 310 
 311         retval = nc_register_read(dev, REG_STATUS, &vp);
 312         status = vp;
 313         if (retval != 0) {
 314                 netdev_dbg(dev->net, "net1080_check_conn read - %d\n", retval);
 315                 return retval;
 316         }
 317         if ((status & STATUS_CONN_OTHER) != STATUS_CONN_OTHER)
 318                 return -ENOLINK;
 319         return 0;
 320 }
 321 
 322 static void nc_ensure_sync(struct usbnet *dev)
 323 {
 324         if (++dev->frame_errors <= 5)
 325                 return;
 326 
 327         if (usbnet_write_cmd_async(dev, REQUEST_REGISTER,
 328                                         USB_DIR_OUT | USB_TYPE_VENDOR |
 329                                         USB_RECIP_DEVICE,
 330                                         USBCTL_FLUSH_THIS |
 331                                         USBCTL_FLUSH_OTHER,
 332                                         REG_USBCTL, NULL, 0))
 333                 return;
 334 
 335         netif_dbg(dev, rx_err, dev->net,
 336                   "flush net1080; too many framing errors\n");
 337         dev->frame_errors = 0;
 338 }
 339 
 340 static int net1080_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
 341 {
 342         struct nc_header        *header;
 343         struct nc_trailer       *trailer;
 344         u16                     hdr_len, packet_len;
 345 
 346         /* This check is no longer done by usbnet */
 347         if (skb->len < dev->net->hard_header_len)
 348                 return 0;
 349 
 350         if (!(skb->len & 0x01)) {
 351                 netdev_dbg(dev->net, "rx framesize %d range %d..%d mtu %d\n",
 352                            skb->len, dev->net->hard_header_len, dev->hard_mtu,
 353                            dev->net->mtu);
 354                 dev->net->stats.rx_frame_errors++;
 355                 nc_ensure_sync(dev);
 356                 return 0;
 357         }
 358 
 359         header = (struct nc_header *) skb->data;
 360         hdr_len = le16_to_cpup(&header->hdr_len);
 361         packet_len = le16_to_cpup(&header->packet_len);
 362         if (FRAMED_SIZE(packet_len) > NC_MAX_PACKET) {
 363                 dev->net->stats.rx_frame_errors++;
 364                 netdev_dbg(dev->net, "packet too big, %d\n", packet_len);
 365                 nc_ensure_sync(dev);
 366                 return 0;
 367         } else if (hdr_len < MIN_HEADER) {
 368                 dev->net->stats.rx_frame_errors++;
 369                 netdev_dbg(dev->net, "header too short, %d\n", hdr_len);
 370                 nc_ensure_sync(dev);
 371                 return 0;
 372         } else if (hdr_len > MIN_HEADER) {
 373                 // out of band data for us?
 374                 netdev_dbg(dev->net, "header OOB, %d bytes\n", hdr_len - MIN_HEADER);
 375                 nc_ensure_sync(dev);
 376                 // switch (vendor/product ids) { ... }
 377         }
 378         skb_pull(skb, hdr_len);
 379 
 380         trailer = (struct nc_trailer *)
 381                 (skb->data + skb->len - sizeof *trailer);
 382         skb_trim(skb, skb->len - sizeof *trailer);
 383 
 384         if ((packet_len & 0x01) == 0) {
 385                 if (skb->data [packet_len] != PAD_BYTE) {
 386                         dev->net->stats.rx_frame_errors++;
 387                         netdev_dbg(dev->net, "bad pad\n");
 388                         return 0;
 389                 }
 390                 skb_trim(skb, skb->len - 1);
 391         }
 392         if (skb->len != packet_len) {
 393                 dev->net->stats.rx_frame_errors++;
 394                 netdev_dbg(dev->net, "bad packet len %d (expected %d)\n",
 395                            skb->len, packet_len);
 396                 nc_ensure_sync(dev);
 397                 return 0;
 398         }
 399         if (header->packet_id != get_unaligned(&trailer->packet_id)) {
 400                 dev->net->stats.rx_fifo_errors++;
 401                 netdev_dbg(dev->net, "(2+ dropped) rx packet_id mismatch 0x%x 0x%x\n",
 402                            le16_to_cpu(header->packet_id),
 403                            le16_to_cpu(trailer->packet_id));
 404                 return 0;
 405         }
 406 #if 0
 407         netdev_dbg(dev->net, "frame <rx h %d p %d id %d\n", header->hdr_len,
 408                    header->packet_len, header->packet_id);
 409 #endif
 410         dev->frame_errors = 0;
 411         return 1;
 412 }
 413 
 414 static struct sk_buff *
 415 net1080_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
 416 {
 417         struct sk_buff          *skb2;
 418         struct nc_header        *header = NULL;
 419         struct nc_trailer       *trailer = NULL;
 420         int                     padlen = sizeof (struct nc_trailer);
 421         int                     len = skb->len;
 422 
 423         if (!((len + padlen + sizeof (struct nc_header)) & 0x01))
 424                 padlen++;
 425         if (!skb_cloned(skb)) {
 426                 int     headroom = skb_headroom(skb);
 427                 int     tailroom = skb_tailroom(skb);
 428 
 429                 if (padlen <= tailroom &&
 430                     sizeof(struct nc_header) <= headroom)
 431                         /* There's enough head and tail room */
 432                         goto encapsulate;
 433 
 434                 if ((sizeof (struct nc_header) + padlen) <
 435                                 (headroom + tailroom)) {
 436                         /* There's enough total room, so just readjust */
 437                         skb->data = memmove(skb->head
 438                                                 + sizeof (struct nc_header),
 439                                             skb->data, skb->len);
 440                         skb_set_tail_pointer(skb, len);
 441                         goto encapsulate;
 442                 }
 443         }
 444 
 445         /* Create a new skb to use with the correct size */
 446         skb2 = skb_copy_expand(skb,
 447                                 sizeof (struct nc_header),
 448                                 padlen,
 449                                 flags);
 450         dev_kfree_skb_any(skb);
 451         if (!skb2)
 452                 return skb2;
 453         skb = skb2;
 454 
 455 encapsulate:
 456         /* header first */
 457         header = skb_push(skb, sizeof *header);
 458         header->hdr_len = cpu_to_le16(sizeof (*header));
 459         header->packet_len = cpu_to_le16(len);
 460         header->packet_id = cpu_to_le16((u16)dev->xid++);
 461 
 462         /* maybe pad; then trailer */
 463         if (!((skb->len + sizeof *trailer) & 0x01))
 464                 skb_put_u8(skb, PAD_BYTE);
 465         trailer = skb_put(skb, sizeof *trailer);
 466         put_unaligned(header->packet_id, &trailer->packet_id);
 467 #if 0
 468         netdev_dbg(dev->net, "frame >tx h %d p %d id %d\n",
 469                    header->hdr_len, header->packet_len,
 470                    header->packet_id);
 471 #endif
 472         return skb;
 473 }
 474 
 475 static int net1080_bind(struct usbnet *dev, struct usb_interface *intf)
 476 {
 477         unsigned        extra = sizeof (struct nc_header)
 478                                 + 1
 479                                 + sizeof (struct nc_trailer);
 480 
 481         dev->net->hard_header_len += extra;
 482         dev->rx_urb_size = dev->net->hard_header_len + dev->net->mtu;
 483         dev->hard_mtu = NC_MAX_PACKET;
 484         return usbnet_get_endpoints (dev, intf);
 485 }
 486 
 487 static const struct driver_info net1080_info = {
 488         .description =  "NetChip TurboCONNECT",
 489         .flags =        FLAG_POINTTOPOINT | FLAG_FRAMING_NC,
 490         .bind =         net1080_bind,
 491         .reset =        net1080_reset,
 492         .check_connect = net1080_check_connect,
 493         .rx_fixup =     net1080_rx_fixup,
 494         .tx_fixup =     net1080_tx_fixup,
 495 };
 496 
 497 static const struct usb_device_id       products [] = {
 498 {
 499         USB_DEVICE(0x0525, 0x1080),     // NetChip ref design
 500         .driver_info =  (unsigned long) &net1080_info,
 501 }, {
 502         USB_DEVICE(0x06D0, 0x0622),     // Laplink Gold
 503         .driver_info =  (unsigned long) &net1080_info,
 504 },
 505         { },            // END
 506 };
 507 MODULE_DEVICE_TABLE(usb, products);
 508 
 509 static struct usb_driver net1080_driver = {
 510         .name =         "net1080",
 511         .id_table =     products,
 512         .probe =        usbnet_probe,
 513         .disconnect =   usbnet_disconnect,
 514         .suspend =      usbnet_suspend,
 515         .resume =       usbnet_resume,
 516         .disable_hub_initiated_lpm = 1,
 517 };
 518 
 519 module_usb_driver(net1080_driver);
 520 
 521 MODULE_AUTHOR("David Brownell");
 522 MODULE_DESCRIPTION("NetChip 1080 based USB Host-to-Host Links");
 523 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */