提交 c010b2f7 编写于 作者: L Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (82 commits)
  ipw2200: Call netif_*_queue() interfaces properly.
  netxen: Needs to include linux/vmalloc.h
  [netdrvr] atl1d: fix !CONFIG_PM build
  r6040: rework init_one error handling
  r6040: bump release number to 0.18
  r6040: handle RX fifo full and no descriptor interrupts
  r6040: change the default waiting time
  r6040: use definitions for magic values in descriptor status
  r6040: completely rework the RX path
  r6040: call napi_disable when puting down the interface and set lp->dev accordingly.
  mv643xx_eth: fix NETPOLL build
  r6040: rework the RX buffers allocation routine
  r6040: fix scheduling while atomic in r6040_tx_timeout
  r6040: fix null pointer access and tx timeouts
  r6040: prefix all functions with r6040
  rndis_host: support WM6 devices as modems
  at91_ether: use netstats in net_device structure
  sfc: Create one RX queue and interrupt per CPU package by default
  sfc: Use a separate workqueue for resets
  sfc: I2C adapter initialisation fixes
  ...
...@@ -513,21 +513,11 @@ Additional Configurations ...@@ -513,21 +513,11 @@ Additional Configurations
Intel(R) PRO/1000 PT Dual Port Server Connection Intel(R) PRO/1000 PT Dual Port Server Connection
Intel(R) PRO/1000 PT Dual Port Server Adapter Intel(R) PRO/1000 PT Dual Port Server Adapter
Intel(R) PRO/1000 PF Dual Port Server Adapter Intel(R) PRO/1000 PF Dual Port Server Adapter
Intel(R) PRO/1000 PT Quad Port Server Adapter Intel(R) PRO/1000 PT Quad Port Server Adapter
NAPI NAPI
---- ----
NAPI (Rx polling mode) is supported in the e1000 driver. NAPI is enabled NAPI (Rx polling mode) is enabled in the e1000 driver.
or disabled based on the configuration of the kernel. To override
the default, use the following compile-time flags.
To enable NAPI, compile the driver module, passing in a configuration option:
make CFLAGS_EXTRA=-DE1000_NAPI install
To disable NAPI, compile the driver module, passing in a configuration option:
make CFLAGS_EXTRA=-DE1000_NO_NAPI install
See www.cyberus.ca/~hadi/usenix-paper.tgz for more information on NAPI. See www.cyberus.ca/~hadi/usenix-paper.tgz for more information on NAPI.
......
...@@ -148,7 +148,7 @@ ...@@ -148,7 +148,7 @@
getsockopt(sockfd, SOL_SOCKET, SO_NO_CHECK, &value, ...); getsockopt(sockfd, SOL_SOCKET, SO_NO_CHECK, &value, ...);
is meaningless (as in TCP). Packets with a zero checksum field are is meaningless (as in TCP). Packets with a zero checksum field are
illegal (cf. RFC 3828, sec. 3.1) will be silently discarded. illegal (cf. RFC 3828, sec. 3.1) and will be silently discarded.
4) Fragmentation 4) Fragmentation
......
...@@ -3533,7 +3533,7 @@ S: Supported ...@@ -3533,7 +3533,7 @@ S: Supported
S390 NETWORK DRIVERS S390 NETWORK DRIVERS
P: Ursula Braun P: Ursula Braun
M: ubraun@linux.vnet.ibm.com M: ursula.braun@de.ibm.com
P: Frank Blaschka P: Frank Blaschka
M: blaschka@linux.vnet.ibm.com M: blaschka@linux.vnet.ibm.com
M: linux390@de.ibm.com M: linux390@de.ibm.com
...@@ -3553,7 +3553,7 @@ S: Supported ...@@ -3553,7 +3553,7 @@ S: Supported
S390 IUCV NETWORK LAYER S390 IUCV NETWORK LAYER
P: Ursula Braun P: Ursula Braun
M: ubraun@linux.vnet.ibm.com M: ursula.braun@de.ibm.com
M: linux390@de.ibm.com M: linux390@de.ibm.com
L: linux-s390@vger.kernel.org L: linux-s390@vger.kernel.org
W: http://www.ibm.com/developerworks/linux/linux390/ W: http://www.ibm.com/developerworks/linux/linux390/
......
...@@ -98,7 +98,6 @@ ...@@ -98,7 +98,6 @@
#include <linux/compiler.h> #include <linux/compiler.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/ioport.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
#include <linux/rtnetlink.h> #include <linux/rtnetlink.h>
...@@ -120,11 +119,6 @@ ...@@ -120,11 +119,6 @@
NETIF_MSG_LINK) NETIF_MSG_LINK)
/* enable PIO instead of MMIO, if CONFIG_8139TOO_PIO is selected */
#ifdef CONFIG_8139TOO_PIO
#define USE_IO_OPS 1
#endif
/* define to 1, 2 or 3 to enable copious debugging info */ /* define to 1, 2 or 3 to enable copious debugging info */
#define RTL8139_DEBUG 0 #define RTL8139_DEBUG 0
...@@ -156,6 +150,13 @@ ...@@ -156,6 +150,13 @@
static int media[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1}; static int media[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1}; static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
/* Whether to use MMIO or PIO. Default to MMIO. */
#ifdef CONFIG_8139TOO_PIO
static int use_io = 1;
#else
static int use_io = 0;
#endif
/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast). /* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
The RTL chips use a 64 element hash table based on the Ethernet CRC. */ The RTL chips use a 64 element hash table based on the Ethernet CRC. */
static int multicast_filter_limit = 32; static int multicast_filter_limit = 32;
...@@ -614,6 +615,8 @@ MODULE_DESCRIPTION ("RealTek RTL-8139 Fast Ethernet driver"); ...@@ -614,6 +615,8 @@ MODULE_DESCRIPTION ("RealTek RTL-8139 Fast Ethernet driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION); MODULE_VERSION(DRV_VERSION);
module_param(use_io, int, 0);
MODULE_PARM_DESC(use_io, "Force use of I/O access mode. 0=MMIO 1=PIO");
module_param(multicast_filter_limit, int, 0); module_param(multicast_filter_limit, int, 0);
module_param_array(media, int, NULL, 0); module_param_array(media, int, NULL, 0);
module_param_array(full_duplex, int, NULL, 0); module_param_array(full_duplex, int, NULL, 0);
...@@ -709,13 +712,8 @@ static void __rtl8139_cleanup_dev (struct net_device *dev) ...@@ -709,13 +712,8 @@ static void __rtl8139_cleanup_dev (struct net_device *dev)
assert (tp->pci_dev != NULL); assert (tp->pci_dev != NULL);
pdev = tp->pci_dev; pdev = tp->pci_dev;
#ifdef USE_IO_OPS
if (tp->mmio_addr)
ioport_unmap (tp->mmio_addr);
#else
if (tp->mmio_addr) if (tp->mmio_addr)
pci_iounmap (pdev, tp->mmio_addr); pci_iounmap (pdev, tp->mmio_addr);
#endif /* USE_IO_OPS */
/* it's ok to call this even if we have no regions to free */ /* it's ok to call this even if we have no regions to free */
pci_release_regions (pdev); pci_release_regions (pdev);
...@@ -790,32 +788,33 @@ static int __devinit rtl8139_init_board (struct pci_dev *pdev, ...@@ -790,32 +788,33 @@ static int __devinit rtl8139_init_board (struct pci_dev *pdev,
DPRINTK("PIO region size == 0x%02X\n", pio_len); DPRINTK("PIO region size == 0x%02X\n", pio_len);
DPRINTK("MMIO region size == 0x%02lX\n", mmio_len); DPRINTK("MMIO region size == 0x%02lX\n", mmio_len);
#ifdef USE_IO_OPS retry:
/* make sure PCI base addr 0 is PIO */ if (use_io) {
if (!(pio_flags & IORESOURCE_IO)) { /* make sure PCI base addr 0 is PIO */
dev_err(&pdev->dev, "region #0 not a PIO resource, aborting\n"); if (!(pio_flags & IORESOURCE_IO)) {
rc = -ENODEV; dev_err(&pdev->dev, "region #0 not a PIO resource, aborting\n");
goto err_out; rc = -ENODEV;
} goto err_out;
/* check for weird/broken PCI region reporting */ }
if (pio_len < RTL_MIN_IO_SIZE) { /* check for weird/broken PCI region reporting */
dev_err(&pdev->dev, "Invalid PCI I/O region size(s), aborting\n"); if (pio_len < RTL_MIN_IO_SIZE) {
rc = -ENODEV; dev_err(&pdev->dev, "Invalid PCI I/O region size(s), aborting\n");
goto err_out; rc = -ENODEV;
} goto err_out;
#else }
/* make sure PCI base addr 1 is MMIO */ } else {
if (!(mmio_flags & IORESOURCE_MEM)) { /* make sure PCI base addr 1 is MMIO */
dev_err(&pdev->dev, "region #1 not an MMIO resource, aborting\n"); if (!(mmio_flags & IORESOURCE_MEM)) {
rc = -ENODEV; dev_err(&pdev->dev, "region #1 not an MMIO resource, aborting\n");
goto err_out; rc = -ENODEV;
} goto err_out;
if (mmio_len < RTL_MIN_IO_SIZE) { }
dev_err(&pdev->dev, "Invalid PCI mem region size(s), aborting\n"); if (mmio_len < RTL_MIN_IO_SIZE) {
rc = -ENODEV; dev_err(&pdev->dev, "Invalid PCI mem region size(s), aborting\n");
goto err_out; rc = -ENODEV;
goto err_out;
}
} }
#endif
rc = pci_request_regions (pdev, DRV_NAME); rc = pci_request_regions (pdev, DRV_NAME);
if (rc) if (rc)
...@@ -825,28 +824,28 @@ static int __devinit rtl8139_init_board (struct pci_dev *pdev, ...@@ -825,28 +824,28 @@ static int __devinit rtl8139_init_board (struct pci_dev *pdev,
/* enable PCI bus-mastering */ /* enable PCI bus-mastering */
pci_set_master (pdev); pci_set_master (pdev);
#ifdef USE_IO_OPS if (use_io) {
ioaddr = ioport_map(pio_start, pio_len); ioaddr = pci_iomap(pdev, 0, 0);
if (!ioaddr) { if (!ioaddr) {
dev_err(&pdev->dev, "cannot map PIO, aborting\n"); dev_err(&pdev->dev, "cannot map PIO, aborting\n");
rc = -EIO; rc = -EIO;
goto err_out; goto err_out;
} }
dev->base_addr = pio_start; dev->base_addr = pio_start;
tp->mmio_addr = ioaddr; tp->regs_len = pio_len;
tp->regs_len = pio_len; } else {
#else /* ioremap MMIO region */
/* ioremap MMIO region */ ioaddr = pci_iomap(pdev, 1, 0);
ioaddr = pci_iomap(pdev, 1, 0); if (ioaddr == NULL) {
if (ioaddr == NULL) { dev_err(&pdev->dev, "cannot remap MMIO, trying PIO\n");
dev_err(&pdev->dev, "cannot remap MMIO, aborting\n"); pci_release_regions(pdev);
rc = -EIO; use_io = 1;
goto err_out; goto retry;
}
dev->base_addr = (long) ioaddr;
tp->regs_len = mmio_len;
} }
dev->base_addr = (long) ioaddr;
tp->mmio_addr = ioaddr; tp->mmio_addr = ioaddr;
tp->regs_len = mmio_len;
#endif /* USE_IO_OPS */
/* Bring old chips out of low-power mode. */ /* Bring old chips out of low-power mode. */
RTL_W8 (HltClk, 'R'); RTL_W8 (HltClk, 'R');
...@@ -952,6 +951,14 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev, ...@@ -952,6 +951,14 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
"Use the \"8139cp\" driver for improved performance and stability.\n"); "Use the \"8139cp\" driver for improved performance and stability.\n");
} }
if (pdev->vendor == PCI_VENDOR_ID_REALTEK &&
pdev->device == PCI_DEVICE_ID_REALTEK_8139 &&
pdev->subsystem_vendor == PCI_VENDOR_ID_ATHEROS &&
pdev->subsystem_device == PCI_DEVICE_ID_REALTEK_8139) {
printk(KERN_INFO "8139too: OQO Model 2 detected. Forcing PIO\n");
use_io = 1;
}
i = rtl8139_init_board (pdev, &dev); i = rtl8139_init_board (pdev, &dev);
if (i < 0) if (i < 0)
return i; return i;
...@@ -2381,20 +2388,24 @@ static void rtl8139_set_msglevel(struct net_device *dev, u32 datum) ...@@ -2381,20 +2388,24 @@ static void rtl8139_set_msglevel(struct net_device *dev, u32 datum)
np->msg_enable = datum; np->msg_enable = datum;
} }
/* TODO: we are too slack to do reg dumping for pio, for now */
#ifdef CONFIG_8139TOO_PIO
#define rtl8139_get_regs_len NULL
#define rtl8139_get_regs NULL
#else
static int rtl8139_get_regs_len(struct net_device *dev) static int rtl8139_get_regs_len(struct net_device *dev)
{ {
struct rtl8139_private *np = netdev_priv(dev); struct rtl8139_private *np;
/* TODO: we are too slack to do reg dumping for pio, for now */
if (use_io)
return 0;
np = netdev_priv(dev);
return np->regs_len; return np->regs_len;
} }
static void rtl8139_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regbuf) static void rtl8139_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regbuf)
{ {
struct rtl8139_private *np = netdev_priv(dev); struct rtl8139_private *np;
/* TODO: we are too slack to do reg dumping for pio, for now */
if (use_io)
return;
np = netdev_priv(dev);
regs->version = RTL_REGS_VER; regs->version = RTL_REGS_VER;
...@@ -2402,7 +2413,6 @@ static void rtl8139_get_regs(struct net_device *dev, struct ethtool_regs *regs, ...@@ -2402,7 +2413,6 @@ static void rtl8139_get_regs(struct net_device *dev, struct ethtool_regs *regs,
memcpy_fromio(regbuf, np->mmio_addr, regs->len); memcpy_fromio(regbuf, np->mmio_addr, regs->len);
spin_unlock_irq(&np->lock); spin_unlock_irq(&np->lock);
} }
#endif /* CONFIG_8139TOO_MMIO */
static int rtl8139_get_sset_count(struct net_device *dev, int sset) static int rtl8139_get_sset_count(struct net_device *dev, int sset)
{ {
......
...@@ -1926,20 +1926,6 @@ config E1000 ...@@ -1926,20 +1926,6 @@ config E1000
To compile this driver as a module, choose M here. The module To compile this driver as a module, choose M here. The module
will be called e1000. will be called e1000.
config E1000_NAPI
bool "Use Rx Polling (NAPI)"
depends on E1000
help
NAPI is a new driver API designed to reduce CPU and interrupt load
when the driver is receiving lots of packets from the card. It is
still somewhat experimental and thus not yet enabled by default.
If your estimated Rx load is 10kpps or more, or if the card will be
deployed on potentially unfriendly networks (e.g. in a firewall),
then say Y here.
If in doubt, say N.
config E1000_DISABLE_PACKET_SPLIT config E1000_DISABLE_PACKET_SPLIT
bool "Disable Packet Split for PCI express adapters" bool "Disable Packet Split for PCI express adapters"
depends on E1000 depends on E1000
...@@ -2304,6 +2290,17 @@ config ATL1 ...@@ -2304,6 +2290,17 @@ config ATL1
To compile this driver as a module, choose M here. The module To compile this driver as a module, choose M here. The module
will be called atl1. will be called atl1.
config ATL1E
tristate "Atheros L1E Gigabit Ethernet support (EXPERIMENTAL)"
depends on PCI && EXPERIMENTAL
select CRC32
select MII
help
This driver supports the Atheros L1E gigabit ethernet adapter.
To compile this driver as a module, choose M here. The module
will be called atl1e.
endif # NETDEV_1000 endif # NETDEV_1000
# #
......
...@@ -15,6 +15,7 @@ obj-$(CONFIG_EHEA) += ehea/ ...@@ -15,6 +15,7 @@ obj-$(CONFIG_EHEA) += ehea/
obj-$(CONFIG_CAN) += can/ obj-$(CONFIG_CAN) += can/
obj-$(CONFIG_BONDING) += bonding/ obj-$(CONFIG_BONDING) += bonding/
obj-$(CONFIG_ATL1) += atlx/ obj-$(CONFIG_ATL1) += atlx/
obj-$(CONFIG_ATL1E) += atl1e/
obj-$(CONFIG_GIANFAR) += gianfar_driver.o obj-$(CONFIG_GIANFAR) += gianfar_driver.o
obj-$(CONFIG_TEHUTI) += tehuti.o obj-$(CONFIG_TEHUTI) += tehuti.o
......
...@@ -820,7 +820,7 @@ static int at91ether_tx(struct sk_buff *skb, struct net_device *dev) ...@@ -820,7 +820,7 @@ static int at91ether_tx(struct sk_buff *skb, struct net_device *dev)
lp->skb = skb; lp->skb = skb;
lp->skb_length = skb->len; lp->skb_length = skb->len;
lp->skb_physaddr = dma_map_single(NULL, skb->data, skb->len, DMA_TO_DEVICE); lp->skb_physaddr = dma_map_single(NULL, skb->data, skb->len, DMA_TO_DEVICE);
lp->stats.tx_bytes += skb->len; dev->stats.tx_bytes += skb->len;
/* Set address of the data in the Transmit Address register */ /* Set address of the data in the Transmit Address register */
at91_emac_write(AT91_EMAC_TAR, lp->skb_physaddr); at91_emac_write(AT91_EMAC_TAR, lp->skb_physaddr);
...@@ -843,34 +843,33 @@ static int at91ether_tx(struct sk_buff *skb, struct net_device *dev) ...@@ -843,34 +843,33 @@ static int at91ether_tx(struct sk_buff *skb, struct net_device *dev)
*/ */
static struct net_device_stats *at91ether_stats(struct net_device *dev) static struct net_device_stats *at91ether_stats(struct net_device *dev)
{ {
struct at91_private *lp = netdev_priv(dev);
int ale, lenerr, seqe, lcol, ecol; int ale, lenerr, seqe, lcol, ecol;
if (netif_running(dev)) { if (netif_running(dev)) {
lp->stats.rx_packets += at91_emac_read(AT91_EMAC_OK); /* Good frames received */ dev->stats.rx_packets += at91_emac_read(AT91_EMAC_OK); /* Good frames received */
ale = at91_emac_read(AT91_EMAC_ALE); ale = at91_emac_read(AT91_EMAC_ALE);
lp->stats.rx_frame_errors += ale; /* Alignment errors */ dev->stats.rx_frame_errors += ale; /* Alignment errors */
lenerr = at91_emac_read(AT91_EMAC_ELR) + at91_emac_read(AT91_EMAC_USF); lenerr = at91_emac_read(AT91_EMAC_ELR) + at91_emac_read(AT91_EMAC_USF);
lp->stats.rx_length_errors += lenerr; /* Excessive Length or Undersize Frame error */ dev->stats.rx_length_errors += lenerr; /* Excessive Length or Undersize Frame error */
seqe = at91_emac_read(AT91_EMAC_SEQE); seqe = at91_emac_read(AT91_EMAC_SEQE);
lp->stats.rx_crc_errors += seqe; /* CRC error */ dev->stats.rx_crc_errors += seqe; /* CRC error */
lp->stats.rx_fifo_errors += at91_emac_read(AT91_EMAC_DRFC); /* Receive buffer not available */ dev->stats.rx_fifo_errors += at91_emac_read(AT91_EMAC_DRFC); /* Receive buffer not available */
lp->stats.rx_errors += (ale + lenerr + seqe dev->stats.rx_errors += (ale + lenerr + seqe
+ at91_emac_read(AT91_EMAC_CDE) + at91_emac_read(AT91_EMAC_RJB)); + at91_emac_read(AT91_EMAC_CDE) + at91_emac_read(AT91_EMAC_RJB));
lp->stats.tx_packets += at91_emac_read(AT91_EMAC_FRA); /* Frames successfully transmitted */ dev->stats.tx_packets += at91_emac_read(AT91_EMAC_FRA); /* Frames successfully transmitted */
lp->stats.tx_fifo_errors += at91_emac_read(AT91_EMAC_TUE); /* Transmit FIFO underruns */ dev->stats.tx_fifo_errors += at91_emac_read(AT91_EMAC_TUE); /* Transmit FIFO underruns */
lp->stats.tx_carrier_errors += at91_emac_read(AT91_EMAC_CSE); /* Carrier Sense errors */ dev->stats.tx_carrier_errors += at91_emac_read(AT91_EMAC_CSE); /* Carrier Sense errors */
lp->stats.tx_heartbeat_errors += at91_emac_read(AT91_EMAC_SQEE);/* Heartbeat error */ dev->stats.tx_heartbeat_errors += at91_emac_read(AT91_EMAC_SQEE);/* Heartbeat error */
lcol = at91_emac_read(AT91_EMAC_LCOL); lcol = at91_emac_read(AT91_EMAC_LCOL);
ecol = at91_emac_read(AT91_EMAC_ECOL); ecol = at91_emac_read(AT91_EMAC_ECOL);
lp->stats.tx_window_errors += lcol; /* Late collisions */ dev->stats.tx_window_errors += lcol; /* Late collisions */
lp->stats.tx_aborted_errors += ecol; /* 16 collisions */ dev->stats.tx_aborted_errors += ecol; /* 16 collisions */
lp->stats.collisions += (at91_emac_read(AT91_EMAC_SCOL) + at91_emac_read(AT91_EMAC_MCOL) + lcol + ecol); dev->stats.collisions += (at91_emac_read(AT91_EMAC_SCOL) + at91_emac_read(AT91_EMAC_MCOL) + lcol + ecol);
} }
return &lp->stats; return &dev->stats;
} }
/* /*
...@@ -896,16 +895,16 @@ static void at91ether_rx(struct net_device *dev) ...@@ -896,16 +895,16 @@ static void at91ether_rx(struct net_device *dev)
skb->protocol = eth_type_trans(skb, dev); skb->protocol = eth_type_trans(skb, dev);
dev->last_rx = jiffies; dev->last_rx = jiffies;
lp->stats.rx_bytes += pktlen; dev->stats.rx_bytes += pktlen;
netif_rx(skb); netif_rx(skb);
} }
else { else {
lp->stats.rx_dropped += 1; dev->stats.rx_dropped += 1;
printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name); printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
} }
if (dlist->descriptors[lp->rxBuffIndex].size & EMAC_MULTICAST) if (dlist->descriptors[lp->rxBuffIndex].size & EMAC_MULTICAST)
lp->stats.multicast++; dev->stats.multicast++;
dlist->descriptors[lp->rxBuffIndex].addr &= ~EMAC_DESC_DONE; /* reset ownership bit */ dlist->descriptors[lp->rxBuffIndex].addr &= ~EMAC_DESC_DONE; /* reset ownership bit */
if (lp->rxBuffIndex == MAX_RX_DESCR-1) /* wrap after last buffer */ if (lp->rxBuffIndex == MAX_RX_DESCR-1) /* wrap after last buffer */
...@@ -934,7 +933,7 @@ static irqreturn_t at91ether_interrupt(int irq, void *dev_id) ...@@ -934,7 +933,7 @@ static irqreturn_t at91ether_interrupt(int irq, void *dev_id)
if (intstatus & AT91_EMAC_TCOM) { /* Transmit complete */ if (intstatus & AT91_EMAC_TCOM) { /* Transmit complete */
/* The TCOM bit is set even if the transmission failed. */ /* The TCOM bit is set even if the transmission failed. */
if (intstatus & (AT91_EMAC_TUND | AT91_EMAC_RTRY)) if (intstatus & (AT91_EMAC_TUND | AT91_EMAC_RTRY))
lp->stats.tx_errors += 1; dev->stats.tx_errors += 1;
if (lp->skb) { if (lp->skb) {
dev_kfree_skb_irq(lp->skb); dev_kfree_skb_irq(lp->skb);
......
...@@ -84,7 +84,6 @@ struct recv_desc_bufs ...@@ -84,7 +84,6 @@ struct recv_desc_bufs
struct at91_private struct at91_private
{ {
struct net_device_stats stats;
struct mii_if_info mii; /* ethtool support */ struct mii_if_info mii; /* ethtool support */
struct at91_eth_data board_data; /* board-specific configuration */ struct at91_eth_data board_data; /* board-specific configuration */
struct clk *ether_clk; /* clock */ struct clk *ether_clk; /* clock */
......
obj-$(CONFIG_ATL1E) += atl1e.o
atl1e-objs += atl1e_main.o atl1e_hw.o atl1e_ethtool.o atl1e_param.o
/*
* Copyright(c) 2007 Atheros Corporation. All rights reserved.
* Copyright(c) 2007 xiong huang <xiong.huang@atheros.com>
*
* Derived from Intel e1000 driver
* Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _ATL1E_H_
#define _ATL1E_H_
#include <linux/version.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/ioport.h>
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/udp.h>
#include <linux/mii.h>
#include <linux/io.h>
#include <linux/vmalloc.h>
#include <linux/pagemap.h>
#include <linux/tcp.h>
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
#include <linux/workqueue.h>
#include <net/checksum.h>
#include <net/ip6_checksum.h>
#include "atl1e_hw.h"
#define PCI_REG_COMMAND 0x04 /* PCI Command Register */
#define CMD_IO_SPACE 0x0001
#define CMD_MEMORY_SPACE 0x0002
#define CMD_BUS_MASTER 0x0004
#define BAR_0 0
#define BAR_1 1
#define BAR_5 5
/* Wake Up Filter Control */
#define AT_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
#define AT_WUFC_MAG 0x00000002 /* Magic Packet Wakeup Enable */
#define AT_WUFC_EX 0x00000004 /* Directed Exact Wakeup Enable */
#define AT_WUFC_MC 0x00000008 /* Multicast Wakeup Enable */
#define AT_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */
#define SPEED_0 0xffff
#define HALF_DUPLEX 1
#define FULL_DUPLEX 2
/* Error Codes */
#define AT_ERR_EEPROM 1
#define AT_ERR_PHY 2
#define AT_ERR_CONFIG 3
#define AT_ERR_PARAM 4
#define AT_ERR_MAC_TYPE 5
#define AT_ERR_PHY_TYPE 6
#define AT_ERR_PHY_SPEED 7
#define AT_ERR_PHY_RES 8
#define AT_ERR_TIMEOUT 9
#define MAX_JUMBO_FRAME_SIZE 0x2000
#define AT_VLAN_TAG_TO_TPD_TAG(_vlan, _tpd) \
_tpd = (((_vlan) << (4)) | (((_vlan) >> 13) & 7) |\
(((_vlan) >> 9) & 8))
#define AT_TPD_TAG_TO_VLAN_TAG(_tpd, _vlan) \
_vlan = (((_tpd) >> 8) | (((_tpd) & 0x77) << 9) |\
(((_tdp) & 0x88) << 5))
#define AT_MAX_RECEIVE_QUEUE 4
#define AT_PAGE_NUM_PER_QUEUE 2
#define AT_DMA_HI_ADDR_MASK 0xffffffff00000000ULL
#define AT_DMA_LO_ADDR_MASK 0x00000000ffffffffULL
#define AT_TX_WATCHDOG (5 * HZ)
#define AT_MAX_INT_WORK 10
#define AT_TWSI_EEPROM_TIMEOUT 100
#define AT_HW_MAX_IDLE_DELAY 10
#define AT_SUSPEND_LINK_TIMEOUT 28
#define AT_REGS_LEN 75
#define AT_EEPROM_LEN 512
#define AT_ADV_MASK (ADVERTISE_10_HALF |\
ADVERTISE_10_FULL |\
ADVERTISE_100_HALF |\
ADVERTISE_100_FULL |\
ADVERTISE_1000_FULL)
/* tpd word 2 */
#define TPD_BUFLEN_MASK 0x3FFF
#define TPD_BUFLEN_SHIFT 0
#define TPD_DMAINT_MASK 0x0001
#define TPD_DMAINT_SHIFT 14
#define TPD_PKTNT_MASK 0x0001
#define TPD_PKTINT_SHIFT 15
#define TPD_VLANTAG_MASK 0xFFFF
#define TPD_VLAN_SHIFT 16
/* tpd word 3 bits 0:4 */
#define TPD_EOP_MASK 0x0001
#define TPD_EOP_SHIFT 0
#define TPD_IP_VERSION_MASK 0x0001
#define TPD_IP_VERSION_SHIFT 1 /* 0 : IPV4, 1 : IPV6 */
#define TPD_INS_VL_TAG_MASK 0x0001
#define TPD_INS_VL_TAG_SHIFT 2
#define TPD_CC_SEGMENT_EN_MASK 0x0001
#define TPD_CC_SEGMENT_EN_SHIFT 3
#define TPD_SEGMENT_EN_MASK 0x0001
#define TPD_SEGMENT_EN_SHIFT 4
/* tdp word 3 bits 5:7 if ip version is 0 */
#define TPD_IP_CSUM_MASK 0x0001
#define TPD_IP_CSUM_SHIFT 5
#define TPD_TCP_CSUM_MASK 0x0001
#define TPD_TCP_CSUM_SHIFT 6
#define TPD_UDP_CSUM_MASK 0x0001
#define TPD_UDP_CSUM_SHIFT 7
/* tdp word 3 bits 5:7 if ip version is 1 */
#define TPD_V6_IPHLLO_MASK 0x0007
#define TPD_V6_IPHLLO_SHIFT 7
/* tpd word 3 bits 8:9 bit */
#define TPD_VL_TAGGED_MASK 0x0001
#define TPD_VL_TAGGED_SHIFT 8
#define TPD_ETHTYPE_MASK 0x0001
#define TPD_ETHTYPE_SHIFT 9
/* tdp word 3 bits 10:13 if ip version is 0 */
#define TDP_V4_IPHL_MASK 0x000F
#define TPD_V4_IPHL_SHIFT 10
/* tdp word 3 bits 10:13 if ip version is 1 */
#define TPD_V6_IPHLHI_MASK 0x000F
#define TPD_V6_IPHLHI_SHIFT 10
/* tpd word 3 bit 14:31 if segment enabled */
#define TPD_TCPHDRLEN_MASK 0x000F
#define TPD_TCPHDRLEN_SHIFT 14
#define TPD_HDRFLAG_MASK 0x0001
#define TPD_HDRFLAG_SHIFT 18
#define TPD_MSS_MASK 0x1FFF
#define TPD_MSS_SHIFT 19
/* tdp word 3 bit 16:31 if custom csum enabled */
#define TPD_PLOADOFFSET_MASK 0x00FF
#define TPD_PLOADOFFSET_SHIFT 16
#define TPD_CCSUMOFFSET_MASK 0x00FF
#define TPD_CCSUMOFFSET_SHIFT 24
struct atl1e_tpd_desc {
__le64 buffer_addr;
__le32 word2;
__le32 word3;
};
/* how about 0x2000 */
#define MAX_TX_BUF_LEN 0x2000
#define MAX_TX_BUF_SHIFT 13
/*#define MAX_TX_BUF_LEN 0x3000 */
/* rrs word 1 bit 0:31 */
#define RRS_RX_CSUM_MASK 0xFFFF
#define RRS_RX_CSUM_SHIFT 0
#define RRS_PKT_SIZE_MASK 0x3FFF
#define RRS_PKT_SIZE_SHIFT 16
#define RRS_CPU_NUM_MASK 0x0003
#define RRS_CPU_NUM_SHIFT 30
#define RRS_IS_RSS_IPV4 0x0001
#define RRS_IS_RSS_IPV4_TCP 0x0002
#define RRS_IS_RSS_IPV6 0x0004
#define RRS_IS_RSS_IPV6_TCP 0x0008
#define RRS_IS_IPV6 0x0010
#define RRS_IS_IP_FRAG 0x0020
#define RRS_IS_IP_DF 0x0040
#define RRS_IS_802_3 0x0080
#define RRS_IS_VLAN_TAG 0x0100
#define RRS_IS_ERR_FRAME 0x0200
#define RRS_IS_IPV4 0x0400
#define RRS_IS_UDP 0x0800
#define RRS_IS_TCP 0x1000
#define RRS_IS_BCAST 0x2000
#define RRS_IS_MCAST 0x4000
#define RRS_IS_PAUSE 0x8000
#define RRS_ERR_BAD_CRC 0x0001
#define RRS_ERR_CODE 0x0002
#define RRS_ERR_DRIBBLE 0x0004
#define RRS_ERR_RUNT 0x0008
#define RRS_ERR_RX_OVERFLOW 0x0010
#define RRS_ERR_TRUNC 0x0020
#define RRS_ERR_IP_CSUM 0x0040
#define RRS_ERR_L4_CSUM 0x0080
#define RRS_ERR_LENGTH 0x0100
#define RRS_ERR_DES_ADDR 0x0200
struct atl1e_recv_ret_status {
u16 seq_num;
u16 hash_lo;
__le32 word1;
u16 pkt_flag;
u16 err_flag;
u16 hash_hi;
u16 vtag;
};
enum atl1e_dma_req_block {
atl1e_dma_req_128 = 0,
atl1e_dma_req_256 = 1,
atl1e_dma_req_512 = 2,
atl1e_dma_req_1024 = 3,
atl1e_dma_req_2048 = 4,
atl1e_dma_req_4096 = 5
};
enum atl1e_rrs_type {
atl1e_rrs_disable = 0,
atl1e_rrs_ipv4 = 1,
atl1e_rrs_ipv4_tcp = 2,
atl1e_rrs_ipv6 = 4,
atl1e_rrs_ipv6_tcp = 8
};
enum atl1e_nic_type {
athr_l1e = 0,
athr_l2e_revA = 1,
athr_l2e_revB = 2
};
struct atl1e_hw_stats {
/* rx */
unsigned long rx_ok; /* The number of good packet received. */
unsigned long rx_bcast; /* The number of good broadcast packet received. */
unsigned long rx_mcast; /* The number of good multicast packet received. */
unsigned long rx_pause; /* The number of Pause packet received. */
unsigned long rx_ctrl; /* The number of Control packet received other than Pause frame. */
unsigned long rx_fcs_err; /* The number of packets with bad FCS. */
unsigned long rx_len_err; /* The number of packets with mismatch of length field and actual size. */
unsigned long rx_byte_cnt; /* The number of bytes of good packet received. FCS is NOT included. */
unsigned long rx_runt; /* The number of packets received that are less than 64 byte long and with good FCS. */
unsigned long rx_frag; /* The number of packets received that are less than 64 byte long and with bad FCS. */
unsigned long rx_sz_64; /* The number of good and bad packets received that are 64 byte long. */
unsigned long rx_sz_65_127; /* The number of good and bad packets received that are between 65 and 127-byte long. */
unsigned long rx_sz_128_255; /* The number of good and bad packets received that are between 128 and 255-byte long. */
unsigned long rx_sz_256_511; /* The number of good and bad packets received that are between 256 and 511-byte long. */
unsigned long rx_sz_512_1023; /* The number of good and bad packets received that are between 512 and 1023-byte long. */
unsigned long rx_sz_1024_1518; /* The number of good and bad packets received that are between 1024 and 1518-byte long. */
unsigned long rx_sz_1519_max; /* The number of good and bad packets received that are between 1519-byte and MTU. */
unsigned long rx_sz_ov; /* The number of good and bad packets received that are more than MTU size truncated by Selene. */
unsigned long rx_rxf_ov; /* The number of frame dropped due to occurrence of RX FIFO overflow. */
unsigned long rx_rrd_ov; /* The number of frame dropped due to occurrence of RRD overflow. */
unsigned long rx_align_err; /* Alignment Error */
unsigned long rx_bcast_byte_cnt; /* The byte count of broadcast packet received, excluding FCS. */
unsigned long rx_mcast_byte_cnt; /* The byte count of multicast packet received, excluding FCS. */
unsigned long rx_err_addr; /* The number of packets dropped due to address filtering. */
/* tx */
unsigned long tx_ok; /* The number of good packet transmitted. */
unsigned long tx_bcast; /* The number of good broadcast packet transmitted. */
unsigned long tx_mcast; /* The number of good multicast packet transmitted. */
unsigned long tx_pause; /* The number of Pause packet transmitted. */
unsigned long tx_exc_defer; /* The number of packets transmitted with excessive deferral. */
unsigned long tx_ctrl; /* The number of packets transmitted is a control frame, excluding Pause frame. */
unsigned long tx_defer; /* The number of packets transmitted that is deferred. */
unsigned long tx_byte_cnt; /* The number of bytes of data transmitted. FCS is NOT included. */
unsigned long tx_sz_64; /* The number of good and bad packets transmitted that are 64 byte long. */
unsigned long tx_sz_65_127; /* The number of good and bad packets transmitted that are between 65 and 127-byte long. */
unsigned long tx_sz_128_255; /* The number of good and bad packets transmitted that are between 128 and 255-byte long. */
unsigned long tx_sz_256_511; /* The number of good and bad packets transmitted that are between 256 and 511-byte long. */
unsigned long tx_sz_512_1023; /* The number of good and bad packets transmitted that are between 512 and 1023-byte long. */
unsigned long tx_sz_1024_1518; /* The number of good and bad packets transmitted that are between 1024 and 1518-byte long. */
unsigned long tx_sz_1519_max; /* The number of good and bad packets transmitted that are between 1519-byte and MTU. */
unsigned long tx_1_col; /* The number of packets subsequently transmitted successfully with a single prior collision. */
unsigned long tx_2_col; /* The number of packets subsequently transmitted successfully with multiple prior collisions. */
unsigned long tx_late_col; /* The number of packets transmitted with late collisions. */
unsigned long tx_abort_col; /* The number of transmit packets aborted due to excessive collisions. */
unsigned long tx_underrun; /* The number of transmit packets aborted due to transmit FIFO underrun, or TRD FIFO underrun */
unsigned long tx_rd_eop; /* The number of times that read beyond the EOP into the next frame area when TRD was not written timely */
unsigned long tx_len_err; /* The number of transmit packets with length field does NOT match the actual frame size. */
unsigned long tx_trunc; /* The number of transmit packets truncated due to size exceeding MTU. */
unsigned long tx_bcast_byte; /* The byte count of broadcast packet transmitted, excluding FCS. */
unsigned long tx_mcast_byte; /* The byte count of multicast packet transmitted, excluding FCS. */
};
struct atl1e_hw {
u8 __iomem *hw_addr; /* inner register address */
resource_size_t mem_rang;
struct atl1e_adapter *adapter;
enum atl1e_nic_type nic_type;
u16 device_id;
u16 vendor_id;
u16 subsystem_id;
u16 subsystem_vendor_id;
u8 revision_id;
u16 pci_cmd_word;
u8 mac_addr[ETH_ALEN];
u8 perm_mac_addr[ETH_ALEN];
u8 preamble_len;
u16 max_frame_size;
u16 rx_jumbo_th;
u16 tx_jumbo_th;
u16 media_type;
#define MEDIA_TYPE_AUTO_SENSOR 0
#define MEDIA_TYPE_100M_FULL 1
#define MEDIA_TYPE_100M_HALF 2
#define MEDIA_TYPE_10M_FULL 3
#define MEDIA_TYPE_10M_HALF 4
u16 autoneg_advertised;
#define ADVERTISE_10_HALF 0x0001
#define ADVERTISE_10_FULL 0x0002
#define ADVERTISE_100_HALF 0x0004
#define ADVERTISE_100_FULL 0x0008
#define ADVERTISE_1000_HALF 0x0010 /* Not used, just FYI */
#define ADVERTISE_1000_FULL 0x0020
u16 mii_autoneg_adv_reg;
u16 mii_1000t_ctrl_reg;
u16 imt; /* Interrupt Moderator timer ( 2us resolution) */
u16 ict; /* Interrupt Clear timer (2us resolution) */
u32 smb_timer;
u16 rrd_thresh; /* Threshold of number of RRD produced to trigger
interrupt request */
u16 tpd_thresh;
u16 rx_count_down; /* 2us resolution */
u16 tx_count_down;
u8 tpd_burst; /* Number of TPD to prefetch in cache-aligned burst. */
enum atl1e_rrs_type rrs_type;
u32 base_cpu;
u32 indirect_tab;
enum atl1e_dma_req_block dmar_block;
enum atl1e_dma_req_block dmaw_block;
u8 dmaw_dly_cnt;
u8 dmar_dly_cnt;
bool phy_configured;
bool re_autoneg;
bool emi_ca;
};
/*
* wrapper around a pointer to a socket buffer,
* so a DMA handle can be stored along with the buffer
*/
struct atl1e_tx_buffer {
struct sk_buff *skb;
u16 length;
dma_addr_t dma;
};
struct atl1e_rx_page {
dma_addr_t dma; /* receive rage DMA address */
u8 *addr; /* receive rage virtual address */
dma_addr_t write_offset_dma; /* the DMA address which contain the
receive data offset in the page */
u32 *write_offset_addr; /* the virtaul address which contain
the receive data offset in the page */
u32 read_offset; /* the offset where we have read */
};
struct atl1e_rx_page_desc {
struct atl1e_rx_page rx_page[AT_PAGE_NUM_PER_QUEUE];
u8 rx_using;
u16 rx_nxseq;
};
/* transmit packet descriptor (tpd) ring */
struct atl1e_tx_ring {
struct atl1e_tpd_desc *desc; /* descriptor ring virtual address */
dma_addr_t dma; /* descriptor ring physical address */
u16 count; /* the count of transmit rings */
rwlock_t tx_lock;
u16 next_to_use;
atomic_t next_to_clean;
struct atl1e_tx_buffer *tx_buffer;
dma_addr_t cmb_dma;
u32 *cmb;
};
/* receive packet descriptor ring */
struct atl1e_rx_ring {
void *desc;
dma_addr_t dma;
int size;
u32 page_size; /* bytes length of rxf page */
u32 real_page_size; /* real_page_size = page_size + jumbo + aliagn */
struct atl1e_rx_page_desc rx_page_desc[AT_MAX_RECEIVE_QUEUE];
};
/* board specific private data structure */
struct atl1e_adapter {
struct net_device *netdev;
struct pci_dev *pdev;
struct vlan_group *vlgrp;
struct napi_struct napi;
struct mii_if_info mii; /* MII interface info */
struct atl1e_hw hw;
struct atl1e_hw_stats hw_stats;
struct net_device_stats net_stats;
bool have_msi;
u32 wol;
u16 link_speed;
u16 link_duplex;
spinlock_t mdio_lock;
spinlock_t tx_lock;
atomic_t irq_sem;
struct work_struct reset_task;
struct work_struct link_chg_task;
struct timer_list watchdog_timer;
struct timer_list phy_config_timer;
/* All Descriptor memory */
dma_addr_t ring_dma;
void *ring_vir_addr;
int ring_size;
struct atl1e_tx_ring tx_ring;
struct atl1e_rx_ring rx_ring;
int num_rx_queues;
unsigned long flags;
#define __AT_TESTING 0x0001
#define __AT_RESETTING 0x0002
#define __AT_DOWN 0x0003
u32 bd_number; /* board number;*/
u32 pci_state[16];
u32 *config_space;
};
#define AT_WRITE_REG(a, reg, value) ( \
writel((value), ((a)->hw_addr + reg)))
#define AT_WRITE_FLUSH(a) (\
readl((a)->hw_addr))
#define AT_READ_REG(a, reg) ( \
readl((a)->hw_addr + reg))
#define AT_WRITE_REGB(a, reg, value) (\
writeb((value), ((a)->hw_addr + reg)))
#define AT_READ_REGB(a, reg) (\
readb((a)->hw_addr + reg))
#define AT_WRITE_REGW(a, reg, value) (\
writew((value), ((a)->hw_addr + reg)))
#define AT_READ_REGW(a, reg) (\
readw((a)->hw_addr + reg))
#define AT_WRITE_REG_ARRAY(a, reg, offset, value) ( \
writel((value), (((a)->hw_addr + reg) + ((offset) << 2))))
#define AT_READ_REG_ARRAY(a, reg, offset) ( \
readl(((a)->hw_addr + reg) + ((offset) << 2)))
extern char atl1e_driver_name[];
extern char atl1e_driver_version[];
extern void atl1e_check_options(struct atl1e_adapter *adapter);
extern int atl1e_up(struct atl1e_adapter *adapter);
extern void atl1e_down(struct atl1e_adapter *adapter);
extern void atl1e_reinit_locked(struct atl1e_adapter *adapter);
extern s32 atl1e_reset_hw(struct atl1e_hw *hw);
extern void atl1e_set_ethtool_ops(struct net_device *netdev);
#endif /* _ATL1_E_H_ */
/*
* Copyright(c) 2007 Atheros Corporation. All rights reserved.
*
* Derived from Intel e1000 driver
* Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#include <linux/netdevice.h>
#include <linux/ethtool.h>
#include "atl1e.h"
static int atl1e_get_settings(struct net_device *netdev,
struct ethtool_cmd *ecmd)
{
struct atl1e_adapter *adapter = netdev_priv(netdev);
struct atl1e_hw *hw = &adapter->hw;
ecmd->supported = (SUPPORTED_10baseT_Half |
SUPPORTED_10baseT_Full |
SUPPORTED_100baseT_Half |
SUPPORTED_100baseT_Full |
SUPPORTED_Autoneg |
SUPPORTED_TP);
if (hw->nic_type == athr_l1e)
ecmd->supported |= SUPPORTED_1000baseT_Full;
ecmd->advertising = ADVERTISED_TP;
ecmd->advertising |= ADVERTISED_Autoneg;
ecmd->advertising |= hw->autoneg_advertised;
ecmd->port = PORT_TP;
ecmd->phy_address = 0;
ecmd->transceiver = XCVR_INTERNAL;
if (adapter->link_speed != SPEED_0) {
ecmd->speed = adapter->link_speed;
if (adapter->link_duplex == FULL_DUPLEX)
ecmd->duplex = DUPLEX_FULL;
else
ecmd->duplex = DUPLEX_HALF;
} else {
ecmd->speed = -1;
ecmd->duplex = -1;
}
ecmd->autoneg = AUTONEG_ENABLE;
return 0;
}
static int atl1e_set_settings(struct net_device *netdev,
struct ethtool_cmd *ecmd)
{
struct atl1e_adapter *adapter = netdev_priv(netdev);
struct atl1e_hw *hw = &adapter->hw;
while (test_and_set_bit(__AT_RESETTING, &adapter->flags))
msleep(1);
if (ecmd->autoneg == AUTONEG_ENABLE) {
u16 adv4, adv9;
if ((ecmd->advertising&ADVERTISE_1000_FULL)) {
if (hw->nic_type == athr_l1e) {
hw->autoneg_advertised =
ecmd->advertising & AT_ADV_MASK;
} else {
clear_bit(__AT_RESETTING, &adapter->flags);
return -EINVAL;
}
} else if (ecmd->advertising&ADVERTISE_1000_HALF) {
clear_bit(__AT_RESETTING, &adapter->flags);
return -EINVAL;
} else {
hw->autoneg_advertised =
ecmd->advertising & AT_ADV_MASK;
}
ecmd->advertising = hw->autoneg_advertised |
ADVERTISED_TP | ADVERTISED_Autoneg;
adv4 = hw->mii_autoneg_adv_reg & ~MII_AR_SPEED_MASK;
adv9 = hw->mii_1000t_ctrl_reg & ~MII_AT001_CR_1000T_SPEED_MASK;
if (hw->autoneg_advertised & ADVERTISE_10_HALF)
adv4 |= MII_AR_10T_HD_CAPS;
if (hw->autoneg_advertised & ADVERTISE_10_FULL)
adv4 |= MII_AR_10T_FD_CAPS;
if (hw->autoneg_advertised & ADVERTISE_100_HALF)
adv4 |= MII_AR_100TX_HD_CAPS;
if (hw->autoneg_advertised & ADVERTISE_100_FULL)
adv4 |= MII_AR_100TX_FD_CAPS;
if (hw->autoneg_advertised & ADVERTISE_1000_FULL)
adv9 |= MII_AT001_CR_1000T_FD_CAPS;
if (adv4 != hw->mii_autoneg_adv_reg ||
adv9 != hw->mii_1000t_ctrl_reg) {
hw->mii_autoneg_adv_reg = adv4;
hw->mii_1000t_ctrl_reg = adv9;
hw->re_autoneg = true;
}
} else {
clear_bit(__AT_RESETTING, &adapter->flags);
return -EINVAL;
}
/* reset the link */
if (netif_running(adapter->netdev)) {
atl1e_down(adapter);
atl1e_up(adapter);
} else
atl1e_reset_hw(&adapter->hw);
clear_bit(__AT_RESETTING, &adapter->flags);
return 0;
}
static u32 atl1e_get_tx_csum(struct net_device *netdev)
{
return (netdev->features & NETIF_F_HW_CSUM) != 0;
}
static u32 atl1e_get_msglevel(struct net_device *netdev)
{
#ifdef DBG
return 1;
#else
return 0;
#endif
}
static void atl1e_set_msglevel(struct net_device *netdev, u32 data)
{
}
static int atl1e_get_regs_len(struct net_device *netdev)
{
return AT_REGS_LEN * sizeof(u32);
}
static void atl1e_get_regs(struct net_device *netdev,
struct ethtool_regs *regs, void *p)
{
struct atl1e_adapter *adapter = netdev_priv(netdev);
struct atl1e_hw *hw = &adapter->hw;
u32 *regs_buff = p;
u16 phy_data;
memset(p, 0, AT_REGS_LEN * sizeof(u32));
regs->version = (1 << 24) | (hw->revision_id << 16) | hw->device_id;
regs_buff[0] = AT_READ_REG(hw, REG_VPD_CAP);
regs_buff[1] = AT_READ_REG(hw, REG_SPI_FLASH_CTRL);
regs_buff[2] = AT_READ_REG(hw, REG_SPI_FLASH_CONFIG);
regs_buff[3] = AT_READ_REG(hw, REG_TWSI_CTRL);
regs_buff[4] = AT_READ_REG(hw, REG_PCIE_DEV_MISC_CTRL);
regs_buff[5] = AT_READ_REG(hw, REG_MASTER_CTRL);
regs_buff[6] = AT_READ_REG(hw, REG_MANUAL_TIMER_INIT);
regs_buff[7] = AT_READ_REG(hw, REG_IRQ_MODU_TIMER_INIT);
regs_buff[8] = AT_READ_REG(hw, REG_GPHY_CTRL);
regs_buff[9] = AT_READ_REG(hw, REG_CMBDISDMA_TIMER);
regs_buff[10] = AT_READ_REG(hw, REG_IDLE_STATUS);
regs_buff[11] = AT_READ_REG(hw, REG_MDIO_CTRL);
regs_buff[12] = AT_READ_REG(hw, REG_SERDES_LOCK);
regs_buff[13] = AT_READ_REG(hw, REG_MAC_CTRL);
regs_buff[14] = AT_READ_REG(hw, REG_MAC_IPG_IFG);
regs_buff[15] = AT_READ_REG(hw, REG_MAC_STA_ADDR);
regs_buff[16] = AT_READ_REG(hw, REG_MAC_STA_ADDR+4);
regs_buff[17] = AT_READ_REG(hw, REG_RX_HASH_TABLE);
regs_buff[18] = AT_READ_REG(hw, REG_RX_HASH_TABLE+4);
regs_buff[19] = AT_READ_REG(hw, REG_MAC_HALF_DUPLX_CTRL);
regs_buff[20] = AT_READ_REG(hw, REG_MTU);
regs_buff[21] = AT_READ_REG(hw, REG_WOL_CTRL);
regs_buff[22] = AT_READ_REG(hw, REG_SRAM_TRD_ADDR);
regs_buff[23] = AT_READ_REG(hw, REG_SRAM_TRD_LEN);
regs_buff[24] = AT_READ_REG(hw, REG_SRAM_RXF_ADDR);
regs_buff[25] = AT_READ_REG(hw, REG_SRAM_RXF_LEN);
regs_buff[26] = AT_READ_REG(hw, REG_SRAM_TXF_ADDR);
regs_buff[27] = AT_READ_REG(hw, REG_SRAM_TXF_LEN);
regs_buff[28] = AT_READ_REG(hw, REG_SRAM_TCPH_ADDR);
regs_buff[29] = AT_READ_REG(hw, REG_SRAM_PKTH_ADDR);
atl1e_read_phy_reg(hw, MII_BMCR, &phy_data);
regs_buff[73] = (u32)phy_data;
atl1e_read_phy_reg(hw, MII_BMSR, &phy_data);
regs_buff[74] = (u32)phy_data;
}
static int atl1e_get_eeprom_len(struct net_device *netdev)
{
struct atl1e_adapter *adapter = netdev_priv(netdev);
if (!atl1e_check_eeprom_exist(&adapter->hw))
return AT_EEPROM_LEN;
else
return 0;
}
static int atl1e_get_eeprom(struct net_device *netdev,
struct ethtool_eeprom *eeprom, u8 *bytes)
{
struct atl1e_adapter *adapter = netdev_priv(netdev);
struct atl1e_hw *hw = &adapter->hw;
u32 *eeprom_buff;
int first_dword, last_dword;
int ret_val = 0;
int i;
if (eeprom->len == 0)
return -EINVAL;
if (atl1e_check_eeprom_exist(hw)) /* not exist */
return -EINVAL;
eeprom->magic = hw->vendor_id | (hw->device_id << 16);
first_dword = eeprom->offset >> 2;
last_dword = (eeprom->offset + eeprom->len - 1) >> 2;
eeprom_buff = kmalloc(sizeof(u32) *
(last_dword - first_dword + 1), GFP_KERNEL);
if (eeprom_buff == NULL)
return -ENOMEM;
for (i = first_dword; i < last_dword; i++) {
if (!atl1e_read_eeprom(hw, i * 4, &(eeprom_buff[i-first_dword]))) {
kfree(eeprom_buff);
return -EIO;
}
}
memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 3),
eeprom->len);
kfree(eeprom_buff);
return ret_val;
}
static int atl1e_set_eeprom(struct net_device *netdev,
struct ethtool_eeprom *eeprom, u8 *bytes)
{
struct atl1e_adapter *adapter = netdev_priv(netdev);
struct atl1e_hw *hw = &adapter->hw;
u32 *eeprom_buff;
u32 *ptr;
int first_dword, last_dword;
int ret_val = 0;
int i;
if (eeprom->len == 0)
return -EOPNOTSUPP;
if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
return -EINVAL;
first_dword = eeprom->offset >> 2;
last_dword = (eeprom->offset + eeprom->len - 1) >> 2;
eeprom_buff = kmalloc(AT_EEPROM_LEN, GFP_KERNEL);
if (eeprom_buff == NULL)
return -ENOMEM;
ptr = (u32 *)eeprom_buff;
if (eeprom->offset & 3) {
/* need read/modify/write of first changed EEPROM word */
/* only the second byte of the word is being modified */
if (!atl1e_read_eeprom(hw, first_dword * 4, &(eeprom_buff[0]))) {
ret_val = -EIO;
goto out;
}
ptr++;
}
if (((eeprom->offset + eeprom->len) & 3)) {
/* need read/modify/write of last changed EEPROM word */
/* only the first byte of the word is being modified */
if (!atl1e_read_eeprom(hw, last_dword * 4,
&(eeprom_buff[last_dword - first_dword]))) {
ret_val = -EIO;
goto out;
}
}
/* Device's eeprom is always little-endian, word addressable */
memcpy(ptr, bytes, eeprom->len);
for (i = 0; i < last_dword - first_dword + 1; i++) {
if (!atl1e_write_eeprom(hw, ((first_dword + i) * 4),
eeprom_buff[i])) {
ret_val = -EIO;
goto out;
}
}
out:
kfree(eeprom_buff);
return ret_val;
}
static void atl1e_get_drvinfo(struct net_device *netdev,
struct ethtool_drvinfo *drvinfo)
{
struct atl1e_adapter *adapter = netdev_priv(netdev);
strncpy(drvinfo->driver, atl1e_driver_name, 32);
strncpy(drvinfo->version, atl1e_driver_version, 32);
strncpy(drvinfo->fw_version, "L1e", 32);
strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
drvinfo->n_stats = 0;
drvinfo->testinfo_len = 0;
drvinfo->regdump_len = atl1e_get_regs_len(netdev);
drvinfo->eedump_len = atl1e_get_eeprom_len(netdev);
}
static void atl1e_get_wol(struct net_device *netdev,
struct ethtool_wolinfo *wol)
{
struct atl1e_adapter *adapter = netdev_priv(netdev);
wol->supported = WAKE_MAGIC | WAKE_PHY;
wol->wolopts = 0;
if (adapter->wol & AT_WUFC_EX)
wol->wolopts |= WAKE_UCAST;
if (adapter->wol & AT_WUFC_MC)
wol->wolopts |= WAKE_MCAST;
if (adapter->wol & AT_WUFC_BC)
wol->wolopts |= WAKE_BCAST;
if (adapter->wol & AT_WUFC_MAG)
wol->wolopts |= WAKE_MAGIC;
if (adapter->wol & AT_WUFC_LNKC)
wol->wolopts |= WAKE_PHY;
return;
}
static int atl1e_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
{
struct atl1e_adapter *adapter = netdev_priv(netdev);
if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE |
WAKE_MCAST | WAKE_BCAST | WAKE_MCAST))
return -EOPNOTSUPP;
/* these settings will always override what we currently have */
adapter->wol = 0;
if (wol->wolopts & WAKE_MAGIC)
adapter->wol |= AT_WUFC_MAG;
if (wol->wolopts & WAKE_PHY)
adapter->wol |= AT_WUFC_LNKC;
return 0;
}
static int atl1e_nway_reset(struct net_device *netdev)
{
struct atl1e_adapter *adapter = netdev_priv(netdev);
if (netif_running(netdev))
atl1e_reinit_locked(adapter);
return 0;
}
static struct ethtool_ops atl1e_ethtool_ops = {
.get_settings = atl1e_get_settings,
.set_settings = atl1e_set_settings,
.get_drvinfo = atl1e_get_drvinfo,
.get_regs_len = atl1e_get_regs_len,
.get_regs = atl1e_get_regs,
.get_wol = atl1e_get_wol,
.set_wol = atl1e_set_wol,
.get_msglevel = atl1e_get_msglevel,
.set_msglevel = atl1e_set_msglevel,
.nway_reset = atl1e_nway_reset,
.get_link = ethtool_op_get_link,
.get_eeprom_len = atl1e_get_eeprom_len,
.get_eeprom = atl1e_get_eeprom,
.set_eeprom = atl1e_set_eeprom,
.get_tx_csum = atl1e_get_tx_csum,
.get_sg = ethtool_op_get_sg,
.set_sg = ethtool_op_set_sg,
#ifdef NETIF_F_TSO
.get_tso = ethtool_op_get_tso,
#endif
};
void atl1e_set_ethtool_ops(struct net_device *netdev)
{
SET_ETHTOOL_OPS(netdev, &atl1e_ethtool_ops);
}
/*
* Copyright(c) 2007 Atheros Corporation. All rights reserved.
*
* Derived from Intel e1000 driver
* Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/mii.h>
#include <linux/crc32.h>
#include "atl1e.h"
/*
* check_eeprom_exist
* return 0 if eeprom exist
*/
int atl1e_check_eeprom_exist(struct atl1e_hw *hw)
{
u32 value;
value = AT_READ_REG(hw, REG_SPI_FLASH_CTRL);
if (value & SPI_FLASH_CTRL_EN_VPD) {
value &= ~SPI_FLASH_CTRL_EN_VPD;
AT_WRITE_REG(hw, REG_SPI_FLASH_CTRL, value);
}
value = AT_READ_REGW(hw, REG_PCIE_CAP_LIST);
return ((value & 0xFF00) == 0x6C00) ? 0 : 1;
}
void atl1e_hw_set_mac_addr(struct atl1e_hw *hw)
{
u32 value;
/*
* 00-0B-6A-F6-00-DC
* 0: 6AF600DC 1: 000B
* low dword
*/
value = (((u32)hw->mac_addr[2]) << 24) |
(((u32)hw->mac_addr[3]) << 16) |
(((u32)hw->mac_addr[4]) << 8) |
(((u32)hw->mac_addr[5])) ;
AT_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 0, value);
/* hight dword */
value = (((u32)hw->mac_addr[0]) << 8) |
(((u32)hw->mac_addr[1])) ;
AT_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 1, value);
}
/*
* atl1e_get_permanent_address
* return 0 if get valid mac address,
*/
static int atl1e_get_permanent_address(struct atl1e_hw *hw)
{
u32 addr[2];
u32 i;
u32 twsi_ctrl_data;
u8 eth_addr[ETH_ALEN];
if (is_valid_ether_addr(hw->perm_mac_addr))
return 0;
/* init */
addr[0] = addr[1] = 0;
if (!atl1e_check_eeprom_exist(hw)) {
/* eeprom exist */
twsi_ctrl_data = AT_READ_REG(hw, REG_TWSI_CTRL);
twsi_ctrl_data |= TWSI_CTRL_SW_LDSTART;
AT_WRITE_REG(hw, REG_TWSI_CTRL, twsi_ctrl_data);
for (i = 0; i < AT_TWSI_EEPROM_TIMEOUT; i++) {
msleep(10);
twsi_ctrl_data = AT_READ_REG(hw, REG_TWSI_CTRL);
if ((twsi_ctrl_data & TWSI_CTRL_SW_LDSTART) == 0)
break;
}
if (i >= AT_TWSI_EEPROM_TIMEOUT)
return AT_ERR_TIMEOUT;
}
/* maybe MAC-address is from BIOS */
addr[0] = AT_READ_REG(hw, REG_MAC_STA_ADDR);
addr[1] = AT_READ_REG(hw, REG_MAC_STA_ADDR + 4);
*(u32 *) &eth_addr[2] = swab32(addr[0]);
*(u16 *) &eth_addr[0] = swab16(*(u16 *)&addr[1]);
if (is_valid_ether_addr(eth_addr)) {
memcpy(hw->perm_mac_addr, eth_addr, ETH_ALEN);
return 0;
}
return AT_ERR_EEPROM;
}
bool atl1e_write_eeprom(struct atl1e_hw *hw, u32 offset, u32 value)
{
return true;
}
bool atl1e_read_eeprom(struct atl1e_hw *hw, u32 offset, u32 *p_value)
{
int i;
u32 control;
if (offset & 3)
return false; /* address do not align */
AT_WRITE_REG(hw, REG_VPD_DATA, 0);
control = (offset & VPD_CAP_VPD_ADDR_MASK) << VPD_CAP_VPD_ADDR_SHIFT;
AT_WRITE_REG(hw, REG_VPD_CAP, control);
for (i = 0; i < 10; i++) {
msleep(2);
control = AT_READ_REG(hw, REG_VPD_CAP);
if (control & VPD_CAP_VPD_FLAG)
break;
}
if (control & VPD_CAP_VPD_FLAG) {
*p_value = AT_READ_REG(hw, REG_VPD_DATA);
return true;
}
return false; /* timeout */
}
void atl1e_force_ps(struct atl1e_hw *hw)
{
AT_WRITE_REGW(hw, REG_GPHY_CTRL,
GPHY_CTRL_PW_WOL_DIS | GPHY_CTRL_EXT_RESET);
}
/*
* Reads the adapter's MAC address from the EEPROM
*
* hw - Struct containing variables accessed by shared code
*/
int atl1e_read_mac_addr(struct atl1e_hw *hw)
{
int err = 0;
err = atl1e_get_permanent_address(hw);
if (err)
return AT_ERR_EEPROM;
memcpy(hw->mac_addr, hw->perm_mac_addr, sizeof(hw->perm_mac_addr));
return 0;
}
/*
* atl1e_hash_mc_addr
* purpose
* set hash value for a multicast address
* hash calcu processing :
* 1. calcu 32bit CRC for multicast address
* 2. reverse crc with MSB to LSB
*/
u32 atl1e_hash_mc_addr(struct atl1e_hw *hw, u8 *mc_addr)
{
u32 crc32;
u32 value = 0;
int i;
crc32 = ether_crc_le(6, mc_addr);
crc32 = ~crc32;
for (i = 0; i < 32; i++)
value |= (((crc32 >> i) & 1) << (31 - i));
return value;
}
/*
* Sets the bit in the multicast table corresponding to the hash value.
* hw - Struct containing variables accessed by shared code
* hash_value - Multicast address hash value
*/
void atl1e_hash_set(struct atl1e_hw *hw, u32 hash_value)
{
u32 hash_bit, hash_reg;
u32 mta;
/*
* The HASH Table is a register array of 2 32-bit registers.
* It is treated like an array of 64 bits. We want to set
* bit BitArray[hash_value]. So we figure out what register
* the bit is in, read it, OR in the new bit, then write
* back the new value. The register is determined by the
* upper 7 bits of the hash value and the bit within that
* register are determined by the lower 5 bits of the value.
*/
hash_reg = (hash_value >> 31) & 0x1;
hash_bit = (hash_value >> 26) & 0x1F;
mta = AT_READ_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg);
mta |= (1 << hash_bit);
AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg, mta);
}
/*
* Reads the value from a PHY register
* hw - Struct containing variables accessed by shared code
* reg_addr - address of the PHY register to read
*/
int atl1e_read_phy_reg(struct atl1e_hw *hw, u16 reg_addr, u16 *phy_data)
{
u32 val;
int i;
val = ((u32)(reg_addr & MDIO_REG_ADDR_MASK)) << MDIO_REG_ADDR_SHIFT |
MDIO_START | MDIO_SUP_PREAMBLE | MDIO_RW |
MDIO_CLK_25_4 << MDIO_CLK_SEL_SHIFT;
AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
wmb();
for (i = 0; i < MDIO_WAIT_TIMES; i++) {
udelay(2);
val = AT_READ_REG(hw, REG_MDIO_CTRL);
if (!(val & (MDIO_START | MDIO_BUSY)))
break;
wmb();
}
if (!(val & (MDIO_START | MDIO_BUSY))) {
*phy_data = (u16)val;
return 0;
}
return AT_ERR_PHY;
}
/*
* Writes a value to a PHY register
* hw - Struct containing variables accessed by shared code
* reg_addr - address of the PHY register to write
* data - data to write to the PHY
*/
int atl1e_write_phy_reg(struct atl1e_hw *hw, u32 reg_addr, u16 phy_data)
{
int i;
u32 val;
val = ((u32)(phy_data & MDIO_DATA_MASK)) << MDIO_DATA_SHIFT |
(reg_addr&MDIO_REG_ADDR_MASK) << MDIO_REG_ADDR_SHIFT |
MDIO_SUP_PREAMBLE |
MDIO_START |
MDIO_CLK_25_4 << MDIO_CLK_SEL_SHIFT;
AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
wmb();
for (i = 0; i < MDIO_WAIT_TIMES; i++) {
udelay(2);
val = AT_READ_REG(hw, REG_MDIO_CTRL);
if (!(val & (MDIO_START | MDIO_BUSY)))
break;
wmb();
}
if (!(val & (MDIO_START | MDIO_BUSY)))
return 0;
return AT_ERR_PHY;
}
/*
* atl1e_init_pcie - init PCIE module
*/
static void atl1e_init_pcie(struct atl1e_hw *hw)
{
u32 value;
/* comment 2lines below to save more power when sususpend
value = LTSSM_TEST_MODE_DEF;
AT_WRITE_REG(hw, REG_LTSSM_TEST_MODE, value);
*/
/* pcie flow control mode change */
value = AT_READ_REG(hw, 0x1008);
value |= 0x8000;
AT_WRITE_REG(hw, 0x1008, value);
}
/*
* Configures PHY autoneg and flow control advertisement settings
*
* hw - Struct containing variables accessed by shared code
*/
static int atl1e_phy_setup_autoneg_adv(struct atl1e_hw *hw)
{
s32 ret_val;
u16 mii_autoneg_adv_reg;
u16 mii_1000t_ctrl_reg;
if (0 != hw->mii_autoneg_adv_reg)
return 0;
/* Read the MII Auto-Neg Advertisement Register (Address 4/9). */
mii_autoneg_adv_reg = MII_AR_DEFAULT_CAP_MASK;
mii_1000t_ctrl_reg = MII_AT001_CR_1000T_DEFAULT_CAP_MASK;
/*
* Need to parse autoneg_advertised and set up
* the appropriate PHY registers. First we will parse for
* autoneg_advertised software override. Since we can advertise
* a plethora of combinations, we need to check each bit
* individually.
*/
/*
* First we clear all the 10/100 mb speed bits in the Auto-Neg
* Advertisement Register (Address 4) and the 1000 mb speed bits in
* the 1000Base-T control Register (Address 9).
*/
mii_autoneg_adv_reg &= ~MII_AR_SPEED_MASK;
mii_1000t_ctrl_reg &= ~MII_AT001_CR_1000T_SPEED_MASK;
/*
* Need to parse MediaType and setup the
* appropriate PHY registers.
*/
switch (hw->media_type) {
case MEDIA_TYPE_AUTO_SENSOR:
mii_autoneg_adv_reg |= (MII_AR_10T_HD_CAPS |
MII_AR_10T_FD_CAPS |
MII_AR_100TX_HD_CAPS |
MII_AR_100TX_FD_CAPS);
hw->autoneg_advertised = ADVERTISE_10_HALF |
ADVERTISE_10_FULL |
ADVERTISE_100_HALF |
ADVERTISE_100_FULL;
if (hw->nic_type == athr_l1e) {
mii_1000t_ctrl_reg |=
MII_AT001_CR_1000T_FD_CAPS;
hw->autoneg_advertised |= ADVERTISE_1000_FULL;
}
break;
case MEDIA_TYPE_100M_FULL:
mii_autoneg_adv_reg |= MII_AR_100TX_FD_CAPS;
hw->autoneg_advertised = ADVERTISE_100_FULL;
break;
case MEDIA_TYPE_100M_HALF:
mii_autoneg_adv_reg |= MII_AR_100TX_HD_CAPS;
hw->autoneg_advertised = ADVERTISE_100_HALF;
break;
case MEDIA_TYPE_10M_FULL:
mii_autoneg_adv_reg |= MII_AR_10T_FD_CAPS;
hw->autoneg_advertised = ADVERTISE_10_FULL;
break;
default:
mii_autoneg_adv_reg |= MII_AR_10T_HD_CAPS;
hw->autoneg_advertised = ADVERTISE_10_HALF;
break;
}
/* flow control fixed to enable all */
mii_autoneg_adv_reg |= (MII_AR_ASM_DIR | MII_AR_PAUSE);
hw->mii_autoneg_adv_reg = mii_autoneg_adv_reg;
hw->mii_1000t_ctrl_reg = mii_1000t_ctrl_reg;
ret_val = atl1e_write_phy_reg(hw, MII_ADVERTISE, mii_autoneg_adv_reg);
if (ret_val)
return ret_val;
if (hw->nic_type == athr_l1e || hw->nic_type == athr_l2e_revA) {
ret_val = atl1e_write_phy_reg(hw, MII_AT001_CR,
mii_1000t_ctrl_reg);
if (ret_val)
return ret_val;
}
return 0;
}
/*
* Resets the PHY and make all config validate
*
* hw - Struct containing variables accessed by shared code
*
* Sets bit 15 and 12 of the MII control regiser (for F001 bug)
*/
int atl1e_phy_commit(struct atl1e_hw *hw)
{
struct atl1e_adapter *adapter = (struct atl1e_adapter *)hw->adapter;
struct pci_dev *pdev = adapter->pdev;
int ret_val;
u16 phy_data;
phy_data = MII_CR_RESET | MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG;
ret_val = atl1e_write_phy_reg(hw, MII_BMCR, phy_data);
if (ret_val) {
u32 val;
int i;
/**************************************
* pcie serdes link may be down !
**************************************/
for (i = 0; i < 25; i++) {
msleep(1);
val = AT_READ_REG(hw, REG_MDIO_CTRL);
if (!(val & (MDIO_START | MDIO_BUSY)))
break;
}
if (0 != (val & (MDIO_START | MDIO_BUSY))) {
dev_err(&pdev->dev,
"pcie linkdown at least for 25ms\n");
return ret_val;
}
dev_err(&pdev->dev, "pcie linkup after %d ms\n", i);
}
return 0;
}
int atl1e_phy_init(struct atl1e_hw *hw)
{
struct atl1e_adapter *adapter = (struct atl1e_adapter *)hw->adapter;
struct pci_dev *pdev = adapter->pdev;
s32 ret_val;
u16 phy_val;
if (hw->phy_configured) {
if (hw->re_autoneg) {
hw->re_autoneg = false;
return atl1e_restart_autoneg(hw);
}
return 0;
}
/* RESET GPHY Core */
AT_WRITE_REGW(hw, REG_GPHY_CTRL, GPHY_CTRL_DEFAULT);
msleep(2);
AT_WRITE_REGW(hw, REG_GPHY_CTRL, GPHY_CTRL_DEFAULT |
GPHY_CTRL_EXT_RESET);
msleep(2);
/* patches */
/* p1. eable hibernation mode */
ret_val = atl1e_write_phy_reg(hw, MII_DBG_ADDR, 0xB);
if (ret_val)
return ret_val;
ret_val = atl1e_write_phy_reg(hw, MII_DBG_DATA, 0xBC00);
if (ret_val)
return ret_val;
/* p2. set Class A/B for all modes */
ret_val = atl1e_write_phy_reg(hw, MII_DBG_ADDR, 0);
if (ret_val)
return ret_val;
phy_val = 0x02ef;
/* remove Class AB */
/* phy_val = hw->emi_ca ? 0x02ef : 0x02df; */
ret_val = atl1e_write_phy_reg(hw, MII_DBG_DATA, phy_val);
if (ret_val)
return ret_val;
/* p3. 10B ??? */
ret_val = atl1e_write_phy_reg(hw, MII_DBG_ADDR, 0x12);
if (ret_val)
return ret_val;
ret_val = atl1e_write_phy_reg(hw, MII_DBG_DATA, 0x4C04);
if (ret_val)
return ret_val;
/* p4. 1000T power */
ret_val = atl1e_write_phy_reg(hw, MII_DBG_ADDR, 0x4);
if (ret_val)
return ret_val;
ret_val = atl1e_write_phy_reg(hw, MII_DBG_DATA, 0x8BBB);
if (ret_val)
return ret_val;
ret_val = atl1e_write_phy_reg(hw, MII_DBG_ADDR, 0x5);
if (ret_val)
return ret_val;
ret_val = atl1e_write_phy_reg(hw, MII_DBG_DATA, 0x2C46);
if (ret_val)
return ret_val;
msleep(1);
/*Enable PHY LinkChange Interrupt */
ret_val = atl1e_write_phy_reg(hw, MII_INT_CTRL, 0xC00);
if (ret_val) {
dev_err(&pdev->dev, "Error enable PHY linkChange Interrupt\n");
return ret_val;
}
/* setup AutoNeg parameters */
ret_val = atl1e_phy_setup_autoneg_adv(hw);
if (ret_val) {
dev_err(&pdev->dev, "Error Setting up Auto-Negotiation\n");
return ret_val;
}
/* SW.Reset & En-Auto-Neg to restart Auto-Neg*/
dev_dbg(&pdev->dev, "Restarting Auto-Neg");
ret_val = atl1e_phy_commit(hw);
if (ret_val) {
dev_err(&pdev->dev, "Error Resetting the phy");
return ret_val;
}
hw->phy_configured = true;
return 0;
}
/*
* Reset the transmit and receive units; mask and clear all interrupts.
* hw - Struct containing variables accessed by shared code
* return : 0 or idle status (if error)
*/
int atl1e_reset_hw(struct atl1e_hw *hw)
{
struct atl1e_adapter *adapter = (struct atl1e_adapter *)hw->adapter;
struct pci_dev *pdev = adapter->pdev;
u32 idle_status_data = 0;
u16 pci_cfg_cmd_word = 0;
int timeout = 0;
/* Workaround for PCI problem when BIOS sets MMRBC incorrectly. */
pci_read_config_word(pdev, PCI_REG_COMMAND, &pci_cfg_cmd_word);
if ((pci_cfg_cmd_word & (CMD_IO_SPACE |
CMD_MEMORY_SPACE | CMD_BUS_MASTER))
!= (CMD_IO_SPACE | CMD_MEMORY_SPACE | CMD_BUS_MASTER)) {
pci_cfg_cmd_word |= (CMD_IO_SPACE |
CMD_MEMORY_SPACE | CMD_BUS_MASTER);
pci_write_config_word(pdev, PCI_REG_COMMAND, pci_cfg_cmd_word);
}
/*
* Issue Soft Reset to the MAC. This will reset the chip's
* transmit, receive, DMA. It will not effect
* the current PCI configuration. The global reset bit is self-
* clearing, and should clear within a microsecond.
*/
AT_WRITE_REG(hw, REG_MASTER_CTRL,
MASTER_CTRL_LED_MODE | MASTER_CTRL_SOFT_RST);
wmb();
msleep(1);
/* Wait at least 10ms for All module to be Idle */
for (timeout = 0; timeout < AT_HW_MAX_IDLE_DELAY; timeout++) {
idle_status_data = AT_READ_REG(hw, REG_IDLE_STATUS);
if (idle_status_data == 0)
break;
msleep(1);
cpu_relax();
}
if (timeout >= AT_HW_MAX_IDLE_DELAY) {
dev_err(&pdev->dev,
"MAC state machine cann't be idle since"
" disabled for 10ms second\n");
return AT_ERR_TIMEOUT;
}
return 0;
}
/*
* Performs basic configuration of the adapter.
*
* hw - Struct containing variables accessed by shared code
* Assumes that the controller has previously been reset and is in a
* post-reset uninitialized state. Initializes multicast table,
* and Calls routines to setup link
* Leaves the transmit and receive units disabled and uninitialized.
*/
int atl1e_init_hw(struct atl1e_hw *hw)
{
s32 ret_val = 0;
atl1e_init_pcie(hw);
/* Zero out the Multicast HASH table */
/* clear the old settings from the multicast hash table */
AT_WRITE_REG(hw, REG_RX_HASH_TABLE, 0);
AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0);
ret_val = atl1e_phy_init(hw);
return ret_val;
}
/*
* Detects the current speed and duplex settings of the hardware.
*
* hw - Struct containing variables accessed by shared code
* speed - Speed of the connection
* duplex - Duplex setting of the connection
*/
int atl1e_get_speed_and_duplex(struct atl1e_hw *hw, u16 *speed, u16 *duplex)
{
int err;
u16 phy_data;
/* Read PHY Specific Status Register (17) */
err = atl1e_read_phy_reg(hw, MII_AT001_PSSR, &phy_data);
if (err)
return err;
if (!(phy_data & MII_AT001_PSSR_SPD_DPLX_RESOLVED))
return AT_ERR_PHY_RES;
switch (phy_data & MII_AT001_PSSR_SPEED) {
case MII_AT001_PSSR_1000MBS:
*speed = SPEED_1000;
break;
case MII_AT001_PSSR_100MBS:
*speed = SPEED_100;
break;
case MII_AT001_PSSR_10MBS:
*speed = SPEED_10;
break;
default:
return AT_ERR_PHY_SPEED;
break;
}
if (phy_data & MII_AT001_PSSR_DPLX)
*duplex = FULL_DUPLEX;
else
*duplex = HALF_DUPLEX;
return 0;
}
int atl1e_restart_autoneg(struct atl1e_hw *hw)
{
int err = 0;
err = atl1e_write_phy_reg(hw, MII_ADVERTISE, hw->mii_autoneg_adv_reg);
if (err)
return err;
if (hw->nic_type == athr_l1e || hw->nic_type == athr_l2e_revA) {
err = atl1e_write_phy_reg(hw, MII_AT001_CR,
hw->mii_1000t_ctrl_reg);
if (err)
return err;
}
err = atl1e_write_phy_reg(hw, MII_BMCR,
MII_CR_RESET | MII_CR_AUTO_NEG_EN |
MII_CR_RESTART_AUTO_NEG);
return err;
}
此差异已折叠。
此差异已折叠。
/*
* Copyright(c) 2007 Atheros Corporation. All rights reserved.
*
* Derived from Intel e1000 driver
* Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/netdevice.h>
#include "atl1e.h"
/* This is the only thing that needs to be changed to adjust the
* maximum number of ports that the driver can manage.
*/
#define ATL1E_MAX_NIC 32
#define OPTION_UNSET -1
#define OPTION_DISABLED 0
#define OPTION_ENABLED 1
/* All parameters are treated the same, as an integer array of values.
* This macro just reduces the need to repeat the same declaration code
* over and over (plus this helps to avoid typo bugs).
*/
#define ATL1E_PARAM_INIT { [0 ... ATL1E_MAX_NIC] = OPTION_UNSET }
#define ATL1E_PARAM(x, desc) \
static int __devinitdata x[ATL1E_MAX_NIC + 1] = ATL1E_PARAM_INIT; \
static int num_##x; \
module_param_array_named(x, x, int, &num_##x, 0); \
MODULE_PARM_DESC(x, desc);
/* Transmit Memory count
*
* Valid Range: 64-2048
*
* Default Value: 128
*/
#define ATL1E_MIN_TX_DESC_CNT 32
#define ATL1E_MAX_TX_DESC_CNT 1020
#define ATL1E_DEFAULT_TX_DESC_CNT 128
ATL1E_PARAM(tx_desc_cnt, "Transmit description count");
/* Receive Memory Block Count
*
* Valid Range: 16-512
*
* Default Value: 128
*/
#define ATL1E_MIN_RX_MEM_SIZE 8 /* 8KB */
#define ATL1E_MAX_RX_MEM_SIZE 1024 /* 1MB */
#define ATL1E_DEFAULT_RX_MEM_SIZE 256 /* 128KB */
ATL1E_PARAM(rx_mem_size, "memory size of rx buffer(KB)");
/* User Specified MediaType Override
*
* Valid Range: 0-5
* - 0 - auto-negotiate at all supported speeds
* - 1 - only link at 100Mbps Full Duplex
* - 2 - only link at 100Mbps Half Duplex
* - 3 - only link at 10Mbps Full Duplex
* - 4 - only link at 10Mbps Half Duplex
* Default Value: 0
*/
ATL1E_PARAM(media_type, "MediaType Select");
/* Interrupt Moderate Timer in units of 2 us
*
* Valid Range: 10-65535
*
* Default Value: 45000(90ms)
*/
#define INT_MOD_DEFAULT_CNT 100 /* 200us */
#define INT_MOD_MAX_CNT 65000
#define INT_MOD_MIN_CNT 50
ATL1E_PARAM(int_mod_timer, "Interrupt Moderator Timer");
#define AUTONEG_ADV_DEFAULT 0x2F
#define AUTONEG_ADV_MASK 0x2F
#define FLOW_CONTROL_DEFAULT FLOW_CONTROL_FULL
#define FLASH_VENDOR_DEFAULT 0
#define FLASH_VENDOR_MIN 0
#define FLASH_VENDOR_MAX 2
struct atl1e_option {
enum { enable_option, range_option, list_option } type;
char *name;
char *err;
int def;
union {
struct { /* range_option info */
int min;
int max;
} r;
struct { /* list_option info */
int nr;
struct atl1e_opt_list { int i; char *str; } *p;
} l;
} arg;
};
static int __devinit atl1e_validate_option(int *value, struct atl1e_option *opt, struct pci_dev *pdev)
{
if (*value == OPTION_UNSET) {
*value = opt->def;
return 0;
}
switch (opt->type) {
case enable_option:
switch (*value) {
case OPTION_ENABLED:
dev_info(&pdev->dev, "%s Enabled\n", opt->name);
return 0;
case OPTION_DISABLED:
dev_info(&pdev->dev, "%s Disabled\n", opt->name);
return 0;
}
break;
case range_option:
if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
dev_info(&pdev->dev, "%s set to %i\n", opt->name, *value);
return 0;
}
break;
case list_option:{
int i;
struct atl1e_opt_list *ent;
for (i = 0; i < opt->arg.l.nr; i++) {
ent = &opt->arg.l.p[i];
if (*value == ent->i) {
if (ent->str[0] != '\0')
dev_info(&pdev->dev, "%s\n",
ent->str);
return 0;
}
}
break;
}
default:
BUG();
}
dev_info(&pdev->dev, "Invalid %s specified (%i) %s\n",
opt->name, *value, opt->err);
*value = opt->def;
return -1;
}
/*
* atl1e_check_options - Range Checking for Command Line Parameters
* @adapter: board private structure
*
* This routine checks all command line parameters for valid user
* input. If an invalid value is given, or if no user specified
* value exists, a default value is used. The final value is stored
* in a variable in the adapter structure.
*/
void __devinit atl1e_check_options(struct atl1e_adapter *adapter)
{
struct pci_dev *pdev = adapter->pdev;
int bd = adapter->bd_number;
if (bd >= ATL1E_MAX_NIC) {
dev_notice(&pdev->dev, "no configuration for board #%i\n", bd);
dev_notice(&pdev->dev, "Using defaults for all values\n");
}
{ /* Transmit Ring Size */
struct atl1e_option opt = {
.type = range_option,
.name = "Transmit Ddescription Count",
.err = "using default of "
__MODULE_STRING(ATL1E_DEFAULT_TX_DESC_CNT),
.def = ATL1E_DEFAULT_TX_DESC_CNT,
.arg = { .r = { .min = ATL1E_MIN_TX_DESC_CNT,
.max = ATL1E_MAX_TX_DESC_CNT} }
};
int val;
if (num_tx_desc_cnt > bd) {
val = tx_desc_cnt[bd];
atl1e_validate_option(&val, &opt, pdev);
adapter->tx_ring.count = (u16) val & 0xFFFC;
} else
adapter->tx_ring.count = (u16)opt.def;
}
{ /* Receive Memory Block Count */
struct atl1e_option opt = {
.type = range_option,
.name = "Memory size of rx buffer(KB)",
.err = "using default of "
__MODULE_STRING(ATL1E_DEFAULT_RX_MEM_SIZE),
.def = ATL1E_DEFAULT_RX_MEM_SIZE,
.arg = { .r = { .min = ATL1E_MIN_RX_MEM_SIZE,
.max = ATL1E_MAX_RX_MEM_SIZE} }
};
int val;
if (num_rx_mem_size > bd) {
val = rx_mem_size[bd];
atl1e_validate_option(&val, &opt, pdev);
adapter->rx_ring.page_size = (u32)val * 1024;
} else {
adapter->rx_ring.page_size = (u32)opt.def * 1024;
}
}
{ /* Interrupt Moderate Timer */
struct atl1e_option opt = {
.type = range_option,
.name = "Interrupt Moderate Timer",
.err = "using default of "
__MODULE_STRING(INT_MOD_DEFAULT_CNT),
.def = INT_MOD_DEFAULT_CNT,
.arg = { .r = { .min = INT_MOD_MIN_CNT,
.max = INT_MOD_MAX_CNT} }
} ;
int val;
if (num_int_mod_timer > bd) {
val = int_mod_timer[bd];
atl1e_validate_option(&val, &opt, pdev);
adapter->hw.imt = (u16) val;
} else
adapter->hw.imt = (u16)(opt.def);
}
{ /* MediaType */
struct atl1e_option opt = {
.type = range_option,
.name = "Speed/Duplex Selection",
.err = "using default of "
__MODULE_STRING(MEDIA_TYPE_AUTO_SENSOR),
.def = MEDIA_TYPE_AUTO_SENSOR,
.arg = { .r = { .min = MEDIA_TYPE_AUTO_SENSOR,
.max = MEDIA_TYPE_10M_HALF} }
} ;
int val;
if (num_media_type > bd) {
val = media_type[bd];
atl1e_validate_option(&val, &opt, pdev);
adapter->hw.media_type = (u16) val;
} else
adapter->hw.media_type = (u16)(opt.def);
}
}
...@@ -911,9 +911,8 @@ au1000_adjust_link(struct net_device *dev) ...@@ -911,9 +911,8 @@ au1000_adjust_link(struct net_device *dev)
if(phydev->link != aup->old_link) { if(phydev->link != aup->old_link) {
// link state changed // link state changed
if (phydev->link) // link went up if (!phydev->link) {
netif_tx_schedule_all(dev); /* link went down */
else { // link went down
aup->old_speed = 0; aup->old_speed = 0;
aup->old_duplex = -1; aup->old_duplex = -1;
} }
......
...@@ -357,7 +357,6 @@ static void bfin_mac_adjust_link(struct net_device *dev) ...@@ -357,7 +357,6 @@ static void bfin_mac_adjust_link(struct net_device *dev)
if (!lp->old_link) { if (!lp->old_link) {
new_state = 1; new_state = 1;
lp->old_link = 1; lp->old_link = 1;
netif_tx_schedule_all(dev);
} }
} else if (lp->old_link) { } else if (lp->old_link) {
new_state = 1; new_state = 1;
......
...@@ -5041,6 +5041,7 @@ static int bond_check_params(struct bond_params *params) ...@@ -5041,6 +5041,7 @@ static int bond_check_params(struct bond_params *params)
} }
static struct lock_class_key bonding_netdev_xmit_lock_key; static struct lock_class_key bonding_netdev_xmit_lock_key;
static struct lock_class_key bonding_netdev_addr_lock_key;
static void bond_set_lockdep_class_one(struct net_device *dev, static void bond_set_lockdep_class_one(struct net_device *dev,
struct netdev_queue *txq, struct netdev_queue *txq,
...@@ -5052,6 +5053,8 @@ static void bond_set_lockdep_class_one(struct net_device *dev, ...@@ -5052,6 +5053,8 @@ static void bond_set_lockdep_class_one(struct net_device *dev,
static void bond_set_lockdep_class(struct net_device *dev) static void bond_set_lockdep_class(struct net_device *dev)
{ {
lockdep_set_class(&dev->addr_list_lock,
&bonding_netdev_addr_lock_key);
netdev_for_each_tx_queue(dev, bond_set_lockdep_class_one, NULL); netdev_for_each_tx_queue(dev, bond_set_lockdep_class_one, NULL);
} }
......
...@@ -945,10 +945,8 @@ static void cpmac_adjust_link(struct net_device *dev) ...@@ -945,10 +945,8 @@ static void cpmac_adjust_link(struct net_device *dev)
if (!priv->oldlink) { if (!priv->oldlink) {
new_state = 1; new_state = 1;
priv->oldlink = 1; priv->oldlink = 1;
netif_tx_schedule_all(dev);
} }
} else if (priv->oldlink) { } else if (priv->oldlink) {
netif_tx_stop_all_queues(dev);
new_state = 1; new_state = 1;
priv->oldlink = 0; priv->oldlink = 0;
priv->oldspeed = 0; priv->oldspeed = 0;
......
...@@ -888,19 +888,22 @@ dm9000_rx(struct net_device *dev) ...@@ -888,19 +888,22 @@ dm9000_rx(struct net_device *dev)
dev_dbg(db->dev, "RST: RX Len:%x\n", RxLen); dev_dbg(db->dev, "RST: RX Len:%x\n", RxLen);
} }
if (rxhdr.RxStatus & 0xbf) { /* rxhdr.RxStatus is identical to RSR register. */
if (rxhdr.RxStatus & (RSR_FOE | RSR_CE | RSR_AE |
RSR_PLE | RSR_RWTO |
RSR_LCS | RSR_RF)) {
GoodPacket = false; GoodPacket = false;
if (rxhdr.RxStatus & 0x01) { if (rxhdr.RxStatus & RSR_FOE) {
if (netif_msg_rx_err(db)) if (netif_msg_rx_err(db))
dev_dbg(db->dev, "fifo error\n"); dev_dbg(db->dev, "fifo error\n");
dev->stats.rx_fifo_errors++; dev->stats.rx_fifo_errors++;
} }
if (rxhdr.RxStatus & 0x02) { if (rxhdr.RxStatus & RSR_CE) {
if (netif_msg_rx_err(db)) if (netif_msg_rx_err(db))
dev_dbg(db->dev, "crc error\n"); dev_dbg(db->dev, "crc error\n");
dev->stats.rx_crc_errors++; dev->stats.rx_crc_errors++;
} }
if (rxhdr.RxStatus & 0x80) { if (rxhdr.RxStatus & RSR_RF) {
if (netif_msg_rx_err(db)) if (netif_msg_rx_err(db))
dev_dbg(db->dev, "length error\n"); dev_dbg(db->dev, "length error\n");
dev->stats.rx_length_errors++; dev->stats.rx_length_errors++;
...@@ -1067,7 +1070,7 @@ dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg) ...@@ -1067,7 +1070,7 @@ dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
/* Fill the phyxcer register into REG_0C */ /* Fill the phyxcer register into REG_0C */
iow(db, DM9000_EPAR, DM9000_PHY | reg); iow(db, DM9000_EPAR, DM9000_PHY | reg);
iow(db, DM9000_EPCR, 0xc); /* Issue phyxcer read command */ iow(db, DM9000_EPCR, EPCR_ERPRR | EPCR_EPOS); /* Issue phyxcer read command */
writeb(reg_save, db->io_addr); writeb(reg_save, db->io_addr);
spin_unlock_irqrestore(&db->lock,flags); spin_unlock_irqrestore(&db->lock,flags);
...@@ -1118,7 +1121,7 @@ dm9000_phy_write(struct net_device *dev, ...@@ -1118,7 +1121,7 @@ dm9000_phy_write(struct net_device *dev,
iow(db, DM9000_EPDRL, value); iow(db, DM9000_EPDRL, value);
iow(db, DM9000_EPDRH, value >> 8); iow(db, DM9000_EPDRH, value >> 8);
iow(db, DM9000_EPCR, 0xa); /* Issue phyxcer write command */ iow(db, DM9000_EPCR, EPCR_EPOS | EPCR_ERPRW); /* Issue phyxcer write command */
writeb(reg_save, db->io_addr); writeb(reg_save, db->io_addr);
spin_unlock_irqrestore(&db->lock, flags); spin_unlock_irqrestore(&db->lock, flags);
......
...@@ -90,10 +90,13 @@ struct e1000_adapter; ...@@ -90,10 +90,13 @@ struct e1000_adapter;
#define E1000_ERR(args...) printk(KERN_ERR "e1000: " args) #define E1000_ERR(args...) printk(KERN_ERR "e1000: " args)
#define PFX "e1000: " #define PFX "e1000: "
#define DPRINTK(nlevel, klevel, fmt, args...) \
(void)((NETIF_MSG_##nlevel & adapter->msg_enable) && \ #define DPRINTK(nlevel, klevel, fmt, args...) \
printk(KERN_##klevel PFX "%s: %s: " fmt, adapter->netdev->name, \ do { \
__FUNCTION__ , ## args)) if (NETIF_MSG_##nlevel & adapter->msg_enable) \
printk(KERN_##klevel PFX "%s: %s: " fmt, \
adapter->netdev->name, __func__, ##args); \
} while (0)
#define E1000_MAX_INTR 10 #define E1000_MAX_INTR 10
...@@ -151,9 +154,9 @@ struct e1000_adapter; ...@@ -151,9 +154,9 @@ struct e1000_adapter;
#define E1000_MASTER_SLAVE e1000_ms_hw_default #define E1000_MASTER_SLAVE e1000_ms_hw_default
#endif #endif
#define E1000_MNG_VLAN_NONE -1 #define E1000_MNG_VLAN_NONE (-1)
/* Number of packet split data buffers (not including the header buffer) */ /* Number of packet split data buffers (not including the header buffer) */
#define PS_PAGE_BUFFERS MAX_PS_BUFFERS-1 #define PS_PAGE_BUFFERS (MAX_PS_BUFFERS - 1)
/* wrapper around a pointer to a socket buffer, /* wrapper around a pointer to a socket buffer,
* so a DMA handle can be stored along with the buffer */ * so a DMA handle can be stored along with the buffer */
...@@ -165,9 +168,13 @@ struct e1000_buffer { ...@@ -165,9 +168,13 @@ struct e1000_buffer {
u16 next_to_watch; u16 next_to_watch;
}; };
struct e1000_ps_page {
struct page *ps_page[PS_PAGE_BUFFERS];
};
struct e1000_ps_page { struct page *ps_page[PS_PAGE_BUFFERS]; }; struct e1000_ps_page_dma {
struct e1000_ps_page_dma { u64 ps_page_dma[PS_PAGE_BUFFERS]; }; u64 ps_page_dma[PS_PAGE_BUFFERS];
};
struct e1000_tx_ring { struct e1000_tx_ring {
/* pointer to the descriptor ring memory */ /* pointer to the descriptor ring memory */
...@@ -217,13 +224,13 @@ struct e1000_rx_ring { ...@@ -217,13 +224,13 @@ struct e1000_rx_ring {
u16 rdt; u16 rdt;
}; };
#define E1000_DESC_UNUSED(R) \ #define E1000_DESC_UNUSED(R) \
((((R)->next_to_clean > (R)->next_to_use) ? 0 : (R)->count) + \ ((((R)->next_to_clean > (R)->next_to_use) \
(R)->next_to_clean - (R)->next_to_use - 1) ? 0 : (R)->count) + (R)->next_to_clean - (R)->next_to_use - 1)
#define E1000_RX_DESC_PS(R, i) \ #define E1000_RX_DESC_PS(R, i) \
(&(((union e1000_rx_desc_packet_split *)((R).desc))[i])) (&(((union e1000_rx_desc_packet_split *)((R).desc))[i]))
#define E1000_RX_DESC_EXT(R, i) \ #define E1000_RX_DESC_EXT(R, i) \
(&(((union e1000_rx_desc_extended *)((R).desc))[i])) (&(((union e1000_rx_desc_extended *)((R).desc))[i]))
#define E1000_GET_DESC(R, i, type) (&(((struct type *)((R).desc))[i])) #define E1000_GET_DESC(R, i, type) (&(((struct type *)((R).desc))[i]))
#define E1000_RX_DESC(R, i) E1000_GET_DESC(R, i, e1000_rx_desc) #define E1000_RX_DESC(R, i) E1000_GET_DESC(R, i, e1000_rx_desc)
...@@ -246,9 +253,7 @@ struct e1000_adapter { ...@@ -246,9 +253,7 @@ struct e1000_adapter {
u16 link_speed; u16 link_speed;
u16 link_duplex; u16 link_duplex;
spinlock_t stats_lock; spinlock_t stats_lock;
#ifdef CONFIG_E1000_NAPI
spinlock_t tx_queue_lock; spinlock_t tx_queue_lock;
#endif
unsigned int total_tx_bytes; unsigned int total_tx_bytes;
unsigned int total_tx_packets; unsigned int total_tx_packets;
unsigned int total_rx_bytes; unsigned int total_rx_bytes;
...@@ -286,22 +291,16 @@ struct e1000_adapter { ...@@ -286,22 +291,16 @@ struct e1000_adapter {
bool detect_tx_hung; bool detect_tx_hung;
/* RX */ /* RX */
#ifdef CONFIG_E1000_NAPI bool (*clean_rx)(struct e1000_adapter *adapter,
bool (*clean_rx) (struct e1000_adapter *adapter, struct e1000_rx_ring *rx_ring,
struct e1000_rx_ring *rx_ring, int *work_done, int work_to_do);
int *work_done, int work_to_do); void (*alloc_rx_buf)(struct e1000_adapter *adapter,
#else struct e1000_rx_ring *rx_ring,
bool (*clean_rx) (struct e1000_adapter *adapter, int cleaned_count);
struct e1000_rx_ring *rx_ring);
#endif
void (*alloc_rx_buf) (struct e1000_adapter *adapter,
struct e1000_rx_ring *rx_ring,
int cleaned_count);
struct e1000_rx_ring *rx_ring; /* One per active queue */ struct e1000_rx_ring *rx_ring; /* One per active queue */
#ifdef CONFIG_E1000_NAPI
struct napi_struct napi; struct napi_struct napi;
struct net_device *polling_netdev; /* One per active queue */ struct net_device *polling_netdev; /* One per active queue */
#endif
int num_tx_queues; int num_tx_queues;
int num_rx_queues; int num_rx_queues;
...@@ -317,7 +316,6 @@ struct e1000_adapter { ...@@ -317,7 +316,6 @@ struct e1000_adapter {
u64 gorcl_old; u64 gorcl_old;
u16 rx_ps_bsize0; u16 rx_ps_bsize0;
/* OS defined structs */ /* OS defined structs */
struct net_device *netdev; struct net_device *netdev;
struct pci_dev *pdev; struct pci_dev *pdev;
...@@ -342,6 +340,10 @@ struct e1000_adapter { ...@@ -342,6 +340,10 @@ struct e1000_adapter {
bool quad_port_a; bool quad_port_a;
unsigned long flags; unsigned long flags;
u32 eeprom_wol; u32 eeprom_wol;
/* for ioport free */
int bars;
int need_ioport;
}; };
enum e1000_state_t { enum e1000_state_t {
...@@ -353,9 +355,18 @@ enum e1000_state_t { ...@@ -353,9 +355,18 @@ enum e1000_state_t {
extern char e1000_driver_name[]; extern char e1000_driver_name[];
extern const char e1000_driver_version[]; extern const char e1000_driver_version[];
extern int e1000_up(struct e1000_adapter *adapter);
extern void e1000_down(struct e1000_adapter *adapter);
extern void e1000_reinit_locked(struct e1000_adapter *adapter);
extern void e1000_reset(struct e1000_adapter *adapter);
extern int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx);
extern int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
extern int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
extern void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
extern void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
extern void e1000_update_stats(struct e1000_adapter *adapter);
extern void e1000_power_up_phy(struct e1000_adapter *); extern void e1000_power_up_phy(struct e1000_adapter *);
extern void e1000_set_ethtool_ops(struct net_device *netdev); extern void e1000_set_ethtool_ops(struct net_device *netdev);
extern void e1000_check_options(struct e1000_adapter *adapter); extern void e1000_check_options(struct e1000_adapter *adapter);
#endif /* _E1000_H_ */ #endif /* _E1000_H_ */
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -55,13 +55,13 @@ ...@@ -55,13 +55,13 @@
#define DEBUGOUT7 DEBUGOUT3 #define DEBUGOUT7 DEBUGOUT3
#define E1000_WRITE_REG(a, reg, value) ( \ #define er32(reg) \
writel((value), ((a)->hw_addr + \ (readl(hw->hw_addr + ((hw->mac_type >= e1000_82543) \
(((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg)))) ? E1000_##reg : E1000_82542_##reg)))
#define E1000_READ_REG(a, reg) ( \ #define ew32(reg, value) \
readl((a)->hw_addr + \ (writel((value), (hw->hw_addr + ((hw->mac_type >= e1000_82543) \
(((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg))) ? E1000_##reg : E1000_82542_##reg))))
#define E1000_WRITE_REG_ARRAY(a, reg, offset, value) ( \ #define E1000_WRITE_REG_ARRAY(a, reg, offset, value) ( \
writel((value), ((a)->hw_addr + \ writel((value), ((a)->hw_addr + \
...@@ -96,7 +96,7 @@ ...@@ -96,7 +96,7 @@
(((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \ (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
(offset))) (offset)))
#define E1000_WRITE_FLUSH(a) E1000_READ_REG(a, STATUS) #define E1000_WRITE_FLUSH() er32(STATUS)
#define E1000_WRITE_ICH_FLASH_REG(a, reg, value) ( \ #define E1000_WRITE_ICH_FLASH_REG(a, reg, value) ( \
writel((value), ((a)->flash_address + reg))) writel((value), ((a)->flash_address + reg)))
......
...@@ -213,10 +213,9 @@ struct e1000_option { ...@@ -213,10 +213,9 @@ struct e1000_option {
} arg; } arg;
}; };
static int __devinit static int __devinit e1000_validate_option(unsigned int *value,
e1000_validate_option(unsigned int *value, const struct e1000_option *opt,
const struct e1000_option *opt, struct e1000_adapter *adapter)
struct e1000_adapter *adapter)
{ {
if (*value == OPTION_UNSET) { if (*value == OPTION_UNSET) {
*value = opt->def; *value = opt->def;
...@@ -278,8 +277,7 @@ static void e1000_check_copper_options(struct e1000_adapter *adapter); ...@@ -278,8 +277,7 @@ static void e1000_check_copper_options(struct e1000_adapter *adapter);
* in a variable in the adapter structure. * in a variable in the adapter structure.
**/ **/
void __devinit void __devinit e1000_check_options(struct e1000_adapter *adapter)
e1000_check_options(struct e1000_adapter *adapter)
{ {
int bd = adapter->bd_number; int bd = adapter->bd_number;
if (bd >= E1000_MAX_NIC) { if (bd >= E1000_MAX_NIC) {
...@@ -551,8 +549,7 @@ e1000_check_options(struct e1000_adapter *adapter) ...@@ -551,8 +549,7 @@ e1000_check_options(struct e1000_adapter *adapter)
* Handles speed and duplex options on fiber adapters * Handles speed and duplex options on fiber adapters
**/ **/
static void __devinit static void __devinit e1000_check_fiber_options(struct e1000_adapter *adapter)
e1000_check_fiber_options(struct e1000_adapter *adapter)
{ {
int bd = adapter->bd_number; int bd = adapter->bd_number;
if (num_Speed > bd) { if (num_Speed > bd) {
...@@ -579,8 +576,7 @@ e1000_check_fiber_options(struct e1000_adapter *adapter) ...@@ -579,8 +576,7 @@ e1000_check_fiber_options(struct e1000_adapter *adapter)
* Handles speed and duplex options on copper adapters * Handles speed and duplex options on copper adapters
**/ **/
static void __devinit static void __devinit e1000_check_copper_options(struct e1000_adapter *adapter)
e1000_check_copper_options(struct e1000_adapter *adapter)
{ {
unsigned int speed, dplx, an; unsigned int speed, dplx, an;
int bd = adapter->bd_number; int bd = adapter->bd_number;
......
...@@ -197,9 +197,6 @@ static void mpc52xx_fec_adjust_link(struct net_device *dev) ...@@ -197,9 +197,6 @@ static void mpc52xx_fec_adjust_link(struct net_device *dev)
if (priv->link == PHY_DOWN) { if (priv->link == PHY_DOWN) {
new_state = 1; new_state = 1;
priv->link = phydev->link; priv->link = phydev->link;
netif_tx_schedule_all(dev);
netif_carrier_on(dev);
netif_start_queue(dev);
} }
} else if (priv->link) { } else if (priv->link) {
...@@ -207,8 +204,6 @@ static void mpc52xx_fec_adjust_link(struct net_device *dev) ...@@ -207,8 +204,6 @@ static void mpc52xx_fec_adjust_link(struct net_device *dev)
priv->link = PHY_DOWN; priv->link = PHY_DOWN;
priv->speed = 0; priv->speed = 0;
priv->duplex = -1; priv->duplex = -1;
netif_stop_queue(dev);
netif_carrier_off(dev);
} }
if (new_state && netif_msg_link(priv)) if (new_state && netif_msg_link(priv))
......
...@@ -730,9 +730,6 @@ static void generic_adjust_link(struct net_device *dev) ...@@ -730,9 +730,6 @@ static void generic_adjust_link(struct net_device *dev)
if (!fep->oldlink) { if (!fep->oldlink) {
new_state = 1; new_state = 1;
fep->oldlink = 1; fep->oldlink = 1;
netif_tx_schedule_all(dev);
netif_carrier_on(dev);
netif_start_queue(dev);
} }
if (new_state) if (new_state)
...@@ -742,8 +739,6 @@ static void generic_adjust_link(struct net_device *dev) ...@@ -742,8 +739,6 @@ static void generic_adjust_link(struct net_device *dev)
fep->oldlink = 0; fep->oldlink = 0;
fep->oldspeed = 0; fep->oldspeed = 0;
fep->oldduplex = -1; fep->oldduplex = -1;
netif_carrier_off(dev);
netif_stop_queue(dev);
} }
if (new_state && netif_msg_link(fep)) if (new_state && netif_msg_link(fep))
...@@ -818,6 +813,8 @@ static int fs_enet_open(struct net_device *dev) ...@@ -818,6 +813,8 @@ static int fs_enet_open(struct net_device *dev)
} }
phy_start(fep->phydev); phy_start(fep->phydev);
netif_start_queue(dev);
return 0; return 0;
} }
......
...@@ -123,6 +123,7 @@ static LIST_HEAD(bpq_devices); ...@@ -123,6 +123,7 @@ static LIST_HEAD(bpq_devices);
* off into a separate class since they always nest. * off into a separate class since they always nest.
*/ */
static struct lock_class_key bpq_netdev_xmit_lock_key; static struct lock_class_key bpq_netdev_xmit_lock_key;
static struct lock_class_key bpq_netdev_addr_lock_key;
static void bpq_set_lockdep_class_one(struct net_device *dev, static void bpq_set_lockdep_class_one(struct net_device *dev,
struct netdev_queue *txq, struct netdev_queue *txq,
...@@ -133,6 +134,7 @@ static void bpq_set_lockdep_class_one(struct net_device *dev, ...@@ -133,6 +134,7 @@ static void bpq_set_lockdep_class_one(struct net_device *dev,
static void bpq_set_lockdep_class(struct net_device *dev) static void bpq_set_lockdep_class(struct net_device *dev)
{ {
lockdep_set_class(&dev->addr_list_lock, &bpq_netdev_addr_lock_key);
netdev_for_each_tx_queue(dev, bpq_set_lockdep_class_one, NULL); netdev_for_each_tx_queue(dev, bpq_set_lockdep_class_one, NULL);
} }
......
...@@ -262,7 +262,7 @@ static int __init hpp_probe1(struct net_device *dev, int ioaddr) ...@@ -262,7 +262,7 @@ static int __init hpp_probe1(struct net_device *dev, int ioaddr)
} }
outw(Perf_Page, ioaddr + HP_PAGING); outw(Perf_Page, ioaddr + HP_PAGING);
NS8390_init(dev, 0); NS8390p_init(dev, 0);
/* Leave the 8390 and HP chip reset. */ /* Leave the 8390 and HP chip reset. */
outw(inw(ioaddr + HPP_OPTION) & ~EnableIRQ, ioaddr + HPP_OPTION); outw(inw(ioaddr + HPP_OPTION) & ~EnableIRQ, ioaddr + HPP_OPTION);
......
...@@ -389,7 +389,7 @@ static void __init ...@@ -389,7 +389,7 @@ static void __init
hp_init_card(struct net_device *dev) hp_init_card(struct net_device *dev)
{ {
int irq = dev->irq; int irq = dev->irq;
NS8390_init(dev, 0); NS8390p_init(dev, 0);
outb_p(irqmap[irq&0x0f] | HP_RUN, outb_p(irqmap[irq&0x0f] | HP_RUN,
dev->base_addr - NIC_OFFSET + HP_CONFIGURE); dev->base_addr - NIC_OFFSET + HP_CONFIGURE);
return; return;
......
...@@ -385,7 +385,7 @@ static void igb_configure_msix(struct igb_adapter *adapter) ...@@ -385,7 +385,7 @@ static void igb_configure_msix(struct igb_adapter *adapter)
for (i = 0; i < adapter->num_rx_queues; i++) { for (i = 0; i < adapter->num_rx_queues; i++) {
struct igb_ring *rx_ring = &adapter->rx_ring[i]; struct igb_ring *rx_ring = &adapter->rx_ring[i];
rx_ring->buddy = 0; rx_ring->buddy = NULL;
igb_assign_vector(adapter, i, IGB_N0_QUEUE, vector++); igb_assign_vector(adapter, i, IGB_N0_QUEUE, vector++);
adapter->eims_enable_mask |= rx_ring->eims_value; adapter->eims_enable_mask |= rx_ring->eims_value;
if (rx_ring->itr_val) if (rx_ring->itr_val)
......
...@@ -70,8 +70,6 @@ static struct pci_device_id ixgbe_pci_tbl[] = { ...@@ -70,8 +70,6 @@ static struct pci_device_id ixgbe_pci_tbl[] = {
board_82598 }, board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AF_SINGLE_PORT), {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AF_SINGLE_PORT),
board_82598 }, board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AT_DUAL_PORT),
board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_CX4), {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_CX4),
board_82598 }, board_82598 },
......
...@@ -164,9 +164,7 @@ static void macb_handle_link_change(struct net_device *dev) ...@@ -164,9 +164,7 @@ static void macb_handle_link_change(struct net_device *dev)
} }
if (phydev->link != bp->link) { if (phydev->link != bp->link) {
if (phydev->link) if (!phydev->link) {
netif_tx_schedule_all(dev);
else {
bp->speed = 0; bp->speed = 0;
bp->duplex = -1; bp->duplex = -1;
} }
......
...@@ -276,6 +276,7 @@ static int macvlan_change_mtu(struct net_device *dev, int new_mtu) ...@@ -276,6 +276,7 @@ static int macvlan_change_mtu(struct net_device *dev, int new_mtu)
* separate class since they always nest. * separate class since they always nest.
*/ */
static struct lock_class_key macvlan_netdev_xmit_lock_key; static struct lock_class_key macvlan_netdev_xmit_lock_key;
static struct lock_class_key macvlan_netdev_addr_lock_key;
#define MACVLAN_FEATURES \ #define MACVLAN_FEATURES \
(NETIF_F_SG | NETIF_F_ALL_CSUM | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \ (NETIF_F_SG | NETIF_F_ALL_CSUM | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \
...@@ -295,6 +296,8 @@ static void macvlan_set_lockdep_class_one(struct net_device *dev, ...@@ -295,6 +296,8 @@ static void macvlan_set_lockdep_class_one(struct net_device *dev,
static void macvlan_set_lockdep_class(struct net_device *dev) static void macvlan_set_lockdep_class(struct net_device *dev)
{ {
lockdep_set_class(&dev->addr_list_lock,
&macvlan_netdev_addr_lock_key);
netdev_for_each_tx_queue(dev, macvlan_set_lockdep_class_one, NULL); netdev_for_each_tx_queue(dev, macvlan_set_lockdep_class_one, NULL);
} }
......
...@@ -287,7 +287,7 @@ int meth_reset(struct net_device *dev) ...@@ -287,7 +287,7 @@ int meth_reset(struct net_device *dev)
/* Initial mode: 10 | Half-duplex | Accept normal packets */ /* Initial mode: 10 | Half-duplex | Accept normal packets */
priv->mac_ctrl = METH_ACCEPT_MCAST | METH_DEFAULT_IPG; priv->mac_ctrl = METH_ACCEPT_MCAST | METH_DEFAULT_IPG;
if (dev->flags | IFF_PROMISC) if (dev->flags & IFF_PROMISC)
priv->mac_ctrl |= METH_PROMISC; priv->mac_ctrl |= METH_PROMISC;
mace->eth.mac_ctrl = priv->mac_ctrl; mace->eth.mac_ctrl = priv->mac_ctrl;
......
...@@ -2112,7 +2112,7 @@ static void mv643xx_eth_netpoll(struct net_device *dev) ...@@ -2112,7 +2112,7 @@ static void mv643xx_eth_netpoll(struct net_device *dev)
mv643xx_eth_irq(dev->irq, dev); mv643xx_eth_irq(dev->irq, dev);
wrl(mp, INT_MASK(mp->port_num), INT_TX_END | INT_RX | INT_CAUSE_EXT); wrl(mp, INT_MASK(mp->port_num), INT_TX_END | INT_RX | INT_EXT);
} }
#endif #endif
......
...@@ -125,7 +125,6 @@ struct myri10ge_cmd { ...@@ -125,7 +125,6 @@ struct myri10ge_cmd {
struct myri10ge_rx_buf { struct myri10ge_rx_buf {
struct mcp_kreq_ether_recv __iomem *lanai; /* lanai ptr for recv ring */ struct mcp_kreq_ether_recv __iomem *lanai; /* lanai ptr for recv ring */
u8 __iomem *wc_fifo; /* w/c rx dma addr fifo address */
struct mcp_kreq_ether_recv *shadow; /* host shadow of recv ring */ struct mcp_kreq_ether_recv *shadow; /* host shadow of recv ring */
struct myri10ge_rx_buffer_state *info; struct myri10ge_rx_buffer_state *info;
struct page *page; struct page *page;
...@@ -140,7 +139,6 @@ struct myri10ge_rx_buf { ...@@ -140,7 +139,6 @@ struct myri10ge_rx_buf {
struct myri10ge_tx_buf { struct myri10ge_tx_buf {
struct mcp_kreq_ether_send __iomem *lanai; /* lanai ptr for sendq */ struct mcp_kreq_ether_send __iomem *lanai; /* lanai ptr for sendq */
u8 __iomem *wc_fifo; /* w/c send fifo address */
struct mcp_kreq_ether_send *req_list; /* host shadow of sendq */ struct mcp_kreq_ether_send *req_list; /* host shadow of sendq */
char *req_bytes; char *req_bytes;
struct myri10ge_tx_buffer_state *info; struct myri10ge_tx_buffer_state *info;
...@@ -332,10 +330,6 @@ MODULE_PARM_DESC(myri10ge_fill_thresh, "Number of empty rx slots allowed"); ...@@ -332,10 +330,6 @@ MODULE_PARM_DESC(myri10ge_fill_thresh, "Number of empty rx slots allowed");
static int myri10ge_reset_recover = 1; static int myri10ge_reset_recover = 1;
static int myri10ge_wcfifo = 0;
module_param(myri10ge_wcfifo, int, S_IRUGO);
MODULE_PARM_DESC(myri10ge_wcfifo, "Enable WC Fifo when WC is enabled");
static int myri10ge_max_slices = 1; static int myri10ge_max_slices = 1;
module_param(myri10ge_max_slices, int, S_IRUGO); module_param(myri10ge_max_slices, int, S_IRUGO);
MODULE_PARM_DESC(myri10ge_max_slices, "Max tx/rx queues"); MODULE_PARM_DESC(myri10ge_max_slices, "Max tx/rx queues");
...@@ -1218,14 +1212,8 @@ myri10ge_alloc_rx_pages(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx, ...@@ -1218,14 +1212,8 @@ myri10ge_alloc_rx_pages(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx,
/* copy 8 descriptors to the firmware at a time */ /* copy 8 descriptors to the firmware at a time */
if ((idx & 7) == 7) { if ((idx & 7) == 7) {
if (rx->wc_fifo == NULL) myri10ge_submit_8rx(&rx->lanai[idx - 7],
myri10ge_submit_8rx(&rx->lanai[idx - 7], &rx->shadow[idx - 7]);
&rx->shadow[idx - 7]);
else {
mb();
myri10ge_pio_copy(rx->wc_fifo,
&rx->shadow[idx - 7], 64);
}
} }
} }
} }
...@@ -2229,18 +2217,6 @@ static int myri10ge_get_txrx(struct myri10ge_priv *mgp, int slice) ...@@ -2229,18 +2217,6 @@ static int myri10ge_get_txrx(struct myri10ge_priv *mgp, int slice)
ss->rx_big.lanai = (struct mcp_kreq_ether_recv __iomem *) ss->rx_big.lanai = (struct mcp_kreq_ether_recv __iomem *)
(mgp->sram + cmd.data0); (mgp->sram + cmd.data0);
if (myri10ge_wcfifo && mgp->wc_enabled) {
ss->tx.wc_fifo = (u8 __iomem *)
mgp->sram + MXGEFW_ETH_SEND_4 + 64 * slice;
ss->rx_small.wc_fifo = (u8 __iomem *)
mgp->sram + MXGEFW_ETH_RECV_SMALL + 64 * slice;
ss->rx_big.wc_fifo = (u8 __iomem *)
mgp->sram + MXGEFW_ETH_RECV_BIG + 64 * slice;
} else {
ss->tx.wc_fifo = NULL;
ss->rx_small.wc_fifo = NULL;
ss->rx_big.wc_fifo = NULL;
}
return status; return status;
} }
...@@ -2573,27 +2549,6 @@ myri10ge_submit_req(struct myri10ge_tx_buf *tx, struct mcp_kreq_ether_send *src, ...@@ -2573,27 +2549,6 @@ myri10ge_submit_req(struct myri10ge_tx_buf *tx, struct mcp_kreq_ether_send *src,
mb(); mb();
} }
static inline void
myri10ge_submit_req_wc(struct myri10ge_tx_buf *tx,
struct mcp_kreq_ether_send *src, int cnt)
{
tx->req += cnt;
mb();
while (cnt >= 4) {
myri10ge_pio_copy(tx->wc_fifo, src, 64);
mb();
src += 4;
cnt -= 4;
}
if (cnt > 0) {
/* pad it to 64 bytes. The src is 64 bytes bigger than it
* needs to be so that we don't overrun it */
myri10ge_pio_copy(tx->wc_fifo + MXGEFW_ETH_SEND_OFFSET(cnt),
src, 64);
mb();
}
}
/* /*
* Transmit a packet. We need to split the packet so that a single * Transmit a packet. We need to split the packet so that a single
* segment does not cross myri10ge->tx_boundary, so this makes segment * segment does not cross myri10ge->tx_boundary, so this makes segment
...@@ -2830,10 +2785,7 @@ static int myri10ge_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -2830,10 +2785,7 @@ static int myri10ge_xmit(struct sk_buff *skb, struct net_device *dev)
MXGEFW_FLAGS_FIRST))); MXGEFW_FLAGS_FIRST)));
idx = ((count - 1) + tx->req) & tx->mask; idx = ((count - 1) + tx->req) & tx->mask;
tx->info[idx].last = 1; tx->info[idx].last = 1;
if (tx->wc_fifo == NULL) myri10ge_submit_req(tx, tx->req_list, count);
myri10ge_submit_req(tx, tx->req_list, count);
else
myri10ge_submit_req_wc(tx, tx->req_list, count);
tx->pkt_start++; tx->pkt_start++;
if ((avail - count) < MXGEFW_MAX_SEND_DESC) { if ((avail - count) < MXGEFW_MAX_SEND_DESC) {
tx->stop_queue++; tx->stop_queue++;
...@@ -3768,14 +3720,14 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -3768,14 +3720,14 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (mgp->sram_size > mgp->board_span) { if (mgp->sram_size > mgp->board_span) {
dev_err(&pdev->dev, "board span %ld bytes too small\n", dev_err(&pdev->dev, "board span %ld bytes too small\n",
mgp->board_span); mgp->board_span);
goto abort_with_wc; goto abort_with_mtrr;
} }
mgp->sram = ioremap(mgp->iomem_base, mgp->board_span); mgp->sram = ioremap_wc(mgp->iomem_base, mgp->board_span);
if (mgp->sram == NULL) { if (mgp->sram == NULL) {
dev_err(&pdev->dev, "ioremap failed for %ld bytes at 0x%lx\n", dev_err(&pdev->dev, "ioremap failed for %ld bytes at 0x%lx\n",
mgp->board_span, mgp->iomem_base); mgp->board_span, mgp->iomem_base);
status = -ENXIO; status = -ENXIO;
goto abort_with_wc; goto abort_with_mtrr;
} }
memcpy_fromio(mgp->eeprom_strings, memcpy_fromio(mgp->eeprom_strings,
mgp->sram + mgp->sram_size - MYRI10GE_EEPROM_STRINGS_SIZE, mgp->sram + mgp->sram_size - MYRI10GE_EEPROM_STRINGS_SIZE,
...@@ -3876,7 +3828,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -3876,7 +3828,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
abort_with_ioremap: abort_with_ioremap:
iounmap(mgp->sram); iounmap(mgp->sram);
abort_with_wc: abort_with_mtrr:
#ifdef CONFIG_MTRR #ifdef CONFIG_MTRR
if (mgp->mtrr >= 0) if (mgp->mtrr >= 0)
mtrr_del(mgp->mtrr, mgp->iomem_base, mgp->board_span); mtrr_del(mgp->mtrr, mgp->iomem_base, mgp->board_span);
......
...@@ -355,7 +355,7 @@ static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr) ...@@ -355,7 +355,7 @@ static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr)
} }
/* Read the 16 bytes of station address PROM. /* Read the 16 bytes of station address PROM.
We must first initialize registers, similar to NS8390_init(eifdev, 0). We must first initialize registers, similar to NS8390p_init(eifdev, 0).
We can't reliably read the SAPROM address without this. We can't reliably read the SAPROM address without this.
(I learned the hard way!). */ (I learned the hard way!). */
{ {
......
...@@ -404,7 +404,7 @@ static int __init ne2_probe1(struct net_device *dev, int slot) ...@@ -404,7 +404,7 @@ static int __init ne2_probe1(struct net_device *dev, int slot)
/* Read the 16 bytes of station address PROM. /* Read the 16 bytes of station address PROM.
We must first initialize registers, similar to We must first initialize registers, similar to
NS8390_init(eifdev, 0). NS8390p_init(eifdev, 0).
We can't reliably read the SAPROM address without this. We can't reliably read the SAPROM address without this.
(I learned the hard way!). */ (I learned the hard way!). */
{ {
......
...@@ -32,4 +32,4 @@ ...@@ -32,4 +32,4 @@
obj-$(CONFIG_NETXEN_NIC) := netxen_nic.o obj-$(CONFIG_NETXEN_NIC) := netxen_nic.o
netxen_nic-y := netxen_nic_hw.o netxen_nic_main.o netxen_nic_init.o \ netxen_nic-y := netxen_nic_hw.o netxen_nic_main.o netxen_nic_init.o \
netxen_nic_isr.o netxen_nic_ethtool.o netxen_nic_niu.o netxen_nic_ethtool.o netxen_nic_niu.o netxen_nic_ctx.o
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -82,19 +82,9 @@ struct netxen_adapter; ...@@ -82,19 +82,9 @@ struct netxen_adapter;
#define NETXEN_PCI_MAPSIZE_BYTES (NETXEN_PCI_MAPSIZE << 20) #define NETXEN_PCI_MAPSIZE_BYTES (NETXEN_PCI_MAPSIZE << 20)
#define NETXEN_NIC_LOCKED_READ_REG(X, Y) \
addr = pci_base_offset(adapter, X); \
*(u32 *)Y = readl((void __iomem*) addr);
struct netxen_port; struct netxen_port;
void netxen_nic_set_link_parameters(struct netxen_adapter *adapter); void netxen_nic_set_link_parameters(struct netxen_adapter *adapter);
void netxen_nic_flash_print(struct netxen_adapter *adapter); void netxen_nic_flash_print(struct netxen_adapter *adapter);
int netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off,
void *data, int len);
void netxen_crb_writelit_adapter(struct netxen_adapter *adapter,
unsigned long off, int data);
int netxen_nic_hw_read_wx(struct netxen_adapter *adapter, u64 off,
void *data, int len);
typedef u8 netxen_ethernet_macaddr_t[6]; typedef u8 netxen_ethernet_macaddr_t[6];
...@@ -432,7 +422,8 @@ typedef enum { ...@@ -432,7 +422,8 @@ typedef enum {
/* Promiscous mode options (GbE mode only) */ /* Promiscous mode options (GbE mode only) */
typedef enum { typedef enum {
NETXEN_NIU_PROMISC_MODE = 0, NETXEN_NIU_PROMISC_MODE = 0,
NETXEN_NIU_NON_PROMISC_MODE NETXEN_NIU_NON_PROMISC_MODE,
NETXEN_NIU_ALLMULTI_MODE
} netxen_niu_prom_mode_t; } netxen_niu_prom_mode_t;
/* /*
...@@ -478,42 +469,6 @@ typedef enum { ...@@ -478,42 +469,6 @@ typedef enum {
#define netxen_xg_soft_reset(config_word) \ #define netxen_xg_soft_reset(config_word) \
((config_word) |= 1 << 4) ((config_word) |= 1 << 4)
/*
* MAC Control Register
*
* Bit 0-1 : id_pool0
* Bit 2 : enable_xtnd0
* Bit 4-5 : id_pool1
* Bit 6 : enable_xtnd1
* Bit 8-9 : id_pool2
* Bit 10 : enable_xtnd2
* Bit 12-13 : id_pool3
* Bit 14 : enable_xtnd3
* Bit 24-25 : mode_select
* Bit 28-31 : enable_pool
*/
#define netxen_nic_mcr_set_id_pool0(config, val) \
((config) |= ((val) &0x03))
#define netxen_nic_mcr_set_enable_xtnd0(config) \
((config) |= 1 << 3)
#define netxen_nic_mcr_set_id_pool1(config, val) \
((config) |= (((val) & 0x03) << 4))
#define netxen_nic_mcr_set_enable_xtnd1(config) \
((config) |= 1 << 6)
#define netxen_nic_mcr_set_id_pool2(config, val) \
((config) |= (((val) & 0x03) << 8))
#define netxen_nic_mcr_set_enable_xtnd2(config) \
((config) |= 1 << 10)
#define netxen_nic_mcr_set_id_pool3(config, val) \
((config) |= (((val) & 0x03) << 12))
#define netxen_nic_mcr_set_enable_xtnd3(config) \
((config) |= 1 << 14)
#define netxen_nic_mcr_set_mode_select(config, val) \
((config) |= (((val) & 0x03) << 24))
#define netxen_nic_mcr_set_enable_pool(config, val) \
((config) |= (((val) & 0x0f) << 28))
/* Set promiscuous mode for a GbE interface */ /* Set promiscuous mode for a GbE interface */
int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter, int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter,
netxen_niu_prom_mode_t mode); netxen_niu_prom_mode_t mode);
...@@ -538,4 +493,15 @@ int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter); ...@@ -538,4 +493,15 @@ int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter);
int netxen_niu_disable_xg_port(struct netxen_adapter *adapter); int netxen_niu_disable_xg_port(struct netxen_adapter *adapter);
typedef struct {
unsigned valid;
unsigned start_128M;
unsigned end_128M;
unsigned start_2M;
} crb_128M_2M_sub_block_map_t;
typedef struct {
crb_128M_2M_sub_block_map_t sub_block[16];
} crb_128M_2M_block_map_t;
#endif /* __NETXEN_NIC_HW_H_ */ #endif /* __NETXEN_NIC_HW_H_ */
此差异已折叠。
此差异已折叠。
...@@ -158,11 +158,10 @@ static int m88e1111_config_init(struct phy_device *phydev) ...@@ -158,11 +158,10 @@ static int m88e1111_config_init(struct phy_device *phydev)
{ {
int err; int err;
int temp; int temp;
int mode;
/* Enable Fiber/Copper auto selection */ /* Enable Fiber/Copper auto selection */
temp = phy_read(phydev, MII_M1111_PHY_EXT_SR); temp = phy_read(phydev, MII_M1111_PHY_EXT_SR);
temp |= MII_M1111_HWCFG_FIBER_COPPER_AUTO; temp &= ~MII_M1111_HWCFG_FIBER_COPPER_AUTO;
phy_write(phydev, MII_M1111_PHY_EXT_SR, temp); phy_write(phydev, MII_M1111_PHY_EXT_SR, temp);
temp = phy_read(phydev, MII_BMCR); temp = phy_read(phydev, MII_BMCR);
...@@ -198,9 +197,7 @@ static int m88e1111_config_init(struct phy_device *phydev) ...@@ -198,9 +197,7 @@ static int m88e1111_config_init(struct phy_device *phydev)
temp &= ~(MII_M1111_HWCFG_MODE_MASK); temp &= ~(MII_M1111_HWCFG_MODE_MASK);
mode = phy_read(phydev, MII_M1111_PHY_EXT_CR); if (temp & MII_M1111_HWCFG_FIBER_COPPER_RES)
if (mode & MII_M1111_HWCFG_FIBER_COPPER_RES)
temp |= MII_M1111_HWCFG_MODE_FIBER_RGMII; temp |= MII_M1111_HWCFG_MODE_FIBER_RGMII;
else else
temp |= MII_M1111_HWCFG_MODE_COPPER_RGMII; temp |= MII_M1111_HWCFG_MODE_COPPER_RGMII;
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -616,7 +616,9 @@ union efx_multicast_hash { ...@@ -616,7 +616,9 @@ union efx_multicast_hash {
* @pci_dev: The PCI device * @pci_dev: The PCI device
* @type: Controller type attributes * @type: Controller type attributes
* @legacy_irq: IRQ number * @legacy_irq: IRQ number
* @workqueue: Workqueue for resets, port reconfigures and the HW monitor * @workqueue: Workqueue for port reconfigures and the HW monitor.
* Work items do not hold and must not acquire RTNL.
* @reset_workqueue: Workqueue for resets. Work item will acquire RTNL.
* @reset_work: Scheduled reset workitem * @reset_work: Scheduled reset workitem
* @monitor_work: Hardware monitor workitem * @monitor_work: Hardware monitor workitem
* @membase_phys: Memory BAR value as physical address * @membase_phys: Memory BAR value as physical address
...@@ -684,6 +686,7 @@ struct efx_nic { ...@@ -684,6 +686,7 @@ struct efx_nic {
const struct efx_nic_type *type; const struct efx_nic_type *type;
int legacy_irq; int legacy_irq;
struct workqueue_struct *workqueue; struct workqueue_struct *workqueue;
struct workqueue_struct *reset_workqueue;
struct work_struct reset_work; struct work_struct reset_work;
struct delayed_work monitor_work; struct delayed_work monitor_work;
resource_size_t membase_phys; resource_size_t membase_phys;
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册