* [SUNGEM] add tx_lock
@ 2004-09-15 6:43 Eric Lemoine
2004-09-15 15:33 ` David S. Miller
0 siblings, 1 reply; 2+ messages in thread
From: Eric Lemoine @ 2004-09-15 6:43 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev
[-- Attachment #1: Type: text/plain, Size: 167 bytes --]
The attached patch makes SunGEM NAPI driver in conformance to tg3 and
e1000 in terms of locking logic. Applies to current BK:net-2.6.
[LLTX patch to follow]
--
Eric
[-- Attachment #2: patch-rset-sungem_txlock-2-6-9-rc1 --]
[-- Type: application/octet-stream, Size: 10992 bytes --]
# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
# 2004/09/15 08:26:55+02:00 eric.lemoine@gmail.com
# [SUNGEM]: add tx_lock to conform to tg3 and e1000
#
# Using tx_lock in SunGEM makes the driver logic in conformance
# with tg3 and e1000, easing maintainance.
#
# Signed-off-by: Eric Lemoine <eric.lemoine@gmail.com>
#
#
# drivers/net/sungem.h
# 2004/09/15 08:26:47+02:00 eric.lemoine@gmail.com +1 -0
# [SUNGEM]: add tx_lock to conform to tg3 and e1000
#
# Signed-off-by: Eric Lemoine <eric.lemoine@gmail.com>
#
#
# drivers/net/sungem.c
# 2004/09/15 08:26:47+02:00 eric.lemoine@gmail.com +58 -17
# [SunGEM]: add tx_lock to conform to tg3 and e1000
#
# Signed-off-by: Eric Lemoine <eric.lemoine@gmail.com>
#
#
diff -Nru a/drivers/net/sungem.c b/drivers/net/sungem.c
--- a/drivers/net/sungem.c 2004-09-15 08:37:52 +02:00
+++ b/drivers/net/sungem.c 2004-09-15 08:37:52 +02:00
@@ -832,7 +832,9 @@
}
/* Run TX completion thread */
+ spin_lock(&gp->tx_lock);
gem_tx(dev, gp, gp->status);
+ spin_unlock(&gp->tx_lock);
spin_unlock_irqrestore(&gp->lock, flags);
@@ -917,10 +919,12 @@
readl(gp->regs + MAC_RXCFG));
spin_lock_irq(&gp->lock);
+ spin_lock(&gp->tx_lock);
gp->reset_task_pending = 2;
schedule_work(&gp->reset_task);
+ spin_unlock(&gp->tx_lock);
spin_unlock_irq(&gp->lock);
}
@@ -951,12 +955,12 @@
(csum_stuff_off << 21));
}
- spin_lock_irq(&gp->lock);
+ spin_lock_irq(&gp->tx_lock);
/* This is a hard error, log it. */
if (TX_BUFFS_AVAIL(gp) <= (skb_shinfo(skb)->nr_frags + 1)) {
netif_stop_queue(dev);
- spin_unlock_irq(&gp->lock);
+ spin_unlock_irq(&gp->tx_lock);
printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
dev->name);
return 1;
@@ -1043,7 +1047,7 @@
dev->name, entry, skb->len);
mb();
writel(gp->tx_new, gp->regs + TXDMA_KICK);
- spin_unlock_irq(&gp->lock);
+ spin_unlock_irq(&gp->tx_lock);
dev->trans_start = jiffies;
@@ -1074,9 +1078,11 @@
}
spin_lock_irq(&gp->lock);
+ spin_lock(&gp->tx_lock);
dev->mtu = new_mtu;
gp->reset_task_pending = 1;
schedule_work(&gp->reset_task);
+ spin_unlock(&gp->tx_lock);
spin_unlock_irq(&gp->lock);
flush_scheduled_work();
@@ -1086,7 +1092,7 @@
#define STOP_TRIES 32
-/* Must be invoked under gp->lock. */
+/* Must be invoked under gp->lock and gp->tx_lock. */
static void gem_stop(struct gem *gp)
{
int limit;
@@ -1112,7 +1118,7 @@
printk(KERN_ERR "%s: SW reset is ghetto.\n", gp->dev->name);
}
-/* Must be invoked under gp->lock. */
+/* Must be invoked under gp->lock and gp->tx_lock. */
static void gem_start_dma(struct gem *gp)
{
unsigned long val;
@@ -1137,7 +1143,7 @@
}
-/* Must be invoked under gp->lock. */
+/* Must be invoked under gp->lock and gp->tx_lock. */
// XXX dbl check what that function should do when called on PCS PHY
static void gem_begin_auto_negotiation(struct gem *gp, struct ethtool_cmd *ep)
{
@@ -1224,7 +1230,7 @@
/* A link-up condition has occurred, initialize and enable the
* rest of the chip.
*
- * Must be invoked under gp->lock.
+ * Must be invoked under gp->lock and gp->tx_lock.
*/
static int gem_set_link_modes(struct gem *gp)
{
@@ -1331,7 +1337,7 @@
return 0;
}
-/* Must be invoked under gp->lock. */
+/* Must be invoked under gp->lock and gp->tx_lock. */
static int gem_mdio_link_not_up(struct gem *gp)
{
switch (gp->lstate) {
@@ -1389,6 +1395,7 @@
netif_poll_disable(gp->dev);
spin_lock_irq(&gp->lock);
+ spin_lock(&gp->tx_lock);
if (gp->hw_running && gp->opened) {
netif_stop_queue(gp->dev);
@@ -1404,6 +1411,7 @@
}
gp->reset_task_pending = 0;
+ spin_unlock(&gp->tx_lock);
spin_unlock_irq(&gp->lock);
netif_poll_enable(gp->dev);
}
@@ -1417,6 +1425,7 @@
return;
spin_lock_irq(&gp->lock);
+ spin_lock(&gp->tx_lock);
/* If the link of task is still pending, we just
* reschedule the link timer
@@ -1486,10 +1495,11 @@
restart:
mod_timer(&gp->link_timer, jiffies + ((12 * HZ) / 10));
out_unlock:
+ spin_unlock(&gp->tx_lock);
spin_unlock_irq(&gp->lock);
}
-/* Must be invoked under gp->lock. */
+/* Must be invoked under gp->lock and gp->tx_lock. */
static void gem_clean_rings(struct gem *gp)
{
struct gem_init_block *gb = gp->init_block;
@@ -1540,7 +1550,7 @@
}
}
-/* Must be invoked under gp->lock. */
+/* Must be invoked under gp->lock and gp->tx_lock. */
static void gem_init_rings(struct gem *gp)
{
struct gem_init_block *gb = gp->init_block;
@@ -1590,7 +1600,7 @@
wmb();
}
-/* Must be invoked under gp->lock. */
+/* Must be invoked under gp->lock and gp->tx_lock. */
static void gem_init_phy(struct gem *gp)
{
u32 mifcfg;
@@ -1728,7 +1738,7 @@
}
}
-/* Must be invoked under gp->lock. */
+/* Must be invoked under gp->lock and gp->tx_lock. */
static void gem_init_dma(struct gem *gp)
{
u64 desc_dma = (u64) gp->gblock_dvma;
@@ -1766,7 +1776,7 @@
gp->regs + RXDMA_BLANK);
}
-/* Must be invoked under gp->lock. */
+/* Must be invoked under gp->lock and gp->tx_lock. */
static u32
gem_setup_multicast(struct gem *gp)
{
@@ -1809,7 +1819,7 @@
return rxcfg;
}
-/* Must be invoked under gp->lock. */
+/* Must be invoked under gp->lock and gp->tx_lock. */
static void gem_init_mac(struct gem *gp)
{
unsigned char *e = &gp->dev->dev_addr[0];
@@ -1887,7 +1897,7 @@
writel(0xffffffff, gp->regs + MAC_MCMASK);
}
-/* Must be invoked under gp->lock. */
+/* Must be invoked under gp->lock and gp->tx_lock. */
static void gem_init_pause_thresholds(struct gem *gp)
{
u32 cfg;
@@ -2023,7 +2033,7 @@
return 0;
}
-/* Must be invoked under gp->lock. */
+/* Must be invoked under gp->lock and gp->tx_lock. */
static void gem_init_hw(struct gem *gp, int restart_link)
{
/* On Apple's gmac, I initialize the PHY only after
@@ -2121,9 +2131,11 @@
if (!gp->wake_on_lan) {
spin_lock_irqsave(&gp->lock, flags);
+ spin_lock(&gp->tx_lock);
gem_stop(gp);
writel(MAC_TXRST_CMD, gp->regs + MAC_TXRST);
writel(MAC_RXRST_CMD, gp->regs + MAC_RXRST);
+ spin_unlock(&gp->tx_lock);
spin_unlock_irqrestore(&gp->lock, flags);
}
@@ -2171,8 +2183,10 @@
unsigned long flags;
spin_lock_irqsave(&gp->lock, flags);
+ spin_lock(&gp->tx_lock);
gem_stop(gp);
- spin_unlock_irqrestore(&gp->lock, flags);
+ spin_unlock(&gp->tx_lock);
+ spin_unlock_irqrestore(&gp->lock, flags);
}
}
@@ -2232,7 +2246,9 @@
/* Reset the chip */
spin_lock_irq(&gp->lock);
+ spin_lock(&gp->tx_lock);
gem_stop(gp);
+ spin_unlock(&gp->tx_lock);
spin_unlock_irq(&gp->lock);
gp->hw_running = 1;
@@ -2246,6 +2262,7 @@
printk(KERN_ERR "%s: failed to request irq !\n", gp->dev->name);
spin_lock_irq(&gp->lock);
+ spin_lock(&gp->tx_lock);
#ifdef CONFIG_PPC_PMAC
if (!hw_was_up && gp->pdev->vendor == PCI_VENDOR_ID_APPLE)
gem_apple_powerdown(gp);
@@ -2254,12 +2271,14 @@
gp->pm_timer.expires = jiffies + 10*HZ;
add_timer(&gp->pm_timer);
up(&gp->pm_sem);
+ spin_unlock(&gp->tx_lock);
spin_unlock_irq(&gp->lock);
return -EAGAIN;
}
spin_lock_irq(&gp->lock);
+ spin_lock(&gp->tx_lock);
/* Allocate & setup ring buffers */
gem_init_rings(gp);
@@ -2269,6 +2288,7 @@
gp->opened = 1;
+ spin_unlock(&gp->tx_lock);
spin_unlock_irq(&gp->lock);
up(&gp->pm_sem);
@@ -2289,6 +2309,7 @@
/* Stop traffic, mark us closed */
spin_lock_irq(&gp->lock);
+ spin_lock(&gp->tx_lock);
gp->opened = 0;
@@ -2303,6 +2324,7 @@
/* Bye, the pm timer will finish the job */
free_irq(gp->pdev->irq, (void *) dev);
+ spin_unlock(&gp->tx_lock);
spin_unlock_irq(&gp->lock);
/* Fire the PM timer that will shut us down in about 10 seconds */
@@ -2333,6 +2355,7 @@
/* If the driver is opened, we stop the DMA */
if (gp->opened) {
spin_lock_irq(&gp->lock);
+ spin_lock(&gp->tx_lock);
/* Stop traffic, mark us closed */
netif_device_detach(dev);
@@ -2343,6 +2366,7 @@
/* Get rid of ring buffers */
gem_clean_rings(gp);
+ spin_unlock(&gp->tx_lock);
spin_unlock_irq(&gp->lock);
if (gp->pdev->vendor == PCI_VENDOR_ID_APPLE)
@@ -2376,12 +2400,14 @@
}
#endif /* CONFIG_PPC_PMAC */
spin_lock_irq(&gp->lock);
+ spin_lock(&gp->tx_lock);
gem_stop(gp);
gp->hw_running = 1;
gem_init_rings(gp);
gem_init_hw(gp, 1);
+ spin_unlock(&gp->tx_lock);
spin_unlock_irq(&gp->lock);
netif_device_attach(dev);
@@ -2402,6 +2428,7 @@
struct net_device_stats *stats = &gp->net_stats;
spin_lock_irq(&gp->lock);
+ spin_lock(&gp->tx_lock);
if (gp->hw_running) {
stats->rx_crc_errors += readl(gp->regs + MAC_FCSERR);
@@ -2421,6 +2448,7 @@
writel(0, gp->regs + MAC_LCOLL);
}
+ spin_unlock(&gp->tx_lock);
spin_unlock_irq(&gp->lock);
return &gp->net_stats;
@@ -2436,6 +2464,7 @@
return;
spin_lock_irq(&gp->lock);
+ spin_lock(&gp->tx_lock);
netif_stop_queue(dev);
@@ -2460,6 +2489,7 @@
netif_wake_queue(dev);
+ spin_unlock(&gp->tx_lock);
spin_unlock_irq(&gp->lock);
}
@@ -2491,6 +2521,7 @@
/* Return current PHY settings */
spin_lock_irq(&gp->lock);
+ spin_lock(&gp->tx_lock);
cmd->autoneg = gp->want_autoneg;
cmd->speed = gp->phy_mii.speed;
cmd->duplex = gp->phy_mii.duplex;
@@ -2502,6 +2533,7 @@
*/
if (cmd->advertising == 0)
cmd->advertising = cmd->supported;
+ spin_unlock(&gp->tx_lock);
spin_unlock_irq(&gp->lock);
} else { // XXX PCS ?
cmd->supported =
@@ -2541,7 +2573,9 @@
/* Apply settings and restart link process. */
spin_lock_irq(&gp->lock);
+ spin_lock(&gp->tx_lock);
gem_begin_auto_negotiation(gp, cmd);
+ spin_unlock(&gp->tx_lock);
spin_unlock_irq(&gp->lock);
return 0;
@@ -2556,7 +2590,9 @@
/* Restart link process. */
spin_lock_irq(&gp->lock);
+ spin_lock(&gp->tx_lock);
gem_begin_auto_negotiation(gp, NULL);
+ spin_unlock(&gp->tx_lock);
spin_unlock_irq(&gp->lock);
return 0;
@@ -2808,6 +2844,7 @@
gp->msg_enable = DEFAULT_MSG;
spin_lock_init(&gp->lock);
+ spin_lock_init(&gp->tx_lock);
init_MUTEX(&gp->pm_sem);
init_timer(&gp->link_timer);
@@ -2843,7 +2880,9 @@
gem_apple_powerup(gp);
#endif
spin_lock_irq(&gp->lock);
+ spin_lock(&gp->tx_lock);
gem_stop(gp);
+ spin_unlock(&gp->tx_lock);
spin_unlock_irq(&gp->lock);
/* Fill up the mii_phy structure (even if we won't use it) */
@@ -2906,9 +2945,11 @@
/* Detect & init PHY, start autoneg */
spin_lock_irq(&gp->lock);
+ spin_lock(&gp->tx_lock);
gp->hw_running = 1;
gem_init_phy(gp);
gem_begin_auto_negotiation(gp, NULL);
+ spin_unlock(&gp->tx_lock);
spin_unlock_irq(&gp->lock);
if (gp->phy_type == phy_mii_mdio0 ||
diff -Nru a/drivers/net/sungem.h b/drivers/net/sungem.h
--- a/drivers/net/sungem.h 2004-09-15 08:37:52 +02:00
+++ b/drivers/net/sungem.h 2004-09-15 08:37:52 +02:00
@@ -953,6 +953,7 @@
struct gem {
spinlock_t lock;
+ spinlock_t tx_lock;
unsigned long regs;
int rx_new, rx_old;
int tx_new, tx_old;
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [SUNGEM] add tx_lock
2004-09-15 6:43 [SUNGEM] add tx_lock Eric Lemoine
@ 2004-09-15 15:33 ` David S. Miller
0 siblings, 0 replies; 2+ messages in thread
From: David S. Miller @ 2004-09-15 15:33 UTC (permalink / raw)
To: Eric Lemoine; +Cc: netdev
On Wed, 15 Sep 2004 08:43:39 +0200
Eric Lemoine <eric.lemoine@gmail.com> wrote:
> The attached patch makes SunGEM NAPI driver in conformance to tg3 and
> e1000 in terms of locking logic. Applies to current BK:net-2.6.
Applied, thanks Eric.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2004-09-15 15:33 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-09-15 6:43 [SUNGEM] add tx_lock Eric Lemoine
2004-09-15 15:33 ` David S. Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).