Commit c9b37458e95629b1d1171457afdcc1bf1eb7881d

Authored by Liu Junliang
Committed by David S. Miller
1 parent a77dcb8c8f

USB2NET : SR9700 : One chip USB 1.1 USB2NET SR9700Device Driver Support

Signed-off-by: Liu Junliang <liujunliang_ljl@163.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 4 changed files with 742 additions and 0 deletions Side-by-side Diff

drivers/net/usb/Kconfig
... ... @@ -268,6 +268,14 @@
268 268 This option adds support for Davicom DM9601 based USB 1.1
269 269 10/100 Ethernet adapters.
270 270  
  271 +config USB_NET_SR9700
  272 + tristate "CoreChip-sz SR9700 based USB 1.1 10/100 ethernet devices"
  273 + depends on USB_USBNET
  274 + select CRC32
  275 + help
  276 + This option adds support for CoreChip-sz SR9700 based USB 1.1
  277 + 10/100 Ethernet adapters.
  278 +
271 279 config USB_NET_SMSC75XX
272 280 tristate "SMSC LAN75XX based USB 2.0 gigabit ethernet devices"
273 281 depends on USB_USBNET
drivers/net/usb/Makefile
... ... @@ -14,6 +14,7 @@
14 14 obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o r815x.o
15 15 obj-$(CONFIG_USB_NET_CDC_EEM) += cdc_eem.o
16 16 obj-$(CONFIG_USB_NET_DM9601) += dm9601.o
  17 +obj-$(CONFIG_USB_NET_SR9700) += sr9700.o
17 18 obj-$(CONFIG_USB_NET_SMSC75XX) += smsc75xx.o
18 19 obj-$(CONFIG_USB_NET_SMSC95XX) += smsc95xx.o
19 20 obj-$(CONFIG_USB_NET_GL620A) += gl620a.o
drivers/net/usb/sr9700.c
  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/init.h>
  17 +#include <linux/netdevice.h>
  18 +#include <linux/etherdevice.h>
  19 +#include <linux/ethtool.h>
  20 +#include <linux/mii.h>
  21 +#include <linux/usb.h>
  22 +#include <linux/crc32.h>
  23 +#include <linux/usb/usbnet.h>
  24 +
  25 +#include "sr9700.h"
  26 +
  27 +static int sr_read(struct usbnet *dev, u8 reg, u16 length, void *data)
  28 +{
  29 + int err;
  30 +
  31 + err = usbnet_read_cmd(dev, SR_RD_REGS, SR_REQ_RD_REG, 0, reg, data,
  32 + length);
  33 + if ((err != length) && (err >= 0))
  34 + err = -EINVAL;
  35 + return err;
  36 +}
  37 +
  38 +static int sr_write(struct usbnet *dev, u8 reg, u16 length, void *data)
  39 +{
  40 + int err;
  41 +
  42 + err = usbnet_write_cmd(dev, SR_WR_REGS, SR_REQ_WR_REG, 0, reg, data,
  43 + length);
  44 + if ((err >= 0) && (err < length))
  45 + err = -EINVAL;
  46 + return err;
  47 +}
  48 +
  49 +static int sr_read_reg(struct usbnet *dev, u8 reg, u8 *value)
  50 +{
  51 + return sr_read(dev, reg, 1, value);
  52 +}
  53 +
  54 +static int sr_write_reg(struct usbnet *dev, u8 reg, u8 value)
  55 +{
  56 + return usbnet_write_cmd(dev, SR_WR_REGS, SR_REQ_WR_REG,
  57 + value, reg, NULL, 0);
  58 +}
  59 +
  60 +static void sr_write_async(struct usbnet *dev, u8 reg, u16 length, void *data)
  61 +{
  62 + usbnet_write_cmd_async(dev, SR_WR_REGS, SR_REQ_WR_REG,
  63 + 0, reg, data, length);
  64 +}
  65 +
  66 +static void sr_write_reg_async(struct usbnet *dev, u8 reg, u8 value)
  67 +{
  68 + usbnet_write_cmd_async(dev, SR_WR_REGS, SR_REQ_WR_REG,
  69 + value, reg, NULL, 0);
  70 +}
  71 +
  72 +static int wait_phy_eeprom_ready(struct usbnet *dev, int phy)
  73 +{
  74 + int i;
  75 +
  76 + for (i = 0; i < SR_SHARE_TIMEOUT; i++) {
  77 + u8 tmp = 0;
  78 + int ret;
  79 +
  80 + udelay(1);
  81 + ret = sr_read_reg(dev, EPCR, &tmp);
  82 + if (ret < 0)
  83 + return ret;
  84 +
  85 + /* ready */
  86 + if (!(tmp & EPCR_ERRE))
  87 + return 0;
  88 + }
  89 +
  90 + netdev_err(dev->net, "%s write timed out!\n", phy ? "phy" : "eeprom");
  91 +
  92 + return -EIO;
  93 +}
  94 +
  95 +static int sr_share_read_word(struct usbnet *dev, int phy, u8 reg,
  96 + __le16 *value)
  97 +{
  98 + int ret;
  99 +
  100 + mutex_lock(&dev->phy_mutex);
  101 +
  102 + sr_write_reg(dev, EPAR, phy ? (reg | EPAR_PHY_ADR) : reg);
  103 + sr_write_reg(dev, EPCR, phy ? (EPCR_EPOS | EPCR_ERPRR) : EPCR_ERPRR);
  104 +
  105 + ret = wait_phy_eeprom_ready(dev, phy);
  106 + if (ret < 0)
  107 + goto out_unlock;
  108 +
  109 + sr_write_reg(dev, EPCR, 0x0);
  110 + ret = sr_read(dev, EPDR, 2, value);
  111 +
  112 + netdev_dbg(dev->net, "read shared %d 0x%02x returned 0x%04x, %d\n",
  113 + phy, reg, *value, ret);
  114 +
  115 +out_unlock:
  116 + mutex_unlock(&dev->phy_mutex);
  117 + return ret;
  118 +}
  119 +
  120 +static int sr_share_write_word(struct usbnet *dev, int phy, u8 reg,
  121 + __le16 value)
  122 +{
  123 + int ret;
  124 +
  125 + mutex_lock(&dev->phy_mutex);
  126 +
  127 + ret = sr_write(dev, EPDR, 2, &value);
  128 + if (ret < 0)
  129 + goto out_unlock;
  130 +
  131 + sr_write_reg(dev, EPAR, phy ? (reg | EPAR_PHY_ADR) : reg);
  132 + sr_write_reg(dev, EPCR, phy ? (EPCR_WEP | EPCR_EPOS | EPCR_ERPRW) :
  133 + (EPCR_WEP | EPCR_ERPRW));
  134 +
  135 + ret = wait_phy_eeprom_ready(dev, phy);
  136 + if (ret < 0)
  137 + goto out_unlock;
  138 +
  139 + sr_write_reg(dev, EPCR, 0x0);
  140 +
  141 +out_unlock:
  142 + mutex_unlock(&dev->phy_mutex);
  143 + return ret;
  144 +}
  145 +
  146 +static int sr_read_eeprom_word(struct usbnet *dev, u8 offset, void *value)
  147 +{
  148 + return sr_share_read_word(dev, 0, offset, value);
  149 +}
  150 +
  151 +static int sr9700_get_eeprom_len(struct net_device *netdev)
  152 +{
  153 + return SR_EEPROM_LEN;
  154 +}
  155 +
  156 +static int sr9700_get_eeprom(struct net_device *netdev,
  157 + struct ethtool_eeprom *eeprom, u8 *data)
  158 +{
  159 + struct usbnet *dev = netdev_priv(netdev);
  160 + __le16 *buf = (__le16 *)data;
  161 + int ret = 0;
  162 + int i;
  163 +
  164 + /* access is 16bit */
  165 + if ((eeprom->offset & 0x01) || (eeprom->len & 0x01))
  166 + return -EINVAL;
  167 +
  168 + for (i = 0; i < eeprom->len / 2; i++) {
  169 + ret = sr_read_eeprom_word(dev, eeprom->offset / 2 + i, buf + i);
  170 + if (ret < 0)
  171 + break;
  172 + }
  173 +
  174 + return ret;
  175 +}
  176 +
  177 +static int sr_mdio_read(struct net_device *netdev, int phy_id, int loc)
  178 +{
  179 + struct usbnet *dev = netdev_priv(netdev);
  180 + __le16 res;
  181 + int rc = 0;
  182 +
  183 + if (phy_id) {
  184 + netdev_dbg(netdev, "Only internal phy supported\n");
  185 + return 0;
  186 + }
  187 +
  188 + /* Access NSR_LINKST bit for link status instead of MII_BMSR */
  189 + if (loc == MII_BMSR) {
  190 + u8 value;
  191 +
  192 + sr_read_reg(dev, NSR, &value);
  193 + if (value & NSR_LINKST)
  194 + rc = 1;
  195 + }
  196 + sr_share_read_word(dev, 1, loc, &res);
  197 + if (rc == 1)
  198 + res = le16_to_cpu(res) | BMSR_LSTATUS;
  199 + else
  200 + res = le16_to_cpu(res) & ~BMSR_LSTATUS;
  201 +
  202 + netdev_dbg(netdev, "sr_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n",
  203 + phy_id, loc, res);
  204 +
  205 + return res;
  206 +}
  207 +
  208 +static void sr_mdio_write(struct net_device *netdev, int phy_id, int loc,
  209 + int val)
  210 +{
  211 + struct usbnet *dev = netdev_priv(netdev);
  212 + __le16 res = cpu_to_le16(val);
  213 +
  214 + if (phy_id) {
  215 + netdev_dbg(netdev, "Only internal phy supported\n");
  216 + return;
  217 + }
  218 +
  219 + netdev_dbg(netdev, "sr_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n",
  220 + phy_id, loc, val);
  221 +
  222 + sr_share_write_word(dev, 1, loc, res);
  223 +}
  224 +
  225 +static u32 sr9700_get_link(struct net_device *netdev)
  226 +{
  227 + struct usbnet *dev = netdev_priv(netdev);
  228 + u8 value = 0;
  229 + int rc = 0;
  230 +
  231 + /* Get the Link Status directly */
  232 + sr_read_reg(dev, NSR, &value);
  233 + if (value & NSR_LINKST)
  234 + rc = 1;
  235 +
  236 + return rc;
  237 +}
  238 +
  239 +static int sr9700_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
  240 +{
  241 + struct usbnet *dev = netdev_priv(netdev);
  242 +
  243 + return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
  244 +}
  245 +
  246 +static const struct ethtool_ops sr9700_ethtool_ops = {
  247 + .get_drvinfo = usbnet_get_drvinfo,
  248 + .get_link = sr9700_get_link,
  249 + .get_msglevel = usbnet_get_msglevel,
  250 + .set_msglevel = usbnet_set_msglevel,
  251 + .get_eeprom_len = sr9700_get_eeprom_len,
  252 + .get_eeprom = sr9700_get_eeprom,
  253 + .get_settings = usbnet_get_settings,
  254 + .set_settings = usbnet_set_settings,
  255 + .nway_reset = usbnet_nway_reset,
  256 +};
  257 +
  258 +static void sr9700_set_multicast(struct net_device *netdev)
  259 +{
  260 + struct usbnet *dev = netdev_priv(netdev);
  261 + /* We use the 20 byte dev->data for our 8 byte filter buffer
  262 + * to avoid allocating memory that is tricky to free later
  263 + */
  264 + u8 *hashes = (u8 *)&dev->data;
  265 + /* rx_ctl setting : enable, disable_long, disable_crc */
  266 + u8 rx_ctl = RCR_RXEN | RCR_DIS_CRC | RCR_DIS_LONG;
  267 +
  268 + memset(hashes, 0x00, SR_MCAST_SIZE);
  269 + /* broadcast address */
  270 + hashes[SR_MCAST_SIZE - 1] |= SR_MCAST_ADDR_FLAG;
  271 + if (netdev->flags & IFF_PROMISC) {
  272 + rx_ctl |= RCR_PRMSC;
  273 + } else if (netdev->flags & IFF_ALLMULTI ||
  274 + netdev_mc_count(netdev) > SR_MCAST_MAX) {
  275 + rx_ctl |= RCR_RUNT;
  276 + } else if (!netdev_mc_empty(netdev)) {
  277 + struct netdev_hw_addr *ha;
  278 +
  279 + netdev_for_each_mc_addr(ha, netdev) {
  280 + u32 crc = ether_crc(ETH_ALEN, ha->addr) >> 26;
  281 + hashes[crc >> 3] |= 1 << (crc & 0x7);
  282 + }
  283 + }
  284 +
  285 + sr_write_async(dev, MAR, SR_MCAST_SIZE, hashes);
  286 + sr_write_reg_async(dev, RCR, rx_ctl);
  287 +}
  288 +
  289 +static int sr9700_set_mac_address(struct net_device *netdev, void *p)
  290 +{
  291 + struct usbnet *dev = netdev_priv(netdev);
  292 + struct sockaddr *addr = p;
  293 +
  294 + if (!is_valid_ether_addr(addr->sa_data)) {
  295 + netdev_err(netdev, "not setting invalid mac address %pM\n",
  296 + addr->sa_data);
  297 + return -EINVAL;
  298 + }
  299 +
  300 + memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
  301 + sr_write_async(dev, PAR, 6, netdev->dev_addr);
  302 +
  303 + return 0;
  304 +}
  305 +
  306 +static const struct net_device_ops sr9700_netdev_ops = {
  307 + .ndo_open = usbnet_open,
  308 + .ndo_stop = usbnet_stop,
  309 + .ndo_start_xmit = usbnet_start_xmit,
  310 + .ndo_tx_timeout = usbnet_tx_timeout,
  311 + .ndo_change_mtu = usbnet_change_mtu,
  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, 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, 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, PRR, PRR_PHY_RST);
  360 + /* at least 10ms, here 20ms for safe */
  361 + mdelay(20);
  362 + sr_write_reg(dev, 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_headroom(skb) < SR_TX_OVERHEAD) {
  461 + struct sk_buff *skb2;
  462 +
  463 + skb2 = skb_copy_expand(skb, SR_TX_OVERHEAD, 0, flags);
  464 + dev_kfree_skb_any(skb);
  465 + skb = skb2;
  466 + if (!skb)
  467 + return NULL;
  468 + }
  469 +
  470 + __skb_push(skb, SR_TX_OVERHEAD);
  471 +
  472 + /* usbnet adds padding if length is a multiple of packet size
  473 + * if so, adjust length value in header
  474 + */
  475 + if ((skb->len % dev->maxpacket) == 0)
  476 + len++;
  477 +
  478 + skb->data[0] = len;
  479 + skb->data[1] = len >> 8;
  480 +
  481 + return skb;
  482 +}
  483 +
  484 +static void sr9700_status(struct usbnet *dev, struct urb *urb)
  485 +{
  486 + int link;
  487 + u8 *buf;
  488 +
  489 + /* format:
  490 + b0: net status
  491 + b1: tx status 1
  492 + b2: tx status 2
  493 + b3: rx status
  494 + b4: rx overflow
  495 + b5: rx count
  496 + b6: tx count
  497 + b7: gpr
  498 + */
  499 +
  500 + if (urb->actual_length < 8)
  501 + return;
  502 +
  503 + buf = urb->transfer_buffer;
  504 +
  505 + link = !!(buf[0] & 0x40);
  506 + if (netif_carrier_ok(dev->net) != link) {
  507 + usbnet_link_change(dev, link, 1);
  508 + netdev_dbg(dev->net, "Link Status is: %d\n", link);
  509 + }
  510 +}
  511 +
  512 +static int sr9700_link_reset(struct usbnet *dev)
  513 +{
  514 + struct ethtool_cmd ecmd;
  515 +
  516 + mii_check_media(&dev->mii, 1, 1);
  517 + mii_ethtool_gset(&dev->mii, &ecmd);
  518 +
  519 + netdev_dbg(dev->net, "link_reset() speed: %d duplex: %d\n",
  520 + ecmd.speed, ecmd.duplex);
  521 +
  522 + return 0;
  523 +}
  524 +
  525 +static const struct driver_info sr9700_driver_info = {
  526 + .description = "CoreChip SR9700 USB Ethernet",
  527 + .flags = FLAG_ETHER,
  528 + .bind = sr9700_bind,
  529 + .rx_fixup = sr9700_rx_fixup,
  530 + .tx_fixup = sr9700_tx_fixup,
  531 + .status = sr9700_status,
  532 + .link_reset = sr9700_link_reset,
  533 + .reset = sr9700_link_reset,
  534 +};
  535 +
  536 +static const struct usb_device_id products[] = {
  537 + {
  538 + USB_DEVICE(0x0fe6, 0x9700), /* SR9700 device */
  539 + .driver_info = (unsigned long)&sr9700_driver_info,
  540 + },
  541 + {}, /* END */
  542 +};
  543 +
  544 +MODULE_DEVICE_TABLE(usb, products);
  545 +
  546 +static struct usb_driver sr9700_usb_driver = {
  547 + .name = "sr9700",
  548 + .id_table = products,
  549 + .probe = usbnet_probe,
  550 + .disconnect = usbnet_disconnect,
  551 + .suspend = usbnet_suspend,
  552 + .resume = usbnet_resume,
  553 + .disable_hub_initiated_lpm = 1,
  554 +};
  555 +
  556 +module_usb_driver(sr9700_usb_driver);
  557 +
  558 +MODULE_AUTHOR("liujl <liujunliang_ljl@163.com>");
  559 +MODULE_DESCRIPTION("SR9700 one chip USB 1.1 USB to Ethernet device from http://www.corechip-sz.com/");
  560 +MODULE_LICENSE("GPL");
drivers/net/usb/sr9700.h
  1 +/*
  2 + * CoreChip-sz SR9700 one chip USB 1.1 Ethernet Devices
  3 + *
  4 + * Author : Liu Junliang <liujunliang_ljl@163.com>
  5 + *
  6 + * This program is free software; you can redistribute it and/or
  7 + * modify it under the terms of the GNU General Public License
  8 + * version 2 as published by the Free Software Foundation.
  9 + */
  10 +
  11 +#ifndef _SR9700_H
  12 +#define _SR9700_H
  13 +
  14 +/* sr9700 spec. register table on Linux platform */
  15 +
  16 +/* Network Control Reg */
  17 +#define NCR 0x00
  18 +#define NCR_RST (1 << 0)
  19 +#define NCR_LBK (3 << 1)
  20 +#define NCR_FDX (1 << 3)
  21 +#define NCR_WAKEEN (1 << 6)
  22 +/* Network Status Reg */
  23 +#define NSR 0x01
  24 +#define NSR_RXRDY (1 << 0)
  25 +#define NSR_RXOV (1 << 1)
  26 +#define NSR_TX1END (1 << 2)
  27 +#define NSR_TX2END (1 << 3)
  28 +#define NSR_TXFULL (1 << 4)
  29 +#define NSR_WAKEST (1 << 5)
  30 +#define NSR_LINKST (1 << 6)
  31 +#define NSR_SPEED (1 << 7)
  32 +/* Tx Control Reg */
  33 +#define TCR 0x02
  34 +#define TCR_CRC_DIS (1 << 1)
  35 +#define TCR_PAD_DIS (1 << 2)
  36 +#define TCR_LC_CARE (1 << 3)
  37 +#define TCR_CRS_CARE (1 << 4)
  38 +#define TCR_EXCECM (1 << 5)
  39 +#define TCR_LF_EN (1 << 6)
  40 +/* Tx Status Reg for Packet Index 1 */
  41 +#define TSR1 0x03
  42 +#define TSR1_EC (1 << 2)
  43 +#define TSR1_COL (1 << 3)
  44 +#define TSR1_LC (1 << 4)
  45 +#define TSR1_NC (1 << 5)
  46 +#define TSR1_LOC (1 << 6)
  47 +#define TSR1_TLF (1 << 7)
  48 +/* Tx Status Reg for Packet Index 2 */
  49 +#define TSR2 0x04
  50 +#define TSR2_EC (1 << 2)
  51 +#define TSR2_COL (1 << 3)
  52 +#define TSR2_LC (1 << 4)
  53 +#define TSR2_NC (1 << 5)
  54 +#define TSR2_LOC (1 << 6)
  55 +#define TSR2_TLF (1 << 7)
  56 +/* Rx Control Reg*/
  57 +#define RCR 0x05
  58 +#define RCR_RXEN (1 << 0)
  59 +#define RCR_PRMSC (1 << 1)
  60 +#define RCR_RUNT (1 << 2)
  61 +#define RCR_ALL (1 << 3)
  62 +#define RCR_DIS_CRC (1 << 4)
  63 +#define RCR_DIS_LONG (1 << 5)
  64 +/* Rx Status Reg */
  65 +#define RSR 0x06
  66 +#define RSR_AE (1 << 2)
  67 +#define RSR_MF (1 << 6)
  68 +#define RSR_RF (1 << 7)
  69 +/* Rx Overflow Counter Reg */
  70 +#define ROCR 0x07
  71 +#define ROCR_ROC (0x7F << 0)
  72 +#define ROCR_RXFU (1 << 7)
  73 +/* Back Pressure Threshold Reg */
  74 +#define BPTR 0x08
  75 +#define BPTR_JPT (0x0F << 0)
  76 +#define BPTR_BPHW (0x0F << 4)
  77 +/* Flow Control Threshold Reg */
  78 +#define FCTR 0x09
  79 +#define FCTR_LWOT (0x0F << 0)
  80 +#define FCTR_HWOT (0x0F << 4)
  81 +/* rx/tx Flow Control Reg */
  82 +#define FCR 0x0A
  83 +#define FCR_FLCE (1 << 0)
  84 +#define FCR_BKPA (1 << 4)
  85 +#define FCR_TXPEN (1 << 5)
  86 +#define FCR_TXPF (1 << 6)
  87 +#define FCR_TXP0 (1 << 7)
  88 +/* Eeprom & Phy Control Reg */
  89 +#define EPCR 0x0B
  90 +#define EPCR_ERRE (1 << 0)
  91 +#define EPCR_ERPRW (1 << 1)
  92 +#define EPCR_ERPRR (1 << 2)
  93 +#define EPCR_EPOS (1 << 3)
  94 +#define EPCR_WEP (1 << 4)
  95 +/* Eeprom & Phy Address Reg */
  96 +#define EPAR 0x0C
  97 +#define EPAR_EROA (0x3F << 0)
  98 +#define EPAR_PHY_ADR_MASK (0x03 << 6)
  99 +#define EPAR_PHY_ADR (0x01 << 6)
  100 +/* Eeprom & Phy Data Reg */
  101 +#define EPDR 0x0D /* 0x0D ~ 0x0E for Data Reg Low & High */
  102 +/* Wakeup Control Reg */
  103 +#define WCR 0x0F
  104 +#define WCR_MAGICST (1 << 0)
  105 +#define WCR_LINKST (1 << 2)
  106 +#define WCR_MAGICEN (1 << 3)
  107 +#define WCR_LINKEN (1 << 5)
  108 +/* Physical Address Reg */
  109 +#define PAR 0x10 /* 0x10 ~ 0x15 6 bytes for PAR */
  110 +/* Multicast Address Reg */
  111 +#define MAR 0x16 /* 0x16 ~ 0x1D 8 bytes for MAR */
  112 +/* 0x1e unused */
  113 +/* Phy Reset Reg */
  114 +#define PRR 0x1F
  115 +#define PRR_PHY_RST (1 << 0)
  116 +/* Tx sdram Write Pointer Address Low */
  117 +#define TWPAL 0x20
  118 +/* Tx sdram Write Pointer Address High */
  119 +#define TWPAH 0x21
  120 +/* Tx sdram Read Pointer Address Low */
  121 +#define TRPAL 0x22
  122 +/* Tx sdram Read Pointer Address High */
  123 +#define TRPAH 0x23
  124 +/* Rx sdram Write Pointer Address Low */
  125 +#define RWPAL 0x24
  126 +/* Rx sdram Write Pointer Address High */
  127 +#define RWPAH 0x25
  128 +/* Rx sdram Read Pointer Address Low */
  129 +#define RRPAL 0x26
  130 +/* Rx sdram Read Pointer Address High */
  131 +#define RRPAH 0x27
  132 +/* Vendor ID register */
  133 +#define VID 0x28 /* 0x28 ~ 0x29 2 bytes for VID */
  134 +/* Product ID register */
  135 +#define PID 0x2A /* 0x2A ~ 0x2B 2 bytes for PID */
  136 +/* CHIP Revision register */
  137 +#define CHIPR 0x2C
  138 +/* 0x2D --> 0xEF unused */
  139 +/* USB Device Address */
  140 +#define USBDA 0xF0
  141 +#define USBDA_USBFA (0x7F << 0)
  142 +/* RX packet Counter Reg */
  143 +#define RXC 0xF1
  144 +/* Tx packet Counter & USB Status Reg */
  145 +#define TXC_USBS 0xF2
  146 +#define TXC_USBS_TXC0 (1 << 0)
  147 +#define TXC_USBS_TXC1 (1 << 1)
  148 +#define TXC_USBS_TXC2 (1 << 2)
  149 +#define TXC_USBS_EP1RDY (1 << 5)
  150 +#define TXC_USBS_SUSFLAG (1 << 6)
  151 +#define TXC_USBS_RXFAULT (1 << 7)
  152 +/* USB Control register */
  153 +#define USBC 0xF4
  154 +#define USBC_EP3NAK (1 << 4)
  155 +#define USBC_EP3ACK (1 << 5)
  156 +
  157 +/* Register access commands and flags */
  158 +#define SR_RD_REGS 0x00
  159 +#define SR_WR_REGS 0x01
  160 +#define SR_WR_REG 0x03
  161 +#define SR_REQ_RD_REG (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE)
  162 +#define SR_REQ_WR_REG (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE)
  163 +
  164 +/* parameters */
  165 +#define SR_SHARE_TIMEOUT 1000
  166 +#define SR_EEPROM_LEN 256
  167 +#define SR_MCAST_SIZE 8
  168 +#define SR_MCAST_ADDR_FLAG 0x80
  169 +#define SR_MCAST_MAX 64
  170 +#define SR_TX_OVERHEAD 2 /* 2bytes header */
  171 +#define SR_RX_OVERHEAD 7 /* 3bytes header + 4crc tail */
  172 +
  173 +#endif /* _SR9700_H */