^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * CoreChip-sz SR9700 one chip USB 1.1 Ethernet Devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Author : Liu Junliang <liujunliang_ljl@163.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Based on dm9601.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * This file is licensed under the terms of the GNU General Public License
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * version 2. This program is licensed "as is" without any warranty of any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * kind, whether express or implied.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) */
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "sr9700.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) static int sr_read(struct usbnet *dev, u8 reg, u16 length, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) err = usbnet_read_cmd(dev, SR_RD_REGS, SR_REQ_RD_REG, 0, reg, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) if ((err != length) && (err >= 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static int sr_write(struct usbnet *dev, u8 reg, u16 length, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) err = usbnet_write_cmd(dev, SR_WR_REGS, SR_REQ_WR_REG, 0, reg, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) if ((err >= 0) && (err < length))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) static int sr_read_reg(struct usbnet *dev, u8 reg, u8 *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) return sr_read(dev, reg, 1, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static int sr_write_reg(struct usbnet *dev, u8 reg, u8 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) return usbnet_write_cmd(dev, SR_WR_REGS, SR_REQ_WR_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) value, reg, NULL, 0);
^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) static void sr_write_async(struct usbnet *dev, u8 reg, u16 length, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) usbnet_write_cmd_async(dev, SR_WR_REGS, SR_REQ_WR_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) 0, reg, data, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static void sr_write_reg_async(struct usbnet *dev, u8 reg, u8 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) usbnet_write_cmd_async(dev, SR_WR_REGS, SR_REQ_WR_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) value, reg, NULL, 0);
^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) static int wait_phy_eeprom_ready(struct usbnet *dev, int phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) for (i = 0; i < SR_SHARE_TIMEOUT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) u8 tmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) ret = sr_read_reg(dev, SR_EPCR, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /* ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (!(tmp & EPCR_ERRE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) return 0;
^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) netdev_err(dev->net, "%s write timed out!\n", phy ? "phy" : "eeprom");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) static int sr_share_read_word(struct usbnet *dev, int phy, u8 reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) __le16 *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) mutex_lock(&dev->phy_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) sr_write_reg(dev, SR_EPAR, phy ? (reg | EPAR_PHY_ADR) : reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) sr_write_reg(dev, SR_EPCR, phy ? (EPCR_EPOS | EPCR_ERPRR) : EPCR_ERPRR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) ret = wait_phy_eeprom_ready(dev, phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) sr_write_reg(dev, SR_EPCR, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) ret = sr_read(dev, SR_EPDR, 2, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) netdev_dbg(dev->net, "read shared %d 0x%02x returned 0x%04x, %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) phy, reg, *value, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) mutex_unlock(&dev->phy_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static int sr_share_write_word(struct usbnet *dev, int phy, u8 reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) __le16 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) mutex_lock(&dev->phy_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) ret = sr_write(dev, SR_EPDR, 2, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) sr_write_reg(dev, SR_EPAR, phy ? (reg | EPAR_PHY_ADR) : reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) sr_write_reg(dev, SR_EPCR, phy ? (EPCR_WEP | EPCR_EPOS | EPCR_ERPRW) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) (EPCR_WEP | EPCR_ERPRW));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) ret = wait_phy_eeprom_ready(dev, phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) sr_write_reg(dev, SR_EPCR, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) mutex_unlock(&dev->phy_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return ret;
^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) static int sr_read_eeprom_word(struct usbnet *dev, u8 offset, void *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return sr_share_read_word(dev, 0, offset, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) static int sr9700_get_eeprom_len(struct net_device *netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return SR_EEPROM_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) static int sr9700_get_eeprom(struct net_device *netdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) struct ethtool_eeprom *eeprom, u8 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct usbnet *dev = netdev_priv(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) __le16 *buf = (__le16 *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /* access is 16bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if ((eeprom->offset & 0x01) || (eeprom->len & 0x01))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) for (i = 0; i < eeprom->len / 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) ret = sr_read_eeprom_word(dev, eeprom->offset / 2 + i, buf + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) static int sr_mdio_read(struct net_device *netdev, int phy_id, int loc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) struct usbnet *dev = netdev_priv(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) __le16 res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (phy_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) netdev_dbg(netdev, "Only internal phy supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /* Access NSR_LINKST bit for link status instead of MII_BMSR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (loc == MII_BMSR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) u8 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) sr_read_reg(dev, SR_NSR, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (value & NSR_LINKST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) rc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) sr_share_read_word(dev, 1, loc, &res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if (rc == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) res = le16_to_cpu(res) | BMSR_LSTATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) res = le16_to_cpu(res) & ~BMSR_LSTATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) netdev_dbg(netdev, "sr_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) phy_id, loc, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) static void sr_mdio_write(struct net_device *netdev, int phy_id, int loc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) struct usbnet *dev = netdev_priv(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) __le16 res = cpu_to_le16(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (phy_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) netdev_dbg(netdev, "Only internal phy supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) netdev_dbg(netdev, "sr_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) phy_id, loc, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) sr_share_write_word(dev, 1, loc, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) static u32 sr9700_get_link(struct net_device *netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) struct usbnet *dev = netdev_priv(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) u8 value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) /* Get the Link Status directly */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) sr_read_reg(dev, SR_NSR, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (value & NSR_LINKST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) rc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) static int sr9700_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) struct usbnet *dev = netdev_priv(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) static const struct ethtool_ops sr9700_ethtool_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) .get_drvinfo = usbnet_get_drvinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) .get_link = sr9700_get_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) .get_msglevel = usbnet_get_msglevel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) .set_msglevel = usbnet_set_msglevel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) .get_eeprom_len = sr9700_get_eeprom_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) .get_eeprom = sr9700_get_eeprom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) .nway_reset = usbnet_nway_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) .get_link_ksettings = usbnet_get_link_ksettings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) .set_link_ksettings = usbnet_set_link_ksettings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) static void sr9700_set_multicast(struct net_device *netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) struct usbnet *dev = netdev_priv(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) /* We use the 20 byte dev->data for our 8 byte filter buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) * to avoid allocating memory that is tricky to free later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) u8 *hashes = (u8 *)&dev->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) /* rx_ctl setting : enable, disable_long, disable_crc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) u8 rx_ctl = RCR_RXEN | RCR_DIS_CRC | RCR_DIS_LONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) memset(hashes, 0x00, SR_MCAST_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) /* broadcast address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) hashes[SR_MCAST_SIZE - 1] |= SR_MCAST_ADDR_FLAG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) if (netdev->flags & IFF_PROMISC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) rx_ctl |= RCR_PRMSC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) } else if (netdev->flags & IFF_ALLMULTI ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) netdev_mc_count(netdev) > SR_MCAST_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) rx_ctl |= RCR_RUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) } else if (!netdev_mc_empty(netdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) struct netdev_hw_addr *ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) netdev_for_each_mc_addr(ha, netdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) u32 crc = ether_crc(ETH_ALEN, ha->addr) >> 26;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) hashes[crc >> 3] |= 1 << (crc & 0x7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) sr_write_async(dev, SR_MAR, SR_MCAST_SIZE, hashes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) sr_write_reg_async(dev, SR_RCR, rx_ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) static int sr9700_set_mac_address(struct net_device *netdev, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) struct usbnet *dev = netdev_priv(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) struct sockaddr *addr = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (!is_valid_ether_addr(addr->sa_data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) netdev_err(netdev, "not setting invalid mac address %pM\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) addr->sa_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) sr_write_async(dev, SR_PAR, 6, netdev->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) static const struct net_device_ops sr9700_netdev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) .ndo_open = usbnet_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) .ndo_stop = usbnet_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) .ndo_start_xmit = usbnet_start_xmit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) .ndo_tx_timeout = usbnet_tx_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) .ndo_change_mtu = usbnet_change_mtu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) .ndo_get_stats64 = usbnet_get_stats64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) .ndo_validate_addr = eth_validate_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) .ndo_do_ioctl = sr9700_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) .ndo_set_rx_mode = sr9700_set_multicast,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) .ndo_set_mac_address = sr9700_set_mac_address,
^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 int sr9700_bind(struct usbnet *dev, struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) struct net_device *netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) struct mii_if_info *mii;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) ret = usbnet_get_endpoints(dev, intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) netdev = dev->net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) netdev->netdev_ops = &sr9700_netdev_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) netdev->ethtool_ops = &sr9700_ethtool_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) netdev->hard_header_len += SR_TX_OVERHEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) dev->hard_mtu = netdev->mtu + netdev->hard_header_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) /* bulkin buffer is preferably not less than 3K */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) dev->rx_urb_size = 3072;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) mii = &dev->mii;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) mii->dev = netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) mii->mdio_read = sr_mdio_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) mii->mdio_write = sr_mdio_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) mii->phy_id_mask = 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) mii->reg_num_mask = 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) sr_write_reg(dev, SR_NCR, NCR_RST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) udelay(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) /* read MAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) * After Chip Power on, the Chip will reload the MAC from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) * EEPROM automatically to PAR. In case there is no EEPROM externally,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) * a default MAC address is stored in PAR for making chip work properly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (sr_read(dev, SR_PAR, ETH_ALEN, netdev->dev_addr) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) netdev_err(netdev, "Error reading MAC address\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) /* power up and reset phy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) sr_write_reg(dev, SR_PRR, PRR_PHY_RST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) /* at least 10ms, here 20ms for safe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) msleep(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) sr_write_reg(dev, SR_PRR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) /* at least 1ms, here 2ms for reading right register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) udelay(2 * 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) /* receive broadcast packets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) sr9700_set_multicast(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) sr_mdio_write(netdev, mii->phy_id, MII_BMCR, BMCR_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) sr_mdio_write(netdev, mii->phy_id, MII_ADVERTISE, ADVERTISE_ALL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) mii_nway_restart(mii);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) static int sr9700_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) struct sk_buff *sr_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) /* skb content (packets) format :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) * p0 p1 p2 ...... pm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) * / \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) * / \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) * / \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) * / \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) * p0b0 p0b1 p0b2 p0b3 ...... p0b(n-4) p0b(n-3)...p0bn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) * p0 : packet 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) * p0b0 : packet 0 byte 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) * b0: rx status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) * b1: packet length (incl crc) low
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * b2: packet length (incl crc) high
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) * b3..n-4: packet data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * bn-3..bn: ethernet packet crc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (unlikely(skb->len < SR_RX_OVERHEAD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) netdev_err(dev->net, "unexpected tiny rx frame\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) /* one skb may contains multiple packets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) while (skb->len > SR_RX_OVERHEAD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) if (skb->data[0] != 0x40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) /* ignore the CRC length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) len = (skb->data[1] | (skb->data[2] << 8)) - 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (len > ETH_FRAME_LEN || len > skb->len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) /* the last packet of current skb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (skb->len == (len + SR_RX_OVERHEAD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) skb_pull(skb, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) skb->len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) skb_set_tail_pointer(skb, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) skb->truesize = len + sizeof(struct sk_buff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) return 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) /* skb_clone is used for address align */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) sr_skb = skb_clone(skb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (!sr_skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) sr_skb->len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) sr_skb->data = skb->data + 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) skb_set_tail_pointer(sr_skb, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) sr_skb->truesize = len + sizeof(struct sk_buff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) usbnet_skb_return(dev, sr_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) skb_pull(skb, len + SR_RX_OVERHEAD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) static struct sk_buff *sr9700_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) gfp_t flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) /* SR9700 can only send out one ethernet packet at once.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) * b0 b1 b2 b3 ...... b(n-4) b(n-3)...bn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) * b0: rx status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) * b1: packet length (incl crc) low
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) * b2: packet length (incl crc) high
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) * b3..n-4: packet data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) * bn-3..bn: ethernet packet crc
^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) len = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) if (skb_cow_head(skb, SR_TX_OVERHEAD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) dev_kfree_skb_any(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) __skb_push(skb, SR_TX_OVERHEAD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) /* usbnet adds padding if length is a multiple of packet size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) * if so, adjust length value in header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if ((skb->len % dev->maxpacket) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) len++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) skb->data[0] = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) skb->data[1] = len >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) static void sr9700_status(struct usbnet *dev, struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) int link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) u8 *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) /* format:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) b0: net status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) b1: tx status 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) b2: tx status 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) b3: rx status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) b4: rx overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) b5: rx count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) b6: tx count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) b7: gpr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) if (urb->actual_length < 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) buf = urb->transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) link = !!(buf[0] & 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (netif_carrier_ok(dev->net) != link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) usbnet_link_change(dev, link, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) netdev_dbg(dev->net, "Link Status is: %d\n", link);
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) static int sr9700_link_reset(struct usbnet *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) struct ethtool_cmd ecmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) mii_check_media(&dev->mii, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) mii_ethtool_gset(&dev->mii, &ecmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) netdev_dbg(dev->net, "link_reset() speed: %d duplex: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) ecmd.speed, ecmd.duplex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) return 0;
^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) static const struct driver_info sr9700_driver_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) .description = "CoreChip SR9700 USB Ethernet",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) .flags = FLAG_ETHER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) .bind = sr9700_bind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) .rx_fixup = sr9700_rx_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) .tx_fixup = sr9700_tx_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) .status = sr9700_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) .link_reset = sr9700_link_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) .reset = sr9700_link_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) static const struct usb_device_id products[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) USB_DEVICE(0x0fe6, 0x9700), /* SR9700 device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) .driver_info = (unsigned long)&sr9700_driver_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) {}, /* END */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) MODULE_DEVICE_TABLE(usb, products);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) static struct usb_driver sr9700_usb_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) .name = "sr9700",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) .id_table = products,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) .probe = usbnet_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) .disconnect = usbnet_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) .suspend = usbnet_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) .resume = usbnet_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) .disable_hub_initiated_lpm = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) module_usb_driver(sr9700_usb_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) MODULE_AUTHOR("liujl <liujunliang_ljl@163.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) MODULE_DESCRIPTION("SR9700 one chip USB 1.1 USB to Ethernet device from http://www.corechip-sz.com/");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) MODULE_LICENSE("GPL");