^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) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * kaweth.c - driver for KL5KUSB101 based USB->Ethernet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * (c) 2000 Interlan Communications
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * (c) 2000 Stephane Alnet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * (C) 2001 Brad Hards
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * (C) 2002 Oliver Neukum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Original author: The Zapman <zapman@interlan.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Inspired by, and much credit goes to Michael Rothwell
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * <rothwell@interlan.net> for the test equipment, help, and patience
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Based off of (and with thanks to) Petko Manolov's pegaus.c driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Also many thanks to Joel Silverman and Ed Surprenant at Kawasaki
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * for providing the firmware and driver resources.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) ****************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) /* TODO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * Develop test procedures for USB net interfaces
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * Run test procedures
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * Fix bugs from previous two steps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * Snoop other OSs for any tricks we're not doing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * Reduce arbitrary timeouts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * Smart multicast support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * Temporary MAC change support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * Tunable SOFs parameter - ioctl()?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * Ethernet stats collection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * Code formatting improvements
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/ethtool.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <linux/firmware.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <asm/byteorder.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #undef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define KAWETH_MTU 1514
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define KAWETH_BUF_SIZE 1664
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define KAWETH_TX_TIMEOUT (5 * HZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define KAWETH_SCRATCH_SIZE 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define KAWETH_FIRMWARE_BUF_SIZE 4096
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define KAWETH_CONTROL_TIMEOUT (30000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define KAWETH_STATUS_BROKEN 0x0000001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define KAWETH_STATUS_CLOSING 0x0000002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define KAWETH_STATUS_SUSPENDING 0x0000004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define KAWETH_STATUS_BLOCKED (KAWETH_STATUS_CLOSING | KAWETH_STATUS_SUSPENDING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define KAWETH_PACKET_FILTER_PROMISCUOUS 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define KAWETH_PACKET_FILTER_ALL_MULTICAST 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define KAWETH_PACKET_FILTER_DIRECTED 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define KAWETH_PACKET_FILTER_BROADCAST 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define KAWETH_PACKET_FILTER_MULTICAST 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) /* Table 7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define KAWETH_COMMAND_GET_ETHERNET_DESC 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define KAWETH_COMMAND_MULTICAST_FILTERS 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define KAWETH_COMMAND_SET_PACKET_FILTER 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define KAWETH_COMMAND_STATISTICS 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define KAWETH_COMMAND_SET_TEMP_MAC 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define KAWETH_COMMAND_GET_TEMP_MAC 0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define KAWETH_COMMAND_SET_URB_SIZE 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define KAWETH_COMMAND_SET_SOFS_WAIT 0x09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define KAWETH_COMMAND_SCAN 0xFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define KAWETH_SOFS_TO_WAIT 0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define INTBUFFERSIZE 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define STATE_OFFSET 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define STATE_MASK 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define STATE_SHIFT 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define IS_BLOCKED(s) (s & KAWETH_STATUS_BLOCKED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) MODULE_AUTHOR("Michael Zappe <zapman@interlan.net>, Stephane Alnet <stephane@u-picardie.fr>, Brad Hards <bhards@bigpond.net.au> and Oliver Neukum <oliver@neukum.org>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) MODULE_DESCRIPTION("KL5USB101 USB Ethernet driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) MODULE_FIRMWARE("kaweth/new_code.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) MODULE_FIRMWARE("kaweth/new_code_fix.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) MODULE_FIRMWARE("kaweth/trigger_code.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) MODULE_FIRMWARE("kaweth/trigger_code_fix.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) static const char driver_name[] = "kaweth";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static int kaweth_probe(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct usb_interface *intf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) const struct usb_device_id *id /* from id_table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static void kaweth_disconnect(struct usb_interface *intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) static int kaweth_suspend(struct usb_interface *intf, pm_message_t message);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static int kaweth_resume(struct usb_interface *intf);
^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) * usb_device_id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) ****************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static const struct usb_device_id usb_klsi_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) { USB_DEVICE(0x03e8, 0x0008) }, /* AOX Endpoints USB Ethernet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) { USB_DEVICE(0x04bb, 0x0901) }, /* I-O DATA USB-ET/T */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) { USB_DEVICE(0x0506, 0x03e8) }, /* 3Com 3C19250 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) { USB_DEVICE(0x0506, 0x11f8) }, /* 3Com 3C460 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) { USB_DEVICE(0x0557, 0x2002) }, /* ATEN USB Ethernet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) { USB_DEVICE(0x0557, 0x4000) }, /* D-Link DSB-650C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) { USB_DEVICE(0x0565, 0x0002) }, /* Peracom Enet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) { USB_DEVICE(0x0565, 0x0003) }, /* Optus@Home UEP1045A */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) { USB_DEVICE(0x0565, 0x0005) }, /* Peracom Enet2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) { USB_DEVICE(0x05e9, 0x0008) }, /* KLSI KL5KUSB101B */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) { USB_DEVICE(0x05e9, 0x0009) }, /* KLSI KL5KUSB101B (Board change) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) { USB_DEVICE(0x066b, 0x2202) }, /* Linksys USB10T */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) { USB_DEVICE(0x06e1, 0x0008) }, /* ADS USB-10BT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) { USB_DEVICE(0x06e1, 0x0009) }, /* ADS USB-10BT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) { USB_DEVICE(0x0707, 0x0100) }, /* SMC 2202USB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) { USB_DEVICE(0x07aa, 0x0001) }, /* Correga K.K. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) { USB_DEVICE(0x07b8, 0x4000) }, /* D-Link DU-E10 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) { USB_DEVICE(0x07c9, 0xb010) }, /* Allied Telesyn AT-USB10 USB Ethernet Adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) { USB_DEVICE(0x0846, 0x1001) }, /* NetGear EA-101 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) { USB_DEVICE(0x0846, 0x1002) }, /* NetGear EA-101 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) { USB_DEVICE(0x085a, 0x0008) }, /* PortGear Ethernet Adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) { USB_DEVICE(0x085a, 0x0009) }, /* PortGear Ethernet Adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) { USB_DEVICE(0x087d, 0x5704) }, /* Jaton USB Ethernet Device Adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) { USB_DEVICE(0x0951, 0x0008) }, /* Kingston Technology USB Ethernet Adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) { USB_DEVICE(0x095a, 0x3003) }, /* Portsmith Express Ethernet Adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) { USB_DEVICE(0x10bd, 0x1427) }, /* ASANTE USB To Ethernet Adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) { USB_DEVICE(0x1342, 0x0204) }, /* Mobility USB-Ethernet Adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) { USB_DEVICE(0x13d2, 0x0400) }, /* Shark Pocket Adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) { USB_DEVICE(0x1485, 0x0001) }, /* Silicom U2E */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) { USB_DEVICE(0x1485, 0x0002) }, /* Psion Dacom Gold Port Ethernet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) { USB_DEVICE(0x1645, 0x0005) }, /* Entrega E45 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) { USB_DEVICE(0x1645, 0x0008) }, /* Entrega USB Ethernet Adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) { USB_DEVICE(0x1645, 0x8005) }, /* PortGear Ethernet Adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) { USB_DEVICE(0x1668, 0x0323) }, /* Actiontec USB Ethernet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) { USB_DEVICE(0x2001, 0x4000) }, /* D-link DSB-650C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) {} /* Null terminator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) MODULE_DEVICE_TABLE (usb, usb_klsi_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /****************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * kaweth_driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) ****************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) static struct usb_driver kaweth_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) .name = driver_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) .probe = kaweth_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) .disconnect = kaweth_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) .suspend = kaweth_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) .resume = kaweth_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) .id_table = usb_klsi_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) .supports_autosuspend = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) .disable_hub_initiated_lpm = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) typedef __u8 eth_addr_t[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) /****************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * usb_eth_dev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) ****************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct usb_eth_dev {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) __u16 vendor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) __u16 device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) void *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) /****************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * kaweth_ethernet_configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) * Refer Table 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) ****************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct kaweth_ethernet_configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) __u8 size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) __u8 reserved1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) __u8 reserved2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) eth_addr_t hw_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) __u32 statistics_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) __le16 segment_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) __u16 max_multicast_filters;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) __u8 reserved3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) /****************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * kaweth_device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) ****************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) struct kaweth_device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) spinlock_t device_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) __u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) int end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) int suspend_lowmem_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) int suspend_lowmem_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) int linkstate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) int opened;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) struct delayed_work lowmem_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) struct usb_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) struct usb_interface *intf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) struct net_device *net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) wait_queue_head_t term_wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) struct urb *rx_urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) struct urb *tx_urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) struct urb *irq_urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) dma_addr_t intbufferhandle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) __u8 *intbuffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) dma_addr_t rxbufferhandle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) __u8 *rx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) struct sk_buff *tx_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) __u8 *firmware_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) __u8 scratch[KAWETH_SCRATCH_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) __u16 packet_filter_bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) struct kaweth_ethernet_configuration configuration;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) /****************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * kaweth_read_configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) ****************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static int kaweth_read_configuration(struct kaweth_device *kaweth)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) return usb_control_msg(kaweth->dev, usb_rcvctrlpipe(kaweth->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) KAWETH_COMMAND_GET_ETHERNET_DESC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) &kaweth->configuration,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) sizeof(kaweth->configuration),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) KAWETH_CONTROL_TIMEOUT);
^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) * kaweth_set_urb_size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) ****************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) static int kaweth_set_urb_size(struct kaweth_device *kaweth, __u16 urb_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) netdev_dbg(kaweth->net, "Setting URB size to %d\n", (unsigned)urb_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return usb_control_msg(kaweth->dev, usb_sndctrlpipe(kaweth->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) KAWETH_COMMAND_SET_URB_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) urb_size, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) &kaweth->scratch, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) KAWETH_CONTROL_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) /****************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) * kaweth_set_sofs_wait
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) ****************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) static int kaweth_set_sofs_wait(struct kaweth_device *kaweth, __u16 sofs_wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) netdev_dbg(kaweth->net, "Set SOFS wait to %d\n", (unsigned)sofs_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) return usb_control_msg(kaweth->dev, usb_sndctrlpipe(kaweth->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) KAWETH_COMMAND_SET_SOFS_WAIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) sofs_wait, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) &kaweth->scratch, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) KAWETH_CONTROL_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) /****************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * kaweth_set_receive_filter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) ****************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) static int kaweth_set_receive_filter(struct kaweth_device *kaweth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) __u16 receive_filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) netdev_dbg(kaweth->net, "Set receive filter to %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) (unsigned)receive_filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return usb_control_msg(kaweth->dev, usb_sndctrlpipe(kaweth->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) KAWETH_COMMAND_SET_PACKET_FILTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) receive_filter, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) &kaweth->scratch, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) KAWETH_CONTROL_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) /****************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) * kaweth_download_firmware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) ****************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) static int kaweth_download_firmware(struct kaweth_device *kaweth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) const char *fwname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) __u8 interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) __u8 type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) const struct firmware *fw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) int data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) ret = request_firmware(&fw, fwname, &kaweth->dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) dev_err(&kaweth->intf->dev, "Firmware request failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if (fw->size > KAWETH_FIRMWARE_BUF_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) dev_err(&kaweth->intf->dev, "Firmware too big: %zu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) fw->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) release_firmware(fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) data_len = fw->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) memcpy(kaweth->firmware_buf, fw->data, fw->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) release_firmware(fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) kaweth->firmware_buf[2] = (data_len & 0xFF) - 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) kaweth->firmware_buf[3] = data_len >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) kaweth->firmware_buf[4] = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) kaweth->firmware_buf[5] = interrupt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) netdev_dbg(kaweth->net, "High: %i, Low:%i\n", kaweth->firmware_buf[3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) kaweth->firmware_buf[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) netdev_dbg(kaweth->net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) "Downloading firmware at %p to kaweth device at %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) kaweth->firmware_buf, kaweth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) netdev_dbg(kaweth->net, "Firmware length: %d\n", data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) return usb_control_msg(kaweth->dev, usb_sndctrlpipe(kaweth->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) KAWETH_COMMAND_SCAN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) kaweth->firmware_buf, data_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) KAWETH_CONTROL_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) /****************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) * kaweth_trigger_firmware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) ****************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) static int kaweth_trigger_firmware(struct kaweth_device *kaweth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) __u8 interrupt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) kaweth->firmware_buf[0] = 0xB6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) kaweth->firmware_buf[1] = 0xC3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) kaweth->firmware_buf[2] = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) kaweth->firmware_buf[3] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) kaweth->firmware_buf[4] = 0x06;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) kaweth->firmware_buf[5] = interrupt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) kaweth->firmware_buf[6] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) kaweth->firmware_buf[7] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) return usb_control_msg(kaweth->dev, usb_sndctrlpipe(kaweth->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) KAWETH_COMMAND_SCAN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) (void *)kaweth->firmware_buf, 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) KAWETH_CONTROL_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) /****************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) * kaweth_reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) ****************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) static int kaweth_reset(struct kaweth_device *kaweth)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) result = usb_reset_configuration(kaweth->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) mdelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) netdev_dbg(kaweth->net, "kaweth_reset() returns %d.\n", result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) static void kaweth_usb_receive(struct urb *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) static int kaweth_resubmit_rx_urb(struct kaweth_device *, gfp_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) /****************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) int_callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) *****************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) static void kaweth_resubmit_int_urb(struct kaweth_device *kaweth, gfp_t mf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) status = usb_submit_urb (kaweth->irq_urb, mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (unlikely(status == -ENOMEM)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) kaweth->suspend_lowmem_ctrl = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) schedule_delayed_work(&kaweth->lowmem_work, HZ/4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) kaweth->suspend_lowmem_ctrl = 0;
^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) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) dev_err(&kaweth->intf->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) "can't resubmit intr, %s-%s, status %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) kaweth->dev->bus->bus_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) kaweth->dev->devpath, status);
^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) static void int_callback(struct urb *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) struct kaweth_device *kaweth = u->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) int act_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) int status = u->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) switch (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) case 0: /* success */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) case -ECONNRESET: /* unlink */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) case -ENOENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) case -ESHUTDOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) /* -EPIPE: should clear the halt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) default: /* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) goto resubmit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) /* we check the link state to report changes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (kaweth->linkstate != (act_state = ( kaweth->intbuffer[STATE_OFFSET] | STATE_MASK) >> STATE_SHIFT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (act_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) netif_carrier_on(kaweth->net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) netif_carrier_off(kaweth->net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) kaweth->linkstate = act_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) resubmit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) kaweth_resubmit_int_urb(kaweth, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) static void kaweth_resubmit_tl(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) struct kaweth_device *kaweth =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) container_of(work, struct kaweth_device, lowmem_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) if (IS_BLOCKED(kaweth->status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (kaweth->suspend_lowmem_rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) kaweth_resubmit_rx_urb(kaweth, GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (kaweth->suspend_lowmem_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) kaweth_resubmit_int_urb(kaweth, GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) /****************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) * kaweth_resubmit_rx_urb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) ****************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) static int kaweth_resubmit_rx_urb(struct kaweth_device *kaweth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) gfp_t mem_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) usb_fill_bulk_urb(kaweth->rx_urb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) kaweth->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) usb_rcvbulkpipe(kaweth->dev, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) kaweth->rx_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) KAWETH_BUF_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) kaweth_usb_receive,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) kaweth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) kaweth->rx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) kaweth->rx_urb->transfer_dma = kaweth->rxbufferhandle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if((result = usb_submit_urb(kaweth->rx_urb, mem_flags))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (result == -ENOMEM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) kaweth->suspend_lowmem_rx = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) schedule_delayed_work(&kaweth->lowmem_work, HZ/4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) dev_err(&kaweth->intf->dev, "resubmitting rx_urb %d failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) kaweth->suspend_lowmem_rx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) static void kaweth_async_set_rx_mode(struct kaweth_device *kaweth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) bool may_sleep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) /****************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) * kaweth_usb_receive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) ****************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) static void kaweth_usb_receive(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) struct device *dev = &urb->dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) struct kaweth_device *kaweth = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) struct net_device *net = kaweth->net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) int status = urb->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) int count = urb->actual_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) int count2 = urb->transfer_buffer_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) __u16 pkt_len = le16_to_cpup((__le16 *)kaweth->rx_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) if (unlikely(status == -EPIPE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) net->stats.rx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) kaweth->end = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) wake_up(&kaweth->term_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) dev_dbg(dev, "Status was -EPIPE.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) if (unlikely(status == -ECONNRESET || status == -ESHUTDOWN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) /* we are killed - set a flag and wake the disconnect handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) kaweth->end = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) wake_up(&kaweth->term_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) dev_dbg(dev, "Status was -ECONNRESET or -ESHUTDOWN.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (unlikely(status == -EPROTO || status == -ETIME ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) status == -EILSEQ)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) net->stats.rx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) dev_dbg(dev, "Status was -EPROTO, -ETIME, or -EILSEQ.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) if (unlikely(status == -EOVERFLOW)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) net->stats.rx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) dev_dbg(dev, "Status was -EOVERFLOW.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) spin_lock_irqsave(&kaweth->device_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if (IS_BLOCKED(kaweth->status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) spin_unlock_irqrestore(&kaweth->device_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) spin_unlock_irqrestore(&kaweth->device_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) if(status && status != -EREMOTEIO && count != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) dev_err(&kaweth->intf->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) "%s RX status: %d count: %d packet_len: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) net->name, status, count, (int)pkt_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) kaweth_resubmit_rx_urb(kaweth, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if(kaweth->net && (count > 2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) if(pkt_len > (count - 2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) dev_err(&kaweth->intf->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) "Packet length too long for USB frame (pkt_len: %x, count: %x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) pkt_len, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) dev_err(&kaweth->intf->dev, "Packet len & 2047: %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) pkt_len & 2047);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) dev_err(&kaweth->intf->dev, "Count 2: %x\n", count2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) kaweth_resubmit_rx_urb(kaweth, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) if(!(skb = dev_alloc_skb(pkt_len+2))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) kaweth_resubmit_rx_urb(kaweth, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) skb_copy_to_linear_data(skb, kaweth->rx_buf + 2, pkt_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) skb_put(skb, pkt_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) skb->protocol = eth_type_trans(skb, net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) netif_rx(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) net->stats.rx_packets++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) net->stats.rx_bytes += pkt_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) kaweth_resubmit_rx_urb(kaweth, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) /****************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) * kaweth_open
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) ****************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) static int kaweth_open(struct net_device *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) struct kaweth_device *kaweth = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) res = usb_autopm_get_interface(kaweth->intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) if (res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) dev_err(&kaweth->intf->dev, "Interface cannot be resumed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) res = kaweth_resubmit_rx_urb(kaweth, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) usb_fill_int_urb(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) kaweth->irq_urb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) kaweth->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) usb_rcvintpipe(kaweth->dev, 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) kaweth->intbuffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) INTBUFFERSIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) int_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) kaweth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 250); /* overriding the descriptor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) kaweth->irq_urb->transfer_dma = kaweth->intbufferhandle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) kaweth->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) res = usb_submit_urb(kaweth->irq_urb, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) if (res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) usb_kill_urb(kaweth->rx_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) kaweth->opened = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) netif_start_queue(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) kaweth_async_set_rx_mode(kaweth, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) usb_autopm_put_interface(kaweth->intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) /****************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) * kaweth_kill_urbs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) ****************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) static void kaweth_kill_urbs(struct kaweth_device *kaweth)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) usb_kill_urb(kaweth->irq_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) usb_kill_urb(kaweth->rx_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) usb_kill_urb(kaweth->tx_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) cancel_delayed_work_sync(&kaweth->lowmem_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) /* a scheduled work may have resubmitted,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) we hit them again */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) usb_kill_urb(kaweth->irq_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) usb_kill_urb(kaweth->rx_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) /****************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) * kaweth_close
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) ****************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) static int kaweth_close(struct net_device *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) struct kaweth_device *kaweth = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) netif_stop_queue(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) kaweth->opened = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) kaweth->status |= KAWETH_STATUS_CLOSING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) kaweth_kill_urbs(kaweth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) kaweth->status &= ~KAWETH_STATUS_CLOSING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) usb_autopm_put_interface(kaweth->intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) static u32 kaweth_get_link(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) struct kaweth_device *kaweth = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) return kaweth->linkstate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) static const struct ethtool_ops ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) .get_link = kaweth_get_link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) /****************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) * kaweth_usb_transmit_complete
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) ****************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) static void kaweth_usb_transmit_complete(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) struct kaweth_device *kaweth = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) struct sk_buff *skb = kaweth->tx_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) int status = urb->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if (unlikely(status != 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if (status != -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) dev_dbg(&urb->dev->dev, "%s: TX status %d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) kaweth->net->name, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) netif_wake_queue(kaweth->net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) dev_kfree_skb_irq(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) /****************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) * kaweth_start_xmit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) ****************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) static netdev_tx_t kaweth_start_xmit(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) struct net_device *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) struct kaweth_device *kaweth = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) __le16 *private_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) spin_lock_irq(&kaweth->device_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) kaweth_async_set_rx_mode(kaweth, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) netif_stop_queue(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) if (IS_BLOCKED(kaweth->status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) goto skip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) /* We now decide whether we can put our special header into the sk_buff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) if (skb_cow_head(skb, 2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) net->stats.tx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) netif_start_queue(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) spin_unlock_irq(&kaweth->device_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) dev_kfree_skb_any(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) return NETDEV_TX_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) private_header = __skb_push(skb, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) *private_header = cpu_to_le16(skb->len-2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) kaweth->tx_skb = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) usb_fill_bulk_urb(kaweth->tx_urb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) kaweth->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) usb_sndbulkpipe(kaweth->dev, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) private_header,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) skb->len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) kaweth_usb_transmit_complete,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) kaweth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) kaweth->end = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) if((res = usb_submit_urb(kaweth->tx_urb, GFP_ATOMIC)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) dev_warn(&net->dev, "kaweth failed tx_urb %d\n", res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) skip:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) net->stats.tx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) netif_start_queue(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) dev_kfree_skb_irq(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) net->stats.tx_packets++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) net->stats.tx_bytes += skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) spin_unlock_irq(&kaweth->device_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) return NETDEV_TX_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) /****************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) * kaweth_set_rx_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) ****************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) static void kaweth_set_rx_mode(struct net_device *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) struct kaweth_device *kaweth = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) __u16 packet_filter_bitmap = KAWETH_PACKET_FILTER_DIRECTED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) KAWETH_PACKET_FILTER_BROADCAST |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) KAWETH_PACKET_FILTER_MULTICAST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) netdev_dbg(net, "Setting Rx mode to %d\n", packet_filter_bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) netif_stop_queue(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) if (net->flags & IFF_PROMISC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) packet_filter_bitmap |= KAWETH_PACKET_FILTER_PROMISCUOUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) else if (!netdev_mc_empty(net) || (net->flags & IFF_ALLMULTI)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) packet_filter_bitmap |= KAWETH_PACKET_FILTER_ALL_MULTICAST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) kaweth->packet_filter_bitmap = packet_filter_bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) netif_wake_queue(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) /****************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) * kaweth_async_set_rx_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) ****************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) static void kaweth_async_set_rx_mode(struct kaweth_device *kaweth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) bool may_sleep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) __u16 packet_filter_bitmap = kaweth->packet_filter_bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) kaweth->packet_filter_bitmap = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) if (packet_filter_bitmap == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) if (!may_sleep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) ret = usb_control_msg(kaweth->dev, usb_sndctrlpipe(kaweth->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) KAWETH_COMMAND_SET_PACKET_FILTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) packet_filter_bitmap, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) &kaweth->scratch, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) KAWETH_CONTROL_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) dev_err(&kaweth->intf->dev, "Failed to set Rx mode: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) netdev_dbg(kaweth->net, "Set Rx mode to %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) packet_filter_bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) /****************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) * kaweth_tx_timeout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) ****************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) static void kaweth_tx_timeout(struct net_device *net, unsigned int txqueue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) struct kaweth_device *kaweth = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) dev_warn(&net->dev, "%s: Tx timed out. Resetting.\n", net->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) net->stats.tx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) netif_trans_update(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) usb_unlink_urb(kaweth->tx_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) /****************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) * kaweth_suspend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) ****************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) static int kaweth_suspend(struct usb_interface *intf, pm_message_t message)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) struct kaweth_device *kaweth = usb_get_intfdata(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) spin_lock_irqsave(&kaweth->device_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) kaweth->status |= KAWETH_STATUS_SUSPENDING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) spin_unlock_irqrestore(&kaweth->device_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) kaweth_kill_urbs(kaweth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) /****************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) * kaweth_resume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) ****************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) static int kaweth_resume(struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) struct kaweth_device *kaweth = usb_get_intfdata(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) spin_lock_irqsave(&kaweth->device_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) kaweth->status &= ~KAWETH_STATUS_SUSPENDING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) spin_unlock_irqrestore(&kaweth->device_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) if (!kaweth->opened)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) kaweth_resubmit_rx_urb(kaweth, GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) kaweth_resubmit_int_urb(kaweth, GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) /****************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) * kaweth_probe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) ****************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) static const struct net_device_ops kaweth_netdev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) .ndo_open = kaweth_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) .ndo_stop = kaweth_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) .ndo_start_xmit = kaweth_start_xmit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) .ndo_tx_timeout = kaweth_tx_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) .ndo_set_rx_mode = kaweth_set_rx_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) .ndo_set_mac_address = eth_mac_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) .ndo_validate_addr = eth_validate_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) static int kaweth_probe(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) struct usb_interface *intf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) const struct usb_device_id *id /* from id_table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) struct device *dev = &intf->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) struct usb_device *udev = interface_to_usbdev(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) struct kaweth_device *kaweth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) struct net_device *netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) const eth_addr_t bcast_addr = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) int result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) int rv = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) dev_dbg(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) "Kawasaki Device Probe (Device number:%d): 0x%4.4x:0x%4.4x:0x%4.4x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) udev->devnum, le16_to_cpu(udev->descriptor.idVendor),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) le16_to_cpu(udev->descriptor.idProduct),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) le16_to_cpu(udev->descriptor.bcdDevice));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) dev_dbg(dev, "Device at %p\n", udev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) dev_dbg(dev, "Descriptor length: %x type: %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) (int)udev->descriptor.bLength,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) (int)udev->descriptor.bDescriptorType);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) netdev = alloc_etherdev(sizeof(*kaweth));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) if (!netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) kaweth = netdev_priv(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) kaweth->dev = udev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) kaweth->net = netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) kaweth->intf = intf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) spin_lock_init(&kaweth->device_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) init_waitqueue_head(&kaweth->term_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) dev_dbg(dev, "Resetting.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) kaweth_reset(kaweth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) * If high byte of bcdDevice is nonzero, firmware is already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) * downloaded. Don't try to do it again, or we'll hang the device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) if (le16_to_cpu(udev->descriptor.bcdDevice) >> 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) dev_info(dev, "Firmware present in device.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) /* Download the firmware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) dev_info(dev, "Downloading firmware...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) kaweth->firmware_buf = (__u8 *)__get_free_page(GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) if (!kaweth->firmware_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) rv = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) goto err_free_netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) if ((result = kaweth_download_firmware(kaweth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) "kaweth/new_code.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) 100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) 2)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) dev_err(dev, "Error downloading firmware (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) goto err_fw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) if ((result = kaweth_download_firmware(kaweth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) "kaweth/new_code_fix.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) 100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) 3)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) dev_err(dev, "Error downloading firmware fix (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) goto err_fw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) if ((result = kaweth_download_firmware(kaweth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) "kaweth/trigger_code.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) 126,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) 2)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) dev_err(dev, "Error downloading trigger code (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) goto err_fw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) if ((result = kaweth_download_firmware(kaweth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) "kaweth/trigger_code_fix.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) 126,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) 3)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) dev_err(dev, "Error downloading trigger code fix (%d)\n", result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) goto err_fw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) if ((result = kaweth_trigger_firmware(kaweth, 126)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) dev_err(dev, "Error triggering firmware (%d)\n", result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) goto err_fw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) /* Device will now disappear for a moment... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) dev_info(dev, "Firmware loaded. I'll be back...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) err_fw:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) free_page((unsigned long)kaweth->firmware_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) free_netdev(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) result = kaweth_read_configuration(kaweth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) if(result < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) dev_err(dev, "Error reading configuration (%d), no net device created\n", result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) goto err_free_netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) dev_info(dev, "Statistics collection: %x\n", kaweth->configuration.statistics_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) dev_info(dev, "Multicast filter limit: %x\n", kaweth->configuration.max_multicast_filters & ((1 << 15) - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) dev_info(dev, "MTU: %d\n", le16_to_cpu(kaweth->configuration.segment_size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) dev_info(dev, "Read MAC address %pM\n", kaweth->configuration.hw_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) if(!memcmp(&kaweth->configuration.hw_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) &bcast_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) sizeof(bcast_addr))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) dev_err(dev, "Firmware not functioning properly, no net device created\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) goto err_free_netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) if(kaweth_set_urb_size(kaweth, KAWETH_BUF_SIZE) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) dev_dbg(dev, "Error setting URB size\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) goto err_free_netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) if(kaweth_set_sofs_wait(kaweth, KAWETH_SOFS_TO_WAIT) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) dev_err(dev, "Error setting SOFS wait\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) goto err_free_netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) result = kaweth_set_receive_filter(kaweth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) KAWETH_PACKET_FILTER_DIRECTED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) KAWETH_PACKET_FILTER_BROADCAST |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) KAWETH_PACKET_FILTER_MULTICAST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) if(result < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) dev_err(dev, "Error setting receive filter\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) goto err_free_netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) dev_dbg(dev, "Initializing net device.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) kaweth->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) if (!kaweth->tx_urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) goto err_free_netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) kaweth->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) if (!kaweth->rx_urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) goto err_only_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) kaweth->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) if (!kaweth->irq_urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) goto err_tx_and_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) kaweth->intbuffer = usb_alloc_coherent( kaweth->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) INTBUFFERSIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) GFP_KERNEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) &kaweth->intbufferhandle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) if (!kaweth->intbuffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) goto err_tx_and_rx_and_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) kaweth->rx_buf = usb_alloc_coherent( kaweth->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) KAWETH_BUF_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) GFP_KERNEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) &kaweth->rxbufferhandle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) if (!kaweth->rx_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) goto err_all_but_rxbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) memcpy(netdev->broadcast, &bcast_addr, sizeof(bcast_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) memcpy(netdev->dev_addr, &kaweth->configuration.hw_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) sizeof(kaweth->configuration.hw_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) netdev->netdev_ops = &kaweth_netdev_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) netdev->watchdog_timeo = KAWETH_TX_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) netdev->mtu = le16_to_cpu(kaweth->configuration.segment_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) netdev->ethtool_ops = &ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) /* kaweth is zeroed as part of alloc_netdev */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) INIT_DELAYED_WORK(&kaweth->lowmem_work, kaweth_resubmit_tl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) usb_set_intfdata(intf, kaweth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) SET_NETDEV_DEV(netdev, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) if (register_netdev(netdev) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) dev_err(dev, "Error registering netdev.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) goto err_intfdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) dev_info(dev, "kaweth interface created at %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) kaweth->net->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) err_intfdata:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) usb_set_intfdata(intf, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) usb_free_coherent(kaweth->dev, KAWETH_BUF_SIZE, (void *)kaweth->rx_buf, kaweth->rxbufferhandle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) err_all_but_rxbuf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) usb_free_coherent(kaweth->dev, INTBUFFERSIZE, (void *)kaweth->intbuffer, kaweth->intbufferhandle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) err_tx_and_rx_and_irq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) usb_free_urb(kaweth->irq_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) err_tx_and_rx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) usb_free_urb(kaweth->rx_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) err_only_tx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) usb_free_urb(kaweth->tx_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) err_free_netdev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) free_netdev(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) return rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) /****************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) * kaweth_disconnect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) ****************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) static void kaweth_disconnect(struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) struct kaweth_device *kaweth = usb_get_intfdata(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) struct net_device *netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) usb_set_intfdata(intf, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) if (!kaweth) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) dev_warn(&intf->dev, "unregistering non-existent device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) netdev = kaweth->net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) netdev_dbg(kaweth->net, "Unregistering net device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) unregister_netdev(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) usb_free_urb(kaweth->rx_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) usb_free_urb(kaweth->tx_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) usb_free_urb(kaweth->irq_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) usb_free_coherent(kaweth->dev, KAWETH_BUF_SIZE, (void *)kaweth->rx_buf, kaweth->rxbufferhandle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) usb_free_coherent(kaweth->dev, INTBUFFERSIZE, (void *)kaweth->intbuffer, kaweth->intbufferhandle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) free_netdev(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) module_usb_driver(kaweth_driver);