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 .get_settings = usbnet_get_settings, 253 .set_settings = usbnet_set_settings, 254 .nway_reset = usbnet_nway_reset, 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 memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); 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_validate_addr = eth_validate_addr, 312 .ndo_do_ioctl = sr9700_ioctl, 313 .ndo_set_rx_mode = sr9700_set_multicast, 314 .ndo_set_mac_address = sr9700_set_mac_address, 315 }; 316 317 static int sr9700_bind(struct usbnet *dev, struct usb_interface *intf) 318 { 319 struct net_device *netdev; 320 struct mii_if_info *mii; 321 int ret; 322 323 ret = usbnet_get_endpoints(dev, intf); 324 if (ret) 325 goto out; 326 327 netdev = dev->net; 328 329 netdev->netdev_ops = &sr9700_netdev_ops; 330 netdev->ethtool_ops = &sr9700_ethtool_ops; 331 netdev->hard_header_len += SR_TX_OVERHEAD; 332 dev->hard_mtu = netdev->mtu + netdev->hard_header_len; 333 /* bulkin buffer is preferably not less than 3K */ 334 dev->rx_urb_size = 3072; 335 336 mii = &dev->mii; 337 mii->dev = netdev; 338 mii->mdio_read = sr_mdio_read; 339 mii->mdio_write = sr_mdio_write; 340 mii->phy_id_mask = 0x1f; 341 mii->reg_num_mask = 0x1f; 342 343 sr_write_reg(dev, SR_NCR, NCR_RST); 344 udelay(20); 345 346 /* read MAC 347 * After Chip Power on, the Chip will reload the MAC from 348 * EEPROM automatically to PAR. In case there is no EEPROM externally, 349 * a default MAC address is stored in PAR for making chip work properly. 350 */ 351 if (sr_read(dev, SR_PAR, ETH_ALEN, netdev->dev_addr) < 0) { 352 netdev_err(netdev, "Error reading MAC address\n"); 353 ret = -ENODEV; 354 goto out; 355 } 356 357 /* power up and reset phy */ 358 sr_write_reg(dev, SR_PRR, PRR_PHY_RST); 359 /* at least 10ms, here 20ms for safe */ 360 mdelay(20); 361 sr_write_reg(dev, SR_PRR, 0); 362 /* at least 1ms, here 2ms for reading right register */ 363 udelay(2 * 1000); 364 365 /* receive broadcast packets */ 366 sr9700_set_multicast(netdev); 367 368 sr_mdio_write(netdev, mii->phy_id, MII_BMCR, BMCR_RESET); 369 sr_mdio_write(netdev, mii->phy_id, MII_ADVERTISE, ADVERTISE_ALL | 370 ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP); 371 mii_nway_restart(mii); 372 373 out: 374 return ret; 375 } 376 377 static int sr9700_rx_fixup(struct usbnet *dev, struct sk_buff *skb) 378 { 379 struct sk_buff *sr_skb; 380 int len; 381 382 /* skb content (packets) format : 383 * p0 p1 p2 ...... pm 384 * / \ 385 * / \ 386 * / \ 387 * / \ 388 * p0b0 p0b1 p0b2 p0b3 ...... p0b(n-4) p0b(n-3)...p0bn 389 * 390 * p0 : packet 0 391 * p0b0 : packet 0 byte 0 392 * 393 * b0: rx status 394 * b1: packet length (incl crc) low 395 * b2: packet length (incl crc) high 396 * b3..n-4: packet data 397 * bn-3..bn: ethernet packet crc 398 */ 399 if (unlikely(skb->len < SR_RX_OVERHEAD)) { 400 netdev_err(dev->net, "unexpected tiny rx frame\n"); 401 return 0; 402 } 403 404 /* one skb may contains multiple packets */ 405 while (skb->len > SR_RX_OVERHEAD) { 406 if (skb->data[0] != 0x40) 407 return 0; 408 409 /* ignore the CRC length */ 410 len = (skb->data[1] | (skb->data[2] << 8)) - 4; 411 412 if (len > ETH_FRAME_LEN) 413 return 0; 414 415 /* the last packet of current skb */ 416 if (skb->len == (len + SR_RX_OVERHEAD)) { 417 skb_pull(skb, 3); 418 skb->len = len; 419 skb_set_tail_pointer(skb, len); 420 skb->truesize = len + sizeof(struct sk_buff); 421 return 2; 422 } 423 424 /* skb_clone is used for address align */ 425 sr_skb = skb_clone(skb, GFP_ATOMIC); 426 if (!sr_skb) 427 return 0; 428 429 sr_skb->len = len; 430 sr_skb->data = skb->data + 3; 431 skb_set_tail_pointer(sr_skb, len); 432 sr_skb->truesize = len + sizeof(struct sk_buff); 433 usbnet_skb_return(dev, sr_skb); 434 435 skb_pull(skb, len + SR_RX_OVERHEAD); 436 }; 437 438 return 0; 439 } 440 441 static struct sk_buff *sr9700_tx_fixup(struct usbnet *dev, struct sk_buff *skb, 442 gfp_t flags) 443 { 444 int len; 445 446 /* SR9700 can only send out one ethernet packet at once. 447 * 448 * b0 b1 b2 b3 ...... b(n-4) b(n-3)...bn 449 * 450 * b0: rx status 451 * b1: packet length (incl crc) low 452 * b2: packet length (incl crc) high 453 * b3..n-4: packet data 454 * bn-3..bn: ethernet packet crc 455 */ 456 457 len = skb->len; 458 459 if (skb_headroom(skb) < SR_TX_OVERHEAD) { 460 struct sk_buff *skb2; 461 462 skb2 = skb_copy_expand(skb, SR_TX_OVERHEAD, 0, flags); 463 dev_kfree_skb_any(skb); 464 skb = skb2; 465 if (!skb) 466 return NULL; 467 } 468 469 __skb_push(skb, SR_TX_OVERHEAD); 470 471 /* usbnet adds padding if length is a multiple of packet size 472 * if so, adjust length value in header 473 */ 474 if ((skb->len % dev->maxpacket) == 0) 475 len++; 476 477 skb->data[0] = len; 478 skb->data[1] = len >> 8; 479 480 return skb; 481 } 482 483 static void sr9700_status(struct usbnet *dev, struct urb *urb) 484 { 485 int link; 486 u8 *buf; 487 488 /* format: 489 b0: net status 490 b1: tx status 1 491 b2: tx status 2 492 b3: rx status 493 b4: rx overflow 494 b5: rx count 495 b6: tx count 496 b7: gpr 497 */ 498 499 if (urb->actual_length < 8) 500 return; 501 502 buf = urb->transfer_buffer; 503 504 link = !!(buf[0] & 0x40); 505 if (netif_carrier_ok(dev->net) != link) { 506 usbnet_link_change(dev, link, 1); 507 netdev_dbg(dev->net, "Link Status is: %d\n", link); 508 } 509 } 510 511 static int sr9700_link_reset(struct usbnet *dev) 512 { 513 struct ethtool_cmd ecmd; 514 515 mii_check_media(&dev->mii, 1, 1); 516 mii_ethtool_gset(&dev->mii, &ecmd); 517 518 netdev_dbg(dev->net, "link_reset() speed: %d duplex: %d\n", 519 ecmd.speed, ecmd.duplex); 520 521 return 0; 522 } 523 524 static const struct driver_info sr9700_driver_info = { 525 .description = "CoreChip SR9700 USB Ethernet", 526 .flags = FLAG_ETHER, 527 .bind = sr9700_bind, 528 .rx_fixup = sr9700_rx_fixup, 529 .tx_fixup = sr9700_tx_fixup, 530 .status = sr9700_status, 531 .link_reset = sr9700_link_reset, 532 .reset = sr9700_link_reset, 533 }; 534 535 static const struct usb_device_id products[] = { 536 { 537 USB_DEVICE(0x0fe6, 0x9700), /* SR9700 device */ 538 .driver_info = (unsigned long)&sr9700_driver_info, 539 }, 540 {}, /* END */ 541 }; 542 543 MODULE_DEVICE_TABLE(usb, products); 544 545 static struct usb_driver sr9700_usb_driver = { 546 .name = "sr9700", 547 .id_table = products, 548 .probe = usbnet_probe, 549 .disconnect = usbnet_disconnect, 550 .suspend = usbnet_suspend, 551 .resume = usbnet_resume, 552 .disable_hub_initiated_lpm = 1, 553 }; 554 555 module_usb_driver(sr9700_usb_driver); 556 557 MODULE_AUTHOR("liujl <liujunliang_ljl@163.com>"); 558 MODULE_DESCRIPTION("SR9700 one chip USB 1.1 USB to Ethernet device from http://www.corechip-sz.com/"); 559 MODULE_LICENSE("GPL"); 560