Commit ecea2e46 authored by Eric Lemoine's avatar Eric Lemoine Committed by David S. Miller

[SUNGEM]: Add tx_lock

Using tx_lock in SunGEM makes the driver logic in conformance
with tg3 and e1000, easing maintainance.
Signed-off-by: default avatarEric Lemoine <eric.lemoine@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ba2f2520
...@@ -832,7 +832,9 @@ static int gem_poll(struct net_device *dev, int *budget) ...@@ -832,7 +832,9 @@ static int gem_poll(struct net_device *dev, int *budget)
} }
/* Run TX completion thread */ /* Run TX completion thread */
spin_lock(&gp->tx_lock);
gem_tx(dev, gp, gp->status); gem_tx(dev, gp, gp->status);
spin_unlock(&gp->tx_lock);
spin_unlock_irqrestore(&gp->lock, flags); spin_unlock_irqrestore(&gp->lock, flags);
...@@ -917,10 +919,12 @@ static void gem_tx_timeout(struct net_device *dev) ...@@ -917,10 +919,12 @@ static void gem_tx_timeout(struct net_device *dev)
readl(gp->regs + MAC_RXCFG)); readl(gp->regs + MAC_RXCFG));
spin_lock_irq(&gp->lock); spin_lock_irq(&gp->lock);
spin_lock(&gp->tx_lock);
gp->reset_task_pending = 2; gp->reset_task_pending = 2;
schedule_work(&gp->reset_task); schedule_work(&gp->reset_task);
spin_unlock(&gp->tx_lock);
spin_unlock_irq(&gp->lock); spin_unlock_irq(&gp->lock);
} }
...@@ -951,12 +955,12 @@ static int gem_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -951,12 +955,12 @@ static int gem_start_xmit(struct sk_buff *skb, struct net_device *dev)
(csum_stuff_off << 21)); (csum_stuff_off << 21));
} }
spin_lock_irq(&gp->lock); spin_lock_irq(&gp->tx_lock);
/* This is a hard error, log it. */ /* This is a hard error, log it. */
if (TX_BUFFS_AVAIL(gp) <= (skb_shinfo(skb)->nr_frags + 1)) { if (TX_BUFFS_AVAIL(gp) <= (skb_shinfo(skb)->nr_frags + 1)) {
netif_stop_queue(dev); 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", printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
dev->name); dev->name);
return 1; return 1;
...@@ -1043,7 +1047,7 @@ static int gem_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -1043,7 +1047,7 @@ static int gem_start_xmit(struct sk_buff *skb, struct net_device *dev)
dev->name, entry, skb->len); dev->name, entry, skb->len);
mb(); mb();
writel(gp->tx_new, gp->regs + TXDMA_KICK); writel(gp->tx_new, gp->regs + TXDMA_KICK);
spin_unlock_irq(&gp->lock); spin_unlock_irq(&gp->tx_lock);
dev->trans_start = jiffies; dev->trans_start = jiffies;
...@@ -1074,9 +1078,11 @@ static int gem_change_mtu(struct net_device *dev, int new_mtu) ...@@ -1074,9 +1078,11 @@ static int gem_change_mtu(struct net_device *dev, int new_mtu)
} }
spin_lock_irq(&gp->lock); spin_lock_irq(&gp->lock);
spin_lock(&gp->tx_lock);
dev->mtu = new_mtu; dev->mtu = new_mtu;
gp->reset_task_pending = 1; gp->reset_task_pending = 1;
schedule_work(&gp->reset_task); schedule_work(&gp->reset_task);
spin_unlock(&gp->tx_lock);
spin_unlock_irq(&gp->lock); spin_unlock_irq(&gp->lock);
flush_scheduled_work(); flush_scheduled_work();
...@@ -1086,7 +1092,7 @@ static int gem_change_mtu(struct net_device *dev, int new_mtu) ...@@ -1086,7 +1092,7 @@ static int gem_change_mtu(struct net_device *dev, int new_mtu)
#define STOP_TRIES 32 #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) static void gem_stop(struct gem *gp)
{ {
int limit; int limit;
...@@ -1112,7 +1118,7 @@ static void gem_stop(struct gem *gp) ...@@ -1112,7 +1118,7 @@ static void gem_stop(struct gem *gp)
printk(KERN_ERR "%s: SW reset is ghetto.\n", gp->dev->name); 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) static void gem_start_dma(struct gem *gp)
{ {
unsigned long val; unsigned long val;
...@@ -1137,7 +1143,7 @@ static void gem_start_dma(struct gem *gp) ...@@ -1137,7 +1143,7 @@ static void gem_start_dma(struct gem *gp)
} }
/* 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 // 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) static void gem_begin_auto_negotiation(struct gem *gp, struct ethtool_cmd *ep)
{ {
...@@ -1224,7 +1230,7 @@ static void gem_begin_auto_negotiation(struct gem *gp, struct ethtool_cmd *ep) ...@@ -1224,7 +1230,7 @@ static void gem_begin_auto_negotiation(struct gem *gp, struct ethtool_cmd *ep)
/* A link-up condition has occurred, initialize and enable the /* A link-up condition has occurred, initialize and enable the
* rest of the chip. * 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) static int gem_set_link_modes(struct gem *gp)
{ {
...@@ -1331,7 +1337,7 @@ static int gem_set_link_modes(struct gem *gp) ...@@ -1331,7 +1337,7 @@ static int gem_set_link_modes(struct gem *gp)
return 0; 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) static int gem_mdio_link_not_up(struct gem *gp)
{ {
switch (gp->lstate) { switch (gp->lstate) {
...@@ -1389,6 +1395,7 @@ static void gem_reset_task(void *data) ...@@ -1389,6 +1395,7 @@ static void gem_reset_task(void *data)
netif_poll_disable(gp->dev); netif_poll_disable(gp->dev);
spin_lock_irq(&gp->lock); spin_lock_irq(&gp->lock);
spin_lock(&gp->tx_lock);
if (gp->hw_running && gp->opened) { if (gp->hw_running && gp->opened) {
netif_stop_queue(gp->dev); netif_stop_queue(gp->dev);
...@@ -1404,6 +1411,7 @@ static void gem_reset_task(void *data) ...@@ -1404,6 +1411,7 @@ static void gem_reset_task(void *data)
} }
gp->reset_task_pending = 0; gp->reset_task_pending = 0;
spin_unlock(&gp->tx_lock);
spin_unlock_irq(&gp->lock); spin_unlock_irq(&gp->lock);
netif_poll_enable(gp->dev); netif_poll_enable(gp->dev);
} }
...@@ -1417,6 +1425,7 @@ static void gem_link_timer(unsigned long data) ...@@ -1417,6 +1425,7 @@ static void gem_link_timer(unsigned long data)
return; return;
spin_lock_irq(&gp->lock); spin_lock_irq(&gp->lock);
spin_lock(&gp->tx_lock);
/* If the link of task is still pending, we just /* If the link of task is still pending, we just
* reschedule the link timer * reschedule the link timer
...@@ -1486,10 +1495,11 @@ static void gem_link_timer(unsigned long data) ...@@ -1486,10 +1495,11 @@ static void gem_link_timer(unsigned long data)
restart: restart:
mod_timer(&gp->link_timer, jiffies + ((12 * HZ) / 10)); mod_timer(&gp->link_timer, jiffies + ((12 * HZ) / 10));
out_unlock: out_unlock:
spin_unlock(&gp->tx_lock);
spin_unlock_irq(&gp->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) static void gem_clean_rings(struct gem *gp)
{ {
struct gem_init_block *gb = gp->init_block; struct gem_init_block *gb = gp->init_block;
...@@ -1540,7 +1550,7 @@ static void gem_clean_rings(struct gem *gp) ...@@ -1540,7 +1550,7 @@ static void gem_clean_rings(struct gem *gp)
} }
} }
/* Must be invoked under gp->lock. */ /* Must be invoked under gp->lock and gp->tx_lock. */
static void gem_init_rings(struct gem *gp) static void gem_init_rings(struct gem *gp)
{ {
struct gem_init_block *gb = gp->init_block; struct gem_init_block *gb = gp->init_block;
...@@ -1590,7 +1600,7 @@ static void gem_init_rings(struct gem *gp) ...@@ -1590,7 +1600,7 @@ static void gem_init_rings(struct gem *gp)
wmb(); 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) static void gem_init_phy(struct gem *gp)
{ {
u32 mifcfg; u32 mifcfg;
...@@ -1728,7 +1738,7 @@ static void gem_init_phy(struct gem *gp) ...@@ -1728,7 +1738,7 @@ static void gem_init_phy(struct gem *gp)
} }
} }
/* Must be invoked under gp->lock. */ /* Must be invoked under gp->lock and gp->tx_lock. */
static void gem_init_dma(struct gem *gp) static void gem_init_dma(struct gem *gp)
{ {
u64 desc_dma = (u64) gp->gblock_dvma; u64 desc_dma = (u64) gp->gblock_dvma;
...@@ -1766,7 +1776,7 @@ static void gem_init_dma(struct gem *gp) ...@@ -1766,7 +1776,7 @@ static void gem_init_dma(struct gem *gp)
gp->regs + RXDMA_BLANK); gp->regs + RXDMA_BLANK);
} }
/* Must be invoked under gp->lock. */ /* Must be invoked under gp->lock and gp->tx_lock. */
static u32 static u32
gem_setup_multicast(struct gem *gp) gem_setup_multicast(struct gem *gp)
{ {
...@@ -1809,7 +1819,7 @@ gem_setup_multicast(struct gem *gp) ...@@ -1809,7 +1819,7 @@ gem_setup_multicast(struct gem *gp)
return rxcfg; 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) static void gem_init_mac(struct gem *gp)
{ {
unsigned char *e = &gp->dev->dev_addr[0]; unsigned char *e = &gp->dev->dev_addr[0];
...@@ -1887,7 +1897,7 @@ static void gem_init_mac(struct gem *gp) ...@@ -1887,7 +1897,7 @@ static void gem_init_mac(struct gem *gp)
writel(0xffffffff, gp->regs + MAC_MCMASK); 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) static void gem_init_pause_thresholds(struct gem *gp)
{ {
u32 cfg; u32 cfg;
...@@ -2023,7 +2033,7 @@ static int gem_check_invariants(struct gem *gp) ...@@ -2023,7 +2033,7 @@ static int gem_check_invariants(struct gem *gp)
return 0; 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) static void gem_init_hw(struct gem *gp, int restart_link)
{ {
/* On Apple's gmac, I initialize the PHY only after /* On Apple's gmac, I initialize the PHY only after
...@@ -2121,9 +2131,11 @@ static void gem_stop_phy(struct gem *gp) ...@@ -2121,9 +2131,11 @@ static void gem_stop_phy(struct gem *gp)
if (!gp->wake_on_lan) { if (!gp->wake_on_lan) {
spin_lock_irqsave(&gp->lock, flags); spin_lock_irqsave(&gp->lock, flags);
spin_lock(&gp->tx_lock);
gem_stop(gp); gem_stop(gp);
writel(MAC_TXRST_CMD, gp->regs + MAC_TXRST); writel(MAC_TXRST_CMD, gp->regs + MAC_TXRST);
writel(MAC_RXRST_CMD, gp->regs + MAC_RXRST); writel(MAC_RXRST_CMD, gp->regs + MAC_RXRST);
spin_unlock(&gp->tx_lock);
spin_unlock_irqrestore(&gp->lock, flags); spin_unlock_irqrestore(&gp->lock, flags);
} }
...@@ -2171,8 +2183,10 @@ static void gem_shutdown(struct gem *gp) ...@@ -2171,8 +2183,10 @@ static void gem_shutdown(struct gem *gp)
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&gp->lock, flags); spin_lock_irqsave(&gp->lock, flags);
spin_lock(&gp->tx_lock);
gem_stop(gp); gem_stop(gp);
spin_unlock_irqrestore(&gp->lock, flags); spin_unlock(&gp->tx_lock);
spin_unlock_irqrestore(&gp->lock, flags);
} }
} }
...@@ -2232,7 +2246,9 @@ static int gem_open(struct net_device *dev) ...@@ -2232,7 +2246,9 @@ static int gem_open(struct net_device *dev)
/* Reset the chip */ /* Reset the chip */
spin_lock_irq(&gp->lock); spin_lock_irq(&gp->lock);
spin_lock(&gp->tx_lock);
gem_stop(gp); gem_stop(gp);
spin_unlock(&gp->tx_lock);
spin_unlock_irq(&gp->lock); spin_unlock_irq(&gp->lock);
gp->hw_running = 1; gp->hw_running = 1;
...@@ -2246,6 +2262,7 @@ static int gem_open(struct net_device *dev) ...@@ -2246,6 +2262,7 @@ static int gem_open(struct net_device *dev)
printk(KERN_ERR "%s: failed to request irq !\n", gp->dev->name); printk(KERN_ERR "%s: failed to request irq !\n", gp->dev->name);
spin_lock_irq(&gp->lock); spin_lock_irq(&gp->lock);
spin_lock(&gp->tx_lock);
#ifdef CONFIG_PPC_PMAC #ifdef CONFIG_PPC_PMAC
if (!hw_was_up && gp->pdev->vendor == PCI_VENDOR_ID_APPLE) if (!hw_was_up && gp->pdev->vendor == PCI_VENDOR_ID_APPLE)
gem_apple_powerdown(gp); gem_apple_powerdown(gp);
...@@ -2254,12 +2271,14 @@ static int gem_open(struct net_device *dev) ...@@ -2254,12 +2271,14 @@ static int gem_open(struct net_device *dev)
gp->pm_timer.expires = jiffies + 10*HZ; gp->pm_timer.expires = jiffies + 10*HZ;
add_timer(&gp->pm_timer); add_timer(&gp->pm_timer);
up(&gp->pm_sem); up(&gp->pm_sem);
spin_unlock(&gp->tx_lock);
spin_unlock_irq(&gp->lock); spin_unlock_irq(&gp->lock);
return -EAGAIN; return -EAGAIN;
} }
spin_lock_irq(&gp->lock); spin_lock_irq(&gp->lock);
spin_lock(&gp->tx_lock);
/* Allocate & setup ring buffers */ /* Allocate & setup ring buffers */
gem_init_rings(gp); gem_init_rings(gp);
...@@ -2269,6 +2288,7 @@ static int gem_open(struct net_device *dev) ...@@ -2269,6 +2288,7 @@ static int gem_open(struct net_device *dev)
gp->opened = 1; gp->opened = 1;
spin_unlock(&gp->tx_lock);
spin_unlock_irq(&gp->lock); spin_unlock_irq(&gp->lock);
up(&gp->pm_sem); up(&gp->pm_sem);
...@@ -2289,6 +2309,7 @@ static int gem_close(struct net_device *dev) ...@@ -2289,6 +2309,7 @@ static int gem_close(struct net_device *dev)
/* Stop traffic, mark us closed */ /* Stop traffic, mark us closed */
spin_lock_irq(&gp->lock); spin_lock_irq(&gp->lock);
spin_lock(&gp->tx_lock);
gp->opened = 0; gp->opened = 0;
...@@ -2303,6 +2324,7 @@ static int gem_close(struct net_device *dev) ...@@ -2303,6 +2324,7 @@ static int gem_close(struct net_device *dev)
/* Bye, the pm timer will finish the job */ /* Bye, the pm timer will finish the job */
free_irq(gp->pdev->irq, (void *) dev); free_irq(gp->pdev->irq, (void *) dev);
spin_unlock(&gp->tx_lock);
spin_unlock_irq(&gp->lock); spin_unlock_irq(&gp->lock);
/* Fire the PM timer that will shut us down in about 10 seconds */ /* Fire the PM timer that will shut us down in about 10 seconds */
...@@ -2333,6 +2355,7 @@ static int gem_suspend(struct pci_dev *pdev, u32 state) ...@@ -2333,6 +2355,7 @@ static int gem_suspend(struct pci_dev *pdev, u32 state)
/* If the driver is opened, we stop the DMA */ /* If the driver is opened, we stop the DMA */
if (gp->opened) { if (gp->opened) {
spin_lock_irq(&gp->lock); spin_lock_irq(&gp->lock);
spin_lock(&gp->tx_lock);
/* Stop traffic, mark us closed */ /* Stop traffic, mark us closed */
netif_device_detach(dev); netif_device_detach(dev);
...@@ -2343,6 +2366,7 @@ static int gem_suspend(struct pci_dev *pdev, u32 state) ...@@ -2343,6 +2366,7 @@ static int gem_suspend(struct pci_dev *pdev, u32 state)
/* Get rid of ring buffers */ /* Get rid of ring buffers */
gem_clean_rings(gp); gem_clean_rings(gp);
spin_unlock(&gp->tx_lock);
spin_unlock_irq(&gp->lock); spin_unlock_irq(&gp->lock);
if (gp->pdev->vendor == PCI_VENDOR_ID_APPLE) if (gp->pdev->vendor == PCI_VENDOR_ID_APPLE)
...@@ -2376,12 +2400,14 @@ static int gem_resume(struct pci_dev *pdev) ...@@ -2376,12 +2400,14 @@ static int gem_resume(struct pci_dev *pdev)
} }
#endif /* CONFIG_PPC_PMAC */ #endif /* CONFIG_PPC_PMAC */
spin_lock_irq(&gp->lock); spin_lock_irq(&gp->lock);
spin_lock(&gp->tx_lock);
gem_stop(gp); gem_stop(gp);
gp->hw_running = 1; gp->hw_running = 1;
gem_init_rings(gp); gem_init_rings(gp);
gem_init_hw(gp, 1); gem_init_hw(gp, 1);
spin_unlock(&gp->tx_lock);
spin_unlock_irq(&gp->lock); spin_unlock_irq(&gp->lock);
netif_device_attach(dev); netif_device_attach(dev);
...@@ -2402,6 +2428,7 @@ static struct net_device_stats *gem_get_stats(struct net_device *dev) ...@@ -2402,6 +2428,7 @@ static struct net_device_stats *gem_get_stats(struct net_device *dev)
struct net_device_stats *stats = &gp->net_stats; struct net_device_stats *stats = &gp->net_stats;
spin_lock_irq(&gp->lock); spin_lock_irq(&gp->lock);
spin_lock(&gp->tx_lock);
if (gp->hw_running) { if (gp->hw_running) {
stats->rx_crc_errors += readl(gp->regs + MAC_FCSERR); stats->rx_crc_errors += readl(gp->regs + MAC_FCSERR);
...@@ -2421,6 +2448,7 @@ static struct net_device_stats *gem_get_stats(struct net_device *dev) ...@@ -2421,6 +2448,7 @@ static struct net_device_stats *gem_get_stats(struct net_device *dev)
writel(0, gp->regs + MAC_LCOLL); writel(0, gp->regs + MAC_LCOLL);
} }
spin_unlock(&gp->tx_lock);
spin_unlock_irq(&gp->lock); spin_unlock_irq(&gp->lock);
return &gp->net_stats; return &gp->net_stats;
...@@ -2436,6 +2464,7 @@ static void gem_set_multicast(struct net_device *dev) ...@@ -2436,6 +2464,7 @@ static void gem_set_multicast(struct net_device *dev)
return; return;
spin_lock_irq(&gp->lock); spin_lock_irq(&gp->lock);
spin_lock(&gp->tx_lock);
netif_stop_queue(dev); netif_stop_queue(dev);
...@@ -2460,6 +2489,7 @@ static void gem_set_multicast(struct net_device *dev) ...@@ -2460,6 +2489,7 @@ static void gem_set_multicast(struct net_device *dev)
netif_wake_queue(dev); netif_wake_queue(dev);
spin_unlock(&gp->tx_lock);
spin_unlock_irq(&gp->lock); spin_unlock_irq(&gp->lock);
} }
...@@ -2491,6 +2521,7 @@ static int gem_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) ...@@ -2491,6 +2521,7 @@ static int gem_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
/* Return current PHY settings */ /* Return current PHY settings */
spin_lock_irq(&gp->lock); spin_lock_irq(&gp->lock);
spin_lock(&gp->tx_lock);
cmd->autoneg = gp->want_autoneg; cmd->autoneg = gp->want_autoneg;
cmd->speed = gp->phy_mii.speed; cmd->speed = gp->phy_mii.speed;
cmd->duplex = gp->phy_mii.duplex; cmd->duplex = gp->phy_mii.duplex;
...@@ -2502,6 +2533,7 @@ static int gem_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) ...@@ -2502,6 +2533,7 @@ static int gem_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
*/ */
if (cmd->advertising == 0) if (cmd->advertising == 0)
cmd->advertising = cmd->supported; cmd->advertising = cmd->supported;
spin_unlock(&gp->tx_lock);
spin_unlock_irq(&gp->lock); spin_unlock_irq(&gp->lock);
} else { // XXX PCS ? } else { // XXX PCS ?
cmd->supported = cmd->supported =
...@@ -2541,7 +2573,9 @@ static int gem_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) ...@@ -2541,7 +2573,9 @@ static int gem_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
/* Apply settings and restart link process. */ /* Apply settings and restart link process. */
spin_lock_irq(&gp->lock); spin_lock_irq(&gp->lock);
spin_lock(&gp->tx_lock);
gem_begin_auto_negotiation(gp, cmd); gem_begin_auto_negotiation(gp, cmd);
spin_unlock(&gp->tx_lock);
spin_unlock_irq(&gp->lock); spin_unlock_irq(&gp->lock);
return 0; return 0;
...@@ -2556,7 +2590,9 @@ static int gem_nway_reset(struct net_device *dev) ...@@ -2556,7 +2590,9 @@ static int gem_nway_reset(struct net_device *dev)
/* Restart link process. */ /* Restart link process. */
spin_lock_irq(&gp->lock); spin_lock_irq(&gp->lock);
spin_lock(&gp->tx_lock);
gem_begin_auto_negotiation(gp, NULL); gem_begin_auto_negotiation(gp, NULL);
spin_unlock(&gp->tx_lock);
spin_unlock_irq(&gp->lock); spin_unlock_irq(&gp->lock);
return 0; return 0;
...@@ -2808,6 +2844,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev, ...@@ -2808,6 +2844,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
gp->msg_enable = DEFAULT_MSG; gp->msg_enable = DEFAULT_MSG;
spin_lock_init(&gp->lock); spin_lock_init(&gp->lock);
spin_lock_init(&gp->tx_lock);
init_MUTEX(&gp->pm_sem); init_MUTEX(&gp->pm_sem);
init_timer(&gp->link_timer); init_timer(&gp->link_timer);
...@@ -2843,7 +2880,9 @@ static int __devinit gem_init_one(struct pci_dev *pdev, ...@@ -2843,7 +2880,9 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
gem_apple_powerup(gp); gem_apple_powerup(gp);
#endif #endif
spin_lock_irq(&gp->lock); spin_lock_irq(&gp->lock);
spin_lock(&gp->tx_lock);
gem_stop(gp); gem_stop(gp);
spin_unlock(&gp->tx_lock);
spin_unlock_irq(&gp->lock); spin_unlock_irq(&gp->lock);
/* Fill up the mii_phy structure (even if we won't use it) */ /* Fill up the mii_phy structure (even if we won't use it) */
...@@ -2906,9 +2945,11 @@ static int __devinit gem_init_one(struct pci_dev *pdev, ...@@ -2906,9 +2945,11 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
/* Detect & init PHY, start autoneg */ /* Detect & init PHY, start autoneg */
spin_lock_irq(&gp->lock); spin_lock_irq(&gp->lock);
spin_lock(&gp->tx_lock);
gp->hw_running = 1; gp->hw_running = 1;
gem_init_phy(gp); gem_init_phy(gp);
gem_begin_auto_negotiation(gp, NULL); gem_begin_auto_negotiation(gp, NULL);
spin_unlock(&gp->tx_lock);
spin_unlock_irq(&gp->lock); spin_unlock_irq(&gp->lock);
if (gp->phy_type == phy_mii_mdio0 || if (gp->phy_type == phy_mii_mdio0 ||
......
...@@ -953,6 +953,7 @@ enum link_state { ...@@ -953,6 +953,7 @@ enum link_state {
struct gem { struct gem {
spinlock_t lock; spinlock_t lock;
spinlock_t tx_lock;
void __iomem *regs; void __iomem *regs;
int rx_new, rx_old; int rx_new, rx_old;
int tx_new, tx_old; int tx_new, tx_old;
......
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