^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * USB 10M/100M ethernet adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * This file is licensed under the terms of the GNU General Public License
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * version 2. This program is licensed "as is" without any warranty of any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * kind, whether express or implied
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/stddef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/ethtool.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/mii.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/crc32.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/usb/usbnet.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define CH9200_VID 0x1A86
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define CH9200_PID_E092 0xE092
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define CTRL_TIMEOUT_MS 1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define CONTROL_TIMEOUT_MS 1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define REQUEST_READ 0x0E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define REQUEST_WRITE 0x0F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) /* Address space:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * 00-63 : MII
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * 64-128: MAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * Note: all accesses must be 16-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define MAC_REG_CTRL 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define MAC_REG_STATUS 66
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define MAC_REG_INTERRUPT_MASK 68
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define MAC_REG_PHY_COMMAND 70
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define MAC_REG_PHY_DATA 72
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define MAC_REG_STATION_L 74
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define MAC_REG_STATION_M 76
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define MAC_REG_STATION_H 78
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define MAC_REG_HASH_L 80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define MAC_REG_HASH_M1 82
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define MAC_REG_HASH_M2 84
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define MAC_REG_HASH_H 86
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define MAC_REG_THRESHOLD 88
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define MAC_REG_FIFO_DEPTH 90
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define MAC_REG_PAUSE 92
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define MAC_REG_FLOW_CONTROL 94
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /* Control register bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * Note: bits 13 and 15 are reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define LOOPBACK (0x01 << 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define BASE100X (0x01 << 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define MBPS_10 (0x01 << 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define DUPLEX_MODE (0x01 << 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define PAUSE_FRAME (0x01 << 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define PROMISCUOUS (0x01 << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define MULTICAST (0x01 << 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define BROADCAST (0x01 << 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define HASH (0x01 << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define APPEND_PAD (0x01 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define APPEND_CRC (0x01 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define TRANSMITTER_ACTION (0x01 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define RECEIVER_ACTION (0x01 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define DMA_ACTION (0x01 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /* Status register bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * Note: bits 7-15 are reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define ALIGNMENT (0x01 << 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define FIFO_OVER_RUN (0x01 << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define FIFO_UNDER_RUN (0x01 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define RX_ERROR (0x01 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define RX_COMPLETE (0x01 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define TX_ERROR (0x01 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define TX_COMPLETE (0x01 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) /* FIFO depth register bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * Note: bits 6 and 14 are reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define ETH_TXBD (0x01 << 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define ETN_TX_FIFO_DEPTH (0x01 << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define ETH_RXBD (0x01 << 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define ETH_RX_FIFO_DEPTH (0x01 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) static int control_read(struct usbnet *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) unsigned char request, unsigned short value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) unsigned short index, void *data, unsigned short size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) int timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) unsigned char *buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) unsigned char request_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (request == REQUEST_READ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) request_type = (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) request_type = (USB_DIR_IN | USB_TYPE_VENDOR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) USB_RECIP_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) netdev_dbg(dev->net, "%s() index=0x%02x size=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) __func__, index, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) buf = kmalloc(size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (!buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) err = usb_control_msg(dev->udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) usb_rcvctrlpipe(dev->udev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) request, request_type, value, index, buf, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (err == size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) memcpy(data, buf, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) else if (err >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static int control_write(struct usbnet *dev, unsigned char request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) unsigned short value, unsigned short index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) void *data, unsigned short size, int timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) unsigned char *buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) unsigned char request_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (request == REQUEST_WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) request_type = (USB_DIR_OUT | USB_TYPE_VENDOR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) USB_RECIP_OTHER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) request_type = (USB_DIR_OUT | USB_TYPE_VENDOR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) USB_RECIP_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) netdev_dbg(dev->net, "%s() index=0x%02x size=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) __func__, index, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) buf = kmemdup(data, size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (!buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) goto err_out;
^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) err = usb_control_msg(dev->udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) usb_sndctrlpipe(dev->udev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) request, request_type, value, index, buf, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if (err >= 0 && err < size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) static int ch9200_mdio_read(struct net_device *netdev, int phy_id, int loc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) struct usbnet *dev = netdev_priv(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) unsigned char buff[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) netdev_dbg(netdev, "%s phy_id:%02x loc:%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) __func__, phy_id, loc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if (phy_id != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) control_read(dev, REQUEST_READ, 0, loc * 2, buff, 0x02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) CONTROL_TIMEOUT_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) return (buff[0] | buff[1] << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) static void ch9200_mdio_write(struct net_device *netdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) int phy_id, int loc, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) struct usbnet *dev = netdev_priv(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) unsigned char buff[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) netdev_dbg(netdev, "%s() phy_id=%02x loc:%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) __func__, phy_id, loc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (phy_id != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) buff[0] = (unsigned char)val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) buff[1] = (unsigned char)(val >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) control_write(dev, REQUEST_WRITE, 0, loc * 2, buff, 0x02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) CONTROL_TIMEOUT_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) static int ch9200_link_reset(struct usbnet *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) struct ethtool_cmd ecmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) mii_check_media(&dev->mii, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) mii_ethtool_gset(&dev->mii, &ecmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) netdev_dbg(dev->net, "%s() speed:%d duplex:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) __func__, ecmd.speed, ecmd.duplex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) static void ch9200_status(struct usbnet *dev, struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) int link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) unsigned char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if (urb->actual_length < 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) buf = urb->transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) link = !!(buf[0] & 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) netif_carrier_on(dev->net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) usbnet_defer_kevent(dev, EVENT_LINK_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) netif_carrier_off(dev->net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) static struct sk_buff *ch9200_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) gfp_t flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) int len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) int tx_overhead = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) tx_overhead = 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) len = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (skb_cow_head(skb, tx_overhead)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) dev_kfree_skb_any(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) __skb_push(skb, tx_overhead);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) /* usbnet adds padding if length is a multiple of packet size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * if so, adjust length value in header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if ((skb->len % dev->maxpacket) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) len++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) skb->data[0] = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) skb->data[1] = len >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) skb->data[2] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) skb->data[3] = 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) for (i = 4; i < 48; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) skb->data[i] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) skb->data[48] = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) skb->data[49] = len >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) skb->data[50] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) skb->data[51] = 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) for (i = 52; i < 64; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) skb->data[i] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) static int ch9200_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) int len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) int rx_overhead = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) rx_overhead = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (unlikely(skb->len < rx_overhead)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) dev_err(&dev->udev->dev, "unexpected tiny rx frame\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) len = (skb->data[skb->len - 16] | skb->data[skb->len - 15] << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) skb_trim(skb, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) return 1;
^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 get_mac_address(struct usbnet *dev, unsigned char *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) unsigned char mac_addr[0x06];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) int rd_mac_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) netdev_dbg(dev->net, "%s:\n\tusbnet VID:%0x PID:%0x\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) le16_to_cpu(dev->udev->descriptor.idVendor),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) le16_to_cpu(dev->udev->descriptor.idProduct));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) memset(mac_addr, 0, sizeof(mac_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) rd_mac_len = control_read(dev, REQUEST_READ, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) MAC_REG_STATION_L, mac_addr, 0x02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) CONTROL_TIMEOUT_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) rd_mac_len += control_read(dev, REQUEST_READ, 0, MAC_REG_STATION_M,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) mac_addr + 2, 0x02, CONTROL_TIMEOUT_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) rd_mac_len += control_read(dev, REQUEST_READ, 0, MAC_REG_STATION_H,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) mac_addr + 4, 0x02, CONTROL_TIMEOUT_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (rd_mac_len != ETH_ALEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) data[0] = mac_addr[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) data[1] = mac_addr[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) data[2] = mac_addr[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) data[3] = mac_addr[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) data[4] = mac_addr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) data[5] = mac_addr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) static int ch9200_bind(struct usbnet *dev, struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) unsigned char data[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) retval = usbnet_get_endpoints(dev, intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) dev->mii.dev = dev->net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) dev->mii.mdio_read = ch9200_mdio_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) dev->mii.mdio_write = ch9200_mdio_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) dev->mii.reg_num_mask = 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) dev->mii.phy_id_mask = 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) dev->rx_urb_size = 24 * 64 + 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) mii_nway_restart(&dev->mii);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) data[0] = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) data[1] = 0x0F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) retval = control_write(dev, REQUEST_WRITE, 0, MAC_REG_THRESHOLD, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 0x02, CONTROL_TIMEOUT_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) data[0] = 0xA0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) data[1] = 0x90;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) retval = control_write(dev, REQUEST_WRITE, 0, MAC_REG_FIFO_DEPTH, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 0x02, CONTROL_TIMEOUT_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) data[0] = 0x30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) data[1] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) retval = control_write(dev, REQUEST_WRITE, 0, MAC_REG_PAUSE, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 0x02, CONTROL_TIMEOUT_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) data[0] = 0x17;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) data[1] = 0xD8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) retval = control_write(dev, REQUEST_WRITE, 0, MAC_REG_FLOW_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) data, 0x02, CONTROL_TIMEOUT_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) /* Undocumented register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) data[0] = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) data[1] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) retval = control_write(dev, REQUEST_WRITE, 0, 254, data, 0x02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) CONTROL_TIMEOUT_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) data[0] = 0x5F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) data[1] = 0x0D;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) retval = control_write(dev, REQUEST_WRITE, 0, MAC_REG_CTRL, data, 0x02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) CONTROL_TIMEOUT_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) retval = get_mac_address(dev, dev->net->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) static const struct driver_info ch9200_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) .description = "CH9200 USB to Network Adaptor",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) .flags = FLAG_ETHER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) .bind = ch9200_bind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) .rx_fixup = ch9200_rx_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) .tx_fixup = ch9200_tx_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) .status = ch9200_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) .link_reset = ch9200_link_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) .reset = ch9200_link_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) static const struct usb_device_id ch9200_products[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) USB_DEVICE(0x1A86, 0xE092),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) .driver_info = (unsigned long)&ch9200_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) MODULE_DEVICE_TABLE(usb, ch9200_products);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) static struct usb_driver ch9200_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) .name = "ch9200",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) .id_table = ch9200_products,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) .probe = usbnet_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) .disconnect = usbnet_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) .suspend = usbnet_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) .resume = usbnet_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) module_usb_driver(ch9200_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) MODULE_DESCRIPTION("QinHeng CH9200 USB Network device");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) MODULE_LICENSE("GPL");