diff options
| -rw-r--r-- | drivers/net/skge.c | 21 | ||||
| -rw-r--r-- | drivers/net/skge.h | 1 |
2 files changed, 15 insertions, 7 deletions
diff --git a/drivers/net/skge.c b/drivers/net/skge.c index af2e6782031b..25e028b7ce48 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c | |||
| @@ -2185,8 +2185,10 @@ static int skge_up(struct net_device *dev) | |||
| 2185 | skge->tx_avail = skge->tx_ring.count - 1; | 2185 | skge->tx_avail = skge->tx_ring.count - 1; |
| 2186 | 2186 | ||
| 2187 | /* Enable IRQ from port */ | 2187 | /* Enable IRQ from port */ |
| 2188 | spin_lock_irq(&hw->hw_lock); | ||
| 2188 | hw->intr_mask |= portirqmask[port]; | 2189 | hw->intr_mask |= portirqmask[port]; |
| 2189 | skge_write32(hw, B0_IMSK, hw->intr_mask); | 2190 | skge_write32(hw, B0_IMSK, hw->intr_mask); |
| 2191 | spin_unlock_irq(&hw->hw_lock); | ||
| 2190 | 2192 | ||
| 2191 | /* Initialize MAC */ | 2193 | /* Initialize MAC */ |
| 2192 | spin_lock_bh(&hw->phy_lock); | 2194 | spin_lock_bh(&hw->phy_lock); |
| @@ -2244,8 +2246,10 @@ static int skge_down(struct net_device *dev) | |||
| 2244 | else | 2246 | else |
| 2245 | yukon_stop(skge); | 2247 | yukon_stop(skge); |
| 2246 | 2248 | ||
| 2249 | spin_lock_irq(&hw->hw_lock); | ||
| 2247 | hw->intr_mask &= ~portirqmask[skge->port]; | 2250 | hw->intr_mask &= ~portirqmask[skge->port]; |
| 2248 | skge_write32(hw, B0_IMSK, hw->intr_mask); | 2251 | skge_write32(hw, B0_IMSK, hw->intr_mask); |
| 2252 | spin_unlock_irq(&hw->hw_lock); | ||
| 2249 | 2253 | ||
| 2250 | /* Stop transmitter */ | 2254 | /* Stop transmitter */ |
| 2251 | skge_write8(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_STOP); | 2255 | skge_write8(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_STOP); |
| @@ -2701,10 +2705,11 @@ static int skge_poll(struct net_device *dev, int *budget) | |||
| 2701 | if (work_done >= to_do) | 2705 | if (work_done >= to_do) |
| 2702 | return 1; /* not done */ | 2706 | return 1; /* not done */ |
| 2703 | 2707 | ||
| 2704 | netif_rx_complete(dev); | 2708 | spin_lock_irq(&hw->hw_lock); |
| 2705 | hw->intr_mask |= portirqmask[skge->port]; | 2709 | __netif_rx_complete(dev); |
| 2706 | skge_write32(hw, B0_IMSK, hw->intr_mask); | 2710 | hw->intr_mask |= portirqmask[skge->port]; |
| 2707 | skge_read32(hw, B0_IMSK); | 2711 | skge_write32(hw, B0_IMSK, hw->intr_mask); |
| 2712 | spin_unlock_irq(&hw->hw_lock); | ||
| 2708 | 2713 | ||
| 2709 | return 0; | 2714 | return 0; |
| 2710 | } | 2715 | } |
| @@ -2864,10 +2869,10 @@ static void skge_extirq(unsigned long data) | |||
| 2864 | } | 2869 | } |
| 2865 | spin_unlock(&hw->phy_lock); | 2870 | spin_unlock(&hw->phy_lock); |
| 2866 | 2871 | ||
| 2867 | local_irq_disable(); | 2872 | spin_lock_irq(&hw->hw_lock); |
| 2868 | hw->intr_mask |= IS_EXT_REG; | 2873 | hw->intr_mask |= IS_EXT_REG; |
| 2869 | skge_write32(hw, B0_IMSK, hw->intr_mask); | 2874 | skge_write32(hw, B0_IMSK, hw->intr_mask); |
| 2870 | local_irq_enable(); | 2875 | spin_unlock_irq(&hw->hw_lock); |
| 2871 | } | 2876 | } |
| 2872 | 2877 | ||
| 2873 | static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs) | 2878 | static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs) |
| @@ -2878,7 +2883,7 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs) | |||
| 2878 | if (status == 0 || status == ~0) /* hotplug or shared irq */ | 2883 | if (status == 0 || status == ~0) /* hotplug or shared irq */ |
| 2879 | return IRQ_NONE; | 2884 | return IRQ_NONE; |
| 2880 | 2885 | ||
| 2881 | status &= hw->intr_mask; | 2886 | spin_lock(&hw->hw_lock); |
| 2882 | if (status & IS_R1_F) { | 2887 | if (status & IS_R1_F) { |
| 2883 | skge_write8(hw, Q_ADDR(Q_R1, Q_CSR), CSR_IRQ_CL_F); | 2888 | skge_write8(hw, Q_ADDR(Q_R1, Q_CSR), CSR_IRQ_CL_F); |
| 2884 | hw->intr_mask &= ~IS_R1_F; | 2889 | hw->intr_mask &= ~IS_R1_F; |
| @@ -2930,6 +2935,7 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs) | |||
| 2930 | } | 2935 | } |
| 2931 | 2936 | ||
| 2932 | skge_write32(hw, B0_IMSK, hw->intr_mask); | 2937 | skge_write32(hw, B0_IMSK, hw->intr_mask); |
| 2938 | spin_unlock(&hw->hw_lock); | ||
| 2933 | 2939 | ||
| 2934 | return IRQ_HANDLED; | 2940 | return IRQ_HANDLED; |
| 2935 | } | 2941 | } |
| @@ -3298,6 +3304,7 @@ static int __devinit skge_probe(struct pci_dev *pdev, | |||
| 3298 | 3304 | ||
| 3299 | hw->pdev = pdev; | 3305 | hw->pdev = pdev; |
| 3300 | spin_lock_init(&hw->phy_lock); | 3306 | spin_lock_init(&hw->phy_lock); |
| 3307 | spin_lock_init(&hw->hw_lock); | ||
| 3301 | tasklet_init(&hw->ext_tasklet, skge_extirq, (unsigned long) hw); | 3308 | tasklet_init(&hw->ext_tasklet, skge_extirq, (unsigned long) hw); |
| 3302 | 3309 | ||
| 3303 | hw->regs = ioremap_nocache(pci_resource_start(pdev, 0), 0x4000); | 3310 | hw->regs = ioremap_nocache(pci_resource_start(pdev, 0), 0x4000); |
diff --git a/drivers/net/skge.h b/drivers/net/skge.h index 2efdacc290e5..941f12a333b6 100644 --- a/drivers/net/skge.h +++ b/drivers/net/skge.h | |||
| @@ -2402,6 +2402,7 @@ struct skge_hw { | |||
| 2402 | 2402 | ||
| 2403 | struct tasklet_struct ext_tasklet; | 2403 | struct tasklet_struct ext_tasklet; |
| 2404 | spinlock_t phy_lock; | 2404 | spinlock_t phy_lock; |
| 2405 | spinlock_t hw_lock; | ||
| 2405 | }; | 2406 | }; |
| 2406 | 2407 | ||
| 2407 | enum { | 2408 | enum { |
