Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 203226
b: refs/heads/master
c: de84727
h: refs/heads/master
v: v3
  • Loading branch information
Ben Hutchings authored and David S. Miller committed Jun 30, 2010
1 parent f96ed4a commit f6006dd
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 28 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 5a86f28f954c3841d3a6df4d07d2ed17088c3711
refs/heads/master: de847272149365363a6043a963a6f42fb91566e2
68 changes: 41 additions & 27 deletions trunk/drivers/net/3c59x.c
Original file line number Diff line number Diff line change
Expand Up @@ -644,9 +644,15 @@ struct vortex_private {
u16 deferred; /* Resend these interrupts when we
* bale from the ISR */
u16 io_size; /* Size of PCI region (for release_region) */
spinlock_t lock; /* Serialise access to device & its vortex_private */
struct mii_if_info mii; /* MII lib hooks/info */
int window; /* Register window */

/* Serialises access to hardware other than MII and variables below.
* The lock hierarchy is rtnl_lock > lock > mii_lock > window_lock. */
spinlock_t lock;

spinlock_t mii_lock; /* Serialises access to MII */
struct mii_if_info mii; /* MII lib hooks/info */
spinlock_t window_lock; /* Serialises access to windowed regs */
int window; /* Register window */
};

static void window_set(struct vortex_private *vp, int window)
Expand All @@ -661,15 +667,23 @@ static void window_set(struct vortex_private *vp, int window)
static u ## size \
window_read ## size(struct vortex_private *vp, int window, int addr) \
{ \
unsigned long flags; \
u ## size ret; \
spin_lock_irqsave(&vp->window_lock, flags); \
window_set(vp, window); \
return ioread ## size(vp->ioaddr + addr); \
ret = ioread ## size(vp->ioaddr + addr); \
spin_unlock_irqrestore(&vp->window_lock, flags); \
return ret; \
} \
static void \
window_write ## size(struct vortex_private *vp, u ## size value, \
int window, int addr) \
{ \
unsigned long flags; \
spin_lock_irqsave(&vp->window_lock, flags); \
window_set(vp, window); \
iowrite ## size(value, vp->ioaddr + addr); \
spin_unlock_irqrestore(&vp->window_lock, flags); \
}
DEFINE_WINDOW_IO(8)
DEFINE_WINDOW_IO(16)
Expand Down Expand Up @@ -1181,6 +1195,8 @@ static int __devinit vortex_probe1(struct device *gendev,
}

spin_lock_init(&vp->lock);
spin_lock_init(&vp->mii_lock);
spin_lock_init(&vp->window_lock);
vp->gendev = gendev;
vp->mii.dev = dev;
vp->mii.mdio_read = mdio_read;
Expand Down Expand Up @@ -1784,7 +1800,6 @@ vortex_timer(unsigned long data)
pr_debug("dev->watchdog_timeo=%d\n", dev->watchdog_timeo);
}

disable_irq_lockdep(dev->irq);
media_status = window_read16(vp, 4, Wn4_Media);
switch (dev->if_port) {
case XCVR_10baseT: case XCVR_100baseTx: case XCVR_100baseFx:
Expand All @@ -1805,10 +1820,7 @@ vortex_timer(unsigned long data)
case XCVR_MII: case XCVR_NWAY:
{
ok = 1;
/* Interrupts are already disabled */
spin_lock(&vp->lock);
vortex_check_media(dev, 0);
spin_unlock(&vp->lock);
}
break;
default: /* Other media types handled by Tx timeouts. */
Expand All @@ -1827,6 +1839,8 @@ vortex_timer(unsigned long data)
if (!ok) {
unsigned int config;

spin_lock_irq(&vp->lock);

do {
dev->if_port = media_tbl[dev->if_port].next;
} while ( ! (vp->available_media & media_tbl[dev->if_port].mask));
Expand Down Expand Up @@ -1855,14 +1869,15 @@ vortex_timer(unsigned long data)
if (vortex_debug > 1)
pr_debug("wrote 0x%08x to Wn3_Config\n", config);
/* AKPM: FIXME: Should reset Rx & Tx here. P60 of 3c90xc.pdf */

spin_unlock_irq(&vp->lock);
}

leave_media_alone:
if (vortex_debug > 2)
pr_debug("%s: Media selection timer finished, %s.\n",
dev->name, media_tbl[dev->if_port].name);

enable_irq_lockdep(dev->irq);
mod_timer(&vp->timer, RUN_AT(next_tick));
if (vp->deferred)
iowrite16(FakeIntr, ioaddr + EL3_CMD);
Expand Down Expand Up @@ -2051,9 +2066,11 @@ vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
int len = (skb->len + 3) & ~3;
vp->tx_skb_dma = pci_map_single(VORTEX_PCI(vp), skb->data, len,
PCI_DMA_TODEVICE);
spin_lock_irq(&vp->window_lock);
window_set(vp, 7);
iowrite32(vp->tx_skb_dma, ioaddr + Wn7_MasterAddr);
iowrite16(len, ioaddr + Wn7_MasterLen);
spin_unlock_irq(&vp->window_lock);
vp->tx_skb = skb;
iowrite16(StartDMADown, ioaddr + EL3_CMD);
/* netif_wake_queue() will be called at the DMADone interrupt. */
Expand Down Expand Up @@ -2225,6 +2242,7 @@ vortex_interrupt(int irq, void *dev_id)
pr_debug("%s: interrupt, status %4.4x, latency %d ticks.\n",
dev->name, status, ioread8(ioaddr + Timer));

spin_lock(&vp->window_lock);
window_set(vp, 7);

do {
Expand Down Expand Up @@ -2285,6 +2303,8 @@ vortex_interrupt(int irq, void *dev_id)
iowrite16(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
} while ((status = ioread16(ioaddr + EL3_STATUS)) & (IntLatch | RxComplete));

spin_unlock(&vp->window_lock);

if (vortex_debug > 4)
pr_debug("%s: exiting interrupt, status %4.4x.\n",
dev->name, status);
Expand Down Expand Up @@ -2806,37 +2826,22 @@ static void update_stats(void __iomem *ioaddr, struct net_device *dev)
static int vortex_nway_reset(struct net_device *dev)
{
struct vortex_private *vp = netdev_priv(dev);
unsigned long flags;
int rc;

spin_lock_irqsave(&vp->lock, flags);
rc = mii_nway_restart(&vp->mii);
spin_unlock_irqrestore(&vp->lock, flags);
return rc;
return mii_nway_restart(&vp->mii);
}

static int vortex_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct vortex_private *vp = netdev_priv(dev);
unsigned long flags;
int rc;

spin_lock_irqsave(&vp->lock, flags);
rc = mii_ethtool_gset(&vp->mii, cmd);
spin_unlock_irqrestore(&vp->lock, flags);
return rc;
return mii_ethtool_gset(&vp->mii, cmd);
}

static int vortex_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct vortex_private *vp = netdev_priv(dev);
unsigned long flags;
int rc;

spin_lock_irqsave(&vp->lock, flags);
rc = mii_ethtool_sset(&vp->mii, cmd);
spin_unlock_irqrestore(&vp->lock, flags);
return rc;
return mii_ethtool_sset(&vp->mii, cmd);
}

static u32 vortex_get_msglevel(struct net_device *dev)
Expand Down Expand Up @@ -3059,6 +3064,8 @@ static int mdio_read(struct net_device *dev, int phy_id, int location)
int read_cmd = (0xf6 << 10) | (phy_id << 5) | location;
unsigned int retval = 0;

spin_lock_bh(&vp->mii_lock);

if (mii_preamble_required)
mdio_sync(vp, 32);

Expand All @@ -3082,6 +3089,9 @@ static int mdio_read(struct net_device *dev, int phy_id, int location)
4, Wn4_PhysicalMgmt);
mdio_delay(vp);
}

spin_unlock_bh(&vp->mii_lock);

return retval & 0x20000 ? 0xffff : retval>>1 & 0xffff;
}

Expand All @@ -3091,6 +3101,8 @@ static void mdio_write(struct net_device *dev, int phy_id, int location, int val
int write_cmd = 0x50020000 | (phy_id << 23) | (location << 18) | value;
int i;

spin_lock_bh(&vp->mii_lock);

if (mii_preamble_required)
mdio_sync(vp, 32);

Expand All @@ -3111,6 +3123,8 @@ static void mdio_write(struct net_device *dev, int phy_id, int location, int val
4, Wn4_PhysicalMgmt);
mdio_delay(vp);
}

spin_unlock_bh(&vp->mii_lock);
}

/* ACPI: Advanced Configuration and Power Interface. */
Expand Down

0 comments on commit f6006dd

Please sign in to comment.