1 /* 2 * CoreChip-sz SR9700 one chip USB 1.1 Ethernet Devices 3 * 4 * Author : Liu Junliang <liujunliang_ljl@163.com> 5 * 6 * Based on dm9601.c 7 * 8 * This file is licensed under the terms of the GNU General Public License 9 * version 2. This program is licensed "as is" without any warranty of any 10 * kind, whether express or implied. 11 */ 12 13 #include <linux/module.h> 14 #include <linux/sched.h> 15 #include <linux/stddef.h> 16 #include <linux/netdevice.h> 17 #include <linux/etherdevice.h> 18 #include <linux/ethtool.h> 19 #include <linux/usb.h> 20 #include <linux/usb/usbnet.h> 21 22 #include "sr9700.h" 23 24 static int sr_read(struct usbnet *dev, u8 reg, u16 length, void *data) 25 { 26 int err; 27 28 err = usbnet_read_cmd(dev, SR_RD_REGS, SR_REQ_RD_REG, 0, reg, data, 29 length); 30 if ((err != length) && (err >= 0)) 31 err = -EINVAL; 32 return err; 33 } 34 35 static int sr_write(struct usbnet *dev, u8 reg, u16 length, void *data) 36 { 37 int err; 38 39 err = usbnet_write_cmd(dev, SR_WR_MULTIPLE_REGS, SR_REQ_WR_REG, 0, reg, data, 40 length); 41 if ((err >= 0) && (err < length)) 42 err = -EINVAL; 43 return err; 44 } 45 46 static int sr_read_reg(struct usbnet *dev, u8 reg, u8 *value) 47 { 48 return sr_read(dev, reg, 1, value); 49 } 50 51 static int sr_write_reg(struct usbnet *dev, u8 reg, u8 value) 52 { 53 return usbnet_write_cmd(dev, SR_WR_SINGLE_REG, SR_REQ_WR_REG, 54 value, reg, NULL, 0); 55 } 56 57 static void sr_write_async(struct usbnet *dev, u8 reg, u16 length, 58 const void *data) 59 { 60 usbnet_write_cmd_async(dev, SR_WR_MULTIPLE_REGS, SR_REQ_WR_REG, 61 0, reg, data, length); 62 } 63 64 static void sr_write_reg_async(struct usbnet *dev, u8 reg, u8 value) 65 { 66 usbnet_write_cmd_async(dev, SR_WR_SINGLE_REG, SR_REQ_WR_REG, 67 value, reg, NULL, 0); 68 } 69 70 static int wait_eeprom_ready(struct usbnet *dev) 71 { 72 int i; 73 74 for (i = 0; i < SR_EEPROM_TIMEOUT; i++) { 75 u8 tmp = 0; 76 int ret; 77 78 udelay(1); 79 ret = sr_read_reg(dev, SR_EPCR, &tmp); 80 if (ret < 0) 81 return ret; 82 83 /* ready */ 84 if (!(tmp & EPCR_ERRE)) 85 return 0; 86 } 87 88 netdev_err(dev->net, "eeprom write timed out!\n"); 89 90 return -EIO; 91 } 92 93 static int sr_read_eeprom_word(struct usbnet *dev, u8 reg, __le16 *value) 94 { 95 int ret; 96 97 mutex_lock(&dev->phy_mutex); 98 99 sr_write_reg(dev, SR_EPAR, reg); 100 sr_write_reg(dev, SR_EPCR, EPCR_ERPRR); 101 102 ret = wait_eeprom_ready(dev); 103 if (ret < 0) 104 goto out_unlock; 105 106 sr_write_reg(dev, SR_EPCR, 0x0); 107 ret = sr_read(dev, SR_EPDR, 2, value); 108 109 netdev_dbg(dev->net, "read eeprom 0x%02x returned 0x%04x, %d\n", 110 reg, *value, ret); 111 112 out_unlock: 113 mutex_unlock(&dev->phy_mutex); 114 return ret; 115 } 116 117 static int __maybe_unused sr_write_eeprom_word(struct usbnet *dev, u8 reg, 118 __le16 value) 119 { 120 int ret; 121 122 mutex_lock(&dev->phy_mutex); 123 124 ret = sr_write(dev, SR_EPDR, 2, &value); 125 if (ret < 0) 126 goto out_unlock; 127 128 sr_write_reg(dev, SR_EPAR, reg); 129 sr_write_reg(dev, SR_EPCR, EPCR_WEP | EPCR_ERPRW); 130 131 ret = wait_eeprom_ready(dev); 132 if (ret < 0) 133 goto out_unlock; 134 135 sr_write_reg(dev, SR_EPCR, 0x0); 136 137 out_unlock: 138 mutex_unlock(&dev->phy_mutex); 139 return ret; 140 } 141 142 static int sr9700_get_eeprom_len(struct net_device *netdev) 143 { 144 return SR_EEPROM_LEN; 145 } 146 147 static int sr9700_get_eeprom(struct net_device *netdev, 148 struct ethtool_eeprom *eeprom, u8 *data) 149 { 150 struct usbnet *dev = netdev_priv(netdev); 151 __le16 *buf = (__le16 *)data; 152 int ret = 0; 153 int i; 154 155 /* access is 16bit */ 156 if ((eeprom->offset & 0x01) || (eeprom->len & 0x01)) 157 return -EINVAL; 158 159 for (i = 0; i < eeprom->len / 2; i++) { 160 ret = sr_read_eeprom_word(dev, eeprom->offset / 2 + i, buf + i); 161 if (ret < 0) 162 break; 163 } 164 165 return ret; 166 } 167 168 static void sr9700_handle_link_change(struct net_device *netdev, bool link) 169 { 170 if (netif_carrier_ok(netdev) != link) { 171 if (link) { 172 netif_carrier_on(netdev); 173 netdev_info(netdev, "link up, 10Mbps, half-duplex\n"); 174 } else { 175 netif_carrier_off(netdev); 176 netdev_info(netdev, "link down\n"); 177 } 178 } 179 } 180 181 static u32 sr9700_get_link(struct net_device *netdev) 182 { 183 struct usbnet *dev = netdev_priv(netdev); 184 u8 value = 0; 185 u32 link = 0; 186 187 sr_read_reg(dev, SR_NSR, &value); 188 link = !!(value & NSR_LINKST); 189 190 sr9700_handle_link_change(netdev, link); 191 192 return link; 193 } 194 195 /* 196 * The device supports only 10Mbps half-duplex operation. It implements the 197 * DM9601 speed/duplex status registers, but as the values are always the same, 198 * using them would add unnecessary complexity. 199 */ 200 static int sr9700_get_link_ksettings(struct net_device *dev, 201 struct ethtool_link_ksettings *cmd) 202 { 203 ethtool_link_ksettings_zero_link_mode(cmd, supported); 204 ethtool_link_ksettings_add_link_mode(cmd, supported, 10baseT_Half); 205 ethtool_link_ksettings_add_link_mode(cmd, supported, TP); 206 207 ethtool_link_ksettings_zero_link_mode(cmd, advertising); 208 ethtool_link_ksettings_add_link_mode(cmd, advertising, 10baseT_Half); 209 ethtool_link_ksettings_add_link_mode(cmd, advertising, TP); 210 211 cmd->base.speed = SPEED_10; 212 cmd->base.duplex = DUPLEX_HALF; 213 cmd->base.port = PORT_TP; 214 cmd->base.phy_address = 0; 215 cmd->base.autoneg = AUTONEG_DISABLE; 216 217 return 0; 218 } 219 220 static const struct ethtool_ops sr9700_ethtool_ops = { 221 .get_drvinfo = usbnet_get_drvinfo, 222 .get_link = sr9700_get_link, 223 .get_msglevel = usbnet_get_msglevel, 224 .set_msglevel = usbnet_set_msglevel, 225 .get_eeprom_len = sr9700_get_eeprom_len, 226 .get_eeprom = sr9700_get_eeprom, 227 .get_link_ksettings = sr9700_get_link_ksettings, 228 }; 229 230 static void sr9700_set_multicast(struct net_device *netdev) 231 { 232 struct usbnet *dev = netdev_priv(netdev); 233 /* rx_ctl setting : enable, disable_long, disable_crc */ 234 u8 rx_ctl = RCR_RXEN | RCR_DIS_CRC | RCR_DIS_LONG; 235 236 if (netdev->flags & IFF_PROMISC) 237 rx_ctl |= RCR_PRMSC; 238 else if (netdev->flags & IFF_ALLMULTI || !netdev_mc_empty(netdev)) 239 /* The chip has no multicast filter */ 240 rx_ctl |= RCR_ALL; 241 242 sr_write_reg_async(dev, SR_RCR, rx_ctl); 243 } 244 245 static int sr9700_set_mac_address(struct net_device *netdev, void *p) 246 { 247 struct usbnet *dev = netdev_priv(netdev); 248 struct sockaddr *addr = p; 249 250 if (!is_valid_ether_addr(addr->sa_data)) { 251 netdev_err(netdev, "not setting invalid mac address %pM\n", 252 addr->sa_data); 253 return -EINVAL; 254 } 255 256 eth_hw_addr_set(netdev, addr->sa_data); 257 sr_write_async(dev, SR_PAR, ETH_ALEN, netdev->dev_addr); 258 259 return 0; 260 } 261 262 static const struct net_device_ops sr9700_netdev_ops = { 263 .ndo_open = usbnet_open, 264 .ndo_stop = usbnet_stop, 265 .ndo_start_xmit = usbnet_start_xmit, 266 .ndo_tx_timeout = usbnet_tx_timeout, 267 .ndo_change_mtu = usbnet_change_mtu, 268 .ndo_get_stats64 = dev_get_tstats64, 269 .ndo_validate_addr = eth_validate_addr, 270 .ndo_set_rx_mode = sr9700_set_multicast, 271 .ndo_set_mac_address = sr9700_set_mac_address, 272 }; 273 274 static int sr9700_bind(struct usbnet *dev, struct usb_interface *intf) 275 { 276 struct net_device *netdev; 277 u8 addr[ETH_ALEN]; 278 int ret; 279 280 ret = usbnet_get_endpoints(dev, intf); 281 if (ret) 282 goto out; 283 284 netdev = dev->net; 285 286 netdev->netdev_ops = &sr9700_netdev_ops; 287 netdev->ethtool_ops = &sr9700_ethtool_ops; 288 netdev->hard_header_len += SR_TX_OVERHEAD; 289 dev->hard_mtu = netdev->mtu + netdev->hard_header_len; 290 /* bulkin buffer is preferably not less than 3K */ 291 dev->rx_urb_size = 3072; 292 293 sr_write_reg(dev, SR_NCR, NCR_RST); 294 udelay(20); 295 296 /* read MAC 297 * After Chip Power on, the Chip will reload the MAC from 298 * EEPROM automatically to PAR. In case there is no EEPROM externally, 299 * a default MAC address is stored in PAR for making chip work properly. 300 */ 301 if (sr_read(dev, SR_PAR, ETH_ALEN, addr) < 0) { 302 netdev_err(netdev, "Error reading MAC address\n"); 303 ret = -ENODEV; 304 goto out; 305 } 306 eth_hw_addr_set(netdev, addr); 307 308 /* power up and reset phy */ 309 sr_write_reg(dev, SR_PRR, PRR_PHY_RST); 310 /* at least 10ms, here 20ms for safe */ 311 msleep(20); 312 sr_write_reg(dev, SR_PRR, 0); 313 /* at least 1ms, here 2ms for reading right register */ 314 udelay(2 * 1000); 315 316 /* receive broadcast packets */ 317 sr9700_set_multicast(netdev); 318 319 out: 320 return ret; 321 } 322 323 static int sr9700_rx_fixup(struct usbnet *dev, struct sk_buff *skb) 324 { 325 struct sk_buff *sr_skb; 326 int len; 327 328 /* skb content (packets) format : 329 * p1 p2 p3 ...... pn 330 * / \ 331 * / \ 332 * / \ 333 * / \ 334 * p1b1 p1b2 p1b3 p1b4 ...... p1b(n-4) p1b(n-3)...p1bn 335 * 336 * p1 : packet 1 337 * p1b1 : packet 1 byte 1 338 * 339 * b1: rx status 340 * b2: packet length (incl crc) low 341 * b3: packet length (incl crc) high 342 * b4..n-4: packet data 343 * bn-3..bn: ethernet packet crc 344 */ 345 if (unlikely(skb->len < SR_RX_OVERHEAD)) { 346 netdev_err(dev->net, "unexpected tiny rx frame\n"); 347 return 0; 348 } 349 350 /* one skb may contains multiple packets */ 351 while (skb->len > SR_RX_OVERHEAD) { 352 if (skb->data[0] != RSR_MF) 353 return 0; 354 355 /* ignore the CRC length */ 356 len = (skb->data[1] | (skb->data[2] << 8)) - 4; 357 358 if (len > ETH_FRAME_LEN || len > skb->len || len < 0) 359 return 0; 360 361 /* the last packet of current skb */ 362 if (skb->len == (len + SR_RX_OVERHEAD)) { 363 skb_pull(skb, 3); 364 skb->len = len; 365 skb_set_tail_pointer(skb, len); 366 return 2; 367 } 368 369 sr_skb = netdev_alloc_skb_ip_align(dev->net, len); 370 if (!sr_skb) 371 return 0; 372 373 skb_put(sr_skb, len); 374 memcpy(sr_skb->data, skb->data + 3, len); 375 usbnet_skb_return(dev, sr_skb); 376 377 skb_pull(skb, len + SR_RX_OVERHEAD); 378 } 379 380 return 0; 381 } 382 383 static struct sk_buff *sr9700_tx_fixup(struct usbnet *dev, struct sk_buff *skb, 384 gfp_t flags) 385 { 386 int len; 387 388 /* SR9700 can only send out one ethernet packet at once. 389 * 390 * b1 b2 b3 b4 ...... b(n-4) b(n-3)...bn 391 * 392 * b1: rx status 393 * b2: packet length (incl crc) low 394 * b3: packet length (incl crc) high 395 * b4..n-4: packet data 396 * bn-3..bn: ethernet packet crc 397 */ 398 399 len = skb->len; 400 401 if (skb_cow_head(skb, SR_TX_OVERHEAD)) { 402 dev_kfree_skb_any(skb); 403 return NULL; 404 } 405 406 __skb_push(skb, SR_TX_OVERHEAD); 407 408 /* usbnet adds padding if length is a multiple of packet size 409 * if so, adjust length value in header 410 */ 411 if ((skb->len % dev->maxpacket) == 0) 412 len++; 413 414 skb->data[0] = len; 415 skb->data[1] = len >> 8; 416 417 return skb; 418 } 419 420 static void sr9700_status(struct usbnet *dev, struct urb *urb) 421 { 422 bool link; 423 u8 *buf; 424 425 /* format: 426 b1: net status 427 b2: tx status 1 428 b3: tx status 2 429 b4: rx status 430 b5: rx overflow 431 b6: rx count 432 b7: tx count 433 b8: gpr 434 */ 435 436 if (urb->actual_length < 8) 437 return; 438 439 buf = urb->transfer_buffer; 440 441 link = !!(buf[0] & NSR_LINKST); 442 sr9700_handle_link_change(dev->net, link); 443 } 444 445 static const struct driver_info sr9700_driver_info = { 446 .description = "CoreChip SR9700 USB Ethernet", 447 .flags = FLAG_ETHER, 448 .bind = sr9700_bind, 449 .rx_fixup = sr9700_rx_fixup, 450 .tx_fixup = sr9700_tx_fixup, 451 .status = sr9700_status, 452 }; 453 454 static const struct usb_device_id products[] = { 455 { 456 USB_DEVICE(0x0fe6, 0x9700), /* SR9700 device */ 457 .driver_info = (unsigned long)&sr9700_driver_info, 458 }, 459 { 460 /* SR9700 with virtual driver CD-ROM - interface 0 is the CD-ROM device */ 461 USB_DEVICE_INTERFACE_NUMBER(0x0fe6, 0x9702, 1), 462 .driver_info = (unsigned long)&sr9700_driver_info, 463 }, 464 {}, /* END */ 465 }; 466 467 MODULE_DEVICE_TABLE(usb, products); 468 469 static struct usb_driver sr9700_usb_driver = { 470 .name = "sr9700", 471 .id_table = products, 472 .probe = usbnet_probe, 473 .disconnect = usbnet_disconnect, 474 .suspend = usbnet_suspend, 475 .resume = usbnet_resume, 476 .disable_hub_initiated_lpm = 1, 477 }; 478 479 module_usb_driver(sr9700_usb_driver); 480 481 MODULE_AUTHOR("liujl <liujunliang_ljl@163.com>"); 482 MODULE_DESCRIPTION("SR9700 one chip USB 1.1 USB to Ethernet device from http://www.corechip-sz.com/"); 483 MODULE_LICENSE("GPL"); 484