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