mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 10:41:38 -04:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1244 commits) pkt_sched: Rename PSCHED_US2NS and PSCHED_NS2US ipv4: Fix fib_trie rebalancing Bluetooth: Fix issue with uninitialized nsh.type in DTL-1 driver Bluetooth: Fix Kconfig issue with RFKILL integration PIM-SM: namespace changes ipv4: update ARPD help text net: use a deferred timer in rt_check_expire ieee802154: fix kconfig bool/tristate muckup bonding: initialization rework bonding: use is_zero_ether_addr bonding: network device names are case sensative bonding: elminate bad refcount code bonding: fix style issues bonding: fix destructor bonding: remove bonding read/write semaphore bonding: initialize before registration bonding: bond_create always called with default parameters x_tables: Convert printk to pr_err netfilter: conntrack: optional reliable conntrack event delivery list_nulls: add hlist_nulls_add_head and hlist_nulls_del ...
This commit is contained in:
commit
2ed0e21b30
1136 changed files with 106264 additions and 47651 deletions
|
|
@ -281,7 +281,7 @@ static int __init el1_probe1(struct net_device *dev, int ioaddr)
|
|||
autoirq = probe_irq_off(irq_mask);
|
||||
|
||||
if (autoirq == 0) {
|
||||
printk(KERN_WARNING "%s probe at %#x failed to detect IRQ line.\n",
|
||||
pr_warning("%s probe at %#x failed to detect IRQ line.\n",
|
||||
mname, ioaddr);
|
||||
release_region(ioaddr, EL1_IO_EXTENT);
|
||||
return -EAGAIN;
|
||||
|
|
@ -297,16 +297,16 @@ static int __init el1_probe1(struct net_device *dev, int ioaddr)
|
|||
if (autoirq)
|
||||
dev->irq = autoirq;
|
||||
|
||||
printk(KERN_INFO "%s: %s EtherLink at %#lx, using %sIRQ %d.\n",
|
||||
pr_info("%s: %s EtherLink at %#lx, using %sIRQ %d.\n",
|
||||
dev->name, mname, dev->base_addr,
|
||||
autoirq ? "auto":"assigned ", dev->irq);
|
||||
|
||||
#ifdef CONFIG_IP_MULTICAST
|
||||
printk(KERN_WARNING "WARNING: Use of the 3c501 in a multicast kernel is NOT recommended.\n");
|
||||
pr_warning("WARNING: Use of the 3c501 in a multicast kernel is NOT recommended.\n");
|
||||
#endif
|
||||
|
||||
if (el_debug)
|
||||
printk(KERN_DEBUG "%s", version);
|
||||
pr_debug("%s", version);
|
||||
|
||||
lp = netdev_priv(dev);
|
||||
memset(lp, 0, sizeof(struct net_local));
|
||||
|
|
@ -343,7 +343,7 @@ static int el_open(struct net_device *dev)
|
|||
unsigned long flags;
|
||||
|
||||
if (el_debug > 2)
|
||||
printk(KERN_DEBUG "%s: Doing el_open()...", dev->name);
|
||||
pr_debug("%s: Doing el_open()...\n", dev->name);
|
||||
|
||||
retval = request_irq(dev->irq, &el_interrupt, 0, dev->name, dev);
|
||||
if (retval)
|
||||
|
|
@ -374,7 +374,7 @@ static void el_timeout(struct net_device *dev)
|
|||
int ioaddr = dev->base_addr;
|
||||
|
||||
if (el_debug)
|
||||
printk(KERN_DEBUG "%s: transmit timed out, txsr %#2x axsr=%02x rxsr=%02x.\n",
|
||||
pr_debug("%s: transmit timed out, txsr %#2x axsr=%02x rxsr=%02x.\n",
|
||||
dev->name, inb(TX_STATUS),
|
||||
inb(AX_STATUS), inb(RX_STATUS));
|
||||
dev->stats.tx_errors++;
|
||||
|
|
@ -483,14 +483,13 @@ static int el_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
lp->loading = 0;
|
||||
dev->trans_start = jiffies;
|
||||
if (el_debug > 2)
|
||||
printk(KERN_DEBUG " queued xmit.\n");
|
||||
pr_debug(" queued xmit.\n");
|
||||
dev_kfree_skb(skb);
|
||||
return 0;
|
||||
}
|
||||
/* A receive upset our load, despite our best efforts */
|
||||
if (el_debug > 2)
|
||||
printk(KERN_DEBUG "%s: burped during tx load.\n",
|
||||
dev->name);
|
||||
pr_debug("%s: burped during tx load.\n", dev->name);
|
||||
spin_lock_irqsave(&lp->lock, flags);
|
||||
} while (1);
|
||||
}
|
||||
|
|
@ -540,11 +539,10 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
|
|||
*/
|
||||
|
||||
if (el_debug > 3)
|
||||
printk(KERN_DEBUG "%s: el_interrupt() aux=%#02x",
|
||||
dev->name, axsr);
|
||||
pr_debug("%s: el_interrupt() aux=%#02x\n", dev->name, axsr);
|
||||
|
||||
if (lp->loading == 1 && !lp->txing)
|
||||
printk(KERN_WARNING "%s: Inconsistent state loading while not in tx\n",
|
||||
pr_warning("%s: Inconsistent state loading while not in tx\n",
|
||||
dev->name);
|
||||
|
||||
if (lp->txing) {
|
||||
|
|
@ -555,19 +553,17 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
|
|||
int txsr = inb(TX_STATUS);
|
||||
|
||||
if (lp->loading == 1) {
|
||||
if (el_debug > 2) {
|
||||
printk(KERN_DEBUG "%s: Interrupt while loading [",
|
||||
dev->name);
|
||||
printk(" txsr=%02x gp=%04x rp=%04x]\n",
|
||||
txsr, inw(GP_LOW), inw(RX_LOW));
|
||||
}
|
||||
if (el_debug > 2)
|
||||
pr_debug("%s: Interrupt while loading [txsr=%02x gp=%04x rp=%04x]\n",
|
||||
dev->name, txsr, inw(GP_LOW), inw(RX_LOW));
|
||||
|
||||
/* Force a reload */
|
||||
lp->loading = 2;
|
||||
spin_unlock(&lp->lock);
|
||||
goto out;
|
||||
}
|
||||
if (el_debug > 6)
|
||||
printk(KERN_DEBUG " txsr=%02x gp=%04x rp=%04x",
|
||||
pr_debug("%s: txsr=%02x gp=%04x rp=%04x\n", dev->name,
|
||||
txsr, inw(GP_LOW), inw(RX_LOW));
|
||||
|
||||
if ((axsr & 0x80) && (txsr & TX_READY) == 0) {
|
||||
|
|
@ -576,7 +572,7 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
|
|||
* on trying or reset immediately ?
|
||||
*/
|
||||
if (el_debug > 1)
|
||||
printk(KERN_DEBUG "%s: Unusual interrupt during Tx, txsr=%02x axsr=%02x gp=%03x rp=%03x.\n",
|
||||
pr_debug("%s: Unusual interrupt during Tx, txsr=%02x axsr=%02x gp=%03x rp=%03x.\n",
|
||||
dev->name, txsr, axsr,
|
||||
inw(ioaddr + EL1_DATAPTR),
|
||||
inw(ioaddr + EL1_RXPTR));
|
||||
|
|
@ -587,7 +583,7 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
|
|||
* Timed out
|
||||
*/
|
||||
if (el_debug)
|
||||
printk(KERN_DEBUG "%s: Transmit failed 16 times, Ethernet jammed?\n", dev->name);
|
||||
pr_debug("%s: Transmit failed 16 times, Ethernet jammed?\n", dev->name);
|
||||
outb(AX_SYS, AX_CMD);
|
||||
lp->txing = 0;
|
||||
dev->stats.tx_aborted_errors++;
|
||||
|
|
@ -598,7 +594,7 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
|
|||
*/
|
||||
|
||||
if (el_debug > 6)
|
||||
printk(KERN_DEBUG " retransmitting after a collision.\n");
|
||||
pr_debug("%s: retransmitting after a collision.\n", dev->name);
|
||||
/*
|
||||
* Poor little chip can't reset its own start
|
||||
* pointer
|
||||
|
|
@ -616,9 +612,8 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
|
|||
*/
|
||||
dev->stats.tx_packets++;
|
||||
if (el_debug > 6)
|
||||
printk(KERN_DEBUG " Tx succeeded %s\n",
|
||||
(txsr & TX_RDY) ? "." :
|
||||
"but tx is busy!");
|
||||
pr_debug("%s: Tx succeeded %s\n", dev->name,
|
||||
(txsr & TX_RDY) ? "." : "but tx is busy!");
|
||||
/*
|
||||
* This is safe the interrupt is atomic WRT itself.
|
||||
*/
|
||||
|
|
@ -633,7 +628,8 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
|
|||
|
||||
int rxsr = inb(RX_STATUS);
|
||||
if (el_debug > 5)
|
||||
printk(KERN_DEBUG " rxsr=%02x txsr=%02x rp=%04x", rxsr, inb(TX_STATUS), inw(RX_LOW));
|
||||
pr_debug("%s: rxsr=%02x txsr=%02x rp=%04x\n",
|
||||
dev->name, rxsr, inb(TX_STATUS), inw(RX_LOW));
|
||||
/*
|
||||
* Just reading rx_status fixes most errors.
|
||||
*/
|
||||
|
|
@ -643,7 +639,7 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
|
|||
/* Handled to avoid board lock-up. */
|
||||
dev->stats.rx_length_errors++;
|
||||
if (el_debug > 5)
|
||||
printk(KERN_DEBUG " runt.\n");
|
||||
pr_debug("%s: runt.\n", dev->name);
|
||||
} else if (rxsr & RX_GOOD) {
|
||||
/*
|
||||
* Receive worked.
|
||||
|
|
@ -654,12 +650,10 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
|
|||
* Nothing? Something is broken!
|
||||
*/
|
||||
if (el_debug > 2)
|
||||
printk(KERN_DEBUG "%s: No packet seen, rxsr=%02x **resetting 3c501***\n",
|
||||
pr_debug("%s: No packet seen, rxsr=%02x **resetting 3c501***\n",
|
||||
dev->name, rxsr);
|
||||
el_reset(dev);
|
||||
}
|
||||
if (el_debug > 3)
|
||||
printk(KERN_DEBUG ".\n");
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -695,11 +689,11 @@ static void el_receive(struct net_device *dev)
|
|||
pkt_len = inw(RX_LOW);
|
||||
|
||||
if (el_debug > 4)
|
||||
printk(KERN_DEBUG " el_receive %d.\n", pkt_len);
|
||||
pr_debug(" el_receive %d.\n", pkt_len);
|
||||
|
||||
if (pkt_len < 60 || pkt_len > 1536) {
|
||||
if (el_debug)
|
||||
printk(KERN_DEBUG "%s: bogus packet, length=%d\n",
|
||||
pr_debug("%s: bogus packet, length=%d\n",
|
||||
dev->name, pkt_len);
|
||||
dev->stats.rx_over_errors++;
|
||||
return;
|
||||
|
|
@ -718,8 +712,7 @@ static void el_receive(struct net_device *dev)
|
|||
|
||||
outw(0x00, GP_LOW);
|
||||
if (skb == NULL) {
|
||||
printk(KERN_INFO "%s: Memory squeeze, dropping packet.\n",
|
||||
dev->name);
|
||||
pr_info("%s: Memory squeeze, dropping packet.\n", dev->name);
|
||||
dev->stats.rx_dropped++;
|
||||
return;
|
||||
} else {
|
||||
|
|
@ -753,7 +746,7 @@ static void el_reset(struct net_device *dev)
|
|||
int ioaddr = dev->base_addr;
|
||||
|
||||
if (el_debug > 2)
|
||||
printk(KERN_INFO "3c501 reset...");
|
||||
pr_info("3c501 reset...\n");
|
||||
outb(AX_RESET, AX_CMD); /* Reset the chip */
|
||||
/* Aux control, irq and loopback enabled */
|
||||
outb(AX_LOOP, AX_CMD);
|
||||
|
|
@ -787,7 +780,7 @@ static int el1_close(struct net_device *dev)
|
|||
int ioaddr = dev->base_addr;
|
||||
|
||||
if (el_debug > 2)
|
||||
printk(KERN_INFO "%s: Shutting down Ethernet card at %#x.\n",
|
||||
pr_info("%s: Shutting down Ethernet card at %#x.\n",
|
||||
dev->name, ioaddr);
|
||||
|
||||
netif_stop_queue(dev);
|
||||
|
|
|
|||
|
|
@ -234,16 +234,16 @@ el2_probe1(struct net_device *dev, int ioaddr)
|
|||
}
|
||||
|
||||
if (ei_debug && version_printed++ == 0)
|
||||
printk(version);
|
||||
pr_debug("%s", version);
|
||||
|
||||
dev->base_addr = ioaddr;
|
||||
|
||||
printk("%s: 3c503 at i/o base %#3x, node ", dev->name, ioaddr);
|
||||
pr_info("%s: 3c503 at i/o base %#3x, node ", dev->name, ioaddr);
|
||||
|
||||
/* Retrieve and print the ethernet address. */
|
||||
for (i = 0; i < 6; i++)
|
||||
dev->dev_addr[i] = inb(ioaddr + i);
|
||||
printk("%pM", dev->dev_addr);
|
||||
pr_cont("%pM", dev->dev_addr);
|
||||
|
||||
/* Map the 8390 back into the window. */
|
||||
outb(ECNTRL_THIN, ioaddr + 0x406);
|
||||
|
|
@ -256,7 +256,8 @@ el2_probe1(struct net_device *dev, int ioaddr)
|
|||
outb_p(E8390_PAGE0, ioaddr + E8390_CMD);
|
||||
|
||||
/* Probe for, turn on and clear the board's shared memory. */
|
||||
if (ei_debug > 2) printk(" memory jumpers %2.2x ", membase_reg);
|
||||
if (ei_debug > 2)
|
||||
pr_cont(" memory jumpers %2.2x ", membase_reg);
|
||||
outb(EGACFR_NORM, ioaddr + 0x405); /* Enable RAM */
|
||||
|
||||
/* This should be probed for (or set via an ioctl()) at run-time.
|
||||
|
|
@ -268,7 +269,7 @@ el2_probe1(struct net_device *dev, int ioaddr)
|
|||
#else
|
||||
ei_status.interface_num = dev->mem_end & 0xf;
|
||||
#endif
|
||||
printk(", using %sternal xcvr.\n", ei_status.interface_num == 0 ? "in" : "ex");
|
||||
pr_cont(", using %sternal xcvr.\n", ei_status.interface_num == 0 ? "in" : "ex");
|
||||
|
||||
if ((membase_reg & 0xf0) == 0) {
|
||||
dev->mem_start = 0;
|
||||
|
|
@ -292,7 +293,7 @@ el2_probe1(struct net_device *dev, int ioaddr)
|
|||
writel(test_val, mem_base + i);
|
||||
if (readl(mem_base) != 0xba5eba5e
|
||||
|| readl(mem_base + i) != test_val) {
|
||||
printk("3c503: memory failure or memory address conflict.\n");
|
||||
pr_warning("3c503: memory failure or memory address conflict.\n");
|
||||
dev->mem_start = 0;
|
||||
ei_status.name = "3c503-PIO";
|
||||
iounmap(mem_base);
|
||||
|
|
@ -344,7 +345,7 @@ el2_probe1(struct net_device *dev, int ioaddr)
|
|||
if (dev->irq == 2)
|
||||
dev->irq = 9;
|
||||
else if (dev->irq > 5 && dev->irq != 9) {
|
||||
printk("3c503: configured interrupt %d invalid, will use autoIRQ.\n",
|
||||
pr_warning("3c503: configured interrupt %d invalid, will use autoIRQ.\n",
|
||||
dev->irq);
|
||||
dev->irq = 0;
|
||||
}
|
||||
|
|
@ -359,7 +360,7 @@ el2_probe1(struct net_device *dev, int ioaddr)
|
|||
goto out1;
|
||||
|
||||
if (dev->mem_start)
|
||||
printk("%s: %s - %dkB RAM, 8kB shared mem window at %#6lx-%#6lx.\n",
|
||||
pr_info("%s: %s - %dkB RAM, 8kB shared mem window at %#6lx-%#6lx.\n",
|
||||
dev->name, ei_status.name, (wordlength+1)<<3,
|
||||
dev->mem_start, dev->mem_end-1);
|
||||
|
||||
|
|
@ -367,7 +368,7 @@ el2_probe1(struct net_device *dev, int ioaddr)
|
|||
{
|
||||
ei_status.tx_start_page = EL2_MB1_START_PG;
|
||||
ei_status.rx_start_page = EL2_MB1_START_PG + TX_PAGES;
|
||||
printk("\n%s: %s, %dkB RAM, using programmed I/O (REJUMPER for SHARED MEMORY).\n",
|
||||
pr_info("%s: %s, %dkB RAM, using programmed I/O (REJUMPER for SHARED MEMORY).\n",
|
||||
dev->name, ei_status.name, (wordlength+1)<<3);
|
||||
}
|
||||
release_region(ioaddr + 0x400, 8);
|
||||
|
|
@ -435,15 +436,16 @@ static void
|
|||
el2_reset_8390(struct net_device *dev)
|
||||
{
|
||||
if (ei_debug > 1) {
|
||||
printk("%s: Resetting the 3c503 board...", dev->name);
|
||||
printk("%#lx=%#02x %#lx=%#02x %#lx=%#02x...", E33G_IDCFR, inb(E33G_IDCFR),
|
||||
pr_debug("%s: Resetting the 3c503 board...", dev->name);
|
||||
pr_cont(" %#lx=%#02x %#lx=%#02x %#lx=%#02x...", E33G_IDCFR, inb(E33G_IDCFR),
|
||||
E33G_CNTRL, inb(E33G_CNTRL), E33G_GACFR, inb(E33G_GACFR));
|
||||
}
|
||||
outb_p(ECNTRL_RESET|ECNTRL_THIN, E33G_CNTRL);
|
||||
ei_status.txing = 0;
|
||||
outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
|
||||
el2_init_card(dev);
|
||||
if (ei_debug > 1) printk("done\n");
|
||||
if (ei_debug > 1)
|
||||
pr_cont("done\n");
|
||||
}
|
||||
|
||||
/* Initialize the 3c503 GA registers after a reset. */
|
||||
|
|
@ -529,7 +531,7 @@ el2_block_output(struct net_device *dev, int count,
|
|||
{
|
||||
if(!boguscount--)
|
||||
{
|
||||
printk("%s: FIFO blocked in el2_block_output.\n", dev->name);
|
||||
pr_notice("%s: FIFO blocked in el2_block_output.\n", dev->name);
|
||||
el2_reset_8390(dev);
|
||||
goto blocked;
|
||||
}
|
||||
|
|
@ -581,7 +583,7 @@ el2_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_pag
|
|||
{
|
||||
if(!boguscount--)
|
||||
{
|
||||
printk("%s: FIFO blocked in el2_get_8390_hdr.\n", dev->name);
|
||||
pr_notice("%s: FIFO blocked in el2_get_8390_hdr.\n", dev->name);
|
||||
memset(hdr, 0x00, sizeof(struct e8390_pkt_hdr));
|
||||
el2_reset_8390(dev);
|
||||
goto blocked;
|
||||
|
|
@ -645,7 +647,7 @@ el2_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring
|
|||
{
|
||||
if(!boguscount--)
|
||||
{
|
||||
printk("%s: FIFO blocked in el2_block_input.\n", dev->name);
|
||||
pr_notice("%s: FIFO blocked in el2_block_input.\n", dev->name);
|
||||
el2_reset_8390(dev);
|
||||
goto blocked;
|
||||
}
|
||||
|
|
@ -707,7 +709,7 @@ init_module(void)
|
|||
for (this_dev = 0; this_dev < MAX_EL2_CARDS; this_dev++) {
|
||||
if (io[this_dev] == 0) {
|
||||
if (this_dev != 0) break; /* only autoprobe 1st one */
|
||||
printk(KERN_NOTICE "3c503.c: Presently autoprobing (not recommended) for a single card.\n");
|
||||
pr_notice("3c503.c: Presently autoprobing (not recommended) for a single card.\n");
|
||||
}
|
||||
dev = alloc_eip_netdev();
|
||||
if (!dev)
|
||||
|
|
@ -720,7 +722,7 @@ init_module(void)
|
|||
continue;
|
||||
}
|
||||
free_netdev(dev);
|
||||
printk(KERN_WARNING "3c503.c: No 3c503 card found (i/o = 0x%x).\n", io[this_dev]);
|
||||
pr_warning("3c503.c: No 3c503 card found (i/o = 0x%x).\n", io[this_dev]);
|
||||
break;
|
||||
}
|
||||
if (found)
|
||||
|
|
|
|||
|
|
@ -126,26 +126,25 @@
|
|||
*
|
||||
*********************************************************/
|
||||
|
||||
static const char filename[] = __FILE__;
|
||||
#define filename __FILE__
|
||||
|
||||
static const char timeout_msg[] = "*** timeout at %s:%s (line %d) ***\n";
|
||||
#define timeout_msg "*** timeout at %s:%s (line %d) ***\n"
|
||||
#define TIMEOUT_MSG(lineno) \
|
||||
printk(timeout_msg, filename,__func__,(lineno))
|
||||
pr_notice(timeout_msg, filename, __func__, (lineno))
|
||||
|
||||
static const char invalid_pcb_msg[] =
|
||||
"*** invalid pcb length %d at %s:%s (line %d) ***\n";
|
||||
#define invalid_pcb_msg "*** invalid pcb length %d at %s:%s (line %d) ***\n"
|
||||
#define INVALID_PCB_MSG(len) \
|
||||
printk(invalid_pcb_msg, (len),filename,__func__,__LINE__)
|
||||
pr_notice(invalid_pcb_msg, (len), filename, __func__, __LINE__)
|
||||
|
||||
static char search_msg[] __initdata = KERN_INFO "%s: Looking for 3c505 adapter at address %#x...";
|
||||
#define search_msg "%s: Looking for 3c505 adapter at address %#x..."
|
||||
|
||||
static char stilllooking_msg[] __initdata = "still looking...";
|
||||
#define stilllooking_msg "still looking..."
|
||||
|
||||
static char found_msg[] __initdata = "found.\n";
|
||||
#define found_msg "found.\n"
|
||||
|
||||
static char notfound_msg[] __initdata = "not found (reason = %d)\n";
|
||||
#define notfound_msg "not found (reason = %d)\n"
|
||||
|
||||
static char couldnot_msg[] __initdata = KERN_INFO "%s: 3c505 not found\n";
|
||||
#define couldnot_msg "%s: 3c505 not found\n"
|
||||
|
||||
/*********************************************************
|
||||
*
|
||||
|
|
@ -284,7 +283,7 @@ static inline void adapter_reset(struct net_device *dev)
|
|||
|
||||
outb_control(orig_hcr, dev);
|
||||
if (!start_receive(dev, &adapter->tx_pcb))
|
||||
printk(KERN_ERR "%s: start receive command failed \n", dev->name);
|
||||
pr_err("%s: start receive command failed\n", dev->name);
|
||||
}
|
||||
|
||||
/* Check to make sure that a DMA transfer hasn't timed out. This should
|
||||
|
|
@ -296,7 +295,9 @@ static inline void check_3c505_dma(struct net_device *dev)
|
|||
elp_device *adapter = netdev_priv(dev);
|
||||
if (adapter->dmaing && time_after(jiffies, adapter->current_dma.start_time + 10)) {
|
||||
unsigned long flags, f;
|
||||
printk(KERN_ERR "%s: DMA %s timed out, %d bytes left\n", dev->name, adapter->current_dma.direction ? "download" : "upload", get_dma_residue(dev->dma));
|
||||
pr_err("%s: DMA %s timed out, %d bytes left\n", dev->name,
|
||||
adapter->current_dma.direction ? "download" : "upload",
|
||||
get_dma_residue(dev->dma));
|
||||
spin_lock_irqsave(&adapter->lock, flags);
|
||||
adapter->dmaing = 0;
|
||||
adapter->busy = 0;
|
||||
|
|
@ -321,7 +322,7 @@ static inline bool send_pcb_slow(unsigned int base_addr, unsigned char byte)
|
|||
if (inb_status(base_addr) & HCRE)
|
||||
return false;
|
||||
}
|
||||
printk(KERN_WARNING "3c505: send_pcb_slow timed out\n");
|
||||
pr_warning("3c505: send_pcb_slow timed out\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -333,7 +334,7 @@ static inline bool send_pcb_fast(unsigned int base_addr, unsigned char byte)
|
|||
if (inb_status(base_addr) & HCRE)
|
||||
return false;
|
||||
}
|
||||
printk(KERN_WARNING "3c505: send_pcb_fast timed out\n");
|
||||
pr_warning("3c505: send_pcb_fast timed out\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -386,7 +387,7 @@ static bool send_pcb(struct net_device *dev, pcb_struct * pcb)
|
|||
/* Avoid contention */
|
||||
if (test_and_set_bit(1, &adapter->send_pcb_semaphore)) {
|
||||
if (elp_debug >= 3) {
|
||||
printk(KERN_DEBUG "%s: send_pcb entered while threaded\n", dev->name);
|
||||
pr_debug("%s: send_pcb entered while threaded\n", dev->name);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -424,14 +425,15 @@ static bool send_pcb(struct net_device *dev, pcb_struct * pcb)
|
|||
|
||||
case ASF_PCB_NAK:
|
||||
#ifdef ELP_DEBUG
|
||||
printk(KERN_DEBUG "%s: send_pcb got NAK\n", dev->name);
|
||||
pr_debug("%s: send_pcb got NAK\n", dev->name);
|
||||
#endif
|
||||
goto abort;
|
||||
}
|
||||
}
|
||||
|
||||
if (elp_debug >= 1)
|
||||
printk(KERN_DEBUG "%s: timeout waiting for PCB acknowledge (status %02x)\n", dev->name, inb_status(dev->base_addr));
|
||||
pr_debug("%s: timeout waiting for PCB acknowledge (status %02x)\n",
|
||||
dev->name, inb_status(dev->base_addr));
|
||||
goto abort;
|
||||
|
||||
sti_abort:
|
||||
|
|
@ -481,7 +483,7 @@ static bool receive_pcb(struct net_device *dev, pcb_struct * pcb)
|
|||
while (((stat = get_status(dev->base_addr)) & ACRF) == 0 && time_before(jiffies, timeout));
|
||||
if (time_after_eq(jiffies, timeout)) {
|
||||
TIMEOUT_MSG(__LINE__);
|
||||
printk(KERN_INFO "%s: status %02x\n", dev->name, stat);
|
||||
pr_info("%s: status %02x\n", dev->name, stat);
|
||||
return false;
|
||||
}
|
||||
pcb->length = inb_command(dev->base_addr);
|
||||
|
|
@ -518,7 +520,7 @@ static bool receive_pcb(struct net_device *dev, pcb_struct * pcb)
|
|||
/* safety check total length vs data length */
|
||||
if (total_length != (pcb->length + 2)) {
|
||||
if (elp_debug >= 2)
|
||||
printk(KERN_WARNING "%s: mangled PCB received\n", dev->name);
|
||||
pr_warning("%s: mangled PCB received\n", dev->name);
|
||||
set_hsf(dev, HSF_PCB_NAK);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -527,7 +529,7 @@ static bool receive_pcb(struct net_device *dev, pcb_struct * pcb)
|
|||
if (test_and_set_bit(0, (void *) &adapter->busy)) {
|
||||
if (backlog_next(adapter->rx_backlog.in) == adapter->rx_backlog.out) {
|
||||
set_hsf(dev, HSF_PCB_NAK);
|
||||
printk(KERN_WARNING "%s: PCB rejected, transfer in progress and backlog full\n", dev->name);
|
||||
pr_warning("%s: PCB rejected, transfer in progress and backlog full\n", dev->name);
|
||||
pcb->command = 0;
|
||||
return true;
|
||||
} else {
|
||||
|
|
@ -552,7 +554,7 @@ static bool start_receive(struct net_device *dev, pcb_struct * tx_pcb)
|
|||
elp_device *adapter = netdev_priv(dev);
|
||||
|
||||
if (elp_debug >= 3)
|
||||
printk(KERN_DEBUG "%s: restarting receiver\n", dev->name);
|
||||
pr_debug("%s: restarting receiver\n", dev->name);
|
||||
tx_pcb->command = CMD_RECEIVE_PACKET;
|
||||
tx_pcb->length = sizeof(struct Rcv_pkt);
|
||||
tx_pcb->data.rcv_pkt.buf_seg
|
||||
|
|
@ -586,7 +588,7 @@ static void receive_packet(struct net_device *dev, int len)
|
|||
skb = dev_alloc_skb(rlen + 2);
|
||||
|
||||
if (!skb) {
|
||||
printk(KERN_WARNING "%s: memory squeeze, dropping packet\n", dev->name);
|
||||
pr_warning("%s: memory squeeze, dropping packet\n", dev->name);
|
||||
target = adapter->dma_buffer;
|
||||
adapter->current_dma.target = NULL;
|
||||
/* FIXME: stats */
|
||||
|
|
@ -604,7 +606,8 @@ static void receive_packet(struct net_device *dev, int len)
|
|||
|
||||
/* if this happens, we die */
|
||||
if (test_and_set_bit(0, (void *) &adapter->dmaing))
|
||||
printk(KERN_ERR "%s: rx blocked, DMA in progress, dir %d\n", dev->name, adapter->current_dma.direction);
|
||||
pr_err("%s: rx blocked, DMA in progress, dir %d\n",
|
||||
dev->name, adapter->current_dma.direction);
|
||||
|
||||
adapter->current_dma.direction = 0;
|
||||
adapter->current_dma.length = rlen;
|
||||
|
|
@ -623,14 +626,14 @@ static void receive_packet(struct net_device *dev, int len)
|
|||
release_dma_lock(flags);
|
||||
|
||||
if (elp_debug >= 3) {
|
||||
printk(KERN_DEBUG "%s: rx DMA transfer started\n", dev->name);
|
||||
pr_debug("%s: rx DMA transfer started\n", dev->name);
|
||||
}
|
||||
|
||||
if (adapter->rx_active)
|
||||
adapter->rx_active--;
|
||||
|
||||
if (!adapter->busy)
|
||||
printk(KERN_WARNING "%s: receive_packet called, busy not set.\n", dev->name);
|
||||
pr_warning("%s: receive_packet called, busy not set.\n", dev->name);
|
||||
}
|
||||
|
||||
/******************************************************
|
||||
|
|
@ -655,12 +658,13 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
|
|||
* has a DMA transfer finished?
|
||||
*/
|
||||
if (inb_status(dev->base_addr) & DONE) {
|
||||
if (!adapter->dmaing) {
|
||||
printk(KERN_WARNING "%s: phantom DMA completed\n", dev->name);
|
||||
}
|
||||
if (elp_debug >= 3) {
|
||||
printk(KERN_DEBUG "%s: %s DMA complete, status %02x\n", dev->name, adapter->current_dma.direction ? "tx" : "rx", inb_status(dev->base_addr));
|
||||
}
|
||||
if (!adapter->dmaing)
|
||||
pr_warning("%s: phantom DMA completed\n", dev->name);
|
||||
|
||||
if (elp_debug >= 3)
|
||||
pr_debug("%s: %s DMA complete, status %02x\n", dev->name,
|
||||
adapter->current_dma.direction ? "tx" : "rx",
|
||||
inb_status(dev->base_addr));
|
||||
|
||||
outb_control(adapter->hcr_val & ~(DMAE | TCEN | DIR), dev);
|
||||
if (adapter->current_dma.direction) {
|
||||
|
|
@ -682,7 +686,7 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
|
|||
int t = adapter->rx_backlog.length[adapter->rx_backlog.out];
|
||||
adapter->rx_backlog.out = backlog_next(adapter->rx_backlog.out);
|
||||
if (elp_debug >= 2)
|
||||
printk(KERN_DEBUG "%s: receiving backlogged packet (%d)\n", dev->name, t);
|
||||
pr_debug("%s: receiving backlogged packet (%d)\n", dev->name, t);
|
||||
receive_packet(dev, t);
|
||||
} else {
|
||||
adapter->busy = 0;
|
||||
|
|
@ -713,21 +717,23 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
|
|||
len = adapter->irx_pcb.data.rcv_resp.pkt_len;
|
||||
dlen = adapter->irx_pcb.data.rcv_resp.buf_len;
|
||||
if (adapter->irx_pcb.data.rcv_resp.timeout != 0) {
|
||||
printk(KERN_ERR "%s: interrupt - packet not received correctly\n", dev->name);
|
||||
pr_err("%s: interrupt - packet not received correctly\n", dev->name);
|
||||
} else {
|
||||
if (elp_debug >= 3) {
|
||||
printk(KERN_DEBUG "%s: interrupt - packet received of length %i (%i)\n", dev->name, len, dlen);
|
||||
pr_debug("%s: interrupt - packet received of length %i (%i)\n",
|
||||
dev->name, len, dlen);
|
||||
}
|
||||
if (adapter->irx_pcb.command == 0xff) {
|
||||
if (elp_debug >= 2)
|
||||
printk(KERN_DEBUG "%s: adding packet to backlog (len = %d)\n", dev->name, dlen);
|
||||
pr_debug("%s: adding packet to backlog (len = %d)\n",
|
||||
dev->name, dlen);
|
||||
adapter->rx_backlog.length[adapter->rx_backlog.in] = dlen;
|
||||
adapter->rx_backlog.in = backlog_next(adapter->rx_backlog.in);
|
||||
} else {
|
||||
receive_packet(dev, dlen);
|
||||
}
|
||||
if (elp_debug >= 3)
|
||||
printk(KERN_DEBUG "%s: packet received\n", dev->name);
|
||||
pr_debug("%s: packet received\n", dev->name);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -737,7 +743,7 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
|
|||
case CMD_CONFIGURE_82586_RESPONSE:
|
||||
adapter->got[CMD_CONFIGURE_82586] = 1;
|
||||
if (elp_debug >= 3)
|
||||
printk(KERN_DEBUG "%s: interrupt - configure response received\n", dev->name);
|
||||
pr_debug("%s: interrupt - configure response received\n", dev->name);
|
||||
break;
|
||||
|
||||
/*
|
||||
|
|
@ -746,7 +752,7 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
|
|||
case CMD_CONFIGURE_ADAPTER_RESPONSE:
|
||||
adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] = 1;
|
||||
if (elp_debug >= 3)
|
||||
printk(KERN_DEBUG "%s: Adapter memory configuration %s.\n", dev->name,
|
||||
pr_debug("%s: Adapter memory configuration %s.\n", dev->name,
|
||||
adapter->irx_pcb.data.failed ? "failed" : "succeeded");
|
||||
break;
|
||||
|
||||
|
|
@ -756,7 +762,7 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
|
|||
case CMD_LOAD_MULTICAST_RESPONSE:
|
||||
adapter->got[CMD_LOAD_MULTICAST_LIST] = 1;
|
||||
if (elp_debug >= 3)
|
||||
printk(KERN_DEBUG "%s: Multicast address list loading %s.\n", dev->name,
|
||||
pr_debug("%s: Multicast address list loading %s.\n", dev->name,
|
||||
adapter->irx_pcb.data.failed ? "failed" : "succeeded");
|
||||
break;
|
||||
|
||||
|
|
@ -766,7 +772,7 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
|
|||
case CMD_SET_ADDRESS_RESPONSE:
|
||||
adapter->got[CMD_SET_STATION_ADDRESS] = 1;
|
||||
if (elp_debug >= 3)
|
||||
printk(KERN_DEBUG "%s: Ethernet address setting %s.\n", dev->name,
|
||||
pr_debug("%s: Ethernet address setting %s.\n", dev->name,
|
||||
adapter->irx_pcb.data.failed ? "failed" : "succeeded");
|
||||
break;
|
||||
|
||||
|
|
@ -783,7 +789,7 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
|
|||
dev->stats.rx_over_errors += adapter->irx_pcb.data.netstat.err_res;
|
||||
adapter->got[CMD_NETWORK_STATISTICS] = 1;
|
||||
if (elp_debug >= 3)
|
||||
printk(KERN_DEBUG "%s: interrupt - statistics response received\n", dev->name);
|
||||
pr_debug("%s: interrupt - statistics response received\n", dev->name);
|
||||
break;
|
||||
|
||||
/*
|
||||
|
|
@ -791,17 +797,17 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
|
|||
*/
|
||||
case CMD_TRANSMIT_PACKET_COMPLETE:
|
||||
if (elp_debug >= 3)
|
||||
printk(KERN_DEBUG "%s: interrupt - packet sent\n", dev->name);
|
||||
pr_debug("%s: interrupt - packet sent\n", dev->name);
|
||||
if (!netif_running(dev))
|
||||
break;
|
||||
switch (adapter->irx_pcb.data.xmit_resp.c_stat) {
|
||||
case 0xffff:
|
||||
dev->stats.tx_aborted_errors++;
|
||||
printk(KERN_INFO "%s: transmit timed out, network cable problem?\n", dev->name);
|
||||
pr_info("%s: transmit timed out, network cable problem?\n", dev->name);
|
||||
break;
|
||||
case 0xfffe:
|
||||
dev->stats.tx_fifo_errors++;
|
||||
printk(KERN_INFO "%s: transmit timed out, FIFO underrun\n", dev->name);
|
||||
pr_info("%s: transmit timed out, FIFO underrun\n", dev->name);
|
||||
break;
|
||||
}
|
||||
netif_wake_queue(dev);
|
||||
|
|
@ -811,11 +817,12 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
|
|||
* some unknown PCB
|
||||
*/
|
||||
default:
|
||||
printk(KERN_DEBUG "%s: unknown PCB received - %2.2x\n", dev->name, adapter->irx_pcb.command);
|
||||
pr_debug("%s: unknown PCB received - %2.2x\n",
|
||||
dev->name, adapter->irx_pcb.command);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
printk(KERN_WARNING "%s: failed to read PCB on interrupt\n", dev->name);
|
||||
pr_warning("%s: failed to read PCB on interrupt\n", dev->name);
|
||||
adapter_reset(dev);
|
||||
}
|
||||
}
|
||||
|
|
@ -844,13 +851,13 @@ static int elp_open(struct net_device *dev)
|
|||
int retval;
|
||||
|
||||
if (elp_debug >= 3)
|
||||
printk(KERN_DEBUG "%s: request to open device\n", dev->name);
|
||||
pr_debug("%s: request to open device\n", dev->name);
|
||||
|
||||
/*
|
||||
* make sure we actually found the device
|
||||
*/
|
||||
if (adapter == NULL) {
|
||||
printk(KERN_ERR "%s: Opening a non-existent physical device\n", dev->name);
|
||||
pr_err("%s: Opening a non-existent physical device\n", dev->name);
|
||||
return -EAGAIN;
|
||||
}
|
||||
/*
|
||||
|
|
@ -880,17 +887,17 @@ static int elp_open(struct net_device *dev)
|
|||
* install our interrupt service routine
|
||||
*/
|
||||
if ((retval = request_irq(dev->irq, &elp_interrupt, 0, dev->name, dev))) {
|
||||
printk(KERN_ERR "%s: could not allocate IRQ%d\n", dev->name, dev->irq);
|
||||
pr_err("%s: could not allocate IRQ%d\n", dev->name, dev->irq);
|
||||
return retval;
|
||||
}
|
||||
if ((retval = request_dma(dev->dma, dev->name))) {
|
||||
free_irq(dev->irq, dev);
|
||||
printk(KERN_ERR "%s: could not allocate DMA%d channel\n", dev->name, dev->dma);
|
||||
pr_err("%s: could not allocate DMA%d channel\n", dev->name, dev->dma);
|
||||
return retval;
|
||||
}
|
||||
adapter->dma_buffer = (void *) dma_mem_alloc(DMA_BUFFER_SIZE);
|
||||
if (!adapter->dma_buffer) {
|
||||
printk(KERN_ERR "%s: could not allocate DMA buffer\n", dev->name);
|
||||
pr_err("%s: could not allocate DMA buffer\n", dev->name);
|
||||
free_dma(dev->dma);
|
||||
free_irq(dev->irq, dev);
|
||||
return -ENOMEM;
|
||||
|
|
@ -906,7 +913,7 @@ static int elp_open(struct net_device *dev)
|
|||
* configure adapter memory: we need 10 multicast addresses, default==0
|
||||
*/
|
||||
if (elp_debug >= 3)
|
||||
printk(KERN_DEBUG "%s: sending 3c505 memory configuration command\n", dev->name);
|
||||
pr_debug("%s: sending 3c505 memory configuration command\n", dev->name);
|
||||
adapter->tx_pcb.command = CMD_CONFIGURE_ADAPTER_MEMORY;
|
||||
adapter->tx_pcb.data.memconf.cmd_q = 10;
|
||||
adapter->tx_pcb.data.memconf.rcv_q = 20;
|
||||
|
|
@ -917,7 +924,7 @@ static int elp_open(struct net_device *dev)
|
|||
adapter->tx_pcb.length = sizeof(struct Memconf);
|
||||
adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] = 0;
|
||||
if (!send_pcb(dev, &adapter->tx_pcb))
|
||||
printk(KERN_ERR "%s: couldn't send memory configuration command\n", dev->name);
|
||||
pr_err("%s: couldn't send memory configuration command\n", dev->name);
|
||||
else {
|
||||
unsigned long timeout = jiffies + TIMEOUT;
|
||||
while (adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] == 0 && time_before(jiffies, timeout));
|
||||
|
|
@ -930,13 +937,13 @@ static int elp_open(struct net_device *dev)
|
|||
* configure adapter to receive broadcast messages and wait for response
|
||||
*/
|
||||
if (elp_debug >= 3)
|
||||
printk(KERN_DEBUG "%s: sending 82586 configure command\n", dev->name);
|
||||
pr_debug("%s: sending 82586 configure command\n", dev->name);
|
||||
adapter->tx_pcb.command = CMD_CONFIGURE_82586;
|
||||
adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD;
|
||||
adapter->tx_pcb.length = 2;
|
||||
adapter->got[CMD_CONFIGURE_82586] = 0;
|
||||
if (!send_pcb(dev, &adapter->tx_pcb))
|
||||
printk(KERN_ERR "%s: couldn't send 82586 configure command\n", dev->name);
|
||||
pr_err("%s: couldn't send 82586 configure command\n", dev->name);
|
||||
else {
|
||||
unsigned long timeout = jiffies + TIMEOUT;
|
||||
while (adapter->got[CMD_CONFIGURE_82586] == 0 && time_before(jiffies, timeout));
|
||||
|
|
@ -952,7 +959,7 @@ static int elp_open(struct net_device *dev)
|
|||
*/
|
||||
prime_rx(dev);
|
||||
if (elp_debug >= 3)
|
||||
printk(KERN_DEBUG "%s: %d receive PCBs active\n", dev->name, adapter->rx_active);
|
||||
pr_debug("%s: %d receive PCBs active\n", dev->name, adapter->rx_active);
|
||||
|
||||
/*
|
||||
* device is now officially open!
|
||||
|
|
@ -982,7 +989,7 @@ static bool send_packet(struct net_device *dev, struct sk_buff *skb)
|
|||
|
||||
if (test_and_set_bit(0, (void *) &adapter->busy)) {
|
||||
if (elp_debug >= 2)
|
||||
printk(KERN_DEBUG "%s: transmit blocked\n", dev->name);
|
||||
pr_debug("%s: transmit blocked\n", dev->name);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -1004,7 +1011,7 @@ static bool send_packet(struct net_device *dev, struct sk_buff *skb)
|
|||
}
|
||||
/* if this happens, we die */
|
||||
if (test_and_set_bit(0, (void *) &adapter->dmaing))
|
||||
printk(KERN_DEBUG "%s: tx: DMA %d in progress\n", dev->name, adapter->current_dma.direction);
|
||||
pr_debug("%s: tx: DMA %d in progress\n", dev->name, adapter->current_dma.direction);
|
||||
|
||||
adapter->current_dma.direction = 1;
|
||||
adapter->current_dma.start_time = jiffies;
|
||||
|
|
@ -1030,7 +1037,7 @@ static bool send_packet(struct net_device *dev, struct sk_buff *skb)
|
|||
release_dma_lock(flags);
|
||||
|
||||
if (elp_debug >= 3)
|
||||
printk(KERN_DEBUG "%s: DMA transfer started\n", dev->name);
|
||||
pr_debug("%s: DMA transfer started\n", dev->name);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1044,9 +1051,10 @@ static void elp_timeout(struct net_device *dev)
|
|||
int stat;
|
||||
|
||||
stat = inb_status(dev->base_addr);
|
||||
printk(KERN_WARNING "%s: transmit timed out, lost %s?\n", dev->name, (stat & ACRF) ? "interrupt" : "command");
|
||||
pr_warning("%s: transmit timed out, lost %s?\n", dev->name,
|
||||
(stat & ACRF) ? "interrupt" : "command");
|
||||
if (elp_debug >= 1)
|
||||
printk(KERN_DEBUG "%s: status %#02x\n", dev->name, stat);
|
||||
pr_debug("%s: status %#02x\n", dev->name, stat);
|
||||
dev->trans_start = jiffies;
|
||||
dev->stats.tx_dropped++;
|
||||
netif_wake_queue(dev);
|
||||
|
|
@ -1068,7 +1076,7 @@ static int elp_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
check_3c505_dma(dev);
|
||||
|
||||
if (elp_debug >= 3)
|
||||
printk(KERN_DEBUG "%s: request to send packet of length %d\n", dev->name, (int) skb->len);
|
||||
pr_debug("%s: request to send packet of length %d\n", dev->name, (int) skb->len);
|
||||
|
||||
netif_stop_queue(dev);
|
||||
|
||||
|
|
@ -1077,13 +1085,13 @@ static int elp_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
*/
|
||||
if (!send_packet(dev, skb)) {
|
||||
if (elp_debug >= 2) {
|
||||
printk(KERN_DEBUG "%s: failed to transmit packet\n", dev->name);
|
||||
pr_debug("%s: failed to transmit packet\n", dev->name);
|
||||
}
|
||||
spin_unlock_irqrestore(&adapter->lock, flags);
|
||||
return 1;
|
||||
return NETDEV_TX_BUSY;
|
||||
}
|
||||
if (elp_debug >= 3)
|
||||
printk(KERN_DEBUG "%s: packet of length %d sent\n", dev->name, (int) skb->len);
|
||||
pr_debug("%s: packet of length %d sent\n", dev->name, (int) skb->len);
|
||||
|
||||
/*
|
||||
* start the transmit timeout
|
||||
|
|
@ -1107,7 +1115,7 @@ static struct net_device_stats *elp_get_stats(struct net_device *dev)
|
|||
elp_device *adapter = netdev_priv(dev);
|
||||
|
||||
if (elp_debug >= 3)
|
||||
printk(KERN_DEBUG "%s: request for stats\n", dev->name);
|
||||
pr_debug("%s: request for stats\n", dev->name);
|
||||
|
||||
/* If the device is closed, just return the latest stats we have,
|
||||
- we cannot ask from the adapter without interrupts */
|
||||
|
|
@ -1119,7 +1127,7 @@ static struct net_device_stats *elp_get_stats(struct net_device *dev)
|
|||
adapter->tx_pcb.length = 0;
|
||||
adapter->got[CMD_NETWORK_STATISTICS] = 0;
|
||||
if (!send_pcb(dev, &adapter->tx_pcb))
|
||||
printk(KERN_ERR "%s: couldn't send get statistics command\n", dev->name);
|
||||
pr_err("%s: couldn't send get statistics command\n", dev->name);
|
||||
else {
|
||||
unsigned long timeout = jiffies + TIMEOUT;
|
||||
while (adapter->got[CMD_NETWORK_STATISTICS] == 0 && time_before(jiffies, timeout));
|
||||
|
|
@ -1169,7 +1177,7 @@ static int elp_close(struct net_device *dev)
|
|||
elp_device *adapter = netdev_priv(dev);
|
||||
|
||||
if (elp_debug >= 3)
|
||||
printk(KERN_DEBUG "%s: request to close device\n", dev->name);
|
||||
pr_debug("%s: request to close device\n", dev->name);
|
||||
|
||||
netif_stop_queue(dev);
|
||||
|
||||
|
|
@ -1213,7 +1221,7 @@ static void elp_set_mc_list(struct net_device *dev)
|
|||
unsigned long flags;
|
||||
|
||||
if (elp_debug >= 3)
|
||||
printk(KERN_DEBUG "%s: request to set multicast list\n", dev->name);
|
||||
pr_debug("%s: request to set multicast list\n", dev->name);
|
||||
|
||||
spin_lock_irqsave(&adapter->lock, flags);
|
||||
|
||||
|
|
@ -1228,7 +1236,7 @@ static void elp_set_mc_list(struct net_device *dev)
|
|||
}
|
||||
adapter->got[CMD_LOAD_MULTICAST_LIST] = 0;
|
||||
if (!send_pcb(dev, &adapter->tx_pcb))
|
||||
printk(KERN_ERR "%s: couldn't send set_multicast command\n", dev->name);
|
||||
pr_err("%s: couldn't send set_multicast command\n", dev->name);
|
||||
else {
|
||||
unsigned long timeout = jiffies + TIMEOUT;
|
||||
while (adapter->got[CMD_LOAD_MULTICAST_LIST] == 0 && time_before(jiffies, timeout));
|
||||
|
|
@ -1247,14 +1255,14 @@ static void elp_set_mc_list(struct net_device *dev)
|
|||
* and wait for response
|
||||
*/
|
||||
if (elp_debug >= 3)
|
||||
printk(KERN_DEBUG "%s: sending 82586 configure command\n", dev->name);
|
||||
pr_debug("%s: sending 82586 configure command\n", dev->name);
|
||||
adapter->tx_pcb.command = CMD_CONFIGURE_82586;
|
||||
adapter->tx_pcb.length = 2;
|
||||
adapter->got[CMD_CONFIGURE_82586] = 0;
|
||||
if (!send_pcb(dev, &adapter->tx_pcb))
|
||||
{
|
||||
spin_unlock_irqrestore(&adapter->lock, flags);
|
||||
printk(KERN_ERR "%s: couldn't send 82586 configure command\n", dev->name);
|
||||
pr_err("%s: couldn't send 82586 configure command\n", dev->name);
|
||||
}
|
||||
else {
|
||||
unsigned long timeout = jiffies + TIMEOUT;
|
||||
|
|
@ -1283,17 +1291,17 @@ static int __init elp_sense(struct net_device *dev)
|
|||
orig_HSR = inb_status(addr);
|
||||
|
||||
if (elp_debug > 0)
|
||||
printk(search_msg, name, addr);
|
||||
pr_debug(search_msg, name, addr);
|
||||
|
||||
if (orig_HSR == 0xff) {
|
||||
if (elp_debug > 0)
|
||||
printk(notfound_msg, 1);
|
||||
pr_cont(notfound_msg, 1);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Wait for a while; the adapter may still be booting up */
|
||||
if (elp_debug > 0)
|
||||
printk(stilllooking_msg);
|
||||
pr_cont(stilllooking_msg);
|
||||
|
||||
if (orig_HSR & DIR) {
|
||||
/* If HCR.DIR is up, we pull it down. HSR.DIR should follow. */
|
||||
|
|
@ -1301,7 +1309,7 @@ static int __init elp_sense(struct net_device *dev)
|
|||
msleep(300);
|
||||
if (inb_status(addr) & DIR) {
|
||||
if (elp_debug > 0)
|
||||
printk(notfound_msg, 2);
|
||||
pr_cont(notfound_msg, 2);
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -1310,7 +1318,7 @@ static int __init elp_sense(struct net_device *dev)
|
|||
msleep(300);
|
||||
if (!(inb_status(addr) & DIR)) {
|
||||
if (elp_debug > 0)
|
||||
printk(notfound_msg, 3);
|
||||
pr_cont(notfound_msg, 3);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
|
@ -1318,7 +1326,7 @@ static int __init elp_sense(struct net_device *dev)
|
|||
* It certainly looks like a 3c505.
|
||||
*/
|
||||
if (elp_debug > 0)
|
||||
printk(found_msg);
|
||||
pr_cont(found_msg);
|
||||
|
||||
return 0;
|
||||
out:
|
||||
|
|
@ -1349,7 +1357,7 @@ static int __init elp_autodetect(struct net_device *dev)
|
|||
|
||||
/* could not find an adapter */
|
||||
if (elp_debug > 0)
|
||||
printk(couldnot_msg, dev->name);
|
||||
pr_debug(couldnot_msg, dev->name);
|
||||
|
||||
return 0; /* Because of this, the layer above will return -ENODEV */
|
||||
}
|
||||
|
|
@ -1424,16 +1432,16 @@ static int __init elplus_setup(struct net_device *dev)
|
|||
/* Nope, it's ignoring the command register. This means that
|
||||
* either it's still booting up, or it's died.
|
||||
*/
|
||||
printk(KERN_ERR "%s: command register wouldn't drain, ", dev->name);
|
||||
pr_err("%s: command register wouldn't drain, ", dev->name);
|
||||
if ((inb_status(dev->base_addr) & 7) == 3) {
|
||||
/* If the adapter status is 3, it *could* still be booting.
|
||||
* Give it the benefit of the doubt for 10 seconds.
|
||||
*/
|
||||
printk("assuming 3c505 still starting\n");
|
||||
pr_cont("assuming 3c505 still starting\n");
|
||||
timeout = jiffies + 10*HZ;
|
||||
while (time_before(jiffies, timeout) && (inb_status(dev->base_addr) & 7));
|
||||
if (inb_status(dev->base_addr) & 7) {
|
||||
printk(KERN_ERR "%s: 3c505 failed to start\n", dev->name);
|
||||
pr_err("%s: 3c505 failed to start\n", dev->name);
|
||||
} else {
|
||||
okay = 1; /* It started */
|
||||
}
|
||||
|
|
@ -1441,7 +1449,7 @@ static int __init elplus_setup(struct net_device *dev)
|
|||
/* Otherwise, it must just be in a strange
|
||||
* state. We probably need to kick it.
|
||||
*/
|
||||
printk("3c505 is sulking\n");
|
||||
pr_cont("3c505 is sulking\n");
|
||||
}
|
||||
}
|
||||
for (tries = 0; tries < 5 && okay; tries++) {
|
||||
|
|
@ -1454,18 +1462,19 @@ static int __init elplus_setup(struct net_device *dev)
|
|||
adapter->tx_pcb.length = 0;
|
||||
cookie = probe_irq_on();
|
||||
if (!send_pcb(dev, &adapter->tx_pcb)) {
|
||||
printk(KERN_ERR "%s: could not send first PCB\n", dev->name);
|
||||
pr_err("%s: could not send first PCB\n", dev->name);
|
||||
probe_irq_off(cookie);
|
||||
continue;
|
||||
}
|
||||
if (!receive_pcb(dev, &adapter->rx_pcb)) {
|
||||
printk(KERN_ERR "%s: could not read first PCB\n", dev->name);
|
||||
pr_err("%s: could not read first PCB\n", dev->name);
|
||||
probe_irq_off(cookie);
|
||||
continue;
|
||||
}
|
||||
if ((adapter->rx_pcb.command != CMD_ADDRESS_RESPONSE) ||
|
||||
(adapter->rx_pcb.length != 6)) {
|
||||
printk(KERN_ERR "%s: first PCB wrong (%d, %d)\n", dev->name, adapter->rx_pcb.command, adapter->rx_pcb.length);
|
||||
pr_err("%s: first PCB wrong (%d, %d)\n", dev->name,
|
||||
adapter->rx_pcb.command, adapter->rx_pcb.length);
|
||||
probe_irq_off(cookie);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1474,32 +1483,32 @@ static int __init elplus_setup(struct net_device *dev)
|
|||
/* It's broken. Do a hard reset to re-initialise the board,
|
||||
* and try again.
|
||||
*/
|
||||
printk(KERN_INFO "%s: resetting adapter\n", dev->name);
|
||||
pr_info("%s: resetting adapter\n", dev->name);
|
||||
outb_control(adapter->hcr_val | FLSH | ATTN, dev);
|
||||
outb_control(adapter->hcr_val & ~(FLSH | ATTN), dev);
|
||||
}
|
||||
printk(KERN_ERR "%s: failed to initialise 3c505\n", dev->name);
|
||||
pr_err("%s: failed to initialise 3c505\n", dev->name);
|
||||
goto out;
|
||||
|
||||
okay:
|
||||
if (dev->irq) { /* Is there a preset IRQ? */
|
||||
int rpt = probe_irq_off(cookie);
|
||||
if (dev->irq != rpt) {
|
||||
printk(KERN_WARNING "%s: warning, irq %d configured but %d detected\n", dev->name, dev->irq, rpt);
|
||||
pr_warning("%s: warning, irq %d configured but %d detected\n", dev->name, dev->irq, rpt);
|
||||
}
|
||||
/* if dev->irq == probe_irq_off(cookie), all is well */
|
||||
} else /* No preset IRQ; just use what we can detect */
|
||||
dev->irq = probe_irq_off(cookie);
|
||||
switch (dev->irq) { /* Legal, sane? */
|
||||
case 0:
|
||||
printk(KERN_ERR "%s: IRQ probe failed: check 3c505 jumpers.\n",
|
||||
pr_err("%s: IRQ probe failed: check 3c505 jumpers.\n",
|
||||
dev->name);
|
||||
goto out;
|
||||
case 1:
|
||||
case 6:
|
||||
case 8:
|
||||
case 13:
|
||||
printk(KERN_ERR "%s: Impossible IRQ %d reported by probe_irq_off().\n",
|
||||
pr_err("%s: Impossible IRQ %d reported by probe_irq_off().\n",
|
||||
dev->name, dev->irq);
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -1521,7 +1530,7 @@ static int __init elplus_setup(struct net_device *dev)
|
|||
dev->dma = dev->mem_start & 7;
|
||||
}
|
||||
else {
|
||||
printk(KERN_WARNING "%s: warning, DMA channel not specified, using default\n", dev->name);
|
||||
pr_warning("%s: warning, DMA channel not specified, using default\n", dev->name);
|
||||
dev->dma = ELP_DMA;
|
||||
}
|
||||
}
|
||||
|
|
@ -1529,11 +1538,8 @@ static int __init elplus_setup(struct net_device *dev)
|
|||
/*
|
||||
* print remainder of startup message
|
||||
*/
|
||||
printk(KERN_INFO "%s: 3c505 at %#lx, irq %d, dma %d, "
|
||||
"addr %pM, ",
|
||||
dev->name, dev->base_addr, dev->irq, dev->dma,
|
||||
dev->dev_addr);
|
||||
|
||||
pr_info("%s: 3c505 at %#lx, irq %d, dma %d, addr %pM, ",
|
||||
dev->name, dev->base_addr, dev->irq, dev->dma, dev->dev_addr);
|
||||
/*
|
||||
* read more information from the adapter
|
||||
*/
|
||||
|
|
@ -1544,9 +1550,10 @@ static int __init elplus_setup(struct net_device *dev)
|
|||
!receive_pcb(dev, &adapter->rx_pcb) ||
|
||||
(adapter->rx_pcb.command != CMD_ADAPTER_INFO_RESPONSE) ||
|
||||
(adapter->rx_pcb.length != 10)) {
|
||||
printk("not responding to second PCB\n");
|
||||
pr_cont("not responding to second PCB\n");
|
||||
}
|
||||
printk("rev %d.%d, %dk\n", adapter->rx_pcb.data.info.major_vers, adapter->rx_pcb.data.info.minor_vers, adapter->rx_pcb.data.info.RAM_sz);
|
||||
pr_cont("rev %d.%d, %dk\n", adapter->rx_pcb.data.info.major_vers,
|
||||
adapter->rx_pcb.data.info.minor_vers, adapter->rx_pcb.data.info.RAM_sz);
|
||||
|
||||
/*
|
||||
* reconfigure the adapter memory to better suit our purposes
|
||||
|
|
@ -1563,10 +1570,10 @@ static int __init elplus_setup(struct net_device *dev)
|
|||
!receive_pcb(dev, &adapter->rx_pcb) ||
|
||||
(adapter->rx_pcb.command != CMD_CONFIGURE_ADAPTER_RESPONSE) ||
|
||||
(adapter->rx_pcb.length != 2)) {
|
||||
printk(KERN_ERR "%s: could not configure adapter memory\n", dev->name);
|
||||
pr_err("%s: could not configure adapter memory\n", dev->name);
|
||||
}
|
||||
if (adapter->rx_pcb.data.configure) {
|
||||
printk(KERN_ERR "%s: adapter configuration failed\n", dev->name);
|
||||
pr_err("%s: adapter configuration failed\n", dev->name);
|
||||
}
|
||||
|
||||
dev->netdev_ops = &elp_netdev_ops;
|
||||
|
|
@ -1631,17 +1638,17 @@ int __init init_module(void)
|
|||
dev->dma = dma[this_dev];
|
||||
} else {
|
||||
dev->dma = ELP_DMA;
|
||||
printk(KERN_WARNING "3c505.c: warning, using default DMA channel,\n");
|
||||
pr_warning("3c505.c: warning, using default DMA channel,\n");
|
||||
}
|
||||
if (io[this_dev] == 0) {
|
||||
if (this_dev) {
|
||||
free_netdev(dev);
|
||||
break;
|
||||
}
|
||||
printk(KERN_NOTICE "3c505.c: module autoprobe not recommended, give io=xx.\n");
|
||||
pr_notice("3c505.c: module autoprobe not recommended, give io=xx.\n");
|
||||
}
|
||||
if (elplus_setup(dev) != 0) {
|
||||
printk(KERN_WARNING "3c505.c: Failed to register card at 0x%x.\n", io[this_dev]);
|
||||
pr_warning("3c505.c: Failed to register card at 0x%x.\n", io[this_dev]);
|
||||
free_netdev(dev);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -364,7 +364,7 @@ static const struct net_device_ops netdev_ops = {
|
|||
|
||||
static int __init el16_probe1(struct net_device *dev, int ioaddr)
|
||||
{
|
||||
static unsigned char init_ID_done, version_printed;
|
||||
static unsigned char init_ID_done;
|
||||
int i, irq, irqval, retval;
|
||||
struct net_local *lp;
|
||||
|
||||
|
|
@ -391,10 +391,7 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr)
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (net_debug && version_printed++ == 0)
|
||||
printk(version);
|
||||
|
||||
printk("%s: 3c507 at %#x,", dev->name, ioaddr);
|
||||
pr_info("%s: 3c507 at %#x,", dev->name, ioaddr);
|
||||
|
||||
/* We should make a few more checks here, like the first three octets of
|
||||
the S.A. for the manufacturer's code. */
|
||||
|
|
@ -403,7 +400,8 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr)
|
|||
|
||||
irqval = request_irq(irq, &el16_interrupt, 0, DRV_NAME, dev);
|
||||
if (irqval) {
|
||||
printk(KERN_ERR "3c507: unable to get IRQ %d (irqval=%d).\n", irq, irqval);
|
||||
pr_cont("\n");
|
||||
pr_err("3c507: unable to get IRQ %d (irqval=%d).\n", irq, irqval);
|
||||
retval = -EAGAIN;
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -414,7 +412,7 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr)
|
|||
outb(0x01, ioaddr + MISC_CTRL);
|
||||
for (i = 0; i < 6; i++)
|
||||
dev->dev_addr[i] = inb(ioaddr + i);
|
||||
printk(" %pM", dev->dev_addr);
|
||||
pr_cont(" %pM", dev->dev_addr);
|
||||
|
||||
if (mem_start)
|
||||
net_debug = mem_start & 7;
|
||||
|
|
@ -443,18 +441,18 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr)
|
|||
dev->if_port = (inb(ioaddr + ROM_CONFIG) & 0x80) ? 1 : 0;
|
||||
dev->irq = inb(ioaddr + IRQ_CONFIG) & 0x0f;
|
||||
|
||||
printk(", IRQ %d, %sternal xcvr, memory %#lx-%#lx.\n", dev->irq,
|
||||
pr_cont(", IRQ %d, %sternal xcvr, memory %#lx-%#lx.\n", dev->irq,
|
||||
dev->if_port ? "ex" : "in", dev->mem_start, dev->mem_end-1);
|
||||
|
||||
if (net_debug)
|
||||
printk(version);
|
||||
pr_debug("%s", version);
|
||||
|
||||
lp = netdev_priv(dev);
|
||||
memset(lp, 0, sizeof(*lp));
|
||||
spin_lock_init(&lp->lock);
|
||||
lp->base = ioremap(dev->mem_start, RX_BUF_END);
|
||||
if (!lp->base) {
|
||||
printk(KERN_ERR "3c507: unable to remap memory\n");
|
||||
pr_err("3c507: unable to remap memory\n");
|
||||
retval = -EAGAIN;
|
||||
goto out1;
|
||||
}
|
||||
|
|
@ -488,20 +486,20 @@ static void el16_tx_timeout (struct net_device *dev)
|
|||
void __iomem *shmem = lp->base;
|
||||
|
||||
if (net_debug > 1)
|
||||
printk ("%s: transmit timed out, %s? ", dev->name,
|
||||
pr_debug("%s: transmit timed out, %s? ", dev->name,
|
||||
readw(shmem + iSCB_STATUS) & 0x8000 ? "IRQ conflict" :
|
||||
"network cable problem");
|
||||
/* Try to restart the adaptor. */
|
||||
if (lp->last_restart == dev->stats.tx_packets) {
|
||||
if (net_debug > 1)
|
||||
printk ("Resetting board.\n");
|
||||
pr_cont("Resetting board.\n");
|
||||
/* Completely reset the adaptor. */
|
||||
init_82586_mem (dev);
|
||||
lp->tx_pkts_in_ring = 0;
|
||||
} else {
|
||||
/* Issue the channel attention signal and hope it "gets better". */
|
||||
if (net_debug > 1)
|
||||
printk ("Kicking board.\n");
|
||||
pr_cont("Kicking board.\n");
|
||||
writew(0xf000 | CUC_START | RX_START, shmem + iSCB_CMD);
|
||||
outb (0, ioaddr + SIGNAL_CA); /* Issue channel-attn. */
|
||||
lp->last_restart = dev->stats.tx_packets;
|
||||
|
|
@ -553,7 +551,8 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id)
|
|||
void __iomem *shmem;
|
||||
|
||||
if (dev == NULL) {
|
||||
printk ("net_interrupt(): irq %d for unknown device.\n", irq);
|
||||
pr_err("%s: net_interrupt(): irq %d for unknown device.\n",
|
||||
dev->name, irq);
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
|
|
@ -566,7 +565,7 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id)
|
|||
status = readw(shmem+iSCB_STATUS);
|
||||
|
||||
if (net_debug > 4) {
|
||||
printk("%s: 3c507 interrupt, status %4.4x.\n", dev->name, status);
|
||||
pr_debug("%s: 3c507 interrupt, status %4.4x.\n", dev->name, status);
|
||||
}
|
||||
|
||||
/* Disable the 82586's input to the interrupt line. */
|
||||
|
|
@ -577,7 +576,7 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id)
|
|||
unsigned short tx_status = readw(shmem+lp->tx_reap);
|
||||
if (!(tx_status & 0x8000)) {
|
||||
if (net_debug > 5)
|
||||
printk("Tx command incomplete (%#x).\n", lp->tx_reap);
|
||||
pr_debug("Tx command incomplete (%#x).\n", lp->tx_reap);
|
||||
break;
|
||||
}
|
||||
/* Tx unsuccessful or some interesting status bit set. */
|
||||
|
|
@ -591,7 +590,7 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id)
|
|||
}
|
||||
dev->stats.tx_packets++;
|
||||
if (net_debug > 5)
|
||||
printk("Reaped %x, Tx status %04x.\n" , lp->tx_reap, tx_status);
|
||||
pr_debug("Reaped %x, Tx status %04x.\n" , lp->tx_reap, tx_status);
|
||||
lp->tx_reap += TX_BUF_SIZE;
|
||||
if (lp->tx_reap > RX_BUF_START - TX_BUF_SIZE)
|
||||
lp->tx_reap = TX_BUF_START;
|
||||
|
|
@ -606,7 +605,7 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id)
|
|||
|
||||
if (status & 0x4000) { /* Packet received. */
|
||||
if (net_debug > 5)
|
||||
printk("Received packet, rx_head %04x.\n", lp->rx_head);
|
||||
pr_debug("Received packet, rx_head %04x.\n", lp->rx_head);
|
||||
el16_rx(dev);
|
||||
}
|
||||
|
||||
|
|
@ -615,7 +614,7 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id)
|
|||
|
||||
if ((status & 0x0700) != 0x0200 && netif_running(dev)) {
|
||||
if (net_debug)
|
||||
printk("%s: Command unit stopped, status %04x, restarting.\n",
|
||||
pr_debug("%s: Command unit stopped, status %04x, restarting.\n",
|
||||
dev->name, status);
|
||||
/* If this ever occurs we should really re-write the idle loop, reset
|
||||
the Tx list, and do a complete restart of the command unit.
|
||||
|
|
@ -627,7 +626,7 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id)
|
|||
/* The Rx unit is not ready, it must be hung. Restart the receiver by
|
||||
initializing the rx buffers, and issuing an Rx start command. */
|
||||
if (net_debug)
|
||||
printk("%s: Rx unit stopped, status %04x, restarting.\n",
|
||||
pr_debug("%s: Rx unit stopped, status %04x, restarting.\n",
|
||||
dev->name, status);
|
||||
init_rx_bufs(dev);
|
||||
writew(RX_BUF_START,shmem+iSCB_RFA);
|
||||
|
|
@ -753,9 +752,8 @@ static void init_82586_mem(struct net_device *dev)
|
|||
int boguscnt = 50;
|
||||
while (readw(shmem+iSCB_STATUS) == 0)
|
||||
if (--boguscnt == 0) {
|
||||
printk("%s: i82586 initialization timed out with status %04x, "
|
||||
"cmd %04x.\n", dev->name,
|
||||
readw(shmem+iSCB_STATUS), readw(shmem+iSCB_CMD));
|
||||
pr_warning("%s: i82586 initialization timed out with status %04x, cmd %04x.\n",
|
||||
dev->name, readw(shmem+iSCB_STATUS), readw(shmem+iSCB_CMD));
|
||||
break;
|
||||
}
|
||||
/* Issue channel-attn -- the 82586 won't start. */
|
||||
|
|
@ -765,7 +763,7 @@ static void init_82586_mem(struct net_device *dev)
|
|||
/* Disable loopback and enable interrupts. */
|
||||
outb(0x84, ioaddr + MISC_CTRL);
|
||||
if (net_debug > 4)
|
||||
printk("%s: Initialized 82586, status %04x.\n", dev->name,
|
||||
pr_debug("%s: Initialized 82586, status %04x.\n", dev->name,
|
||||
readw(shmem+iSCB_STATUS));
|
||||
return;
|
||||
}
|
||||
|
|
@ -810,7 +808,7 @@ static void hardware_send_packet(struct net_device *dev, void *buf, short length
|
|||
lp->tx_head = TX_BUF_START;
|
||||
|
||||
if (net_debug > 4) {
|
||||
printk("%s: 3c507 @%x send length = %d, tx_block %3x, next %3x.\n",
|
||||
pr_debug("%s: 3c507 @%x send length = %d, tx_block %3x, next %3x.\n",
|
||||
dev->name, ioaddr, length, tx_block, lp->tx_head);
|
||||
}
|
||||
|
||||
|
|
@ -838,7 +836,7 @@ static void el16_rx(struct net_device *dev)
|
|||
|
||||
if (rfd_cmd != 0 || data_buffer_addr != rx_head + 22
|
||||
|| (pkt_len & 0xC000) != 0xC000) {
|
||||
printk(KERN_ERR "%s: Rx frame at %#x corrupted, "
|
||||
pr_err("%s: Rx frame at %#x corrupted, "
|
||||
"status %04x cmd %04x next %04x "
|
||||
"data-buf @%04x %04x.\n",
|
||||
dev->name, rx_head, frame_status, rfd_cmd,
|
||||
|
|
@ -858,8 +856,7 @@ static void el16_rx(struct net_device *dev)
|
|||
pkt_len &= 0x3fff;
|
||||
skb = dev_alloc_skb(pkt_len+2);
|
||||
if (skb == NULL) {
|
||||
printk(KERN_ERR "%s: Memory squeeze, "
|
||||
"dropping packet.\n",
|
||||
pr_err("%s: Memory squeeze, dropping packet.\n",
|
||||
dev->name);
|
||||
dev->stats.rx_dropped++;
|
||||
break;
|
||||
|
|
@ -926,7 +923,7 @@ MODULE_PARM_DESC(irq, "(ignored)");
|
|||
int __init init_module(void)
|
||||
{
|
||||
if (io == 0)
|
||||
printk("3c507: You should not use auto-probing with insmod!\n");
|
||||
pr_notice("3c507: You should not use auto-probing with insmod!\n");
|
||||
dev_3c507 = el16_probe(-1);
|
||||
return IS_ERR(dev_3c507) ? PTR_ERR(dev_3c507) : 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -257,7 +257,7 @@ static int el3_isa_id_sequence(__be16 *phys_addr)
|
|||
&& !memcmp(phys_addr, el3_devs[i]->dev_addr,
|
||||
ETH_ALEN)) {
|
||||
if (el3_debug > 3)
|
||||
printk(KERN_DEBUG "3c509 with address %02x %02x %02x %02x %02x %02x was found by ISAPnP\n",
|
||||
pr_debug("3c509 with address %02x %02x %02x %02x %02x %02x was found by ISAPnP\n",
|
||||
phys_addr[0] & 0xff, phys_addr[0] >> 8,
|
||||
phys_addr[1] & 0xff, phys_addr[1] >> 8,
|
||||
phys_addr[2] & 0xff, phys_addr[2] >> 8);
|
||||
|
|
@ -578,19 +578,18 @@ static int __devinit el3_common_init(struct net_device *dev)
|
|||
|
||||
err = register_netdev(dev);
|
||||
if (err) {
|
||||
printk(KERN_ERR "Failed to register 3c5x9 at %#3.3lx, IRQ %d.\n",
|
||||
pr_err("Failed to register 3c5x9 at %#3.3lx, IRQ %d.\n",
|
||||
dev->base_addr, dev->irq);
|
||||
release_region(dev->base_addr, EL3_IO_EXTENT);
|
||||
return err;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "%s: 3c5x9 found at %#3.3lx, %s port, "
|
||||
"address %pM, IRQ %d.\n",
|
||||
pr_info("%s: 3c5x9 found at %#3.3lx, %s port, address %pM, IRQ %d.\n",
|
||||
dev->name, dev->base_addr, if_names[(dev->if_port & 0x03)],
|
||||
dev->dev_addr, dev->irq);
|
||||
|
||||
if (el3_debug > 0)
|
||||
printk(KERN_INFO "%s", version);
|
||||
pr_info("%s", version);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
|
@ -629,8 +628,8 @@ static int __init el3_mca_probe(struct device *device)
|
|||
irq = pos5 & 0x0f;
|
||||
|
||||
|
||||
printk(KERN_INFO "3c529: found %s at slot %d\n",
|
||||
el3_mca_adapter_names[mdev->index], slot + 1);
|
||||
pr_info("3c529: found %s at slot %d\n",
|
||||
el3_mca_adapter_names[mdev->index], slot + 1);
|
||||
|
||||
/* claim the slot */
|
||||
strncpy(mdev->name, el3_mca_adapter_names[mdev->index],
|
||||
|
|
@ -642,7 +641,7 @@ static int __init el3_mca_probe(struct device *device)
|
|||
irq = mca_device_transform_irq(mdev, irq);
|
||||
ioaddr = mca_device_transform_ioport(mdev, ioaddr);
|
||||
if (el3_debug > 2) {
|
||||
printk(KERN_DEBUG "3c529: irq %d ioaddr 0x%x ifport %d\n", irq, ioaddr, if_port);
|
||||
pr_debug("3c529: irq %d ioaddr 0x%x ifport %d\n", irq, ioaddr, if_port);
|
||||
}
|
||||
EL3WINDOW(0);
|
||||
for (i = 0; i < 3; i++)
|
||||
|
|
@ -657,11 +656,11 @@ static int __init el3_mca_probe(struct device *device)
|
|||
netdev_boot_setup_check(dev);
|
||||
|
||||
el3_dev_fill(dev, phys_addr, ioaddr, irq, if_port, EL3_MCA);
|
||||
device->driver_data = dev;
|
||||
dev_set_drvdata(device, dev);
|
||||
err = el3_common_init(dev);
|
||||
|
||||
if (err) {
|
||||
device->driver_data = NULL;
|
||||
dev_set_drvdata(device, NULL);
|
||||
free_netdev(dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
|
@ -725,12 +724,12 @@ static int __init el3_eisa_probe (struct device *device)
|
|||
|
||||
/* This remove works for all device types.
|
||||
*
|
||||
* The net dev must be stored in the driver_data field */
|
||||
* The net dev must be stored in the driver data field */
|
||||
static int __devexit el3_device_remove (struct device *device)
|
||||
{
|
||||
struct net_device *dev;
|
||||
|
||||
dev = device->driver_data;
|
||||
dev = dev_get_drvdata(device);
|
||||
|
||||
el3_common_remove (dev);
|
||||
return 0;
|
||||
|
|
@ -765,7 +764,7 @@ static ushort id_read_eeprom(int index)
|
|||
word = (word << 1) + (inb(id_port) & 0x01);
|
||||
|
||||
if (el3_debug > 3)
|
||||
printk(KERN_DEBUG " 3c509 EEPROM word %d %#4.4x.\n", index, word);
|
||||
pr_debug(" 3c509 EEPROM word %d %#4.4x.\n", index, word);
|
||||
|
||||
return word;
|
||||
}
|
||||
|
|
@ -787,13 +786,13 @@ el3_open(struct net_device *dev)
|
|||
|
||||
EL3WINDOW(0);
|
||||
if (el3_debug > 3)
|
||||
printk(KERN_DEBUG "%s: Opening, IRQ %d status@%x %4.4x.\n", dev->name,
|
||||
pr_debug("%s: Opening, IRQ %d status@%x %4.4x.\n", dev->name,
|
||||
dev->irq, ioaddr + EL3_STATUS, inw(ioaddr + EL3_STATUS));
|
||||
|
||||
el3_up(dev);
|
||||
|
||||
if (el3_debug > 3)
|
||||
printk(KERN_DEBUG "%s: Opened 3c509 IRQ %d status %4.4x.\n",
|
||||
pr_debug("%s: Opened 3c509 IRQ %d status %4.4x.\n",
|
||||
dev->name, dev->irq, inw(ioaddr + EL3_STATUS));
|
||||
|
||||
return 0;
|
||||
|
|
@ -805,8 +804,7 @@ el3_tx_timeout (struct net_device *dev)
|
|||
int ioaddr = dev->base_addr;
|
||||
|
||||
/* Transmitter timeout, serious problems. */
|
||||
printk(KERN_WARNING "%s: transmit timed out, Tx_status %2.2x status %4.4x "
|
||||
"Tx FIFO room %d.\n",
|
||||
pr_warning("%s: transmit timed out, Tx_status %2.2x status %4.4x Tx FIFO room %d.\n",
|
||||
dev->name, inb(ioaddr + TX_STATUS), inw(ioaddr + EL3_STATUS),
|
||||
inw(ioaddr + TX_FREE));
|
||||
dev->stats.tx_errors++;
|
||||
|
|
@ -830,7 +828,7 @@ el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
dev->stats.tx_bytes += skb->len;
|
||||
|
||||
if (el3_debug > 4) {
|
||||
printk(KERN_DEBUG "%s: el3_start_xmit(length = %u) called, status %4.4x.\n",
|
||||
pr_debug("%s: el3_start_xmit(length = %u) called, status %4.4x.\n",
|
||||
dev->name, skb->len, inw(ioaddr + EL3_STATUS));
|
||||
}
|
||||
#if 0
|
||||
|
|
@ -839,7 +837,7 @@ el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
ushort status = inw(ioaddr + EL3_STATUS);
|
||||
if (status & 0x0001 /* IRQ line active, missed one. */
|
||||
&& inw(ioaddr + EL3_STATUS) & 1) { /* Make sure. */
|
||||
printk(KERN_DEBUG "%s: Missed interrupt, status then %04x now %04x"
|
||||
pr_debug("%s: Missed interrupt, status then %04x now %04x"
|
||||
" Tx %2.2x Rx %4.4x.\n", dev->name, status,
|
||||
inw(ioaddr + EL3_STATUS), inb(ioaddr + TX_STATUS),
|
||||
inw(ioaddr + RX_STATUS));
|
||||
|
|
@ -913,7 +911,7 @@ el3_interrupt(int irq, void *dev_id)
|
|||
|
||||
if (el3_debug > 4) {
|
||||
status = inw(ioaddr + EL3_STATUS);
|
||||
printk(KERN_DEBUG "%s: interrupt, status %4.4x.\n", dev->name, status);
|
||||
pr_debug("%s: interrupt, status %4.4x.\n", dev->name, status);
|
||||
}
|
||||
|
||||
while ((status = inw(ioaddr + EL3_STATUS)) &
|
||||
|
|
@ -924,7 +922,7 @@ el3_interrupt(int irq, void *dev_id)
|
|||
|
||||
if (status & TxAvailable) {
|
||||
if (el3_debug > 5)
|
||||
printk(KERN_DEBUG " TX room bit was handled.\n");
|
||||
pr_debug(" TX room bit was handled.\n");
|
||||
/* There's room in the FIFO for a full-sized packet. */
|
||||
outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
|
||||
netif_wake_queue (dev);
|
||||
|
|
@ -962,7 +960,7 @@ el3_interrupt(int irq, void *dev_id)
|
|||
}
|
||||
|
||||
if (--i < 0) {
|
||||
printk(KERN_ERR "%s: Infinite loop in interrupt, status %4.4x.\n",
|
||||
pr_err("%s: Infinite loop in interrupt, status %4.4x.\n",
|
||||
dev->name, status);
|
||||
/* Clear all interrupts. */
|
||||
outw(AckIntr | 0xFF, ioaddr + EL3_CMD);
|
||||
|
|
@ -973,7 +971,7 @@ el3_interrupt(int irq, void *dev_id)
|
|||
}
|
||||
|
||||
if (el3_debug > 4) {
|
||||
printk(KERN_DEBUG "%s: exiting interrupt, status %4.4x.\n", dev->name,
|
||||
pr_debug("%s: exiting interrupt, status %4.4x.\n", dev->name,
|
||||
inw(ioaddr + EL3_STATUS));
|
||||
}
|
||||
spin_unlock(&lp->lock);
|
||||
|
|
@ -1021,7 +1019,7 @@ static void update_stats(struct net_device *dev)
|
|||
int ioaddr = dev->base_addr;
|
||||
|
||||
if (el3_debug > 5)
|
||||
printk(" Updating the statistics.\n");
|
||||
pr_debug(" Updating the statistics.\n");
|
||||
/* Turn off statistics updates while reading. */
|
||||
outw(StatsDisable, ioaddr + EL3_CMD);
|
||||
/* Switch to the stats window, and read everything. */
|
||||
|
|
@ -1051,7 +1049,7 @@ el3_rx(struct net_device *dev)
|
|||
short rx_status;
|
||||
|
||||
if (el3_debug > 5)
|
||||
printk(" In rx_packet(), status %4.4x, rx_status %4.4x.\n",
|
||||
pr_debug(" In rx_packet(), status %4.4x, rx_status %4.4x.\n",
|
||||
inw(ioaddr+EL3_STATUS), inw(ioaddr+RX_STATUS));
|
||||
while ((rx_status = inw(ioaddr + RX_STATUS)) > 0) {
|
||||
if (rx_status & 0x4000) { /* Error, update stats. */
|
||||
|
|
@ -1073,7 +1071,7 @@ el3_rx(struct net_device *dev)
|
|||
|
||||
skb = dev_alloc_skb(pkt_len+5);
|
||||
if (el3_debug > 4)
|
||||
printk("Receiving packet size %d status %4.4x.\n",
|
||||
pr_debug("Receiving packet size %d status %4.4x.\n",
|
||||
pkt_len, rx_status);
|
||||
if (skb != NULL) {
|
||||
skb_reserve(skb, 2); /* Align IP on 16 byte */
|
||||
|
|
@ -1092,12 +1090,12 @@ el3_rx(struct net_device *dev)
|
|||
outw(RxDiscard, ioaddr + EL3_CMD);
|
||||
dev->stats.rx_dropped++;
|
||||
if (el3_debug)
|
||||
printk("%s: Couldn't allocate a sk_buff of size %d.\n",
|
||||
pr_debug("%s: Couldn't allocate a sk_buff of size %d.\n",
|
||||
dev->name, pkt_len);
|
||||
}
|
||||
inw(ioaddr + EL3_STATUS); /* Delay. */
|
||||
while (inw(ioaddr + EL3_STATUS) & 0x1000)
|
||||
printk(KERN_DEBUG " Waiting for 3c509 to discard packet, status %x.\n",
|
||||
pr_debug(" Waiting for 3c509 to discard packet, status %x.\n",
|
||||
inw(ioaddr + EL3_STATUS) );
|
||||
}
|
||||
|
||||
|
|
@ -1118,7 +1116,7 @@ set_multicast_list(struct net_device *dev)
|
|||
static int old;
|
||||
if (old != dev->mc_count) {
|
||||
old = dev->mc_count;
|
||||
printk("%s: Setting Rx mode to %d addresses.\n", dev->name, dev->mc_count);
|
||||
pr_debug("%s: Setting Rx mode to %d addresses.\n", dev->name, dev->mc_count);
|
||||
}
|
||||
}
|
||||
spin_lock_irqsave(&lp->lock, flags);
|
||||
|
|
@ -1141,7 +1139,7 @@ el3_close(struct net_device *dev)
|
|||
struct el3_private *lp = netdev_priv(dev);
|
||||
|
||||
if (el3_debug > 2)
|
||||
printk("%s: Shutting down ethercard.\n", dev->name);
|
||||
pr_debug("%s: Shutting down ethercard.\n", dev->name);
|
||||
|
||||
el3_down(dev);
|
||||
|
||||
|
|
@ -1388,30 +1386,30 @@ el3_up(struct net_device *dev)
|
|||
EL3WINDOW(4);
|
||||
net_diag = inw(ioaddr + WN4_NETDIAG);
|
||||
net_diag = (net_diag | FD_ENABLE); /* temporarily assume full-duplex will be set */
|
||||
printk("%s: ", dev->name);
|
||||
pr_info("%s: ", dev->name);
|
||||
switch (dev->if_port & 0x0c) {
|
||||
case 12:
|
||||
/* force full-duplex mode if 3c5x9b */
|
||||
if (sw_info & 0x000f) {
|
||||
printk("Forcing 3c5x9b full-duplex mode");
|
||||
pr_cont("Forcing 3c5x9b full-duplex mode");
|
||||
break;
|
||||
}
|
||||
case 8:
|
||||
/* set full-duplex mode based on eeprom config setting */
|
||||
if ((sw_info & 0x000f) && (sw_info & 0x8000)) {
|
||||
printk("Setting 3c5x9b full-duplex mode (from EEPROM configuration bit)");
|
||||
pr_cont("Setting 3c5x9b full-duplex mode (from EEPROM configuration bit)");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
/* xcvr=(0 || 4) OR user has an old 3c5x9 non "B" model */
|
||||
printk("Setting 3c5x9/3c5x9B half-duplex mode");
|
||||
pr_cont("Setting 3c5x9/3c5x9B half-duplex mode");
|
||||
net_diag = (net_diag & ~FD_ENABLE); /* disable full duplex */
|
||||
}
|
||||
|
||||
outw(net_diag, ioaddr + WN4_NETDIAG);
|
||||
printk(" if_port: %d, sw_info: %4.4x\n", dev->if_port, sw_info);
|
||||
pr_cont(" if_port: %d, sw_info: %4.4x\n", dev->if_port, sw_info);
|
||||
if (el3_debug > 3)
|
||||
printk("%s: 3c5x9 net diag word is now: %4.4x.\n", dev->name, net_diag);
|
||||
pr_debug("%s: 3c5x9 net diag word is now: %4.4x.\n", dev->name, net_diag);
|
||||
/* Enable link beat and jabber check. */
|
||||
outw(inw(ioaddr + WN4_MEDIA) | MEDIA_TP, ioaddr + WN4_MEDIA);
|
||||
}
|
||||
|
|
@ -1455,7 +1453,7 @@ el3_suspend(struct device *pdev, pm_message_t state)
|
|||
struct el3_private *lp;
|
||||
int ioaddr;
|
||||
|
||||
dev = pdev->driver_data;
|
||||
dev = dev_get_drvdata(pdev);
|
||||
lp = netdev_priv(dev);
|
||||
ioaddr = dev->base_addr;
|
||||
|
||||
|
|
@ -1479,7 +1477,7 @@ el3_resume(struct device *pdev)
|
|||
struct el3_private *lp;
|
||||
int ioaddr;
|
||||
|
||||
dev = pdev->driver_data;
|
||||
dev = dev_get_drvdata(pdev);
|
||||
lp = netdev_priv(dev);
|
||||
ioaddr = dev->base_addr;
|
||||
|
||||
|
|
@ -1539,7 +1537,7 @@ static int __init el3_init_module(void)
|
|||
}
|
||||
if (id_port >= 0x200) {
|
||||
id_port = 0;
|
||||
printk(KERN_ERR "No I/O port available for 3c509 activation.\n");
|
||||
pr_err("No I/O port available for 3c509 activation.\n");
|
||||
} else {
|
||||
ret = isa_register_driver(&el3_isa_driver, EL3_MAX_CARDS);
|
||||
if (!ret)
|
||||
|
|
|
|||
|
|
@ -420,7 +420,7 @@ int init_module(void)
|
|||
if (debug >= 0)
|
||||
corkscrew_debug = debug;
|
||||
if (corkscrew_debug)
|
||||
printk(version);
|
||||
pr_debug("%s", version);
|
||||
while (corkscrew_scan(-1))
|
||||
found++;
|
||||
return found ? 0 : -ENODEV;
|
||||
|
|
@ -437,7 +437,7 @@ struct net_device *tc515_probe(int unit)
|
|||
|
||||
if (corkscrew_debug > 0 && !printed) {
|
||||
printed = 1;
|
||||
printk(version);
|
||||
pr_debug("%s", version);
|
||||
}
|
||||
|
||||
return dev;
|
||||
|
|
@ -516,7 +516,7 @@ static struct net_device *corkscrew_scan(int unit)
|
|||
if (pnp_device_attach(idev) < 0)
|
||||
continue;
|
||||
if (pnp_activate_dev(idev) < 0) {
|
||||
printk("pnp activate failed (out of resources?)\n");
|
||||
pr_warning("pnp activate failed (out of resources?)\n");
|
||||
pnp_device_detach(idev);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -531,9 +531,9 @@ static struct net_device *corkscrew_scan(int unit)
|
|||
continue;
|
||||
}
|
||||
if(corkscrew_debug)
|
||||
printk ("ISAPNP reports %s at i/o 0x%x, irq %d\n",
|
||||
pr_debug("ISAPNP reports %s at i/o 0x%x, irq %d\n",
|
||||
(char*) corkscrew_isapnp_adapters[i].driver_data, ioaddr, irq);
|
||||
printk(KERN_INFO "3c515 Resource configuration register %#4.4x, DCR %4.4x.\n",
|
||||
pr_info("3c515 Resource configuration register %#4.4x, DCR %4.4x.\n",
|
||||
inl(ioaddr + 0x2002), inw(ioaddr + 0x2000));
|
||||
/* irq = inw(ioaddr + 0x2002) & 15; */ /* Use the irq from isapnp */
|
||||
SET_NETDEV_DEV(dev, &idev->dev);
|
||||
|
|
@ -552,7 +552,7 @@ no_pnp:
|
|||
if (!check_device(ioaddr))
|
||||
continue;
|
||||
|
||||
printk(KERN_INFO "3c515 Resource configuration register %#4.4x, DCR %4.4x.\n",
|
||||
pr_info("3c515 Resource configuration register %#4.4x, DCR %4.4x.\n",
|
||||
inl(ioaddr + 0x2002), inw(ioaddr + 0x2000));
|
||||
err = corkscrew_setup(dev, ioaddr, NULL, cards_found++);
|
||||
if (!err)
|
||||
|
|
@ -625,7 +625,7 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr,
|
|||
list_add(&vp->list, &root_corkscrew_dev);
|
||||
#endif
|
||||
|
||||
printk(KERN_INFO "%s: 3Com %s at %#3x,", dev->name, vp->product_name, ioaddr);
|
||||
pr_info("%s: 3Com %s at %#3x,", dev->name, vp->product_name, ioaddr);
|
||||
|
||||
spin_lock_init(&vp->lock);
|
||||
|
||||
|
|
@ -648,19 +648,19 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr,
|
|||
}
|
||||
checksum = (checksum ^ (checksum >> 8)) & 0xff;
|
||||
if (checksum != 0x00)
|
||||
printk(" ***INVALID CHECKSUM %4.4x*** ", checksum);
|
||||
printk(" %pM", dev->dev_addr);
|
||||
pr_cont(" ***INVALID CHECKSUM %4.4x*** ", checksum);
|
||||
pr_cont(" %pM", dev->dev_addr);
|
||||
if (eeprom[16] == 0x11c7) { /* Corkscrew */
|
||||
if (request_dma(dev->dma, "3c515")) {
|
||||
printk(", DMA %d allocation failed", dev->dma);
|
||||
pr_cont(", DMA %d allocation failed", dev->dma);
|
||||
dev->dma = 0;
|
||||
} else
|
||||
printk(", DMA %d", dev->dma);
|
||||
pr_cont(", DMA %d", dev->dma);
|
||||
}
|
||||
printk(", IRQ %d\n", dev->irq);
|
||||
pr_cont(", IRQ %d\n", dev->irq);
|
||||
/* Tell them about an invalid IRQ. */
|
||||
if (corkscrew_debug && (dev->irq <= 0 || dev->irq > 15))
|
||||
printk(KERN_WARNING " *** Warning: this IRQ is unlikely to work! ***\n");
|
||||
pr_warning(" *** Warning: this IRQ is unlikely to work! ***\n");
|
||||
|
||||
{
|
||||
char *ram_split[] = { "5:3", "3:1", "1:1", "3:5" };
|
||||
|
|
@ -669,9 +669,9 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr,
|
|||
vp->available_media = inw(ioaddr + Wn3_Options);
|
||||
config = inl(ioaddr + Wn3_Config);
|
||||
if (corkscrew_debug > 1)
|
||||
printk(KERN_INFO " Internal config register is %4.4x, transceivers %#x.\n",
|
||||
pr_info(" Internal config register is %4.4x, transceivers %#x.\n",
|
||||
config, inw(ioaddr + Wn3_Options));
|
||||
printk(KERN_INFO " %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
|
||||
pr_info(" %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
|
||||
8 << config & Ram_size,
|
||||
config & Ram_width ? "word" : "byte",
|
||||
ram_split[(config & Ram_split) >> Ram_split_shift],
|
||||
|
|
@ -682,7 +682,7 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr,
|
|||
dev->if_port = vp->default_media;
|
||||
}
|
||||
if (vp->media_override != 7) {
|
||||
printk(KERN_INFO " Media override to transceiver type %d (%s).\n",
|
||||
pr_info(" Media override to transceiver type %d (%s).\n",
|
||||
vp->media_override,
|
||||
media_tbl[vp->media_override].name);
|
||||
dev->if_port = vp->media_override;
|
||||
|
|
@ -718,7 +718,7 @@ static int corkscrew_open(struct net_device *dev)
|
|||
|
||||
if (vp->media_override != 7) {
|
||||
if (corkscrew_debug > 1)
|
||||
printk(KERN_INFO "%s: Media override to transceiver %d (%s).\n",
|
||||
pr_info("%s: Media override to transceiver %d (%s).\n",
|
||||
dev->name, vp->media_override,
|
||||
media_tbl[vp->media_override].name);
|
||||
dev->if_port = vp->media_override;
|
||||
|
|
@ -729,7 +729,7 @@ static int corkscrew_open(struct net_device *dev)
|
|||
dev->if_port = media_tbl[dev->if_port].next;
|
||||
|
||||
if (corkscrew_debug > 1)
|
||||
printk("%s: Initial media type %s.\n",
|
||||
pr_debug("%s: Initial media type %s.\n",
|
||||
dev->name, media_tbl[dev->if_port].name);
|
||||
|
||||
init_timer(&vp->timer);
|
||||
|
|
@ -744,7 +744,7 @@ static int corkscrew_open(struct net_device *dev)
|
|||
outl(config, ioaddr + Wn3_Config);
|
||||
|
||||
if (corkscrew_debug > 1) {
|
||||
printk("%s: corkscrew_open() InternalConfig %8.8x.\n",
|
||||
pr_debug("%s: corkscrew_open() InternalConfig %8.8x.\n",
|
||||
dev->name, config);
|
||||
}
|
||||
|
||||
|
|
@ -777,7 +777,7 @@ static int corkscrew_open(struct net_device *dev)
|
|||
|
||||
if (corkscrew_debug > 1) {
|
||||
EL3WINDOW(4);
|
||||
printk("%s: corkscrew_open() irq %d media status %4.4x.\n",
|
||||
pr_debug("%s: corkscrew_open() irq %d media status %4.4x.\n",
|
||||
dev->name, dev->irq, inw(ioaddr + Wn4_Media));
|
||||
}
|
||||
|
||||
|
|
@ -814,8 +814,7 @@ static int corkscrew_open(struct net_device *dev)
|
|||
if (vp->full_bus_master_rx) { /* Boomerang bus master. */
|
||||
vp->cur_rx = vp->dirty_rx = 0;
|
||||
if (corkscrew_debug > 2)
|
||||
printk("%s: Filling in the Rx ring.\n",
|
||||
dev->name);
|
||||
pr_debug("%s: Filling in the Rx ring.\n", dev->name);
|
||||
for (i = 0; i < RX_RING_SIZE; i++) {
|
||||
struct sk_buff *skb;
|
||||
if (i < (RX_RING_SIZE - 1))
|
||||
|
|
@ -877,7 +876,7 @@ static void corkscrew_timer(unsigned long data)
|
|||
int ok = 0;
|
||||
|
||||
if (corkscrew_debug > 1)
|
||||
printk("%s: Media selection timer tick happened, %s.\n",
|
||||
pr_debug("%s: Media selection timer tick happened, %s.\n",
|
||||
dev->name, media_tbl[dev->if_port].name);
|
||||
|
||||
spin_lock_irqsave(&vp->lock, flags);
|
||||
|
|
@ -894,12 +893,12 @@ static void corkscrew_timer(unsigned long data)
|
|||
if (media_status & Media_LnkBeat) {
|
||||
ok = 1;
|
||||
if (corkscrew_debug > 1)
|
||||
printk("%s: Media %s has link beat, %x.\n",
|
||||
pr_debug("%s: Media %s has link beat, %x.\n",
|
||||
dev->name,
|
||||
media_tbl[dev->if_port].name,
|
||||
media_status);
|
||||
} else if (corkscrew_debug > 1)
|
||||
printk("%s: Media %s is has no link beat, %x.\n",
|
||||
pr_debug("%s: Media %s is has no link beat, %x.\n",
|
||||
dev->name,
|
||||
media_tbl[dev->if_port].name,
|
||||
media_status);
|
||||
|
|
@ -907,7 +906,7 @@ static void corkscrew_timer(unsigned long data)
|
|||
break;
|
||||
default: /* Other media types handled by Tx timeouts. */
|
||||
if (corkscrew_debug > 1)
|
||||
printk("%s: Media %s is has no indication, %x.\n",
|
||||
pr_debug("%s: Media %s is has no indication, %x.\n",
|
||||
dev->name,
|
||||
media_tbl[dev->if_port].name,
|
||||
media_status);
|
||||
|
|
@ -925,12 +924,12 @@ static void corkscrew_timer(unsigned long data)
|
|||
if (dev->if_port == 8) { /* Go back to default. */
|
||||
dev->if_port = vp->default_media;
|
||||
if (corkscrew_debug > 1)
|
||||
printk("%s: Media selection failing, using default %s port.\n",
|
||||
pr_debug("%s: Media selection failing, using default %s port.\n",
|
||||
dev->name,
|
||||
media_tbl[dev->if_port].name);
|
||||
} else {
|
||||
if (corkscrew_debug > 1)
|
||||
printk("%s: Media selection failed, now trying %s port.\n",
|
||||
pr_debug("%s: Media selection failed, now trying %s port.\n",
|
||||
dev->name,
|
||||
media_tbl[dev->if_port].name);
|
||||
vp->timer.expires = jiffies + media_tbl[dev->if_port].wait;
|
||||
|
|
@ -953,7 +952,7 @@ static void corkscrew_timer(unsigned long data)
|
|||
|
||||
spin_unlock_irqrestore(&vp->lock, flags);
|
||||
if (corkscrew_debug > 1)
|
||||
printk("%s: Media selection timer finished, %s.\n",
|
||||
pr_debug("%s: Media selection timer finished, %s.\n",
|
||||
dev->name, media_tbl[dev->if_port].name);
|
||||
|
||||
#endif /* AUTOMEDIA */
|
||||
|
|
@ -966,23 +965,21 @@ static void corkscrew_timeout(struct net_device *dev)
|
|||
struct corkscrew_private *vp = netdev_priv(dev);
|
||||
int ioaddr = dev->base_addr;
|
||||
|
||||
printk(KERN_WARNING
|
||||
"%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
|
||||
pr_warning("%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
|
||||
dev->name, inb(ioaddr + TxStatus),
|
||||
inw(ioaddr + EL3_STATUS));
|
||||
/* Slight code bloat to be user friendly. */
|
||||
if ((inb(ioaddr + TxStatus) & 0x88) == 0x88)
|
||||
printk(KERN_WARNING
|
||||
"%s: Transmitter encountered 16 collisions -- network"
|
||||
pr_warning("%s: Transmitter encountered 16 collisions --"
|
||||
" network cable problem?\n", dev->name);
|
||||
#ifndef final_version
|
||||
printk(" Flags; bus-master %d, full %d; dirty %d current %d.\n",
|
||||
pr_debug(" Flags; bus-master %d, full %d; dirty %d current %d.\n",
|
||||
vp->full_bus_master_tx, vp->tx_full, vp->dirty_tx,
|
||||
vp->cur_tx);
|
||||
printk(" Down list %8.8x vs. %p.\n", inl(ioaddr + DownListPtr),
|
||||
pr_debug(" Down list %8.8x vs. %p.\n", inl(ioaddr + DownListPtr),
|
||||
&vp->tx_ring[0]);
|
||||
for (i = 0; i < TX_RING_SIZE; i++) {
|
||||
printk(" %d: %p length %8.8x status %8.8x\n", i,
|
||||
pr_debug(" %d: %p length %8.8x status %8.8x\n", i,
|
||||
&vp->tx_ring[i],
|
||||
vp->tx_ring[i].length, vp->tx_ring[i].status);
|
||||
}
|
||||
|
|
@ -1017,13 +1014,13 @@ static int corkscrew_start_xmit(struct sk_buff *skb,
|
|||
int i;
|
||||
|
||||
if (vp->tx_full) /* No room to transmit with */
|
||||
return 1;
|
||||
return NETDEV_TX_BUSY;
|
||||
if (vp->cur_tx != 0)
|
||||
prev_entry = &vp->tx_ring[(vp->cur_tx - 1) % TX_RING_SIZE];
|
||||
else
|
||||
prev_entry = NULL;
|
||||
if (corkscrew_debug > 3)
|
||||
printk("%s: Trying to send a packet, Tx index %d.\n",
|
||||
pr_debug("%s: Trying to send a packet, Tx index %d.\n",
|
||||
dev->name, vp->cur_tx);
|
||||
/* vp->tx_full = 1; */
|
||||
vp->tx_skbuff[entry] = skb;
|
||||
|
|
@ -1102,7 +1099,7 @@ static int corkscrew_start_xmit(struct sk_buff *skb,
|
|||
while (--i > 0 && (tx_status = inb(ioaddr + TxStatus)) > 0) {
|
||||
if (tx_status & 0x3C) { /* A Tx-disabling error occurred. */
|
||||
if (corkscrew_debug > 2)
|
||||
printk("%s: Tx error, status %2.2x.\n",
|
||||
pr_debug("%s: Tx error, status %2.2x.\n",
|
||||
dev->name, tx_status);
|
||||
if (tx_status & 0x04)
|
||||
dev->stats.tx_fifo_errors++;
|
||||
|
|
@ -1143,7 +1140,7 @@ static irqreturn_t corkscrew_interrupt(int irq, void *dev_id)
|
|||
status = inw(ioaddr + EL3_STATUS);
|
||||
|
||||
if (corkscrew_debug > 4)
|
||||
printk("%s: interrupt, status %4.4x, timer %d.\n",
|
||||
pr_debug("%s: interrupt, status %4.4x, timer %d.\n",
|
||||
dev->name, status, latency);
|
||||
if ((status & 0xE000) != 0xE000) {
|
||||
static int donedidthis;
|
||||
|
|
@ -1151,7 +1148,7 @@ static irqreturn_t corkscrew_interrupt(int irq, void *dev_id)
|
|||
Ignore a single early interrupt, but don't hang the machine for
|
||||
other interrupt problems. */
|
||||
if (donedidthis++ > 100) {
|
||||
printk(KERN_ERR "%s: Bogus interrupt, bailing. Status %4.4x, start=%d.\n",
|
||||
pr_err("%s: Bogus interrupt, bailing. Status %4.4x, start=%d.\n",
|
||||
dev->name, status, netif_running(dev));
|
||||
free_irq(dev->irq, dev);
|
||||
dev->irq = -1;
|
||||
|
|
@ -1160,14 +1157,14 @@ static irqreturn_t corkscrew_interrupt(int irq, void *dev_id)
|
|||
|
||||
do {
|
||||
if (corkscrew_debug > 5)
|
||||
printk("%s: In interrupt loop, status %4.4x.\n",
|
||||
pr_debug("%s: In interrupt loop, status %4.4x.\n",
|
||||
dev->name, status);
|
||||
if (status & RxComplete)
|
||||
corkscrew_rx(dev);
|
||||
|
||||
if (status & TxAvailable) {
|
||||
if (corkscrew_debug > 5)
|
||||
printk(" TX room bit was handled.\n");
|
||||
pr_debug(" TX room bit was handled.\n");
|
||||
/* There's room in the FIFO for a full-sized packet. */
|
||||
outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
|
||||
netif_wake_queue(dev);
|
||||
|
|
@ -1212,19 +1209,20 @@ static irqreturn_t corkscrew_interrupt(int irq, void *dev_id)
|
|||
if (status & StatsFull) { /* Empty statistics. */
|
||||
static int DoneDidThat;
|
||||
if (corkscrew_debug > 4)
|
||||
printk("%s: Updating stats.\n", dev->name);
|
||||
pr_debug("%s: Updating stats.\n", dev->name);
|
||||
update_stats(ioaddr, dev);
|
||||
/* DEBUG HACK: Disable statistics as an interrupt source. */
|
||||
/* This occurs when we have the wrong media type! */
|
||||
if (DoneDidThat == 0 && inw(ioaddr + EL3_STATUS) & StatsFull) {
|
||||
int win, reg;
|
||||
printk("%s: Updating stats failed, disabling stats as an"
|
||||
" interrupt source.\n", dev->name);
|
||||
pr_notice("%s: Updating stats failed, disabling stats as an interrupt source.\n",
|
||||
dev->name);
|
||||
for (win = 0; win < 8; win++) {
|
||||
EL3WINDOW(win);
|
||||
printk("\n Vortex window %d:", win);
|
||||
pr_notice("Vortex window %d:", win);
|
||||
for (reg = 0; reg < 16; reg++)
|
||||
printk(" %2.2x", inb(ioaddr + reg));
|
||||
pr_cont(" %2.2x", inb(ioaddr + reg));
|
||||
pr_cont("\n");
|
||||
}
|
||||
EL3WINDOW(7);
|
||||
outw(SetIntrEnb | TxAvailable |
|
||||
|
|
@ -1246,9 +1244,8 @@ static irqreturn_t corkscrew_interrupt(int irq, void *dev_id)
|
|||
}
|
||||
|
||||
if (--i < 0) {
|
||||
printk(KERN_ERR "%s: Too much work in interrupt, status %4.4x. "
|
||||
"Disabling functions (%4.4x).\n", dev->name,
|
||||
status, SetStatusEnb | ((~status) & 0x7FE));
|
||||
pr_err("%s: Too much work in interrupt, status %4.4x. Disabling functions (%4.4x).\n",
|
||||
dev->name, status, SetStatusEnb | ((~status) & 0x7FE));
|
||||
/* Disable all pending interrupts. */
|
||||
outw(SetStatusEnb | ((~status) & 0x7FE), ioaddr + EL3_CMD);
|
||||
outw(AckIntr | 0x7FF, ioaddr + EL3_CMD);
|
||||
|
|
@ -1262,7 +1259,7 @@ static irqreturn_t corkscrew_interrupt(int irq, void *dev_id)
|
|||
spin_unlock(&lp->lock);
|
||||
|
||||
if (corkscrew_debug > 4)
|
||||
printk("%s: exiting interrupt, status %4.4x.\n", dev->name, status);
|
||||
pr_debug("%s: exiting interrupt, status %4.4x.\n", dev->name, status);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
|
@ -1273,13 +1270,13 @@ static int corkscrew_rx(struct net_device *dev)
|
|||
short rx_status;
|
||||
|
||||
if (corkscrew_debug > 5)
|
||||
printk(" In rx_packet(), status %4.4x, rx_status %4.4x.\n",
|
||||
pr_debug(" In rx_packet(), status %4.4x, rx_status %4.4x.\n",
|
||||
inw(ioaddr + EL3_STATUS), inw(ioaddr + RxStatus));
|
||||
while ((rx_status = inw(ioaddr + RxStatus)) > 0) {
|
||||
if (rx_status & 0x4000) { /* Error, update stats. */
|
||||
unsigned char rx_error = inb(ioaddr + RxErrors);
|
||||
if (corkscrew_debug > 2)
|
||||
printk(" Rx error: status %2.2x.\n",
|
||||
pr_debug(" Rx error: status %2.2x.\n",
|
||||
rx_error);
|
||||
dev->stats.rx_errors++;
|
||||
if (rx_error & 0x01)
|
||||
|
|
@ -1299,7 +1296,7 @@ static int corkscrew_rx(struct net_device *dev)
|
|||
|
||||
skb = dev_alloc_skb(pkt_len + 5 + 2);
|
||||
if (corkscrew_debug > 4)
|
||||
printk("Receiving packet size %d status %4.4x.\n",
|
||||
pr_debug("Receiving packet size %d status %4.4x.\n",
|
||||
pkt_len, rx_status);
|
||||
if (skb != NULL) {
|
||||
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
|
||||
|
|
@ -1318,7 +1315,7 @@ static int corkscrew_rx(struct net_device *dev)
|
|||
break;
|
||||
continue;
|
||||
} else if (corkscrew_debug)
|
||||
printk("%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, pkt_len);
|
||||
pr_debug("%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, pkt_len);
|
||||
}
|
||||
outw(RxDiscard, ioaddr + EL3_CMD);
|
||||
dev->stats.rx_dropped++;
|
||||
|
|
@ -1338,13 +1335,13 @@ static int boomerang_rx(struct net_device *dev)
|
|||
int rx_status;
|
||||
|
||||
if (corkscrew_debug > 5)
|
||||
printk(" In boomerang_rx(), status %4.4x, rx_status %4.4x.\n",
|
||||
pr_debug(" In boomerang_rx(), status %4.4x, rx_status %4.4x.\n",
|
||||
inw(ioaddr + EL3_STATUS), inw(ioaddr + RxStatus));
|
||||
while ((rx_status = vp->rx_ring[entry].status) & RxDComplete) {
|
||||
if (rx_status & RxDError) { /* Error, update stats. */
|
||||
unsigned char rx_error = rx_status >> 16;
|
||||
if (corkscrew_debug > 2)
|
||||
printk(" Rx error: status %2.2x.\n",
|
||||
pr_debug(" Rx error: status %2.2x.\n",
|
||||
rx_error);
|
||||
dev->stats.rx_errors++;
|
||||
if (rx_error & 0x01)
|
||||
|
|
@ -1364,7 +1361,7 @@ static int boomerang_rx(struct net_device *dev)
|
|||
|
||||
dev->stats.rx_bytes += pkt_len;
|
||||
if (corkscrew_debug > 4)
|
||||
printk("Receiving packet size %d status %4.4x.\n",
|
||||
pr_debug("Receiving packet size %d status %4.4x.\n",
|
||||
pkt_len, rx_status);
|
||||
|
||||
/* Check if the packet is long enough to just accept without
|
||||
|
|
@ -1385,7 +1382,7 @@ static int boomerang_rx(struct net_device *dev)
|
|||
temp = skb_put(skb, pkt_len);
|
||||
/* Remove this checking code for final release. */
|
||||
if (isa_bus_to_virt(vp->rx_ring[entry].addr) != temp)
|
||||
printk("%s: Warning -- the skbuff addresses do not match"
|
||||
pr_warning("%s: Warning -- the skbuff addresses do not match"
|
||||
" in boomerang_rx: %p vs. %p / %p.\n",
|
||||
dev->name,
|
||||
isa_bus_to_virt(vp->
|
||||
|
|
@ -1427,12 +1424,11 @@ static int corkscrew_close(struct net_device *dev)
|
|||
netif_stop_queue(dev);
|
||||
|
||||
if (corkscrew_debug > 1) {
|
||||
printk("%s: corkscrew_close() status %4.4x, Tx status %2.2x.\n",
|
||||
pr_debug("%s: corkscrew_close() status %4.4x, Tx status %2.2x.\n",
|
||||
dev->name, inw(ioaddr + EL3_STATUS),
|
||||
inb(ioaddr + TxStatus));
|
||||
printk("%s: corkscrew close stats: rx_nocopy %d rx_copy %d"
|
||||
" tx_queued %d.\n", dev->name, rx_nocopy, rx_copy,
|
||||
queued_packet);
|
||||
pr_debug("%s: corkscrew close stats: rx_nocopy %d rx_copy %d tx_queued %d.\n",
|
||||
dev->name, rx_nocopy, rx_copy, queued_packet);
|
||||
}
|
||||
|
||||
del_timer(&vp->timer);
|
||||
|
|
@ -1534,7 +1530,7 @@ static void set_rx_mode(struct net_device *dev)
|
|||
|
||||
if (dev->flags & IFF_PROMISC) {
|
||||
if (corkscrew_debug > 3)
|
||||
printk("%s: Setting promiscuous mode.\n",
|
||||
pr_debug("%s: Setting promiscuous mode.\n",
|
||||
dev->name);
|
||||
new_mode = SetRxFilter | RxStation | RxMulticast | RxBroadcast | RxProm;
|
||||
} else if ((dev->mc_list) || (dev->flags & IFF_ALLMULTI)) {
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ sizeof(nop_cmd) = 8;
|
|||
if(!p->scb->cmd) break; \
|
||||
DELAY_16(); \
|
||||
if(i == 1023) { \
|
||||
printk(KERN_WARNING "%s:%d: scb_cmd timed out .. resetting i82586\n",\
|
||||
pr_warning("%s:%d: scb_cmd timed out .. resetting i82586\n",\
|
||||
dev->name,__LINE__); \
|
||||
elmc_id_reset586(); } } }
|
||||
|
||||
|
|
@ -291,7 +291,7 @@ static int elmc_open(struct net_device *dev)
|
|||
ret = request_irq(dev->irq, &elmc_interrupt, IRQF_SHARED | IRQF_SAMPLE_RANDOM,
|
||||
dev->name, dev);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "%s: couldn't get irq %d\n", dev->name, dev->irq);
|
||||
pr_err("%s: couldn't get irq %d\n", dev->name, dev->irq);
|
||||
elmc_id_reset586();
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -371,9 +371,9 @@ static void alloc586(struct net_device *dev)
|
|||
|
||||
DELAY(2);
|
||||
|
||||
if (p->iscp->busy) {
|
||||
printk(KERN_ERR "%s: Init-Problems (alloc).\n", dev->name);
|
||||
}
|
||||
if (p->iscp->busy)
|
||||
pr_err("%s: Init-Problems (alloc).\n", dev->name);
|
||||
|
||||
memset((char *) p->scb, 0, sizeof(struct scb_struct));
|
||||
}
|
||||
|
||||
|
|
@ -470,7 +470,7 @@ static int __init do_elmc_probe(struct net_device *dev)
|
|||
mca_set_adapter_procfn(slot, (MCA_ProcFn) elmc_getinfo, dev);
|
||||
|
||||
/* if we get this far, adapter has been found - carry on */
|
||||
printk(KERN_INFO "%s: 3c523 adapter found in slot %d\n", dev->name, slot + 1);
|
||||
pr_info("%s: 3c523 adapter found in slot %d\n", dev->name, slot + 1);
|
||||
|
||||
/* Now we extract configuration info from the card.
|
||||
The 3c523 provides information in two of the POS registers, but
|
||||
|
|
@ -507,7 +507,7 @@ static int __init do_elmc_probe(struct net_device *dev)
|
|||
memset(pr, 0, sizeof(struct priv));
|
||||
pr->slot = slot;
|
||||
|
||||
printk(KERN_INFO "%s: 3Com 3c523 Rev 0x%x at %#lx\n", dev->name, (int) revision,
|
||||
pr_info("%s: 3Com 3c523 Rev 0x%x at %#lx\n", dev->name, (int) revision,
|
||||
dev->base_addr);
|
||||
|
||||
/* Determine if we're using the on-board transceiver (i.e. coax) or
|
||||
|
|
@ -529,7 +529,7 @@ static int __init do_elmc_probe(struct net_device *dev)
|
|||
|
||||
size = 0x4000; /* check for 16K mem */
|
||||
if (!check586(dev, dev->mem_start, size)) {
|
||||
printk(KERN_ERR "%s: memprobe, Can't find memory at 0x%lx!\n", dev->name,
|
||||
pr_err("%s: memprobe, Can't find memory at 0x%lx!\n", dev->name,
|
||||
dev->mem_start);
|
||||
retval = -ENODEV;
|
||||
goto err_out;
|
||||
|
|
@ -546,7 +546,7 @@ static int __init do_elmc_probe(struct net_device *dev)
|
|||
pr->num_recv_buffs = NUM_RECV_BUFFS_16;
|
||||
|
||||
/* dump all the assorted information */
|
||||
printk(KERN_INFO "%s: IRQ %d, %sternal xcvr, memory %#lx-%#lx.\n", dev->name,
|
||||
pr_info("%s: IRQ %d, %sternal xcvr, memory %#lx-%#lx.\n", dev->name,
|
||||
dev->irq, dev->if_port ? "ex" : "in",
|
||||
dev->mem_start, dev->mem_end - 1);
|
||||
|
||||
|
|
@ -555,7 +555,7 @@ static int __init do_elmc_probe(struct net_device *dev)
|
|||
for (i = 0; i < 6; i++)
|
||||
dev->dev_addr[i] = inb(dev->base_addr + i);
|
||||
|
||||
printk(KERN_INFO "%s: hardware address %pM\n",
|
||||
pr_info("%s: hardware address %pM\n",
|
||||
dev->name, dev->dev_addr);
|
||||
|
||||
dev->netdev_ops = &netdev_ops;
|
||||
|
|
@ -660,7 +660,7 @@ static int init586(struct net_device *dev)
|
|||
}
|
||||
|
||||
if ((cfg_cmd->cmd_status & (STAT_OK | STAT_COMPL)) != (STAT_COMPL | STAT_OK)) {
|
||||
printk(KERN_WARNING "%s (elmc): configure command failed: %x\n", dev->name, cfg_cmd->cmd_status);
|
||||
pr_warning("%s (elmc): configure command failed: %x\n", dev->name, cfg_cmd->cmd_status);
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
|
|
@ -686,7 +686,8 @@ static int init586(struct net_device *dev)
|
|||
}
|
||||
|
||||
if ((ias_cmd->cmd_status & (STAT_OK | STAT_COMPL)) != (STAT_OK | STAT_COMPL)) {
|
||||
printk(KERN_WARNING "%s (elmc): individual address setup command failed: %04x\n", dev->name, ias_cmd->cmd_status);
|
||||
pr_warning("%s (elmc): individual address setup command failed: %04x\n",
|
||||
dev->name, ias_cmd->cmd_status);
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
|
|
@ -707,7 +708,7 @@ static int init586(struct net_device *dev)
|
|||
s = jiffies;
|
||||
while (!(tdr_cmd->cmd_status & STAT_COMPL)) {
|
||||
if (time_after(jiffies, s + 30*HZ/100)) {
|
||||
printk(KERN_WARNING "%s: %d Problems while running the TDR.\n", dev->name, __LINE__);
|
||||
pr_warning("%s: %d Problems while running the TDR.\n", dev->name, __LINE__);
|
||||
result = 1;
|
||||
break;
|
||||
}
|
||||
|
|
@ -723,14 +724,14 @@ static int init586(struct net_device *dev)
|
|||
if (result & TDR_LNK_OK) {
|
||||
/* empty */
|
||||
} else if (result & TDR_XCVR_PRB) {
|
||||
printk(KERN_WARNING "%s: TDR: Transceiver problem!\n", dev->name);
|
||||
pr_warning("%s: TDR: Transceiver problem!\n", dev->name);
|
||||
} else if (result & TDR_ET_OPN) {
|
||||
printk(KERN_WARNING "%s: TDR: No correct termination %d clocks away.\n", dev->name, result & TDR_TIMEMASK);
|
||||
pr_warning("%s: TDR: No correct termination %d clocks away.\n", dev->name, result & TDR_TIMEMASK);
|
||||
} else if (result & TDR_ET_SRT) {
|
||||
if (result & TDR_TIMEMASK) /* time == 0 -> strange :-) */
|
||||
printk(KERN_WARNING "%s: TDR: Detected a short circuit %d clocks away.\n", dev->name, result & TDR_TIMEMASK);
|
||||
pr_warning("%s: TDR: Detected a short circuit %d clocks away.\n", dev->name, result & TDR_TIMEMASK);
|
||||
} else {
|
||||
printk(KERN_WARNING "%s: TDR: Unknown status %04x\n", dev->name, result);
|
||||
pr_warning("%s: TDR: Unknown status %04x\n", dev->name, result);
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
|
@ -774,11 +775,11 @@ static int init586(struct net_device *dev)
|
|||
/* I don't understand this: do we really need memory after the init? */
|
||||
int len = ((char *) p->iscp - (char *) ptr - 8) / 6;
|
||||
if (len <= 0) {
|
||||
printk(KERN_ERR "%s: Ooooops, no memory for MC-Setup!\n", dev->name);
|
||||
pr_err("%s: Ooooops, no memory for MC-Setup!\n", dev->name);
|
||||
} else {
|
||||
if (len < num_addrs) {
|
||||
num_addrs = len;
|
||||
printk(KERN_WARNING "%s: Sorry, can only apply %d MC-Address(es).\n",
|
||||
pr_warning("%s: Sorry, can only apply %d MC-Address(es).\n",
|
||||
dev->name, num_addrs);
|
||||
}
|
||||
mc_cmd = (struct mcsetup_cmd_struct *) ptr;
|
||||
|
|
@ -799,7 +800,7 @@ static int init586(struct net_device *dev)
|
|||
break;
|
||||
}
|
||||
if (!(mc_cmd->cmd_status & STAT_COMPL)) {
|
||||
printk(KERN_WARNING "%s: Can't apply multicast-address-list.\n", dev->name);
|
||||
pr_warning("%s: Can't apply multicast-address-list.\n", dev->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -812,7 +813,7 @@ static int init586(struct net_device *dev)
|
|||
p->xmit_buffs[i] = (struct tbd_struct *) ptr; /* TBD */
|
||||
ptr = (char *) ptr + sizeof(struct tbd_struct);
|
||||
if ((void *) ptr > (void *) p->iscp) {
|
||||
printk(KERN_ERR "%s: not enough shared-mem for your configuration!\n", dev->name);
|
||||
pr_err("%s: not enough shared-mem for your configuration!\n", dev->name);
|
||||
return 1;
|
||||
}
|
||||
memset((char *) (p->xmit_cmds[i]), 0, sizeof(struct transmit_cmd_struct));
|
||||
|
|
@ -936,7 +937,8 @@ elmc_interrupt(int irq, void *dev_id)
|
|||
if (stat & STAT_CNA) {
|
||||
/* CU went 'not ready' */
|
||||
if (netif_running(dev)) {
|
||||
printk(KERN_WARNING "%s: oops! CU has left active state. stat: %04x/%04x.\n", dev->name, (int) stat, (int) p->scb->status);
|
||||
pr_warning("%s: oops! CU has left active state. stat: %04x/%04x.\n",
|
||||
dev->name, (int) stat, (int) p->scb->status);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -951,7 +953,8 @@ elmc_interrupt(int irq, void *dev_id)
|
|||
p->scb->cmd = RUC_RESUME;
|
||||
elmc_attn586();
|
||||
} else {
|
||||
printk(KERN_WARNING "%s: Receiver-Unit went 'NOT READY': %04x/%04x.\n", dev->name, (int) stat, (int) p->scb->status);
|
||||
pr_warning("%s: Receiver-Unit went 'NOT READY': %04x/%04x.\n",
|
||||
dev->name, (int) stat, (int) p->scb->status);
|
||||
elmc_rnr_int(dev);
|
||||
}
|
||||
}
|
||||
|
|
@ -995,11 +998,11 @@ static void elmc_rcv_int(struct net_device *dev)
|
|||
dev->stats.rx_dropped++;
|
||||
}
|
||||
} else {
|
||||
printk(KERN_WARNING "%s: received oversized frame.\n", dev->name);
|
||||
pr_warning("%s: received oversized frame.\n", dev->name);
|
||||
dev->stats.rx_dropped++;
|
||||
}
|
||||
} else { /* frame !(ok), only with 'save-bad-frames' */
|
||||
printk(KERN_WARNING "%s: oops! rfd-error-status: %04x\n", dev->name, status);
|
||||
pr_warning("%s: oops! rfd-error-status: %04x\n", dev->name, status);
|
||||
dev->stats.rx_errors++;
|
||||
}
|
||||
p->rfd_top->status = 0;
|
||||
|
|
@ -1028,7 +1031,7 @@ static void elmc_rnr_int(struct net_device *dev)
|
|||
alloc_rfa(dev, (char *) p->rfd_first);
|
||||
startrecv586(dev); /* restart RU */
|
||||
|
||||
printk(KERN_WARNING "%s: Receive-Unit restarted. Status: %04x\n", dev->name, p->scb->status);
|
||||
pr_warning("%s: Receive-Unit restarted. Status: %04x\n", dev->name, p->scb->status);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1043,7 +1046,7 @@ static void elmc_xmt_int(struct net_device *dev)
|
|||
|
||||
status = p->xmit_cmds[p->xmit_last]->cmd_status;
|
||||
if (!(status & STAT_COMPL)) {
|
||||
printk(KERN_WARNING "%s: strange .. xmit-int without a 'COMPLETE'\n", dev->name);
|
||||
pr_warning("%s: strange .. xmit-int without a 'COMPLETE'\n", dev->name);
|
||||
}
|
||||
if (status & STAT_OK) {
|
||||
dev->stats.tx_packets++;
|
||||
|
|
@ -1051,18 +1054,18 @@ static void elmc_xmt_int(struct net_device *dev)
|
|||
} else {
|
||||
dev->stats.tx_errors++;
|
||||
if (status & TCMD_LATECOLL) {
|
||||
printk(KERN_WARNING "%s: late collision detected.\n", dev->name);
|
||||
pr_warning("%s: late collision detected.\n", dev->name);
|
||||
dev->stats.collisions++;
|
||||
} else if (status & TCMD_NOCARRIER) {
|
||||
dev->stats.tx_carrier_errors++;
|
||||
printk(KERN_WARNING "%s: no carrier detected.\n", dev->name);
|
||||
pr_warning("%s: no carrier detected.\n", dev->name);
|
||||
} else if (status & TCMD_LOSTCTS) {
|
||||
printk(KERN_WARNING "%s: loss of CTS detected.\n", dev->name);
|
||||
pr_warning("%s: loss of CTS detected.\n", dev->name);
|
||||
} else if (status & TCMD_UNDERRUN) {
|
||||
dev->stats.tx_fifo_errors++;
|
||||
printk(KERN_WARNING "%s: DMA underrun detected.\n", dev->name);
|
||||
pr_warning("%s: DMA underrun detected.\n", dev->name);
|
||||
} else if (status & TCMD_MAXCOLL) {
|
||||
printk(KERN_WARNING "%s: Max. collisions exceeded.\n", dev->name);
|
||||
pr_warning("%s: Max. collisions exceeded.\n", dev->name);
|
||||
dev->stats.collisions += 16;
|
||||
}
|
||||
}
|
||||
|
|
@ -1099,10 +1102,11 @@ static void elmc_timeout(struct net_device *dev)
|
|||
struct priv *p = netdev_priv(dev);
|
||||
/* COMMAND-UNIT active? */
|
||||
if (p->scb->status & CU_ACTIVE) {
|
||||
#ifdef DEBUG
|
||||
printk("%s: strange ... timeout with CU active?!?\n", dev->name);
|
||||
printk("%s: X0: %04x N0: %04x N1: %04x %d\n", dev->name, (int) p->xmit_cmds[0]->cmd_status, (int) p->nop_cmds[0]->cmd_status, (int) p->nop_cmds[1]->cmd_status, (int) p->nop_point);
|
||||
#endif
|
||||
pr_debug("%s: strange ... timeout with CU active?!?\n", dev->name);
|
||||
pr_debug("%s: X0: %04x N0: %04x N1: %04x %d\n", dev->name,
|
||||
(int)p->xmit_cmds[0]->cmd_status,
|
||||
(int)p->nop_cmds[0]->cmd_status,
|
||||
(int)p->nop_cmds[1]->cmd_status, (int)p->nop_point);
|
||||
p->scb->cmd = CUC_ABORT;
|
||||
elmc_attn586();
|
||||
WAIT_4_SCB_CMD();
|
||||
|
|
@ -1112,10 +1116,10 @@ static void elmc_timeout(struct net_device *dev)
|
|||
WAIT_4_SCB_CMD();
|
||||
netif_wake_queue(dev);
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
printk("%s: xmitter timed out, try to restart! stat: %04x\n", dev->name, p->scb->status);
|
||||
printk("%s: command-stats: %04x %04x\n", dev->name, p->xmit_cmds[0]->cmd_status, p->xmit_cmds[1]->cmd_status);
|
||||
#endif
|
||||
pr_debug("%s: xmitter timed out, try to restart! stat: %04x\n",
|
||||
dev->name, p->scb->status);
|
||||
pr_debug("%s: command-stats: %04x %04x\n", dev->name,
|
||||
p->xmit_cmds[0]->cmd_status, p->xmit_cmds[1]->cmd_status);
|
||||
elmc_close(dev);
|
||||
elmc_open(dev);
|
||||
}
|
||||
|
|
@ -1162,7 +1166,7 @@ static int elmc_send_packet(struct sk_buff *skb, struct net_device *dev)
|
|||
break;
|
||||
}
|
||||
if (i == 15) {
|
||||
printk(KERN_WARNING "%s: Can't start transmit-command.\n", dev->name);
|
||||
pr_warning("%s: Can't start transmit-command.\n", dev->name);
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
|
@ -1287,11 +1291,12 @@ int __init init_module(void)
|
|||
free_netdev(dev);
|
||||
if (io[this_dev]==0)
|
||||
break;
|
||||
printk(KERN_WARNING "3c523.c: No 3c523 card found at io=%#x\n",io[this_dev]);
|
||||
pr_warning("3c523.c: No 3c523 card found at io=%#x\n",io[this_dev]);
|
||||
}
|
||||
|
||||
if(found==0) {
|
||||
if(io[0]==0) printk(KERN_NOTICE "3c523.c: No 3c523 cards found\n");
|
||||
if (io[0]==0)
|
||||
pr_notice("3c523.c: No 3c523 cards found\n");
|
||||
return -ENXIO;
|
||||
} else return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -125,8 +125,6 @@ static const char* cardname = DRV_NAME;
|
|||
#define NET_DEBUG 2
|
||||
#endif
|
||||
|
||||
#undef DEBUG_IRQ
|
||||
|
||||
static unsigned int mc32_debug = NET_DEBUG;
|
||||
|
||||
/* The number of low I/O ports used by the ethercard. */
|
||||
|
|
@ -351,15 +349,15 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
|
|||
/* Time to play MCA games */
|
||||
|
||||
if (mc32_debug && version_printed++ == 0)
|
||||
printk(KERN_DEBUG "%s", version);
|
||||
pr_debug("%s", version);
|
||||
|
||||
printk(KERN_INFO "%s: %s found in slot %d:", dev->name, cardname, slot);
|
||||
pr_info("%s: %s found in slot %d: ", dev->name, cardname, slot);
|
||||
|
||||
POS = mca_read_stored_pos(slot, 2);
|
||||
|
||||
if(!(POS&1))
|
||||
{
|
||||
printk(" disabled.\n");
|
||||
pr_cont("disabled.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
|
@ -370,7 +368,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
|
|||
POS = mca_read_stored_pos(slot, 4);
|
||||
if(!(POS&1))
|
||||
{
|
||||
printk("memory window disabled.\n");
|
||||
pr_cont("memory window disabled.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
|
@ -379,7 +377,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
|
|||
i=(POS>>4)&3;
|
||||
if(i==3)
|
||||
{
|
||||
printk("invalid memory window.\n");
|
||||
pr_cont("invalid memory window.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
|
@ -392,11 +390,11 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
|
|||
|
||||
if(!request_region(dev->base_addr, MC32_IO_EXTENT, cardname))
|
||||
{
|
||||
printk("io 0x%3lX, which is busy.\n", dev->base_addr);
|
||||
pr_cont("io 0x%3lX, which is busy.\n", dev->base_addr);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
printk("io 0x%3lX irq %d mem 0x%lX (%dK)\n",
|
||||
pr_cont("io 0x%3lX irq %d mem 0x%lX (%dK)\n",
|
||||
dev->base_addr, dev->irq, dev->mem_start, i/1024);
|
||||
|
||||
|
||||
|
|
@ -416,7 +414,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
|
|||
dev->dev_addr[i] = mca_read_pos(slot,3);
|
||||
}
|
||||
|
||||
printk("%s: Address %pM", dev->name, dev->dev_addr);
|
||||
pr_info("%s: Address %pM ", dev->name, dev->dev_addr);
|
||||
|
||||
mca_write_pos(slot, 6, 0);
|
||||
mca_write_pos(slot, 7, 0);
|
||||
|
|
@ -424,9 +422,9 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
|
|||
POS = mca_read_stored_pos(slot, 4);
|
||||
|
||||
if(POS&2)
|
||||
printk(" : BNC port selected.\n");
|
||||
pr_cont(": BNC port selected.\n");
|
||||
else
|
||||
printk(" : AUI port selected.\n");
|
||||
pr_cont(": AUI port selected.\n");
|
||||
|
||||
POS=inb(dev->base_addr+HOST_CTRL);
|
||||
POS|=HOST_CTRL_ATTN|HOST_CTRL_RESET;
|
||||
|
|
@ -447,7 +445,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
|
|||
err = request_irq(dev->irq, &mc32_interrupt, IRQF_SHARED | IRQF_SAMPLE_RANDOM, DRV_NAME, dev);
|
||||
if (err) {
|
||||
release_region(dev->base_addr, MC32_IO_EXTENT);
|
||||
printk(KERN_ERR "%s: unable to get IRQ %d.\n", DRV_NAME, dev->irq);
|
||||
pr_err("%s: unable to get IRQ %d.\n", DRV_NAME, dev->irq);
|
||||
goto err_exit_ports;
|
||||
}
|
||||
|
||||
|
|
@ -463,7 +461,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
|
|||
i++;
|
||||
if(i == 1000)
|
||||
{
|
||||
printk(KERN_ERR "%s: failed to boot adapter.\n", dev->name);
|
||||
pr_err("%s: failed to boot adapter.\n", dev->name);
|
||||
err = -ENODEV;
|
||||
goto err_exit_irq;
|
||||
}
|
||||
|
|
@ -475,10 +473,10 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
|
|||
if(base>0)
|
||||
{
|
||||
if(base < 0x0C)
|
||||
printk(KERN_ERR "%s: %s%s.\n", dev->name, failures[base-1],
|
||||
pr_err("%s: %s%s.\n", dev->name, failures[base-1],
|
||||
base<0x0A?" test failure":"");
|
||||
else
|
||||
printk(KERN_ERR "%s: unknown failure %d.\n", dev->name, base);
|
||||
pr_err("%s: unknown failure %d.\n", dev->name, base);
|
||||
err = -ENODEV;
|
||||
goto err_exit_irq;
|
||||
}
|
||||
|
|
@ -494,7 +492,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
|
|||
udelay(50);
|
||||
if(n>100)
|
||||
{
|
||||
printk(KERN_ERR "%s: mailbox read fail (%d).\n", dev->name, i);
|
||||
pr_err("%s: mailbox read fail (%d).\n", dev->name, i);
|
||||
err = -ENODEV;
|
||||
goto err_exit_irq;
|
||||
}
|
||||
|
|
@ -527,7 +525,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
|
|||
init_completion(&lp->execution_cmd);
|
||||
init_completion(&lp->xceiver_cmd);
|
||||
|
||||
printk("%s: Firmware Rev %d. %d RX buffers, %d TX buffers. Base of 0x%08X.\n",
|
||||
pr_info("%s: Firmware Rev %d. %d RX buffers, %d TX buffers. Base of 0x%08X.\n",
|
||||
dev->name, lp->exec_box->data[12], lp->rx_len, lp->tx_len, lp->base);
|
||||
|
||||
dev->netdev_ops = &netdev_ops;
|
||||
|
|
@ -939,7 +937,7 @@ static int mc32_open(struct net_device *dev)
|
|||
*/
|
||||
|
||||
if(mc32_command(dev, 8, descnumbuffs, 4)) {
|
||||
printk("%s: %s rejected our buffer configuration!\n",
|
||||
pr_info("%s: %s rejected our buffer configuration!\n",
|
||||
dev->name, cardname);
|
||||
mc32_close(dev);
|
||||
return -ENOBUFS;
|
||||
|
|
@ -995,7 +993,7 @@ static int mc32_open(struct net_device *dev)
|
|||
|
||||
static void mc32_timeout(struct net_device *dev)
|
||||
{
|
||||
printk(KERN_WARNING "%s: transmit timed out?\n", dev->name);
|
||||
pr_warning("%s: transmit timed out?\n", dev->name);
|
||||
/* Try to restart the adaptor. */
|
||||
netif_wake_queue(dev);
|
||||
}
|
||||
|
|
@ -1032,7 +1030,7 @@ static int mc32_send_packet(struct sk_buff *skb, struct net_device *dev)
|
|||
netif_stop_queue(dev);
|
||||
|
||||
if(atomic_read(&lp->tx_count)==0) {
|
||||
return 1;
|
||||
return NETDEV_TX_BUSY;
|
||||
}
|
||||
|
||||
if (skb_padto(skb, ETH_ZLEN)) {
|
||||
|
|
@ -1335,11 +1333,9 @@ static irqreturn_t mc32_interrupt(int irq, void *dev_id)
|
|||
{
|
||||
status=inb(ioaddr+HOST_CMD);
|
||||
|
||||
#ifdef DEBUG_IRQ
|
||||
printk("Status TX%d RX%d EX%d OV%d BC%d\n",
|
||||
pr_debug("Status TX%d RX%d EX%d OV%d BC%d\n",
|
||||
(status&7), (status>>3)&7, (status>>6)&1,
|
||||
(status>>7)&1, boguscount);
|
||||
#endif
|
||||
|
||||
switch(status&7)
|
||||
{
|
||||
|
|
@ -1354,7 +1350,7 @@ static irqreturn_t mc32_interrupt(int irq, void *dev_id)
|
|||
complete(&lp->xceiver_cmd);
|
||||
break;
|
||||
default:
|
||||
printk("%s: strange tx ack %d\n", dev->name, status&7);
|
||||
pr_notice("%s: strange tx ack %d\n", dev->name, status&7);
|
||||
}
|
||||
status>>=3;
|
||||
switch(status&7)
|
||||
|
|
@ -1376,7 +1372,7 @@ static irqreturn_t mc32_interrupt(int irq, void *dev_id)
|
|||
mc32_start_transceiver(dev);
|
||||
break;
|
||||
default:
|
||||
printk("%s: strange rx ack %d\n",
|
||||
pr_notice("%s: strange rx ack %d\n",
|
||||
dev->name, status&7);
|
||||
}
|
||||
status>>=3;
|
||||
|
|
|
|||
|
|
@ -828,14 +828,14 @@ static int vortex_resume(struct pci_dev *pdev)
|
|||
pci_restore_state(pdev);
|
||||
err = pci_enable_device(pdev);
|
||||
if (err) {
|
||||
printk(KERN_WARNING "%s: Could not enable device \n",
|
||||
pr_warning("%s: Could not enable device\n",
|
||||
dev->name);
|
||||
return err;
|
||||
}
|
||||
pci_set_master(pdev);
|
||||
if (request_irq(dev->irq, vp->full_bus_master_rx ?
|
||||
&boomerang_interrupt : &vortex_interrupt, IRQF_SHARED, dev->name, dev)) {
|
||||
printk(KERN_WARNING "%s: Could not reserve IRQ %d\n", dev->name, dev->irq);
|
||||
pr_warning("%s: Could not reserve IRQ %d\n", dev->name, dev->irq);
|
||||
pci_disable_device(pdev);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
|
@ -894,7 +894,7 @@ static int __devexit vortex_eisa_remove(struct device *device)
|
|||
dev = eisa_get_drvdata(edev);
|
||||
|
||||
if (!dev) {
|
||||
printk("vortex_eisa_remove called for Compaq device!\n");
|
||||
pr_err("vortex_eisa_remove called for Compaq device!\n");
|
||||
BUG();
|
||||
}
|
||||
|
||||
|
|
@ -1051,7 +1051,7 @@ static int __devinit vortex_probe1(struct device *gendev,
|
|||
struct eisa_device *edev = NULL;
|
||||
|
||||
if (!printed_version) {
|
||||
printk (version);
|
||||
pr_info("%s", version);
|
||||
printed_version = 1;
|
||||
}
|
||||
|
||||
|
|
@ -1068,7 +1068,7 @@ static int __devinit vortex_probe1(struct device *gendev,
|
|||
dev = alloc_etherdev(sizeof(*vp));
|
||||
retval = -ENOMEM;
|
||||
if (!dev) {
|
||||
printk (KERN_ERR PFX "unable to allocate etherdev, aborting\n");
|
||||
pr_err(PFX "unable to allocate etherdev, aborting\n");
|
||||
goto out;
|
||||
}
|
||||
SET_NETDEV_DEV(dev, gendev);
|
||||
|
|
@ -1100,9 +1100,9 @@ static int __devinit vortex_probe1(struct device *gendev,
|
|||
|
||||
print_info = (vortex_debug > 1);
|
||||
if (print_info)
|
||||
printk (KERN_INFO "See Documentation/networking/vortex.txt\n");
|
||||
pr_info("See Documentation/networking/vortex.txt\n");
|
||||
|
||||
printk(KERN_INFO "%s: 3Com %s %s at %p.\n",
|
||||
pr_info("%s: 3Com %s %s at %p.\n",
|
||||
print_name,
|
||||
pdev ? "PCI" : "EISA",
|
||||
vci->name,
|
||||
|
|
@ -1144,10 +1144,9 @@ static int __devinit vortex_probe1(struct device *gendev,
|
|||
chip only. */
|
||||
pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency);
|
||||
if (pci_latency < new_latency) {
|
||||
printk(KERN_INFO "%s: Overriding PCI latency"
|
||||
" timer (CFLT) setting of %d, new value is %d.\n",
|
||||
pr_info("%s: Overriding PCI latency timer (CFLT) setting of %d, new value is %d.\n",
|
||||
print_name, pci_latency, new_latency);
|
||||
pci_write_config_byte(pdev, PCI_LATENCY_TIMER, new_latency);
|
||||
pci_write_config_byte(pdev, PCI_LATENCY_TIMER, new_latency);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1236,17 +1235,17 @@ static int __devinit vortex_probe1(struct device *gendev,
|
|||
checksum = (checksum ^ (checksum >> 8)) & 0xff;
|
||||
}
|
||||
if ((checksum != 0x00) && !(vci->drv_flags & IS_TORNADO))
|
||||
printk(" ***INVALID CHECKSUM %4.4x*** ", checksum);
|
||||
pr_cont(" ***INVALID CHECKSUM %4.4x*** ", checksum);
|
||||
for (i = 0; i < 3; i++)
|
||||
((__be16 *)dev->dev_addr)[i] = htons(eeprom[i + 10]);
|
||||
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
|
||||
if (print_info)
|
||||
printk(" %pM", dev->dev_addr);
|
||||
pr_cont(" %pM", dev->dev_addr);
|
||||
/* Unfortunately an all zero eeprom passes the checksum and this
|
||||
gets found in the wild in failure cases. Crypto is hard 8) */
|
||||
if (!is_valid_ether_addr(dev->dev_addr)) {
|
||||
retval = -EINVAL;
|
||||
printk(KERN_ERR "*** EEPROM MAC address is invalid.\n");
|
||||
pr_err("*** EEPROM MAC address is invalid.\n");
|
||||
goto free_ring; /* With every pack */
|
||||
}
|
||||
EL3WINDOW(2);
|
||||
|
|
@ -1254,17 +1253,17 @@ static int __devinit vortex_probe1(struct device *gendev,
|
|||
iowrite8(dev->dev_addr[i], ioaddr + i);
|
||||
|
||||
if (print_info)
|
||||
printk(", IRQ %d\n", dev->irq);
|
||||
pr_cont(", IRQ %d\n", dev->irq);
|
||||
/* Tell them about an invalid IRQ. */
|
||||
if (dev->irq <= 0 || dev->irq >= nr_irqs)
|
||||
printk(KERN_WARNING " *** Warning: IRQ %d is unlikely to work! ***\n",
|
||||
pr_warning(" *** Warning: IRQ %d is unlikely to work! ***\n",
|
||||
dev->irq);
|
||||
|
||||
EL3WINDOW(4);
|
||||
step = (ioread8(ioaddr + Wn4_NetDiag) & 0x1e) >> 1;
|
||||
if (print_info) {
|
||||
printk(KERN_INFO " product code %02x%02x rev %02x.%d date %02d-"
|
||||
"%02d-%02d\n", eeprom[6]&0xff, eeprom[6]>>8, eeprom[0x14],
|
||||
pr_info(" product code %02x%02x rev %02x.%d date %02d-%02d-%02d\n",
|
||||
eeprom[6]&0xff, eeprom[6]>>8, eeprom[0x14],
|
||||
step, (eeprom[4]>>5) & 15, eeprom[4] & 31, eeprom[4]>>9);
|
||||
}
|
||||
|
||||
|
|
@ -1279,8 +1278,7 @@ static int __devinit vortex_probe1(struct device *gendev,
|
|||
}
|
||||
|
||||
if (print_info) {
|
||||
printk(KERN_INFO "%s: CardBus functions mapped "
|
||||
"%16.16llx->%p\n",
|
||||
pr_info("%s: CardBus functions mapped %16.16llx->%p\n",
|
||||
print_name,
|
||||
(unsigned long long)pci_resource_start(pdev, 2),
|
||||
vp->cb_fn_base);
|
||||
|
|
@ -1307,7 +1305,7 @@ static int __devinit vortex_probe1(struct device *gendev,
|
|||
if (vp->info1 & 0x8000) {
|
||||
vp->full_duplex = 1;
|
||||
if (print_info)
|
||||
printk(KERN_INFO "Full duplex capable\n");
|
||||
pr_info("Full duplex capable\n");
|
||||
}
|
||||
|
||||
{
|
||||
|
|
@ -1319,9 +1317,9 @@ static int __devinit vortex_probe1(struct device *gendev,
|
|||
vp->available_media = 0x40;
|
||||
config = ioread32(ioaddr + Wn3_Config);
|
||||
if (print_info) {
|
||||
printk(KERN_DEBUG " Internal config register is %4.4x, "
|
||||
"transceivers %#x.\n", config, ioread16(ioaddr + Wn3_Options));
|
||||
printk(KERN_INFO " %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
|
||||
pr_debug(" Internal config register is %4.4x, transceivers %#x.\n",
|
||||
config, ioread16(ioaddr + Wn3_Options));
|
||||
pr_info(" %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
|
||||
8 << RAM_SIZE(config),
|
||||
RAM_WIDTH(config) ? "word" : "byte",
|
||||
ram_split[RAM_SPLIT(config)],
|
||||
|
|
@ -1336,7 +1334,7 @@ static int __devinit vortex_probe1(struct device *gendev,
|
|||
}
|
||||
|
||||
if (vp->media_override != 7) {
|
||||
printk(KERN_INFO "%s: Media override to transceiver type %d (%s).\n",
|
||||
pr_info("%s: Media override to transceiver type %d (%s).\n",
|
||||
print_name, vp->media_override,
|
||||
media_tbl[vp->media_override].name);
|
||||
dev->if_port = vp->media_override;
|
||||
|
|
@ -1369,8 +1367,8 @@ static int __devinit vortex_probe1(struct device *gendev,
|
|||
if (mii_status && mii_status != 0xffff) {
|
||||
vp->phys[phy_idx++] = phyx;
|
||||
if (print_info) {
|
||||
printk(KERN_INFO " MII transceiver found at address %d,"
|
||||
" status %4x.\n", phyx, mii_status);
|
||||
pr_info(" MII transceiver found at address %d, status %4x.\n",
|
||||
phyx, mii_status);
|
||||
}
|
||||
if ((mii_status & 0x0040) == 0)
|
||||
mii_preamble_required++;
|
||||
|
|
@ -1378,7 +1376,7 @@ static int __devinit vortex_probe1(struct device *gendev,
|
|||
}
|
||||
mii_preamble_required--;
|
||||
if (phy_idx == 0) {
|
||||
printk(KERN_WARNING" ***WARNING*** No MII transceivers found!\n");
|
||||
pr_warning(" ***WARNING*** No MII transceivers found!\n");
|
||||
vp->phys[0] = 24;
|
||||
} else {
|
||||
vp->advertising = mdio_read(dev, vp->phys[0], MII_ADVERTISE);
|
||||
|
|
@ -1394,7 +1392,7 @@ static int __devinit vortex_probe1(struct device *gendev,
|
|||
if (vp->capabilities & CapBusMaster) {
|
||||
vp->full_bus_master_tx = 1;
|
||||
if (print_info) {
|
||||
printk(KERN_INFO " Enabling bus-master transmits and %s receives.\n",
|
||||
pr_info(" Enabling bus-master transmits and %s receives.\n",
|
||||
(vp->info2 & 1) ? "early" : "whole-frame" );
|
||||
}
|
||||
vp->full_bus_master_rx = (vp->info2 & 1) ? 1 : 2;
|
||||
|
|
@ -1414,7 +1412,7 @@ static int __devinit vortex_probe1(struct device *gendev,
|
|||
dev->netdev_ops = &vortex_netdev_ops;
|
||||
|
||||
if (print_info) {
|
||||
printk(KERN_INFO "%s: scatter/gather %sabled. h/w checksums %sabled\n",
|
||||
pr_info("%s: scatter/gather %sabled. h/w checksums %sabled\n",
|
||||
print_name,
|
||||
(dev->features & NETIF_F_SG) ? "en":"dis",
|
||||
(dev->features & NETIF_F_IP_CSUM) ? "en":"dis");
|
||||
|
|
@ -1442,7 +1440,7 @@ free_region:
|
|||
if (vp->must_free_region)
|
||||
release_region(dev->base_addr, vci->io_size);
|
||||
free_netdev(dev);
|
||||
printk(KERN_ERR PFX "vortex_probe1 fails. Returns %d\n", retval);
|
||||
pr_err(PFX "vortex_probe1 fails. Returns %d\n", retval);
|
||||
out:
|
||||
return retval;
|
||||
}
|
||||
|
|
@ -1464,13 +1462,13 @@ issue_and_wait(struct net_device *dev, int cmd)
|
|||
for (i = 0; i < 100000; i++) {
|
||||
if (!(ioread16(ioaddr + EL3_STATUS) & CmdInProgress)) {
|
||||
if (vortex_debug > 1)
|
||||
printk(KERN_INFO "%s: command 0x%04x took %d usecs\n",
|
||||
pr_info("%s: command 0x%04x took %d usecs\n",
|
||||
dev->name, cmd, i * 10);
|
||||
return;
|
||||
}
|
||||
udelay(10);
|
||||
}
|
||||
printk(KERN_ERR "%s: command 0x%04x did not complete! Status=0x%x\n",
|
||||
pr_err("%s: command 0x%04x did not complete! Status=0x%x\n",
|
||||
dev->name, cmd, ioread16(ioaddr + EL3_STATUS));
|
||||
}
|
||||
|
||||
|
|
@ -1480,7 +1478,7 @@ vortex_set_duplex(struct net_device *dev)
|
|||
struct vortex_private *vp = netdev_priv(dev);
|
||||
void __iomem *ioaddr = vp->ioaddr;
|
||||
|
||||
printk(KERN_INFO "%s: setting %s-duplex.\n",
|
||||
pr_info("%s: setting %s-duplex.\n",
|
||||
dev->name, (vp->full_duplex) ? "full" : "half");
|
||||
|
||||
EL3WINDOW(3);
|
||||
|
|
@ -1522,7 +1520,7 @@ vortex_up(struct net_device *dev)
|
|||
pci_restore_state(VORTEX_PCI(vp));
|
||||
err = pci_enable_device(VORTEX_PCI(vp));
|
||||
if (err) {
|
||||
printk(KERN_WARNING "%s: Could not enable device \n",
|
||||
pr_warning("%s: Could not enable device\n",
|
||||
dev->name);
|
||||
goto err_out;
|
||||
}
|
||||
|
|
@ -1533,14 +1531,14 @@ vortex_up(struct net_device *dev)
|
|||
config = ioread32(ioaddr + Wn3_Config);
|
||||
|
||||
if (vp->media_override != 7) {
|
||||
printk(KERN_INFO "%s: Media override to transceiver %d (%s).\n",
|
||||
pr_info("%s: Media override to transceiver %d (%s).\n",
|
||||
dev->name, vp->media_override,
|
||||
media_tbl[vp->media_override].name);
|
||||
dev->if_port = vp->media_override;
|
||||
} else if (vp->autoselect) {
|
||||
if (vp->has_nway) {
|
||||
if (vortex_debug > 1)
|
||||
printk(KERN_INFO "%s: using NWAY device table, not %d\n",
|
||||
pr_info("%s: using NWAY device table, not %d\n",
|
||||
dev->name, dev->if_port);
|
||||
dev->if_port = XCVR_NWAY;
|
||||
} else {
|
||||
|
|
@ -1549,13 +1547,13 @@ vortex_up(struct net_device *dev)
|
|||
while (! (vp->available_media & media_tbl[dev->if_port].mask))
|
||||
dev->if_port = media_tbl[dev->if_port].next;
|
||||
if (vortex_debug > 1)
|
||||
printk(KERN_INFO "%s: first available media type: %s\n",
|
||||
pr_info("%s: first available media type: %s\n",
|
||||
dev->name, media_tbl[dev->if_port].name);
|
||||
}
|
||||
} else {
|
||||
dev->if_port = vp->default_media;
|
||||
if (vortex_debug > 1)
|
||||
printk(KERN_INFO "%s: using default media %s\n",
|
||||
pr_info("%s: using default media %s\n",
|
||||
dev->name, media_tbl[dev->if_port].name);
|
||||
}
|
||||
|
||||
|
|
@ -1570,13 +1568,13 @@ vortex_up(struct net_device *dev)
|
|||
vp->rx_oom_timer.function = rx_oom_timer;
|
||||
|
||||
if (vortex_debug > 1)
|
||||
printk(KERN_DEBUG "%s: Initial media type %s.\n",
|
||||
pr_debug("%s: Initial media type %s.\n",
|
||||
dev->name, media_tbl[dev->if_port].name);
|
||||
|
||||
vp->full_duplex = vp->mii.force_media;
|
||||
config = BFINS(config, dev->if_port, 20, 4);
|
||||
if (vortex_debug > 6)
|
||||
printk(KERN_DEBUG "vortex_up(): writing 0x%x to InternalConfig\n", config);
|
||||
pr_debug("vortex_up(): writing 0x%x to InternalConfig\n", config);
|
||||
iowrite32(config, ioaddr + Wn3_Config);
|
||||
|
||||
if (dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) {
|
||||
|
|
@ -1602,7 +1600,7 @@ vortex_up(struct net_device *dev)
|
|||
|
||||
if (vortex_debug > 1) {
|
||||
EL3WINDOW(4);
|
||||
printk(KERN_DEBUG "%s: vortex_up() irq %d media status %4.4x.\n",
|
||||
pr_debug("%s: vortex_up() irq %d media status %4.4x.\n",
|
||||
dev->name, dev->irq, ioread16(ioaddr + Wn4_Media));
|
||||
}
|
||||
|
||||
|
|
@ -1704,13 +1702,13 @@ vortex_open(struct net_device *dev)
|
|||
/* Use the now-standard shared IRQ implementation. */
|
||||
if ((retval = request_irq(dev->irq, vp->full_bus_master_rx ?
|
||||
&boomerang_interrupt : &vortex_interrupt, IRQF_SHARED, dev->name, dev))) {
|
||||
printk(KERN_ERR "%s: Could not reserve IRQ %d\n", dev->name, dev->irq);
|
||||
pr_err("%s: Could not reserve IRQ %d\n", dev->name, dev->irq);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (vp->full_bus_master_rx) { /* Boomerang bus master. */
|
||||
if (vortex_debug > 2)
|
||||
printk(KERN_DEBUG "%s: Filling in the Rx ring.\n", dev->name);
|
||||
pr_debug("%s: Filling in the Rx ring.\n", dev->name);
|
||||
for (i = 0; i < RX_RING_SIZE; i++) {
|
||||
struct sk_buff *skb;
|
||||
vp->rx_ring[i].next = cpu_to_le32(vp->rx_ring_dma + sizeof(struct boom_rx_desc) * (i+1));
|
||||
|
|
@ -1728,7 +1726,7 @@ vortex_open(struct net_device *dev)
|
|||
}
|
||||
if (i != RX_RING_SIZE) {
|
||||
int j;
|
||||
printk(KERN_EMERG "%s: no memory for rx ring\n", dev->name);
|
||||
pr_emerg("%s: no memory for rx ring\n", dev->name);
|
||||
for (j = 0; j < i; j++) {
|
||||
if (vp->rx_skbuff[j]) {
|
||||
dev_kfree_skb(vp->rx_skbuff[j]);
|
||||
|
|
@ -1750,7 +1748,7 @@ err_free_irq:
|
|||
free_irq(dev->irq, dev);
|
||||
err:
|
||||
if (vortex_debug > 1)
|
||||
printk(KERN_ERR "%s: vortex_open() fails: returning %d\n", dev->name, retval);
|
||||
pr_err("%s: vortex_open() fails: returning %d\n", dev->name, retval);
|
||||
out:
|
||||
return retval;
|
||||
}
|
||||
|
|
@ -1766,9 +1764,9 @@ vortex_timer(unsigned long data)
|
|||
int media_status, old_window;
|
||||
|
||||
if (vortex_debug > 2) {
|
||||
printk(KERN_DEBUG "%s: Media selection timer tick happened, %s.\n",
|
||||
pr_debug("%s: Media selection timer tick happened, %s.\n",
|
||||
dev->name, media_tbl[dev->if_port].name);
|
||||
printk(KERN_DEBUG "dev->watchdog_timeo=%d\n", dev->watchdog_timeo);
|
||||
pr_debug("dev->watchdog_timeo=%d\n", dev->watchdog_timeo);
|
||||
}
|
||||
|
||||
disable_irq_lockdep(dev->irq);
|
||||
|
|
@ -1781,12 +1779,12 @@ vortex_timer(unsigned long data)
|
|||
netif_carrier_on(dev);
|
||||
ok = 1;
|
||||
if (vortex_debug > 1)
|
||||
printk(KERN_DEBUG "%s: Media %s has link beat, %x.\n",
|
||||
pr_debug("%s: Media %s has link beat, %x.\n",
|
||||
dev->name, media_tbl[dev->if_port].name, media_status);
|
||||
} else {
|
||||
netif_carrier_off(dev);
|
||||
if (vortex_debug > 1) {
|
||||
printk(KERN_DEBUG "%s: Media %s has no link beat, %x.\n",
|
||||
pr_debug("%s: Media %s has no link beat, %x.\n",
|
||||
dev->name, media_tbl[dev->if_port].name, media_status);
|
||||
}
|
||||
}
|
||||
|
|
@ -1802,7 +1800,7 @@ vortex_timer(unsigned long data)
|
|||
break;
|
||||
default: /* Other media types handled by Tx timeouts. */
|
||||
if (vortex_debug > 1)
|
||||
printk(KERN_DEBUG "%s: Media %s has no indication, %x.\n",
|
||||
pr_debug("%s: Media %s has no indication, %x.\n",
|
||||
dev->name, media_tbl[dev->if_port].name, media_status);
|
||||
ok = 1;
|
||||
}
|
||||
|
|
@ -1822,13 +1820,11 @@ vortex_timer(unsigned long data)
|
|||
if (dev->if_port == XCVR_Default) { /* Go back to default. */
|
||||
dev->if_port = vp->default_media;
|
||||
if (vortex_debug > 1)
|
||||
printk(KERN_DEBUG "%s: Media selection failing, using default "
|
||||
"%s port.\n",
|
||||
pr_debug("%s: Media selection failing, using default %s port.\n",
|
||||
dev->name, media_tbl[dev->if_port].name);
|
||||
} else {
|
||||
if (vortex_debug > 1)
|
||||
printk(KERN_DEBUG "%s: Media selection failed, now trying "
|
||||
"%s port.\n",
|
||||
pr_debug("%s: Media selection failed, now trying %s port.\n",
|
||||
dev->name, media_tbl[dev->if_port].name);
|
||||
next_tick = media_tbl[dev->if_port].wait;
|
||||
}
|
||||
|
|
@ -1843,13 +1839,13 @@ vortex_timer(unsigned long data)
|
|||
iowrite16(dev->if_port == XCVR_10base2 ? StartCoax : StopCoax,
|
||||
ioaddr + EL3_CMD);
|
||||
if (vortex_debug > 1)
|
||||
printk(KERN_DEBUG "wrote 0x%08x to Wn3_Config\n", config);
|
||||
pr_debug("wrote 0x%08x to Wn3_Config\n", config);
|
||||
/* AKPM: FIXME: Should reset Rx & Tx here. P60 of 3c90xc.pdf */
|
||||
}
|
||||
|
||||
leave_media_alone:
|
||||
if (vortex_debug > 2)
|
||||
printk(KERN_DEBUG "%s: Media selection timer finished, %s.\n",
|
||||
pr_debug("%s: Media selection timer finished, %s.\n",
|
||||
dev->name, media_tbl[dev->if_port].name);
|
||||
|
||||
EL3WINDOW(old_window);
|
||||
|
|
@ -1865,21 +1861,21 @@ static void vortex_tx_timeout(struct net_device *dev)
|
|||
struct vortex_private *vp = netdev_priv(dev);
|
||||
void __iomem *ioaddr = vp->ioaddr;
|
||||
|
||||
printk(KERN_ERR "%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
|
||||
pr_err("%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
|
||||
dev->name, ioread8(ioaddr + TxStatus),
|
||||
ioread16(ioaddr + EL3_STATUS));
|
||||
EL3WINDOW(4);
|
||||
printk(KERN_ERR " diagnostics: net %04x media %04x dma %08x fifo %04x\n",
|
||||
pr_err(" diagnostics: net %04x media %04x dma %08x fifo %04x\n",
|
||||
ioread16(ioaddr + Wn4_NetDiag),
|
||||
ioread16(ioaddr + Wn4_Media),
|
||||
ioread32(ioaddr + PktStatus),
|
||||
ioread16(ioaddr + Wn4_FIFODiag));
|
||||
/* Slight code bloat to be user friendly. */
|
||||
if ((ioread8(ioaddr + TxStatus) & 0x88) == 0x88)
|
||||
printk(KERN_ERR "%s: Transmitter encountered 16 collisions --"
|
||||
pr_err("%s: Transmitter encountered 16 collisions --"
|
||||
" network cable problem?\n", dev->name);
|
||||
if (ioread16(ioaddr + EL3_STATUS) & IntLatch) {
|
||||
printk(KERN_ERR "%s: Interrupt posted but not delivered --"
|
||||
pr_err("%s: Interrupt posted but not delivered --"
|
||||
" IRQ blocked by another device?\n", dev->name);
|
||||
/* Bad idea here.. but we might as well handle a few events. */
|
||||
{
|
||||
|
|
@ -1903,7 +1899,7 @@ static void vortex_tx_timeout(struct net_device *dev)
|
|||
|
||||
dev->stats.tx_errors++;
|
||||
if (vp->full_bus_master_tx) {
|
||||
printk(KERN_DEBUG "%s: Resetting the Tx ring pointer.\n", dev->name);
|
||||
pr_debug("%s: Resetting the Tx ring pointer.\n", dev->name);
|
||||
if (vp->cur_tx - vp->dirty_tx > 0 && ioread32(ioaddr + DownListPtr) == 0)
|
||||
iowrite32(vp->tx_ring_dma + (vp->dirty_tx % TX_RING_SIZE) * sizeof(struct boom_tx_desc),
|
||||
ioaddr + DownListPtr);
|
||||
|
|
@ -1938,7 +1934,7 @@ vortex_error(struct net_device *dev, int status)
|
|||
unsigned char tx_status = 0;
|
||||
|
||||
if (vortex_debug > 2) {
|
||||
printk(KERN_ERR "%s: vortex_error(), status=0x%x\n", dev->name, status);
|
||||
pr_err("%s: vortex_error(), status=0x%x\n", dev->name, status);
|
||||
}
|
||||
|
||||
if (status & TxComplete) { /* Really "TxError" for us. */
|
||||
|
|
@ -1946,10 +1942,10 @@ vortex_error(struct net_device *dev, int status)
|
|||
/* Presumably a tx-timeout. We must merely re-enable. */
|
||||
if (vortex_debug > 2
|
||||
|| (tx_status != 0x88 && vortex_debug > 0)) {
|
||||
printk(KERN_ERR "%s: Transmit error, Tx status register %2.2x.\n",
|
||||
pr_err("%s: Transmit error, Tx status register %2.2x.\n",
|
||||
dev->name, tx_status);
|
||||
if (tx_status == 0x82) {
|
||||
printk(KERN_ERR "Probably a duplex mismatch. See "
|
||||
pr_err("Probably a duplex mismatch. See "
|
||||
"Documentation/networking/vortex.txt\n");
|
||||
}
|
||||
dump_tx_ring(dev);
|
||||
|
|
@ -1975,13 +1971,13 @@ vortex_error(struct net_device *dev, int status)
|
|||
if (status & StatsFull) { /* Empty statistics. */
|
||||
static int DoneDidThat;
|
||||
if (vortex_debug > 4)
|
||||
printk(KERN_DEBUG "%s: Updating stats.\n", dev->name);
|
||||
pr_debug("%s: Updating stats.\n", dev->name);
|
||||
update_stats(ioaddr, dev);
|
||||
/* HACK: Disable statistics as an interrupt source. */
|
||||
/* This occurs when we have the wrong media type! */
|
||||
if (DoneDidThat == 0 &&
|
||||
ioread16(ioaddr + EL3_STATUS) & StatsFull) {
|
||||
printk(KERN_WARNING "%s: Updating statistics failed, disabling "
|
||||
pr_warning("%s: Updating statistics failed, disabling "
|
||||
"stats as an interrupt source.\n", dev->name);
|
||||
EL3WINDOW(5);
|
||||
iowrite16(SetIntrEnb | (ioread16(ioaddr + 10) & ~StatsFull), ioaddr + EL3_CMD);
|
||||
|
|
@ -1998,7 +1994,7 @@ vortex_error(struct net_device *dev, int status)
|
|||
u16 fifo_diag;
|
||||
EL3WINDOW(4);
|
||||
fifo_diag = ioread16(ioaddr + Wn4_FIFODiag);
|
||||
printk(KERN_ERR "%s: Host error, FIFO diagnostic register %4.4x.\n",
|
||||
pr_err("%s: Host error, FIFO diagnostic register %4.4x.\n",
|
||||
dev->name, fifo_diag);
|
||||
/* Adapter failure requires Tx/Rx reset and reinit. */
|
||||
if (vp->full_bus_master_tx) {
|
||||
|
|
@ -2006,7 +2002,7 @@ vortex_error(struct net_device *dev, int status)
|
|||
/* 0x80000000 PCI master abort. */
|
||||
/* 0x40000000 PCI target abort. */
|
||||
if (vortex_debug)
|
||||
printk(KERN_ERR "%s: PCI bus error, bus status %8.8x\n", dev->name, bus_status);
|
||||
pr_err("%s: PCI bus error, bus status %8.8x\n", dev->name, bus_status);
|
||||
|
||||
/* In this case, blow the card away */
|
||||
/* Must not enter D3 or we can't legally issue the reset! */
|
||||
|
|
@ -2075,7 +2071,7 @@ vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
while (--i > 0 && (tx_status = ioread8(ioaddr + TxStatus)) > 0) {
|
||||
if (tx_status & 0x3C) { /* A Tx-disabling error occurred. */
|
||||
if (vortex_debug > 2)
|
||||
printk(KERN_DEBUG "%s: Tx error, status %2.2x.\n",
|
||||
pr_debug("%s: Tx error, status %2.2x.\n",
|
||||
dev->name, tx_status);
|
||||
if (tx_status & 0x04) dev->stats.tx_fifo_errors++;
|
||||
if (tx_status & 0x38) dev->stats.tx_aborted_errors++;
|
||||
|
|
@ -2101,17 +2097,17 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
unsigned long flags;
|
||||
|
||||
if (vortex_debug > 6) {
|
||||
printk(KERN_DEBUG "boomerang_start_xmit()\n");
|
||||
printk(KERN_DEBUG "%s: Trying to send a packet, Tx index %d.\n",
|
||||
pr_debug("boomerang_start_xmit()\n");
|
||||
pr_debug("%s: Trying to send a packet, Tx index %d.\n",
|
||||
dev->name, vp->cur_tx);
|
||||
}
|
||||
|
||||
if (vp->cur_tx - vp->dirty_tx >= TX_RING_SIZE) {
|
||||
if (vortex_debug > 0)
|
||||
printk(KERN_WARNING "%s: BUG! Tx Ring full, refusing to send buffer.\n",
|
||||
pr_warning("%s: BUG! Tx Ring full, refusing to send buffer.\n",
|
||||
dev->name);
|
||||
netif_stop_queue(dev);
|
||||
return 1;
|
||||
return NETDEV_TX_BUSY;
|
||||
}
|
||||
|
||||
vp->tx_skbuff[entry] = skb;
|
||||
|
|
@ -2204,7 +2200,7 @@ vortex_interrupt(int irq, void *dev_id)
|
|||
status = ioread16(ioaddr + EL3_STATUS);
|
||||
|
||||
if (vortex_debug > 6)
|
||||
printk("vortex_interrupt(). status=0x%4x\n", status);
|
||||
pr_debug("vortex_interrupt(). status=0x%4x\n", status);
|
||||
|
||||
if ((status & IntLatch) == 0)
|
||||
goto handler_exit; /* No interrupt: shared IRQs cause this */
|
||||
|
|
@ -2219,19 +2215,19 @@ vortex_interrupt(int irq, void *dev_id)
|
|||
goto handler_exit;
|
||||
|
||||
if (vortex_debug > 4)
|
||||
printk(KERN_DEBUG "%s: interrupt, status %4.4x, latency %d ticks.\n",
|
||||
pr_debug("%s: interrupt, status %4.4x, latency %d ticks.\n",
|
||||
dev->name, status, ioread8(ioaddr + Timer));
|
||||
|
||||
do {
|
||||
if (vortex_debug > 5)
|
||||
printk(KERN_DEBUG "%s: In interrupt loop, status %4.4x.\n",
|
||||
pr_debug("%s: In interrupt loop, status %4.4x.\n",
|
||||
dev->name, status);
|
||||
if (status & RxComplete)
|
||||
vortex_rx(dev);
|
||||
|
||||
if (status & TxAvailable) {
|
||||
if (vortex_debug > 5)
|
||||
printk(KERN_DEBUG " TX room bit was handled.\n");
|
||||
pr_debug(" TX room bit was handled.\n");
|
||||
/* There's room in the FIFO for a full-sized packet. */
|
||||
iowrite16(AckIntr | TxAvailable, ioaddr + EL3_CMD);
|
||||
netif_wake_queue (dev);
|
||||
|
|
@ -2263,8 +2259,8 @@ vortex_interrupt(int irq, void *dev_id)
|
|||
}
|
||||
|
||||
if (--work_done < 0) {
|
||||
printk(KERN_WARNING "%s: Too much work in interrupt, status "
|
||||
"%4.4x.\n", dev->name, status);
|
||||
pr_warning("%s: Too much work in interrupt, status %4.4x.\n",
|
||||
dev->name, status);
|
||||
/* Disable all pending interrupts. */
|
||||
do {
|
||||
vp->deferred |= status;
|
||||
|
|
@ -2281,7 +2277,7 @@ vortex_interrupt(int irq, void *dev_id)
|
|||
} while ((status = ioread16(ioaddr + EL3_STATUS)) & (IntLatch | RxComplete));
|
||||
|
||||
if (vortex_debug > 4)
|
||||
printk(KERN_DEBUG "%s: exiting interrupt, status %4.4x.\n",
|
||||
pr_debug("%s: exiting interrupt, status %4.4x.\n",
|
||||
dev->name, status);
|
||||
handler_exit:
|
||||
spin_unlock(&vp->lock);
|
||||
|
|
@ -2313,14 +2309,14 @@ boomerang_interrupt(int irq, void *dev_id)
|
|||
status = ioread16(ioaddr + EL3_STATUS);
|
||||
|
||||
if (vortex_debug > 6)
|
||||
printk(KERN_DEBUG "boomerang_interrupt. status=0x%4x\n", status);
|
||||
pr_debug("boomerang_interrupt. status=0x%4x\n", status);
|
||||
|
||||
if ((status & IntLatch) == 0)
|
||||
goto handler_exit; /* No interrupt: shared IRQs can cause this */
|
||||
|
||||
if (status == 0xffff) { /* h/w no longer present (hotplug)? */
|
||||
if (vortex_debug > 1)
|
||||
printk(KERN_DEBUG "boomerang_interrupt(1): status = 0xffff\n");
|
||||
pr_debug("boomerang_interrupt(1): status = 0xffff\n");
|
||||
goto handler_exit;
|
||||
}
|
||||
|
||||
|
|
@ -2330,16 +2326,16 @@ boomerang_interrupt(int irq, void *dev_id)
|
|||
}
|
||||
|
||||
if (vortex_debug > 4)
|
||||
printk(KERN_DEBUG "%s: interrupt, status %4.4x, latency %d ticks.\n",
|
||||
pr_debug("%s: interrupt, status %4.4x, latency %d ticks.\n",
|
||||
dev->name, status, ioread8(ioaddr + Timer));
|
||||
do {
|
||||
if (vortex_debug > 5)
|
||||
printk(KERN_DEBUG "%s: In interrupt loop, status %4.4x.\n",
|
||||
pr_debug("%s: In interrupt loop, status %4.4x.\n",
|
||||
dev->name, status);
|
||||
if (status & UpComplete) {
|
||||
iowrite16(AckIntr | UpComplete, ioaddr + EL3_CMD);
|
||||
if (vortex_debug > 5)
|
||||
printk(KERN_DEBUG "boomerang_interrupt->boomerang_rx\n");
|
||||
pr_debug("boomerang_interrupt->boomerang_rx\n");
|
||||
boomerang_rx(dev);
|
||||
}
|
||||
|
||||
|
|
@ -2374,7 +2370,7 @@ boomerang_interrupt(int irq, void *dev_id)
|
|||
dev_kfree_skb_irq(skb);
|
||||
vp->tx_skbuff[entry] = NULL;
|
||||
} else {
|
||||
printk(KERN_DEBUG "boomerang_interrupt: no skb!\n");
|
||||
pr_debug("boomerang_interrupt: no skb!\n");
|
||||
}
|
||||
/* dev->stats.tx_packets++; Counted below. */
|
||||
dirty_tx++;
|
||||
|
|
@ -2382,7 +2378,7 @@ boomerang_interrupt(int irq, void *dev_id)
|
|||
vp->dirty_tx = dirty_tx;
|
||||
if (vp->cur_tx - dirty_tx <= TX_RING_SIZE - 1) {
|
||||
if (vortex_debug > 6)
|
||||
printk(KERN_DEBUG "boomerang_interrupt: wake queue\n");
|
||||
pr_debug("boomerang_interrupt: wake queue\n");
|
||||
netif_wake_queue (dev);
|
||||
}
|
||||
}
|
||||
|
|
@ -2392,8 +2388,8 @@ boomerang_interrupt(int irq, void *dev_id)
|
|||
vortex_error(dev, status);
|
||||
|
||||
if (--work_done < 0) {
|
||||
printk(KERN_WARNING "%s: Too much work in interrupt, status "
|
||||
"%4.4x.\n", dev->name, status);
|
||||
pr_warning("%s: Too much work in interrupt, status %4.4x.\n",
|
||||
dev->name, status);
|
||||
/* Disable all pending interrupts. */
|
||||
do {
|
||||
vp->deferred |= status;
|
||||
|
|
@ -2413,7 +2409,7 @@ boomerang_interrupt(int irq, void *dev_id)
|
|||
} while ((status = ioread16(ioaddr + EL3_STATUS)) & IntLatch);
|
||||
|
||||
if (vortex_debug > 4)
|
||||
printk(KERN_DEBUG "%s: exiting interrupt, status %4.4x.\n",
|
||||
pr_debug("%s: exiting interrupt, status %4.4x.\n",
|
||||
dev->name, status);
|
||||
handler_exit:
|
||||
spin_unlock(&vp->lock);
|
||||
|
|
@ -2428,13 +2424,13 @@ static int vortex_rx(struct net_device *dev)
|
|||
short rx_status;
|
||||
|
||||
if (vortex_debug > 5)
|
||||
printk(KERN_DEBUG "vortex_rx(): status %4.4x, rx_status %4.4x.\n",
|
||||
pr_debug("vortex_rx(): status %4.4x, rx_status %4.4x.\n",
|
||||
ioread16(ioaddr+EL3_STATUS), ioread16(ioaddr+RxStatus));
|
||||
while ((rx_status = ioread16(ioaddr + RxStatus)) > 0) {
|
||||
if (rx_status & 0x4000) { /* Error, update stats. */
|
||||
unsigned char rx_error = ioread8(ioaddr + RxErrors);
|
||||
if (vortex_debug > 2)
|
||||
printk(KERN_DEBUG " Rx error: status %2.2x.\n", rx_error);
|
||||
pr_debug(" Rx error: status %2.2x.\n", rx_error);
|
||||
dev->stats.rx_errors++;
|
||||
if (rx_error & 0x01) dev->stats.rx_over_errors++;
|
||||
if (rx_error & 0x02) dev->stats.rx_length_errors++;
|
||||
|
|
@ -2448,7 +2444,7 @@ static int vortex_rx(struct net_device *dev)
|
|||
|
||||
skb = dev_alloc_skb(pkt_len + 5);
|
||||
if (vortex_debug > 4)
|
||||
printk(KERN_DEBUG "Receiving packet size %d status %4.4x.\n",
|
||||
pr_debug("Receiving packet size %d status %4.4x.\n",
|
||||
pkt_len, rx_status);
|
||||
if (skb != NULL) {
|
||||
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
|
||||
|
|
@ -2478,8 +2474,8 @@ static int vortex_rx(struct net_device *dev)
|
|||
break;
|
||||
continue;
|
||||
} else if (vortex_debug > 0)
|
||||
printk(KERN_NOTICE "%s: No memory to allocate a sk_buff of "
|
||||
"size %d.\n", dev->name, pkt_len);
|
||||
pr_notice("%s: No memory to allocate a sk_buff of size %d.\n",
|
||||
dev->name, pkt_len);
|
||||
dev->stats.rx_dropped++;
|
||||
}
|
||||
issue_and_wait(dev, RxDiscard);
|
||||
|
|
@ -2498,7 +2494,7 @@ boomerang_rx(struct net_device *dev)
|
|||
int rx_work_limit = vp->dirty_rx + RX_RING_SIZE - vp->cur_rx;
|
||||
|
||||
if (vortex_debug > 5)
|
||||
printk(KERN_DEBUG "boomerang_rx(): status %4.4x\n", ioread16(ioaddr+EL3_STATUS));
|
||||
pr_debug("boomerang_rx(): status %4.4x\n", ioread16(ioaddr+EL3_STATUS));
|
||||
|
||||
while ((rx_status = le32_to_cpu(vp->rx_ring[entry].status)) & RxDComplete){
|
||||
if (--rx_work_limit < 0)
|
||||
|
|
@ -2506,7 +2502,7 @@ boomerang_rx(struct net_device *dev)
|
|||
if (rx_status & RxDError) { /* Error, update stats. */
|
||||
unsigned char rx_error = rx_status >> 16;
|
||||
if (vortex_debug > 2)
|
||||
printk(KERN_DEBUG " Rx error: status %2.2x.\n", rx_error);
|
||||
pr_debug(" Rx error: status %2.2x.\n", rx_error);
|
||||
dev->stats.rx_errors++;
|
||||
if (rx_error & 0x01) dev->stats.rx_over_errors++;
|
||||
if (rx_error & 0x02) dev->stats.rx_length_errors++;
|
||||
|
|
@ -2520,7 +2516,7 @@ boomerang_rx(struct net_device *dev)
|
|||
dma_addr_t dma = le32_to_cpu(vp->rx_ring[entry].addr);
|
||||
|
||||
if (vortex_debug > 4)
|
||||
printk(KERN_DEBUG "Receiving packet size %d status %4.4x.\n",
|
||||
pr_debug("Receiving packet size %d status %4.4x.\n",
|
||||
pkt_len, rx_status);
|
||||
|
||||
/* Check if the packet is long enough to just accept without
|
||||
|
|
@ -2566,7 +2562,7 @@ boomerang_rx(struct net_device *dev)
|
|||
if (skb == NULL) {
|
||||
static unsigned long last_jif;
|
||||
if (time_after(jiffies, last_jif + 10 * HZ)) {
|
||||
printk(KERN_WARNING "%s: memory shortage\n", dev->name);
|
||||
pr_warning("%s: memory shortage\n", dev->name);
|
||||
last_jif = jiffies;
|
||||
}
|
||||
if ((vp->cur_rx - vp->dirty_rx) == RX_RING_SIZE)
|
||||
|
|
@ -2598,7 +2594,7 @@ rx_oom_timer(unsigned long arg)
|
|||
if ((vp->cur_rx - vp->dirty_rx) == RX_RING_SIZE) /* This test is redundant, but makes me feel good */
|
||||
boomerang_rx(dev);
|
||||
if (vortex_debug > 1) {
|
||||
printk(KERN_DEBUG "%s: rx_oom_timer %s\n", dev->name,
|
||||
pr_debug("%s: rx_oom_timer %s\n", dev->name,
|
||||
((vp->cur_rx - vp->dirty_rx) != RX_RING_SIZE) ? "succeeded" : "retrying");
|
||||
}
|
||||
spin_unlock_irq(&vp->lock);
|
||||
|
|
@ -2655,9 +2651,9 @@ vortex_close(struct net_device *dev)
|
|||
vortex_down(dev, 1);
|
||||
|
||||
if (vortex_debug > 1) {
|
||||
printk(KERN_DEBUG"%s: vortex_close() status %4.4x, Tx status %2.2x.\n",
|
||||
pr_debug("%s: vortex_close() status %4.4x, Tx status %2.2x.\n",
|
||||
dev->name, ioread16(ioaddr + EL3_STATUS), ioread8(ioaddr + TxStatus));
|
||||
printk(KERN_DEBUG "%s: vortex close stats: rx_nocopy %d rx_copy %d"
|
||||
pr_debug("%s: vortex close stats: rx_nocopy %d rx_copy %d"
|
||||
" tx_queued %d Rx pre-checksummed %d.\n",
|
||||
dev->name, vp->rx_nocopy, vp->rx_copy, vp->queued_packet, vp->rx_csumhits);
|
||||
}
|
||||
|
|
@ -2666,8 +2662,7 @@ vortex_close(struct net_device *dev)
|
|||
if (vp->rx_csumhits &&
|
||||
(vp->drv_flags & HAS_HWCKSM) == 0 &&
|
||||
(vp->card_idx >= MAX_UNITS || hw_checksums[vp->card_idx] == -1)) {
|
||||
printk(KERN_WARNING "%s supports hardware checksums, and we're "
|
||||
"not using them!\n", dev->name);
|
||||
pr_warning("%s supports hardware checksums, and we're not using them!\n", dev->name);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -2717,16 +2712,16 @@ dump_tx_ring(struct net_device *dev)
|
|||
int i;
|
||||
int stalled = ioread32(ioaddr + PktStatus) & 0x04; /* Possible racy. But it's only debug stuff */
|
||||
|
||||
printk(KERN_ERR " Flags; bus-master %d, dirty %d(%d) current %d(%d)\n",
|
||||
pr_err(" Flags; bus-master %d, dirty %d(%d) current %d(%d)\n",
|
||||
vp->full_bus_master_tx,
|
||||
vp->dirty_tx, vp->dirty_tx % TX_RING_SIZE,
|
||||
vp->cur_tx, vp->cur_tx % TX_RING_SIZE);
|
||||
printk(KERN_ERR " Transmit list %8.8x vs. %p.\n",
|
||||
pr_err(" Transmit list %8.8x vs. %p.\n",
|
||||
ioread32(ioaddr + DownListPtr),
|
||||
&vp->tx_ring[vp->dirty_tx % TX_RING_SIZE]);
|
||||
issue_and_wait(dev, DownStall);
|
||||
for (i = 0; i < TX_RING_SIZE; i++) {
|
||||
printk(KERN_ERR " %d: @%p length %8.8x status %8.8x\n", i,
|
||||
pr_err(" %d: @%p length %8.8x status %8.8x\n", i,
|
||||
&vp->tx_ring[i],
|
||||
#if DO_ZEROCOPY
|
||||
le32_to_cpu(vp->tx_ring[i].frag[0].length),
|
||||
|
|
@ -2970,7 +2965,7 @@ static void set_rx_mode(struct net_device *dev)
|
|||
|
||||
if (dev->flags & IFF_PROMISC) {
|
||||
if (vortex_debug > 3)
|
||||
printk(KERN_NOTICE "%s: Setting promiscuous mode.\n", dev->name);
|
||||
pr_notice("%s: Setting promiscuous mode.\n", dev->name);
|
||||
new_mode = SetRxFilter|RxStation|RxMulticast|RxBroadcast|RxProm;
|
||||
} else if ((dev->mc_list) || (dev->flags & IFF_ALLMULTI)) {
|
||||
new_mode = SetRxFilter|RxStation|RxMulticast|RxBroadcast;
|
||||
|
|
@ -3145,8 +3140,7 @@ static void acpi_set_WOL(struct net_device *dev)
|
|||
iowrite16(RxEnable, ioaddr + EL3_CMD);
|
||||
|
||||
if (pci_enable_wake(VORTEX_PCI(vp), PCI_D3hot, 1)) {
|
||||
printk(KERN_INFO "%s: WOL not supported.\n",
|
||||
pci_name(VORTEX_PCI(vp)));
|
||||
pr_info("%s: WOL not supported.\n", pci_name(VORTEX_PCI(vp)));
|
||||
|
||||
vp->enable_wol = 0;
|
||||
return;
|
||||
|
|
@ -3164,7 +3158,7 @@ static void __devexit vortex_remove_one(struct pci_dev *pdev)
|
|||
struct vortex_private *vp;
|
||||
|
||||
if (!dev) {
|
||||
printk("vortex_remove_one called for Compaq device!\n");
|
||||
pr_err("vortex_remove_one called for Compaq device!\n");
|
||||
BUG();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -541,7 +541,7 @@ int lance_start_xmit (struct sk_buff *skb, struct net_device *dev)
|
|||
unsigned long flags;
|
||||
|
||||
if (!TX_BUFFS_AVAIL)
|
||||
return -1;
|
||||
return NETDEV_TX_LOCKED;
|
||||
|
||||
netif_stop_queue (dev);
|
||||
|
||||
|
|
|
|||
|
|
@ -471,8 +471,7 @@ static void cp_rx_err_acct (struct cp_private *cp, unsigned rx_tail,
|
|||
u32 status, u32 len)
|
||||
{
|
||||
if (netif_msg_rx_err (cp))
|
||||
printk (KERN_DEBUG
|
||||
"%s: rx err, slot %d status 0x%x len %d\n",
|
||||
pr_debug("%s: rx err, slot %d status 0x%x len %d\n",
|
||||
cp->dev->name, rx_tail, status, len);
|
||||
cp->dev->stats.rx_errors++;
|
||||
if (status & RxErrFrame)
|
||||
|
|
@ -547,7 +546,7 @@ rx_status_loop:
|
|||
}
|
||||
|
||||
if (netif_msg_rx_status(cp))
|
||||
printk(KERN_DEBUG "%s: rx slot %d status 0x%x len %d\n",
|
||||
pr_debug("%s: rx slot %d status 0x%x len %d\n",
|
||||
dev->name, rx_tail, status, len);
|
||||
|
||||
buflen = cp->rx_buf_sz + NET_IP_ALIGN;
|
||||
|
|
@ -626,7 +625,7 @@ static irqreturn_t cp_interrupt (int irq, void *dev_instance)
|
|||
return IRQ_NONE;
|
||||
|
||||
if (netif_msg_intr(cp))
|
||||
printk(KERN_DEBUG "%s: intr, status %04x cmd %02x cpcmd %04x\n",
|
||||
pr_debug("%s: intr, status %04x cmd %02x cpcmd %04x\n",
|
||||
dev->name, status, cpr8(Cmd), cpr16(CpCmd));
|
||||
|
||||
cpw16(IntrStatus, status & ~cp_rx_intr_mask);
|
||||
|
|
@ -658,7 +657,7 @@ static irqreturn_t cp_interrupt (int irq, void *dev_instance)
|
|||
|
||||
pci_read_config_word(cp->pdev, PCI_STATUS, &pci_status);
|
||||
pci_write_config_word(cp->pdev, PCI_STATUS, pci_status);
|
||||
printk(KERN_ERR "%s: PCI bus error, status=%04x, PCI status=%04x\n",
|
||||
pr_err("%s: PCI bus error, status=%04x, PCI status=%04x\n",
|
||||
dev->name, status, pci_status);
|
||||
|
||||
/* TODO: reset hardware */
|
||||
|
|
@ -705,7 +704,7 @@ static void cp_tx (struct cp_private *cp)
|
|||
if (status & LastFrag) {
|
||||
if (status & (TxError | TxFIFOUnder)) {
|
||||
if (netif_msg_tx_err(cp))
|
||||
printk(KERN_DEBUG "%s: tx err, status 0x%x\n",
|
||||
pr_debug("%s: tx err, status 0x%x\n",
|
||||
cp->dev->name, status);
|
||||
cp->dev->stats.tx_errors++;
|
||||
if (status & TxOWC)
|
||||
|
|
@ -722,7 +721,7 @@ static void cp_tx (struct cp_private *cp)
|
|||
cp->dev->stats.tx_packets++;
|
||||
cp->dev->stats.tx_bytes += skb->len;
|
||||
if (netif_msg_tx_done(cp))
|
||||
printk(KERN_DEBUG "%s: tx done, slot %d\n", cp->dev->name, tx_tail);
|
||||
pr_debug("%s: tx done, slot %d\n", cp->dev->name, tx_tail);
|
||||
}
|
||||
dev_kfree_skb_irq(skb);
|
||||
}
|
||||
|
|
@ -755,9 +754,9 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev)
|
|||
if (TX_BUFFS_AVAIL(cp) <= (skb_shinfo(skb)->nr_frags + 1)) {
|
||||
netif_stop_queue(dev);
|
||||
spin_unlock_irqrestore(&cp->lock, intr_flags);
|
||||
printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
|
||||
pr_err(PFX "%s: BUG! Tx Ring full when queue awake!\n",
|
||||
dev->name);
|
||||
return 1;
|
||||
return NETDEV_TX_BUSY;
|
||||
}
|
||||
|
||||
#if CP_VLAN_TAG_USED
|
||||
|
|
@ -882,7 +881,7 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev)
|
|||
}
|
||||
cp->tx_head = entry;
|
||||
if (netif_msg_tx_queued(cp))
|
||||
printk(KERN_DEBUG "%s: tx queued, slot %d, skblen %d\n",
|
||||
pr_debug("%s: tx queued, slot %d, skblen %d\n",
|
||||
dev->name, entry, skb->len);
|
||||
if (TX_BUFFS_AVAIL(cp) <= (MAX_SKB_FRAGS + 1))
|
||||
netif_stop_queue(dev);
|
||||
|
|
@ -996,7 +995,7 @@ static void cp_reset_hw (struct cp_private *cp)
|
|||
schedule_timeout_uninterruptible(10);
|
||||
}
|
||||
|
||||
printk(KERN_ERR "%s: hardware reset timeout\n", cp->dev->name);
|
||||
pr_err("%s: hardware reset timeout\n", cp->dev->name);
|
||||
}
|
||||
|
||||
static inline void cp_start_hw (struct cp_private *cp)
|
||||
|
|
@ -1166,7 +1165,7 @@ static int cp_open (struct net_device *dev)
|
|||
int rc;
|
||||
|
||||
if (netif_msg_ifup(cp))
|
||||
printk(KERN_DEBUG "%s: enabling interface\n", dev->name);
|
||||
pr_debug("%s: enabling interface\n", dev->name);
|
||||
|
||||
rc = cp_alloc_rings(cp);
|
||||
if (rc)
|
||||
|
|
@ -1201,7 +1200,7 @@ static int cp_close (struct net_device *dev)
|
|||
napi_disable(&cp->napi);
|
||||
|
||||
if (netif_msg_ifdown(cp))
|
||||
printk(KERN_DEBUG "%s: disabling interface\n", dev->name);
|
||||
pr_debug("%s: disabling interface\n", dev->name);
|
||||
|
||||
spin_lock_irqsave(&cp->lock, flags);
|
||||
|
||||
|
|
@ -1224,7 +1223,7 @@ static void cp_tx_timeout(struct net_device *dev)
|
|||
unsigned long flags;
|
||||
int rc;
|
||||
|
||||
printk(KERN_WARNING "%s: Transmit timeout, status %2x %4x %4x %4x\n",
|
||||
pr_warning("%s: Transmit timeout, status %2x %4x %4x %4x\n",
|
||||
dev->name, cpr8(Cmd), cpr16(CpCmd),
|
||||
cpr16(IntrStatus), cpr16(IntrMask));
|
||||
|
||||
|
|
@ -1873,7 +1872,7 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
#ifndef MODULE
|
||||
static int version_printed;
|
||||
if (version_printed++ == 0)
|
||||
printk("%s", version);
|
||||
pr_info("%s", version);
|
||||
#endif
|
||||
|
||||
if (pdev->vendor == PCI_VENDOR_ID_REALTEK &&
|
||||
|
|
@ -1995,8 +1994,7 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
if (rc)
|
||||
goto err_out_iomap;
|
||||
|
||||
printk (KERN_INFO "%s: RTL-8139C+ at 0x%lx, "
|
||||
"%pM, IRQ %d\n",
|
||||
pr_info("%s: RTL-8139C+ at 0x%lx, %pM, IRQ %d\n",
|
||||
dev->name,
|
||||
dev->base_addr,
|
||||
dev->dev_addr,
|
||||
|
|
@ -2113,7 +2111,7 @@ static struct pci_driver cp_driver = {
|
|||
static int __init cp_init (void)
|
||||
{
|
||||
#ifdef MODULE
|
||||
printk("%s", version);
|
||||
pr_info("%s", version);
|
||||
#endif
|
||||
return pci_register_driver(&cp_driver);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -126,19 +126,12 @@
|
|||
#undef RTL8139_NDEBUG
|
||||
|
||||
|
||||
#if RTL8139_DEBUG
|
||||
/* note: prints function name for you */
|
||||
# define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)
|
||||
#else
|
||||
# define DPRINTK(fmt, args...)
|
||||
#endif
|
||||
|
||||
#ifdef RTL8139_NDEBUG
|
||||
# define assert(expr) do {} while (0)
|
||||
#else
|
||||
# define assert(expr) \
|
||||
if(unlikely(!(expr))) { \
|
||||
printk(KERN_ERR "Assertion failed! %s,%s,%s,line=%d\n", \
|
||||
pr_err("Assertion failed! %s,%s,%s,line=%d\n", \
|
||||
#expr, __FILE__, __func__, __LINE__); \
|
||||
}
|
||||
#endif
|
||||
|
|
@ -784,8 +777,8 @@ static __devinit struct net_device * rtl8139_init_board (struct pci_dev *pdev)
|
|||
|
||||
/* set this immediately, we need to know before
|
||||
* we talk to the chip directly */
|
||||
DPRINTK("PIO region size == 0x%02X\n", pio_len);
|
||||
DPRINTK("MMIO region size == 0x%02lX\n", mmio_len);
|
||||
pr_debug("PIO region size == 0x%02lX\n", pio_len);
|
||||
pr_debug("MMIO region size == 0x%02lX\n", mmio_len);
|
||||
|
||||
retry:
|
||||
if (use_io) {
|
||||
|
|
@ -865,19 +858,17 @@ retry:
|
|||
}
|
||||
|
||||
/* if unknown chip, assume array element #0, original RTL-8139 in this case */
|
||||
dev_printk (KERN_DEBUG, &pdev->dev,
|
||||
"unknown chip version, assuming RTL-8139\n");
|
||||
dev_printk (KERN_DEBUG, &pdev->dev,
|
||||
"TxConfig = 0x%lx\n", RTL_R32 (TxConfig));
|
||||
dev_dbg(&pdev->dev, "unknown chip version, assuming RTL-8139\n");
|
||||
dev_dbg(&pdev->dev, "TxConfig = 0x%lx\n", RTL_R32 (TxConfig));
|
||||
tp->chipset = 0;
|
||||
|
||||
match:
|
||||
DPRINTK ("chipset id (%d) == index %d, '%s'\n",
|
||||
pr_debug("chipset id (%d) == index %d, '%s'\n",
|
||||
version, i, rtl_chip_info[i].name);
|
||||
|
||||
if (tp->chipset >= CH_8139B) {
|
||||
u8 new_tmp8 = tmp8 = RTL_R8 (Config1);
|
||||
DPRINTK("PCI PM wakeup\n");
|
||||
pr_debug("PCI PM wakeup\n");
|
||||
if ((rtl_chip_info[tp->chipset].flags & HasLWake) &&
|
||||
(tmp8 & LWAKE))
|
||||
new_tmp8 &= ~LWAKE;
|
||||
|
|
@ -896,7 +887,7 @@ match:
|
|||
}
|
||||
}
|
||||
} else {
|
||||
DPRINTK("Old chip wakeup\n");
|
||||
pr_debug("Old chip wakeup\n");
|
||||
tmp8 = RTL_R8 (Config1);
|
||||
tmp8 &= ~(SLEEP | PWRDN);
|
||||
RTL_W8 (Config1, tmp8);
|
||||
|
|
@ -949,7 +940,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
|
|||
{
|
||||
static int printed_version;
|
||||
if (!printed_version++)
|
||||
printk (KERN_INFO RTL8139_DRIVER_NAME "\n");
|
||||
pr_info(RTL8139_DRIVER_NAME "\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -965,7 +956,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
|
|||
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");
|
||||
pr_info("8139too: OQO Model 2 detected. Forcing PIO\n");
|
||||
use_io = 1;
|
||||
}
|
||||
|
||||
|
|
@ -1018,21 +1009,20 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
|
|||
tp->mii.reg_num_mask = 0x1f;
|
||||
|
||||
/* dev is fully set up and ready to use now */
|
||||
DPRINTK("about to register device named %s (%p)...\n", dev->name, dev);
|
||||
pr_debug("about to register device named %s (%p)...\n", dev->name, dev);
|
||||
i = register_netdev (dev);
|
||||
if (i) goto err_out;
|
||||
|
||||
pci_set_drvdata (pdev, dev);
|
||||
|
||||
printk (KERN_INFO "%s: %s at 0x%lx, "
|
||||
"%pM, IRQ %d\n",
|
||||
pr_info("%s: %s at 0x%lx, %pM, IRQ %d\n",
|
||||
dev->name,
|
||||
board_info[ent->driver_data].name,
|
||||
dev->base_addr,
|
||||
dev->dev_addr,
|
||||
dev->irq);
|
||||
|
||||
printk (KERN_DEBUG "%s: Identified 8139 chip type '%s'\n",
|
||||
pr_debug("%s: Identified 8139 chip type '%s'\n",
|
||||
dev->name, rtl_chip_info[tp->chipset].name);
|
||||
|
||||
/* Find the connected MII xcvrs.
|
||||
|
|
@ -1046,14 +1036,12 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
|
|||
if (mii_status != 0xffff && mii_status != 0x0000) {
|
||||
u16 advertising = mdio_read(dev, phy, 4);
|
||||
tp->phys[phy_idx++] = phy;
|
||||
printk(KERN_INFO "%s: MII transceiver %d status 0x%4.4x "
|
||||
"advertising %4.4x.\n",
|
||||
pr_info("%s: MII transceiver %d status 0x%4.4x advertising %4.4x.\n",
|
||||
dev->name, phy, mii_status, advertising);
|
||||
}
|
||||
}
|
||||
if (phy_idx == 0) {
|
||||
printk(KERN_INFO "%s: No MII transceivers found! Assuming SYM "
|
||||
"transceiver.\n",
|
||||
pr_info("%s: No MII transceivers found! Assuming SYM transceiver.\n",
|
||||
dev->name);
|
||||
tp->phys[0] = 32;
|
||||
}
|
||||
|
|
@ -1073,13 +1061,13 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
|
|||
if (board_idx < MAX_UNITS && full_duplex[board_idx] > 0)
|
||||
tp->mii.full_duplex = full_duplex[board_idx];
|
||||
if (tp->mii.full_duplex) {
|
||||
printk(KERN_INFO "%s: Media type forced to Full Duplex.\n", dev->name);
|
||||
pr_info("%s: Media type forced to Full Duplex.\n", dev->name);
|
||||
/* Changing the MII-advertised media because might prevent
|
||||
re-connection. */
|
||||
tp->mii.force_media = 1;
|
||||
}
|
||||
if (tp->default_port) {
|
||||
printk(KERN_INFO " Forcing %dMbps %s-duplex operation.\n",
|
||||
pr_info(" Forcing %dMbps %s-duplex operation.\n",
|
||||
(option & 0x20 ? 100 : 10),
|
||||
(option & 0x10 ? "full" : "half"));
|
||||
mdio_write(dev, tp->phys[0], 0,
|
||||
|
|
@ -1342,7 +1330,7 @@ static int rtl8139_open (struct net_device *dev)
|
|||
netif_start_queue (dev);
|
||||
|
||||
if (netif_msg_ifup(tp))
|
||||
printk(KERN_DEBUG "%s: rtl8139_open() ioaddr %#llx IRQ %d"
|
||||
pr_debug("%s: rtl8139_open() ioaddr %#llx IRQ %d"
|
||||
" GP Pins %2.2x %s-duplex.\n", dev->name,
|
||||
(unsigned long long)pci_resource_start (tp->pci_dev, 1),
|
||||
dev->irq, RTL_R8 (MediaStatus),
|
||||
|
|
@ -1404,7 +1392,7 @@ static void rtl8139_hw_start (struct net_device *dev)
|
|||
RTL_W8 (Config3, RTL_R8 (Config3) & ~Cfg3_Magic);
|
||||
}
|
||||
|
||||
DPRINTK("init buffer addresses\n");
|
||||
pr_debug("init buffer addresses\n");
|
||||
|
||||
/* Lock Config[01234] and BMCR register writes */
|
||||
RTL_W8 (Cfg9346, Cfg9346_Lock);
|
||||
|
|
@ -1566,14 +1554,13 @@ static inline void rtl8139_thread_iter (struct net_device *dev,
|
|||
tp->mii.full_duplex = duplex;
|
||||
|
||||
if (mii_lpa) {
|
||||
printk (KERN_INFO
|
||||
"%s: Setting %s-duplex based on MII #%d link"
|
||||
pr_info("%s: Setting %s-duplex based on MII #%d link"
|
||||
" partner ability of %4.4x.\n",
|
||||
dev->name,
|
||||
tp->mii.full_duplex ? "full" : "half",
|
||||
tp->phys[0], mii_lpa);
|
||||
} else {
|
||||
printk(KERN_INFO"%s: media is unconnected, link down, or incompatible connection\n",
|
||||
pr_info("%s: media is unconnected, link down, or incompatible connection\n",
|
||||
dev->name);
|
||||
}
|
||||
#if 0
|
||||
|
|
@ -1588,11 +1575,11 @@ static inline void rtl8139_thread_iter (struct net_device *dev,
|
|||
|
||||
rtl8139_tune_twister (dev, tp);
|
||||
|
||||
DPRINTK ("%s: Media selection tick, Link partner %4.4x.\n",
|
||||
pr_debug("%s: Media selection tick, Link partner %4.4x.\n",
|
||||
dev->name, RTL_R16 (NWayLPAR));
|
||||
DPRINTK ("%s: Other registers are IntMask %4.4x IntStatus %4.4x\n",
|
||||
pr_debug("%s: Other registers are IntMask %4.4x IntStatus %4.4x\n",
|
||||
dev->name, RTL_R16 (IntrMask), RTL_R16 (IntrStatus));
|
||||
DPRINTK ("%s: Chip config %2.2x %2.2x.\n",
|
||||
pr_debug("%s: Chip config %2.2x %2.2x.\n",
|
||||
dev->name, RTL_R8 (Config0),
|
||||
RTL_R8 (Config1));
|
||||
}
|
||||
|
|
@ -1652,14 +1639,14 @@ static void rtl8139_tx_timeout_task (struct work_struct *work)
|
|||
int i;
|
||||
u8 tmp8;
|
||||
|
||||
printk (KERN_DEBUG "%s: Transmit timeout, status %2.2x %4.4x %4.4x "
|
||||
"media %2.2x.\n", dev->name, RTL_R8 (ChipCmd),
|
||||
pr_debug("%s: Transmit timeout, status %2.2x %4.4x %4.4x media %2.2x.\n",
|
||||
dev->name, RTL_R8 (ChipCmd),
|
||||
RTL_R16(IntrStatus), RTL_R16(IntrMask), RTL_R8(MediaStatus));
|
||||
/* Emit info to figure out what went wrong. */
|
||||
printk (KERN_DEBUG "%s: Tx queue start entry %ld dirty entry %ld.\n",
|
||||
pr_debug("%s: Tx queue start entry %ld dirty entry %ld.\n",
|
||||
dev->name, tp->cur_tx, tp->dirty_tx);
|
||||
for (i = 0; i < NUM_TX_DESC; i++)
|
||||
printk (KERN_DEBUG "%s: Tx descriptor %d is %8.8lx.%s\n",
|
||||
pr_debug("%s: Tx descriptor %d is %8.8lx.%s\n",
|
||||
dev->name, i, RTL_R32 (TxStatus0 + (i * 4)),
|
||||
i == tp->dirty_tx % NUM_TX_DESC ?
|
||||
" (queue head)" : "");
|
||||
|
|
@ -1741,7 +1728,7 @@ static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
|
|||
spin_unlock_irqrestore(&tp->lock, flags);
|
||||
|
||||
if (netif_msg_tx_queued(tp))
|
||||
printk (KERN_DEBUG "%s: Queued Tx packet size %u to slot %d.\n",
|
||||
pr_debug("%s: Queued Tx packet size %u to slot %d.\n",
|
||||
dev->name, len, entry);
|
||||
|
||||
return 0;
|
||||
|
|
@ -1772,7 +1759,7 @@ static void rtl8139_tx_interrupt (struct net_device *dev,
|
|||
if (txstatus & (TxOutOfWindow | TxAborted)) {
|
||||
/* There was an major error, log it. */
|
||||
if (netif_msg_tx_err(tp))
|
||||
printk(KERN_DEBUG "%s: Transmit error, Tx status %8.8x.\n",
|
||||
pr_debug("%s: Transmit error, Tx status %8.8x.\n",
|
||||
dev->name, txstatus);
|
||||
dev->stats.tx_errors++;
|
||||
if (txstatus & TxAborted) {
|
||||
|
|
@ -1803,7 +1790,7 @@ static void rtl8139_tx_interrupt (struct net_device *dev,
|
|||
|
||||
#ifndef RTL8139_NDEBUG
|
||||
if (tp->cur_tx - dirty_tx > NUM_TX_DESC) {
|
||||
printk (KERN_ERR "%s: Out-of-sync dirty pointer, %ld vs. %ld.\n",
|
||||
pr_err("%s: Out-of-sync dirty pointer, %ld vs. %ld.\n",
|
||||
dev->name, dirty_tx, tp->cur_tx);
|
||||
dirty_tx += NUM_TX_DESC;
|
||||
}
|
||||
|
|
@ -1828,12 +1815,12 @@ static void rtl8139_rx_err (u32 rx_status, struct net_device *dev,
|
|||
#endif
|
||||
|
||||
if (netif_msg_rx_err (tp))
|
||||
printk(KERN_DEBUG "%s: Ethernet frame had errors, status %8.8x.\n",
|
||||
pr_debug("%s: Ethernet frame had errors, status %8.8x.\n",
|
||||
dev->name, rx_status);
|
||||
dev->stats.rx_errors++;
|
||||
if (!(rx_status & RxStatusOK)) {
|
||||
if (rx_status & RxTooLong) {
|
||||
DPRINTK ("%s: Oversized Ethernet frame, status %4.4x!\n",
|
||||
pr_debug("%s: Oversized Ethernet frame, status %4.4x!\n",
|
||||
dev->name, rx_status);
|
||||
/* A.C.: The chip hangs here. */
|
||||
}
|
||||
|
|
@ -1866,7 +1853,7 @@ static void rtl8139_rx_err (u32 rx_status, struct net_device *dev,
|
|||
break;
|
||||
}
|
||||
if (tmp_work <= 0)
|
||||
printk (KERN_WARNING PFX "rx stop wait too long\n");
|
||||
pr_warning(PFX "rx stop wait too long\n");
|
||||
/* restart receive */
|
||||
tmp_work = 200;
|
||||
while (--tmp_work > 0) {
|
||||
|
|
@ -1877,7 +1864,7 @@ static void rtl8139_rx_err (u32 rx_status, struct net_device *dev,
|
|||
break;
|
||||
}
|
||||
if (tmp_work <= 0)
|
||||
printk (KERN_WARNING PFX "tx/rx enable wait too long\n");
|
||||
pr_warning(PFX "tx/rx enable wait too long\n");
|
||||
|
||||
/* and reinitialize all rx related registers */
|
||||
RTL_W8_F (Cfg9346, Cfg9346_Unlock);
|
||||
|
|
@ -1888,7 +1875,7 @@ static void rtl8139_rx_err (u32 rx_status, struct net_device *dev,
|
|||
RTL_W32 (RxConfig, tp->rx_config);
|
||||
tp->cur_rx = 0;
|
||||
|
||||
DPRINTK("init buffer addresses\n");
|
||||
pr_debug("init buffer addresses\n");
|
||||
|
||||
/* Lock Config[01234] and BMCR register writes */
|
||||
RTL_W8 (Cfg9346, Cfg9346_Lock);
|
||||
|
|
@ -1942,7 +1929,7 @@ static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
|
|||
unsigned int cur_rx = tp->cur_rx;
|
||||
unsigned int rx_size = 0;
|
||||
|
||||
DPRINTK ("%s: In rtl8139_rx(), current %4.4x BufAddr %4.4x,"
|
||||
pr_debug("%s: In rtl8139_rx(), current %4.4x BufAddr %4.4x,"
|
||||
" free to %4.4x, Cmd %2.2x.\n", dev->name, (u16)cur_rx,
|
||||
RTL_R16 (RxBufAddr),
|
||||
RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
|
||||
|
|
@ -1962,17 +1949,17 @@ static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
|
|||
pkt_size = rx_size - 4;
|
||||
|
||||
if (netif_msg_rx_status(tp))
|
||||
printk(KERN_DEBUG "%s: rtl8139_rx() status %4.4x, size %4.4x,"
|
||||
pr_debug("%s: rtl8139_rx() status %4.4x, size %4.4x,"
|
||||
" cur %4.4x.\n", dev->name, rx_status,
|
||||
rx_size, cur_rx);
|
||||
#if RTL8139_DEBUG > 2
|
||||
{
|
||||
int i;
|
||||
DPRINTK ("%s: Frame contents ", dev->name);
|
||||
pr_debug("%s: Frame contents ", dev->name);
|
||||
for (i = 0; i < 70; i++)
|
||||
printk (" %2.2x",
|
||||
pr_cont(" %2.2x",
|
||||
rx_ring[ring_offset + i]);
|
||||
printk (".\n");
|
||||
pr_cont(".\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -1984,12 +1971,12 @@ static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
|
|||
if (!tp->fifo_copy_timeout)
|
||||
tp->fifo_copy_timeout = jiffies + 2;
|
||||
else if (time_after(jiffies, tp->fifo_copy_timeout)) {
|
||||
DPRINTK ("%s: hung FIFO. Reset.", dev->name);
|
||||
pr_debug("%s: hung FIFO. Reset.", dev->name);
|
||||
rx_size = 0;
|
||||
goto no_early_rx;
|
||||
}
|
||||
if (netif_msg_intr(tp)) {
|
||||
printk(KERN_DEBUG "%s: fifo copy in progress.",
|
||||
pr_debug("%s: fifo copy in progress.",
|
||||
dev->name);
|
||||
}
|
||||
tp->xstats.early_rx++;
|
||||
|
|
@ -2033,8 +2020,7 @@ no_early_rx:
|
|||
netif_receive_skb (skb);
|
||||
} else {
|
||||
if (net_ratelimit())
|
||||
printk (KERN_WARNING
|
||||
"%s: Memory squeeze, dropping packet.\n",
|
||||
pr_warning("%s: Memory squeeze, dropping packet.\n",
|
||||
dev->name);
|
||||
dev->stats.rx_dropped++;
|
||||
}
|
||||
|
|
@ -2049,12 +2035,10 @@ no_early_rx:
|
|||
if (unlikely(!received || rx_size == 0xfff0))
|
||||
rtl8139_isr_ack(tp);
|
||||
|
||||
#if RTL8139_DEBUG > 1
|
||||
DPRINTK ("%s: Done rtl8139_rx(), current %4.4x BufAddr %4.4x,"
|
||||
pr_debug("%s: Done rtl8139_rx(), current %4.4x BufAddr %4.4x,"
|
||||
" free to %4.4x, Cmd %2.2x.\n", dev->name, cur_rx,
|
||||
RTL_R16 (RxBufAddr),
|
||||
RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
|
||||
#endif
|
||||
|
||||
tp->cur_rx = cur_rx;
|
||||
|
||||
|
|
@ -2075,7 +2059,7 @@ static void rtl8139_weird_interrupt (struct net_device *dev,
|
|||
void __iomem *ioaddr,
|
||||
int status, int link_changed)
|
||||
{
|
||||
DPRINTK ("%s: Abnormal interrupt, status %8.8x.\n",
|
||||
pr_debug("%s: Abnormal interrupt, status %8.8x.\n",
|
||||
dev->name, status);
|
||||
|
||||
assert (dev != NULL);
|
||||
|
|
@ -2104,7 +2088,7 @@ static void rtl8139_weird_interrupt (struct net_device *dev,
|
|||
pci_read_config_word (tp->pci_dev, PCI_STATUS, &pci_cmd_status);
|
||||
pci_write_config_word (tp->pci_dev, PCI_STATUS, pci_cmd_status);
|
||||
|
||||
printk (KERN_ERR "%s: PCI Bus error %4.4x.\n",
|
||||
pr_err("%s: PCI Bus error %4.4x.\n",
|
||||
dev->name, pci_cmd_status);
|
||||
}
|
||||
}
|
||||
|
|
@ -2198,7 +2182,7 @@ static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance)
|
|||
out:
|
||||
spin_unlock (&tp->lock);
|
||||
|
||||
DPRINTK ("%s: exiting interrupt, intr_status=%#4.4x.\n",
|
||||
pr_debug("%s: exiting interrupt, intr_status=%#4.4x.\n",
|
||||
dev->name, RTL_R16 (IntrStatus));
|
||||
return IRQ_RETVAL(handled);
|
||||
}
|
||||
|
|
@ -2249,7 +2233,7 @@ static int rtl8139_close (struct net_device *dev)
|
|||
napi_disable(&tp->napi);
|
||||
|
||||
if (netif_msg_ifdown(tp))
|
||||
printk(KERN_DEBUG "%s: Shutting down ethercard, status was 0x%4.4x.\n",
|
||||
pr_debug("%s: Shutting down ethercard, status was 0x%4.4x.\n",
|
||||
dev->name, RTL_R16 (IntrStatus));
|
||||
|
||||
spin_lock_irqsave (&tp->lock, flags);
|
||||
|
|
@ -2292,11 +2276,11 @@ static int rtl8139_close (struct net_device *dev)
|
|||
other threads or interrupts aren't messing with the 8139. */
|
||||
static void rtl8139_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
|
||||
{
|
||||
struct rtl8139_private *np = netdev_priv(dev);
|
||||
void __iomem *ioaddr = np->mmio_addr;
|
||||
struct rtl8139_private *tp = netdev_priv(dev);
|
||||
void __iomem *ioaddr = tp->mmio_addr;
|
||||
|
||||
spin_lock_irq(&np->lock);
|
||||
if (rtl_chip_info[np->chipset].flags & HasLWake) {
|
||||
spin_lock_irq(&tp->lock);
|
||||
if (rtl_chip_info[tp->chipset].flags & HasLWake) {
|
||||
u8 cfg3 = RTL_R8 (Config3);
|
||||
u8 cfg5 = RTL_R8 (Config5);
|
||||
|
||||
|
|
@ -2317,7 +2301,7 @@ static void rtl8139_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
|
|||
if (cfg5 & Cfg5_BWF)
|
||||
wol->wolopts |= WAKE_BCAST;
|
||||
}
|
||||
spin_unlock_irq(&np->lock);
|
||||
spin_unlock_irq(&tp->lock);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2326,19 +2310,19 @@ static void rtl8139_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
|
|||
aren't messing with the 8139. */
|
||||
static int rtl8139_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
|
||||
{
|
||||
struct rtl8139_private *np = netdev_priv(dev);
|
||||
void __iomem *ioaddr = np->mmio_addr;
|
||||
struct rtl8139_private *tp = netdev_priv(dev);
|
||||
void __iomem *ioaddr = tp->mmio_addr;
|
||||
u32 support;
|
||||
u8 cfg3, cfg5;
|
||||
|
||||
support = ((rtl_chip_info[np->chipset].flags & HasLWake)
|
||||
support = ((rtl_chip_info[tp->chipset].flags & HasLWake)
|
||||
? (WAKE_PHY | WAKE_MAGIC
|
||||
| WAKE_UCAST | WAKE_MCAST | WAKE_BCAST)
|
||||
: 0);
|
||||
if (wol->wolopts & ~support)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irq(&np->lock);
|
||||
spin_lock_irq(&tp->lock);
|
||||
cfg3 = RTL_R8 (Config3) & ~(Cfg3_LinkUp | Cfg3_Magic);
|
||||
if (wol->wolopts & WAKE_PHY)
|
||||
cfg3 |= Cfg3_LinkUp;
|
||||
|
|
@ -2359,87 +2343,87 @@ static int rtl8139_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
|
|||
if (wol->wolopts & WAKE_BCAST)
|
||||
cfg5 |= Cfg5_BWF;
|
||||
RTL_W8 (Config5, cfg5); /* need not unlock via Cfg9346 */
|
||||
spin_unlock_irq(&np->lock);
|
||||
spin_unlock_irq(&tp->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rtl8139_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
|
||||
{
|
||||
struct rtl8139_private *np = netdev_priv(dev);
|
||||
struct rtl8139_private *tp = netdev_priv(dev);
|
||||
strcpy(info->driver, DRV_NAME);
|
||||
strcpy(info->version, DRV_VERSION);
|
||||
strcpy(info->bus_info, pci_name(np->pci_dev));
|
||||
info->regdump_len = np->regs_len;
|
||||
strcpy(info->bus_info, pci_name(tp->pci_dev));
|
||||
info->regdump_len = tp->regs_len;
|
||||
}
|
||||
|
||||
static int rtl8139_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
|
||||
{
|
||||
struct rtl8139_private *np = netdev_priv(dev);
|
||||
spin_lock_irq(&np->lock);
|
||||
mii_ethtool_gset(&np->mii, cmd);
|
||||
spin_unlock_irq(&np->lock);
|
||||
struct rtl8139_private *tp = netdev_priv(dev);
|
||||
spin_lock_irq(&tp->lock);
|
||||
mii_ethtool_gset(&tp->mii, cmd);
|
||||
spin_unlock_irq(&tp->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtl8139_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
|
||||
{
|
||||
struct rtl8139_private *np = netdev_priv(dev);
|
||||
struct rtl8139_private *tp = netdev_priv(dev);
|
||||
int rc;
|
||||
spin_lock_irq(&np->lock);
|
||||
rc = mii_ethtool_sset(&np->mii, cmd);
|
||||
spin_unlock_irq(&np->lock);
|
||||
spin_lock_irq(&tp->lock);
|
||||
rc = mii_ethtool_sset(&tp->mii, cmd);
|
||||
spin_unlock_irq(&tp->lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int rtl8139_nway_reset(struct net_device *dev)
|
||||
{
|
||||
struct rtl8139_private *np = netdev_priv(dev);
|
||||
return mii_nway_restart(&np->mii);
|
||||
struct rtl8139_private *tp = netdev_priv(dev);
|
||||
return mii_nway_restart(&tp->mii);
|
||||
}
|
||||
|
||||
static u32 rtl8139_get_link(struct net_device *dev)
|
||||
{
|
||||
struct rtl8139_private *np = netdev_priv(dev);
|
||||
return mii_link_ok(&np->mii);
|
||||
struct rtl8139_private *tp = netdev_priv(dev);
|
||||
return mii_link_ok(&tp->mii);
|
||||
}
|
||||
|
||||
static u32 rtl8139_get_msglevel(struct net_device *dev)
|
||||
{
|
||||
struct rtl8139_private *np = netdev_priv(dev);
|
||||
return np->msg_enable;
|
||||
struct rtl8139_private *tp = netdev_priv(dev);
|
||||
return tp->msg_enable;
|
||||
}
|
||||
|
||||
static void rtl8139_set_msglevel(struct net_device *dev, u32 datum)
|
||||
{
|
||||
struct rtl8139_private *np = netdev_priv(dev);
|
||||
np->msg_enable = datum;
|
||||
struct rtl8139_private *tp = netdev_priv(dev);
|
||||
tp->msg_enable = datum;
|
||||
}
|
||||
|
||||
static int rtl8139_get_regs_len(struct net_device *dev)
|
||||
{
|
||||
struct rtl8139_private *np;
|
||||
struct rtl8139_private *tp;
|
||||
/* 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;
|
||||
tp = netdev_priv(dev);
|
||||
return tp->regs_len;
|
||||
}
|
||||
|
||||
static void rtl8139_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regbuf)
|
||||
{
|
||||
struct rtl8139_private *np;
|
||||
struct rtl8139_private *tp;
|
||||
|
||||
/* TODO: we are too slack to do reg dumping for pio, for now */
|
||||
if (use_io)
|
||||
return;
|
||||
np = netdev_priv(dev);
|
||||
tp = netdev_priv(dev);
|
||||
|
||||
regs->version = RTL_REGS_VER;
|
||||
|
||||
spin_lock_irq(&np->lock);
|
||||
memcpy_fromio(regbuf, np->mmio_addr, regs->len);
|
||||
spin_unlock_irq(&np->lock);
|
||||
spin_lock_irq(&tp->lock);
|
||||
memcpy_fromio(regbuf, tp->mmio_addr, regs->len);
|
||||
spin_unlock_irq(&tp->lock);
|
||||
}
|
||||
|
||||
static int rtl8139_get_sset_count(struct net_device *dev, int sset)
|
||||
|
|
@ -2454,12 +2438,12 @@ static int rtl8139_get_sset_count(struct net_device *dev, int sset)
|
|||
|
||||
static void rtl8139_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *stats, u64 *data)
|
||||
{
|
||||
struct rtl8139_private *np = netdev_priv(dev);
|
||||
struct rtl8139_private *tp = netdev_priv(dev);
|
||||
|
||||
data[0] = np->xstats.early_rx;
|
||||
data[1] = np->xstats.tx_buf_mapped;
|
||||
data[2] = np->xstats.tx_timeouts;
|
||||
data[3] = np->xstats.rx_lost_in_ring;
|
||||
data[0] = tp->xstats.early_rx;
|
||||
data[1] = tp->xstats.tx_buf_mapped;
|
||||
data[2] = tp->xstats.tx_timeouts;
|
||||
data[3] = tp->xstats.rx_lost_in_ring;
|
||||
}
|
||||
|
||||
static void rtl8139_get_strings(struct net_device *dev, u32 stringset, u8 *data)
|
||||
|
|
@ -2486,15 +2470,15 @@ static const struct ethtool_ops rtl8139_ethtool_ops = {
|
|||
|
||||
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
|
||||
{
|
||||
struct rtl8139_private *np = netdev_priv(dev);
|
||||
struct rtl8139_private *tp = netdev_priv(dev);
|
||||
int rc;
|
||||
|
||||
if (!netif_running(dev))
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irq(&np->lock);
|
||||
rc = generic_mii_ioctl(&np->mii, if_mii(rq), cmd, NULL);
|
||||
spin_unlock_irq(&np->lock);
|
||||
spin_lock_irq(&tp->lock);
|
||||
rc = generic_mii_ioctl(&tp->mii, if_mii(rq), cmd, NULL);
|
||||
spin_unlock_irq(&tp->lock);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -2527,7 +2511,7 @@ static void __set_rx_mode (struct net_device *dev)
|
|||
int i, rx_mode;
|
||||
u32 tmp;
|
||||
|
||||
DPRINTK ("%s: rtl8139_set_rx_mode(%4.4x) done -- Rx config %8.8lx.\n",
|
||||
pr_debug("%s: rtl8139_set_rx_mode(%4.4x) done -- Rx config %8.8lx.\n",
|
||||
dev->name, dev->flags, RTL_R32 (RxConfig));
|
||||
|
||||
/* Note: do not reorder, GCC is clever about common statements. */
|
||||
|
|
@ -2643,7 +2627,7 @@ static int __init rtl8139_init_module (void)
|
|||
* even if no 8139 board is found.
|
||||
*/
|
||||
#ifdef MODULE
|
||||
printk (KERN_INFO RTL8139_DRIVER_NAME "\n");
|
||||
pr_info(RTL8139_DRIVER_NAME "\n");
|
||||
#endif
|
||||
|
||||
return pci_register_driver(&rtl8139_pci_driver);
|
||||
|
|
|
|||
|
|
@ -122,13 +122,13 @@ static char version[] __initdata =
|
|||
#define ISCP_BUSY 0x00010000
|
||||
#define MACH_IS_APRICOT 0
|
||||
#else
|
||||
#define WSWAPrfd(x) ((struct i596_rfd *)(x))
|
||||
#define WSWAPrbd(x) ((struct i596_rbd *)(x))
|
||||
#define WSWAPiscp(x) ((struct i596_iscp *)(x))
|
||||
#define WSWAPscb(x) ((struct i596_scb *)(x))
|
||||
#define WSWAPcmd(x) ((struct i596_cmd *)(x))
|
||||
#define WSWAPtbd(x) ((struct i596_tbd *)(x))
|
||||
#define WSWAPchar(x) ((char *)(x))
|
||||
#define WSWAPrfd(x) ((struct i596_rfd *)((long)x))
|
||||
#define WSWAPrbd(x) ((struct i596_rbd *)((long)x))
|
||||
#define WSWAPiscp(x) ((struct i596_iscp *)((long)x))
|
||||
#define WSWAPscb(x) ((struct i596_scb *)((long)x))
|
||||
#define WSWAPcmd(x) ((struct i596_cmd *)((long)x))
|
||||
#define WSWAPtbd(x) ((struct i596_tbd *)((long)x))
|
||||
#define WSWAPchar(x) ((char *)((long)x))
|
||||
#define ISCP_BUSY 0x0001
|
||||
#define MACH_IS_APRICOT 1
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -74,14 +74,8 @@ EXPORT_SYMBOL(ei_netdev_ops);
|
|||
struct net_device *__alloc_ei_netdev(int size)
|
||||
{
|
||||
struct net_device *dev = ____alloc_ei_netdev(size);
|
||||
#ifdef CONFIG_COMPAT_NET_DEV_OPS
|
||||
if (dev) {
|
||||
dev->hard_start_xmit = ei_start_xmit;
|
||||
dev->get_stats = ei_get_stats;
|
||||
dev->set_multicast_list = ei_set_multicast_list;
|
||||
dev->tx_timeout = ei_tx_timeout;
|
||||
}
|
||||
#endif
|
||||
if (dev)
|
||||
dev->netdev_ops = &ei_netdev_ops;
|
||||
return dev;
|
||||
}
|
||||
EXPORT_SYMBOL(__alloc_ei_netdev);
|
||||
|
|
|
|||
|
|
@ -79,14 +79,8 @@ EXPORT_SYMBOL(eip_netdev_ops);
|
|||
struct net_device *__alloc_eip_netdev(int size)
|
||||
{
|
||||
struct net_device *dev = ____alloc_ei_netdev(size);
|
||||
#ifdef CONFIG_COMPAT_NET_DEV_OPS
|
||||
if (dev) {
|
||||
dev->hard_start_xmit = eip_start_xmit;
|
||||
dev->get_stats = eip_get_stats;
|
||||
dev->set_multicast_list = eip_set_multicast_list;
|
||||
dev->tx_timeout = eip_tx_timeout;
|
||||
}
|
||||
#endif
|
||||
if (dev)
|
||||
dev->netdev_ops = &eip_netdev_ops;
|
||||
return dev;
|
||||
}
|
||||
EXPORT_SYMBOL(__alloc_eip_netdev);
|
||||
|
|
@ -97,16 +91,15 @@ void NS8390p_init(struct net_device *dev, int startp)
|
|||
}
|
||||
EXPORT_SYMBOL(NS8390p_init);
|
||||
|
||||
#if defined(MODULE)
|
||||
|
||||
int init_module(void)
|
||||
static int __init NS8390p_init_module(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cleanup_module(void)
|
||||
static void __exit NS8390p_cleanup_module(void)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* MODULE */
|
||||
module_init(NS8390p_init_module);
|
||||
module_exit(NS8390p_cleanup_module);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
#
|
||||
# Network device configuration
|
||||
#
|
||||
|
|
@ -26,15 +25,6 @@ menuconfig NETDEVICES
|
|||
# that for each of the symbols.
|
||||
if NETDEVICES
|
||||
|
||||
config COMPAT_NET_DEV_OPS
|
||||
default y
|
||||
bool "Enable older network device API compatibility"
|
||||
---help---
|
||||
This option enables kernel compatibility with older network devices
|
||||
that do not use net_device_ops interface.
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config IFB
|
||||
tristate "Intermediate Functional Block support"
|
||||
depends on NET_CLS_ACT
|
||||
|
|
@ -526,15 +516,16 @@ config STNIC
|
|||
config SH_ETH
|
||||
tristate "Renesas SuperH Ethernet support"
|
||||
depends on SUPERH && \
|
||||
(CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712 || CPU_SUBTYPE_SH7763 || \
|
||||
CPU_SUBTYPE_SH7619)
|
||||
(CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712 || \
|
||||
CPU_SUBTYPE_SH7763 || CPU_SUBTYPE_SH7619 || \
|
||||
CPU_SUBTYPE_SH7724)
|
||||
select CRC32
|
||||
select MII
|
||||
select MDIO_BITBANG
|
||||
select PHYLIB
|
||||
help
|
||||
Renesas SuperH Ethernet device driver.
|
||||
This driver support SH7710, SH7712, SH7763 and SH7619.
|
||||
This driver support SH7710, SH7712, SH7763, SH7619, and SH7724.
|
||||
|
||||
config SUNLANCE
|
||||
tristate "Sun LANCE support"
|
||||
|
|
@ -927,6 +918,16 @@ config NET_NETX
|
|||
To compile this driver as a module, choose M here. The module
|
||||
will be called netx-eth.
|
||||
|
||||
config TI_DAVINCI_EMAC
|
||||
tristate "TI DaVinci EMAC Support"
|
||||
depends on ARM && ARCH_DAVINCI
|
||||
select PHYLIB
|
||||
help
|
||||
This driver supports TI's DaVinci Ethernet .
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called davinci_emac_driver. This is recommended.
|
||||
|
||||
config DM9000
|
||||
tristate "DM9000 support"
|
||||
depends on ARM || BLACKFIN || MIPS
|
||||
|
|
@ -1000,7 +1001,7 @@ config SMC911X
|
|||
|
||||
config SMSC911X
|
||||
tristate "SMSC LAN911x/LAN921x families embedded ethernet support"
|
||||
depends on ARM || SUPERH
|
||||
depends on ARM || SUPERH || BLACKFIN
|
||||
select CRC32
|
||||
select MII
|
||||
select PHYLIB
|
||||
|
|
@ -1722,6 +1723,11 @@ config TLAN
|
|||
|
||||
Please email feedback to <[email protected]>.
|
||||
|
||||
config KS8842
|
||||
tristate "Micrel KSZ8842"
|
||||
help
|
||||
This platform driver is for Micrel KSZ8842 chip.
|
||||
|
||||
config VIA_RHINE
|
||||
tristate "VIA Rhine support"
|
||||
depends on NET_PCI && PCI
|
||||
|
|
@ -1858,8 +1864,8 @@ config 68360_ENET
|
|||
the Motorola 68360 processor.
|
||||
|
||||
config FEC
|
||||
bool "FEC ethernet controller (of ColdFire CPUs)"
|
||||
depends on M523x || M527x || M5272 || M528x || M520x || M532x || MACH_MX27
|
||||
bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)"
|
||||
depends on M523x || M527x || M5272 || M528x || M520x || M532x || MACH_MX27 || ARCH_MX35
|
||||
help
|
||||
Say Y here if you want to use the built-in 10/100 Fast ethernet
|
||||
controller on some Motorola ColdFire and Freescale i.MX processors.
|
||||
|
|
@ -2362,7 +2368,7 @@ config UGETH_TX_ON_DEMAND
|
|||
|
||||
config MV643XX_ETH
|
||||
tristate "Marvell Discovery (643XX) and Orion ethernet support"
|
||||
depends on MV64360 || MV64X60 || (PPC_MULTIPLATFORM && PPC32) || PLAT_ORION
|
||||
depends on MV64X60 || PPC32 || PLAT_ORION
|
||||
select INET_LRO
|
||||
select PHYLIB
|
||||
help
|
||||
|
|
@ -2373,6 +2379,14 @@ config MV643XX_ETH
|
|||
Some boards that use the Discovery chipset are the Momenco
|
||||
Ocelot C and Jaguar ATX and Pegasos II.
|
||||
|
||||
config XILINX_LL_TEMAC
|
||||
tristate "Xilinx LL TEMAC (LocalLink Tri-mode Ethernet MAC) driver"
|
||||
select PHYLIB
|
||||
depends on PPC_DCR_NATIVE
|
||||
help
|
||||
This driver supports the Xilinx 10/100/1000 LocalLink TEMAC
|
||||
core used in Xilinx Spartan and Virtex FPGAs
|
||||
|
||||
config QLA3XXX
|
||||
tristate "QLogic QLA3XXX Network Driver Support"
|
||||
depends on PCI
|
||||
|
|
@ -2446,10 +2460,14 @@ menuconfig NETDEV_10000
|
|||
|
||||
if NETDEV_10000
|
||||
|
||||
config MDIO
|
||||
tristate
|
||||
|
||||
config CHELSIO_T1
|
||||
tristate "Chelsio 10Gb Ethernet support"
|
||||
depends on PCI
|
||||
select CRC32
|
||||
select MDIO
|
||||
help
|
||||
This driver supports Chelsio gigabit and 10-gigabit
|
||||
Ethernet cards. More information about adapter features and
|
||||
|
|
@ -2482,6 +2500,7 @@ config CHELSIO_T3
|
|||
tristate "Chelsio Communications T3 10Gb Ethernet support"
|
||||
depends on CHELSIO_T3_DEPENDS
|
||||
select FW_LOADER
|
||||
select MDIO
|
||||
help
|
||||
This driver supports Chelsio T3-based gigabit and 10Gb Ethernet
|
||||
adapters.
|
||||
|
|
@ -2517,6 +2536,7 @@ config ENIC
|
|||
config IXGBE
|
||||
tristate "Intel(R) 10GbE PCI Express adapters support"
|
||||
depends on PCI && INET
|
||||
select MDIO
|
||||
---help---
|
||||
This driver supports Intel(R) 10GbE PCI Express family of
|
||||
adapters. For more information on how to identify your adapter, go
|
||||
|
|
@ -2679,6 +2699,7 @@ config TEHUTI
|
|||
config BNX2X
|
||||
tristate "Broadcom NetXtremeII 10Gb support"
|
||||
depends on PCI
|
||||
select FW_LOADER
|
||||
select ZLIB_INFLATE
|
||||
select LIBCRC32C
|
||||
help
|
||||
|
|
@ -2715,6 +2736,8 @@ source "drivers/net/wan/Kconfig"
|
|||
|
||||
source "drivers/atm/Kconfig"
|
||||
|
||||
source "drivers/ieee802154/Kconfig"
|
||||
|
||||
source "drivers/s390/net/Kconfig"
|
||||
|
||||
config XEN_NETDEV_FRONTEND
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
# Makefile for the Linux network (ethercard) device drivers.
|
||||
#
|
||||
|
||||
obj-$(CONFIG_TI_DAVINCI_EMAC) += davinci_emac.o
|
||||
|
||||
obj-$(CONFIG_E1000) += e1000/
|
||||
obj-$(CONFIG_E1000E) += e1000e/
|
||||
obj-$(CONFIG_IBM_NEW_EMAC) += ibm_newemac/
|
||||
|
|
@ -85,6 +87,7 @@ obj-$(CONFIG_TC35815) += tc35815.o
|
|||
obj-$(CONFIG_SKGE) += skge.o
|
||||
obj-$(CONFIG_SKY2) += sky2.o
|
||||
obj-$(CONFIG_SKFP) += skfp/
|
||||
obj-$(CONFIG_KS8842) += ks8842.o
|
||||
obj-$(CONFIG_VIA_RHINE) += via-rhine.o
|
||||
obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o
|
||||
obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o
|
||||
|
|
@ -96,6 +99,7 @@ obj-$(CONFIG_SH_ETH) += sh_eth.o
|
|||
#
|
||||
|
||||
obj-$(CONFIG_MII) += mii.o
|
||||
obj-$(CONFIG_MDIO) += mdio.o
|
||||
obj-$(CONFIG_PHYLIB) += phy/
|
||||
|
||||
obj-$(CONFIG_SUNDANCE) += sundance.o
|
||||
|
|
@ -135,6 +139,8 @@ obj-$(CONFIG_AX88796) += ax88796.o
|
|||
|
||||
obj-$(CONFIG_TSI108_ETH) += tsi108_eth.o
|
||||
obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o
|
||||
ll_temac-objs := ll_temac_main.o ll_temac_mdio.o
|
||||
obj-$(CONFIG_XILINX_LL_TEMAC) += ll_temac.o
|
||||
obj-$(CONFIG_QLA3XXX) += qla3xxx.o
|
||||
obj-$(CONFIG_QLGE) += qlge/
|
||||
|
||||
|
|
|
|||
|
|
@ -564,7 +564,7 @@ static int lance_start_xmit (struct sk_buff *skb, struct net_device *dev)
|
|||
|
||||
if (!TX_BUFFS_AVAIL){
|
||||
local_irq_restore(flags);
|
||||
return -1;
|
||||
return NETDEV_TX_LOCKED;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_DRIVER
|
||||
|
|
|
|||
|
|
@ -2573,7 +2573,6 @@ restart:
|
|||
netif_wake_queue(dev);
|
||||
}
|
||||
|
||||
dev->trans_start = jiffies;
|
||||
return NETDEV_TX_OK;
|
||||
|
||||
overflow:
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
static const char version[] = KERN_INFO "ipddp.c:v0.01 8/28/97 Bradford W. Johnson <[email protected]>\n";
|
||||
|
||||
static struct ipddp_route *ipddp_route_list;
|
||||
static DEFINE_SPINLOCK(ipddp_route_lock);
|
||||
|
||||
#ifdef CONFIG_IPDDP_ENCAP
|
||||
static int ipddp_mode = IPDDP_ENCAP;
|
||||
|
|
@ -50,7 +51,7 @@ static int ipddp_mode = IPDDP_DECAP;
|
|||
static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev);
|
||||
static int ipddp_create(struct ipddp_route *new_rt);
|
||||
static int ipddp_delete(struct ipddp_route *rt);
|
||||
static struct ipddp_route* ipddp_find_route(struct ipddp_route *rt);
|
||||
static struct ipddp_route* __ipddp_find_route(struct ipddp_route *rt);
|
||||
static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
|
||||
|
||||
static const struct net_device_ops ipddp_netdev_ops = {
|
||||
|
|
@ -71,6 +72,7 @@ static struct net_device * __init ipddp_init(void)
|
|||
if (!dev)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
|
||||
strcpy(dev->name, "ipddp%d");
|
||||
|
||||
if (version_printed++ == 0)
|
||||
|
|
@ -113,11 +115,13 @@ static struct net_device * __init ipddp_init(void)
|
|||
*/
|
||||
static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
__be32 paddr = ((struct rtable*)skb->dst)->rt_gateway;
|
||||
__be32 paddr = skb_rtable(skb)->rt_gateway;
|
||||
struct ddpehdr *ddp;
|
||||
struct ipddp_route *rt;
|
||||
struct atalk_addr *our_addr;
|
||||
|
||||
spin_lock(&ipddp_route_lock);
|
||||
|
||||
/*
|
||||
* Find appropriate route to use, based only on IP number.
|
||||
*/
|
||||
|
|
@ -126,8 +130,10 @@ static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
if(rt->ip == paddr)
|
||||
break;
|
||||
}
|
||||
if(rt == NULL)
|
||||
if(rt == NULL) {
|
||||
spin_unlock(&ipddp_route_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
our_addr = atalk_find_dev_addr(rt->dev);
|
||||
|
||||
|
|
@ -173,6 +179,8 @@ static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
if(aarp_send_ddp(rt->dev, skb, &rt->at, NULL) < 0)
|
||||
dev_kfree_skb(skb);
|
||||
|
||||
spin_unlock(&ipddp_route_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -195,7 +203,9 @@ static int ipddp_create(struct ipddp_route *new_rt)
|
|||
return -ENETUNREACH;
|
||||
}
|
||||
|
||||
if (ipddp_find_route(rt)) {
|
||||
spin_lock_bh(&ipddp_route_lock);
|
||||
if (__ipddp_find_route(rt)) {
|
||||
spin_unlock_bh(&ipddp_route_lock);
|
||||
kfree(rt);
|
||||
return -EEXIST;
|
||||
}
|
||||
|
|
@ -203,6 +213,8 @@ static int ipddp_create(struct ipddp_route *new_rt)
|
|||
rt->next = ipddp_route_list;
|
||||
ipddp_route_list = rt;
|
||||
|
||||
spin_unlock_bh(&ipddp_route_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -215,6 +227,7 @@ static int ipddp_delete(struct ipddp_route *rt)
|
|||
struct ipddp_route **r = &ipddp_route_list;
|
||||
struct ipddp_route *tmp;
|
||||
|
||||
spin_lock_bh(&ipddp_route_lock);
|
||||
while((tmp = *r) != NULL)
|
||||
{
|
||||
if(tmp->ip == rt->ip
|
||||
|
|
@ -222,19 +235,21 @@ static int ipddp_delete(struct ipddp_route *rt)
|
|||
&& tmp->at.s_node == rt->at.s_node)
|
||||
{
|
||||
*r = tmp->next;
|
||||
spin_unlock_bh(&ipddp_route_lock);
|
||||
kfree(tmp);
|
||||
return 0;
|
||||
}
|
||||
r = &tmp->next;
|
||||
}
|
||||
|
||||
spin_unlock_bh(&ipddp_route_lock);
|
||||
return (-ENOENT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find a routing entry, we only return a FULL match
|
||||
*/
|
||||
static struct ipddp_route* ipddp_find_route(struct ipddp_route *rt)
|
||||
static struct ipddp_route* __ipddp_find_route(struct ipddp_route *rt)
|
||||
{
|
||||
struct ipddp_route *f;
|
||||
|
||||
|
|
@ -252,7 +267,7 @@ static struct ipddp_route* ipddp_find_route(struct ipddp_route *rt)
|
|||
static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||
{
|
||||
struct ipddp_route __user *rt = ifr->ifr_data;
|
||||
struct ipddp_route rcp;
|
||||
struct ipddp_route rcp, rcp2, *rp;
|
||||
|
||||
if(!capable(CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
|
|
@ -266,9 +281,19 @@ static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
|||
return (ipddp_create(&rcp));
|
||||
|
||||
case SIOCFINDIPDDPRT:
|
||||
if(copy_to_user(rt, ipddp_find_route(&rcp), sizeof(struct ipddp_route)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
spin_lock_bh(&ipddp_route_lock);
|
||||
rp = __ipddp_find_route(&rcp);
|
||||
if (rp)
|
||||
memcpy(&rcp2, rp, sizeof(rcp2));
|
||||
spin_unlock_bh(&ipddp_route_lock);
|
||||
|
||||
if (rp) {
|
||||
if (copy_to_user(rt, &rcp2,
|
||||
sizeof(struct ipddp_route)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
} else
|
||||
return -ENOENT;
|
||||
|
||||
case SIOCDELIPDDPRT:
|
||||
return (ipddp_delete(&rcp));
|
||||
|
|
|
|||
|
|
@ -829,7 +829,7 @@ static int at91ether_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
dev->trans_start = jiffies;
|
||||
} else {
|
||||
printk(KERN_ERR "at91_ether.c: at91ether_start_xmit() called, but device is busy!\n");
|
||||
return 1; /* if we return anything but zero, dev.c:1055 calls kfree_skb(skb)
|
||||
return NETDEV_TX_BUSY; /* if we return anything but zero, dev.c:1055 calls kfree_skb(skb)
|
||||
on this skb, he also reports -ENETDOWN and printk's, so either
|
||||
we free and return(0) or don't free and return 1 */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -253,7 +253,7 @@ static int ep93xx_rx(struct net_device *dev, int processed, int budget)
|
|||
skb = dev_alloc_skb(length + 2);
|
||||
if (likely(skb != NULL)) {
|
||||
skb_reserve(skb, 2);
|
||||
dma_sync_single(NULL, ep->descs->rdesc[entry].buf_addr,
|
||||
dma_sync_single_for_cpu(NULL, ep->descs->rdesc[entry].buf_addr,
|
||||
length, DMA_FROM_DEVICE);
|
||||
skb_copy_to_linear_data(skb, ep->rx_buf[entry], length);
|
||||
skb_put(skb, length);
|
||||
|
|
@ -331,7 +331,7 @@ static int ep93xx_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
ep->descs->tdesc[entry].tdesc1 =
|
||||
TDESC1_EOF | (entry << 16) | (skb->len & 0xfff);
|
||||
skb_copy_and_csum_dev(skb, ep->tx_buf[entry]);
|
||||
dma_sync_single(NULL, ep->descs->tdesc[entry].buf_addr,
|
||||
dma_sync_single_for_cpu(NULL, ep->descs->tdesc[entry].buf_addr,
|
||||
skb->len, DMA_TO_DEVICE);
|
||||
dev_kfree_skb(skb);
|
||||
|
||||
|
|
|
|||
|
|
@ -526,7 +526,7 @@ ether3_sendpacket(struct sk_buff *skb, struct net_device *dev)
|
|||
|
||||
if (priv(dev)->tx_tail == next_ptr) {
|
||||
local_irq_restore(flags);
|
||||
return 1; /* unable to queue */
|
||||
return NETDEV_TX_BUSY; /* unable to queue */
|
||||
}
|
||||
|
||||
dev->trans_start = jiffies;
|
||||
|
|
|
|||
|
|
@ -562,8 +562,8 @@ static int eth_poll(struct napi_struct *napi, int budget)
|
|||
dma_unmap_single(&dev->dev, desc->data - NET_IP_ALIGN,
|
||||
RX_BUFF_SIZE, DMA_FROM_DEVICE);
|
||||
#else
|
||||
dma_sync_single(&dev->dev, desc->data - NET_IP_ALIGN,
|
||||
RX_BUFF_SIZE, DMA_FROM_DEVICE);
|
||||
dma_sync_single_for_cpu(&dev->dev, desc->data - NET_IP_ALIGN,
|
||||
RX_BUFF_SIZE, DMA_FROM_DEVICE);
|
||||
memcpy_swab32((u32 *)skb->data, (u32 *)port->rx_buff_tab[n],
|
||||
ALIGN(NET_IP_ALIGN + desc->pkt_len, 4) / 4);
|
||||
#endif
|
||||
|
|
@ -1151,7 +1151,7 @@ static int __devinit eth_init_one(struct platform_device *pdev)
|
|||
struct net_device *dev;
|
||||
struct eth_plat_info *plat = pdev->dev.platform_data;
|
||||
u32 regs_phys;
|
||||
char phy_id[BUS_ID_SIZE];
|
||||
char phy_id[MII_BUS_ID_SIZE + 3];
|
||||
int err;
|
||||
|
||||
if (!(dev = alloc_etherdev(sizeof(struct port))))
|
||||
|
|
@ -1209,7 +1209,7 @@ static int __devinit eth_init_one(struct platform_device *pdev)
|
|||
__raw_writel(DEFAULT_CORE_CNTRL, &port->regs->core_control);
|
||||
udelay(50);
|
||||
|
||||
snprintf(phy_id, BUS_ID_SIZE, PHY_ID_FMT, "0", plat->phy);
|
||||
snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, "0", plat->phy);
|
||||
port->phydev = phy_connect(dev, phy_id, &ixp4xx_adjust_link, 0,
|
||||
PHY_INTERFACE_MODE_MII);
|
||||
if ((err = IS_ERR(port->phydev)))
|
||||
|
|
|
|||
|
|
@ -271,7 +271,7 @@ static int atl1c_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
|
|||
struct atl1c_adapter *adapter = netdev_priv(netdev);
|
||||
|
||||
if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE |
|
||||
WAKE_MCAST | WAKE_BCAST | WAKE_MCAST))
|
||||
WAKE_UCAST | WAKE_BCAST | WAKE_MCAST))
|
||||
return -EOPNOTSUPP;
|
||||
/* these settings will always override what we currently have */
|
||||
adapter->wol = 0;
|
||||
|
|
|
|||
|
|
@ -163,6 +163,24 @@ static inline void atl1c_irq_reset(struct atl1c_adapter *adapter)
|
|||
atl1c_irq_enable(adapter);
|
||||
}
|
||||
|
||||
/*
|
||||
* atl1c_wait_until_idle - wait up to AT_HW_MAX_IDLE_DELAY reads
|
||||
* of the idle status register until the device is actually idle
|
||||
*/
|
||||
static u32 atl1c_wait_until_idle(struct atl1c_hw *hw)
|
||||
{
|
||||
int timeout;
|
||||
u32 data;
|
||||
|
||||
for (timeout = 0; timeout < AT_HW_MAX_IDLE_DELAY; timeout++) {
|
||||
AT_READ_REG(hw, REG_IDLE_STATUS, &data);
|
||||
if ((data & IDLE_STATUS_MASK) == 0)
|
||||
return 0;
|
||||
msleep(1);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/*
|
||||
* atl1c_phy_config - Timer Call-back
|
||||
* @data: pointer to netdev cast into an unsigned long
|
||||
|
|
@ -220,11 +238,11 @@ static void atl1c_check_link_status(struct atl1c_adapter *adapter)
|
|||
/* link down */
|
||||
if (netif_carrier_ok(netdev)) {
|
||||
hw->hibernate = true;
|
||||
atl1c_set_aspm(hw, false);
|
||||
if (atl1c_stop_mac(hw) != 0)
|
||||
if (netif_msg_hw(adapter))
|
||||
dev_warn(&pdev->dev,
|
||||
"stop mac failed\n");
|
||||
atl1c_set_aspm(hw, false);
|
||||
}
|
||||
netif_carrier_off(netdev);
|
||||
} else {
|
||||
|
|
@ -240,10 +258,10 @@ static void atl1c_check_link_status(struct atl1c_adapter *adapter)
|
|||
adapter->link_duplex != duplex) {
|
||||
adapter->link_speed = speed;
|
||||
adapter->link_duplex = duplex;
|
||||
atl1c_set_aspm(hw, true);
|
||||
atl1c_enable_tx_ctrl(hw);
|
||||
atl1c_enable_rx_ctrl(hw);
|
||||
atl1c_setup_mac_ctrl(adapter);
|
||||
atl1c_set_aspm(hw, true);
|
||||
if (netif_msg_link(adapter))
|
||||
dev_info(&pdev->dev,
|
||||
"%s: %s NIC Link is Up<%d Mbps %s>\n",
|
||||
|
|
@ -1106,7 +1124,6 @@ static void atl1c_configure_dma(struct atl1c_adapter *adapter)
|
|||
static int atl1c_stop_mac(struct atl1c_hw *hw)
|
||||
{
|
||||
u32 data;
|
||||
int timeout;
|
||||
|
||||
AT_READ_REG(hw, REG_RXQ_CTRL, &data);
|
||||
data &= ~(RXQ1_CTRL_EN | RXQ2_CTRL_EN |
|
||||
|
|
@ -1117,25 +1134,13 @@ static int atl1c_stop_mac(struct atl1c_hw *hw)
|
|||
data &= ~TXQ_CTRL_EN;
|
||||
AT_WRITE_REG(hw, REG_TWSI_CTRL, data);
|
||||
|
||||
for (timeout = 0; timeout < AT_HW_MAX_IDLE_DELAY; timeout++) {
|
||||
AT_READ_REG(hw, REG_IDLE_STATUS, &data);
|
||||
if ((data & (IDLE_STATUS_RXQ_NO_IDLE |
|
||||
IDLE_STATUS_TXQ_NO_IDLE)) == 0)
|
||||
break;
|
||||
msleep(1);
|
||||
}
|
||||
atl1c_wait_until_idle(hw);
|
||||
|
||||
AT_READ_REG(hw, REG_MAC_CTRL, &data);
|
||||
data &= ~(MAC_CTRL_TX_EN | MAC_CTRL_RX_EN);
|
||||
AT_WRITE_REG(hw, REG_MAC_CTRL, data);
|
||||
|
||||
for (timeout = 0; timeout < AT_HW_MAX_IDLE_DELAY; timeout++) {
|
||||
AT_READ_REG(hw, REG_IDLE_STATUS, &data);
|
||||
if ((data & IDLE_STATUS_MASK) == 0)
|
||||
return 0;
|
||||
msleep(1);
|
||||
}
|
||||
return data;
|
||||
return (int)atl1c_wait_until_idle(hw);
|
||||
}
|
||||
|
||||
static void atl1c_enable_rx_ctrl(struct atl1c_hw *hw)
|
||||
|
|
@ -1178,8 +1183,6 @@ static int atl1c_reset_mac(struct atl1c_hw *hw)
|
|||
{
|
||||
struct atl1c_adapter *adapter = (struct atl1c_adapter *)hw->adapter;
|
||||
struct pci_dev *pdev = adapter->pdev;
|
||||
u32 idle_status_data = 0;
|
||||
int timeout = 0;
|
||||
int ret;
|
||||
|
||||
AT_WRITE_REG(hw, REG_IMR, 0);
|
||||
|
|
@ -1198,15 +1201,10 @@ static int atl1c_reset_mac(struct atl1c_hw *hw)
|
|||
AT_WRITE_FLUSH(hw);
|
||||
msleep(10);
|
||||
/* Wait at least 10ms for All module to be Idle */
|
||||
for (timeout = 0; timeout < AT_HW_MAX_IDLE_DELAY; timeout++) {
|
||||
AT_READ_REG(hw, REG_IDLE_STATUS, &idle_status_data);
|
||||
if ((idle_status_data & IDLE_STATUS_MASK) == 0)
|
||||
break;
|
||||
msleep(1);
|
||||
}
|
||||
if (timeout >= AT_HW_MAX_IDLE_DELAY) {
|
||||
|
||||
if (atl1c_wait_until_idle(hw)) {
|
||||
dev_err(&pdev->dev,
|
||||
"MAC state machine cann't be idle since"
|
||||
"MAC state machine can't be idle since"
|
||||
" disabled for 10ms second\n");
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -1242,9 +1240,7 @@ static void atl1c_set_aspm(struct atl1c_hw *hw, bool linkup)
|
|||
|
||||
AT_READ_REG(hw, REG_PM_CTRL, &pm_ctrl_data);
|
||||
|
||||
pm_ctrl_data &= PM_CTRL_SERDES_PD_EX_L1;
|
||||
pm_ctrl_data |= ~PM_CTRL_SERDES_BUDS_RX_L1_EN;
|
||||
pm_ctrl_data |= ~PM_CTRL_SERDES_L1_EN;
|
||||
pm_ctrl_data &= ~PM_CTRL_SERDES_PD_EX_L1;
|
||||
pm_ctrl_data &= ~(PM_CTRL_L1_ENTRY_TIMER_MASK <<
|
||||
PM_CTRL_L1_ENTRY_TIMER_SHIFT);
|
||||
|
||||
|
|
@ -1254,19 +1250,11 @@ static void atl1c_set_aspm(struct atl1c_hw *hw, bool linkup)
|
|||
pm_ctrl_data |= PM_CTRL_SERDES_PLL_L1_EN;
|
||||
pm_ctrl_data &= ~PM_CTRL_CLK_SWH_L1;
|
||||
|
||||
if (hw->ctrl_flags & ATL1C_ASPM_L1_SUPPORT) {
|
||||
pm_ctrl_data |= AT_ASPM_L1_TIMER <<
|
||||
PM_CTRL_L1_ENTRY_TIMER_SHIFT;
|
||||
pm_ctrl_data |= PM_CTRL_ASPM_L1_EN;
|
||||
} else
|
||||
pm_ctrl_data &= ~PM_CTRL_ASPM_L1_EN;
|
||||
|
||||
if (hw->ctrl_flags & ATL1C_ASPM_L0S_SUPPORT)
|
||||
pm_ctrl_data |= PM_CTRL_ASPM_L0S_EN;
|
||||
else
|
||||
pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN;
|
||||
|
||||
pm_ctrl_data |= PM_CTRL_SERDES_BUDS_RX_L1_EN;
|
||||
pm_ctrl_data |= PM_CTRL_SERDES_L1_EN;
|
||||
} else {
|
||||
pm_ctrl_data &= ~PM_CTRL_SERDES_BUDS_RX_L1_EN;
|
||||
pm_ctrl_data &= ~PM_CTRL_SERDES_L1_EN;
|
||||
pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN;
|
||||
pm_ctrl_data &= ~PM_CTRL_SERDES_PLL_L1_EN;
|
||||
|
||||
|
|
@ -2123,7 +2111,6 @@ static int atl1c_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
|
|||
atl1c_tx_map(adapter, skb, tpd, type);
|
||||
atl1c_tx_queue(adapter, skb, tpd, type);
|
||||
|
||||
netdev->trans_start = jiffies;
|
||||
spin_unlock_irqrestore(&adapter->tx_lock, flags);
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -429,7 +429,6 @@ struct atl1e_adapter {
|
|||
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;
|
||||
|
|
|
|||
|
|
@ -1154,7 +1154,7 @@ static struct net_device_stats *atl1e_get_stats(struct net_device *netdev)
|
|||
{
|
||||
struct atl1e_adapter *adapter = netdev_priv(netdev);
|
||||
struct atl1e_hw_stats *hw_stats = &adapter->hw_stats;
|
||||
struct net_device_stats *net_stats = &adapter->net_stats;
|
||||
struct net_device_stats *net_stats = &netdev->stats;
|
||||
|
||||
net_stats->rx_packets = hw_stats->rx_ok;
|
||||
net_stats->tx_packets = hw_stats->tx_ok;
|
||||
|
|
@ -1182,7 +1182,7 @@ static struct net_device_stats *atl1e_get_stats(struct net_device *netdev)
|
|||
net_stats->tx_aborted_errors = hw_stats->tx_abort_col;
|
||||
net_stats->tx_window_errors = hw_stats->tx_late_col;
|
||||
|
||||
return &adapter->net_stats;
|
||||
return net_stats;
|
||||
}
|
||||
|
||||
static void atl1e_update_hw_stats(struct atl1e_adapter *adapter)
|
||||
|
|
@ -1310,7 +1310,7 @@ static irqreturn_t atl1e_intr(int irq, void *data)
|
|||
|
||||
/* link event */
|
||||
if (status & (ISR_GPHY | ISR_MANUAL)) {
|
||||
adapter->net_stats.tx_carrier_errors++;
|
||||
netdev->stats.tx_carrier_errors++;
|
||||
atl1e_link_chg_event(adapter);
|
||||
break;
|
||||
}
|
||||
|
|
@ -1602,7 +1602,7 @@ static u16 atl1e_cal_tdp_req(const struct sk_buff *skb)
|
|||
}
|
||||
|
||||
if (skb_is_gso(skb)) {
|
||||
if (skb->protocol == ntohs(ETH_P_IP) ||
|
||||
if (skb->protocol == htons(ETH_P_IP) ||
|
||||
(skb_shinfo(skb)->gso_type == SKB_GSO_TCPV6)) {
|
||||
proto_hdr_len = skb_transport_offset(skb) +
|
||||
tcp_hdrlen(skb);
|
||||
|
|
@ -1795,8 +1795,7 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter,
|
|||
memcpy(use_tpd, tpd, sizeof(struct atl1e_tpd_desc));
|
||||
|
||||
tx_buffer = atl1e_get_tx_buffer(adapter, use_tpd);
|
||||
if (tx_buffer->skb)
|
||||
BUG();
|
||||
BUG_ON(tx_buffer->skb);
|
||||
|
||||
tx_buffer->skb = NULL;
|
||||
tx_buffer->length =
|
||||
|
|
@ -1879,7 +1878,7 @@ static int atl1e_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
|
|||
TPD_VLAN_SHIFT;
|
||||
}
|
||||
|
||||
if (skb->protocol == ntohs(ETH_P_8021Q))
|
||||
if (skb->protocol == htons(ETH_P_8021Q))
|
||||
tpd->word3 |= 1 << TPD_VL_TAGGED_SHIFT;
|
||||
|
||||
if (skb_network_offset(skb) != ETH_HLEN)
|
||||
|
|
@ -1895,7 +1894,7 @@ static int atl1e_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
|
|||
atl1e_tx_map(adapter, skb, tpd);
|
||||
atl1e_tx_queue(adapter, tpd_req, tpd);
|
||||
|
||||
netdev->trans_start = jiffies;
|
||||
netdev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */
|
||||
spin_unlock_irqrestore(&adapter->tx_lock, flags);
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2213,8 +2213,7 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb,
|
|||
nr_frags = skb_shinfo(skb)->nr_frags;
|
||||
next_to_use = atomic_read(&tpd_ring->next_to_use);
|
||||
buffer_info = &tpd_ring->buffer_info[next_to_use];
|
||||
if (unlikely(buffer_info->skb))
|
||||
BUG();
|
||||
BUG_ON(buffer_info->skb);
|
||||
/* put skb in last TPD */
|
||||
buffer_info->skb = NULL;
|
||||
|
||||
|
|
@ -2280,8 +2279,8 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb,
|
|||
ATL1_MAX_TX_BUF_LEN;
|
||||
for (i = 0; i < nseg; i++) {
|
||||
buffer_info = &tpd_ring->buffer_info[next_to_use];
|
||||
if (unlikely(buffer_info->skb))
|
||||
BUG();
|
||||
BUG_ON(buffer_info->skb);
|
||||
|
||||
buffer_info->skb = NULL;
|
||||
buffer_info->length = (buf_len > ATL1_MAX_TX_BUF_LEN) ?
|
||||
ATL1_MAX_TX_BUF_LEN : buf_len;
|
||||
|
|
@ -2383,7 +2382,7 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
|
|||
|
||||
mss = skb_shinfo(skb)->gso_size;
|
||||
if (mss) {
|
||||
if (skb->protocol == ntohs(ETH_P_IP)) {
|
||||
if (skb->protocol == htons(ETH_P_IP)) {
|
||||
proto_hdr_len = (skb_transport_offset(skb) +
|
||||
tcp_hdrlen(skb));
|
||||
if (unlikely(proto_hdr_len > len)) {
|
||||
|
|
@ -2438,7 +2437,6 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
|
|||
atl1_tx_queue(adapter, count, ptpd);
|
||||
atl1_update_mailbox(adapter);
|
||||
mmiowb();
|
||||
netdev->trans_start = jiffies;
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -957,7 +957,7 @@ static int au1000_tx(struct sk_buff *skb, struct net_device *dev)
|
|||
/* We've wrapped around and the transmitter is still busy */
|
||||
netif_stop_queue(dev);
|
||||
aup->tx_full = 1;
|
||||
return 1;
|
||||
return NETDEV_TX_BUSY;
|
||||
}
|
||||
else if (buff_stat & TX_T_DONE) {
|
||||
update_tx_stats(dev, ptxd->status);
|
||||
|
|
|
|||
|
|
@ -782,7 +782,7 @@ static int b44_rx(struct b44 *bp, int budget)
|
|||
drop_it:
|
||||
b44_recycle_rx(bp, cons, bp->rx_prod);
|
||||
drop_it_no_recycle:
|
||||
bp->stats.rx_dropped++;
|
||||
bp->dev->stats.rx_dropped++;
|
||||
goto next_pkt;
|
||||
}
|
||||
|
||||
|
|
@ -1647,7 +1647,7 @@ static int b44_close(struct net_device *dev)
|
|||
static struct net_device_stats *b44_get_stats(struct net_device *dev)
|
||||
{
|
||||
struct b44 *bp = netdev_priv(dev);
|
||||
struct net_device_stats *nstat = &bp->stats;
|
||||
struct net_device_stats *nstat = &dev->stats;
|
||||
struct b44_hw_stats *hwstat = &bp->hw_stats;
|
||||
|
||||
/* Convert HW stats into netdevice stats. */
|
||||
|
|
|
|||
|
|
@ -384,7 +384,6 @@ struct b44 {
|
|||
|
||||
struct timer_list timer;
|
||||
|
||||
struct net_device_stats stats;
|
||||
struct b44_hw_stats hw_stats;
|
||||
|
||||
struct ssb_device *sdev;
|
||||
|
|
|
|||
|
|
@ -168,6 +168,7 @@ static void netdev_stats_update(struct be_adapter *adapter)
|
|||
struct be_port_rxf_stats *port_stats =
|
||||
&rxf_stats->port[adapter->port_num];
|
||||
struct net_device_stats *dev_stats = &adapter->stats.net_stats;
|
||||
struct be_erx_stats *erx_stats = &hw_stats->erx;
|
||||
|
||||
dev_stats->rx_packets = port_stats->rx_total_frames;
|
||||
dev_stats->tx_packets = port_stats->tx_unicastframes +
|
||||
|
|
@ -181,29 +182,33 @@ static void netdev_stats_update(struct be_adapter *adapter)
|
|||
dev_stats->rx_errors = port_stats->rx_crc_errors +
|
||||
port_stats->rx_alignment_symbol_errors +
|
||||
port_stats->rx_in_range_errors +
|
||||
port_stats->rx_out_range_errors + port_stats->rx_frame_too_long;
|
||||
port_stats->rx_out_range_errors +
|
||||
port_stats->rx_frame_too_long +
|
||||
port_stats->rx_dropped_too_small +
|
||||
port_stats->rx_dropped_too_short +
|
||||
port_stats->rx_dropped_header_too_small +
|
||||
port_stats->rx_dropped_tcp_length +
|
||||
port_stats->rx_dropped_runt +
|
||||
port_stats->rx_tcp_checksum_errs +
|
||||
port_stats->rx_ip_checksum_errs +
|
||||
port_stats->rx_udp_checksum_errs;
|
||||
|
||||
/* packet transmit problems */
|
||||
dev_stats->tx_errors = 0;
|
||||
|
||||
/* no space in linux buffers */
|
||||
dev_stats->rx_dropped = 0;
|
||||
|
||||
/* no space available in linux */
|
||||
dev_stats->tx_dropped = 0;
|
||||
|
||||
dev_stats->multicast = port_stats->tx_multicastframes;
|
||||
dev_stats->collisions = 0;
|
||||
/* no space in linux buffers: best possible approximation */
|
||||
dev_stats->rx_dropped = erx_stats->rx_drops_no_fragments[0];
|
||||
|
||||
/* detailed rx errors */
|
||||
dev_stats->rx_length_errors = port_stats->rx_in_range_errors +
|
||||
port_stats->rx_out_range_errors + port_stats->rx_frame_too_long;
|
||||
port_stats->rx_out_range_errors +
|
||||
port_stats->rx_frame_too_long;
|
||||
|
||||
/* receive ring buffer overflow */
|
||||
dev_stats->rx_over_errors = 0;
|
||||
|
||||
dev_stats->rx_crc_errors = port_stats->rx_crc_errors;
|
||||
|
||||
/* frame alignment errors */
|
||||
dev_stats->rx_frame_errors = port_stats->rx_alignment_symbol_errors;
|
||||
|
||||
/* receiver fifo overrun */
|
||||
/* drops_no_pbuf is no per i/f, it's per BE card */
|
||||
dev_stats->rx_fifo_errors = port_stats->rx_fifo_overflow +
|
||||
|
|
@ -211,6 +216,16 @@ static void netdev_stats_update(struct be_adapter *adapter)
|
|||
rxf_stats->rx_drops_no_pbuf;
|
||||
/* receiver missed packetd */
|
||||
dev_stats->rx_missed_errors = 0;
|
||||
|
||||
/* packet transmit problems */
|
||||
dev_stats->tx_errors = 0;
|
||||
|
||||
/* no space available in linux */
|
||||
dev_stats->tx_dropped = 0;
|
||||
|
||||
dev_stats->multicast = port_stats->tx_multicastframes;
|
||||
dev_stats->collisions = 0;
|
||||
|
||||
/* detailed tx_errors */
|
||||
dev_stats->tx_aborted_errors = 0;
|
||||
dev_stats->tx_carrier_errors = 0;
|
||||
|
|
@ -337,13 +352,10 @@ static void be_tx_stats_update(struct be_adapter *adapter,
|
|||
/* Determine number of WRB entries needed to xmit data in an skb */
|
||||
static u32 wrb_cnt_for_skb(struct sk_buff *skb, bool *dummy)
|
||||
{
|
||||
int cnt = 0;
|
||||
while (skb) {
|
||||
if (skb->len > skb->data_len)
|
||||
cnt++;
|
||||
cnt += skb_shinfo(skb)->nr_frags;
|
||||
skb = skb_shinfo(skb)->frag_list;
|
||||
}
|
||||
int cnt = (skb->len > skb->data_len);
|
||||
|
||||
cnt += skb_shinfo(skb)->nr_frags;
|
||||
|
||||
/* to account for hdr wrb */
|
||||
cnt++;
|
||||
if (cnt & 1) {
|
||||
|
|
@ -409,31 +421,28 @@ static int make_tx_wrbs(struct be_adapter *adapter,
|
|||
hdr = queue_head_node(txq);
|
||||
queue_head_inc(txq);
|
||||
|
||||
while (skb) {
|
||||
if (skb->len > skb->data_len) {
|
||||
int len = skb->len - skb->data_len;
|
||||
busaddr = pci_map_single(pdev, skb->data, len,
|
||||
PCI_DMA_TODEVICE);
|
||||
wrb = queue_head_node(txq);
|
||||
wrb_fill(wrb, busaddr, len);
|
||||
be_dws_cpu_to_le(wrb, sizeof(*wrb));
|
||||
queue_head_inc(txq);
|
||||
copied += len;
|
||||
}
|
||||
if (skb->len > skb->data_len) {
|
||||
int len = skb->len - skb->data_len;
|
||||
busaddr = pci_map_single(pdev, skb->data, len,
|
||||
PCI_DMA_TODEVICE);
|
||||
wrb = queue_head_node(txq);
|
||||
wrb_fill(wrb, busaddr, len);
|
||||
be_dws_cpu_to_le(wrb, sizeof(*wrb));
|
||||
queue_head_inc(txq);
|
||||
copied += len;
|
||||
}
|
||||
|
||||
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
|
||||
struct skb_frag_struct *frag =
|
||||
&skb_shinfo(skb)->frags[i];
|
||||
busaddr = pci_map_page(pdev, frag->page,
|
||||
frag->page_offset,
|
||||
frag->size, PCI_DMA_TODEVICE);
|
||||
wrb = queue_head_node(txq);
|
||||
wrb_fill(wrb, busaddr, frag->size);
|
||||
be_dws_cpu_to_le(wrb, sizeof(*wrb));
|
||||
queue_head_inc(txq);
|
||||
copied += frag->size;
|
||||
}
|
||||
skb = skb_shinfo(skb)->frag_list;
|
||||
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
|
||||
struct skb_frag_struct *frag =
|
||||
&skb_shinfo(skb)->frags[i];
|
||||
busaddr = pci_map_page(pdev, frag->page,
|
||||
frag->page_offset,
|
||||
frag->size, PCI_DMA_TODEVICE);
|
||||
wrb = queue_head_node(txq);
|
||||
wrb_fill(wrb, busaddr, frag->size);
|
||||
be_dws_cpu_to_le(wrb, sizeof(*wrb));
|
||||
queue_head_inc(txq);
|
||||
copied += frag->size;
|
||||
}
|
||||
|
||||
if (dummy_wrb) {
|
||||
|
|
@ -478,8 +487,6 @@ static int be_xmit(struct sk_buff *skb, struct net_device *netdev)
|
|||
|
||||
be_txq_notify(&adapter->ctrl, txq->id, wrb_cnt);
|
||||
|
||||
netdev->trans_start = jiffies;
|
||||
|
||||
be_tx_stats_update(adapter, wrb_cnt, copied, stopped);
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
|
@ -637,6 +644,22 @@ static void be_rx_stats_update(struct be_adapter *adapter,
|
|||
stats->be_rx_bytes += pktsize;
|
||||
}
|
||||
|
||||
static inline bool do_pkt_csum(struct be_eth_rx_compl *rxcp, bool cso)
|
||||
{
|
||||
u8 l4_cksm, ip_version, ipcksm, tcpf = 0, udpf = 0, ipv6_chk;
|
||||
|
||||
l4_cksm = AMAP_GET_BITS(struct amap_eth_rx_compl, l4_cksm, rxcp);
|
||||
ipcksm = AMAP_GET_BITS(struct amap_eth_rx_compl, ipcksm, rxcp);
|
||||
ip_version = AMAP_GET_BITS(struct amap_eth_rx_compl, ip_version, rxcp);
|
||||
if (ip_version) {
|
||||
tcpf = AMAP_GET_BITS(struct amap_eth_rx_compl, tcpf, rxcp);
|
||||
udpf = AMAP_GET_BITS(struct amap_eth_rx_compl, udpf, rxcp);
|
||||
}
|
||||
ipv6_chk = (ip_version && (tcpf || udpf));
|
||||
|
||||
return ((l4_cksm && ipv6_chk && ipcksm) && cso) ? false : true;
|
||||
}
|
||||
|
||||
static struct be_rx_page_info *
|
||||
get_rx_page_info(struct be_adapter *adapter, u16 frag_idx)
|
||||
{
|
||||
|
|
@ -720,7 +743,7 @@ static void skb_fill_rx_data(struct be_adapter *adapter,
|
|||
|
||||
if (pktsize <= rx_frag_size) {
|
||||
BUG_ON(num_rcvd != 1);
|
||||
return;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* More frags present for this completion */
|
||||
|
|
@ -742,6 +765,7 @@ static void skb_fill_rx_data(struct be_adapter *adapter,
|
|||
memset(page_info, 0, sizeof(*page_info));
|
||||
}
|
||||
|
||||
done:
|
||||
be_rx_stats_update(adapter, pktsize, num_rcvd);
|
||||
return;
|
||||
}
|
||||
|
|
@ -752,9 +776,7 @@ static void be_rx_compl_process(struct be_adapter *adapter,
|
|||
{
|
||||
struct sk_buff *skb;
|
||||
u32 vtp, vid;
|
||||
int l4_cksm;
|
||||
|
||||
l4_cksm = AMAP_GET_BITS(struct amap_eth_rx_compl, l4_cksm, rxcp);
|
||||
vtp = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp);
|
||||
|
||||
skb = netdev_alloc_skb(adapter->netdev, BE_HDR_LEN + NET_IP_ALIGN);
|
||||
|
|
@ -769,10 +791,10 @@ static void be_rx_compl_process(struct be_adapter *adapter,
|
|||
|
||||
skb_fill_rx_data(adapter, skb, rxcp);
|
||||
|
||||
if (l4_cksm && adapter->rx_csum)
|
||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
else
|
||||
if (do_pkt_csum(rxcp, adapter->rx_csum))
|
||||
skb->ip_summed = CHECKSUM_NONE;
|
||||
else
|
||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
|
||||
skb->truesize = skb->len + sizeof(struct sk_buff);
|
||||
skb->protocol = eth_type_trans(skb, adapter->netdev);
|
||||
|
|
@ -854,12 +876,19 @@ static struct be_eth_rx_compl *be_rx_compl_get(struct be_adapter *adapter)
|
|||
|
||||
be_dws_le_to_cpu(rxcp, sizeof(*rxcp));
|
||||
|
||||
rxcp->dw[offsetof(struct amap_eth_rx_compl, valid) / 32] = 0;
|
||||
|
||||
queue_tail_inc(&adapter->rx_obj.cq);
|
||||
return rxcp;
|
||||
}
|
||||
|
||||
/* To reset the valid bit, we need to reset the whole word as
|
||||
* when walking the queue the valid entries are little-endian
|
||||
* and invalid entries are host endian
|
||||
*/
|
||||
static inline void be_rx_compl_reset(struct be_eth_rx_compl *rxcp)
|
||||
{
|
||||
rxcp->dw[offsetof(struct amap_eth_rx_compl, valid) / 32] = 0;
|
||||
}
|
||||
|
||||
static inline struct page *be_alloc_pages(u32 size)
|
||||
{
|
||||
gfp_t alloc_flags = GFP_ATOMIC;
|
||||
|
|
@ -991,6 +1020,7 @@ static void be_rx_q_clean(struct be_adapter *adapter)
|
|||
/* First cleanup pending rx completions */
|
||||
while ((rxcp = be_rx_compl_get(adapter)) != NULL) {
|
||||
be_rx_compl_discard(adapter, rxcp);
|
||||
be_rx_compl_reset(rxcp);
|
||||
be_cq_notify(&adapter->ctrl, rx_cq->id, true, 1);
|
||||
}
|
||||
|
||||
|
|
@ -1026,8 +1056,13 @@ static void be_tx_queues_destroy(struct be_adapter *adapter)
|
|||
struct be_queue_info *q;
|
||||
|
||||
q = &adapter->tx_obj.q;
|
||||
if (q->created)
|
||||
if (q->created) {
|
||||
be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_TXQ);
|
||||
|
||||
/* No more tx completions can be rcvd now; clean up if there
|
||||
* are any pending completions or pending tx requests */
|
||||
be_tx_q_clean(adapter);
|
||||
}
|
||||
be_queue_free(adapter, q);
|
||||
|
||||
q = &adapter->tx_obj.cq;
|
||||
|
|
@ -1035,10 +1070,6 @@ static void be_tx_queues_destroy(struct be_adapter *adapter)
|
|||
be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_CQ);
|
||||
be_queue_free(adapter, q);
|
||||
|
||||
/* No more tx completions can be rcvd now; clean up if there are
|
||||
* any pending completions or pending tx requests */
|
||||
be_tx_q_clean(adapter);
|
||||
|
||||
q = &adapter->tx_eq.q;
|
||||
if (q->created)
|
||||
be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_EQ);
|
||||
|
|
@ -1272,6 +1303,8 @@ int be_poll_rx(struct napi_struct *napi, int budget)
|
|||
be_rx_compl_process_lro(adapter, rxcp);
|
||||
else
|
||||
be_rx_compl_process(adapter, rxcp);
|
||||
|
||||
be_rx_compl_reset(rxcp);
|
||||
}
|
||||
|
||||
lro_flush_all(&adapter->rx_obj.lro_mgr);
|
||||
|
|
@ -1527,7 +1560,7 @@ static int be_close(struct net_device *netdev)
|
|||
struct be_eq_obj *tx_eq = &adapter->tx_eq;
|
||||
int vec;
|
||||
|
||||
cancel_delayed_work(&adapter->work);
|
||||
cancel_delayed_work_sync(&adapter->work);
|
||||
|
||||
netif_stop_queue(netdev);
|
||||
netif_carrier_off(netdev);
|
||||
|
|
@ -1626,10 +1659,12 @@ static void be_netdev_init(struct net_device *netdev)
|
|||
|
||||
netdev->features |= NETIF_F_SG | NETIF_F_HW_VLAN_RX | NETIF_F_TSO |
|
||||
NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER | NETIF_F_IP_CSUM |
|
||||
NETIF_F_IPV6_CSUM | NETIF_F_TSO6;
|
||||
NETIF_F_IPV6_CSUM;
|
||||
|
||||
netdev->flags |= IFF_MULTICAST;
|
||||
|
||||
adapter->rx_csum = true;
|
||||
|
||||
BE_SET_NETDEV_OPS(netdev, &be_netdev_ops);
|
||||
|
||||
SET_ETHTOOL_OPS(netdev, &be_ethtool_ops);
|
||||
|
|
|
|||
|
|
@ -194,13 +194,13 @@ static int desc_list_init(void)
|
|||
struct dma_descriptor *b = &(r->desc_b);
|
||||
|
||||
/* allocate a new skb for next time receive */
|
||||
new_skb = dev_alloc_skb(PKT_BUF_SZ + 2);
|
||||
new_skb = dev_alloc_skb(PKT_BUF_SZ + NET_IP_ALIGN);
|
||||
if (!new_skb) {
|
||||
printk(KERN_NOTICE DRV_NAME
|
||||
": init: low on mem - packet dropped\n");
|
||||
goto init_error;
|
||||
}
|
||||
skb_reserve(new_skb, 2);
|
||||
skb_reserve(new_skb, NET_IP_ALIGN);
|
||||
r->skb = new_skb;
|
||||
|
||||
/*
|
||||
|
|
@ -566,9 +566,9 @@ static void adjust_tx_list(void)
|
|||
*/
|
||||
if (current_tx_ptr->next->next == tx_list_head) {
|
||||
while (tx_list_head->status.status_word == 0) {
|
||||
mdelay(1);
|
||||
udelay(10);
|
||||
if (tx_list_head->status.status_word != 0
|
||||
|| !(bfin_read_DMA2_IRQ_STATUS() & 0x08)) {
|
||||
|| !(bfin_read_DMA2_IRQ_STATUS() & DMA_RUN)) {
|
||||
goto adjust_head;
|
||||
}
|
||||
if (timeout_cnt-- < 0) {
|
||||
|
|
@ -606,93 +606,41 @@ static int bfin_mac_hard_start_xmit(struct sk_buff *skb,
|
|||
struct net_device *dev)
|
||||
{
|
||||
u16 *data;
|
||||
|
||||
u32 data_align = (unsigned long)(skb->data) & 0x3;
|
||||
current_tx_ptr->skb = skb;
|
||||
|
||||
if (ANOMALY_05000285) {
|
||||
/*
|
||||
* TXDWA feature is not avaible to older revision < 0.3 silicon
|
||||
* of BF537
|
||||
*
|
||||
* Only if data buffer is ODD WORD alignment, we do not
|
||||
* need to memcpy
|
||||
*/
|
||||
u32 data_align = (u32)(skb->data) & 0x3;
|
||||
if (data_align == 0x2) {
|
||||
/* move skb->data to current_tx_ptr payload */
|
||||
data = (u16 *)(skb->data) - 1;
|
||||
*data = (u16)(skb->len);
|
||||
current_tx_ptr->desc_a.start_addr = (u32)data;
|
||||
/* this is important! */
|
||||
blackfin_dcache_flush_range((u32)data,
|
||||
(u32)((u8 *)data + skb->len + 4));
|
||||
} else {
|
||||
*((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len);
|
||||
memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data,
|
||||
skb->len);
|
||||
current_tx_ptr->desc_a.start_addr =
|
||||
(u32)current_tx_ptr->packet;
|
||||
if (current_tx_ptr->status.status_word != 0)
|
||||
current_tx_ptr->status.status_word = 0;
|
||||
blackfin_dcache_flush_range(
|
||||
(u32)current_tx_ptr->packet,
|
||||
(u32)(current_tx_ptr->packet + skb->len + 2));
|
||||
}
|
||||
if (data_align == 0x2) {
|
||||
/* move skb->data to current_tx_ptr payload */
|
||||
data = (u16 *)(skb->data) - 1;
|
||||
*data = (u16)(skb->len);
|
||||
current_tx_ptr->desc_a.start_addr = (u32)data;
|
||||
/* this is important! */
|
||||
blackfin_dcache_flush_range((u32)data,
|
||||
(u32)((u8 *)data + skb->len + 4));
|
||||
} else {
|
||||
/*
|
||||
* TXDWA feature is avaible to revision < 0.3 silicon of
|
||||
* BF537 and always avaible to BF52x
|
||||
*/
|
||||
u32 data_align = (u32)(skb->data) & 0x3;
|
||||
if (data_align == 0x0) {
|
||||
u16 sysctl = bfin_read_EMAC_SYSCTL();
|
||||
sysctl |= TXDWA;
|
||||
bfin_write_EMAC_SYSCTL(sysctl);
|
||||
|
||||
/* move skb->data to current_tx_ptr payload */
|
||||
data = (u16 *)(skb->data) - 2;
|
||||
*data = (u16)(skb->len);
|
||||
current_tx_ptr->desc_a.start_addr = (u32)data;
|
||||
/* this is important! */
|
||||
blackfin_dcache_flush_range(
|
||||
(u32)data,
|
||||
(u32)((u8 *)data + skb->len + 4));
|
||||
} else if (data_align == 0x2) {
|
||||
u16 sysctl = bfin_read_EMAC_SYSCTL();
|
||||
sysctl &= ~TXDWA;
|
||||
bfin_write_EMAC_SYSCTL(sysctl);
|
||||
|
||||
/* move skb->data to current_tx_ptr payload */
|
||||
data = (u16 *)(skb->data) - 1;
|
||||
*data = (u16)(skb->len);
|
||||
current_tx_ptr->desc_a.start_addr = (u32)data;
|
||||
/* this is important! */
|
||||
blackfin_dcache_flush_range(
|
||||
(u32)data,
|
||||
(u32)((u8 *)data + skb->len + 4));
|
||||
} else {
|
||||
u16 sysctl = bfin_read_EMAC_SYSCTL();
|
||||
sysctl &= ~TXDWA;
|
||||
bfin_write_EMAC_SYSCTL(sysctl);
|
||||
|
||||
*((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len);
|
||||
memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data,
|
||||
skb->len);
|
||||
current_tx_ptr->desc_a.start_addr =
|
||||
(u32)current_tx_ptr->packet;
|
||||
if (current_tx_ptr->status.status_word != 0)
|
||||
current_tx_ptr->status.status_word = 0;
|
||||
blackfin_dcache_flush_range(
|
||||
(u32)current_tx_ptr->packet,
|
||||
(u32)(current_tx_ptr->packet + skb->len + 2));
|
||||
}
|
||||
*((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len);
|
||||
memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data,
|
||||
skb->len);
|
||||
current_tx_ptr->desc_a.start_addr =
|
||||
(u32)current_tx_ptr->packet;
|
||||
if (current_tx_ptr->status.status_word != 0)
|
||||
current_tx_ptr->status.status_word = 0;
|
||||
blackfin_dcache_flush_range(
|
||||
(u32)current_tx_ptr->packet,
|
||||
(u32)(current_tx_ptr->packet + skb->len + 2));
|
||||
}
|
||||
|
||||
/* make sure the internal data buffers in the core are drained
|
||||
* so that the DMA descriptors are completely written when the
|
||||
* DMA engine goes to fetch them below
|
||||
*/
|
||||
SSYNC();
|
||||
|
||||
/* enable this packet's dma */
|
||||
current_tx_ptr->desc_a.config |= DMAEN;
|
||||
|
||||
/* tx dma is running, just return */
|
||||
if (bfin_read_DMA2_IRQ_STATUS() & 0x08)
|
||||
if (bfin_read_DMA2_IRQ_STATUS() & DMA_RUN)
|
||||
goto out;
|
||||
|
||||
/* tx dma is not running */
|
||||
|
|
@ -718,7 +666,7 @@ static void bfin_mac_rx(struct net_device *dev)
|
|||
|
||||
/* allocate a new skb for next time receive */
|
||||
skb = current_rx_ptr->skb;
|
||||
new_skb = dev_alloc_skb(PKT_BUF_SZ + 2);
|
||||
new_skb = dev_alloc_skb(PKT_BUF_SZ + NET_IP_ALIGN);
|
||||
if (!new_skb) {
|
||||
printk(KERN_NOTICE DRV_NAME
|
||||
": rx: low on mem - packet dropped\n");
|
||||
|
|
@ -726,7 +674,7 @@ static void bfin_mac_rx(struct net_device *dev)
|
|||
goto out;
|
||||
}
|
||||
/* reserve 2 bytes for RXDWA padding */
|
||||
skb_reserve(new_skb, 2);
|
||||
skb_reserve(new_skb, NET_IP_ALIGN);
|
||||
current_rx_ptr->skb = new_skb;
|
||||
current_rx_ptr->desc_a.start_addr = (unsigned long)new_skb->data - 2;
|
||||
|
||||
|
|
@ -1022,7 +970,8 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev)
|
|||
{
|
||||
struct net_device *ndev;
|
||||
struct bfin_mac_local *lp;
|
||||
int rc, i;
|
||||
struct platform_device *pd;
|
||||
int rc;
|
||||
|
||||
ndev = alloc_etherdev(sizeof(struct bfin_mac_local));
|
||||
if (!ndev) {
|
||||
|
|
@ -1047,13 +996,6 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev)
|
|||
goto out_err_probe_mac;
|
||||
}
|
||||
|
||||
/* set the GPIO pins to Ethernet mode */
|
||||
rc = peripheral_request_list(pin_req, DRV_NAME);
|
||||
if (rc) {
|
||||
dev_err(&pdev->dev, "Requesting peripherals failed!\n");
|
||||
rc = -EFAULT;
|
||||
goto out_err_setup_pin_mux;
|
||||
}
|
||||
|
||||
/*
|
||||
* Is it valid? (Did bootloader initialize it?)
|
||||
|
|
@ -1069,26 +1011,14 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev)
|
|||
|
||||
setup_mac_addr(ndev->dev_addr);
|
||||
|
||||
/* MDIO bus initial */
|
||||
lp->mii_bus = mdiobus_alloc();
|
||||
if (lp->mii_bus == NULL)
|
||||
goto out_err_mdiobus_alloc;
|
||||
|
||||
lp->mii_bus->priv = ndev;
|
||||
lp->mii_bus->read = bfin_mdiobus_read;
|
||||
lp->mii_bus->write = bfin_mdiobus_write;
|
||||
lp->mii_bus->reset = bfin_mdiobus_reset;
|
||||
lp->mii_bus->name = "bfin_mac_mdio";
|
||||
snprintf(lp->mii_bus->id, MII_BUS_ID_SIZE, "0");
|
||||
lp->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
|
||||
for (i = 0; i < PHY_MAX_ADDR; ++i)
|
||||
lp->mii_bus->irq[i] = PHY_POLL;
|
||||
|
||||
rc = mdiobus_register(lp->mii_bus);
|
||||
if (rc) {
|
||||
dev_err(&pdev->dev, "Cannot register MDIO bus!\n");
|
||||
goto out_err_mdiobus_register;
|
||||
if (!pdev->dev.platform_data) {
|
||||
dev_err(&pdev->dev, "Cannot get platform device bfin_mii_bus!\n");
|
||||
rc = -ENODEV;
|
||||
goto out_err_probe_mac;
|
||||
}
|
||||
pd = pdev->dev.platform_data;
|
||||
lp->mii_bus = platform_get_drvdata(pd);
|
||||
lp->mii_bus->priv = ndev;
|
||||
|
||||
rc = mii_probe(ndev);
|
||||
if (rc) {
|
||||
|
|
@ -1107,7 +1037,7 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev)
|
|||
/* now, enable interrupts */
|
||||
/* register irq handler */
|
||||
rc = request_irq(IRQ_MAC_RX, bfin_mac_interrupt,
|
||||
IRQF_DISABLED | IRQF_SHARED, "EMAC_RX", ndev);
|
||||
IRQF_DISABLED, "EMAC_RX", ndev);
|
||||
if (rc) {
|
||||
dev_err(&pdev->dev, "Cannot request Blackfin MAC RX IRQ!\n");
|
||||
rc = -EBUSY;
|
||||
|
|
@ -1130,11 +1060,8 @@ out_err_reg_ndev:
|
|||
out_err_request_irq:
|
||||
out_err_mii_probe:
|
||||
mdiobus_unregister(lp->mii_bus);
|
||||
out_err_mdiobus_register:
|
||||
mdiobus_free(lp->mii_bus);
|
||||
out_err_mdiobus_alloc:
|
||||
peripheral_free_list(pin_req);
|
||||
out_err_setup_pin_mux:
|
||||
out_err_probe_mac:
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
free_netdev(ndev);
|
||||
|
|
@ -1149,8 +1076,7 @@ static int __devexit bfin_mac_remove(struct platform_device *pdev)
|
|||
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
|
||||
mdiobus_unregister(lp->mii_bus);
|
||||
mdiobus_free(lp->mii_bus);
|
||||
lp->mii_bus->priv = NULL;
|
||||
|
||||
unregister_netdev(ndev);
|
||||
|
||||
|
|
@ -1188,6 +1114,74 @@ static int bfin_mac_resume(struct platform_device *pdev)
|
|||
#define bfin_mac_resume NULL
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static int __devinit bfin_mii_bus_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct mii_bus *miibus;
|
||||
int rc, i;
|
||||
|
||||
/*
|
||||
* We are setting up a network card,
|
||||
* so set the GPIO pins to Ethernet mode
|
||||
*/
|
||||
rc = peripheral_request_list(pin_req, DRV_NAME);
|
||||
if (rc) {
|
||||
dev_err(&pdev->dev, "Requesting peripherals failed!\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = -ENOMEM;
|
||||
miibus = mdiobus_alloc();
|
||||
if (miibus == NULL)
|
||||
goto out_err_alloc;
|
||||
miibus->read = bfin_mdiobus_read;
|
||||
miibus->write = bfin_mdiobus_write;
|
||||
miibus->reset = bfin_mdiobus_reset;
|
||||
|
||||
miibus->parent = &pdev->dev;
|
||||
miibus->name = "bfin_mii_bus";
|
||||
snprintf(miibus->id, MII_BUS_ID_SIZE, "0");
|
||||
miibus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
|
||||
if (miibus->irq == NULL)
|
||||
goto out_err_alloc;
|
||||
for (i = 0; i < PHY_MAX_ADDR; ++i)
|
||||
miibus->irq[i] = PHY_POLL;
|
||||
|
||||
rc = mdiobus_register(miibus);
|
||||
if (rc) {
|
||||
dev_err(&pdev->dev, "Cannot register MDIO bus!\n");
|
||||
goto out_err_mdiobus_register;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, miibus);
|
||||
return 0;
|
||||
|
||||
out_err_mdiobus_register:
|
||||
mdiobus_free(miibus);
|
||||
out_err_alloc:
|
||||
peripheral_free_list(pin_req);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int __devexit bfin_mii_bus_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct mii_bus *miibus = platform_get_drvdata(pdev);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
mdiobus_unregister(miibus);
|
||||
mdiobus_free(miibus);
|
||||
peripheral_free_list(pin_req);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver bfin_mii_bus_driver = {
|
||||
.probe = bfin_mii_bus_probe,
|
||||
.remove = __devexit_p(bfin_mii_bus_remove),
|
||||
.driver = {
|
||||
.name = "bfin_mii_bus",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_driver bfin_mac_driver = {
|
||||
.probe = bfin_mac_probe,
|
||||
.remove = __devexit_p(bfin_mac_remove),
|
||||
|
|
@ -1201,7 +1195,11 @@ static struct platform_driver bfin_mac_driver = {
|
|||
|
||||
static int __init bfin_mac_init(void)
|
||||
{
|
||||
return platform_driver_register(&bfin_mac_driver);
|
||||
int ret;
|
||||
ret = platform_driver_register(&bfin_mii_bus_driver);
|
||||
if (!ret)
|
||||
return platform_driver_register(&bfin_mac_driver);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
module_init(bfin_mac_init);
|
||||
|
|
@ -1209,6 +1207,7 @@ module_init(bfin_mac_init);
|
|||
static void __exit bfin_mac_cleanup(void)
|
||||
{
|
||||
platform_driver_unregister(&bfin_mac_driver);
|
||||
platform_driver_unregister(&bfin_mii_bus_driver);
|
||||
}
|
||||
|
||||
module_exit(bfin_mac_cleanup);
|
||||
|
|
|
|||
|
|
@ -1247,6 +1247,16 @@ static const struct ethtool_ops bmac_ethtool_ops = {
|
|||
.get_link = ethtool_op_get_link,
|
||||
};
|
||||
|
||||
static const struct net_device_ops bmac_netdev_ops = {
|
||||
.ndo_open = bmac_open,
|
||||
.ndo_stop = bmac_close,
|
||||
.ndo_start_xmit = bmac_output,
|
||||
.ndo_set_multicast_list = bmac_set_multicast,
|
||||
.ndo_set_mac_address = bmac_set_address,
|
||||
.ndo_change_mtu = eth_change_mtu,
|
||||
.ndo_validate_addr = eth_validate_addr,
|
||||
};
|
||||
|
||||
static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_id *match)
|
||||
{
|
||||
int j, rev, ret;
|
||||
|
|
@ -1308,12 +1318,8 @@ static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_i
|
|||
bmac_enable_and_reset_chip(dev);
|
||||
bmwrite(dev, INTDISABLE, DisableAll);
|
||||
|
||||
dev->open = bmac_open;
|
||||
dev->stop = bmac_close;
|
||||
dev->netdev_ops = &bmac_netdev_ops;
|
||||
dev->ethtool_ops = &bmac_ethtool_ops;
|
||||
dev->hard_start_xmit = bmac_output;
|
||||
dev->set_multicast_list = bmac_set_multicast;
|
||||
dev->set_mac_address = bmac_set_address;
|
||||
|
||||
bmac_get_station_address(dev, addr);
|
||||
if (bmac_verify_checksum(dev) != 0)
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@
|
|||
#include <linux/cache.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/log2.h>
|
||||
#include <linux/list.h>
|
||||
|
||||
#if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE)
|
||||
#define BCM_CNIC 1
|
||||
|
|
@ -703,8 +704,7 @@ bnx2_free_rx_mem(struct bnx2 *bp)
|
|||
rxr->rx_desc_mapping[j]);
|
||||
rxr->rx_desc_ring[j] = NULL;
|
||||
}
|
||||
if (rxr->rx_buf_ring)
|
||||
vfree(rxr->rx_buf_ring);
|
||||
vfree(rxr->rx_buf_ring);
|
||||
rxr->rx_buf_ring = NULL;
|
||||
|
||||
for (j = 0; j < bp->rx_max_pg_ring; j++) {
|
||||
|
|
@ -714,8 +714,7 @@ bnx2_free_rx_mem(struct bnx2 *bp)
|
|||
rxr->rx_pg_desc_mapping[j]);
|
||||
rxr->rx_pg_desc_ring[j] = NULL;
|
||||
}
|
||||
if (rxr->rx_pg_ring)
|
||||
vfree(rxr->rx_pg_ring);
|
||||
vfree(rxr->rx_pg_ring);
|
||||
rxr->rx_pg_ring = NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -2788,14 +2787,15 @@ bnx2_tx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
|
|||
tx_buf = &txr->tx_buf_ring[sw_ring_cons];
|
||||
skb = tx_buf->skb;
|
||||
|
||||
/* prefetch skb_end_pointer() to speedup skb_shinfo(skb) */
|
||||
prefetch(&skb->end);
|
||||
|
||||
/* partial BD completions possible with TSO packets */
|
||||
if (skb_is_gso(skb)) {
|
||||
if (tx_buf->is_gso) {
|
||||
u16 last_idx, last_ring_idx;
|
||||
|
||||
last_idx = sw_cons +
|
||||
skb_shinfo(skb)->nr_frags + 1;
|
||||
last_ring_idx = sw_ring_cons +
|
||||
skb_shinfo(skb)->nr_frags + 1;
|
||||
last_idx = sw_cons + tx_buf->nr_frags + 1;
|
||||
last_ring_idx = sw_ring_cons + tx_buf->nr_frags + 1;
|
||||
if (unlikely(last_ring_idx >= MAX_TX_DESC_CNT)) {
|
||||
last_idx++;
|
||||
}
|
||||
|
|
@ -2807,7 +2807,7 @@ bnx2_tx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
|
|||
skb_dma_unmap(&bp->pdev->dev, skb, DMA_TO_DEVICE);
|
||||
|
||||
tx_buf->skb = NULL;
|
||||
last = skb_shinfo(skb)->nr_frags;
|
||||
last = tx_buf->nr_frags;
|
||||
|
||||
for (i = 0; i < last; i++) {
|
||||
sw_cons = NEXT_TX_BD(sw_cons);
|
||||
|
|
@ -2820,7 +2820,8 @@ bnx2_tx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
|
|||
if (tx_pkt == budget)
|
||||
break;
|
||||
|
||||
hw_cons = bnx2_get_hw_tx_cons(bnapi);
|
||||
if (hw_cons == sw_cons)
|
||||
hw_cons = bnx2_get_hw_tx_cons(bnapi);
|
||||
}
|
||||
|
||||
txr->hw_tx_cons = hw_cons;
|
||||
|
|
@ -3492,7 +3493,7 @@ bnx2_set_rx_mode(struct net_device *dev)
|
|||
{
|
||||
struct bnx2 *bp = netdev_priv(dev);
|
||||
u32 rx_mode, sort_mode;
|
||||
struct dev_addr_list *uc_ptr;
|
||||
struct netdev_hw_addr *ha;
|
||||
int i;
|
||||
|
||||
if (!netif_running(dev))
|
||||
|
|
@ -3551,21 +3552,19 @@ bnx2_set_rx_mode(struct net_device *dev)
|
|||
sort_mode |= BNX2_RPM_SORT_USER0_MC_HSH_EN;
|
||||
}
|
||||
|
||||
uc_ptr = NULL;
|
||||
if (dev->uc_count > BNX2_MAX_UNICAST_ADDRESSES) {
|
||||
rx_mode |= BNX2_EMAC_RX_MODE_PROMISCUOUS;
|
||||
sort_mode |= BNX2_RPM_SORT_USER0_PROM_EN |
|
||||
BNX2_RPM_SORT_USER0_PROM_VLAN;
|
||||
} else if (!(dev->flags & IFF_PROMISC)) {
|
||||
uc_ptr = dev->uc_list;
|
||||
|
||||
/* Add all entries into to the match filter list */
|
||||
for (i = 0; i < dev->uc_count; i++) {
|
||||
bnx2_set_mac_addr(bp, uc_ptr->da_addr,
|
||||
i = 0;
|
||||
list_for_each_entry(ha, &dev->uc_list, list) {
|
||||
bnx2_set_mac_addr(bp, ha->addr,
|
||||
i + BNX2_START_UNICAST_ADDRESS_INDEX);
|
||||
sort_mode |= (1 <<
|
||||
(i + BNX2_START_UNICAST_ADDRESS_INDEX));
|
||||
uc_ptr = uc_ptr->next;
|
||||
i++;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -5673,7 +5672,7 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode)
|
|||
dev_kfree_skb(skb);
|
||||
return -EIO;
|
||||
}
|
||||
map = skb_shinfo(skb)->dma_maps[0];
|
||||
map = skb_shinfo(skb)->dma_head;
|
||||
|
||||
REG_WR(bp, BNX2_HC_COMMAND,
|
||||
bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT);
|
||||
|
|
@ -6353,7 +6352,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
}
|
||||
|
||||
sp = skb_shinfo(skb);
|
||||
mapping = sp->dma_maps[0];
|
||||
mapping = sp->dma_head;
|
||||
|
||||
tx_buf = &txr->tx_buf_ring[ring_prod];
|
||||
tx_buf->skb = skb;
|
||||
|
|
@ -6366,6 +6365,8 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
txbd->tx_bd_vlan_tag_flags = vlan_tag_flags | TX_BD_FLAGS_START;
|
||||
|
||||
last_frag = skb_shinfo(skb)->nr_frags;
|
||||
tx_buf->nr_frags = last_frag;
|
||||
tx_buf->is_gso = skb_is_gso(skb);
|
||||
|
||||
for (i = 0; i < last_frag; i++) {
|
||||
skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
|
||||
|
|
@ -6375,7 +6376,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
txbd = &txr->tx_desc_ring[ring_prod];
|
||||
|
||||
len = frag->size;
|
||||
mapping = sp->dma_maps[i + 1];
|
||||
mapping = sp->dma_maps[i];
|
||||
|
||||
txbd->tx_bd_haddr_hi = (u64) mapping >> 32;
|
||||
txbd->tx_bd_haddr_lo = (u64) mapping & 0xffffffff;
|
||||
|
|
@ -6394,7 +6395,6 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
mmiowb();
|
||||
|
||||
txr->tx_prod = prod;
|
||||
dev->trans_start = jiffies;
|
||||
|
||||
if (unlikely(bnx2_tx_avail(bp, txr) <= MAX_SKB_FRAGS)) {
|
||||
netif_tx_stop_queue(txq);
|
||||
|
|
|
|||
|
|
@ -6556,6 +6556,8 @@ struct sw_pg {
|
|||
|
||||
struct sw_tx_bd {
|
||||
struct sk_buff *skb;
|
||||
unsigned short is_gso;
|
||||
unsigned short nr_frags;
|
||||
};
|
||||
|
||||
#define SW_RXBD_RING_SIZE (sizeof(struct sw_bd) * RX_DESC_CNT)
|
||||
|
|
|
|||
|
|
@ -965,6 +965,21 @@ struct bnx2x {
|
|||
int gunzip_outlen;
|
||||
#define FW_BUF_SIZE 0x8000
|
||||
|
||||
struct raw_op *init_ops;
|
||||
/* Init blocks offsets inside init_ops */
|
||||
u16 *init_ops_offsets;
|
||||
/* Data blob - has 32 bit granularity */
|
||||
u32 *init_data;
|
||||
/* Zipped PRAM blobs - raw data */
|
||||
const u8 *tsem_int_table_data;
|
||||
const u8 *tsem_pram_data;
|
||||
const u8 *usem_int_table_data;
|
||||
const u8 *usem_pram_data;
|
||||
const u8 *xsem_int_table_data;
|
||||
const u8 *xsem_pram_data;
|
||||
const u8 *csem_int_table_data;
|
||||
const u8 *csem_pram_data;
|
||||
const struct firmware *firmware;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
37
drivers/net/bnx2x_fw_file_hdr.h
Normal file
37
drivers/net/bnx2x_fw_file_hdr.h
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/* bnx2x_fw_file_hdr.h: FW binary file header structure.
|
||||
*
|
||||
* Copyright (c) 2007-2009 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Maintained by: Eilon Greenstein <eilong@broadcom.com>
|
||||
* Written by: Vladislav Zolotarov <vladz@broadcom.com>
|
||||
* Based on the original idea of John Wright <john.wright@hp.com>.
|
||||
*/
|
||||
|
||||
#ifndef BNX2X_INIT_FILE_HDR_H
|
||||
#define BNX2X_INIT_FILE_HDR_H
|
||||
|
||||
struct bnx2x_fw_file_section {
|
||||
__be32 len;
|
||||
__be32 offset;
|
||||
};
|
||||
|
||||
struct bnx2x_fw_file_hdr {
|
||||
struct bnx2x_fw_file_section init_ops;
|
||||
struct bnx2x_fw_file_section init_ops_offsets;
|
||||
struct bnx2x_fw_file_section init_data;
|
||||
struct bnx2x_fw_file_section tsem_int_table_data;
|
||||
struct bnx2x_fw_file_section tsem_pram_data;
|
||||
struct bnx2x_fw_file_section usem_int_table_data;
|
||||
struct bnx2x_fw_file_section usem_pram_data;
|
||||
struct bnx2x_fw_file_section csem_int_table_data;
|
||||
struct bnx2x_fw_file_section csem_pram_data;
|
||||
struct bnx2x_fw_file_section xsem_int_table_data;
|
||||
struct bnx2x_fw_file_section xsem_pram_data;
|
||||
struct bnx2x_fw_file_section fw_version;
|
||||
};
|
||||
|
||||
#endif /* BNX2X_INIT_FILE_HDR_H */
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
/* bnx2x_init.h: Broadcom Everest network driver.
|
||||
* Structures and macroes needed during the initialization.
|
||||
*
|
||||
* Copyright (c) 2007-2009 Broadcom Corporation
|
||||
*
|
||||
|
|
@ -8,6 +9,7 @@
|
|||
*
|
||||
* Maintained by: Eilon Greenstein <eilong@broadcom.com>
|
||||
* Written by: Eliezer Tamir
|
||||
* Modified by: Vladislav Zolotarov <vladz@broadcom.com>
|
||||
*/
|
||||
|
||||
#ifndef BNX2X_INIT_H
|
||||
|
|
@ -45,33 +47,71 @@
|
|||
#define OP_WR_64 0x8 /* write 64 bit pattern */
|
||||
#define OP_WB 0x9 /* copy a string using DMAE */
|
||||
|
||||
/* Operation specific for E1 */
|
||||
#define OP_RD_E1 0xa /* read single register */
|
||||
#define OP_WR_E1 0xb /* write single register */
|
||||
#define OP_IW_E1 0xc /* write single register using mailbox */
|
||||
#define OP_SW_E1 0xd /* copy a string to the device */
|
||||
#define OP_SI_E1 0xe /* copy a string using mailbox */
|
||||
#define OP_ZR_E1 0xf /* clear memory */
|
||||
#define OP_ZP_E1 0x10 /* unzip then copy with DMAE */
|
||||
#define OP_WR_64_E1 0x11 /* write 64 bit pattern on E1 */
|
||||
#define OP_WB_E1 0x12 /* copy a string using DMAE */
|
||||
|
||||
/* Operation specific for E1H */
|
||||
#define OP_RD_E1H 0x13 /* read single register */
|
||||
#define OP_WR_E1H 0x14 /* write single register */
|
||||
#define OP_IW_E1H 0x15 /* write single register using mailbox */
|
||||
#define OP_SW_E1H 0x16 /* copy a string to the device */
|
||||
#define OP_SI_E1H 0x17 /* copy a string using mailbox */
|
||||
#define OP_ZR_E1H 0x18 /* clear memory */
|
||||
#define OP_ZP_E1H 0x19 /* unzip then copy with DMAE */
|
||||
#define OP_WR_64_E1H 0x1a /* write 64 bit pattern on E1H */
|
||||
#define OP_WB_E1H 0x1b /* copy a string using DMAE */
|
||||
|
||||
/* FPGA and EMUL specific operations */
|
||||
#define OP_WR_EMUL_E1H 0x1c /* write single register on E1H Emul */
|
||||
#define OP_WR_EMUL 0x1d /* write single register on Emulation */
|
||||
#define OP_WR_FPGA 0x1e /* write single register on FPGA */
|
||||
#define OP_WR_ASIC 0x1f /* write single register on ASIC */
|
||||
#define OP_WR_EMUL 0xa /* write single register on Emulation */
|
||||
#define OP_WR_FPGA 0xb /* write single register on FPGA */
|
||||
#define OP_WR_ASIC 0xc /* write single register on ASIC */
|
||||
|
||||
/* Init stages */
|
||||
#define COMMON_STAGE 0
|
||||
#define PORT0_STAGE 1
|
||||
#define PORT1_STAGE 2
|
||||
/* Never reorder FUNCx stages !!! */
|
||||
#define FUNC0_STAGE 3
|
||||
#define FUNC1_STAGE 4
|
||||
#define FUNC2_STAGE 5
|
||||
#define FUNC3_STAGE 6
|
||||
#define FUNC4_STAGE 7
|
||||
#define FUNC5_STAGE 8
|
||||
#define FUNC6_STAGE 9
|
||||
#define FUNC7_STAGE 10
|
||||
#define STAGE_IDX_MAX 11
|
||||
|
||||
#define STAGE_START 0
|
||||
#define STAGE_END 1
|
||||
|
||||
|
||||
/* Indices of blocks */
|
||||
#define PRS_BLOCK 0
|
||||
#define SRCH_BLOCK 1
|
||||
#define TSDM_BLOCK 2
|
||||
#define TCM_BLOCK 3
|
||||
#define BRB1_BLOCK 4
|
||||
#define TSEM_BLOCK 5
|
||||
#define PXPCS_BLOCK 6
|
||||
#define EMAC0_BLOCK 7
|
||||
#define EMAC1_BLOCK 8
|
||||
#define DBU_BLOCK 9
|
||||
#define MISC_BLOCK 10
|
||||
#define DBG_BLOCK 11
|
||||
#define NIG_BLOCK 12
|
||||
#define MCP_BLOCK 13
|
||||
#define UPB_BLOCK 14
|
||||
#define CSDM_BLOCK 15
|
||||
#define USDM_BLOCK 16
|
||||
#define CCM_BLOCK 17
|
||||
#define UCM_BLOCK 18
|
||||
#define USEM_BLOCK 19
|
||||
#define CSEM_BLOCK 20
|
||||
#define XPB_BLOCK 21
|
||||
#define DQ_BLOCK 22
|
||||
#define TIMERS_BLOCK 23
|
||||
#define XSDM_BLOCK 24
|
||||
#define QM_BLOCK 25
|
||||
#define PBF_BLOCK 26
|
||||
#define XCM_BLOCK 27
|
||||
#define XSEM_BLOCK 28
|
||||
#define CDU_BLOCK 29
|
||||
#define DMAE_BLOCK 30
|
||||
#define PXP_BLOCK 31
|
||||
#define CFC_BLOCK 32
|
||||
#define HC_BLOCK 33
|
||||
#define PXP2_BLOCK 34
|
||||
#define MISC_AEU_BLOCK 35
|
||||
|
||||
/* Returns the index of start or end of a specific block stage in ops array*/
|
||||
#define BLOCK_OPS_IDX(block, stage, end) \
|
||||
(2*(((block)*STAGE_IDX_MAX) + (stage)) + (end))
|
||||
|
||||
|
||||
struct raw_op {
|
||||
|
|
@ -118,292 +158,6 @@ union init_op {
|
|||
struct raw_op raw;
|
||||
};
|
||||
|
||||
#include "bnx2x_init_values.h"
|
||||
|
||||
static void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val);
|
||||
static int bnx2x_gunzip(struct bnx2x *bp, u8 *zbuf, int len);
|
||||
|
||||
static void bnx2x_init_str_wr(struct bnx2x *bp, u32 addr, const u32 *data,
|
||||
u32 len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
REG_WR(bp, addr + i*4, data[i]);
|
||||
if (!(i % 10000)) {
|
||||
touch_softlockup_watchdog();
|
||||
cpu_relax();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void bnx2x_init_ind_wr(struct bnx2x *bp, u32 addr, const u32 *data,
|
||||
u16 len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
REG_WR_IND(bp, addr + i*4, data[i]);
|
||||
if (!(i % 10000)) {
|
||||
touch_softlockup_watchdog();
|
||||
cpu_relax();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void bnx2x_write_big_buf(struct bnx2x *bp, u32 addr, u32 len)
|
||||
{
|
||||
int offset = 0;
|
||||
|
||||
if (bp->dmae_ready) {
|
||||
while (len > DMAE_LEN32_WR_MAX) {
|
||||
bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
|
||||
addr + offset, DMAE_LEN32_WR_MAX);
|
||||
offset += DMAE_LEN32_WR_MAX * 4;
|
||||
len -= DMAE_LEN32_WR_MAX;
|
||||
}
|
||||
bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
|
||||
addr + offset, len);
|
||||
} else
|
||||
bnx2x_init_str_wr(bp, addr, bp->gunzip_buf, len);
|
||||
}
|
||||
|
||||
static void bnx2x_init_fill(struct bnx2x *bp, u32 addr, int fill, u32 len)
|
||||
{
|
||||
u32 buf_len = (((len * 4) > FW_BUF_SIZE) ? FW_BUF_SIZE : (len * 4));
|
||||
u32 buf_len32 = buf_len / 4;
|
||||
int i;
|
||||
|
||||
memset(bp->gunzip_buf, fill, buf_len);
|
||||
|
||||
for (i = 0; i < len; i += buf_len32) {
|
||||
u32 cur_len = min(buf_len32, len - i);
|
||||
|
||||
bnx2x_write_big_buf(bp, addr + i * 4, cur_len);
|
||||
}
|
||||
}
|
||||
|
||||
static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr, const u32 *data,
|
||||
u32 len64)
|
||||
{
|
||||
u32 buf_len32 = FW_BUF_SIZE / 4;
|
||||
u32 len = len64 * 2;
|
||||
u64 data64 = 0;
|
||||
int i;
|
||||
|
||||
/* 64 bit value is in a blob: first low DWORD, then high DWORD */
|
||||
data64 = HILO_U64((*(data + 1)), (*data));
|
||||
len64 = min((u32)(FW_BUF_SIZE/8), len64);
|
||||
for (i = 0; i < len64; i++) {
|
||||
u64 *pdata = ((u64 *)(bp->gunzip_buf)) + i;
|
||||
|
||||
*pdata = data64;
|
||||
}
|
||||
|
||||
for (i = 0; i < len; i += buf_len32) {
|
||||
u32 cur_len = min(buf_len32, len - i);
|
||||
|
||||
bnx2x_write_big_buf(bp, addr + i * 4, cur_len);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************
|
||||
There are different blobs for each PRAM section.
|
||||
In addition, each blob write operation is divided into a few operations
|
||||
in order to decrease the amount of phys. contiguous buffer needed.
|
||||
Thus, when we select a blob the address may be with some offset
|
||||
from the beginning of PRAM section.
|
||||
The same holds for the INT_TABLE sections.
|
||||
**********************************************************/
|
||||
#define IF_IS_INT_TABLE_ADDR(base, addr) \
|
||||
if (((base) <= (addr)) && ((base) + 0x400 >= (addr)))
|
||||
|
||||
#define IF_IS_PRAM_ADDR(base, addr) \
|
||||
if (((base) <= (addr)) && ((base) + 0x40000 >= (addr)))
|
||||
|
||||
static const u32 *bnx2x_sel_blob(u32 addr, const u32 *data, int is_e1)
|
||||
{
|
||||
IF_IS_INT_TABLE_ADDR(TSEM_REG_INT_TABLE, addr)
|
||||
data = is_e1 ? tsem_int_table_data_e1 :
|
||||
tsem_int_table_data_e1h;
|
||||
else
|
||||
IF_IS_INT_TABLE_ADDR(CSEM_REG_INT_TABLE, addr)
|
||||
data = is_e1 ? csem_int_table_data_e1 :
|
||||
csem_int_table_data_e1h;
|
||||
else
|
||||
IF_IS_INT_TABLE_ADDR(USEM_REG_INT_TABLE, addr)
|
||||
data = is_e1 ? usem_int_table_data_e1 :
|
||||
usem_int_table_data_e1h;
|
||||
else
|
||||
IF_IS_INT_TABLE_ADDR(XSEM_REG_INT_TABLE, addr)
|
||||
data = is_e1 ? xsem_int_table_data_e1 :
|
||||
xsem_int_table_data_e1h;
|
||||
else
|
||||
IF_IS_PRAM_ADDR(TSEM_REG_PRAM, addr)
|
||||
data = is_e1 ? tsem_pram_data_e1 : tsem_pram_data_e1h;
|
||||
else
|
||||
IF_IS_PRAM_ADDR(CSEM_REG_PRAM, addr)
|
||||
data = is_e1 ? csem_pram_data_e1 : csem_pram_data_e1h;
|
||||
else
|
||||
IF_IS_PRAM_ADDR(USEM_REG_PRAM, addr)
|
||||
data = is_e1 ? usem_pram_data_e1 : usem_pram_data_e1h;
|
||||
else
|
||||
IF_IS_PRAM_ADDR(XSEM_REG_PRAM, addr)
|
||||
data = is_e1 ? xsem_pram_data_e1 : xsem_pram_data_e1h;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, const u32 *data,
|
||||
u32 len, int gunzip, int is_e1, u32 blob_off)
|
||||
{
|
||||
int offset = 0;
|
||||
|
||||
data = bnx2x_sel_blob(addr, data, is_e1) + blob_off;
|
||||
|
||||
if (gunzip) {
|
||||
int rc;
|
||||
#ifdef __BIG_ENDIAN
|
||||
int i, size;
|
||||
u32 *temp;
|
||||
|
||||
temp = kmalloc(len, GFP_KERNEL);
|
||||
size = (len / 4) + ((len % 4) ? 1 : 0);
|
||||
for (i = 0; i < size; i++)
|
||||
temp[i] = swab32(data[i]);
|
||||
data = temp;
|
||||
#endif
|
||||
rc = bnx2x_gunzip(bp, (u8 *)data, len);
|
||||
if (rc) {
|
||||
BNX2X_ERR("gunzip failed ! rc %d\n", rc);
|
||||
#ifdef __BIG_ENDIAN
|
||||
kfree(temp);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
len = bp->gunzip_outlen;
|
||||
#ifdef __BIG_ENDIAN
|
||||
kfree(temp);
|
||||
for (i = 0; i < len; i++)
|
||||
((u32 *)bp->gunzip_buf)[i] =
|
||||
swab32(((u32 *)bp->gunzip_buf)[i]);
|
||||
#endif
|
||||
} else {
|
||||
if ((len * 4) > FW_BUF_SIZE) {
|
||||
BNX2X_ERR("LARGE DMAE OPERATION ! "
|
||||
"addr 0x%x len 0x%x\n", addr, len*4);
|
||||
return;
|
||||
}
|
||||
memcpy(bp->gunzip_buf, data, len * 4);
|
||||
}
|
||||
|
||||
if (bp->dmae_ready) {
|
||||
while (len > DMAE_LEN32_WR_MAX) {
|
||||
bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
|
||||
addr + offset, DMAE_LEN32_WR_MAX);
|
||||
offset += DMAE_LEN32_WR_MAX * 4;
|
||||
len -= DMAE_LEN32_WR_MAX;
|
||||
}
|
||||
bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
|
||||
addr + offset, len);
|
||||
} else
|
||||
bnx2x_init_ind_wr(bp, addr, bp->gunzip_buf, len);
|
||||
}
|
||||
|
||||
static void bnx2x_init_block(struct bnx2x *bp, u32 op_start, u32 op_end)
|
||||
{
|
||||
int is_e1 = CHIP_IS_E1(bp);
|
||||
int is_e1h = CHIP_IS_E1H(bp);
|
||||
int is_emul_e1h = (CHIP_REV_IS_EMUL(bp) && is_e1h);
|
||||
int hw_wr, i;
|
||||
union init_op *op;
|
||||
u32 op_type, addr, len;
|
||||
const u32 *data, *data_base;
|
||||
|
||||
if (CHIP_REV_IS_FPGA(bp))
|
||||
hw_wr = OP_WR_FPGA;
|
||||
else if (CHIP_REV_IS_EMUL(bp))
|
||||
hw_wr = OP_WR_EMUL;
|
||||
else
|
||||
hw_wr = OP_WR_ASIC;
|
||||
|
||||
if (is_e1)
|
||||
data_base = init_data_e1;
|
||||
else /* CHIP_IS_E1H(bp) */
|
||||
data_base = init_data_e1h;
|
||||
|
||||
for (i = op_start; i < op_end; i++) {
|
||||
|
||||
op = (union init_op *)&(init_ops[i]);
|
||||
|
||||
op_type = op->str_wr.op;
|
||||
addr = op->str_wr.offset;
|
||||
len = op->str_wr.data_len;
|
||||
data = data_base + op->str_wr.data_off;
|
||||
|
||||
/* careful! it must be in order */
|
||||
if (unlikely(op_type > OP_WB)) {
|
||||
|
||||
/* If E1 only */
|
||||
if (op_type <= OP_WB_E1) {
|
||||
if (is_e1)
|
||||
op_type -= (OP_RD_E1 - OP_RD);
|
||||
|
||||
/* If E1H only */
|
||||
} else if (op_type <= OP_WB_E1H) {
|
||||
if (is_e1h)
|
||||
op_type -= (OP_RD_E1H - OP_RD);
|
||||
}
|
||||
|
||||
/* HW/EMUL specific */
|
||||
if (op_type == hw_wr)
|
||||
op_type = OP_WR;
|
||||
|
||||
/* EMUL on E1H is special */
|
||||
if ((op_type == OP_WR_EMUL_E1H) && is_emul_e1h)
|
||||
op_type = OP_WR;
|
||||
}
|
||||
|
||||
switch (op_type) {
|
||||
case OP_RD:
|
||||
REG_RD(bp, addr);
|
||||
break;
|
||||
case OP_WR:
|
||||
REG_WR(bp, addr, op->write.val);
|
||||
break;
|
||||
case OP_SW:
|
||||
bnx2x_init_str_wr(bp, addr, data, len);
|
||||
break;
|
||||
case OP_WB:
|
||||
bnx2x_init_wr_wb(bp, addr, data, len, 0, is_e1, 0);
|
||||
break;
|
||||
case OP_SI:
|
||||
bnx2x_init_ind_wr(bp, addr, data, len);
|
||||
break;
|
||||
case OP_ZR:
|
||||
bnx2x_init_fill(bp, addr, 0, op->zero.len);
|
||||
break;
|
||||
case OP_ZP:
|
||||
bnx2x_init_wr_wb(bp, addr, data, len, 1, is_e1,
|
||||
op->str_wr.data_off);
|
||||
break;
|
||||
case OP_WR_64:
|
||||
bnx2x_init_wr_64(bp, addr, data, len);
|
||||
break;
|
||||
default:
|
||||
/* happens whenever an op is of a diff HW */
|
||||
#if 0
|
||||
DP(NETIF_MSG_HW, "skipping init operation "
|
||||
"index %d[%d:%d]: type %d addr 0x%x "
|
||||
"len %d(0x%x)\n",
|
||||
i, op_start, op_end, op_type, addr, len, len);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* PXP
|
||||
****************************************************************************/
|
||||
|
|
@ -567,111 +321,6 @@ static const struct arb_line write_arb_addr[NUM_WR_Q-1] = {
|
|||
PXP2_REG_RQ_BW_WR_UBOUND30}
|
||||
};
|
||||
|
||||
static void bnx2x_init_pxp(struct bnx2x *bp)
|
||||
{
|
||||
u16 devctl;
|
||||
int r_order, w_order;
|
||||
u32 val, i;
|
||||
|
||||
pci_read_config_word(bp->pdev,
|
||||
bp->pcie_cap + PCI_EXP_DEVCTL, &devctl);
|
||||
DP(NETIF_MSG_HW, "read 0x%x from devctl\n", devctl);
|
||||
w_order = ((devctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
|
||||
if (bp->mrrs == -1)
|
||||
r_order = ((devctl & PCI_EXP_DEVCTL_READRQ) >> 12);
|
||||
else {
|
||||
DP(NETIF_MSG_HW, "force read order to %d\n", bp->mrrs);
|
||||
r_order = bp->mrrs;
|
||||
}
|
||||
|
||||
if (r_order > MAX_RD_ORD) {
|
||||
DP(NETIF_MSG_HW, "read order of %d order adjusted to %d\n",
|
||||
r_order, MAX_RD_ORD);
|
||||
r_order = MAX_RD_ORD;
|
||||
}
|
||||
if (w_order > MAX_WR_ORD) {
|
||||
DP(NETIF_MSG_HW, "write order of %d order adjusted to %d\n",
|
||||
w_order, MAX_WR_ORD);
|
||||
w_order = MAX_WR_ORD;
|
||||
}
|
||||
if (CHIP_REV_IS_FPGA(bp)) {
|
||||
DP(NETIF_MSG_HW, "write order adjusted to 1 for FPGA\n");
|
||||
w_order = 0;
|
||||
}
|
||||
DP(NETIF_MSG_HW, "read order %d write order %d\n", r_order, w_order);
|
||||
|
||||
for (i = 0; i < NUM_RD_Q-1; i++) {
|
||||
REG_WR(bp, read_arb_addr[i].l, read_arb_data[i][r_order].l);
|
||||
REG_WR(bp, read_arb_addr[i].add,
|
||||
read_arb_data[i][r_order].add);
|
||||
REG_WR(bp, read_arb_addr[i].ubound,
|
||||
read_arb_data[i][r_order].ubound);
|
||||
}
|
||||
|
||||
for (i = 0; i < NUM_WR_Q-1; i++) {
|
||||
if ((write_arb_addr[i].l == PXP2_REG_RQ_BW_WR_L29) ||
|
||||
(write_arb_addr[i].l == PXP2_REG_RQ_BW_WR_L30)) {
|
||||
|
||||
REG_WR(bp, write_arb_addr[i].l,
|
||||
write_arb_data[i][w_order].l);
|
||||
|
||||
REG_WR(bp, write_arb_addr[i].add,
|
||||
write_arb_data[i][w_order].add);
|
||||
|
||||
REG_WR(bp, write_arb_addr[i].ubound,
|
||||
write_arb_data[i][w_order].ubound);
|
||||
} else {
|
||||
|
||||
val = REG_RD(bp, write_arb_addr[i].l);
|
||||
REG_WR(bp, write_arb_addr[i].l,
|
||||
val | (write_arb_data[i][w_order].l << 10));
|
||||
|
||||
val = REG_RD(bp, write_arb_addr[i].add);
|
||||
REG_WR(bp, write_arb_addr[i].add,
|
||||
val | (write_arb_data[i][w_order].add << 10));
|
||||
|
||||
val = REG_RD(bp, write_arb_addr[i].ubound);
|
||||
REG_WR(bp, write_arb_addr[i].ubound,
|
||||
val | (write_arb_data[i][w_order].ubound << 7));
|
||||
}
|
||||
}
|
||||
|
||||
val = write_arb_data[NUM_WR_Q-1][w_order].add;
|
||||
val += write_arb_data[NUM_WR_Q-1][w_order].ubound << 10;
|
||||
val += write_arb_data[NUM_WR_Q-1][w_order].l << 17;
|
||||
REG_WR(bp, PXP2_REG_PSWRQ_BW_RD, val);
|
||||
|
||||
val = read_arb_data[NUM_RD_Q-1][r_order].add;
|
||||
val += read_arb_data[NUM_RD_Q-1][r_order].ubound << 10;
|
||||
val += read_arb_data[NUM_RD_Q-1][r_order].l << 17;
|
||||
REG_WR(bp, PXP2_REG_PSWRQ_BW_WR, val);
|
||||
|
||||
REG_WR(bp, PXP2_REG_RQ_WR_MBS0, w_order);
|
||||
REG_WR(bp, PXP2_REG_RQ_WR_MBS1, w_order);
|
||||
REG_WR(bp, PXP2_REG_RQ_RD_MBS0, r_order);
|
||||
REG_WR(bp, PXP2_REG_RQ_RD_MBS1, r_order);
|
||||
|
||||
if (r_order == MAX_RD_ORD)
|
||||
REG_WR(bp, PXP2_REG_RQ_PDR_LIMIT, 0xe00);
|
||||
|
||||
REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order));
|
||||
|
||||
if (CHIP_IS_E1H(bp)) {
|
||||
val = ((w_order == 0) ? 2 : 3);
|
||||
REG_WR(bp, PXP2_REG_WR_HC_MPS, val);
|
||||
REG_WR(bp, PXP2_REG_WR_USDM_MPS, val);
|
||||
REG_WR(bp, PXP2_REG_WR_CSDM_MPS, val);
|
||||
REG_WR(bp, PXP2_REG_WR_TSDM_MPS, val);
|
||||
REG_WR(bp, PXP2_REG_WR_XSDM_MPS, val);
|
||||
REG_WR(bp, PXP2_REG_WR_QM_MPS, val);
|
||||
REG_WR(bp, PXP2_REG_WR_TM_MPS, val);
|
||||
REG_WR(bp, PXP2_REG_WR_SRC_MPS, val);
|
||||
REG_WR(bp, PXP2_REG_WR_DBG_MPS, val);
|
||||
REG_WR(bp, PXP2_REG_WR_DMAE_MPS, 2); /* DMAE is special */
|
||||
REG_WR(bp, PXP2_REG_WR_CDU_MPS, val);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* CDU
|
||||
|
|
@ -695,128 +344,12 @@ static void bnx2x_init_pxp(struct bnx2x *bp)
|
|||
(0x80 | ((_type) & 0xf << 3) | (CDU_CRC8(_cid, _region, _type) & 0x7))
|
||||
#define CDU_RSRVD_INVALIDATE_CONTEXT_VALUE(_val) ((_val) & ~0x80)
|
||||
|
||||
/*****************************************************************************
|
||||
* Description:
|
||||
* Calculates crc 8 on a word value: polynomial 0-1-2-8
|
||||
* Code was translated from Verilog.
|
||||
****************************************************************************/
|
||||
static u8 calc_crc8(u32 data, u8 crc)
|
||||
{
|
||||
u8 D[32];
|
||||
u8 NewCRC[8];
|
||||
u8 C[8];
|
||||
u8 crc_res;
|
||||
u8 i;
|
||||
|
||||
/* split the data into 31 bits */
|
||||
for (i = 0; i < 32; i++) {
|
||||
D[i] = data & 1;
|
||||
data = data >> 1;
|
||||
}
|
||||
|
||||
/* split the crc into 8 bits */
|
||||
for (i = 0; i < 8; i++) {
|
||||
C[i] = crc & 1;
|
||||
crc = crc >> 1;
|
||||
}
|
||||
|
||||
NewCRC[0] = D[31] ^ D[30] ^ D[28] ^ D[23] ^ D[21] ^ D[19] ^ D[18] ^
|
||||
D[16] ^ D[14] ^ D[12] ^ D[8] ^ D[7] ^ D[6] ^ D[0] ^ C[4] ^
|
||||
C[6] ^ C[7];
|
||||
NewCRC[1] = D[30] ^ D[29] ^ D[28] ^ D[24] ^ D[23] ^ D[22] ^ D[21] ^
|
||||
D[20] ^ D[18] ^ D[17] ^ D[16] ^ D[15] ^ D[14] ^ D[13] ^
|
||||
D[12] ^ D[9] ^ D[6] ^ D[1] ^ D[0] ^ C[0] ^ C[4] ^ C[5] ^ C[6];
|
||||
NewCRC[2] = D[29] ^ D[28] ^ D[25] ^ D[24] ^ D[22] ^ D[17] ^ D[15] ^
|
||||
D[13] ^ D[12] ^ D[10] ^ D[8] ^ D[6] ^ D[2] ^ D[1] ^ D[0] ^
|
||||
C[0] ^ C[1] ^ C[4] ^ C[5];
|
||||
NewCRC[3] = D[30] ^ D[29] ^ D[26] ^ D[25] ^ D[23] ^ D[18] ^ D[16] ^
|
||||
D[14] ^ D[13] ^ D[11] ^ D[9] ^ D[7] ^ D[3] ^ D[2] ^ D[1] ^
|
||||
C[1] ^ C[2] ^ C[5] ^ C[6];
|
||||
NewCRC[4] = D[31] ^ D[30] ^ D[27] ^ D[26] ^ D[24] ^ D[19] ^ D[17] ^
|
||||
D[15] ^ D[14] ^ D[12] ^ D[10] ^ D[8] ^ D[4] ^ D[3] ^ D[2] ^
|
||||
C[0] ^ C[2] ^ C[3] ^ C[6] ^ C[7];
|
||||
NewCRC[5] = D[31] ^ D[28] ^ D[27] ^ D[25] ^ D[20] ^ D[18] ^ D[16] ^
|
||||
D[15] ^ D[13] ^ D[11] ^ D[9] ^ D[5] ^ D[4] ^ D[3] ^ C[1] ^
|
||||
C[3] ^ C[4] ^ C[7];
|
||||
NewCRC[6] = D[29] ^ D[28] ^ D[26] ^ D[21] ^ D[19] ^ D[17] ^ D[16] ^
|
||||
D[14] ^ D[12] ^ D[10] ^ D[6] ^ D[5] ^ D[4] ^ C[2] ^ C[4] ^
|
||||
C[5];
|
||||
NewCRC[7] = D[30] ^ D[29] ^ D[27] ^ D[22] ^ D[20] ^ D[18] ^ D[17] ^
|
||||
D[15] ^ D[13] ^ D[11] ^ D[7] ^ D[6] ^ D[5] ^ C[3] ^ C[5] ^
|
||||
C[6];
|
||||
|
||||
crc_res = 0;
|
||||
for (i = 0; i < 8; i++)
|
||||
crc_res |= (NewCRC[i] << i);
|
||||
|
||||
return crc_res;
|
||||
}
|
||||
|
||||
/* registers addresses are not in order
|
||||
so these arrays help simplify the code */
|
||||
static const int cm_start[E1H_FUNC_MAX][9] = {
|
||||
{MISC_FUNC0_START, TCM_FUNC0_START, UCM_FUNC0_START, CCM_FUNC0_START,
|
||||
XCM_FUNC0_START, TSEM_FUNC0_START, USEM_FUNC0_START, CSEM_FUNC0_START,
|
||||
XSEM_FUNC0_START},
|
||||
{MISC_FUNC1_START, TCM_FUNC1_START, UCM_FUNC1_START, CCM_FUNC1_START,
|
||||
XCM_FUNC1_START, TSEM_FUNC1_START, USEM_FUNC1_START, CSEM_FUNC1_START,
|
||||
XSEM_FUNC1_START},
|
||||
{MISC_FUNC2_START, TCM_FUNC2_START, UCM_FUNC2_START, CCM_FUNC2_START,
|
||||
XCM_FUNC2_START, TSEM_FUNC2_START, USEM_FUNC2_START, CSEM_FUNC2_START,
|
||||
XSEM_FUNC2_START},
|
||||
{MISC_FUNC3_START, TCM_FUNC3_START, UCM_FUNC3_START, CCM_FUNC3_START,
|
||||
XCM_FUNC3_START, TSEM_FUNC3_START, USEM_FUNC3_START, CSEM_FUNC3_START,
|
||||
XSEM_FUNC3_START},
|
||||
{MISC_FUNC4_START, TCM_FUNC4_START, UCM_FUNC4_START, CCM_FUNC4_START,
|
||||
XCM_FUNC4_START, TSEM_FUNC4_START, USEM_FUNC4_START, CSEM_FUNC4_START,
|
||||
XSEM_FUNC4_START},
|
||||
{MISC_FUNC5_START, TCM_FUNC5_START, UCM_FUNC5_START, CCM_FUNC5_START,
|
||||
XCM_FUNC5_START, TSEM_FUNC5_START, USEM_FUNC5_START, CSEM_FUNC5_START,
|
||||
XSEM_FUNC5_START},
|
||||
{MISC_FUNC6_START, TCM_FUNC6_START, UCM_FUNC6_START, CCM_FUNC6_START,
|
||||
XCM_FUNC6_START, TSEM_FUNC6_START, USEM_FUNC6_START, CSEM_FUNC6_START,
|
||||
XSEM_FUNC6_START},
|
||||
{MISC_FUNC7_START, TCM_FUNC7_START, UCM_FUNC7_START, CCM_FUNC7_START,
|
||||
XCM_FUNC7_START, TSEM_FUNC7_START, USEM_FUNC7_START, CSEM_FUNC7_START,
|
||||
XSEM_FUNC7_START}
|
||||
};
|
||||
|
||||
static const int cm_end[E1H_FUNC_MAX][9] = {
|
||||
{MISC_FUNC0_END, TCM_FUNC0_END, UCM_FUNC0_END, CCM_FUNC0_END,
|
||||
XCM_FUNC0_END, TSEM_FUNC0_END, USEM_FUNC0_END, CSEM_FUNC0_END,
|
||||
XSEM_FUNC0_END},
|
||||
{MISC_FUNC1_END, TCM_FUNC1_END, UCM_FUNC1_END, CCM_FUNC1_END,
|
||||
XCM_FUNC1_END, TSEM_FUNC1_END, USEM_FUNC1_END, CSEM_FUNC1_END,
|
||||
XSEM_FUNC1_END},
|
||||
{MISC_FUNC2_END, TCM_FUNC2_END, UCM_FUNC2_END, CCM_FUNC2_END,
|
||||
XCM_FUNC2_END, TSEM_FUNC2_END, USEM_FUNC2_END, CSEM_FUNC2_END,
|
||||
XSEM_FUNC2_END},
|
||||
{MISC_FUNC3_END, TCM_FUNC3_END, UCM_FUNC3_END, CCM_FUNC3_END,
|
||||
XCM_FUNC3_END, TSEM_FUNC3_END, USEM_FUNC3_END, CSEM_FUNC3_END,
|
||||
XSEM_FUNC3_END},
|
||||
{MISC_FUNC4_END, TCM_FUNC4_END, UCM_FUNC4_END, CCM_FUNC4_END,
|
||||
XCM_FUNC4_END, TSEM_FUNC4_END, USEM_FUNC4_END, CSEM_FUNC4_END,
|
||||
XSEM_FUNC4_END},
|
||||
{MISC_FUNC5_END, TCM_FUNC5_END, UCM_FUNC5_END, CCM_FUNC5_END,
|
||||
XCM_FUNC5_END, TSEM_FUNC5_END, USEM_FUNC5_END, CSEM_FUNC5_END,
|
||||
XSEM_FUNC5_END},
|
||||
{MISC_FUNC6_END, TCM_FUNC6_END, UCM_FUNC6_END, CCM_FUNC6_END,
|
||||
XCM_FUNC6_END, TSEM_FUNC6_END, USEM_FUNC6_END, CSEM_FUNC6_END,
|
||||
XSEM_FUNC6_END},
|
||||
{MISC_FUNC7_END, TCM_FUNC7_END, UCM_FUNC7_END, CCM_FUNC7_END,
|
||||
XCM_FUNC7_END, TSEM_FUNC7_END, USEM_FUNC7_END, CSEM_FUNC7_END,
|
||||
XSEM_FUNC7_END},
|
||||
};
|
||||
|
||||
static const int hc_limits[E1H_FUNC_MAX][2] = {
|
||||
{HC_FUNC0_START, HC_FUNC0_END},
|
||||
{HC_FUNC1_START, HC_FUNC1_END},
|
||||
{HC_FUNC2_START, HC_FUNC2_END},
|
||||
{HC_FUNC3_START, HC_FUNC3_END},
|
||||
{HC_FUNC4_START, HC_FUNC4_END},
|
||||
{HC_FUNC5_START, HC_FUNC5_END},
|
||||
{HC_FUNC6_START, HC_FUNC6_END},
|
||||
{HC_FUNC7_START, HC_FUNC7_END}
|
||||
static const int cm_blocks[9] = {
|
||||
MISC_BLOCK, TCM_BLOCK, UCM_BLOCK, CCM_BLOCK, XCM_BLOCK,
|
||||
TSEM_BLOCK, USEM_BLOCK, CSEM_BLOCK, XSEM_BLOCK
|
||||
};
|
||||
|
||||
#endif /* BNX2X_INIT_H */
|
||||
|
|
|
|||
442
drivers/net/bnx2x_init_ops.h
Normal file
442
drivers/net/bnx2x_init_ops.h
Normal file
|
|
@ -0,0 +1,442 @@
|
|||
/* bnx2x_init_ops.h: Broadcom Everest network driver.
|
||||
* Static functions needed during the initialization.
|
||||
* This file is "included" in bnx2x_main.c.
|
||||
*
|
||||
* Copyright (c) 2007-2009 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Maintained by: Eilon Greenstein <eilong@broadcom.com>
|
||||
* Written by: Vladislav Zolotarov <vladz@broadcom.com>
|
||||
*/
|
||||
#ifndef BNX2X_INIT_OPS_H
|
||||
#define BNX2X_INIT_OPS_H
|
||||
|
||||
static void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val);
|
||||
static int bnx2x_gunzip(struct bnx2x *bp, const u8 *zbuf, int len);
|
||||
|
||||
static void bnx2x_init_str_wr(struct bnx2x *bp, u32 addr, const u32 *data,
|
||||
u32 len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
REG_WR(bp, addr + i*4, data[i]);
|
||||
if (!(i % 10000)) {
|
||||
touch_softlockup_watchdog();
|
||||
cpu_relax();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void bnx2x_init_ind_wr(struct bnx2x *bp, u32 addr, const u32 *data,
|
||||
u16 len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
REG_WR_IND(bp, addr + i*4, data[i]);
|
||||
if (!(i % 10000)) {
|
||||
touch_softlockup_watchdog();
|
||||
cpu_relax();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void bnx2x_write_big_buf(struct bnx2x *bp, u32 addr, u32 len)
|
||||
{
|
||||
int offset = 0;
|
||||
|
||||
if (bp->dmae_ready) {
|
||||
while (len > DMAE_LEN32_WR_MAX) {
|
||||
bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
|
||||
addr + offset, DMAE_LEN32_WR_MAX);
|
||||
offset += DMAE_LEN32_WR_MAX * 4;
|
||||
len -= DMAE_LEN32_WR_MAX;
|
||||
}
|
||||
bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
|
||||
addr + offset, len);
|
||||
} else
|
||||
bnx2x_init_str_wr(bp, addr, bp->gunzip_buf, len);
|
||||
}
|
||||
|
||||
static void bnx2x_init_fill(struct bnx2x *bp, u32 addr, int fill, u32 len)
|
||||
{
|
||||
u32 buf_len = (((len * 4) > FW_BUF_SIZE) ? FW_BUF_SIZE : (len * 4));
|
||||
u32 buf_len32 = buf_len / 4;
|
||||
int i;
|
||||
|
||||
memset(bp->gunzip_buf, fill, buf_len);
|
||||
|
||||
for (i = 0; i < len; i += buf_len32) {
|
||||
u32 cur_len = min(buf_len32, len - i);
|
||||
|
||||
bnx2x_write_big_buf(bp, addr + i * 4, cur_len);
|
||||
}
|
||||
}
|
||||
|
||||
static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr, const u32 *data,
|
||||
u32 len64)
|
||||
{
|
||||
u32 buf_len32 = FW_BUF_SIZE / 4;
|
||||
u32 len = len64 * 2;
|
||||
u64 data64 = 0;
|
||||
int i;
|
||||
|
||||
/* 64 bit value is in a blob: first low DWORD, then high DWORD */
|
||||
data64 = HILO_U64((*(data + 1)), (*data));
|
||||
len64 = min((u32)(FW_BUF_SIZE/8), len64);
|
||||
for (i = 0; i < len64; i++) {
|
||||
u64 *pdata = ((u64 *)(bp->gunzip_buf)) + i;
|
||||
|
||||
*pdata = data64;
|
||||
}
|
||||
|
||||
for (i = 0; i < len; i += buf_len32) {
|
||||
u32 cur_len = min(buf_len32, len - i);
|
||||
|
||||
bnx2x_write_big_buf(bp, addr + i * 4, cur_len);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************
|
||||
There are different blobs for each PRAM section.
|
||||
In addition, each blob write operation is divided into a few operations
|
||||
in order to decrease the amount of phys. contiguous buffer needed.
|
||||
Thus, when we select a blob the address may be with some offset
|
||||
from the beginning of PRAM section.
|
||||
The same holds for the INT_TABLE sections.
|
||||
**********************************************************/
|
||||
#define IF_IS_INT_TABLE_ADDR(base, addr) \
|
||||
if (((base) <= (addr)) && ((base) + 0x400 >= (addr)))
|
||||
|
||||
#define IF_IS_PRAM_ADDR(base, addr) \
|
||||
if (((base) <= (addr)) && ((base) + 0x40000 >= (addr)))
|
||||
|
||||
static const u8 *bnx2x_sel_blob(struct bnx2x *bp, u32 addr, const u8 *data)
|
||||
{
|
||||
IF_IS_INT_TABLE_ADDR(TSEM_REG_INT_TABLE, addr)
|
||||
data = bp->tsem_int_table_data;
|
||||
else IF_IS_INT_TABLE_ADDR(CSEM_REG_INT_TABLE, addr)
|
||||
data = bp->csem_int_table_data;
|
||||
else IF_IS_INT_TABLE_ADDR(USEM_REG_INT_TABLE, addr)
|
||||
data = bp->usem_int_table_data;
|
||||
else IF_IS_INT_TABLE_ADDR(XSEM_REG_INT_TABLE, addr)
|
||||
data = bp->xsem_int_table_data;
|
||||
else IF_IS_PRAM_ADDR(TSEM_REG_PRAM, addr)
|
||||
data = bp->tsem_pram_data;
|
||||
else IF_IS_PRAM_ADDR(CSEM_REG_PRAM, addr)
|
||||
data = bp->csem_pram_data;
|
||||
else IF_IS_PRAM_ADDR(USEM_REG_PRAM, addr)
|
||||
data = bp->usem_pram_data;
|
||||
else IF_IS_PRAM_ADDR(XSEM_REG_PRAM, addr)
|
||||
data = bp->xsem_pram_data;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static void bnx2x_write_big_buf_wb(struct bnx2x *bp, u32 addr, u32 len)
|
||||
{
|
||||
int offset = 0;
|
||||
|
||||
if (bp->dmae_ready) {
|
||||
while (len > DMAE_LEN32_WR_MAX) {
|
||||
bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
|
||||
addr + offset, DMAE_LEN32_WR_MAX);
|
||||
offset += DMAE_LEN32_WR_MAX * 4;
|
||||
len -= DMAE_LEN32_WR_MAX;
|
||||
}
|
||||
bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
|
||||
addr + offset, len);
|
||||
} else
|
||||
bnx2x_init_ind_wr(bp, addr, bp->gunzip_buf, len);
|
||||
}
|
||||
|
||||
static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, const u32 *data,
|
||||
u32 len)
|
||||
{
|
||||
/* This is needed for NO_ZIP mode, currently supported
|
||||
in little endian mode only */
|
||||
data = (const u32*)bnx2x_sel_blob(bp, addr, (const u8*)data);
|
||||
|
||||
if ((len * 4) > FW_BUF_SIZE) {
|
||||
BNX2X_ERR("LARGE DMAE OPERATION ! "
|
||||
"addr 0x%x len 0x%x\n", addr, len*4);
|
||||
return;
|
||||
}
|
||||
memcpy(bp->gunzip_buf, data, len * 4);
|
||||
|
||||
bnx2x_write_big_buf_wb(bp, addr, len);
|
||||
}
|
||||
|
||||
static void bnx2x_init_wr_zp(struct bnx2x *bp, u32 addr,
|
||||
u32 len, u32 blob_off)
|
||||
{
|
||||
int rc, i;
|
||||
const u8 *data = NULL;
|
||||
|
||||
data = bnx2x_sel_blob(bp, addr, data) + 4*blob_off;
|
||||
|
||||
if (data == NULL) {
|
||||
panic("Blob not found for addr 0x%x\n", addr);
|
||||
return;
|
||||
}
|
||||
|
||||
rc = bnx2x_gunzip(bp, data, len);
|
||||
if (rc) {
|
||||
BNX2X_ERR("gunzip failed ! addr 0x%x rc %d\n", addr, rc);
|
||||
BNX2X_ERR("blob_offset=0x%x\n", blob_off);
|
||||
return;
|
||||
}
|
||||
|
||||
/* gunzip_outlen is in dwords */
|
||||
len = bp->gunzip_outlen;
|
||||
for (i = 0; i < len; i++)
|
||||
((u32 *)bp->gunzip_buf)[i] =
|
||||
cpu_to_le32(((u32 *)bp->gunzip_buf)[i]);
|
||||
|
||||
bnx2x_write_big_buf_wb(bp, addr, len);
|
||||
}
|
||||
|
||||
static void bnx2x_init_block(struct bnx2x *bp, u32 block, u32 stage)
|
||||
{
|
||||
int hw_wr, i;
|
||||
u16 op_start =
|
||||
bp->init_ops_offsets[BLOCK_OPS_IDX(block,stage,STAGE_START)];
|
||||
u16 op_end =
|
||||
bp->init_ops_offsets[BLOCK_OPS_IDX(block,stage,STAGE_END)];
|
||||
union init_op *op;
|
||||
u32 op_type, addr, len;
|
||||
const u32 *data, *data_base;
|
||||
|
||||
/* If empty block */
|
||||
if (op_start == op_end)
|
||||
return;
|
||||
|
||||
if (CHIP_REV_IS_FPGA(bp))
|
||||
hw_wr = OP_WR_FPGA;
|
||||
else if (CHIP_REV_IS_EMUL(bp))
|
||||
hw_wr = OP_WR_EMUL;
|
||||
else
|
||||
hw_wr = OP_WR_ASIC;
|
||||
|
||||
data_base = bp->init_data;
|
||||
|
||||
for (i = op_start; i < op_end; i++) {
|
||||
|
||||
op = (union init_op *)&(bp->init_ops[i]);
|
||||
|
||||
op_type = op->str_wr.op;
|
||||
addr = op->str_wr.offset;
|
||||
len = op->str_wr.data_len;
|
||||
data = data_base + op->str_wr.data_off;
|
||||
|
||||
/* HW/EMUL specific */
|
||||
if (unlikely((op_type > OP_WB) && (op_type == hw_wr)))
|
||||
op_type = OP_WR;
|
||||
|
||||
switch (op_type) {
|
||||
case OP_RD:
|
||||
REG_RD(bp, addr);
|
||||
break;
|
||||
case OP_WR:
|
||||
REG_WR(bp, addr, op->write.val);
|
||||
break;
|
||||
case OP_SW:
|
||||
bnx2x_init_str_wr(bp, addr, data, len);
|
||||
break;
|
||||
case OP_WB:
|
||||
bnx2x_init_wr_wb(bp, addr, data, len);
|
||||
break;
|
||||
case OP_SI:
|
||||
bnx2x_init_ind_wr(bp, addr, data, len);
|
||||
break;
|
||||
case OP_ZR:
|
||||
bnx2x_init_fill(bp, addr, 0, op->zero.len);
|
||||
break;
|
||||
case OP_ZP:
|
||||
bnx2x_init_wr_zp(bp, addr, len,
|
||||
op->str_wr.data_off);
|
||||
break;
|
||||
case OP_WR_64:
|
||||
bnx2x_init_wr_64(bp, addr, data, len);
|
||||
break;
|
||||
default:
|
||||
/* happens whenever an op is of a diff HW */
|
||||
#if 0
|
||||
DP(NETIF_MSG_HW, "skipping init operation "
|
||||
"index %d[%d:%d]: type %d addr 0x%x "
|
||||
"len %d(0x%x)\n",
|
||||
i, op_start, op_end, op_type, addr, len, len);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* PXP */
|
||||
static void bnx2x_init_pxp(struct bnx2x *bp)
|
||||
{
|
||||
u16 devctl;
|
||||
int r_order, w_order;
|
||||
u32 val, i;
|
||||
|
||||
pci_read_config_word(bp->pdev,
|
||||
bp->pcie_cap + PCI_EXP_DEVCTL, &devctl);
|
||||
DP(NETIF_MSG_HW, "read 0x%x from devctl\n", devctl);
|
||||
w_order = ((devctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
|
||||
if (bp->mrrs == -1)
|
||||
r_order = ((devctl & PCI_EXP_DEVCTL_READRQ) >> 12);
|
||||
else {
|
||||
DP(NETIF_MSG_HW, "force read order to %d\n", bp->mrrs);
|
||||
r_order = bp->mrrs;
|
||||
}
|
||||
|
||||
if (r_order > MAX_RD_ORD) {
|
||||
DP(NETIF_MSG_HW, "read order of %d order adjusted to %d\n",
|
||||
r_order, MAX_RD_ORD);
|
||||
r_order = MAX_RD_ORD;
|
||||
}
|
||||
if (w_order > MAX_WR_ORD) {
|
||||
DP(NETIF_MSG_HW, "write order of %d order adjusted to %d\n",
|
||||
w_order, MAX_WR_ORD);
|
||||
w_order = MAX_WR_ORD;
|
||||
}
|
||||
if (CHIP_REV_IS_FPGA(bp)) {
|
||||
DP(NETIF_MSG_HW, "write order adjusted to 1 for FPGA\n");
|
||||
w_order = 0;
|
||||
}
|
||||
DP(NETIF_MSG_HW, "read order %d write order %d\n", r_order, w_order);
|
||||
|
||||
for (i = 0; i < NUM_RD_Q-1; i++) {
|
||||
REG_WR(bp, read_arb_addr[i].l, read_arb_data[i][r_order].l);
|
||||
REG_WR(bp, read_arb_addr[i].add,
|
||||
read_arb_data[i][r_order].add);
|
||||
REG_WR(bp, read_arb_addr[i].ubound,
|
||||
read_arb_data[i][r_order].ubound);
|
||||
}
|
||||
|
||||
for (i = 0; i < NUM_WR_Q-1; i++) {
|
||||
if ((write_arb_addr[i].l == PXP2_REG_RQ_BW_WR_L29) ||
|
||||
(write_arb_addr[i].l == PXP2_REG_RQ_BW_WR_L30)) {
|
||||
|
||||
REG_WR(bp, write_arb_addr[i].l,
|
||||
write_arb_data[i][w_order].l);
|
||||
|
||||
REG_WR(bp, write_arb_addr[i].add,
|
||||
write_arb_data[i][w_order].add);
|
||||
|
||||
REG_WR(bp, write_arb_addr[i].ubound,
|
||||
write_arb_data[i][w_order].ubound);
|
||||
} else {
|
||||
|
||||
val = REG_RD(bp, write_arb_addr[i].l);
|
||||
REG_WR(bp, write_arb_addr[i].l,
|
||||
val | (write_arb_data[i][w_order].l << 10));
|
||||
|
||||
val = REG_RD(bp, write_arb_addr[i].add);
|
||||
REG_WR(bp, write_arb_addr[i].add,
|
||||
val | (write_arb_data[i][w_order].add << 10));
|
||||
|
||||
val = REG_RD(bp, write_arb_addr[i].ubound);
|
||||
REG_WR(bp, write_arb_addr[i].ubound,
|
||||
val | (write_arb_data[i][w_order].ubound << 7));
|
||||
}
|
||||
}
|
||||
|
||||
val = write_arb_data[NUM_WR_Q-1][w_order].add;
|
||||
val += write_arb_data[NUM_WR_Q-1][w_order].ubound << 10;
|
||||
val += write_arb_data[NUM_WR_Q-1][w_order].l << 17;
|
||||
REG_WR(bp, PXP2_REG_PSWRQ_BW_RD, val);
|
||||
|
||||
val = read_arb_data[NUM_RD_Q-1][r_order].add;
|
||||
val += read_arb_data[NUM_RD_Q-1][r_order].ubound << 10;
|
||||
val += read_arb_data[NUM_RD_Q-1][r_order].l << 17;
|
||||
REG_WR(bp, PXP2_REG_PSWRQ_BW_WR, val);
|
||||
|
||||
REG_WR(bp, PXP2_REG_RQ_WR_MBS0, w_order);
|
||||
REG_WR(bp, PXP2_REG_RQ_WR_MBS1, w_order);
|
||||
REG_WR(bp, PXP2_REG_RQ_RD_MBS0, r_order);
|
||||
REG_WR(bp, PXP2_REG_RQ_RD_MBS1, r_order);
|
||||
|
||||
if (r_order == MAX_RD_ORD)
|
||||
REG_WR(bp, PXP2_REG_RQ_PDR_LIMIT, 0xe00);
|
||||
|
||||
REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order));
|
||||
|
||||
if (CHIP_IS_E1H(bp)) {
|
||||
val = ((w_order == 0) ? 2 : 3);
|
||||
REG_WR(bp, PXP2_REG_WR_HC_MPS, val);
|
||||
REG_WR(bp, PXP2_REG_WR_USDM_MPS, val);
|
||||
REG_WR(bp, PXP2_REG_WR_CSDM_MPS, val);
|
||||
REG_WR(bp, PXP2_REG_WR_TSDM_MPS, val);
|
||||
REG_WR(bp, PXP2_REG_WR_XSDM_MPS, val);
|
||||
REG_WR(bp, PXP2_REG_WR_QM_MPS, val);
|
||||
REG_WR(bp, PXP2_REG_WR_TM_MPS, val);
|
||||
REG_WR(bp, PXP2_REG_WR_SRC_MPS, val);
|
||||
REG_WR(bp, PXP2_REG_WR_DBG_MPS, val);
|
||||
REG_WR(bp, PXP2_REG_WR_DMAE_MPS, 2); /* DMAE is special */
|
||||
REG_WR(bp, PXP2_REG_WR_CDU_MPS, val);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Description:
|
||||
* Calculates crc 8 on a word value: polynomial 0-1-2-8
|
||||
* Code was translated from Verilog.
|
||||
****************************************************************************/
|
||||
static u8 calc_crc8(u32 data, u8 crc)
|
||||
{
|
||||
u8 D[32];
|
||||
u8 NewCRC[8];
|
||||
u8 C[8];
|
||||
u8 crc_res;
|
||||
u8 i;
|
||||
|
||||
/* split the data into 31 bits */
|
||||
for (i = 0; i < 32; i++) {
|
||||
D[i] = data & 1;
|
||||
data = data >> 1;
|
||||
}
|
||||
|
||||
/* split the crc into 8 bits */
|
||||
for (i = 0; i < 8; i++) {
|
||||
C[i] = crc & 1;
|
||||
crc = crc >> 1;
|
||||
}
|
||||
|
||||
NewCRC[0] = D[31] ^ D[30] ^ D[28] ^ D[23] ^ D[21] ^ D[19] ^ D[18] ^
|
||||
D[16] ^ D[14] ^ D[12] ^ D[8] ^ D[7] ^ D[6] ^ D[0] ^ C[4] ^
|
||||
C[6] ^ C[7];
|
||||
NewCRC[1] = D[30] ^ D[29] ^ D[28] ^ D[24] ^ D[23] ^ D[22] ^ D[21] ^
|
||||
D[20] ^ D[18] ^ D[17] ^ D[16] ^ D[15] ^ D[14] ^ D[13] ^
|
||||
D[12] ^ D[9] ^ D[6] ^ D[1] ^ D[0] ^ C[0] ^ C[4] ^ C[5] ^ C[6];
|
||||
NewCRC[2] = D[29] ^ D[28] ^ D[25] ^ D[24] ^ D[22] ^ D[17] ^ D[15] ^
|
||||
D[13] ^ D[12] ^ D[10] ^ D[8] ^ D[6] ^ D[2] ^ D[1] ^ D[0] ^
|
||||
C[0] ^ C[1] ^ C[4] ^ C[5];
|
||||
NewCRC[3] = D[30] ^ D[29] ^ D[26] ^ D[25] ^ D[23] ^ D[18] ^ D[16] ^
|
||||
D[14] ^ D[13] ^ D[11] ^ D[9] ^ D[7] ^ D[3] ^ D[2] ^ D[1] ^
|
||||
C[1] ^ C[2] ^ C[5] ^ C[6];
|
||||
NewCRC[4] = D[31] ^ D[30] ^ D[27] ^ D[26] ^ D[24] ^ D[19] ^ D[17] ^
|
||||
D[15] ^ D[14] ^ D[12] ^ D[10] ^ D[8] ^ D[4] ^ D[3] ^ D[2] ^
|
||||
C[0] ^ C[2] ^ C[3] ^ C[6] ^ C[7];
|
||||
NewCRC[5] = D[31] ^ D[28] ^ D[27] ^ D[25] ^ D[20] ^ D[18] ^ D[16] ^
|
||||
D[15] ^ D[13] ^ D[11] ^ D[9] ^ D[5] ^ D[4] ^ D[3] ^ C[1] ^
|
||||
C[3] ^ C[4] ^ C[7];
|
||||
NewCRC[6] = D[29] ^ D[28] ^ D[26] ^ D[21] ^ D[19] ^ D[17] ^ D[16] ^
|
||||
D[14] ^ D[12] ^ D[10] ^ D[6] ^ D[5] ^ D[4] ^ C[2] ^ C[4] ^
|
||||
C[5];
|
||||
NewCRC[7] = D[30] ^ D[29] ^ D[27] ^ D[22] ^ D[20] ^ D[18] ^ D[17] ^
|
||||
D[15] ^ D[13] ^ D[11] ^ D[7] ^ D[6] ^ D[5] ^ C[3] ^ C[5] ^
|
||||
C[6];
|
||||
|
||||
crc_res = 0;
|
||||
for (i = 0; i < 8; i++)
|
||||
crc_res |= (NewCRC[i] << i);
|
||||
|
||||
return crc_res;
|
||||
}
|
||||
|
||||
#endif /* BNX2X_INIT_OPS_H */
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -53,12 +53,19 @@
|
|||
|
||||
#include "bnx2x.h"
|
||||
#include "bnx2x_init.h"
|
||||
#include "bnx2x_init_ops.h"
|
||||
#include "bnx2x_dump.h"
|
||||
|
||||
#define DRV_MODULE_VERSION "1.48.105"
|
||||
#define DRV_MODULE_RELDATE "2009/03/02"
|
||||
#define DRV_MODULE_VERSION "1.48.105-1"
|
||||
#define DRV_MODULE_RELDATE "2009/04/22"
|
||||
#define BNX2X_BC_VER 0x040200
|
||||
|
||||
#include <linux/firmware.h>
|
||||
#include "bnx2x_fw_file_hdr.h"
|
||||
/* FW files */
|
||||
#define FW_FILE_PREFIX_E1 "bnx2x-e1-"
|
||||
#define FW_FILE_PREFIX_E1H "bnx2x-e1h-"
|
||||
|
||||
/* Time in jiffies before concluding the transmitter is hung */
|
||||
#define TX_TIMEOUT (5*HZ)
|
||||
|
||||
|
|
@ -1539,7 +1546,7 @@ static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
|
|||
len, cqe, comp_ring_cons);
|
||||
#ifdef BNX2X_STOP_ON_ERROR
|
||||
if (bp->panic)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
bnx2x_update_sge_prod(fp,
|
||||
|
|
@ -5232,13 +5239,15 @@ static void bnx2x_gunzip_end(struct bnx2x *bp)
|
|||
}
|
||||
}
|
||||
|
||||
static int bnx2x_gunzip(struct bnx2x *bp, u8 *zbuf, int len)
|
||||
static int bnx2x_gunzip(struct bnx2x *bp, const u8 *zbuf, int len)
|
||||
{
|
||||
int n, rc;
|
||||
|
||||
/* check gzip header */
|
||||
if ((zbuf[0] != 0x1f) || (zbuf[1] != 0x8b) || (zbuf[2] != Z_DEFLATED))
|
||||
if ((zbuf[0] != 0x1f) || (zbuf[1] != 0x8b) || (zbuf[2] != Z_DEFLATED)) {
|
||||
BNX2X_ERR("Bad gzip header\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
n = 10;
|
||||
|
||||
|
|
@ -5247,7 +5256,7 @@ static int bnx2x_gunzip(struct bnx2x *bp, u8 *zbuf, int len)
|
|||
if (zbuf[3] & FNAME)
|
||||
while ((zbuf[n++] != 0) && (n < len));
|
||||
|
||||
bp->strm->next_in = zbuf + n;
|
||||
bp->strm->next_in = (typeof(bp->strm->next_in))zbuf + n;
|
||||
bp->strm->avail_in = len - n;
|
||||
bp->strm->next_out = bp->gunzip_buf;
|
||||
bp->strm->avail_out = FW_BUF_SIZE;
|
||||
|
|
@ -5369,8 +5378,8 @@ static int bnx2x_int_mem_test(struct bnx2x *bp)
|
|||
msleep(50);
|
||||
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0x03);
|
||||
msleep(50);
|
||||
bnx2x_init_block(bp, BRB1_COMMON_START, BRB1_COMMON_END);
|
||||
bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END);
|
||||
bnx2x_init_block(bp, BRB1_BLOCK, COMMON_STAGE);
|
||||
bnx2x_init_block(bp, PRS_BLOCK, COMMON_STAGE);
|
||||
|
||||
DP(NETIF_MSG_HW, "part2\n");
|
||||
|
||||
|
|
@ -5434,8 +5443,8 @@ static int bnx2x_int_mem_test(struct bnx2x *bp)
|
|||
msleep(50);
|
||||
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0x03);
|
||||
msleep(50);
|
||||
bnx2x_init_block(bp, BRB1_COMMON_START, BRB1_COMMON_END);
|
||||
bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END);
|
||||
bnx2x_init_block(bp, BRB1_BLOCK, COMMON_STAGE);
|
||||
bnx2x_init_block(bp, PRS_BLOCK, COMMON_STAGE);
|
||||
#ifndef BCM_ISCSI
|
||||
/* set NIC mode */
|
||||
REG_WR(bp, PRS_REG_NIC_MODE, 1);
|
||||
|
|
@ -5510,7 +5519,7 @@ static int bnx2x_init_common(struct bnx2x *bp)
|
|||
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0xffffffff);
|
||||
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, 0xfffc);
|
||||
|
||||
bnx2x_init_block(bp, MISC_COMMON_START, MISC_COMMON_END);
|
||||
bnx2x_init_block(bp, MISC_BLOCK, COMMON_STAGE);
|
||||
if (CHIP_IS_E1H(bp))
|
||||
REG_WR(bp, MISC_REG_E1HMF_MODE, IS_E1HMF(bp));
|
||||
|
||||
|
|
@ -5518,14 +5527,14 @@ static int bnx2x_init_common(struct bnx2x *bp)
|
|||
msleep(30);
|
||||
REG_WR(bp, MISC_REG_LCPLL_CTRL_REG_2, 0x0);
|
||||
|
||||
bnx2x_init_block(bp, PXP_COMMON_START, PXP_COMMON_END);
|
||||
bnx2x_init_block(bp, PXP_BLOCK, COMMON_STAGE);
|
||||
if (CHIP_IS_E1(bp)) {
|
||||
/* enable HW interrupt from PXP on USDM overflow
|
||||
bit 16 on INT_MASK_0 */
|
||||
REG_WR(bp, PXP_REG_PXP_INT_MASK_0, 0);
|
||||
}
|
||||
|
||||
bnx2x_init_block(bp, PXP2_COMMON_START, PXP2_COMMON_END);
|
||||
bnx2x_init_block(bp, PXP2_BLOCK, COMMON_STAGE);
|
||||
bnx2x_init_pxp(bp);
|
||||
|
||||
#ifdef __BIG_ENDIAN
|
||||
|
|
@ -5571,60 +5580,60 @@ static int bnx2x_init_common(struct bnx2x *bp)
|
|||
REG_WR(bp, PXP2_REG_RQ_DISABLE_INPUTS, 0);
|
||||
REG_WR(bp, PXP2_REG_RD_DISABLE_INPUTS, 0);
|
||||
|
||||
bnx2x_init_block(bp, DMAE_COMMON_START, DMAE_COMMON_END);
|
||||
bnx2x_init_block(bp, DMAE_BLOCK, COMMON_STAGE);
|
||||
|
||||
/* clean the DMAE memory */
|
||||
bp->dmae_ready = 1;
|
||||
bnx2x_init_fill(bp, TSEM_REG_PRAM, 0, 8);
|
||||
|
||||
bnx2x_init_block(bp, TCM_COMMON_START, TCM_COMMON_END);
|
||||
bnx2x_init_block(bp, UCM_COMMON_START, UCM_COMMON_END);
|
||||
bnx2x_init_block(bp, CCM_COMMON_START, CCM_COMMON_END);
|
||||
bnx2x_init_block(bp, XCM_COMMON_START, XCM_COMMON_END);
|
||||
bnx2x_init_block(bp, TCM_BLOCK, COMMON_STAGE);
|
||||
bnx2x_init_block(bp, UCM_BLOCK, COMMON_STAGE);
|
||||
bnx2x_init_block(bp, CCM_BLOCK, COMMON_STAGE);
|
||||
bnx2x_init_block(bp, XCM_BLOCK, COMMON_STAGE);
|
||||
|
||||
bnx2x_read_dmae(bp, XSEM_REG_PASSIVE_BUFFER, 3);
|
||||
bnx2x_read_dmae(bp, CSEM_REG_PASSIVE_BUFFER, 3);
|
||||
bnx2x_read_dmae(bp, TSEM_REG_PASSIVE_BUFFER, 3);
|
||||
bnx2x_read_dmae(bp, USEM_REG_PASSIVE_BUFFER, 3);
|
||||
|
||||
bnx2x_init_block(bp, QM_COMMON_START, QM_COMMON_END);
|
||||
bnx2x_init_block(bp, QM_BLOCK, COMMON_STAGE);
|
||||
/* soft reset pulse */
|
||||
REG_WR(bp, QM_REG_SOFT_RESET, 1);
|
||||
REG_WR(bp, QM_REG_SOFT_RESET, 0);
|
||||
|
||||
#ifdef BCM_ISCSI
|
||||
bnx2x_init_block(bp, TIMERS_COMMON_START, TIMERS_COMMON_END);
|
||||
bnx2x_init_block(bp, TIMERS_BLOCK, COMMON_STAGE);
|
||||
#endif
|
||||
|
||||
bnx2x_init_block(bp, DQ_COMMON_START, DQ_COMMON_END);
|
||||
bnx2x_init_block(bp, DQ_BLOCK, COMMON_STAGE);
|
||||
REG_WR(bp, DORQ_REG_DPM_CID_OFST, BCM_PAGE_SHIFT);
|
||||
if (!CHIP_REV_IS_SLOW(bp)) {
|
||||
/* enable hw interrupt from doorbell Q */
|
||||
REG_WR(bp, DORQ_REG_DORQ_INT_MASK, 0);
|
||||
}
|
||||
|
||||
bnx2x_init_block(bp, BRB1_COMMON_START, BRB1_COMMON_END);
|
||||
bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END);
|
||||
bnx2x_init_block(bp, BRB1_BLOCK, COMMON_STAGE);
|
||||
bnx2x_init_block(bp, PRS_BLOCK, COMMON_STAGE);
|
||||
REG_WR(bp, PRS_REG_A_PRSU_20, 0xf);
|
||||
/* set NIC mode */
|
||||
REG_WR(bp, PRS_REG_NIC_MODE, 1);
|
||||
if (CHIP_IS_E1H(bp))
|
||||
REG_WR(bp, PRS_REG_E1HOV_MODE, IS_E1HMF(bp));
|
||||
|
||||
bnx2x_init_block(bp, TSDM_COMMON_START, TSDM_COMMON_END);
|
||||
bnx2x_init_block(bp, CSDM_COMMON_START, CSDM_COMMON_END);
|
||||
bnx2x_init_block(bp, USDM_COMMON_START, USDM_COMMON_END);
|
||||
bnx2x_init_block(bp, XSDM_COMMON_START, XSDM_COMMON_END);
|
||||
bnx2x_init_block(bp, TSDM_BLOCK, COMMON_STAGE);
|
||||
bnx2x_init_block(bp, CSDM_BLOCK, COMMON_STAGE);
|
||||
bnx2x_init_block(bp, USDM_BLOCK, COMMON_STAGE);
|
||||
bnx2x_init_block(bp, XSDM_BLOCK, COMMON_STAGE);
|
||||
|
||||
bnx2x_init_fill(bp, TSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp));
|
||||
bnx2x_init_fill(bp, USTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp));
|
||||
bnx2x_init_fill(bp, CSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp));
|
||||
bnx2x_init_fill(bp, XSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp));
|
||||
|
||||
bnx2x_init_block(bp, TSEM_COMMON_START, TSEM_COMMON_END);
|
||||
bnx2x_init_block(bp, USEM_COMMON_START, USEM_COMMON_END);
|
||||
bnx2x_init_block(bp, CSEM_COMMON_START, CSEM_COMMON_END);
|
||||
bnx2x_init_block(bp, XSEM_COMMON_START, XSEM_COMMON_END);
|
||||
bnx2x_init_block(bp, TSEM_BLOCK, COMMON_STAGE);
|
||||
bnx2x_init_block(bp, USEM_BLOCK, COMMON_STAGE);
|
||||
bnx2x_init_block(bp, CSEM_BLOCK, COMMON_STAGE);
|
||||
bnx2x_init_block(bp, XSEM_BLOCK, COMMON_STAGE);
|
||||
|
||||
/* sync semi rtc */
|
||||
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR,
|
||||
|
|
@ -5632,16 +5641,16 @@ static int bnx2x_init_common(struct bnx2x *bp)
|
|||
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET,
|
||||
0x80000000);
|
||||
|
||||
bnx2x_init_block(bp, UPB_COMMON_START, UPB_COMMON_END);
|
||||
bnx2x_init_block(bp, XPB_COMMON_START, XPB_COMMON_END);
|
||||
bnx2x_init_block(bp, PBF_COMMON_START, PBF_COMMON_END);
|
||||
bnx2x_init_block(bp, UPB_BLOCK, COMMON_STAGE);
|
||||
bnx2x_init_block(bp, XPB_BLOCK, COMMON_STAGE);
|
||||
bnx2x_init_block(bp, PBF_BLOCK, COMMON_STAGE);
|
||||
|
||||
REG_WR(bp, SRC_REG_SOFT_RST, 1);
|
||||
for (i = SRC_REG_KEYRSS0_0; i <= SRC_REG_KEYRSS1_9; i += 4) {
|
||||
REG_WR(bp, i, 0xc0cac01a);
|
||||
/* TODO: replace with something meaningful */
|
||||
}
|
||||
bnx2x_init_block(bp, SRCH_COMMON_START, SRCH_COMMON_END);
|
||||
bnx2x_init_block(bp, SRCH_BLOCK, COMMON_STAGE);
|
||||
REG_WR(bp, SRC_REG_SOFT_RST, 0);
|
||||
|
||||
if (sizeof(union cdu_context) != 1024)
|
||||
|
|
@ -5649,7 +5658,7 @@ static int bnx2x_init_common(struct bnx2x *bp)
|
|||
printk(KERN_ALERT PFX "please adjust the size of"
|
||||
" cdu_context(%ld)\n", (long)sizeof(union cdu_context));
|
||||
|
||||
bnx2x_init_block(bp, CDU_COMMON_START, CDU_COMMON_END);
|
||||
bnx2x_init_block(bp, CDU_BLOCK, COMMON_STAGE);
|
||||
val = (4 << 24) + (0 << 12) + 1024;
|
||||
REG_WR(bp, CDU_REG_CDU_GLOBAL_PARAMS, val);
|
||||
if (CHIP_IS_E1(bp)) {
|
||||
|
|
@ -5658,7 +5667,7 @@ static int bnx2x_init_common(struct bnx2x *bp)
|
|||
REG_WR(bp, CDU_REG_CDU_DEBUG, 0);
|
||||
}
|
||||
|
||||
bnx2x_init_block(bp, CFC_COMMON_START, CFC_COMMON_END);
|
||||
bnx2x_init_block(bp, CFC_BLOCK, COMMON_STAGE);
|
||||
REG_WR(bp, CFC_REG_INIT_REG, 0x7FF);
|
||||
/* enable context validation interrupt from CFC */
|
||||
REG_WR(bp, CFC_REG_CFC_INT_MASK, 0);
|
||||
|
|
@ -5666,20 +5675,25 @@ static int bnx2x_init_common(struct bnx2x *bp)
|
|||
/* set the thresholds to prevent CFC/CDU race */
|
||||
REG_WR(bp, CFC_REG_DEBUG0, 0x20020000);
|
||||
|
||||
bnx2x_init_block(bp, HC_COMMON_START, HC_COMMON_END);
|
||||
bnx2x_init_block(bp, MISC_AEU_COMMON_START, MISC_AEU_COMMON_END);
|
||||
bnx2x_init_block(bp, HC_BLOCK, COMMON_STAGE);
|
||||
bnx2x_init_block(bp, MISC_AEU_BLOCK, COMMON_STAGE);
|
||||
|
||||
/* PXPCS COMMON comes here */
|
||||
bnx2x_init_block(bp, PXPCS_BLOCK, COMMON_STAGE);
|
||||
/* Reset PCIE errors for debug */
|
||||
REG_WR(bp, 0x2814, 0xffffffff);
|
||||
REG_WR(bp, 0x3820, 0xffffffff);
|
||||
|
||||
/* EMAC0 COMMON comes here */
|
||||
bnx2x_init_block(bp, EMAC0_BLOCK, COMMON_STAGE);
|
||||
/* EMAC1 COMMON comes here */
|
||||
bnx2x_init_block(bp, EMAC1_BLOCK, COMMON_STAGE);
|
||||
/* DBU COMMON comes here */
|
||||
bnx2x_init_block(bp, DBU_BLOCK, COMMON_STAGE);
|
||||
/* DBG COMMON comes here */
|
||||
bnx2x_init_block(bp, DBG_BLOCK, COMMON_STAGE);
|
||||
|
||||
bnx2x_init_block(bp, NIG_COMMON_START, NIG_COMMON_END);
|
||||
bnx2x_init_block(bp, NIG_BLOCK, COMMON_STAGE);
|
||||
if (CHIP_IS_E1H(bp)) {
|
||||
REG_WR(bp, NIG_REG_LLH_MF_MODE, IS_E1HMF(bp));
|
||||
REG_WR(bp, NIG_REG_LLH_E1HOV_MODE, IS_E1HMF(bp));
|
||||
|
|
@ -5763,6 +5777,7 @@ static int bnx2x_init_common(struct bnx2x *bp)
|
|||
static int bnx2x_init_port(struct bnx2x *bp)
|
||||
{
|
||||
int port = BP_PORT(bp);
|
||||
int init_stage = port ? PORT1_STAGE : PORT0_STAGE;
|
||||
u32 low, high;
|
||||
u32 val;
|
||||
|
||||
|
|
@ -5771,7 +5786,9 @@ static int bnx2x_init_port(struct bnx2x *bp)
|
|||
REG_WR(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, 0);
|
||||
|
||||
/* Port PXP comes here */
|
||||
bnx2x_init_block(bp, PXP_BLOCK, init_stage);
|
||||
/* Port PXP2 comes here */
|
||||
bnx2x_init_block(bp, PXP2_BLOCK, init_stage);
|
||||
#ifdef BCM_ISCSI
|
||||
/* Port0 1
|
||||
* Port1 385 */
|
||||
|
|
@ -5798,21 +5815,19 @@ static int bnx2x_init_port(struct bnx2x *bp)
|
|||
REG_WR(bp, PXP2_REG_PSWRQ_SRC0_L2P + func*4, PXP_ONE_ILT(i));
|
||||
#endif
|
||||
/* Port CMs come here */
|
||||
bnx2x_init_block(bp, (port ? XCM_PORT1_START : XCM_PORT0_START),
|
||||
(port ? XCM_PORT1_END : XCM_PORT0_END));
|
||||
bnx2x_init_block(bp, XCM_BLOCK, init_stage);
|
||||
|
||||
/* Port QM comes here */
|
||||
#ifdef BCM_ISCSI
|
||||
REG_WR(bp, TM_REG_LIN0_SCAN_TIME + func*4, 1024/64*20);
|
||||
REG_WR(bp, TM_REG_LIN0_MAX_ACTIVE_CID + func*4, 31);
|
||||
|
||||
bnx2x_init_block(bp, func ? TIMERS_PORT1_START : TIMERS_PORT0_START,
|
||||
func ? TIMERS_PORT1_END : TIMERS_PORT0_END);
|
||||
bnx2x_init_block(bp, TIMERS_BLOCK, init_stage);
|
||||
#endif
|
||||
/* Port DQ comes here */
|
||||
bnx2x_init_block(bp, DQ_BLOCK, init_stage);
|
||||
|
||||
bnx2x_init_block(bp, (port ? BRB1_PORT1_START : BRB1_PORT0_START),
|
||||
(port ? BRB1_PORT1_END : BRB1_PORT0_END));
|
||||
bnx2x_init_block(bp, BRB1_BLOCK, init_stage);
|
||||
if (CHIP_REV_IS_SLOW(bp) && !CHIP_IS_E1H(bp)) {
|
||||
/* no pause for emulation and FPGA */
|
||||
low = 0;
|
||||
|
|
@ -5837,25 +5852,27 @@ static int bnx2x_init_port(struct bnx2x *bp)
|
|||
|
||||
|
||||
/* Port PRS comes here */
|
||||
bnx2x_init_block(bp, PRS_BLOCK, init_stage);
|
||||
/* Port TSDM comes here */
|
||||
bnx2x_init_block(bp, TSDM_BLOCK, init_stage);
|
||||
/* Port CSDM comes here */
|
||||
bnx2x_init_block(bp, CSDM_BLOCK, init_stage);
|
||||
/* Port USDM comes here */
|
||||
bnx2x_init_block(bp, USDM_BLOCK, init_stage);
|
||||
/* Port XSDM comes here */
|
||||
bnx2x_init_block(bp, XSDM_BLOCK, init_stage);
|
||||
|
||||
bnx2x_init_block(bp, port ? TSEM_PORT1_START : TSEM_PORT0_START,
|
||||
port ? TSEM_PORT1_END : TSEM_PORT0_END);
|
||||
bnx2x_init_block(bp, port ? USEM_PORT1_START : USEM_PORT0_START,
|
||||
port ? USEM_PORT1_END : USEM_PORT0_END);
|
||||
bnx2x_init_block(bp, port ? CSEM_PORT1_START : CSEM_PORT0_START,
|
||||
port ? CSEM_PORT1_END : CSEM_PORT0_END);
|
||||
bnx2x_init_block(bp, port ? XSEM_PORT1_START : XSEM_PORT0_START,
|
||||
port ? XSEM_PORT1_END : XSEM_PORT0_END);
|
||||
bnx2x_init_block(bp, TSEM_BLOCK, init_stage);
|
||||
bnx2x_init_block(bp, USEM_BLOCK, init_stage);
|
||||
bnx2x_init_block(bp, CSEM_BLOCK, init_stage);
|
||||
bnx2x_init_block(bp, XSEM_BLOCK, init_stage);
|
||||
|
||||
/* Port UPB comes here */
|
||||
bnx2x_init_block(bp, UPB_BLOCK, init_stage);
|
||||
/* Port XPB comes here */
|
||||
bnx2x_init_block(bp, XPB_BLOCK, init_stage);
|
||||
|
||||
bnx2x_init_block(bp, port ? PBF_PORT1_START : PBF_PORT0_START,
|
||||
port ? PBF_PORT1_END : PBF_PORT0_END);
|
||||
bnx2x_init_block(bp, PBF_BLOCK, init_stage);
|
||||
|
||||
/* configure PBF to work without PAUSE mtu 9000 */
|
||||
REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
|
||||
|
|
@ -5885,18 +5902,17 @@ static int bnx2x_init_port(struct bnx2x *bp)
|
|||
/* Port SRCH comes here */
|
||||
#endif
|
||||
/* Port CDU comes here */
|
||||
bnx2x_init_block(bp, CDU_BLOCK, init_stage);
|
||||
/* Port CFC comes here */
|
||||
bnx2x_init_block(bp, CFC_BLOCK, init_stage);
|
||||
|
||||
if (CHIP_IS_E1(bp)) {
|
||||
REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0);
|
||||
REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0);
|
||||
}
|
||||
bnx2x_init_block(bp, port ? HC_PORT1_START : HC_PORT0_START,
|
||||
port ? HC_PORT1_END : HC_PORT0_END);
|
||||
bnx2x_init_block(bp, HC_BLOCK, init_stage);
|
||||
|
||||
bnx2x_init_block(bp, port ? MISC_AEU_PORT1_START :
|
||||
MISC_AEU_PORT0_START,
|
||||
port ? MISC_AEU_PORT1_END : MISC_AEU_PORT0_END);
|
||||
bnx2x_init_block(bp, MISC_AEU_BLOCK, init_stage);
|
||||
/* init aeu_mask_attn_func_0/1:
|
||||
* - SF mode: bits 3-7 are masked. only bits 0-2 are in use
|
||||
* - MF mode: bit 3 is masked. bits 0-2 are in use as in SF
|
||||
|
|
@ -5905,13 +5921,17 @@ static int bnx2x_init_port(struct bnx2x *bp)
|
|||
(IS_E1HMF(bp) ? 0xF7 : 0x7));
|
||||
|
||||
/* Port PXPCS comes here */
|
||||
bnx2x_init_block(bp, PXPCS_BLOCK, init_stage);
|
||||
/* Port EMAC0 comes here */
|
||||
bnx2x_init_block(bp, EMAC0_BLOCK, init_stage);
|
||||
/* Port EMAC1 comes here */
|
||||
bnx2x_init_block(bp, EMAC1_BLOCK, init_stage);
|
||||
/* Port DBU comes here */
|
||||
bnx2x_init_block(bp, DBU_BLOCK, init_stage);
|
||||
/* Port DBG comes here */
|
||||
bnx2x_init_block(bp, DBG_BLOCK, init_stage);
|
||||
|
||||
bnx2x_init_block(bp, port ? NIG_PORT1_START : NIG_PORT0_START,
|
||||
port ? NIG_PORT1_END : NIG_PORT0_END);
|
||||
bnx2x_init_block(bp, NIG_BLOCK, init_stage);
|
||||
|
||||
REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1);
|
||||
|
||||
|
|
@ -5931,7 +5951,9 @@ static int bnx2x_init_port(struct bnx2x *bp)
|
|||
}
|
||||
|
||||
/* Port MCP comes here */
|
||||
bnx2x_init_block(bp, MCP_BLOCK, init_stage);
|
||||
/* Port DMAE comes here */
|
||||
bnx2x_init_block(bp, DMAE_BLOCK, init_stage);
|
||||
|
||||
switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) {
|
||||
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
|
||||
|
|
@ -6036,7 +6058,7 @@ static int bnx2x_init_func(struct bnx2x *bp)
|
|||
if (CHIP_IS_E1H(bp)) {
|
||||
for (i = 0; i < 9; i++)
|
||||
bnx2x_init_block(bp,
|
||||
cm_start[func][i], cm_end[func][i]);
|
||||
cm_blocks[i], FUNC0_STAGE + func);
|
||||
|
||||
REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 1);
|
||||
REG_WR(bp, NIG_REG_LLH0_FUNC_VLAN_ID + port*8, bp->e1hov);
|
||||
|
|
@ -6049,7 +6071,7 @@ static int bnx2x_init_func(struct bnx2x *bp)
|
|||
REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0);
|
||||
REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0);
|
||||
}
|
||||
bnx2x_init_block(bp, hc_limits[func][0], hc_limits[func][1]);
|
||||
bnx2x_init_block(bp, HC_BLOCK, FUNC0_STAGE + func);
|
||||
|
||||
/* Reset PCIE errors for debug */
|
||||
REG_WR(bp, 0x2114, 0xffffffff);
|
||||
|
|
@ -10595,7 +10617,6 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
mmiowb();
|
||||
|
||||
fp->tx_bd_prod += nbd;
|
||||
dev->trans_start = jiffies;
|
||||
|
||||
if (unlikely(bnx2x_tx_avail(fp) < MAX_SKB_FRAGS + 3)) {
|
||||
/* We want bnx2x_tx_int to "see" the updated tx_bd_prod
|
||||
|
|
@ -11082,6 +11103,190 @@ static int __devinit bnx2x_get_pcie_speed(struct bnx2x *bp)
|
|||
val = (val & PCICFG_LINK_SPEED) >> PCICFG_LINK_SPEED_SHIFT;
|
||||
return val;
|
||||
}
|
||||
static int __devinit bnx2x_check_firmware(struct bnx2x *bp)
|
||||
{
|
||||
struct bnx2x_fw_file_hdr *fw_hdr;
|
||||
struct bnx2x_fw_file_section *sections;
|
||||
u16 *ops_offsets;
|
||||
u32 offset, len, num_ops;
|
||||
int i;
|
||||
const struct firmware *firmware = bp->firmware;
|
||||
const u8 * fw_ver;
|
||||
|
||||
if (firmware->size < sizeof(struct bnx2x_fw_file_hdr))
|
||||
return -EINVAL;
|
||||
|
||||
fw_hdr = (struct bnx2x_fw_file_hdr *)firmware->data;
|
||||
sections = (struct bnx2x_fw_file_section *)fw_hdr;
|
||||
|
||||
/* Make sure none of the offsets and sizes make us read beyond
|
||||
* the end of the firmware data */
|
||||
for (i = 0; i < sizeof(*fw_hdr) / sizeof(*sections); i++) {
|
||||
offset = be32_to_cpu(sections[i].offset);
|
||||
len = be32_to_cpu(sections[i].len);
|
||||
if (offset + len > firmware->size) {
|
||||
printk(KERN_ERR PFX "Section %d length is out of bounds\n", i);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Likewise for the init_ops offsets */
|
||||
offset = be32_to_cpu(fw_hdr->init_ops_offsets.offset);
|
||||
ops_offsets = (u16 *)(firmware->data + offset);
|
||||
num_ops = be32_to_cpu(fw_hdr->init_ops.len) / sizeof(struct raw_op);
|
||||
|
||||
for (i = 0; i < be32_to_cpu(fw_hdr->init_ops_offsets.len) / 2; i++) {
|
||||
if (be16_to_cpu(ops_offsets[i]) > num_ops) {
|
||||
printk(KERN_ERR PFX "Section offset %d is out of bounds\n", i);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check FW version */
|
||||
offset = be32_to_cpu(fw_hdr->fw_version.offset);
|
||||
fw_ver = firmware->data + offset;
|
||||
if ((fw_ver[0] != BCM_5710_FW_MAJOR_VERSION) ||
|
||||
(fw_ver[1] != BCM_5710_FW_MINOR_VERSION) ||
|
||||
(fw_ver[2] != BCM_5710_FW_REVISION_VERSION) ||
|
||||
(fw_ver[3] != BCM_5710_FW_ENGINEERING_VERSION)) {
|
||||
printk(KERN_ERR PFX "Bad FW version:%d.%d.%d.%d."
|
||||
" Should be %d.%d.%d.%d\n",
|
||||
fw_ver[0], fw_ver[1], fw_ver[2],
|
||||
fw_ver[3], BCM_5710_FW_MAJOR_VERSION,
|
||||
BCM_5710_FW_MINOR_VERSION,
|
||||
BCM_5710_FW_REVISION_VERSION,
|
||||
BCM_5710_FW_ENGINEERING_VERSION);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void inline be32_to_cpu_n(const u8 *_source, u8 *_target, u32 n)
|
||||
{
|
||||
u32 i;
|
||||
const __be32 *source = (const __be32*)_source;
|
||||
u32 *target = (u32*)_target;
|
||||
|
||||
for (i = 0; i < n/4; i++)
|
||||
target[i] = be32_to_cpu(source[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
Ops array is stored in the following format:
|
||||
{op(8bit), offset(24bit, big endian), data(32bit, big endian)}
|
||||
*/
|
||||
static void inline bnx2x_prep_ops(const u8 *_source, u8 *_target, u32 n)
|
||||
{
|
||||
u32 i, j, tmp;
|
||||
const __be32 *source = (const __be32*)_source;
|
||||
struct raw_op *target = (struct raw_op*)_target;
|
||||
|
||||
for (i = 0, j = 0; i < n/8; i++, j+=2) {
|
||||
tmp = be32_to_cpu(source[j]);
|
||||
target[i].op = (tmp >> 24) & 0xff;
|
||||
target[i].offset = tmp & 0xffffff;
|
||||
target[i].raw_data = be32_to_cpu(source[j+1]);
|
||||
}
|
||||
}
|
||||
static void inline be16_to_cpu_n(const u8 *_source, u8 *_target, u32 n)
|
||||
{
|
||||
u32 i;
|
||||
u16 *target = (u16*)_target;
|
||||
const __be16 *source = (const __be16*)_source;
|
||||
|
||||
for (i = 0; i < n/2; i++)
|
||||
target[i] = be16_to_cpu(source[i]);
|
||||
}
|
||||
|
||||
#define BNX2X_ALLOC_AND_SET(arr, lbl, func) \
|
||||
do { \
|
||||
u32 len = be32_to_cpu(fw_hdr->arr.len); \
|
||||
bp->arr = kmalloc(len, GFP_KERNEL); \
|
||||
if (!bp->arr) { \
|
||||
printk(KERN_ERR PFX "Failed to allocate %d bytes for "#arr"\n", len); \
|
||||
goto lbl; \
|
||||
} \
|
||||
func(bp->firmware->data + \
|
||||
be32_to_cpu(fw_hdr->arr.offset), \
|
||||
(u8*)bp->arr, len); \
|
||||
} while (0)
|
||||
|
||||
|
||||
static int __devinit bnx2x_init_firmware(struct bnx2x *bp, struct device *dev)
|
||||
{
|
||||
char fw_file_name[40] = {0};
|
||||
int rc, offset;
|
||||
struct bnx2x_fw_file_hdr *fw_hdr;
|
||||
|
||||
/* Create a FW file name */
|
||||
if (CHIP_IS_E1(bp))
|
||||
offset = sprintf(fw_file_name, FW_FILE_PREFIX_E1);
|
||||
else
|
||||
offset = sprintf(fw_file_name, FW_FILE_PREFIX_E1H);
|
||||
|
||||
sprintf(fw_file_name + offset, "%d.%d.%d.%d.fw",
|
||||
BCM_5710_FW_MAJOR_VERSION,
|
||||
BCM_5710_FW_MINOR_VERSION,
|
||||
BCM_5710_FW_REVISION_VERSION,
|
||||
BCM_5710_FW_ENGINEERING_VERSION);
|
||||
|
||||
printk(KERN_INFO PFX "Loading %s\n", fw_file_name);
|
||||
|
||||
rc = request_firmware(&bp->firmware, fw_file_name, dev);
|
||||
if (rc) {
|
||||
printk(KERN_ERR PFX "Can't load firmware file %s\n", fw_file_name);
|
||||
goto request_firmware_exit;
|
||||
}
|
||||
|
||||
rc = bnx2x_check_firmware(bp);
|
||||
if (rc) {
|
||||
printk(KERN_ERR PFX "Corrupt firmware file %s\n", fw_file_name);
|
||||
goto request_firmware_exit;
|
||||
}
|
||||
|
||||
fw_hdr = (struct bnx2x_fw_file_hdr *)bp->firmware->data;
|
||||
|
||||
/* Initialize the pointers to the init arrays */
|
||||
/* Blob */
|
||||
BNX2X_ALLOC_AND_SET(init_data, request_firmware_exit, be32_to_cpu_n);
|
||||
|
||||
/* Opcodes */
|
||||
BNX2X_ALLOC_AND_SET(init_ops, init_ops_alloc_err, bnx2x_prep_ops);
|
||||
|
||||
/* Offsets */
|
||||
BNX2X_ALLOC_AND_SET(init_ops_offsets, init_offsets_alloc_err, be16_to_cpu_n);
|
||||
|
||||
/* STORMs firmware */
|
||||
bp->tsem_int_table_data = bp->firmware->data +
|
||||
be32_to_cpu(fw_hdr->tsem_int_table_data.offset);
|
||||
bp->tsem_pram_data = bp->firmware->data +
|
||||
be32_to_cpu(fw_hdr->tsem_pram_data.offset);
|
||||
bp->usem_int_table_data = bp->firmware->data +
|
||||
be32_to_cpu(fw_hdr->usem_int_table_data.offset);
|
||||
bp->usem_pram_data = bp->firmware->data +
|
||||
be32_to_cpu(fw_hdr->usem_pram_data.offset);
|
||||
bp->xsem_int_table_data = bp->firmware->data +
|
||||
be32_to_cpu(fw_hdr->xsem_int_table_data.offset);
|
||||
bp->xsem_pram_data = bp->firmware->data +
|
||||
be32_to_cpu(fw_hdr->xsem_pram_data.offset);
|
||||
bp->csem_int_table_data = bp->firmware->data +
|
||||
be32_to_cpu(fw_hdr->csem_int_table_data.offset);
|
||||
bp->csem_pram_data = bp->firmware->data +
|
||||
be32_to_cpu(fw_hdr->csem_pram_data.offset);
|
||||
|
||||
return 0;
|
||||
init_offsets_alloc_err:
|
||||
kfree(bp->init_ops);
|
||||
init_ops_alloc_err:
|
||||
kfree(bp->init_data);
|
||||
request_firmware_exit:
|
||||
release_firmware(bp->firmware);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int __devinit bnx2x_init_one(struct pci_dev *pdev,
|
||||
const struct pci_device_id *ent)
|
||||
|
|
@ -11116,6 +11321,13 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
|
|||
if (rc)
|
||||
goto init_one_exit;
|
||||
|
||||
/* Set init arrays */
|
||||
rc = bnx2x_init_firmware(bp, &pdev->dev);
|
||||
if (rc) {
|
||||
printk(KERN_ERR PFX "Error loading firmware\n");
|
||||
goto init_one_exit;
|
||||
}
|
||||
|
||||
rc = register_netdev(dev);
|
||||
if (rc) {
|
||||
dev_err(&pdev->dev, "Cannot register net device\n");
|
||||
|
|
@ -11163,6 +11375,11 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev)
|
|||
|
||||
unregister_netdev(dev);
|
||||
|
||||
kfree(bp->init_ops_offsets);
|
||||
kfree(bp->init_ops);
|
||||
kfree(bp->init_data);
|
||||
release_firmware(bp->firmware);
|
||||
|
||||
if (bp->regview)
|
||||
iounmap(bp->regview);
|
||||
|
||||
|
|
@ -11412,13 +11629,20 @@ static struct pci_driver bnx2x_pci_driver = {
|
|||
|
||||
static int __init bnx2x_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
bnx2x_wq = create_singlethread_workqueue("bnx2x");
|
||||
if (bnx2x_wq == NULL) {
|
||||
printk(KERN_ERR PFX "Cannot create workqueue\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return pci_register_driver(&bnx2x_pci_driver);
|
||||
ret = pci_register_driver(&bnx2x_pci_driver);
|
||||
if (ret) {
|
||||
printk(KERN_ERR PFX "Cannot register driver\n");
|
||||
destroy_workqueue(bnx2x_wq);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit bnx2x_cleanup(void)
|
||||
|
|
@ -11431,3 +11655,4 @@ static void __exit bnx2x_cleanup(void)
|
|||
module_init(bnx2x_init);
|
||||
module_exit(bnx2x_cleanup);
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1850,9 +1850,10 @@ static u16 aggregator_identifier;
|
|||
* Can be called only after the mac address of the bond is set.
|
||||
*/
|
||||
void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution, int lacp_fast)
|
||||
{
|
||||
{
|
||||
// check that the bond is not initialized yet
|
||||
if (MAC_ADDRESS_COMPARE(&(BOND_AD_INFO(bond).system.sys_mac_addr), &(bond->dev->dev_addr))) {
|
||||
if (MAC_ADDRESS_COMPARE(&(BOND_AD_INFO(bond).system.sys_mac_addr),
|
||||
bond->dev->dev_addr)) {
|
||||
|
||||
aggregator_identifier = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -26,10 +26,10 @@
|
|||
#include <asm/byteorder.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/if_ether.h>
|
||||
|
||||
// General definitions
|
||||
#define BOND_ETH_P_LACPDU 0x8809
|
||||
#define PKT_TYPE_LACPDU cpu_to_be16(BOND_ETH_P_LACPDU)
|
||||
#define PKT_TYPE_LACPDU cpu_to_be16(ETH_P_SLOW)
|
||||
#define AD_TIMER_INTERVAL 100 /*msec*/
|
||||
|
||||
#define MULTICAST_LACPDU_ADDR {0x01, 0x80, 0xC2, 0x00, 0x00, 0x02}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -286,8 +286,7 @@ static inline unsigned long slave_last_rx(struct bonding *bond,
|
|||
static inline void bond_set_slave_inactive_flags(struct slave *slave)
|
||||
{
|
||||
struct bonding *bond = netdev_priv(slave->dev->master);
|
||||
if (bond->params.mode != BOND_MODE_TLB &&
|
||||
bond->params.mode != BOND_MODE_ALB)
|
||||
if (!bond_is_lb(bond))
|
||||
slave->state = BOND_STATE_BACKUP;
|
||||
slave->dev->priv_flags |= IFF_SLAVE_INACTIVE;
|
||||
if (slave_do_arp_validate(bond, slave))
|
||||
|
|
@ -322,8 +321,7 @@ static inline void bond_unset_master_alb_flags(struct bonding *bond)
|
|||
|
||||
struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr);
|
||||
int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev);
|
||||
int bond_create(char *name, struct bond_params *params);
|
||||
void bond_destroy(struct bonding *bond);
|
||||
int bond_create(const char *name);
|
||||
int bond_release_and_destroy(struct net_device *bond_dev, struct net_device *slave_dev);
|
||||
int bond_create_sysfs(void);
|
||||
void bond_destroy_sysfs(void);
|
||||
|
|
@ -350,12 +348,8 @@ extern const struct bond_parm_tbl bond_mode_tbl[];
|
|||
extern const struct bond_parm_tbl xmit_hashtype_tbl[];
|
||||
extern const struct bond_parm_tbl arp_validate_tbl[];
|
||||
extern const struct bond_parm_tbl fail_over_mac_tbl[];
|
||||
extern struct bond_params bonding_defaults;
|
||||
extern struct bond_parm_tbl ad_select_tbl[];
|
||||
|
||||
/* exported from bond_sysfs.c */
|
||||
extern struct rw_semaphore bonding_rwsem;
|
||||
|
||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
||||
void bond_send_unsolicited_na(struct bonding *bond);
|
||||
void bond_register_ipv6_notifier(void);
|
||||
|
|
|
|||
|
|
@ -12,6 +12,68 @@ config CAN_VCAN
|
|||
This driver can also be built as a module. If so, the module
|
||||
will be called vcan.
|
||||
|
||||
config CAN_DEV
|
||||
tristate "Platform CAN drivers with Netlink support"
|
||||
depends on CAN
|
||||
default Y
|
||||
---help---
|
||||
Enables the common framework for platform CAN drivers with Netlink
|
||||
support. This is the standard library for CAN drivers.
|
||||
If unsure, say Y.
|
||||
|
||||
config CAN_CALC_BITTIMING
|
||||
bool "CAN bit-timing calculation"
|
||||
depends on CAN_DEV
|
||||
default Y
|
||||
---help---
|
||||
If enabled, CAN bit-timing parameters will be calculated for the
|
||||
bit-rate specified via Netlink argument "bitrate" when the device
|
||||
get started. This works fine for the most common CAN controllers
|
||||
with standard bit-rates but may fail for exotic bit-rates or CAN
|
||||
source clock frequencies. Disabling saves some space, but then the
|
||||
bit-timing parameters must be specified directly using the Netlink
|
||||
arguments "tq", "prop_seg", "phase_seg1", "phase_seg2" and "sjw".
|
||||
If unsure, say Y.
|
||||
|
||||
config CAN_SJA1000
|
||||
depends on CAN_DEV
|
||||
tristate "Philips SJA1000"
|
||||
---help---
|
||||
Driver for the SJA1000 CAN controllers from Philips or NXP
|
||||
|
||||
config CAN_SJA1000_PLATFORM
|
||||
depends on CAN_SJA1000
|
||||
tristate "Generic Platform Bus based SJA1000 driver"
|
||||
---help---
|
||||
This driver adds support for the SJA1000 chips connected to
|
||||
the "platform bus" (Linux abstraction for directly to the
|
||||
processor attached devices). Which can be found on various
|
||||
boards from Phytec (http://www.phytec.de) like the PCM027,
|
||||
PCM038.
|
||||
|
||||
config CAN_SJA1000_OF_PLATFORM
|
||||
depends on CAN_SJA1000 && PPC_OF
|
||||
tristate "Generic OF Platform Bus based SJA1000 driver"
|
||||
---help---
|
||||
This driver adds support for the SJA1000 chips connected to
|
||||
the OpenFirmware "platform bus" found on embedded systems with
|
||||
OpenFirmware bindings, e.g. if you have a PowerPC based system
|
||||
you may want to enable this option.
|
||||
|
||||
config CAN_EMS_PCI
|
||||
tristate "EMS CPC-PCI and CPC-PCIe Card"
|
||||
depends on PCI && CAN_SJA1000
|
||||
---help---
|
||||
This driver is for the one or two channel CPC-PCI and CPC-PCIe
|
||||
cards from EMS Dr. Thomas Wuensche (http://www.ems-wuensche.de).
|
||||
|
||||
config CAN_KVASER_PCI
|
||||
tristate "Kvaser PCIcanx and Kvaser PCIcan PCI Cards"
|
||||
depends on PCI && CAN_SJA1000
|
||||
---help---
|
||||
This driver is for the the PCIcanx and PCIcan cards (1, 2 or
|
||||
4 channel) from Kvaser (http://www.kvaser.com).
|
||||
|
||||
config CAN_DEBUG_DEVICES
|
||||
bool "CAN devices debugging messages"
|
||||
depends on CAN
|
||||
|
|
|
|||
|
|
@ -3,3 +3,10 @@
|
|||
#
|
||||
|
||||
obj-$(CONFIG_CAN_VCAN) += vcan.o
|
||||
|
||||
obj-$(CONFIG_CAN_DEV) += can-dev.o
|
||||
can-dev-y := dev.o
|
||||
|
||||
obj-$(CONFIG_CAN_SJA1000) += sja1000/
|
||||
|
||||
ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
|
||||
|
|
|
|||
657
drivers/net/can/dev.c
Normal file
657
drivers/net/can/dev.c
Normal file
|
|
@ -0,0 +1,657 @@
|
|||
/*
|
||||
* Copyright (C) 2005 Marc Kleine-Budde, Pengutronix
|
||||
* Copyright (C) 2006 Andrey Volkov, Varma Electronics
|
||||
* Copyright (C) 2008-2009 Wolfgang Grandegger <wg@grandegger.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the version 2 of the GNU General Public License
|
||||
* as published by the Free Software Foundation
|
||||
*
|
||||
* 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/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/if_arp.h>
|
||||
#include <linux/can.h>
|
||||
#include <linux/can/dev.h>
|
||||
#include <linux/can/netlink.h>
|
||||
#include <net/rtnetlink.h>
|
||||
|
||||
#define MOD_DESC "CAN device driver interface"
|
||||
|
||||
MODULE_DESCRIPTION(MOD_DESC);
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_AUTHOR("Wolfgang Grandegger <[email protected]>");
|
||||
|
||||
#ifdef CONFIG_CAN_CALC_BITTIMING
|
||||
#define CAN_CALC_MAX_ERROR 50 /* in one-tenth of a percent */
|
||||
|
||||
/*
|
||||
* Bit-timing calculation derived from:
|
||||
*
|
||||
* Code based on LinCAN sources and H8S2638 project
|
||||
* Copyright 2004-2006 Pavel Pisa - DCE FELK CVUT cz
|
||||
* Copyright 2005 Stanislav Marek
|
||||
* email: pisa@cmp.felk.cvut.cz
|
||||
*
|
||||
* Calculates proper bit-timing parameters for a specified bit-rate
|
||||
* and sample-point, which can then be used to set the bit-timing
|
||||
* registers of the CAN controller. You can find more information
|
||||
* in the header file linux/can/netlink.h.
|
||||
*/
|
||||
static int can_update_spt(const struct can_bittiming_const *btc,
|
||||
int sampl_pt, int tseg, int *tseg1, int *tseg2)
|
||||
{
|
||||
*tseg2 = tseg + 1 - (sampl_pt * (tseg + 1)) / 1000;
|
||||
if (*tseg2 < btc->tseg2_min)
|
||||
*tseg2 = btc->tseg2_min;
|
||||
if (*tseg2 > btc->tseg2_max)
|
||||
*tseg2 = btc->tseg2_max;
|
||||
*tseg1 = tseg - *tseg2;
|
||||
if (*tseg1 > btc->tseg1_max) {
|
||||
*tseg1 = btc->tseg1_max;
|
||||
*tseg2 = tseg - *tseg1;
|
||||
}
|
||||
return 1000 * (tseg + 1 - *tseg2) / (tseg + 1);
|
||||
}
|
||||
|
||||
static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt)
|
||||
{
|
||||
struct can_priv *priv = netdev_priv(dev);
|
||||
const struct can_bittiming_const *btc = priv->bittiming_const;
|
||||
long rate, best_rate = 0;
|
||||
long best_error = 1000000000, error = 0;
|
||||
int best_tseg = 0, best_brp = 0, brp = 0;
|
||||
int tsegall, tseg = 0, tseg1 = 0, tseg2 = 0;
|
||||
int spt_error = 1000, spt = 0, sampl_pt;
|
||||
u64 v64;
|
||||
|
||||
if (!priv->bittiming_const)
|
||||
return -ENOTSUPP;
|
||||
|
||||
/* Use CIA recommended sample points */
|
||||
if (bt->sample_point) {
|
||||
sampl_pt = bt->sample_point;
|
||||
} else {
|
||||
if (bt->bitrate > 800000)
|
||||
sampl_pt = 750;
|
||||
else if (bt->bitrate > 500000)
|
||||
sampl_pt = 800;
|
||||
else
|
||||
sampl_pt = 875;
|
||||
}
|
||||
|
||||
/* tseg even = round down, odd = round up */
|
||||
for (tseg = (btc->tseg1_max + btc->tseg2_max) * 2 + 1;
|
||||
tseg >= (btc->tseg1_min + btc->tseg2_min) * 2; tseg--) {
|
||||
tsegall = 1 + tseg / 2;
|
||||
/* Compute all possible tseg choices (tseg=tseg1+tseg2) */
|
||||
brp = priv->clock.freq / (tsegall * bt->bitrate) + tseg % 2;
|
||||
/* chose brp step which is possible in system */
|
||||
brp = (brp / btc->brp_inc) * btc->brp_inc;
|
||||
if ((brp < btc->brp_min) || (brp > btc->brp_max))
|
||||
continue;
|
||||
rate = priv->clock.freq / (brp * tsegall);
|
||||
error = bt->bitrate - rate;
|
||||
/* tseg brp biterror */
|
||||
if (error < 0)
|
||||
error = -error;
|
||||
if (error > best_error)
|
||||
continue;
|
||||
best_error = error;
|
||||
if (error == 0) {
|
||||
spt = can_update_spt(btc, sampl_pt, tseg / 2,
|
||||
&tseg1, &tseg2);
|
||||
error = sampl_pt - spt;
|
||||
if (error < 0)
|
||||
error = -error;
|
||||
if (error > spt_error)
|
||||
continue;
|
||||
spt_error = error;
|
||||
}
|
||||
best_tseg = tseg / 2;
|
||||
best_brp = brp;
|
||||
best_rate = rate;
|
||||
if (error == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (best_error) {
|
||||
/* Error in one-tenth of a percent */
|
||||
error = (best_error * 1000) / bt->bitrate;
|
||||
if (error > CAN_CALC_MAX_ERROR) {
|
||||
dev_err(dev->dev.parent,
|
||||
"bitrate error %ld.%ld%% too high\n",
|
||||
error / 10, error % 10);
|
||||
return -EDOM;
|
||||
} else {
|
||||
dev_warn(dev->dev.parent, "bitrate error %ld.%ld%%\n",
|
||||
error / 10, error % 10);
|
||||
}
|
||||
}
|
||||
|
||||
/* real sample point */
|
||||
bt->sample_point = can_update_spt(btc, sampl_pt, best_tseg,
|
||||
&tseg1, &tseg2);
|
||||
|
||||
v64 = (u64)best_brp * 1000000000UL;
|
||||
do_div(v64, priv->clock.freq);
|
||||
bt->tq = (u32)v64;
|
||||
bt->prop_seg = tseg1 / 2;
|
||||
bt->phase_seg1 = tseg1 - bt->prop_seg;
|
||||
bt->phase_seg2 = tseg2;
|
||||
bt->sjw = 1;
|
||||
bt->brp = best_brp;
|
||||
/* real bit-rate */
|
||||
bt->bitrate = priv->clock.freq / (bt->brp * (tseg1 + tseg2 + 1));
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else /* !CONFIG_CAN_CALC_BITTIMING */
|
||||
static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt)
|
||||
{
|
||||
dev_err(dev->dev.parent, "bit-timing calculation not available\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif /* CONFIG_CAN_CALC_BITTIMING */
|
||||
|
||||
/*
|
||||
* Checks the validity of the specified bit-timing parameters prop_seg,
|
||||
* phase_seg1, phase_seg2 and sjw and tries to determine the bitrate
|
||||
* prescaler value brp. You can find more information in the header
|
||||
* file linux/can/netlink.h.
|
||||
*/
|
||||
static int can_fixup_bittiming(struct net_device *dev, struct can_bittiming *bt)
|
||||
{
|
||||
struct can_priv *priv = netdev_priv(dev);
|
||||
const struct can_bittiming_const *btc = priv->bittiming_const;
|
||||
int tseg1, alltseg;
|
||||
u64 brp64;
|
||||
|
||||
if (!priv->bittiming_const)
|
||||
return -ENOTSUPP;
|
||||
|
||||
tseg1 = bt->prop_seg + bt->phase_seg1;
|
||||
if (!bt->sjw)
|
||||
bt->sjw = 1;
|
||||
if (bt->sjw > btc->sjw_max ||
|
||||
tseg1 < btc->tseg1_min || tseg1 > btc->tseg1_max ||
|
||||
bt->phase_seg2 < btc->tseg2_min || bt->phase_seg2 > btc->tseg2_max)
|
||||
return -ERANGE;
|
||||
|
||||
brp64 = (u64)priv->clock.freq * (u64)bt->tq;
|
||||
if (btc->brp_inc > 1)
|
||||
do_div(brp64, btc->brp_inc);
|
||||
brp64 += 500000000UL - 1;
|
||||
do_div(brp64, 1000000000UL); /* the practicable BRP */
|
||||
if (btc->brp_inc > 1)
|
||||
brp64 *= btc->brp_inc;
|
||||
bt->brp = (u32)brp64;
|
||||
|
||||
if (bt->brp < btc->brp_min || bt->brp > btc->brp_max)
|
||||
return -EINVAL;
|
||||
|
||||
alltseg = bt->prop_seg + bt->phase_seg1 + bt->phase_seg2 + 1;
|
||||
bt->bitrate = priv->clock.freq / (bt->brp * alltseg);
|
||||
bt->sample_point = ((tseg1 + 1) * 1000) / alltseg;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt)
|
||||
{
|
||||
struct can_priv *priv = netdev_priv(dev);
|
||||
int err;
|
||||
|
||||
/* Check if the CAN device has bit-timing parameters */
|
||||
if (priv->bittiming_const) {
|
||||
|
||||
/* Non-expert mode? Check if the bitrate has been pre-defined */
|
||||
if (!bt->tq)
|
||||
/* Determine bit-timing parameters */
|
||||
err = can_calc_bittiming(dev, bt);
|
||||
else
|
||||
/* Check bit-timing params and calculate proper brp */
|
||||
err = can_fixup_bittiming(dev, bt);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local echo of CAN messages
|
||||
*
|
||||
* CAN network devices *should* support a local echo functionality
|
||||
* (see Documentation/networking/can.txt). To test the handling of CAN
|
||||
* interfaces that do not support the local echo both driver types are
|
||||
* implemented. In the case that the driver does not support the echo
|
||||
* the IFF_ECHO remains clear in dev->flags. This causes the PF_CAN core
|
||||
* to perform the echo as a fallback solution.
|
||||
*/
|
||||
static void can_flush_echo_skb(struct net_device *dev)
|
||||
{
|
||||
struct can_priv *priv = netdev_priv(dev);
|
||||
struct net_device_stats *stats = &dev->stats;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CAN_ECHO_SKB_MAX; i++) {
|
||||
if (priv->echo_skb[i]) {
|
||||
kfree_skb(priv->echo_skb[i]);
|
||||
priv->echo_skb[i] = NULL;
|
||||
stats->tx_dropped++;
|
||||
stats->tx_aborted_errors++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Put the skb on the stack to be looped backed locally lateron
|
||||
*
|
||||
* The function is typically called in the start_xmit function
|
||||
* of the device driver. The driver must protect access to
|
||||
* priv->echo_skb, if necessary.
|
||||
*/
|
||||
void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, int idx)
|
||||
{
|
||||
struct can_priv *priv = netdev_priv(dev);
|
||||
|
||||
/* check flag whether this packet has to be looped back */
|
||||
if (!(dev->flags & IFF_ECHO) || skb->pkt_type != PACKET_LOOPBACK) {
|
||||
kfree_skb(skb);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!priv->echo_skb[idx]) {
|
||||
struct sock *srcsk = skb->sk;
|
||||
|
||||
if (atomic_read(&skb->users) != 1) {
|
||||
struct sk_buff *old_skb = skb;
|
||||
|
||||
skb = skb_clone(old_skb, GFP_ATOMIC);
|
||||
kfree_skb(old_skb);
|
||||
if (!skb)
|
||||
return;
|
||||
} else
|
||||
skb_orphan(skb);
|
||||
|
||||
skb->sk = srcsk;
|
||||
|
||||
/* make settings for echo to reduce code in irq context */
|
||||
skb->protocol = htons(ETH_P_CAN);
|
||||
skb->pkt_type = PACKET_BROADCAST;
|
||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
skb->dev = dev;
|
||||
|
||||
/* save this skb for tx interrupt echo handling */
|
||||
priv->echo_skb[idx] = skb;
|
||||
} else {
|
||||
/* locking problem with netif_stop_queue() ?? */
|
||||
dev_err(dev->dev.parent, "%s: BUG! echo_skb is occupied!\n",
|
||||
__func__);
|
||||
kfree_skb(skb);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(can_put_echo_skb);
|
||||
|
||||
/*
|
||||
* Get the skb from the stack and loop it back locally
|
||||
*
|
||||
* The function is typically called when the TX done interrupt
|
||||
* is handled in the device driver. The driver must protect
|
||||
* access to priv->echo_skb, if necessary.
|
||||
*/
|
||||
void can_get_echo_skb(struct net_device *dev, int idx)
|
||||
{
|
||||
struct can_priv *priv = netdev_priv(dev);
|
||||
|
||||
if ((dev->flags & IFF_ECHO) && priv->echo_skb[idx]) {
|
||||
netif_rx(priv->echo_skb[idx]);
|
||||
priv->echo_skb[idx] = NULL;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(can_get_echo_skb);
|
||||
|
||||
/*
|
||||
* CAN device restart for bus-off recovery
|
||||
*/
|
||||
void can_restart(unsigned long data)
|
||||
{
|
||||
struct net_device *dev = (struct net_device *)data;
|
||||
struct can_priv *priv = netdev_priv(dev);
|
||||
struct net_device_stats *stats = &dev->stats;
|
||||
struct sk_buff *skb;
|
||||
struct can_frame *cf;
|
||||
int err;
|
||||
|
||||
BUG_ON(netif_carrier_ok(dev));
|
||||
|
||||
/*
|
||||
* No synchronization needed because the device is bus-off and
|
||||
* no messages can come in or go out.
|
||||
*/
|
||||
can_flush_echo_skb(dev);
|
||||
|
||||
/* send restart message upstream */
|
||||
skb = dev_alloc_skb(sizeof(struct can_frame));
|
||||
if (skb == NULL) {
|
||||
err = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
skb->dev = dev;
|
||||
skb->protocol = htons(ETH_P_CAN);
|
||||
cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
|
||||
memset(cf, 0, sizeof(struct can_frame));
|
||||
cf->can_id = CAN_ERR_FLAG | CAN_ERR_RESTARTED;
|
||||
cf->can_dlc = CAN_ERR_DLC;
|
||||
|
||||
netif_rx(skb);
|
||||
|
||||
dev->last_rx = jiffies;
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
|
||||
dev_dbg(dev->dev.parent, "restarted\n");
|
||||
priv->can_stats.restarts++;
|
||||
|
||||
/* Now restart the device */
|
||||
err = priv->do_set_mode(dev, CAN_MODE_START);
|
||||
|
||||
out:
|
||||
netif_carrier_on(dev);
|
||||
if (err)
|
||||
dev_err(dev->dev.parent, "Error %d during restart", err);
|
||||
}
|
||||
|
||||
int can_restart_now(struct net_device *dev)
|
||||
{
|
||||
struct can_priv *priv = netdev_priv(dev);
|
||||
|
||||
/*
|
||||
* A manual restart is only permitted if automatic restart is
|
||||
* disabled and the device is in the bus-off state
|
||||
*/
|
||||
if (priv->restart_ms)
|
||||
return -EINVAL;
|
||||
if (priv->state != CAN_STATE_BUS_OFF)
|
||||
return -EBUSY;
|
||||
|
||||
/* Runs as soon as possible in the timer context */
|
||||
mod_timer(&priv->restart_timer, jiffies);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* CAN bus-off
|
||||
*
|
||||
* This functions should be called when the device goes bus-off to
|
||||
* tell the netif layer that no more packets can be sent or received.
|
||||
* If enabled, a timer is started to trigger bus-off recovery.
|
||||
*/
|
||||
void can_bus_off(struct net_device *dev)
|
||||
{
|
||||
struct can_priv *priv = netdev_priv(dev);
|
||||
|
||||
dev_dbg(dev->dev.parent, "bus-off\n");
|
||||
|
||||
netif_carrier_off(dev);
|
||||
priv->can_stats.bus_off++;
|
||||
|
||||
if (priv->restart_ms)
|
||||
mod_timer(&priv->restart_timer,
|
||||
jiffies + (priv->restart_ms * HZ) / 1000);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(can_bus_off);
|
||||
|
||||
static void can_setup(struct net_device *dev)
|
||||
{
|
||||
dev->type = ARPHRD_CAN;
|
||||
dev->mtu = sizeof(struct can_frame);
|
||||
dev->hard_header_len = 0;
|
||||
dev->addr_len = 0;
|
||||
dev->tx_queue_len = 10;
|
||||
|
||||
/* New-style flags. */
|
||||
dev->flags = IFF_NOARP;
|
||||
dev->features = NETIF_F_NO_CSUM;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate and setup space for the CAN network device
|
||||
*/
|
||||
struct net_device *alloc_candev(int sizeof_priv)
|
||||
{
|
||||
struct net_device *dev;
|
||||
struct can_priv *priv;
|
||||
|
||||
dev = alloc_netdev(sizeof_priv, "can%d", can_setup);
|
||||
if (!dev)
|
||||
return NULL;
|
||||
|
||||
priv = netdev_priv(dev);
|
||||
|
||||
priv->state = CAN_STATE_STOPPED;
|
||||
|
||||
init_timer(&priv->restart_timer);
|
||||
|
||||
return dev;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(alloc_candev);
|
||||
|
||||
/*
|
||||
* Free space of the CAN network device
|
||||
*/
|
||||
void free_candev(struct net_device *dev)
|
||||
{
|
||||
free_netdev(dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(free_candev);
|
||||
|
||||
/*
|
||||
* Common open function when the device gets opened.
|
||||
*
|
||||
* This function should be called in the open function of the device
|
||||
* driver.
|
||||
*/
|
||||
int open_candev(struct net_device *dev)
|
||||
{
|
||||
struct can_priv *priv = netdev_priv(dev);
|
||||
|
||||
if (!priv->bittiming.tq && !priv->bittiming.bitrate) {
|
||||
dev_err(dev->dev.parent, "bit-timing not yet defined\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
setup_timer(&priv->restart_timer, can_restart, (unsigned long)dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(open_candev);
|
||||
|
||||
/*
|
||||
* Common close function for cleanup before the device gets closed.
|
||||
*
|
||||
* This function should be called in the close function of the device
|
||||
* driver.
|
||||
*/
|
||||
void close_candev(struct net_device *dev)
|
||||
{
|
||||
struct can_priv *priv = netdev_priv(dev);
|
||||
|
||||
if (del_timer_sync(&priv->restart_timer))
|
||||
dev_put(dev);
|
||||
can_flush_echo_skb(dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(close_candev);
|
||||
|
||||
/*
|
||||
* CAN netlink interface
|
||||
*/
|
||||
static const struct nla_policy can_policy[IFLA_CAN_MAX + 1] = {
|
||||
[IFLA_CAN_STATE] = { .type = NLA_U32 },
|
||||
[IFLA_CAN_CTRLMODE] = { .len = sizeof(struct can_ctrlmode) },
|
||||
[IFLA_CAN_RESTART_MS] = { .type = NLA_U32 },
|
||||
[IFLA_CAN_RESTART] = { .type = NLA_U32 },
|
||||
[IFLA_CAN_BITTIMING] = { .len = sizeof(struct can_bittiming) },
|
||||
[IFLA_CAN_BITTIMING_CONST]
|
||||
= { .len = sizeof(struct can_bittiming_const) },
|
||||
[IFLA_CAN_CLOCK] = { .len = sizeof(struct can_clock) },
|
||||
};
|
||||
|
||||
static int can_changelink(struct net_device *dev,
|
||||
struct nlattr *tb[], struct nlattr *data[])
|
||||
{
|
||||
struct can_priv *priv = netdev_priv(dev);
|
||||
int err;
|
||||
|
||||
/* We need synchronization with dev->stop() */
|
||||
ASSERT_RTNL();
|
||||
|
||||
if (data[IFLA_CAN_CTRLMODE]) {
|
||||
struct can_ctrlmode *cm;
|
||||
|
||||
/* Do not allow changing controller mode while running */
|
||||
if (dev->flags & IFF_UP)
|
||||
return -EBUSY;
|
||||
cm = nla_data(data[IFLA_CAN_CTRLMODE]);
|
||||
priv->ctrlmode &= ~cm->mask;
|
||||
priv->ctrlmode |= cm->flags;
|
||||
}
|
||||
|
||||
if (data[IFLA_CAN_BITTIMING]) {
|
||||
struct can_bittiming bt;
|
||||
|
||||
/* Do not allow changing bittiming while running */
|
||||
if (dev->flags & IFF_UP)
|
||||
return -EBUSY;
|
||||
memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt));
|
||||
if ((!bt.bitrate && !bt.tq) || (bt.bitrate && bt.tq))
|
||||
return -EINVAL;
|
||||
err = can_get_bittiming(dev, &bt);
|
||||
if (err)
|
||||
return err;
|
||||
memcpy(&priv->bittiming, &bt, sizeof(bt));
|
||||
|
||||
if (priv->do_set_bittiming) {
|
||||
/* Finally, set the bit-timing registers */
|
||||
err = priv->do_set_bittiming(dev);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
if (data[IFLA_CAN_RESTART_MS]) {
|
||||
/* Do not allow changing restart delay while running */
|
||||
if (dev->flags & IFF_UP)
|
||||
return -EBUSY;
|
||||
priv->restart_ms = nla_get_u32(data[IFLA_CAN_RESTART_MS]);
|
||||
}
|
||||
|
||||
if (data[IFLA_CAN_RESTART]) {
|
||||
/* Do not allow a restart while not running */
|
||||
if (!(dev->flags & IFF_UP))
|
||||
return -EINVAL;
|
||||
err = can_restart_now(dev);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int can_fill_info(struct sk_buff *skb, const struct net_device *dev)
|
||||
{
|
||||
struct can_priv *priv = netdev_priv(dev);
|
||||
struct can_ctrlmode cm = {.flags = priv->ctrlmode};
|
||||
enum can_state state = priv->state;
|
||||
|
||||
if (priv->do_get_state)
|
||||
priv->do_get_state(dev, &state);
|
||||
NLA_PUT_U32(skb, IFLA_CAN_STATE, state);
|
||||
NLA_PUT(skb, IFLA_CAN_CTRLMODE, sizeof(cm), &cm);
|
||||
NLA_PUT_U32(skb, IFLA_CAN_RESTART_MS, priv->restart_ms);
|
||||
NLA_PUT(skb, IFLA_CAN_BITTIMING,
|
||||
sizeof(priv->bittiming), &priv->bittiming);
|
||||
NLA_PUT(skb, IFLA_CAN_CLOCK, sizeof(cm), &priv->clock);
|
||||
if (priv->bittiming_const)
|
||||
NLA_PUT(skb, IFLA_CAN_BITTIMING_CONST,
|
||||
sizeof(*priv->bittiming_const), priv->bittiming_const);
|
||||
|
||||
return 0;
|
||||
|
||||
nla_put_failure:
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
static int can_fill_xstats(struct sk_buff *skb, const struct net_device *dev)
|
||||
{
|
||||
struct can_priv *priv = netdev_priv(dev);
|
||||
|
||||
NLA_PUT(skb, IFLA_INFO_XSTATS,
|
||||
sizeof(priv->can_stats), &priv->can_stats);
|
||||
|
||||
return 0;
|
||||
|
||||
nla_put_failure:
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
static struct rtnl_link_ops can_link_ops __read_mostly = {
|
||||
.kind = "can",
|
||||
.maxtype = IFLA_CAN_MAX,
|
||||
.policy = can_policy,
|
||||
.setup = can_setup,
|
||||
.changelink = can_changelink,
|
||||
.fill_info = can_fill_info,
|
||||
.fill_xstats = can_fill_xstats,
|
||||
};
|
||||
|
||||
/*
|
||||
* Register the CAN network device
|
||||
*/
|
||||
int register_candev(struct net_device *dev)
|
||||
{
|
||||
dev->rtnl_link_ops = &can_link_ops;
|
||||
return register_netdev(dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(register_candev);
|
||||
|
||||
/*
|
||||
* Unregister the CAN network device
|
||||
*/
|
||||
void unregister_candev(struct net_device *dev)
|
||||
{
|
||||
unregister_netdev(dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(unregister_candev);
|
||||
|
||||
static __init int can_dev_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = rtnl_link_register(&can_link_ops);
|
||||
if (!err)
|
||||
printk(KERN_INFO MOD_DESC "\n");
|
||||
|
||||
return err;
|
||||
}
|
||||
module_init(can_dev_init);
|
||||
|
||||
static __exit void can_dev_exit(void)
|
||||
{
|
||||
rtnl_link_unregister(&can_link_ops);
|
||||
}
|
||||
module_exit(can_dev_exit);
|
||||
|
||||
MODULE_ALIAS_RTNL_LINK("can");
|
||||
11
drivers/net/can/sja1000/Makefile
Normal file
11
drivers/net/can/sja1000/Makefile
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#
|
||||
# Makefile for the SJA1000 CAN controller drivers.
|
||||
#
|
||||
|
||||
obj-$(CONFIG_CAN_SJA1000) += sja1000.o
|
||||
obj-$(CONFIG_CAN_SJA1000_PLATFORM) += sja1000_platform.o
|
||||
obj-$(CONFIG_CAN_SJA1000_OF_PLATFORM) += sja1000_of_platform.o
|
||||
obj-$(CONFIG_CAN_EMS_PCI) += ems_pci.o
|
||||
obj-$(CONFIG_CAN_KVASER_PCI) += kvaser_pci.o
|
||||
|
||||
ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
|
||||
320
drivers/net/can/sja1000/ems_pci.c
Normal file
320
drivers/net/can/sja1000/ems_pci.c
Normal file
|
|
@ -0,0 +1,320 @@
|
|||
/*
|
||||
* Copyright (C) 2007 Wolfgang Grandegger <wg@grandegger.com>
|
||||
* Copyright (C) 2008 Markus Plessing <plessing@ems-wuensche.com>
|
||||
* Copyright (C) 2008 Sebastian Haas <haas@ems-wuensche.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the version 2 of the GNU General Public License
|
||||
* as published by the Free Software Foundation
|
||||
*
|
||||
* 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/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/can.h>
|
||||
#include <linux/can/dev.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include "sja1000.h"
|
||||
|
||||
#define DRV_NAME "ems_pci"
|
||||
|
||||
MODULE_AUTHOR("Sebastian Haas <[email protected]>");
|
||||
MODULE_DESCRIPTION("Socket-CAN driver for EMS CPC-PCI/PCIe CAN cards");
|
||||
MODULE_SUPPORTED_DEVICE("EMS CPC-PCI/PCIe CAN card");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
||||
#define EMS_PCI_MAX_CHAN 2
|
||||
|
||||
struct ems_pci_card {
|
||||
int channels;
|
||||
|
||||
struct pci_dev *pci_dev;
|
||||
struct net_device *net_dev[EMS_PCI_MAX_CHAN];
|
||||
|
||||
void __iomem *conf_addr;
|
||||
void __iomem *base_addr;
|
||||
};
|
||||
|
||||
#define EMS_PCI_CAN_CLOCK (16000000 / 2)
|
||||
|
||||
/*
|
||||
* Register definitions and descriptions are from LinCAN 0.3.3.
|
||||
*
|
||||
* PSB4610 PITA-2 bridge control registers
|
||||
*/
|
||||
#define PITA2_ICR 0x00 /* Interrupt Control Register */
|
||||
#define PITA2_ICR_INT0 0x00000002 /* [RC] INT0 Active/Clear */
|
||||
#define PITA2_ICR_INT0_EN 0x00020000 /* [RW] Enable INT0 */
|
||||
|
||||
#define PITA2_MISC 0x1c /* Miscellaneous Register */
|
||||
#define PITA2_MISC_CONFIG 0x04000000 /* Multiplexed parallel interface */
|
||||
|
||||
/*
|
||||
* The board configuration is probably following:
|
||||
* RX1 is connected to ground.
|
||||
* TX1 is not connected.
|
||||
* CLKO is not connected.
|
||||
* Setting the OCR register to 0xDA is a good idea.
|
||||
* This means normal output mode , push-pull and the correct polarity.
|
||||
*/
|
||||
#define EMS_PCI_OCR (OCR_TX0_PUSHPULL | OCR_TX1_PUSHPULL)
|
||||
|
||||
/*
|
||||
* In the CDR register, you should set CBP to 1.
|
||||
* You will probably also want to set the clock divider value to 7
|
||||
* (meaning direct oscillator output) because the second SJA1000 chip
|
||||
* is driven by the first one CLKOUT output.
|
||||
*/
|
||||
#define EMS_PCI_CDR (CDR_CBP | CDR_CLKOUT_MASK)
|
||||
#define EMS_PCI_MEM_SIZE 4096 /* Size of the remapped io-memory */
|
||||
#define EMS_PCI_CAN_BASE_OFFSET 0x400 /* offset where the controllers starts */
|
||||
#define EMS_PCI_CAN_CTRL_SIZE 0x200 /* memory size for each controller */
|
||||
|
||||
#define EMS_PCI_PORT_BYTES 0x4 /* Each register occupies 4 bytes */
|
||||
|
||||
#define EMS_PCI_VENDOR_ID 0x110a /* PCI device and vendor ID */
|
||||
#define EMS_PCI_DEVICE_ID 0x2104
|
||||
|
||||
static struct pci_device_id ems_pci_tbl[] = {
|
||||
{EMS_PCI_VENDOR_ID, EMS_PCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
|
||||
{0,}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, ems_pci_tbl);
|
||||
|
||||
/*
|
||||
* Helper to read internal registers from card logic (not CAN)
|
||||
*/
|
||||
static u8 ems_pci_readb(struct ems_pci_card *card, unsigned int port)
|
||||
{
|
||||
return readb(card->base_addr + (port * EMS_PCI_PORT_BYTES));
|
||||
}
|
||||
|
||||
static u8 ems_pci_read_reg(const struct sja1000_priv *priv, int port)
|
||||
{
|
||||
return readb(priv->reg_base + (port * EMS_PCI_PORT_BYTES));
|
||||
}
|
||||
|
||||
static void ems_pci_write_reg(const struct sja1000_priv *priv, int port, u8 val)
|
||||
{
|
||||
writeb(val, priv->reg_base + (port * EMS_PCI_PORT_BYTES));
|
||||
}
|
||||
|
||||
static void ems_pci_post_irq(const struct sja1000_priv *priv)
|
||||
{
|
||||
struct ems_pci_card *card = (struct ems_pci_card *)priv->priv;
|
||||
|
||||
/* reset int flag of pita */
|
||||
writel(PITA2_ICR_INT0_EN | PITA2_ICR_INT0, card->conf_addr
|
||||
+ PITA2_ICR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if a CAN controller is present at the specified location
|
||||
* by trying to set 'em into the PeliCAN mode
|
||||
*/
|
||||
static inline int ems_pci_check_chan(const struct sja1000_priv *priv)
|
||||
{
|
||||
unsigned char res;
|
||||
|
||||
/* Make sure SJA1000 is in reset mode */
|
||||
ems_pci_write_reg(priv, REG_MOD, 1);
|
||||
|
||||
ems_pci_write_reg(priv, REG_CDR, CDR_PELICAN);
|
||||
|
||||
/* read reset-values */
|
||||
res = ems_pci_read_reg(priv, REG_CDR);
|
||||
|
||||
if (res == CDR_PELICAN)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ems_pci_del_card(struct pci_dev *pdev)
|
||||
{
|
||||
struct ems_pci_card *card = pci_get_drvdata(pdev);
|
||||
struct net_device *dev;
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < card->channels; i++) {
|
||||
dev = card->net_dev[i];
|
||||
|
||||
if (!dev)
|
||||
continue;
|
||||
|
||||
dev_info(&pdev->dev, "Removing %s.\n", dev->name);
|
||||
unregister_sja1000dev(dev);
|
||||
free_sja1000dev(dev);
|
||||
}
|
||||
|
||||
if (card->base_addr != NULL)
|
||||
pci_iounmap(card->pci_dev, card->base_addr);
|
||||
|
||||
if (card->conf_addr != NULL)
|
||||
pci_iounmap(card->pci_dev, card->conf_addr);
|
||||
|
||||
kfree(card);
|
||||
|
||||
pci_disable_device(pdev);
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
}
|
||||
|
||||
static void ems_pci_card_reset(struct ems_pci_card *card)
|
||||
{
|
||||
/* Request board reset */
|
||||
writeb(0, card->base_addr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Probe PCI device for EMS CAN signature and register each available
|
||||
* CAN channel to SJA1000 Socket-CAN subsystem.
|
||||
*/
|
||||
static int __devinit ems_pci_add_card(struct pci_dev *pdev,
|
||||
const struct pci_device_id *ent)
|
||||
{
|
||||
struct sja1000_priv *priv;
|
||||
struct net_device *dev;
|
||||
struct ems_pci_card *card;
|
||||
int err, i;
|
||||
|
||||
/* Enabling PCI device */
|
||||
if (pci_enable_device(pdev) < 0) {
|
||||
dev_err(&pdev->dev, "Enabling PCI device failed\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Allocating card structures to hold addresses, ... */
|
||||
card = kzalloc(sizeof(struct ems_pci_card), GFP_KERNEL);
|
||||
if (card == NULL) {
|
||||
dev_err(&pdev->dev, "Unable to allocate memory\n");
|
||||
pci_disable_device(pdev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
pci_set_drvdata(pdev, card);
|
||||
|
||||
card->pci_dev = pdev;
|
||||
|
||||
card->channels = 0;
|
||||
|
||||
/* Remap PITA configuration space, and controller memory area */
|
||||
card->conf_addr = pci_iomap(pdev, 0, EMS_PCI_MEM_SIZE);
|
||||
if (card->conf_addr == NULL) {
|
||||
err = -ENOMEM;
|
||||
goto failure_cleanup;
|
||||
}
|
||||
|
||||
card->base_addr = pci_iomap(pdev, 1, EMS_PCI_MEM_SIZE);
|
||||
if (card->base_addr == NULL) {
|
||||
err = -ENOMEM;
|
||||
goto failure_cleanup;
|
||||
}
|
||||
|
||||
/* Configure PITA-2 parallel interface (enable MUX) */
|
||||
writel(PITA2_MISC_CONFIG, card->conf_addr + PITA2_MISC);
|
||||
|
||||
/* Check for unique EMS CAN signature */
|
||||
if (ems_pci_readb(card, 0) != 0x55 ||
|
||||
ems_pci_readb(card, 1) != 0xAA ||
|
||||
ems_pci_readb(card, 2) != 0x01 ||
|
||||
ems_pci_readb(card, 3) != 0xCB ||
|
||||
ems_pci_readb(card, 4) != 0x11) {
|
||||
dev_err(&pdev->dev, "Not EMS Dr. Thomas Wuensche interface\n");
|
||||
err = -ENODEV;
|
||||
goto failure_cleanup;
|
||||
}
|
||||
|
||||
ems_pci_card_reset(card);
|
||||
|
||||
/* Detect available channels */
|
||||
for (i = 0; i < EMS_PCI_MAX_CHAN; i++) {
|
||||
dev = alloc_sja1000dev(0);
|
||||
if (dev == NULL) {
|
||||
err = -ENOMEM;
|
||||
goto failure_cleanup;
|
||||
}
|
||||
|
||||
card->net_dev[i] = dev;
|
||||
priv = netdev_priv(dev);
|
||||
priv->priv = card;
|
||||
priv->irq_flags = IRQF_SHARED;
|
||||
|
||||
dev->irq = pdev->irq;
|
||||
priv->reg_base = card->base_addr + EMS_PCI_CAN_BASE_OFFSET
|
||||
+ (i * EMS_PCI_CAN_CTRL_SIZE);
|
||||
|
||||
/* Check if channel is present */
|
||||
if (ems_pci_check_chan(priv)) {
|
||||
priv->read_reg = ems_pci_read_reg;
|
||||
priv->write_reg = ems_pci_write_reg;
|
||||
priv->post_irq = ems_pci_post_irq;
|
||||
priv->can.clock.freq = EMS_PCI_CAN_CLOCK;
|
||||
priv->ocr = EMS_PCI_OCR;
|
||||
priv->cdr = EMS_PCI_CDR;
|
||||
|
||||
SET_NETDEV_DEV(dev, &pdev->dev);
|
||||
|
||||
/* Enable interrupts from card */
|
||||
writel(PITA2_ICR_INT0_EN, card->conf_addr + PITA2_ICR);
|
||||
|
||||
/* Register SJA1000 device */
|
||||
err = register_sja1000dev(dev);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "Registering device failed "
|
||||
"(err=%d)\n", err);
|
||||
free_sja1000dev(dev);
|
||||
goto failure_cleanup;
|
||||
}
|
||||
|
||||
card->channels++;
|
||||
|
||||
dev_info(&pdev->dev, "Channel #%d at 0x%p, irq %d\n",
|
||||
i + 1, priv->reg_base, dev->irq);
|
||||
} else {
|
||||
free_sja1000dev(dev);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
failure_cleanup:
|
||||
dev_err(&pdev->dev, "Error: %d. Cleaning Up.\n", err);
|
||||
|
||||
ems_pci_del_card(pdev);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct pci_driver ems_pci_driver = {
|
||||
.name = DRV_NAME,
|
||||
.id_table = ems_pci_tbl,
|
||||
.probe = ems_pci_add_card,
|
||||
.remove = ems_pci_del_card,
|
||||
};
|
||||
|
||||
static int __init ems_pci_init(void)
|
||||
{
|
||||
return pci_register_driver(&ems_pci_driver);
|
||||
}
|
||||
|
||||
static void __exit ems_pci_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&ems_pci_driver);
|
||||
}
|
||||
|
||||
module_init(ems_pci_init);
|
||||
module_exit(ems_pci_exit);
|
||||
|
||||
412
drivers/net/can/sja1000/kvaser_pci.c
Normal file
412
drivers/net/can/sja1000/kvaser_pci.c
Normal file
|
|
@ -0,0 +1,412 @@
|
|||
/*
|
||||
* Copyright (C) 2008 Per Dalen <per.dalen@cnw.se>
|
||||
*
|
||||
* Parts of this software are based on (derived) the following:
|
||||
*
|
||||
* - Kvaser linux driver, version 4.72 BETA
|
||||
* Copyright (C) 2002-2007 KVASER AB
|
||||
*
|
||||
* - Lincan driver, version 0.3.3, OCERA project
|
||||
* Copyright (C) 2004 Pavel Pisa
|
||||
* Copyright (C) 2001 Arnaud Westenberg
|
||||
*
|
||||
* - Socketcan SJA1000 drivers
|
||||
* Copyright (C) 2007 Wolfgang Grandegger <wg@grandegger.com>
|
||||
* Copyright (c) 2002-2007 Volkswagen Group Electronic Research
|
||||
* Copyright (c) 2003 Matthias Brukner, Trajet Gmbh, Rebenring 33,
|
||||
* 38106 Braunschweig, GERMANY
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the version 2 of the GNU General Public License
|
||||
* as published by the Free Software Foundation
|
||||
*
|
||||
* 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/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/can.h>
|
||||
#include <linux/can/dev.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include "sja1000.h"
|
||||
|
||||
#define DRV_NAME "kvaser_pci"
|
||||
|
||||
MODULE_AUTHOR("Per Dalen <[email protected]>");
|
||||
MODULE_DESCRIPTION("Socket-CAN driver for KVASER PCAN PCI cards");
|
||||
MODULE_SUPPORTED_DEVICE("KVASER PCAN PCI CAN card");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
||||
#define MAX_NO_OF_CHANNELS 4 /* max no of channels on a single card */
|
||||
|
||||
struct kvaser_pci {
|
||||
int channel;
|
||||
struct pci_dev *pci_dev;
|
||||
struct net_device *slave_dev[MAX_NO_OF_CHANNELS-1];
|
||||
void __iomem *conf_addr;
|
||||
void __iomem *res_addr;
|
||||
int no_channels;
|
||||
u8 xilinx_ver;
|
||||
};
|
||||
|
||||
#define KVASER_PCI_CAN_CLOCK (16000000 / 2)
|
||||
|
||||
/*
|
||||
* The board configuration is probably following:
|
||||
* RX1 is connected to ground.
|
||||
* TX1 is not connected.
|
||||
* CLKO is not connected.
|
||||
* Setting the OCR register to 0xDA is a good idea.
|
||||
* This means normal output mode , push-pull and the correct polarity.
|
||||
*/
|
||||
#define KVASER_PCI_OCR (OCR_TX0_PUSHPULL | OCR_TX1_PUSHPULL)
|
||||
|
||||
/*
|
||||
* In the CDR register, you should set CBP to 1.
|
||||
* You will probably also want to set the clock divider value to 0
|
||||
* (meaning divide-by-2), the Pelican bit, and the clock-off bit
|
||||
* (you will have no need for CLKOUT anyway).
|
||||
*/
|
||||
#define KVASER_PCI_CDR (CDR_CBP | CDR_CLKOUT_MASK)
|
||||
|
||||
/*
|
||||
* These register values are valid for revision 14 of the Xilinx logic.
|
||||
*/
|
||||
#define XILINX_VERINT 7 /* Lower nibble simulate interrupts,
|
||||
high nibble version number. */
|
||||
|
||||
#define XILINX_PRESUMED_VERSION 14
|
||||
|
||||
/*
|
||||
* Important S5920 registers
|
||||
*/
|
||||
#define S5920_INTCSR 0x38
|
||||
#define S5920_PTCR 0x60
|
||||
#define INTCSR_ADDON_INTENABLE_M 0x2000
|
||||
|
||||
|
||||
#define KVASER_PCI_PORT_BYTES 0x20
|
||||
|
||||
#define PCI_CONFIG_PORT_SIZE 0x80 /* size of the config io-memory */
|
||||
#define PCI_PORT_SIZE 0x80 /* size of a channel io-memory */
|
||||
#define PCI_PORT_XILINX_SIZE 0x08 /* size of a xilinx io-memory */
|
||||
|
||||
#define KVASER_PCI_VENDOR_ID1 0x10e8 /* the PCI device and vendor IDs */
|
||||
#define KVASER_PCI_DEVICE_ID1 0x8406
|
||||
|
||||
#define KVASER_PCI_VENDOR_ID2 0x1a07 /* the PCI device and vendor IDs */
|
||||
#define KVASER_PCI_DEVICE_ID2 0x0008
|
||||
|
||||
static struct pci_device_id kvaser_pci_tbl[] = {
|
||||
{KVASER_PCI_VENDOR_ID1, KVASER_PCI_DEVICE_ID1, PCI_ANY_ID, PCI_ANY_ID,},
|
||||
{KVASER_PCI_VENDOR_ID2, KVASER_PCI_DEVICE_ID2, PCI_ANY_ID, PCI_ANY_ID,},
|
||||
{ 0,}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, kvaser_pci_tbl);
|
||||
|
||||
static u8 kvaser_pci_read_reg(const struct sja1000_priv *priv, int port)
|
||||
{
|
||||
return ioread8(priv->reg_base + port);
|
||||
}
|
||||
|
||||
static void kvaser_pci_write_reg(const struct sja1000_priv *priv,
|
||||
int port, u8 val)
|
||||
{
|
||||
iowrite8(val, priv->reg_base + port);
|
||||
}
|
||||
|
||||
static void kvaser_pci_disable_irq(struct net_device *dev)
|
||||
{
|
||||
struct sja1000_priv *priv = netdev_priv(dev);
|
||||
struct kvaser_pci *board = priv->priv;
|
||||
u32 intcsr;
|
||||
|
||||
/* Disable interrupts from card */
|
||||
intcsr = ioread32(board->conf_addr + S5920_INTCSR);
|
||||
intcsr &= ~INTCSR_ADDON_INTENABLE_M;
|
||||
iowrite32(intcsr, board->conf_addr + S5920_INTCSR);
|
||||
}
|
||||
|
||||
static void kvaser_pci_enable_irq(struct net_device *dev)
|
||||
{
|
||||
struct sja1000_priv *priv = netdev_priv(dev);
|
||||
struct kvaser_pci *board = priv->priv;
|
||||
u32 tmp_en_io;
|
||||
|
||||
/* Enable interrupts from card */
|
||||
tmp_en_io = ioread32(board->conf_addr + S5920_INTCSR);
|
||||
tmp_en_io |= INTCSR_ADDON_INTENABLE_M;
|
||||
iowrite32(tmp_en_io, board->conf_addr + S5920_INTCSR);
|
||||
}
|
||||
|
||||
static int number_of_sja1000_chip(void __iomem *base_addr)
|
||||
{
|
||||
u8 status;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_NO_OF_CHANNELS; i++) {
|
||||
/* reset chip */
|
||||
iowrite8(MOD_RM, base_addr +
|
||||
(i * KVASER_PCI_PORT_BYTES) + REG_MOD);
|
||||
status = ioread8(base_addr +
|
||||
(i * KVASER_PCI_PORT_BYTES) + REG_MOD);
|
||||
/* check reset bit */
|
||||
if (!(status & MOD_RM))
|
||||
break;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static void kvaser_pci_del_chan(struct net_device *dev)
|
||||
{
|
||||
struct sja1000_priv *priv;
|
||||
struct kvaser_pci *board;
|
||||
int i;
|
||||
|
||||
if (!dev)
|
||||
return;
|
||||
priv = netdev_priv(dev);
|
||||
board = priv->priv;
|
||||
if (!board)
|
||||
return;
|
||||
|
||||
dev_info(&board->pci_dev->dev, "Removing device %s\n",
|
||||
dev->name);
|
||||
|
||||
/* Disable PCI interrupts */
|
||||
kvaser_pci_disable_irq(dev);
|
||||
|
||||
for (i = 0; i < board->no_channels - 1; i++) {
|
||||
if (board->slave_dev[i]) {
|
||||
dev_info(&board->pci_dev->dev, "Removing device %s\n",
|
||||
board->slave_dev[i]->name);
|
||||
unregister_sja1000dev(board->slave_dev[i]);
|
||||
free_sja1000dev(board->slave_dev[i]);
|
||||
}
|
||||
}
|
||||
unregister_sja1000dev(dev);
|
||||
|
||||
pci_iounmap(board->pci_dev, priv->reg_base);
|
||||
pci_iounmap(board->pci_dev, board->conf_addr);
|
||||
pci_iounmap(board->pci_dev, board->res_addr);
|
||||
|
||||
free_sja1000dev(dev);
|
||||
}
|
||||
|
||||
static int kvaser_pci_add_chan(struct pci_dev *pdev, int channel,
|
||||
struct net_device **master_dev,
|
||||
void __iomem *conf_addr,
|
||||
void __iomem *res_addr,
|
||||
void __iomem *base_addr)
|
||||
{
|
||||
struct net_device *dev;
|
||||
struct sja1000_priv *priv;
|
||||
struct kvaser_pci *board;
|
||||
int err, init_step;
|
||||
|
||||
dev = alloc_sja1000dev(sizeof(struct kvaser_pci));
|
||||
if (dev == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
priv = netdev_priv(dev);
|
||||
board = priv->priv;
|
||||
|
||||
board->pci_dev = pdev;
|
||||
board->channel = channel;
|
||||
|
||||
/* S5920 */
|
||||
board->conf_addr = conf_addr;
|
||||
|
||||
/* XILINX board wide address */
|
||||
board->res_addr = res_addr;
|
||||
|
||||
if (channel == 0) {
|
||||
board->xilinx_ver =
|
||||
ioread8(board->res_addr + XILINX_VERINT) >> 4;
|
||||
init_step = 2;
|
||||
|
||||
/* Assert PTADR# - we're in passive mode so the other bits are
|
||||
not important */
|
||||
iowrite32(0x80808080UL, board->conf_addr + S5920_PTCR);
|
||||
|
||||
/* Enable interrupts from card */
|
||||
kvaser_pci_enable_irq(dev);
|
||||
} else {
|
||||
struct sja1000_priv *master_priv = netdev_priv(*master_dev);
|
||||
struct kvaser_pci *master_board = master_priv->priv;
|
||||
master_board->slave_dev[channel - 1] = dev;
|
||||
master_board->no_channels = channel + 1;
|
||||
board->xilinx_ver = master_board->xilinx_ver;
|
||||
}
|
||||
|
||||
priv->reg_base = base_addr + channel * KVASER_PCI_PORT_BYTES;
|
||||
|
||||
priv->read_reg = kvaser_pci_read_reg;
|
||||
priv->write_reg = kvaser_pci_write_reg;
|
||||
|
||||
priv->can.clock.freq = KVASER_PCI_CAN_CLOCK;
|
||||
|
||||
priv->ocr = KVASER_PCI_OCR;
|
||||
priv->cdr = KVASER_PCI_CDR;
|
||||
|
||||
priv->irq_flags = IRQF_SHARED;
|
||||
dev->irq = pdev->irq;
|
||||
|
||||
init_step = 4;
|
||||
|
||||
dev_info(&pdev->dev, "reg_base=%p conf_addr=%p irq=%d\n",
|
||||
priv->reg_base, board->conf_addr, dev->irq);
|
||||
|
||||
SET_NETDEV_DEV(dev, &pdev->dev);
|
||||
|
||||
/* Register SJA1000 device */
|
||||
err = register_sja1000dev(dev);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "Registering device failed (err=%d)\n",
|
||||
err);
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (channel == 0)
|
||||
*master_dev = dev;
|
||||
|
||||
return 0;
|
||||
|
||||
failure:
|
||||
kvaser_pci_del_chan(dev);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int __devinit kvaser_pci_init_one(struct pci_dev *pdev,
|
||||
const struct pci_device_id *ent)
|
||||
{
|
||||
int err;
|
||||
struct net_device *master_dev = NULL;
|
||||
struct sja1000_priv *priv;
|
||||
struct kvaser_pci *board;
|
||||
int no_channels;
|
||||
void __iomem *base_addr = NULL;
|
||||
void __iomem *conf_addr = NULL;
|
||||
void __iomem *res_addr = NULL;
|
||||
int i;
|
||||
|
||||
dev_info(&pdev->dev, "initializing device %04x:%04x\n",
|
||||
pdev->vendor, pdev->device);
|
||||
|
||||
err = pci_enable_device(pdev);
|
||||
if (err)
|
||||
goto failure;
|
||||
|
||||
err = pci_request_regions(pdev, DRV_NAME);
|
||||
if (err)
|
||||
goto failure_release_pci;
|
||||
|
||||
/* S5920 */
|
||||
conf_addr = pci_iomap(pdev, 0, PCI_CONFIG_PORT_SIZE);
|
||||
if (conf_addr == NULL) {
|
||||
err = -ENODEV;
|
||||
goto failure_release_regions;
|
||||
}
|
||||
|
||||
/* XILINX board wide address */
|
||||
res_addr = pci_iomap(pdev, 2, PCI_PORT_XILINX_SIZE);
|
||||
if (res_addr == NULL) {
|
||||
err = -ENOMEM;
|
||||
goto failure_iounmap;
|
||||
}
|
||||
|
||||
base_addr = pci_iomap(pdev, 1, PCI_PORT_SIZE);
|
||||
if (base_addr == NULL) {
|
||||
err = -ENOMEM;
|
||||
goto failure_iounmap;
|
||||
}
|
||||
|
||||
no_channels = number_of_sja1000_chip(base_addr);
|
||||
if (no_channels == 0) {
|
||||
err = -ENOMEM;
|
||||
goto failure_iounmap;
|
||||
}
|
||||
|
||||
for (i = 0; i < no_channels; i++) {
|
||||
err = kvaser_pci_add_chan(pdev, i, &master_dev,
|
||||
conf_addr, res_addr,
|
||||
base_addr);
|
||||
if (err)
|
||||
goto failure_cleanup;
|
||||
}
|
||||
|
||||
priv = netdev_priv(master_dev);
|
||||
board = priv->priv;
|
||||
|
||||
dev_info(&pdev->dev, "xilinx version=%d number of channels=%d\n",
|
||||
board->xilinx_ver, board->no_channels);
|
||||
|
||||
pci_set_drvdata(pdev, master_dev);
|
||||
return 0;
|
||||
|
||||
failure_cleanup:
|
||||
kvaser_pci_del_chan(master_dev);
|
||||
|
||||
failure_iounmap:
|
||||
if (conf_addr != NULL)
|
||||
pci_iounmap(pdev, conf_addr);
|
||||
if (res_addr != NULL)
|
||||
pci_iounmap(pdev, res_addr);
|
||||
if (base_addr != NULL)
|
||||
pci_iounmap(pdev, base_addr);
|
||||
|
||||
failure_release_regions:
|
||||
pci_release_regions(pdev);
|
||||
|
||||
failure_release_pci:
|
||||
pci_disable_device(pdev);
|
||||
|
||||
failure:
|
||||
return err;
|
||||
|
||||
}
|
||||
|
||||
static void __devexit kvaser_pci_remove_one(struct pci_dev *pdev)
|
||||
{
|
||||
struct net_device *dev = pci_get_drvdata(pdev);
|
||||
|
||||
kvaser_pci_del_chan(dev);
|
||||
|
||||
pci_release_regions(pdev);
|
||||
pci_disable_device(pdev);
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
}
|
||||
|
||||
static struct pci_driver kvaser_pci_driver = {
|
||||
.name = DRV_NAME,
|
||||
.id_table = kvaser_pci_tbl,
|
||||
.probe = kvaser_pci_init_one,
|
||||
.remove = __devexit_p(kvaser_pci_remove_one),
|
||||
};
|
||||
|
||||
static int __init kvaser_pci_init(void)
|
||||
{
|
||||
return pci_register_driver(&kvaser_pci_driver);
|
||||
}
|
||||
|
||||
static void __exit kvaser_pci_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&kvaser_pci_driver);
|
||||
}
|
||||
|
||||
module_init(kvaser_pci_init);
|
||||
module_exit(kvaser_pci_exit);
|
||||
637
drivers/net/can/sja1000/sja1000.c
Normal file
637
drivers/net/can/sja1000/sja1000.c
Normal file
|
|
@ -0,0 +1,637 @@
|
|||
/*
|
||||
* sja1000.c - Philips SJA1000 network device driver
|
||||
*
|
||||
* Copyright (c) 2003 Matthias Brukner, Trajet Gmbh, Rebenring 33,
|
||||
* 38106 Braunschweig, GERMANY
|
||||
*
|
||||
* Copyright (c) 2002-2007 Volkswagen Group Electronic Research
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of Volkswagen nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* Alternatively, provided that this notice is retained in full, this
|
||||
* software may be distributed under the terms of the GNU General
|
||||
* Public License ("GPL") version 2, in which case the provisions of the
|
||||
* GPL apply INSTEAD OF those given above.
|
||||
*
|
||||
* The provided data structures and external interfaces from this code
|
||||
* are not restricted to be used by modules with a GPL compatible license.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* Send feedback to <socketcan-users@lists.berlios.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/if_arp.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <linux/can.h>
|
||||
#include <linux/can/dev.h>
|
||||
#include <linux/can/error.h>
|
||||
#include <linux/can/dev.h>
|
||||
|
||||
#include "sja1000.h"
|
||||
|
||||
#define DRV_NAME "sja1000"
|
||||
|
||||
MODULE_AUTHOR("Oliver Hartkopp <[email protected]>");
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
||||
MODULE_DESCRIPTION(DRV_NAME "CAN netdevice driver");
|
||||
|
||||
static struct can_bittiming_const sja1000_bittiming_const = {
|
||||
.name = DRV_NAME,
|
||||
.tseg1_min = 1,
|
||||
.tseg1_max = 16,
|
||||
.tseg2_min = 1,
|
||||
.tseg2_max = 8,
|
||||
.sjw_max = 4,
|
||||
.brp_min = 1,
|
||||
.brp_max = 64,
|
||||
.brp_inc = 1,
|
||||
};
|
||||
|
||||
static int sja1000_probe_chip(struct net_device *dev)
|
||||
{
|
||||
struct sja1000_priv *priv = netdev_priv(dev);
|
||||
|
||||
if (priv->reg_base && (priv->read_reg(priv, 0) == 0xFF)) {
|
||||
printk(KERN_INFO "%s: probing @0x%lX failed\n",
|
||||
DRV_NAME, dev->base_addr);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void set_reset_mode(struct net_device *dev)
|
||||
{
|
||||
struct sja1000_priv *priv = netdev_priv(dev);
|
||||
unsigned char status = priv->read_reg(priv, REG_MOD);
|
||||
int i;
|
||||
|
||||
/* disable interrupts */
|
||||
priv->write_reg(priv, REG_IER, IRQ_OFF);
|
||||
|
||||
for (i = 0; i < 100; i++) {
|
||||
/* check reset bit */
|
||||
if (status & MOD_RM) {
|
||||
priv->can.state = CAN_STATE_STOPPED;
|
||||
return;
|
||||
}
|
||||
|
||||
priv->write_reg(priv, REG_MOD, MOD_RM); /* reset chip */
|
||||
udelay(10);
|
||||
status = priv->read_reg(priv, REG_MOD);
|
||||
}
|
||||
|
||||
dev_err(dev->dev.parent, "setting SJA1000 into reset mode failed!\n");
|
||||
}
|
||||
|
||||
static void set_normal_mode(struct net_device *dev)
|
||||
{
|
||||
struct sja1000_priv *priv = netdev_priv(dev);
|
||||
unsigned char status = priv->read_reg(priv, REG_MOD);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 100; i++) {
|
||||
/* check reset bit */
|
||||
if ((status & MOD_RM) == 0) {
|
||||
priv->can.state = CAN_STATE_ERROR_ACTIVE;
|
||||
/* enable all interrupts */
|
||||
priv->write_reg(priv, REG_IER, IRQ_ALL);
|
||||
return;
|
||||
}
|
||||
|
||||
/* set chip to normal mode */
|
||||
priv->write_reg(priv, REG_MOD, 0x00);
|
||||
udelay(10);
|
||||
status = priv->read_reg(priv, REG_MOD);
|
||||
}
|
||||
|
||||
dev_err(dev->dev.parent, "setting SJA1000 into normal mode failed!\n");
|
||||
}
|
||||
|
||||
static void sja1000_start(struct net_device *dev)
|
||||
{
|
||||
struct sja1000_priv *priv = netdev_priv(dev);
|
||||
|
||||
/* leave reset mode */
|
||||
if (priv->can.state != CAN_STATE_STOPPED)
|
||||
set_reset_mode(dev);
|
||||
|
||||
/* Clear error counters and error code capture */
|
||||
priv->write_reg(priv, REG_TXERR, 0x0);
|
||||
priv->write_reg(priv, REG_RXERR, 0x0);
|
||||
priv->read_reg(priv, REG_ECC);
|
||||
|
||||
/* leave reset mode */
|
||||
set_normal_mode(dev);
|
||||
}
|
||||
|
||||
static int sja1000_set_mode(struct net_device *dev, enum can_mode mode)
|
||||
{
|
||||
struct sja1000_priv *priv = netdev_priv(dev);
|
||||
|
||||
if (!priv->open_time)
|
||||
return -EINVAL;
|
||||
|
||||
switch (mode) {
|
||||
case CAN_MODE_START:
|
||||
sja1000_start(dev);
|
||||
if (netif_queue_stopped(dev))
|
||||
netif_wake_queue(dev);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sja1000_set_bittiming(struct net_device *dev)
|
||||
{
|
||||
struct sja1000_priv *priv = netdev_priv(dev);
|
||||
struct can_bittiming *bt = &priv->can.bittiming;
|
||||
u8 btr0, btr1;
|
||||
|
||||
btr0 = ((bt->brp - 1) & 0x3f) | (((bt->sjw - 1) & 0x3) << 6);
|
||||
btr1 = ((bt->prop_seg + bt->phase_seg1 - 1) & 0xf) |
|
||||
(((bt->phase_seg2 - 1) & 0x7) << 4);
|
||||
if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
|
||||
btr1 |= 0x80;
|
||||
|
||||
dev_info(dev->dev.parent,
|
||||
"setting BTR0=0x%02x BTR1=0x%02x\n", btr0, btr1);
|
||||
|
||||
priv->write_reg(priv, REG_BTR0, btr0);
|
||||
priv->write_reg(priv, REG_BTR1, btr1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* initialize SJA1000 chip:
|
||||
* - reset chip
|
||||
* - set output mode
|
||||
* - set baudrate
|
||||
* - enable interrupts
|
||||
* - start operating mode
|
||||
*/
|
||||
static void chipset_init(struct net_device *dev)
|
||||
{
|
||||
struct sja1000_priv *priv = netdev_priv(dev);
|
||||
|
||||
/* set clock divider and output control register */
|
||||
priv->write_reg(priv, REG_CDR, priv->cdr | CDR_PELICAN);
|
||||
|
||||
/* set acceptance filter (accept all) */
|
||||
priv->write_reg(priv, REG_ACCC0, 0x00);
|
||||
priv->write_reg(priv, REG_ACCC1, 0x00);
|
||||
priv->write_reg(priv, REG_ACCC2, 0x00);
|
||||
priv->write_reg(priv, REG_ACCC3, 0x00);
|
||||
|
||||
priv->write_reg(priv, REG_ACCM0, 0xFF);
|
||||
priv->write_reg(priv, REG_ACCM1, 0xFF);
|
||||
priv->write_reg(priv, REG_ACCM2, 0xFF);
|
||||
priv->write_reg(priv, REG_ACCM3, 0xFF);
|
||||
|
||||
priv->write_reg(priv, REG_OCR, priv->ocr | OCR_MODE_NORMAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* transmit a CAN message
|
||||
* message layout in the sk_buff should be like this:
|
||||
* xx xx xx xx ff ll 00 11 22 33 44 55 66 77
|
||||
* [ can-id ] [flags] [len] [can data (up to 8 bytes]
|
||||
*/
|
||||
static int sja1000_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
struct sja1000_priv *priv = netdev_priv(dev);
|
||||
struct net_device_stats *stats = &dev->stats;
|
||||
struct can_frame *cf = (struct can_frame *)skb->data;
|
||||
uint8_t fi;
|
||||
uint8_t dlc;
|
||||
canid_t id;
|
||||
uint8_t dreg;
|
||||
int i;
|
||||
|
||||
netif_stop_queue(dev);
|
||||
|
||||
fi = dlc = cf->can_dlc;
|
||||
id = cf->can_id;
|
||||
|
||||
if (id & CAN_RTR_FLAG)
|
||||
fi |= FI_RTR;
|
||||
|
||||
if (id & CAN_EFF_FLAG) {
|
||||
fi |= FI_FF;
|
||||
dreg = EFF_BUF;
|
||||
priv->write_reg(priv, REG_FI, fi);
|
||||
priv->write_reg(priv, REG_ID1, (id & 0x1fe00000) >> (5 + 16));
|
||||
priv->write_reg(priv, REG_ID2, (id & 0x001fe000) >> (5 + 8));
|
||||
priv->write_reg(priv, REG_ID3, (id & 0x00001fe0) >> 5);
|
||||
priv->write_reg(priv, REG_ID4, (id & 0x0000001f) << 3);
|
||||
} else {
|
||||
dreg = SFF_BUF;
|
||||
priv->write_reg(priv, REG_FI, fi);
|
||||
priv->write_reg(priv, REG_ID1, (id & 0x000007f8) >> 3);
|
||||
priv->write_reg(priv, REG_ID2, (id & 0x00000007) << 5);
|
||||
}
|
||||
|
||||
for (i = 0; i < dlc; i++)
|
||||
priv->write_reg(priv, dreg++, cf->data[i]);
|
||||
|
||||
stats->tx_bytes += dlc;
|
||||
dev->trans_start = jiffies;
|
||||
|
||||
can_put_echo_skb(skb, dev, 0);
|
||||
|
||||
priv->write_reg(priv, REG_CMR, CMD_TR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sja1000_rx(struct net_device *dev)
|
||||
{
|
||||
struct sja1000_priv *priv = netdev_priv(dev);
|
||||
struct net_device_stats *stats = &dev->stats;
|
||||
struct can_frame *cf;
|
||||
struct sk_buff *skb;
|
||||
uint8_t fi;
|
||||
uint8_t dreg;
|
||||
canid_t id;
|
||||
uint8_t dlc;
|
||||
int i;
|
||||
|
||||
skb = dev_alloc_skb(sizeof(struct can_frame));
|
||||
if (skb == NULL)
|
||||
return;
|
||||
skb->dev = dev;
|
||||
skb->protocol = htons(ETH_P_CAN);
|
||||
|
||||
fi = priv->read_reg(priv, REG_FI);
|
||||
dlc = fi & 0x0F;
|
||||
|
||||
if (fi & FI_FF) {
|
||||
/* extended frame format (EFF) */
|
||||
dreg = EFF_BUF;
|
||||
id = (priv->read_reg(priv, REG_ID1) << (5 + 16))
|
||||
| (priv->read_reg(priv, REG_ID2) << (5 + 8))
|
||||
| (priv->read_reg(priv, REG_ID3) << 5)
|
||||
| (priv->read_reg(priv, REG_ID4) >> 3);
|
||||
id |= CAN_EFF_FLAG;
|
||||
} else {
|
||||
/* standard frame format (SFF) */
|
||||
dreg = SFF_BUF;
|
||||
id = (priv->read_reg(priv, REG_ID1) << 3)
|
||||
| (priv->read_reg(priv, REG_ID2) >> 5);
|
||||
}
|
||||
|
||||
if (fi & FI_RTR)
|
||||
id |= CAN_RTR_FLAG;
|
||||
|
||||
cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
|
||||
memset(cf, 0, sizeof(struct can_frame));
|
||||
cf->can_id = id;
|
||||
cf->can_dlc = dlc;
|
||||
for (i = 0; i < dlc; i++)
|
||||
cf->data[i] = priv->read_reg(priv, dreg++);
|
||||
|
||||
while (i < 8)
|
||||
cf->data[i++] = 0;
|
||||
|
||||
/* release receive buffer */
|
||||
priv->write_reg(priv, REG_CMR, CMD_RRB);
|
||||
|
||||
netif_rx(skb);
|
||||
|
||||
dev->last_rx = jiffies;
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += dlc;
|
||||
}
|
||||
|
||||
static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
|
||||
{
|
||||
struct sja1000_priv *priv = netdev_priv(dev);
|
||||
struct net_device_stats *stats = &dev->stats;
|
||||
struct can_frame *cf;
|
||||
struct sk_buff *skb;
|
||||
enum can_state state = priv->can.state;
|
||||
uint8_t ecc, alc;
|
||||
|
||||
skb = dev_alloc_skb(sizeof(struct can_frame));
|
||||
if (skb == NULL)
|
||||
return -ENOMEM;
|
||||
skb->dev = dev;
|
||||
skb->protocol = htons(ETH_P_CAN);
|
||||
cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
|
||||
memset(cf, 0, sizeof(struct can_frame));
|
||||
cf->can_id = CAN_ERR_FLAG;
|
||||
cf->can_dlc = CAN_ERR_DLC;
|
||||
|
||||
if (isrc & IRQ_DOI) {
|
||||
/* data overrun interrupt */
|
||||
dev_dbg(dev->dev.parent, "data overrun interrupt\n");
|
||||
cf->can_id |= CAN_ERR_CRTL;
|
||||
cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
|
||||
stats->rx_over_errors++;
|
||||
stats->rx_errors++;
|
||||
priv->write_reg(priv, REG_CMR, CMD_CDO); /* clear bit */
|
||||
}
|
||||
|
||||
if (isrc & IRQ_EI) {
|
||||
/* error warning interrupt */
|
||||
dev_dbg(dev->dev.parent, "error warning interrupt\n");
|
||||
|
||||
if (status & SR_BS) {
|
||||
state = CAN_STATE_BUS_OFF;
|
||||
cf->can_id |= CAN_ERR_BUSOFF;
|
||||
can_bus_off(dev);
|
||||
} else if (status & SR_ES) {
|
||||
state = CAN_STATE_ERROR_WARNING;
|
||||
} else
|
||||
state = CAN_STATE_ERROR_ACTIVE;
|
||||
}
|
||||
if (isrc & IRQ_BEI) {
|
||||
/* bus error interrupt */
|
||||
priv->can.can_stats.bus_error++;
|
||||
stats->rx_errors++;
|
||||
|
||||
ecc = priv->read_reg(priv, REG_ECC);
|
||||
|
||||
cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
|
||||
|
||||
switch (ecc & ECC_MASK) {
|
||||
case ECC_BIT:
|
||||
cf->data[2] |= CAN_ERR_PROT_BIT;
|
||||
break;
|
||||
case ECC_FORM:
|
||||
cf->data[2] |= CAN_ERR_PROT_FORM;
|
||||
break;
|
||||
case ECC_STUFF:
|
||||
cf->data[2] |= CAN_ERR_PROT_STUFF;
|
||||
break;
|
||||
default:
|
||||
cf->data[2] |= CAN_ERR_PROT_UNSPEC;
|
||||
cf->data[3] = ecc & ECC_SEG;
|
||||
break;
|
||||
}
|
||||
/* Error occured during transmission? */
|
||||
if ((ecc & ECC_DIR) == 0)
|
||||
cf->data[2] |= CAN_ERR_PROT_TX;
|
||||
}
|
||||
if (isrc & IRQ_EPI) {
|
||||
/* error passive interrupt */
|
||||
dev_dbg(dev->dev.parent, "error passive interrupt\n");
|
||||
if (status & SR_ES)
|
||||
state = CAN_STATE_ERROR_PASSIVE;
|
||||
else
|
||||
state = CAN_STATE_ERROR_ACTIVE;
|
||||
}
|
||||
if (isrc & IRQ_ALI) {
|
||||
/* arbitration lost interrupt */
|
||||
dev_dbg(dev->dev.parent, "arbitration lost interrupt\n");
|
||||
alc = priv->read_reg(priv, REG_ALC);
|
||||
priv->can.can_stats.arbitration_lost++;
|
||||
stats->rx_errors++;
|
||||
cf->can_id |= CAN_ERR_LOSTARB;
|
||||
cf->data[0] = alc & 0x1f;
|
||||
}
|
||||
|
||||
if (state != priv->can.state && (state == CAN_STATE_ERROR_WARNING ||
|
||||
state == CAN_STATE_ERROR_PASSIVE)) {
|
||||
uint8_t rxerr = priv->read_reg(priv, REG_RXERR);
|
||||
uint8_t txerr = priv->read_reg(priv, REG_TXERR);
|
||||
cf->can_id |= CAN_ERR_CRTL;
|
||||
if (state == CAN_STATE_ERROR_WARNING) {
|
||||
priv->can.can_stats.error_warning++;
|
||||
cf->data[1] = (txerr > rxerr) ?
|
||||
CAN_ERR_CRTL_TX_WARNING :
|
||||
CAN_ERR_CRTL_RX_WARNING;
|
||||
} else {
|
||||
priv->can.can_stats.error_passive++;
|
||||
cf->data[1] = (txerr > rxerr) ?
|
||||
CAN_ERR_CRTL_TX_PASSIVE :
|
||||
CAN_ERR_CRTL_RX_PASSIVE;
|
||||
}
|
||||
}
|
||||
|
||||
priv->can.state = state;
|
||||
|
||||
netif_rx(skb);
|
||||
|
||||
dev->last_rx = jiffies;
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
irqreturn_t sja1000_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct net_device *dev = (struct net_device *)dev_id;
|
||||
struct sja1000_priv *priv = netdev_priv(dev);
|
||||
struct net_device_stats *stats = &dev->stats;
|
||||
uint8_t isrc, status;
|
||||
int n = 0;
|
||||
|
||||
/* Shared interrupts and IRQ off? */
|
||||
if (priv->read_reg(priv, REG_IER) == IRQ_OFF)
|
||||
return IRQ_NONE;
|
||||
|
||||
if (priv->pre_irq)
|
||||
priv->pre_irq(priv);
|
||||
|
||||
while ((isrc = priv->read_reg(priv, REG_IR)) && (n < SJA1000_MAX_IRQ)) {
|
||||
n++;
|
||||
status = priv->read_reg(priv, REG_SR);
|
||||
|
||||
if (isrc & IRQ_WUI)
|
||||
dev_warn(dev->dev.parent, "wakeup interrupt\n");
|
||||
|
||||
if (isrc & IRQ_TI) {
|
||||
/* transmission complete interrupt */
|
||||
stats->tx_packets++;
|
||||
can_get_echo_skb(dev, 0);
|
||||
netif_wake_queue(dev);
|
||||
}
|
||||
if (isrc & IRQ_RI) {
|
||||
/* receive interrupt */
|
||||
while (status & SR_RBS) {
|
||||
sja1000_rx(dev);
|
||||
status = priv->read_reg(priv, REG_SR);
|
||||
}
|
||||
}
|
||||
if (isrc & (IRQ_DOI | IRQ_EI | IRQ_BEI | IRQ_EPI | IRQ_ALI)) {
|
||||
/* error interrupt */
|
||||
if (sja1000_err(dev, isrc, status))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->post_irq)
|
||||
priv->post_irq(priv);
|
||||
|
||||
if (n >= SJA1000_MAX_IRQ)
|
||||
dev_dbg(dev->dev.parent, "%d messages handled in ISR", n);
|
||||
|
||||
return (n) ? IRQ_HANDLED : IRQ_NONE;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sja1000_interrupt);
|
||||
|
||||
static int sja1000_open(struct net_device *dev)
|
||||
{
|
||||
struct sja1000_priv *priv = netdev_priv(dev);
|
||||
int err;
|
||||
|
||||
/* set chip into reset mode */
|
||||
set_reset_mode(dev);
|
||||
|
||||
/* common open */
|
||||
err = open_candev(dev);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* register interrupt handler, if not done by the device driver */
|
||||
if (!(priv->flags & SJA1000_CUSTOM_IRQ_HANDLER)) {
|
||||
err = request_irq(dev->irq, &sja1000_interrupt, priv->irq_flags,
|
||||
dev->name, (void *)dev);
|
||||
if (err) {
|
||||
close_candev(dev);
|
||||
return -EAGAIN;
|
||||
}
|
||||
}
|
||||
|
||||
/* init and start chi */
|
||||
sja1000_start(dev);
|
||||
priv->open_time = jiffies;
|
||||
|
||||
netif_start_queue(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sja1000_close(struct net_device *dev)
|
||||
{
|
||||
struct sja1000_priv *priv = netdev_priv(dev);
|
||||
|
||||
netif_stop_queue(dev);
|
||||
set_reset_mode(dev);
|
||||
|
||||
if (!(priv->flags & SJA1000_CUSTOM_IRQ_HANDLER))
|
||||
free_irq(dev->irq, (void *)dev);
|
||||
|
||||
close_candev(dev);
|
||||
|
||||
priv->open_time = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct net_device *alloc_sja1000dev(int sizeof_priv)
|
||||
{
|
||||
struct net_device *dev;
|
||||
struct sja1000_priv *priv;
|
||||
|
||||
dev = alloc_candev(sizeof(struct sja1000_priv) + sizeof_priv);
|
||||
if (!dev)
|
||||
return NULL;
|
||||
|
||||
priv = netdev_priv(dev);
|
||||
|
||||
priv->dev = dev;
|
||||
priv->can.bittiming_const = &sja1000_bittiming_const;
|
||||
priv->can.do_set_bittiming = sja1000_set_bittiming;
|
||||
priv->can.do_set_mode = sja1000_set_mode;
|
||||
|
||||
if (sizeof_priv)
|
||||
priv->priv = (void *)priv + sizeof(struct sja1000_priv);
|
||||
|
||||
return dev;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(alloc_sja1000dev);
|
||||
|
||||
void free_sja1000dev(struct net_device *dev)
|
||||
{
|
||||
free_candev(dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(free_sja1000dev);
|
||||
|
||||
static const struct net_device_ops sja1000_netdev_ops = {
|
||||
.ndo_open = sja1000_open,
|
||||
.ndo_stop = sja1000_close,
|
||||
.ndo_start_xmit = sja1000_start_xmit,
|
||||
};
|
||||
|
||||
int register_sja1000dev(struct net_device *dev)
|
||||
{
|
||||
if (!sja1000_probe_chip(dev))
|
||||
return -ENODEV;
|
||||
|
||||
dev->flags |= IFF_ECHO; /* we support local echo */
|
||||
dev->netdev_ops = &sja1000_netdev_ops;
|
||||
|
||||
set_reset_mode(dev);
|
||||
chipset_init(dev);
|
||||
|
||||
return register_candev(dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(register_sja1000dev);
|
||||
|
||||
void unregister_sja1000dev(struct net_device *dev)
|
||||
{
|
||||
set_reset_mode(dev);
|
||||
unregister_candev(dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(unregister_sja1000dev);
|
||||
|
||||
static __init int sja1000_init(void)
|
||||
{
|
||||
printk(KERN_INFO "%s CAN netdevice driver\n", DRV_NAME);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
module_init(sja1000_init);
|
||||
|
||||
static __exit void sja1000_exit(void)
|
||||
{
|
||||
printk(KERN_INFO "%s: driver removed\n", DRV_NAME);
|
||||
}
|
||||
|
||||
module_exit(sja1000_exit);
|
||||
181
drivers/net/can/sja1000/sja1000.h
Normal file
181
drivers/net/can/sja1000/sja1000.h
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
/*
|
||||
* sja1000.h - Philips SJA1000 network device driver
|
||||
*
|
||||
* Copyright (c) 2003 Matthias Brukner, Trajet Gmbh, Rebenring 33,
|
||||
* 38106 Braunschweig, GERMANY
|
||||
*
|
||||
* Copyright (c) 2002-2007 Volkswagen Group Electronic Research
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of Volkswagen nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* Alternatively, provided that this notice is retained in full, this
|
||||
* software may be distributed under the terms of the GNU General
|
||||
* Public License ("GPL") version 2, in which case the provisions of the
|
||||
* GPL apply INSTEAD OF those given above.
|
||||
*
|
||||
* The provided data structures and external interfaces from this code
|
||||
* are not restricted to be used by modules with a GPL compatible license.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* Send feedback to <socketcan-users@lists.berlios.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SJA1000_DEV_H
|
||||
#define SJA1000_DEV_H
|
||||
|
||||
#include <linux/can/dev.h>
|
||||
#include <linux/can/platform/sja1000.h>
|
||||
|
||||
#define SJA1000_MAX_IRQ 20 /* max. number of interrupts handled in ISR */
|
||||
|
||||
/* SJA1000 registers - manual section 6.4 (Pelican Mode) */
|
||||
#define REG_MOD 0x00
|
||||
#define REG_CMR 0x01
|
||||
#define REG_SR 0x02
|
||||
#define REG_IR 0x03
|
||||
#define REG_IER 0x04
|
||||
#define REG_ALC 0x0B
|
||||
#define REG_ECC 0x0C
|
||||
#define REG_EWL 0x0D
|
||||
#define REG_RXERR 0x0E
|
||||
#define REG_TXERR 0x0F
|
||||
#define REG_ACCC0 0x10
|
||||
#define REG_ACCC1 0x11
|
||||
#define REG_ACCC2 0x12
|
||||
#define REG_ACCC3 0x13
|
||||
#define REG_ACCM0 0x14
|
||||
#define REG_ACCM1 0x15
|
||||
#define REG_ACCM2 0x16
|
||||
#define REG_ACCM3 0x17
|
||||
#define REG_RMC 0x1D
|
||||
#define REG_RBSA 0x1E
|
||||
|
||||
/* Common registers - manual section 6.5 */
|
||||
#define REG_BTR0 0x06
|
||||
#define REG_BTR1 0x07
|
||||
#define REG_OCR 0x08
|
||||
#define REG_CDR 0x1F
|
||||
|
||||
#define REG_FI 0x10
|
||||
#define SFF_BUF 0x13
|
||||
#define EFF_BUF 0x15
|
||||
|
||||
#define FI_FF 0x80
|
||||
#define FI_RTR 0x40
|
||||
|
||||
#define REG_ID1 0x11
|
||||
#define REG_ID2 0x12
|
||||
#define REG_ID3 0x13
|
||||
#define REG_ID4 0x14
|
||||
|
||||
#define CAN_RAM 0x20
|
||||
|
||||
/* mode register */
|
||||
#define MOD_RM 0x01
|
||||
#define MOD_LOM 0x02
|
||||
#define MOD_STM 0x04
|
||||
#define MOD_AFM 0x08
|
||||
#define MOD_SM 0x10
|
||||
|
||||
/* commands */
|
||||
#define CMD_SRR 0x10
|
||||
#define CMD_CDO 0x08
|
||||
#define CMD_RRB 0x04
|
||||
#define CMD_AT 0x02
|
||||
#define CMD_TR 0x01
|
||||
|
||||
/* interrupt sources */
|
||||
#define IRQ_BEI 0x80
|
||||
#define IRQ_ALI 0x40
|
||||
#define IRQ_EPI 0x20
|
||||
#define IRQ_WUI 0x10
|
||||
#define IRQ_DOI 0x08
|
||||
#define IRQ_EI 0x04
|
||||
#define IRQ_TI 0x02
|
||||
#define IRQ_RI 0x01
|
||||
#define IRQ_ALL 0xFF
|
||||
#define IRQ_OFF 0x00
|
||||
|
||||
/* status register content */
|
||||
#define SR_BS 0x80
|
||||
#define SR_ES 0x40
|
||||
#define SR_TS 0x20
|
||||
#define SR_RS 0x10
|
||||
#define SR_TCS 0x08
|
||||
#define SR_TBS 0x04
|
||||
#define SR_DOS 0x02
|
||||
#define SR_RBS 0x01
|
||||
|
||||
#define SR_CRIT (SR_BS|SR_ES)
|
||||
|
||||
/* ECC register */
|
||||
#define ECC_SEG 0x1F
|
||||
#define ECC_DIR 0x20
|
||||
#define ECC_ERR 6
|
||||
#define ECC_BIT 0x00
|
||||
#define ECC_FORM 0x40
|
||||
#define ECC_STUFF 0x80
|
||||
#define ECC_MASK 0xc0
|
||||
|
||||
/*
|
||||
* Flags for sja1000priv.flags
|
||||
*/
|
||||
#define SJA1000_CUSTOM_IRQ_HANDLER 0x1
|
||||
|
||||
/*
|
||||
* SJA1000 private data structure
|
||||
*/
|
||||
struct sja1000_priv {
|
||||
struct can_priv can; /* must be the first member */
|
||||
int open_time;
|
||||
struct sk_buff *echo_skb;
|
||||
|
||||
/* the lower-layer is responsible for appropriate locking */
|
||||
u8 (*read_reg) (const struct sja1000_priv *priv, int reg);
|
||||
void (*write_reg) (const struct sja1000_priv *priv, int reg, u8 val);
|
||||
void (*pre_irq) (const struct sja1000_priv *priv);
|
||||
void (*post_irq) (const struct sja1000_priv *priv);
|
||||
|
||||
void *priv; /* for board-specific data */
|
||||
struct net_device *dev;
|
||||
|
||||
void __iomem *reg_base; /* ioremap'ed address to registers */
|
||||
unsigned long irq_flags; /* for request_irq() */
|
||||
|
||||
u16 flags; /* custom mode flags */
|
||||
u8 ocr; /* output control register */
|
||||
u8 cdr; /* clock divider register */
|
||||
};
|
||||
|
||||
struct net_device *alloc_sja1000dev(int sizeof_priv);
|
||||
void free_sja1000dev(struct net_device *dev);
|
||||
int register_sja1000dev(struct net_device *dev);
|
||||
void unregister_sja1000dev(struct net_device *dev);
|
||||
|
||||
irqreturn_t sja1000_interrupt(int irq, void *dev_id);
|
||||
|
||||
#endif /* SJA1000_DEV_H */
|
||||
235
drivers/net/can/sja1000/sja1000_of_platform.c
Normal file
235
drivers/net/can/sja1000/sja1000_of_platform.c
Normal file
|
|
@ -0,0 +1,235 @@
|
|||
/*
|
||||
* Driver for SJA1000 CAN controllers on the OpenFirmware platform bus
|
||||
*
|
||||
* Copyright (C) 2008-2009 Wolfgang Grandegger <wg@grandegger.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the version 2 of the GNU General Public License
|
||||
* as published by the Free Software Foundation
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* This is a generic driver for SJA1000 chips on the OpenFirmware platform
|
||||
* bus found on embedded PowerPC systems. You need a SJA1000 CAN node
|
||||
* definition in your flattened device tree source (DTS) file similar to:
|
||||
*
|
||||
* can@3,100 {
|
||||
* compatible = "nxp,sja1000";
|
||||
* reg = <3 0x100 0x80>;
|
||||
* interrupts = <2 0>;
|
||||
* interrupt-parent = <&mpic>;
|
||||
* nxp,external-clock-frequency = <16000000>;
|
||||
* };
|
||||
*
|
||||
* See "Documentation/powerpc/dts-bindings/can/sja1000.txt" for further
|
||||
* information.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/can.h>
|
||||
#include <linux/can/dev.h>
|
||||
|
||||
#include <linux/of_platform.h>
|
||||
#include <asm/prom.h>
|
||||
|
||||
#include "sja1000.h"
|
||||
|
||||
#define DRV_NAME "sja1000_of_platform"
|
||||
|
||||
MODULE_AUTHOR("Wolfgang Grandegger <[email protected]>");
|
||||
MODULE_DESCRIPTION("Socket-CAN driver for SJA1000 on the OF platform bus");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
||||
#define SJA1000_OFP_CAN_CLOCK (16000000 / 2)
|
||||
|
||||
#define SJA1000_OFP_OCR OCR_TX0_PULLDOWN
|
||||
#define SJA1000_OFP_CDR (CDR_CBP | CDR_CLK_OFF)
|
||||
|
||||
static u8 sja1000_ofp_read_reg(const struct sja1000_priv *priv, int reg)
|
||||
{
|
||||
return in_8(priv->reg_base + reg);
|
||||
}
|
||||
|
||||
static void sja1000_ofp_write_reg(const struct sja1000_priv *priv,
|
||||
int reg, u8 val)
|
||||
{
|
||||
out_8(priv->reg_base + reg, val);
|
||||
}
|
||||
|
||||
static int __devexit sja1000_ofp_remove(struct of_device *ofdev)
|
||||
{
|
||||
struct net_device *dev = dev_get_drvdata(&ofdev->dev);
|
||||
struct sja1000_priv *priv = netdev_priv(dev);
|
||||
struct device_node *np = ofdev->node;
|
||||
struct resource res;
|
||||
|
||||
dev_set_drvdata(&ofdev->dev, NULL);
|
||||
|
||||
unregister_sja1000dev(dev);
|
||||
free_sja1000dev(dev);
|
||||
iounmap(priv->reg_base);
|
||||
irq_dispose_mapping(dev->irq);
|
||||
|
||||
of_address_to_resource(np, 0, &res);
|
||||
release_mem_region(res.start, resource_size(&res));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit sja1000_ofp_probe(struct of_device *ofdev,
|
||||
const struct of_device_id *id)
|
||||
{
|
||||
struct device_node *np = ofdev->node;
|
||||
struct net_device *dev;
|
||||
struct sja1000_priv *priv;
|
||||
struct resource res;
|
||||
const u32 *prop;
|
||||
int err, irq, res_size, prop_size;
|
||||
void __iomem *base;
|
||||
|
||||
err = of_address_to_resource(np, 0, &res);
|
||||
if (err) {
|
||||
dev_err(&ofdev->dev, "invalid address\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
res_size = resource_size(&res);
|
||||
|
||||
if (!request_mem_region(res.start, res_size, DRV_NAME)) {
|
||||
dev_err(&ofdev->dev, "couldn't request %#llx..%#llx\n",
|
||||
(unsigned long long)res.start,
|
||||
(unsigned long long)res.end);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
base = ioremap_nocache(res.start, res_size);
|
||||
if (!base) {
|
||||
dev_err(&ofdev->dev, "couldn't ioremap %#llx..%#llx\n",
|
||||
(unsigned long long)res.start,
|
||||
(unsigned long long)res.end);
|
||||
err = -ENOMEM;
|
||||
goto exit_release_mem;
|
||||
}
|
||||
|
||||
irq = irq_of_parse_and_map(np, 0);
|
||||
if (irq == NO_IRQ) {
|
||||
dev_err(&ofdev->dev, "no irq found\n");
|
||||
err = -ENODEV;
|
||||
goto exit_unmap_mem;
|
||||
}
|
||||
|
||||
dev = alloc_sja1000dev(0);
|
||||
if (!dev) {
|
||||
err = -ENOMEM;
|
||||
goto exit_dispose_irq;
|
||||
}
|
||||
|
||||
priv = netdev_priv(dev);
|
||||
|
||||
priv->read_reg = sja1000_ofp_read_reg;
|
||||
priv->write_reg = sja1000_ofp_write_reg;
|
||||
|
||||
prop = of_get_property(np, "nxp,external-clock-frequency", &prop_size);
|
||||
if (prop && (prop_size == sizeof(u32)))
|
||||
priv->can.clock.freq = *prop / 2;
|
||||
else
|
||||
priv->can.clock.freq = SJA1000_OFP_CAN_CLOCK; /* default */
|
||||
|
||||
prop = of_get_property(np, "nxp,tx-output-mode", &prop_size);
|
||||
if (prop && (prop_size == sizeof(u32)))
|
||||
priv->ocr |= *prop & OCR_MODE_MASK;
|
||||
else
|
||||
priv->ocr |= OCR_MODE_NORMAL; /* default */
|
||||
|
||||
prop = of_get_property(np, "nxp,tx-output-config", &prop_size);
|
||||
if (prop && (prop_size == sizeof(u32)))
|
||||
priv->ocr |= (*prop << OCR_TX_SHIFT) & OCR_TX_MASK;
|
||||
else
|
||||
priv->ocr |= OCR_TX0_PULLDOWN; /* default */
|
||||
|
||||
prop = of_get_property(np, "nxp,clock-out-frequency", &prop_size);
|
||||
if (prop && (prop_size == sizeof(u32)) && *prop) {
|
||||
u32 divider = priv->can.clock.freq * 2 / *prop;
|
||||
|
||||
if (divider > 1)
|
||||
priv->cdr |= divider / 2 - 1;
|
||||
else
|
||||
priv->cdr |= CDR_CLKOUT_MASK;
|
||||
} else {
|
||||
priv->cdr |= CDR_CLK_OFF; /* default */
|
||||
}
|
||||
|
||||
prop = of_get_property(np, "nxp,no-comparator-bypass", NULL);
|
||||
if (!prop)
|
||||
priv->cdr |= CDR_CBP; /* default */
|
||||
|
||||
priv->irq_flags = IRQF_SHARED;
|
||||
priv->reg_base = base;
|
||||
|
||||
dev->irq = irq;
|
||||
|
||||
dev_info(&ofdev->dev,
|
||||
"reg_base=0x%p irq=%d clock=%d ocr=0x%02x cdr=0x%02x\n",
|
||||
priv->reg_base, dev->irq, priv->can.clock.freq,
|
||||
priv->ocr, priv->cdr);
|
||||
|
||||
dev_set_drvdata(&ofdev->dev, dev);
|
||||
SET_NETDEV_DEV(dev, &ofdev->dev);
|
||||
|
||||
err = register_sja1000dev(dev);
|
||||
if (err) {
|
||||
dev_err(&ofdev->dev, "registering %s failed (err=%d)\n",
|
||||
DRV_NAME, err);
|
||||
goto exit_free_sja1000;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
exit_free_sja1000:
|
||||
free_sja1000dev(dev);
|
||||
exit_dispose_irq:
|
||||
irq_dispose_mapping(irq);
|
||||
exit_unmap_mem:
|
||||
iounmap(base);
|
||||
exit_release_mem:
|
||||
release_mem_region(res.start, res_size);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct of_device_id __devinitdata sja1000_ofp_table[] = {
|
||||
{.compatible = "nxp,sja1000"},
|
||||
{},
|
||||
};
|
||||
|
||||
static struct of_platform_driver sja1000_ofp_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = DRV_NAME,
|
||||
.probe = sja1000_ofp_probe,
|
||||
.remove = __devexit_p(sja1000_ofp_remove),
|
||||
.match_table = sja1000_ofp_table,
|
||||
};
|
||||
|
||||
static int __init sja1000_ofp_init(void)
|
||||
{
|
||||
return of_register_platform_driver(&sja1000_ofp_driver);
|
||||
}
|
||||
module_init(sja1000_ofp_init);
|
||||
|
||||
static void __exit sja1000_ofp_exit(void)
|
||||
{
|
||||
return of_unregister_platform_driver(&sja1000_ofp_driver);
|
||||
};
|
||||
module_exit(sja1000_ofp_exit);
|
||||
165
drivers/net/can/sja1000/sja1000_platform.c
Normal file
165
drivers/net/can/sja1000/sja1000_platform.c
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
/*
|
||||
* Copyright (C) 2005 Sascha Hauer, Pengutronix
|
||||
* Copyright (C) 2007 Wolfgang Grandegger <wg@grandegger.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the version 2 of the GNU General Public License
|
||||
* as published by the Free Software Foundation
|
||||
*
|
||||
* 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/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/can.h>
|
||||
#include <linux/can/dev.h>
|
||||
#include <linux/can/platform/sja1000.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include "sja1000.h"
|
||||
|
||||
#define DRV_NAME "sja1000_platform"
|
||||
|
||||
MODULE_AUTHOR("Sascha Hauer <[email protected]>");
|
||||
MODULE_DESCRIPTION("Socket-CAN driver for SJA1000 on the platform bus");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
||||
static u8 sp_read_reg(const struct sja1000_priv *priv, int reg)
|
||||
{
|
||||
return ioread8(priv->reg_base + reg);
|
||||
}
|
||||
|
||||
static void sp_write_reg(const struct sja1000_priv *priv, int reg, u8 val)
|
||||
{
|
||||
iowrite8(val, priv->reg_base + reg);
|
||||
}
|
||||
|
||||
static int sp_probe(struct platform_device *pdev)
|
||||
{
|
||||
int err;
|
||||
void __iomem *addr;
|
||||
struct net_device *dev;
|
||||
struct sja1000_priv *priv;
|
||||
struct resource *res_mem, *res_irq;
|
||||
struct sja1000_platform_data *pdata;
|
||||
|
||||
pdata = pdev->dev.platform_data;
|
||||
if (!pdata) {
|
||||
dev_err(&pdev->dev, "No platform data provided!\n");
|
||||
err = -ENODEV;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
if (!res_mem || !res_irq) {
|
||||
err = -ENODEV;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!request_mem_region(res_mem->start, resource_size(res_mem),
|
||||
DRV_NAME)) {
|
||||
err = -EBUSY;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
addr = ioremap_nocache(res_mem->start, resource_size(res_mem));
|
||||
if (!addr) {
|
||||
err = -ENOMEM;
|
||||
goto exit_release;
|
||||
}
|
||||
|
||||
dev = alloc_sja1000dev(0);
|
||||
if (!dev) {
|
||||
err = -ENOMEM;
|
||||
goto exit_iounmap;
|
||||
}
|
||||
priv = netdev_priv(dev);
|
||||
|
||||
dev->irq = res_irq->start;
|
||||
priv->irq_flags = res_irq->flags & IRQF_TRIGGER_MASK;
|
||||
priv->reg_base = addr;
|
||||
priv->read_reg = sp_read_reg;
|
||||
priv->write_reg = sp_write_reg;
|
||||
priv->can.clock.freq = pdata->clock;
|
||||
priv->ocr = pdata->ocr;
|
||||
priv->cdr = pdata->cdr;
|
||||
|
||||
dev_set_drvdata(&pdev->dev, dev);
|
||||
SET_NETDEV_DEV(dev, &pdev->dev);
|
||||
|
||||
err = register_sja1000dev(dev);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "registering %s failed (err=%d)\n",
|
||||
DRV_NAME, err);
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
dev_info(&pdev->dev, "%s device registered (reg_base=%p, irq=%d)\n",
|
||||
DRV_NAME, priv->reg_base, dev->irq);
|
||||
return 0;
|
||||
|
||||
exit_free:
|
||||
free_sja1000dev(dev);
|
||||
exit_iounmap:
|
||||
iounmap(addr);
|
||||
exit_release:
|
||||
release_mem_region(res_mem->start, resource_size(res_mem));
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int sp_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct net_device *dev = dev_get_drvdata(&pdev->dev);
|
||||
struct sja1000_priv *priv = netdev_priv(dev);
|
||||
struct resource *res;
|
||||
|
||||
unregister_sja1000dev(dev);
|
||||
dev_set_drvdata(&pdev->dev, NULL);
|
||||
|
||||
if (priv->reg_base)
|
||||
iounmap(priv->reg_base);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
release_mem_region(res->start, resource_size(res));
|
||||
|
||||
free_sja1000dev(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver sp_driver = {
|
||||
.probe = sp_probe,
|
||||
.remove = sp_remove,
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init sp_init(void)
|
||||
{
|
||||
return platform_driver_register(&sp_driver);
|
||||
}
|
||||
|
||||
static void __exit sp_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&sp_driver);
|
||||
}
|
||||
|
||||
module_init(sp_init);
|
||||
module_exit(sp_exit);
|
||||
|
|
@ -2934,7 +2934,7 @@ static int cas_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
* individual queues.
|
||||
*/
|
||||
if (cas_xmit_tx_ringN(cp, ring++ & N_TX_RINGS_MASK, skb))
|
||||
return 1;
|
||||
return NETDEV_TX_BUSY;
|
||||
dev->trans_start = jiffies;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@
|
|||
#include <linux/pci.h>
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/if_vlan.h>
|
||||
#include <linux/mii.h>
|
||||
#include <linux/mdio.h>
|
||||
#include <linux/crc32.h>
|
||||
#include <linux/init.h>
|
||||
#include <asm/io.h>
|
||||
|
|
|
|||
|
|
@ -43,10 +43,11 @@
|
|||
|
||||
struct mdio_ops {
|
||||
void (*init)(adapter_t *adapter, const struct board_info *bi);
|
||||
int (*read)(adapter_t *adapter, int phy_addr, int mmd_addr,
|
||||
int reg_addr, unsigned int *val);
|
||||
int (*write)(adapter_t *adapter, int phy_addr, int mmd_addr,
|
||||
int reg_addr, unsigned int val);
|
||||
int (*read)(struct net_device *dev, int phy_addr, int mmd_addr,
|
||||
u16 reg_addr);
|
||||
int (*write)(struct net_device *dev, int phy_addr, int mmd_addr,
|
||||
u16 reg_addr, u16 val);
|
||||
unsigned mode_support;
|
||||
};
|
||||
|
||||
/* PHY interrupt types */
|
||||
|
|
@ -83,11 +84,12 @@ struct cphy_ops {
|
|||
int (*set_speed_duplex)(struct cphy *phy, int speed, int duplex);
|
||||
int (*get_link_status)(struct cphy *phy, int *link_ok, int *speed,
|
||||
int *duplex, int *fc);
|
||||
|
||||
u32 mmds;
|
||||
};
|
||||
|
||||
/* A PHY instance */
|
||||
struct cphy {
|
||||
int addr; /* PHY address */
|
||||
int state; /* Link status state machine */
|
||||
adapter_t *adapter; /* associated adapter */
|
||||
|
||||
|
|
@ -101,56 +103,61 @@ struct cphy {
|
|||
u32 elmer_gpo;
|
||||
|
||||
const struct cphy_ops *ops; /* PHY operations */
|
||||
int (*mdio_read)(adapter_t *adapter, int phy_addr, int mmd_addr,
|
||||
int reg_addr, unsigned int *val);
|
||||
int (*mdio_write)(adapter_t *adapter, int phy_addr, int mmd_addr,
|
||||
int reg_addr, unsigned int val);
|
||||
struct mdio_if_info mdio;
|
||||
struct cphy_instance *instance;
|
||||
};
|
||||
|
||||
/* Convenience MDIO read/write wrappers */
|
||||
static inline int mdio_read(struct cphy *cphy, int mmd, int reg,
|
||||
unsigned int *valp)
|
||||
static inline int cphy_mdio_read(struct cphy *cphy, int mmd, int reg,
|
||||
unsigned int *valp)
|
||||
{
|
||||
return cphy->mdio_read(cphy->adapter, cphy->addr, mmd, reg, valp);
|
||||
int rc = cphy->mdio.mdio_read(cphy->mdio.dev, cphy->mdio.prtad, mmd,
|
||||
reg);
|
||||
*valp = (rc >= 0) ? rc : -1;
|
||||
return (rc >= 0) ? 0 : rc;
|
||||
}
|
||||
|
||||
static inline int mdio_write(struct cphy *cphy, int mmd, int reg,
|
||||
unsigned int val)
|
||||
static inline int cphy_mdio_write(struct cphy *cphy, int mmd, int reg,
|
||||
unsigned int val)
|
||||
{
|
||||
return cphy->mdio_write(cphy->adapter, cphy->addr, mmd, reg, val);
|
||||
return cphy->mdio.mdio_write(cphy->mdio.dev, cphy->mdio.prtad, mmd,
|
||||
reg, val);
|
||||
}
|
||||
|
||||
static inline int simple_mdio_read(struct cphy *cphy, int reg,
|
||||
unsigned int *valp)
|
||||
{
|
||||
return mdio_read(cphy, 0, reg, valp);
|
||||
return cphy_mdio_read(cphy, MDIO_DEVAD_NONE, reg, valp);
|
||||
}
|
||||
|
||||
static inline int simple_mdio_write(struct cphy *cphy, int reg,
|
||||
unsigned int val)
|
||||
{
|
||||
return mdio_write(cphy, 0, reg, val);
|
||||
return cphy_mdio_write(cphy, MDIO_DEVAD_NONE, reg, val);
|
||||
}
|
||||
|
||||
/* Convenience initializer */
|
||||
static inline void cphy_init(struct cphy *phy, adapter_t *adapter,
|
||||
static inline void cphy_init(struct cphy *phy, struct net_device *dev,
|
||||
int phy_addr, struct cphy_ops *phy_ops,
|
||||
const struct mdio_ops *mdio_ops)
|
||||
{
|
||||
struct adapter *adapter = netdev_priv(dev);
|
||||
phy->adapter = adapter;
|
||||
phy->addr = phy_addr;
|
||||
phy->ops = phy_ops;
|
||||
if (mdio_ops) {
|
||||
phy->mdio_read = mdio_ops->read;
|
||||
phy->mdio_write = mdio_ops->write;
|
||||
phy->mdio.prtad = phy_addr;
|
||||
phy->mdio.mmds = phy_ops->mmds;
|
||||
phy->mdio.mode_support = mdio_ops->mode_support;
|
||||
phy->mdio.mdio_read = mdio_ops->read;
|
||||
phy->mdio.mdio_write = mdio_ops->write;
|
||||
}
|
||||
phy->mdio.dev = dev;
|
||||
}
|
||||
|
||||
/* Operations of the PHY-instance factory */
|
||||
struct gphy {
|
||||
/* Construct a PHY instance with the given PHY address */
|
||||
struct cphy *(*create)(adapter_t *adapter, int phy_addr,
|
||||
struct cphy *(*create)(struct net_device *dev, int phy_addr,
|
||||
const struct mdio_ops *mdio_ops);
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -589,7 +589,7 @@ static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
|
|||
}
|
||||
|
||||
cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE;
|
||||
cmd->phy_address = p->phy->addr;
|
||||
cmd->phy_address = p->phy->mdio.prtad;
|
||||
cmd->transceiver = XCVR_EXTERNAL;
|
||||
cmd->autoneg = p->link_config.autoneg;
|
||||
cmd->maxtxpkt = 0;
|
||||
|
|
@ -849,39 +849,9 @@ static const struct ethtool_ops t1_ethtool_ops = {
|
|||
static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
|
||||
{
|
||||
struct adapter *adapter = dev->ml_priv;
|
||||
struct mii_ioctl_data *data = if_mii(req);
|
||||
struct mdio_if_info *mdio = &adapter->port[dev->if_port].phy->mdio;
|
||||
|
||||
switch (cmd) {
|
||||
case SIOCGMIIPHY:
|
||||
data->phy_id = adapter->port[dev->if_port].phy->addr;
|
||||
/* FALLTHRU */
|
||||
case SIOCGMIIREG: {
|
||||
struct cphy *phy = adapter->port[dev->if_port].phy;
|
||||
u32 val;
|
||||
|
||||
if (!phy->mdio_read)
|
||||
return -EOPNOTSUPP;
|
||||
phy->mdio_read(adapter, data->phy_id, 0, data->reg_num & 0x1f,
|
||||
&val);
|
||||
data->val_out = val;
|
||||
break;
|
||||
}
|
||||
case SIOCSMIIREG: {
|
||||
struct cphy *phy = adapter->port[dev->if_port].phy;
|
||||
|
||||
if (!capable(CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
if (!phy->mdio_write)
|
||||
return -EOPNOTSUPP;
|
||||
phy->mdio_write(adapter, data->phy_id, 0, data->reg_num & 0x1f,
|
||||
data->val_in);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
return 0;
|
||||
return mdio_mii_ioctl(mdio, if_mii(req), cmd);
|
||||
}
|
||||
|
||||
static int t1_change_mtu(struct net_device *dev, int new_mtu)
|
||||
|
|
|
|||
|
|
@ -353,15 +353,16 @@ static struct cphy_ops mv88e1xxx_ops = {
|
|||
.get_link_status = mv88e1xxx_get_link_status,
|
||||
};
|
||||
|
||||
static struct cphy *mv88e1xxx_phy_create(adapter_t *adapter, int phy_addr,
|
||||
static struct cphy *mv88e1xxx_phy_create(struct net_device *dev, int phy_addr,
|
||||
const struct mdio_ops *mdio_ops)
|
||||
{
|
||||
struct adapter *adapter = netdev_priv(dev);
|
||||
struct cphy *cphy = kzalloc(sizeof(*cphy), GFP_KERNEL);
|
||||
|
||||
if (!cphy)
|
||||
return NULL;
|
||||
|
||||
cphy_init(cphy, adapter, phy_addr, &mv88e1xxx_ops, mdio_ops);
|
||||
cphy_init(cphy, dev, phy_addr, &mv88e1xxx_ops, mdio_ops);
|
||||
|
||||
/* Configure particular PHY's to run in a different mode. */
|
||||
if ((board_info(adapter)->caps & SUPPORTED_TP) &&
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ static int led_init(struct cphy *cphy)
|
|||
* Writing these bits maps control to another
|
||||
* register. mmd(0x1) addr(0x7)
|
||||
*/
|
||||
mdio_write(cphy, 0x3, 0x8304, 0xdddd);
|
||||
cphy_mdio_write(cphy, MDIO_MMD_PCS, 0x8304, 0xdddd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -62,14 +62,14 @@ static int led_link(struct cphy *cphy, u32 do_enable)
|
|||
u32 led = 0;
|
||||
#define LINK_ENABLE_BIT 0x1
|
||||
|
||||
mdio_read(cphy, 0x1, 0x7, &led);
|
||||
cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_CTRL2, &led);
|
||||
|
||||
if (do_enable & LINK_ENABLE_BIT) {
|
||||
led |= LINK_ENABLE_BIT;
|
||||
mdio_write(cphy, 0x1, 0x7, led);
|
||||
cphy_mdio_write(cphy, MDIO_MMD_PMAPMD, MDIO_CTRL2, led);
|
||||
} else {
|
||||
led &= ~LINK_ENABLE_BIT;
|
||||
mdio_write(cphy, 0x1, 0x7, led);
|
||||
cphy_mdio_write(cphy, MDIO_MMD_PMAPMD, MDIO_CTRL2, led);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -86,7 +86,8 @@ static int mv88x201x_reset(struct cphy *cphy, int wait)
|
|||
static int mv88x201x_interrupt_enable(struct cphy *cphy)
|
||||
{
|
||||
/* Enable PHY LASI interrupts. */
|
||||
mdio_write(cphy, 0x1, 0x9002, 0x1);
|
||||
cphy_mdio_write(cphy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_CTRL,
|
||||
MDIO_PMA_LASI_LSALARM);
|
||||
|
||||
/* Enable Marvell interrupts through Elmer0. */
|
||||
if (t1_is_asic(cphy->adapter)) {
|
||||
|
|
@ -102,7 +103,7 @@ static int mv88x201x_interrupt_enable(struct cphy *cphy)
|
|||
static int mv88x201x_interrupt_disable(struct cphy *cphy)
|
||||
{
|
||||
/* Disable PHY LASI interrupts. */
|
||||
mdio_write(cphy, 0x1, 0x9002, 0x0);
|
||||
cphy_mdio_write(cphy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_CTRL, 0x0);
|
||||
|
||||
/* Disable Marvell interrupts through Elmer0. */
|
||||
if (t1_is_asic(cphy->adapter)) {
|
||||
|
|
@ -122,25 +123,25 @@ static int mv88x201x_interrupt_clear(struct cphy *cphy)
|
|||
|
||||
#ifdef MV88x2010_LINK_STATUS_BUGS
|
||||
/* Required to read twice before clear takes affect. */
|
||||
mdio_read(cphy, 0x1, 0x9003, &val);
|
||||
mdio_read(cphy, 0x1, 0x9004, &val);
|
||||
mdio_read(cphy, 0x1, 0x9005, &val);
|
||||
cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_RXSTAT, &val);
|
||||
cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_TXSTAT, &val);
|
||||
cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_STAT, &val);
|
||||
|
||||
/* Read this register after the others above it else
|
||||
* the register doesn't clear correctly.
|
||||
*/
|
||||
mdio_read(cphy, 0x1, 0x1, &val);
|
||||
cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT1, &val);
|
||||
#endif
|
||||
|
||||
/* Clear link status. */
|
||||
mdio_read(cphy, 0x1, 0x1, &val);
|
||||
cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT1, &val);
|
||||
/* Clear PHY LASI interrupts. */
|
||||
mdio_read(cphy, 0x1, 0x9005, &val);
|
||||
cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_STAT, &val);
|
||||
|
||||
#ifdef MV88x2010_LINK_STATUS_BUGS
|
||||
/* Do it again. */
|
||||
mdio_read(cphy, 0x1, 0x9003, &val);
|
||||
mdio_read(cphy, 0x1, 0x9004, &val);
|
||||
cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_RXSTAT, &val);
|
||||
cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_TXSTAT, &val);
|
||||
#endif
|
||||
|
||||
/* Clear Marvell interrupts through Elmer0. */
|
||||
|
|
@ -172,13 +173,12 @@ static int mv88x201x_get_link_status(struct cphy *cphy, int *link_ok,
|
|||
int *speed, int *duplex, int *fc)
|
||||
{
|
||||
u32 val = 0;
|
||||
#define LINK_STATUS_BIT 0x4
|
||||
|
||||
if (link_ok) {
|
||||
/* Read link status. */
|
||||
mdio_read(cphy, 0x1, 0x1, &val);
|
||||
val &= LINK_STATUS_BIT;
|
||||
*link_ok = (val == LINK_STATUS_BIT);
|
||||
cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT1, &val);
|
||||
val &= MDIO_STAT1_LSTATUS;
|
||||
*link_ok = (val == MDIO_STAT1_LSTATUS);
|
||||
/* Turn on/off Link LED */
|
||||
led_link(cphy, *link_ok);
|
||||
}
|
||||
|
|
@ -205,9 +205,11 @@ static struct cphy_ops mv88x201x_ops = {
|
|||
.interrupt_handler = mv88x201x_interrupt_handler,
|
||||
.get_link_status = mv88x201x_get_link_status,
|
||||
.set_loopback = mv88x201x_set_loopback,
|
||||
.mmds = (MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS |
|
||||
MDIO_DEVS_PHYXS | MDIO_DEVS_WIS),
|
||||
};
|
||||
|
||||
static struct cphy *mv88x201x_phy_create(adapter_t *adapter, int phy_addr,
|
||||
static struct cphy *mv88x201x_phy_create(struct net_device *dev, int phy_addr,
|
||||
const struct mdio_ops *mdio_ops)
|
||||
{
|
||||
u32 val;
|
||||
|
|
@ -216,15 +218,15 @@ static struct cphy *mv88x201x_phy_create(adapter_t *adapter, int phy_addr,
|
|||
if (!cphy)
|
||||
return NULL;
|
||||
|
||||
cphy_init(cphy, adapter, phy_addr, &mv88x201x_ops, mdio_ops);
|
||||
cphy_init(cphy, dev, phy_addr, &mv88x201x_ops, mdio_ops);
|
||||
|
||||
/* Commands the PHY to enable XFP's clock. */
|
||||
mdio_read(cphy, 0x3, 0x8300, &val);
|
||||
mdio_write(cphy, 0x3, 0x8300, val | 1);
|
||||
cphy_mdio_read(cphy, MDIO_MMD_PCS, 0x8300, &val);
|
||||
cphy_mdio_write(cphy, MDIO_MMD_PCS, 0x8300, val | 1);
|
||||
|
||||
/* Clear link status. Required because of a bug in the PHY. */
|
||||
mdio_read(cphy, 0x1, 0x8, &val);
|
||||
mdio_read(cphy, 0x3, 0x8, &val);
|
||||
cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT2, &val);
|
||||
cphy_mdio_read(cphy, MDIO_MMD_PCS, MDIO_STAT2, &val);
|
||||
|
||||
/* Allows for Link,Ack LED turn on/off */
|
||||
led_init(cphy);
|
||||
|
|
|
|||
|
|
@ -43,11 +43,11 @@ static int my3126_interrupt_handler(struct cphy *cphy)
|
|||
adapter = cphy->adapter;
|
||||
|
||||
if (cphy->count == 50) {
|
||||
mdio_read(cphy, 0x1, 0x1, &val);
|
||||
cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT1, &val);
|
||||
val16 = (u16) val;
|
||||
status = cphy->bmsr ^ val16;
|
||||
|
||||
if (status & BMSR_LSTATUS)
|
||||
if (status & MDIO_STAT1_LSTATUS)
|
||||
t1_link_changed(adapter, 0);
|
||||
cphy->bmsr = val16;
|
||||
|
||||
|
|
@ -114,14 +114,14 @@ static int my3126_get_link_status(struct cphy *cphy,
|
|||
adapter_t *adapter;
|
||||
|
||||
adapter = cphy->adapter;
|
||||
mdio_read(cphy, 0x1, 0x1, &val);
|
||||
cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT1, &val);
|
||||
val16 = (u16) val;
|
||||
|
||||
/* Populate elmer_gpo with the register value */
|
||||
t1_tpi_read(adapter, A_ELMER0_GPO, &val);
|
||||
cphy->elmer_gpo = val;
|
||||
|
||||
*link_ok = (val16 & BMSR_LSTATUS);
|
||||
*link_ok = (val16 & MDIO_STAT1_LSTATUS);
|
||||
|
||||
if (*link_ok) {
|
||||
/* Turn on the LED. */
|
||||
|
|
@ -163,9 +163,11 @@ static struct cphy_ops my3126_ops = {
|
|||
.interrupt_handler = my3126_interrupt_handler,
|
||||
.get_link_status = my3126_get_link_status,
|
||||
.set_loopback = my3126_set_loopback,
|
||||
.mmds = (MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS |
|
||||
MDIO_DEVS_PHYXS),
|
||||
};
|
||||
|
||||
static struct cphy *my3126_phy_create(adapter_t *adapter,
|
||||
static struct cphy *my3126_phy_create(struct net_device *dev,
|
||||
int phy_addr, const struct mdio_ops *mdio_ops)
|
||||
{
|
||||
struct cphy *cphy = kzalloc(sizeof (*cphy), GFP_KERNEL);
|
||||
|
|
@ -173,7 +175,7 @@ static struct cphy *my3126_phy_create(adapter_t *adapter,
|
|||
if (!cphy)
|
||||
return NULL;
|
||||
|
||||
cphy_init(cphy, adapter, phy_addr, &my3126_ops, mdio_ops);
|
||||
cphy_init(cphy, dev, phy_addr, &my3126_ops, mdio_ops);
|
||||
INIT_DELAYED_WORK(&cphy->phy_update, my3216_poll);
|
||||
cphy->bmsr = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -1149,8 +1149,8 @@ static inline void write_tx_desc(struct cmdQ_e *e, dma_addr_t mapping,
|
|||
unsigned int len, unsigned int gen,
|
||||
unsigned int eop)
|
||||
{
|
||||
if (unlikely(len > SGE_TX_DESC_MAX_PLEN))
|
||||
BUG();
|
||||
BUG_ON(len > SGE_TX_DESC_MAX_PLEN);
|
||||
|
||||
e->addr_lo = (u32)mapping;
|
||||
e->addr_hi = (u64)mapping >> 32;
|
||||
e->len_gen = V_CMD_LEN(len) | V_CMD_GEN1(gen);
|
||||
|
|
@ -1879,7 +1879,6 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
cpl->vlan_valid = 0;
|
||||
|
||||
send:
|
||||
dev->trans_start = jiffies;
|
||||
ret = t1_sge_tx(skb, adapter, 0, dev);
|
||||
|
||||
/* If transmit busy, and we reallocated skb's due to headroom limit,
|
||||
|
|
|
|||
|
|
@ -284,32 +284,29 @@ static void mi1_mdio_init(adapter_t *adapter, const struct board_info *bi)
|
|||
/*
|
||||
* Elmer MI1 MDIO read/write operations.
|
||||
*/
|
||||
static int mi1_mdio_read(adapter_t *adapter, int phy_addr, int mmd_addr,
|
||||
int reg_addr, unsigned int *valp)
|
||||
static int mi1_mdio_read(struct net_device *dev, int phy_addr, int mmd_addr,
|
||||
u16 reg_addr)
|
||||
{
|
||||
struct adapter *adapter = dev->ml_priv;
|
||||
u32 addr = V_MI1_REG_ADDR(reg_addr) | V_MI1_PHY_ADDR(phy_addr);
|
||||
|
||||
if (mmd_addr)
|
||||
return -EINVAL;
|
||||
unsigned int val;
|
||||
|
||||
spin_lock(&adapter->tpi_lock);
|
||||
__t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr);
|
||||
__t1_tpi_write(adapter,
|
||||
A_ELMER0_PORT0_MI1_OP, MI1_OP_DIRECT_READ);
|
||||
mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
|
||||
__t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, valp);
|
||||
__t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, &val);
|
||||
spin_unlock(&adapter->tpi_lock);
|
||||
return 0;
|
||||
return val;
|
||||
}
|
||||
|
||||
static int mi1_mdio_write(adapter_t *adapter, int phy_addr, int mmd_addr,
|
||||
int reg_addr, unsigned int val)
|
||||
static int mi1_mdio_write(struct net_device *dev, int phy_addr, int mmd_addr,
|
||||
u16 reg_addr, u16 val)
|
||||
{
|
||||
struct adapter *adapter = dev->ml_priv;
|
||||
u32 addr = V_MI1_REG_ADDR(reg_addr) | V_MI1_PHY_ADDR(phy_addr);
|
||||
|
||||
if (mmd_addr)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock(&adapter->tpi_lock);
|
||||
__t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr);
|
||||
__t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, val);
|
||||
|
|
@ -324,16 +321,19 @@ static int mi1_mdio_write(adapter_t *adapter, int phy_addr, int mmd_addr,
|
|||
static const struct mdio_ops mi1_mdio_ops = {
|
||||
.init = mi1_mdio_init,
|
||||
.read = mi1_mdio_read,
|
||||
.write = mi1_mdio_write
|
||||
.write = mi1_mdio_write,
|
||||
.mode_support = MDIO_SUPPORTS_C22
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
static int mi1_mdio_ext_read(adapter_t *adapter, int phy_addr, int mmd_addr,
|
||||
int reg_addr, unsigned int *valp)
|
||||
static int mi1_mdio_ext_read(struct net_device *dev, int phy_addr, int mmd_addr,
|
||||
u16 reg_addr)
|
||||
{
|
||||
struct adapter *adapter = dev->ml_priv;
|
||||
u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr);
|
||||
unsigned int val;
|
||||
|
||||
spin_lock(&adapter->tpi_lock);
|
||||
|
||||
|
|
@ -350,14 +350,15 @@ static int mi1_mdio_ext_read(adapter_t *adapter, int phy_addr, int mmd_addr,
|
|||
mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
|
||||
|
||||
/* Read the data. */
|
||||
__t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, valp);
|
||||
__t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, &val);
|
||||
spin_unlock(&adapter->tpi_lock);
|
||||
return 0;
|
||||
return val;
|
||||
}
|
||||
|
||||
static int mi1_mdio_ext_write(adapter_t *adapter, int phy_addr, int mmd_addr,
|
||||
int reg_addr, unsigned int val)
|
||||
static int mi1_mdio_ext_write(struct net_device *dev, int phy_addr,
|
||||
int mmd_addr, u16 reg_addr, u16 val)
|
||||
{
|
||||
struct adapter *adapter = dev->ml_priv;
|
||||
u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr);
|
||||
|
||||
spin_lock(&adapter->tpi_lock);
|
||||
|
|
@ -380,7 +381,8 @@ static int mi1_mdio_ext_write(adapter_t *adapter, int phy_addr, int mmd_addr,
|
|||
static const struct mdio_ops mi1_mdio_ext_ops = {
|
||||
.init = mi1_mdio_init,
|
||||
.read = mi1_mdio_ext_read,
|
||||
.write = mi1_mdio_ext_write
|
||||
.write = mi1_mdio_ext_write,
|
||||
.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22
|
||||
};
|
||||
|
||||
enum {
|
||||
|
|
@ -1133,8 +1135,8 @@ int __devinit t1_init_sw_modules(adapter_t *adapter,
|
|||
struct cmac *mac;
|
||||
int phy_addr = bi->mdio_phybaseaddr + i;
|
||||
|
||||
adapter->port[i].phy = bi->gphy->create(adapter, phy_addr,
|
||||
bi->mdio_ops);
|
||||
adapter->port[i].phy = bi->gphy->create(adapter->port[i].dev,
|
||||
phy_addr, bi->mdio_ops);
|
||||
if (!adapter->port[i].phy) {
|
||||
CH_ERR("%s: PHY %d initialization failed\n",
|
||||
adapter->name, i);
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ struct cpmac_priv {
|
|||
void __iomem *regs;
|
||||
struct mii_bus *mii_bus;
|
||||
struct phy_device *phy;
|
||||
char phy_name[BUS_ID_SIZE];
|
||||
char phy_name[MII_BUS_ID_SIZE + 3];
|
||||
int oldlink, oldspeed, oldduplex;
|
||||
u32 msg_enable;
|
||||
struct net_device *dev;
|
||||
|
|
@ -615,13 +615,13 @@ static void cpmac_end_xmit(struct net_device *dev, int queue)
|
|||
|
||||
dev_kfree_skb_irq(desc->skb);
|
||||
desc->skb = NULL;
|
||||
if (netif_subqueue_stopped(dev, queue))
|
||||
if (__netif_subqueue_stopped(dev, queue))
|
||||
netif_wake_subqueue(dev, queue);
|
||||
} else {
|
||||
if (netif_msg_tx_err(priv) && net_ratelimit())
|
||||
printk(KERN_WARNING
|
||||
"%s: end_xmit: spurious interrupt\n", dev->name);
|
||||
if (netif_subqueue_stopped(dev, queue))
|
||||
if (__netif_subqueue_stopped(dev, queue))
|
||||
netif_wake_subqueue(dev, queue);
|
||||
}
|
||||
}
|
||||
|
|
@ -731,7 +731,6 @@ static void cpmac_clear_tx(struct net_device *dev)
|
|||
|
||||
static void cpmac_hw_error(struct work_struct *work)
|
||||
{
|
||||
int i;
|
||||
struct cpmac_priv *priv =
|
||||
container_of(work, struct cpmac_priv, reset_work);
|
||||
|
||||
|
|
@ -818,7 +817,6 @@ static irqreturn_t cpmac_irq(int irq, void *dev_id)
|
|||
|
||||
static void cpmac_tx_timeout(struct net_device *dev)
|
||||
{
|
||||
int i;
|
||||
struct cpmac_priv *priv = netdev_priv(dev);
|
||||
|
||||
spin_lock(&priv->lock);
|
||||
|
|
@ -1093,11 +1091,24 @@ static int cpmac_stop(struct net_device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const struct net_device_ops cpmac_netdev_ops = {
|
||||
.ndo_open = cpmac_open,
|
||||
.ndo_stop = cpmac_stop,
|
||||
.ndo_start_xmit = cpmac_start_xmit,
|
||||
.ndo_tx_timeout = cpmac_tx_timeout,
|
||||
.ndo_set_multicast_list = cpmac_set_multicast_list,
|
||||
.ndo_so_ioctl = cpmac_ioctl,
|
||||
.ndo_set_config = cpmac_config,
|
||||
.ndo_change_mtu = eth_change_mtu,
|
||||
.ndo_validate_addr = eth_validate_addr,
|
||||
.ndo_set_mac_address = eth_mac_addr,
|
||||
};
|
||||
|
||||
static int external_switch;
|
||||
|
||||
static int __devinit cpmac_probe(struct platform_device *pdev)
|
||||
{
|
||||
int rc, phy_id, i;
|
||||
int rc, phy_id;
|
||||
char *mdio_bus_id = "0";
|
||||
struct resource *mem;
|
||||
struct cpmac_priv *priv;
|
||||
|
|
@ -1143,14 +1154,8 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
|
|||
|
||||
dev->irq = platform_get_irq_byname(pdev, "irq");
|
||||
|
||||
dev->open = cpmac_open;
|
||||
dev->stop = cpmac_stop;
|
||||
dev->set_config = cpmac_config;
|
||||
dev->hard_start_xmit = cpmac_start_xmit;
|
||||
dev->do_ioctl = cpmac_ioctl;
|
||||
dev->set_multicast_list = cpmac_set_multicast_list;
|
||||
dev->tx_timeout = cpmac_tx_timeout;
|
||||
dev->ethtool_ops = &cpmac_ethtool_ops;
|
||||
dev->netdev_ops = &cpmac_netdev_ops;
|
||||
dev->ethtool_ops = &cpmac_ethtool_ops;
|
||||
|
||||
netif_napi_add(dev, &priv->napi, cpmac_poll, 64);
|
||||
|
||||
|
|
|
|||
|
|
@ -1551,7 +1551,7 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev)
|
|||
|
||||
spin_unlock_irq(&lp->lock);
|
||||
if (net_debug) printk("cs89x0: Tx buffer not free!\n");
|
||||
return 1;
|
||||
return NETDEV_TX_BUSY;
|
||||
}
|
||||
/* Write the contents of the packet */
|
||||
writewords(dev->base_addr, TX_FRAME_PORT,skb->data,(skb->len+1) >>1);
|
||||
|
|
|
|||
|
|
@ -5,4 +5,4 @@
|
|||
obj-$(CONFIG_CHELSIO_T3) += cxgb3.o
|
||||
|
||||
cxgb3-objs := cxgb3_main.o ael1002.o vsc8211.o t3_hw.o mc5.o \
|
||||
xgmac.o sge.o l2t.o cxgb3_offload.o
|
||||
xgmac.o sge.o l2t.o cxgb3_offload.o aq100x.o
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ struct sge_qset { /* an SGE queue set */
|
|||
struct sge_rspq rspq;
|
||||
struct sge_fl fl[SGE_RXQ_PER_SET];
|
||||
struct sge_txq txq[SGE_TXQ_PER_SET];
|
||||
struct napi_gro_fraginfo lro_frag_tbl;
|
||||
int nomem;
|
||||
int lro_enabled;
|
||||
void *lro_va;
|
||||
struct net_device *netdev;
|
||||
|
|
@ -253,6 +253,8 @@ struct adapter {
|
|||
struct mutex mdio_lock;
|
||||
spinlock_t stats_lock;
|
||||
spinlock_t work_lock;
|
||||
|
||||
struct sk_buff *nofail_skb;
|
||||
};
|
||||
|
||||
static inline u32 t3_read_reg(struct adapter *adapter, u32 reg_addr)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
355
drivers/net/cxgb3/aq100x.c
Normal file
355
drivers/net/cxgb3/aq100x.c
Normal file
|
|
@ -0,0 +1,355 @@
|
|||
/*
|
||||
* Copyright (c) 2005-2008 Chelsio, Inc. All rights reserved.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL) Version 2, available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "regs.h"
|
||||
|
||||
enum {
|
||||
/* MDIO_DEV_PMA_PMD registers */
|
||||
AQ_LINK_STAT = 0xe800,
|
||||
AQ_IMASK_PMA = 0xf000,
|
||||
|
||||
/* MDIO_DEV_XGXS registers */
|
||||
AQ_XAUI_RX_CFG = 0xc400,
|
||||
AQ_XAUI_TX_CFG = 0xe400,
|
||||
|
||||
/* MDIO_DEV_ANEG registers */
|
||||
AQ_1G_CTRL = 0xc400,
|
||||
AQ_ANEG_STAT = 0xc800,
|
||||
|
||||
/* MDIO_DEV_VEND1 registers */
|
||||
AQ_FW_VERSION = 0x0020,
|
||||
AQ_IFLAG_GLOBAL = 0xfc00,
|
||||
AQ_IMASK_GLOBAL = 0xff00,
|
||||
};
|
||||
|
||||
enum {
|
||||
IMASK_PMA = 1 << 2,
|
||||
IMASK_GLOBAL = 1 << 15,
|
||||
ADV_1G_FULL = 1 << 15,
|
||||
ADV_1G_HALF = 1 << 14,
|
||||
ADV_10G_FULL = 1 << 12,
|
||||
AQ_RESET = (1 << 14) | (1 << 15),
|
||||
AQ_LOWPOWER = 1 << 12,
|
||||
};
|
||||
|
||||
static int aq100x_reset(struct cphy *phy, int wait)
|
||||
{
|
||||
/*
|
||||
* Ignore the caller specified wait time; always wait for the reset to
|
||||
* complete. Can take up to 3s.
|
||||
*/
|
||||
int err = t3_phy_reset(phy, MDIO_MMD_VEND1, 3000);
|
||||
|
||||
if (err)
|
||||
CH_WARN(phy->adapter, "PHY%d: reset failed (0x%x).\n",
|
||||
phy->mdio.prtad, err);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int aq100x_intr_enable(struct cphy *phy)
|
||||
{
|
||||
int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AQ_IMASK_PMA, IMASK_PMA);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = t3_mdio_write(phy, MDIO_MMD_VEND1, AQ_IMASK_GLOBAL, IMASK_GLOBAL);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int aq100x_intr_disable(struct cphy *phy)
|
||||
{
|
||||
return t3_mdio_write(phy, MDIO_MMD_VEND1, AQ_IMASK_GLOBAL, 0);
|
||||
}
|
||||
|
||||
static int aq100x_intr_clear(struct cphy *phy)
|
||||
{
|
||||
unsigned int v;
|
||||
|
||||
t3_mdio_read(phy, MDIO_MMD_VEND1, AQ_IFLAG_GLOBAL, &v);
|
||||
t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_STAT1, &v);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aq100x_intr_handler(struct cphy *phy)
|
||||
{
|
||||
int err;
|
||||
unsigned int cause, v;
|
||||
|
||||
err = t3_mdio_read(phy, MDIO_MMD_VEND1, AQ_IFLAG_GLOBAL, &cause);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Read (and reset) the latching version of the status */
|
||||
t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_STAT1, &v);
|
||||
|
||||
return cphy_cause_link_change;
|
||||
}
|
||||
|
||||
static int aq100x_power_down(struct cphy *phy, int off)
|
||||
{
|
||||
return mdio_set_flag(&phy->mdio, phy->mdio.prtad,
|
||||
MDIO_MMD_PMAPMD, MDIO_CTRL1,
|
||||
MDIO_CTRL1_LPOWER, off);
|
||||
}
|
||||
|
||||
static int aq100x_autoneg_enable(struct cphy *phy)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = aq100x_power_down(phy, 0);
|
||||
if (!err)
|
||||
err = mdio_set_flag(&phy->mdio, phy->mdio.prtad,
|
||||
MDIO_MMD_AN, MDIO_CTRL1,
|
||||
BMCR_ANENABLE | BMCR_ANRESTART, 1);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int aq100x_autoneg_restart(struct cphy *phy)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = aq100x_power_down(phy, 0);
|
||||
if (!err)
|
||||
err = mdio_set_flag(&phy->mdio, phy->mdio.prtad,
|
||||
MDIO_MMD_AN, MDIO_CTRL1,
|
||||
BMCR_ANENABLE | BMCR_ANRESTART, 1);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int aq100x_advertise(struct cphy *phy, unsigned int advertise_map)
|
||||
{
|
||||
unsigned int adv;
|
||||
int err;
|
||||
|
||||
/* 10G advertisement */
|
||||
adv = 0;
|
||||
if (advertise_map & ADVERTISED_10000baseT_Full)
|
||||
adv |= ADV_10G_FULL;
|
||||
err = t3_mdio_change_bits(phy, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
|
||||
ADV_10G_FULL, adv);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* 1G advertisement */
|
||||
adv = 0;
|
||||
if (advertise_map & ADVERTISED_1000baseT_Full)
|
||||
adv |= ADV_1G_FULL;
|
||||
if (advertise_map & ADVERTISED_1000baseT_Half)
|
||||
adv |= ADV_1G_HALF;
|
||||
err = t3_mdio_change_bits(phy, MDIO_MMD_AN, AQ_1G_CTRL,
|
||||
ADV_1G_FULL | ADV_1G_HALF, adv);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* 100M, pause advertisement */
|
||||
adv = 0;
|
||||
if (advertise_map & ADVERTISED_100baseT_Half)
|
||||
adv |= ADVERTISE_100HALF;
|
||||
if (advertise_map & ADVERTISED_100baseT_Full)
|
||||
adv |= ADVERTISE_100FULL;
|
||||
if (advertise_map & ADVERTISED_Pause)
|
||||
adv |= ADVERTISE_PAUSE_CAP;
|
||||
if (advertise_map & ADVERTISED_Asym_Pause)
|
||||
adv |= ADVERTISE_PAUSE_ASYM;
|
||||
err = t3_mdio_change_bits(phy, MDIO_MMD_AN, MDIO_AN_ADVERTISE,
|
||||
0xfe0, adv);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int aq100x_set_loopback(struct cphy *phy, int mmd, int dir, int enable)
|
||||
{
|
||||
return mdio_set_flag(&phy->mdio, phy->mdio.prtad,
|
||||
MDIO_MMD_PMAPMD, MDIO_CTRL1,
|
||||
BMCR_LOOPBACK, enable);
|
||||
}
|
||||
|
||||
static int aq100x_set_speed_duplex(struct cphy *phy, int speed, int duplex)
|
||||
{
|
||||
/* no can do */
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int aq100x_get_link_status(struct cphy *phy, int *link_ok,
|
||||
int *speed, int *duplex, int *fc)
|
||||
{
|
||||
int err;
|
||||
unsigned int v;
|
||||
|
||||
if (link_ok) {
|
||||
err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AQ_LINK_STAT, &v);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
*link_ok = v & 1;
|
||||
if (!*link_ok)
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = t3_mdio_read(phy, MDIO_MMD_AN, AQ_ANEG_STAT, &v);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (speed) {
|
||||
switch (v & 0x6) {
|
||||
case 0x6:
|
||||
*speed = SPEED_10000;
|
||||
break;
|
||||
case 0x4:
|
||||
*speed = SPEED_1000;
|
||||
break;
|
||||
case 0x2:
|
||||
*speed = SPEED_100;
|
||||
break;
|
||||
case 0x0:
|
||||
*speed = SPEED_10;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (duplex)
|
||||
*duplex = v & 1 ? DUPLEX_FULL : DUPLEX_HALF;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cphy_ops aq100x_ops = {
|
||||
.reset = aq100x_reset,
|
||||
.intr_enable = aq100x_intr_enable,
|
||||
.intr_disable = aq100x_intr_disable,
|
||||
.intr_clear = aq100x_intr_clear,
|
||||
.intr_handler = aq100x_intr_handler,
|
||||
.autoneg_enable = aq100x_autoneg_enable,
|
||||
.autoneg_restart = aq100x_autoneg_restart,
|
||||
.advertise = aq100x_advertise,
|
||||
.set_loopback = aq100x_set_loopback,
|
||||
.set_speed_duplex = aq100x_set_speed_duplex,
|
||||
.get_link_status = aq100x_get_link_status,
|
||||
.power_down = aq100x_power_down,
|
||||
.mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS,
|
||||
};
|
||||
|
||||
int t3_aq100x_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr,
|
||||
const struct mdio_ops *mdio_ops)
|
||||
{
|
||||
unsigned int v, v2, gpio, wait;
|
||||
int err;
|
||||
|
||||
cphy_init(phy, adapter, phy_addr, &aq100x_ops, mdio_ops,
|
||||
SUPPORTED_1000baseT_Full | SUPPORTED_10000baseT_Full |
|
||||
SUPPORTED_Autoneg | SUPPORTED_AUI, "1000/10GBASE-T");
|
||||
|
||||
/*
|
||||
* The PHY has been out of reset ever since the system powered up. So
|
||||
* we do a hard reset over here.
|
||||
*/
|
||||
gpio = phy_addr ? F_GPIO10_OUT_VAL : F_GPIO6_OUT_VAL;
|
||||
t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, gpio, 0);
|
||||
msleep(1);
|
||||
t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, gpio, gpio);
|
||||
|
||||
/*
|
||||
* Give it enough time to load the firmware and get ready for mdio.
|
||||
*/
|
||||
msleep(1000);
|
||||
wait = 500; /* in 10ms increments */
|
||||
do {
|
||||
err = t3_mdio_read(phy, MDIO_MMD_VEND1, MDIO_CTRL1, &v);
|
||||
if (err || v == 0xffff) {
|
||||
|
||||
/* Allow prep_adapter to succeed when ffff is read */
|
||||
|
||||
CH_WARN(adapter, "PHY%d: reset failed (0x%x, 0x%x).\n",
|
||||
phy_addr, err, v);
|
||||
goto done;
|
||||
}
|
||||
|
||||
v &= AQ_RESET;
|
||||
if (v)
|
||||
msleep(10);
|
||||
} while (v && --wait);
|
||||
if (v) {
|
||||
CH_WARN(adapter, "PHY%d: reset timed out (0x%x).\n",
|
||||
phy_addr, v);
|
||||
|
||||
goto done; /* let prep_adapter succeed */
|
||||
}
|
||||
|
||||
/* Datasheet says 3s max but this has been observed */
|
||||
wait = (500 - wait) * 10 + 1000;
|
||||
if (wait > 3000)
|
||||
CH_WARN(adapter, "PHY%d: reset took %ums\n", phy_addr, wait);
|
||||
|
||||
/* Firmware version check. */
|
||||
t3_mdio_read(phy, MDIO_MMD_VEND1, AQ_FW_VERSION, &v);
|
||||
if (v != 30) {
|
||||
CH_WARN(adapter, "PHY%d: unsupported firmware %d\n",
|
||||
phy_addr, v);
|
||||
return 0; /* allow t3_prep_adapter to succeed */
|
||||
}
|
||||
|
||||
/*
|
||||
* The PHY should start in really-low-power mode. Prepare it for normal
|
||||
* operations.
|
||||
*/
|
||||
err = t3_mdio_read(phy, MDIO_MMD_VEND1, MDIO_CTRL1, &v);
|
||||
if (err)
|
||||
return err;
|
||||
if (v & AQ_LOWPOWER) {
|
||||
err = t3_mdio_change_bits(phy, MDIO_MMD_VEND1, MDIO_CTRL1,
|
||||
AQ_LOWPOWER, 0);
|
||||
if (err)
|
||||
return err;
|
||||
msleep(10);
|
||||
} else
|
||||
CH_WARN(adapter, "PHY%d does not start in low power mode.\n",
|
||||
phy_addr);
|
||||
|
||||
/*
|
||||
* Verify XAUI settings, but let prep succeed no matter what.
|
||||
*/
|
||||
v = v2 = 0;
|
||||
t3_mdio_read(phy, MDIO_MMD_PHYXS, AQ_XAUI_RX_CFG, &v);
|
||||
t3_mdio_read(phy, MDIO_MMD_PHYXS, AQ_XAUI_TX_CFG, &v2);
|
||||
if (v != 0x1b || v2 != 0x1b)
|
||||
CH_WARN(adapter,
|
||||
"PHY%d: incorrect XAUI settings (0x%x, 0x%x).\n",
|
||||
phy_addr, v, v2);
|
||||
|
||||
done:
|
||||
return err;
|
||||
}
|
||||
|
|
@ -39,7 +39,7 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/mii.h>
|
||||
#include <linux/mdio.h>
|
||||
#include "version.h"
|
||||
|
||||
#define CH_ERR(adap, fmt, ...) dev_err(&adap->pdev->dev, fmt, ## __VA_ARGS__)
|
||||
|
|
@ -184,10 +184,11 @@ struct cphy;
|
|||
struct adapter;
|
||||
|
||||
struct mdio_ops {
|
||||
int (*read)(struct adapter *adapter, int phy_addr, int mmd_addr,
|
||||
int reg_addr, unsigned int *val);
|
||||
int (*write)(struct adapter *adapter, int phy_addr, int mmd_addr,
|
||||
int reg_addr, unsigned int val);
|
||||
int (*read)(struct net_device *dev, int phy_addr, int mmd_addr,
|
||||
u16 reg_addr);
|
||||
int (*write)(struct net_device *dev, int phy_addr, int mmd_addr,
|
||||
u16 reg_addr, u16 val);
|
||||
unsigned mode_support;
|
||||
};
|
||||
|
||||
struct adapter_info {
|
||||
|
|
@ -520,27 +521,6 @@ enum {
|
|||
MAC_RXFIFO_SIZE = 32768
|
||||
};
|
||||
|
||||
/* IEEE 802.3 specified MDIO devices */
|
||||
enum {
|
||||
MDIO_DEV_PMA_PMD = 1,
|
||||
MDIO_DEV_WIS = 2,
|
||||
MDIO_DEV_PCS = 3,
|
||||
MDIO_DEV_XGXS = 4,
|
||||
MDIO_DEV_ANEG = 7,
|
||||
MDIO_DEV_VEND1 = 30,
|
||||
MDIO_DEV_VEND2 = 31
|
||||
};
|
||||
|
||||
/* LASI control and status registers */
|
||||
enum {
|
||||
RX_ALARM_CTRL = 0x9000,
|
||||
TX_ALARM_CTRL = 0x9001,
|
||||
LASI_CTRL = 0x9002,
|
||||
RX_ALARM_STAT = 0x9003,
|
||||
TX_ALARM_STAT = 0x9004,
|
||||
LASI_STAT = 0x9005
|
||||
};
|
||||
|
||||
/* PHY loopback direction */
|
||||
enum {
|
||||
PHY_LOOPBACK_TX = 1,
|
||||
|
|
@ -583,11 +563,12 @@ struct cphy_ops {
|
|||
int (*get_link_status)(struct cphy *phy, int *link_ok, int *speed,
|
||||
int *duplex, int *fc);
|
||||
int (*power_down)(struct cphy *phy, int enable);
|
||||
|
||||
u32 mmds;
|
||||
};
|
||||
|
||||
/* A PHY instance */
|
||||
struct cphy {
|
||||
u8 addr; /* PHY address */
|
||||
u8 modtype; /* PHY module type */
|
||||
short priv; /* scratch pad */
|
||||
unsigned int caps; /* PHY capabilities */
|
||||
|
|
@ -595,23 +576,23 @@ struct cphy {
|
|||
const char *desc; /* PHY description */
|
||||
unsigned long fifo_errors; /* FIFO over/under-flows */
|
||||
const struct cphy_ops *ops; /* PHY operations */
|
||||
int (*mdio_read)(struct adapter *adapter, int phy_addr, int mmd_addr,
|
||||
int reg_addr, unsigned int *val);
|
||||
int (*mdio_write)(struct adapter *adapter, int phy_addr, int mmd_addr,
|
||||
int reg_addr, unsigned int val);
|
||||
struct mdio_if_info mdio;
|
||||
};
|
||||
|
||||
/* Convenience MDIO read/write wrappers */
|
||||
static inline int mdio_read(struct cphy *phy, int mmd, int reg,
|
||||
unsigned int *valp)
|
||||
static inline int t3_mdio_read(struct cphy *phy, int mmd, int reg,
|
||||
unsigned int *valp)
|
||||
{
|
||||
return phy->mdio_read(phy->adapter, phy->addr, mmd, reg, valp);
|
||||
int rc = phy->mdio.mdio_read(phy->mdio.dev, phy->mdio.prtad, mmd, reg);
|
||||
*valp = (rc >= 0) ? rc : -1;
|
||||
return (rc >= 0) ? 0 : rc;
|
||||
}
|
||||
|
||||
static inline int mdio_write(struct cphy *phy, int mmd, int reg,
|
||||
unsigned int val)
|
||||
static inline int t3_mdio_write(struct cphy *phy, int mmd, int reg,
|
||||
unsigned int val)
|
||||
{
|
||||
return phy->mdio_write(phy->adapter, phy->addr, mmd, reg, val);
|
||||
return phy->mdio.mdio_write(phy->mdio.dev, phy->mdio.prtad, mmd,
|
||||
reg, val);
|
||||
}
|
||||
|
||||
/* Convenience initializer */
|
||||
|
|
@ -620,14 +601,16 @@ static inline void cphy_init(struct cphy *phy, struct adapter *adapter,
|
|||
const struct mdio_ops *mdio_ops,
|
||||
unsigned int caps, const char *desc)
|
||||
{
|
||||
phy->addr = phy_addr;
|
||||
phy->caps = caps;
|
||||
phy->adapter = adapter;
|
||||
phy->desc = desc;
|
||||
phy->ops = phy_ops;
|
||||
if (mdio_ops) {
|
||||
phy->mdio_read = mdio_ops->read;
|
||||
phy->mdio_write = mdio_ops->write;
|
||||
phy->mdio.prtad = phy_addr;
|
||||
phy->mdio.mmds = phy_ops->mmds;
|
||||
phy->mdio.mode_support = mdio_ops->mode_support;
|
||||
phy->mdio.mdio_read = mdio_ops->read;
|
||||
phy->mdio.mdio_write = mdio_ops->write;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -819,8 +802,12 @@ int t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter,
|
|||
int phy_addr, const struct mdio_ops *mdio_ops);
|
||||
int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter,
|
||||
int phy_addr, const struct mdio_ops *mdio_ops);
|
||||
int t3_ael2020_phy_prep(struct cphy *phy, struct adapter *adapter,
|
||||
int phy_addr, const struct mdio_ops *mdio_ops);
|
||||
int t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr,
|
||||
const struct mdio_ops *mdio_ops);
|
||||
int t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter,
|
||||
int phy_addr, const struct mdio_ops *mdio_ops);
|
||||
int t3_aq100x_phy_prep(struct cphy *phy, struct adapter *adapter,
|
||||
int phy_addr, const struct mdio_ops *mdio_ops);
|
||||
#endif /* __CHELSIO_COMMON_H */
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/if_vlan.h>
|
||||
#include <linux/mii.h>
|
||||
#include <linux/mdio.h>
|
||||
#include <linux/sockios.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/proc_fs.h>
|
||||
|
|
@ -91,6 +91,8 @@ static const struct pci_device_id cxgb3_pci_tbl[] = {
|
|||
CH_DEVICE(0x31, 3), /* T3B20 */
|
||||
CH_DEVICE(0x32, 1), /* T3B02 */
|
||||
CH_DEVICE(0x35, 6), /* T3C20-derived T3C10 */
|
||||
CH_DEVICE(0x36, 3), /* S320E-CR */
|
||||
CH_DEVICE(0x37, 7), /* N320E-G2 */
|
||||
{0,}
|
||||
};
|
||||
|
||||
|
|
@ -431,40 +433,78 @@ static int init_tp_parity(struct adapter *adap)
|
|||
for (i = 0; i < 16; i++) {
|
||||
struct cpl_smt_write_req *req;
|
||||
|
||||
skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL);
|
||||
skb = alloc_skb(sizeof(*req), GFP_KERNEL);
|
||||
if (!skb)
|
||||
skb = adap->nofail_skb;
|
||||
if (!skb)
|
||||
goto alloc_skb_fail;
|
||||
|
||||
req = (struct cpl_smt_write_req *)__skb_put(skb, sizeof(*req));
|
||||
memset(req, 0, sizeof(*req));
|
||||
req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
|
||||
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SMT_WRITE_REQ, i));
|
||||
req->iff = i;
|
||||
t3_mgmt_tx(adap, skb);
|
||||
if (skb == adap->nofail_skb) {
|
||||
await_mgmt_replies(adap, cnt, i + 1);
|
||||
adap->nofail_skb = alloc_skb(sizeof(*greq), GFP_KERNEL);
|
||||
if (!adap->nofail_skb)
|
||||
goto alloc_skb_fail;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 2048; i++) {
|
||||
struct cpl_l2t_write_req *req;
|
||||
|
||||
skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL);
|
||||
skb = alloc_skb(sizeof(*req), GFP_KERNEL);
|
||||
if (!skb)
|
||||
skb = adap->nofail_skb;
|
||||
if (!skb)
|
||||
goto alloc_skb_fail;
|
||||
|
||||
req = (struct cpl_l2t_write_req *)__skb_put(skb, sizeof(*req));
|
||||
memset(req, 0, sizeof(*req));
|
||||
req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
|
||||
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_L2T_WRITE_REQ, i));
|
||||
req->params = htonl(V_L2T_W_IDX(i));
|
||||
t3_mgmt_tx(adap, skb);
|
||||
if (skb == adap->nofail_skb) {
|
||||
await_mgmt_replies(adap, cnt, 16 + i + 1);
|
||||
adap->nofail_skb = alloc_skb(sizeof(*greq), GFP_KERNEL);
|
||||
if (!adap->nofail_skb)
|
||||
goto alloc_skb_fail;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 2048; i++) {
|
||||
struct cpl_rte_write_req *req;
|
||||
|
||||
skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL);
|
||||
skb = alloc_skb(sizeof(*req), GFP_KERNEL);
|
||||
if (!skb)
|
||||
skb = adap->nofail_skb;
|
||||
if (!skb)
|
||||
goto alloc_skb_fail;
|
||||
|
||||
req = (struct cpl_rte_write_req *)__skb_put(skb, sizeof(*req));
|
||||
memset(req, 0, sizeof(*req));
|
||||
req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
|
||||
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_RTE_WRITE_REQ, i));
|
||||
req->l2t_idx = htonl(V_L2T_W_IDX(i));
|
||||
t3_mgmt_tx(adap, skb);
|
||||
if (skb == adap->nofail_skb) {
|
||||
await_mgmt_replies(adap, cnt, 16 + 2048 + i + 1);
|
||||
adap->nofail_skb = alloc_skb(sizeof(*greq), GFP_KERNEL);
|
||||
if (!adap->nofail_skb)
|
||||
goto alloc_skb_fail;
|
||||
}
|
||||
}
|
||||
|
||||
skb = alloc_skb(sizeof(*greq), GFP_KERNEL | __GFP_NOFAIL);
|
||||
skb = alloc_skb(sizeof(*greq), GFP_KERNEL);
|
||||
if (!skb)
|
||||
skb = adap->nofail_skb;
|
||||
if (!skb)
|
||||
goto alloc_skb_fail;
|
||||
|
||||
greq = (struct cpl_set_tcb_field *)__skb_put(skb, sizeof(*greq));
|
||||
memset(greq, 0, sizeof(*greq));
|
||||
greq->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
|
||||
|
|
@ -473,8 +513,17 @@ static int init_tp_parity(struct adapter *adap)
|
|||
t3_mgmt_tx(adap, skb);
|
||||
|
||||
i = await_mgmt_replies(adap, cnt, 16 + 2048 + 2048 + 1);
|
||||
if (skb == adap->nofail_skb) {
|
||||
i = await_mgmt_replies(adap, cnt, 16 + 2048 + 2048 + 1);
|
||||
adap->nofail_skb = alloc_skb(sizeof(*greq), GFP_KERNEL);
|
||||
}
|
||||
|
||||
t3_tp_set_offload_mode(adap, 0);
|
||||
return i;
|
||||
|
||||
alloc_skb_fail:
|
||||
t3_tp_set_offload_mode(adap, 0);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -869,7 +918,12 @@ static int send_pktsched_cmd(struct adapter *adap, int sched, int qidx, int lo,
|
|||
struct mngt_pktsched_wr *req;
|
||||
int ret;
|
||||
|
||||
skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL);
|
||||
skb = alloc_skb(sizeof(*req), GFP_KERNEL);
|
||||
if (!skb)
|
||||
skb = adap->nofail_skb;
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
req = (struct mngt_pktsched_wr *)skb_put(skb, sizeof(*req));
|
||||
req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_MNGT));
|
||||
req->mngt_opcode = FW_MNGTOPCODE_PKTSCHED_SET;
|
||||
|
|
@ -879,6 +933,12 @@ static int send_pktsched_cmd(struct adapter *adap, int sched, int qidx, int lo,
|
|||
req->max = hi;
|
||||
req->binding = port;
|
||||
ret = t3_mgmt_tx(adap, skb);
|
||||
if (skb == adap->nofail_skb) {
|
||||
adap->nofail_skb = alloc_skb(sizeof(struct cpl_set_tcb_field),
|
||||
GFP_KERNEL);
|
||||
if (!adap->nofail_skb)
|
||||
ret = -ENOMEM;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1593,7 +1653,7 @@ static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
|
|||
}
|
||||
|
||||
cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE;
|
||||
cmd->phy_address = p->phy.addr;
|
||||
cmd->phy_address = p->phy.mdio.prtad;
|
||||
cmd->transceiver = XCVR_EXTERNAL;
|
||||
cmd->autoneg = p->link_config.autoneg;
|
||||
cmd->maxtxpkt = 0;
|
||||
|
|
@ -2308,70 +2368,25 @@ static int cxgb_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
|
|||
struct mii_ioctl_data *data = if_mii(req);
|
||||
struct port_info *pi = netdev_priv(dev);
|
||||
struct adapter *adapter = pi->adapter;
|
||||
int ret, mmd;
|
||||
|
||||
switch (cmd) {
|
||||
case SIOCGMIIPHY:
|
||||
data->phy_id = pi->phy.addr;
|
||||
case SIOCGMIIREG:
|
||||
case SIOCSMIIREG:
|
||||
/* Convert phy_id from older PRTAD/DEVAD format */
|
||||
if (is_10G(adapter) &&
|
||||
!mdio_phy_id_is_c45(data->phy_id) &&
|
||||
(data->phy_id & 0x1f00) &&
|
||||
!(data->phy_id & 0xe0e0))
|
||||
data->phy_id = mdio_phy_id_c45(data->phy_id >> 8,
|
||||
data->phy_id & 0x1f);
|
||||
/* FALLTHRU */
|
||||
case SIOCGMIIREG:{
|
||||
u32 val;
|
||||
struct cphy *phy = &pi->phy;
|
||||
|
||||
if (!phy->mdio_read)
|
||||
return -EOPNOTSUPP;
|
||||
if (is_10G(adapter)) {
|
||||
mmd = data->phy_id >> 8;
|
||||
if (!mmd)
|
||||
mmd = MDIO_DEV_PCS;
|
||||
else if (mmd > MDIO_DEV_VEND2)
|
||||
return -EINVAL;
|
||||
|
||||
ret =
|
||||
phy->mdio_read(adapter, data->phy_id & 0x1f,
|
||||
mmd, data->reg_num, &val);
|
||||
} else
|
||||
ret =
|
||||
phy->mdio_read(adapter, data->phy_id & 0x1f,
|
||||
0, data->reg_num & 0x1f,
|
||||
&val);
|
||||
if (!ret)
|
||||
data->val_out = val;
|
||||
break;
|
||||
}
|
||||
case SIOCSMIIREG:{
|
||||
struct cphy *phy = &pi->phy;
|
||||
|
||||
if (!capable(CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
if (!phy->mdio_write)
|
||||
return -EOPNOTSUPP;
|
||||
if (is_10G(adapter)) {
|
||||
mmd = data->phy_id >> 8;
|
||||
if (!mmd)
|
||||
mmd = MDIO_DEV_PCS;
|
||||
else if (mmd > MDIO_DEV_VEND2)
|
||||
return -EINVAL;
|
||||
|
||||
ret =
|
||||
phy->mdio_write(adapter,
|
||||
data->phy_id & 0x1f, mmd,
|
||||
data->reg_num,
|
||||
data->val_in);
|
||||
} else
|
||||
ret =
|
||||
phy->mdio_write(adapter,
|
||||
data->phy_id & 0x1f, 0,
|
||||
data->reg_num & 0x1f,
|
||||
data->val_in);
|
||||
break;
|
||||
}
|
||||
case SIOCGMIIPHY:
|
||||
return mdio_mii_ioctl(&pi->phy.mdio, data, cmd);
|
||||
case SIOCCHIOCTL:
|
||||
return cxgb_extension_ioctl(dev, req->ifr_data);
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cxgb_change_mtu(struct net_device *dev, int new_mtu)
|
||||
|
|
@ -3063,6 +3078,14 @@ static int __devinit init_one(struct pci_dev *pdev,
|
|||
goto out_disable_device;
|
||||
}
|
||||
|
||||
adapter->nofail_skb =
|
||||
alloc_skb(sizeof(struct cpl_set_tcb_field), GFP_KERNEL);
|
||||
if (!adapter->nofail_skb) {
|
||||
dev_err(&pdev->dev, "cannot allocate nofail buffer\n");
|
||||
err = -ENOMEM;
|
||||
goto out_free_adapter;
|
||||
}
|
||||
|
||||
adapter->regs = ioremap_nocache(mmio_start, mmio_len);
|
||||
if (!adapter->regs) {
|
||||
dev_err(&pdev->dev, "cannot map device registers\n");
|
||||
|
|
@ -3106,7 +3129,6 @@ static int __devinit init_one(struct pci_dev *pdev,
|
|||
netdev->mem_start = mmio_start;
|
||||
netdev->mem_end = mmio_start + mmio_len - 1;
|
||||
netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO;
|
||||
netdev->features |= NETIF_F_LLTX;
|
||||
netdev->features |= NETIF_F_GRO;
|
||||
if (pci_using_dac)
|
||||
netdev->features |= NETIF_F_HIGHDMA;
|
||||
|
|
@ -3220,6 +3242,8 @@ static void __devexit remove_one(struct pci_dev *pdev)
|
|||
free_netdev(adapter->port[i]);
|
||||
|
||||
iounmap(adapter->regs);
|
||||
if (adapter->nofail_skb)
|
||||
kfree_skb(adapter->nofail_skb);
|
||||
kfree(adapter);
|
||||
pci_release_regions(pdev);
|
||||
pci_disable_device(pdev);
|
||||
|
|
|
|||
|
|
@ -566,13 +566,31 @@ static void t3_process_tid_release_list(struct work_struct *work)
|
|||
spin_unlock_bh(&td->tid_release_lock);
|
||||
|
||||
skb = alloc_skb(sizeof(struct cpl_tid_release),
|
||||
GFP_KERNEL | __GFP_NOFAIL);
|
||||
GFP_KERNEL);
|
||||
if (!skb)
|
||||
skb = td->nofail_skb;
|
||||
if (!skb) {
|
||||
spin_lock_bh(&td->tid_release_lock);
|
||||
p->ctx = (void *)td->tid_release_list;
|
||||
td->tid_release_list = (struct t3c_tid_entry *)p;
|
||||
break;
|
||||
}
|
||||
mk_tid_release(skb, p - td->tid_maps.tid_tab);
|
||||
cxgb3_ofld_send(tdev, skb);
|
||||
p->ctx = NULL;
|
||||
if (skb == td->nofail_skb)
|
||||
td->nofail_skb =
|
||||
alloc_skb(sizeof(struct cpl_tid_release),
|
||||
GFP_KERNEL);
|
||||
spin_lock_bh(&td->tid_release_lock);
|
||||
}
|
||||
td->release_list_incomplete = (td->tid_release_list == NULL) ? 0 : 1;
|
||||
spin_unlock_bh(&td->tid_release_lock);
|
||||
|
||||
if (!td->nofail_skb)
|
||||
td->nofail_skb =
|
||||
alloc_skb(sizeof(struct cpl_tid_release),
|
||||
GFP_KERNEL);
|
||||
}
|
||||
|
||||
/* use ctx as a next pointer in the tid release list */
|
||||
|
|
@ -585,7 +603,7 @@ void cxgb3_queue_tid_release(struct t3cdev *tdev, unsigned int tid)
|
|||
p->ctx = (void *)td->tid_release_list;
|
||||
p->client = NULL;
|
||||
td->tid_release_list = p;
|
||||
if (!p->ctx)
|
||||
if (!p->ctx || td->release_list_incomplete)
|
||||
schedule_work(&td->tid_release_task);
|
||||
spin_unlock_bh(&td->tid_release_lock);
|
||||
}
|
||||
|
|
@ -1274,6 +1292,9 @@ int cxgb3_offload_activate(struct adapter *adapter)
|
|||
if (list_empty(&adapter_list))
|
||||
register_netevent_notifier(&nb);
|
||||
|
||||
t->nofail_skb = alloc_skb(sizeof(struct cpl_tid_release), GFP_KERNEL);
|
||||
t->release_list_incomplete = 0;
|
||||
|
||||
add_adapter(adapter);
|
||||
return 0;
|
||||
|
||||
|
|
@ -1298,6 +1319,8 @@ void cxgb3_offload_deactivate(struct adapter *adapter)
|
|||
T3C_DATA(tdev) = NULL;
|
||||
t3_free_l2t(L2DATA(tdev));
|
||||
L2DATA(tdev) = NULL;
|
||||
if (t->nofail_skb)
|
||||
kfree_skb(t->nofail_skb);
|
||||
kfree(t);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -191,6 +191,9 @@ struct t3c_data {
|
|||
struct t3c_tid_entry *tid_release_list;
|
||||
spinlock_t tid_release_lock;
|
||||
struct work_struct tid_release_task;
|
||||
|
||||
struct sk_buff *nofail_skb;
|
||||
unsigned int release_list_incomplete;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -653,7 +653,8 @@ static void t3_reset_qset(struct sge_qset *q)
|
|||
q->txq_stopped = 0;
|
||||
q->tx_reclaim_timer.function = NULL; /* for t3_stop_sge_timers() */
|
||||
q->rx_reclaim_timer.function = NULL;
|
||||
q->lro_frag_tbl.nr_frags = q->lro_frag_tbl.len = 0;
|
||||
q->nomem = 0;
|
||||
napi_free_frags(&q->napi);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1239,7 +1240,6 @@ int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
q = &qs->txq[TXQ_ETH];
|
||||
txq = netdev_get_tx_queue(dev, qidx);
|
||||
|
||||
spin_lock(&q->lock);
|
||||
reclaim_completed_tx(adap, q, TX_RECLAIM_CHUNK);
|
||||
|
||||
credits = q->size - q->in_use;
|
||||
|
|
@ -1250,7 +1250,6 @@ int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
dev_err(&adap->pdev->dev,
|
||||
"%s: Tx ring %u full while queue awake!\n",
|
||||
dev->name, q->cntxt_id & 7);
|
||||
spin_unlock(&q->lock);
|
||||
return NETDEV_TX_BUSY;
|
||||
}
|
||||
|
||||
|
|
@ -1284,9 +1283,6 @@ int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
if (vlan_tx_tag_present(skb) && pi->vlan_grp)
|
||||
qs->port_stats[SGE_PSTAT_VLANINS]++;
|
||||
|
||||
dev->trans_start = jiffies;
|
||||
spin_unlock(&q->lock);
|
||||
|
||||
/*
|
||||
* We do not use Tx completion interrupts to free DMAd Tx packets.
|
||||
* This is good for performamce but means that we rely on new Tx
|
||||
|
|
@ -2073,20 +2069,19 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
|
|||
struct sge_fl *fl, int len, int complete)
|
||||
{
|
||||
struct rx_sw_desc *sd = &fl->sdesc[fl->cidx];
|
||||
struct sk_buff *skb = NULL;
|
||||
struct cpl_rx_pkt *cpl;
|
||||
struct skb_frag_struct *rx_frag = qs->lro_frag_tbl.frags;
|
||||
int nr_frags = qs->lro_frag_tbl.nr_frags;
|
||||
int frag_len = qs->lro_frag_tbl.len;
|
||||
struct skb_frag_struct *rx_frag;
|
||||
int nr_frags;
|
||||
int offset = 0;
|
||||
|
||||
if (!nr_frags) {
|
||||
offset = 2 + sizeof(struct cpl_rx_pkt);
|
||||
qs->lro_va = cpl = sd->pg_chunk.va + 2;
|
||||
if (!qs->nomem) {
|
||||
skb = napi_get_frags(&qs->napi);
|
||||
qs->nomem = !skb;
|
||||
}
|
||||
|
||||
fl->credits--;
|
||||
|
||||
len -= offset;
|
||||
pci_dma_sync_single_for_cpu(adap->pdev,
|
||||
pci_unmap_addr(sd, dma_addr),
|
||||
fl->buf_size - SGE_PG_RSVD,
|
||||
|
|
@ -2099,21 +2094,38 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
|
|||
fl->alloc_size,
|
||||
PCI_DMA_FROMDEVICE);
|
||||
|
||||
if (!skb) {
|
||||
put_page(sd->pg_chunk.page);
|
||||
if (complete)
|
||||
qs->nomem = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
rx_frag = skb_shinfo(skb)->frags;
|
||||
nr_frags = skb_shinfo(skb)->nr_frags;
|
||||
|
||||
if (!nr_frags) {
|
||||
offset = 2 + sizeof(struct cpl_rx_pkt);
|
||||
qs->lro_va = sd->pg_chunk.va + 2;
|
||||
}
|
||||
len -= offset;
|
||||
|
||||
prefetch(qs->lro_va);
|
||||
|
||||
rx_frag += nr_frags;
|
||||
rx_frag->page = sd->pg_chunk.page;
|
||||
rx_frag->page_offset = sd->pg_chunk.offset + offset;
|
||||
rx_frag->size = len;
|
||||
frag_len += len;
|
||||
qs->lro_frag_tbl.nr_frags++;
|
||||
qs->lro_frag_tbl.len = frag_len;
|
||||
|
||||
skb->len += len;
|
||||
skb->data_len += len;
|
||||
skb->truesize += len;
|
||||
skb_shinfo(skb)->nr_frags++;
|
||||
|
||||
if (!complete)
|
||||
return;
|
||||
|
||||
qs->lro_frag_tbl.ip_summed = CHECKSUM_UNNECESSARY;
|
||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
cpl = qs->lro_va;
|
||||
|
||||
if (unlikely(cpl->vlan_valid)) {
|
||||
|
|
@ -2122,15 +2134,11 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
|
|||
struct vlan_group *grp = pi->vlan_grp;
|
||||
|
||||
if (likely(grp != NULL)) {
|
||||
vlan_gro_frags(&qs->napi, grp, ntohs(cpl->vlan),
|
||||
&qs->lro_frag_tbl);
|
||||
goto out;
|
||||
vlan_gro_frags(&qs->napi, grp, ntohs(cpl->vlan));
|
||||
return;
|
||||
}
|
||||
}
|
||||
napi_gro_frags(&qs->napi, &qs->lro_frag_tbl);
|
||||
|
||||
out:
|
||||
qs->lro_frag_tbl.nr_frags = qs->lro_frag_tbl.len = 0;
|
||||
napi_gro_frags(&qs->napi);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2299,8 +2307,6 @@ no_mem:
|
|||
if (fl->use_pages) {
|
||||
void *addr = fl->sdesc[fl->cidx].pg_chunk.va;
|
||||
|
||||
prefetch(&qs->lro_frag_tbl);
|
||||
|
||||
prefetch(addr);
|
||||
#if L1_CACHE_BYTES < 128
|
||||
prefetch(addr + L1_CACHE_BYTES);
|
||||
|
|
@ -2846,11 +2852,12 @@ static void sge_timer_tx(unsigned long data)
|
|||
unsigned int tbd[SGE_TXQ_PER_SET] = {0, 0};
|
||||
unsigned long next_period;
|
||||
|
||||
if (spin_trylock(&qs->txq[TXQ_ETH].lock)) {
|
||||
tbd[TXQ_ETH] = reclaim_completed_tx(adap, &qs->txq[TXQ_ETH],
|
||||
TX_RECLAIM_TIMER_CHUNK);
|
||||
spin_unlock(&qs->txq[TXQ_ETH].lock);
|
||||
if (__netif_tx_trylock(qs->tx_q)) {
|
||||
tbd[TXQ_ETH] = reclaim_completed_tx(adap, &qs->txq[TXQ_ETH],
|
||||
TX_RECLAIM_TIMER_CHUNK);
|
||||
__netif_tx_unlock(qs->tx_q);
|
||||
}
|
||||
|
||||
if (spin_trylock(&qs->txq[TXQ_OFLD].lock)) {
|
||||
tbd[TXQ_OFLD] = reclaim_completed_tx(adap, &qs->txq[TXQ_OFLD],
|
||||
TX_RECLAIM_TIMER_CHUNK);
|
||||
|
|
@ -2858,8 +2865,8 @@ static void sge_timer_tx(unsigned long data)
|
|||
}
|
||||
|
||||
next_period = TX_RECLAIM_PERIOD >>
|
||||
(max(tbd[TXQ_ETH], tbd[TXQ_OFLD]) /
|
||||
TX_RECLAIM_TIMER_CHUNK);
|
||||
(max(tbd[TXQ_ETH], tbd[TXQ_OFLD]) /
|
||||
TX_RECLAIM_TIMER_CHUNK);
|
||||
mod_timer(&qs->tx_reclaim_timer, jiffies + next_period);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -204,35 +204,33 @@ static void mi1_init(struct adapter *adap, const struct adapter_info *ai)
|
|||
/*
|
||||
* MI1 read/write operations for clause 22 PHYs.
|
||||
*/
|
||||
static int t3_mi1_read(struct adapter *adapter, int phy_addr, int mmd_addr,
|
||||
int reg_addr, unsigned int *valp)
|
||||
static int t3_mi1_read(struct net_device *dev, int phy_addr, int mmd_addr,
|
||||
u16 reg_addr)
|
||||
{
|
||||
struct port_info *pi = netdev_priv(dev);
|
||||
struct adapter *adapter = pi->adapter;
|
||||
int ret;
|
||||
u32 addr = V_REGADDR(reg_addr) | V_PHYADDR(phy_addr);
|
||||
|
||||
if (mmd_addr)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&adapter->mdio_lock);
|
||||
t3_set_reg_field(adapter, A_MI1_CFG, V_ST(M_ST), V_ST(1));
|
||||
t3_write_reg(adapter, A_MI1_ADDR, addr);
|
||||
t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(2));
|
||||
ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 10);
|
||||
if (!ret)
|
||||
*valp = t3_read_reg(adapter, A_MI1_DATA);
|
||||
ret = t3_read_reg(adapter, A_MI1_DATA);
|
||||
mutex_unlock(&adapter->mdio_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int t3_mi1_write(struct adapter *adapter, int phy_addr, int mmd_addr,
|
||||
int reg_addr, unsigned int val)
|
||||
static int t3_mi1_write(struct net_device *dev, int phy_addr, int mmd_addr,
|
||||
u16 reg_addr, u16 val)
|
||||
{
|
||||
struct port_info *pi = netdev_priv(dev);
|
||||
struct adapter *adapter = pi->adapter;
|
||||
int ret;
|
||||
u32 addr = V_REGADDR(reg_addr) | V_PHYADDR(phy_addr);
|
||||
|
||||
if (mmd_addr)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&adapter->mdio_lock);
|
||||
t3_set_reg_field(adapter, A_MI1_CFG, V_ST(M_ST), V_ST(1));
|
||||
t3_write_reg(adapter, A_MI1_ADDR, addr);
|
||||
|
|
@ -244,8 +242,9 @@ static int t3_mi1_write(struct adapter *adapter, int phy_addr, int mmd_addr,
|
|||
}
|
||||
|
||||
static const struct mdio_ops mi1_mdio_ops = {
|
||||
t3_mi1_read,
|
||||
t3_mi1_write
|
||||
.read = t3_mi1_read,
|
||||
.write = t3_mi1_write,
|
||||
.mode_support = MDIO_SUPPORTS_C22
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -268,9 +267,11 @@ static int mi1_wr_addr(struct adapter *adapter, int phy_addr, int mmd_addr,
|
|||
/*
|
||||
* MI1 read/write operations for indirect-addressed PHYs.
|
||||
*/
|
||||
static int mi1_ext_read(struct adapter *adapter, int phy_addr, int mmd_addr,
|
||||
int reg_addr, unsigned int *valp)
|
||||
static int mi1_ext_read(struct net_device *dev, int phy_addr, int mmd_addr,
|
||||
u16 reg_addr)
|
||||
{
|
||||
struct port_info *pi = netdev_priv(dev);
|
||||
struct adapter *adapter = pi->adapter;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&adapter->mdio_lock);
|
||||
|
|
@ -280,15 +281,17 @@ static int mi1_ext_read(struct adapter *adapter, int phy_addr, int mmd_addr,
|
|||
ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0,
|
||||
MDIO_ATTEMPTS, 10);
|
||||
if (!ret)
|
||||
*valp = t3_read_reg(adapter, A_MI1_DATA);
|
||||
ret = t3_read_reg(adapter, A_MI1_DATA);
|
||||
}
|
||||
mutex_unlock(&adapter->mdio_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mi1_ext_write(struct adapter *adapter, int phy_addr, int mmd_addr,
|
||||
int reg_addr, unsigned int val)
|
||||
static int mi1_ext_write(struct net_device *dev, int phy_addr, int mmd_addr,
|
||||
u16 reg_addr, u16 val)
|
||||
{
|
||||
struct port_info *pi = netdev_priv(dev);
|
||||
struct adapter *adapter = pi->adapter;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&adapter->mdio_lock);
|
||||
|
|
@ -304,8 +307,9 @@ static int mi1_ext_write(struct adapter *adapter, int phy_addr, int mmd_addr,
|
|||
}
|
||||
|
||||
static const struct mdio_ops mi1_mdio_ext_ops = {
|
||||
mi1_ext_read,
|
||||
mi1_ext_write
|
||||
.read = mi1_ext_read,
|
||||
.write = mi1_ext_write,
|
||||
.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -325,10 +329,10 @@ int t3_mdio_change_bits(struct cphy *phy, int mmd, int reg, unsigned int clear,
|
|||
int ret;
|
||||
unsigned int val;
|
||||
|
||||
ret = mdio_read(phy, mmd, reg, &val);
|
||||
ret = t3_mdio_read(phy, mmd, reg, &val);
|
||||
if (!ret) {
|
||||
val &= ~clear;
|
||||
ret = mdio_write(phy, mmd, reg, val | set);
|
||||
ret = t3_mdio_write(phy, mmd, reg, val | set);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -348,15 +352,16 @@ int t3_phy_reset(struct cphy *phy, int mmd, int wait)
|
|||
int err;
|
||||
unsigned int ctl;
|
||||
|
||||
err = t3_mdio_change_bits(phy, mmd, MII_BMCR, BMCR_PDOWN, BMCR_RESET);
|
||||
err = t3_mdio_change_bits(phy, mmd, MDIO_CTRL1, MDIO_CTRL1_LPOWER,
|
||||
MDIO_CTRL1_RESET);
|
||||
if (err || !wait)
|
||||
return err;
|
||||
|
||||
do {
|
||||
err = mdio_read(phy, mmd, MII_BMCR, &ctl);
|
||||
err = t3_mdio_read(phy, mmd, MDIO_CTRL1, &ctl);
|
||||
if (err)
|
||||
return err;
|
||||
ctl &= BMCR_RESET;
|
||||
ctl &= MDIO_CTRL1_RESET;
|
||||
if (ctl)
|
||||
msleep(1);
|
||||
} while (ctl && --wait);
|
||||
|
|
@ -377,7 +382,7 @@ int t3_phy_advertise(struct cphy *phy, unsigned int advert)
|
|||
int err;
|
||||
unsigned int val = 0;
|
||||
|
||||
err = mdio_read(phy, 0, MII_CTRL1000, &val);
|
||||
err = t3_mdio_read(phy, MDIO_DEVAD_NONE, MII_CTRL1000, &val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
@ -387,7 +392,7 @@ int t3_phy_advertise(struct cphy *phy, unsigned int advert)
|
|||
if (advert & ADVERTISED_1000baseT_Full)
|
||||
val |= ADVERTISE_1000FULL;
|
||||
|
||||
err = mdio_write(phy, 0, MII_CTRL1000, val);
|
||||
err = t3_mdio_write(phy, MDIO_DEVAD_NONE, MII_CTRL1000, val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
@ -404,7 +409,7 @@ int t3_phy_advertise(struct cphy *phy, unsigned int advert)
|
|||
val |= ADVERTISE_PAUSE_CAP;
|
||||
if (advert & ADVERTISED_Asym_Pause)
|
||||
val |= ADVERTISE_PAUSE_ASYM;
|
||||
return mdio_write(phy, 0, MII_ADVERTISE, val);
|
||||
return t3_mdio_write(phy, MDIO_DEVAD_NONE, MII_ADVERTISE, val);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -427,7 +432,7 @@ int t3_phy_advertise_fiber(struct cphy *phy, unsigned int advert)
|
|||
val |= ADVERTISE_1000XPAUSE;
|
||||
if (advert & ADVERTISED_Asym_Pause)
|
||||
val |= ADVERTISE_1000XPSE_ASYM;
|
||||
return mdio_write(phy, 0, MII_ADVERTISE, val);
|
||||
return t3_mdio_write(phy, MDIO_DEVAD_NONE, MII_ADVERTISE, val);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -444,7 +449,7 @@ int t3_set_phy_speed_duplex(struct cphy *phy, int speed, int duplex)
|
|||
int err;
|
||||
unsigned int ctl;
|
||||
|
||||
err = mdio_read(phy, 0, MII_BMCR, &ctl);
|
||||
err = t3_mdio_read(phy, MDIO_DEVAD_NONE, MII_BMCR, &ctl);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
@ -462,34 +467,36 @@ int t3_set_phy_speed_duplex(struct cphy *phy, int speed, int duplex)
|
|||
}
|
||||
if (ctl & BMCR_SPEED1000) /* auto-negotiation required for GigE */
|
||||
ctl |= BMCR_ANENABLE;
|
||||
return mdio_write(phy, 0, MII_BMCR, ctl);
|
||||
return t3_mdio_write(phy, MDIO_DEVAD_NONE, MII_BMCR, ctl);
|
||||
}
|
||||
|
||||
int t3_phy_lasi_intr_enable(struct cphy *phy)
|
||||
{
|
||||
return mdio_write(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, 1);
|
||||
return t3_mdio_write(phy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_CTRL,
|
||||
MDIO_PMA_LASI_LSALARM);
|
||||
}
|
||||
|
||||
int t3_phy_lasi_intr_disable(struct cphy *phy)
|
||||
{
|
||||
return mdio_write(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, 0);
|
||||
return t3_mdio_write(phy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_CTRL, 0);
|
||||
}
|
||||
|
||||
int t3_phy_lasi_intr_clear(struct cphy *phy)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
return mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_STAT, &val);
|
||||
return t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_STAT, &val);
|
||||
}
|
||||
|
||||
int t3_phy_lasi_intr_handler(struct cphy *phy)
|
||||
{
|
||||
unsigned int status;
|
||||
int err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_STAT, &status);
|
||||
int err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_STAT,
|
||||
&status);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
return (status & 1) ? cphy_cause_link_change : 0;
|
||||
return (status & MDIO_PMA_LASI_LSALARM) ? cphy_cause_link_change : 0;
|
||||
}
|
||||
|
||||
static const struct adapter_info t3_adap_info[] = {
|
||||
|
|
@ -519,6 +526,11 @@ static const struct adapter_info t3_adap_info[] = {
|
|||
F_GPIO10_OEN | F_GPIO1_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL,
|
||||
{ S_GPIO9 }, SUPPORTED_10000baseT_Full | SUPPORTED_AUI,
|
||||
&mi1_mdio_ext_ops, "Chelsio T310" },
|
||||
{1, 0, 0,
|
||||
F_GPIO1_OEN | F_GPIO6_OEN | F_GPIO7_OEN |
|
||||
F_GPIO1_OUT_VAL | F_GPIO6_OUT_VAL,
|
||||
{ S_GPIO9 }, SUPPORTED_10000baseT_Full | SUPPORTED_AUI,
|
||||
&mi1_mdio_ext_ops, "Chelsio N320E-G2" },
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -545,6 +557,8 @@ static const struct port_type_info port_types[] = {
|
|||
{ t3_qt2045_phy_prep },
|
||||
{ t3_ael1006_phy_prep },
|
||||
{ NULL },
|
||||
{ t3_aq100x_phy_prep },
|
||||
{ t3_ael2020_phy_prep },
|
||||
};
|
||||
|
||||
#define VPD_ENTRY(name, len) \
|
||||
|
|
@ -3864,6 +3878,7 @@ int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
p->phy.mdio.dev = adapter->port[i];
|
||||
ret = pti->phy_prep(&p->phy, adapter, ai->phy_base_addr + j,
|
||||
ai->mdio_ops);
|
||||
if (ret)
|
||||
|
|
@ -3923,7 +3938,7 @@ int t3_replay_prep_adapter(struct adapter *adapter)
|
|||
;
|
||||
|
||||
pti = &port_types[adapter->params.vpd.port_type[j]];
|
||||
ret = pti->phy_prep(&p->phy, adapter, p->phy.addr, NULL);
|
||||
ret = pti->phy_prep(&p->phy, adapter, p->phy.mdio.prtad, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
p->phy.ops->power_down(&p->phy, 1);
|
||||
|
|
|
|||
|
|
@ -35,10 +35,10 @@
|
|||
#define DRV_DESC "Chelsio T3 Network Driver"
|
||||
#define DRV_NAME "cxgb3"
|
||||
/* Driver version */
|
||||
#define DRV_VERSION "1.1.2-ko"
|
||||
#define DRV_VERSION "1.1.3-ko"
|
||||
|
||||
/* Firmware version */
|
||||
#define FW_VERSION_MAJOR 7
|
||||
#define FW_VERSION_MINOR 1
|
||||
#define FW_VERSION_MINOR 4
|
||||
#define FW_VERSION_MICRO 0
|
||||
#endif /* __CHELSIO_VERSION_H */
|
||||
|
|
|
|||
|
|
@ -91,17 +91,18 @@ enum {
|
|||
*/
|
||||
static int vsc8211_reset(struct cphy *cphy, int wait)
|
||||
{
|
||||
return t3_phy_reset(cphy, 0, 0);
|
||||
return t3_phy_reset(cphy, MDIO_DEVAD_NONE, 0);
|
||||
}
|
||||
|
||||
static int vsc8211_intr_enable(struct cphy *cphy)
|
||||
{
|
||||
return mdio_write(cphy, 0, VSC8211_INTR_ENABLE, INTR_MASK);
|
||||
return t3_mdio_write(cphy, MDIO_DEVAD_NONE, VSC8211_INTR_ENABLE,
|
||||
INTR_MASK);
|
||||
}
|
||||
|
||||
static int vsc8211_intr_disable(struct cphy *cphy)
|
||||
{
|
||||
return mdio_write(cphy, 0, VSC8211_INTR_ENABLE, 0);
|
||||
return t3_mdio_write(cphy, MDIO_DEVAD_NONE, VSC8211_INTR_ENABLE, 0);
|
||||
}
|
||||
|
||||
static int vsc8211_intr_clear(struct cphy *cphy)
|
||||
|
|
@ -109,18 +110,20 @@ static int vsc8211_intr_clear(struct cphy *cphy)
|
|||
u32 val;
|
||||
|
||||
/* Clear PHY interrupts by reading the register. */
|
||||
return mdio_read(cphy, 0, VSC8211_INTR_STATUS, &val);
|
||||
return t3_mdio_read(cphy, MDIO_DEVAD_NONE, VSC8211_INTR_STATUS, &val);
|
||||
}
|
||||
|
||||
static int vsc8211_autoneg_enable(struct cphy *cphy)
|
||||
{
|
||||
return t3_mdio_change_bits(cphy, 0, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE,
|
||||
return t3_mdio_change_bits(cphy, MDIO_DEVAD_NONE, MII_BMCR,
|
||||
BMCR_PDOWN | BMCR_ISOLATE,
|
||||
BMCR_ANENABLE | BMCR_ANRESTART);
|
||||
}
|
||||
|
||||
static int vsc8211_autoneg_restart(struct cphy *cphy)
|
||||
{
|
||||
return t3_mdio_change_bits(cphy, 0, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE,
|
||||
return t3_mdio_change_bits(cphy, MDIO_DEVAD_NONE, MII_BMCR,
|
||||
BMCR_PDOWN | BMCR_ISOLATE,
|
||||
BMCR_ANRESTART);
|
||||
}
|
||||
|
||||
|
|
@ -130,9 +133,9 @@ static int vsc8211_get_link_status(struct cphy *cphy, int *link_ok,
|
|||
unsigned int bmcr, status, lpa, adv;
|
||||
int err, sp = -1, dplx = -1, pause = 0;
|
||||
|
||||
err = mdio_read(cphy, 0, MII_BMCR, &bmcr);
|
||||
err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_BMCR, &bmcr);
|
||||
if (!err)
|
||||
err = mdio_read(cphy, 0, MII_BMSR, &status);
|
||||
err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_BMSR, &status);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
@ -142,7 +145,8 @@ static int vsc8211_get_link_status(struct cphy *cphy, int *link_ok,
|
|||
* once more to get the current link state.
|
||||
*/
|
||||
if (!(status & BMSR_LSTATUS))
|
||||
err = mdio_read(cphy, 0, MII_BMSR, &status);
|
||||
err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_BMSR,
|
||||
&status);
|
||||
if (err)
|
||||
return err;
|
||||
*link_ok = (status & BMSR_LSTATUS) != 0;
|
||||
|
|
@ -156,7 +160,8 @@ static int vsc8211_get_link_status(struct cphy *cphy, int *link_ok,
|
|||
else
|
||||
sp = SPEED_10;
|
||||
} else if (status & BMSR_ANEGCOMPLETE) {
|
||||
err = mdio_read(cphy, 0, VSC8211_AUX_CTRL_STAT, &status);
|
||||
err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, VSC8211_AUX_CTRL_STAT,
|
||||
&status);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
@ -170,9 +175,11 @@ static int vsc8211_get_link_status(struct cphy *cphy, int *link_ok,
|
|||
sp = SPEED_1000;
|
||||
|
||||
if (fc && dplx == DUPLEX_FULL) {
|
||||
err = mdio_read(cphy, 0, MII_LPA, &lpa);
|
||||
err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_LPA,
|
||||
&lpa);
|
||||
if (!err)
|
||||
err = mdio_read(cphy, 0, MII_ADVERTISE, &adv);
|
||||
err = t3_mdio_read(cphy, MDIO_DEVAD_NONE,
|
||||
MII_ADVERTISE, &adv);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
@ -202,9 +209,9 @@ static int vsc8211_get_link_status_fiber(struct cphy *cphy, int *link_ok,
|
|||
unsigned int bmcr, status, lpa, adv;
|
||||
int err, sp = -1, dplx = -1, pause = 0;
|
||||
|
||||
err = mdio_read(cphy, 0, MII_BMCR, &bmcr);
|
||||
err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_BMCR, &bmcr);
|
||||
if (!err)
|
||||
err = mdio_read(cphy, 0, MII_BMSR, &status);
|
||||
err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_BMSR, &status);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
@ -214,7 +221,8 @@ static int vsc8211_get_link_status_fiber(struct cphy *cphy, int *link_ok,
|
|||
* once more to get the current link state.
|
||||
*/
|
||||
if (!(status & BMSR_LSTATUS))
|
||||
err = mdio_read(cphy, 0, MII_BMSR, &status);
|
||||
err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_BMSR,
|
||||
&status);
|
||||
if (err)
|
||||
return err;
|
||||
*link_ok = (status & BMSR_LSTATUS) != 0;
|
||||
|
|
@ -228,9 +236,10 @@ static int vsc8211_get_link_status_fiber(struct cphy *cphy, int *link_ok,
|
|||
else
|
||||
sp = SPEED_10;
|
||||
} else if (status & BMSR_ANEGCOMPLETE) {
|
||||
err = mdio_read(cphy, 0, MII_LPA, &lpa);
|
||||
err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_LPA, &lpa);
|
||||
if (!err)
|
||||
err = mdio_read(cphy, 0, MII_ADVERTISE, &adv);
|
||||
err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_ADVERTISE,
|
||||
&adv);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
@ -270,23 +279,23 @@ static int vsc8211_set_automdi(struct cphy *phy, int enable)
|
|||
{
|
||||
int err;
|
||||
|
||||
err = mdio_write(phy, 0, VSC8211_EXT_PAGE_AXS, 0x52b5);
|
||||
err = t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_EXT_PAGE_AXS, 0x52b5);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = mdio_write(phy, 0, 18, 0x12);
|
||||
err = t3_mdio_write(phy, MDIO_DEVAD_NONE, 18, 0x12);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = mdio_write(phy, 0, 17, enable ? 0x2803 : 0x3003);
|
||||
err = t3_mdio_write(phy, MDIO_DEVAD_NONE, 17, enable ? 0x2803 : 0x3003);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = mdio_write(phy, 0, 16, 0x87fa);
|
||||
err = t3_mdio_write(phy, MDIO_DEVAD_NONE, 16, 0x87fa);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = mdio_write(phy, 0, VSC8211_EXT_PAGE_AXS, 0);
|
||||
err = t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_EXT_PAGE_AXS, 0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
@ -315,7 +324,7 @@ static int vsc8211_intr_handler(struct cphy *cphy)
|
|||
unsigned int cause;
|
||||
int err, cphy_cause = 0;
|
||||
|
||||
err = mdio_read(cphy, 0, VSC8211_INTR_STATUS, &cause);
|
||||
err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, VSC8211_INTR_STATUS, &cause);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
@ -367,12 +376,13 @@ int t3_vsc8211_phy_prep(struct cphy *phy, struct adapter *adapter,
|
|||
SUPPORTED_TP | SUPPORTED_IRQ, "10/100/1000BASE-T");
|
||||
msleep(20); /* PHY needs ~10ms to start responding to MDIO */
|
||||
|
||||
err = mdio_read(phy, 0, VSC8211_EXT_CTRL, &val);
|
||||
err = t3_mdio_read(phy, MDIO_DEVAD_NONE, VSC8211_EXT_CTRL, &val);
|
||||
if (err)
|
||||
return err;
|
||||
if (val & VSC_CTRL_MEDIA_MODE_HI) {
|
||||
/* copper interface, just need to configure the LEDs */
|
||||
return mdio_write(phy, 0, VSC8211_LED_CTRL, 0x100);
|
||||
return t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_LED_CTRL,
|
||||
0x100);
|
||||
}
|
||||
|
||||
phy->caps = SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg |
|
||||
|
|
@ -380,20 +390,20 @@ int t3_vsc8211_phy_prep(struct cphy *phy, struct adapter *adapter,
|
|||
phy->desc = "1000BASE-X";
|
||||
phy->ops = &vsc8211_fiber_ops;
|
||||
|
||||
err = mdio_write(phy, 0, VSC8211_EXT_PAGE_AXS, 1);
|
||||
err = t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_EXT_PAGE_AXS, 1);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = mdio_write(phy, 0, VSC8211_SIGDET_CTRL, 1);
|
||||
err = t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_SIGDET_CTRL, 1);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = mdio_write(phy, 0, VSC8211_EXT_PAGE_AXS, 0);
|
||||
err = t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_EXT_PAGE_AXS, 0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = mdio_write(phy, 0, VSC8211_EXT_CTRL,
|
||||
val | VSC_CTRL_CLAUSE37_VIEW);
|
||||
err = t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_EXT_CTRL,
|
||||
val | VSC_CTRL_CLAUSE37_VIEW);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
|
|||
2830
drivers/net/davinci_emac.c
Normal file
2830
drivers/net/davinci_emac.c
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -38,14 +38,6 @@ static const char version[] = "de600.c: $Revision: 1.41-2.5 $, Bjorn Ekwall (bj
|
|||
/* Add more time here if your adapter won't work OK: */
|
||||
#define DE600_SLOW_DOWN udelay(delay_time)
|
||||
|
||||
/* use 0 for production, 1 for verification, >2 for debug */
|
||||
#ifdef DE600_DEBUG
|
||||
#define PRINTK(x) if (de600_debug >= 2) printk x
|
||||
#else
|
||||
#define DE600_DEBUG 0
|
||||
#define PRINTK(x) /**/
|
||||
#endif
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
|
|
@ -67,10 +59,6 @@ static const char version[] = "de600.c: $Revision: 1.41-2.5 $, Bjorn Ekwall (bj
|
|||
|
||||
#include "de600.h"
|
||||
|
||||
static unsigned int de600_debug = DE600_DEBUG;
|
||||
module_param(de600_debug, int, 0);
|
||||
MODULE_PARM_DESC(de600_debug, "DE-600 debug level (0-2)");
|
||||
|
||||
static unsigned int check_lost = 1;
|
||||
module_param(check_lost, bool, 0);
|
||||
MODULE_PARM_DESC(check_lost, "If set then check for unplugged de600");
|
||||
|
|
@ -180,20 +168,20 @@ static int de600_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
if (free_tx_pages <= 0) { /* Do timeouts, to avoid hangs. */
|
||||
tickssofar = jiffies - dev->trans_start;
|
||||
if (tickssofar < 5)
|
||||
return 1;
|
||||
return NETDEV_TX_BUSY;
|
||||
/* else */
|
||||
printk(KERN_WARNING "%s: transmit timed out (%d), %s?\n", dev->name, tickssofar, "network cable problem");
|
||||
/* Restart the adapter. */
|
||||
spin_lock_irqsave(&de600_lock, flags);
|
||||
if (adapter_init(dev)) {
|
||||
spin_unlock_irqrestore(&de600_lock, flags);
|
||||
return 1;
|
||||
return NETDEV_TX_BUSY;
|
||||
}
|
||||
spin_unlock_irqrestore(&de600_lock, flags);
|
||||
}
|
||||
|
||||
/* Start real output */
|
||||
PRINTK(("de600_start_xmit:len=%d, page %d/%d\n", skb->len, tx_fifo_in, free_tx_pages));
|
||||
pr_debug("de600_start_xmit:len=%d, page %d/%d\n", skb->len, tx_fifo_in, free_tx_pages);
|
||||
|
||||
if ((len = skb->len) < RUNT)
|
||||
len = RUNT;
|
||||
|
|
@ -211,7 +199,7 @@ static int de600_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
if (was_down || (de600_read_byte(READ_DATA, dev) != 0xde)) {
|
||||
if (adapter_init(dev)) {
|
||||
spin_unlock_irqrestore(&de600_lock, flags);
|
||||
return 1;
|
||||
return NETDEV_TX_BUSY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -259,7 +247,7 @@ static irqreturn_t de600_interrupt(int irq, void *dev_id)
|
|||
irq_status = de600_read_status(dev);
|
||||
|
||||
do {
|
||||
PRINTK(("de600_interrupt (%02X)\n", irq_status));
|
||||
pr_debug("de600_interrupt (%02X)\n", irq_status);
|
||||
|
||||
if (irq_status & RX_GOOD)
|
||||
de600_rx_intr(dev);
|
||||
|
|
@ -407,8 +395,7 @@ static struct net_device * __init de600_probe(void)
|
|||
|
||||
printk(KERN_INFO "%s: D-Link DE-600 pocket adapter", dev->name);
|
||||
/* Alpha testers must have the version number to report bugs. */
|
||||
if (de600_debug > 1)
|
||||
printk(version);
|
||||
pr_debug("%s", version);
|
||||
|
||||
/* probe for adapter */
|
||||
err = -ENODEV;
|
||||
|
|
|
|||
|
|
@ -48,7 +48,6 @@ static const char version[] =
|
|||
* Compile-time options: (see below for descriptions)
|
||||
* -DDE620_IO=0x378 (lpt1)
|
||||
* -DDE620_IRQ=7 (lpt1)
|
||||
* -DDE602_DEBUG=...
|
||||
* -DSHUTDOWN_WHEN_LOST
|
||||
* -DCOUNT_LOOPS
|
||||
* -DLOWSPEED
|
||||
|
|
@ -98,15 +97,6 @@ static const char version[] =
|
|||
#define SHUTDOWN_WHEN_LOST
|
||||
*/
|
||||
|
||||
/*
|
||||
* Enable debugging by "-DDE620_DEBUG=3" when compiling,
|
||||
* OR by enabling the following #define
|
||||
*
|
||||
* use 0 for production, 1 for verification, >2 for debug
|
||||
*
|
||||
#define DE620_DEBUG 3
|
||||
*/
|
||||
|
||||
#ifdef LOWSPEED
|
||||
/*
|
||||
* Enable this #define if you want to see debugging output that show how long
|
||||
|
|
@ -160,14 +150,6 @@ typedef unsigned char byte;
|
|||
#define RUNT 60 /* Too small Ethernet packet */
|
||||
#define GIANT 1514 /* largest legal size packet, no fcs */
|
||||
|
||||
#ifdef DE620_DEBUG /* Compile-time configurable */
|
||||
#define PRINTK(x) if (de620_debug >= 2) printk x
|
||||
#else
|
||||
#define DE620_DEBUG 0
|
||||
#define PRINTK(x) /**/
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Force media with insmod:
|
||||
* insmod de620.o bnc=1
|
||||
|
|
@ -186,8 +168,6 @@ static int io = DE620_IO;
|
|||
static int irq = DE620_IRQ;
|
||||
static int clone = DE620_CLONE;
|
||||
|
||||
static unsigned int de620_debug = DE620_DEBUG;
|
||||
|
||||
static spinlock_t de620_lock;
|
||||
|
||||
module_param(bnc, int, 0);
|
||||
|
|
@ -195,13 +175,11 @@ module_param(utp, int, 0);
|
|||
module_param(io, int, 0);
|
||||
module_param(irq, int, 0);
|
||||
module_param(clone, int, 0);
|
||||
module_param(de620_debug, int, 0);
|
||||
MODULE_PARM_DESC(bnc, "DE-620 set BNC medium (0-1)");
|
||||
MODULE_PARM_DESC(utp, "DE-620 set UTP medium (0-1)");
|
||||
MODULE_PARM_DESC(io, "DE-620 I/O base address,required");
|
||||
MODULE_PARM_DESC(irq, "DE-620 IRQ number,required");
|
||||
MODULE_PARM_DESC(clone, "Check also for non-D-Link DE-620 clones (0-1)");
|
||||
MODULE_PARM_DESC(de620_debug, "DE-620 debug level (0-2)");
|
||||
|
||||
/***********************************************
|
||||
* *
|
||||
|
|
@ -533,9 +511,9 @@ static int de620_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
|
||||
/* Start real output */
|
||||
|
||||
spin_lock_irqsave(&de620_lock, flags)
|
||||
PRINTK(("de620_start_xmit: len=%d, bufs 0x%02x\n",
|
||||
(int)skb->len, using_txbuf));
|
||||
spin_lock_irqsave(&de620_lock, flags);
|
||||
pr_debug("de620_start_xmit: len=%d, bufs 0x%02x\n",
|
||||
(int)skb->len, using_txbuf);
|
||||
|
||||
/* select a free tx buffer. if there is one... */
|
||||
switch (using_txbuf) {
|
||||
|
|
@ -553,7 +531,7 @@ static int de620_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
case (TXBF0 | TXBF1): /* NONE!!! */
|
||||
printk(KERN_WARNING "%s: No tx-buffer available!\n", dev->name);
|
||||
spin_unlock_irqrestore(&de620_lock, flags);
|
||||
return 1;
|
||||
return NETDEV_TX_BUSY;
|
||||
}
|
||||
de620_write_block(dev, buffer, skb->len, len-skb->len);
|
||||
|
||||
|
|
@ -585,12 +563,12 @@ de620_interrupt(int irq_in, void *dev_id)
|
|||
/* Read the status register (_not_ the status port) */
|
||||
irq_status = de620_get_register(dev, R_STS);
|
||||
|
||||
PRINTK(("de620_interrupt (%2.2X)\n", irq_status));
|
||||
pr_debug("de620_interrupt (%2.2X)\n", irq_status);
|
||||
|
||||
if (irq_status & RXGOOD) {
|
||||
do {
|
||||
again = de620_rx_intr(dev);
|
||||
PRINTK(("again=%d\n", again));
|
||||
pr_debug("again=%d\n", again);
|
||||
}
|
||||
while (again && (++bogus_count < 100));
|
||||
}
|
||||
|
|
@ -622,7 +600,7 @@ static int de620_rx_intr(struct net_device *dev)
|
|||
byte pagelink;
|
||||
byte curr_page;
|
||||
|
||||
PRINTK(("de620_rx_intr: next_rx_page = %d\n", next_rx_page));
|
||||
pr_debug("de620_rx_intr: next_rx_page = %d\n", next_rx_page);
|
||||
|
||||
/* Tell the adapter that we are going to read data, and from where */
|
||||
de620_send_command(dev, W_CR | RRN);
|
||||
|
|
@ -631,8 +609,9 @@ static int de620_rx_intr(struct net_device *dev)
|
|||
|
||||
/* Deep breath, and away we goooooo */
|
||||
de620_read_block(dev, (byte *)&header_buf, sizeof(struct header_buf));
|
||||
PRINTK(("page status=0x%02x, nextpage=%d, packetsize=%d\n",
|
||||
header_buf.status, header_buf.Rx_NextPage, header_buf.Rx_ByteCount));
|
||||
pr_debug("page status=0x%02x, nextpage=%d, packetsize=%d\n",
|
||||
header_buf.status, header_buf.Rx_NextPage,
|
||||
header_buf.Rx_ByteCount);
|
||||
|
||||
/* Plausible page header? */
|
||||
pagelink = header_buf.Rx_NextPage;
|
||||
|
|
@ -683,7 +662,7 @@ static int de620_rx_intr(struct net_device *dev)
|
|||
buffer = skb_put(skb,size);
|
||||
/* copy the packet into the buffer */
|
||||
de620_read_block(dev, buffer, size);
|
||||
PRINTK(("Read %d bytes\n", size));
|
||||
pr_debug("Read %d bytes\n", size);
|
||||
skb->protocol=eth_type_trans(skb,dev);
|
||||
netif_rx(skb); /* deliver it "upstairs" */
|
||||
/* count all receives */
|
||||
|
|
@ -696,7 +675,7 @@ static int de620_rx_intr(struct net_device *dev)
|
|||
/* NOTE! We're _not_ checking the 'EMPTY'-flag! This seems better... */
|
||||
curr_page = de620_get_register(dev, R_CPR);
|
||||
de620_set_register(dev, W_NPRF, next_rx_page);
|
||||
PRINTK(("next_rx_page=%d CPR=%d\n", next_rx_page, curr_page));
|
||||
pr_debug("next_rx_page=%d CPR=%d\n", next_rx_page, curr_page);
|
||||
|
||||
return (next_rx_page != curr_page); /* That was slightly tricky... */
|
||||
}
|
||||
|
|
@ -830,8 +809,7 @@ struct net_device * __init de620_probe(int unit)
|
|||
netdev_boot_setup_check(dev);
|
||||
}
|
||||
|
||||
if (de620_debug)
|
||||
printk(version);
|
||||
pr_debug("%s", version);
|
||||
|
||||
printk(KERN_INFO "D-Link DE-620 pocket adapter");
|
||||
|
||||
|
|
@ -878,14 +856,13 @@ struct net_device * __init de620_probe(int unit)
|
|||
/* base_addr and irq are already set, see above! */
|
||||
|
||||
/* dump eeprom */
|
||||
if (de620_debug) {
|
||||
printk("\nEEPROM contents:\n");
|
||||
printk("RAM_Size = 0x%02X\n", nic_data.RAM_Size);
|
||||
printk("NodeID = %pM\n", nic_data.NodeID);
|
||||
printk("Model = %d\n", nic_data.Model);
|
||||
printk("Media = %d\n", nic_data.Media);
|
||||
printk("SCR = 0x%02x\n", nic_data.SCR);
|
||||
}
|
||||
pr_debug("\nEEPROM contents:\n"
|
||||
"RAM_Size = 0x%02X\n"
|
||||
"NodeID = %pM\n"
|
||||
"Model = %d\n"
|
||||
"Media = %d\n"
|
||||
"SCR = 0x%02x\n", nic_data.RAM_Size, nic_data.NodeID,
|
||||
nic_data.Model, nic_data.Media, nic_data.SCR);
|
||||
|
||||
err = register_netdev(dev);
|
||||
if (err)
|
||||
|
|
|
|||
|
|
@ -895,6 +895,7 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
struct lance_private *lp = netdev_priv(dev);
|
||||
volatile struct lance_regs *ll = lp->ll;
|
||||
volatile u16 *ib = (volatile u16 *)dev->mem_start;
|
||||
unsigned long flags;
|
||||
int entry, len;
|
||||
|
||||
len = skb->len;
|
||||
|
|
@ -907,6 +908,8 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
|
||||
dev->stats.tx_bytes += len;
|
||||
|
||||
spin_lock_irqsave(&lp->lock, flags);
|
||||
|
||||
entry = lp->tx_new;
|
||||
*lib_ptr(ib, btx_ring[entry].length, lp->type) = (-len);
|
||||
*lib_ptr(ib, btx_ring[entry].misc, lp->type) = 0;
|
||||
|
|
@ -925,6 +928,8 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
/* Kick the lance: transmit now */
|
||||
writereg(&ll->rdp, LE_C0_INEA | LE_C0_TDMD);
|
||||
|
||||
spin_unlock_irqrestore(&lp->lock, flags);
|
||||
|
||||
dev->trans_start = jiffies;
|
||||
dev_kfree_skb(skb);
|
||||
|
||||
|
|
|
|||
|
|
@ -3318,7 +3318,7 @@ static int dfx_xmt_queue_pkt(
|
|||
{
|
||||
skb_pull(skb,3);
|
||||
spin_unlock_irqrestore(&bp->lock, flags);
|
||||
return(1); /* requeue packet for later */
|
||||
return NETDEV_TX_BUSY; /* requeue packet for later */
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -810,7 +810,7 @@ static int __init depca_hw_init (struct net_device *dev, struct device *device)
|
|||
|
||||
dev->mem_start = 0;
|
||||
|
||||
device->driver_data = dev;
|
||||
dev_set_drvdata(device, dev);
|
||||
SET_NETDEV_DEV (dev, device);
|
||||
|
||||
status = register_netdev(dev);
|
||||
|
|
@ -957,7 +957,7 @@ static int depca_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
if (TX_BUFFS_AVAIL)
|
||||
netif_start_queue(dev);
|
||||
} else
|
||||
status = -1;
|
||||
status = NETDEV_TX_LOCKED;
|
||||
|
||||
out:
|
||||
return status;
|
||||
|
|
@ -1614,7 +1614,7 @@ static int __devexit depca_device_remove (struct device *device)
|
|||
struct depca_private *lp;
|
||||
int bus;
|
||||
|
||||
dev = device->driver_data;
|
||||
dev = dev_get_drvdata(device);
|
||||
lp = netdev_priv(dev);
|
||||
|
||||
unregister_netdev (dev);
|
||||
|
|
@ -1839,7 +1839,7 @@ static int load_packet(struct net_device *dev, struct sk_buff *skb)
|
|||
|
||||
lp->tx_new = (++end) & lp->txRingMask; /* update current pointers */
|
||||
} else {
|
||||
status = -1;
|
||||
status = NETDEV_TX_LOCKED;
|
||||
}
|
||||
|
||||
return status;
|
||||
|
|
|
|||
|
|
@ -539,7 +539,7 @@ rio_tx_timeout (struct net_device *dev)
|
|||
dev->name, readl (ioaddr + TxStatus));
|
||||
rio_free_tx(dev, 0);
|
||||
dev->if_port = 0;
|
||||
dev->trans_start = jiffies;
|
||||
dev->trans_start = jiffies; /* prevent tx timeout */
|
||||
}
|
||||
|
||||
/* allocate and initialize Tx and Rx descriptors */
|
||||
|
|
@ -610,7 +610,7 @@ start_xmit (struct sk_buff *skb, struct net_device *dev)
|
|||
|
||||
if (np->link_status == 0) { /* Link Down */
|
||||
dev_kfree_skb(skb);
|
||||
return 0;
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
ioaddr = dev->base_addr;
|
||||
entry = np->cur_tx % TX_RING_SIZE;
|
||||
|
|
@ -665,9 +665,7 @@ start_xmit (struct sk_buff *skb, struct net_device *dev)
|
|||
writel (0, dev->base_addr + TFDListPtr1);
|
||||
}
|
||||
|
||||
/* NETDEV WATCHDOG timer */
|
||||
dev->trans_start = jiffies;
|
||||
return 0;
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
static irqreturn_t
|
||||
|
|
|
|||
|
|
@ -756,7 +756,7 @@ dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
dm9000_dbg(db, 3, "%s:\n", __func__);
|
||||
|
||||
if (db->tx_pkt_cnt > 1)
|
||||
return 1;
|
||||
return NETDEV_TX_BUSY;
|
||||
|
||||
spin_lock_irqsave(&db->lock, flags);
|
||||
|
||||
|
|
@ -1170,6 +1170,21 @@ dm9000_stop(struct net_device *ndev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const struct net_device_ops dm9000_netdev_ops = {
|
||||
.ndo_open = dm9000_open,
|
||||
.ndo_stop = dm9000_stop,
|
||||
.ndo_start_xmit = dm9000_start_xmit,
|
||||
.ndo_tx_timeout = dm9000_timeout,
|
||||
.ndo_set_multicast_list = dm9000_hash_table,
|
||||
.ndo_do_ioctl = dm9000_ioctl,
|
||||
.ndo_change_mtu = eth_change_mtu,
|
||||
.ndo_validate_addr = eth_validate_addr,
|
||||
.ndo_set_mac_address = eth_mac_addr,
|
||||
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||
.ndo_poll_controller = dm9000_poll_controller,
|
||||
#endif
|
||||
};
|
||||
|
||||
#define res_size(_r) (((_r)->end - (_r)->start) + 1)
|
||||
|
||||
/*
|
||||
|
|
@ -1339,18 +1354,9 @@ dm9000_probe(struct platform_device *pdev)
|
|||
/* driver system function */
|
||||
ether_setup(ndev);
|
||||
|
||||
ndev->open = &dm9000_open;
|
||||
ndev->hard_start_xmit = &dm9000_start_xmit;
|
||||
ndev->tx_timeout = &dm9000_timeout;
|
||||
ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
|
||||
ndev->stop = &dm9000_stop;
|
||||
ndev->set_multicast_list = &dm9000_hash_table;
|
||||
ndev->ethtool_ops = &dm9000_ethtool_ops;
|
||||
ndev->do_ioctl = &dm9000_ioctl;
|
||||
|
||||
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||
ndev->poll_controller = &dm9000_poll_controller;
|
||||
#endif
|
||||
ndev->netdev_ops = &dm9000_netdev_ops;
|
||||
ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
|
||||
ndev->ethtool_ops = &dm9000_ethtool_ops;
|
||||
|
||||
db->msg_enable = NETIF_MSG_LINK;
|
||||
db->mii.phy_id_mask = 0x1f;
|
||||
|
|
|
|||
|
|
@ -143,6 +143,8 @@
|
|||
* FIXES:
|
||||
* 2005/12/02 - Michael O'Donnell <Michael.ODonnell at stratus dot com>
|
||||
* - Stratus87247: protect MDI control register manipulations
|
||||
* 2009/06/01 - Andreas Mohr <andi at lisas dot de>
|
||||
* - add clean lowlevel I/O emulation for cards with MII-lacking PHYs
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
|
@ -372,6 +374,7 @@ enum eeprom_op {
|
|||
|
||||
enum eeprom_offsets {
|
||||
eeprom_cnfg_mdix = 0x03,
|
||||
eeprom_phy_iface = 0x06,
|
||||
eeprom_id = 0x0A,
|
||||
eeprom_config_asf = 0x0D,
|
||||
eeprom_smbus_addr = 0x90,
|
||||
|
|
@ -381,6 +384,18 @@ enum eeprom_cnfg_mdix {
|
|||
eeprom_mdix_enabled = 0x0080,
|
||||
};
|
||||
|
||||
enum eeprom_phy_iface {
|
||||
NoSuchPhy = 0,
|
||||
I82553AB,
|
||||
I82553C,
|
||||
I82503,
|
||||
DP83840,
|
||||
S80C240,
|
||||
S80C24,
|
||||
I82555,
|
||||
DP83840A = 10,
|
||||
};
|
||||
|
||||
enum eeprom_id {
|
||||
eeprom_id_wol = 0x0020,
|
||||
};
|
||||
|
|
@ -545,6 +560,7 @@ struct nic {
|
|||
u32 msg_enable ____cacheline_aligned;
|
||||
struct net_device *netdev;
|
||||
struct pci_dev *pdev;
|
||||
u16 (*mdio_ctrl)(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data);
|
||||
|
||||
struct rx *rxs ____cacheline_aligned;
|
||||
struct rx *rx_to_use;
|
||||
|
|
@ -899,7 +915,21 @@ err_unlock:
|
|||
return err;
|
||||
}
|
||||
|
||||
static u16 mdio_ctrl(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data)
|
||||
static int mdio_read(struct net_device *netdev, int addr, int reg)
|
||||
{
|
||||
struct nic *nic = netdev_priv(netdev);
|
||||
return nic->mdio_ctrl(nic, addr, mdi_read, reg, 0);
|
||||
}
|
||||
|
||||
static void mdio_write(struct net_device *netdev, int addr, int reg, int data)
|
||||
{
|
||||
struct nic *nic = netdev_priv(netdev);
|
||||
|
||||
nic->mdio_ctrl(nic, addr, mdi_write, reg, data);
|
||||
}
|
||||
|
||||
/* the standard mdio_ctrl() function for usual MII-compliant hardware */
|
||||
static u16 mdio_ctrl_hw(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data)
|
||||
{
|
||||
u32 data_out = 0;
|
||||
unsigned int i;
|
||||
|
|
@ -938,30 +968,83 @@ static u16 mdio_ctrl(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data)
|
|||
return (u16)data_out;
|
||||
}
|
||||
|
||||
static int mdio_read(struct net_device *netdev, int addr, int reg)
|
||||
/* slightly tweaked mdio_ctrl() function for phy_82552_v specifics */
|
||||
static u16 mdio_ctrl_phy_82552_v(struct nic *nic,
|
||||
u32 addr,
|
||||
u32 dir,
|
||||
u32 reg,
|
||||
u16 data)
|
||||
{
|
||||
return mdio_ctrl(netdev_priv(netdev), addr, mdi_read, reg, 0);
|
||||
if ((reg == MII_BMCR) && (dir == mdi_write)) {
|
||||
if (data & (BMCR_ANRESTART | BMCR_ANENABLE)) {
|
||||
u16 advert = mdio_read(nic->netdev, nic->mii.phy_id,
|
||||
MII_ADVERTISE);
|
||||
|
||||
/*
|
||||
* Workaround Si issue where sometimes the part will not
|
||||
* autoneg to 100Mbps even when advertised.
|
||||
*/
|
||||
if (advert & ADVERTISE_100FULL)
|
||||
data |= BMCR_SPEED100 | BMCR_FULLDPLX;
|
||||
else if (advert & ADVERTISE_100HALF)
|
||||
data |= BMCR_SPEED100;
|
||||
}
|
||||
}
|
||||
return mdio_ctrl_hw(nic, addr, dir, reg, data);
|
||||
}
|
||||
|
||||
static void mdio_write(struct net_device *netdev, int addr, int reg, int data)
|
||||
/* Fully software-emulated mdio_ctrl() function for cards without
|
||||
* MII-compliant PHYs.
|
||||
* For now, this is mainly geared towards 80c24 support; in case of further
|
||||
* requirements for other types (i82503, ...?) either extend this mechanism
|
||||
* or split it, whichever is cleaner.
|
||||
*/
|
||||
static u16 mdio_ctrl_phy_mii_emulated(struct nic *nic,
|
||||
u32 addr,
|
||||
u32 dir,
|
||||
u32 reg,
|
||||
u16 data)
|
||||
{
|
||||
struct nic *nic = netdev_priv(netdev);
|
||||
/* might need to allocate a netdev_priv'ed register array eventually
|
||||
* to be able to record state changes, but for now
|
||||
* some fully hardcoded register handling ought to be ok I guess. */
|
||||
|
||||
if ((nic->phy == phy_82552_v) && (reg == MII_BMCR) &&
|
||||
(data & (BMCR_ANRESTART | BMCR_ANENABLE))) {
|
||||
u16 advert = mdio_read(netdev, nic->mii.phy_id, MII_ADVERTISE);
|
||||
|
||||
/*
|
||||
* Workaround Si issue where sometimes the part will not
|
||||
* autoneg to 100Mbps even when advertised.
|
||||
*/
|
||||
if (advert & ADVERTISE_100FULL)
|
||||
data |= BMCR_SPEED100 | BMCR_FULLDPLX;
|
||||
else if (advert & ADVERTISE_100HALF)
|
||||
data |= BMCR_SPEED100;
|
||||
if (dir == mdi_read) {
|
||||
switch (reg) {
|
||||
case MII_BMCR:
|
||||
/* Auto-negotiation, right? */
|
||||
return BMCR_ANENABLE |
|
||||
BMCR_FULLDPLX;
|
||||
case MII_BMSR:
|
||||
return BMSR_LSTATUS /* for mii_link_ok() */ |
|
||||
BMSR_ANEGCAPABLE |
|
||||
BMSR_10FULL;
|
||||
case MII_ADVERTISE:
|
||||
/* 80c24 is a "combo card" PHY, right? */
|
||||
return ADVERTISE_10HALF |
|
||||
ADVERTISE_10FULL;
|
||||
default:
|
||||
DPRINTK(HW, DEBUG,
|
||||
"%s:addr=%d, reg=%d, data=0x%04X: unimplemented emulation!\n",
|
||||
dir == mdi_read ? "READ" : "WRITE", addr, reg, data);
|
||||
return 0xFFFF;
|
||||
}
|
||||
} else {
|
||||
switch (reg) {
|
||||
default:
|
||||
DPRINTK(HW, DEBUG,
|
||||
"%s:addr=%d, reg=%d, data=0x%04X: unimplemented emulation!\n",
|
||||
dir == mdi_read ? "READ" : "WRITE", addr, reg, data);
|
||||
return 0xFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
mdio_ctrl(netdev_priv(netdev), addr, mdi_write, reg, data);
|
||||
}
|
||||
static inline int e100_phy_supports_mii(struct nic *nic)
|
||||
{
|
||||
/* for now, just check it by comparing whether we
|
||||
are using MII software emulation.
|
||||
*/
|
||||
return (nic->mdio_ctrl != mdio_ctrl_phy_mii_emulated);
|
||||
}
|
||||
|
||||
static void e100_get_defaults(struct nic *nic)
|
||||
|
|
@ -1013,7 +1096,8 @@ static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb)
|
|||
config->standard_stat_counter = 0x1; /* 1=standard, 0=extended */
|
||||
config->rx_discard_short_frames = 0x1; /* 1=discard, 0=pass */
|
||||
config->tx_underrun_retry = 0x3; /* # of underrun retries */
|
||||
config->mii_mode = 0x1; /* 1=MII mode, 0=503 mode */
|
||||
if (e100_phy_supports_mii(nic))
|
||||
config->mii_mode = 1; /* 1=MII mode, 0=i82503 mode */
|
||||
config->pad10 = 0x6;
|
||||
config->no_source_addr_insertion = 0x1; /* 1=no, 0=yes */
|
||||
config->preamble_length = 0x2; /* 0=1, 1=3, 2=7, 3=15 bytes */
|
||||
|
|
@ -1270,6 +1354,42 @@ static void e100_dump(struct nic *nic, struct cb *cb, struct sk_buff *skb)
|
|||
offsetof(struct mem, dump_buf));
|
||||
}
|
||||
|
||||
static int e100_phy_check_without_mii(struct nic *nic)
|
||||
{
|
||||
u8 phy_type;
|
||||
int without_mii;
|
||||
|
||||
phy_type = (nic->eeprom[eeprom_phy_iface] >> 8) & 0x0f;
|
||||
|
||||
switch (phy_type) {
|
||||
case NoSuchPhy: /* Non-MII PHY; UNTESTED! */
|
||||
case I82503: /* Non-MII PHY; UNTESTED! */
|
||||
case S80C24: /* Non-MII PHY; tested and working */
|
||||
/* paragraph from the FreeBSD driver, "FXP_PHY_80C24":
|
||||
* The Seeq 80c24 AutoDUPLEX(tm) Ethernet Interface Adapter
|
||||
* doesn't have a programming interface of any sort. The
|
||||
* media is sensed automatically based on how the link partner
|
||||
* is configured. This is, in essence, manual configuration.
|
||||
*/
|
||||
DPRINTK(PROBE, INFO,
|
||||
"found MII-less i82503 or 80c24 or other PHY\n");
|
||||
|
||||
nic->mdio_ctrl = mdio_ctrl_phy_mii_emulated;
|
||||
nic->mii.phy_id = 0; /* is this ok for an MII-less PHY? */
|
||||
|
||||
/* these might be needed for certain MII-less cards...
|
||||
* nic->flags |= ich;
|
||||
* nic->flags |= ich_10h_workaround; */
|
||||
|
||||
without_mii = 1;
|
||||
break;
|
||||
default:
|
||||
without_mii = 0;
|
||||
break;
|
||||
}
|
||||
return without_mii;
|
||||
}
|
||||
|
||||
#define NCONFIG_AUTO_SWITCH 0x0080
|
||||
#define MII_NSC_CONG MII_RESV1
|
||||
#define NSC_CONG_ENABLE 0x0100
|
||||
|
|
@ -1290,9 +1410,21 @@ static int e100_phy_init(struct nic *nic)
|
|||
if (!((bmcr == 0xFFFF) || ((stat == 0) && (bmcr == 0))))
|
||||
break;
|
||||
}
|
||||
DPRINTK(HW, DEBUG, "phy_addr = %d\n", nic->mii.phy_id);
|
||||
if (addr == 32)
|
||||
return -EAGAIN;
|
||||
if (addr == 32) {
|
||||
/* uhoh, no PHY detected: check whether we seem to be some
|
||||
* weird, rare variant which is *known* to not have any MII.
|
||||
* But do this AFTER MII checking only, since this does
|
||||
* lookup of EEPROM values which may easily be unreliable. */
|
||||
if (e100_phy_check_without_mii(nic))
|
||||
return 0; /* simply return and hope for the best */
|
||||
else {
|
||||
/* for unknown cases log a fatal error */
|
||||
DPRINTK(HW, ERR,
|
||||
"Failed to locate any known PHY, aborting.\n");
|
||||
return -EAGAIN;
|
||||
}
|
||||
} else
|
||||
DPRINTK(HW, DEBUG, "phy_addr = %d\n", nic->mii.phy_id);
|
||||
|
||||
/* Isolate all the PHY ids */
|
||||
for (addr = 0; addr < 32; addr++)
|
||||
|
|
@ -1320,6 +1452,9 @@ static int e100_phy_init(struct nic *nic)
|
|||
if (nic->phy == phy_82552_v) {
|
||||
u16 advert = mdio_read(netdev, nic->mii.phy_id, MII_ADVERTISE);
|
||||
|
||||
/* assign special tweaked mdio_ctrl() function */
|
||||
nic->mdio_ctrl = mdio_ctrl_phy_82552_v;
|
||||
|
||||
/* Workaround Si not advertising flow-control during autoneg */
|
||||
advert |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
|
||||
mdio_write(netdev, nic->mii.phy_id, MII_ADVERTISE, advert);
|
||||
|
|
@ -1581,7 +1716,7 @@ static int e100_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
|
|||
/* This is a hard error - log it. */
|
||||
DPRINTK(TX_ERR, DEBUG, "Out of Tx resources, returning skb\n");
|
||||
netif_stop_queue(netdev);
|
||||
return 1;
|
||||
return NETDEV_TX_BUSY;
|
||||
}
|
||||
|
||||
netdev->trans_start = jiffies;
|
||||
|
|
@ -2585,6 +2720,7 @@ static int __devinit e100_probe(struct pci_dev *pdev,
|
|||
nic->netdev = netdev;
|
||||
nic->pdev = pdev;
|
||||
nic->msg_enable = (1 << debug) - 1;
|
||||
nic->mdio_ctrl = mdio_ctrl_hw;
|
||||
pci_set_drvdata(pdev, netdev);
|
||||
|
||||
if ((err = pci_enable_device(pdev))) {
|
||||
|
|
@ -2822,12 +2958,13 @@ static pci_ers_result_t e100_io_error_detected(struct pci_dev *pdev, pci_channel
|
|||
struct net_device *netdev = pci_get_drvdata(pdev);
|
||||
struct nic *nic = netdev_priv(netdev);
|
||||
|
||||
/* Similar to calling e100_down(), but avoids adapter I/O. */
|
||||
e100_close(netdev);
|
||||
|
||||
/* Detach; put netif into a state similar to hotplug unplug. */
|
||||
napi_enable(&nic->napi);
|
||||
netif_device_detach(netdev);
|
||||
|
||||
if (state == pci_channel_io_perm_failure)
|
||||
return PCI_ERS_RESULT_DISCONNECT;
|
||||
|
||||
if (netif_running(netdev))
|
||||
e100_down(nic);
|
||||
pci_disable_device(pdev);
|
||||
|
||||
/* Request a slot reset. */
|
||||
|
|
|
|||
|
|
@ -498,6 +498,8 @@ int e1000_up(struct e1000_adapter *adapter)
|
|||
|
||||
e1000_irq_enable(adapter);
|
||||
|
||||
netif_wake_queue(adapter->netdev);
|
||||
|
||||
/* fire a link change interrupt to start the watchdog */
|
||||
ew32(ICS, E1000_ICS_LSC);
|
||||
return 0;
|
||||
|
|
@ -1234,15 +1236,14 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
|
|||
!e1000_check_mng_mode(hw))
|
||||
e1000_get_hw_control(adapter);
|
||||
|
||||
/* tell the stack to leave us alone until e1000_open() is called */
|
||||
netif_carrier_off(netdev);
|
||||
netif_stop_queue(netdev);
|
||||
|
||||
strcpy(netdev->name, "eth%d");
|
||||
err = register_netdev(netdev);
|
||||
if (err)
|
||||
goto err_register;
|
||||
|
||||
/* carrier off reporting is important to ethtool even BEFORE open */
|
||||
netif_carrier_off(netdev);
|
||||
|
||||
DPRINTK(PROBE, INFO, "Intel(R) PRO/1000 Network Connection\n");
|
||||
|
||||
cards_found++;
|
||||
|
|
@ -1441,6 +1442,8 @@ static int e1000_open(struct net_device *netdev)
|
|||
if (test_bit(__E1000_TESTING, &adapter->flags))
|
||||
return -EBUSY;
|
||||
|
||||
netif_carrier_off(netdev);
|
||||
|
||||
/* allocate transmit descriptors */
|
||||
err = e1000_setup_all_tx_resources(adapter);
|
||||
if (err)
|
||||
|
|
@ -2327,7 +2330,8 @@ static void e1000_set_rx_mode(struct net_device *netdev)
|
|||
{
|
||||
struct e1000_adapter *adapter = netdev_priv(netdev);
|
||||
struct e1000_hw *hw = &adapter->hw;
|
||||
struct dev_addr_list *uc_ptr;
|
||||
struct netdev_hw_addr *ha;
|
||||
bool use_uc = false;
|
||||
struct dev_addr_list *mc_ptr;
|
||||
u32 rctl;
|
||||
u32 hash_value;
|
||||
|
|
@ -2366,12 +2370,11 @@ static void e1000_set_rx_mode(struct net_device *netdev)
|
|||
rctl |= E1000_RCTL_VFE;
|
||||
}
|
||||
|
||||
uc_ptr = NULL;
|
||||
if (netdev->uc_count > rar_entries - 1) {
|
||||
rctl |= E1000_RCTL_UPE;
|
||||
} else if (!(netdev->flags & IFF_PROMISC)) {
|
||||
rctl &= ~E1000_RCTL_UPE;
|
||||
uc_ptr = netdev->uc_list;
|
||||
use_uc = true;
|
||||
}
|
||||
|
||||
ew32(RCTL, rctl);
|
||||
|
|
@ -2389,13 +2392,20 @@ static void e1000_set_rx_mode(struct net_device *netdev)
|
|||
* if there are not 14 addresses, go ahead and clear the filters
|
||||
* -- with 82571 controllers only 0-13 entries are filled here
|
||||
*/
|
||||
i = 1;
|
||||
if (use_uc)
|
||||
list_for_each_entry(ha, &netdev->uc_list, list) {
|
||||
if (i == rar_entries)
|
||||
break;
|
||||
e1000_rar_set(hw, ha->addr, i++);
|
||||
}
|
||||
|
||||
WARN_ON(i == rar_entries);
|
||||
|
||||
mc_ptr = netdev->mc_list;
|
||||
|
||||
for (i = 1; i < rar_entries; i++) {
|
||||
if (uc_ptr) {
|
||||
e1000_rar_set(hw, uc_ptr->da_addr, i);
|
||||
uc_ptr = uc_ptr->next;
|
||||
} else if (mc_ptr) {
|
||||
for (; i < rar_entries; i++) {
|
||||
if (mc_ptr) {
|
||||
e1000_rar_set(hw, mc_ptr->da_addr, i);
|
||||
mc_ptr = mc_ptr->next;
|
||||
} else {
|
||||
|
|
@ -2405,7 +2415,6 @@ static void e1000_set_rx_mode(struct net_device *netdev)
|
|||
E1000_WRITE_FLUSH();
|
||||
}
|
||||
}
|
||||
WARN_ON(uc_ptr != NULL);
|
||||
|
||||
/* load any remaining addresses into the hash table */
|
||||
|
||||
|
|
@ -2590,7 +2599,6 @@ static void e1000_watchdog(unsigned long data)
|
|||
ew32(TCTL, tctl);
|
||||
|
||||
netif_carrier_on(netdev);
|
||||
netif_wake_queue(netdev);
|
||||
mod_timer(&adapter->phy_info_timer, round_jiffies(jiffies + 2 * HZ));
|
||||
adapter->smartspeed = 0;
|
||||
} else {
|
||||
|
|
@ -2607,7 +2615,6 @@ static void e1000_watchdog(unsigned long data)
|
|||
printk(KERN_INFO "e1000: %s NIC Link is Down\n",
|
||||
netdev->name);
|
||||
netif_carrier_off(netdev);
|
||||
netif_stop_queue(netdev);
|
||||
mod_timer(&adapter->phy_info_timer, round_jiffies(jiffies + 2 * HZ));
|
||||
|
||||
/* 80003ES2LAN workaround--
|
||||
|
|
@ -2645,6 +2652,8 @@ static void e1000_watchdog(unsigned long data)
|
|||
* (Do the reset outside of interrupt context). */
|
||||
adapter->tx_timeout_count++;
|
||||
schedule_work(&adapter->reset_task);
|
||||
/* return immediately since reset is imminent */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2989,7 +2998,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
|
|||
size -= 4;
|
||||
|
||||
buffer_info->length = size;
|
||||
buffer_info->dma = map[0] + offset;
|
||||
buffer_info->dma = skb_shinfo(skb)->dma_head + offset;
|
||||
buffer_info->time_stamp = jiffies;
|
||||
buffer_info->next_to_watch = i;
|
||||
|
||||
|
|
@ -3030,7 +3039,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
|
|||
size -= 4;
|
||||
|
||||
buffer_info->length = size;
|
||||
buffer_info->dma = map[f + 1] + offset;
|
||||
buffer_info->dma = map[f] + offset;
|
||||
buffer_info->time_stamp = jiffies;
|
||||
buffer_info->next_to_watch = i;
|
||||
|
||||
|
|
@ -3362,7 +3371,6 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
|
|||
|
||||
if (count) {
|
||||
e1000_tx_queue(adapter, tx_ring, tx_flags, count);
|
||||
netdev->trans_start = jiffies;
|
||||
/* Make sure there is space in the ring for the next send. */
|
||||
e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
|
||||
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ static s32 e1000_setup_link_82571(struct e1000_hw *hw);
|
|||
static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw);
|
||||
static bool e1000_check_mng_mode_82574(struct e1000_hw *hw);
|
||||
static s32 e1000_led_on_82574(struct e1000_hw *hw);
|
||||
static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw);
|
||||
|
||||
/**
|
||||
* e1000_init_phy_params_82571 - Init PHY func ptrs.
|
||||
|
|
@ -212,6 +213,9 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter)
|
|||
struct e1000_hw *hw = &adapter->hw;
|
||||
struct e1000_mac_info *mac = &hw->mac;
|
||||
struct e1000_mac_operations *func = &mac->ops;
|
||||
u32 swsm = 0;
|
||||
u32 swsm2 = 0;
|
||||
bool force_clear_smbi = false;
|
||||
|
||||
/* Set media type */
|
||||
switch (adapter->pdev->device) {
|
||||
|
|
@ -276,6 +280,50 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter)
|
|||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure that the inter-port SWSM.SMBI lock bit is clear before
|
||||
* first NVM or PHY acess. This should be done for single-port
|
||||
* devices, and for one port only on dual-port devices so that
|
||||
* for those devices we can still use the SMBI lock to synchronize
|
||||
* inter-port accesses to the PHY & NVM.
|
||||
*/
|
||||
switch (hw->mac.type) {
|
||||
case e1000_82571:
|
||||
case e1000_82572:
|
||||
swsm2 = er32(SWSM2);
|
||||
|
||||
if (!(swsm2 & E1000_SWSM2_LOCK)) {
|
||||
/* Only do this for the first interface on this card */
|
||||
ew32(SWSM2,
|
||||
swsm2 | E1000_SWSM2_LOCK);
|
||||
force_clear_smbi = true;
|
||||
} else
|
||||
force_clear_smbi = false;
|
||||
break;
|
||||
default:
|
||||
force_clear_smbi = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (force_clear_smbi) {
|
||||
/* Make sure SWSM.SMBI is clear */
|
||||
swsm = er32(SWSM);
|
||||
if (swsm & E1000_SWSM_SMBI) {
|
||||
/* This bit should not be set on a first interface, and
|
||||
* indicates that the bootagent or EFI code has
|
||||
* improperly left this bit enabled
|
||||
*/
|
||||
hw_dbg(hw, "Please update your 82571 Bootagent\n");
|
||||
}
|
||||
ew32(SWSM, swsm & ~E1000_SWSM_SMBI);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialze device specific counter of SMBI acquisition
|
||||
* timeouts.
|
||||
*/
|
||||
hw->dev_spec.e82571.smb_counter = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -341,8 +389,10 @@ static s32 e1000_get_variants_82571(struct e1000_adapter *adapter)
|
|||
if (e1000_read_nvm(&adapter->hw, NVM_INIT_3GIO_3, 1,
|
||||
&eeprom_data) < 0)
|
||||
break;
|
||||
if (eeprom_data & NVM_WORD1A_ASPM_MASK)
|
||||
adapter->flags &= ~FLAG_HAS_JUMBO_FRAMES;
|
||||
if (!(eeprom_data & NVM_WORD1A_ASPM_MASK)) {
|
||||
adapter->flags |= FLAG_HAS_JUMBO_FRAMES;
|
||||
adapter->max_hw_frame_size = DEFAULT_JUMBO;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
@ -411,11 +461,37 @@ static s32 e1000_get_phy_id_82571(struct e1000_hw *hw)
|
|||
static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw)
|
||||
{
|
||||
u32 swsm;
|
||||
s32 timeout = hw->nvm.word_size + 1;
|
||||
s32 sw_timeout = hw->nvm.word_size + 1;
|
||||
s32 fw_timeout = hw->nvm.word_size + 1;
|
||||
s32 i = 0;
|
||||
|
||||
/*
|
||||
* If we have timedout 3 times on trying to acquire
|
||||
* the inter-port SMBI semaphore, there is old code
|
||||
* operating on the other port, and it is not
|
||||
* releasing SMBI. Modify the number of times that
|
||||
* we try for the semaphore to interwork with this
|
||||
* older code.
|
||||
*/
|
||||
if (hw->dev_spec.e82571.smb_counter > 2)
|
||||
sw_timeout = 1;
|
||||
|
||||
/* Get the SW semaphore */
|
||||
while (i < sw_timeout) {
|
||||
swsm = er32(SWSM);
|
||||
if (!(swsm & E1000_SWSM_SMBI))
|
||||
break;
|
||||
|
||||
udelay(50);
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i == sw_timeout) {
|
||||
hw_dbg(hw, "Driver can't access device - SMBI bit is set.\n");
|
||||
hw->dev_spec.e82571.smb_counter++;
|
||||
}
|
||||
/* Get the FW semaphore. */
|
||||
for (i = 0; i < timeout; i++) {
|
||||
for (i = 0; i < fw_timeout; i++) {
|
||||
swsm = er32(SWSM);
|
||||
ew32(SWSM, swsm | E1000_SWSM_SWESMBI);
|
||||
|
||||
|
|
@ -426,9 +502,9 @@ static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw)
|
|||
udelay(50);
|
||||
}
|
||||
|
||||
if (i == timeout) {
|
||||
if (i == fw_timeout) {
|
||||
/* Release semaphores */
|
||||
e1000e_put_hw_semaphore(hw);
|
||||
e1000_put_hw_semaphore_82571(hw);
|
||||
hw_dbg(hw, "Driver can't access the NVM\n");
|
||||
return -E1000_ERR_NVM;
|
||||
}
|
||||
|
|
@ -447,9 +523,7 @@ static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw)
|
|||
u32 swsm;
|
||||
|
||||
swsm = er32(SWSM);
|
||||
|
||||
swsm &= ~E1000_SWSM_SWESMBI;
|
||||
|
||||
swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);
|
||||
ew32(SWSM, swsm);
|
||||
}
|
||||
|
||||
|
|
@ -1585,6 +1659,7 @@ static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw)
|
|||
static struct e1000_mac_operations e82571_mac_ops = {
|
||||
/* .check_mng_mode: mac type dependent */
|
||||
/* .check_for_link: media type dependent */
|
||||
.id_led_init = e1000e_id_led_init,
|
||||
.cleanup_led = e1000e_cleanup_led_generic,
|
||||
.clear_hw_cntrs = e1000_clear_hw_cntrs_82571,
|
||||
.get_bus_info = e1000e_get_bus_info_pcie,
|
||||
|
|
@ -1596,6 +1671,7 @@ static struct e1000_mac_operations e82571_mac_ops = {
|
|||
.init_hw = e1000_init_hw_82571,
|
||||
.setup_link = e1000_setup_link_82571,
|
||||
/* .setup_physical_interface: media type dependent */
|
||||
.setup_led = e1000e_setup_led_generic,
|
||||
};
|
||||
|
||||
static struct e1000_phy_operations e82_phy_ops_igp = {
|
||||
|
|
@ -1672,6 +1748,7 @@ struct e1000_info e1000_82571_info = {
|
|||
| FLAG_TARC_SPEED_MODE_BIT /* errata */
|
||||
| FLAG_APME_CHECK_PORT_B,
|
||||
.pba = 38,
|
||||
.max_hw_frame_size = DEFAULT_JUMBO,
|
||||
.get_variants = e1000_get_variants_82571,
|
||||
.mac_ops = &e82571_mac_ops,
|
||||
.phy_ops = &e82_phy_ops_igp,
|
||||
|
|
@ -1688,6 +1765,7 @@ struct e1000_info e1000_82572_info = {
|
|||
| FLAG_HAS_CTRLEXT_ON_LOAD
|
||||
| FLAG_TARC_SPEED_MODE_BIT, /* errata */
|
||||
.pba = 38,
|
||||
.max_hw_frame_size = DEFAULT_JUMBO,
|
||||
.get_variants = e1000_get_variants_82571,
|
||||
.mac_ops = &e82571_mac_ops,
|
||||
.phy_ops = &e82_phy_ops_igp,
|
||||
|
|
@ -1706,6 +1784,7 @@ struct e1000_info e1000_82573_info = {
|
|||
| FLAG_HAS_ERT
|
||||
| FLAG_HAS_SWSM_ON_LOAD,
|
||||
.pba = 20,
|
||||
.max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN,
|
||||
.get_variants = e1000_get_variants_82571,
|
||||
.mac_ops = &e82571_mac_ops,
|
||||
.phy_ops = &e82_phy_ops_m88,
|
||||
|
|
@ -1724,6 +1803,7 @@ struct e1000_info e1000_82574_info = {
|
|||
| FLAG_HAS_AMT
|
||||
| FLAG_HAS_CTRLEXT_ON_LOAD,
|
||||
.pba = 20,
|
||||
.max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN,
|
||||
.get_variants = e1000_get_variants_82571,
|
||||
.mac_ops = &e82571_mac_ops,
|
||||
.phy_ops = &e82_phy_ops_bm,
|
||||
|
|
@ -1740,6 +1820,7 @@ struct e1000_info e1000_82583_info = {
|
|||
| FLAG_HAS_AMT
|
||||
| FLAG_HAS_CTRLEXT_ON_LOAD,
|
||||
.pba = 20,
|
||||
.max_hw_frame_size = DEFAULT_JUMBO,
|
||||
.get_variants = e1000_get_variants_82571,
|
||||
.mac_ops = &e82571_mac_ops,
|
||||
.phy_ops = &e82_phy_ops_bm,
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@
|
|||
/* Wake Up Control */
|
||||
#define E1000_WUC_APME 0x00000001 /* APM Enable */
|
||||
#define E1000_WUC_PME_EN 0x00000002 /* PME Enable */
|
||||
#define E1000_WUC_PHY_WAKE 0x00000100 /* if PHY supports wakeup */
|
||||
|
||||
/* Wake Up Filter Control */
|
||||
#define E1000_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
|
||||
|
|
@ -65,6 +66,13 @@
|
|||
#define E1000_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */
|
||||
#define E1000_WUFC_ARP 0x00000020 /* ARP Request Packet Wakeup Enable */
|
||||
|
||||
/* Wake Up Status */
|
||||
#define E1000_WUS_LNKC E1000_WUFC_LNKC
|
||||
#define E1000_WUS_MAG E1000_WUFC_MAG
|
||||
#define E1000_WUS_EX E1000_WUFC_EX
|
||||
#define E1000_WUS_MC E1000_WUFC_MC
|
||||
#define E1000_WUS_BC E1000_WUFC_BC
|
||||
|
||||
/* Extended Device Control */
|
||||
#define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Definable Pin 7 */
|
||||
#define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */
|
||||
|
|
@ -77,6 +85,7 @@
|
|||
#define E1000_CTRL_EXT_IAME 0x08000000 /* Interrupt acknowledge Auto-mask */
|
||||
#define E1000_CTRL_EXT_INT_TIMER_CLR 0x20000000 /* Clear Interrupt timers after IMS clear */
|
||||
#define E1000_CTRL_EXT_PBA_CLR 0x80000000 /* PBA Clear */
|
||||
#define E1000_CTRL_EXT_PHYPDEN 0x00100000
|
||||
|
||||
/* Receive Descriptor bit definitions */
|
||||
#define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */
|
||||
|
|
@ -140,6 +149,7 @@
|
|||
#define E1000_RCTL_DTYP_PS 0x00000400 /* Packet Split descriptor */
|
||||
#define E1000_RCTL_RDMTS_HALF 0x00000000 /* Rx desc min threshold size */
|
||||
#define E1000_RCTL_MO_SHIFT 12 /* multicast offset shift */
|
||||
#define E1000_RCTL_MO_3 0x00003000 /* multicast offset 15:4 */
|
||||
#define E1000_RCTL_BAM 0x00008000 /* broadcast enable */
|
||||
/* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */
|
||||
#define E1000_RCTL_SZ_2048 0x00000000 /* Rx buffer size 2048 */
|
||||
|
|
@ -153,6 +163,7 @@
|
|||
#define E1000_RCTL_VFE 0x00040000 /* vlan filter enable */
|
||||
#define E1000_RCTL_CFIEN 0x00080000 /* canonical form enable */
|
||||
#define E1000_RCTL_CFI 0x00100000 /* canonical form indicator */
|
||||
#define E1000_RCTL_PMCF 0x00800000 /* pass MAC control frames */
|
||||
#define E1000_RCTL_BSEX 0x02000000 /* Buffer size extension */
|
||||
#define E1000_RCTL_SECRC 0x04000000 /* Strip Ethernet CRC */
|
||||
|
||||
|
|
@ -255,11 +266,16 @@
|
|||
#define AUTONEG_ADVERTISE_SPEED_DEFAULT E1000_ALL_SPEED_DUPLEX
|
||||
|
||||
/* LED Control */
|
||||
#define E1000_PHY_LED0_MODE_MASK 0x00000007
|
||||
#define E1000_PHY_LED0_IVRT 0x00000008
|
||||
#define E1000_PHY_LED0_MASK 0x0000001F
|
||||
|
||||
#define E1000_LEDCTL_LED0_MODE_MASK 0x0000000F
|
||||
#define E1000_LEDCTL_LED0_MODE_SHIFT 0
|
||||
#define E1000_LEDCTL_LED0_IVRT 0x00000040
|
||||
#define E1000_LEDCTL_LED0_BLINK 0x00000080
|
||||
|
||||
#define E1000_LEDCTL_MODE_LINK_UP 0x2
|
||||
#define E1000_LEDCTL_MODE_LED_ON 0xE
|
||||
#define E1000_LEDCTL_MODE_LED_OFF 0xF
|
||||
|
||||
|
|
@ -360,6 +376,8 @@
|
|||
#define E1000_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */
|
||||
#define E1000_SWSM_DRV_LOAD 0x00000008 /* Driver Loaded Bit */
|
||||
|
||||
#define E1000_SWSM2_LOCK 0x00000002 /* Secondary driver semaphore bit */
|
||||
|
||||
/* Interrupt Cause Read */
|
||||
#define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */
|
||||
#define E1000_ICR_LSC 0x00000004 /* Link Status Change */
|
||||
|
|
@ -469,6 +487,8 @@
|
|||
#define AUTO_READ_DONE_TIMEOUT 10
|
||||
|
||||
/* Flow Control */
|
||||
#define E1000_FCRTH_RTH 0x0000FFF8 /* Mask Bits[15:3] for RTH */
|
||||
#define E1000_FCRTL_RTL 0x0000FFF8 /* Mask Bits[15:3] for RTL */
|
||||
#define E1000_FCRTL_XONE 0x80000000 /* Enable XON frame transmission */
|
||||
|
||||
/* Transmit Configuration Word */
|
||||
|
|
@ -674,6 +694,8 @@
|
|||
#define IFE_C_E_PHY_ID 0x02A80310
|
||||
#define BME1000_E_PHY_ID 0x01410CB0
|
||||
#define BME1000_E_PHY_ID_R2 0x01410CB1
|
||||
#define I82577_E_PHY_ID 0x01540050
|
||||
#define I82578_E_PHY_ID 0x004DD040
|
||||
|
||||
/* M88E1000 Specific Registers */
|
||||
#define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */
|
||||
|
|
@ -727,6 +749,9 @@
|
|||
#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK 0x0E00
|
||||
#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X 0x0800
|
||||
|
||||
#define I82578_EPSCR_DOWNSHIFT_ENABLE 0x0020
|
||||
#define I82578_EPSCR_DOWNSHIFT_COUNTER_MASK 0x001C
|
||||
|
||||
/* BME1000 PHY Specific Control Register */
|
||||
#define BME1000_PSCR_ENABLE_DOWNSHIFT 0x0800 /* 1 = enable downshift */
|
||||
|
||||
|
|
|
|||
|
|
@ -96,6 +96,51 @@ struct e1000_info;
|
|||
/* Number of packet split data buffers (not including the header buffer) */
|
||||
#define PS_PAGE_BUFFERS (MAX_PS_BUFFERS - 1)
|
||||
|
||||
#define DEFAULT_JUMBO 9234
|
||||
|
||||
/* BM/HV Specific Registers */
|
||||
#define BM_PORT_CTRL_PAGE 769
|
||||
|
||||
#define PHY_UPPER_SHIFT 21
|
||||
#define BM_PHY_REG(page, reg) \
|
||||
(((reg) & MAX_PHY_REG_ADDRESS) |\
|
||||
(((page) & 0xFFFF) << PHY_PAGE_SHIFT) |\
|
||||
(((reg) & ~MAX_PHY_REG_ADDRESS) << (PHY_UPPER_SHIFT - PHY_PAGE_SHIFT)))
|
||||
|
||||
/* PHY Wakeup Registers and defines */
|
||||
#define BM_RCTL PHY_REG(BM_WUC_PAGE, 0)
|
||||
#define BM_WUC PHY_REG(BM_WUC_PAGE, 1)
|
||||
#define BM_WUFC PHY_REG(BM_WUC_PAGE, 2)
|
||||
#define BM_WUS PHY_REG(BM_WUC_PAGE, 3)
|
||||
#define BM_RAR_L(_i) (BM_PHY_REG(BM_WUC_PAGE, 16 + ((_i) << 2)))
|
||||
#define BM_RAR_M(_i) (BM_PHY_REG(BM_WUC_PAGE, 17 + ((_i) << 2)))
|
||||
#define BM_RAR_H(_i) (BM_PHY_REG(BM_WUC_PAGE, 18 + ((_i) << 2)))
|
||||
#define BM_RAR_CTRL(_i) (BM_PHY_REG(BM_WUC_PAGE, 19 + ((_i) << 2)))
|
||||
#define BM_MTA(_i) (BM_PHY_REG(BM_WUC_PAGE, 128 + ((_i) << 1)))
|
||||
|
||||
#define BM_RCTL_UPE 0x0001 /* Unicast Promiscuous Mode */
|
||||
#define BM_RCTL_MPE 0x0002 /* Multicast Promiscuous Mode */
|
||||
#define BM_RCTL_MO_SHIFT 3 /* Multicast Offset Shift */
|
||||
#define BM_RCTL_MO_MASK (3 << 3) /* Multicast Offset Mask */
|
||||
#define BM_RCTL_BAM 0x0020 /* Broadcast Accept Mode */
|
||||
#define BM_RCTL_PMCF 0x0040 /* Pass MAC Control Frames */
|
||||
#define BM_RCTL_RFCE 0x0080 /* Rx Flow Control Enable */
|
||||
|
||||
#define HV_SCC_UPPER PHY_REG(778, 16) /* Single Collision Count */
|
||||
#define HV_SCC_LOWER PHY_REG(778, 17)
|
||||
#define HV_ECOL_UPPER PHY_REG(778, 18) /* Excessive Collision Count */
|
||||
#define HV_ECOL_LOWER PHY_REG(778, 19)
|
||||
#define HV_MCC_UPPER PHY_REG(778, 20) /* Multiple Collision Count */
|
||||
#define HV_MCC_LOWER PHY_REG(778, 21)
|
||||
#define HV_LATECOL_UPPER PHY_REG(778, 23) /* Late Collision Count */
|
||||
#define HV_LATECOL_LOWER PHY_REG(778, 24)
|
||||
#define HV_COLC_UPPER PHY_REG(778, 25) /* Collision Count */
|
||||
#define HV_COLC_LOWER PHY_REG(778, 26)
|
||||
#define HV_DC_UPPER PHY_REG(778, 27) /* Defer Count */
|
||||
#define HV_DC_LOWER PHY_REG(778, 28)
|
||||
#define HV_TNCRS_UPPER PHY_REG(778, 29) /* Transmit with no CRS */
|
||||
#define HV_TNCRS_LOWER PHY_REG(778, 30)
|
||||
|
||||
enum e1000_boards {
|
||||
board_82571,
|
||||
board_82572,
|
||||
|
|
@ -106,6 +151,7 @@ enum e1000_boards {
|
|||
board_ich8lan,
|
||||
board_ich9lan,
|
||||
board_ich10lan,
|
||||
board_pchlan,
|
||||
};
|
||||
|
||||
struct e1000_queue_stats {
|
||||
|
|
@ -293,6 +339,7 @@ struct e1000_adapter {
|
|||
u32 eeprom_wol;
|
||||
u32 wol;
|
||||
u32 pba;
|
||||
u32 max_hw_frame_size;
|
||||
|
||||
bool fc_autoneg;
|
||||
|
||||
|
|
@ -302,6 +349,7 @@ struct e1000_adapter {
|
|||
unsigned int flags2;
|
||||
struct work_struct downshift_task;
|
||||
struct work_struct update_phy_task;
|
||||
struct work_struct led_blink_task;
|
||||
};
|
||||
|
||||
struct e1000_info {
|
||||
|
|
@ -309,6 +357,7 @@ struct e1000_info {
|
|||
unsigned int flags;
|
||||
unsigned int flags2;
|
||||
u32 pba;
|
||||
u32 max_hw_frame_size;
|
||||
s32 (*get_variants)(struct e1000_adapter *);
|
||||
struct e1000_mac_operations *mac_ops;
|
||||
struct e1000_phy_operations *phy_ops;
|
||||
|
|
@ -351,6 +400,7 @@ struct e1000_info {
|
|||
|
||||
/* CRC Stripping defines */
|
||||
#define FLAG2_CRC_STRIPPING (1 << 0)
|
||||
#define FLAG2_HAS_PHY_WAKEUP (1 << 1)
|
||||
|
||||
#define E1000_RX_DESC_PS(R, i) \
|
||||
(&(((union e1000_rx_desc_packet_split *)((R).desc))[i]))
|
||||
|
|
@ -404,6 +454,7 @@ extern struct e1000_info e1000_82583_info;
|
|||
extern struct e1000_info e1000_ich8_info;
|
||||
extern struct e1000_info e1000_ich9_info;
|
||||
extern struct e1000_info e1000_ich10_info;
|
||||
extern struct e1000_info e1000_pch_info;
|
||||
extern struct e1000_info e1000_es2_info;
|
||||
|
||||
extern s32 e1000e_read_pba_num(struct e1000_hw *hw, u32 *pba_num);
|
||||
|
|
@ -425,6 +476,7 @@ extern void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw);
|
|||
extern s32 e1000e_check_for_copper_link(struct e1000_hw *hw);
|
||||
extern s32 e1000e_check_for_fiber_link(struct e1000_hw *hw);
|
||||
extern s32 e1000e_check_for_serdes_link(struct e1000_hw *hw);
|
||||
extern s32 e1000e_setup_led_generic(struct e1000_hw *hw);
|
||||
extern s32 e1000e_cleanup_led_generic(struct e1000_hw *hw);
|
||||
extern s32 e1000e_led_on_generic(struct e1000_hw *hw);
|
||||
extern s32 e1000e_led_off_generic(struct e1000_hw *hw);
|
||||
|
|
@ -493,6 +545,15 @@ extern s32 e1000e_phy_reset_dsp(struct e1000_hw *hw);
|
|||
extern s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data);
|
||||
extern s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
|
||||
extern s32 e1000e_check_downshift(struct e1000_hw *hw);
|
||||
extern s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data);
|
||||
extern s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data);
|
||||
extern s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw, bool slow);
|
||||
extern s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw);
|
||||
extern s32 e1000_copper_link_setup_82577(struct e1000_hw *hw);
|
||||
extern s32 e1000_check_polarity_82577(struct e1000_hw *hw);
|
||||
extern s32 e1000_get_phy_info_82577(struct e1000_hw *hw);
|
||||
extern s32 e1000_phy_force_speed_duplex_82577(struct e1000_hw *hw);
|
||||
extern s32 e1000_get_cable_length_82577(struct e1000_hw *hw);
|
||||
|
||||
static inline s32 e1000_phy_hw_reset(struct e1000_hw *hw)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1366,6 +1366,7 @@ static void e1000_clear_hw_cntrs_80003es2lan(struct e1000_hw *hw)
|
|||
}
|
||||
|
||||
static struct e1000_mac_operations es2_mac_ops = {
|
||||
.id_led_init = e1000e_id_led_init,
|
||||
.check_mng_mode = e1000e_check_mng_mode_generic,
|
||||
/* check_for_link dependent on media type */
|
||||
.cleanup_led = e1000e_cleanup_led_generic,
|
||||
|
|
@ -1379,6 +1380,7 @@ static struct e1000_mac_operations es2_mac_ops = {
|
|||
.init_hw = e1000_init_hw_80003es2lan,
|
||||
.setup_link = e1000e_setup_link,
|
||||
/* setup_physical_interface dependent on media type */
|
||||
.setup_led = e1000e_setup_led_generic,
|
||||
};
|
||||
|
||||
static struct e1000_phy_operations es2_phy_ops = {
|
||||
|
|
@ -1422,6 +1424,7 @@ struct e1000_info e1000_es2_info = {
|
|||
| FLAG_DISABLE_FC_PAUSE_TIME /* errata */
|
||||
| FLAG_TIPG_MEDIUM_FOR_80003ESLAN,
|
||||
.pba = 38,
|
||||
.max_hw_frame_size = DEFAULT_JUMBO,
|
||||
.get_variants = e1000_get_variants_80003es2lan,
|
||||
.mac_ops = &es2_mac_ops,
|
||||
.phy_ops = &es2_phy_ops,
|
||||
|
|
|
|||
|
|
@ -167,6 +167,15 @@ static int e1000_get_settings(struct net_device *netdev,
|
|||
|
||||
ecmd->autoneg = ((hw->phy.media_type == e1000_media_type_fiber) ||
|
||||
hw->mac.autoneg) ? AUTONEG_ENABLE : AUTONEG_DISABLE;
|
||||
|
||||
/* MDI-X => 2; MDI =>1; Invalid =>0 */
|
||||
if ((hw->phy.media_type == e1000_media_type_copper) &&
|
||||
!hw->mac.get_link_status)
|
||||
ecmd->eth_tp_mdix = hw->phy.is_mdix ? ETH_TP_MDI_X :
|
||||
ETH_TP_MDI;
|
||||
else
|
||||
ecmd->eth_tp_mdix = ETH_TP_MDI_INVALID;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -776,6 +785,7 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
|
|||
u32 after;
|
||||
u32 i;
|
||||
u32 toggle;
|
||||
u32 mask;
|
||||
|
||||
/*
|
||||
* The status register is Read Only, so a write should fail.
|
||||
|
|
@ -788,17 +798,9 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
|
|||
case e1000_80003es2lan:
|
||||
toggle = 0x7FFFF3FF;
|
||||
break;
|
||||
case e1000_82573:
|
||||
case e1000_82574:
|
||||
case e1000_82583:
|
||||
case e1000_ich8lan:
|
||||
case e1000_ich9lan:
|
||||
case e1000_ich10lan:
|
||||
default:
|
||||
toggle = 0x7FFFF033;
|
||||
break;
|
||||
default:
|
||||
toggle = 0xFFFFF833;
|
||||
break;
|
||||
}
|
||||
|
||||
before = er32(STATUS);
|
||||
|
|
@ -844,11 +846,18 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
|
|||
REG_PATTERN_TEST(E1000_TXCW, 0xC000FFFF, 0x0000FFFF);
|
||||
REG_PATTERN_TEST(E1000_TDBAL, 0xFFFFFFF0, 0xFFFFFFFF);
|
||||
REG_PATTERN_TEST(E1000_TIDV, 0x0000FFFF, 0x0000FFFF);
|
||||
mask = 0x8003FFFF;
|
||||
switch (mac->type) {
|
||||
case e1000_ich10lan:
|
||||
case e1000_pchlan:
|
||||
mask |= (1 << 18);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < mac->rar_entry_count; i++)
|
||||
REG_PATTERN_TEST_ARRAY(E1000_RA, ((i << 1) + 1),
|
||||
((mac->type == e1000_ich10lan) ?
|
||||
0x8007FFFF : 0x8003FFFF),
|
||||
0xFFFFFFFF);
|
||||
mask, 0xFFFFFFFF);
|
||||
|
||||
for (i = 0; i < mac->mta_reg_count; i++)
|
||||
REG_PATTERN_TEST_ARRAY(E1000_MTA, i, 0xFFFFFFFF, 0xFFFFFFFF);
|
||||
|
|
@ -1786,15 +1795,22 @@ static int e1000_set_wol(struct net_device *netdev,
|
|||
/* bit defines for adapter->led_status */
|
||||
#define E1000_LED_ON 0
|
||||
|
||||
static void e1000_led_blink_callback(unsigned long data)
|
||||
static void e1000e_led_blink_task(struct work_struct *work)
|
||||
{
|
||||
struct e1000_adapter *adapter = (struct e1000_adapter *) data;
|
||||
struct e1000_adapter *adapter = container_of(work,
|
||||
struct e1000_adapter, led_blink_task);
|
||||
|
||||
if (test_and_change_bit(E1000_LED_ON, &adapter->led_status))
|
||||
adapter->hw.mac.ops.led_off(&adapter->hw);
|
||||
else
|
||||
adapter->hw.mac.ops.led_on(&adapter->hw);
|
||||
}
|
||||
|
||||
static void e1000_led_blink_callback(unsigned long data)
|
||||
{
|
||||
struct e1000_adapter *adapter = (struct e1000_adapter *) data;
|
||||
|
||||
schedule_work(&adapter->led_blink_task);
|
||||
mod_timer(&adapter->blink_timer, jiffies + E1000_ID_INTERVAL);
|
||||
}
|
||||
|
||||
|
|
@ -1807,7 +1823,9 @@ static int e1000_phys_id(struct net_device *netdev, u32 data)
|
|||
data = INT_MAX;
|
||||
|
||||
if ((hw->phy.type == e1000_phy_ife) ||
|
||||
(hw->mac.type == e1000_pchlan) ||
|
||||
(hw->mac.type == e1000_82574)) {
|
||||
INIT_WORK(&adapter->led_blink_task, e1000e_led_blink_task);
|
||||
if (!adapter->blink_timer.function) {
|
||||
init_timer(&adapter->blink_timer);
|
||||
adapter->blink_timer.function =
|
||||
|
|
|
|||
|
|
@ -193,7 +193,11 @@ enum e1e_registers {
|
|||
E1000_RXCSUM = 0x05000, /* Rx Checksum Control - RW */
|
||||
E1000_RFCTL = 0x05008, /* Receive Filter Control */
|
||||
E1000_MTA = 0x05200, /* Multicast Table Array - RW Array */
|
||||
E1000_RA = 0x05400, /* Receive Address - RW Array */
|
||||
E1000_RAL_BASE = 0x05400, /* Receive Address Low - RW */
|
||||
#define E1000_RAL(_n) (E1000_RAL_BASE + ((_n) * 8))
|
||||
#define E1000_RA (E1000_RAL(0))
|
||||
E1000_RAH_BASE = 0x05404, /* Receive Address High - RW */
|
||||
#define E1000_RAH(_n) (E1000_RAH_BASE + ((_n) * 8))
|
||||
E1000_VFTA = 0x05600, /* VLAN Filter Table Array - RW Array */
|
||||
E1000_WUC = 0x05800, /* Wakeup Control - RW */
|
||||
E1000_WUFC = 0x05808, /* Wakeup Filter Control - RW */
|
||||
|
|
@ -210,6 +214,7 @@ enum e1e_registers {
|
|||
E1000_FACTPS = 0x05B30, /* Function Active and Power State to MNG */
|
||||
E1000_SWSM = 0x05B50, /* SW Semaphore */
|
||||
E1000_FWSM = 0x05B54, /* FW Semaphore */
|
||||
E1000_SWSM2 = 0x05B58, /* Driver-only SW semaphore */
|
||||
E1000_HICR = 0x08F00, /* Host Interface Control */
|
||||
};
|
||||
|
||||
|
|
@ -253,7 +258,7 @@ enum e1e_registers {
|
|||
#define IGP01E1000_PLHR_SS_DOWNGRADE 0x8000
|
||||
|
||||
#define IGP01E1000_PSSR_POLARITY_REVERSED 0x0002
|
||||
#define IGP01E1000_PSSR_MDIX 0x0008
|
||||
#define IGP01E1000_PSSR_MDIX 0x0800
|
||||
#define IGP01E1000_PSSR_SPEED_MASK 0xC000
|
||||
#define IGP01E1000_PSSR_SPEED_1000MBPS 0xC000
|
||||
|
||||
|
|
@ -368,6 +373,10 @@ enum e1e_registers {
|
|||
#define E1000_DEV_ID_ICH10_R_BM_V 0x10CE
|
||||
#define E1000_DEV_ID_ICH10_D_BM_LM 0x10DE
|
||||
#define E1000_DEV_ID_ICH10_D_BM_LF 0x10DF
|
||||
#define E1000_DEV_ID_PCH_M_HV_LM 0x10EA
|
||||
#define E1000_DEV_ID_PCH_M_HV_LC 0x10EB
|
||||
#define E1000_DEV_ID_PCH_D_HV_DM 0x10EF
|
||||
#define E1000_DEV_ID_PCH_D_HV_DC 0x10F0
|
||||
|
||||
#define E1000_REVISION_4 4
|
||||
|
||||
|
|
@ -383,6 +392,7 @@ enum e1000_mac_type {
|
|||
e1000_ich8lan,
|
||||
e1000_ich9lan,
|
||||
e1000_ich10lan,
|
||||
e1000_pchlan,
|
||||
};
|
||||
|
||||
enum e1000_media_type {
|
||||
|
|
@ -417,6 +427,8 @@ enum e1000_phy_type {
|
|||
e1000_phy_igp_3,
|
||||
e1000_phy_ife,
|
||||
e1000_phy_bm,
|
||||
e1000_phy_82578,
|
||||
e1000_phy_82577,
|
||||
};
|
||||
|
||||
enum e1000_bus_width {
|
||||
|
|
@ -720,6 +732,7 @@ struct e1000_host_mng_command_info {
|
|||
|
||||
/* Function pointers and static data for the MAC. */
|
||||
struct e1000_mac_operations {
|
||||
s32 (*id_led_init)(struct e1000_hw *);
|
||||
bool (*check_mng_mode)(struct e1000_hw *);
|
||||
s32 (*check_for_link)(struct e1000_hw *);
|
||||
s32 (*cleanup_led)(struct e1000_hw *);
|
||||
|
|
@ -733,11 +746,13 @@ struct e1000_mac_operations {
|
|||
s32 (*init_hw)(struct e1000_hw *);
|
||||
s32 (*setup_link)(struct e1000_hw *);
|
||||
s32 (*setup_physical_interface)(struct e1000_hw *);
|
||||
s32 (*setup_led)(struct e1000_hw *);
|
||||
};
|
||||
|
||||
/* Function pointers for the PHY. */
|
||||
struct e1000_phy_operations {
|
||||
s32 (*acquire_phy)(struct e1000_hw *);
|
||||
s32 (*check_polarity)(struct e1000_hw *);
|
||||
s32 (*check_reset_block)(struct e1000_hw *);
|
||||
s32 (*commit_phy)(struct e1000_hw *);
|
||||
s32 (*force_speed_duplex)(struct e1000_hw *);
|
||||
|
|
@ -869,6 +884,7 @@ struct e1000_fc_info {
|
|||
struct e1000_dev_spec_82571 {
|
||||
bool laa_is_present;
|
||||
bool alt_mac_addr_is_present;
|
||||
u32 smb_counter;
|
||||
};
|
||||
|
||||
struct e1000_shadow_ram {
|
||||
|
|
|
|||
|
|
@ -48,6 +48,10 @@
|
|||
* 82567LF-3 Gigabit Network Connection
|
||||
* 82567LM-3 Gigabit Network Connection
|
||||
* 82567LM-4 Gigabit Network Connection
|
||||
* 82577LM Gigabit Network Connection
|
||||
* 82577LC Gigabit Network Connection
|
||||
* 82578DM Gigabit Network Connection
|
||||
* 82578DC Gigabit Network Connection
|
||||
*/
|
||||
|
||||
#include <linux/netdevice.h>
|
||||
|
|
@ -116,6 +120,8 @@
|
|||
#define IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK 0x0300
|
||||
#define IGP3_VR_CTRL_MODE_SHUTDOWN 0x0200
|
||||
|
||||
#define HV_LED_CONFIG PHY_REG(768, 30) /* LED Configuration */
|
||||
|
||||
/* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */
|
||||
/* Offset 04h HSFSTS */
|
||||
union ich8_hws_flash_status {
|
||||
|
|
@ -186,6 +192,14 @@ static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
|
|||
static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw);
|
||||
static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw);
|
||||
static s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw);
|
||||
static s32 e1000_cleanup_led_ich8lan(struct e1000_hw *hw);
|
||||
static s32 e1000_led_on_ich8lan(struct e1000_hw *hw);
|
||||
static s32 e1000_led_off_ich8lan(struct e1000_hw *hw);
|
||||
static s32 e1000_id_led_init_pchlan(struct e1000_hw *hw);
|
||||
static s32 e1000_setup_led_pchlan(struct e1000_hw *hw);
|
||||
static s32 e1000_cleanup_led_pchlan(struct e1000_hw *hw);
|
||||
static s32 e1000_led_on_pchlan(struct e1000_hw *hw);
|
||||
static s32 e1000_led_off_pchlan(struct e1000_hw *hw);
|
||||
|
||||
static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg)
|
||||
{
|
||||
|
|
@ -212,6 +226,41 @@ static inline void __ew32flash(struct e1000_hw *hw, unsigned long reg, u32 val)
|
|||
#define ew16flash(reg,val) __ew16flash(hw, (reg), (val))
|
||||
#define ew32flash(reg,val) __ew32flash(hw, (reg), (val))
|
||||
|
||||
/**
|
||||
* e1000_init_phy_params_pchlan - Initialize PHY function pointers
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Initialize family-specific PHY parameters and function pointers.
|
||||
**/
|
||||
static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_phy_info *phy = &hw->phy;
|
||||
s32 ret_val = 0;
|
||||
|
||||
phy->addr = 1;
|
||||
phy->reset_delay_us = 100;
|
||||
|
||||
phy->ops.check_polarity = e1000_check_polarity_ife_ich8lan;
|
||||
phy->ops.read_phy_reg = e1000_read_phy_reg_hv;
|
||||
phy->ops.write_phy_reg = e1000_write_phy_reg_hv;
|
||||
phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
|
||||
|
||||
phy->id = e1000_phy_unknown;
|
||||
e1000e_get_phy_id(hw);
|
||||
phy->type = e1000e_get_phy_type_from_id(phy->id);
|
||||
|
||||
if (phy->type == e1000_phy_82577) {
|
||||
phy->ops.check_polarity = e1000_check_polarity_82577;
|
||||
phy->ops.force_speed_duplex =
|
||||
e1000_phy_force_speed_duplex_82577;
|
||||
phy->ops.get_cable_length = e1000_get_cable_length_82577;
|
||||
phy->ops.get_phy_info = e1000_get_phy_info_82577;
|
||||
phy->ops.commit_phy = e1000e_phy_sw_reset;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_init_phy_params_ich8lan - Initialize PHY function pointers
|
||||
* @hw: pointer to the HW structure
|
||||
|
|
@ -273,6 +322,8 @@ static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw)
|
|||
break;
|
||||
}
|
||||
|
||||
phy->ops.check_polarity = e1000_check_polarity_ife_ich8lan;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -358,6 +409,36 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_adapter *adapter)
|
|||
/* Set if manageability features are enabled. */
|
||||
mac->arc_subsystem_valid = 1;
|
||||
|
||||
/* LED operations */
|
||||
switch (mac->type) {
|
||||
case e1000_ich8lan:
|
||||
case e1000_ich9lan:
|
||||
case e1000_ich10lan:
|
||||
/* ID LED init */
|
||||
mac->ops.id_led_init = e1000e_id_led_init;
|
||||
/* setup LED */
|
||||
mac->ops.setup_led = e1000e_setup_led_generic;
|
||||
/* cleanup LED */
|
||||
mac->ops.cleanup_led = e1000_cleanup_led_ich8lan;
|
||||
/* turn on/off LED */
|
||||
mac->ops.led_on = e1000_led_on_ich8lan;
|
||||
mac->ops.led_off = e1000_led_off_ich8lan;
|
||||
break;
|
||||
case e1000_pchlan:
|
||||
/* ID LED init */
|
||||
mac->ops.id_led_init = e1000_id_led_init_pchlan;
|
||||
/* setup LED */
|
||||
mac->ops.setup_led = e1000_setup_led_pchlan;
|
||||
/* cleanup LED */
|
||||
mac->ops.cleanup_led = e1000_cleanup_led_pchlan;
|
||||
/* turn on/off LED */
|
||||
mac->ops.led_on = e1000_led_on_pchlan;
|
||||
mac->ops.led_off = e1000_led_off_pchlan;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Enable PCS Lock-loss workaround for ICH8 */
|
||||
if (mac->type == e1000_ich8lan)
|
||||
e1000e_set_kmrn_lock_loss_workaround_ich8lan(hw, 1);
|
||||
|
|
@ -378,10 +459,18 @@ static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter)
|
|||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = e1000_init_phy_params_ich8lan(hw);
|
||||
if (hw->mac.type == e1000_pchlan)
|
||||
rc = e1000_init_phy_params_pchlan(hw);
|
||||
else
|
||||
rc = e1000_init_phy_params_ich8lan(hw);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (adapter->hw.phy.type == e1000_phy_ife) {
|
||||
adapter->flags &= ~FLAG_HAS_JUMBO_FRAMES;
|
||||
adapter->max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN;
|
||||
}
|
||||
|
||||
if ((adapter->hw.mac.type == e1000_ich8lan) &&
|
||||
(adapter->hw.phy.type == e1000_phy_igp_3))
|
||||
adapter->flags |= FLAG_LSC_GIG_SPEED_DROP;
|
||||
|
|
@ -410,12 +499,15 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
|
|||
|
||||
while (timeout) {
|
||||
extcnf_ctrl = er32(EXTCNF_CTRL);
|
||||
extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG;
|
||||
ew32(EXTCNF_CTRL, extcnf_ctrl);
|
||||
|
||||
extcnf_ctrl = er32(EXTCNF_CTRL);
|
||||
if (extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG)
|
||||
break;
|
||||
if (!(extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG)) {
|
||||
extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG;
|
||||
ew32(EXTCNF_CTRL, extcnf_ctrl);
|
||||
|
||||
extcnf_ctrl = er32(EXTCNF_CTRL);
|
||||
if (extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG)
|
||||
break;
|
||||
}
|
||||
mdelay(1);
|
||||
timeout--;
|
||||
}
|
||||
|
|
@ -554,6 +646,53 @@ static s32 e1000_phy_force_speed_duplex_ich8lan(struct e1000_hw *hw)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_hv_phy_workarounds_ich8lan - A series of Phy workarounds to be
|
||||
* done after every PHY reset.
|
||||
**/
|
||||
static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw)
|
||||
{
|
||||
s32 ret_val = 0;
|
||||
|
||||
if (hw->mac.type != e1000_pchlan)
|
||||
return ret_val;
|
||||
|
||||
if (((hw->phy.type == e1000_phy_82577) &&
|
||||
((hw->phy.revision == 1) || (hw->phy.revision == 2))) ||
|
||||
((hw->phy.type == e1000_phy_82578) && (hw->phy.revision == 1))) {
|
||||
/* Disable generation of early preamble */
|
||||
ret_val = e1e_wphy(hw, PHY_REG(769, 25), 0x4431);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
/* Preamble tuning for SSC */
|
||||
ret_val = e1e_wphy(hw, PHY_REG(770, 16), 0xA204);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
if (hw->phy.type == e1000_phy_82578) {
|
||||
/*
|
||||
* Return registers to default by doing a soft reset then
|
||||
* writing 0x3140 to the control register.
|
||||
*/
|
||||
if (hw->phy.revision < 2) {
|
||||
e1000e_phy_sw_reset(hw);
|
||||
ret_val = e1e_wphy(hw, PHY_CONTROL, 0x3140);
|
||||
}
|
||||
}
|
||||
|
||||
/* Select page 0 */
|
||||
ret_val = hw->phy.ops.acquire_phy(hw);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
hw->phy.addr = 1;
|
||||
e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 0);
|
||||
hw->phy.ops.release_phy(hw);
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_phy_hw_reset_ich8lan - Performs a PHY reset
|
||||
* @hw: pointer to the HW structure
|
||||
|
|
@ -575,6 +714,12 @@ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw)
|
|||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
if (hw->mac.type == e1000_pchlan) {
|
||||
ret_val = e1000_hv_phy_workarounds_ich8lan(hw);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the PHY from the NVM on ICH platforms. This
|
||||
* is needed due to an issue where the NVM configuration is
|
||||
|
|
@ -701,7 +846,7 @@ static s32 e1000_get_phy_info_ife_ich8lan(struct e1000_hw *hw)
|
|||
phy->polarity_correction = (!(data & IFE_PSC_AUTO_POLARITY_DISABLE));
|
||||
|
||||
if (phy->polarity_correction) {
|
||||
ret_val = e1000_check_polarity_ife_ich8lan(hw);
|
||||
ret_val = phy->ops.check_polarity(hw);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
} else {
|
||||
|
|
@ -741,6 +886,8 @@ static s32 e1000_get_phy_info_ich8lan(struct e1000_hw *hw)
|
|||
break;
|
||||
case e1000_phy_igp_3:
|
||||
case e1000_phy_bm:
|
||||
case e1000_phy_82578:
|
||||
case e1000_phy_82577:
|
||||
return e1000e_get_phy_info_igp(hw);
|
||||
break;
|
||||
default:
|
||||
|
|
@ -1851,6 +1998,79 @@ static s32 e1000_valid_led_default_ich8lan(struct e1000_hw *hw, u16 *data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_id_led_init_pchlan - store LED configurations
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* PCH does not control LEDs via the LEDCTL register, rather it uses
|
||||
* the PHY LED configuration register.
|
||||
*
|
||||
* PCH also does not have an "always on" or "always off" mode which
|
||||
* complicates the ID feature. Instead of using the "on" mode to indicate
|
||||
* in ledctl_mode2 the LEDs to use for ID (see e1000e_id_led_init()),
|
||||
* use "link_up" mode. The LEDs will still ID on request if there is no
|
||||
* link based on logic in e1000_led_[on|off]_pchlan().
|
||||
**/
|
||||
static s32 e1000_id_led_init_pchlan(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_mac_info *mac = &hw->mac;
|
||||
s32 ret_val;
|
||||
const u32 ledctl_on = E1000_LEDCTL_MODE_LINK_UP;
|
||||
const u32 ledctl_off = E1000_LEDCTL_MODE_LINK_UP | E1000_PHY_LED0_IVRT;
|
||||
u16 data, i, temp, shift;
|
||||
|
||||
/* Get default ID LED modes */
|
||||
ret_val = hw->nvm.ops.valid_led_default(hw, &data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
mac->ledctl_default = er32(LEDCTL);
|
||||
mac->ledctl_mode1 = mac->ledctl_default;
|
||||
mac->ledctl_mode2 = mac->ledctl_default;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
temp = (data >> (i << 2)) & E1000_LEDCTL_LED0_MODE_MASK;
|
||||
shift = (i * 5);
|
||||
switch (temp) {
|
||||
case ID_LED_ON1_DEF2:
|
||||
case ID_LED_ON1_ON2:
|
||||
case ID_LED_ON1_OFF2:
|
||||
mac->ledctl_mode1 &= ~(E1000_PHY_LED0_MASK << shift);
|
||||
mac->ledctl_mode1 |= (ledctl_on << shift);
|
||||
break;
|
||||
case ID_LED_OFF1_DEF2:
|
||||
case ID_LED_OFF1_ON2:
|
||||
case ID_LED_OFF1_OFF2:
|
||||
mac->ledctl_mode1 &= ~(E1000_PHY_LED0_MASK << shift);
|
||||
mac->ledctl_mode1 |= (ledctl_off << shift);
|
||||
break;
|
||||
default:
|
||||
/* Do nothing */
|
||||
break;
|
||||
}
|
||||
switch (temp) {
|
||||
case ID_LED_DEF1_ON2:
|
||||
case ID_LED_ON1_ON2:
|
||||
case ID_LED_OFF1_ON2:
|
||||
mac->ledctl_mode2 &= ~(E1000_PHY_LED0_MASK << shift);
|
||||
mac->ledctl_mode2 |= (ledctl_on << shift);
|
||||
break;
|
||||
case ID_LED_DEF1_OFF2:
|
||||
case ID_LED_ON1_OFF2:
|
||||
case ID_LED_OFF1_OFF2:
|
||||
mac->ledctl_mode2 &= ~(E1000_PHY_LED0_MASK << shift);
|
||||
mac->ledctl_mode2 |= (ledctl_off << shift);
|
||||
break;
|
||||
default:
|
||||
/* Do nothing */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_get_bus_info_ich8lan - Get/Set the bus type and width
|
||||
* @hw: pointer to the HW structure
|
||||
|
|
@ -1960,6 +2180,9 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
|
|||
kab |= E1000_KABGTXD_BGSQLBIAS;
|
||||
ew32(KABGTXD, kab);
|
||||
|
||||
if (hw->mac.type == e1000_pchlan)
|
||||
ret_val = e1000_hv_phy_workarounds_ich8lan(hw);
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
|
|
@ -1985,7 +2208,7 @@ static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw)
|
|||
e1000_initialize_hw_bits_ich8lan(hw);
|
||||
|
||||
/* Initialize identification LED */
|
||||
ret_val = e1000e_id_led_init(hw);
|
||||
ret_val = mac->ops.id_led_init(hw);
|
||||
if (ret_val) {
|
||||
hw_dbg(hw, "Error initializing identification LED\n");
|
||||
return ret_val;
|
||||
|
|
@ -2030,6 +2253,16 @@ static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw)
|
|||
ctrl_ext |= E1000_CTRL_EXT_RO_DIS;
|
||||
ew32(CTRL_EXT, ctrl_ext);
|
||||
|
||||
/*
|
||||
* The 82578 Rx buffer will stall if wakeup is enabled in host and
|
||||
* the ME. Reading the BM_WUC register will clear the host wakeup bit.
|
||||
* Reset the phy after disabling host wakeup to reset the Rx buffer.
|
||||
*/
|
||||
if (hw->phy.type == e1000_phy_82578) {
|
||||
e1e_rphy(hw, BM_WUC, &i);
|
||||
e1000e_phy_hw_reset_generic(hw);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear all of the statistics registers (clear on read). It is
|
||||
* important that we do this after we have tried to establish link
|
||||
|
|
@ -2054,6 +2287,9 @@ static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw)
|
|||
/* Extended Device Control */
|
||||
reg = er32(CTRL_EXT);
|
||||
reg |= (1 << 22);
|
||||
/* Enable PHY low-power state when MAC is at D3 w/o WoL */
|
||||
if (hw->mac.type >= e1000_pchlan)
|
||||
reg |= E1000_CTRL_EXT_PHYPDEN;
|
||||
ew32(CTRL_EXT, reg);
|
||||
|
||||
/* Transmit Descriptor Control 0 */
|
||||
|
|
@ -2112,8 +2348,13 @@ static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw)
|
|||
* the default flow control setting, so we explicitly
|
||||
* set it to full.
|
||||
*/
|
||||
if (hw->fc.requested_mode == e1000_fc_default)
|
||||
hw->fc.requested_mode = e1000_fc_full;
|
||||
if (hw->fc.requested_mode == e1000_fc_default) {
|
||||
/* Workaround h/w hang when Tx flow control enabled */
|
||||
if (hw->mac.type == e1000_pchlan)
|
||||
hw->fc.requested_mode = e1000_fc_rx_pause;
|
||||
else
|
||||
hw->fc.requested_mode = e1000_fc_full;
|
||||
}
|
||||
|
||||
/*
|
||||
* Save off the requested flow control mode for use later. Depending
|
||||
|
|
@ -2130,6 +2371,14 @@ static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw)
|
|||
return ret_val;
|
||||
|
||||
ew32(FCTTV, hw->fc.pause_time);
|
||||
if ((hw->phy.type == e1000_phy_82578) ||
|
||||
(hw->phy.type == e1000_phy_82577)) {
|
||||
ret_val = hw->phy.ops.write_phy_reg(hw,
|
||||
PHY_REG(BM_PORT_CTRL_PAGE, 27),
|
||||
hw->fc.pause_time);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
return e1000e_set_fc_watermarks(hw);
|
||||
}
|
||||
|
|
@ -2169,18 +2418,26 @@ static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw)
|
|||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
if (hw->phy.type == e1000_phy_igp_3) {
|
||||
switch (hw->phy.type) {
|
||||
case e1000_phy_igp_3:
|
||||
ret_val = e1000e_copper_link_setup_igp(hw);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
} else if (hw->phy.type == e1000_phy_bm) {
|
||||
break;
|
||||
case e1000_phy_bm:
|
||||
case e1000_phy_82578:
|
||||
ret_val = e1000e_copper_link_setup_m88(hw);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
if (hw->phy.type == e1000_phy_ife) {
|
||||
ret_val = e1e_rphy(hw, IFE_PHY_MDIX_CONTROL, ®_data);
|
||||
break;
|
||||
case e1000_phy_82577:
|
||||
ret_val = e1000_copper_link_setup_82577(hw);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
break;
|
||||
case e1000_phy_ife:
|
||||
ret_val = hw->phy.ops.read_phy_reg(hw, IFE_PHY_MDIX_CONTROL,
|
||||
®_data);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
|
|
@ -2198,9 +2455,13 @@ static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw)
|
|||
reg_data |= IFE_PMC_AUTO_MDIX;
|
||||
break;
|
||||
}
|
||||
ret_val = e1e_wphy(hw, IFE_PHY_MDIX_CONTROL, reg_data);
|
||||
ret_val = hw->phy.ops.write_phy_reg(hw, IFE_PHY_MDIX_CONTROL,
|
||||
reg_data);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return e1000e_setup_copper_link(hw);
|
||||
}
|
||||
|
|
@ -2417,18 +2678,26 @@ void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw)
|
|||
* 'LPLU Enabled' and 'Gig Disable' to force link speed negotiation
|
||||
* to a lower speed.
|
||||
*
|
||||
* Should only be called for ICH9 and ICH10 devices.
|
||||
* Should only be called for applicable parts.
|
||||
**/
|
||||
void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw)
|
||||
{
|
||||
u32 phy_ctrl;
|
||||
|
||||
if ((hw->mac.type == e1000_ich10lan) ||
|
||||
(hw->mac.type == e1000_ich9lan)) {
|
||||
switch (hw->mac.type) {
|
||||
case e1000_ich9lan:
|
||||
case e1000_ich10lan:
|
||||
case e1000_pchlan:
|
||||
phy_ctrl = er32(PHY_CTRL);
|
||||
phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU |
|
||||
E1000_PHY_CTRL_GBE_DISABLE;
|
||||
ew32(PHY_CTRL, phy_ctrl);
|
||||
|
||||
/* Workaround SWFLAG unexpectedly set during S0->Sx */
|
||||
if (hw->mac.type == e1000_pchlan)
|
||||
udelay(500);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
|
|
@ -2481,6 +2750,92 @@ static s32 e1000_led_off_ich8lan(struct e1000_hw *hw)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_setup_led_pchlan - Configures SW controllable LED
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* This prepares the SW controllable LED for use.
|
||||
**/
|
||||
static s32 e1000_setup_led_pchlan(struct e1000_hw *hw)
|
||||
{
|
||||
return hw->phy.ops.write_phy_reg(hw, HV_LED_CONFIG,
|
||||
(u16)hw->mac.ledctl_mode1);
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_cleanup_led_pchlan - Restore the default LED operation
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Return the LED back to the default configuration.
|
||||
**/
|
||||
static s32 e1000_cleanup_led_pchlan(struct e1000_hw *hw)
|
||||
{
|
||||
return hw->phy.ops.write_phy_reg(hw, HV_LED_CONFIG,
|
||||
(u16)hw->mac.ledctl_default);
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_led_on_pchlan - Turn LEDs on
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Turn on the LEDs.
|
||||
**/
|
||||
static s32 e1000_led_on_pchlan(struct e1000_hw *hw)
|
||||
{
|
||||
u16 data = (u16)hw->mac.ledctl_mode2;
|
||||
u32 i, led;
|
||||
|
||||
/*
|
||||
* If no link, then turn LED on by setting the invert bit
|
||||
* for each LED that's mode is "link_up" in ledctl_mode2.
|
||||
*/
|
||||
if (!(er32(STATUS) & E1000_STATUS_LU)) {
|
||||
for (i = 0; i < 3; i++) {
|
||||
led = (data >> (i * 5)) & E1000_PHY_LED0_MASK;
|
||||
if ((led & E1000_PHY_LED0_MODE_MASK) !=
|
||||
E1000_LEDCTL_MODE_LINK_UP)
|
||||
continue;
|
||||
if (led & E1000_PHY_LED0_IVRT)
|
||||
data &= ~(E1000_PHY_LED0_IVRT << (i * 5));
|
||||
else
|
||||
data |= (E1000_PHY_LED0_IVRT << (i * 5));
|
||||
}
|
||||
}
|
||||
|
||||
return hw->phy.ops.write_phy_reg(hw, HV_LED_CONFIG, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_led_off_pchlan - Turn LEDs off
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Turn off the LEDs.
|
||||
**/
|
||||
static s32 e1000_led_off_pchlan(struct e1000_hw *hw)
|
||||
{
|
||||
u16 data = (u16)hw->mac.ledctl_mode1;
|
||||
u32 i, led;
|
||||
|
||||
/*
|
||||
* If no link, then turn LED off by clearing the invert bit
|
||||
* for each LED that's mode is "link_up" in ledctl_mode1.
|
||||
*/
|
||||
if (!(er32(STATUS) & E1000_STATUS_LU)) {
|
||||
for (i = 0; i < 3; i++) {
|
||||
led = (data >> (i * 5)) & E1000_PHY_LED0_MASK;
|
||||
if ((led & E1000_PHY_LED0_MODE_MASK) !=
|
||||
E1000_LEDCTL_MODE_LINK_UP)
|
||||
continue;
|
||||
if (led & E1000_PHY_LED0_IVRT)
|
||||
data &= ~(E1000_PHY_LED0_IVRT << (i * 5));
|
||||
else
|
||||
data |= (E1000_PHY_LED0_IVRT << (i * 5));
|
||||
}
|
||||
}
|
||||
|
||||
return hw->phy.ops.write_phy_reg(hw, HV_LED_CONFIG, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_get_cfg_done_ich8lan - Read config done bit
|
||||
* @hw: pointer to the HW structure
|
||||
|
|
@ -2488,7 +2843,7 @@ static s32 e1000_led_off_ich8lan(struct e1000_hw *hw)
|
|||
* Read the management control register for the config done bit for
|
||||
* completion status. NOTE: silicon which is EEPROM-less will fail trying
|
||||
* to read the config done bit, so an error is *ONLY* logged and returns
|
||||
* E1000_SUCCESS. If we were to return with error, EEPROM-less silicon
|
||||
* 0. If we were to return with error, EEPROM-less silicon
|
||||
* would not be able to be reset or change link.
|
||||
**/
|
||||
static s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw)
|
||||
|
|
@ -2498,7 +2853,8 @@ static s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw)
|
|||
e1000e_get_cfg_done(hw);
|
||||
|
||||
/* If EEPROM is not marked present, init the IGP 3 PHY manually */
|
||||
if (hw->mac.type != e1000_ich10lan) {
|
||||
if ((hw->mac.type != e1000_ich10lan) &&
|
||||
(hw->mac.type != e1000_pchlan)) {
|
||||
if (((er32(EECD) & E1000_EECD_PRES) == 0) &&
|
||||
(hw->phy.type == e1000_phy_igp_3)) {
|
||||
e1000e_phy_init_script_igp3(hw);
|
||||
|
|
@ -2524,6 +2880,7 @@ static s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw)
|
|||
static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw)
|
||||
{
|
||||
u32 temp;
|
||||
u16 phy_data;
|
||||
|
||||
e1000e_clear_hw_cntrs_base(hw);
|
||||
|
||||
|
|
@ -2541,22 +2898,42 @@ static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw)
|
|||
temp = er32(IAC);
|
||||
temp = er32(ICRXOC);
|
||||
|
||||
/* Clear PHY statistics registers */
|
||||
if ((hw->phy.type == e1000_phy_82578) ||
|
||||
(hw->phy.type == e1000_phy_82577)) {
|
||||
hw->phy.ops.read_phy_reg(hw, HV_SCC_UPPER, &phy_data);
|
||||
hw->phy.ops.read_phy_reg(hw, HV_SCC_LOWER, &phy_data);
|
||||
hw->phy.ops.read_phy_reg(hw, HV_ECOL_UPPER, &phy_data);
|
||||
hw->phy.ops.read_phy_reg(hw, HV_ECOL_LOWER, &phy_data);
|
||||
hw->phy.ops.read_phy_reg(hw, HV_MCC_UPPER, &phy_data);
|
||||
hw->phy.ops.read_phy_reg(hw, HV_MCC_LOWER, &phy_data);
|
||||
hw->phy.ops.read_phy_reg(hw, HV_LATECOL_UPPER, &phy_data);
|
||||
hw->phy.ops.read_phy_reg(hw, HV_LATECOL_LOWER, &phy_data);
|
||||
hw->phy.ops.read_phy_reg(hw, HV_COLC_UPPER, &phy_data);
|
||||
hw->phy.ops.read_phy_reg(hw, HV_COLC_LOWER, &phy_data);
|
||||
hw->phy.ops.read_phy_reg(hw, HV_DC_UPPER, &phy_data);
|
||||
hw->phy.ops.read_phy_reg(hw, HV_DC_LOWER, &phy_data);
|
||||
hw->phy.ops.read_phy_reg(hw, HV_TNCRS_UPPER, &phy_data);
|
||||
hw->phy.ops.read_phy_reg(hw, HV_TNCRS_LOWER, &phy_data);
|
||||
}
|
||||
}
|
||||
|
||||
static struct e1000_mac_operations ich8_mac_ops = {
|
||||
.id_led_init = e1000e_id_led_init,
|
||||
.check_mng_mode = e1000_check_mng_mode_ich8lan,
|
||||
.check_for_link = e1000e_check_for_copper_link,
|
||||
.cleanup_led = e1000_cleanup_led_ich8lan,
|
||||
/* cleanup_led dependent on mac type */
|
||||
.clear_hw_cntrs = e1000_clear_hw_cntrs_ich8lan,
|
||||
.get_bus_info = e1000_get_bus_info_ich8lan,
|
||||
.get_link_up_info = e1000_get_link_up_info_ich8lan,
|
||||
.led_on = e1000_led_on_ich8lan,
|
||||
.led_off = e1000_led_off_ich8lan,
|
||||
/* led_on dependent on mac type */
|
||||
/* led_off dependent on mac type */
|
||||
.update_mc_addr_list = e1000e_update_mc_addr_list_generic,
|
||||
.reset_hw = e1000_reset_hw_ich8lan,
|
||||
.init_hw = e1000_init_hw_ich8lan,
|
||||
.setup_link = e1000_setup_link_ich8lan,
|
||||
.setup_physical_interface= e1000_setup_copper_link_ich8lan,
|
||||
/* id_led_init dependent on mac type */
|
||||
};
|
||||
|
||||
static struct e1000_phy_operations ich8_phy_ops = {
|
||||
|
|
@ -2595,6 +2972,7 @@ struct e1000_info e1000_ich8_info = {
|
|||
| FLAG_HAS_FLASH
|
||||
| FLAG_APME_IN_WUC,
|
||||
.pba = 8,
|
||||
.max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN,
|
||||
.get_variants = e1000_get_variants_ich8lan,
|
||||
.mac_ops = &ich8_mac_ops,
|
||||
.phy_ops = &ich8_phy_ops,
|
||||
|
|
@ -2613,6 +2991,7 @@ struct e1000_info e1000_ich9_info = {
|
|||
| FLAG_HAS_FLASH
|
||||
| FLAG_APME_IN_WUC,
|
||||
.pba = 10,
|
||||
.max_hw_frame_size = DEFAULT_JUMBO,
|
||||
.get_variants = e1000_get_variants_ich8lan,
|
||||
.mac_ops = &ich8_mac_ops,
|
||||
.phy_ops = &ich8_phy_ops,
|
||||
|
|
@ -2631,6 +3010,25 @@ struct e1000_info e1000_ich10_info = {
|
|||
| FLAG_HAS_FLASH
|
||||
| FLAG_APME_IN_WUC,
|
||||
.pba = 10,
|
||||
.max_hw_frame_size = DEFAULT_JUMBO,
|
||||
.get_variants = e1000_get_variants_ich8lan,
|
||||
.mac_ops = &ich8_mac_ops,
|
||||
.phy_ops = &ich8_phy_ops,
|
||||
.nvm_ops = &ich8_nvm_ops,
|
||||
};
|
||||
|
||||
struct e1000_info e1000_pch_info = {
|
||||
.mac = e1000_pchlan,
|
||||
.flags = FLAG_IS_ICH
|
||||
| FLAG_HAS_WOL
|
||||
| FLAG_RX_CSUM_ENABLED
|
||||
| FLAG_HAS_CTRLEXT_ON_LOAD
|
||||
| FLAG_HAS_AMT
|
||||
| FLAG_HAS_FLASH
|
||||
| FLAG_HAS_JUMBO_FRAMES
|
||||
| FLAG_APME_IN_WUC,
|
||||
.pba = 26,
|
||||
.max_hw_frame_size = 4096,
|
||||
.get_variants = e1000_get_variants_ich8lan,
|
||||
.mac_ops = &ich8_mac_ops,
|
||||
.phy_ops = &ich8_phy_ops,
|
||||
|
|
|
|||
|
|
@ -378,6 +378,12 @@ s32 e1000e_check_for_copper_link(struct e1000_hw *hw)
|
|||
|
||||
mac->get_link_status = 0;
|
||||
|
||||
if (hw->phy.type == e1000_phy_82578) {
|
||||
ret_val = e1000_link_stall_workaround_hv(hw);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if there was DownShift, must be checked
|
||||
* immediately after link-up
|
||||
|
|
@ -1405,6 +1411,38 @@ s32 e1000e_id_led_init(struct e1000_hw *hw)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000e_setup_led_generic - Configures SW controllable LED
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* This prepares the SW controllable LED for use and saves the current state
|
||||
* of the LED so it can be later restored.
|
||||
**/
|
||||
s32 e1000e_setup_led_generic(struct e1000_hw *hw)
|
||||
{
|
||||
u32 ledctl;
|
||||
|
||||
if (hw->mac.ops.setup_led != e1000e_setup_led_generic) {
|
||||
return -E1000_ERR_CONFIG;
|
||||
}
|
||||
|
||||
if (hw->phy.media_type == e1000_media_type_fiber) {
|
||||
ledctl = er32(LEDCTL);
|
||||
hw->mac.ledctl_default = ledctl;
|
||||
/* Turn off LED0 */
|
||||
ledctl &= ~(E1000_LEDCTL_LED0_IVRT |
|
||||
E1000_LEDCTL_LED0_BLINK |
|
||||
E1000_LEDCTL_LED0_MODE_MASK);
|
||||
ledctl |= (E1000_LEDCTL_MODE_LED_OFF <<
|
||||
E1000_LEDCTL_LED0_MODE_SHIFT);
|
||||
ew32(LEDCTL, ledctl);
|
||||
} else if (hw->phy.media_type == e1000_media_type_copper) {
|
||||
ew32(LEDCTL, hw->mac.ledctl_mode1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000e_cleanup_led_generic - Set LED config to default operation
|
||||
* @hw: pointer to the HW structure
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@
|
|||
|
||||
#include "e1000.h"
|
||||
|
||||
#define DRV_VERSION "0.3.3.4-k4"
|
||||
#define DRV_VERSION "1.0.2-k2"
|
||||
char e1000e_driver_name[] = "e1000e";
|
||||
const char e1000e_driver_version[] = DRV_VERSION;
|
||||
|
||||
|
|
@ -62,6 +62,7 @@ static const struct e1000_info *e1000_info_tbl[] = {
|
|||
[board_ich8lan] = &e1000_ich8_info,
|
||||
[board_ich9lan] = &e1000_ich9_info,
|
||||
[board_ich10lan] = &e1000_ich10_info,
|
||||
[board_pchlan] = &e1000_pch_info,
|
||||
};
|
||||
|
||||
#ifdef DEBUG
|
||||
|
|
@ -2255,8 +2256,6 @@ static void e1000_configure_tx(struct e1000_adapter *adapter)
|
|||
ew32(TARC(1), tarc);
|
||||
}
|
||||
|
||||
e1000e_config_collision_dist(hw);
|
||||
|
||||
/* Setup Transmit Descriptor Settings for eop descriptor */
|
||||
adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS;
|
||||
|
||||
|
|
@ -2269,6 +2268,8 @@ static void e1000_configure_tx(struct e1000_adapter *adapter)
|
|||
|
||||
ew32(TCTL, tctl);
|
||||
|
||||
e1000e_config_collision_dist(hw);
|
||||
|
||||
adapter->tx_queue_len = adapter->netdev->tx_queue_len;
|
||||
}
|
||||
|
||||
|
|
@ -2308,6 +2309,23 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
|
|||
if (adapter->flags2 & FLAG2_CRC_STRIPPING)
|
||||
rctl |= E1000_RCTL_SECRC;
|
||||
|
||||
/* Workaround Si errata on 82577 PHY - configure IPG for jumbos */
|
||||
if ((hw->phy.type == e1000_phy_82577) && (rctl & E1000_RCTL_LPE)) {
|
||||
u16 phy_data;
|
||||
|
||||
e1e_rphy(hw, PHY_REG(770, 26), &phy_data);
|
||||
phy_data &= 0xfff8;
|
||||
phy_data |= (1 << 2);
|
||||
e1e_wphy(hw, PHY_REG(770, 26), phy_data);
|
||||
|
||||
e1e_rphy(hw, 22, &phy_data);
|
||||
phy_data &= 0x0fff;
|
||||
phy_data |= (1 << 14);
|
||||
e1e_wphy(hw, 0x10, 0x2823);
|
||||
e1e_wphy(hw, 0x11, 0x0003);
|
||||
e1e_wphy(hw, 22, phy_data);
|
||||
}
|
||||
|
||||
/* Setup buffer sizes */
|
||||
rctl &= ~E1000_RCTL_SZ_4096;
|
||||
rctl |= E1000_RCTL_BSEX;
|
||||
|
|
@ -2751,23 +2769,25 @@ void e1000e_reset(struct e1000_adapter *adapter)
|
|||
/*
|
||||
* flow control settings
|
||||
*
|
||||
* The high water mark must be low enough to fit one full frame
|
||||
* The high water mark must be low enough to fit two full frame
|
||||
* (or the size used for early receive) above it in the Rx FIFO.
|
||||
* Set it to the lower of:
|
||||
* - 90% of the Rx FIFO size, and
|
||||
* - the full Rx FIFO size minus the early receive size (for parts
|
||||
* with ERT support assuming ERT set to E1000_ERT_2048), or
|
||||
* - the full Rx FIFO size minus one full frame
|
||||
* - the full Rx FIFO size minus two full frames
|
||||
*/
|
||||
if (adapter->flags & FLAG_HAS_ERT)
|
||||
if ((adapter->flags & FLAG_HAS_ERT) &&
|
||||
(adapter->netdev->mtu > ETH_DATA_LEN))
|
||||
hwm = min(((pba << 10) * 9 / 10),
|
||||
((pba << 10) - (E1000_ERT_2048 << 3)));
|
||||
else
|
||||
hwm = min(((pba << 10) * 9 / 10),
|
||||
((pba << 10) - adapter->max_frame_size));
|
||||
((pba << 10) - (2 * adapter->max_frame_size)));
|
||||
|
||||
fc->high_water = hwm & 0xFFF8; /* 8-byte granularity */
|
||||
fc->low_water = fc->high_water - 8;
|
||||
fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */
|
||||
fc->low_water = (fc->high_water - (2 * adapter->max_frame_size));
|
||||
fc->low_water &= E1000_FCRTL_RTL; /* 8-byte granularity */
|
||||
|
||||
if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME)
|
||||
fc->pause_time = 0xFFFF;
|
||||
|
|
@ -2787,6 +2807,8 @@ void e1000e_reset(struct e1000_adapter *adapter)
|
|||
e1000_get_hw_control(adapter);
|
||||
|
||||
ew32(WUC, 0);
|
||||
if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP)
|
||||
e1e_wphy(&adapter->hw, BM_WUC, 0);
|
||||
|
||||
if (mac->ops.init_hw(hw))
|
||||
e_err("Hardware Error\n");
|
||||
|
|
@ -2799,7 +2821,8 @@ void e1000e_reset(struct e1000_adapter *adapter)
|
|||
e1000e_reset_adaptive(hw);
|
||||
e1000_get_phy_info(hw);
|
||||
|
||||
if (!(adapter->flags & FLAG_SMART_POWER_DOWN)) {
|
||||
if ((adapter->flags & FLAG_HAS_SMART_POWER_DOWN) &&
|
||||
!(adapter->flags & FLAG_SMART_POWER_DOWN)) {
|
||||
u16 phy_data = 0;
|
||||
/*
|
||||
* speed up time to link by disabling smart power down, ignore
|
||||
|
|
@ -2826,6 +2849,8 @@ int e1000e_up(struct e1000_adapter *adapter)
|
|||
e1000_configure_msix(adapter);
|
||||
e1000_irq_enable(adapter);
|
||||
|
||||
netif_wake_queue(adapter->netdev);
|
||||
|
||||
/* fire a link change interrupt to start the watchdog */
|
||||
ew32(ICS, E1000_ICS_LSC);
|
||||
return 0;
|
||||
|
|
@ -2848,7 +2873,7 @@ void e1000e_down(struct e1000_adapter *adapter)
|
|||
ew32(RCTL, rctl & ~E1000_RCTL_EN);
|
||||
/* flush and sleep below */
|
||||
|
||||
netif_tx_stop_all_queues(netdev);
|
||||
netif_stop_queue(netdev);
|
||||
|
||||
/* disable transmits in the hardware */
|
||||
tctl = er32(TCTL);
|
||||
|
|
@ -3072,6 +3097,8 @@ static int e1000_open(struct net_device *netdev)
|
|||
if (test_bit(__E1000_TESTING, &adapter->state))
|
||||
return -EBUSY;
|
||||
|
||||
netif_carrier_off(netdev);
|
||||
|
||||
/* allocate transmit descriptors */
|
||||
err = e1000e_setup_tx_resources(adapter);
|
||||
if (err)
|
||||
|
|
@ -3128,7 +3155,7 @@ static int e1000_open(struct net_device *netdev)
|
|||
|
||||
e1000_irq_enable(adapter);
|
||||
|
||||
netif_tx_start_all_queues(netdev);
|
||||
netif_start_queue(netdev);
|
||||
|
||||
/* fire a link status change interrupt to start the watchdog */
|
||||
ew32(ICS, E1000_ICS_LSC);
|
||||
|
|
@ -3262,6 +3289,7 @@ void e1000e_update_stats(struct e1000_adapter *adapter)
|
|||
{
|
||||
struct e1000_hw *hw = &adapter->hw;
|
||||
struct pci_dev *pdev = adapter->pdev;
|
||||
u16 phy_data;
|
||||
|
||||
/*
|
||||
* Prevent stats update while adapter is being reset, or if the pci
|
||||
|
|
@ -3281,11 +3309,34 @@ void e1000e_update_stats(struct e1000_adapter *adapter)
|
|||
adapter->stats.roc += er32(ROC);
|
||||
|
||||
adapter->stats.mpc += er32(MPC);
|
||||
adapter->stats.scc += er32(SCC);
|
||||
adapter->stats.ecol += er32(ECOL);
|
||||
adapter->stats.mcc += er32(MCC);
|
||||
adapter->stats.latecol += er32(LATECOL);
|
||||
adapter->stats.dc += er32(DC);
|
||||
if ((hw->phy.type == e1000_phy_82578) ||
|
||||
(hw->phy.type == e1000_phy_82577)) {
|
||||
e1e_rphy(hw, HV_SCC_UPPER, &phy_data);
|
||||
e1e_rphy(hw, HV_SCC_LOWER, &phy_data);
|
||||
adapter->stats.scc += phy_data;
|
||||
|
||||
e1e_rphy(hw, HV_ECOL_UPPER, &phy_data);
|
||||
e1e_rphy(hw, HV_ECOL_LOWER, &phy_data);
|
||||
adapter->stats.ecol += phy_data;
|
||||
|
||||
e1e_rphy(hw, HV_MCC_UPPER, &phy_data);
|
||||
e1e_rphy(hw, HV_MCC_LOWER, &phy_data);
|
||||
adapter->stats.mcc += phy_data;
|
||||
|
||||
e1e_rphy(hw, HV_LATECOL_UPPER, &phy_data);
|
||||
e1e_rphy(hw, HV_LATECOL_LOWER, &phy_data);
|
||||
adapter->stats.latecol += phy_data;
|
||||
|
||||
e1e_rphy(hw, HV_DC_UPPER, &phy_data);
|
||||
e1e_rphy(hw, HV_DC_LOWER, &phy_data);
|
||||
adapter->stats.dc += phy_data;
|
||||
} else {
|
||||
adapter->stats.scc += er32(SCC);
|
||||
adapter->stats.ecol += er32(ECOL);
|
||||
adapter->stats.mcc += er32(MCC);
|
||||
adapter->stats.latecol += er32(LATECOL);
|
||||
adapter->stats.dc += er32(DC);
|
||||
}
|
||||
adapter->stats.xonrxc += er32(XONRXC);
|
||||
adapter->stats.xontxc += er32(XONTXC);
|
||||
adapter->stats.xoffrxc += er32(XOFFRXC);
|
||||
|
|
@ -3303,13 +3354,28 @@ void e1000e_update_stats(struct e1000_adapter *adapter)
|
|||
|
||||
hw->mac.tx_packet_delta = er32(TPT);
|
||||
adapter->stats.tpt += hw->mac.tx_packet_delta;
|
||||
hw->mac.collision_delta = er32(COLC);
|
||||
if ((hw->phy.type == e1000_phy_82578) ||
|
||||
(hw->phy.type == e1000_phy_82577)) {
|
||||
e1e_rphy(hw, HV_COLC_UPPER, &phy_data);
|
||||
e1e_rphy(hw, HV_COLC_LOWER, &phy_data);
|
||||
hw->mac.collision_delta = phy_data;
|
||||
} else {
|
||||
hw->mac.collision_delta = er32(COLC);
|
||||
}
|
||||
adapter->stats.colc += hw->mac.collision_delta;
|
||||
|
||||
adapter->stats.algnerrc += er32(ALGNERRC);
|
||||
adapter->stats.rxerrc += er32(RXERRC);
|
||||
if ((hw->mac.type != e1000_82574) && (hw->mac.type != e1000_82583))
|
||||
adapter->stats.tncrs += er32(TNCRS);
|
||||
if ((hw->phy.type == e1000_phy_82578) ||
|
||||
(hw->phy.type == e1000_phy_82577)) {
|
||||
e1e_rphy(hw, HV_TNCRS_UPPER, &phy_data);
|
||||
e1e_rphy(hw, HV_TNCRS_LOWER, &phy_data);
|
||||
adapter->stats.tncrs += phy_data;
|
||||
} else {
|
||||
if ((hw->mac.type != e1000_82574) &&
|
||||
(hw->mac.type != e1000_82583))
|
||||
adapter->stats.tncrs += er32(TNCRS);
|
||||
}
|
||||
adapter->stats.cexterr += er32(CEXTERR);
|
||||
adapter->stats.tsctc += er32(TSCTC);
|
||||
adapter->stats.tsctfc += er32(TSCTFC);
|
||||
|
|
@ -3598,7 +3664,6 @@ static void e1000_watchdog_task(struct work_struct *work)
|
|||
phy->ops.cfg_on_link_up(hw);
|
||||
|
||||
netif_carrier_on(netdev);
|
||||
netif_tx_wake_all_queues(netdev);
|
||||
|
||||
if (!test_bit(__E1000_DOWN, &adapter->state))
|
||||
mod_timer(&adapter->phy_info_timer,
|
||||
|
|
@ -3612,7 +3677,6 @@ static void e1000_watchdog_task(struct work_struct *work)
|
|||
printk(KERN_INFO "e1000e: %s NIC Link is Down\n",
|
||||
adapter->netdev->name);
|
||||
netif_carrier_off(netdev);
|
||||
netif_tx_stop_all_queues(netdev);
|
||||
if (!test_bit(__E1000_DOWN, &adapter->state))
|
||||
mod_timer(&adapter->phy_info_timer,
|
||||
round_jiffies(jiffies + 2 * HZ));
|
||||
|
|
@ -3649,6 +3713,8 @@ link_up:
|
|||
*/
|
||||
adapter->tx_timeout_count++;
|
||||
schedule_work(&adapter->reset_task);
|
||||
/* return immediately since reset is imminent */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3850,7 +3916,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
|
|||
buffer_info->length = size;
|
||||
buffer_info->time_stamp = jiffies;
|
||||
buffer_info->next_to_watch = i;
|
||||
buffer_info->dma = map[0] + offset;
|
||||
buffer_info->dma = skb_shinfo(skb)->dma_head + offset;
|
||||
count++;
|
||||
|
||||
len -= size;
|
||||
|
|
@ -3881,7 +3947,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
|
|||
buffer_info->length = size;
|
||||
buffer_info->time_stamp = jiffies;
|
||||
buffer_info->next_to_watch = i;
|
||||
buffer_info->dma = map[f + 1] + offset;
|
||||
buffer_info->dma = map[f] + offset;
|
||||
|
||||
len -= size;
|
||||
offset += size;
|
||||
|
|
@ -4145,7 +4211,6 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
|
|||
count = e1000_tx_map(adapter, skb, first, max_per_txd, nr_frags, mss);
|
||||
if (count) {
|
||||
e1000_tx_queue(adapter, tx_flags, count);
|
||||
netdev->trans_start = jiffies;
|
||||
/* Make sure there is space in the ring for the next send. */
|
||||
e1000_maybe_stop_tx(netdev, MAX_SKB_FRAGS + 2);
|
||||
|
||||
|
|
@ -4206,27 +4271,17 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
|
|||
struct e1000_adapter *adapter = netdev_priv(netdev);
|
||||
int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
|
||||
|
||||
if ((new_mtu < ETH_ZLEN + ETH_FCS_LEN + VLAN_HLEN) ||
|
||||
(max_frame > MAX_JUMBO_FRAME_SIZE)) {
|
||||
e_err("Invalid MTU setting\n");
|
||||
/* Jumbo frame support */
|
||||
if ((max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) &&
|
||||
!(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) {
|
||||
e_err("Jumbo Frames not supported.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Jumbo frame size limits */
|
||||
if (max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) {
|
||||
if (!(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) {
|
||||
e_err("Jumbo Frames not supported.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (adapter->hw.phy.type == e1000_phy_ife) {
|
||||
e_err("Jumbo Frames not supported.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
#define MAX_STD_JUMBO_FRAME_SIZE 9234
|
||||
if (max_frame > MAX_STD_JUMBO_FRAME_SIZE) {
|
||||
e_err("MTU > 9216 not supported.\n");
|
||||
/* Supported frame sizes */
|
||||
if ((new_mtu < ETH_ZLEN + ETH_FCS_LEN + VLAN_HLEN) ||
|
||||
(max_frame > adapter->max_hw_frame_size)) {
|
||||
e_err("Unsupported MTU setting\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -4346,6 +4401,81 @@ static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
|
|||
}
|
||||
}
|
||||
|
||||
static int e1000_init_phy_wakeup(struct e1000_adapter *adapter, u32 wufc)
|
||||
{
|
||||
struct e1000_hw *hw = &adapter->hw;
|
||||
u32 i, mac_reg;
|
||||
u16 phy_reg;
|
||||
int retval = 0;
|
||||
|
||||
/* copy MAC RARs to PHY RARs */
|
||||
for (i = 0; i < adapter->hw.mac.rar_entry_count; i++) {
|
||||
mac_reg = er32(RAL(i));
|
||||
e1e_wphy(hw, BM_RAR_L(i), (u16)(mac_reg & 0xFFFF));
|
||||
e1e_wphy(hw, BM_RAR_M(i), (u16)((mac_reg >> 16) & 0xFFFF));
|
||||
mac_reg = er32(RAH(i));
|
||||
e1e_wphy(hw, BM_RAR_H(i), (u16)(mac_reg & 0xFFFF));
|
||||
e1e_wphy(hw, BM_RAR_CTRL(i), (u16)((mac_reg >> 16) & 0xFFFF));
|
||||
}
|
||||
|
||||
/* copy MAC MTA to PHY MTA */
|
||||
for (i = 0; i < adapter->hw.mac.mta_reg_count; i++) {
|
||||
mac_reg = E1000_READ_REG_ARRAY(hw, E1000_MTA, i);
|
||||
e1e_wphy(hw, BM_MTA(i), (u16)(mac_reg & 0xFFFF));
|
||||
e1e_wphy(hw, BM_MTA(i) + 1, (u16)((mac_reg >> 16) & 0xFFFF));
|
||||
}
|
||||
|
||||
/* configure PHY Rx Control register */
|
||||
e1e_rphy(&adapter->hw, BM_RCTL, &phy_reg);
|
||||
mac_reg = er32(RCTL);
|
||||
if (mac_reg & E1000_RCTL_UPE)
|
||||
phy_reg |= BM_RCTL_UPE;
|
||||
if (mac_reg & E1000_RCTL_MPE)
|
||||
phy_reg |= BM_RCTL_MPE;
|
||||
phy_reg &= ~(BM_RCTL_MO_MASK);
|
||||
if (mac_reg & E1000_RCTL_MO_3)
|
||||
phy_reg |= (((mac_reg & E1000_RCTL_MO_3) >> E1000_RCTL_MO_SHIFT)
|
||||
<< BM_RCTL_MO_SHIFT);
|
||||
if (mac_reg & E1000_RCTL_BAM)
|
||||
phy_reg |= BM_RCTL_BAM;
|
||||
if (mac_reg & E1000_RCTL_PMCF)
|
||||
phy_reg |= BM_RCTL_PMCF;
|
||||
mac_reg = er32(CTRL);
|
||||
if (mac_reg & E1000_CTRL_RFCE)
|
||||
phy_reg |= BM_RCTL_RFCE;
|
||||
e1e_wphy(&adapter->hw, BM_RCTL, phy_reg);
|
||||
|
||||
/* enable PHY wakeup in MAC register */
|
||||
ew32(WUFC, wufc);
|
||||
ew32(WUC, E1000_WUC_PHY_WAKE | E1000_WUC_PME_EN);
|
||||
|
||||
/* configure and enable PHY wakeup in PHY registers */
|
||||
e1e_wphy(&adapter->hw, BM_WUFC, wufc);
|
||||
e1e_wphy(&adapter->hw, BM_WUC, E1000_WUC_PME_EN);
|
||||
|
||||
/* activate PHY wakeup */
|
||||
retval = hw->phy.ops.acquire_phy(hw);
|
||||
if (retval) {
|
||||
e_err("Could not acquire PHY\n");
|
||||
return retval;
|
||||
}
|
||||
e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
|
||||
(BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT));
|
||||
retval = e1000e_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, &phy_reg);
|
||||
if (retval) {
|
||||
e_err("Could not read PHY page 769\n");
|
||||
goto out;
|
||||
}
|
||||
phy_reg |= BM_WUC_ENABLE_BIT | BM_WUC_HOST_WU_BIT;
|
||||
retval = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg);
|
||||
if (retval)
|
||||
e_err("Could not set PHY Host Wakeup bit\n");
|
||||
out:
|
||||
hw->phy.ops.release_phy(hw);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
|
||||
{
|
||||
struct net_device *netdev = pci_get_drvdata(pdev);
|
||||
|
|
@ -4388,8 +4518,9 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
|
|||
#define E1000_CTRL_ADVD3WUC 0x00100000
|
||||
/* phy power management enable */
|
||||
#define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000
|
||||
ctrl |= E1000_CTRL_ADVD3WUC |
|
||||
E1000_CTRL_EN_PHY_PWR_MGMT;
|
||||
ctrl |= E1000_CTRL_ADVD3WUC;
|
||||
if (!(adapter->flags2 & FLAG2_HAS_PHY_WAKEUP))
|
||||
ctrl |= E1000_CTRL_EN_PHY_PWR_MGMT;
|
||||
ew32(CTRL, ctrl);
|
||||
|
||||
if (adapter->hw.phy.media_type == e1000_media_type_fiber ||
|
||||
|
|
@ -4407,8 +4538,17 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
|
|||
/* Allow time for pending master requests to run */
|
||||
e1000e_disable_pcie_master(&adapter->hw);
|
||||
|
||||
ew32(WUC, E1000_WUC_PME_EN);
|
||||
ew32(WUFC, wufc);
|
||||
if ((adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) &&
|
||||
!(hw->mac.ops.check_mng_mode(hw))) {
|
||||
/* enable wakeup by the PHY */
|
||||
retval = e1000_init_phy_wakeup(adapter, wufc);
|
||||
if (retval)
|
||||
return retval;
|
||||
} else {
|
||||
/* enable wakeup by the MAC */
|
||||
ew32(WUFC, wufc);
|
||||
ew32(WUC, E1000_WUC_PME_EN);
|
||||
}
|
||||
} else {
|
||||
ew32(WUC, 0);
|
||||
ew32(WUFC, 0);
|
||||
|
|
@ -4551,8 +4691,37 @@ static int e1000_resume(struct pci_dev *pdev)
|
|||
}
|
||||
|
||||
e1000e_power_up_phy(adapter);
|
||||
|
||||
/* report the system wakeup cause from S3/S4 */
|
||||
if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) {
|
||||
u16 phy_data;
|
||||
|
||||
e1e_rphy(&adapter->hw, BM_WUS, &phy_data);
|
||||
if (phy_data) {
|
||||
e_info("PHY Wakeup cause - %s\n",
|
||||
phy_data & E1000_WUS_EX ? "Unicast Packet" :
|
||||
phy_data & E1000_WUS_MC ? "Multicast Packet" :
|
||||
phy_data & E1000_WUS_BC ? "Broadcast Packet" :
|
||||
phy_data & E1000_WUS_MAG ? "Magic Packet" :
|
||||
phy_data & E1000_WUS_LNKC ? "Link Status "
|
||||
" Change" : "other");
|
||||
}
|
||||
e1e_wphy(&adapter->hw, BM_WUS, ~0);
|
||||
} else {
|
||||
u32 wus = er32(WUS);
|
||||
if (wus) {
|
||||
e_info("MAC Wakeup cause - %s\n",
|
||||
wus & E1000_WUS_EX ? "Unicast Packet" :
|
||||
wus & E1000_WUS_MC ? "Multicast Packet" :
|
||||
wus & E1000_WUS_BC ? "Broadcast Packet" :
|
||||
wus & E1000_WUS_MAG ? "Magic Packet" :
|
||||
wus & E1000_WUS_LNKC ? "Link Status Change" :
|
||||
"other");
|
||||
}
|
||||
ew32(WUS, ~0);
|
||||
}
|
||||
|
||||
e1000e_reset(adapter);
|
||||
ew32(WUS, ~0);
|
||||
|
||||
e1000_init_manageability(adapter);
|
||||
|
||||
|
|
@ -4842,6 +5011,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
|
|||
adapter->flags2 = ei->flags2;
|
||||
adapter->hw.adapter = adapter;
|
||||
adapter->hw.mac.type = ei->mac;
|
||||
adapter->max_hw_frame_size = ei->max_hw_frame_size;
|
||||
adapter->msg_enable = (1 << NETIF_MSG_DRV | NETIF_MSG_PROBE) - 1;
|
||||
|
||||
mmio_start = pci_resource_start(pdev, 0);
|
||||
|
|
@ -4997,6 +5167,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
|
|||
/* APME bit in EEPROM is mapped to WUC.APME */
|
||||
eeprom_data = er32(WUC);
|
||||
eeprom_apme_mask = E1000_WUC_APME;
|
||||
if (eeprom_data & E1000_WUC_PHY_WAKE)
|
||||
adapter->flags2 |= FLAG2_HAS_PHY_WAKEUP;
|
||||
} else if (adapter->flags & FLAG_APME_IN_CTRL3) {
|
||||
if (adapter->flags & FLAG_APME_CHECK_PORT_B &&
|
||||
(adapter->hw.bus.func == 1))
|
||||
|
|
@ -5037,15 +5209,14 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
|
|||
if (!(adapter->flags & FLAG_HAS_AMT))
|
||||
e1000_get_hw_control(adapter);
|
||||
|
||||
/* tell the stack to leave us alone until e1000_open() is called */
|
||||
netif_carrier_off(netdev);
|
||||
netif_tx_stop_all_queues(netdev);
|
||||
|
||||
strcpy(netdev->name, "eth%d");
|
||||
err = register_netdev(netdev);
|
||||
if (err)
|
||||
goto err_register;
|
||||
|
||||
/* carrier off reporting is important to ethtool even BEFORE open */
|
||||
netif_carrier_off(netdev);
|
||||
|
||||
e1000_print_device_info(adapter);
|
||||
|
||||
return 0;
|
||||
|
|
@ -5199,6 +5370,11 @@ static struct pci_device_id e1000_pci_tbl[] = {
|
|||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_LM), board_ich10lan },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_LF), board_ich10lan },
|
||||
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_M_HV_LM), board_pchlan },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_M_HV_LC), board_pchlan },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_D_HV_DM), board_pchlan },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_D_HV_DC), board_pchlan },
|
||||
|
||||
{ } /* terminate list */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue