Commit 0f300cbf authored by Jeff Garzik's avatar Jeff Garzik

Merge redhat.com:/spare/repo/netdev-2.6/e1000

into redhat.com:/spare/repo/net-drivers-2.6
parents 4ec21f9f d9224c2c
/* 8139cp.c: A Linux PCI Ethernet driver for the RealTek 8139C+ chips. */ /* 8139cp.c: A Linux PCI Ethernet driver for the RealTek 8139C+ chips. */
/* /*
Copyright 2001,2002 Jeff Garzik <jgarzik@pobox.com> Copyright 2001-2004 Jeff Garzik <jgarzik@pobox.com>
Copyright (C) 2001, 2002 David S. Miller (davem@redhat.com) [tg3.c] Copyright (C) 2001, 2002 David S. Miller (davem@redhat.com) [tg3.c]
Copyright (C) 2000, 2001 David S. Miller (davem@redhat.com) [sungem.c] Copyright (C) 2000, 2001 David S. Miller (davem@redhat.com) [sungem.c]
...@@ -48,8 +48,8 @@ ...@@ -48,8 +48,8 @@
*/ */
#define DRV_NAME "8139cp" #define DRV_NAME "8139cp"
#define DRV_VERSION "1.1" #define DRV_VERSION "1.2"
#define DRV_RELDATE "Aug 30, 2003" #define DRV_RELDATE "Mar 22, 2004"
#include <linux/config.h> #include <linux/config.h>
...@@ -69,6 +69,7 @@ ...@@ -69,6 +69,7 @@
#include <linux/ip.h> #include <linux/ip.h>
#include <linux/tcp.h> #include <linux/tcp.h>
#include <linux/udp.h> #include <linux/udp.h>
#include <linux/cache.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -334,36 +335,36 @@ struct cp_extra_stats { ...@@ -334,36 +335,36 @@ struct cp_extra_stats {
}; };
struct cp_private { struct cp_private {
unsigned tx_head;
unsigned tx_tail;
unsigned rx_tail;
void *regs; void *regs;
struct net_device *dev; struct net_device *dev;
spinlock_t lock; spinlock_t lock;
u32 msg_enable;
struct pci_dev *pdev;
u32 rx_config;
u16 cpcmd;
struct net_device_stats net_stats;
struct cp_extra_stats cp_stats;
struct cp_dma_stats *nic_stats;
dma_addr_t nic_stats_dma;
unsigned rx_tail ____cacheline_aligned;
struct cp_desc *rx_ring; struct cp_desc *rx_ring;
struct cp_desc *tx_ring;
struct ring_info tx_skb[CP_TX_RING_SIZE];
struct ring_info rx_skb[CP_RX_RING_SIZE]; struct ring_info rx_skb[CP_RX_RING_SIZE];
unsigned rx_buf_sz; unsigned rx_buf_sz;
unsigned tx_head ____cacheline_aligned;
unsigned tx_tail;
struct cp_desc *tx_ring;
struct ring_info tx_skb[CP_TX_RING_SIZE];
dma_addr_t ring_dma; dma_addr_t ring_dma;
#if CP_VLAN_TAG_USED #if CP_VLAN_TAG_USED
struct vlan_group *vlgrp; struct vlan_group *vlgrp;
#endif #endif
u32 msg_enable;
struct net_device_stats net_stats;
struct cp_extra_stats cp_stats;
struct cp_dma_stats *nic_stats;
dma_addr_t nic_stats_dma;
struct pci_dev *pdev;
u32 rx_config;
u16 cpcmd;
unsigned int wol_enabled : 1; /* Is Wake-on-LAN enabled? */ unsigned int wol_enabled : 1; /* Is Wake-on-LAN enabled? */
u32 power_state[16]; u32 power_state[16];
...@@ -424,25 +425,27 @@ static struct { ...@@ -424,25 +425,27 @@ static struct {
#if CP_VLAN_TAG_USED #if CP_VLAN_TAG_USED
static void cp_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) static void cp_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
{ {
struct cp_private *cp = dev->priv; struct cp_private *cp = netdev_priv(dev);
unsigned long flags;
spin_lock_irq(&cp->lock); spin_lock_irqsave(&cp->lock, flags);
cp->vlgrp = grp; cp->vlgrp = grp;
cp->cpcmd |= RxVlanOn; cp->cpcmd |= RxVlanOn;
cpw16(CpCmd, cp->cpcmd); cpw16(CpCmd, cp->cpcmd);
spin_unlock_irq(&cp->lock); spin_unlock_irqrestore(&cp->lock, flags);
} }
static void cp_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) static void cp_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
{ {
struct cp_private *cp = dev->priv; struct cp_private *cp = netdev_priv(dev);
unsigned long flags;
spin_lock_irq(&cp->lock); spin_lock_irqsave(&cp->lock, flags);
cp->cpcmd &= ~RxVlanOn; cp->cpcmd &= ~RxVlanOn;
cpw16(CpCmd, cp->cpcmd); cpw16(CpCmd, cp->cpcmd);
if (cp->vlgrp) if (cp->vlgrp)
cp->vlgrp->vlan_devices[vid] = NULL; cp->vlgrp->vlan_devices[vid] = NULL;
spin_unlock_irq(&cp->lock); spin_unlock_irqrestore(&cp->lock, flags);
} }
#endif /* CP_VLAN_TAG_USED */ #endif /* CP_VLAN_TAG_USED */
...@@ -510,7 +513,7 @@ static inline unsigned int cp_rx_csum_ok (u32 status) ...@@ -510,7 +513,7 @@ static inline unsigned int cp_rx_csum_ok (u32 status)
static int cp_rx_poll (struct net_device *dev, int *budget) static int cp_rx_poll (struct net_device *dev, int *budget)
{ {
struct cp_private *cp = dev->priv; struct cp_private *cp = netdev_priv(dev);
unsigned rx_tail = cp->rx_tail; unsigned rx_tail = cp->rx_tail;
unsigned rx_work = dev->quota; unsigned rx_work = dev->quota;
unsigned rx; unsigned rx;
...@@ -630,9 +633,13 @@ static irqreturn_t ...@@ -630,9 +633,13 @@ static irqreturn_t
cp_interrupt (int irq, void *dev_instance, struct pt_regs *regs) cp_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
{ {
struct net_device *dev = dev_instance; struct net_device *dev = dev_instance;
struct cp_private *cp = dev->priv; struct cp_private *cp;
u16 status; u16 status;
if (unlikely(dev == NULL))
return IRQ_NONE;
cp = netdev_priv(dev);
status = cpr16(IntrStatus); status = cpr16(IntrStatus);
if (!status || (status == 0xFFFF)) if (!status || (status == 0xFFFF))
return IRQ_NONE; return IRQ_NONE;
...@@ -648,20 +655,23 @@ cp_interrupt (int irq, void *dev_instance, struct pt_regs *regs) ...@@ -648,20 +655,23 @@ cp_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
/* close possible race's with dev_close */ /* close possible race's with dev_close */
if (unlikely(!netif_running(dev))) { if (unlikely(!netif_running(dev))) {
cpw16(IntrMask, 0); cpw16(IntrMask, 0);
goto out; spin_unlock(&cp->lock);
return IRQ_HANDLED;
} }
if (status & (RxOK | RxErr | RxEmpty | RxFIFOOvr)) { if (status & (RxOK | RxErr | RxEmpty | RxFIFOOvr))
if (netif_rx_schedule_prep(dev)) { if (netif_rx_schedule_prep(dev)) {
cpw16_f(IntrMask, cp_norx_intr_mask); cpw16_f(IntrMask, cp_norx_intr_mask);
__netif_rx_schedule(dev); __netif_rx_schedule(dev);
} }
}
if (status & (TxOK | TxErr | TxEmpty | SWInt)) if (status & (TxOK | TxErr | TxEmpty | SWInt))
cp_tx(cp); cp_tx(cp);
if (status & LinkChg) if (status & LinkChg)
mii_check_media(&cp->mii_if, netif_msg_link(cp), FALSE); mii_check_media(&cp->mii_if, netif_msg_link(cp), FALSE);
spin_unlock(&cp->lock);
if (status & PciErr) { if (status & PciErr) {
u16 pci_status; u16 pci_status;
...@@ -672,8 +682,7 @@ cp_interrupt (int irq, void *dev_instance, struct pt_regs *regs) ...@@ -672,8 +682,7 @@ cp_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
/* TODO: reset hardware */ /* TODO: reset hardware */
} }
out:
spin_unlock(&cp->lock);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -736,7 +745,7 @@ static void cp_tx (struct cp_private *cp) ...@@ -736,7 +745,7 @@ static void cp_tx (struct cp_private *cp)
static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev) static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev)
{ {
struct cp_private *cp = dev->priv; struct cp_private *cp = netdev_priv(dev);
unsigned entry; unsigned entry;
u32 eor; u32 eor;
#if CP_VLAN_TAG_USED #if CP_VLAN_TAG_USED
...@@ -894,7 +903,7 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev) ...@@ -894,7 +903,7 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev)
static void __cp_set_rx_mode (struct net_device *dev) static void __cp_set_rx_mode (struct net_device *dev)
{ {
struct cp_private *cp = dev->priv; struct cp_private *cp = netdev_priv(dev);
u32 mc_filter[2]; /* Multicast hash filter */ u32 mc_filter[2]; /* Multicast hash filter */
int i, rx_mode; int i, rx_mode;
u32 tmp; u32 tmp;
...@@ -939,7 +948,7 @@ static void __cp_set_rx_mode (struct net_device *dev) ...@@ -939,7 +948,7 @@ static void __cp_set_rx_mode (struct net_device *dev)
static void cp_set_rx_mode (struct net_device *dev) static void cp_set_rx_mode (struct net_device *dev)
{ {
unsigned long flags; unsigned long flags;
struct cp_private *cp = dev->priv; struct cp_private *cp = netdev_priv(dev);
spin_lock_irqsave (&cp->lock, flags); spin_lock_irqsave (&cp->lock, flags);
__cp_set_rx_mode(dev); __cp_set_rx_mode(dev);
...@@ -955,35 +964,28 @@ static void __cp_get_stats(struct cp_private *cp) ...@@ -955,35 +964,28 @@ static void __cp_get_stats(struct cp_private *cp)
static struct net_device_stats *cp_get_stats(struct net_device *dev) static struct net_device_stats *cp_get_stats(struct net_device *dev)
{ {
struct cp_private *cp = dev->priv; struct cp_private *cp = netdev_priv(dev);
unsigned long flags;
/* The chip only need report frame silently dropped. */ /* The chip only need report frame silently dropped. */
spin_lock_irq(&cp->lock); spin_lock_irqsave(&cp->lock, flags);
if (netif_running(dev) && netif_device_present(dev)) if (netif_running(dev) && netif_device_present(dev))
__cp_get_stats(cp); __cp_get_stats(cp);
spin_unlock_irq(&cp->lock); spin_unlock_irqrestore(&cp->lock, flags);
return &cp->net_stats; return &cp->net_stats;
} }
static void cp_stop_hw (struct cp_private *cp) static void cp_stop_hw (struct cp_private *cp)
{ {
struct net_device *dev = cp->dev;
cpw16(IntrStatus, ~(cpr16(IntrStatus))); cpw16(IntrStatus, ~(cpr16(IntrStatus)));
cpw16_f(IntrMask, 0); cpw16_f(IntrMask, 0);
cpw8(Cmd, 0); cpw8(Cmd, 0);
cpw16_f(CpCmd, 0); cpw16_f(CpCmd, 0);
cpw16(IntrStatus, ~(cpr16(IntrStatus))); cpw16_f(IntrStatus, ~(cpr16(IntrStatus)));
synchronize_irq(dev->irq);
udelay(10);
cp->rx_tail = 0; cp->rx_tail = 0;
cp->tx_head = cp->tx_tail = 0; cp->tx_head = cp->tx_tail = 0;
(void) dev; /* avoid compiler warning when synchronize_irq()
* disappears during !CONFIG_SMP
*/
} }
static void cp_reset_hw (struct cp_private *cp) static void cp_reset_hw (struct cp_private *cp)
...@@ -1012,6 +1014,7 @@ static inline void cp_start_hw (struct cp_private *cp) ...@@ -1012,6 +1014,7 @@ static inline void cp_start_hw (struct cp_private *cp)
static void cp_init_hw (struct cp_private *cp) static void cp_init_hw (struct cp_private *cp)
{ {
struct net_device *dev = cp->dev; struct net_device *dev = cp->dev;
dma_addr_t ring_dma;
cp_reset_hw(cp); cp_reset_hw(cp);
...@@ -1037,10 +1040,13 @@ static void cp_init_hw (struct cp_private *cp) ...@@ -1037,10 +1040,13 @@ static void cp_init_hw (struct cp_private *cp)
cpw32_f(HiTxRingAddr, 0); cpw32_f(HiTxRingAddr, 0);
cpw32_f(HiTxRingAddr + 4, 0); cpw32_f(HiTxRingAddr + 4, 0);
cpw32_f(RxRingAddr, cp->ring_dma); ring_dma = cp->ring_dma;
cpw32_f(RxRingAddr + 4, 0); /* FIXME: 64-bit PCI */ cpw32_f(RxRingAddr, ring_dma & 0xffffffff);
cpw32_f(TxRingAddr, cp->ring_dma + (sizeof(struct cp_desc) * CP_RX_RING_SIZE)); cpw32_f(RxRingAddr + 4, (ring_dma >> 16) >> 16);
cpw32_f(TxRingAddr + 4, 0); /* FIXME: 64-bit PCI */
ring_dma += sizeof(struct cp_desc) * CP_RX_RING_SIZE;
cpw32_f(TxRingAddr, ring_dma & 0xffffffff);
cpw32_f(TxRingAddr + 4, (ring_dma >> 16) >> 16);
cpw16(MultiIntr, 0); cpw16(MultiIntr, 0);
...@@ -1154,7 +1160,7 @@ static void cp_free_rings (struct cp_private *cp) ...@@ -1154,7 +1160,7 @@ static void cp_free_rings (struct cp_private *cp)
static int cp_open (struct net_device *dev) static int cp_open (struct net_device *dev)
{ {
struct cp_private *cp = dev->priv; struct cp_private *cp = netdev_priv(dev);
int rc; int rc;
if (netif_msg_ifup(cp)) if (netif_msg_ifup(cp))
...@@ -1184,19 +1190,24 @@ static int cp_open (struct net_device *dev) ...@@ -1184,19 +1190,24 @@ static int cp_open (struct net_device *dev)
static int cp_close (struct net_device *dev) static int cp_close (struct net_device *dev)
{ {
struct cp_private *cp = dev->priv; struct cp_private *cp = netdev_priv(dev);
unsigned long flags;
if (netif_msg_ifdown(cp)) if (netif_msg_ifdown(cp))
printk(KERN_DEBUG "%s: disabling interface\n", dev->name); printk(KERN_DEBUG "%s: disabling interface\n", dev->name);
spin_lock_irqsave(&cp->lock, flags);
netif_stop_queue(dev); netif_stop_queue(dev);
netif_carrier_off(dev); netif_carrier_off(dev);
spin_lock_irq(&cp->lock);
cp_stop_hw(cp); cp_stop_hw(cp);
spin_unlock_irq(&cp->lock);
spin_unlock_irqrestore(&cp->lock, flags);
synchronize_irq(dev->irq);
free_irq(dev->irq, dev); free_irq(dev->irq, dev);
cp_free_rings(cp); cp_free_rings(cp);
return 0; return 0;
} }
...@@ -1204,8 +1215,9 @@ static int cp_close (struct net_device *dev) ...@@ -1204,8 +1215,9 @@ static int cp_close (struct net_device *dev)
#ifdef BROKEN #ifdef BROKEN
static int cp_change_mtu(struct net_device *dev, int new_mtu) static int cp_change_mtu(struct net_device *dev, int new_mtu)
{ {
struct cp_private *cp = dev->priv; struct cp_private *cp = netdev_priv(dev);
int rc; int rc;
unsigned long flags;
/* check for invalid MTU, according to hardware limits */ /* check for invalid MTU, according to hardware limits */
if (new_mtu < CP_MIN_MTU || new_mtu > CP_MAX_MTU) if (new_mtu < CP_MIN_MTU || new_mtu > CP_MAX_MTU)
...@@ -1218,7 +1230,7 @@ static int cp_change_mtu(struct net_device *dev, int new_mtu) ...@@ -1218,7 +1230,7 @@ static int cp_change_mtu(struct net_device *dev, int new_mtu)
return 0; return 0;
} }
spin_lock_irq(&cp->lock); spin_lock_irqsave(&cp->lock, flags);
cp_stop_hw(cp); /* stop h/w and free rings */ cp_stop_hw(cp); /* stop h/w and free rings */
cp_clean_rings(cp); cp_clean_rings(cp);
...@@ -1229,7 +1241,7 @@ static int cp_change_mtu(struct net_device *dev, int new_mtu) ...@@ -1229,7 +1241,7 @@ static int cp_change_mtu(struct net_device *dev, int new_mtu)
rc = cp_init_rings(cp); /* realloc and restart h/w */ rc = cp_init_rings(cp); /* realloc and restart h/w */
cp_start_hw(cp); cp_start_hw(cp);
spin_unlock_irq(&cp->lock); spin_unlock_irqrestore(&cp->lock, flags);
return rc; return rc;
} }
...@@ -1248,7 +1260,7 @@ static char mii_2_8139_map[8] = { ...@@ -1248,7 +1260,7 @@ static char mii_2_8139_map[8] = {
static int mdio_read(struct net_device *dev, int phy_id, int location) static int mdio_read(struct net_device *dev, int phy_id, int location)
{ {
struct cp_private *cp = dev->priv; struct cp_private *cp = netdev_priv(dev);
return location < 8 && mii_2_8139_map[location] ? return location < 8 && mii_2_8139_map[location] ?
readw(cp->regs + mii_2_8139_map[location]) : 0; readw(cp->regs + mii_2_8139_map[location]) : 0;
...@@ -1258,7 +1270,7 @@ static int mdio_read(struct net_device *dev, int phy_id, int location) ...@@ -1258,7 +1270,7 @@ static int mdio_read(struct net_device *dev, int phy_id, int location)
static void mdio_write(struct net_device *dev, int phy_id, int location, static void mdio_write(struct net_device *dev, int phy_id, int location,
int value) int value)
{ {
struct cp_private *cp = dev->priv; struct cp_private *cp = netdev_priv(dev);
if (location == 0) { if (location == 0) {
cpw8(Cfg9346, Cfg9346_Unlock); cpw8(Cfg9346, Cfg9346_Unlock);
...@@ -1326,7 +1338,7 @@ static void netdev_get_wol (struct cp_private *cp, ...@@ -1326,7 +1338,7 @@ static void netdev_get_wol (struct cp_private *cp,
static void cp_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *info) static void cp_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *info)
{ {
struct cp_private *cp = dev->priv; struct cp_private *cp = netdev_priv(dev);
strcpy (info->driver, DRV_NAME); strcpy (info->driver, DRV_NAME);
strcpy (info->version, DRV_VERSION); strcpy (info->version, DRV_VERSION);
...@@ -1345,55 +1357,57 @@ static int cp_get_stats_count (struct net_device *dev) ...@@ -1345,55 +1357,57 @@ static int cp_get_stats_count (struct net_device *dev)
static int cp_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) static int cp_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{ {
struct cp_private *cp = dev->priv; struct cp_private *cp = netdev_priv(dev);
int rc; int rc;
unsigned long flags;
spin_lock_irq(&cp->lock); spin_lock_irqsave(&cp->lock, flags);
rc = mii_ethtool_gset(&cp->mii_if, cmd); rc = mii_ethtool_gset(&cp->mii_if, cmd);
spin_unlock_irq(&cp->lock); spin_unlock_irqrestore(&cp->lock, flags);
return rc; return rc;
} }
static int cp_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) static int cp_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{ {
struct cp_private *cp = dev->priv; struct cp_private *cp = netdev_priv(dev);
int rc; int rc;
unsigned long flags;
spin_lock_irq(&cp->lock); spin_lock_irqsave(&cp->lock, flags);
rc = mii_ethtool_sset(&cp->mii_if, cmd); rc = mii_ethtool_sset(&cp->mii_if, cmd);
spin_unlock_irq(&cp->lock); spin_unlock_irqrestore(&cp->lock, flags);
return rc; return rc;
} }
static int cp_nway_reset(struct net_device *dev) static int cp_nway_reset(struct net_device *dev)
{ {
struct cp_private *cp = dev->priv; struct cp_private *cp = netdev_priv(dev);
return mii_nway_restart(&cp->mii_if); return mii_nway_restart(&cp->mii_if);
} }
static u32 cp_get_msglevel(struct net_device *dev) static u32 cp_get_msglevel(struct net_device *dev)
{ {
struct cp_private *cp = dev->priv; struct cp_private *cp = netdev_priv(dev);
return cp->msg_enable; return cp->msg_enable;
} }
static void cp_set_msglevel(struct net_device *dev, u32 value) static void cp_set_msglevel(struct net_device *dev, u32 value)
{ {
struct cp_private *cp = dev->priv; struct cp_private *cp = netdev_priv(dev);
cp->msg_enable = value; cp->msg_enable = value;
} }
static u32 cp_get_rx_csum(struct net_device *dev) static u32 cp_get_rx_csum(struct net_device *dev)
{ {
struct cp_private *cp = dev->priv; struct cp_private *cp = netdev_priv(dev);
return (cpr16(CpCmd) & RxChkSum) ? 1 : 0; return (cpr16(CpCmd) & RxChkSum) ? 1 : 0;
} }
static int cp_set_rx_csum(struct net_device *dev, u32 data) static int cp_set_rx_csum(struct net_device *dev, u32 data)
{ {
struct cp_private *cp = dev->priv; struct cp_private *cp = netdev_priv(dev);
u16 cmd = cp->cpcmd, newcmd; u16 cmd = cp->cpcmd, newcmd;
newcmd = cmd; newcmd = cmd;
...@@ -1404,10 +1418,12 @@ static int cp_set_rx_csum(struct net_device *dev, u32 data) ...@@ -1404,10 +1418,12 @@ static int cp_set_rx_csum(struct net_device *dev, u32 data)
newcmd &= ~RxChkSum; newcmd &= ~RxChkSum;
if (newcmd != cmd) { if (newcmd != cmd) {
spin_lock_irq(&cp->lock); unsigned long flags;
spin_lock_irqsave(&cp->lock, flags);
cp->cpcmd = newcmd; cp->cpcmd = newcmd;
cpw16_f(CpCmd, newcmd); cpw16_f(CpCmd, newcmd);
spin_unlock_irq(&cp->lock); spin_unlock_irqrestore(&cp->lock, flags);
} }
return 0; return 0;
...@@ -1416,35 +1432,38 @@ static int cp_set_rx_csum(struct net_device *dev, u32 data) ...@@ -1416,35 +1432,38 @@ static int cp_set_rx_csum(struct net_device *dev, u32 data)
static void cp_get_regs(struct net_device *dev, struct ethtool_regs *regs, static void cp_get_regs(struct net_device *dev, struct ethtool_regs *regs,
void *p) void *p)
{ {
struct cp_private *cp = dev->priv; struct cp_private *cp = netdev_priv(dev);
unsigned long flags;
if (regs->len < CP_REGS_SIZE) if (regs->len < CP_REGS_SIZE)
return /* -EINVAL */; return /* -EINVAL */;
regs->version = CP_REGS_VER; regs->version = CP_REGS_VER;
spin_lock_irq(&cp->lock); spin_lock_irqsave(&cp->lock, flags);
memcpy_fromio(p, cp->regs, CP_REGS_SIZE); memcpy_fromio(p, cp->regs, CP_REGS_SIZE);
spin_unlock_irq(&cp->lock); spin_unlock_irqrestore(&cp->lock, flags);
} }
static void cp_get_wol (struct net_device *dev, struct ethtool_wolinfo *wol) static void cp_get_wol (struct net_device *dev, struct ethtool_wolinfo *wol)
{ {
struct cp_private *cp = dev->priv; struct cp_private *cp = netdev_priv(dev);
unsigned long flags;
spin_lock_irq (&cp->lock); spin_lock_irqsave (&cp->lock, flags);
netdev_get_wol (cp, wol); netdev_get_wol (cp, wol);
spin_unlock_irq (&cp->lock); spin_unlock_irqrestore (&cp->lock, flags);
} }
static int cp_set_wol (struct net_device *dev, struct ethtool_wolinfo *wol) static int cp_set_wol (struct net_device *dev, struct ethtool_wolinfo *wol)
{ {
struct cp_private *cp = dev->priv; struct cp_private *cp = netdev_priv(dev);
unsigned long flags;
int rc; int rc;
spin_lock_irq (&cp->lock); spin_lock_irqsave (&cp->lock, flags);
rc = netdev_set_wol (cp, wol); rc = netdev_set_wol (cp, wol);
spin_unlock_irq (&cp->lock); spin_unlock_irqrestore (&cp->lock, flags);
return rc; return rc;
} }
...@@ -1464,13 +1483,13 @@ static void cp_get_strings (struct net_device *dev, u32 stringset, u8 *buf) ...@@ -1464,13 +1483,13 @@ static void cp_get_strings (struct net_device *dev, u32 stringset, u8 *buf)
static void cp_get_ethtool_stats (struct net_device *dev, static void cp_get_ethtool_stats (struct net_device *dev,
struct ethtool_stats *estats, u64 *tmp_stats) struct ethtool_stats *estats, u64 *tmp_stats)
{ {
struct cp_private *cp = dev->priv; struct cp_private *cp = netdev_priv(dev);
unsigned int work = 100; unsigned int work = 100;
int i; int i;
/* begin NIC statistics dump */ /* begin NIC statistics dump */
cpw32(StatsAddr + 4, 0); /* FIXME: 64-bit PCI */ cpw32(StatsAddr + 4, (cp->nic_stats_dma >> 16) >> 16);
cpw32(StatsAddr, cp->nic_stats_dma | DumpStats); cpw32(StatsAddr, (cp->nic_stats_dma & 0xffffffff) | DumpStats);
cpr32(StatsAddr); cpr32(StatsAddr);
while (work-- > 0) { while (work-- > 0) {
...@@ -1526,16 +1545,17 @@ static struct ethtool_ops cp_ethtool_ops = { ...@@ -1526,16 +1545,17 @@ static struct ethtool_ops cp_ethtool_ops = {
static int cp_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) static int cp_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
{ {
struct cp_private *cp = dev->priv; struct cp_private *cp = netdev_priv(dev);
struct mii_ioctl_data *mii = (struct mii_ioctl_data *) &rq->ifr_data; struct mii_ioctl_data *mii = (struct mii_ioctl_data *) &rq->ifr_data;
int rc; int rc;
unsigned long flags;
if (!netif_running(dev)) if (!netif_running(dev))
return -EINVAL; return -EINVAL;
spin_lock_irq(&cp->lock); spin_lock_irqsave(&cp->lock, flags);
rc = generic_mii_ioctl(&cp->mii_if, mii, cmd, NULL); rc = generic_mii_ioctl(&cp->mii_if, mii, cmd, NULL);
spin_unlock_irq(&cp->lock); spin_unlock_irqrestore(&cp->lock, flags);
return rc; return rc;
} }
...@@ -1639,7 +1659,7 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1639,7 +1659,7 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
SET_MODULE_OWNER(dev); SET_MODULE_OWNER(dev);
SET_NETDEV_DEV(dev, &pdev->dev); SET_NETDEV_DEV(dev, &pdev->dev);
cp = dev->priv; cp = netdev_priv(dev);
cp->pdev = pdev; cp->pdev = pdev;
cp->dev = dev; cp->dev = dev;
cp->msg_enable = (debug < 0 ? CP_DEF_MSG_ENABLE : debug); cp->msg_enable = (debug < 0 ? CP_DEF_MSG_ENABLE : debug);
...@@ -1664,12 +1684,6 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1664,12 +1684,6 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (rc) if (rc)
goto err_out_mwi; goto err_out_mwi;
if (pdev->irq < 2) {
rc = -EIO;
printk(KERN_ERR PFX "invalid irq (%d) for pci dev %s\n",
pdev->irq, pci_name(pdev));
goto err_out_res;
}
pciaddr = pci_resource_start(pdev, 1); pciaddr = pci_resource_start(pdev, 1);
if (!pciaddr) { if (!pciaddr) {
rc = -EIO; rc = -EIO;
...@@ -1686,22 +1700,30 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1686,22 +1700,30 @@ 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) > 32) &&
!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;
} else { } else {
pci_using_dac = 0;
rc = pci_set_dma_mask(pdev, 0xffffffffULL); rc = pci_set_dma_mask(pdev, 0xffffffffULL);
if (rc) { if (rc) {
printk(KERN_ERR PFX "No usable DMA configuration, " printk(KERN_ERR PFX "No usable DMA configuration, "
"aborting.\n"); "aborting.\n");
goto err_out_res; goto err_out_res;
} }
pci_using_dac = 0; rc = pci_set_consistent_dma_mask(pdev, 0xffffffffULL);
if (rc) {
printk(KERN_ERR PFX "No usable consistent DMA configuration, "
"aborting.\n");
goto err_out_res;
}
} }
cp->cpcmd = (pci_using_dac ? PCIDAC : 0) | cp->cpcmd = (pci_using_dac ? PCIDAC : 0) |
PCIMulRW | RxChkSum | CpRxOn | CpTxOn; PCIMulRW | RxChkSum | CpRxOn | CpTxOn;
regs = ioremap_nocache(pciaddr, CP_REGS_SIZE); regs = ioremap(pciaddr, CP_REGS_SIZE);
if (!regs) { if (!regs) {
rc = -EIO; rc = -EIO;
printk(KERN_ERR PFX "Cannot map PCI MMIO (%lx@%lx) on pci dev %s\n", printk(KERN_ERR PFX "Cannot map PCI MMIO (%lx@%lx) on pci dev %s\n",
...@@ -1742,6 +1764,9 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1742,6 +1764,9 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
dev->vlan_rx_kill_vid = cp_vlan_rx_kill_vid; dev->vlan_rx_kill_vid = cp_vlan_rx_kill_vid;
#endif #endif
if (pci_using_dac)
dev->features |= NETIF_F_HIGHDMA;
dev->irq = pdev->irq; dev->irq = pdev->irq;
rc = register_netdev(dev); rc = register_netdev(dev);
...@@ -1783,7 +1808,7 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1783,7 +1808,7 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
static void cp_remove_one (struct pci_dev *pdev) static void cp_remove_one (struct pci_dev *pdev)
{ {
struct net_device *dev = pci_get_drvdata(pdev); struct net_device *dev = pci_get_drvdata(pdev);
struct cp_private *cp = dev->priv; struct cp_private *cp = netdev_priv(dev);
if (!dev) if (!dev)
BUG(); BUG();
...@@ -1805,7 +1830,7 @@ static int cp_suspend (struct pci_dev *pdev, u32 state) ...@@ -1805,7 +1830,7 @@ static int cp_suspend (struct pci_dev *pdev, u32 state)
unsigned long flags; unsigned long flags;
dev = pci_get_drvdata (pdev); dev = pci_get_drvdata (pdev);
cp = dev->priv; cp = netdev_priv(dev);
if (!dev || !netif_running (dev)) return 0; if (!dev || !netif_running (dev)) return 0;
...@@ -1834,7 +1859,7 @@ static int cp_resume (struct pci_dev *pdev) ...@@ -1834,7 +1859,7 @@ static int cp_resume (struct pci_dev *pdev)
struct cp_private *cp; struct cp_private *cp;
dev = pci_get_drvdata (pdev); dev = pci_get_drvdata (pdev);
cp = dev->priv; cp = netdev_priv(dev);
netif_device_attach (dev); netif_device_attach (dev);
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
* *
* Copyright (C) 2002 David S. Miller (davem@redhat.com) * Copyright (C) 2002 David S. Miller (davem@redhat.com)
* Fixed by Pekka Pietikainen (pp@ee.oulu.fi) * Fixed by Pekka Pietikainen (pp@ee.oulu.fi)
*
* Distribute under GPL.
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -25,8 +27,8 @@ ...@@ -25,8 +27,8 @@
#define DRV_MODULE_NAME "b44" #define DRV_MODULE_NAME "b44"
#define PFX DRV_MODULE_NAME ": " #define PFX DRV_MODULE_NAME ": "
#define DRV_MODULE_VERSION "0.92" #define DRV_MODULE_VERSION "0.93"
#define DRV_MODULE_RELDATE "Nov 4, 2003" #define DRV_MODULE_RELDATE "Mar, 2004"
#define B44_DEF_MSG_ENABLE \ #define B44_DEF_MSG_ENABLE \
(NETIF_MSG_DRV | \ (NETIF_MSG_DRV | \
...@@ -83,6 +85,10 @@ static int b44_debug = -1; /* -1 == use B44_DEF_MSG_ENABLE as value */ ...@@ -83,6 +85,10 @@ static int b44_debug = -1; /* -1 == use B44_DEF_MSG_ENABLE as value */
static struct pci_device_id b44_pci_tbl[] = { static struct pci_device_id b44_pci_tbl[] = {
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401, { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401B0,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401B1,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{ } /* terminate list with empty entry */ { } /* terminate list with empty entry */
}; };
...@@ -1178,7 +1184,6 @@ static int b44_init_hw(struct b44 *bp) ...@@ -1178,7 +1184,6 @@ static int b44_init_hw(struct b44 *bp)
{ {
u32 val; u32 val;
b44_disable_ints(bp);
b44_chip_reset(bp); b44_chip_reset(bp);
b44_phy_reset(bp); b44_phy_reset(bp);
b44_setup_phy(bp); b44_setup_phy(bp);
......
#ifndef _B44_H #ifndef _B44_H
#define _B44_H #define _B44_H
/* Register layout. */ /* Register layout. (These correspond to struct _bcmenettregs in bcm4400.) */
#define B44_DEVCTRL 0x0000UL /* Device Control */ #define B44_DEVCTRL 0x0000UL /* Device Control */
#define DEVCTRL_MPM 0x00000040 /* Magic Packet PME Enable (B0 only) */
#define DEVCTRL_PFE 0x00000080 /* Pattern Filtering Enable */ #define DEVCTRL_PFE 0x00000080 /* Pattern Filtering Enable */
#define DEVCTRL_IPP 0x00000400 /* Internal EPHY Present */ #define DEVCTRL_IPP 0x00000400 /* Internal EPHY Present */
#define DEVCTRL_EPR 0x00008000 /* EPHY Reset */ #define DEVCTRL_EPR 0x00008000 /* EPHY Reset */
...@@ -24,6 +25,7 @@ ...@@ -24,6 +25,7 @@
#define WKUP_LEN_P3_SHIFT 24 #define WKUP_LEN_P3_SHIFT 24
#define WKUP_LEN_D3 0x80000000 #define WKUP_LEN_D3 0x80000000
#define B44_ISTAT 0x0020UL /* Interrupt Status */ #define B44_ISTAT 0x0020UL /* Interrupt Status */
#define ISTAT_LS 0x00000020 /* Link Change (B0 only) */
#define ISTAT_PME 0x00000040 /* Power Management Event */ #define ISTAT_PME 0x00000040 /* Power Management Event */
#define ISTAT_TO 0x00000080 /* General Purpose Timeout */ #define ISTAT_TO 0x00000080 /* General Purpose Timeout */
#define ISTAT_DSCE 0x00000400 /* Descriptor Error */ #define ISTAT_DSCE 0x00000400 /* Descriptor Error */
...@@ -41,6 +43,8 @@ ...@@ -41,6 +43,8 @@
#define B44_IMASK 0x0024UL /* Interrupt Mask */ #define B44_IMASK 0x0024UL /* Interrupt Mask */
#define IMASK_DEF (ISTAT_ERRORS | ISTAT_TO | ISTAT_RX | ISTAT_TX) #define IMASK_DEF (ISTAT_ERRORS | ISTAT_TO | ISTAT_RX | ISTAT_TX)
#define B44_GPTIMER 0x0028UL /* General Purpose Timer */ #define B44_GPTIMER 0x0028UL /* General Purpose Timer */
#define B44_ADDR_LO 0x0088UL /* ENET Address Lo (B0 only) */
#define B44_ADDR_HI 0x008CUL /* ENET Address Hi (B0 only) */
#define B44_FILT_ADDR 0x0090UL /* ENET Filter Address */ #define B44_FILT_ADDR 0x0090UL /* ENET Filter Address */
#define B44_FILT_DATA 0x0094UL /* ENET Filter Data */ #define B44_FILT_DATA 0x0094UL /* ENET Filter Data */
#define B44_TXBURST 0x00A0UL /* TX Max Burst Length */ #define B44_TXBURST 0x00A0UL /* TX Max Burst Length */
......
...@@ -1838,6 +1838,8 @@ ...@@ -1838,6 +1838,8 @@
#define PCI_DEVICE_ID_TIGON3_5901 0x170d #define PCI_DEVICE_ID_TIGON3_5901 0x170d
#define PCI_DEVICE_ID_TIGON3_5901_2 0x170e #define PCI_DEVICE_ID_TIGON3_5901_2 0x170e
#define PCI_DEVICE_ID_BCM4401 0x4401 #define PCI_DEVICE_ID_BCM4401 0x4401
#define PCI_DEVICE_ID_BCM4401B0 0x4402
#define PCI_DEVICE_ID_BCM4401B1 0x170c
#define PCI_VENDOR_ID_ENE 0x1524 #define PCI_VENDOR_ID_ENE 0x1524
#define PCI_DEVICE_ID_ENE_1211 0x1211 #define PCI_DEVICE_ID_ENE_1211 0x1211
......
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