^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) * Copyright (c) 2001 Vojtech Pavlik
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * CATC EL1210A NetMate USB Ethernet driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Sponsored by SuSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Based on the work of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Donald Becker
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Old chipset support added by Simon Evans <spse@secret.org.uk> 2002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * - adds support for Belkin F5U011
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * Should you need to contact me, the author, you can do so either by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/ethtool.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/crc32.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/gfp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #undef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/usb.h>
^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) * Version information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define DRIVER_VERSION "v2.8"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@suse.cz>"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define DRIVER_DESC "CATC EL1210A NetMate USB Ethernet driver"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define SHORT_DRIVER_DESC "EL1210A NetMate USB Ethernet"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) MODULE_AUTHOR(DRIVER_AUTHOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) MODULE_DESCRIPTION(DRIVER_DESC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static const char driver_name[] = "catc";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * Some defines.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define STATS_UPDATE (HZ) /* Time between stats updates */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define TX_TIMEOUT (5*HZ) /* Max time the queue can be stopped */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define PKT_SZ 1536 /* Max Ethernet packet size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define RX_MAX_BURST 15 /* Max packets per rx buffer (> 0, < 16) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define TX_MAX_BURST 15 /* Max full sized packets per tx buffer (> 0) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define CTRL_QUEUE 16 /* Max control requests in flight (power of two) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define RX_PKT_SZ 1600 /* Max size of receive packet for F5U011 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * Control requests.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) enum control_requests {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) ReadMem = 0xf1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) GetMac = 0xf2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) Reset = 0xf4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) SetMac = 0xf5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) SetRxMode = 0xf5, /* F5U011 only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) WriteROM = 0xf8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) SetReg = 0xfa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) GetReg = 0xfb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) WriteMem = 0xfc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) ReadROM = 0xfd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * Registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) enum register_offsets {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) TxBufCount = 0x20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) RxBufCount = 0x21,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) OpModes = 0x22,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) TxQed = 0x23,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) RxQed = 0x24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) MaxBurst = 0x25,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) RxUnit = 0x60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) EthStatus = 0x61,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) StationAddr0 = 0x67,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) EthStats = 0x69,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) LEDCtrl = 0x81,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) enum eth_stats {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) TxSingleColl = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) TxMultiColl = 0x02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) TxExcessColl = 0x04,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) RxFramErr = 0x06,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) enum op_mode_bits {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) Op3MemWaits = 0x03,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) OpLenInclude = 0x08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) OpRxMerge = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) OpTxMerge = 0x20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) OpWin95bugfix = 0x40,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) OpLoopback = 0x80,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) enum rx_filter_bits {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) RxEnable = 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) RxPolarity = 0x02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) RxForceOK = 0x04,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) RxMultiCast = 0x08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) RxPromisc = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) AltRxPromisc = 0x20, /* F5U011 uses different bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) enum led_values {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) LEDFast = 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) LEDSlow = 0x02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) LEDFlash = 0x03,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) LEDPulse = 0x04,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) LEDLink = 0x08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) enum link_status {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) LinkNoChange = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) LinkGood = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) LinkBad = 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * The catc struct.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #define CTRL_RUNNING 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #define RX_RUNNING 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #define TX_RUNNING 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) struct catc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) struct net_device *netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) struct usb_device *usbdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) unsigned int tx_ptr, tx_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) unsigned int ctrl_head, ctrl_tail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) spinlock_t tx_lock, ctrl_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) u8 tx_buf[2][TX_MAX_BURST * (PKT_SZ + 2)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) u8 rx_buf[RX_MAX_BURST * (PKT_SZ + 2)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) u8 irq_buf[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) u8 ctrl_buf[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) struct usb_ctrlrequest ctrl_dr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) struct timer_list timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) u8 stats_buf[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) u16 stats_vals[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) unsigned long last_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) u8 multicast[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct ctrl_queue {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) u8 dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) u8 request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) u16 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) u16 index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) void *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) void (*callback)(struct catc *catc, struct ctrl_queue *q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) } ctrl_queue[CTRL_QUEUE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) struct urb *tx_urb, *rx_urb, *irq_urb, *ctrl_urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) u8 is_f5u011; /* Set if device is an F5U011 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) u8 rxmode[2]; /* Used for F5U011 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) atomic_t recq_sz; /* Used for F5U011 - counter of waiting rx packets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * Useful macros.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) #define catc_get_mac(catc, mac) catc_ctrl_msg(catc, USB_DIR_IN, GetMac, 0, 0, mac, 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) #define catc_reset(catc) catc_ctrl_msg(catc, USB_DIR_OUT, Reset, 0, 0, NULL, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) #define catc_set_reg(catc, reg, val) catc_ctrl_msg(catc, USB_DIR_OUT, SetReg, val, reg, NULL, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) #define catc_get_reg(catc, reg, buf) catc_ctrl_msg(catc, USB_DIR_IN, GetReg, 0, reg, buf, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) #define catc_write_mem(catc, addr, buf, size) catc_ctrl_msg(catc, USB_DIR_OUT, WriteMem, 0, addr, buf, size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) #define catc_read_mem(catc, addr, buf, size) catc_ctrl_msg(catc, USB_DIR_IN, ReadMem, 0, addr, buf, size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) #define f5u011_rxmode(catc, rxmode) catc_ctrl_msg(catc, USB_DIR_OUT, SetRxMode, 0, 1, rxmode, 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) #define f5u011_rxmode_async(catc, rxmode) catc_ctrl_async(catc, USB_DIR_OUT, SetRxMode, 0, 1, &rxmode, 2, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) #define f5u011_mchash_async(catc, hash) catc_ctrl_async(catc, USB_DIR_OUT, SetRxMode, 0, 2, &hash, 8, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) #define catc_set_reg_async(catc, reg, val) catc_ctrl_async(catc, USB_DIR_OUT, SetReg, val, reg, NULL, 0, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) #define catc_get_reg_async(catc, reg, cb) catc_ctrl_async(catc, USB_DIR_IN, GetReg, 0, reg, NULL, 1, cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) #define catc_write_mem_async(catc, addr, buf, size) catc_ctrl_async(catc, USB_DIR_OUT, WriteMem, 0, addr, buf, size, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) * Receive routines.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) static void catc_rx_done(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) struct catc *catc = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) u8 *pkt_start = urb->transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) int pkt_len, pkt_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) int status = urb->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if (!catc->is_f5u011) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) clear_bit(RX_RUNNING, &catc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) pkt_offset = 2;
^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) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) dev_dbg(&urb->dev->dev, "rx_done, status %d, length %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) status, urb->actual_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if(!catc->is_f5u011) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) pkt_len = le16_to_cpup((__le16*)pkt_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) if (pkt_len > urb->actual_length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) catc->netdev->stats.rx_length_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) catc->netdev->stats.rx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) pkt_len = urb->actual_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) if (!(skb = dev_alloc_skb(pkt_len)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) skb_copy_to_linear_data(skb, pkt_start + pkt_offset, pkt_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) skb_put(skb, pkt_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) skb->protocol = eth_type_trans(skb, catc->netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) netif_rx(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) catc->netdev->stats.rx_packets++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) catc->netdev->stats.rx_bytes += pkt_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) /* F5U011 only does one packet per RX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (catc->is_f5u011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) pkt_start += (((pkt_len + 1) >> 6) + 1) << 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) } while (pkt_start - (u8 *) urb->transfer_buffer < urb->actual_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) if (catc->is_f5u011) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (atomic_read(&catc->recq_sz)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) int state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) atomic_dec(&catc->recq_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) netdev_dbg(catc->netdev, "getting extra packet\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) urb->dev = catc->usbdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) if ((state = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) netdev_dbg(catc->netdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) "submit(rx_urb) status %d\n", state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) clear_bit(RX_RUNNING, &catc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^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) static void catc_irq_done(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) struct catc *catc = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) u8 *data = urb->transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) int status = urb->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) unsigned int hasdata = 0, linksts = LinkNoChange;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (!catc->is_f5u011) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) hasdata = data[1] & 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (data[1] & 0x40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) linksts = LinkGood;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) else if (data[1] & 0x20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) linksts = LinkBad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) hasdata = (unsigned int)(be16_to_cpup((__be16*)data) & 0x0fff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (data[0] == 0x90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) linksts = LinkGood;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) else if (data[0] == 0xA0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) linksts = LinkBad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) switch (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) case 0: /* success */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) case -ECONNRESET: /* unlink */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) case -ENOENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) case -ESHUTDOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) /* -EPIPE: should clear the halt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) default: /* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) dev_dbg(&urb->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) "irq_done, status %d, data %02x %02x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) status, data[0], data[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) goto resubmit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if (linksts == LinkGood) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) netif_carrier_on(catc->netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) netdev_dbg(catc->netdev, "link ok\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (linksts == LinkBad) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) netif_carrier_off(catc->netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) netdev_dbg(catc->netdev, "link bad\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) if (hasdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) if (test_and_set_bit(RX_RUNNING, &catc->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (catc->is_f5u011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) atomic_inc(&catc->recq_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) catc->rx_urb->dev = catc->usbdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if ((res = usb_submit_urb(catc->rx_urb, GFP_ATOMIC)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) dev_err(&catc->usbdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) "submit(rx_urb) status %d\n", res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) resubmit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) res = usb_submit_urb (urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) dev_err(&catc->usbdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) "can't resubmit intr, %s-%s, status %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) catc->usbdev->bus->bus_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) catc->usbdev->devpath, res);
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) * Transmit routines.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) static int catc_tx_run(struct catc *catc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) if (catc->is_f5u011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) catc->tx_ptr = (catc->tx_ptr + 63) & ~63;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) catc->tx_urb->transfer_buffer_length = catc->tx_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) catc->tx_urb->transfer_buffer = catc->tx_buf[catc->tx_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) catc->tx_urb->dev = catc->usbdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if ((status = usb_submit_urb(catc->tx_urb, GFP_ATOMIC)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) dev_err(&catc->usbdev->dev, "submit(tx_urb), status %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) catc->tx_idx = !catc->tx_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) catc->tx_ptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) netif_trans_update(catc->netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) static void catc_tx_done(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) struct catc *catc = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) int r, status = urb->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (status == -ECONNRESET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) dev_dbg(&urb->dev->dev, "Tx Reset.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) urb->status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) netif_trans_update(catc->netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) catc->netdev->stats.tx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) clear_bit(TX_RUNNING, &catc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) netif_wake_queue(catc->netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) dev_dbg(&urb->dev->dev, "tx_done, status %d, length %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) status, urb->actual_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) spin_lock_irqsave(&catc->tx_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (catc->tx_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) r = catc_tx_run(catc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) if (unlikely(r < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) clear_bit(TX_RUNNING, &catc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) clear_bit(TX_RUNNING, &catc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) netif_wake_queue(catc->netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) spin_unlock_irqrestore(&catc->tx_lock, flags);
^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 netdev_tx_t catc_start_xmit(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) struct net_device *netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) struct catc *catc = netdev_priv(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) int r = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) char *tx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) spin_lock_irqsave(&catc->tx_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) catc->tx_ptr = (((catc->tx_ptr - 1) >> 6) + 1) << 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) tx_buf = catc->tx_buf[catc->tx_idx] + catc->tx_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) if (catc->is_f5u011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) *(__be16 *)tx_buf = cpu_to_be16(skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) *(__le16 *)tx_buf = cpu_to_le16(skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) skb_copy_from_linear_data(skb, tx_buf + 2, skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) catc->tx_ptr += skb->len + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (!test_and_set_bit(TX_RUNNING, &catc->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) r = catc_tx_run(catc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) if (r < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) clear_bit(TX_RUNNING, &catc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if ((catc->is_f5u011 && catc->tx_ptr) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) (catc->tx_ptr >= ((TX_MAX_BURST - 1) * (PKT_SZ + 2))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) netif_stop_queue(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) spin_unlock_irqrestore(&catc->tx_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (r >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) catc->netdev->stats.tx_bytes += skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) catc->netdev->stats.tx_packets++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) dev_kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) return NETDEV_TX_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) static void catc_tx_timeout(struct net_device *netdev, unsigned int txqueue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) struct catc *catc = netdev_priv(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) dev_warn(&netdev->dev, "Transmit timed out.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) usb_unlink_urb(catc->tx_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) * Control messages.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) static int catc_ctrl_msg(struct catc *catc, u8 dir, u8 request, u16 value, u16 index, void *buf, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) int retval = usb_control_msg(catc->usbdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) dir ? usb_rcvctrlpipe(catc->usbdev, 0) : usb_sndctrlpipe(catc->usbdev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) request, 0x40 | dir, value, index, buf, len, 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) return retval < 0 ? retval : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) static void catc_ctrl_run(struct catc *catc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) struct ctrl_queue *q = catc->ctrl_queue + catc->ctrl_tail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) struct usb_device *usbdev = catc->usbdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) struct urb *urb = catc->ctrl_urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) struct usb_ctrlrequest *dr = &catc->ctrl_dr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) dr->bRequest = q->request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) dr->bRequestType = 0x40 | q->dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) dr->wValue = cpu_to_le16(q->value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) dr->wIndex = cpu_to_le16(q->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) dr->wLength = cpu_to_le16(q->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) urb->pipe = q->dir ? usb_rcvctrlpipe(usbdev, 0) : usb_sndctrlpipe(usbdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) urb->transfer_buffer_length = q->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) urb->transfer_buffer = catc->ctrl_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) urb->setup_packet = (void *) dr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) urb->dev = usbdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (!q->dir && q->buf && q->len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) memcpy(catc->ctrl_buf, q->buf, q->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if ((status = usb_submit_urb(catc->ctrl_urb, GFP_ATOMIC)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) dev_err(&catc->usbdev->dev, "submit(ctrl_urb) status %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) static void catc_ctrl_done(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) struct catc *catc = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) struct ctrl_queue *q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) int status = urb->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) dev_dbg(&urb->dev->dev, "ctrl_done, status %d, len %d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) status, urb->actual_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) spin_lock_irqsave(&catc->ctrl_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) q = catc->ctrl_queue + catc->ctrl_tail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (q->dir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (q->buf && q->len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) memcpy(q->buf, catc->ctrl_buf, q->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) q->buf = catc->ctrl_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) if (q->callback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) q->callback(catc, q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) catc->ctrl_tail = (catc->ctrl_tail + 1) & (CTRL_QUEUE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if (catc->ctrl_head != catc->ctrl_tail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) catc_ctrl_run(catc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) clear_bit(CTRL_RUNNING, &catc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) spin_unlock_irqrestore(&catc->ctrl_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) static int catc_ctrl_async(struct catc *catc, u8 dir, u8 request, u16 value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) u16 index, void *buf, int len, void (*callback)(struct catc *catc, struct ctrl_queue *q))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) struct ctrl_queue *q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) spin_lock_irqsave(&catc->ctrl_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) q = catc->ctrl_queue + catc->ctrl_head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) q->dir = dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) q->request = request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) q->value = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) q->index = index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) q->buf = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) q->len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) q->callback = callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) catc->ctrl_head = (catc->ctrl_head + 1) & (CTRL_QUEUE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) if (catc->ctrl_head == catc->ctrl_tail) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) dev_err(&catc->usbdev->dev, "ctrl queue full\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) catc->ctrl_tail = (catc->ctrl_tail + 1) & (CTRL_QUEUE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) retval = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) if (!test_and_set_bit(CTRL_RUNNING, &catc->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) catc_ctrl_run(catc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) spin_unlock_irqrestore(&catc->ctrl_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) * Statistics.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) static void catc_stats_done(struct catc *catc, struct ctrl_queue *q)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) int index = q->index - EthStats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) u16 data, last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) catc->stats_buf[index] = *((char *)q->buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) if (index & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) data = ((u16)catc->stats_buf[index] << 8) | catc->stats_buf[index + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) last = catc->stats_vals[index >> 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) switch (index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) case TxSingleColl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) case TxMultiColl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) catc->netdev->stats.collisions += data - last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) case TxExcessColl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) catc->netdev->stats.tx_aborted_errors += data - last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) catc->netdev->stats.tx_errors += data - last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) case RxFramErr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) catc->netdev->stats.rx_frame_errors += data - last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) catc->netdev->stats.rx_errors += data - last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) catc->stats_vals[index >> 1] = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) static void catc_stats_timer(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) struct catc *catc = from_timer(catc, t, timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) for (i = 0; i < 8; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) catc_get_reg_async(catc, EthStats + 7 - i, catc_stats_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) mod_timer(&catc->timer, jiffies + STATS_UPDATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) * Receive modes. Broadcast, Multicast, Promisc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) static void catc_multicast(unsigned char *addr, u8 *multicast)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) u32 crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) crc = ether_crc_le(6, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) multicast[(crc >> 3) & 0x3f] |= 1 << (crc & 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) static void catc_set_multicast_list(struct net_device *netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) struct catc *catc = netdev_priv(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) struct netdev_hw_addr *ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) u8 broadcast[ETH_ALEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) u8 rx = RxEnable | RxPolarity | RxMultiCast;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) eth_broadcast_addr(broadcast);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) memset(catc->multicast, 0, 64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) catc_multicast(broadcast, catc->multicast);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) catc_multicast(netdev->dev_addr, catc->multicast);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) if (netdev->flags & IFF_PROMISC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) memset(catc->multicast, 0xff, 64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) rx |= (!catc->is_f5u011) ? RxPromisc : AltRxPromisc;
^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) if (netdev->flags & IFF_ALLMULTI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) memset(catc->multicast, 0xff, 64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) netdev_for_each_mc_addr(ha, netdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) u32 crc = ether_crc_le(6, ha->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) if (!catc->is_f5u011) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) catc->multicast[(crc >> 3) & 0x3f] |= 1 << (crc & 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) catc->multicast[7-(crc >> 29)] |= 1 << ((crc >> 26) & 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) if (!catc->is_f5u011) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) catc_set_reg_async(catc, RxUnit, rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) catc_write_mem_async(catc, 0xfa80, catc->multicast, 64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) f5u011_mchash_async(catc, catc->multicast);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) if (catc->rxmode[0] != rx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) catc->rxmode[0] = rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) netdev_dbg(catc->netdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) "Setting RX mode to %2.2X %2.2X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) catc->rxmode[0], catc->rxmode[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) f5u011_rxmode_async(catc, catc->rxmode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) static void catc_get_drvinfo(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) struct ethtool_drvinfo *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) struct catc *catc = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) strlcpy(info->driver, driver_name, sizeof(info->driver));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) strlcpy(info->version, DRIVER_VERSION, sizeof(info->version));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) usb_make_path(catc->usbdev, info->bus_info, sizeof(info->bus_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) static int catc_get_link_ksettings(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) struct ethtool_link_ksettings *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) struct catc *catc = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) if (!catc->is_f5u011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) ethtool_link_ksettings_zero_link_mode(cmd, supported);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) ethtool_link_ksettings_add_link_mode(cmd, supported, 10baseT_Half);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) ethtool_link_ksettings_add_link_mode(cmd, supported, TP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) ethtool_link_ksettings_zero_link_mode(cmd, advertising);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) ethtool_link_ksettings_add_link_mode(cmd, advertising, 10baseT_Half);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) ethtool_link_ksettings_add_link_mode(cmd, advertising, TP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) cmd->base.speed = SPEED_10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) cmd->base.duplex = DUPLEX_HALF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) cmd->base.port = PORT_TP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) cmd->base.phy_address = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) cmd->base.autoneg = AUTONEG_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) static const struct ethtool_ops ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) .get_drvinfo = catc_get_drvinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) .get_link = ethtool_op_get_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) .get_link_ksettings = catc_get_link_ksettings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) * Open, close.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) static int catc_open(struct net_device *netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) struct catc *catc = netdev_priv(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) catc->irq_urb->dev = catc->usbdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) if ((status = usb_submit_urb(catc->irq_urb, GFP_KERNEL)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) dev_err(&catc->usbdev->dev, "submit(irq_urb) status %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) netif_start_queue(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) if (!catc->is_f5u011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) mod_timer(&catc->timer, jiffies + STATS_UPDATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) static int catc_stop(struct net_device *netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) struct catc *catc = netdev_priv(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) netif_stop_queue(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) if (!catc->is_f5u011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) del_timer_sync(&catc->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) usb_kill_urb(catc->rx_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) usb_kill_urb(catc->tx_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) usb_kill_urb(catc->irq_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) usb_kill_urb(catc->ctrl_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) static const struct net_device_ops catc_netdev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) .ndo_open = catc_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) .ndo_stop = catc_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) .ndo_start_xmit = catc_start_xmit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) .ndo_tx_timeout = catc_tx_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) .ndo_set_rx_mode = catc_set_multicast_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) .ndo_set_mac_address = eth_mac_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) .ndo_validate_addr = eth_validate_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) * USB probe, disconnect.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) struct device *dev = &intf->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) struct usb_device *usbdev = interface_to_usbdev(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) struct net_device *netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) struct catc *catc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) u8 broadcast[ETH_ALEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) int pktsz, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) if (usb_set_interface(usbdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) intf->altsetting->desc.bInterfaceNumber, 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) dev_err(dev, "Can't set altsetting 1.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) return -EIO;
^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) netdev = alloc_etherdev(sizeof(struct catc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) if (!netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) catc = netdev_priv(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) netdev->netdev_ops = &catc_netdev_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) netdev->watchdog_timeo = TX_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) netdev->ethtool_ops = &ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) catc->usbdev = usbdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) catc->netdev = netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) spin_lock_init(&catc->tx_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) spin_lock_init(&catc->ctrl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) timer_setup(&catc->timer, catc_stats_timer, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) catc->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) catc->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) catc->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) catc->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) if ((!catc->ctrl_urb) || (!catc->tx_urb) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) (!catc->rx_urb) || (!catc->irq_urb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) dev_err(&intf->dev, "No free urbs available.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) goto fail_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) /* The F5U011 has the same vendor/product as the netmate but a device version of 0x130 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) if (le16_to_cpu(usbdev->descriptor.idVendor) == 0x0423 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) le16_to_cpu(usbdev->descriptor.idProduct) == 0xa &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) le16_to_cpu(catc->usbdev->descriptor.bcdDevice) == 0x0130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) dev_dbg(dev, "Testing for f5u011\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) catc->is_f5u011 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) atomic_set(&catc->recq_sz, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) pktsz = RX_PKT_SZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) pktsz = RX_MAX_BURST * (PKT_SZ + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) usb_fill_control_urb(catc->ctrl_urb, usbdev, usb_sndctrlpipe(usbdev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) NULL, NULL, 0, catc_ctrl_done, catc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) usb_fill_bulk_urb(catc->tx_urb, usbdev, usb_sndbulkpipe(usbdev, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) NULL, 0, catc_tx_done, catc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) usb_fill_bulk_urb(catc->rx_urb, usbdev, usb_rcvbulkpipe(usbdev, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) catc->rx_buf, pktsz, catc_rx_done, catc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) usb_fill_int_urb(catc->irq_urb, usbdev, usb_rcvintpipe(usbdev, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) catc->irq_buf, 2, catc_irq_done, catc, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) if (!catc->is_f5u011) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) u32 *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) dev_dbg(dev, "Checking memory size\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) buf = kmalloc(4, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) if (!buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) goto fail_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) *buf = 0x12345678;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) catc_write_mem(catc, 0x7a80, buf, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) *buf = 0x87654321;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) catc_write_mem(catc, 0xfa80, buf, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) catc_read_mem(catc, 0x7a80, buf, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) switch (*buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) case 0x12345678:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) catc_set_reg(catc, TxBufCount, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) catc_set_reg(catc, RxBufCount, 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) dev_dbg(dev, "64k Memory\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) dev_warn(&intf->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) "Couldn't detect memory size, assuming 32k\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) case 0x87654321:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) catc_set_reg(catc, TxBufCount, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) catc_set_reg(catc, RxBufCount, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) dev_dbg(dev, "32k Memory\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) dev_dbg(dev, "Getting MAC from SEEROM.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) catc_get_mac(catc, netdev->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) dev_dbg(dev, "Setting MAC into registers.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) for (i = 0; i < 6; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) catc_set_reg(catc, StationAddr0 - i, netdev->dev_addr[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) dev_dbg(dev, "Filling the multicast list.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) eth_broadcast_addr(broadcast);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) catc_multicast(broadcast, catc->multicast);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) catc_multicast(netdev->dev_addr, catc->multicast);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) catc_write_mem(catc, 0xfa80, catc->multicast, 64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) dev_dbg(dev, "Clearing error counters.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) for (i = 0; i < 8; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) catc_set_reg(catc, EthStats + i, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) catc->last_stats = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) dev_dbg(dev, "Enabling.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) catc_set_reg(catc, MaxBurst, RX_MAX_BURST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) catc_set_reg(catc, OpModes, OpTxMerge | OpRxMerge | OpLenInclude | Op3MemWaits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) catc_set_reg(catc, LEDCtrl, LEDLink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) catc_set_reg(catc, RxUnit, RxEnable | RxPolarity | RxMultiCast);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) dev_dbg(dev, "Performing reset\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) catc_reset(catc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) catc_get_mac(catc, netdev->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) dev_dbg(dev, "Setting RX Mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) catc->rxmode[0] = RxEnable | RxPolarity | RxMultiCast;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) catc->rxmode[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) f5u011_rxmode(catc, catc->rxmode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) dev_dbg(dev, "Init done.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) printk(KERN_INFO "%s: %s USB Ethernet at usb-%s-%s, %pM.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) netdev->name, (catc->is_f5u011) ? "Belkin F5U011" : "CATC EL1210A NetMate",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) usbdev->bus->bus_name, usbdev->devpath, netdev->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) usb_set_intfdata(intf, catc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) SET_NETDEV_DEV(netdev, &intf->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) ret = register_netdev(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) goto fail_clear_intfdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) fail_clear_intfdata:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) usb_set_intfdata(intf, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) fail_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) usb_free_urb(catc->ctrl_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) usb_free_urb(catc->tx_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) usb_free_urb(catc->rx_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) usb_free_urb(catc->irq_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) free_netdev(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) static void catc_disconnect(struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) struct catc *catc = usb_get_intfdata(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) usb_set_intfdata(intf, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) if (catc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) unregister_netdev(catc->netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) usb_free_urb(catc->ctrl_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) usb_free_urb(catc->tx_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) usb_free_urb(catc->rx_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) usb_free_urb(catc->irq_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) free_netdev(catc->netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) * Module functions and tables.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) static const struct usb_device_id catc_id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) { USB_DEVICE(0x0423, 0xa) }, /* CATC Netmate, Belkin F5U011 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) { USB_DEVICE(0x0423, 0xc) }, /* CATC Netmate II, Belkin F5U111 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) { USB_DEVICE(0x08d1, 0x1) }, /* smartBridges smartNIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) { }
^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) MODULE_DEVICE_TABLE(usb, catc_id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) static struct usb_driver catc_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) .name = driver_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) .probe = catc_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) .disconnect = catc_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) .id_table = catc_id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) .disable_hub_initiated_lpm = 1,
^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) module_usb_driver(catc_driver);