^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Davicom DM96xx USB 10/100Mbps ethernet devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Peter Korsgaard <jacmet@sunsite.dk>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * This file is licensed under the terms of the GNU General Public License
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * version 2. This program is licensed "as is" without any warranty of any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * kind, whether express or implied.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) //#define DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/stddef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/ethtool.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/mii.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/crc32.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/usb/usbnet.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /* datasheet:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) http://ptm2.cc.utu.fi/ftp/network/cards/DM9601/From_NET/DM9601-DS-P01-930914.pdf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /* control requests */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define DM_READ_REGS 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define DM_WRITE_REGS 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define DM_READ_MEMS 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define DM_WRITE_REG 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define DM_WRITE_MEMS 0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define DM_WRITE_MEM 0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) /* registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define DM_NET_CTRL 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define DM_RX_CTRL 0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define DM_SHARED_CTRL 0x0b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define DM_SHARED_ADDR 0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define DM_SHARED_DATA 0x0d /* low + high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define DM_PHY_ADDR 0x10 /* 6 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define DM_MCAST_ADDR 0x16 /* 8 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define DM_GPR_CTRL 0x1e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define DM_GPR_DATA 0x1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define DM_CHIP_ID 0x2c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define DM_MODE_CTRL 0x91 /* only on dm9620 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /* chip id values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define ID_DM9601 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define ID_DM9620 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define DM_MAX_MCAST 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define DM_MCAST_SIZE 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define DM_EEPROM_LEN 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define DM_TX_OVERHEAD 2 /* 2 byte header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define DM_RX_OVERHEAD 7 /* 3 byte header + 4 byte crc tail */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define DM_TIMEOUT 1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static int dm_read(struct usbnet *dev, u8 reg, u16 length, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) err = usbnet_read_cmd(dev, DM_READ_REGS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) 0, reg, data, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) if(err != length && err >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static int dm_read_reg(struct usbnet *dev, u8 reg, u8 *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return dm_read(dev, reg, 1, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static int dm_write(struct usbnet *dev, u8 reg, u16 length, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) err = usbnet_write_cmd(dev, DM_WRITE_REGS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) 0, reg, data, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) if (err >= 0 && err < length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static int dm_write_reg(struct usbnet *dev, u8 reg, u8 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return usbnet_write_cmd(dev, DM_WRITE_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) value, reg, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static void dm_write_async(struct usbnet *dev, u8 reg, u16 length, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) usbnet_write_cmd_async(dev, DM_WRITE_REGS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 0, reg, data, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static void dm_write_reg_async(struct usbnet *dev, u8 reg, u8 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) usbnet_write_cmd_async(dev, DM_WRITE_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) value, reg, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static int dm_read_shared_word(struct usbnet *dev, int phy, u8 reg, __le16 *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) mutex_lock(&dev->phy_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) dm_write_reg(dev, DM_SHARED_ADDR, phy ? (reg | 0x40) : reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) dm_write_reg(dev, DM_SHARED_CTRL, phy ? 0xc : 0x4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) for (i = 0; i < DM_TIMEOUT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) u8 tmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) ret = dm_read_reg(dev, DM_SHARED_CTRL, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /* ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if ((tmp & 1) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (i == DM_TIMEOUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) netdev_err(dev->net, "%s read timed out!\n", phy ? "phy" : "eeprom");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) dm_write_reg(dev, DM_SHARED_CTRL, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) ret = dm_read(dev, DM_SHARED_DATA, 2, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) netdev_dbg(dev->net, "read shared %d 0x%02x returned 0x%04x, %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) phy, reg, *value, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) mutex_unlock(&dev->phy_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) static int dm_write_shared_word(struct usbnet *dev, int phy, u8 reg, __le16 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) mutex_lock(&dev->phy_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) ret = dm_write(dev, DM_SHARED_DATA, 2, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) dm_write_reg(dev, DM_SHARED_ADDR, phy ? (reg | 0x40) : reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) dm_write_reg(dev, DM_SHARED_CTRL, phy ? 0x1a : 0x12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) for (i = 0; i < DM_TIMEOUT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) u8 tmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) ret = dm_read_reg(dev, DM_SHARED_CTRL, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) /* ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if ((tmp & 1) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (i == DM_TIMEOUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) netdev_err(dev->net, "%s write timed out!\n", phy ? "phy" : "eeprom");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) dm_write_reg(dev, DM_SHARED_CTRL, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) mutex_unlock(&dev->phy_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) static int dm_read_eeprom_word(struct usbnet *dev, u8 offset, void *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return dm_read_shared_word(dev, 0, offset, value);
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static int dm9601_get_eeprom_len(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) return DM_EEPROM_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) static int dm9601_get_eeprom(struct net_device *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct ethtool_eeprom *eeprom, u8 * data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) struct usbnet *dev = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) __le16 *ebuf = (__le16 *) data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) /* access is 16bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if ((eeprom->offset % 2) || (eeprom->len % 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) for (i = 0; i < eeprom->len / 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (dm_read_eeprom_word(dev, eeprom->offset / 2 + i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) &ebuf[i]) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) static int dm9601_mdio_read(struct net_device *netdev, int phy_id, int loc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) struct usbnet *dev = netdev_priv(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) __le16 res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (phy_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) netdev_dbg(dev->net, "Only internal phy supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) dm_read_shared_word(dev, 1, loc, &res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) netdev_dbg(dev->net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) "dm9601_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) phy_id, loc, le16_to_cpu(res));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return le16_to_cpu(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) static void dm9601_mdio_write(struct net_device *netdev, int phy_id, int loc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) struct usbnet *dev = netdev_priv(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) __le16 res = cpu_to_le16(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (phy_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) netdev_dbg(dev->net, "Only internal phy supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) netdev_dbg(dev->net, "dm9601_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) phy_id, loc, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) dm_write_shared_word(dev, 1, loc, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) static void dm9601_get_drvinfo(struct net_device *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) struct ethtool_drvinfo *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) /* Inherit standard device info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) usbnet_get_drvinfo(net, info);
^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) static u32 dm9601_get_link(struct net_device *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) struct usbnet *dev = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) return mii_link_ok(&dev->mii);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) static int dm9601_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) struct usbnet *dev = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
^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) static const struct ethtool_ops dm9601_ethtool_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) .get_drvinfo = dm9601_get_drvinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) .get_link = dm9601_get_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) .get_msglevel = usbnet_get_msglevel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) .set_msglevel = usbnet_set_msglevel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) .get_eeprom_len = dm9601_get_eeprom_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) .get_eeprom = dm9601_get_eeprom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) .nway_reset = usbnet_nway_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) .get_link_ksettings = usbnet_get_link_ksettings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) .set_link_ksettings = usbnet_set_link_ksettings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) static void dm9601_set_multicast(struct net_device *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) struct usbnet *dev = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) /* We use the 20 byte dev->data for our 8 byte filter buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) * to avoid allocating memory that is tricky to free later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) u8 *hashes = (u8 *) & dev->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) u8 rx_ctl = 0x31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) memset(hashes, 0x00, DM_MCAST_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) hashes[DM_MCAST_SIZE - 1] |= 0x80; /* broadcast address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (net->flags & IFF_PROMISC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) rx_ctl |= 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) } else if (net->flags & IFF_ALLMULTI ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) netdev_mc_count(net) > DM_MAX_MCAST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) rx_ctl |= 0x08;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) } else if (!netdev_mc_empty(net)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) struct netdev_hw_addr *ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) netdev_for_each_mc_addr(ha, net) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) u32 crc = ether_crc(ETH_ALEN, ha->addr) >> 26;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) hashes[crc >> 3] |= 1 << (crc & 0x7);
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) dm_write_async(dev, DM_MCAST_ADDR, DM_MCAST_SIZE, hashes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) dm_write_reg_async(dev, DM_RX_CTRL, rx_ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) static void __dm9601_set_mac_address(struct usbnet *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) dm_write_async(dev, DM_PHY_ADDR, ETH_ALEN, dev->net->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) static int dm9601_set_mac_address(struct net_device *net, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) struct sockaddr *addr = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) struct usbnet *dev = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) if (!is_valid_ether_addr(addr->sa_data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) dev_err(&net->dev, "not setting invalid mac address %pM\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) addr->sa_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) memcpy(net->dev_addr, addr->sa_data, net->addr_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) __dm9601_set_mac_address(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) static const struct net_device_ops dm9601_netdev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) .ndo_open = usbnet_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) .ndo_stop = usbnet_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) .ndo_start_xmit = usbnet_start_xmit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) .ndo_tx_timeout = usbnet_tx_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) .ndo_change_mtu = usbnet_change_mtu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) .ndo_get_stats64 = usbnet_get_stats64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) .ndo_validate_addr = eth_validate_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) .ndo_do_ioctl = dm9601_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) .ndo_set_rx_mode = dm9601_set_multicast,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) .ndo_set_mac_address = dm9601_set_mac_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) u8 mac[ETH_ALEN], id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) ret = usbnet_get_endpoints(dev, intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) dev->net->netdev_ops = &dm9601_netdev_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) dev->net->ethtool_ops = &dm9601_ethtool_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) dev->net->hard_header_len += DM_TX_OVERHEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) /* dm9620/21a require room for 4 byte padding, even in dm9601
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) * mode, so we need +1 to be able to receive full size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) * ethernet frames.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) dev->rx_urb_size = dev->net->mtu + ETH_HLEN + DM_RX_OVERHEAD + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) dev->mii.dev = dev->net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) dev->mii.mdio_read = dm9601_mdio_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) dev->mii.mdio_write = dm9601_mdio_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) dev->mii.phy_id_mask = 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) dev->mii.reg_num_mask = 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) /* reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) dm_write_reg(dev, DM_NET_CTRL, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) udelay(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) /* read MAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (dm_read(dev, DM_PHY_ADDR, ETH_ALEN, mac) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) printk(KERN_ERR "Error reading MAC address\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) goto out;
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) * Overwrite the auto-generated address only with good ones.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) if (is_valid_ether_addr(mac))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) memcpy(dev->net->dev_addr, mac, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) "dm9601: No valid MAC address in EEPROM, using %pM\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) dev->net->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) __dm9601_set_mac_address(dev);
^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 (dm_read_reg(dev, DM_CHIP_ID, &id) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) netdev_err(dev->net, "Error reading chip ID\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) /* put dm9620 devices in dm9601 mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) if (id == ID_DM9620) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) u8 mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) if (dm_read_reg(dev, DM_MODE_CTRL, &mode) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) netdev_err(dev->net, "Error reading MODE_CTRL\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) dm_write_reg(dev, DM_MODE_CTRL, mode & 0x7f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) /* power up phy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) dm_write_reg(dev, DM_GPR_CTRL, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) dm_write_reg(dev, DM_GPR_DATA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) /* receive broadcast packets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) dm9601_set_multicast(dev->net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) dm9601_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) dm9601_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) mii_nway_restart(&dev->mii);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) static int dm9601_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) u8 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) /* format:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) b1: rx status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) b2: packet length (incl crc) low
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) b3: packet length (incl crc) high
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) b4..n-4: packet data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) bn-3..bn: ethernet crc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) if (unlikely(skb->len < DM_RX_OVERHEAD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) dev_err(&dev->udev->dev, "unexpected tiny rx frame\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) status = skb->data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) len = (skb->data[1] | (skb->data[2] << 8)) - 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (unlikely(status & 0xbf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) if (status & 0x01) dev->net->stats.rx_fifo_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (status & 0x02) dev->net->stats.rx_crc_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) if (status & 0x04) dev->net->stats.rx_frame_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (status & 0x20) dev->net->stats.rx_missed_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) if (status & 0x90) dev->net->stats.rx_length_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) skb_pull(skb, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) skb_trim(skb, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) static struct sk_buff *dm9601_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) gfp_t flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) int len, pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) /* format:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) b1: packet length low
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) b2: packet length high
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) b3..n: packet data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) len = skb->len + DM_TX_OVERHEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) /* workaround for dm962x errata with tx fifo getting out of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) * sync if a USB bulk transfer retry happens right after a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) * packet with odd / maxpacket length by adding up to 3 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) * padding.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) while ((len & 1) || !(len % dev->maxpacket))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) len++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) len -= DM_TX_OVERHEAD; /* hw header doesn't count as part of length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) pad = len - skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (skb_headroom(skb) < DM_TX_OVERHEAD || skb_tailroom(skb) < pad) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) struct sk_buff *skb2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) skb2 = skb_copy_expand(skb, DM_TX_OVERHEAD, pad, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) dev_kfree_skb_any(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) skb = skb2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) __skb_push(skb, DM_TX_OVERHEAD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) if (pad) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) memset(skb->data + skb->len, 0, pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) __skb_put(skb, pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) skb->data[0] = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) skb->data[1] = len >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) static void dm9601_status(struct usbnet *dev, struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) int link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) u8 *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) /* format:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) b0: net status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) b1: tx status 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) b2: tx status 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) b3: rx status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) b4: rx overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) b5: rx count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) b6: tx count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) b7: gpr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) if (urb->actual_length < 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) buf = urb->transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) link = !!(buf[0] & 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) if (netif_carrier_ok(dev->net) != link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) usbnet_link_change(dev, link, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) netdev_dbg(dev->net, "Link Status is: %d\n", link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) }
^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) static int dm9601_link_reset(struct usbnet *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) mii_check_media(&dev->mii, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) mii_ethtool_gset(&dev->mii, &ecmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) netdev_dbg(dev->net, "link_reset() speed: %u duplex: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) ethtool_cmd_speed(&ecmd), ecmd.duplex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) return 0;
^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) static const struct driver_info dm9601_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) .description = "Davicom DM96xx USB 10/100 Ethernet",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) .flags = FLAG_ETHER | FLAG_LINK_INTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) .bind = dm9601_bind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) .rx_fixup = dm9601_rx_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) .tx_fixup = dm9601_tx_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) .status = dm9601_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) .link_reset = dm9601_link_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) .reset = dm9601_link_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) static const struct usb_device_id products[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) USB_DEVICE(0x07aa, 0x9601), /* Corega FEther USB-TXC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) .driver_info = (unsigned long)&dm9601_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) USB_DEVICE(0x0a46, 0x9601), /* Davicom USB-100 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) .driver_info = (unsigned long)&dm9601_info,
^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) USB_DEVICE(0x0a46, 0x6688), /* ZT6688 USB NIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) .driver_info = (unsigned long)&dm9601_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) USB_DEVICE(0x0a46, 0x0268), /* ShanTou ST268 USB NIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) .driver_info = (unsigned long)&dm9601_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) USB_DEVICE(0x0a46, 0x8515), /* ADMtek ADM8515 USB NIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) .driver_info = (unsigned long)&dm9601_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) USB_DEVICE(0x0a47, 0x9601), /* Hirose USB-100 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) .driver_info = (unsigned long)&dm9601_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) USB_DEVICE(0x0fe6, 0x8101), /* DM9601 USB to Fast Ethernet Adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) .driver_info = (unsigned long)&dm9601_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) USB_DEVICE(0x0fe6, 0x9700), /* DM9601 USB to Fast Ethernet Adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) .driver_info = (unsigned long)&dm9601_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) USB_DEVICE(0x0a46, 0x9000), /* DM9000E */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) .driver_info = (unsigned long)&dm9601_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) USB_DEVICE(0x0a46, 0x9620), /* DM9620 USB to Fast Ethernet Adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) .driver_info = (unsigned long)&dm9601_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) USB_DEVICE(0x0a46, 0x9621), /* DM9621A USB to Fast Ethernet Adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) .driver_info = (unsigned long)&dm9601_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) USB_DEVICE(0x0a46, 0x9622), /* DM9622 USB to Fast Ethernet Adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) .driver_info = (unsigned long)&dm9601_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) USB_DEVICE(0x0a46, 0x0269), /* DM962OA USB to Fast Ethernet Adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) .driver_info = (unsigned long)&dm9601_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) USB_DEVICE(0x0a46, 0x1269), /* DM9621A USB to Fast Ethernet Adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) .driver_info = (unsigned long)&dm9601_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) USB_DEVICE(0x0586, 0x3427), /* ZyXEL Keenetic Plus DSL xDSL modem */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) .driver_info = (unsigned long)&dm9601_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) {}, // END
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) MODULE_DEVICE_TABLE(usb, products);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) static struct usb_driver dm9601_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) .name = "dm9601",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) .id_table = products,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) .probe = usbnet_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) .disconnect = usbnet_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) .suspend = usbnet_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) .resume = usbnet_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) .disable_hub_initiated_lpm = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) module_usb_driver(dm9601_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) MODULE_AUTHOR("Peter Korsgaard <jacmet@sunsite.dk>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) MODULE_DESCRIPTION("Davicom DM96xx USB 10/100 ethernet devices");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) MODULE_LICENSE("GPL");