Commit 95dfec6a authored by Linus Torvalds's avatar 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: (53 commits)
  tcp: Overflow bug in Vegas
  [IPv4] UFO: prevent generation of chained skb destined to UFO device
  iwlwifi: move the selects to the tristate drivers
  ipv4: annotate a few functions __init in ipconfig.c
  atm: ambassador: vcc_sf semaphore to mutex
  MAINTAINERS: The socketcan-core list is subscribers-only.
  netfilter: nf_conntrack: padding breaks conntrack hash on ARM
  ipv4: Update MTU to all related cache entries in ip_rt_frag_needed()
  sch_sfq: use del_timer_sync() in sfq_destroy()
  net: Add compat support for getsockopt (MCAST_MSFILTER)
  net: Several cleanups for the setsockopt compat support.
  ipvs: fix oops in backup for fwmark conn templates
  bridge: kernel panic when unloading bridge module
  bridge: fix error handling in br_add_if()
  netfilter: {nfnetlink,ip,ip6}_queue: fix skb_over_panic when enlarging packets
  netfilter: x_tables: fix net namespace leak when reading /proc/net/xxx_tables_names
  netfilter: xt_TCPOPTSTRIP: signed tcphoff for ipv6_skip_exthdr() retval
  tcp: Limit cwnd growth when deferring for GSO
  tcp: Allow send-limited cwnd to grow up to max_burst when gso disabled
  [netdrvr] gianfar: Determine TBIPA value dynamically
  ...
parents ae3a0064 15913114
...@@ -1039,7 +1039,7 @@ P: Urs Thuermann ...@@ -1039,7 +1039,7 @@ P: Urs Thuermann
M: urs.thuermann@volkswagen.de M: urs.thuermann@volkswagen.de
P: Oliver Hartkopp P: Oliver Hartkopp
M: oliver.hartkopp@volkswagen.de M: oliver.hartkopp@volkswagen.de
L: socketcan-core@lists.berlios.de L: socketcan-core@lists.berlios.de (subscribers-only)
W: http://developer.berlios.de/projects/socketcan/ W: http://developer.berlios.de/projects/socketcan/
S: Maintained S: Maintained
...@@ -3577,6 +3577,13 @@ M: pfg@sgi.com ...@@ -3577,6 +3577,13 @@ M: pfg@sgi.com
L: linux-ia64@vger.kernel.org L: linux-ia64@vger.kernel.org
S: Supported S: Supported
SFC NETWORK DRIVER
P: Steve Hodgson
P: Ben Hutchings
P: Robert Stonehouse
M: linux-net-drivers@solarflare.com
S: Supported
SGI VISUAL WORKSTATION 320 AND 540 SGI VISUAL WORKSTATION 320 AND 540
P: Andrey Panin P: Andrey Panin
M: pazke@donpac.ru M: pazke@donpac.ru
......
...@@ -448,7 +448,9 @@ int npe_send_message(struct npe *npe, const void *msg, const char *what) ...@@ -448,7 +448,9 @@ int npe_send_message(struct npe *npe, const void *msg, const char *what)
return -ETIMEDOUT; return -ETIMEDOUT;
} }
#if DEBUG_MSG > 1
debug_msg(npe, "Sending a message took %i cycles\n", cycles); debug_msg(npe, "Sending a message took %i cycles\n", cycles);
#endif
return 0; return 0;
} }
...@@ -484,7 +486,9 @@ int npe_recv_message(struct npe *npe, void *msg, const char *what) ...@@ -484,7 +486,9 @@ int npe_recv_message(struct npe *npe, void *msg, const char *what)
return -ETIMEDOUT; return -ETIMEDOUT;
} }
#if DEBUG_MSG > 1
debug_msg(npe, "Receiving a message took %i cycles\n", cycles); debug_msg(npe, "Receiving a message took %i cycles\n", cycles);
#endif
return 0; return 0;
} }
......
...@@ -184,6 +184,8 @@ void qmgr_release_queue(unsigned int queue) ...@@ -184,6 +184,8 @@ void qmgr_release_queue(unsigned int queue)
case 3: mask[0] = 0xFF; break; case 3: mask[0] = 0xFF; break;
} }
mask[1] = mask[2] = mask[3] = 0;
while (addr--) while (addr--)
shift_mask(mask); shift_mask(mask);
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/poison.h> #include <linux/poison.h>
#include <linux/bitrev.h> #include <linux/bitrev.h>
#include <linux/mutex.h>
#include <asm/atomic.h> #include <asm/atomic.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -1177,7 +1178,7 @@ static int amb_open (struct atm_vcc * atm_vcc) ...@@ -1177,7 +1178,7 @@ static int amb_open (struct atm_vcc * atm_vcc)
vcc->tx_frame_bits = tx_frame_bits; vcc->tx_frame_bits = tx_frame_bits;
down (&dev->vcc_sf); mutex_lock(&dev->vcc_sf);
if (dev->rxer[vci]) { if (dev->rxer[vci]) {
// RXer on the channel already, just modify rate... // RXer on the channel already, just modify rate...
cmd.request = cpu_to_be32 (SRB_MODIFY_VC_RATE); cmd.request = cpu_to_be32 (SRB_MODIFY_VC_RATE);
...@@ -1203,7 +1204,7 @@ static int amb_open (struct atm_vcc * atm_vcc) ...@@ -1203,7 +1204,7 @@ static int amb_open (struct atm_vcc * atm_vcc)
schedule(); schedule();
} }
dev->txer[vci].tx_present = 1; dev->txer[vci].tx_present = 1;
up (&dev->vcc_sf); mutex_unlock(&dev->vcc_sf);
} }
if (rxtp->traffic_class != ATM_NONE) { if (rxtp->traffic_class != ATM_NONE) {
...@@ -1211,7 +1212,7 @@ static int amb_open (struct atm_vcc * atm_vcc) ...@@ -1211,7 +1212,7 @@ static int amb_open (struct atm_vcc * atm_vcc)
vcc->rx_info.pool = pool; vcc->rx_info.pool = pool;
down (&dev->vcc_sf); mutex_lock(&dev->vcc_sf);
/* grow RX buffer pool */ /* grow RX buffer pool */
if (!dev->rxq[pool].buffers_wanted) if (!dev->rxq[pool].buffers_wanted)
dev->rxq[pool].buffers_wanted = rx_lats; dev->rxq[pool].buffers_wanted = rx_lats;
...@@ -1237,7 +1238,7 @@ static int amb_open (struct atm_vcc * atm_vcc) ...@@ -1237,7 +1238,7 @@ static int amb_open (struct atm_vcc * atm_vcc)
schedule(); schedule();
// this link allows RX frames through // this link allows RX frames through
dev->rxer[vci] = atm_vcc; dev->rxer[vci] = atm_vcc;
up (&dev->vcc_sf); mutex_unlock(&dev->vcc_sf);
} }
// indicate readiness // indicate readiness
...@@ -1262,7 +1263,7 @@ static void amb_close (struct atm_vcc * atm_vcc) { ...@@ -1262,7 +1263,7 @@ static void amb_close (struct atm_vcc * atm_vcc) {
if (atm_vcc->qos.txtp.traffic_class != ATM_NONE) { if (atm_vcc->qos.txtp.traffic_class != ATM_NONE) {
command cmd; command cmd;
down (&dev->vcc_sf); mutex_lock(&dev->vcc_sf);
if (dev->rxer[vci]) { if (dev->rxer[vci]) {
// RXer still on the channel, just modify rate... XXX not really needed // RXer still on the channel, just modify rate... XXX not really needed
cmd.request = cpu_to_be32 (SRB_MODIFY_VC_RATE); cmd.request = cpu_to_be32 (SRB_MODIFY_VC_RATE);
...@@ -1277,7 +1278,7 @@ static void amb_close (struct atm_vcc * atm_vcc) { ...@@ -1277,7 +1278,7 @@ static void amb_close (struct atm_vcc * atm_vcc) {
dev->txer[vci].tx_present = 0; dev->txer[vci].tx_present = 0;
while (command_do (dev, &cmd)) while (command_do (dev, &cmd))
schedule(); schedule();
up (&dev->vcc_sf); mutex_unlock(&dev->vcc_sf);
} }
// disable RXing // disable RXing
...@@ -1287,7 +1288,7 @@ static void amb_close (struct atm_vcc * atm_vcc) { ...@@ -1287,7 +1288,7 @@ static void amb_close (struct atm_vcc * atm_vcc) {
// this is (the?) one reason why we need the amb_vcc struct // this is (the?) one reason why we need the amb_vcc struct
unsigned char pool = vcc->rx_info.pool; unsigned char pool = vcc->rx_info.pool;
down (&dev->vcc_sf); mutex_lock(&dev->vcc_sf);
if (dev->txer[vci].tx_present) { if (dev->txer[vci].tx_present) {
// TXer still on the channel, just go to pool zero XXX not really needed // TXer still on the channel, just go to pool zero XXX not really needed
cmd.request = cpu_to_be32 (SRB_MODIFY_VC_FLAGS); cmd.request = cpu_to_be32 (SRB_MODIFY_VC_FLAGS);
...@@ -1314,7 +1315,7 @@ static void amb_close (struct atm_vcc * atm_vcc) { ...@@ -1314,7 +1315,7 @@ static void amb_close (struct atm_vcc * atm_vcc) {
dev->rxq[pool].buffers_wanted = 0; dev->rxq[pool].buffers_wanted = 0;
drain_rx_pool (dev, pool); drain_rx_pool (dev, pool);
} }
up (&dev->vcc_sf); mutex_unlock(&dev->vcc_sf);
} }
// free our structure // free our structure
...@@ -2188,7 +2189,7 @@ static void setup_dev(amb_dev *dev, struct pci_dev *pci_dev) ...@@ -2188,7 +2189,7 @@ static void setup_dev(amb_dev *dev, struct pci_dev *pci_dev)
// semaphore for txer/rxer modifications - we cannot use a // semaphore for txer/rxer modifications - we cannot use a
// spinlock as the critical region needs to switch processes // spinlock as the critical region needs to switch processes
init_MUTEX (&dev->vcc_sf); mutex_init(&dev->vcc_sf);
// queue manipulation spinlocks; we want atomic reads and // queue manipulation spinlocks; we want atomic reads and
// writes to the queue descriptors (handles IRQ and SMP) // writes to the queue descriptors (handles IRQ and SMP)
// consider replacing "int pending" -> "atomic_t available" // consider replacing "int pending" -> "atomic_t available"
......
...@@ -638,7 +638,7 @@ struct amb_dev { ...@@ -638,7 +638,7 @@ struct amb_dev {
amb_txq txq; amb_txq txq;
amb_rxq rxq[NUM_RX_POOLS]; amb_rxq rxq[NUM_RX_POOLS];
struct semaphore vcc_sf; struct mutex vcc_sf;
amb_tx_info txer[NUM_VCS]; amb_tx_info txer[NUM_VCS];
struct atm_vcc * rxer[NUM_VCS]; struct atm_vcc * rxer[NUM_VCS];
unsigned int tx_avail; unsigned int tx_avail;
......
...@@ -670,7 +670,7 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id) ...@@ -670,7 +670,7 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
memcpy(adapter->current_dma.target, adapter->dma_buffer, adapter->current_dma.length); memcpy(adapter->current_dma.target, adapter->dma_buffer, adapter->current_dma.length);
} }
skb->protocol = eth_type_trans(skb,dev); skb->protocol = eth_type_trans(skb,dev);
adapter->stats.rx_bytes += skb->len; dev->stats.rx_bytes += skb->len;
netif_rx(skb); netif_rx(skb);
dev->last_rx = jiffies; dev->last_rx = jiffies;
} }
...@@ -773,12 +773,12 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id) ...@@ -773,12 +773,12 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
* received board statistics * received board statistics
*/ */
case CMD_NETWORK_STATISTICS_RESPONSE: case CMD_NETWORK_STATISTICS_RESPONSE:
adapter->stats.rx_packets += adapter->irx_pcb.data.netstat.tot_recv; dev->stats.rx_packets += adapter->irx_pcb.data.netstat.tot_recv;
adapter->stats.tx_packets += adapter->irx_pcb.data.netstat.tot_xmit; dev->stats.tx_packets += adapter->irx_pcb.data.netstat.tot_xmit;
adapter->stats.rx_crc_errors += adapter->irx_pcb.data.netstat.err_CRC; dev->stats.rx_crc_errors += adapter->irx_pcb.data.netstat.err_CRC;
adapter->stats.rx_frame_errors += adapter->irx_pcb.data.netstat.err_align; dev->stats.rx_frame_errors += adapter->irx_pcb.data.netstat.err_align;
adapter->stats.rx_fifo_errors += adapter->irx_pcb.data.netstat.err_ovrrun; dev->stats.rx_fifo_errors += adapter->irx_pcb.data.netstat.err_ovrrun;
adapter->stats.rx_over_errors += adapter->irx_pcb.data.netstat.err_res; dev->stats.rx_over_errors += adapter->irx_pcb.data.netstat.err_res;
adapter->got[CMD_NETWORK_STATISTICS] = 1; adapter->got[CMD_NETWORK_STATISTICS] = 1;
if (elp_debug >= 3) if (elp_debug >= 3)
printk(KERN_DEBUG "%s: interrupt - statistics response received\n", dev->name); printk(KERN_DEBUG "%s: interrupt - statistics response received\n", dev->name);
...@@ -794,11 +794,11 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id) ...@@ -794,11 +794,11 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
break; break;
switch (adapter->irx_pcb.data.xmit_resp.c_stat) { switch (adapter->irx_pcb.data.xmit_resp.c_stat) {
case 0xffff: case 0xffff:
adapter->stats.tx_aborted_errors++; dev->stats.tx_aborted_errors++;
printk(KERN_INFO "%s: transmit timed out, network cable problem?\n", dev->name); printk(KERN_INFO "%s: transmit timed out, network cable problem?\n", dev->name);
break; break;
case 0xfffe: case 0xfffe:
adapter->stats.tx_fifo_errors++; dev->stats.tx_fifo_errors++;
printk(KERN_INFO "%s: transmit timed out, FIFO underrun\n", dev->name); printk(KERN_INFO "%s: transmit timed out, FIFO underrun\n", dev->name);
break; break;
} }
...@@ -986,7 +986,7 @@ static bool send_packet(struct net_device *dev, struct sk_buff *skb) ...@@ -986,7 +986,7 @@ static bool send_packet(struct net_device *dev, struct sk_buff *skb)
return false; return false;
} }
adapter->stats.tx_bytes += nlen; dev->stats.tx_bytes += nlen;
/* /*
* send the adapter a transmit packet command. Ignore segment and offset * send the adapter a transmit packet command. Ignore segment and offset
...@@ -1041,7 +1041,6 @@ static bool send_packet(struct net_device *dev, struct sk_buff *skb) ...@@ -1041,7 +1041,6 @@ static bool send_packet(struct net_device *dev, struct sk_buff *skb)
static void elp_timeout(struct net_device *dev) static void elp_timeout(struct net_device *dev)
{ {
elp_device *adapter = dev->priv;
int stat; int stat;
stat = inb_status(dev->base_addr); stat = inb_status(dev->base_addr);
...@@ -1049,7 +1048,7 @@ static void elp_timeout(struct net_device *dev) ...@@ -1049,7 +1048,7 @@ static void elp_timeout(struct net_device *dev)
if (elp_debug >= 1) if (elp_debug >= 1)
printk(KERN_DEBUG "%s: status %#02x\n", dev->name, stat); printk(KERN_DEBUG "%s: status %#02x\n", dev->name, stat);
dev->trans_start = jiffies; dev->trans_start = jiffies;
adapter->stats.tx_dropped++; dev->stats.tx_dropped++;
netif_wake_queue(dev); netif_wake_queue(dev);
} }
...@@ -1113,7 +1112,7 @@ static struct net_device_stats *elp_get_stats(struct net_device *dev) ...@@ -1113,7 +1112,7 @@ static struct net_device_stats *elp_get_stats(struct net_device *dev)
/* If the device is closed, just return the latest stats we have, /* If the device is closed, just return the latest stats we have,
- we cannot ask from the adapter without interrupts */ - we cannot ask from the adapter without interrupts */
if (!netif_running(dev)) if (!netif_running(dev))
return &adapter->stats; return &dev->stats;
/* send a get statistics command to the board */ /* send a get statistics command to the board */
adapter->tx_pcb.command = CMD_NETWORK_STATISTICS; adapter->tx_pcb.command = CMD_NETWORK_STATISTICS;
...@@ -1126,12 +1125,12 @@ static struct net_device_stats *elp_get_stats(struct net_device *dev) ...@@ -1126,12 +1125,12 @@ static struct net_device_stats *elp_get_stats(struct net_device *dev)
while (adapter->got[CMD_NETWORK_STATISTICS] == 0 && time_before(jiffies, timeout)); while (adapter->got[CMD_NETWORK_STATISTICS] == 0 && time_before(jiffies, timeout));
if (time_after_eq(jiffies, timeout)) { if (time_after_eq(jiffies, timeout)) {
TIMEOUT_MSG(__LINE__); TIMEOUT_MSG(__LINE__);
return &adapter->stats; return &dev->stats;
} }
} }
/* statistics are now up to date */ /* statistics are now up to date */
return &adapter->stats; return &dev->stats;
} }
...@@ -1571,7 +1570,6 @@ static int __init elplus_setup(struct net_device *dev) ...@@ -1571,7 +1570,6 @@ static int __init elplus_setup(struct net_device *dev)
dev->set_multicast_list = elp_set_mc_list; /* local */ dev->set_multicast_list = elp_set_mc_list; /* local */
dev->ethtool_ops = &netdev_ethtool_ops; /* local */ dev->ethtool_ops = &netdev_ethtool_ops; /* local */
memset(&(adapter->stats), 0, sizeof(struct net_device_stats));
dev->mem_start = dev->mem_end = 0; dev->mem_start = dev->mem_end = 0;
err = register_netdev(dev); err = register_netdev(dev);
......
...@@ -264,7 +264,6 @@ typedef struct { ...@@ -264,7 +264,6 @@ typedef struct {
pcb_struct rx_pcb; /* PCB for foreground receiving */ pcb_struct rx_pcb; /* PCB for foreground receiving */
pcb_struct itx_pcb; /* PCB for background sending */ pcb_struct itx_pcb; /* PCB for background sending */
pcb_struct irx_pcb; /* PCB for background receiving */ pcb_struct irx_pcb; /* PCB for background receiving */
struct net_device_stats stats;
void *dma_buffer; void *dma_buffer;
......
...@@ -167,7 +167,6 @@ enum RxFilter { ...@@ -167,7 +167,6 @@ enum RxFilter {
enum el3_cardtype { EL3_ISA, EL3_PNP, EL3_MCA, EL3_EISA }; enum el3_cardtype { EL3_ISA, EL3_PNP, EL3_MCA, EL3_EISA };
struct el3_private { struct el3_private {
struct net_device_stats stats;
spinlock_t lock; spinlock_t lock;
/* skb send-queue */ /* skb send-queue */
int head, size; int head, size;
...@@ -794,7 +793,6 @@ el3_open(struct net_device *dev) ...@@ -794,7 +793,6 @@ el3_open(struct net_device *dev)
static void static void
el3_tx_timeout (struct net_device *dev) el3_tx_timeout (struct net_device *dev)
{ {
struct el3_private *lp = netdev_priv(dev);
int ioaddr = dev->base_addr; int ioaddr = dev->base_addr;
/* Transmitter timeout, serious problems. */ /* Transmitter timeout, serious problems. */
...@@ -802,7 +800,7 @@ el3_tx_timeout (struct net_device *dev) ...@@ -802,7 +800,7 @@ el3_tx_timeout (struct net_device *dev)
"Tx FIFO room %d.\n", "Tx FIFO room %d.\n",
dev->name, inb(ioaddr + TX_STATUS), inw(ioaddr + EL3_STATUS), dev->name, inb(ioaddr + TX_STATUS), inw(ioaddr + EL3_STATUS),
inw(ioaddr + TX_FREE)); inw(ioaddr + TX_FREE));
lp->stats.tx_errors++; dev->stats.tx_errors++;
dev->trans_start = jiffies; dev->trans_start = jiffies;
/* Issue TX_RESET and TX_START commands. */ /* Issue TX_RESET and TX_START commands. */
outw(TxReset, ioaddr + EL3_CMD); outw(TxReset, ioaddr + EL3_CMD);
...@@ -820,7 +818,7 @@ el3_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -820,7 +818,7 @@ el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
netif_stop_queue (dev); netif_stop_queue (dev);
lp->stats.tx_bytes += skb->len; dev->stats.tx_bytes += skb->len;
if (el3_debug > 4) { if (el3_debug > 4) {
printk(KERN_DEBUG "%s: el3_start_xmit(length = %u) called, status %4.4x.\n", printk(KERN_DEBUG "%s: el3_start_xmit(length = %u) called, status %4.4x.\n",
...@@ -881,7 +879,7 @@ el3_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -881,7 +879,7 @@ el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
int i = 4; int i = 4;
while (--i > 0 && (tx_status = inb(ioaddr + TX_STATUS)) > 0) { while (--i > 0 && (tx_status = inb(ioaddr + TX_STATUS)) > 0) {
if (tx_status & 0x38) lp->stats.tx_aborted_errors++; if (tx_status & 0x38) dev->stats.tx_aborted_errors++;
if (tx_status & 0x30) outw(TxReset, ioaddr + EL3_CMD); if (tx_status & 0x30) outw(TxReset, ioaddr + EL3_CMD);
if (tx_status & 0x3C) outw(TxEnable, ioaddr + EL3_CMD); if (tx_status & 0x3C) outw(TxEnable, ioaddr + EL3_CMD);
outb(0x00, ioaddr + TX_STATUS); /* Pop the status stack. */ outb(0x00, ioaddr + TX_STATUS); /* Pop the status stack. */
...@@ -931,12 +929,11 @@ el3_interrupt(int irq, void *dev_id) ...@@ -931,12 +929,11 @@ el3_interrupt(int irq, void *dev_id)
outw(AckIntr | RxEarly, ioaddr + EL3_CMD); outw(AckIntr | RxEarly, ioaddr + EL3_CMD);
} }
if (status & TxComplete) { /* Really Tx error. */ if (status & TxComplete) { /* Really Tx error. */
struct el3_private *lp = netdev_priv(dev);
short tx_status; short tx_status;
int i = 4; int i = 4;
while (--i>0 && (tx_status = inb(ioaddr + TX_STATUS)) > 0) { while (--i>0 && (tx_status = inb(ioaddr + TX_STATUS)) > 0) {
if (tx_status & 0x38) lp->stats.tx_aborted_errors++; if (tx_status & 0x38) dev->stats.tx_aborted_errors++;
if (tx_status & 0x30) outw(TxReset, ioaddr + EL3_CMD); if (tx_status & 0x30) outw(TxReset, ioaddr + EL3_CMD);
if (tx_status & 0x3C) outw(TxEnable, ioaddr + EL3_CMD); if (tx_status & 0x3C) outw(TxEnable, ioaddr + EL3_CMD);
outb(0x00, ioaddr + TX_STATUS); /* Pop the status stack. */ outb(0x00, ioaddr + TX_STATUS); /* Pop the status stack. */
...@@ -1002,7 +999,7 @@ el3_get_stats(struct net_device *dev) ...@@ -1002,7 +999,7 @@ el3_get_stats(struct net_device *dev)
spin_lock_irqsave(&lp->lock, flags); spin_lock_irqsave(&lp->lock, flags);
update_stats(dev); update_stats(dev);
spin_unlock_irqrestore(&lp->lock, flags); spin_unlock_irqrestore(&lp->lock, flags);
return &lp->stats; return &dev->stats;
} }
/* Update statistics. We change to register window 6, so this should be run /* Update statistics. We change to register window 6, so this should be run
...@@ -1012,7 +1009,6 @@ el3_get_stats(struct net_device *dev) ...@@ -1012,7 +1009,6 @@ el3_get_stats(struct net_device *dev)
*/ */
static void update_stats(struct net_device *dev) static void update_stats(struct net_device *dev)
{ {
struct el3_private *lp = netdev_priv(dev);
int ioaddr = dev->base_addr; int ioaddr = dev->base_addr;
if (el3_debug > 5) if (el3_debug > 5)
...@@ -1021,13 +1017,13 @@ static void update_stats(struct net_device *dev) ...@@ -1021,13 +1017,13 @@ static void update_stats(struct net_device *dev)
outw(StatsDisable, ioaddr + EL3_CMD); outw(StatsDisable, ioaddr + EL3_CMD);
/* Switch to the stats window, and read everything. */ /* Switch to the stats window, and read everything. */
EL3WINDOW(6); EL3WINDOW(6);
lp->stats.tx_carrier_errors += inb(ioaddr + 0); dev->stats.tx_carrier_errors += inb(ioaddr + 0);
lp->stats.tx_heartbeat_errors += inb(ioaddr + 1); dev->stats.tx_heartbeat_errors += inb(ioaddr + 1);
/* Multiple collisions. */ inb(ioaddr + 2); /* Multiple collisions. */ inb(ioaddr + 2);
lp->stats.collisions += inb(ioaddr + 3); dev->stats.collisions += inb(ioaddr + 3);
lp->stats.tx_window_errors += inb(ioaddr + 4); dev->stats.tx_window_errors += inb(ioaddr + 4);
lp->stats.rx_fifo_errors += inb(ioaddr + 5); dev->stats.rx_fifo_errors += inb(ioaddr + 5);
lp->stats.tx_packets += inb(ioaddr + 6); dev->stats.tx_packets += inb(ioaddr + 6);
/* Rx packets */ inb(ioaddr + 7); /* Rx packets */ inb(ioaddr + 7);
/* Tx deferrals */ inb(ioaddr + 8); /* Tx deferrals */ inb(ioaddr + 8);
inw(ioaddr + 10); /* Total Rx and Tx octets. */ inw(ioaddr + 10); /* Total Rx and Tx octets. */
...@@ -1042,7 +1038,6 @@ static void update_stats(struct net_device *dev) ...@@ -1042,7 +1038,6 @@ static void update_stats(struct net_device *dev)
static int static int
el3_rx(struct net_device *dev) el3_rx(struct net_device *dev)
{ {
struct el3_private *lp = netdev_priv(dev);
int ioaddr = dev->base_addr; int ioaddr = dev->base_addr;
short rx_status; short rx_status;
...@@ -1054,21 +1049,21 @@ el3_rx(struct net_device *dev) ...@@ -1054,21 +1049,21 @@ el3_rx(struct net_device *dev)
short error = rx_status & 0x3800; short error = rx_status & 0x3800;
outw(RxDiscard, ioaddr + EL3_CMD); outw(RxDiscard, ioaddr + EL3_CMD);
lp->stats.rx_errors++; dev->stats.rx_errors++;
switch (error) { switch (error) {
case 0x0000: lp->stats.rx_over_errors++; break; case 0x0000: dev->stats.rx_over_errors++; break;
case 0x0800: lp->stats.rx_length_errors++; break; case 0x0800: dev->stats.rx_length_errors++; break;
case 0x1000: lp->stats.rx_frame_errors++; break; case 0x1000: dev->stats.rx_frame_errors++; break;
case 0x1800: lp->stats.rx_length_errors++; break; case 0x1800: dev->stats.rx_length_errors++; break;
case 0x2000: lp->stats.rx_frame_errors++; break; case 0x2000: dev->stats.rx_frame_errors++; break;
case 0x2800: lp->stats.rx_crc_errors++; break; case 0x2800: dev->stats.rx_crc_errors++; break;
} }
} else { } else {
short pkt_len = rx_status & 0x7ff; short pkt_len = rx_status & 0x7ff;
struct sk_buff *skb; struct sk_buff *skb;
skb = dev_alloc_skb(pkt_len+5); skb = dev_alloc_skb(pkt_len+5);
lp->stats.rx_bytes += pkt_len; dev->stats.rx_bytes += pkt_len;
if (el3_debug > 4) if (el3_debug > 4)
printk("Receiving packet size %d status %4.4x.\n", printk("Receiving packet size %d status %4.4x.\n",
pkt_len, rx_status); pkt_len, rx_status);
...@@ -1083,11 +1078,11 @@ el3_rx(struct net_device *dev) ...@@ -1083,11 +1078,11 @@ el3_rx(struct net_device *dev)
skb->protocol = eth_type_trans(skb,dev); skb->protocol = eth_type_trans(skb,dev);
netif_rx(skb); netif_rx(skb);
dev->last_rx = jiffies; dev->last_rx = jiffies;
lp->stats.rx_packets++; dev->stats.rx_packets++;
continue; continue;
} }
outw(RxDiscard, ioaddr + EL3_CMD); outw(RxDiscard, ioaddr + EL3_CMD);
lp->stats.rx_dropped++; dev->stats.rx_dropped++;
if (el3_debug) if (el3_debug)
printk("%s: Couldn't allocate a sk_buff of size %d.\n", printk("%s: Couldn't allocate a sk_buff of size %d.\n",
dev->name, pkt_len); dev->name, pkt_len);
......
...@@ -310,7 +310,6 @@ struct corkscrew_private { ...@@ -310,7 +310,6 @@ struct corkscrew_private {
struct sk_buff *tx_skbuff[TX_RING_SIZE]; struct sk_buff *tx_skbuff[TX_RING_SIZE];
unsigned int cur_rx, cur_tx; /* The next free ring entry */ unsigned int cur_rx, cur_tx; /* The next free ring entry */
unsigned int dirty_rx, dirty_tx;/* The ring entries to be free()ed. */ unsigned int dirty_rx, dirty_tx;/* The ring entries to be free()ed. */
struct net_device_stats stats;
struct sk_buff *tx_skb; /* Packet being eaten by bus master ctrl. */ struct sk_buff *tx_skb; /* Packet being eaten by bus master ctrl. */
struct timer_list timer; /* Media selection timer. */ struct timer_list timer; /* Media selection timer. */
int capabilities ; /* Adapter capabilities word. */ int capabilities ; /* Adapter capabilities word. */
...@@ -983,8 +982,8 @@ static void corkscrew_timeout(struct net_device *dev) ...@@ -983,8 +982,8 @@ static void corkscrew_timeout(struct net_device *dev)
break; break;
outw(TxEnable, ioaddr + EL3_CMD); outw(TxEnable, ioaddr + EL3_CMD);
dev->trans_start = jiffies; dev->trans_start = jiffies;
vp->stats.tx_errors++; dev->stats.tx_errors++;
vp->stats.tx_dropped++; dev->stats.tx_dropped++;
netif_wake_queue(dev); netif_wake_queue(dev);
} }
...@@ -1050,7 +1049,7 @@ static int corkscrew_start_xmit(struct sk_buff *skb, ...@@ -1050,7 +1049,7 @@ static int corkscrew_start_xmit(struct sk_buff *skb,
} }
/* Put out the doubleword header... */ /* Put out the doubleword header... */
outl(skb->len, ioaddr + TX_FIFO); outl(skb->len, ioaddr + TX_FIFO);
vp->stats.tx_bytes += skb->len; dev->stats.tx_bytes += skb->len;
#ifdef VORTEX_BUS_MASTER #ifdef VORTEX_BUS_MASTER
if (vp->bus_master) { if (vp->bus_master) {
/* Set the bus-master controller to transfer the packet. */ /* Set the bus-master controller to transfer the packet. */
...@@ -1094,9 +1093,9 @@ static int corkscrew_start_xmit(struct sk_buff *skb, ...@@ -1094,9 +1093,9 @@ static int corkscrew_start_xmit(struct sk_buff *skb,
printk("%s: Tx error, status %2.2x.\n", printk("%s: Tx error, status %2.2x.\n",
dev->name, tx_status); dev->name, tx_status);
if (tx_status & 0x04) if (tx_status & 0x04)
vp->stats.tx_fifo_errors++; dev->stats.tx_fifo_errors++;
if (tx_status & 0x38) if (tx_status & 0x38)
vp->stats.tx_aborted_errors++; dev->stats.tx_aborted_errors++;
if (tx_status & 0x30) { if (tx_status & 0x30) {
int j; int j;
outw(TxReset, ioaddr + EL3_CMD); outw(TxReset, ioaddr + EL3_CMD);
...@@ -1257,7 +1256,6 @@ static irqreturn_t corkscrew_interrupt(int irq, void *dev_id) ...@@ -1257,7 +1256,6 @@ static irqreturn_t corkscrew_interrupt(int irq, void *dev_id)
static int corkscrew_rx(struct net_device *dev) static int corkscrew_rx(struct net_device *dev)
{ {
struct corkscrew_private *vp = netdev_priv(dev);
int ioaddr = dev->base_addr; int ioaddr = dev->base_addr;
int i; int i;
short rx_status; short rx_status;
...@@ -1271,17 +1269,17 @@ static int corkscrew_rx(struct net_device *dev) ...@@ -1271,17 +1269,17 @@ static int corkscrew_rx(struct net_device *dev)
if (corkscrew_debug > 2) if (corkscrew_debug > 2)
printk(" Rx error: status %2.2x.\n", printk(" Rx error: status %2.2x.\n",
rx_error); rx_error);
vp->stats.rx_errors++; dev->stats.rx_errors++;
if (rx_error & 0x01) if (rx_error & 0x01)
vp->stats.rx_over_errors++; dev->stats.rx_over_errors++;
if (rx_error & 0x02) if (rx_error & 0x02)
vp->stats.rx_length_errors++; dev->stats.rx_length_errors++;
if (rx_error & 0x04) if (rx_error & 0x04)
vp->stats.rx_frame_errors++; dev->stats.rx_frame_errors++;
if (rx_error & 0x08) if (rx_error & 0x08)
vp->stats.rx_crc_errors++; dev->stats.rx_crc_errors++;
if (rx_error & 0x10) if (rx_error & 0x10)
vp->stats.rx_length_errors++; dev->stats.rx_length_errors++;
} else { } else {
/* The packet length: up to 4.5K!. */ /* The packet length: up to 4.5K!. */
short pkt_len = rx_status & 0x1fff; short pkt_len = rx_status & 0x1fff;
...@@ -1301,8 +1299,8 @@ static int corkscrew_rx(struct net_device *dev) ...@@ -1301,8 +1299,8 @@ static int corkscrew_rx(struct net_device *dev)
skb->protocol = eth_type_trans(skb, dev); skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb); netif_rx(skb);
dev->last_rx = jiffies; dev->last_rx = jiffies;
vp->stats.rx_packets++; dev->stats.rx_packets++;
vp->stats.rx_bytes += pkt_len; dev->stats.rx_bytes += pkt_len;
/* Wait a limited time to go to next packet. */ /* Wait a limited time to go to next packet. */
for (i = 200; i >= 0; i--) for (i = 200; i >= 0; i--)
if (! (inw(ioaddr + EL3_STATUS) & CmdInProgress)) if (! (inw(ioaddr + EL3_STATUS) & CmdInProgress))
...@@ -1312,7 +1310,7 @@ static int corkscrew_rx(struct net_device *dev) ...@@ -1312,7 +1310,7 @@ static int corkscrew_rx(struct net_device *dev)
printk("%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, pkt_len); printk("%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, pkt_len);
} }
outw(RxDiscard, ioaddr + EL3_CMD); outw(RxDiscard, ioaddr + EL3_CMD);
vp->stats.rx_dropped++; dev->stats.rx_dropped++;
/* Wait a limited time to skip this packet. */ /* Wait a limited time to skip this packet. */
for (i = 200; i >= 0; i--) for (i = 200; i >= 0; i--)
if (!(inw(ioaddr + EL3_STATUS) & CmdInProgress)) if (!(inw(ioaddr + EL3_STATUS) & CmdInProgress))
...@@ -1337,23 +1335,23 @@ static int boomerang_rx(struct net_device *dev) ...@@ -1337,23 +1335,23 @@ static int boomerang_rx(struct net_device *dev)
if (corkscrew_debug > 2) if (corkscrew_debug > 2)
printk(" Rx error: status %2.2x.\n", printk(" Rx error: status %2.2x.\n",
rx_error); rx_error);
vp->stats.rx_errors++; dev->stats.rx_errors++;
if (rx_error & 0x01) if (rx_error & 0x01)
vp->stats.rx_over_errors++; dev->stats.rx_over_errors++;
if (rx_error & 0x02) if (rx_error & 0x02)
vp->stats.rx_length_errors++; dev->stats.rx_length_errors++;
if (rx_error & 0x04) if (rx_error & 0x04)
vp->stats.rx_frame_errors++; dev->stats.rx_frame_errors++;
if (rx_error & 0x08) if (rx_error & 0x08)
vp->stats.rx_crc_errors++; dev->stats.rx_crc_errors++;
if (rx_error & 0x10) if (rx_error & 0x10)
vp->stats.rx_length_errors++; dev->stats.rx_length_errors++;
} else { } else {
/* The packet length: up to 4.5K!. */ /* The packet length: up to 4.5K!. */
short pkt_len = rx_status & 0x1fff; short pkt_len = rx_status & 0x1fff;
struct sk_buff *skb; struct sk_buff *skb;
vp->stats.rx_bytes += pkt_len; dev->stats.rx_bytes += pkt_len;
if (corkscrew_debug > 4) if (corkscrew_debug > 4)
printk("Receiving packet size %d status %4.4x.\n", printk("Receiving packet size %d status %4.4x.\n",
pkt_len, rx_status); pkt_len, rx_status);
...@@ -1388,7 +1386,7 @@ static int boomerang_rx(struct net_device *dev) ...@@ -1388,7 +1386,7 @@ static int boomerang_rx(struct net_device *dev)
skb->protocol = eth_type_trans(skb, dev); skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb); netif_rx(skb);
dev->last_rx = jiffies; dev->last_rx = jiffies;
vp->stats.rx_packets++; dev->stats.rx_packets++;
} }
entry = (++vp->cur_rx) % RX_RING_SIZE; entry = (++vp->cur_rx) % RX_RING_SIZE;
} }
...@@ -1475,7 +1473,7 @@ static struct net_device_stats *corkscrew_get_stats(struct net_device *dev) ...@@ -1475,7 +1473,7 @@ static struct net_device_stats *corkscrew_get_stats(struct net_device *dev)
update_stats(dev->base_addr, dev); update_stats(dev->base_addr, dev);
spin_unlock_irqrestore(&vp->lock, flags); spin_unlock_irqrestore(&vp->lock, flags);
} }
return &vp->stats; return &dev->stats;
} }
/* Update statistics. /* Update statistics.
...@@ -1487,19 +1485,17 @@ static struct net_device_stats *corkscrew_get_stats(struct net_device *dev) ...@@ -1487,19 +1485,17 @@ static struct net_device_stats *corkscrew_get_stats(struct net_device *dev)
*/ */
static void update_stats(int ioaddr, struct net_device *dev) static void update_stats(int ioaddr, struct net_device *dev)
{ {
struct corkscrew_private *vp = netdev_priv(dev);
/* Unlike the 3c5x9 we need not turn off stats updates while reading. */ /* Unlike the 3c5x9 we need not turn off stats updates while reading. */
/* Switch to the stats window, and read everything. */ /* Switch to the stats window, and read everything. */
EL3WINDOW(6); EL3WINDOW(6);
vp->stats.tx_carrier_errors += inb(ioaddr + 0); dev->stats.tx_carrier_errors += inb(ioaddr + 0);
vp->stats.tx_heartbeat_errors += inb(ioaddr + 1); dev->stats.tx_heartbeat_errors += inb(ioaddr + 1);
/* Multiple collisions. */ inb(ioaddr + 2); /* Multiple collisions. */ inb(ioaddr + 2);
vp->stats.collisions += inb(ioaddr + 3); dev->stats.collisions += inb(ioaddr + 3);
vp->stats.tx_window_errors += inb(ioaddr + 4); dev->stats.tx_window_errors += inb(ioaddr + 4);
vp->stats.rx_fifo_errors += inb(ioaddr + 5); dev->stats.rx_fifo_errors += inb(ioaddr + 5);
vp->stats.tx_packets += inb(ioaddr + 6); dev->stats.tx_packets += inb(ioaddr + 6);
vp->stats.tx_packets += (inb(ioaddr + 9) & 0x30) << 4; dev->stats.tx_packets += (inb(ioaddr + 9) & 0x30) << 4;
/* Rx packets */ inb(ioaddr + 7); /* Rx packets */ inb(ioaddr + 7);
/* Must read to clear */ /* Must read to clear */
/* Tx deferrals */ inb(ioaddr + 8); /* Tx deferrals */ inb(ioaddr + 8);
......
...@@ -2593,6 +2593,7 @@ config BNX2X ...@@ -2593,6 +2593,7 @@ config BNX2X
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 bnx2x. This is recommended. will be called bnx2x. This is recommended.
source "drivers/net/sfc/Kconfig"
endif # NETDEV_10000 endif # NETDEV_10000
......
...@@ -253,3 +253,5 @@ obj-$(CONFIG_FS_ENET) += fs_enet/ ...@@ -253,3 +253,5 @@ obj-$(CONFIG_FS_ENET) += fs_enet/
obj-$(CONFIG_NETXEN_NIC) += netxen/ obj-$(CONFIG_NETXEN_NIC) += netxen/
obj-$(CONFIG_NIU) += niu.o obj-$(CONFIG_NIU) += niu.o
obj-$(CONFIG_VIRTIO_NET) += virtio_net.o obj-$(CONFIG_VIRTIO_NET) += virtio_net.o
obj-$(CONFIG_SFC) += sfc/
...@@ -47,3 +47,11 @@ config EP93XX_ETH ...@@ -47,3 +47,11 @@ config EP93XX_ETH
help help
This is a driver for the ethernet hardware included in EP93xx CPUs. This is a driver for the ethernet hardware included in EP93xx CPUs.
Say Y if you are building a kernel for EP93xx based devices. Say Y if you are building a kernel for EP93xx based devices.
config IXP4XX_ETH
tristate "Intel IXP4xx Ethernet support"
depends on ARM && ARCH_IXP4XX && IXP4XX_NPE && IXP4XX_QMGR
select MII
help
Say Y here if you want to use built-in Ethernet ports
on IXP4xx processor.
...@@ -9,3 +9,4 @@ obj-$(CONFIG_ARM_ETHER3) += ether3.o ...@@ -9,3 +9,4 @@ obj-$(CONFIG_ARM_ETHER3) += ether3.o
obj-$(CONFIG_ARM_ETHER1) += ether1.o obj-$(CONFIG_ARM_ETHER1) += ether1.o
obj-$(CONFIG_ARM_AT91_ETHER) += at91_ether.o obj-$(CONFIG_ARM_AT91_ETHER) += at91_ether.o
obj-$(CONFIG_EP93XX_ETH) += ep93xx_eth.o obj-$(CONFIG_EP93XX_ETH) += ep93xx_eth.o
obj-$(CONFIG_IXP4XX_ETH) += ixp4xx_eth.o
This diff is collapsed.
This diff is collapsed.
...@@ -49,7 +49,7 @@ struct net_dma_desc_tx { ...@@ -49,7 +49,7 @@ struct net_dma_desc_tx {
struct status_area_tx status; struct status_area_tx status;
}; };
struct bf537mac_local { struct bfin_mac_local {
/* /*
* these are things that the kernel wants me to keep, so users * these are things that the kernel wants me to keep, so users
* can find out semi-useless statistics of how well the card is * can find out semi-useless statistics of how well the card is
......
...@@ -633,7 +633,7 @@ static void __init printEEPROMInfo(struct net_device *dev) ...@@ -633,7 +633,7 @@ static void __init printEEPROMInfo(struct net_device *dev)
printk(KERN_DEBUG " PC: %d\n", GetBit(Word,ee_PC)); printk(KERN_DEBUG " PC: %d\n", GetBit(Word,ee_PC));
printk(KERN_DEBUG " TPE/AUI: %d\n", GetBit(Word,ee_TPE_AUI)); printk(KERN_DEBUG " TPE/AUI: %d\n", GetBit(Word,ee_TPE_AUI));
printk(KERN_DEBUG " Jabber: %d\n", GetBit(Word,ee_Jabber)); printk(KERN_DEBUG " Jabber: %d\n", GetBit(Word,ee_Jabber));
printk(KERN_DEBUG " AutoPort: %d\n", GetBit(!Word,ee_Jabber)); printk(KERN_DEBUG " AutoPort: %d\n", !GetBit(Word,ee_AutoPort));
printk(KERN_DEBUG " Duplex: %d\n", GetBit(Word,ee_Duplex)); printk(KERN_DEBUG " Duplex: %d\n", GetBit(Word,ee_Duplex));
} }
......
...@@ -131,8 +131,6 @@ static void free_skb_resources(struct gfar_private *priv); ...@@ -131,8 +131,6 @@ static void free_skb_resources(struct gfar_private *priv);
static void gfar_set_multi(struct net_device *dev); static void gfar_set_multi(struct net_device *dev);
static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr); static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr);
static void gfar_configure_serdes(struct net_device *dev); static void gfar_configure_serdes(struct net_device *dev);
extern int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id, int regnum, u16 value);
extern int gfar_local_mdio_read(struct gfar_mii __iomem *regs, int mii_id, int regnum);
#ifdef CONFIG_GFAR_NAPI #ifdef CONFIG_GFAR_NAPI
static int gfar_poll(struct napi_struct *napi, int budget); static int gfar_poll(struct napi_struct *napi, int budget);
#endif #endif
...@@ -477,24 +475,30 @@ static int init_phy(struct net_device *dev) ...@@ -477,24 +475,30 @@ static int init_phy(struct net_device *dev)
return 0; return 0;
} }
/*
* Initialize TBI PHY interface for communicating with the
* SERDES lynx PHY on the chip. We communicate with this PHY
* through the MDIO bus on each controller, treating it as a
* "normal" PHY at the address found in the TBIPA register. We assume
* that the TBIPA register is valid. Either the MDIO bus code will set
* it to a value that doesn't conflict with other PHYs on the bus, or the
* value doesn't matter, as there are no other PHYs on the bus.
*/
static void gfar_configure_serdes(struct net_device *dev) static void gfar_configure_serdes(struct net_device *dev)
{ {
struct gfar_private *priv = netdev_priv(dev); struct gfar_private *priv = netdev_priv(dev);
struct gfar_mii __iomem *regs = struct gfar_mii __iomem *regs =
(void __iomem *)&priv->regs->gfar_mii_regs; (void __iomem *)&priv->regs->gfar_mii_regs;
int tbipa = gfar_read(&priv->regs->tbipa);
/* Initialise TBI i/f to communicate with serdes (lynx phy) */ /* Single clk mode, mii mode off(for serdes communication) */
gfar_local_mdio_write(regs, tbipa, MII_TBICON, TBICON_CLK_SELECT);
/* Single clk mode, mii mode off(for aerdes communication) */ gfar_local_mdio_write(regs, tbipa, MII_ADVERTISE,
gfar_local_mdio_write(regs, TBIPA_VALUE, MII_TBICON, TBICON_CLK_SELECT);
/* Supported pause and full-duplex, no half-duplex */
gfar_local_mdio_write(regs, TBIPA_VALUE, MII_ADVERTISE,
ADVERTISE_1000XFULL | ADVERTISE_1000XPAUSE | ADVERTISE_1000XFULL | ADVERTISE_1000XPAUSE |
ADVERTISE_1000XPSE_ASYM); ADVERTISE_1000XPSE_ASYM);
/* ANEG enable, restart ANEG, full duplex mode, speed[1] set */ gfar_local_mdio_write(regs, tbipa, MII_BMCR, BMCR_ANENABLE |
gfar_local_mdio_write(regs, TBIPA_VALUE, MII_BMCR, BMCR_ANENABLE |
BMCR_ANRESTART | BMCR_FULLDPLX | BMCR_SPEED1000); BMCR_ANRESTART | BMCR_FULLDPLX | BMCR_SPEED1000);
} }
...@@ -541,9 +545,6 @@ static void init_registers(struct net_device *dev) ...@@ -541,9 +545,6 @@ static void init_registers(struct net_device *dev)
/* Initialize the Minimum Frame Length Register */ /* Initialize the Minimum Frame Length Register */
gfar_write(&priv->regs->minflr, MINFLR_INIT_SETTINGS); gfar_write(&priv->regs->minflr, MINFLR_INIT_SETTINGS);
/* Assign the TBI an address which won't conflict with the PHYs */
gfar_write(&priv->regs->tbipa, TBIPA_VALUE);
} }
......
...@@ -137,7 +137,6 @@ extern const char gfar_driver_version[]; ...@@ -137,7 +137,6 @@ extern const char gfar_driver_version[];
#define DEFAULT_RXCOUNT 0 #define DEFAULT_RXCOUNT 0
#endif /* CONFIG_GFAR_NAPI */ #endif /* CONFIG_GFAR_NAPI */
#define TBIPA_VALUE 0x1f
#define MIIMCFG_INIT_VALUE 0x00000007 #define MIIMCFG_INIT_VALUE 0x00000007
#define MIIMCFG_RESET 0x80000000 #define MIIMCFG_RESET 0x80000000
#define MIIMIND_BUSY 0x00000001 #define MIIMIND_BUSY 0x00000001
......
...@@ -78,7 +78,6 @@ int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id, ...@@ -78,7 +78,6 @@ int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id,
* same as system mdio bus, used for controlling the external PHYs, for eg. * same as system mdio bus, used for controlling the external PHYs, for eg.
*/ */
int gfar_local_mdio_read(struct gfar_mii __iomem *regs, int mii_id, int regnum) int gfar_local_mdio_read(struct gfar_mii __iomem *regs, int mii_id, int regnum)
{ {
u16 value; u16 value;
...@@ -122,7 +121,7 @@ int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum) ...@@ -122,7 +121,7 @@ int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
} }
/* Reset the MIIM registers, and wait for the bus to free */ /* Reset the MIIM registers, and wait for the bus to free */
int gfar_mdio_reset(struct mii_bus *bus) static int gfar_mdio_reset(struct mii_bus *bus)
{ {
struct gfar_mii __iomem *regs = (void __iomem *)bus->priv; struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;
unsigned int timeout = PHY_INIT_TIMEOUT; unsigned int timeout = PHY_INIT_TIMEOUT;
...@@ -152,14 +151,15 @@ int gfar_mdio_reset(struct mii_bus *bus) ...@@ -152,14 +151,15 @@ int gfar_mdio_reset(struct mii_bus *bus)
} }
int gfar_mdio_probe(struct device *dev) static int gfar_mdio_probe(struct device *dev)
{ {
struct platform_device *pdev = to_platform_device(dev); struct platform_device *pdev = to_platform_device(dev);
struct gianfar_mdio_data *pdata; struct gianfar_mdio_data *pdata;
struct gfar_mii __iomem *regs; struct gfar_mii __iomem *regs;
struct gfar __iomem *enet_regs;
struct mii_bus *new_bus; struct mii_bus *new_bus;
struct resource *r; struct resource *r;
int err = 0; int i, err = 0;
if (NULL == dev) if (NULL == dev)
return -EINVAL; return -EINVAL;
...@@ -199,6 +199,34 @@ int gfar_mdio_probe(struct device *dev) ...@@ -199,6 +199,34 @@ int gfar_mdio_probe(struct device *dev)
new_bus->dev = dev; new_bus->dev = dev;
dev_set_drvdata(dev, new_bus); dev_set_drvdata(dev, new_bus);
/*
* This is mildly evil, but so is our hardware for doing this.
* Also, we have to cast back to struct gfar_mii because of
* definition weirdness done in gianfar.h.
*/
enet_regs = (struct gfar __iomem *)
((char *)regs - offsetof(struct gfar, gfar_mii_regs));
/* Scan the bus, looking for an empty spot for TBIPA */
gfar_write(&enet_regs->tbipa, 0);
for (i = PHY_MAX_ADDR; i > 0; i--) {
u32 phy_id;
int r;
r = get_phy_id(new_bus, i, &phy_id);
if (r)
return r;
if (phy_id == 0xffffffff)
break;
}
/* The bus is full. We don't support using 31 PHYs, sorry */
if (i == 0)
return -EBUSY;
gfar_write(&enet_regs->tbipa, i);
err = mdiobus_register(new_bus); err = mdiobus_register(new_bus);
if (0 != err) { if (0 != err) {
...@@ -218,7 +246,7 @@ int gfar_mdio_probe(struct device *dev) ...@@ -218,7 +246,7 @@ int gfar_mdio_probe(struct device *dev)
} }
int gfar_mdio_remove(struct device *dev) static int gfar_mdio_remove(struct device *dev)
{ {
struct mii_bus *bus = dev_get_drvdata(dev); struct mii_bus *bus = dev_get_drvdata(dev);
......
...@@ -41,6 +41,9 @@ struct gfar_mii { ...@@ -41,6 +41,9 @@ struct gfar_mii {
int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum); int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum);
int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value); int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value);
int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id,
int regnum, u16 value);
int gfar_local_mdio_read(struct gfar_mii __iomem *regs, int mii_id, int regnum);
int __init gfar_mdio_init(void); int __init gfar_mdio_init(void);
void gfar_mdio_exit(void); void gfar_mdio_exit(void);
#endif /* GIANFAR_PHY_H */ #endif /* GIANFAR_PHY_H */
...@@ -48,7 +48,7 @@ config VITESSE_PHY ...@@ -48,7 +48,7 @@ config VITESSE_PHY
config SMSC_PHY config SMSC_PHY
tristate "Drivers for SMSC PHYs" tristate "Drivers for SMSC PHYs"
---help--- ---help---
Currently supports the LAN83C185 PHY Currently supports the LAN83C185, LAN8187 and LAN8700 PHYs
config BROADCOM_PHY config BROADCOM_PHY
tristate "Drivers for Broadcom PHYs" tristate "Drivers for Broadcom PHYs"
......
...@@ -256,7 +256,7 @@ void phy_prepare_link(struct phy_device *phydev, ...@@ -256,7 +256,7 @@ void phy_prepare_link(struct phy_device *phydev,
/** /**
* phy_connect - connect an ethernet device to a PHY device * phy_connect - connect an ethernet device to a PHY device
* @dev: the network device to connect * @dev: the network device to connect
* @phy_id: the PHY device to connect * @bus_id: the id string of the PHY device to connect
* @handler: callback function for state change notifications * @handler: callback function for state change notifications
* @flags: PHY device's dev_flags * @flags: PHY device's dev_flags
* @interface: PHY device's interface * @interface: PHY device's interface
......
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
* Free Software Foundation; either version 2 of the License, or (at your * Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. * option) any later version.
* *
* Support added for SMSC LAN8187 and LAN8700 by steve.glendinning@smsc.com
*
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -38,7 +40,7 @@ ...@@ -38,7 +40,7 @@
(MII_LAN83C185_ISF_INT6 | MII_LAN83C185_ISF_INT4) (MII_LAN83C185_ISF_INT6 | MII_LAN83C185_ISF_INT4)
static int lan83c185_config_intr(struct phy_device *phydev) static int smsc_phy_config_intr(struct phy_device *phydev)
{ {
int rc = phy_write (phydev, MII_LAN83C185_IM, int rc = phy_write (phydev, MII_LAN83C185_IM,
((PHY_INTERRUPT_ENABLED == phydev->interrupts) ((PHY_INTERRUPT_ENABLED == phydev->interrupts)
...@@ -48,16 +50,16 @@ static int lan83c185_config_intr(struct phy_device *phydev) ...@@ -48,16 +50,16 @@ static int lan83c185_config_intr(struct phy_device *phydev)
return rc < 0 ? rc : 0; return rc < 0 ? rc : 0;
} }
static int lan83c185_ack_interrupt(struct phy_device *phydev) static int smsc_phy_ack_interrupt(struct phy_device *phydev)
{ {
int rc = phy_read (phydev, MII_LAN83C185_ISF); int rc = phy_read (phydev, MII_LAN83C185_ISF);
return rc < 0 ? rc : 0; return rc < 0 ? rc : 0;
} }
static int lan83c185_config_init(struct phy_device *phydev) static int smsc_phy_config_init(struct phy_device *phydev)
{ {
return lan83c185_ack_interrupt (phydev); return smsc_phy_ack_interrupt (phydev);
} }
...@@ -73,22 +75,87 @@ static struct phy_driver lan83c185_driver = { ...@@ -73,22 +75,87 @@ static struct phy_driver lan83c185_driver = {
/* basic functions */ /* basic functions */
.config_aneg = genphy_config_aneg, .config_aneg = genphy_config_aneg,
.read_status = genphy_read_status, .read_status = genphy_read_status,
.config_init = lan83c185_config_init, .config_init = smsc_phy_config_init,
/* IRQ related */ /* IRQ related */
.ack_interrupt = lan83c185_ack_interrupt, .ack_interrupt = smsc_phy_ack_interrupt,
.config_intr = lan83c185_config_intr, .config_intr = smsc_phy_config_intr,
.driver = { .owner = THIS_MODULE, }
};
static struct phy_driver lan8187_driver = {
.phy_id = 0x0007c0b0, /* OUI=0x00800f, Model#=0x0b */
.phy_id_mask = 0xfffffff0,
.name = "SMSC LAN8187",
.features = (PHY_BASIC_FEATURES | SUPPORTED_Pause
| SUPPORTED_Asym_Pause),
.flags = PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG,
/* basic functions */
.config_aneg = genphy_config_aneg,
.read_status = genphy_read_status,
.config_init = smsc_phy_config_init,
/* IRQ related */
.ack_interrupt = smsc_phy_ack_interrupt,
.config_intr = smsc_phy_config_intr,
.driver = { .owner = THIS_MODULE, }
};
static struct phy_driver lan8700_driver = {
.phy_id = 0x0007c0c0, /* OUI=0x00800f, Model#=0x0c */
.phy_id_mask = 0xfffffff0,
.name = "SMSC LAN8700",
.features = (PHY_BASIC_FEATURES | SUPPORTED_Pause
| SUPPORTED_Asym_Pause),
.flags = PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG,
/* basic functions */
.config_aneg = genphy_config_aneg,
.read_status = genphy_read_status,
.config_init = smsc_phy_config_init,
/* IRQ related */
.ack_interrupt = smsc_phy_ack_interrupt,
.config_intr = smsc_phy_config_intr,
.driver = { .owner = THIS_MODULE, } .driver = { .owner = THIS_MODULE, }
}; };
static int __init smsc_init(void) static int __init smsc_init(void)
{ {
return phy_driver_register (&lan83c185_driver); int ret;
ret = phy_driver_register (&lan83c185_driver);
if (ret)
goto err1;
ret = phy_driver_register (&lan8187_driver);
if (ret)
goto err2;
ret = phy_driver_register (&lan8700_driver);
if (ret)
goto err3;
return 0;
err3:
phy_driver_unregister (&lan8187_driver);
err2:
phy_driver_unregister (&lan83c185_driver);
err1:
return ret;
} }
static void __exit smsc_exit(void) static void __exit smsc_exit(void)
{ {
phy_driver_unregister (&lan8700_driver);
phy_driver_unregister (&lan8187_driver);
phy_driver_unregister (&lan83c185_driver); phy_driver_unregister (&lan83c185_driver);
} }
......
...@@ -1617,6 +1617,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1617,6 +1617,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
SET_NETDEV_DEV(dev, &pdev->dev); SET_NETDEV_DEV(dev, &pdev->dev);
tp = netdev_priv(dev); tp = netdev_priv(dev);
tp->dev = dev; tp->dev = dev;
tp->pci_dev = pdev;
tp->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT); tp->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT);
/* enable device (incl. PCI PM wakeup and hotplug setup) */ /* enable device (incl. PCI PM wakeup and hotplug setup) */
...@@ -1705,18 +1706,18 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1705,18 +1706,18 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
rtl8169_print_mac_version(tp); rtl8169_print_mac_version(tp);
for (i = ARRAY_SIZE(rtl_chip_info) - 1; i >= 0; i--) { for (i = 0; i < ARRAY_SIZE(rtl_chip_info); i++) {
if (tp->mac_version == rtl_chip_info[i].mac_version) if (tp->mac_version == rtl_chip_info[i].mac_version)
break; break;
} }
if (i < 0) { if (i == ARRAY_SIZE(rtl_chip_info)) {
/* Unknown chip: assume array element #0, original RTL-8169 */ /* Unknown chip: assume array element #0, original RTL-8169 */
if (netif_msg_probe(tp)) { if (netif_msg_probe(tp)) {
dev_printk(KERN_DEBUG, &pdev->dev, dev_printk(KERN_DEBUG, &pdev->dev,
"unknown chip version, assuming %s\n", "unknown chip version, assuming %s\n",
rtl_chip_info[0].name); rtl_chip_info[0].name);
} }
i++; i = 0;
} }
tp->chipset = i; tp->chipset = i;
...@@ -1777,7 +1778,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1777,7 +1778,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
#endif #endif
tp->intr_mask = 0xffff; tp->intr_mask = 0xffff;
tp->pci_dev = pdev;
tp->mmio_addr = ioaddr; tp->mmio_addr = ioaddr;
tp->align = cfg->align; tp->align = cfg->align;
tp->hw_start = cfg->hw_start; tp->hw_start = cfg->hw_start;
......
This diff is collapsed.
...@@ -678,11 +678,53 @@ struct rx_block_info { ...@@ -678,11 +678,53 @@ struct rx_block_info {
struct rxd_info *rxds; struct rxd_info *rxds;
}; };
/* Data structure to represent a LRO session */
struct lro {
struct sk_buff *parent;
struct sk_buff *last_frag;
u8 *l2h;
struct iphdr *iph;
struct tcphdr *tcph;
u32 tcp_next_seq;
__be32 tcp_ack;
int total_len;
int frags_len;
int sg_num;
int in_use;
__be16 window;
u16 vlan_tag;
u32 cur_tsval;
__be32 cur_tsecr;
u8 saw_ts;
} ____cacheline_aligned;
/* Ring specific structure */ /* Ring specific structure */
struct ring_info { struct ring_info {
/* The ring number */ /* The ring number */
int ring_no; int ring_no;
/* per-ring buffer counter */
u32 rx_bufs_left;
#define MAX_LRO_SESSIONS 32
struct lro lro0_n[MAX_LRO_SESSIONS];
u8 lro;
/* copy of sp->rxd_mode flag */
int rxd_mode;
/* Number of rxds per block for the rxd_mode */
int rxd_count;
/* copy of sp pointer */
struct s2io_nic *nic;
/* copy of sp->dev pointer */
struct net_device *dev;
/* copy of sp->pdev pointer */
struct pci_dev *pdev;
/* /*
* Place holders for the virtual and physical addresses of * Place holders for the virtual and physical addresses of
* all the Rx Blocks * all the Rx Blocks
...@@ -703,10 +745,16 @@ struct ring_info { ...@@ -703,10 +745,16 @@ struct ring_info {
*/ */
struct rx_curr_get_info rx_curr_get_info; struct rx_curr_get_info rx_curr_get_info;
/* interface MTU value */
unsigned mtu;
/* Buffer Address store. */ /* Buffer Address store. */
struct buffAdd **ba; struct buffAdd **ba;
struct s2io_nic *nic;
}; /* per-Ring statistics */
unsigned long rx_packets;
unsigned long rx_bytes;
} ____cacheline_aligned;
/* Fifo specific structure */ /* Fifo specific structure */
struct fifo_info { struct fifo_info {
...@@ -813,26 +861,6 @@ struct msix_info_st { ...@@ -813,26 +861,6 @@ struct msix_info_st {
u64 data; u64 data;
}; };
/* Data structure to represent a LRO session */
struct lro {
struct sk_buff *parent;
struct sk_buff *last_frag;
u8 *l2h;
struct iphdr *iph;
struct tcphdr *tcph;
u32 tcp_next_seq;
__be32 tcp_ack;
int total_len;
int frags_len;
int sg_num;
int in_use;
__be16 window;
u16 vlan_tag;
u32 cur_tsval;
__be32 cur_tsecr;
u8 saw_ts;
} ____cacheline_aligned;
/* These flags represent the devices temporary state */ /* These flags represent the devices temporary state */
enum s2io_device_state_t enum s2io_device_state_t
{ {
...@@ -872,8 +900,6 @@ struct s2io_nic { ...@@ -872,8 +900,6 @@ struct s2io_nic {
/* Space to back up the PCI config space */ /* Space to back up the PCI config space */
u32 config_space[256 / sizeof(u32)]; u32 config_space[256 / sizeof(u32)];
atomic_t rx_bufs_left[MAX_RX_RINGS];
#define PROMISC 1 #define PROMISC 1
#define ALL_MULTI 2 #define ALL_MULTI 2
...@@ -950,8 +976,6 @@ struct s2io_nic { ...@@ -950,8 +976,6 @@ struct s2io_nic {
#define XFRAME_II_DEVICE 2 #define XFRAME_II_DEVICE 2
u8 device_type; u8 device_type;
#define MAX_LRO_SESSIONS 32
struct lro lro0_n[MAX_LRO_SESSIONS];
unsigned long clubbed_frms_cnt; unsigned long clubbed_frms_cnt;
unsigned long sending_both; unsigned long sending_both;
u8 lro; u8 lro;
...@@ -1118,9 +1142,9 @@ static int do_s2io_add_mc(struct s2io_nic *sp, u8 *addr); ...@@ -1118,9 +1142,9 @@ static int do_s2io_add_mc(struct s2io_nic *sp, u8 *addr);
static int do_s2io_add_mac(struct s2io_nic *sp, u64 addr, int offset); static int do_s2io_add_mac(struct s2io_nic *sp, u64 addr, int offset);
static int do_s2io_delete_unicast_mc(struct s2io_nic *sp, u64 addr); static int do_s2io_delete_unicast_mc(struct s2io_nic *sp, u64 addr);
static int static int s2io_club_tcp_session(struct ring_info *ring_data, u8 *buffer,
s2io_club_tcp_session(u8 *buffer, u8 **tcp, u32 *tcp_len, struct lro **lro, u8 **tcp, u32 *tcp_len, struct lro **lro, struct RxD_t *rxdp,
struct RxD_t *rxdp, struct s2io_nic *sp); struct s2io_nic *sp);
static void clear_lro_session(struct lro *lro); static void clear_lro_session(struct lro *lro);
static void queue_rx_frame(struct sk_buff *skb, u16 vlan_tag); static void queue_rx_frame(struct sk_buff *skb, u16 vlan_tag);
static void update_L3L4_header(struct s2io_nic *sp, struct lro *lro); static void update_L3L4_header(struct s2io_nic *sp, struct lro *lro);
......
config SFC
tristate "Solarflare Solarstorm SFC4000 support"
depends on PCI && INET
select MII
select INET_LRO
select CRC32
help
This driver supports 10-gigabit Ethernet cards based on
the Solarflare Communications Solarstorm SFC4000 controller.
To compile this driver as a module, choose M here. The module
will be called sfc.
sfc-y += efx.o falcon.o tx.o rx.o falcon_xmac.o \
i2c-direct.o ethtool.o xfp_phy.o mdio_10g.o \
tenxpress.o boards.o sfe4001.o
obj-$(CONFIG_SFC) += sfc.o
This diff is collapsed.
/****************************************************************************
* Driver for Solarflare Solarstorm network controllers and boards
* Copyright 2007 Solarflare Communications Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation, incorporated herein by reference.
*/
#include "net_driver.h"
#include "phy.h"
#include "boards.h"
#include "efx.h"
/* Macros for unpacking the board revision */
/* The revision info is in host byte order. */
#define BOARD_TYPE(_rev) (_rev >> 8)
#define BOARD_MAJOR(_rev) ((_rev >> 4) & 0xf)
#define BOARD_MINOR(_rev) (_rev & 0xf)
/* Blink support. If the PHY has no auto-blink mode so we hang it off a timer */
#define BLINK_INTERVAL (HZ/2)
static void blink_led_timer(unsigned long context)
{
struct efx_nic *efx = (struct efx_nic *)context;
struct efx_blinker *bl = &efx->board_info.blinker;
efx->board_info.set_fault_led(efx, bl->state);
bl->state = !bl->state;
if (bl->resubmit) {
bl->timer.expires = jiffies + BLINK_INTERVAL;
add_timer(&bl->timer);
}
}
static void board_blink(struct efx_nic *efx, int blink)
{
struct efx_blinker *blinker = &efx->board_info.blinker;
/* The rtnl mutex serialises all ethtool ioctls, so
* nothing special needs doing here. */
if (blink) {
blinker->resubmit = 1;
blinker->state = 0;
setup_timer(&blinker->timer, blink_led_timer,
(unsigned long)efx);
blinker->timer.expires = jiffies + BLINK_INTERVAL;
add_timer(&blinker->timer);
} else {
blinker->resubmit = 0;
if (blinker->timer.function)
del_timer_sync(&blinker->timer);
efx->board_info.set_fault_led(efx, 0);
}
}
/*****************************************************************************
* Support for the SFE4002
*
*/
/****************************************************************************/
/* LED allocations. Note that on rev A0 boards the schematic and the reality
* differ: red and green are swapped. Below is the fixed (A1) layout (there
* are only 3 A0 boards in existence, so no real reason to make this
* conditional).
*/
#define SFE4002_FAULT_LED (2) /* Red */
#define SFE4002_RX_LED (0) /* Green */
#define SFE4002_TX_LED (1) /* Amber */
static int sfe4002_init_leds(struct efx_nic *efx)
{
/* Set the TX and RX LEDs to reflect status and activity, and the
* fault LED off */
xfp_set_led(efx, SFE4002_TX_LED,
QUAKE_LED_TXLINK | QUAKE_LED_LINK_ACTSTAT);
xfp_set_led(efx, SFE4002_RX_LED,
QUAKE_LED_RXLINK | QUAKE_LED_LINK_ACTSTAT);
xfp_set_led(efx, SFE4002_FAULT_LED, QUAKE_LED_OFF);
efx->board_info.blinker.led_num = SFE4002_FAULT_LED;
return 0;
}
static void sfe4002_fault_led(struct efx_nic *efx, int state)
{
xfp_set_led(efx, SFE4002_FAULT_LED, state ? QUAKE_LED_ON :
QUAKE_LED_OFF);
}
static int sfe4002_init(struct efx_nic *efx)
{
efx->board_info.init_leds = sfe4002_init_leds;
efx->board_info.set_fault_led = sfe4002_fault_led;
efx->board_info.blink = board_blink;
return 0;
}
/* This will get expanded as board-specific details get moved out of the
* PHY drivers. */
struct efx_board_data {
const char *ref_model;
const char *gen_type;
int (*init) (struct efx_nic *nic);
};
static int dummy_init(struct efx_nic *nic)
{
return 0;
}
static struct efx_board_data board_data[] = {
[EFX_BOARD_INVALID] =
{NULL, NULL, dummy_init},
[EFX_BOARD_SFE4001] =
{"SFE4001", "10GBASE-T adapter", sfe4001_poweron},
[EFX_BOARD_SFE4002] =
{"SFE4002", "XFP adapter", sfe4002_init},
};
int efx_set_board_info(struct efx_nic *efx, u16 revision_info)
{
int rc = 0;
struct efx_board_data *data;
if (BOARD_TYPE(revision_info) >= EFX_BOARD_MAX) {
EFX_ERR(efx, "squashing unknown board type %d\n",
BOARD_TYPE(revision_info));
revision_info = 0;
}
if (BOARD_TYPE(revision_info) == 0) {
efx->board_info.major = 0;
efx->board_info.minor = 0;
/* For early boards that don't have revision info. there is
* only 1 board for each PHY type, so we can work it out, with
* the exception of the PHY-less boards. */
switch (efx->phy_type) {
case PHY_TYPE_10XPRESS:
efx->board_info.type = EFX_BOARD_SFE4001;
break;
case PHY_TYPE_XFP:
efx->board_info.type = EFX_BOARD_SFE4002;
break;
default:
efx->board_info.type = 0;
break;
}
} else {
efx->board_info.type = BOARD_TYPE(revision_info);
efx->board_info.major = BOARD_MAJOR(revision_info);
efx->board_info.minor = BOARD_MINOR(revision_info);
}
data = &board_data[efx->board_info.type];
/* Report the board model number or generic type for recognisable
* boards. */
if (efx->board_info.type != 0)
EFX_INFO(efx, "board is %s rev %c%d\n",
(efx->pci_dev->subsystem_vendor == EFX_VENDID_SFC)
? data->ref_model : data->gen_type,
'A' + efx->board_info.major, efx->board_info.minor);
efx->board_info.init = data->init;
return rc;
}
/****************************************************************************
* Driver for Solarflare Solarstorm network controllers and boards
* Copyright 2007 Solarflare Communications Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation, incorporated herein by reference.
*/
#ifndef EFX_BOARDS_H
#define EFX_BOARDS_H
/* Board IDs (must fit in 8 bits) */
enum efx_board_type {
EFX_BOARD_INVALID = 0,
EFX_BOARD_SFE4001 = 1, /* SFE4001 (10GBASE-T) */
EFX_BOARD_SFE4002 = 2,
/* Insert new types before here */
EFX_BOARD_MAX
};
extern int efx_set_board_info(struct efx_nic *efx, u16 revision_info);
extern int sfe4001_poweron(struct efx_nic *efx);
extern void sfe4001_poweroff(struct efx_nic *efx);
#endif
This diff is collapsed.
/****************************************************************************
* Driver for Solarflare Solarstorm network controllers and boards
* Copyright 2005-2006 Fen Systems Ltd.
* Copyright 2006-2008 Solarflare Communications Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation, incorporated herein by reference.
*/
#ifndef EFX_EFX_H
#define EFX_EFX_H
#include "net_driver.h"
/* PCI IDs */
#define EFX_VENDID_SFC 0x1924
#define FALCON_A_P_DEVID 0x0703
#define FALCON_A_S_DEVID 0x6703
#define FALCON_B_P_DEVID 0x0710
/* TX */
extern int efx_xmit(struct efx_nic *efx,
struct efx_tx_queue *tx_queue, struct sk_buff *skb);
extern void efx_stop_queue(struct efx_nic *efx);
extern void efx_wake_queue(struct efx_nic *efx);
/* RX */
extern void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index);
extern void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
unsigned int len, int checksummed, int discard);
extern void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue, int delay);
/* Channels */
extern void efx_process_channel_now(struct efx_channel *channel);
extern int efx_flush_queues(struct efx_nic *efx);
/* Ports */
extern void efx_reconfigure_port(struct efx_nic *efx);
/* Global */
extern void efx_schedule_reset(struct efx_nic *efx, enum reset_type type);
extern void efx_suspend(struct efx_nic *efx);
extern void efx_resume(struct efx_nic *efx);
extern void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs,
int rx_usecs);
extern int efx_request_power(struct efx_nic *efx, int mw, const char *name);
extern void efx_hex_dump(const u8 *, unsigned int, const char *);
/* Dummy PHY ops for PHY drivers */
extern int efx_port_dummy_op_int(struct efx_nic *efx);
extern void efx_port_dummy_op_void(struct efx_nic *efx);
extern void efx_port_dummy_op_blink(struct efx_nic *efx, int blink);
extern unsigned int efx_monitor_interval;
static inline void efx_schedule_channel(struct efx_channel *channel)
{
EFX_TRACE(channel->efx, "channel %d scheduling NAPI poll on CPU%d\n",
channel->channel, raw_smp_processor_id());
channel->work_pending = 1;
netif_rx_schedule(channel->napi_dev, &channel->napi_str);
}
#endif /* EFX_EFX_H */
/****************************************************************************
* Driver for Solarflare Solarstorm network controllers and boards
* Copyright 2007 Solarflare Communications Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation, incorporated herein by reference.
*/
#ifndef EFX_ENUM_H
#define EFX_ENUM_H
/*****************************************************************************/
/**
* enum reset_type - reset types
*
* %RESET_TYPE_INVSIBLE, %RESET_TYPE_ALL, %RESET_TYPE_WORLD and
* %RESET_TYPE_DISABLE specify the method/scope of the reset. The
* other valuesspecify reasons, which efx_schedule_reset() will choose
* a method for.
*
* @RESET_TYPE_INVISIBLE: don't reset the PHYs or interrupts
* @RESET_TYPE_ALL: reset everything but PCI core blocks
* @RESET_TYPE_WORLD: reset everything, save & restore PCI config
* @RESET_TYPE_DISABLE: disable NIC
* @RESET_TYPE_MONITOR: reset due to hardware monitor
* @RESET_TYPE_INT_ERROR: reset due to internal error
* @RESET_TYPE_RX_RECOVERY: reset to recover from RX datapath errors
* @RESET_TYPE_RX_DESC_FETCH: pcie error during rx descriptor fetch
* @RESET_TYPE_TX_DESC_FETCH: pcie error during tx descriptor fetch
* @RESET_TYPE_TX_SKIP: hardware completed empty tx descriptors
*/
enum reset_type {
RESET_TYPE_NONE = -1,
RESET_TYPE_INVISIBLE = 0,
RESET_TYPE_ALL = 1,
RESET_TYPE_WORLD = 2,
RESET_TYPE_DISABLE = 3,
RESET_TYPE_MAX_METHOD,
RESET_TYPE_MONITOR,
RESET_TYPE_INT_ERROR,
RESET_TYPE_RX_RECOVERY,
RESET_TYPE_RX_DESC_FETCH,
RESET_TYPE_TX_DESC_FETCH,
RESET_TYPE_TX_SKIP,
RESET_TYPE_MAX,
};
#endif /* EFX_ENUM_H */
This diff is collapsed.
/****************************************************************************
* Driver for Solarflare Solarstorm network controllers and boards
* Copyright 2005 Fen Systems Ltd.
* Copyright 2006 Solarflare Communications Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation, incorporated herein by reference.
*/
#ifndef EFX_ETHTOOL_H
#define EFX_ETHTOOL_H
#include "net_driver.h"
/*
* Ethtool support
*/
extern int efx_ethtool_get_settings(struct net_device *net_dev,
struct ethtool_cmd *ecmd);
extern int efx_ethtool_set_settings(struct net_device *net_dev,
struct ethtool_cmd *ecmd);
extern struct ethtool_ops efx_ethtool_ops;
#endif /* EFX_ETHTOOL_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/****************************************************************************
* Driver for Solarflare Solarstorm network controllers and boards
* Copyright 2005 Fen Systems Ltd.
* Copyright 2006 Solarflare Communications Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation, incorporated herein by reference.
*/
#ifndef EFX_I2C_DIRECT_H
#define EFX_I2C_DIRECT_H
#include "net_driver.h"
/*
* Direct control of an I2C bus
*/
struct efx_i2c_interface;
/**
* struct efx_i2c_bit_operations - I2C bus direct control methods
*
* I2C bus direct control methods.
*
* @setsda: Set state of SDA line
* @setscl: Set state of SCL line
* @getsda: Get state of SDA line
* @getscl: Get state of SCL line
* @udelay: Delay between each bit operation
* @mdelay: Delay between each byte write
*/
struct efx_i2c_bit_operations {
void (*setsda) (struct efx_i2c_interface *i2c);
void (*setscl) (struct efx_i2c_interface *i2c);
int (*getsda) (struct efx_i2c_interface *i2c);
int (*getscl) (struct efx_i2c_interface *i2c);
unsigned int udelay;
unsigned int mdelay;
};
/**
* struct efx_i2c_interface - an I2C interface
*
* An I2C interface.
*
* @efx: Attached Efx NIC
* @op: I2C bus control methods
* @sda: Current output state of SDA line
* @scl: Current output state of SCL line
*/
struct efx_i2c_interface {
struct efx_nic *efx;
struct efx_i2c_bit_operations *op;
unsigned int sda:1;
unsigned int scl:1;
};
extern int efx_i2c_check_presence(struct efx_i2c_interface *i2c, u8 device_id);
extern int efx_i2c_fast_read(struct efx_i2c_interface *i2c,
u8 device_id, u8 offset,
u8 *data, unsigned int len);
extern int efx_i2c_fast_write(struct efx_i2c_interface *i2c,
u8 device_id, u8 offset,
const u8 *data, unsigned int len);
extern int efx_i2c_read(struct efx_i2c_interface *i2c,
u8 device_id, u8 offset, u8 *data, unsigned int len);
extern int efx_i2c_write(struct efx_i2c_interface *i2c,
u8 device_id, u8 offset,
const u8 *data, unsigned int len);
extern int efx_i2c_send_bytes(struct efx_i2c_interface *i2c, u8 device_id,
const u8 *bytes, unsigned int len);
extern int efx_i2c_recv_bytes(struct efx_i2c_interface *i2c, u8 device_id,
u8 *bytes, unsigned int len);
/* Versions of the API that retry on failure. */
extern int efx_i2c_check_presence_retry(struct efx_i2c_interface *i2c,
u8 device_id);
extern int efx_i2c_read_retry(struct efx_i2c_interface *i2c,
u8 device_id, u8 offset, u8 *data, unsigned int len);
extern int efx_i2c_write_retry(struct efx_i2c_interface *i2c,
u8 device_id, u8 offset,
const u8 *data, unsigned int len);
#endif /* EFX_I2C_DIRECT_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/****************************************************************************
* Driver for Solarflare Solarstorm network controllers and boards
* Copyright 2006 Solarflare Communications Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation, incorporated herein by reference.
*/
#ifndef EFX_RX_H
#define EFX_RX_H
#include "net_driver.h"
int efx_probe_rx_queue(struct efx_rx_queue *rx_queue);
void efx_remove_rx_queue(struct efx_rx_queue *rx_queue);
int efx_init_rx_queue(struct efx_rx_queue *rx_queue);
void efx_fini_rx_queue(struct efx_rx_queue *rx_queue);
int efx_lro_init(struct net_lro_mgr *lro_mgr, struct efx_nic *efx);
void efx_lro_fini(struct net_lro_mgr *lro_mgr);
void efx_flush_lro(struct efx_channel *channel);
void efx_rx_strategy(struct efx_channel *channel);
void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue);
void efx_rx_work(struct work_struct *data);
void __efx_rx_packet(struct efx_channel *channel,
struct efx_rx_buffer *rx_buf, int checksummed);
#endif /* EFX_RX_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment