aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-06-23 01:15:09 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-23 01:15:09 -0400
commit065a3e17baa36d1d48eb7376138820035b44775e (patch)
tree556abb5dbeaad98fc5a66bd56f6a647dfbd22182 /drivers/net
parent45c091bb2d453ce4a8b06cf19872ec7a77fc4799 (diff)
parentbfcbb00855db21dacd3c154ea13ec3fdd98e747b (diff)
Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6: (33 commits) [PATCH] myri10ge - drop workaround pci_save_state() disabling MSI [PATCH] myri10ge - drop workaround for the missing AER ext cap on nVidia CK804 via-velocity: the link is not correctly detected when the device starts [PATCH] add b44 to maintainers [PATCH] WAN: ioremap() failure checks in drivers [PATCH] WAN: register_hdlc_device() doesn't need dev_alloc_name() [PATCH] skb_padto()-area fixes in 8390, wavelan [PATCH] make drivers/net/forcedeth.c:nv_update_pause() static [PATCH] network driver for Hilscher netx [PATCH] Dereference in tokenring/olympic.c [PATCH] Array overrun in drivers/net/wireless/wavelan.c [PATCH] Remove useless check in drivers/net/pcmcia/xirc2ps_cs.c [PATCH] 8139cp: add ethtool eeprom support [PATCH] 8139cp: fix eeprom read command length [PATCH] b44: update b44 Kconfig entry [PATCH] b44: update version to 1.01 [PATCH] b44: add wol for old nic [PATCH] b44: add parameter [PATCH] b44: add wol [PATCH] b44: fix manual speed/duplex/autoneg settings ...
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/8139cp.c179
-rw-r--r--drivers/net/8390.c10
-rw-r--r--drivers/net/Kconfig15
-rw-r--r--drivers/net/Makefile1
-rw-r--r--drivers/net/arm/at91_ether.c156
-rw-r--r--drivers/net/arm/at91_ether.h1
-rw-r--r--drivers/net/b44.c277
-rw-r--r--drivers/net/b44.h7
-rw-r--r--drivers/net/forcedeth.c2
-rw-r--r--drivers/net/ioc3-eth.c2
-rw-r--r--drivers/net/myri10ge/myri10ge.c8
-rw-r--r--drivers/net/netx-eth.c516
-rw-r--r--drivers/net/pcmcia/xirc2ps_cs.c2
-rw-r--r--drivers/net/s2io.c48
-rw-r--r--drivers/net/sundance.c8
-rw-r--r--drivers/net/tokenring/olympic.c4
-rw-r--r--drivers/net/via-velocity.c6
-rw-r--r--drivers/net/wan/c101.c6
-rw-r--r--drivers/net/wan/hdlc_generic.c24
-rw-r--r--drivers/net/wan/n2.c5
-rw-r--r--drivers/net/wan/pci200syn.c1
-rw-r--r--drivers/net/wan/wanxl.c12
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx.h100
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c33
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_leds.c4
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_main.c221
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_phy.c9
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_pio.c44
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_pio.h13
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c38
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_wx.c107
-rw-r--r--drivers/net/wireless/ipw2200.c41
-rw-r--r--drivers/net/wireless/ipw2200.h1
-rw-r--r--drivers/net/wireless/wavelan.c18
34 files changed, 1570 insertions, 349 deletions
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
index 46d8c01437e9..a26077a175ad 100644
--- a/drivers/net/8139cp.c
+++ b/drivers/net/8139cp.c
@@ -401,6 +401,11 @@ static void cp_clean_rings (struct cp_private *cp);
401#ifdef CONFIG_NET_POLL_CONTROLLER 401#ifdef CONFIG_NET_POLL_CONTROLLER
402static void cp_poll_controller(struct net_device *dev); 402static void cp_poll_controller(struct net_device *dev);
403#endif 403#endif
404static int cp_get_eeprom_len(struct net_device *dev);
405static int cp_get_eeprom(struct net_device *dev,
406 struct ethtool_eeprom *eeprom, u8 *data);
407static int cp_set_eeprom(struct net_device *dev,
408 struct ethtool_eeprom *eeprom, u8 *data);
404 409
405static struct pci_device_id cp_pci_tbl[] = { 410static struct pci_device_id cp_pci_tbl[] = {
406 { PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139, 411 { PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139,
@@ -1577,6 +1582,9 @@ static struct ethtool_ops cp_ethtool_ops = {
1577 .get_strings = cp_get_strings, 1582 .get_strings = cp_get_strings,
1578 .get_ethtool_stats = cp_get_ethtool_stats, 1583 .get_ethtool_stats = cp_get_ethtool_stats,
1579 .get_perm_addr = ethtool_op_get_perm_addr, 1584 .get_perm_addr = ethtool_op_get_perm_addr,
1585 .get_eeprom_len = cp_get_eeprom_len,
1586 .get_eeprom = cp_get_eeprom,
1587 .set_eeprom = cp_set_eeprom,
1580}; 1588};
1581 1589
1582static int cp_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) 1590static int cp_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
@@ -1612,24 +1620,32 @@ static int cp_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
1612#define eeprom_delay() readl(ee_addr) 1620#define eeprom_delay() readl(ee_addr)
1613 1621
1614/* The EEPROM commands include the alway-set leading bit. */ 1622/* The EEPROM commands include the alway-set leading bit. */
1623#define EE_EXTEND_CMD (4)
1615#define EE_WRITE_CMD (5) 1624#define EE_WRITE_CMD (5)
1616#define EE_READ_CMD (6) 1625#define EE_READ_CMD (6)
1617#define EE_ERASE_CMD (7) 1626#define EE_ERASE_CMD (7)
1618 1627
1619static int read_eeprom (void __iomem *ioaddr, int location, int addr_len) 1628#define EE_EWDS_ADDR (0)
1620{ 1629#define EE_WRAL_ADDR (1)
1621 int i; 1630#define EE_ERAL_ADDR (2)
1622 unsigned retval = 0; 1631#define EE_EWEN_ADDR (3)
1623 void __iomem *ee_addr = ioaddr + Cfg9346; 1632
1624 int read_cmd = location | (EE_READ_CMD << addr_len); 1633#define CP_EEPROM_MAGIC PCI_DEVICE_ID_REALTEK_8139
1625 1634
1635static void eeprom_cmd_start(void __iomem *ee_addr)
1636{
1626 writeb (EE_ENB & ~EE_CS, ee_addr); 1637 writeb (EE_ENB & ~EE_CS, ee_addr);
1627 writeb (EE_ENB, ee_addr); 1638 writeb (EE_ENB, ee_addr);
1628 eeprom_delay (); 1639 eeprom_delay ();
1640}
1629 1641
1630 /* Shift the read command bits out. */ 1642static void eeprom_cmd(void __iomem *ee_addr, int cmd, int cmd_len)
1631 for (i = 4 + addr_len; i >= 0; i--) { 1643{
1632 int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; 1644 int i;
1645
1646 /* Shift the command bits out. */
1647 for (i = cmd_len - 1; i >= 0; i--) {
1648 int dataval = (cmd & (1 << i)) ? EE_DATA_WRITE : 0;
1633 writeb (EE_ENB | dataval, ee_addr); 1649 writeb (EE_ENB | dataval, ee_addr);
1634 eeprom_delay (); 1650 eeprom_delay ();
1635 writeb (EE_ENB | dataval | EE_SHIFT_CLK, ee_addr); 1651 writeb (EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
@@ -1637,6 +1653,33 @@ static int read_eeprom (void __iomem *ioaddr, int location, int addr_len)
1637 } 1653 }
1638 writeb (EE_ENB, ee_addr); 1654 writeb (EE_ENB, ee_addr);
1639 eeprom_delay (); 1655 eeprom_delay ();
1656}
1657
1658static void eeprom_cmd_end(void __iomem *ee_addr)
1659{
1660 writeb (~EE_CS, ee_addr);
1661 eeprom_delay ();
1662}
1663
1664static void eeprom_extend_cmd(void __iomem *ee_addr, int extend_cmd,
1665 int addr_len)
1666{
1667 int cmd = (EE_EXTEND_CMD << addr_len) | (extend_cmd << (addr_len - 2));
1668
1669 eeprom_cmd_start(ee_addr);
1670 eeprom_cmd(ee_addr, cmd, 3 + addr_len);
1671 eeprom_cmd_end(ee_addr);
1672}
1673
1674static u16 read_eeprom (void __iomem *ioaddr, int location, int addr_len)
1675{
1676 int i;
1677 u16 retval = 0;
1678 void __iomem *ee_addr = ioaddr + Cfg9346;
1679 int read_cmd = location | (EE_READ_CMD << addr_len);
1680
1681 eeprom_cmd_start(ee_addr);
1682 eeprom_cmd(ee_addr, read_cmd, 3 + addr_len);
1640 1683
1641 for (i = 16; i > 0; i--) { 1684 for (i = 16; i > 0; i--) {
1642 writeb (EE_ENB | EE_SHIFT_CLK, ee_addr); 1685 writeb (EE_ENB | EE_SHIFT_CLK, ee_addr);
@@ -1648,13 +1691,125 @@ static int read_eeprom (void __iomem *ioaddr, int location, int addr_len)
1648 eeprom_delay (); 1691 eeprom_delay ();
1649 } 1692 }
1650 1693
1651 /* Terminate the EEPROM access. */ 1694 eeprom_cmd_end(ee_addr);
1652 writeb (~EE_CS, ee_addr);
1653 eeprom_delay ();
1654 1695
1655 return retval; 1696 return retval;
1656} 1697}
1657 1698
1699static void write_eeprom(void __iomem *ioaddr, int location, u16 val,
1700 int addr_len)
1701{
1702 int i;
1703 void __iomem *ee_addr = ioaddr + Cfg9346;
1704 int write_cmd = location | (EE_WRITE_CMD << addr_len);
1705
1706 eeprom_extend_cmd(ee_addr, EE_EWEN_ADDR, addr_len);
1707
1708 eeprom_cmd_start(ee_addr);
1709 eeprom_cmd(ee_addr, write_cmd, 3 + addr_len);
1710 eeprom_cmd(ee_addr, val, 16);
1711 eeprom_cmd_end(ee_addr);
1712
1713 eeprom_cmd_start(ee_addr);
1714 for (i = 0; i < 20000; i++)
1715 if (readb(ee_addr) & EE_DATA_READ)
1716 break;
1717 eeprom_cmd_end(ee_addr);
1718
1719 eeprom_extend_cmd(ee_addr, EE_EWDS_ADDR, addr_len);
1720}
1721
1722static int cp_get_eeprom_len(struct net_device *dev)
1723{
1724 struct cp_private *cp = netdev_priv(dev);
1725 int size;
1726
1727 spin_lock_irq(&cp->lock);
1728 size = read_eeprom(cp->regs, 0, 8) == 0x8129 ? 256 : 128;
1729 spin_unlock_irq(&cp->lock);
1730
1731 return size;
1732}
1733
1734static int cp_get_eeprom(struct net_device *dev,
1735 struct ethtool_eeprom *eeprom, u8 *data)
1736{
1737 struct cp_private *cp = netdev_priv(dev);
1738 unsigned int addr_len;
1739 u16 val;
1740 u32 offset = eeprom->offset >> 1;
1741 u32 len = eeprom->len;
1742 u32 i = 0;
1743
1744 eeprom->magic = CP_EEPROM_MAGIC;
1745
1746 spin_lock_irq(&cp->lock);
1747
1748 addr_len = read_eeprom(cp->regs, 0, 8) == 0x8129 ? 8 : 6;
1749
1750 if (eeprom->offset & 1) {
1751 val = read_eeprom(cp->regs, offset, addr_len);
1752 data[i++] = (u8)(val >> 8);
1753 offset++;
1754 }
1755
1756 while (i < len - 1) {
1757 val = read_eeprom(cp->regs, offset, addr_len);
1758 data[i++] = (u8)val;
1759 data[i++] = (u8)(val >> 8);
1760 offset++;
1761 }
1762
1763 if (i < len) {
1764 val = read_eeprom(cp->regs, offset, addr_len);
1765 data[i] = (u8)val;
1766 }
1767
1768 spin_unlock_irq(&cp->lock);
1769 return 0;
1770}
1771
1772static int cp_set_eeprom(struct net_device *dev,
1773 struct ethtool_eeprom *eeprom, u8 *data)
1774{
1775 struct cp_private *cp = netdev_priv(dev);
1776 unsigned int addr_len;
1777 u16 val;
1778 u32 offset = eeprom->offset >> 1;
1779 u32 len = eeprom->len;
1780 u32 i = 0;
1781
1782 if (eeprom->magic != CP_EEPROM_MAGIC)
1783 return -EINVAL;
1784
1785 spin_lock_irq(&cp->lock);
1786
1787 addr_len = read_eeprom(cp->regs, 0, 8) == 0x8129 ? 8 : 6;
1788
1789 if (eeprom->offset & 1) {
1790 val = read_eeprom(cp->regs, offset, addr_len) & 0xff;
1791 val |= (u16)data[i++] << 8;
1792 write_eeprom(cp->regs, offset, val, addr_len);
1793 offset++;
1794 }
1795
1796 while (i < len - 1) {
1797 val = (u16)data[i++];
1798 val |= (u16)data[i++] << 8;
1799 write_eeprom(cp->regs, offset, val, addr_len);
1800 offset++;
1801 }
1802
1803 if (i < len) {
1804 val = read_eeprom(cp->regs, offset, addr_len) & 0xff00;
1805 val |= (u16)data[i];
1806 write_eeprom(cp->regs, offset, val, addr_len);
1807 }
1808
1809 spin_unlock_irq(&cp->lock);
1810 return 0;
1811}
1812
1658/* Put the board into D3cold state and wait for WakeUp signal */ 1813/* Put the board into D3cold state and wait for WakeUp signal */
1659static void cp_set_d3_state (struct cp_private *cp) 1814static void cp_set_d3_state (struct cp_private *cp)
1660{ 1815{
diff --git a/drivers/net/8390.c b/drivers/net/8390.c
index f87027420081..86be96af9c8f 100644
--- a/drivers/net/8390.c
+++ b/drivers/net/8390.c
@@ -275,12 +275,14 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
275 struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); 275 struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
276 int send_length = skb->len, output_page; 276 int send_length = skb->len, output_page;
277 unsigned long flags; 277 unsigned long flags;
278 char buf[ETH_ZLEN];
279 char *data = skb->data;
278 280
279 if (skb->len < ETH_ZLEN) { 281 if (skb->len < ETH_ZLEN) {
280 skb = skb_padto(skb, ETH_ZLEN); 282 memset(buf, 0, ETH_ZLEN); /* more efficient than doing just the needed bits */
281 if (skb == NULL) 283 memcpy(buf, data, skb->len);
282 return 0;
283 send_length = ETH_ZLEN; 284 send_length = ETH_ZLEN;
285 data = buf;
284 } 286 }
285 287
286 /* Mask interrupts from the ethercard. 288 /* Mask interrupts from the ethercard.
@@ -347,7 +349,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
347 * trigger the send later, upon receiving a Tx done interrupt. 349 * trigger the send later, upon receiving a Tx done interrupt.
348 */ 350 */
349 351
350 ei_block_output(dev, send_length, skb->data, output_page); 352 ei_block_output(dev, send_length, data, output_page);
351 353
352 if (! ei_local->txing) 354 if (! ei_local->txing)
353 { 355 {
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index c3c1a8d5f7a3..39189903e355 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -854,6 +854,17 @@ config SMC9194
854 <file:Documentation/networking/net-modules.txt>. The module 854 <file:Documentation/networking/net-modules.txt>. The module
855 will be called smc9194. 855 will be called smc9194.
856 856
857config NET_NETX
858 tristate "NetX Ethernet support"
859 select MII
860 depends on NET_ETHERNET && ARCH_NETX
861 help
862 This is support for the Hilscher netX builtin Ethernet ports
863
864 To compile this driver as a module, choose M here and read
865 <file:Documentation/networking/net-modules.txt>. The module
866 will be called netx-eth.
867
857config DM9000 868config DM9000
858 tristate "DM9000 support" 869 tristate "DM9000 support"
859 depends on (ARM || MIPS) && NET_ETHERNET 870 depends on (ARM || MIPS) && NET_ETHERNET
@@ -1376,8 +1387,8 @@ config APRICOT
1376 called apricot. 1387 called apricot.
1377 1388
1378config B44 1389config B44
1379 tristate "Broadcom 4400 ethernet support (EXPERIMENTAL)" 1390 tristate "Broadcom 4400 ethernet support"
1380 depends on NET_PCI && PCI && EXPERIMENTAL 1391 depends on NET_PCI && PCI
1381 select MII 1392 select MII
1382 help 1393 help
1383 If you have a network (Ethernet) controller of this type, say Y and 1394 If you have a network (Ethernet) controller of this type, say Y and
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 1eced3287507..c91e95126f78 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -187,6 +187,7 @@ obj-$(CONFIG_MACSONIC) += macsonic.o
187obj-$(CONFIG_MACMACE) += macmace.o 187obj-$(CONFIG_MACMACE) += macmace.o
188obj-$(CONFIG_MAC89x0) += mac89x0.o 188obj-$(CONFIG_MAC89x0) += mac89x0.o
189obj-$(CONFIG_TUN) += tun.o 189obj-$(CONFIG_TUN) += tun.o
190obj-$(CONFIG_NET_NETX) += netx-eth.o
190obj-$(CONFIG_DL2K) += dl2k.o 191obj-$(CONFIG_DL2K) += dl2k.o
191obj-$(CONFIG_R8169) += r8169.o 192obj-$(CONFIG_R8169) += r8169.o
192obj-$(CONFIG_AMD8111_ETH) += amd8111e.o 193obj-$(CONFIG_AMD8111_ETH) += amd8111e.o
diff --git a/drivers/net/arm/at91_ether.c b/drivers/net/arm/at91_ether.c
index 5503dc8a66e4..613005a0285d 100644
--- a/drivers/net/arm/at91_ether.c
+++ b/drivers/net/arm/at91_ether.c
@@ -43,7 +43,9 @@
43#define DRV_VERSION "1.0" 43#define DRV_VERSION "1.0"
44 44
45static struct net_device *at91_dev; 45static struct net_device *at91_dev;
46static struct clk *ether_clk; 46
47static struct timer_list check_timer;
48#define LINK_POLL_INTERVAL (HZ)
47 49
48/* ..................................................................... */ 50/* ..................................................................... */
49 51
@@ -143,7 +145,7 @@ static void read_phy(unsigned char phy_addr, unsigned char address, unsigned int
143 * MAC accordingly. 145 * MAC accordingly.
144 * If no link or auto-negotiation is busy, then no changes are made. 146 * If no link or auto-negotiation is busy, then no changes are made.
145 */ 147 */
146static void update_linkspeed(struct net_device *dev) 148static void update_linkspeed(struct net_device *dev, int silent)
147{ 149{
148 struct at91_private *lp = (struct at91_private *) dev->priv; 150 struct at91_private *lp = (struct at91_private *) dev->priv;
149 unsigned int bmsr, bmcr, lpa, mac_cfg; 151 unsigned int bmsr, bmcr, lpa, mac_cfg;
@@ -151,7 +153,8 @@ static void update_linkspeed(struct net_device *dev)
151 153
152 if (!mii_link_ok(&lp->mii)) { /* no link */ 154 if (!mii_link_ok(&lp->mii)) { /* no link */
153 netif_carrier_off(dev); 155 netif_carrier_off(dev);
154 printk(KERN_INFO "%s: Link down.\n", dev->name); 156 if (!silent)
157 printk(KERN_INFO "%s: Link down.\n", dev->name);
155 return; 158 return;
156 } 159 }
157 160
@@ -186,7 +189,8 @@ static void update_linkspeed(struct net_device *dev)
186 } 189 }
187 at91_emac_write(AT91_EMAC_CFG, mac_cfg); 190 at91_emac_write(AT91_EMAC_CFG, mac_cfg);
188 191
189 printk(KERN_INFO "%s: Link now %i-%s\n", dev->name, speed, (duplex == DUPLEX_FULL) ? "FullDuplex" : "HalfDuplex"); 192 if (!silent)
193 printk(KERN_INFO "%s: Link now %i-%s\n", dev->name, speed, (duplex == DUPLEX_FULL) ? "FullDuplex" : "HalfDuplex");
190 netif_carrier_on(dev); 194 netif_carrier_on(dev);
191} 195}
192 196
@@ -226,7 +230,7 @@ static irqreturn_t at91ether_phy_interrupt(int irq, void *dev_id, struct pt_regs
226 goto done; 230 goto done;
227 } 231 }
228 232
229 update_linkspeed(dev); 233 update_linkspeed(dev, 0);
230 234
231done: 235done:
232 disable_mdi(); 236 disable_mdi();
@@ -243,14 +247,17 @@ static void enable_phyirq(struct net_device *dev)
243 unsigned int dsintr, irq_number; 247 unsigned int dsintr, irq_number;
244 int status; 248 int status;
245 249
246 if (lp->phy_type == MII_RTL8201_ID) /* RTL8201 does not have an interrupt */ 250 irq_number = lp->board_data.phy_irq_pin;
247 return; 251 if (!irq_number) {
248 if (lp->phy_type == MII_DP83847_ID) /* DP83847 does not have an interrupt */ 252 /*
249 return; 253 * PHY doesn't have an IRQ pin (RTL8201, DP83847, AC101L),
250 if (lp->phy_type == MII_AC101L_ID) /* AC101L interrupt not supported yet */ 254 * or board does not have it connected.
255 */
256 check_timer.expires = jiffies + LINK_POLL_INTERVAL;
257 add_timer(&check_timer);
251 return; 258 return;
259 }
252 260
253 irq_number = lp->board_data.phy_irq_pin;
254 status = request_irq(irq_number, at91ether_phy_interrupt, 0, dev->name, dev); 261 status = request_irq(irq_number, at91ether_phy_interrupt, 0, dev->name, dev);
255 if (status) { 262 if (status) {
256 printk(KERN_ERR "at91_ether: PHY IRQ %d request failed - status %d!\n", irq_number, status); 263 printk(KERN_ERR "at91_ether: PHY IRQ %d request failed - status %d!\n", irq_number, status);
@@ -292,12 +299,11 @@ static void disable_phyirq(struct net_device *dev)
292 unsigned int dsintr; 299 unsigned int dsintr;
293 unsigned int irq_number; 300 unsigned int irq_number;
294 301
295 if (lp->phy_type == MII_RTL8201_ID) /* RTL8201 does not have an interrupt */ 302 irq_number = lp->board_data.phy_irq_pin;
296 return; 303 if (!irq_number) {
297 if (lp->phy_type == MII_DP83847_ID) /* DP83847 does not have an interrupt */ 304 del_timer_sync(&check_timer);
298 return;
299 if (lp->phy_type == MII_AC101L_ID) /* AC101L interrupt not supported yet */
300 return; 305 return;
306 }
301 307
302 spin_lock_irq(&lp->lock); 308 spin_lock_irq(&lp->lock);
303 enable_mdi(); 309 enable_mdi();
@@ -326,7 +332,6 @@ static void disable_phyirq(struct net_device *dev)
326 disable_mdi(); 332 disable_mdi();
327 spin_unlock_irq(&lp->lock); 333 spin_unlock_irq(&lp->lock);
328 334
329 irq_number = lp->board_data.phy_irq_pin;
330 free_irq(irq_number, dev); /* Free interrupt handler */ 335 free_irq(irq_number, dev); /* Free interrupt handler */
331} 336}
332 337
@@ -355,6 +360,18 @@ static void reset_phy(struct net_device *dev)
355} 360}
356#endif 361#endif
357 362
363static void at91ether_check_link(unsigned long dev_id)
364{
365 struct net_device *dev = (struct net_device *) dev_id;
366
367 enable_mdi();
368 update_linkspeed(dev, 1);
369 disable_mdi();
370
371 check_timer.expires = jiffies + LINK_POLL_INTERVAL;
372 add_timer(&check_timer);
373}
374
358/* ......................... ADDRESS MANAGEMENT ........................ */ 375/* ......................... ADDRESS MANAGEMENT ........................ */
359 376
360/* 377/*
@@ -501,7 +518,7 @@ static int hash_get_index(__u8 *addr)
501 hash_index |= (bitval << j); 518 hash_index |= (bitval << j);
502 } 519 }
503 520
504 return hash_index; 521 return hash_index;
505} 522}
506 523
507/* 524/*
@@ -557,10 +574,8 @@ static void at91ether_set_rx_mode(struct net_device *dev)
557 at91_emac_write(AT91_EMAC_CFG, cfg); 574 at91_emac_write(AT91_EMAC_CFG, cfg);
558} 575}
559 576
560
561/* ......................... ETHTOOL SUPPORT ........................... */ 577/* ......................... ETHTOOL SUPPORT ........................... */
562 578
563
564static int mdio_read(struct net_device *dev, int phy_id, int location) 579static int mdio_read(struct net_device *dev, int phy_id, int location)
565{ 580{
566 unsigned int value; 581 unsigned int value;
@@ -642,6 +657,22 @@ static struct ethtool_ops at91ether_ethtool_ops = {
642 .get_link = ethtool_op_get_link, 657 .get_link = ethtool_op_get_link,
643}; 658};
644 659
660static int at91ether_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
661{
662 struct at91_private *lp = (struct at91_private *) dev->priv;
663 int res;
664
665 if (!netif_running(dev))
666 return -EINVAL;
667
668 spin_lock_irq(&lp->lock);
669 enable_mdi();
670 res = generic_mii_ioctl(&lp->mii, if_mii(rq), cmd, NULL);
671 disable_mdi();
672 spin_unlock_irq(&lp->lock);
673
674 return res;
675}
645 676
646/* ................................ MAC ................................ */ 677/* ................................ MAC ................................ */
647 678
@@ -685,10 +716,10 @@ static int at91ether_open(struct net_device *dev)
685 struct at91_private *lp = (struct at91_private *) dev->priv; 716 struct at91_private *lp = (struct at91_private *) dev->priv;
686 unsigned long ctl; 717 unsigned long ctl;
687 718
688 if (!is_valid_ether_addr(dev->dev_addr)) 719 if (!is_valid_ether_addr(dev->dev_addr))
689 return -EADDRNOTAVAIL; 720 return -EADDRNOTAVAIL;
690 721
691 clk_enable(ether_clk); /* Re-enable Peripheral clock */ 722 clk_enable(lp->ether_clk); /* Re-enable Peripheral clock */
692 723
693 /* Clear internal statistics */ 724 /* Clear internal statistics */
694 ctl = at91_emac_read(AT91_EMAC_CTL); 725 ctl = at91_emac_read(AT91_EMAC_CTL);
@@ -708,7 +739,7 @@ static int at91ether_open(struct net_device *dev)
708 /* Determine current link speed */ 739 /* Determine current link speed */
709 spin_lock_irq(&lp->lock); 740 spin_lock_irq(&lp->lock);
710 enable_mdi(); 741 enable_mdi();
711 update_linkspeed(dev); 742 update_linkspeed(dev, 0);
712 disable_mdi(); 743 disable_mdi();
713 spin_unlock_irq(&lp->lock); 744 spin_unlock_irq(&lp->lock);
714 745
@@ -722,6 +753,7 @@ static int at91ether_open(struct net_device *dev)
722 */ 753 */
723static int at91ether_close(struct net_device *dev) 754static int at91ether_close(struct net_device *dev)
724{ 755{
756 struct at91_private *lp = (struct at91_private *) dev->priv;
725 unsigned long ctl; 757 unsigned long ctl;
726 758
727 /* Disable Receiver and Transmitter */ 759 /* Disable Receiver and Transmitter */
@@ -738,7 +770,7 @@ static int at91ether_close(struct net_device *dev)
738 770
739 netif_stop_queue(dev); 771 netif_stop_queue(dev);
740 772
741 clk_disable(ether_clk); /* Disable Peripheral clock */ 773 clk_disable(lp->ether_clk); /* Disable Peripheral clock */
742 774
743 return 0; 775 return 0;
744} 776}
@@ -870,7 +902,7 @@ static irqreturn_t at91ether_interrupt(int irq, void *dev_id, struct pt_regs *re
870 if (intstatus & AT91_EMAC_RCOM) /* Receive complete */ 902 if (intstatus & AT91_EMAC_RCOM) /* Receive complete */
871 at91ether_rx(dev); 903 at91ether_rx(dev);
872 904
873 if (intstatus & AT91_EMAC_TCOM) { /* Transmit complete */ 905 if (intstatus & AT91_EMAC_TCOM) { /* Transmit complete */
874 /* The TCOM bit is set even if the transmission failed. */ 906 /* The TCOM bit is set even if the transmission failed. */
875 if (intstatus & (AT91_EMAC_TUND | AT91_EMAC_RTRY)) 907 if (intstatus & (AT91_EMAC_TUND | AT91_EMAC_RTRY))
876 lp->stats.tx_errors += 1; 908 lp->stats.tx_errors += 1;
@@ -899,7 +931,8 @@ static irqreturn_t at91ether_interrupt(int irq, void *dev_id, struct pt_regs *re
899/* 931/*
900 * Initialize the ethernet interface 932 * Initialize the ethernet interface
901 */ 933 */
902static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_address, struct platform_device *pdev) 934static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_address,
935 struct platform_device *pdev, struct clk *ether_clk)
903{ 936{
904 struct at91_eth_data *board_data = pdev->dev.platform_data; 937 struct at91_eth_data *board_data = pdev->dev.platform_data;
905 struct net_device *dev; 938 struct net_device *dev;
@@ -933,6 +966,7 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add
933 return -ENOMEM; 966 return -ENOMEM;
934 } 967 }
935 lp->board_data = *board_data; 968 lp->board_data = *board_data;
969 lp->ether_clk = ether_clk;
936 platform_set_drvdata(pdev, dev); 970 platform_set_drvdata(pdev, dev);
937 971
938 spin_lock_init(&lp->lock); 972 spin_lock_init(&lp->lock);
@@ -945,6 +979,7 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add
945 dev->set_multicast_list = at91ether_set_rx_mode; 979 dev->set_multicast_list = at91ether_set_rx_mode;
946 dev->set_mac_address = set_mac_address; 980 dev->set_mac_address = set_mac_address;
947 dev->ethtool_ops = &at91ether_ethtool_ops; 981 dev->ethtool_ops = &at91ether_ethtool_ops;
982 dev->do_ioctl = at91ether_ioctl;
948 983
949 SET_NETDEV_DEV(dev, &pdev->dev); 984 SET_NETDEV_DEV(dev, &pdev->dev);
950 985
@@ -975,6 +1010,9 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add
975 lp->mii.dev = dev; /* Support for ethtool */ 1010 lp->mii.dev = dev; /* Support for ethtool */
976 lp->mii.mdio_read = mdio_read; 1011 lp->mii.mdio_read = mdio_read;
977 lp->mii.mdio_write = mdio_write; 1012 lp->mii.mdio_write = mdio_write;
1013 lp->mii.phy_id = phy_address;
1014 lp->mii.phy_id_mask = 0x1f;
1015 lp->mii.reg_num_mask = 0x1f;
978 1016
979 lp->phy_type = phy_type; /* Type of PHY connected */ 1017 lp->phy_type = phy_type; /* Type of PHY connected */
980 lp->phy_address = phy_address; /* MDI address of PHY */ 1018 lp->phy_address = phy_address; /* MDI address of PHY */
@@ -992,11 +1030,18 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add
992 /* Determine current link speed */ 1030 /* Determine current link speed */
993 spin_lock_irq(&lp->lock); 1031 spin_lock_irq(&lp->lock);
994 enable_mdi(); 1032 enable_mdi();
995 update_linkspeed(dev); 1033 update_linkspeed(dev, 0);
996 disable_mdi(); 1034 disable_mdi();
997 spin_unlock_irq(&lp->lock); 1035 spin_unlock_irq(&lp->lock);
998 netif_carrier_off(dev); /* will be enabled in open() */ 1036 netif_carrier_off(dev); /* will be enabled in open() */
999 1037
1038 /* If board has no PHY IRQ, use a timer to poll the PHY */
1039 if (!lp->board_data.phy_irq_pin) {
1040 init_timer(&check_timer);
1041 check_timer.data = (unsigned long)dev;
1042 check_timer.function = at91ether_check_link;
1043 }
1044
1000 /* Display ethernet banner */ 1045 /* Display ethernet banner */
1001 printk(KERN_INFO "%s: AT91 ethernet at 0x%08x int=%d %s%s (%02x:%02x:%02x:%02x:%02x:%02x)\n", 1046 printk(KERN_INFO "%s: AT91 ethernet at 0x%08x int=%d %s%s (%02x:%02x:%02x:%02x:%02x:%02x)\n",
1002 dev->name, (uint) dev->base_addr, dev->irq, 1047 dev->name, (uint) dev->base_addr, dev->irq,
@@ -1005,7 +1050,7 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add
1005 dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], 1050 dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
1006 dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); 1051 dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
1007 if ((phy_type == MII_DM9161_ID) || (lp->phy_type == MII_DM9161A_ID)) 1052 if ((phy_type == MII_DM9161_ID) || (lp->phy_type == MII_DM9161A_ID))
1008 printk(KERN_INFO "%s: Davicom 9196 PHY %s\n", dev->name, (lp->phy_media == PORT_FIBRE) ? "(Fiber)" : "(Copper)"); 1053 printk(KERN_INFO "%s: Davicom 9161 PHY %s\n", dev->name, (lp->phy_media == PORT_FIBRE) ? "(Fiber)" : "(Copper)");
1009 else if (phy_type == MII_LXT971A_ID) 1054 else if (phy_type == MII_LXT971A_ID)
1010 printk(KERN_INFO "%s: Intel LXT971A PHY\n", dev->name); 1055 printk(KERN_INFO "%s: Intel LXT971A PHY\n", dev->name);
1011 else if (phy_type == MII_RTL8201_ID) 1056 else if (phy_type == MII_RTL8201_ID)
@@ -1031,9 +1076,10 @@ static int __init at91ether_probe(struct platform_device *pdev)
1031 int detected = -1; 1076 int detected = -1;
1032 unsigned long phy_id; 1077 unsigned long phy_id;
1033 unsigned short phy_address = 0; 1078 unsigned short phy_address = 0;
1079 struct clk *ether_clk;
1034 1080
1035 ether_clk = clk_get(&pdev->dev, "ether_clk"); 1081 ether_clk = clk_get(&pdev->dev, "ether_clk");
1036 if (!ether_clk) { 1082 if (IS_ERR(ether_clk)) {
1037 printk(KERN_ERR "at91_ether: no clock defined\n"); 1083 printk(KERN_ERR "at91_ether: no clock defined\n");
1038 return -ENODEV; 1084 return -ENODEV;
1039 } 1085 }
@@ -1056,7 +1102,7 @@ static int __init at91ether_probe(struct platform_device *pdev)
1056 case MII_DP83847_ID: /* National Semiconductor DP83847: */ 1102 case MII_DP83847_ID: /* National Semiconductor DP83847: */
1057 case MII_AC101L_ID: /* Altima AC101L: PHY_ID1 = 0x22, PHY_ID2 = 0x5520 */ 1103 case MII_AC101L_ID: /* Altima AC101L: PHY_ID1 = 0x22, PHY_ID2 = 0x5520 */
1058 case MII_KS8721_ID: /* Micrel KS8721: PHY_ID1 = 0x22, PHY_ID2 = 0x1610 */ 1104 case MII_KS8721_ID: /* Micrel KS8721: PHY_ID1 = 0x22, PHY_ID2 = 0x1610 */
1059 detected = at91ether_setup(phy_id, phy_address, pdev); 1105 detected = at91ether_setup(phy_id, phy_address, pdev, ether_clk);
1060 break; 1106 break;
1061 } 1107 }
1062 1108
@@ -1075,17 +1121,61 @@ static int __devexit at91ether_remove(struct platform_device *pdev)
1075 unregister_netdev(at91_dev); 1121 unregister_netdev(at91_dev);
1076 free_irq(at91_dev->irq, at91_dev); 1122 free_irq(at91_dev->irq, at91_dev);
1077 dma_free_coherent(NULL, sizeof(struct recv_desc_bufs), lp->dlist, (dma_addr_t)lp->dlist_phys); 1123 dma_free_coherent(NULL, sizeof(struct recv_desc_bufs), lp->dlist, (dma_addr_t)lp->dlist_phys);
1078 clk_put(ether_clk); 1124 clk_put(lp->ether_clk);
1079 1125
1080 free_netdev(at91_dev); 1126 free_netdev(at91_dev);
1081 at91_dev = NULL; 1127 at91_dev = NULL;
1082 return 0; 1128 return 0;
1083} 1129}
1084 1130
1131#ifdef CONFIG_PM
1132
1133static int at91ether_suspend(struct platform_device *pdev, pm_message_t mesg)
1134{
1135 struct at91_private *lp = (struct at91_private *) at91_dev->priv;
1136 struct net_device *net_dev = platform_get_drvdata(pdev);
1137 int phy_irq = lp->board_data.phy_irq_pin;
1138
1139 if (netif_running(net_dev)) {
1140 if (phy_irq)
1141 disable_irq(phy_irq);
1142
1143 netif_stop_queue(net_dev);
1144 netif_device_detach(net_dev);
1145
1146 clk_disable(lp->ether_clk);
1147 }
1148 return 0;
1149}
1150
1151static int at91ether_resume(struct platform_device *pdev)
1152{
1153 struct at91_private *lp = (struct at91_private *) at91_dev->priv;
1154 struct net_device *net_dev = platform_get_drvdata(pdev);
1155 int phy_irq = lp->board_data.phy_irq_pin;
1156
1157 if (netif_running(net_dev)) {
1158 clk_enable(lp->ether_clk);
1159
1160 netif_device_attach(net_dev);
1161 netif_start_queue(net_dev);
1162
1163 if (phy_irq)
1164 enable_irq(phy_irq);
1165 }
1166 return 0;
1167}
1168
1169#else
1170#define at91ether_suspend NULL
1171#define at91ether_resume NULL
1172#endif
1173
1085static struct platform_driver at91ether_driver = { 1174static struct platform_driver at91ether_driver = {
1086 .probe = at91ether_probe, 1175 .probe = at91ether_probe,
1087 .remove = __devexit_p(at91ether_remove), 1176 .remove = __devexit_p(at91ether_remove),
1088 /* FIXME: support suspend and resume */ 1177 .suspend = at91ether_suspend,
1178 .resume = at91ether_resume,
1089 .driver = { 1179 .driver = {
1090 .name = DRV_NAME, 1180 .name = DRV_NAME,
1091 .owner = THIS_MODULE, 1181 .owner = THIS_MODULE,
diff --git a/drivers/net/arm/at91_ether.h b/drivers/net/arm/at91_ether.h
index 9885735c9c8a..d1e72e02be3a 100644
--- a/drivers/net/arm/at91_ether.h
+++ b/drivers/net/arm/at91_ether.h
@@ -80,6 +80,7 @@ struct at91_private
80 struct net_device_stats stats; 80 struct net_device_stats stats;
81 struct mii_if_info mii; /* ethtool support */ 81 struct mii_if_info mii; /* ethtool support */
82 struct at91_eth_data board_data; /* board-specific configuration */ 82 struct at91_eth_data board_data; /* board-specific configuration */
83 struct clk *ether_clk; /* clock */
83 84
84 /* PHY */ 85 /* PHY */
85 unsigned long phy_type; /* type of PHY (PHY_ID) */ 86 unsigned long phy_type; /* type of PHY (PHY_ID) */
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index d8233e0b7899..a7e4ba5a580f 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -29,8 +29,8 @@
29 29
30#define DRV_MODULE_NAME "b44" 30#define DRV_MODULE_NAME "b44"
31#define PFX DRV_MODULE_NAME ": " 31#define PFX DRV_MODULE_NAME ": "
32#define DRV_MODULE_VERSION "1.00" 32#define DRV_MODULE_VERSION "1.01"
33#define DRV_MODULE_RELDATE "Apr 7, 2006" 33#define DRV_MODULE_RELDATE "Jun 16, 2006"
34 34
35#define B44_DEF_MSG_ENABLE \ 35#define B44_DEF_MSG_ENABLE \
36 (NETIF_MSG_DRV | \ 36 (NETIF_MSG_DRV | \
@@ -75,6 +75,15 @@
75/* minimum number of free TX descriptors required to wake up TX process */ 75/* minimum number of free TX descriptors required to wake up TX process */
76#define B44_TX_WAKEUP_THRESH (B44_TX_RING_SIZE / 4) 76#define B44_TX_WAKEUP_THRESH (B44_TX_RING_SIZE / 4)
77 77
78/* b44 internal pattern match filter info */
79#define B44_PATTERN_BASE 0x400
80#define B44_PATTERN_SIZE 0x80
81#define B44_PMASK_BASE 0x600
82#define B44_PMASK_SIZE 0x10
83#define B44_MAX_PATTERNS 16
84#define B44_ETHIPV6UDP_HLEN 62
85#define B44_ETHIPV4UDP_HLEN 42
86
78static char version[] __devinitdata = 87static char version[] __devinitdata =
79 DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; 88 DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
80 89
@@ -101,7 +110,7 @@ MODULE_DEVICE_TABLE(pci, b44_pci_tbl);
101 110
102static void b44_halt(struct b44 *); 111static void b44_halt(struct b44 *);
103static void b44_init_rings(struct b44 *); 112static void b44_init_rings(struct b44 *);
104static void b44_init_hw(struct b44 *); 113static void b44_init_hw(struct b44 *, int);
105 114
106static int dma_desc_align_mask; 115static int dma_desc_align_mask;
107static int dma_desc_sync_size; 116static int dma_desc_sync_size;
@@ -873,7 +882,7 @@ static int b44_poll(struct net_device *netdev, int *budget)
873 spin_lock_irq(&bp->lock); 882 spin_lock_irq(&bp->lock);
874 b44_halt(bp); 883 b44_halt(bp);
875 b44_init_rings(bp); 884 b44_init_rings(bp);
876 b44_init_hw(bp); 885 b44_init_hw(bp, 1);
877 netif_wake_queue(bp->dev); 886 netif_wake_queue(bp->dev);
878 spin_unlock_irq(&bp->lock); 887 spin_unlock_irq(&bp->lock);
879 done = 1; 888 done = 1;
@@ -942,7 +951,7 @@ static void b44_tx_timeout(struct net_device *dev)
942 951
943 b44_halt(bp); 952 b44_halt(bp);
944 b44_init_rings(bp); 953 b44_init_rings(bp);
945 b44_init_hw(bp); 954 b44_init_hw(bp, 1);
946 955
947 spin_unlock_irq(&bp->lock); 956 spin_unlock_irq(&bp->lock);
948 957
@@ -1059,7 +1068,7 @@ static int b44_change_mtu(struct net_device *dev, int new_mtu)
1059 b44_halt(bp); 1068 b44_halt(bp);
1060 dev->mtu = new_mtu; 1069 dev->mtu = new_mtu;
1061 b44_init_rings(bp); 1070 b44_init_rings(bp);
1062 b44_init_hw(bp); 1071 b44_init_hw(bp, 1);
1063 spin_unlock_irq(&bp->lock); 1072 spin_unlock_irq(&bp->lock);
1064 1073
1065 b44_enable_ints(bp); 1074 b44_enable_ints(bp);
@@ -1356,13 +1365,15 @@ static int b44_set_mac_addr(struct net_device *dev, void *p)
1356 * packet processing. Invoked with bp->lock held. 1365 * packet processing. Invoked with bp->lock held.
1357 */ 1366 */
1358static void __b44_set_rx_mode(struct net_device *); 1367static void __b44_set_rx_mode(struct net_device *);
1359static void b44_init_hw(struct b44 *bp) 1368static void b44_init_hw(struct b44 *bp, int full_reset)
1360{ 1369{
1361 u32 val; 1370 u32 val;
1362 1371
1363 b44_chip_reset(bp); 1372 b44_chip_reset(bp);
1364 b44_phy_reset(bp); 1373 if (full_reset) {
1365 b44_setup_phy(bp); 1374 b44_phy_reset(bp);
1375 b44_setup_phy(bp);
1376 }
1366 1377
1367 /* Enable CRC32, set proper LED modes and power on PHY */ 1378 /* Enable CRC32, set proper LED modes and power on PHY */
1368 bw32(bp, B44_MAC_CTRL, MAC_CTRL_CRC32_ENAB | MAC_CTRL_PHY_LEDCTRL); 1379 bw32(bp, B44_MAC_CTRL, MAC_CTRL_CRC32_ENAB | MAC_CTRL_PHY_LEDCTRL);
@@ -1376,16 +1387,21 @@ static void b44_init_hw(struct b44 *bp)
1376 bw32(bp, B44_TXMAXLEN, bp->dev->mtu + ETH_HLEN + 8 + RX_HEADER_LEN); 1387 bw32(bp, B44_TXMAXLEN, bp->dev->mtu + ETH_HLEN + 8 + RX_HEADER_LEN);
1377 1388
1378 bw32(bp, B44_TX_WMARK, 56); /* XXX magic */ 1389 bw32(bp, B44_TX_WMARK, 56); /* XXX magic */
1379 bw32(bp, B44_DMATX_CTRL, DMATX_CTRL_ENABLE); 1390 if (full_reset) {
1380 bw32(bp, B44_DMATX_ADDR, bp->tx_ring_dma + bp->dma_offset); 1391 bw32(bp, B44_DMATX_CTRL, DMATX_CTRL_ENABLE);
1381 bw32(bp, B44_DMARX_CTRL, (DMARX_CTRL_ENABLE | 1392 bw32(bp, B44_DMATX_ADDR, bp->tx_ring_dma + bp->dma_offset);
1382 (bp->rx_offset << DMARX_CTRL_ROSHIFT))); 1393 bw32(bp, B44_DMARX_CTRL, (DMARX_CTRL_ENABLE |
1383 bw32(bp, B44_DMARX_ADDR, bp->rx_ring_dma + bp->dma_offset); 1394 (bp->rx_offset << DMARX_CTRL_ROSHIFT)));
1395 bw32(bp, B44_DMARX_ADDR, bp->rx_ring_dma + bp->dma_offset);
1384 1396
1385 bw32(bp, B44_DMARX_PTR, bp->rx_pending); 1397 bw32(bp, B44_DMARX_PTR, bp->rx_pending);
1386 bp->rx_prod = bp->rx_pending; 1398 bp->rx_prod = bp->rx_pending;
1387 1399
1388 bw32(bp, B44_MIB_CTRL, MIB_CTRL_CLR_ON_READ); 1400 bw32(bp, B44_MIB_CTRL, MIB_CTRL_CLR_ON_READ);
1401 } else {
1402 bw32(bp, B44_DMARX_CTRL, (DMARX_CTRL_ENABLE |
1403 (bp->rx_offset << DMARX_CTRL_ROSHIFT)));
1404 }
1389 1405
1390 val = br32(bp, B44_ENET_CTRL); 1406 val = br32(bp, B44_ENET_CTRL);
1391 bw32(bp, B44_ENET_CTRL, (val | ENET_CTRL_ENABLE)); 1407 bw32(bp, B44_ENET_CTRL, (val | ENET_CTRL_ENABLE));
@@ -1401,7 +1417,7 @@ static int b44_open(struct net_device *dev)
1401 goto out; 1417 goto out;
1402 1418
1403 b44_init_rings(bp); 1419 b44_init_rings(bp);
1404 b44_init_hw(bp); 1420 b44_init_hw(bp, 1);
1405 1421
1406 b44_check_phy(bp); 1422 b44_check_phy(bp);
1407 1423
@@ -1450,6 +1466,140 @@ static void b44_poll_controller(struct net_device *dev)
1450} 1466}
1451#endif 1467#endif
1452 1468
1469static void bwfilter_table(struct b44 *bp, u8 *pp, u32 bytes, u32 table_offset)
1470{
1471 u32 i;
1472 u32 *pattern = (u32 *) pp;
1473
1474 for (i = 0; i < bytes; i += sizeof(u32)) {
1475 bw32(bp, B44_FILT_ADDR, table_offset + i);
1476 bw32(bp, B44_FILT_DATA, pattern[i / sizeof(u32)]);
1477 }
1478}
1479
1480static int b44_magic_pattern(u8 *macaddr, u8 *ppattern, u8 *pmask, int offset)
1481{
1482 int magicsync = 6;
1483 int k, j, len = offset;
1484 int ethaddr_bytes = ETH_ALEN;
1485
1486 memset(ppattern + offset, 0xff, magicsync);
1487 for (j = 0; j < magicsync; j++)
1488 set_bit(len++, (unsigned long *) pmask);
1489
1490 for (j = 0; j < B44_MAX_PATTERNS; j++) {
1491 if ((B44_PATTERN_SIZE - len) >= ETH_ALEN)
1492 ethaddr_bytes = ETH_ALEN;
1493 else
1494 ethaddr_bytes = B44_PATTERN_SIZE - len;
1495 if (ethaddr_bytes <=0)
1496 break;
1497 for (k = 0; k< ethaddr_bytes; k++) {
1498 ppattern[offset + magicsync +
1499 (j * ETH_ALEN) + k] = macaddr[k];
1500 len++;
1501 set_bit(len, (unsigned long *) pmask);
1502 }
1503 }
1504 return len - 1;
1505}
1506
1507/* Setup magic packet patterns in the b44 WOL
1508 * pattern matching filter.
1509 */
1510static void b44_setup_pseudo_magicp(struct b44 *bp)
1511{
1512
1513 u32 val;
1514 int plen0, plen1, plen2;
1515 u8 *pwol_pattern;
1516 u8 pwol_mask[B44_PMASK_SIZE];
1517
1518 pwol_pattern = kmalloc(B44_PATTERN_SIZE, GFP_KERNEL);
1519 if (!pwol_pattern) {
1520 printk(KERN_ERR PFX "Memory not available for WOL\n");
1521 return;
1522 }
1523
1524 /* Ipv4 magic packet pattern - pattern 0.*/
1525 memset(pwol_pattern, 0, B44_PATTERN_SIZE);
1526 memset(pwol_mask, 0, B44_PMASK_SIZE);
1527 plen0 = b44_magic_pattern(bp->dev->dev_addr, pwol_pattern, pwol_mask,
1528 B44_ETHIPV4UDP_HLEN);
1529
1530 bwfilter_table(bp, pwol_pattern, B44_PATTERN_SIZE, B44_PATTERN_BASE);
1531 bwfilter_table(bp, pwol_mask, B44_PMASK_SIZE, B44_PMASK_BASE);
1532
1533 /* Raw ethernet II magic packet pattern - pattern 1 */
1534 memset(pwol_pattern, 0, B44_PATTERN_SIZE);
1535 memset(pwol_mask, 0, B44_PMASK_SIZE);
1536 plen1 = b44_magic_pattern(bp->dev->dev_addr, pwol_pattern, pwol_mask,
1537 ETH_HLEN);
1538
1539 bwfilter_table(bp, pwol_pattern, B44_PATTERN_SIZE,
1540 B44_PATTERN_BASE + B44_PATTERN_SIZE);
1541 bwfilter_table(bp, pwol_mask, B44_PMASK_SIZE,
1542 B44_PMASK_BASE + B44_PMASK_SIZE);
1543
1544 /* Ipv6 magic packet pattern - pattern 2 */
1545 memset(pwol_pattern, 0, B44_PATTERN_SIZE);
1546 memset(pwol_mask, 0, B44_PMASK_SIZE);
1547 plen2 = b44_magic_pattern(bp->dev->dev_addr, pwol_pattern, pwol_mask,
1548 B44_ETHIPV6UDP_HLEN);
1549
1550 bwfilter_table(bp, pwol_pattern, B44_PATTERN_SIZE,
1551 B44_PATTERN_BASE + B44_PATTERN_SIZE + B44_PATTERN_SIZE);
1552 bwfilter_table(bp, pwol_mask, B44_PMASK_SIZE,
1553 B44_PMASK_BASE + B44_PMASK_SIZE + B44_PMASK_SIZE);
1554
1555 kfree(pwol_pattern);
1556
1557 /* set these pattern's lengths: one less than each real length */
1558 val = plen0 | (plen1 << 8) | (plen2 << 16) | WKUP_LEN_ENABLE_THREE;
1559 bw32(bp, B44_WKUP_LEN, val);
1560
1561 /* enable wakeup pattern matching */
1562 val = br32(bp, B44_DEVCTRL);
1563 bw32(bp, B44_DEVCTRL, val | DEVCTRL_PFE);
1564
1565}
1566
1567static void b44_setup_wol(struct b44 *bp)
1568{
1569 u32 val;
1570 u16 pmval;
1571
1572 bw32(bp, B44_RXCONFIG, RXCONFIG_ALLMULTI);
1573
1574 if (bp->flags & B44_FLAG_B0_ANDLATER) {
1575
1576 bw32(bp, B44_WKUP_LEN, WKUP_LEN_DISABLE);
1577
1578 val = bp->dev->dev_addr[2] << 24 |
1579 bp->dev->dev_addr[3] << 16 |
1580 bp->dev->dev_addr[4] << 8 |
1581 bp->dev->dev_addr[5];
1582 bw32(bp, B44_ADDR_LO, val);
1583
1584 val = bp->dev->dev_addr[0] << 8 |
1585 bp->dev->dev_addr[1];
1586 bw32(bp, B44_ADDR_HI, val);
1587
1588 val = br32(bp, B44_DEVCTRL);
1589 bw32(bp, B44_DEVCTRL, val | DEVCTRL_MPM | DEVCTRL_PFE);
1590
1591 } else {
1592 b44_setup_pseudo_magicp(bp);
1593 }
1594
1595 val = br32(bp, B44_SBTMSLOW);
1596 bw32(bp, B44_SBTMSLOW, val | SBTMSLOW_PE);
1597
1598 pci_read_config_word(bp->pdev, SSB_PMCSR, &pmval);
1599 pci_write_config_word(bp->pdev, SSB_PMCSR, pmval | SSB_PE);
1600
1601}
1602
1453static int b44_close(struct net_device *dev) 1603static int b44_close(struct net_device *dev)
1454{ 1604{
1455 struct b44 *bp = netdev_priv(dev); 1605 struct b44 *bp = netdev_priv(dev);
@@ -1475,6 +1625,11 @@ static int b44_close(struct net_device *dev)
1475 1625
1476 netif_poll_enable(dev); 1626 netif_poll_enable(dev);
1477 1627
1628 if (bp->flags & B44_FLAG_WOL_ENABLE) {
1629 b44_init_hw(bp, 0);
1630 b44_setup_wol(bp);
1631 }
1632
1478 b44_free_consistent(bp); 1633 b44_free_consistent(bp);
1479 1634
1480 return 0; 1635 return 0;
@@ -1620,8 +1775,6 @@ static int b44_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
1620{ 1775{
1621 struct b44 *bp = netdev_priv(dev); 1776 struct b44 *bp = netdev_priv(dev);
1622 1777
1623 if (!netif_running(dev))
1624 return -EAGAIN;
1625 cmd->supported = (SUPPORTED_Autoneg); 1778 cmd->supported = (SUPPORTED_Autoneg);
1626 cmd->supported |= (SUPPORTED_100baseT_Half | 1779 cmd->supported |= (SUPPORTED_100baseT_Half |
1627 SUPPORTED_100baseT_Full | 1780 SUPPORTED_100baseT_Full |
@@ -1649,6 +1802,12 @@ static int b44_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
1649 XCVR_INTERNAL : XCVR_EXTERNAL; 1802 XCVR_INTERNAL : XCVR_EXTERNAL;
1650 cmd->autoneg = (bp->flags & B44_FLAG_FORCE_LINK) ? 1803 cmd->autoneg = (bp->flags & B44_FLAG_FORCE_LINK) ?
1651 AUTONEG_DISABLE : AUTONEG_ENABLE; 1804 AUTONEG_DISABLE : AUTONEG_ENABLE;
1805 if (cmd->autoneg == AUTONEG_ENABLE)
1806 cmd->advertising |= ADVERTISED_Autoneg;
1807 if (!netif_running(dev)){
1808 cmd->speed = 0;
1809 cmd->duplex = 0xff;
1810 }
1652 cmd->maxtxpkt = 0; 1811 cmd->maxtxpkt = 0;
1653 cmd->maxrxpkt = 0; 1812 cmd->maxrxpkt = 0;
1654 return 0; 1813 return 0;
@@ -1658,9 +1817,6 @@ static int b44_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
1658{ 1817{
1659 struct b44 *bp = netdev_priv(dev); 1818 struct b44 *bp = netdev_priv(dev);
1660 1819
1661 if (!netif_running(dev))
1662 return -EAGAIN;
1663
1664 /* We do not support gigabit. */ 1820 /* We do not support gigabit. */
1665 if (cmd->autoneg == AUTONEG_ENABLE) { 1821 if (cmd->autoneg == AUTONEG_ENABLE) {
1666 if (cmd->advertising & 1822 if (cmd->advertising &
@@ -1677,28 +1833,39 @@ static int b44_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
1677 spin_lock_irq(&bp->lock); 1833 spin_lock_irq(&bp->lock);
1678 1834
1679 if (cmd->autoneg == AUTONEG_ENABLE) { 1835 if (cmd->autoneg == AUTONEG_ENABLE) {
1680 bp->flags &= ~B44_FLAG_FORCE_LINK; 1836 bp->flags &= ~(B44_FLAG_FORCE_LINK |
1681 bp->flags &= ~(B44_FLAG_ADV_10HALF | 1837 B44_FLAG_100_BASE_T |
1838 B44_FLAG_FULL_DUPLEX |
1839 B44_FLAG_ADV_10HALF |
1682 B44_FLAG_ADV_10FULL | 1840 B44_FLAG_ADV_10FULL |
1683 B44_FLAG_ADV_100HALF | 1841 B44_FLAG_ADV_100HALF |
1684 B44_FLAG_ADV_100FULL); 1842 B44_FLAG_ADV_100FULL);
1685 if (cmd->advertising & ADVERTISE_10HALF) 1843 if (cmd->advertising == 0) {
1686 bp->flags |= B44_FLAG_ADV_10HALF; 1844 bp->flags |= (B44_FLAG_ADV_10HALF |
1687 if (cmd->advertising & ADVERTISE_10FULL) 1845 B44_FLAG_ADV_10FULL |
1688 bp->flags |= B44_FLAG_ADV_10FULL; 1846 B44_FLAG_ADV_100HALF |
1689 if (cmd->advertising & ADVERTISE_100HALF) 1847 B44_FLAG_ADV_100FULL);
1690 bp->flags |= B44_FLAG_ADV_100HALF; 1848 } else {
1691 if (cmd->advertising & ADVERTISE_100FULL) 1849 if (cmd->advertising & ADVERTISED_10baseT_Half)
1692 bp->flags |= B44_FLAG_ADV_100FULL; 1850 bp->flags |= B44_FLAG_ADV_10HALF;
1851 if (cmd->advertising & ADVERTISED_10baseT_Full)
1852 bp->flags |= B44_FLAG_ADV_10FULL;
1853 if (cmd->advertising & ADVERTISED_100baseT_Half)
1854 bp->flags |= B44_FLAG_ADV_100HALF;
1855 if (cmd->advertising & ADVERTISED_100baseT_Full)
1856 bp->flags |= B44_FLAG_ADV_100FULL;
1857 }
1693 } else { 1858 } else {
1694 bp->flags |= B44_FLAG_FORCE_LINK; 1859 bp->flags |= B44_FLAG_FORCE_LINK;
1860 bp->flags &= ~(B44_FLAG_100_BASE_T | B44_FLAG_FULL_DUPLEX);
1695 if (cmd->speed == SPEED_100) 1861 if (cmd->speed == SPEED_100)
1696 bp->flags |= B44_FLAG_100_BASE_T; 1862 bp->flags |= B44_FLAG_100_BASE_T;
1697 if (cmd->duplex == DUPLEX_FULL) 1863 if (cmd->duplex == DUPLEX_FULL)
1698 bp->flags |= B44_FLAG_FULL_DUPLEX; 1864 bp->flags |= B44_FLAG_FULL_DUPLEX;
1699 } 1865 }
1700 1866
1701 b44_setup_phy(bp); 1867 if (netif_running(dev))
1868 b44_setup_phy(bp);
1702 1869
1703 spin_unlock_irq(&bp->lock); 1870 spin_unlock_irq(&bp->lock);
1704 1871
@@ -1734,7 +1901,7 @@ static int b44_set_ringparam(struct net_device *dev,
1734 1901
1735 b44_halt(bp); 1902 b44_halt(bp);
1736 b44_init_rings(bp); 1903 b44_init_rings(bp);
1737 b44_init_hw(bp); 1904 b44_init_hw(bp, 1);
1738 netif_wake_queue(bp->dev); 1905 netif_wake_queue(bp->dev);
1739 spin_unlock_irq(&bp->lock); 1906 spin_unlock_irq(&bp->lock);
1740 1907
@@ -1777,7 +1944,7 @@ static int b44_set_pauseparam(struct net_device *dev,
1777 if (bp->flags & B44_FLAG_PAUSE_AUTO) { 1944 if (bp->flags & B44_FLAG_PAUSE_AUTO) {
1778 b44_halt(bp); 1945 b44_halt(bp);
1779 b44_init_rings(bp); 1946 b44_init_rings(bp);
1780 b44_init_hw(bp); 1947 b44_init_hw(bp, 1);
1781 } else { 1948 } else {
1782 __b44_set_flow_ctrl(bp, bp->flags); 1949 __b44_set_flow_ctrl(bp, bp->flags);
1783 } 1950 }
@@ -1819,12 +1986,40 @@ static void b44_get_ethtool_stats(struct net_device *dev,
1819 spin_unlock_irq(&bp->lock); 1986 spin_unlock_irq(&bp->lock);
1820} 1987}
1821 1988
1989static void b44_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
1990{
1991 struct b44 *bp = netdev_priv(dev);
1992
1993 wol->supported = WAKE_MAGIC;
1994 if (bp->flags & B44_FLAG_WOL_ENABLE)
1995 wol->wolopts = WAKE_MAGIC;
1996 else
1997 wol->wolopts = 0;
1998 memset(&wol->sopass, 0, sizeof(wol->sopass));
1999}
2000
2001static int b44_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
2002{
2003 struct b44 *bp = netdev_priv(dev);
2004
2005 spin_lock_irq(&bp->lock);
2006 if (wol->wolopts & WAKE_MAGIC)
2007 bp->flags |= B44_FLAG_WOL_ENABLE;
2008 else
2009 bp->flags &= ~B44_FLAG_WOL_ENABLE;
2010 spin_unlock_irq(&bp->lock);
2011
2012 return 0;
2013}
2014
1822static struct ethtool_ops b44_ethtool_ops = { 2015static struct ethtool_ops b44_ethtool_ops = {
1823 .get_drvinfo = b44_get_drvinfo, 2016 .get_drvinfo = b44_get_drvinfo,
1824 .get_settings = b44_get_settings, 2017 .get_settings = b44_get_settings,
1825 .set_settings = b44_set_settings, 2018 .set_settings = b44_set_settings,
1826 .nway_reset = b44_nway_reset, 2019 .nway_reset = b44_nway_reset,
1827 .get_link = ethtool_op_get_link, 2020 .get_link = ethtool_op_get_link,
2021 .get_wol = b44_get_wol,
2022 .set_wol = b44_set_wol,
1828 .get_ringparam = b44_get_ringparam, 2023 .get_ringparam = b44_get_ringparam,
1829 .set_ringparam = b44_set_ringparam, 2024 .set_ringparam = b44_set_ringparam,
1830 .get_pauseparam = b44_get_pauseparam, 2025 .get_pauseparam = b44_get_pauseparam,
@@ -1903,6 +2098,10 @@ static int __devinit b44_get_invariants(struct b44 *bp)
1903 /* XXX - really required? 2098 /* XXX - really required?
1904 bp->flags |= B44_FLAG_BUGGY_TXPTR; 2099 bp->flags |= B44_FLAG_BUGGY_TXPTR;
1905 */ 2100 */
2101
2102 if (ssb_get_core_rev(bp) >= 7)
2103 bp->flags |= B44_FLAG_B0_ANDLATER;
2104
1906out: 2105out:
1907 return err; 2106 return err;
1908} 2107}
@@ -2103,6 +2302,10 @@ static int b44_suspend(struct pci_dev *pdev, pm_message_t state)
2103 spin_unlock_irq(&bp->lock); 2302 spin_unlock_irq(&bp->lock);
2104 2303
2105 free_irq(dev->irq, dev); 2304 free_irq(dev->irq, dev);
2305 if (bp->flags & B44_FLAG_WOL_ENABLE) {
2306 b44_init_hw(bp, 0);
2307 b44_setup_wol(bp);
2308 }
2106 pci_disable_device(pdev); 2309 pci_disable_device(pdev);
2107 return 0; 2310 return 0;
2108} 2311}
@@ -2125,7 +2328,7 @@ static int b44_resume(struct pci_dev *pdev)
2125 spin_lock_irq(&bp->lock); 2328 spin_lock_irq(&bp->lock);
2126 2329
2127 b44_init_rings(bp); 2330 b44_init_rings(bp);
2128 b44_init_hw(bp); 2331 b44_init_hw(bp, 1);
2129 netif_device_attach(bp->dev); 2332 netif_device_attach(bp->dev);
2130 spin_unlock_irq(&bp->lock); 2333 spin_unlock_irq(&bp->lock);
2131 2334
diff --git a/drivers/net/b44.h b/drivers/net/b44.h
index b178662978f3..4944507fad23 100644
--- a/drivers/net/b44.h
+++ b/drivers/net/b44.h
@@ -24,6 +24,9 @@
24#define WKUP_LEN_P3_MASK 0x7f000000 /* Pattern 3 */ 24#define WKUP_LEN_P3_MASK 0x7f000000 /* Pattern 3 */
25#define WKUP_LEN_P3_SHIFT 24 25#define WKUP_LEN_P3_SHIFT 24
26#define WKUP_LEN_D3 0x80000000 26#define WKUP_LEN_D3 0x80000000
27#define WKUP_LEN_DISABLE 0x80808080
28#define WKUP_LEN_ENABLE_TWO 0x80800000
29#define WKUP_LEN_ENABLE_THREE 0x80000000
27#define B44_ISTAT 0x0020UL /* Interrupt Status */ 30#define B44_ISTAT 0x0020UL /* Interrupt Status */
28#define ISTAT_LS 0x00000020 /* Link Change (B0 only) */ 31#define ISTAT_LS 0x00000020 /* Link Change (B0 only) */
29#define ISTAT_PME 0x00000040 /* Power Management Event */ 32#define ISTAT_PME 0x00000040 /* Power Management Event */
@@ -264,6 +267,8 @@
264#define SBIDHIGH_VC_SHIFT 16 267#define SBIDHIGH_VC_SHIFT 16
265 268
266/* SSB PCI config space registers. */ 269/* SSB PCI config space registers. */
270#define SSB_PMCSR 0x44
271#define SSB_PE 0x100
267#define SSB_BAR0_WIN 0x80 272#define SSB_BAR0_WIN 0x80
268#define SSB_BAR1_WIN 0x84 273#define SSB_BAR1_WIN 0x84
269#define SSB_SPROM_CONTROL 0x88 274#define SSB_SPROM_CONTROL 0x88
@@ -420,6 +425,7 @@ struct b44 {
420 425
421 u32 dma_offset; 426 u32 dma_offset;
422 u32 flags; 427 u32 flags;
428#define B44_FLAG_B0_ANDLATER 0x00000001
423#define B44_FLAG_BUGGY_TXPTR 0x00000002 429#define B44_FLAG_BUGGY_TXPTR 0x00000002
424#define B44_FLAG_REORDER_BUG 0x00000004 430#define B44_FLAG_REORDER_BUG 0x00000004
425#define B44_FLAG_PAUSE_AUTO 0x00008000 431#define B44_FLAG_PAUSE_AUTO 0x00008000
@@ -435,6 +441,7 @@ struct b44 {
435#define B44_FLAG_INTERNAL_PHY 0x10000000 441#define B44_FLAG_INTERNAL_PHY 0x10000000
436#define B44_FLAG_RX_RING_HACK 0x20000000 442#define B44_FLAG_RX_RING_HACK 0x20000000
437#define B44_FLAG_TX_RING_HACK 0x40000000 443#define B44_FLAG_TX_RING_HACK 0x40000000
444#define B44_FLAG_WOL_ENABLE 0x80000000
438 445
439 u32 rx_offset; 446 u32 rx_offset;
440 447
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 62b38a4494b8..191383d461d7 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -2076,7 +2076,7 @@ static void nv_set_multicast(struct net_device *dev)
2076 spin_unlock_irq(&np->lock); 2076 spin_unlock_irq(&np->lock);
2077} 2077}
2078 2078
2079void nv_update_pause(struct net_device *dev, u32 pause_flags) 2079static void nv_update_pause(struct net_device *dev, u32 pause_flags)
2080{ 2080{
2081 struct fe_priv *np = netdev_priv(dev); 2081 struct fe_priv *np = netdev_priv(dev);
2082 u8 __iomem *base = get_hwbase(dev); 2082 u8 __iomem *base = get_hwbase(dev);
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c
index ae71ed57c12d..e76e6e7be0b1 100644
--- a/drivers/net/ioc3-eth.c
+++ b/drivers/net/ioc3-eth.c
@@ -145,7 +145,7 @@ static inline struct sk_buff * ioc3_alloc_skb(unsigned long length,
145static inline unsigned long ioc3_map(void *ptr, unsigned long vdev) 145static inline unsigned long ioc3_map(void *ptr, unsigned long vdev)
146{ 146{
147#ifdef CONFIG_SGI_IP27 147#ifdef CONFIG_SGI_IP27
148 vdev <<= 58; /* Shift to PCI64_ATTR_VIRTUAL */ 148 vdev <<= 57; /* Shift to PCI64_ATTR_VIRTUAL */
149 149
150 return vdev | (0xaUL << PCI64_ATTR_TARG_SHFT) | PCI64_ATTR_PREF | 150 return vdev | (0xaUL << PCI64_ATTR_TARG_SHFT) | PCI64_ATTR_PREF |
151 ((unsigned long)ptr & TO_PHYS_MASK); 151 ((unsigned long)ptr & TO_PHYS_MASK);
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index 1a2b9785e998..5a74f63618bc 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -2251,12 +2251,6 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp)
2251 } 2251 }
2252 2252
2253 cap = pci_find_ext_capability(bridge, PCI_EXT_CAP_ID_ERR); 2253 cap = pci_find_ext_capability(bridge, PCI_EXT_CAP_ID_ERR);
2254 /* nvidia ext cap is not always linked in ext cap chain */
2255 if (!cap
2256 && bridge->vendor == PCI_VENDOR_ID_NVIDIA
2257 && bridge->device == PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_PCIE)
2258 cap = 0x160;
2259
2260 if (!cap) 2254 if (!cap)
2261 return; 2255 return;
2262 2256
@@ -2732,8 +2726,6 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
2732 /* Save configuration space to be restored if the 2726 /* Save configuration space to be restored if the
2733 * nic resets due to a parity error */ 2727 * nic resets due to a parity error */
2734 myri10ge_save_state(mgp); 2728 myri10ge_save_state(mgp);
2735 /* Restore state immediately since pci_save_msi_state disables MSI */
2736 myri10ge_restore_state(mgp);
2737 2729
2738 /* Setup the watchdog timer */ 2730 /* Setup the watchdog timer */
2739 setup_timer(&mgp->watchdog_timer, myri10ge_watchdog_timer, 2731 setup_timer(&mgp->watchdog_timer, myri10ge_watchdog_timer,
diff --git a/drivers/net/netx-eth.c b/drivers/net/netx-eth.c
new file mode 100644
index 000000000000..b92430c4e3ac
--- /dev/null
+++ b/drivers/net/netx-eth.c
@@ -0,0 +1,516 @@
1/*
2 * drivers/net/netx-eth.c
3 *
4 * Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2
8 * as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#include <linux/config.h>
21#include <linux/init.h>
22#include <linux/module.h>
23#include <linux/kernel.h>
24#include <linux/delay.h>
25
26#include <linux/netdevice.h>
27#include <linux/platform_device.h>
28#include <linux/etherdevice.h>
29#include <linux/skbuff.h>
30#include <linux/mii.h>
31
32#include <asm/io.h>
33#include <asm/hardware.h>
34#include <asm/arch/hardware.h>
35#include <asm/arch/netx-regs.h>
36#include <asm/arch/pfifo.h>
37#include <asm/arch/xc.h>
38#include <asm/arch/eth.h>
39
40/* XC Fifo Offsets */
41#define EMPTY_PTR_FIFO(xcno) (0 + ((xcno) << 3)) /* Index of the empty pointer FIFO */
42#define IND_FIFO_PORT_HI(xcno) (1 + ((xcno) << 3)) /* Index of the FIFO where received */
43 /* Data packages are indicated by XC */
44#define IND_FIFO_PORT_LO(xcno) (2 + ((xcno) << 3)) /* Index of the FIFO where received */
45 /* Data packages are indicated by XC */
46#define REQ_FIFO_PORT_HI(xcno) (3 + ((xcno) << 3)) /* Index of the FIFO where Data packages */
47 /* have to be indicated by ARM which */
48 /* shall be sent */
49#define REQ_FIFO_PORT_LO(xcno) (4 + ((xcno) << 3)) /* Index of the FIFO where Data packages */
50 /* have to be indicated by ARM which shall */
51 /* be sent */
52#define CON_FIFO_PORT_HI(xcno) (5 + ((xcno) << 3)) /* Index of the FIFO where sent Data packages */
53 /* are confirmed */
54#define CON_FIFO_PORT_LO(xcno) (6 + ((xcno) << 3)) /* Index of the FIFO where sent Data */
55 /* packages are confirmed */
56#define PFIFO_MASK(xcno) (0x7f << (xcno*8))
57
58#define FIFO_PTR_FRAMELEN_SHIFT 0
59#define FIFO_PTR_FRAMELEN_MASK (0x7ff << 0)
60#define FIFO_PTR_FRAMELEN(len) (((len) << 0) & FIFO_PTR_FRAMELEN_MASK)
61#define FIFO_PTR_TIMETRIG (1<<11)
62#define FIFO_PTR_MULTI_REQ
63#define FIFO_PTR_ORIGIN (1<<14)
64#define FIFO_PTR_VLAN (1<<15)
65#define FIFO_PTR_FRAMENO_SHIFT 16
66#define FIFO_PTR_FRAMENO_MASK (0x3f << 16)
67#define FIFO_PTR_FRAMENO(no) (((no) << 16) & FIFO_PTR_FRAMENO_MASK)
68#define FIFO_PTR_SEGMENT_SHIFT 22
69#define FIFO_PTR_SEGMENT_MASK (0xf << 22)
70#define FIFO_PTR_SEGMENT(seg) (((seg) & 0xf) << 22)
71#define FIFO_PTR_ERROR_SHIFT 28
72#define FIFO_PTR_ERROR_MASK (0xf << 28)
73
74#define ISR_LINK_STATUS_CHANGE (1<<4)
75#define ISR_IND_LO (1<<3)
76#define ISR_CON_LO (1<<2)
77#define ISR_IND_HI (1<<1)
78#define ISR_CON_HI (1<<0)
79
80#define ETH_MAC_LOCAL_CONFIG 0x1560
81#define ETH_MAC_4321 0x1564
82#define ETH_MAC_65 0x1568
83
84#define MAC_TRAFFIC_CLASS_ARRANGEMENT_SHIFT 16
85#define MAC_TRAFFIC_CLASS_ARRANGEMENT_MASK (0xf<<MAC_TRAFFIC_CLASS_ARRANGEMENT_SHIFT)
86#define MAC_TRAFFIC_CLASS_ARRANGEMENT(x) (((x)<<MAC_TRAFFIC_CLASS_ARRANGEMENT_SHIFT) & MAC_TRAFFIC_CLASS_ARRANGEMENT_MASK)
87#define LOCAL_CONFIG_LINK_STATUS_IRQ_EN (1<<24)
88#define LOCAL_CONFIG_CON_LO_IRQ_EN (1<<23)
89#define LOCAL_CONFIG_CON_HI_IRQ_EN (1<<22)
90#define LOCAL_CONFIG_IND_LO_IRQ_EN (1<<21)
91#define LOCAL_CONFIG_IND_HI_IRQ_EN (1<<20)
92
93#define CARDNAME "netx-eth"
94
95/* LSB must be zero */
96#define INTERNAL_PHY_ADR 0x1c
97
98struct netx_eth_priv {
99 void __iomem *sram_base, *xpec_base, *xmac_base;
100 int id;
101 struct net_device_stats stats;
102 struct mii_if_info mii;
103 u32 msg_enable;
104 struct xc *xc;
105 spinlock_t lock;
106};
107
108static void netx_eth_set_multicast_list(struct net_device *ndev)
109{
110 /* implement me */
111}
112
113static int
114netx_eth_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev)
115{
116 struct netx_eth_priv *priv = netdev_priv(ndev);
117 unsigned char *buf = skb->data;
118 unsigned int len = skb->len;
119
120 spin_lock_irq(&priv->lock);
121 memcpy_toio(priv->sram_base + 1560, (void *)buf, len);
122 if (len < 60) {
123 memset_io(priv->sram_base + 1560 + len, 0, 60 - len);
124 len = 60;
125 }
126
127 pfifo_push(REQ_FIFO_PORT_LO(priv->id),
128 FIFO_PTR_SEGMENT(priv->id) |
129 FIFO_PTR_FRAMENO(1) |
130 FIFO_PTR_FRAMELEN(len));
131
132 ndev->trans_start = jiffies;
133 priv->stats.tx_packets++;
134 priv->stats.tx_bytes += skb->len;
135
136 netif_stop_queue(ndev);
137 spin_unlock_irq(&priv->lock);
138 dev_kfree_skb(skb);
139
140 return 0;
141}
142
143static void netx_eth_receive(struct net_device *ndev)
144{
145 struct netx_eth_priv *priv = netdev_priv(ndev);
146 unsigned int val, frameno, seg, len;
147 unsigned char *data;
148 struct sk_buff *skb;
149
150 val = pfifo_pop(IND_FIFO_PORT_LO(priv->id));
151
152 frameno = (val & FIFO_PTR_FRAMENO_MASK) >> FIFO_PTR_FRAMENO_SHIFT;
153 seg = (val & FIFO_PTR_SEGMENT_MASK) >> FIFO_PTR_SEGMENT_SHIFT;
154 len = (val & FIFO_PTR_FRAMELEN_MASK) >> FIFO_PTR_FRAMELEN_SHIFT;
155
156 skb = dev_alloc_skb(len);
157 if (unlikely(skb == NULL)) {
158 printk(KERN_NOTICE "%s: Low memory, packet dropped.\n",
159 ndev->name);
160 priv->stats.rx_dropped++;
161 return;
162 }
163
164 data = skb_put(skb, len);
165
166 memcpy_fromio(data, priv->sram_base + frameno * 1560, len);
167
168 pfifo_push(EMPTY_PTR_FIFO(priv->id),
169 FIFO_PTR_SEGMENT(seg) | FIFO_PTR_FRAMENO(frameno));
170
171 ndev->last_rx = jiffies;
172 skb->dev = ndev;
173 skb->protocol = eth_type_trans(skb, ndev);
174 netif_rx(skb);
175 priv->stats.rx_packets++;
176 priv->stats.rx_bytes += len;
177}
178
179static irqreturn_t
180netx_eth_interrupt(int irq, void *dev_id, struct pt_regs *regs)
181{
182 struct net_device *ndev = dev_id;
183 struct netx_eth_priv *priv = netdev_priv(ndev);
184 int status;
185 unsigned long flags;
186
187 spin_lock_irqsave(&priv->lock, flags);
188
189 status = readl(NETX_PFIFO_XPEC_ISR(priv->id));
190 while (status) {
191 int fill_level;
192 writel(status, NETX_PFIFO_XPEC_ISR(priv->id));
193
194 if ((status & ISR_CON_HI) || (status & ISR_IND_HI))
195 printk("%s: unexpected status: 0x%08x\n",
196 __FUNCTION__, status);
197
198 fill_level =
199 readl(NETX_PFIFO_FILL_LEVEL(IND_FIFO_PORT_LO(priv->id)));
200 while (fill_level--)
201 netx_eth_receive(ndev);
202
203 if (status & ISR_CON_LO)
204 netif_wake_queue(ndev);
205
206 if (status & ISR_LINK_STATUS_CHANGE)
207 mii_check_media(&priv->mii, netif_msg_link(priv), 1);
208
209 status = readl(NETX_PFIFO_XPEC_ISR(priv->id));
210 }
211 spin_unlock_irqrestore(&priv->lock, flags);
212 return IRQ_HANDLED;
213}
214
215static struct net_device_stats *netx_eth_query_statistics(struct net_device *ndev)
216{
217 struct netx_eth_priv *priv = netdev_priv(ndev);
218 return &priv->stats;
219}
220
221static int netx_eth_open(struct net_device *ndev)
222{
223 struct netx_eth_priv *priv = netdev_priv(ndev);
224
225 if (request_irq
226 (ndev->irq, &netx_eth_interrupt, SA_SHIRQ, ndev->name, ndev))
227 return -EAGAIN;
228
229 writel(ndev->dev_addr[0] |
230 ndev->dev_addr[1]<<8 |
231 ndev->dev_addr[2]<<16 |
232 ndev->dev_addr[3]<<24,
233 priv->xpec_base + NETX_XPEC_RAM_START_OFS + ETH_MAC_4321);
234 writel(ndev->dev_addr[4] |
235 ndev->dev_addr[5]<<8,
236 priv->xpec_base + NETX_XPEC_RAM_START_OFS + ETH_MAC_65);
237
238 writel(LOCAL_CONFIG_LINK_STATUS_IRQ_EN |
239 LOCAL_CONFIG_CON_LO_IRQ_EN |
240 LOCAL_CONFIG_CON_HI_IRQ_EN |
241 LOCAL_CONFIG_IND_LO_IRQ_EN |
242 LOCAL_CONFIG_IND_HI_IRQ_EN,
243 priv->xpec_base + NETX_XPEC_RAM_START_OFS +
244 ETH_MAC_LOCAL_CONFIG);
245
246 mii_check_media(&priv->mii, netif_msg_link(priv), 1);
247 netif_start_queue(ndev);
248
249 return 0;
250}
251
252static int netx_eth_close(struct net_device *ndev)
253{
254 struct netx_eth_priv *priv = netdev_priv(ndev);
255
256 netif_stop_queue(ndev);
257
258 writel(0,
259 priv->xpec_base + NETX_XPEC_RAM_START_OFS + ETH_MAC_LOCAL_CONFIG);
260
261 free_irq(ndev->irq, ndev);
262
263 return 0;
264}
265
266static void netx_eth_timeout(struct net_device *ndev)
267{
268 struct netx_eth_priv *priv = netdev_priv(ndev);
269 int i;
270
271 printk(KERN_ERR "%s: transmit timed out, resetting\n", ndev->name);
272
273 spin_lock_irq(&priv->lock);
274
275 xc_reset(priv->xc);
276 xc_start(priv->xc);
277
278 for (i=2; i<=18; i++)
279 pfifo_push(EMPTY_PTR_FIFO(priv->id),
280 FIFO_PTR_FRAMENO(i) | FIFO_PTR_SEGMENT(priv->id));
281
282 spin_unlock_irq(&priv->lock);
283
284 netif_wake_queue(ndev);
285}
286
287static int
288netx_eth_phy_read(struct net_device *ndev, int phy_id, int reg)
289{
290 unsigned int val;
291
292 val = MIIMU_SNRDY | MIIMU_PREAMBLE | MIIMU_PHYADDR(phy_id) |
293 MIIMU_REGADDR(reg) | MIIMU_PHY_NRES;
294
295 writel(val, NETX_MIIMU);
296 while (readl(NETX_MIIMU) & MIIMU_SNRDY);
297
298 return readl(NETX_MIIMU) >> 16;
299
300}
301
302static void
303netx_eth_phy_write(struct net_device *ndev, int phy_id, int reg, int value)
304{
305 unsigned int val;
306
307 val = MIIMU_SNRDY | MIIMU_PREAMBLE | MIIMU_PHYADDR(phy_id) |
308 MIIMU_REGADDR(reg) | MIIMU_PHY_NRES | MIIMU_OPMODE_WRITE |
309 MIIMU_DATA(value);
310
311 writel(val, NETX_MIIMU);
312 while (readl(NETX_MIIMU) & MIIMU_SNRDY);
313}
314
315static int netx_eth_enable(struct net_device *ndev)
316{
317 struct netx_eth_priv *priv = netdev_priv(ndev);
318 unsigned int mac4321, mac65;
319 int running, i;
320
321 ether_setup(ndev);
322
323 ndev->open = netx_eth_open;
324 ndev->stop = netx_eth_close;
325 ndev->hard_start_xmit = netx_eth_hard_start_xmit;
326 ndev->tx_timeout = netx_eth_timeout;
327 ndev->watchdog_timeo = msecs_to_jiffies(5000);
328 ndev->get_stats = netx_eth_query_statistics;
329 ndev->set_multicast_list = netx_eth_set_multicast_list;
330
331 priv->msg_enable = NETIF_MSG_LINK;
332 priv->mii.phy_id_mask = 0x1f;
333 priv->mii.reg_num_mask = 0x1f;
334 priv->mii.force_media = 0;
335 priv->mii.full_duplex = 0;
336 priv->mii.dev = ndev;
337 priv->mii.mdio_read = netx_eth_phy_read;
338 priv->mii.mdio_write = netx_eth_phy_write;
339 priv->mii.phy_id = INTERNAL_PHY_ADR + priv->id;
340
341 running = xc_running(priv->xc);
342 xc_stop(priv->xc);
343
344 /* if the xc engine is already running, assume the bootloader has
345 * loaded the firmware for us
346 */
347 if (running) {
348 /* get Node Address from hardware */
349 mac4321 = readl(priv->xpec_base +
350 NETX_XPEC_RAM_START_OFS + ETH_MAC_4321);
351 mac65 = readl(priv->xpec_base +
352 NETX_XPEC_RAM_START_OFS + ETH_MAC_65);
353
354 ndev->dev_addr[0] = mac4321 & 0xff;
355 ndev->dev_addr[1] = (mac4321 >> 8) & 0xff;
356 ndev->dev_addr[2] = (mac4321 >> 16) & 0xff;
357 ndev->dev_addr[3] = (mac4321 >> 24) & 0xff;
358 ndev->dev_addr[4] = mac65 & 0xff;
359 ndev->dev_addr[5] = (mac65 >> 8) & 0xff;
360 } else {
361 if (xc_request_firmware(priv->xc)) {
362 printk(CARDNAME ": requesting firmware failed\n");
363 return -ENODEV;
364 }
365 }
366
367 xc_reset(priv->xc);
368 xc_start(priv->xc);
369
370 if (!is_valid_ether_addr(ndev->dev_addr))
371 printk("%s: Invalid ethernet MAC address. Please "
372 "set using ifconfig\n", ndev->name);
373
374 for (i=2; i<=18; i++)
375 pfifo_push(EMPTY_PTR_FIFO(priv->id),
376 FIFO_PTR_FRAMENO(i) | FIFO_PTR_SEGMENT(priv->id));
377
378 return register_netdev(ndev);
379
380}
381
382static int netx_eth_drv_probe(struct platform_device *pdev)
383{
384 struct netx_eth_priv *priv;
385 struct net_device *ndev;
386 struct netxeth_platform_data *pdata;
387 int ret;
388
389 ndev = alloc_etherdev(sizeof (struct netx_eth_priv));
390 if (!ndev) {
391 printk("%s: could not allocate device.\n", CARDNAME);
392 ret = -ENOMEM;
393 goto exit;
394 }
395 SET_MODULE_OWNER(ndev);
396 SET_NETDEV_DEV(ndev, &pdev->dev);
397
398 platform_set_drvdata(pdev, ndev);
399
400 priv = netdev_priv(ndev);
401
402 pdata = (struct netxeth_platform_data *)pdev->dev.platform_data;
403 priv->xc = request_xc(pdata->xcno, &pdev->dev);
404 if (!priv->xc) {
405 dev_err(&pdev->dev, "unable to request xc engine\n");
406 ret = -ENODEV;
407 goto exit_free_netdev;
408 }
409
410 ndev->irq = priv->xc->irq;
411 priv->id = pdev->id;
412 priv->xpec_base = priv->xc->xpec_base;
413 priv->xmac_base = priv->xc->xmac_base;
414 priv->sram_base = priv->xc->sram_base;
415
416 ret = pfifo_request(PFIFO_MASK(priv->id));
417 if (ret) {
418 printk("unable to request PFIFO\n");
419 goto exit_free_xc;
420 }
421
422 ret = netx_eth_enable(ndev);
423 if (ret)
424 goto exit_free_pfifo;
425
426 return 0;
427exit_free_pfifo:
428 pfifo_free(PFIFO_MASK(priv->id));
429exit_free_xc:
430 free_xc(priv->xc);
431exit_free_netdev:
432 platform_set_drvdata(pdev, NULL);
433 free_netdev(ndev);
434exit:
435 return ret;
436}
437
438static int netx_eth_drv_remove(struct platform_device *pdev)
439{
440 struct net_device *ndev = dev_get_drvdata(&pdev->dev);
441 struct netx_eth_priv *priv = netdev_priv(ndev);
442
443 platform_set_drvdata(pdev, NULL);
444
445 unregister_netdev(ndev);
446 xc_stop(priv->xc);
447 free_xc(priv->xc);
448 free_netdev(ndev);
449 pfifo_free(PFIFO_MASK(priv->id));
450
451 return 0;
452}
453
454static int netx_eth_drv_suspend(struct platform_device *pdev, pm_message_t state)
455{
456 dev_err(&pdev->dev, "suspend not implemented\n");
457 return 0;
458}
459
460static int netx_eth_drv_resume(struct platform_device *pdev)
461{
462 dev_err(&pdev->dev, "resume not implemented\n");
463 return 0;
464}
465
466static struct platform_driver netx_eth_driver = {
467 .probe = netx_eth_drv_probe,
468 .remove = netx_eth_drv_remove,
469 .suspend = netx_eth_drv_suspend,
470 .resume = netx_eth_drv_resume,
471 .driver = {
472 .name = CARDNAME,
473 .owner = THIS_MODULE,
474 },
475};
476
477static int __init netx_eth_init(void)
478{
479 unsigned int phy_control, val;
480
481 printk("NetX Ethernet driver\n");
482
483 phy_control = PHY_CONTROL_PHY_ADDRESS(INTERNAL_PHY_ADR>>1) |
484 PHY_CONTROL_PHY1_MODE(PHY_MODE_ALL) |
485 PHY_CONTROL_PHY1_AUTOMDIX |
486 PHY_CONTROL_PHY1_EN |
487 PHY_CONTROL_PHY0_MODE(PHY_MODE_ALL) |
488 PHY_CONTROL_PHY0_AUTOMDIX |
489 PHY_CONTROL_PHY0_EN |
490 PHY_CONTROL_CLK_XLATIN;
491
492 val = readl(NETX_SYSTEM_IOC_ACCESS_KEY);
493 writel(val, NETX_SYSTEM_IOC_ACCESS_KEY);
494
495 writel(phy_control | PHY_CONTROL_RESET, NETX_SYSTEM_PHY_CONTROL);
496 udelay(100);
497
498 val = readl(NETX_SYSTEM_IOC_ACCESS_KEY);
499 writel(val, NETX_SYSTEM_IOC_ACCESS_KEY);
500
501 writel(phy_control, NETX_SYSTEM_PHY_CONTROL);
502
503 return platform_driver_register(&netx_eth_driver);
504}
505
506static void __exit netx_eth_cleanup(void)
507{
508 platform_driver_unregister(&netx_eth_driver);
509}
510
511module_init(netx_eth_init);
512module_exit(netx_eth_cleanup);
513
514MODULE_AUTHOR("Sascha Hauer, Pengutronix");
515MODULE_LICENSE("GPL");
516
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index 71f45056a70c..e80d1e3aec68 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -1359,7 +1359,7 @@ do_start_xmit(struct sk_buff *skb, struct net_device *dev)
1359 kio_addr_t ioaddr = dev->base_addr; 1359 kio_addr_t ioaddr = dev->base_addr;
1360 int okay; 1360 int okay;
1361 unsigned freespace; 1361 unsigned freespace;
1362 unsigned pktlen = skb? skb->len : 0; 1362 unsigned pktlen = skb->len;
1363 1363
1364 DEBUG(1, "do_start_xmit(skb=%p, dev=%p) len=%u\n", 1364 DEBUG(1, "do_start_xmit(skb=%p, dev=%p) len=%u\n",
1365 skb, dev, pktlen); 1365 skb, dev, pktlen);
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index cac9fdd2e1d5..11daed495b97 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -2627,6 +2627,50 @@ no_rx:
2627#endif 2627#endif
2628 2628
2629/** 2629/**
2630 * s2io_netpoll - Rx interrupt service handler for netpoll support
2631 * @dev : pointer to the device structure.
2632 * Description:
2633 * Polling 'interrupt' - used by things like netconsole to send skbs
2634 * without having to re-enable interrupts. It's not called while
2635 * the interrupt routine is executing.
2636 */
2637
2638#ifdef CONFIG_NET_POLL_CONTROLLER
2639static void s2io_netpoll(struct net_device *dev)
2640{
2641 nic_t *nic = dev->priv;
2642 mac_info_t *mac_control;
2643 struct config_param *config;
2644 XENA_dev_config_t __iomem *bar0 = nic->bar0;
2645 u64 val64;
2646 int i;
2647
2648 disable_irq(dev->irq);
2649
2650 atomic_inc(&nic->isr_cnt);
2651 mac_control = &nic->mac_control;
2652 config = &nic->config;
2653
2654 val64 = readq(&bar0->rx_traffic_int);
2655 writeq(val64, &bar0->rx_traffic_int);
2656
2657 for (i = 0; i < config->rx_ring_num; i++)
2658 rx_intr_handler(&mac_control->rings[i]);
2659
2660 for (i = 0; i < config->rx_ring_num; i++) {
2661 if (fill_rx_buffers(nic, i) == -ENOMEM) {
2662 DBG_PRINT(ERR_DBG, "%s:Out of memory", dev->name);
2663 DBG_PRINT(ERR_DBG, " in Rx Netpoll!!\n");
2664 break;
2665 }
2666 }
2667 atomic_dec(&nic->isr_cnt);
2668 enable_irq(dev->irq);
2669 return;
2670}
2671#endif
2672
2673/**
2630 * rx_intr_handler - Rx interrupt handler 2674 * rx_intr_handler - Rx interrupt handler
2631 * @nic: device private variable. 2675 * @nic: device private variable.
2632 * Description: 2676 * Description:
@@ -6967,6 +7011,10 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
6967 dev->weight = 32; 7011 dev->weight = 32;
6968#endif 7012#endif
6969 7013
7014#ifdef CONFIG_NET_POLL_CONTROLLER
7015 dev->poll_controller = s2io_netpoll;
7016#endif
7017
6970 dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; 7018 dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
6971 if (sp->high_dma_flag == TRUE) 7019 if (sp->high_dma_flag == TRUE)
6972 dev->features |= NETIF_F_HIGHDMA; 7020 dev->features |= NETIF_F_HIGHDMA;
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c
index 61eec46cb111..f13b2a195c70 100644
--- a/drivers/net/sundance.c
+++ b/drivers/net/sundance.c
@@ -94,11 +94,13 @@
94 Version LK1.10 (Philippe De Muyter phdm@macqel.be): 94 Version LK1.10 (Philippe De Muyter phdm@macqel.be):
95 - Make 'unblock interface after Tx underrun' work 95 - Make 'unblock interface after Tx underrun' work
96 96
97 Version LK1.11 (Pedro Alejandro Lopez-Valencia palopezv at gmail.com):
98 - Add support for IC Plus Corporation IP100A chipset
97*/ 99*/
98 100
99#define DRV_NAME "sundance" 101#define DRV_NAME "sundance"
100#define DRV_VERSION "1.01+LK1.10" 102#define DRV_VERSION "1.01+LK1.11"
101#define DRV_RELDATE "28-Oct-2005" 103#define DRV_RELDATE "14-Jun-2006"
102 104
103 105
104/* The user-configurable values. 106/* The user-configurable values.
@@ -287,6 +289,7 @@ static struct pci_device_id sundance_pci_tbl[] = {
287 {0x1186, 0x1002, 0x1186, 0x1040, 0, 0, 3}, 289 {0x1186, 0x1002, 0x1186, 0x1040, 0, 0, 3},
288 {0x1186, 0x1002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4}, 290 {0x1186, 0x1002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
289 {0x13F0, 0x0201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5}, 291 {0x13F0, 0x0201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5},
292 {0x13F0, 0x0200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6},
290 {0,} 293 {0,}
291}; 294};
292MODULE_DEVICE_TABLE(pci, sundance_pci_tbl); 295MODULE_DEVICE_TABLE(pci, sundance_pci_tbl);
@@ -305,6 +308,7 @@ static const struct pci_id_info pci_id_tbl[] = {
305 {"D-Link DFE-530TXS FAST Ethernet Adapter"}, 308 {"D-Link DFE-530TXS FAST Ethernet Adapter"},
306 {"D-Link DL10050-based FAST Ethernet Adapter"}, 309 {"D-Link DL10050-based FAST Ethernet Adapter"},
307 {"Sundance Technology Alta"}, 310 {"Sundance Technology Alta"},
311 {"IC Plus Corporation IP100A FAST Ethernet Adapter"},
308 {NULL,}, /* 0 terminated list. */ 312 {NULL,}, /* 0 terminated list. */
309}; 313};
310 314
diff --git a/drivers/net/tokenring/olympic.c b/drivers/net/tokenring/olympic.c
index 23032a7bc0a9..c3cb8d26cfe3 100644
--- a/drivers/net/tokenring/olympic.c
+++ b/drivers/net/tokenring/olympic.c
@@ -217,7 +217,7 @@ static int __devinit olympic_probe(struct pci_dev *pdev, const struct pci_device
217 dev = alloc_trdev(sizeof(struct olympic_private)) ; 217 dev = alloc_trdev(sizeof(struct olympic_private)) ;
218 if (!dev) { 218 if (!dev) {
219 i = -ENOMEM; 219 i = -ENOMEM;
220 goto op_free_dev; 220 goto op_release_dev;
221 } 221 }
222 222
223 olympic_priv = dev->priv ; 223 olympic_priv = dev->priv ;
@@ -282,8 +282,8 @@ op_free_iomap:
282 if (olympic_priv->olympic_lap) 282 if (olympic_priv->olympic_lap)
283 iounmap(olympic_priv->olympic_lap); 283 iounmap(olympic_priv->olympic_lap);
284 284
285op_free_dev:
286 free_netdev(dev); 285 free_netdev(dev);
286op_release_dev:
287 pci_release_regions(pdev); 287 pci_release_regions(pdev);
288 288
289op_disable_dev: 289op_disable_dev:
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index 2eb6b5f9ba0d..09e05fe40c38 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -248,6 +248,7 @@ static void velocity_free_rd_ring(struct velocity_info *vptr);
248static void velocity_free_tx_buf(struct velocity_info *vptr, struct velocity_td_info *); 248static void velocity_free_tx_buf(struct velocity_info *vptr, struct velocity_td_info *);
249static int velocity_soft_reset(struct velocity_info *vptr); 249static int velocity_soft_reset(struct velocity_info *vptr);
250static void mii_init(struct velocity_info *vptr, u32 mii_status); 250static void mii_init(struct velocity_info *vptr, u32 mii_status);
251static u32 velocity_get_link(struct net_device *dev);
251static u32 velocity_get_opt_media_mode(struct velocity_info *vptr); 252static u32 velocity_get_opt_media_mode(struct velocity_info *vptr);
252static void velocity_print_link_status(struct velocity_info *vptr); 253static void velocity_print_link_status(struct velocity_info *vptr);
253static void safe_disable_mii_autopoll(struct mac_regs __iomem * regs); 254static void safe_disable_mii_autopoll(struct mac_regs __iomem * regs);
@@ -798,6 +799,9 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi
798 if (ret < 0) 799 if (ret < 0)
799 goto err_iounmap; 800 goto err_iounmap;
800 801
802 if (velocity_get_link(dev))
803 netif_carrier_off(dev);
804
801 velocity_print_info(vptr); 805 velocity_print_info(vptr);
802 pci_set_drvdata(pdev, dev); 806 pci_set_drvdata(pdev, dev);
803 807
@@ -1653,8 +1657,10 @@ static void velocity_error(struct velocity_info *vptr, int status)
1653 1657
1654 if (linked) { 1658 if (linked) {
1655 vptr->mii_status &= ~VELOCITY_LINK_FAIL; 1659 vptr->mii_status &= ~VELOCITY_LINK_FAIL;
1660 netif_carrier_on(vptr->dev);
1656 } else { 1661 } else {
1657 vptr->mii_status |= VELOCITY_LINK_FAIL; 1662 vptr->mii_status |= VELOCITY_LINK_FAIL;
1663 netif_carrier_off(vptr->dev);
1658 } 1664 }
1659 1665
1660 velocity_print_link_status(vptr); 1666 velocity_print_link_status(vptr);
diff --git a/drivers/net/wan/c101.c b/drivers/net/wan/c101.c
index 43d854ace233..b60ef02db7b0 100644
--- a/drivers/net/wan/c101.c
+++ b/drivers/net/wan/c101.c
@@ -326,21 +326,21 @@ static int __init c101_run(unsigned long irq, unsigned long winbase)
326 if (request_irq(irq, sca_intr, 0, devname, card)) { 326 if (request_irq(irq, sca_intr, 0, devname, card)) {
327 printk(KERN_ERR "c101: could not allocate IRQ\n"); 327 printk(KERN_ERR "c101: could not allocate IRQ\n");
328 c101_destroy_card(card); 328 c101_destroy_card(card);
329 return(-EBUSY); 329 return -EBUSY;
330 } 330 }
331 card->irq = irq; 331 card->irq = irq;
332 332
333 if (!request_mem_region(winbase, C101_MAPPED_RAM_SIZE, devname)) { 333 if (!request_mem_region(winbase, C101_MAPPED_RAM_SIZE, devname)) {
334 printk(KERN_ERR "c101: could not request RAM window\n"); 334 printk(KERN_ERR "c101: could not request RAM window\n");
335 c101_destroy_card(card); 335 c101_destroy_card(card);
336 return(-EBUSY); 336 return -EBUSY;
337 } 337 }
338 card->phy_winbase = winbase; 338 card->phy_winbase = winbase;
339 card->win0base = ioremap(winbase, C101_MAPPED_RAM_SIZE); 339 card->win0base = ioremap(winbase, C101_MAPPED_RAM_SIZE);
340 if (!card->win0base) { 340 if (!card->win0base) {
341 printk(KERN_ERR "c101: could not map I/O address\n"); 341 printk(KERN_ERR "c101: could not map I/O address\n");
342 c101_destroy_card(card); 342 c101_destroy_card(card);
343 return -EBUSY; 343 return -EFAULT;
344 } 344 }
345 345
346 card->tx_ring_buffers = TX_RING_BUFFERS; 346 card->tx_ring_buffers = TX_RING_BUFFERS;
diff --git a/drivers/net/wan/hdlc_generic.c b/drivers/net/wan/hdlc_generic.c
index 46cef8f92133..57f9538b8fb5 100644
--- a/drivers/net/wan/hdlc_generic.c
+++ b/drivers/net/wan/hdlc_generic.c
@@ -259,7 +259,7 @@ int hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
259 } 259 }
260} 260}
261 261
262static void hdlc_setup(struct net_device *dev) 262void hdlc_setup(struct net_device *dev)
263{ 263{
264 hdlc_device *hdlc = dev_to_hdlc(dev); 264 hdlc_device *hdlc = dev_to_hdlc(dev);
265 265
@@ -288,26 +288,6 @@ struct net_device *alloc_hdlcdev(void *priv)
288 return dev; 288 return dev;
289} 289}
290 290
291int register_hdlc_device(struct net_device *dev)
292{
293 int result = dev_alloc_name(dev, "hdlc%d");
294 if (result < 0)
295 return result;
296
297 result = register_netdev(dev);
298 if (result != 0)
299 return -EIO;
300
301#if 0
302 if (netif_carrier_ok(dev))
303 netif_carrier_off(dev); /* no carrier until DCD goes up */
304#endif
305
306 return 0;
307}
308
309
310
311void unregister_hdlc_device(struct net_device *dev) 291void unregister_hdlc_device(struct net_device *dev)
312{ 292{
313 rtnl_lock(); 293 rtnl_lock();
@@ -326,8 +306,8 @@ EXPORT_SYMBOL(hdlc_open);
326EXPORT_SYMBOL(hdlc_close); 306EXPORT_SYMBOL(hdlc_close);
327EXPORT_SYMBOL(hdlc_set_carrier); 307EXPORT_SYMBOL(hdlc_set_carrier);
328EXPORT_SYMBOL(hdlc_ioctl); 308EXPORT_SYMBOL(hdlc_ioctl);
309EXPORT_SYMBOL(hdlc_setup);
329EXPORT_SYMBOL(alloc_hdlcdev); 310EXPORT_SYMBOL(alloc_hdlcdev);
330EXPORT_SYMBOL(register_hdlc_device);
331EXPORT_SYMBOL(unregister_hdlc_device); 311EXPORT_SYMBOL(unregister_hdlc_device);
332 312
333static struct packet_type hdlc_packet_type = { 313static struct packet_type hdlc_packet_type = {
diff --git a/drivers/net/wan/n2.c b/drivers/net/wan/n2.c
index cd32751b64eb..b7d88db89a5c 100644
--- a/drivers/net/wan/n2.c
+++ b/drivers/net/wan/n2.c
@@ -387,6 +387,11 @@ static int __init n2_run(unsigned long io, unsigned long irq,
387 } 387 }
388 card->phy_winbase = winbase; 388 card->phy_winbase = winbase;
389 card->winbase = ioremap(winbase, USE_WINDOWSIZE); 389 card->winbase = ioremap(winbase, USE_WINDOWSIZE);
390 if (!card->winbase) {
391 printk(KERN_ERR "n2: ioremap() failed\n");
392 n2_destroy_card(card);
393 return -EFAULT;
394 }
390 395
391 outb(0, io + N2_PCR); 396 outb(0, io + N2_PCR);
392 outb(winbase >> 12, io + N2_BAR); 397 outb(winbase >> 12, io + N2_BAR);
diff --git a/drivers/net/wan/pci200syn.c b/drivers/net/wan/pci200syn.c
index f485a97844cc..670e8bd2245c 100644
--- a/drivers/net/wan/pci200syn.c
+++ b/drivers/net/wan/pci200syn.c
@@ -354,6 +354,7 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev,
354 card->rambase == NULL) { 354 card->rambase == NULL) {
355 printk(KERN_ERR "pci200syn: ioremap() failed\n"); 355 printk(KERN_ERR "pci200syn: ioremap() failed\n");
356 pci200_pci_remove_one(pdev); 356 pci200_pci_remove_one(pdev);
357 return -EFAULT;
357 } 358 }
358 359
359 /* Reset PLX */ 360 /* Reset PLX */
diff --git a/drivers/net/wan/wanxl.c b/drivers/net/wan/wanxl.c
index 29a756dd979b..437e0e938e38 100644
--- a/drivers/net/wan/wanxl.c
+++ b/drivers/net/wan/wanxl.c
@@ -634,7 +634,13 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev,
634 634
635 /* set up PLX mapping */ 635 /* set up PLX mapping */
636 plx_phy = pci_resource_start(pdev, 0); 636 plx_phy = pci_resource_start(pdev, 0);
637
637 card->plx = ioremap_nocache(plx_phy, 0x70); 638 card->plx = ioremap_nocache(plx_phy, 0x70);
639 if (!card->plx) {
640 printk(KERN_ERR "wanxl: ioremap() failed\n");
641 wanxl_pci_remove_one(pdev);
642 return -EFAULT;
643 }
638 644
639#if RESET_WHILE_LOADING 645#if RESET_WHILE_LOADING
640 wanxl_reset(card); 646 wanxl_reset(card);
@@ -700,6 +706,12 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev,
700 } 706 }
701 707
702 mem = ioremap_nocache(mem_phy, PDM_OFFSET + sizeof(firmware)); 708 mem = ioremap_nocache(mem_phy, PDM_OFFSET + sizeof(firmware));
709 if (!mem) {
710 printk(KERN_ERR "wanxl: ioremap() failed\n");
711 wanxl_pci_remove_one(pdev);
712 return -EFAULT;
713 }
714
703 for (i = 0; i < sizeof(firmware); i += 4) 715 for (i = 0; i < sizeof(firmware); i += 4)
704 writel(htonl(*(u32*)(firmware + i)), mem + PDM_OFFSET + i); 716 writel(htonl(*(u32*)(firmware + i)), mem + PDM_OFFSET + i);
705 717
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx.h b/drivers/net/wireless/bcm43xx/bcm43xx.h
index e66fdb1f3cfd..d8f917c21ea4 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx.h
@@ -636,6 +636,17 @@ struct bcm43xx_key {
636 u8 algorithm; 636 u8 algorithm;
637}; 637};
638 638
639/* Driver initialization status. */
640enum {
641 BCM43xx_STAT_UNINIT, /* Uninitialized. */
642 BCM43xx_STAT_INITIALIZING, /* init_board() in progress. */
643 BCM43xx_STAT_INITIALIZED, /* Fully operational. */
644 BCM43xx_STAT_SHUTTINGDOWN, /* free_board() in progress. */
645 BCM43xx_STAT_RESTARTING, /* controller_restart() called. */
646};
647#define bcm43xx_status(bcm) atomic_read(&(bcm)->init_status)
648#define bcm43xx_set_status(bcm, stat) atomic_set(&(bcm)->init_status, (stat))
649
639struct bcm43xx_private { 650struct bcm43xx_private {
640 struct ieee80211_device *ieee; 651 struct ieee80211_device *ieee;
641 struct ieee80211softmac_device *softmac; 652 struct ieee80211softmac_device *softmac;
@@ -646,18 +657,17 @@ struct bcm43xx_private {
646 657
647 void __iomem *mmio_addr; 658 void __iomem *mmio_addr;
648 659
649 /* Do not use the lock directly. Use the bcm43xx_lock* helper 660 /* Locking, see "theory of locking" text below. */
650 * functions, to be MMIO-safe. */ 661 spinlock_t irq_lock;
651 spinlock_t _lock; 662 struct mutex mutex;
652 663
653 /* Driver status flags. */ 664 /* Driver initialization status BCM43xx_STAT_*** */
654 u32 initialized:1, /* init_board() succeed */ 665 atomic_t init_status;
655 was_initialized:1, /* for PCI suspend/resume. */ 666
656 shutting_down:1, /* free_board() in progress */ 667 u16 was_initialized:1, /* for PCI suspend/resume. */
657 __using_pio:1, /* Internal, use bcm43xx_using_pio(). */ 668 __using_pio:1, /* Internal, use bcm43xx_using_pio(). */
658 bad_frames_preempt:1, /* Use "Bad Frames Preemption" (default off) */ 669 bad_frames_preempt:1, /* Use "Bad Frames Preemption" (default off) */
659 reg124_set_0x4:1, /* Some variable to keep track of IRQ stuff. */ 670 reg124_set_0x4:1, /* Some variable to keep track of IRQ stuff. */
660 powersaving:1, /* TRUE if we are in PowerSaving mode. FALSE otherwise. */
661 short_preamble:1, /* TRUE, if short preamble is enabled. */ 671 short_preamble:1, /* TRUE, if short preamble is enabled. */
662 firmware_norelease:1; /* Do not release the firmware. Used on suspend. */ 672 firmware_norelease:1; /* Do not release the firmware. Used on suspend. */
663 673
@@ -721,7 +731,7 @@ struct bcm43xx_private {
721 struct tasklet_struct isr_tasklet; 731 struct tasklet_struct isr_tasklet;
722 732
723 /* Periodic tasks */ 733 /* Periodic tasks */
724 struct timer_list periodic_tasks; 734 struct work_struct periodic_work;
725 unsigned int periodic_state; 735 unsigned int periodic_state;
726 736
727 struct work_struct restart_work; 737 struct work_struct restart_work;
@@ -746,21 +756,55 @@ struct bcm43xx_private {
746#endif 756#endif
747}; 757};
748 758
749/* bcm43xx_(un)lock() protect struct bcm43xx_private. 759
750 * Note that _NO_ MMIO writes are allowed. If you want to 760/* *** THEORY OF LOCKING ***
751 * write to the device through MMIO in the critical section, use 761 *
752 * the *_mmio lock functions. 762 * We have two different locks in the bcm43xx driver.
753 * MMIO read-access is allowed, though. 763 * => bcm->mutex: General sleeping mutex. Protects struct bcm43xx_private
754 */ 764 * and the device registers.
755#define bcm43xx_lock(bcm, flags) spin_lock_irqsave(&(bcm)->_lock, flags) 765 * => bcm->irq_lock: IRQ spinlock. Protects against IRQ handler concurrency.
756#define bcm43xx_unlock(bcm, flags) spin_unlock_irqrestore(&(bcm)->_lock, flags) 766 *
757/* bcm43xx_(un)lock_mmio() protect struct bcm43xx_private and MMIO. 767 * We have three types of helper function pairs to utilize these locks.
758 * MMIO write-access to the device is allowed. 768 * (Always use the helper functions.)
759 * All MMIO writes are flushed on unlock, so it is guaranteed to not 769 * 1) bcm43xx_{un}lock_noirq():
760 * interfere with other threads writing MMIO registers. 770 * Takes bcm->mutex. Does _not_ protect against IRQ concurrency,
771 * so it is almost always unsafe, if device IRQs are enabled.
772 * So only use this, if device IRQs are masked.
773 * Locking may sleep.
774 * You can sleep within the critical section.
775 * 2) bcm43xx_{un}lock_irqonly():
776 * Takes bcm->irq_lock. Does _not_ protect against
777 * bcm43xx_lock_noirq() critical sections.
778 * Does only protect against the IRQ handler path and other
779 * irqonly() critical sections.
780 * Locking does not sleep.
781 * You must not sleep within the critical section.
782 * 3) bcm43xx_{un}lock_irqsafe():
783 * This is the cummulative lock and takes both, mutex and irq_lock.
784 * Protects against noirq() and irqonly() critical sections (and
785 * the IRQ handler path).
786 * Locking may sleep.
787 * You must not sleep within the critical section.
761 */ 788 */
762#define bcm43xx_lock_mmio(bcm, flags) bcm43xx_lock(bcm, flags) 789
763#define bcm43xx_unlock_mmio(bcm, flags) do { mmiowb(); bcm43xx_unlock(bcm, flags); } while (0) 790/* Lock type 1 */
791#define bcm43xx_lock_noirq(bcm) mutex_lock(&(bcm)->mutex)
792#define bcm43xx_unlock_noirq(bcm) mutex_unlock(&(bcm)->mutex)
793/* Lock type 2 */
794#define bcm43xx_lock_irqonly(bcm, flags) \
795 spin_lock_irqsave(&(bcm)->irq_lock, flags)
796#define bcm43xx_unlock_irqonly(bcm, flags) \
797 spin_unlock_irqrestore(&(bcm)->irq_lock, flags)
798/* Lock type 3 */
799#define bcm43xx_lock_irqsafe(bcm, flags) do { \
800 bcm43xx_lock_noirq(bcm); \
801 bcm43xx_lock_irqonly(bcm, flags); \
802 } while (0)
803#define bcm43xx_unlock_irqsafe(bcm, flags) do { \
804 bcm43xx_unlock_irqonly(bcm, flags); \
805 bcm43xx_unlock_noirq(bcm); \
806 } while (0)
807
764 808
765static inline 809static inline
766struct bcm43xx_private * bcm43xx_priv(struct net_device *dev) 810struct bcm43xx_private * bcm43xx_priv(struct net_device *dev)
@@ -843,16 +887,6 @@ struct bcm43xx_radioinfo * bcm43xx_current_radio(struct bcm43xx_private *bcm)
843 return &(bcm->core_80211_ext[bcm->current_80211_core_idx].radio); 887 return &(bcm->core_80211_ext[bcm->current_80211_core_idx].radio);
844} 888}
845 889
846/* Are we running in init_board() context? */
847static inline
848int bcm43xx_is_initializing(struct bcm43xx_private *bcm)
849{
850 if (bcm->initialized)
851 return 0;
852 if (bcm->shutting_down)
853 return 0;
854 return 1;
855}
856 890
857static inline 891static inline
858struct bcm43xx_lopair * bcm43xx_get_lopair(struct bcm43xx_phyinfo *phy, 892struct bcm43xx_lopair * bcm43xx_get_lopair(struct bcm43xx_phyinfo *phy,
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c
index 7497fb16076e..ce2e40b29b4f 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c
@@ -77,8 +77,8 @@ static ssize_t devinfo_read_file(struct file *file, char __user *userbuf,
77 77
78 down(&big_buffer_sem); 78 down(&big_buffer_sem);
79 79
80 bcm43xx_lock_mmio(bcm, flags); 80 bcm43xx_lock_irqsafe(bcm, flags);
81 if (!bcm->initialized) { 81 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
82 fappend("Board not initialized.\n"); 82 fappend("Board not initialized.\n");
83 goto out; 83 goto out;
84 } 84 }
@@ -121,7 +121,7 @@ static ssize_t devinfo_read_file(struct file *file, char __user *userbuf,
121 fappend("\n"); 121 fappend("\n");
122 122
123out: 123out:
124 bcm43xx_unlock_mmio(bcm, flags); 124 bcm43xx_unlock_irqsafe(bcm, flags);
125 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); 125 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
126 up(&big_buffer_sem); 126 up(&big_buffer_sem);
127 return res; 127 return res;
@@ -159,8 +159,8 @@ static ssize_t spromdump_read_file(struct file *file, char __user *userbuf,
159 unsigned long flags; 159 unsigned long flags;
160 160
161 down(&big_buffer_sem); 161 down(&big_buffer_sem);
162 bcm43xx_lock_mmio(bcm, flags); 162 bcm43xx_lock_irqsafe(bcm, flags);
163 if (!bcm->initialized) { 163 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
164 fappend("Board not initialized.\n"); 164 fappend("Board not initialized.\n");
165 goto out; 165 goto out;
166 } 166 }
@@ -169,7 +169,7 @@ static ssize_t spromdump_read_file(struct file *file, char __user *userbuf,
169 fappend("boardflags: 0x%04x\n", bcm->sprom.boardflags); 169 fappend("boardflags: 0x%04x\n", bcm->sprom.boardflags);
170 170
171out: 171out:
172 bcm43xx_unlock_mmio(bcm, flags); 172 bcm43xx_unlock_irqsafe(bcm, flags);
173 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); 173 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
174 up(&big_buffer_sem); 174 up(&big_buffer_sem);
175 return res; 175 return res;
@@ -188,8 +188,8 @@ static ssize_t tsf_read_file(struct file *file, char __user *userbuf,
188 u64 tsf; 188 u64 tsf;
189 189
190 down(&big_buffer_sem); 190 down(&big_buffer_sem);
191 bcm43xx_lock_mmio(bcm, flags); 191 bcm43xx_lock_irqsafe(bcm, flags);
192 if (!bcm->initialized) { 192 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
193 fappend("Board not initialized.\n"); 193 fappend("Board not initialized.\n");
194 goto out; 194 goto out;
195 } 195 }
@@ -199,7 +199,7 @@ static ssize_t tsf_read_file(struct file *file, char __user *userbuf,
199 (unsigned int)(tsf & 0xFFFFFFFFULL)); 199 (unsigned int)(tsf & 0xFFFFFFFFULL));
200 200
201out: 201out:
202 bcm43xx_unlock_mmio(bcm, flags); 202 bcm43xx_unlock_irqsafe(bcm, flags);
203 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); 203 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
204 up(&big_buffer_sem); 204 up(&big_buffer_sem);
205 return res; 205 return res;
@@ -221,8 +221,8 @@ static ssize_t tsf_write_file(struct file *file, const char __user *user_buf,
221 res = -EFAULT; 221 res = -EFAULT;
222 goto out_up; 222 goto out_up;
223 } 223 }
224 bcm43xx_lock_mmio(bcm, flags); 224 bcm43xx_lock_irqsafe(bcm, flags);
225 if (!bcm->initialized) { 225 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
226 printk(KERN_INFO PFX "debugfs: Board not initialized.\n"); 226 printk(KERN_INFO PFX "debugfs: Board not initialized.\n");
227 res = -EFAULT; 227 res = -EFAULT;
228 goto out_unlock; 228 goto out_unlock;
@@ -233,10 +233,11 @@ static ssize_t tsf_write_file(struct file *file, const char __user *user_buf,
233 goto out_unlock; 233 goto out_unlock;
234 } 234 }
235 bcm43xx_tsf_write(bcm, tsf); 235 bcm43xx_tsf_write(bcm, tsf);
236 mmiowb();
236 res = buf_size; 237 res = buf_size;
237 238
238out_unlock: 239out_unlock:
239 bcm43xx_unlock_mmio(bcm, flags); 240 bcm43xx_unlock_irqsafe(bcm, flags);
240out_up: 241out_up:
241 up(&big_buffer_sem); 242 up(&big_buffer_sem);
242 return res; 243 return res;
@@ -257,7 +258,7 @@ static ssize_t txstat_read_file(struct file *file, char __user *userbuf,
257 int i, cnt, j = 0; 258 int i, cnt, j = 0;
258 259
259 down(&big_buffer_sem); 260 down(&big_buffer_sem);
260 bcm43xx_lock(bcm, flags); 261 bcm43xx_lock_irqsafe(bcm, flags);
261 262
262 fappend("Last %d logged xmitstatus blobs (Latest first):\n\n", 263 fappend("Last %d logged xmitstatus blobs (Latest first):\n\n",
263 BCM43xx_NR_LOGGED_XMITSTATUS); 264 BCM43xx_NR_LOGGED_XMITSTATUS);
@@ -293,14 +294,14 @@ static ssize_t txstat_read_file(struct file *file, char __user *userbuf,
293 i = BCM43xx_NR_LOGGED_XMITSTATUS - 1; 294 i = BCM43xx_NR_LOGGED_XMITSTATUS - 1;
294 } 295 }
295 296
296 bcm43xx_unlock(bcm, flags); 297 bcm43xx_unlock_irqsafe(bcm, flags);
297 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); 298 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
298 bcm43xx_lock(bcm, flags); 299 bcm43xx_lock_irqsafe(bcm, flags);
299 if (*ppos == pos) { 300 if (*ppos == pos) {
300 /* Done. Drop the copied data. */ 301 /* Done. Drop the copied data. */
301 e->xmitstatus_printing = 0; 302 e->xmitstatus_printing = 0;
302 } 303 }
303 bcm43xx_unlock(bcm, flags); 304 bcm43xx_unlock_irqsafe(bcm, flags);
304 up(&big_buffer_sem); 305 up(&big_buffer_sem);
305 return res; 306 return res;
306} 307}
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c
index 4b2c02c0b31e..ec80692d638a 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c
@@ -51,12 +51,12 @@ static void bcm43xx_led_blink(unsigned long d)
51 struct bcm43xx_private *bcm = led->bcm; 51 struct bcm43xx_private *bcm = led->bcm;
52 unsigned long flags; 52 unsigned long flags;
53 53
54 bcm43xx_lock_mmio(bcm, flags); 54 bcm43xx_lock_irqonly(bcm, flags);
55 if (led->blink_interval) { 55 if (led->blink_interval) {
56 bcm43xx_led_changestate(led); 56 bcm43xx_led_changestate(led);
57 mod_timer(&led->blink_timer, jiffies + led->blink_interval); 57 mod_timer(&led->blink_timer, jiffies + led->blink_interval);
58 } 58 }
59 bcm43xx_unlock_mmio(bcm, flags); 59 bcm43xx_unlock_irqonly(bcm, flags);
60} 60}
61 61
62static void bcm43xx_led_blink_start(struct bcm43xx_led *led, 62static void bcm43xx_led_blink_start(struct bcm43xx_led *led,
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
index 736dde96c4a3..085d7857fe31 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -498,20 +498,31 @@ static inline u32 bcm43xx_interrupt_disable(struct bcm43xx_private *bcm, u32 mas
498 return old_mask; 498 return old_mask;
499} 499}
500 500
501/* Synchronize IRQ top- and bottom-half.
502 * IRQs must be masked before calling this.
503 * This must not be called with the irq_lock held.
504 */
505static void bcm43xx_synchronize_irq(struct bcm43xx_private *bcm)
506{
507 synchronize_irq(bcm->irq);
508 tasklet_disable(&bcm->isr_tasklet);
509}
510
501/* Make sure we don't receive more data from the device. */ 511/* Make sure we don't receive more data from the device. */
502static int bcm43xx_disable_interrupts_sync(struct bcm43xx_private *bcm, u32 *oldstate) 512static int bcm43xx_disable_interrupts_sync(struct bcm43xx_private *bcm, u32 *oldstate)
503{ 513{
504 u32 old;
505 unsigned long flags; 514 unsigned long flags;
515 u32 old;
506 516
507 bcm43xx_lock_mmio(bcm, flags); 517 bcm43xx_lock_irqonly(bcm, flags);
508 if (bcm43xx_is_initializing(bcm) || bcm->shutting_down) { 518 if (unlikely(bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)) {
509 bcm43xx_unlock_mmio(bcm, flags); 519 bcm43xx_unlock_irqonly(bcm, flags);
510 return -EBUSY; 520 return -EBUSY;
511 } 521 }
512 old = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); 522 old = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
513 tasklet_disable(&bcm->isr_tasklet); 523 bcm43xx_unlock_irqonly(bcm, flags);
514 bcm43xx_unlock_mmio(bcm, flags); 524 bcm43xx_synchronize_irq(bcm);
525
515 if (oldstate) 526 if (oldstate)
516 *oldstate = old; 527 *oldstate = old;
517 528
@@ -1389,7 +1400,7 @@ void bcm43xx_wireless_core_reset(struct bcm43xx_private *bcm, int connect_phy)
1389 bcm43xx_dmacontroller_rx_reset(bcm, BCM43xx_MMIO_DMA4_BASE); 1400 bcm43xx_dmacontroller_rx_reset(bcm, BCM43xx_MMIO_DMA4_BASE);
1390#endif 1401#endif
1391 } 1402 }
1392 if (bcm->shutting_down) { 1403 if (bcm43xx_status(bcm) == BCM43xx_STAT_SHUTTINGDOWN) {
1393 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, 1404 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
1394 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD) 1405 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
1395 & ~(BCM43xx_SBF_MAC_ENABLED | 0x00000002)); 1406 & ~(BCM43xx_SBF_MAC_ENABLED | 0x00000002));
@@ -1709,7 +1720,7 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
1709# define bcmirq_handled(irq) do { /* nothing */ } while (0) 1720# define bcmirq_handled(irq) do { /* nothing */ } while (0)
1710#endif /* CONFIG_BCM43XX_DEBUG*/ 1721#endif /* CONFIG_BCM43XX_DEBUG*/
1711 1722
1712 bcm43xx_lock_mmio(bcm, flags); 1723 bcm43xx_lock_irqonly(bcm, flags);
1713 reason = bcm->irq_reason; 1724 reason = bcm->irq_reason;
1714 dma_reason[0] = bcm->dma_reason[0]; 1725 dma_reason[0] = bcm->dma_reason[0];
1715 dma_reason[1] = bcm->dma_reason[1]; 1726 dma_reason[1] = bcm->dma_reason[1];
@@ -1734,7 +1745,8 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
1734 dma_reason[0], dma_reason[1], 1745 dma_reason[0], dma_reason[1],
1735 dma_reason[2], dma_reason[3]); 1746 dma_reason[2], dma_reason[3]);
1736 bcm43xx_controller_restart(bcm, "DMA error"); 1747 bcm43xx_controller_restart(bcm, "DMA error");
1737 bcm43xx_unlock_mmio(bcm, flags); 1748 mmiowb();
1749 bcm43xx_unlock_irqonly(bcm, flags);
1738 return; 1750 return;
1739 } 1751 }
1740 if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_NONFATALMASK) | 1752 if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_NONFATALMASK) |
@@ -1821,7 +1833,8 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
1821 if (!modparam_noleds) 1833 if (!modparam_noleds)
1822 bcm43xx_leds_update(bcm, activity); 1834 bcm43xx_leds_update(bcm, activity);
1823 bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate); 1835 bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate);
1824 bcm43xx_unlock_mmio(bcm, flags); 1836 mmiowb();
1837 bcm43xx_unlock_irqonly(bcm, flags);
1825} 1838}
1826 1839
1827static void pio_irq_workaround(struct bcm43xx_private *bcm, 1840static void pio_irq_workaround(struct bcm43xx_private *bcm,
@@ -1870,7 +1883,7 @@ static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id, struct pt_re
1870 if (!bcm) 1883 if (!bcm)
1871 return IRQ_NONE; 1884 return IRQ_NONE;
1872 1885
1873 spin_lock(&bcm->_lock); 1886 spin_lock(&bcm->irq_lock);
1874 1887
1875 reason = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); 1888 reason = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
1876 if (reason == 0xffffffff) { 1889 if (reason == 0xffffffff) {
@@ -1899,7 +1912,7 @@ static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id, struct pt_re
1899 * completely, but some careful work is needed to fix this. I think it 1912 * completely, but some careful work is needed to fix this. I think it
1900 * is best to stay with this cheap workaround for now... . 1913 * is best to stay with this cheap workaround for now... .
1901 */ 1914 */
1902 if (likely(bcm->initialized)) { 1915 if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)) {
1903 /* disable all IRQs. They are enabled again in the bottom half. */ 1916 /* disable all IRQs. They are enabled again in the bottom half. */
1904 bcm->irq_savedstate = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); 1917 bcm->irq_savedstate = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
1905 /* save the reason code and call our bottom half. */ 1918 /* save the reason code and call our bottom half. */
@@ -1909,7 +1922,7 @@ static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id, struct pt_re
1909 1922
1910out: 1923out:
1911 mmiowb(); 1924 mmiowb();
1912 spin_unlock(&bcm->_lock); 1925 spin_unlock(&bcm->irq_lock);
1913 1926
1914 return ret; 1927 return ret;
1915} 1928}
@@ -2133,6 +2146,13 @@ out:
2133 return err; 2146 return err;
2134} 2147}
2135 2148
2149#ifdef CONFIG_BCM947XX
2150static struct pci_device_id bcm43xx_47xx_ids[] = {
2151 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4324) },
2152 { 0 }
2153};
2154#endif
2155
2136static int bcm43xx_initialize_irq(struct bcm43xx_private *bcm) 2156static int bcm43xx_initialize_irq(struct bcm43xx_private *bcm)
2137{ 2157{
2138 int res; 2158 int res;
@@ -2142,11 +2162,15 @@ static int bcm43xx_initialize_irq(struct bcm43xx_private *bcm)
2142 bcm->irq = bcm->pci_dev->irq; 2162 bcm->irq = bcm->pci_dev->irq;
2143#ifdef CONFIG_BCM947XX 2163#ifdef CONFIG_BCM947XX
2144 if (bcm->pci_dev->bus->number == 0) { 2164 if (bcm->pci_dev->bus->number == 0) {
2145 struct pci_dev *d = NULL; 2165 struct pci_dev *d;
2146 /* FIXME: we will probably need more device IDs here... */ 2166 struct pci_device_id *id;
2147 d = pci_find_device(PCI_VENDOR_ID_BROADCOM, 0x4324, NULL); 2167 for (id = bcm43xx_47xx_ids; id->vendor; id++) {
2148 if (d != NULL) { 2168 d = pci_get_device(id->vendor, id->device, NULL);
2149 bcm->irq = d->irq; 2169 if (d != NULL) {
2170 bcm->irq = d->irq;
2171 pci_dev_put(d);
2172 break;
2173 }
2150 } 2174 }
2151 } 2175 }
2152#endif 2176#endif
@@ -3106,15 +3130,10 @@ static void bcm43xx_periodic_every15sec(struct bcm43xx_private *bcm)
3106 //TODO for APHY (temperature?) 3130 //TODO for APHY (temperature?)
3107} 3131}
3108 3132
3109static void bcm43xx_periodic_task_handler(unsigned long d) 3133static void do_periodic_work(struct bcm43xx_private *bcm)
3110{ 3134{
3111 struct bcm43xx_private *bcm = (struct bcm43xx_private *)d;
3112 unsigned long flags;
3113 unsigned int state; 3135 unsigned int state;
3114 3136
3115 bcm43xx_lock_mmio(bcm, flags);
3116
3117 assert(bcm->initialized);
3118 state = bcm->periodic_state; 3137 state = bcm->periodic_state;
3119 if (state % 8 == 0) 3138 if (state % 8 == 0)
3120 bcm43xx_periodic_every120sec(bcm); 3139 bcm43xx_periodic_every120sec(bcm);
@@ -3122,29 +3141,93 @@ static void bcm43xx_periodic_task_handler(unsigned long d)
3122 bcm43xx_periodic_every60sec(bcm); 3141 bcm43xx_periodic_every60sec(bcm);
3123 if (state % 2 == 0) 3142 if (state % 2 == 0)
3124 bcm43xx_periodic_every30sec(bcm); 3143 bcm43xx_periodic_every30sec(bcm);
3125 bcm43xx_periodic_every15sec(bcm); 3144 if (state % 1 == 0)
3145 bcm43xx_periodic_every15sec(bcm);
3126 bcm->periodic_state = state + 1; 3146 bcm->periodic_state = state + 1;
3127 3147
3128 mod_timer(&bcm->periodic_tasks, jiffies + (HZ * 15)); 3148 schedule_delayed_work(&bcm->periodic_work, HZ * 15);
3149}
3150
3151/* Estimate a "Badness" value based on the periodic work
3152 * state-machine state. "Badness" is worse (bigger), if the
3153 * periodic work will take longer.
3154 */
3155static int estimate_periodic_work_badness(unsigned int state)
3156{
3157 int badness = 0;
3158
3159 if (state % 8 == 0) /* every 120 sec */
3160 badness += 10;
3161 if (state % 4 == 0) /* every 60 sec */
3162 badness += 5;
3163 if (state % 2 == 0) /* every 30 sec */
3164 badness += 1;
3165 if (state % 1 == 0) /* every 15 sec */
3166 badness += 1;
3129 3167
3130 bcm43xx_unlock_mmio(bcm, flags); 3168#define BADNESS_LIMIT 4
3169 return badness;
3170}
3171
3172static void bcm43xx_periodic_work_handler(void *d)
3173{
3174 struct bcm43xx_private *bcm = d;
3175 unsigned long flags;
3176 u32 savedirqs = 0;
3177 int badness;
3178
3179 badness = estimate_periodic_work_badness(bcm->periodic_state);
3180 if (badness > BADNESS_LIMIT) {
3181 /* Periodic work will take a long time, so we want it to
3182 * be preemtible.
3183 */
3184 bcm43xx_lock_irqonly(bcm, flags);
3185 netif_stop_queue(bcm->net_dev);
3186 if (bcm43xx_using_pio(bcm))
3187 bcm43xx_pio_freeze_txqueues(bcm);
3188 savedirqs = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
3189 bcm43xx_unlock_irqonly(bcm, flags);
3190 bcm43xx_lock_noirq(bcm);
3191 bcm43xx_synchronize_irq(bcm);
3192 } else {
3193 /* Periodic work should take short time, so we want low
3194 * locking overhead.
3195 */
3196 bcm43xx_lock_irqsafe(bcm, flags);
3197 }
3198
3199 do_periodic_work(bcm);
3200
3201 if (badness > BADNESS_LIMIT) {
3202 bcm43xx_lock_irqonly(bcm, flags);
3203 if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)) {
3204 tasklet_enable(&bcm->isr_tasklet);
3205 bcm43xx_interrupt_enable(bcm, savedirqs);
3206 if (bcm43xx_using_pio(bcm))
3207 bcm43xx_pio_thaw_txqueues(bcm);
3208 }
3209 netif_wake_queue(bcm->net_dev);
3210 mmiowb();
3211 bcm43xx_unlock_irqonly(bcm, flags);
3212 bcm43xx_unlock_noirq(bcm);
3213 } else {
3214 mmiowb();
3215 bcm43xx_unlock_irqsafe(bcm, flags);
3216 }
3131} 3217}
3132 3218
3133static void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm) 3219static void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm)
3134{ 3220{
3135 del_timer_sync(&bcm->periodic_tasks); 3221 cancel_rearming_delayed_work(&bcm->periodic_work);
3136} 3222}
3137 3223
3138static void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm) 3224static void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm)
3139{ 3225{
3140 struct timer_list *timer = &(bcm->periodic_tasks); 3226 struct work_struct *work = &(bcm->periodic_work);
3141 3227
3142 assert(bcm->initialized); 3228 assert(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED);
3143 setup_timer(timer, 3229 INIT_WORK(work, bcm43xx_periodic_work_handler, bcm);
3144 bcm43xx_periodic_task_handler, 3230 schedule_work(work);
3145 (unsigned long)bcm);
3146 timer->expires = jiffies;
3147 add_timer(timer);
3148} 3231}
3149 3232
3150static void bcm43xx_security_init(struct bcm43xx_private *bcm) 3233static void bcm43xx_security_init(struct bcm43xx_private *bcm)
@@ -3158,16 +3241,12 @@ static void bcm43xx_security_init(struct bcm43xx_private *bcm)
3158static void bcm43xx_free_board(struct bcm43xx_private *bcm) 3241static void bcm43xx_free_board(struct bcm43xx_private *bcm)
3159{ 3242{
3160 int i, err; 3243 int i, err;
3161 unsigned long flags;
3162 3244
3245 bcm43xx_lock_noirq(bcm);
3163 bcm43xx_sysfs_unregister(bcm); 3246 bcm43xx_sysfs_unregister(bcm);
3164
3165 bcm43xx_periodic_tasks_delete(bcm); 3247 bcm43xx_periodic_tasks_delete(bcm);
3166 3248
3167 bcm43xx_lock(bcm, flags); 3249 bcm43xx_set_status(bcm, BCM43xx_STAT_SHUTTINGDOWN);
3168 bcm->initialized = 0;
3169 bcm->shutting_down = 1;
3170 bcm43xx_unlock(bcm, flags);
3171 3250
3172 for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) { 3251 for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) {
3173 if (!bcm->core_80211[i].available) 3252 if (!bcm->core_80211[i].available)
@@ -3182,23 +3261,19 @@ static void bcm43xx_free_board(struct bcm43xx_private *bcm)
3182 3261
3183 bcm43xx_pctl_set_crystal(bcm, 0); 3262 bcm43xx_pctl_set_crystal(bcm, 0);
3184 3263
3185 bcm43xx_lock(bcm, flags); 3264 bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT);
3186 bcm->shutting_down = 0; 3265 bcm43xx_unlock_noirq(bcm);
3187 bcm43xx_unlock(bcm, flags);
3188} 3266}
3189 3267
3190static int bcm43xx_init_board(struct bcm43xx_private *bcm) 3268static int bcm43xx_init_board(struct bcm43xx_private *bcm)
3191{ 3269{
3192 int i, err; 3270 int i, err;
3193 int connect_phy; 3271 int connect_phy;
3194 unsigned long flags;
3195 3272
3196 might_sleep(); 3273 might_sleep();
3197 3274
3198 bcm43xx_lock(bcm, flags); 3275 bcm43xx_lock_noirq(bcm);
3199 bcm->initialized = 0; 3276 bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZING);
3200 bcm->shutting_down = 0;
3201 bcm43xx_unlock(bcm, flags);
3202 3277
3203 err = bcm43xx_pctl_set_crystal(bcm, 1); 3278 err = bcm43xx_pctl_set_crystal(bcm, 1);
3204 if (err) 3279 if (err)
@@ -3265,9 +3340,7 @@ static int bcm43xx_init_board(struct bcm43xx_private *bcm)
3265 } 3340 }
3266 3341
3267 /* Initialization of the board is done. Flag it as such. */ 3342 /* Initialization of the board is done. Flag it as such. */
3268 bcm43xx_lock(bcm, flags); 3343 bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZED);
3269 bcm->initialized = 1;
3270 bcm43xx_unlock(bcm, flags);
3271 3344
3272 bcm43xx_periodic_tasks_setup(bcm); 3345 bcm43xx_periodic_tasks_setup(bcm);
3273 bcm43xx_sysfs_register(bcm); 3346 bcm43xx_sysfs_register(bcm);
@@ -3278,6 +3351,8 @@ static int bcm43xx_init_board(struct bcm43xx_private *bcm)
3278 3351
3279 assert(err == 0); 3352 assert(err == 0);
3280out: 3353out:
3354 bcm43xx_unlock_noirq(bcm);
3355
3281 return err; 3356 return err;
3282 3357
3283err_80211_unwind: 3358err_80211_unwind:
@@ -3534,8 +3609,8 @@ static void bcm43xx_ieee80211_set_chan(struct net_device *net_dev,
3534 struct bcm43xx_radioinfo *radio; 3609 struct bcm43xx_radioinfo *radio;
3535 unsigned long flags; 3610 unsigned long flags;
3536 3611
3537 bcm43xx_lock_mmio(bcm, flags); 3612 bcm43xx_lock_irqsafe(bcm, flags);
3538 if (bcm->initialized) { 3613 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
3539 bcm43xx_mac_suspend(bcm); 3614 bcm43xx_mac_suspend(bcm);
3540 bcm43xx_radio_selectchannel(bcm, channel, 0); 3615 bcm43xx_radio_selectchannel(bcm, channel, 0);
3541 bcm43xx_mac_enable(bcm); 3616 bcm43xx_mac_enable(bcm);
@@ -3543,7 +3618,7 @@ static void bcm43xx_ieee80211_set_chan(struct net_device *net_dev,
3543 radio = bcm43xx_current_radio(bcm); 3618 radio = bcm43xx_current_radio(bcm);
3544 radio->initial_channel = channel; 3619 radio->initial_channel = channel;
3545 } 3620 }
3546 bcm43xx_unlock_mmio(bcm, flags); 3621 bcm43xx_unlock_irqsafe(bcm, flags);
3547} 3622}
3548 3623
3549/* set_security() callback in struct ieee80211_device */ 3624/* set_security() callback in struct ieee80211_device */
@@ -3557,7 +3632,7 @@ static void bcm43xx_ieee80211_set_security(struct net_device *net_dev,
3557 3632
3558 dprintk(KERN_INFO PFX "set security called"); 3633 dprintk(KERN_INFO PFX "set security called");
3559 3634
3560 bcm43xx_lock_mmio(bcm, flags); 3635 bcm43xx_lock_irqsafe(bcm, flags);
3561 3636
3562 for (keyidx = 0; keyidx<WEP_KEYS; keyidx++) 3637 for (keyidx = 0; keyidx<WEP_KEYS; keyidx++)
3563 if (sec->flags & (1<<keyidx)) { 3638 if (sec->flags & (1<<keyidx)) {
@@ -3587,7 +3662,8 @@ static void bcm43xx_ieee80211_set_security(struct net_device *net_dev,
3587 dprintk(", .encrypt = %d", sec->encrypt); 3662 dprintk(", .encrypt = %d", sec->encrypt);
3588 } 3663 }
3589 dprintk("\n"); 3664 dprintk("\n");
3590 if (bcm->initialized && !bcm->ieee->host_encrypt) { 3665 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED &&
3666 !bcm->ieee->host_encrypt) {
3591 if (secinfo->enabled) { 3667 if (secinfo->enabled) {
3592 /* upload WEP keys to hardware */ 3668 /* upload WEP keys to hardware */
3593 char null_address[6] = { 0 }; 3669 char null_address[6] = { 0 };
@@ -3621,7 +3697,7 @@ static void bcm43xx_ieee80211_set_security(struct net_device *net_dev,
3621 } else 3697 } else
3622 bcm43xx_clear_keys(bcm); 3698 bcm43xx_clear_keys(bcm);
3623 } 3699 }
3624 bcm43xx_unlock_mmio(bcm, flags); 3700 bcm43xx_unlock_irqsafe(bcm, flags);
3625} 3701}
3626 3702
3627/* hard_start_xmit() callback in struct ieee80211_device */ 3703/* hard_start_xmit() callback in struct ieee80211_device */
@@ -3633,10 +3709,10 @@ static int bcm43xx_ieee80211_hard_start_xmit(struct ieee80211_txb *txb,
3633 int err = -ENODEV; 3709 int err = -ENODEV;
3634 unsigned long flags; 3710 unsigned long flags;
3635 3711
3636 bcm43xx_lock_mmio(bcm, flags); 3712 bcm43xx_lock_irqonly(bcm, flags);
3637 if (likely(bcm->initialized)) 3713 if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED))
3638 err = bcm43xx_tx(bcm, txb); 3714 err = bcm43xx_tx(bcm, txb);
3639 bcm43xx_unlock_mmio(bcm, flags); 3715 bcm43xx_unlock_irqonly(bcm, flags);
3640 3716
3641 return err; 3717 return err;
3642} 3718}
@@ -3651,9 +3727,9 @@ static void bcm43xx_net_tx_timeout(struct net_device *net_dev)
3651 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 3727 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3652 unsigned long flags; 3728 unsigned long flags;
3653 3729
3654 bcm43xx_lock_mmio(bcm, flags); 3730 bcm43xx_lock_irqonly(bcm, flags);
3655 bcm43xx_controller_restart(bcm, "TX timeout"); 3731 bcm43xx_controller_restart(bcm, "TX timeout");
3656 bcm43xx_unlock_mmio(bcm, flags); 3732 bcm43xx_unlock_irqonly(bcm, flags);
3657} 3733}
3658 3734
3659#ifdef CONFIG_NET_POLL_CONTROLLER 3735#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -3678,9 +3754,11 @@ static int bcm43xx_net_open(struct net_device *net_dev)
3678static int bcm43xx_net_stop(struct net_device *net_dev) 3754static int bcm43xx_net_stop(struct net_device *net_dev)
3679{ 3755{
3680 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 3756 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3757 int err;
3681 3758
3682 ieee80211softmac_stop(net_dev); 3759 ieee80211softmac_stop(net_dev);
3683 bcm43xx_disable_interrupts_sync(bcm, NULL); 3760 err = bcm43xx_disable_interrupts_sync(bcm, NULL);
3761 assert(!err);
3684 bcm43xx_free_board(bcm); 3762 bcm43xx_free_board(bcm);
3685 3763
3686 return 0; 3764 return 0;
@@ -3692,6 +3770,7 @@ static int bcm43xx_init_private(struct bcm43xx_private *bcm,
3692{ 3770{
3693 int err; 3771 int err;
3694 3772
3773 bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT);
3695 bcm->ieee = netdev_priv(net_dev); 3774 bcm->ieee = netdev_priv(net_dev);
3696 bcm->softmac = ieee80211_priv(net_dev); 3775 bcm->softmac = ieee80211_priv(net_dev);
3697 bcm->softmac->set_channel = bcm43xx_ieee80211_set_chan; 3776 bcm->softmac->set_channel = bcm43xx_ieee80211_set_chan;
@@ -3700,7 +3779,8 @@ static int bcm43xx_init_private(struct bcm43xx_private *bcm,
3700 bcm->pci_dev = pci_dev; 3779 bcm->pci_dev = pci_dev;
3701 bcm->net_dev = net_dev; 3780 bcm->net_dev = net_dev;
3702 bcm->bad_frames_preempt = modparam_bad_frames_preempt; 3781 bcm->bad_frames_preempt = modparam_bad_frames_preempt;
3703 spin_lock_init(&bcm->_lock); 3782 spin_lock_init(&bcm->irq_lock);
3783 mutex_init(&bcm->mutex);
3704 tasklet_init(&bcm->isr_tasklet, 3784 tasklet_init(&bcm->isr_tasklet,
3705 (void (*)(unsigned long))bcm43xx_interrupt_tasklet, 3785 (void (*)(unsigned long))bcm43xx_interrupt_tasklet,
3706 (unsigned long)bcm); 3786 (unsigned long)bcm);
@@ -3831,7 +3911,7 @@ static void bcm43xx_chip_reset(void *_bcm)
3831 struct net_device *net_dev = bcm->net_dev; 3911 struct net_device *net_dev = bcm->net_dev;
3832 struct pci_dev *pci_dev = bcm->pci_dev; 3912 struct pci_dev *pci_dev = bcm->pci_dev;
3833 int err; 3913 int err;
3834 int was_initialized = bcm->initialized; 3914 int was_initialized = (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED);
3835 3915
3836 netif_stop_queue(bcm->net_dev); 3916 netif_stop_queue(bcm->net_dev);
3837 tasklet_disable(&bcm->isr_tasklet); 3917 tasklet_disable(&bcm->isr_tasklet);
@@ -3866,6 +3946,7 @@ failure:
3866*/ 3946*/
3867void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason) 3947void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason)
3868{ 3948{
3949 bcm43xx_set_status(bcm, BCM43xx_STAT_RESTARTING);
3869 bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); 3950 bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
3870 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */ 3951 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */
3871 printk(KERN_ERR PFX "Controller RESET (%s) ...\n", reason); 3952 printk(KERN_ERR PFX "Controller RESET (%s) ...\n", reason);
@@ -3884,11 +3965,11 @@ static int bcm43xx_suspend(struct pci_dev *pdev, pm_message_t state)
3884 3965
3885 dprintk(KERN_INFO PFX "Suspending...\n"); 3966 dprintk(KERN_INFO PFX "Suspending...\n");
3886 3967
3887 bcm43xx_lock(bcm, flags); 3968 bcm43xx_lock_irqsafe(bcm, flags);
3888 bcm->was_initialized = bcm->initialized; 3969 bcm->was_initialized = (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED);
3889 if (bcm->initialized) 3970 if (bcm->was_initialized)
3890 try_to_shutdown = 1; 3971 try_to_shutdown = 1;
3891 bcm43xx_unlock(bcm, flags); 3972 bcm43xx_unlock_irqsafe(bcm, flags);
3892 3973
3893 netif_device_detach(net_dev); 3974 netif_device_detach(net_dev);
3894 if (try_to_shutdown) { 3975 if (try_to_shutdown) {
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
index b0abac515530..f8200deecc8a 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
@@ -1410,7 +1410,10 @@ static inline
1410u16 bcm43xx_phy_lo_g_deviation_subval(struct bcm43xx_private *bcm, u16 control) 1410u16 bcm43xx_phy_lo_g_deviation_subval(struct bcm43xx_private *bcm, u16 control)
1411{ 1411{
1412 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); 1412 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
1413 u16 ret;
1414 unsigned long flags;
1413 1415
1416 local_irq_save(flags);
1414 if (phy->connected) { 1417 if (phy->connected) {
1415 bcm43xx_phy_write(bcm, 0x15, 0xE300); 1418 bcm43xx_phy_write(bcm, 0x15, 0xE300);
1416 control <<= 8; 1419 control <<= 8;
@@ -1430,8 +1433,10 @@ u16 bcm43xx_phy_lo_g_deviation_subval(struct bcm43xx_private *bcm, u16 control)
1430 bcm43xx_phy_write(bcm, 0x0015, control | 0xFFE0); 1433 bcm43xx_phy_write(bcm, 0x0015, control | 0xFFE0);
1431 udelay(8); 1434 udelay(8);
1432 } 1435 }
1436 ret = bcm43xx_phy_read(bcm, 0x002D);
1437 local_irq_restore(flags);
1433 1438
1434 return bcm43xx_phy_read(bcm, 0x002D); 1439 return ret;
1435} 1440}
1436 1441
1437static u32 bcm43xx_phy_lo_g_singledeviation(struct bcm43xx_private *bcm, u16 control) 1442static u32 bcm43xx_phy_lo_g_singledeviation(struct bcm43xx_private *bcm, u16 control)
@@ -1648,7 +1653,7 @@ void bcm43xx_phy_set_baseband_attenuation(struct bcm43xx_private *bcm,
1648void bcm43xx_phy_lo_g_measure(struct bcm43xx_private *bcm) 1653void bcm43xx_phy_lo_g_measure(struct bcm43xx_private *bcm)
1649{ 1654{
1650 static const u8 pairorder[10] = { 3, 1, 5, 7, 9, 2, 0, 4, 6, 8 }; 1655 static const u8 pairorder[10] = { 3, 1, 5, 7, 9, 2, 0, 4, 6, 8 };
1651 const int is_initializing = bcm43xx_is_initializing(bcm); 1656 const int is_initializing = (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZING);
1652 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); 1657 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
1653 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); 1658 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
1654 u16 h, i, oldi = 0, j; 1659 u16 h, i, oldi = 0, j;
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_pio.c b/drivers/net/wireless/bcm43xx/bcm43xx_pio.c
index 0aa1bd269a25..574085c46152 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_pio.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_pio.c
@@ -262,8 +262,10 @@ static void tx_tasklet(unsigned long d)
262 int err; 262 int err;
263 u16 txctl; 263 u16 txctl;
264 264
265 bcm43xx_lock_mmio(bcm, flags); 265 bcm43xx_lock_irqonly(bcm, flags);
266 266
267 if (queue->tx_frozen)
268 goto out_unlock;
267 txctl = bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL); 269 txctl = bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL);
268 if (txctl & BCM43xx_PIO_TXCTL_SUSPEND) 270 if (txctl & BCM43xx_PIO_TXCTL_SUSPEND)
269 goto out_unlock; 271 goto out_unlock;
@@ -298,7 +300,7 @@ static void tx_tasklet(unsigned long d)
298 continue; 300 continue;
299 } 301 }
300out_unlock: 302out_unlock:
301 bcm43xx_unlock_mmio(bcm, flags); 303 bcm43xx_unlock_irqonly(bcm, flags);
302} 304}
303 305
304static void setup_txqueues(struct bcm43xx_pioqueue *queue) 306static void setup_txqueues(struct bcm43xx_pioqueue *queue)
@@ -374,7 +376,6 @@ static void cancel_transfers(struct bcm43xx_pioqueue *queue)
374 struct bcm43xx_pio_txpacket *packet, *tmp_packet; 376 struct bcm43xx_pio_txpacket *packet, *tmp_packet;
375 377
376 netif_tx_disable(queue->bcm->net_dev); 378 netif_tx_disable(queue->bcm->net_dev);
377 assert(queue->bcm->shutting_down);
378 tasklet_disable(&queue->txtask); 379 tasklet_disable(&queue->txtask);
379 380
380 list_for_each_entry_safe(packet, tmp_packet, &queue->txrunning, list) 381 list_for_each_entry_safe(packet, tmp_packet, &queue->txrunning, list)
@@ -634,5 +635,40 @@ void bcm43xx_pio_tx_resume(struct bcm43xx_pioqueue *queue)
634 bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL) 635 bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL)
635 & ~BCM43xx_PIO_TXCTL_SUSPEND); 636 & ~BCM43xx_PIO_TXCTL_SUSPEND);
636 bcm43xx_power_saving_ctl_bits(queue->bcm, -1, -1); 637 bcm43xx_power_saving_ctl_bits(queue->bcm, -1, -1);
637 tasklet_schedule(&queue->txtask); 638 if (!list_empty(&queue->txqueue))
639 tasklet_schedule(&queue->txtask);
640}
641
642void bcm43xx_pio_freeze_txqueues(struct bcm43xx_private *bcm)
643{
644 struct bcm43xx_pio *pio;
645
646 assert(bcm43xx_using_pio(bcm));
647 pio = bcm43xx_current_pio(bcm);
648 pio->queue0->tx_frozen = 1;
649 pio->queue1->tx_frozen = 1;
650 pio->queue2->tx_frozen = 1;
651 pio->queue3->tx_frozen = 1;
638} 652}
653
654void bcm43xx_pio_thaw_txqueues(struct bcm43xx_private *bcm)
655{
656 struct bcm43xx_pio *pio;
657
658 assert(bcm43xx_using_pio(bcm));
659 pio = bcm43xx_current_pio(bcm);
660 pio->queue0->tx_frozen = 0;
661 pio->queue1->tx_frozen = 0;
662 pio->queue2->tx_frozen = 0;
663 pio->queue3->tx_frozen = 0;
664 if (!list_empty(&pio->queue0->txqueue))
665 tasklet_schedule(&pio->queue0->txtask);
666 if (!list_empty(&pio->queue1->txqueue))
667 tasklet_schedule(&pio->queue1->txtask);
668 if (!list_empty(&pio->queue2->txqueue))
669 tasklet_schedule(&pio->queue2->txtask);
670 if (!list_empty(&pio->queue3->txqueue))
671 tasklet_schedule(&pio->queue3->txtask);
672}
673
674
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_pio.h b/drivers/net/wireless/bcm43xx/bcm43xx_pio.h
index dfc78209e3a3..bc78a3c2cafb 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_pio.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_pio.h
@@ -54,6 +54,7 @@ struct bcm43xx_pioqueue {
54 u16 mmio_base; 54 u16 mmio_base;
55 55
56 u8 tx_suspended:1, 56 u8 tx_suspended:1,
57 tx_frozen:1,
57 need_workarounds:1; /* Workarounds needed for core.rev < 3 */ 58 need_workarounds:1; /* Workarounds needed for core.rev < 3 */
58 59
59 /* Adjusted size of the device internal TX buffer. */ 60 /* Adjusted size of the device internal TX buffer. */
@@ -108,8 +109,12 @@ void bcm43xx_pio_handle_xmitstatus(struct bcm43xx_private *bcm,
108 struct bcm43xx_xmitstatus *status); 109 struct bcm43xx_xmitstatus *status);
109void bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue); 110void bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue);
110 111
112/* Suspend a TX queue on hardware level. */
111void bcm43xx_pio_tx_suspend(struct bcm43xx_pioqueue *queue); 113void bcm43xx_pio_tx_suspend(struct bcm43xx_pioqueue *queue);
112void bcm43xx_pio_tx_resume(struct bcm43xx_pioqueue *queue); 114void bcm43xx_pio_tx_resume(struct bcm43xx_pioqueue *queue);
115/* Suspend (freeze) the TX tasklet (software level). */
116void bcm43xx_pio_freeze_txqueues(struct bcm43xx_private *bcm);
117void bcm43xx_pio_thaw_txqueues(struct bcm43xx_private *bcm);
113 118
114#else /* CONFIG_BCM43XX_PIO */ 119#else /* CONFIG_BCM43XX_PIO */
115 120
@@ -145,6 +150,14 @@ static inline
145void bcm43xx_pio_tx_resume(struct bcm43xx_pioqueue *queue) 150void bcm43xx_pio_tx_resume(struct bcm43xx_pioqueue *queue)
146{ 151{
147} 152}
153static inline
154void bcm43xx_pio_freeze_txqueues(struct bcm43xx_private *bcm)
155{
156}
157static inline
158void bcm43xx_pio_thaw_txqueues(struct bcm43xx_private *bcm)
159{
160}
148 161
149#endif /* CONFIG_BCM43XX_PIO */ 162#endif /* CONFIG_BCM43XX_PIO */
150#endif /* BCM43xx_PIO_H_ */ 163#endif /* BCM43xx_PIO_H_ */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c
index b438f48e891d..6a23bdc75412 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c
@@ -120,12 +120,12 @@ static ssize_t bcm43xx_attr_sprom_show(struct device *dev,
120 GFP_KERNEL); 120 GFP_KERNEL);
121 if (!sprom) 121 if (!sprom)
122 return -ENOMEM; 122 return -ENOMEM;
123 bcm43xx_lock_mmio(bcm, flags); 123 bcm43xx_lock_irqsafe(bcm, flags);
124 assert(bcm->initialized);
125 err = bcm43xx_sprom_read(bcm, sprom); 124 err = bcm43xx_sprom_read(bcm, sprom);
126 if (!err) 125 if (!err)
127 err = sprom2hex(sprom, buf, PAGE_SIZE); 126 err = sprom2hex(sprom, buf, PAGE_SIZE);
128 bcm43xx_unlock_mmio(bcm, flags); 127 mmiowb();
128 bcm43xx_unlock_irqsafe(bcm, flags);
129 kfree(sprom); 129 kfree(sprom);
130 130
131 return err; 131 return err;
@@ -150,10 +150,10 @@ static ssize_t bcm43xx_attr_sprom_store(struct device *dev,
150 err = hex2sprom(sprom, buf, count); 150 err = hex2sprom(sprom, buf, count);
151 if (err) 151 if (err)
152 goto out_kfree; 152 goto out_kfree;
153 bcm43xx_lock_mmio(bcm, flags); 153 bcm43xx_lock_irqsafe(bcm, flags);
154 assert(bcm->initialized);
155 err = bcm43xx_sprom_write(bcm, sprom); 154 err = bcm43xx_sprom_write(bcm, sprom);
156 bcm43xx_unlock_mmio(bcm, flags); 155 mmiowb();
156 bcm43xx_unlock_irqsafe(bcm, flags);
157out_kfree: 157out_kfree:
158 kfree(sprom); 158 kfree(sprom);
159 159
@@ -170,15 +170,13 @@ static ssize_t bcm43xx_attr_interfmode_show(struct device *dev,
170 char *buf) 170 char *buf)
171{ 171{
172 struct bcm43xx_private *bcm = dev_to_bcm(dev); 172 struct bcm43xx_private *bcm = dev_to_bcm(dev);
173 unsigned long flags;
174 int err; 173 int err;
175 ssize_t count = 0; 174 ssize_t count = 0;
176 175
177 if (!capable(CAP_NET_ADMIN)) 176 if (!capable(CAP_NET_ADMIN))
178 return -EPERM; 177 return -EPERM;
179 178
180 bcm43xx_lock(bcm, flags); 179 bcm43xx_lock_noirq(bcm);
181 assert(bcm->initialized);
182 180
183 switch (bcm43xx_current_radio(bcm)->interfmode) { 181 switch (bcm43xx_current_radio(bcm)->interfmode) {
184 case BCM43xx_RADIO_INTERFMODE_NONE: 182 case BCM43xx_RADIO_INTERFMODE_NONE:
@@ -195,7 +193,7 @@ static ssize_t bcm43xx_attr_interfmode_show(struct device *dev,
195 } 193 }
196 err = 0; 194 err = 0;
197 195
198 bcm43xx_unlock(bcm, flags); 196 bcm43xx_unlock_noirq(bcm);
199 197
200 return err ? err : count; 198 return err ? err : count;
201 199
@@ -231,16 +229,15 @@ static ssize_t bcm43xx_attr_interfmode_store(struct device *dev,
231 return -EINVAL; 229 return -EINVAL;
232 } 230 }
233 231
234 bcm43xx_lock_mmio(bcm, flags); 232 bcm43xx_lock_irqsafe(bcm, flags);
235 assert(bcm->initialized);
236 233
237 err = bcm43xx_radio_set_interference_mitigation(bcm, mode); 234 err = bcm43xx_radio_set_interference_mitigation(bcm, mode);
238 if (err) { 235 if (err) {
239 printk(KERN_ERR PFX "Interference Mitigation not " 236 printk(KERN_ERR PFX "Interference Mitigation not "
240 "supported by device\n"); 237 "supported by device\n");
241 } 238 }
242 239 mmiowb();
243 bcm43xx_unlock_mmio(bcm, flags); 240 bcm43xx_unlock_irqsafe(bcm, flags);
244 241
245 return err ? err : count; 242 return err ? err : count;
246} 243}
@@ -254,15 +251,13 @@ static ssize_t bcm43xx_attr_preamble_show(struct device *dev,
254 char *buf) 251 char *buf)
255{ 252{
256 struct bcm43xx_private *bcm = dev_to_bcm(dev); 253 struct bcm43xx_private *bcm = dev_to_bcm(dev);
257 unsigned long flags;
258 int err; 254 int err;
259 ssize_t count; 255 ssize_t count;
260 256
261 if (!capable(CAP_NET_ADMIN)) 257 if (!capable(CAP_NET_ADMIN))
262 return -EPERM; 258 return -EPERM;
263 259
264 bcm43xx_lock(bcm, flags); 260 bcm43xx_lock_noirq(bcm);
265 assert(bcm->initialized);
266 261
267 if (bcm->short_preamble) 262 if (bcm->short_preamble)
268 count = snprintf(buf, PAGE_SIZE, "1 (Short Preamble enabled)\n"); 263 count = snprintf(buf, PAGE_SIZE, "1 (Short Preamble enabled)\n");
@@ -270,7 +265,7 @@ static ssize_t bcm43xx_attr_preamble_show(struct device *dev,
270 count = snprintf(buf, PAGE_SIZE, "0 (Short Preamble disabled)\n"); 265 count = snprintf(buf, PAGE_SIZE, "0 (Short Preamble disabled)\n");
271 266
272 err = 0; 267 err = 0;
273 bcm43xx_unlock(bcm, flags); 268 bcm43xx_unlock_noirq(bcm);
274 269
275 return err ? err : count; 270 return err ? err : count;
276} 271}
@@ -290,13 +285,12 @@ static ssize_t bcm43xx_attr_preamble_store(struct device *dev,
290 value = get_boolean(buf, count); 285 value = get_boolean(buf, count);
291 if (value < 0) 286 if (value < 0)
292 return value; 287 return value;
293 bcm43xx_lock(bcm, flags); 288 bcm43xx_lock_irqsafe(bcm, flags);
294 assert(bcm->initialized);
295 289
296 bcm->short_preamble = !!value; 290 bcm->short_preamble = !!value;
297 291
298 err = 0; 292 err = 0;
299 bcm43xx_unlock(bcm, flags); 293 bcm43xx_unlock_irqsafe(bcm, flags);
300 294
301 return err ? err : count; 295 return err ? err : count;
302} 296}
@@ -310,7 +304,7 @@ int bcm43xx_sysfs_register(struct bcm43xx_private *bcm)
310 struct device *dev = &bcm->pci_dev->dev; 304 struct device *dev = &bcm->pci_dev->dev;
311 int err; 305 int err;
312 306
313 assert(bcm->initialized); 307 assert(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED);
314 308
315 err = device_create_file(dev, &dev_attr_sprom); 309 err = device_create_file(dev, &dev_attr_sprom);
316 if (err) 310 if (err)
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
index b45063974ae9..c35cb3a0777e 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
@@ -55,13 +55,13 @@ static int bcm43xx_wx_get_name(struct net_device *net_dev,
55 char *extra) 55 char *extra)
56{ 56{
57 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 57 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
58 unsigned long flags;
59 int i; 58 int i;
59 unsigned long flags;
60 struct bcm43xx_phyinfo *phy; 60 struct bcm43xx_phyinfo *phy;
61 char suffix[7] = { 0 }; 61 char suffix[7] = { 0 };
62 int have_a = 0, have_b = 0, have_g = 0; 62 int have_a = 0, have_b = 0, have_g = 0;
63 63
64 bcm43xx_lock(bcm, flags); 64 bcm43xx_lock_irqsafe(bcm, flags);
65 for (i = 0; i < bcm->nr_80211_available; i++) { 65 for (i = 0; i < bcm->nr_80211_available; i++) {
66 phy = &(bcm->core_80211_ext[i].phy); 66 phy = &(bcm->core_80211_ext[i].phy);
67 switch (phy->type) { 67 switch (phy->type) {
@@ -77,7 +77,7 @@ static int bcm43xx_wx_get_name(struct net_device *net_dev,
77 assert(0); 77 assert(0);
78 } 78 }
79 } 79 }
80 bcm43xx_unlock(bcm, flags); 80 bcm43xx_unlock_irqsafe(bcm, flags);
81 81
82 i = 0; 82 i = 0;
83 if (have_a) { 83 if (have_a) {
@@ -111,7 +111,7 @@ static int bcm43xx_wx_set_channelfreq(struct net_device *net_dev,
111 int freq; 111 int freq;
112 int err = -EINVAL; 112 int err = -EINVAL;
113 113
114 bcm43xx_lock_mmio(bcm, flags); 114 bcm43xx_lock_irqsafe(bcm, flags);
115 if ((data->freq.m >= 0) && (data->freq.m <= 1000)) { 115 if ((data->freq.m >= 0) && (data->freq.m <= 1000)) {
116 channel = data->freq.m; 116 channel = data->freq.m;
117 freq = bcm43xx_channel_to_freq(bcm, channel); 117 freq = bcm43xx_channel_to_freq(bcm, channel);
@@ -121,7 +121,7 @@ static int bcm43xx_wx_set_channelfreq(struct net_device *net_dev,
121 } 121 }
122 if (!bcm43xx_is_valid_channel(bcm, channel)) 122 if (!bcm43xx_is_valid_channel(bcm, channel))
123 goto out_unlock; 123 goto out_unlock;
124 if (bcm->initialized) { 124 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
125 //ieee80211softmac_disassoc(softmac, $REASON); 125 //ieee80211softmac_disassoc(softmac, $REASON);
126 bcm43xx_mac_suspend(bcm); 126 bcm43xx_mac_suspend(bcm);
127 err = bcm43xx_radio_selectchannel(bcm, channel, 0); 127 err = bcm43xx_radio_selectchannel(bcm, channel, 0);
@@ -131,7 +131,7 @@ static int bcm43xx_wx_set_channelfreq(struct net_device *net_dev,
131 err = 0; 131 err = 0;
132 } 132 }
133out_unlock: 133out_unlock:
134 bcm43xx_unlock_mmio(bcm, flags); 134 bcm43xx_unlock_irqsafe(bcm, flags);
135 135
136 return err; 136 return err;
137} 137}
@@ -147,11 +147,10 @@ static int bcm43xx_wx_get_channelfreq(struct net_device *net_dev,
147 int err = -ENODEV; 147 int err = -ENODEV;
148 u16 channel; 148 u16 channel;
149 149
150 bcm43xx_lock(bcm, flags); 150 bcm43xx_lock_irqsafe(bcm, flags);
151 radio = bcm43xx_current_radio(bcm); 151 radio = bcm43xx_current_radio(bcm);
152 channel = radio->channel; 152 channel = radio->channel;
153 if (channel == 0xFF) { 153 if (channel == 0xFF) {
154 assert(!bcm->initialized);
155 channel = radio->initial_channel; 154 channel = radio->initial_channel;
156 if (channel == 0xFF) 155 if (channel == 0xFF)
157 goto out_unlock; 156 goto out_unlock;
@@ -163,7 +162,7 @@ static int bcm43xx_wx_get_channelfreq(struct net_device *net_dev,
163 162
164 err = 0; 163 err = 0;
165out_unlock: 164out_unlock:
166 bcm43xx_unlock(bcm, flags); 165 bcm43xx_unlock_irqsafe(bcm, flags);
167 166
168 return err; 167 return err;
169} 168}
@@ -181,13 +180,13 @@ static int bcm43xx_wx_set_mode(struct net_device *net_dev,
181 if (mode == IW_MODE_AUTO) 180 if (mode == IW_MODE_AUTO)
182 mode = BCM43xx_INITIAL_IWMODE; 181 mode = BCM43xx_INITIAL_IWMODE;
183 182
184 bcm43xx_lock_mmio(bcm, flags); 183 bcm43xx_lock_irqsafe(bcm, flags);
185 if (bcm->initialized) { 184 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
186 if (bcm->ieee->iw_mode != mode) 185 if (bcm->ieee->iw_mode != mode)
187 bcm43xx_set_iwmode(bcm, mode); 186 bcm43xx_set_iwmode(bcm, mode);
188 } else 187 } else
189 bcm->ieee->iw_mode = mode; 188 bcm->ieee->iw_mode = mode;
190 bcm43xx_unlock_mmio(bcm, flags); 189 bcm43xx_unlock_irqsafe(bcm, flags);
191 190
192 return 0; 191 return 0;
193} 192}
@@ -200,9 +199,9 @@ static int bcm43xx_wx_get_mode(struct net_device *net_dev,
200 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 199 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
201 unsigned long flags; 200 unsigned long flags;
202 201
203 bcm43xx_lock(bcm, flags); 202 bcm43xx_lock_irqsafe(bcm, flags);
204 data->mode = bcm->ieee->iw_mode; 203 data->mode = bcm->ieee->iw_mode;
205 bcm43xx_unlock(bcm, flags); 204 bcm43xx_unlock_irqsafe(bcm, flags);
206 205
207 return 0; 206 return 0;
208} 207}
@@ -255,7 +254,7 @@ static int bcm43xx_wx_get_rangeparams(struct net_device *net_dev,
255 IW_ENC_CAPA_CIPHER_TKIP | 254 IW_ENC_CAPA_CIPHER_TKIP |
256 IW_ENC_CAPA_CIPHER_CCMP; 255 IW_ENC_CAPA_CIPHER_CCMP;
257 256
258 bcm43xx_lock(bcm, flags); 257 bcm43xx_lock_irqsafe(bcm, flags);
259 phy = bcm43xx_current_phy(bcm); 258 phy = bcm43xx_current_phy(bcm);
260 259
261 range->num_bitrates = 0; 260 range->num_bitrates = 0;
@@ -302,7 +301,7 @@ static int bcm43xx_wx_get_rangeparams(struct net_device *net_dev,
302 } 301 }
303 range->num_frequency = j; 302 range->num_frequency = j;
304 303
305 bcm43xx_unlock(bcm, flags); 304 bcm43xx_unlock_irqsafe(bcm, flags);
306 305
307 return 0; 306 return 0;
308} 307}
@@ -313,14 +312,13 @@ static int bcm43xx_wx_set_nick(struct net_device *net_dev,
313 char *extra) 312 char *extra)
314{ 313{
315 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 314 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
316 unsigned long flags;
317 size_t len; 315 size_t len;
318 316
319 bcm43xx_lock(bcm, flags); 317 bcm43xx_lock_noirq(bcm);
320 len = min((size_t)data->data.length, (size_t)IW_ESSID_MAX_SIZE); 318 len = min((size_t)data->data.length, (size_t)IW_ESSID_MAX_SIZE);
321 memcpy(bcm->nick, extra, len); 319 memcpy(bcm->nick, extra, len);
322 bcm->nick[len] = '\0'; 320 bcm->nick[len] = '\0';
323 bcm43xx_unlock(bcm, flags); 321 bcm43xx_unlock_noirq(bcm);
324 322
325 return 0; 323 return 0;
326} 324}
@@ -331,15 +329,14 @@ static int bcm43xx_wx_get_nick(struct net_device *net_dev,
331 char *extra) 329 char *extra)
332{ 330{
333 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 331 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
334 unsigned long flags;
335 size_t len; 332 size_t len;
336 333
337 bcm43xx_lock(bcm, flags); 334 bcm43xx_lock_noirq(bcm);
338 len = strlen(bcm->nick) + 1; 335 len = strlen(bcm->nick) + 1;
339 memcpy(extra, bcm->nick, len); 336 memcpy(extra, bcm->nick, len);
340 data->data.length = (__u16)len; 337 data->data.length = (__u16)len;
341 data->data.flags = 1; 338 data->data.flags = 1;
342 bcm43xx_unlock(bcm, flags); 339 bcm43xx_unlock_noirq(bcm);
343 340
344 return 0; 341 return 0;
345} 342}
@@ -353,7 +350,7 @@ static int bcm43xx_wx_set_rts(struct net_device *net_dev,
353 unsigned long flags; 350 unsigned long flags;
354 int err = -EINVAL; 351 int err = -EINVAL;
355 352
356 bcm43xx_lock(bcm, flags); 353 bcm43xx_lock_irqsafe(bcm, flags);
357 if (data->rts.disabled) { 354 if (data->rts.disabled) {
358 bcm->rts_threshold = BCM43xx_MAX_RTS_THRESHOLD; 355 bcm->rts_threshold = BCM43xx_MAX_RTS_THRESHOLD;
359 err = 0; 356 err = 0;
@@ -364,7 +361,7 @@ static int bcm43xx_wx_set_rts(struct net_device *net_dev,
364 err = 0; 361 err = 0;
365 } 362 }
366 } 363 }
367 bcm43xx_unlock(bcm, flags); 364 bcm43xx_unlock_irqsafe(bcm, flags);
368 365
369 return err; 366 return err;
370} 367}
@@ -377,11 +374,11 @@ static int bcm43xx_wx_get_rts(struct net_device *net_dev,
377 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 374 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
378 unsigned long flags; 375 unsigned long flags;
379 376
380 bcm43xx_lock(bcm, flags); 377 bcm43xx_lock_irqsafe(bcm, flags);
381 data->rts.value = bcm->rts_threshold; 378 data->rts.value = bcm->rts_threshold;
382 data->rts.fixed = 0; 379 data->rts.fixed = 0;
383 data->rts.disabled = (bcm->rts_threshold == BCM43xx_MAX_RTS_THRESHOLD); 380 data->rts.disabled = (bcm->rts_threshold == BCM43xx_MAX_RTS_THRESHOLD);
384 bcm43xx_unlock(bcm, flags); 381 bcm43xx_unlock_irqsafe(bcm, flags);
385 382
386 return 0; 383 return 0;
387} 384}
@@ -395,7 +392,7 @@ static int bcm43xx_wx_set_frag(struct net_device *net_dev,
395 unsigned long flags; 392 unsigned long flags;
396 int err = -EINVAL; 393 int err = -EINVAL;
397 394
398 bcm43xx_lock(bcm, flags); 395 bcm43xx_lock_irqsafe(bcm, flags);
399 if (data->frag.disabled) { 396 if (data->frag.disabled) {
400 bcm->ieee->fts = MAX_FRAG_THRESHOLD; 397 bcm->ieee->fts = MAX_FRAG_THRESHOLD;
401 err = 0; 398 err = 0;
@@ -406,7 +403,7 @@ static int bcm43xx_wx_set_frag(struct net_device *net_dev,
406 err = 0; 403 err = 0;
407 } 404 }
408 } 405 }
409 bcm43xx_unlock(bcm, flags); 406 bcm43xx_unlock_irqsafe(bcm, flags);
410 407
411 return err; 408 return err;
412} 409}
@@ -419,11 +416,11 @@ static int bcm43xx_wx_get_frag(struct net_device *net_dev,
419 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 416 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
420 unsigned long flags; 417 unsigned long flags;
421 418
422 bcm43xx_lock(bcm, flags); 419 bcm43xx_lock_irqsafe(bcm, flags);
423 data->frag.value = bcm->ieee->fts; 420 data->frag.value = bcm->ieee->fts;
424 data->frag.fixed = 0; 421 data->frag.fixed = 0;
425 data->frag.disabled = (bcm->ieee->fts == MAX_FRAG_THRESHOLD); 422 data->frag.disabled = (bcm->ieee->fts == MAX_FRAG_THRESHOLD);
426 bcm43xx_unlock(bcm, flags); 423 bcm43xx_unlock_irqsafe(bcm, flags);
427 424
428 return 0; 425 return 0;
429} 426}
@@ -445,8 +442,8 @@ static int bcm43xx_wx_set_xmitpower(struct net_device *net_dev,
445 return -EOPNOTSUPP; 442 return -EOPNOTSUPP;
446 } 443 }
447 444
448 bcm43xx_lock_mmio(bcm, flags); 445 bcm43xx_lock_irqsafe(bcm, flags);
449 if (!bcm->initialized) 446 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)
450 goto out_unlock; 447 goto out_unlock;
451 radio = bcm43xx_current_radio(bcm); 448 radio = bcm43xx_current_radio(bcm);
452 phy = bcm43xx_current_phy(bcm); 449 phy = bcm43xx_current_phy(bcm);
@@ -469,7 +466,7 @@ static int bcm43xx_wx_set_xmitpower(struct net_device *net_dev,
469 err = 0; 466 err = 0;
470 467
471out_unlock: 468out_unlock:
472 bcm43xx_unlock_mmio(bcm, flags); 469 bcm43xx_unlock_irqsafe(bcm, flags);
473 470
474 return err; 471 return err;
475} 472}
@@ -484,8 +481,8 @@ static int bcm43xx_wx_get_xmitpower(struct net_device *net_dev,
484 unsigned long flags; 481 unsigned long flags;
485 int err = -ENODEV; 482 int err = -ENODEV;
486 483
487 bcm43xx_lock(bcm, flags); 484 bcm43xx_lock_irqsafe(bcm, flags);
488 if (!bcm->initialized) 485 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)
489 goto out_unlock; 486 goto out_unlock;
490 radio = bcm43xx_current_radio(bcm); 487 radio = bcm43xx_current_radio(bcm);
491 /* desired dBm value is in Q5.2 */ 488 /* desired dBm value is in Q5.2 */
@@ -496,7 +493,7 @@ static int bcm43xx_wx_get_xmitpower(struct net_device *net_dev,
496 493
497 err = 0; 494 err = 0;
498out_unlock: 495out_unlock:
499 bcm43xx_unlock(bcm, flags); 496 bcm43xx_unlock_irqsafe(bcm, flags);
500 497
501 return err; 498 return err;
502} 499}
@@ -583,8 +580,8 @@ static int bcm43xx_wx_set_interfmode(struct net_device *net_dev,
583 return -EINVAL; 580 return -EINVAL;
584 } 581 }
585 582
586 bcm43xx_lock_mmio(bcm, flags); 583 bcm43xx_lock_irqsafe(bcm, flags);
587 if (bcm->initialized) { 584 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
588 err = bcm43xx_radio_set_interference_mitigation(bcm, mode); 585 err = bcm43xx_radio_set_interference_mitigation(bcm, mode);
589 if (err) { 586 if (err) {
590 printk(KERN_ERR PFX "Interference Mitigation not " 587 printk(KERN_ERR PFX "Interference Mitigation not "
@@ -598,7 +595,7 @@ static int bcm43xx_wx_set_interfmode(struct net_device *net_dev,
598 } else 595 } else
599 bcm43xx_current_radio(bcm)->interfmode = mode; 596 bcm43xx_current_radio(bcm)->interfmode = mode;
600 } 597 }
601 bcm43xx_unlock_mmio(bcm, flags); 598 bcm43xx_unlock_irqsafe(bcm, flags);
602 599
603 return err; 600 return err;
604} 601}
@@ -612,9 +609,9 @@ static int bcm43xx_wx_get_interfmode(struct net_device *net_dev,
612 unsigned long flags; 609 unsigned long flags;
613 int mode; 610 int mode;
614 611
615 bcm43xx_lock(bcm, flags); 612 bcm43xx_lock_irqsafe(bcm, flags);
616 mode = bcm43xx_current_radio(bcm)->interfmode; 613 mode = bcm43xx_current_radio(bcm)->interfmode;
617 bcm43xx_unlock(bcm, flags); 614 bcm43xx_unlock_irqsafe(bcm, flags);
618 615
619 switch (mode) { 616 switch (mode) {
620 case BCM43xx_RADIO_INTERFMODE_NONE: 617 case BCM43xx_RADIO_INTERFMODE_NONE:
@@ -644,9 +641,9 @@ static int bcm43xx_wx_set_shortpreamble(struct net_device *net_dev,
644 int on; 641 int on;
645 642
646 on = *((int *)extra); 643 on = *((int *)extra);
647 bcm43xx_lock(bcm, flags); 644 bcm43xx_lock_irqsafe(bcm, flags);
648 bcm->short_preamble = !!on; 645 bcm->short_preamble = !!on;
649 bcm43xx_unlock(bcm, flags); 646 bcm43xx_unlock_irqsafe(bcm, flags);
650 647
651 return 0; 648 return 0;
652} 649}
@@ -660,9 +657,9 @@ static int bcm43xx_wx_get_shortpreamble(struct net_device *net_dev,
660 unsigned long flags; 657 unsigned long flags;
661 int on; 658 int on;
662 659
663 bcm43xx_lock(bcm, flags); 660 bcm43xx_lock_irqsafe(bcm, flags);
664 on = bcm->short_preamble; 661 on = bcm->short_preamble;
665 bcm43xx_unlock(bcm, flags); 662 bcm43xx_unlock_irqsafe(bcm, flags);
666 663
667 if (on) 664 if (on)
668 strncpy(extra, "1 (Short Preamble enabled)", MAX_WX_STRING); 665 strncpy(extra, "1 (Short Preamble enabled)", MAX_WX_STRING);
@@ -684,11 +681,11 @@ static int bcm43xx_wx_set_swencryption(struct net_device *net_dev,
684 681
685 on = *((int *)extra); 682 on = *((int *)extra);
686 683
687 bcm43xx_lock(bcm, flags); 684 bcm43xx_lock_irqsafe(bcm, flags);
688 bcm->ieee->host_encrypt = !!on; 685 bcm->ieee->host_encrypt = !!on;
689 bcm->ieee->host_decrypt = !!on; 686 bcm->ieee->host_decrypt = !!on;
690 bcm->ieee->host_build_iv = !on; 687 bcm->ieee->host_build_iv = !on;
691 bcm43xx_unlock(bcm, flags); 688 bcm43xx_unlock_irqsafe(bcm, flags);
692 689
693 return 0; 690 return 0;
694} 691}
@@ -702,9 +699,9 @@ static int bcm43xx_wx_get_swencryption(struct net_device *net_dev,
702 unsigned long flags; 699 unsigned long flags;
703 int on; 700 int on;
704 701
705 bcm43xx_lock(bcm, flags); 702 bcm43xx_lock_irqsafe(bcm, flags);
706 on = bcm->ieee->host_encrypt; 703 on = bcm->ieee->host_encrypt;
707 bcm43xx_unlock(bcm, flags); 704 bcm43xx_unlock_irqsafe(bcm, flags);
708 705
709 if (on) 706 if (on)
710 strncpy(extra, "1 (SW encryption enabled) ", MAX_WX_STRING); 707 strncpy(extra, "1 (SW encryption enabled) ", MAX_WX_STRING);
@@ -767,11 +764,11 @@ static int bcm43xx_wx_sprom_read(struct net_device *net_dev,
767 if (!sprom) 764 if (!sprom)
768 goto out; 765 goto out;
769 766
770 bcm43xx_lock_mmio(bcm, flags); 767 bcm43xx_lock_irqsafe(bcm, flags);
771 err = -ENODEV; 768 err = -ENODEV;
772 if (bcm->initialized) 769 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)
773 err = bcm43xx_sprom_read(bcm, sprom); 770 err = bcm43xx_sprom_read(bcm, sprom);
774 bcm43xx_unlock_mmio(bcm, flags); 771 bcm43xx_unlock_irqsafe(bcm, flags);
775 if (!err) 772 if (!err)
776 data->data.length = sprom2hex(sprom, extra); 773 data->data.length = sprom2hex(sprom, extra);
777 kfree(sprom); 774 kfree(sprom);
@@ -812,11 +809,11 @@ static int bcm43xx_wx_sprom_write(struct net_device *net_dev,
812 if (err) 809 if (err)
813 goto out_kfree; 810 goto out_kfree;
814 811
815 bcm43xx_lock_mmio(bcm, flags); 812 bcm43xx_lock_irqsafe(bcm, flags);
816 err = -ENODEV; 813 err = -ENODEV;
817 if (bcm->initialized) 814 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)
818 err = bcm43xx_sprom_write(bcm, sprom); 815 err = bcm43xx_sprom_write(bcm, sprom);
819 bcm43xx_unlock_mmio(bcm, flags); 816 bcm43xx_unlock_irqsafe(bcm, flags);
820out_kfree: 817out_kfree:
821 kfree(sprom); 818 kfree(sprom);
822out: 819out:
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 39f82f219749..081a8999666e 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -533,7 +533,7 @@ static inline void ipw_clear_bit(struct ipw_priv *priv, u32 reg, u32 mask)
533 ipw_write32(priv, reg, ipw_read32(priv, reg) & ~mask); 533 ipw_write32(priv, reg, ipw_read32(priv, reg) & ~mask);
534} 534}
535 535
536static inline void ipw_enable_interrupts(struct ipw_priv *priv) 536static inline void __ipw_enable_interrupts(struct ipw_priv *priv)
537{ 537{
538 if (priv->status & STATUS_INT_ENABLED) 538 if (priv->status & STATUS_INT_ENABLED)
539 return; 539 return;
@@ -541,7 +541,7 @@ static inline void ipw_enable_interrupts(struct ipw_priv *priv)
541 ipw_write32(priv, IPW_INTA_MASK_R, IPW_INTA_MASK_ALL); 541 ipw_write32(priv, IPW_INTA_MASK_R, IPW_INTA_MASK_ALL);
542} 542}
543 543
544static inline void ipw_disable_interrupts(struct ipw_priv *priv) 544static inline void __ipw_disable_interrupts(struct ipw_priv *priv)
545{ 545{
546 if (!(priv->status & STATUS_INT_ENABLED)) 546 if (!(priv->status & STATUS_INT_ENABLED))
547 return; 547 return;
@@ -549,6 +549,24 @@ static inline void ipw_disable_interrupts(struct ipw_priv *priv)
549 ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL); 549 ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);
550} 550}
551 551
552static inline void ipw_enable_interrupts(struct ipw_priv *priv)
553{
554 unsigned long flags;
555
556 spin_lock_irqsave(&priv->irq_lock, flags);
557 __ipw_enable_interrupts(priv);
558 spin_unlock_irqrestore(&priv->irq_lock, flags);
559}
560
561static inline void ipw_disable_interrupts(struct ipw_priv *priv)
562{
563 unsigned long flags;
564
565 spin_lock_irqsave(&priv->irq_lock, flags);
566 __ipw_disable_interrupts(priv);
567 spin_unlock_irqrestore(&priv->irq_lock, flags);
568}
569
552#ifdef CONFIG_IPW2200_DEBUG 570#ifdef CONFIG_IPW2200_DEBUG
553static char *ipw_error_desc(u32 val) 571static char *ipw_error_desc(u32 val)
554{ 572{
@@ -1856,7 +1874,7 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
1856 unsigned long flags; 1874 unsigned long flags;
1857 int rc = 0; 1875 int rc = 0;
1858 1876
1859 spin_lock_irqsave(&priv->lock, flags); 1877 spin_lock_irqsave(&priv->irq_lock, flags);
1860 1878
1861 inta = ipw_read32(priv, IPW_INTA_RW); 1879 inta = ipw_read32(priv, IPW_INTA_RW);
1862 inta_mask = ipw_read32(priv, IPW_INTA_MASK_R); 1880 inta_mask = ipw_read32(priv, IPW_INTA_MASK_R);
@@ -1865,6 +1883,10 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
1865 /* Add any cached INTA values that need to be handled */ 1883 /* Add any cached INTA values that need to be handled */
1866 inta |= priv->isr_inta; 1884 inta |= priv->isr_inta;
1867 1885
1886 spin_unlock_irqrestore(&priv->irq_lock, flags);
1887
1888 spin_lock_irqsave(&priv->lock, flags);
1889
1868 /* handle all the justifications for the interrupt */ 1890 /* handle all the justifications for the interrupt */
1869 if (inta & IPW_INTA_BIT_RX_TRANSFER) { 1891 if (inta & IPW_INTA_BIT_RX_TRANSFER) {
1870 ipw_rx(priv); 1892 ipw_rx(priv);
@@ -1993,10 +2015,10 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
1993 IPW_ERROR("Unhandled INTA bits 0x%08x\n", inta & ~handled); 2015 IPW_ERROR("Unhandled INTA bits 0x%08x\n", inta & ~handled);
1994 } 2016 }
1995 2017
2018 spin_unlock_irqrestore(&priv->lock, flags);
2019
1996 /* enable all interrupts */ 2020 /* enable all interrupts */
1997 ipw_enable_interrupts(priv); 2021 ipw_enable_interrupts(priv);
1998
1999 spin_unlock_irqrestore(&priv->lock, flags);
2000} 2022}
2001 2023
2002#define IPW_CMD(x) case IPW_CMD_ ## x : return #x 2024#define IPW_CMD(x) case IPW_CMD_ ## x : return #x
@@ -10460,7 +10482,7 @@ static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs)
10460 if (!priv) 10482 if (!priv)
10461 return IRQ_NONE; 10483 return IRQ_NONE;
10462 10484
10463 spin_lock(&priv->lock); 10485 spin_lock(&priv->irq_lock);
10464 10486
10465 if (!(priv->status & STATUS_INT_ENABLED)) { 10487 if (!(priv->status & STATUS_INT_ENABLED)) {
10466 /* Shared IRQ */ 10488 /* Shared IRQ */
@@ -10482,7 +10504,7 @@ static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs)
10482 } 10504 }
10483 10505
10484 /* tell the device to stop sending interrupts */ 10506 /* tell the device to stop sending interrupts */
10485 ipw_disable_interrupts(priv); 10507 __ipw_disable_interrupts(priv);
10486 10508
10487 /* ack current interrupts */ 10509 /* ack current interrupts */
10488 inta &= (IPW_INTA_MASK_ALL & inta_mask); 10510 inta &= (IPW_INTA_MASK_ALL & inta_mask);
@@ -10493,11 +10515,11 @@ static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs)
10493 10515
10494 tasklet_schedule(&priv->irq_tasklet); 10516 tasklet_schedule(&priv->irq_tasklet);
10495 10517
10496 spin_unlock(&priv->lock); 10518 spin_unlock(&priv->irq_lock);
10497 10519
10498 return IRQ_HANDLED; 10520 return IRQ_HANDLED;
10499 none: 10521 none:
10500 spin_unlock(&priv->lock); 10522 spin_unlock(&priv->irq_lock);
10501 return IRQ_NONE; 10523 return IRQ_NONE;
10502} 10524}
10503 10525
@@ -11477,6 +11499,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
11477#ifdef CONFIG_IPW2200_DEBUG 11499#ifdef CONFIG_IPW2200_DEBUG
11478 ipw_debug_level = debug; 11500 ipw_debug_level = debug;
11479#endif 11501#endif
11502 spin_lock_init(&priv->irq_lock);
11480 spin_lock_init(&priv->lock); 11503 spin_lock_init(&priv->lock);
11481 for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++) 11504 for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++)
11482 INIT_LIST_HEAD(&priv->ibss_mac_hash[i]); 11505 INIT_LIST_HEAD(&priv->ibss_mac_hash[i]);
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
index 6044c0be2c80..ea12ad66b8e8 100644
--- a/drivers/net/wireless/ipw2200.h
+++ b/drivers/net/wireless/ipw2200.h
@@ -1173,6 +1173,7 @@ struct ipw_priv {
1173 struct ieee80211_device *ieee; 1173 struct ieee80211_device *ieee;
1174 1174
1175 spinlock_t lock; 1175 spinlock_t lock;
1176 spinlock_t irq_lock;
1176 struct mutex mutex; 1177 struct mutex mutex;
1177 1178
1178 /* basic pci-network driver stuff */ 1179 /* basic pci-network driver stuff */
diff --git a/drivers/net/wireless/wavelan.c b/drivers/net/wireless/wavelan.c
index dade4b903579..5b69befdab74 100644
--- a/drivers/net/wireless/wavelan.c
+++ b/drivers/net/wireless/wavelan.c
@@ -1695,8 +1695,8 @@ static int wv_frequency_list(unsigned long ioaddr, /* I/O port of the card */
1695 /* Look in the table if the frequency is allowed */ 1695 /* Look in the table if the frequency is allowed */
1696 if (table[9 - (freq / 16)] & (1 << (freq % 16))) { 1696 if (table[9 - (freq / 16)] & (1 << (freq % 16))) {
1697 /* Compute approximate channel number */ 1697 /* Compute approximate channel number */
1698 while ((((channel_bands[c] >> 1) - 24) < freq) && 1698 while ((c < NELS(channel_bands)) &&
1699 (c < NELS(channel_bands))) 1699 (((channel_bands[c] >> 1) - 24) < freq))
1700 c++; 1700 c++;
1701 list[i].i = c; /* Set the list index */ 1701 list[i].i = c; /* Set the list index */
1702 1702
@@ -2903,6 +2903,7 @@ static int wavelan_packet_xmit(struct sk_buff *skb, struct net_device * dev)
2903{ 2903{
2904 net_local *lp = (net_local *) dev->priv; 2904 net_local *lp = (net_local *) dev->priv;
2905 unsigned long flags; 2905 unsigned long flags;
2906 char data[ETH_ZLEN];
2906 2907
2907#ifdef DEBUG_TX_TRACE 2908#ifdef DEBUG_TX_TRACE
2908 printk(KERN_DEBUG "%s: ->wavelan_packet_xmit(0x%X)\n", dev->name, 2909 printk(KERN_DEBUG "%s: ->wavelan_packet_xmit(0x%X)\n", dev->name,
@@ -2937,15 +2938,16 @@ static int wavelan_packet_xmit(struct sk_buff *skb, struct net_device * dev)
2937 * able to detect collisions, therefore in theory we don't really 2938 * able to detect collisions, therefore in theory we don't really
2938 * need to pad. Jean II */ 2939 * need to pad. Jean II */
2939 if (skb->len < ETH_ZLEN) { 2940 if (skb->len < ETH_ZLEN) {
2940 skb = skb_padto(skb, ETH_ZLEN); 2941 memset(data, 0, ETH_ZLEN);
2941 if (skb == NULL) 2942 memcpy(data, skb->data, skb->len);
2942 return 0; 2943 /* Write packet on the card */
2944 if(wv_packet_write(dev, data, ETH_ZLEN))
2945 return 1; /* We failed */
2943 } 2946 }
2944 2947 else if(wv_packet_write(dev, skb->data, skb->len))
2945 /* Write packet on the card */
2946 if(wv_packet_write(dev, skb->data, skb->len))
2947 return 1; /* We failed */ 2948 return 1; /* We failed */
2948 2949
2950
2949 dev_kfree_skb(skb); 2951 dev_kfree_skb(skb);
2950 2952
2951#ifdef DEBUG_TX_TRACE 2953#ifdef DEBUG_TX_TRACE