root/drivers/net/usb/sr9700.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sr_read
  2. sr_write
  3. sr_read_reg
  4. sr_write_reg
  5. sr_write_async
  6. sr_write_reg_async
  7. wait_phy_eeprom_ready
  8. sr_share_read_word
  9. sr_share_write_word
  10. sr_read_eeprom_word
  11. sr9700_get_eeprom_len
  12. sr9700_get_eeprom
  13. sr_mdio_read
  14. sr_mdio_write
  15. sr9700_get_link
  16. sr9700_ioctl
  17. sr9700_set_multicast
  18. sr9700_set_mac_address
  19. sr9700_bind
  20. sr9700_rx_fixup
  21. sr9700_tx_fixup
  22. sr9700_status
  23. sr9700_link_reset

   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,
 254         .set_link_ksettings     = usbnet_set_link_ksettings,
 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_get_stats64        = usbnet_get_stats64,
 312         .ndo_validate_addr      = eth_validate_addr,
 313         .ndo_do_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");

/* [<][>][^][v][top][bottom][index][help] */