Commit b4c22221 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://gkernel.bkbits.net/net-drivers-2.6

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents 6560092a 498566ae
...@@ -751,18 +751,15 @@ static int mc32_load_rx_ring(struct net_device *dev) ...@@ -751,18 +751,15 @@ static int mc32_load_rx_ring(struct net_device *dev)
rx_base=lp->rx_chain; rx_base=lp->rx_chain;
for(i=0; i<RX_RING_LEN; i++) for(i=0; i<RX_RING_LEN; i++) {
{
lp->rx_ring[i].skb=alloc_skb(1532, GFP_KERNEL); lp->rx_ring[i].skb=alloc_skb(1532, GFP_KERNEL);
skb_reserve(lp->rx_ring[i].skb, 18); if (lp->rx_ring[i].skb==NULL) {
for (;i>=0;i--)
if(lp->rx_ring[i].skb==NULL)
{
for(;i>=0;i--)
kfree_skb(lp->rx_ring[i].skb); kfree_skb(lp->rx_ring[i].skb);
return -ENOBUFS; return -ENOBUFS;
} }
skb_reserve(lp->rx_ring[i].skb, 18);
p=isa_bus_to_virt(lp->base+rx_base); p=isa_bus_to_virt(lp->base+rx_base);
p->control=0; p->control=0;
......
...@@ -1698,7 +1698,7 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1698,7 +1698,7 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
} }
/* Configure DMA attributes. */ /* Configure DMA attributes. */
if ((sizeof(dma_addr_t) > 32) && if ((sizeof(dma_addr_t) > 4) &&
!pci_set_consistent_dma_mask(pdev, 0xffffffffffffffffULL) && !pci_set_consistent_dma_mask(pdev, 0xffffffffffffffffULL) &&
!pci_set_dma_mask(pdev, 0xffffffffffffffffULL)) { !pci_set_dma_mask(pdev, 0xffffffffffffffffULL)) {
pci_using_dac = 1; pci_using_dac = 1;
......
...@@ -75,6 +75,7 @@ ...@@ -75,6 +75,7 @@
* added CK804/MCP04 device IDs, code fixes * added CK804/MCP04 device IDs, code fixes
* for registers, link status and other minor fixes. * for registers, link status and other minor fixes.
* 0.28: 21 Jun 2004: Big cleanup, making driver mostly endian safe * 0.28: 21 Jun 2004: Big cleanup, making driver mostly endian safe
* 0.29: 31 Aug 2004: Add backup timer for link change notification.
* *
* Known bugs: * Known bugs:
* We suspect that on some hardware no TX done interrupts are generated. * We suspect that on some hardware no TX done interrupts are generated.
...@@ -86,7 +87,7 @@ ...@@ -86,7 +87,7 @@
* DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
* superfluous timer interrupts from the nic. * superfluous timer interrupts from the nic.
*/ */
#define FORCEDETH_VERSION "0.28" #define FORCEDETH_VERSION "0.29"
#define DRV_NAME "forcedeth" #define DRV_NAME "forcedeth"
#include <linux/module.h> #include <linux/module.h>
...@@ -120,10 +121,11 @@ ...@@ -120,10 +121,11 @@
* Hardware access: * Hardware access:
*/ */
#define DEV_NEED_LASTPACKET1 0x0001 #define DEV_NEED_LASTPACKET1 0x0001 /* set LASTPACKET1 in tx flags */
#define DEV_IRQMASK_1 0x0002 #define DEV_IRQMASK_1 0x0002 /* use NVREG_IRQMASK_WANTED_1 for irq mask */
#define DEV_IRQMASK_2 0x0004 #define DEV_IRQMASK_2 0x0004 /* use NVREG_IRQMASK_WANTED_2 for irq mask */
#define DEV_NEED_TIMERIRQ 0x0008 #define DEV_NEED_TIMERIRQ 0x0008 /* set the timer irq flag in the irq mask */
#define DEV_NEED_LINKTIMER 0x0010 /* poll link settings. Relies on the timer irq */
enum { enum {
NvRegIrqStatus = 0x000, NvRegIrqStatus = 0x000,
...@@ -367,6 +369,7 @@ struct ring_desc { ...@@ -367,6 +369,7 @@ struct ring_desc {
#define OOM_REFILL (1+HZ/20) #define OOM_REFILL (1+HZ/20)
#define POLL_WAIT (1+HZ/100) #define POLL_WAIT (1+HZ/100)
#define LINK_TIMEOUT (3*HZ)
#define DESC_VER_1 0x0 #define DESC_VER_1 0x0
#define DESC_VER_2 0x02100 #define DESC_VER_2 0x02100
...@@ -446,6 +449,11 @@ struct fe_priv { ...@@ -446,6 +449,11 @@ struct fe_priv {
struct timer_list oom_kick; struct timer_list oom_kick;
struct timer_list nic_poll; struct timer_list nic_poll;
/* media detection workaround.
* Locking: Within irq hander or disable_irq+spin_lock(&np->lock);
*/
int need_linktimer;
unsigned long link_timeout;
/* /*
* tx specific fields. * tx specific fields.
*/ */
...@@ -1384,6 +1392,25 @@ static int nv_update_linkspeed(struct net_device *dev) ...@@ -1384,6 +1392,25 @@ static int nv_update_linkspeed(struct net_device *dev)
return retval; return retval;
} }
static void nv_linkchange(struct net_device *dev)
{
if (nv_update_linkspeed(dev)) {
if (netif_carrier_ok(dev)) {
nv_stop_rx(dev);
} else {
netif_carrier_on(dev);
printk(KERN_INFO "%s: link up.\n", dev->name);
}
nv_start_rx(dev);
} else {
if (netif_carrier_ok(dev)) {
netif_carrier_off(dev);
printk(KERN_INFO "%s: link down.\n", dev->name);
nv_stop_rx(dev);
}
}
}
static void nv_link_irq(struct net_device *dev) static void nv_link_irq(struct net_device *dev)
{ {
u8 *base = get_hwbase(dev); u8 *base = get_hwbase(dev);
...@@ -1391,25 +1418,10 @@ static void nv_link_irq(struct net_device *dev) ...@@ -1391,25 +1418,10 @@ static void nv_link_irq(struct net_device *dev)
miistat = readl(base + NvRegMIIStatus); miistat = readl(base + NvRegMIIStatus);
writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus); writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus);
dprintk(KERN_DEBUG "%s: link change notification, status 0x%x.\n", dev->name, miistat); dprintk(KERN_INFO "%s: link change irq, status 0x%x.\n", dev->name, miistat);
if (miistat & (NVREG_MIISTAT_LINKCHANGE)) { if (miistat & (NVREG_MIISTAT_LINKCHANGE))
if (nv_update_linkspeed(dev)) { nv_linkchange(dev);
if (netif_carrier_ok(dev)) {
nv_stop_rx(dev);
} else {
netif_carrier_on(dev);
printk(KERN_INFO "%s: link up.\n", dev->name);
}
nv_start_rx(dev);
} else {
if (netif_carrier_ok(dev)) {
netif_carrier_off(dev);
printk(KERN_INFO "%s: link down.\n", dev->name);
nv_stop_rx(dev);
}
}
}
dprintk(KERN_DEBUG "%s: link change notification done.\n", dev->name); dprintk(KERN_DEBUG "%s: link change notification done.\n", dev->name);
} }
...@@ -1452,6 +1464,12 @@ static irqreturn_t nv_nic_irq(int foo, void *data, struct pt_regs *regs) ...@@ -1452,6 +1464,12 @@ static irqreturn_t nv_nic_irq(int foo, void *data, struct pt_regs *regs)
nv_link_irq(dev); nv_link_irq(dev);
spin_unlock(&np->lock); spin_unlock(&np->lock);
} }
if (np->need_linktimer && time_after(jiffies, np->link_timeout)) {
spin_lock(&np->lock);
nv_linkchange(dev);
spin_unlock(&np->lock);
np->link_timeout = jiffies + LINK_TIMEOUT;
}
if (events & (NVREG_IRQ_TX_ERR)) { if (events & (NVREG_IRQ_TX_ERR)) {
dprintk(KERN_DEBUG "%s: received irq with events 0x%x. Probably TX fail.\n", dprintk(KERN_DEBUG "%s: received irq with events 0x%x. Probably TX fail.\n",
dev->name, events); dev->name, events);
...@@ -1816,6 +1834,14 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i ...@@ -1816,6 +1834,14 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
np->irqmask = NVREG_IRQMASK_WANTED_2; np->irqmask = NVREG_IRQMASK_WANTED_2;
if (id->driver_data & DEV_NEED_TIMERIRQ) if (id->driver_data & DEV_NEED_TIMERIRQ)
np->irqmask |= NVREG_IRQ_TIMER; np->irqmask |= NVREG_IRQ_TIMER;
if (id->driver_data & DEV_NEED_LINKTIMER) {
dprintk(KERN_INFO "%s: link timer on.\n", pci_name(pci_dev));
np->need_linktimer = 1;
np->link_timeout = jiffies + LINK_TIMEOUT;
} else {
dprintk(KERN_INFO "%s: link timer off.\n", pci_name(pci_dev));
np->need_linktimer = 0;
}
/* find a suitable phy */ /* find a suitable phy */
for (i = 1; i < 32; i++) { for (i = 1; i < 32; i++) {
...@@ -1909,21 +1935,21 @@ static struct pci_device_id pci_tbl[] = { ...@@ -1909,21 +1935,21 @@ static struct pci_device_id pci_tbl[] = {
.device = PCI_DEVICE_ID_NVIDIA_NVENET_1, .device = PCI_DEVICE_ID_NVIDIA_NVENET_1,
.subvendor = PCI_ANY_ID, .subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID, .subdevice = PCI_ANY_ID,
.driver_data = DEV_IRQMASK_1|DEV_NEED_TIMERIRQ, .driver_data = DEV_IRQMASK_1|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
}, },
{ /* nForce2 Ethernet Controller */ { /* nForce2 Ethernet Controller */
.vendor = PCI_VENDOR_ID_NVIDIA, .vendor = PCI_VENDOR_ID_NVIDIA,
.device = PCI_DEVICE_ID_NVIDIA_NVENET_2, .device = PCI_DEVICE_ID_NVIDIA_NVENET_2,
.subvendor = PCI_ANY_ID, .subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID, .subdevice = PCI_ANY_ID,
.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
}, },
{ /* nForce3 Ethernet Controller */ { /* nForce3 Ethernet Controller */
.vendor = PCI_VENDOR_ID_NVIDIA, .vendor = PCI_VENDOR_ID_NVIDIA,
.device = PCI_DEVICE_ID_NVIDIA_NVENET_3, .device = PCI_DEVICE_ID_NVIDIA_NVENET_3,
.subvendor = PCI_ANY_ID, .subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID, .subdevice = PCI_ANY_ID,
.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
}, },
{ /* nForce3 Ethernet Controller */ { /* nForce3 Ethernet Controller */
.vendor = PCI_VENDOR_ID_NVIDIA, .vendor = PCI_VENDOR_ID_NVIDIA,
......
...@@ -983,7 +983,7 @@ rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out, ...@@ -983,7 +983,7 @@ rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
tp->cp_cmd = PCIMulRW | RxChkSum; tp->cp_cmd = PCIMulRW | RxChkSum;
if ((sizeof(dma_addr_t) > 32) && if ((sizeof(dma_addr_t) > 4) &&
!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) !pci_set_dma_mask(pdev, DMA_64BIT_MASK))
tp->cp_cmd |= PCIDAC; tp->cp_cmd |= PCIDAC;
else { else {
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/smp_lock.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/ptrace.h> #include <linux/ptrace.h>
......
...@@ -3822,17 +3822,18 @@ static irqreturn_t wavelan_interrupt(int irq, void *dev_id, struct pt_regs *regs ...@@ -3822,17 +3822,18 @@ static irqreturn_t wavelan_interrupt(int irq, void *dev_id, struct pt_regs *regs
if ((hasr & HASR_MMC_INTR) && (lp->hacr & HACR_MMC_INT_ENABLE)) { if ((hasr & HASR_MMC_INTR) && (lp->hacr & HACR_MMC_INT_ENABLE)) {
u8 dce_status; u8 dce_status;
#ifdef DEBUG_INTERRUPT_ERROR
printk(KERN_INFO
"%s: wavelan_interrupt(): unexpected mmc interrupt: status 0x%04x.\n",
dev->name, dce_status);
#endif
/* /*
* Interrupt from the modem management controller. * Interrupt from the modem management controller.
* This will clear it -- ignored for now. * This will clear it -- ignored for now.
*/ */
mmc_read(ioaddr, mmroff(0, mmr_dce_status), &dce_status, mmc_read(ioaddr, mmroff(0, mmr_dce_status), &dce_status,
sizeof(dce_status)); sizeof(dce_status));
#ifdef DEBUG_INTERRUPT_ERROR
printk(KERN_INFO
"%s: wavelan_interrupt(): unexpected mmc interrupt: status 0x%04x.\n",
dev->name, dce_status);
#endif
} }
/* Check if not controller interrupt */ /* Check if not controller interrupt */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment