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