aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/3c59x.c68
1 files changed, 41 insertions, 27 deletions
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index beddef98ad92..069a03f717d3 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -644,9 +644,15 @@ struct vortex_private {
644 u16 deferred; /* Resend these interrupts when we 644 u16 deferred; /* Resend these interrupts when we
645 * bale from the ISR */ 645 * bale from the ISR */
646 u16 io_size; /* Size of PCI region (for release_region) */ 646 u16 io_size; /* Size of PCI region (for release_region) */
647 spinlock_t lock; /* Serialise access to device & its vortex_private */ 647
648 struct mii_if_info mii; /* MII lib hooks/info */ 648 /* Serialises access to hardware other than MII and variables below.
649 int window; /* Register window */ 649 * The lock hierarchy is rtnl_lock > lock > mii_lock > window_lock. */
650 spinlock_t lock;
651
652 spinlock_t mii_lock; /* Serialises access to MII */
653 struct mii_if_info mii; /* MII lib hooks/info */
654 spinlock_t window_lock; /* Serialises access to windowed regs */
655 int window; /* Register window */
650}; 656};
651 657
652static void window_set(struct vortex_private *vp, int window) 658static void window_set(struct vortex_private *vp, int window)
@@ -661,15 +667,23 @@ static void window_set(struct vortex_private *vp, int window)
661static u ## size \ 667static u ## size \
662window_read ## size(struct vortex_private *vp, int window, int addr) \ 668window_read ## size(struct vortex_private *vp, int window, int addr) \
663{ \ 669{ \
670 unsigned long flags; \
671 u ## size ret; \
672 spin_lock_irqsave(&vp->window_lock, flags); \
664 window_set(vp, window); \ 673 window_set(vp, window); \
665 return ioread ## size(vp->ioaddr + addr); \ 674 ret = ioread ## size(vp->ioaddr + addr); \
675 spin_unlock_irqrestore(&vp->window_lock, flags); \
676 return ret; \
666} \ 677} \
667static void \ 678static void \
668window_write ## size(struct vortex_private *vp, u ## size value, \ 679window_write ## size(struct vortex_private *vp, u ## size value, \
669 int window, int addr) \ 680 int window, int addr) \
670{ \ 681{ \
682 unsigned long flags; \
683 spin_lock_irqsave(&vp->window_lock, flags); \
671 window_set(vp, window); \ 684 window_set(vp, window); \
672 iowrite ## size(value, vp->ioaddr + addr); \ 685 iowrite ## size(value, vp->ioaddr + addr); \
686 spin_unlock_irqrestore(&vp->window_lock, flags); \
673} 687}
674DEFINE_WINDOW_IO(8) 688DEFINE_WINDOW_IO(8)
675DEFINE_WINDOW_IO(16) 689DEFINE_WINDOW_IO(16)
@@ -1181,6 +1195,8 @@ static int __devinit vortex_probe1(struct device *gendev,
1181 } 1195 }
1182 1196
1183 spin_lock_init(&vp->lock); 1197 spin_lock_init(&vp->lock);
1198 spin_lock_init(&vp->mii_lock);
1199 spin_lock_init(&vp->window_lock);
1184 vp->gendev = gendev; 1200 vp->gendev = gendev;
1185 vp->mii.dev = dev; 1201 vp->mii.dev = dev;
1186 vp->mii.mdio_read = mdio_read; 1202 vp->mii.mdio_read = mdio_read;
@@ -1784,7 +1800,6 @@ vortex_timer(unsigned long data)
1784 pr_debug("dev->watchdog_timeo=%d\n", dev->watchdog_timeo); 1800 pr_debug("dev->watchdog_timeo=%d\n", dev->watchdog_timeo);
1785 } 1801 }
1786 1802
1787 disable_irq_lockdep(dev->irq);
1788 media_status = window_read16(vp, 4, Wn4_Media); 1803 media_status = window_read16(vp, 4, Wn4_Media);
1789 switch (dev->if_port) { 1804 switch (dev->if_port) {
1790 case XCVR_10baseT: case XCVR_100baseTx: case XCVR_100baseFx: 1805 case XCVR_10baseT: case XCVR_100baseTx: case XCVR_100baseFx:
@@ -1805,10 +1820,7 @@ vortex_timer(unsigned long data)
1805 case XCVR_MII: case XCVR_NWAY: 1820 case XCVR_MII: case XCVR_NWAY:
1806 { 1821 {
1807 ok = 1; 1822 ok = 1;
1808 /* Interrupts are already disabled */
1809 spin_lock(&vp->lock);
1810 vortex_check_media(dev, 0); 1823 vortex_check_media(dev, 0);
1811 spin_unlock(&vp->lock);
1812 } 1824 }
1813 break; 1825 break;
1814 default: /* Other media types handled by Tx timeouts. */ 1826 default: /* Other media types handled by Tx timeouts. */
@@ -1827,6 +1839,8 @@ vortex_timer(unsigned long data)
1827 if (!ok) { 1839 if (!ok) {
1828 unsigned int config; 1840 unsigned int config;
1829 1841
1842 spin_lock_irq(&vp->lock);
1843
1830 do { 1844 do {
1831 dev->if_port = media_tbl[dev->if_port].next; 1845 dev->if_port = media_tbl[dev->if_port].next;
1832 } while ( ! (vp->available_media & media_tbl[dev->if_port].mask)); 1846 } while ( ! (vp->available_media & media_tbl[dev->if_port].mask));
@@ -1855,6 +1869,8 @@ vortex_timer(unsigned long data)
1855 if (vortex_debug > 1) 1869 if (vortex_debug > 1)
1856 pr_debug("wrote 0x%08x to Wn3_Config\n", config); 1870 pr_debug("wrote 0x%08x to Wn3_Config\n", config);
1857 /* AKPM: FIXME: Should reset Rx & Tx here. P60 of 3c90xc.pdf */ 1871 /* AKPM: FIXME: Should reset Rx & Tx here. P60 of 3c90xc.pdf */
1872
1873 spin_unlock_irq(&vp->lock);
1858 } 1874 }
1859 1875
1860leave_media_alone: 1876leave_media_alone:
@@ -1862,7 +1878,6 @@ leave_media_alone:
1862 pr_debug("%s: Media selection timer finished, %s.\n", 1878 pr_debug("%s: Media selection timer finished, %s.\n",
1863 dev->name, media_tbl[dev->if_port].name); 1879 dev->name, media_tbl[dev->if_port].name);
1864 1880
1865 enable_irq_lockdep(dev->irq);
1866 mod_timer(&vp->timer, RUN_AT(next_tick)); 1881 mod_timer(&vp->timer, RUN_AT(next_tick));
1867 if (vp->deferred) 1882 if (vp->deferred)
1868 iowrite16(FakeIntr, ioaddr + EL3_CMD); 1883 iowrite16(FakeIntr, ioaddr + EL3_CMD);
@@ -2051,9 +2066,11 @@ vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
2051 int len = (skb->len + 3) & ~3; 2066 int len = (skb->len + 3) & ~3;
2052 vp->tx_skb_dma = pci_map_single(VORTEX_PCI(vp), skb->data, len, 2067 vp->tx_skb_dma = pci_map_single(VORTEX_PCI(vp), skb->data, len,
2053 PCI_DMA_TODEVICE); 2068 PCI_DMA_TODEVICE);
2069 spin_lock_irq(&vp->window_lock);
2054 window_set(vp, 7); 2070 window_set(vp, 7);
2055 iowrite32(vp->tx_skb_dma, ioaddr + Wn7_MasterAddr); 2071 iowrite32(vp->tx_skb_dma, ioaddr + Wn7_MasterAddr);
2056 iowrite16(len, ioaddr + Wn7_MasterLen); 2072 iowrite16(len, ioaddr + Wn7_MasterLen);
2073 spin_unlock_irq(&vp->window_lock);
2057 vp->tx_skb = skb; 2074 vp->tx_skb = skb;
2058 iowrite16(StartDMADown, ioaddr + EL3_CMD); 2075 iowrite16(StartDMADown, ioaddr + EL3_CMD);
2059 /* netif_wake_queue() will be called at the DMADone interrupt. */ 2076 /* netif_wake_queue() will be called at the DMADone interrupt. */
@@ -2225,6 +2242,7 @@ vortex_interrupt(int irq, void *dev_id)
2225 pr_debug("%s: interrupt, status %4.4x, latency %d ticks.\n", 2242 pr_debug("%s: interrupt, status %4.4x, latency %d ticks.\n",
2226 dev->name, status, ioread8(ioaddr + Timer)); 2243 dev->name, status, ioread8(ioaddr + Timer));
2227 2244
2245 spin_lock(&vp->window_lock);
2228 window_set(vp, 7); 2246 window_set(vp, 7);
2229 2247
2230 do { 2248 do {
@@ -2285,6 +2303,8 @@ vortex_interrupt(int irq, void *dev_id)
2285 iowrite16(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD); 2303 iowrite16(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
2286 } while ((status = ioread16(ioaddr + EL3_STATUS)) & (IntLatch | RxComplete)); 2304 } while ((status = ioread16(ioaddr + EL3_STATUS)) & (IntLatch | RxComplete));
2287 2305
2306 spin_unlock(&vp->window_lock);
2307
2288 if (vortex_debug > 4) 2308 if (vortex_debug > 4)
2289 pr_debug("%s: exiting interrupt, status %4.4x.\n", 2309 pr_debug("%s: exiting interrupt, status %4.4x.\n",
2290 dev->name, status); 2310 dev->name, status);
@@ -2806,37 +2826,22 @@ static void update_stats(void __iomem *ioaddr, struct net_device *dev)
2806static int vortex_nway_reset(struct net_device *dev) 2826static int vortex_nway_reset(struct net_device *dev)
2807{ 2827{
2808 struct vortex_private *vp = netdev_priv(dev); 2828 struct vortex_private *vp = netdev_priv(dev);
2809 unsigned long flags;
2810 int rc;
2811 2829
2812 spin_lock_irqsave(&vp->lock, flags); 2830 return mii_nway_restart(&vp->mii);
2813 rc = mii_nway_restart(&vp->mii);
2814 spin_unlock_irqrestore(&vp->lock, flags);
2815 return rc;
2816} 2831}
2817 2832
2818static int vortex_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) 2833static int vortex_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
2819{ 2834{
2820 struct vortex_private *vp = netdev_priv(dev); 2835 struct vortex_private *vp = netdev_priv(dev);
2821 unsigned long flags;
2822 int rc;
2823 2836
2824 spin_lock_irqsave(&vp->lock, flags); 2837 return mii_ethtool_gset(&vp->mii, cmd);
2825 rc = mii_ethtool_gset(&vp->mii, cmd);
2826 spin_unlock_irqrestore(&vp->lock, flags);
2827 return rc;
2828} 2838}
2829 2839
2830static int vortex_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) 2840static int vortex_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
2831{ 2841{
2832 struct vortex_private *vp = netdev_priv(dev); 2842 struct vortex_private *vp = netdev_priv(dev);
2833 unsigned long flags;
2834 int rc;
2835 2843
2836 spin_lock_irqsave(&vp->lock, flags); 2844 return mii_ethtool_sset(&vp->mii, cmd);
2837 rc = mii_ethtool_sset(&vp->mii, cmd);
2838 spin_unlock_irqrestore(&vp->lock, flags);
2839 return rc;
2840} 2845}
2841 2846
2842static u32 vortex_get_msglevel(struct net_device *dev) 2847static u32 vortex_get_msglevel(struct net_device *dev)
@@ -3059,6 +3064,8 @@ static int mdio_read(struct net_device *dev, int phy_id, int location)
3059 int read_cmd = (0xf6 << 10) | (phy_id << 5) | location; 3064 int read_cmd = (0xf6 << 10) | (phy_id << 5) | location;
3060 unsigned int retval = 0; 3065 unsigned int retval = 0;
3061 3066
3067 spin_lock_bh(&vp->mii_lock);
3068
3062 if (mii_preamble_required) 3069 if (mii_preamble_required)
3063 mdio_sync(vp, 32); 3070 mdio_sync(vp, 32);
3064 3071
@@ -3082,6 +3089,9 @@ static int mdio_read(struct net_device *dev, int phy_id, int location)
3082 4, Wn4_PhysicalMgmt); 3089 4, Wn4_PhysicalMgmt);
3083 mdio_delay(vp); 3090 mdio_delay(vp);
3084 } 3091 }
3092
3093 spin_unlock_bh(&vp->mii_lock);
3094
3085 return retval & 0x20000 ? 0xffff : retval>>1 & 0xffff; 3095 return retval & 0x20000 ? 0xffff : retval>>1 & 0xffff;
3086} 3096}
3087 3097
@@ -3091,6 +3101,8 @@ static void mdio_write(struct net_device *dev, int phy_id, int location, int val
3091 int write_cmd = 0x50020000 | (phy_id << 23) | (location << 18) | value; 3101 int write_cmd = 0x50020000 | (phy_id << 23) | (location << 18) | value;
3092 int i; 3102 int i;
3093 3103
3104 spin_lock_bh(&vp->mii_lock);
3105
3094 if (mii_preamble_required) 3106 if (mii_preamble_required)
3095 mdio_sync(vp, 32); 3107 mdio_sync(vp, 32);
3096 3108
@@ -3111,6 +3123,8 @@ static void mdio_write(struct net_device *dev, int phy_id, int location, int val
3111 4, Wn4_PhysicalMgmt); 3123 4, Wn4_PhysicalMgmt);
3112 mdio_delay(vp); 3124 mdio_delay(vp);
3113 } 3125 }
3126
3127 spin_unlock_bh(&vp->mii_lock);
3114} 3128}
3115 3129
3116/* ACPI: Advanced Configuration and Power Interface. */ 3130/* ACPI: Advanced Configuration and Power Interface. */