aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/pcmcia/smc91c92_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/pcmcia/smc91c92_cs.c')
-rw-r--r--drivers/net/pcmcia/smc91c92_cs.c44
1 files changed, 27 insertions, 17 deletions
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index ff7eb9116b6a..ccc553782a0d 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -1608,9 +1608,12 @@ static void set_rx_mode(struct net_device *dev)
1608{ 1608{
1609 unsigned int ioaddr = dev->base_addr; 1609 unsigned int ioaddr = dev->base_addr;
1610 struct smc_private *smc = netdev_priv(dev); 1610 struct smc_private *smc = netdev_priv(dev);
1611 u_int multicast_table[ 2 ] = { 0, }; 1611 unsigned char multicast_table[8];
1612 unsigned long flags; 1612 unsigned long flags;
1613 u_short rx_cfg_setting; 1613 u_short rx_cfg_setting;
1614 int i;
1615
1616 memset(multicast_table, 0, sizeof(multicast_table));
1614 1617
1615 if (dev->flags & IFF_PROMISC) { 1618 if (dev->flags & IFF_PROMISC) {
1616 rx_cfg_setting = RxStripCRC | RxEnable | RxPromisc | RxAllMulti; 1619 rx_cfg_setting = RxStripCRC | RxEnable | RxPromisc | RxAllMulti;
@@ -1622,10 +1625,6 @@ static void set_rx_mode(struct net_device *dev)
1622 1625
1623 netdev_for_each_mc_addr(mc_addr, dev) { 1626 netdev_for_each_mc_addr(mc_addr, dev) {
1624 u_int position = ether_crc(6, mc_addr->dmi_addr); 1627 u_int position = ether_crc(6, mc_addr->dmi_addr);
1625#ifndef final_version /* Verify multicast address. */
1626 if ((mc_addr->dmi_addr[0] & 1) == 0)
1627 continue;
1628#endif
1629 multicast_table[position >> 29] |= 1 << ((position >> 26) & 7); 1628 multicast_table[position >> 29] |= 1 << ((position >> 26) & 7);
1630 } 1629 }
1631 } 1630 }
@@ -1635,8 +1634,8 @@ static void set_rx_mode(struct net_device *dev)
1635 /* Load MC table and Rx setting into the chip without interrupts. */ 1634 /* Load MC table and Rx setting into the chip without interrupts. */
1636 spin_lock_irqsave(&smc->lock, flags); 1635 spin_lock_irqsave(&smc->lock, flags);
1637 SMC_SELECT_BANK(3); 1636 SMC_SELECT_BANK(3);
1638 outl(multicast_table[0], ioaddr + MULTICAST0); 1637 for (i = 0; i < 8; i++)
1639 outl(multicast_table[1], ioaddr + MULTICAST4); 1638 outb(multicast_table[i], ioaddr + MULTICAST0 + i);
1640 SMC_SELECT_BANK(0); 1639 SMC_SELECT_BANK(0);
1641 outw(rx_cfg_setting, ioaddr + RCR); 1640 outw(rx_cfg_setting, ioaddr + RCR);
1642 SMC_SELECT_BANK(2); 1641 SMC_SELECT_BANK(2);
@@ -1805,23 +1804,30 @@ static void media_check(u_long arg)
1805 SMC_SELECT_BANK(1); 1804 SMC_SELECT_BANK(1);
1806 media |= (inw(ioaddr + CONFIG) & CFG_AUI_SELECT) ? 2 : 1; 1805 media |= (inw(ioaddr + CONFIG) & CFG_AUI_SELECT) ? 2 : 1;
1807 1806
1807 SMC_SELECT_BANK(saved_bank);
1808 spin_unlock_irqrestore(&smc->lock, flags);
1809
1808 /* Check for pending interrupt with watchdog flag set: with 1810 /* Check for pending interrupt with watchdog flag set: with
1809 this, we can limp along even if the interrupt is blocked */ 1811 this, we can limp along even if the interrupt is blocked */
1810 if (smc->watchdog++ && ((i>>8) & i)) { 1812 if (smc->watchdog++ && ((i>>8) & i)) {
1811 if (!smc->fast_poll) 1813 if (!smc->fast_poll)
1812 printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name); 1814 printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name);
1815 local_irq_save(flags);
1813 smc_interrupt(dev->irq, dev); 1816 smc_interrupt(dev->irq, dev);
1817 local_irq_restore(flags);
1814 smc->fast_poll = HZ; 1818 smc->fast_poll = HZ;
1815 } 1819 }
1816 if (smc->fast_poll) { 1820 if (smc->fast_poll) {
1817 smc->fast_poll--; 1821 smc->fast_poll--;
1818 smc->media.expires = jiffies + HZ/100; 1822 smc->media.expires = jiffies + HZ/100;
1819 add_timer(&smc->media); 1823 add_timer(&smc->media);
1820 SMC_SELECT_BANK(saved_bank);
1821 spin_unlock_irqrestore(&smc->lock, flags);
1822 return; 1824 return;
1823 } 1825 }
1824 1826
1827 spin_lock_irqsave(&smc->lock, flags);
1828
1829 saved_bank = inw(ioaddr + BANK_SELECT);
1830
1825 if (smc->cfg & CFG_MII_SELECT) { 1831 if (smc->cfg & CFG_MII_SELECT) {
1826 if (smc->mii_if.phy_id < 0) 1832 if (smc->mii_if.phy_id < 0)
1827 goto reschedule; 1833 goto reschedule;
@@ -1979,15 +1985,16 @@ static int smc_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
1979 unsigned int ioaddr = dev->base_addr; 1985 unsigned int ioaddr = dev->base_addr;
1980 u16 saved_bank = inw(ioaddr + BANK_SELECT); 1986 u16 saved_bank = inw(ioaddr + BANK_SELECT);
1981 int ret; 1987 int ret;
1988 unsigned long flags;
1982 1989
1983 spin_lock_irq(&smc->lock); 1990 spin_lock_irqsave(&smc->lock, flags);
1984 SMC_SELECT_BANK(3); 1991 SMC_SELECT_BANK(3);
1985 if (smc->cfg & CFG_MII_SELECT) 1992 if (smc->cfg & CFG_MII_SELECT)
1986 ret = mii_ethtool_gset(&smc->mii_if, ecmd); 1993 ret = mii_ethtool_gset(&smc->mii_if, ecmd);
1987 else 1994 else
1988 ret = smc_netdev_get_ecmd(dev, ecmd); 1995 ret = smc_netdev_get_ecmd(dev, ecmd);
1989 SMC_SELECT_BANK(saved_bank); 1996 SMC_SELECT_BANK(saved_bank);
1990 spin_unlock_irq(&smc->lock); 1997 spin_unlock_irqrestore(&smc->lock, flags);
1991 return ret; 1998 return ret;
1992} 1999}
1993 2000
@@ -1997,15 +2004,16 @@ static int smc_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
1997 unsigned int ioaddr = dev->base_addr; 2004 unsigned int ioaddr = dev->base_addr;
1998 u16 saved_bank = inw(ioaddr + BANK_SELECT); 2005 u16 saved_bank = inw(ioaddr + BANK_SELECT);
1999 int ret; 2006 int ret;
2007 unsigned long flags;
2000 2008
2001 spin_lock_irq(&smc->lock); 2009 spin_lock_irqsave(&smc->lock, flags);
2002 SMC_SELECT_BANK(3); 2010 SMC_SELECT_BANK(3);
2003 if (smc->cfg & CFG_MII_SELECT) 2011 if (smc->cfg & CFG_MII_SELECT)
2004 ret = mii_ethtool_sset(&smc->mii_if, ecmd); 2012 ret = mii_ethtool_sset(&smc->mii_if, ecmd);
2005 else 2013 else
2006 ret = smc_netdev_set_ecmd(dev, ecmd); 2014 ret = smc_netdev_set_ecmd(dev, ecmd);
2007 SMC_SELECT_BANK(saved_bank); 2015 SMC_SELECT_BANK(saved_bank);
2008 spin_unlock_irq(&smc->lock); 2016 spin_unlock_irqrestore(&smc->lock, flags);
2009 return ret; 2017 return ret;
2010} 2018}
2011 2019
@@ -2015,12 +2023,13 @@ static u32 smc_get_link(struct net_device *dev)
2015 unsigned int ioaddr = dev->base_addr; 2023 unsigned int ioaddr = dev->base_addr;
2016 u16 saved_bank = inw(ioaddr + BANK_SELECT); 2024 u16 saved_bank = inw(ioaddr + BANK_SELECT);
2017 u32 ret; 2025 u32 ret;
2026 unsigned long flags;
2018 2027
2019 spin_lock_irq(&smc->lock); 2028 spin_lock_irqsave(&smc->lock, flags);
2020 SMC_SELECT_BANK(3); 2029 SMC_SELECT_BANK(3);
2021 ret = smc_link_ok(dev); 2030 ret = smc_link_ok(dev);
2022 SMC_SELECT_BANK(saved_bank); 2031 SMC_SELECT_BANK(saved_bank);
2023 spin_unlock_irq(&smc->lock); 2032 spin_unlock_irqrestore(&smc->lock, flags);
2024 return ret; 2033 return ret;
2025} 2034}
2026 2035
@@ -2057,16 +2066,17 @@ static int smc_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
2057 int rc = 0; 2066 int rc = 0;
2058 u16 saved_bank; 2067 u16 saved_bank;
2059 unsigned int ioaddr = dev->base_addr; 2068 unsigned int ioaddr = dev->base_addr;
2069 unsigned long flags;
2060 2070
2061 if (!netif_running(dev)) 2071 if (!netif_running(dev))
2062 return -EINVAL; 2072 return -EINVAL;
2063 2073
2064 spin_lock_irq(&smc->lock); 2074 spin_lock_irqsave(&smc->lock, flags);
2065 saved_bank = inw(ioaddr + BANK_SELECT); 2075 saved_bank = inw(ioaddr + BANK_SELECT);
2066 SMC_SELECT_BANK(3); 2076 SMC_SELECT_BANK(3);
2067 rc = generic_mii_ioctl(&smc->mii_if, mii, cmd, NULL); 2077 rc = generic_mii_ioctl(&smc->mii_if, mii, cmd, NULL);
2068 SMC_SELECT_BANK(saved_bank); 2078 SMC_SELECT_BANK(saved_bank);
2069 spin_unlock_irq(&smc->lock); 2079 spin_unlock_irqrestore(&smc->lock, flags);
2070 return rc; 2080 return rc;
2071} 2081}
2072 2082