Merge branch 'from-linus'
authorJohn W. Linville <linville@tuxdriver.com>
Tue, 28 Feb 2006 01:12:23 +0000 (20:12 -0500)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 28 Feb 2006 01:12:23 +0000 (20:12 -0500)
1  2 
Documentation/feature-removal-schedule.txt
drivers/net/Kconfig
drivers/net/wireless/ipw2200.c

index 79f0ed9f60def897f53bbd5e7ab9f43e925ac570,be5ae600f5337dbb14daa8d4cace110486e14f79..975e14e150ae3d7a8da2817895c332d22220f957
@@@ -151,13 -151,6 +151,13 @@@ Who:     Ralf Baechle <ralf@linux-mips.org
  
  ---------------------------
  
 +What:   eepro100 network driver
 +When:   January 2007
 +Why:    replaced by the e100 driver
 +Who:    Adrian Bunk <bunk@stusta.de>
 +
 +---------------------------
 +
  What: Legacy /proc/pci interface (PCI_LEGACY_PROC)
  When: March 2006
  Why:  deprecated since 2.5.53 in favor of lspci(8)
@@@ -178,3 -171,12 +178,12 @@@ Why:     The ISA interface is faster and sh
        probing is also known to cause trouble in at least one case (see
        bug #5889.)
  Who:  Jean Delvare <khali@linux-fr.org>
+ ---------------------------
+ What: mount/umount uevents
+ When: February 2007
+ Why:  These events are not correct, and do not properly let userspace know
+       when a file system has been mounted or unmounted.  Userspace should
+       poll the /proc/mounts file instead to detect this properly.
+ Who:  Greg Kroah-Hartman <gregkh@suse.de>
diff --combined drivers/net/Kconfig
index 2610cedd55c7dd79921bc7da5898d6ce624ea329,e45a8f9597194810190d3c937f99deb854239f42..840bfed312f6bd1059ecfa89850386e62200fa55
@@@ -66,7 -66,7 +66,7 @@@ config BONDIN
          'Trunking' by Sun, 802.3ad by the IEEE, and 'Bonding' in Linux.
  
          The driver supports multiple bonding modes to allow for both high
 -        perfomance and high availability operation.
 +        performance and high availability operation.
  
          Refer to <file:Documentation/networking/bonding.txt> for more
          information.
@@@ -698,8 -698,8 +698,8 @@@ config VORTE
        depends on NET_VENDOR_3COM && (PCI || EISA)
        select MII
        ---help---
 -        This option enables driver support for a large number of 10mbps and
 -        10/100mbps EISA, PCI and PCMCIA 3Com network cards:
 +        This option enables driver support for a large number of 10Mbps and
 +        10/100Mbps EISA, PCI and PCMCIA 3Com network cards:
  
          "Vortex"    (Fast EtherLink 3c590/3c592/3c595/3c597) EISA and PCI
          "Boomerang" (EtherLink XL 3c900 or 3c905)            PCI
@@@ -1021,7 -1021,7 +1021,7 @@@ config EEXPRESS_PR
        depends on NET_ISA
        ---help---
          If you have a network (Ethernet) card of this type, say Y. This
 -        driver supports intel i82595{FX,TX} based boards. Note however
 +        driver supports Intel i82595{FX,TX} based boards. Note however
          that the EtherExpress PRO/100 Ethernet card has its own separate
          driver.  Please read the Ethernet-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>.
@@@ -1207,7 -1207,7 +1207,7 @@@ config IBM_EMAC_RX_SKB_HEADROO
        help
          Additional receive skb headroom. Note, that driver
          will always reserve at least 2 bytes to make IP header
 -        aligned, so usualy there is no need to add any additional
 +        aligned, so usually there is no need to add any additional
          headroom.
          
          If unsure, set to 0.
@@@ -1933,7 -1933,7 +1933,7 @@@ config MYRI_SBU
          will be called myri_sbus.  This is recommended.
  
  config NS83820
 -      tristate "National Semiconduct DP83820 support"
 +      tristate "National Semiconductor DP83820 support"
        depends on PCI
        help
          This is a driver for the National Semiconductor DP83820 series
@@@ -2020,8 -2020,8 +2020,8 @@@ config SIS19
          will be called sis190.  This is recommended.
  
  config SKGE
-       tristate "New SysKonnect GigaEthernet support (EXPERIMENTAL)"
-       depends on PCI && EXPERIMENTAL
+       tristate "New SysKonnect GigaEthernet support"
+       depends on PCI
        select CRC32
        ---help---
          This driver support the Marvell Yukon or SysKonnect SK-98xx/SK-95xx
@@@ -2082,7 -2082,6 +2082,6 @@@ config SK98LI
            - Allied Telesyn AT-2971SX Gigabit Ethernet Adapter
            - Allied Telesyn AT-2971T Gigabit Ethernet Adapter
            - Belkin Gigabit Desktop Card 10/100/1000Base-T Adapter, Copper RJ-45
-           - DGE-530T Gigabit Ethernet Adapter
            - EG1032 v2 Instant Gigabit Network Adapter
            - EG1064 v2 Instant Gigabit Network Adapter
            - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Abit)
@@@ -2514,7 -2513,7 +2513,7 @@@ config PPP_FILTE
          Say Y here if you want to be able to filter the packets passing over
          PPP interfaces.  This allows you to control which packets count as
          activity (i.e. which packets will reset the idle timer or bring up
 -        a demand-dialled link) and which packets are to be dropped entirely.
 +        a demand-dialed link) and which packets are to be dropped entirely.
          You need to say Y here if you wish to use the pass-filter and
          active-filter options to pppd.
  
@@@ -2702,8 -2701,8 +2701,8 @@@ config SHAPE
          <file:Documentation/networking/shaper.txt> for more information.
  
          An alternative to this traffic shaper is the experimental
 -        Class-Based Queueing (CBQ) scheduling support which you get if you
 -        say Y to "QoS and/or fair queueing" above.
 +        Class-Based Queuing (CBQ) scheduling support which you get if you
 +        say Y to "QoS and/or fair queuing" above.
  
          To compile this driver as a module, choose M here: the module
          will be called shaper.  If unsure, say N.
index 30b13a6e6fd97eb8456d1e023119bab4f484ea4a,287676ad80df824b2b13f845cb26ffb61f4d8d86..ed37141319ea9b8ecc64c8834b81b471198f0612
@@@ -33,7 -33,7 +33,7 @@@
  #include "ipw2200.h"
  #include <linux/version.h>
  
 -#define IPW2200_VERSION "git-1.0.8"
 +#define IPW2200_VERSION "git-1.0.10"
  #define DRV_DESCRIPTION       "Intel(R) PRO/Wireless 2200/2915 Network Driver"
  #define DRV_COPYRIGHT "Copyright(c) 2003-2005 Intel Corporation"
  #define DRV_VERSION     IPW2200_VERSION
@@@ -55,9 -55,7 +55,9 @@@ static int associate = 1
  static int auto_create = 1;
  static int led = 0;
  static int disable = 0;
 -static int hwcrypto = 1;
 +static int bt_coexist = 0;
 +static int hwcrypto = 0;
 +static int roaming = 1;
  static const char ipw_modes[] = {
        'a', 'b', 'g', '?'
  };
@@@ -229,15 -227,12 +229,15 @@@ static int snprintk_buf(u8 * output, si
        return total;
  }
  
 +/* alias for 32-bit indirect read (for SRAM/reg above 4K), with debug wrapper */
  static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg);
  #define ipw_read_reg32(a, b) _ipw_read_reg32(a, b)
  
 +/* alias for 8-bit indirect read (for SRAM/reg above 4K), with debug wrapper */
  static u8 _ipw_read_reg8(struct ipw_priv *ipw, u32 reg);
  #define ipw_read_reg8(a, b) _ipw_read_reg8(a, b)
  
 +/* 8-bit indirect write (for SRAM/reg above 4K), with debug wrapper */
  static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value);
  static inline void ipw_write_reg8(struct ipw_priv *a, u32 b, u8 c)
  {
        _ipw_write_reg8(a, b, c);
  }
  
 +/* 16-bit indirect write (for SRAM/reg above 4K), with debug wrapper */
  static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value);
  static inline void ipw_write_reg16(struct ipw_priv *a, u32 b, u16 c)
  {
        _ipw_write_reg16(a, b, c);
  }
  
 +/* 32-bit indirect write (for SRAM/reg above 4K), with debug wrapper */
  static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value);
  static inline void ipw_write_reg32(struct ipw_priv *a, u32 b, u32 c)
  {
        _ipw_write_reg32(a, b, c);
  }
  
 +/* 8-bit direct write (low 4K) */
  #define _ipw_write8(ipw, ofs, val) writeb((val), (ipw)->hw_base + (ofs))
 +
 +/* 8-bit direct write (for low 4K of SRAM/regs), with debug wrapper */
  #define ipw_write8(ipw, ofs, val) \
   IPW_DEBUG_IO("%s %d: write_direct8(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
   _ipw_write8(ipw, ofs, val)
  
 +/* 16-bit direct write (low 4K) */
  #define _ipw_write16(ipw, ofs, val) writew((val), (ipw)->hw_base + (ofs))
 +
 +/* 16-bit direct write (for low 4K of SRAM/regs), with debug wrapper */
  #define ipw_write16(ipw, ofs, val) \
   IPW_DEBUG_IO("%s %d: write_direct16(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
   _ipw_write16(ipw, ofs, val)
  
 +/* 32-bit direct write (low 4K) */
  #define _ipw_write32(ipw, ofs, val) writel((val), (ipw)->hw_base + (ofs))
 +
 +/* 32-bit direct write (for low 4K of SRAM/regs), with debug wrapper */
  #define ipw_write32(ipw, ofs, val) \
   IPW_DEBUG_IO("%s %d: write_direct32(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
   _ipw_write32(ipw, ofs, val)
  
 +/* 8-bit direct read (low 4K) */
  #define _ipw_read8(ipw, ofs) readb((ipw)->hw_base + (ofs))
 +
 +/* 8-bit direct read (low 4K), with debug wrapper */
  static inline u8 __ipw_read8(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
  {
        IPW_DEBUG_IO("%s %d: read_direct8(0x%08X)\n", f, l, (u32) (ofs));
        return _ipw_read8(ipw, ofs);
  }
  
 +/* alias to 8-bit direct read (low 4K of SRAM/regs), with debug wrapper */
  #define ipw_read8(ipw, ofs) __ipw_read8(__FILE__, __LINE__, ipw, ofs)
  
 +/* 16-bit direct read (low 4K) */
  #define _ipw_read16(ipw, ofs) readw((ipw)->hw_base + (ofs))
 +
 +/* 16-bit direct read (low 4K), with debug wrapper */
  static inline u16 __ipw_read16(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
  {
        IPW_DEBUG_IO("%s %d: read_direct16(0x%08X)\n", f, l, (u32) (ofs));
        return _ipw_read16(ipw, ofs);
  }
  
 +/* alias to 16-bit direct read (low 4K of SRAM/regs), with debug wrapper */
  #define ipw_read16(ipw, ofs) __ipw_read16(__FILE__, __LINE__, ipw, ofs)
  
 +/* 32-bit direct read (low 4K) */
  #define _ipw_read32(ipw, ofs) readl((ipw)->hw_base + (ofs))
 +
 +/* 32-bit direct read (low 4K), with debug wrapper */
  static inline u32 __ipw_read32(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
  {
        IPW_DEBUG_IO("%s %d: read_direct32(0x%08X)\n", f, l, (u32) (ofs));
        return _ipw_read32(ipw, ofs);
  }
  
 +/* alias to 32-bit direct read (low 4K of SRAM/regs), with debug wrapper */
  #define ipw_read32(ipw, ofs) __ipw_read32(__FILE__, __LINE__, ipw, ofs)
  
 +/* multi-byte read (above 4K), with debug wrapper */
  static void _ipw_read_indirect(struct ipw_priv *, u32, u8 *, int);
  static inline void __ipw_read_indirect(const char *f, int l,
                                       struct ipw_priv *a, u32 b, u8 * c, int d)
        _ipw_read_indirect(a, b, c, d);
  }
  
 +/* alias to multi-byte read (SRAM/regs above 4K), with debug wrapper */
  #define ipw_read_indirect(a, b, c, d) __ipw_read_indirect(__FILE__, __LINE__, a, b, c, d)
  
 +/* alias to multi-byte read (SRAM/regs above 4K), with debug wrapper */
  static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * data,
                                int num);
  #define ipw_write_indirect(a, b, c, d) \
        IPW_DEBUG_IO("%s %d: write_indirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \
        _ipw_write_indirect(a, b, c, d)
  
 -/* indirect write s */
 +/* 32-bit indirect write (above 4K) */
  static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value)
  {
        IPW_DEBUG_IO(" %p : reg = 0x%8X : value = 0x%8X\n", priv, reg, value);
        _ipw_write32(priv, IPW_INDIRECT_DATA, value);
  }
  
 +/* 8-bit indirect write (above 4K) */
  static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value)
  {
 +      u32 aligned_addr = reg & IPW_INDIRECT_ADDR_MASK;        /* dword align */
 +      u32 dif_len = reg - aligned_addr;
 +
        IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value);
 -      _ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK);
 -      _ipw_write8(priv, IPW_INDIRECT_DATA, value);
 +      _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
 +      _ipw_write8(priv, IPW_INDIRECT_DATA + dif_len, value);
  }
  
 +/* 16-bit indirect write (above 4K) */
  static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value)
  {
 +      u32 aligned_addr = reg & IPW_INDIRECT_ADDR_MASK;        /* dword align */
 +      u32 dif_len = (reg - aligned_addr) & (~0x1ul);
 +
        IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value);
 -      _ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK);
 -      _ipw_write16(priv, IPW_INDIRECT_DATA, value);
 +      _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
 +      _ipw_write16(priv, IPW_INDIRECT_DATA + dif_len, value);
  }
  
 -/* indirect read s */
 -
 +/* 8-bit indirect read (above 4K) */
  static u8 _ipw_read_reg8(struct ipw_priv *priv, u32 reg)
  {
        u32 word;
        return (word >> ((reg & 0x3) * 8)) & 0xff;
  }
  
 +/* 32-bit indirect read (above 4K) */
  static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg)
  {
        u32 value;
        return value;
  }
  
 -/* iterative/auto-increment 32 bit reads and writes */
 +/* General purpose, no alignment requirement, iterative (multi-byte) read, */
 +/*    for area above 1st 4K of SRAM/reg space */
  static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
                               int num)
  {
 -      u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK;
 +      u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK;       /* dword align */
        u32 dif_len = addr - aligned_addr;
        u32 i;
  
                return;
        }
  
 -      /* Read the first nibble byte by byte */
 +      /* Read the first dword (or portion) byte by byte */
        if (unlikely(dif_len)) {
                _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
                /* Start reading at aligned_addr + dif_len */
                aligned_addr += 4;
        }
  
 +      /* Read all of the middle dwords as dwords, with auto-increment */
        _ipw_write32(priv, IPW_AUTOINC_ADDR, aligned_addr);
        for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4)
                *(u32 *) buf = _ipw_read32(priv, IPW_AUTOINC_DATA);
  
 -      /* Copy the last nibble */
 +      /* Read the last dword (or portion) byte by byte */
        if (unlikely(num)) {
                _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
                for (i = 0; num > 0; i++, num--)
        }
  }
  
 +/* General purpose, no alignment requirement, iterative (multi-byte) write, */
 +/*    for area above 1st 4K of SRAM/reg space */
  static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
                                int num)
  {
 -      u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK;
 +      u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK;       /* dword align */
        u32 dif_len = addr - aligned_addr;
        u32 i;
  
                return;
        }
  
 -      /* Write the first nibble byte by byte */
 +      /* Write the first dword (or portion) byte by byte */
        if (unlikely(dif_len)) {
                _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
 -              /* Start reading at aligned_addr + dif_len */
 +              /* Start writing at aligned_addr + dif_len */
                for (i = dif_len; ((i < 4) && (num > 0)); i++, num--, buf++)
                        _ipw_write8(priv, IPW_INDIRECT_DATA + i, *buf);
                aligned_addr += 4;
        }
  
 +      /* Write all of the middle dwords as dwords, with auto-increment */
        _ipw_write32(priv, IPW_AUTOINC_ADDR, aligned_addr);
        for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4)
                _ipw_write32(priv, IPW_AUTOINC_DATA, *(u32 *) buf);
  
 -      /* Copy the last nibble */
 +      /* Write the last dword (or portion) byte by byte */
        if (unlikely(num)) {
                _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
                for (i = 0; num > 0; i++, num--, buf++)
        }
  }
  
 +/* General purpose, no alignment requirement, iterative (multi-byte) write, */
 +/*    for 1st 4K of SRAM/regs space */
  static void ipw_write_direct(struct ipw_priv *priv, u32 addr, void *buf,
                             int num)
  {
        memcpy_toio((priv->hw_base + addr), buf, num);
  }
  
 +/* Set bit(s) in low 4K of SRAM/regs */
  static inline void ipw_set_bit(struct ipw_priv *priv, u32 reg, u32 mask)
  {
        ipw_write32(priv, reg, ipw_read32(priv, reg) | mask);
  }
  
 +/* Clear bit(s) in low 4K of SRAM/regs */
  static inline void ipw_clear_bit(struct ipw_priv *priv, u32 reg, u32 mask)
  {
        ipw_write32(priv, reg, ipw_read32(priv, reg) & ~mask);
@@@ -749,7 -701,7 +749,7 @@@ static void ipw_init_ordinals(struct ip
  
  }
  
 -u32 ipw_register_toggle(u32 reg)
 +static u32 ipw_register_toggle(u32 reg)
  {
        reg &= ~IPW_START_STANDBY;
        if (reg & IPW_GATE_ODMA)
   * - On radio OFF, turn off any LEDs started during radio on
   *
   */
 -#define LD_TIME_LINK_ON 300
 -#define LD_TIME_LINK_OFF 2700
 -#define LD_TIME_ACT_ON 250
 +#define LD_TIME_LINK_ON msecs_to_jiffies(300)
 +#define LD_TIME_LINK_OFF msecs_to_jiffies(2700)
 +#define LD_TIME_ACT_ON msecs_to_jiffies(250)
  
 -void ipw_led_link_on(struct ipw_priv *priv)
 +static void ipw_led_link_on(struct ipw_priv *priv)
  {
        unsigned long flags;
        u32 led;
  static void ipw_bg_led_link_on(void *data)
  {
        struct ipw_priv *priv = data;
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        ipw_led_link_on(data);
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
  }
  
 -void ipw_led_link_off(struct ipw_priv *priv)
 +static void ipw_led_link_off(struct ipw_priv *priv)
  {
        unsigned long flags;
        u32 led;
  static void ipw_bg_led_link_off(void *data)
  {
        struct ipw_priv *priv = data;
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        ipw_led_link_off(data);
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
  }
  
  static void __ipw_led_activity_on(struct ipw_priv *priv)
        }
  }
  
 +#if 0
  void ipw_led_activity_on(struct ipw_priv *priv)
  {
        unsigned long flags;
        __ipw_led_activity_on(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
  }
 +#endif  /*  0  */
  
 -void ipw_led_activity_off(struct ipw_priv *priv)
 +static void ipw_led_activity_off(struct ipw_priv *priv)
  {
        unsigned long flags;
        u32 led;
  static void ipw_bg_led_activity_off(void *data)
  {
        struct ipw_priv *priv = data;
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        ipw_led_activity_off(data);
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
  }
  
 -void ipw_led_band_on(struct ipw_priv *priv)
 +static void ipw_led_band_on(struct ipw_priv *priv)
  {
        unsigned long flags;
        u32 led;
        spin_unlock_irqrestore(&priv->lock, flags);
  }
  
 -void ipw_led_band_off(struct ipw_priv *priv)
 +static void ipw_led_band_off(struct ipw_priv *priv)
  {
        unsigned long flags;
        u32 led;
        spin_unlock_irqrestore(&priv->lock, flags);
  }
  
 -void ipw_led_radio_on(struct ipw_priv *priv)
 +static void ipw_led_radio_on(struct ipw_priv *priv)
  {
        ipw_led_link_on(priv);
  }
  
 -void ipw_led_radio_off(struct ipw_priv *priv)
 +static void ipw_led_radio_off(struct ipw_priv *priv)
  {
        ipw_led_activity_off(priv);
        ipw_led_link_off(priv);
  }
  
 -void ipw_led_link_up(struct ipw_priv *priv)
 +static void ipw_led_link_up(struct ipw_priv *priv)
  {
        /* Set the Link Led on for all nic types */
        ipw_led_link_on(priv);
  }
  
 -void ipw_led_link_down(struct ipw_priv *priv)
 +static void ipw_led_link_down(struct ipw_priv *priv)
  {
        ipw_led_activity_off(priv);
        ipw_led_link_off(priv);
                ipw_led_radio_off(priv);
  }
  
 -void ipw_led_init(struct ipw_priv *priv)
 +static void ipw_led_init(struct ipw_priv *priv)
  {
        priv->nic_type = priv->eeprom[EEPROM_NIC_TYPE];
  
        }
  }
  
 -void ipw_led_shutdown(struct ipw_priv *priv)
 +static void ipw_led_shutdown(struct ipw_priv *priv)
  {
        ipw_led_activity_off(priv);
        ipw_led_link_off(priv);
@@@ -1124,7 -1074,6 +1124,7 @@@ static DRIVER_ATTR(debug_level, S_IWUS
  
  static inline u32 ipw_get_event_log_len(struct ipw_priv *priv)
  {
 +      /* length = 1st dword in log */
        return ipw_read_reg32(priv, ipw_read32(priv, IPW_EVENT_LOG));
  }
  
@@@ -1921,8 -1870,7 +1921,8 @@@ static char *get_cmd_string(u8 cmd
  }
  
  #define HOST_COMPLETE_TIMEOUT HZ
 -static int ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)
 +
 +static int __ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)
  {
        int rc = 0;
        unsigned long flags;
        IPW_DEBUG_HC("%s command (#%d) %d bytes: 0x%08X\n",
                     get_cmd_string(cmd->cmd), cmd->cmd, cmd->len,
                     priv->status);
 -      printk_buf(IPW_DL_HOST_COMMAND, (u8 *) cmd->param, cmd->len);
  
 -      rc = ipw_queue_tx_hcmd(priv, cmd->cmd, &cmd->param, cmd->len, 0);
 +#ifndef DEBUG_CMD_WEP_KEY
 +      if (cmd->cmd == IPW_CMD_WEP_KEY)
 +              IPW_DEBUG_HC("WEP_KEY command masked out for secure.\n");
 +      else
 +#endif
 +              printk_buf(IPW_DL_HOST_COMMAND, (u8 *) cmd->param, cmd->len);
 +
 +      rc = ipw_queue_tx_hcmd(priv, cmd->cmd, cmd->param, cmd->len, 0);
        if (rc) {
                priv->status &= ~STATUS_HCMD_ACTIVE;
                IPW_ERROR("Failed to send %s: Reason %d\n",
        return rc;
  }
  
 -static int ipw_send_host_complete(struct ipw_priv *priv)
 +static int ipw_send_cmd_simple(struct ipw_priv *priv, u8 command)
  {
        struct host_cmd cmd = {
 -              .cmd = IPW_CMD_HOST_COMPLETE,
 -              .len = 0
 +              .cmd = command,
        };
  
 +      return __ipw_send_cmd(priv, &cmd);
 +}
 +
 +static int ipw_send_cmd_pdu(struct ipw_priv *priv, u8 command, u8 len,
 +                          void *data)
 +{
 +      struct host_cmd cmd = {
 +              .cmd = command,
 +              .len = len,
 +              .param = data,
 +      };
 +
 +      return __ipw_send_cmd(priv, &cmd);
 +}
 +
 +static int ipw_send_host_complete(struct ipw_priv *priv)
 +{
        if (!priv) {
                IPW_ERROR("Invalid args\n");
                return -1;
        }
  
 -      return ipw_send_cmd(priv, &cmd);
 +      return ipw_send_cmd_simple(priv, IPW_CMD_HOST_COMPLETE);
  }
  
  static int ipw_send_system_config(struct ipw_priv *priv,
                                  struct ipw_sys_config *config)
  {
 -      struct host_cmd cmd = {
 -              .cmd = IPW_CMD_SYSTEM_CONFIG,
 -              .len = sizeof(*config)
 -      };
 -
        if (!priv || !config) {
                IPW_ERROR("Invalid args\n");
                return -1;
        }
  
 -      memcpy(cmd.param, config, sizeof(*config));
 -      return ipw_send_cmd(priv, &cmd);
 +      return ipw_send_cmd_pdu(priv, IPW_CMD_SYSTEM_CONFIG, sizeof(*config),
 +                              config);
  }
  
  static int ipw_send_ssid(struct ipw_priv *priv, u8 * ssid, int len)
  {
 -      struct host_cmd cmd = {
 -              .cmd = IPW_CMD_SSID,
 -              .len = min(len, IW_ESSID_MAX_SIZE)
 -      };
 -
        if (!priv || !ssid) {
                IPW_ERROR("Invalid args\n");
                return -1;
        }
  
 -      memcpy(cmd.param, ssid, cmd.len);
 -      return ipw_send_cmd(priv, &cmd);
 +      return ipw_send_cmd_pdu(priv, IPW_CMD_SSID, min(len, IW_ESSID_MAX_SIZE),
 +                              ssid);
  }
  
  static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac)
  {
 -      struct host_cmd cmd = {
 -              .cmd = IPW_CMD_ADAPTER_ADDRESS,
 -              .len = ETH_ALEN
 -      };
 -
        if (!priv || !mac) {
                IPW_ERROR("Invalid args\n");
                return -1;
        IPW_DEBUG_INFO("%s: Setting MAC to " MAC_FMT "\n",
                       priv->net_dev->name, MAC_ARG(mac));
  
 -      memcpy(cmd.param, mac, ETH_ALEN);
 -      return ipw_send_cmd(priv, &cmd);
 +      return ipw_send_cmd_pdu(priv, IPW_CMD_ADAPTER_ADDRESS, ETH_ALEN, mac);
  }
  
  /*
@@@ -2094,9 -2036,9 +2094,9 @@@ static void ipw_adapter_restart(void *a
  static void ipw_bg_adapter_restart(void *data)
  {
        struct ipw_priv *priv = data;
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        ipw_adapter_restart(data);
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
  }
  
  #define IPW_SCAN_CHECK_WATCHDOG (5 * HZ)
@@@ -2106,8 -2048,8 +2106,8 @@@ static void ipw_scan_check(void *data
        struct ipw_priv *priv = data;
        if (priv->status & (STATUS_SCANNING | STATUS_SCAN_ABORTING)) {
                IPW_DEBUG_SCAN("Scan completion watchdog resetting "
 -                             "adapter (%dms).\n",
 -                             IPW_SCAN_CHECK_WATCHDOG / 100);
 +                             "adapter after (%dms).\n",
 +                             jiffies_to_msecs(IPW_SCAN_CHECK_WATCHDOG));
                queue_work(priv->workqueue, &priv->adapter_restart);
        }
  }
  static void ipw_bg_scan_check(void *data)
  {
        struct ipw_priv *priv = data;
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        ipw_scan_check(data);
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
  }
  
  static int ipw_send_scan_request_ext(struct ipw_priv *priv,
                                     struct ipw_scan_request_ext *request)
  {
 -      struct host_cmd cmd = {
 -              .cmd = IPW_CMD_SCAN_REQUEST_EXT,
 -              .len = sizeof(*request)
 -      };
 -
 -      memcpy(cmd.param, request, sizeof(*request));
 -      return ipw_send_cmd(priv, &cmd);
 +      return ipw_send_cmd_pdu(priv, IPW_CMD_SCAN_REQUEST_EXT,
 +                              sizeof(*request), request);
  }
  
  static int ipw_send_scan_abort(struct ipw_priv *priv)
  {
 -      struct host_cmd cmd = {
 -              .cmd = IPW_CMD_SCAN_ABORT,
 -              .len = 0
 -      };
 -
        if (!priv) {
                IPW_ERROR("Invalid args\n");
                return -1;
        }
  
 -      return ipw_send_cmd(priv, &cmd);
 +      return ipw_send_cmd_simple(priv, IPW_CMD_SCAN_ABORT);
  }
  
  static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens)
  {
 -      struct host_cmd cmd = {
 -              .cmd = IPW_CMD_SENSITIVITY_CALIB,
 -              .len = sizeof(struct ipw_sensitivity_calib)
 +      struct ipw_sensitivity_calib calib = {
 +              .beacon_rssi_raw = sens,
        };
 -      struct ipw_sensitivity_calib *calib = (struct ipw_sensitivity_calib *)
 -          &cmd.param;
 -      calib->beacon_rssi_raw = sens;
 -      return ipw_send_cmd(priv, &cmd);
 +
 +      return ipw_send_cmd_pdu(priv, IPW_CMD_SENSITIVITY_CALIB, sizeof(calib),
 +                              &calib);
  }
  
  static int ipw_send_associate(struct ipw_priv *priv,
                              struct ipw_associate *associate)
  {
 -      struct host_cmd cmd = {
 -              .cmd = IPW_CMD_ASSOCIATE,
 -              .len = sizeof(*associate)
 -      };
 -
        struct ipw_associate tmp_associate;
 +
 +      if (!priv || !associate) {
 +              IPW_ERROR("Invalid args\n");
 +              return -1;
 +      }
 +
        memcpy(&tmp_associate, associate, sizeof(*associate));
        tmp_associate.policy_support =
            cpu_to_le16(tmp_associate.policy_support);
            cpu_to_le16(tmp_associate.beacon_interval);
        tmp_associate.atim_window = cpu_to_le16(tmp_associate.atim_window);
  
 -      if (!priv || !associate) {
 -              IPW_ERROR("Invalid args\n");
 -              return -1;
 -      }
 -
 -      memcpy(cmd.param, &tmp_associate, sizeof(*associate));
 -      return ipw_send_cmd(priv, &cmd);
 +      return ipw_send_cmd_pdu(priv, IPW_CMD_ASSOCIATE, sizeof(tmp_associate),
 +                              &tmp_associate);
  }
  
  static int ipw_send_supported_rates(struct ipw_priv *priv,
                                    struct ipw_supported_rates *rates)
  {
 -      struct host_cmd cmd = {
 -              .cmd = IPW_CMD_SUPPORTED_RATES,
 -              .len = sizeof(*rates)
 -      };
 -
        if (!priv || !rates) {
                IPW_ERROR("Invalid args\n");
                return -1;
        }
  
 -      memcpy(cmd.param, rates, sizeof(*rates));
 -      return ipw_send_cmd(priv, &cmd);
 +      return ipw_send_cmd_pdu(priv, IPW_CMD_SUPPORTED_RATES, sizeof(*rates),
 +                              rates);
  }
  
  static int ipw_set_random_seed(struct ipw_priv *priv)
  {
 -      struct host_cmd cmd = {
 -              .cmd = IPW_CMD_SEED_NUMBER,
 -              .len = sizeof(u32)
 -      };
 +      u32 val;
  
        if (!priv) {
                IPW_ERROR("Invalid args\n");
                return -1;
        }
  
 -      get_random_bytes(&cmd.param, sizeof(u32));
 +      get_random_bytes(&val, sizeof(val));
  
 -      return ipw_send_cmd(priv, &cmd);
 +      return ipw_send_cmd_pdu(priv, IPW_CMD_SEED_NUMBER, sizeof(val), &val);
  }
  
  static int ipw_send_card_disable(struct ipw_priv *priv, u32 phy_off)
  {
 -      struct host_cmd cmd = {
 -              .cmd = IPW_CMD_CARD_DISABLE,
 -              .len = sizeof(u32)
 -      };
 -
        if (!priv) {
                IPW_ERROR("Invalid args\n");
                return -1;
        }
  
 -      *((u32 *) & cmd.param) = phy_off;
 -
 -      return ipw_send_cmd(priv, &cmd);
 +      return ipw_send_cmd_pdu(priv, IPW_CMD_CARD_DISABLE, sizeof(phy_off),
 +                              &phy_off);
  }
  
  static int ipw_send_tx_power(struct ipw_priv *priv, struct ipw_tx_power *power)
  {
 -      struct host_cmd cmd = {
 -              .cmd = IPW_CMD_TX_POWER,
 -              .len = sizeof(*power)
 -      };
 -
        if (!priv || !power) {
                IPW_ERROR("Invalid args\n");
                return -1;
        }
  
 -      memcpy(cmd.param, power, sizeof(*power));
 -      return ipw_send_cmd(priv, &cmd);
 +      return ipw_send_cmd_pdu(priv, IPW_CMD_TX_POWER, sizeof(*power), power);
  }
  
  static int ipw_set_tx_power(struct ipw_priv *priv)
@@@ -2269,14 -2247,18 +2269,14 @@@ static int ipw_send_rts_threshold(struc
        struct ipw_rts_threshold rts_threshold = {
                .rts_threshold = rts,
        };
 -      struct host_cmd cmd = {
 -              .cmd = IPW_CMD_RTS_THRESHOLD,
 -              .len = sizeof(rts_threshold)
 -      };
  
        if (!priv) {
                IPW_ERROR("Invalid args\n");
                return -1;
        }
  
 -      memcpy(cmd.param, &rts_threshold, sizeof(rts_threshold));
 -      return ipw_send_cmd(priv, &cmd);
 +      return ipw_send_cmd_pdu(priv, IPW_CMD_RTS_THRESHOLD,
 +                              sizeof(rts_threshold), &rts_threshold);
  }
  
  static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag)
        struct ipw_frag_threshold frag_threshold = {
                .frag_threshold = frag,
        };
 -      struct host_cmd cmd = {
 -              .cmd = IPW_CMD_FRAG_THRESHOLD,
 -              .len = sizeof(frag_threshold)
 -      };
  
        if (!priv) {
                IPW_ERROR("Invalid args\n");
                return -1;
        }
  
 -      memcpy(cmd.param, &frag_threshold, sizeof(frag_threshold));
 -      return ipw_send_cmd(priv, &cmd);
 +      return ipw_send_cmd_pdu(priv, IPW_CMD_FRAG_THRESHOLD,
 +                              sizeof(frag_threshold), &frag_threshold);
  }
  
  static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode)
  {
 -      struct host_cmd cmd = {
 -              .cmd = IPW_CMD_POWER_MODE,
 -              .len = sizeof(u32)
 -      };
 -      u32 *param = (u32 *) (&cmd.param);
 +      u32 param;
  
        if (!priv) {
                IPW_ERROR("Invalid args\n");
         * level */
        switch (mode) {
        case IPW_POWER_BATTERY:
 -              *param = IPW_POWER_INDEX_3;
 +              param = IPW_POWER_INDEX_3;
                break;
        case IPW_POWER_AC:
 -              *param = IPW_POWER_MODE_CAM;
 +              param = IPW_POWER_MODE_CAM;
                break;
        default:
 -              *param = mode;
 +              param = mode;
                break;
        }
  
 -      return ipw_send_cmd(priv, &cmd);
 +      return ipw_send_cmd_pdu(priv, IPW_CMD_POWER_MODE, sizeof(param),
 +                              &param);
  }
  
  static int ipw_send_retry_limit(struct ipw_priv *priv, u8 slimit, u8 llimit)
                .short_retry_limit = slimit,
                .long_retry_limit = llimit
        };
 -      struct host_cmd cmd = {
 -              .cmd = IPW_CMD_RETRY_LIMIT,
 -              .len = sizeof(retry_limit)
 -      };
  
        if (!priv) {
                IPW_ERROR("Invalid args\n");
                return -1;
        }
  
 -      memcpy(cmd.param, &retry_limit, sizeof(retry_limit));
 -      return ipw_send_cmd(priv, &cmd);
 +      return ipw_send_cmd_pdu(priv, IPW_CMD_RETRY_LIMIT, sizeof(retry_limit),
 +                              &retry_limit);
  }
  
  /*
@@@ -2461,7 -2454,7 +2461,7 @@@ static void ipw_eeprom_init_sram(struc
        /*
           If the data looks correct, then copy it to our private
           copy.  Otherwise let the firmware know to perform the operation
 -         on it's own
 +         on its own.
         */
        if (priv->eeprom[EEPROM_VERSION] != 0) {
                IPW_DEBUG_INFO("Writing EEPROM data into SRAM\n");
@@@ -2714,25 -2707,22 +2714,25 @@@ static int ipw_fw_dma_add_buffer(struc
  
  static int ipw_fw_dma_wait(struct ipw_priv *priv)
  {
 -      u32 current_index = 0;
 +      u32 current_index = 0, previous_index;
        u32 watchdog = 0;
  
        IPW_DEBUG_FW(">> : \n");
  
        current_index = ipw_fw_dma_command_block_index(priv);
 -      IPW_DEBUG_FW_INFO("sram_desc.last_cb_index:0x%8X\n",
 +      IPW_DEBUG_FW_INFO("sram_desc.last_cb_index:0x%08X\n",
                          (int)priv->sram_desc.last_cb_index);
  
        while (current_index < priv->sram_desc.last_cb_index) {
                udelay(50);
 +              previous_index = current_index;
                current_index = ipw_fw_dma_command_block_index(priv);
  
 -              watchdog++;
 -
 -              if (watchdog > 400) {
 +              if (previous_index < current_index) {
 +                      watchdog = 0;
 +                      continue;
 +              }
 +              if (++watchdog > 400) {
                        IPW_DEBUG_FW_INFO("Timeout\n");
                        ipw_fw_dma_dump_command_block(priv);
                        ipw_fw_dma_abort(priv);
@@@ -2782,7 -2772,6 +2782,7 @@@ static inline int ipw_alive(struct ipw_
        return ipw_read32(priv, 0x90) == 0xd55555d5;
  }
  
 +/* timeout in msec, attempted in 10-msec quanta */
  static int ipw_poll_bit(struct ipw_priv *priv, u32 addr, u32 mask,
                               int timeout)
  {
@@@ -2811,11 -2800,10 +2811,11 @@@ static int ipw_stop_master(struct ipw_p
        /* stop master. typical delay - 0 */
        ipw_set_bit(priv, IPW_RESET_REG, IPW_RESET_REG_STOP_MASTER);
  
 +      /* timeout is in msec, polled in 10-msec quanta */
        rc = ipw_poll_bit(priv, IPW_RESET_REG,
                          IPW_RESET_REG_MASTER_DISABLED, 100);
        if (rc < 0) {
 -              IPW_ERROR("stop master failed in 10ms\n");
 +              IPW_ERROR("wait for stop master failed after 100ms\n");
                return -1;
        }
  
@@@ -2902,8 -2890,8 +2902,8 @@@ static int ipw_load_ucode(struct ipw_pr
        mdelay(1);
  
        /* enable ucode store */
 -      ipw_write_reg8(priv, DINO_CONTROL_REG, 0x0);
 -      ipw_write_reg8(priv, DINO_CONTROL_REG, DINO_ENABLE_CS);
 +      ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, 0x0);
 +      ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, DINO_ENABLE_CS);
        mdelay(1);
  
        /* write ucode */
@@@ -3048,7 -3036,7 +3048,7 @@@ static int ipw_stop_nic(struct ipw_pri
        rc = ipw_poll_bit(priv, IPW_RESET_REG,
                          IPW_RESET_REG_MASTER_DISABLED, 500);
        if (rc < 0) {
 -              IPW_ERROR("wait for reg master disabled failed\n");
 +              IPW_ERROR("wait for reg master disabled failed after 500ms\n");
                return rc;
        }
  
@@@ -3221,31 -3209,55 +3221,31 @@@ static int ipw_load(struct ipw_priv *pr
        const struct firmware *firmware = NULL;
        const struct firmware *ucode = NULL;
  #endif
 +      char *ucode_name;
 +      char *fw_name;
        int rc = 0, retries = 3;
  
 -#ifdef CONFIG_PM
 -      if (!fw_loaded) {
 -#endif
 -              rc = ipw_get_fw(priv, &bootfw, IPW_FW_NAME("boot"));
 -              if (rc)
 -                      goto error;
 -
 -              switch (priv->ieee->iw_mode) {
 -              case IW_MODE_ADHOC:
 -                      rc = ipw_get_fw(priv, &ucode,
 -                                      IPW_FW_NAME("ibss_ucode"));
 -                      if (rc)
 -                              goto error;
 -
 -                      rc = ipw_get_fw(priv, &firmware, IPW_FW_NAME("ibss"));
 -                      break;
 -
 +      switch (priv->ieee->iw_mode) {
 +      case IW_MODE_ADHOC:
 +              ucode_name = IPW_FW_NAME("ibss_ucode");
 +              fw_name = IPW_FW_NAME("ibss");
 +              break;
  #ifdef CONFIG_IPW2200_MONITOR
 -              case IW_MODE_MONITOR:
 -                      rc = ipw_get_fw(priv, &ucode,
 -                                      IPW_FW_NAME("sniffer_ucode"));
 -                      if (rc)
 -                              goto error;
 -
 -                      rc = ipw_get_fw(priv, &firmware,
 -                                      IPW_FW_NAME("sniffer"));
 -                      break;
 +      case IW_MODE_MONITOR:
 +              ucode_name = IPW_FW_NAME("sniffer_ucode");
 +              fw_name = IPW_FW_NAME("sniffer");
 +              break;
  #endif
 -              case IW_MODE_INFRA:
 -                      rc = ipw_get_fw(priv, &ucode, IPW_FW_NAME("bss_ucode"));
 -                      if (rc)
 -                              goto error;
 -
 -                      rc = ipw_get_fw(priv, &firmware, IPW_FW_NAME("bss"));
 -                      break;
 -
 -              default:
 -                      rc = -EINVAL;
 -              }
 -
 -              if (rc)
 -                      goto error;
 -
 -#ifdef CONFIG_PM
 -              fw_loaded = 1;
 +      case IW_MODE_INFRA:
 +              ucode_name = IPW_FW_NAME("bss_ucode");
 +              fw_name = IPW_FW_NAME("bss");
 +              break;
 +      default:
 +              rc = -EINVAL;
        }
 -#endif
 +
 +      if (rc < 0)
 +              goto error;
  
        if (!priv->rxq)
                priv->rxq = ipw_rx_queue_alloc(priv);
        ipw_stop_nic(priv);
  
        rc = ipw_reset_nic(priv);
 -      if (rc) {
 +      if (rc < 0) {
                IPW_ERROR("Unable to reset NIC\n");
                goto error;
        }
        ipw_zero_memory(priv, IPW_NIC_SRAM_LOWER_BOUND,
                        IPW_NIC_SRAM_UPPER_BOUND - IPW_NIC_SRAM_LOWER_BOUND);
  
 +#ifdef CONFIG_PM
 +      if (!fw_loaded) {
 +#endif
 +              rc = ipw_get_fw(priv, &bootfw, IPW_FW_NAME("boot"));
 +              if (rc < 0)
 +                      goto error;
 +#ifdef CONFIG_PM
 +      }
 +#endif
        /* DMA the initial boot firmware into the device */
        rc = ipw_load_firmware(priv, bootfw->data + sizeof(struct fw_header),
                               bootfw->size - sizeof(struct fw_header));
        /* kick start the device */
        ipw_start_nic(priv);
  
 -      /* wait for the device to finish it's initial startup sequence */
 +      /* wait for the device to finish its initial startup sequence */
        rc = ipw_poll_bit(priv, IPW_INTA_RW,
                          IPW_INTA_BIT_FW_INITIALIZATION_DONE, 500);
        if (rc < 0) {
        /* ack fw init done interrupt */
        ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE);
  
 +#ifdef CONFIG_PM
 +      if (!fw_loaded) {
 +#endif
 +              rc = ipw_get_fw(priv, &ucode, ucode_name);
 +              if (rc < 0)
 +                      goto error;
 +#ifdef CONFIG_PM
 +      }
 +#endif
 +
        /* DMA the ucode into the device */
        rc = ipw_load_ucode(priv, ucode->data + sizeof(struct fw_header),
                            ucode->size - sizeof(struct fw_header));
        /* stop nic */
        ipw_stop_nic(priv);
  
 +#ifdef CONFIG_PM
 +      if (!fw_loaded) {
 +#endif
 +              rc = ipw_get_fw(priv, &firmware, fw_name);
 +              if (rc < 0)
 +                      goto error;
 +#ifdef CONFIG_PM
 +      }
 +#endif
 +
        /* DMA bss firmware into the device */
        rc = ipw_load_firmware(priv, firmware->data +
                               sizeof(struct fw_header),
                IPW_ERROR("Unable to load firmware: %d\n", rc);
                goto error;
        }
 +#ifdef CONFIG_PM
 +      fw_loaded = 1;
 +#endif
  
        ipw_write32(priv, IPW_EEPROM_LOAD_DISABLE, 0);
  
        rc = ipw_queue_reset(priv);
 -      if (rc) {
 +      if (rc < 0) {
                IPW_ERROR("Unable to initialize queues\n");
                goto error;
        }
        rc = ipw_poll_bit(priv, IPW_INTA_RW,
                          IPW_INTA_BIT_FW_INITIALIZATION_DONE, 500);
        if (rc < 0) {
 -              IPW_ERROR("device failed to start after 500ms\n");
 +              IPW_ERROR("device failed to start within 500ms\n");
                goto error;
        }
        IPW_DEBUG_INFO("device response after %dms\n", rc);
@@@ -3735,9 -3715,9 +3735,9 @@@ static int ipw_disassociate(void *data
  static void ipw_bg_disassociate(void *data)
  {
        struct ipw_priv *priv = data;
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        ipw_disassociate(data);
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
  }
  
  static void ipw_system_config(void *data)
@@@ -4097,9 -4077,9 +4097,9 @@@ static void ipw_gather_stats(struct ipw
  static void ipw_bg_gather_stats(void *data)
  {
        struct ipw_priv *priv = data;
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        ipw_gather_stats(data);
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
  }
  
  /* Missed beacon behavior:
@@@ -4141,9 -4121,8 +4141,9 @@@ static void ipw_handle_missed_beacon(st
                return;
        }
  
 -      if (missed_count > priv->roaming_threshold &&
 -          missed_count <= priv->disassociate_threshold) {
 +      if (roaming &&
 +          (missed_count > priv->roaming_threshold &&
 +           missed_count <= priv->disassociate_threshold)) {
                /* If we are not already roaming, set the ROAM
                 * bit in the status and kick off a scan.
                 * This can happen several times before we reach
        }
  
        IPW_DEBUG_NOTIF("Missed beacon: %d\n", missed_count);
 -
  }
  
  /**
@@@ -4636,9 -4616,9 +4636,9 @@@ static void ipw_rx_notification(struct 
                }
  
        default:
-               IPW_ERROR("Unknown notification: "
-                         "subtype=%d,flags=0x%2x,size=%d\n",
-                         notif->subtype, notif->flags, notif->size);
+               IPW_DEBUG_NOTIF("Unknown notification: "
+                               "subtype=%d,flags=0x%2x,size=%d\n",
+                               notif->subtype, notif->flags, notif->size);
        }
  }
  
@@@ -4931,13 -4911,13 +4931,13 @@@ static void ipw_rx_queue_replenish(voi
  static void ipw_bg_rx_queue_replenish(void *data)
  {
        struct ipw_priv *priv = data;
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        ipw_rx_queue_replenish(data);
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
  }
  
  /* Assumes that the skb field of the buffers in 'pool' is kept accurate.
 - * If an SKB has been detached, the POOL needs to have it's SKB set to NULL
 + * If an SKB has been detached, the POOL needs to have its SKB set to NULL
   * This free routine walks the list of POOL entries and if SKB is set to
   * non NULL it is unmapped and freed
   */
@@@ -5277,11 -5257,10 +5277,11 @@@ static int ipw_find_adhoc_network(struc
        if (priv->ieee->scan_age != 0 &&
            time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) {
                IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
 -                              "because of age: %lums.\n",
 +                              "because of age: %ums.\n",
                                escape_essid(network->ssid, network->ssid_len),
                                MAC_ARG(network->bssid),
 -                              1000 * (jiffies - network->last_scanned) / HZ);
 +                              jiffies_to_msecs(jiffies -
 +                                               network->last_scanned));
                return 0;
        }
  
@@@ -5390,7 -5369,7 +5390,7 @@@ static void ipw_merge_adhoc_network(voi
                        return;
                }
  
 -              down(&priv->sem);
 +              mutex_lock(&priv->mutex);
                if ((priv->ieee->iw_mode == IW_MODE_ADHOC)) {
                        IPW_DEBUG_MERGE("remove network %s\n",
                                        escape_essid(priv->essid,
  
                ipw_disassociate(priv);
                priv->assoc_network = match.network;
 -              up(&priv->sem);
 +              mutex_unlock(&priv->mutex);
                return;
        }
  }
@@@ -5488,12 -5467,11 +5488,12 @@@ static int ipw_best_network(struct ipw_
        if (network->last_associate &&
            time_after(network->last_associate + (HZ * 3UL), jiffies)) {
                IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
 -                              "because of storming (%lus since last "
 +                              "because of storming (%ums since last "
                                "assoc attempt).\n",
                                escape_essid(network->ssid, network->ssid_len),
                                MAC_ARG(network->bssid),
 -                              (jiffies - network->last_associate) / HZ);
 +                              jiffies_to_msecs(jiffies -
 +                                               network->last_associate));
                return 0;
        }
  
        if (priv->ieee->scan_age != 0 &&
            time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) {
                IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
 -                              "because of age: %lums.\n",
 +                              "because of age: %ums.\n",
                                escape_essid(network->ssid, network->ssid_len),
                                MAC_ARG(network->bssid),
 -                              1000 * (jiffies - network->last_scanned) / HZ);
 +                              jiffies_to_msecs(jiffies -
 +                                               network->last_scanned));
                return 0;
        }
  
                return 0;
        }
  
 -      if (!priv->ieee->wpa_enabled && (network->wpa_ie_len > 0 ||
 -                                       network->rsn_ie_len > 0)) {
 +      if (priv->ieee->wpa_enabled &&
 +          network->wpa_ie_len == 0 && network->rsn_ie_len == 0) {
                IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
                                "because of WPA capability mismatch.\n",
                                escape_essid(network->ssid, network->ssid_len),
@@@ -5694,44 -5671,54 +5694,44 @@@ static void ipw_adhoc_create(struct ipw
  
  static void ipw_send_tgi_tx_key(struct ipw_priv *priv, int type, int index)
  {
 -      struct ipw_tgi_tx_key *key;
 -      struct host_cmd cmd = {
 -              .cmd = IPW_CMD_TGI_TX_KEY,
 -              .len = sizeof(*key)
 -      };
 +      struct ipw_tgi_tx_key key;
  
        if (!(priv->ieee->sec.flags & (1 << index)))
                return;
  
 -      key = (struct ipw_tgi_tx_key *)&cmd.param;
 -      key->key_id = index;
 -      memcpy(key->key, priv->ieee->sec.keys[index], SCM_TEMPORAL_KEY_LENGTH);
 -      key->security_type = type;
 -      key->station_index = 0; /* always 0 for BSS */
 -      key->flags = 0;
 +      key.key_id = index;
 +      memcpy(key.key, priv->ieee->sec.keys[index], SCM_TEMPORAL_KEY_LENGTH);
 +      key.security_type = type;
 +      key.station_index = 0;  /* always 0 for BSS */
 +      key.flags = 0;
        /* 0 for new key; previous value of counter (after fatal error) */
 -      key->tx_counter[0] = 0;
 -      key->tx_counter[1] = 0;
 +      key.tx_counter[0] = 0;
 +      key.tx_counter[1] = 0;
  
 -      ipw_send_cmd(priv, &cmd);
 +      ipw_send_cmd_pdu(priv, IPW_CMD_TGI_TX_KEY, sizeof(key), &key);
  }
  
  static void ipw_send_wep_keys(struct ipw_priv *priv, int type)
  {
 -      struct ipw_wep_key *key;
 +      struct ipw_wep_key key;
        int i;
 -      struct host_cmd cmd = {
 -              .cmd = IPW_CMD_WEP_KEY,
 -              .len = sizeof(*key)
 -      };
  
 -      key = (struct ipw_wep_key *)&cmd.param;
 -      key->cmd_id = DINO_CMD_WEP_KEY;
 -      key->seq_num = 0;
 +      key.cmd_id = DINO_CMD_WEP_KEY;
 +      key.seq_num = 0;
  
        /* Note: AES keys cannot be set for multiple times.
         * Only set it at the first time. */
        for (i = 0; i < 4; i++) {
 -              key->key_index = i | type;
 +              key.key_index = i | type;
                if (!(priv->ieee->sec.flags & (1 << i))) {
 -                      key->key_size = 0;
 +                      key.key_size = 0;
                        continue;
                }
  
 -              key->key_size = priv->ieee->sec.key_sizes[i];
 -              memcpy(key->key, priv->ieee->sec.keys[i], key->key_size);
 +              key.key_size = priv->ieee->sec.key_sizes[i];
 +              memcpy(key.key, priv->ieee->sec.keys[i], key.key_size);
  
 -              ipw_send_cmd(priv, &cmd);
 +              ipw_send_cmd_pdu(priv, IPW_CMD_WEP_KEY, sizeof(key), &key);
        }
  }
  
@@@ -5835,9 -5822,9 +5835,9 @@@ static void ipw_adhoc_check(void *data
  static void ipw_bg_adhoc_check(void *data)
  {
        struct ipw_priv *priv = data;
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        ipw_adhoc_check(data);
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
  }
  
  #ifdef CONFIG_IPW2200_DEBUG
@@@ -6064,7 -6051,7 +6064,7 @@@ static int ipw_request_scan(struct ipw_
            (priv->status & STATUS_EXIT_PENDING))
                return 0;
  
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
  
        if (priv->status & STATUS_SCANNING) {
                IPW_DEBUG_HC("Concurrent scan requested.  Ignoring.\n");
        queue_delayed_work(priv->workqueue, &priv->scan_check,
                           IPW_SCAN_CHECK_WATCHDOG);
        done:
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
        return err;
  }
  
  static void ipw_bg_abort_scan(void *data)
  {
        struct ipw_priv *priv = data;
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        ipw_abort_scan(data);
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
  }
  
  static int ipw_wpa_enable(struct ipw_priv *priv, int value)
@@@ -6206,9 -6193,6 +6206,9 @@@ static int ipw_wpa_set_auth_algs(struc
        } else if (value & IW_AUTH_ALG_OPEN_SYSTEM) {
                sec.auth_mode = WLAN_AUTH_OPEN;
                ieee->open_wep = 1;
 +      } else if (value & IW_AUTH_ALG_LEAP) {
 +              sec.auth_mode = WLAN_AUTH_LEAP;
 +              ieee->open_wep = 1;
        } else
                return -EINVAL;
  
        return ret;
  }
  
 -void ipw_wpa_assoc_frame(struct ipw_priv *priv, char *wpa_ie, int wpa_ie_len)
 +static void ipw_wpa_assoc_frame(struct ipw_priv *priv, char *wpa_ie,
 +                              int wpa_ie_len)
  {
        /* make sure WPA is enabled */
        ipw_wpa_enable(priv, 1);
  static int ipw_set_rsn_capa(struct ipw_priv *priv,
                            char *capabilities, int length)
  {
 -      struct host_cmd cmd = {
 -              .cmd = IPW_CMD_RSN_CAPABILITIES,
 -              .len = length,
 -      };
 -
        IPW_DEBUG_HC("HOST_CMD_RSN_CAPABILITIES\n");
  
 -      memcpy(cmd.param, capabilities, length);
 -      return ipw_send_cmd(priv, &cmd);
 +      return ipw_send_cmd_pdu(priv, IPW_CMD_RSN_CAPABILITIES, length,
 +                              capabilities);
  }
  
  /*
@@@ -6256,7 -6244,7 +6256,7 @@@ static int ipw_wx_set_genie(struct net_
            (wrqu->data.length && extra == NULL))
                return -EINVAL;
  
 -      //down(&priv->sem);
 +      //mutex_lock(&priv->mutex);
  
        //if (!ieee->wpa_enabled) {
        //      err = -EOPNOTSUPP;
  
        ipw_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len);
        out:
 -      //up(&priv->sem);
 +      //mutex_unlock(&priv->mutex);
        return err;
  }
  
@@@ -6295,7 -6283,7 +6295,7 @@@ static int ipw_wx_get_genie(struct net_
        struct ieee80211_device *ieee = priv->ieee;
        int err = 0;
  
 -      //down(&priv->sem);
 +      //mutex_lock(&priv->mutex);
  
        //if (!ieee->wpa_enabled) {
        //      err = -EOPNOTSUPP;
        memcpy(extra, ieee->wpa_ie, ieee->wpa_ie_len);
  
        out:
 -      //up(&priv->sem);
 +      //mutex_unlock(&priv->mutex);
        return err;
  }
  
@@@ -6976,12 -6964,12 +6976,12 @@@ static void ipw_bg_qos_activate(void *d
        if (priv == NULL)
                return;
  
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
  
        if (priv->status & STATUS_ASSOCIATED)
                ipw_qos_activate(priv, &(priv->assoc_network->qos_data));
  
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
  }
  
  static int ipw_handle_probe_response(struct net_device *dev,
@@@ -7022,15 -7010,25 +7022,15 @@@ static int ipw_handle_assoc_response(st
  static int ipw_send_qos_params_command(struct ipw_priv *priv, struct ieee80211_qos_parameters
                                       *qos_param)
  {
 -      struct host_cmd cmd = {
 -              .cmd = IPW_CMD_QOS_PARAMETERS,
 -              .len = (sizeof(struct ieee80211_qos_parameters) * 3)
 -      };
 -
 -      memcpy(cmd.param, qos_param, sizeof(*qos_param) * 3);
 -      return ipw_send_cmd(priv, &cmd);
 +      return ipw_send_cmd_pdu(priv, IPW_CMD_QOS_PARAMETERS,
 +                              sizeof(*qos_param) * 3, qos_param);
  }
  
  static int ipw_send_qos_info_command(struct ipw_priv *priv, struct ieee80211_qos_information_element
                                     *qos_param)
  {
 -      struct host_cmd cmd = {
 -              .cmd = IPW_CMD_WME_INFO,
 -              .len = sizeof(*qos_param)
 -      };
 -
 -      memcpy(cmd.param, qos_param, sizeof(*qos_param));
 -      return ipw_send_cmd(priv, &cmd);
 +      return ipw_send_cmd_pdu(priv, IPW_CMD_WME_INFO, sizeof(*qos_param),
 +                              qos_param);
  }
  
  #endif                                /* CONFIG_IPW_QOS */
@@@ -7054,21 -7052,19 +7054,21 @@@ static int ipw_associate_network(struc
  
        memset(&priv->assoc_request, 0, sizeof(priv->assoc_request));
        priv->assoc_request.channel = network->channel;
 +      priv->assoc_request.auth_key = 0;
 +
        if ((priv->capability & CAP_PRIVACY_ON) &&
 -          (priv->capability & CAP_SHARED_KEY)) {
 +          (priv->ieee->sec.auth_mode == WLAN_AUTH_SHARED_KEY)) {
                priv->assoc_request.auth_type = AUTH_SHARED_KEY;
                priv->assoc_request.auth_key = priv->ieee->sec.active_key;
  
 -              if ((priv->capability & CAP_PRIVACY_ON) &&
 -                  (priv->ieee->sec.level == SEC_LEVEL_1) &&
 -                  !(priv->ieee->host_encrypt || priv->ieee->host_decrypt))
 +              if (priv->ieee->sec.level == SEC_LEVEL_1)
                        ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_WEP);
 -      } else {
 +
 +      } else if ((priv->capability & CAP_PRIVACY_ON) &&
 +                 (priv->ieee->sec.auth_mode == WLAN_AUTH_LEAP))
 +              priv->assoc_request.auth_type = AUTH_LEAP;
 +      else
                priv->assoc_request.auth_type = AUTH_OPEN;
 -              priv->assoc_request.auth_key = 0;
 -      }
  
        if (priv->ieee->wpa_ie_len) {
                priv->assoc_request.policy_support = 0x02;      /* RSN active */
@@@ -7282,9 -7278,9 +7282,9 @@@ static void ipw_roam(void *data
  static void ipw_bg_roam(void *data)
  {
        struct ipw_priv *priv = data;
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        ipw_roam(data);
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
  }
  
  static int ipw_associate(void *data)
  static void ipw_bg_associate(void *data)
  {
        struct ipw_priv *priv = data;
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        ipw_associate(data);
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
  }
  
  static void ipw_rebuild_decrypted_skb(struct ipw_priv *priv,
@@@ -8130,7 -8126,7 +8130,7 @@@ static int ipw_wx_get_name(struct net_d
                           union iwreq_data *wrqu, char *extra)
  {
        struct ipw_priv *priv = ieee80211_priv(dev);
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        if (priv->status & STATUS_RF_KILL_MASK)
                strcpy(wrqu->name, "radio off");
        else if (!(priv->status & STATUS_ASSOCIATED))
                snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11%c",
                         ipw_modes[priv->assoc_request.ieee_mode]);
        IPW_DEBUG_WX("Name: %s\n", wrqu->name);
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
        return 0;
  }
  
@@@ -8208,9 -8204,9 +8208,9 @@@ static int ipw_wx_set_freq(struct net_d
  
        if (fwrq->m == 0) {
                IPW_DEBUG_WX("SET Freq/Channel -> any\n");
 -              down(&priv->sem);
 +              mutex_lock(&priv->mutex);
                ret = ipw_set_channel(priv, 0);
 -              up(&priv->sem);
 +              mutex_unlock(&priv->mutex);
                return ret;
        }
        /* if setting by freq convert to channel */
        }
  
        IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m);
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        ret = ipw_set_channel(priv, channel);
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
        return ret;
  }
  
@@@ -8254,14 -8250,14 +8254,14 @@@ static int ipw_wx_get_freq(struct net_d
  
        /* If we are associated, trying to associate, or have a statically
         * configured CHANNEL then return that; otherwise return ANY */
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        if (priv->config & CFG_STATIC_CHANNEL ||
            priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED))
                wrqu->freq.m = priv->channel;
        else
                wrqu->freq.m = 0;
  
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
        IPW_DEBUG_WX("GET Freq/Channel -> %d \n", priv->channel);
        return 0;
  }
@@@ -8291,7 -8287,7 +8291,7 @@@ static int ipw_wx_set_mode(struct net_d
        if (wrqu->mode == priv->ieee->iw_mode)
                return 0;
  
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
  
        ipw_sw_reset(priv, 0);
  
        priv->ieee->iw_mode = wrqu->mode;
  
        queue_work(priv->workqueue, &priv->adapter_restart);
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
        return err;
  }
  
@@@ -8323,10 -8319,10 +8323,10 @@@ static int ipw_wx_get_mode(struct net_d
                           union iwreq_data *wrqu, char *extra)
  {
        struct ipw_priv *priv = ieee80211_priv(dev);
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        wrqu->mode = priv->ieee->iw_mode;
        IPW_DEBUG_WX("Get MODE -> %d\n", wrqu->mode);
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
        return 0;
  }
  
@@@ -8373,7 -8369,7 +8373,7 @@@ static int ipw_wx_get_range(struct net_
        range->avg_qual.level = 0;      /* FIXME to real average level */
        range->avg_qual.noise = 0;
        range->avg_qual.updated = 7;    /* Updated all three */
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        range->num_bitrates = min(priv->rates.num_rates, (u8) IW_MAX_BITRATES);
  
        for (i = 0; i < range->num_bitrates; i++)
  
        /* Set the Wireless Extension versions */
        range->we_version_compiled = WIRELESS_EXT;
 -      range->we_version_source = 16;
 +      range->we_version_source = 18;
  
        i = 0;
        if (priv->ieee->mode & (IEEE_B | IEEE_G)) {
        range->num_channels = i;
        range->num_frequency = i;
  
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
  
        /* Event capability (kernel + driver) */
        range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
                                IW_EVENT_CAPA_MASK(SIOCGIWAP));
        range->event_capa[1] = IW_EVENT_CAPA_K_1;
  
 +      range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
 +              IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
 +
        IPW_DEBUG_WX("GET Range\n");
        return 0;
  }
@@@ -8445,7 -8438,7 +8445,7 @@@ static int ipw_wx_set_wap(struct net_de
  
        if (wrqu->ap_addr.sa_family != ARPHRD_ETHER)
                return -EINVAL;
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        if (!memcmp(any, wrqu->ap_addr.sa_data, ETH_ALEN) ||
            !memcmp(off, wrqu->ap_addr.sa_data, ETH_ALEN)) {
                /* we disable mandatory BSSID association */
                IPW_DEBUG_ASSOC("Attempting to associate with new "
                                "parameters.\n");
                ipw_associate(priv);
 -              up(&priv->sem);
 +              mutex_unlock(&priv->mutex);
                return 0;
        }
  
        priv->config |= CFG_STATIC_BSSID;
        if (!memcmp(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN)) {
                IPW_DEBUG_WX("BSSID set to current BSSID.\n");
 -              up(&priv->sem);
 +              mutex_unlock(&priv->mutex);
                return 0;
        }
  
        if (!ipw_disassociate(priv))
                ipw_associate(priv);
  
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
        return 0;
  }
  
@@@ -8486,7 -8479,7 +8486,7 @@@ static int ipw_wx_get_wap(struct net_de
        struct ipw_priv *priv = ieee80211_priv(dev);
        /* If we are associated, trying to associate, or have a statically
         * configured BSSID then return that; otherwise return ANY */
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        if (priv->config & CFG_STATIC_BSSID ||
            priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
                wrqu->ap_addr.sa_family = ARPHRD_ETHER;
  
        IPW_DEBUG_WX("Getting WAP BSSID: " MAC_FMT "\n",
                     MAC_ARG(wrqu->ap_addr.sa_data));
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
        return 0;
  }
  
@@@ -8507,7 -8500,7 +8507,7 @@@ static int ipw_wx_set_essid(struct net_
        struct ipw_priv *priv = ieee80211_priv(dev);
        char *essid = "";       /* ANY */
        int length = 0;
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        if (wrqu->essid.flags && wrqu->essid.length) {
                length = wrqu->essid.length - 1;
                essid = extra;
                        priv->config &= ~CFG_STATIC_ESSID;
                        ipw_associate(priv);
                }
 -              up(&priv->sem);
 +              mutex_unlock(&priv->mutex);
                return 0;
        }
  
  
        if (priv->essid_len == length && !memcmp(priv->essid, extra, length)) {
                IPW_DEBUG_WX("ESSID set to current ESSID.\n");
 -              up(&priv->sem);
 +              mutex_unlock(&priv->mutex);
                return 0;
        }
  
        if (!ipw_disassociate(priv))
                ipw_associate(priv);
  
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
        return 0;
  }
  
@@@ -8559,7 -8552,7 +8559,7 @@@ static int ipw_wx_get_essid(struct net_
  
        /* If we are associated, trying to associate, or have a statically
         * configured ESSID then return that; otherwise return ANY */
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        if (priv->config & CFG_STATIC_ESSID ||
            priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
                IPW_DEBUG_WX("Getting essid: '%s'\n",
                wrqu->essid.length = 0;
                wrqu->essid.flags = 0;  /* active */
        }
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
        return 0;
  }
  
@@@ -8585,12 -8578,12 +8585,12 @@@ static int ipw_wx_set_nick(struct net_d
        IPW_DEBUG_WX("Setting nick to '%s'\n", extra);
        if (wrqu->data.length > IW_ESSID_MAX_SIZE)
                return -E2BIG;
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        wrqu->data.length = min((size_t) wrqu->data.length, sizeof(priv->nick));
        memset(priv->nick, 0, sizeof(priv->nick));
        memcpy(priv->nick, extra, wrqu->data.length);
        IPW_DEBUG_TRACE("<<\n");
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
        return 0;
  
  }
@@@ -8601,11 -8594,11 +8601,11 @@@ static int ipw_wx_get_nick(struct net_d
  {
        struct ipw_priv *priv = ieee80211_priv(dev);
        IPW_DEBUG_WX("Getting nick\n");
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        wrqu->data.length = strlen(priv->nick) + 1;
        memcpy(extra, priv->nick, wrqu->data.length);
        wrqu->data.flags = 1;   /* active */
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
        return 0;
  }
  
@@@ -8698,7 -8691,7 +8698,7 @@@ static int ipw_wx_set_rate(struct net_d
        apply:
        IPW_DEBUG_WX("Setting rate mask to 0x%08X [%s]\n",
                     mask, fixed ? "fixed" : "sub-rates");
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        if (mask == IEEE80211_DEFAULT_RATES_MASK) {
                priv->config &= ~CFG_FIXED_RATE;
                ipw_set_fixed_rate(priv, priv->ieee->mode);
  
        if (priv->rates_mask == mask) {
                IPW_DEBUG_WX("Mask set to current mask.\n");
 -              up(&priv->sem);
 +              mutex_unlock(&priv->mutex);
                return 0;
        }
  
        if (!ipw_disassociate(priv))
                ipw_associate(priv);
  
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
        return 0;
  }
  
@@@ -8727,9 -8720,9 +8727,9 @@@ static int ipw_wx_get_rate(struct net_d
                           union iwreq_data *wrqu, char *extra)
  {
        struct ipw_priv *priv = ieee80211_priv(dev);
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        wrqu->bitrate.value = priv->last_rate;
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
        IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value);
        return 0;
  }
@@@ -8739,20 -8732,20 +8739,20 @@@ static int ipw_wx_set_rts(struct net_de
                          union iwreq_data *wrqu, char *extra)
  {
        struct ipw_priv *priv = ieee80211_priv(dev);
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        if (wrqu->rts.disabled)
                priv->rts_threshold = DEFAULT_RTS_THRESHOLD;
        else {
                if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
                    wrqu->rts.value > MAX_RTS_THRESHOLD) {
 -                      up(&priv->sem);
 +                      mutex_unlock(&priv->mutex);
                        return -EINVAL;
                }
                priv->rts_threshold = wrqu->rts.value;
        }
  
        ipw_send_rts_threshold(priv, priv->rts_threshold);
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
        IPW_DEBUG_WX("SET RTS Threshold -> %d \n", priv->rts_threshold);
        return 0;
  }
@@@ -8762,11 -8755,11 +8762,11 @@@ static int ipw_wx_get_rts(struct net_de
                          union iwreq_data *wrqu, char *extra)
  {
        struct ipw_priv *priv = ieee80211_priv(dev);
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        wrqu->rts.value = priv->rts_threshold;
        wrqu->rts.fixed = 0;    /* no auto select */
        wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD);
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
        IPW_DEBUG_WX("GET RTS Threshold -> %d \n", wrqu->rts.value);
        return 0;
  }
@@@ -8778,7 -8771,7 +8778,7 @@@ static int ipw_wx_set_txpow(struct net_
        struct ipw_priv *priv = ieee80211_priv(dev);
        int err = 0;
  
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        if (ipw_radio_kill_sw(priv, wrqu->power.disabled)) {
                err = -EINPROGRESS;
                goto out;
        priv->tx_power = wrqu->power.value;
        err = ipw_set_tx_power(priv);
        out:
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
        return err;
  }
  
@@@ -8810,12 -8803,12 +8810,12 @@@ static int ipw_wx_get_txpow(struct net_
                            union iwreq_data *wrqu, char *extra)
  {
        struct ipw_priv *priv = ieee80211_priv(dev);
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        wrqu->power.value = priv->tx_power;
        wrqu->power.fixed = 1;
        wrqu->power.flags = IW_TXPOW_DBM;
        wrqu->power.disabled = (priv->status & STATUS_RF_KILL_MASK) ? 1 : 0;
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
  
        IPW_DEBUG_WX("GET TX Power -> %s %d \n",
                     wrqu->power.disabled ? "OFF" : "ON", wrqu->power.value);
@@@ -8828,13 -8821,13 +8828,13 @@@ static int ipw_wx_set_frag(struct net_d
                           union iwreq_data *wrqu, char *extra)
  {
        struct ipw_priv *priv = ieee80211_priv(dev);
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        if (wrqu->frag.disabled)
                priv->ieee->fts = DEFAULT_FTS;
        else {
                if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
                    wrqu->frag.value > MAX_FRAG_THRESHOLD) {
 -                      up(&priv->sem);
 +                      mutex_unlock(&priv->mutex);
                        return -EINVAL;
                }
  
        }
  
        ipw_send_frag_threshold(priv, wrqu->frag.value);
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
        IPW_DEBUG_WX("SET Frag Threshold -> %d \n", wrqu->frag.value);
        return 0;
  }
@@@ -8852,11 -8845,11 +8852,11 @@@ static int ipw_wx_get_frag(struct net_d
                           union iwreq_data *wrqu, char *extra)
  {
        struct ipw_priv *priv = ieee80211_priv(dev);
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        wrqu->frag.value = priv->ieee->fts;
        wrqu->frag.fixed = 0;   /* no auto select */
        wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FTS);
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
        IPW_DEBUG_WX("GET Frag Threshold -> %d \n", wrqu->frag.value);
  
        return 0;
@@@ -8877,7 -8870,7 +8877,7 @@@ static int ipw_wx_set_retry(struct net_
        if (wrqu->retry.value < 0 || wrqu->retry.value > 255)
                return -EINVAL;
  
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        if (wrqu->retry.flags & IW_RETRY_MIN)
                priv->short_retry_limit = (u8) wrqu->retry.value;
        else if (wrqu->retry.flags & IW_RETRY_MAX)
  
        ipw_send_retry_limit(priv, priv->short_retry_limit,
                             priv->long_retry_limit);
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
        IPW_DEBUG_WX("SET retry limit -> short:%d long:%d\n",
                     priv->short_retry_limit, priv->long_retry_limit);
        return 0;
@@@ -8901,11 -8894,11 +8901,11 @@@ static int ipw_wx_get_retry(struct net_
  {
        struct ipw_priv *priv = ieee80211_priv(dev);
  
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        wrqu->retry.disabled = 0;
  
        if ((wrqu->retry.flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
 -              up(&priv->sem);
 +              mutex_unlock(&priv->mutex);
                return -EINVAL;
        }
  
                wrqu->retry.flags = IW_RETRY_LIMIT;
                wrqu->retry.value = priv->short_retry_limit;
        }
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
  
        IPW_DEBUG_WX("GET retry -> %d \n", wrqu->retry.value);
  
@@@ -8936,7 -8929,7 +8936,7 @@@ static int ipw_request_direct_scan(stru
            (priv->status & STATUS_EXIT_PENDING))
                return 0;
  
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
  
        if (priv->status & STATUS_RF_KILL_MASK) {
                IPW_DEBUG_HC("Aborting scan due to RF kill activation\n");
        priv->status |= STATUS_SCANNING;
  
        done:
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
        return err;
  }
  
@@@ -9031,7 -9024,7 +9031,7 @@@ static int ipw_wx_set_encode(struct net
        int ret;
        u32 cap = priv->capability;
  
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        ret = ieee80211_wx_set_encode(priv->ieee, info, wrqu, key);
  
        /* In IBSS mode, we need to notify the firmware to update
            priv->status & STATUS_ASSOCIATED)
                ipw_disassociate(priv);
  
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
        return ret;
  }
  
@@@ -9059,17 -9052,17 +9059,17 @@@ static int ipw_wx_set_power(struct net_
  {
        struct ipw_priv *priv = ieee80211_priv(dev);
        int err;
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        if (wrqu->power.disabled) {
                priv->power_mode = IPW_POWER_LEVEL(priv->power_mode);
                err = ipw_send_power_mode(priv, IPW_POWER_MODE_CAM);
                if (err) {
                        IPW_DEBUG_WX("failed setting power mode.\n");
 -                      up(&priv->sem);
 +                      mutex_unlock(&priv->mutex);
                        return err;
                }
                IPW_DEBUG_WX("SET Power Management Mode -> off\n");
 -              up(&priv->sem);
 +              mutex_unlock(&priv->mutex);
                return 0;
        }
  
        default:                /* Otherwise we don't support it */
                IPW_DEBUG_WX("SET PM Mode: %X not supported.\n",
                             wrqu->power.flags);
 -              up(&priv->sem);
 +              mutex_unlock(&priv->mutex);
                return -EOPNOTSUPP;
        }
  
        err = ipw_send_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode));
        if (err) {
                IPW_DEBUG_WX("failed setting power mode.\n");
 -              up(&priv->sem);
 +              mutex_unlock(&priv->mutex);
                return err;
        }
  
        IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", priv->power_mode);
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
        return 0;
  }
  
@@@ -9108,13 -9101,13 +9108,13 @@@ static int ipw_wx_get_power(struct net_
                            union iwreq_data *wrqu, char *extra)
  {
        struct ipw_priv *priv = ieee80211_priv(dev);
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        if (!(priv->power_mode & IPW_POWER_ENABLED))
                wrqu->power.disabled = 1;
        else
                wrqu->power.disabled = 0;
  
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
        IPW_DEBUG_WX("GET Power Management Mode -> %02X\n", priv->power_mode);
  
        return 0;
@@@ -9127,7 -9120,7 +9127,7 @@@ static int ipw_wx_set_powermode(struct 
        struct ipw_priv *priv = ieee80211_priv(dev);
        int mode = *(int *)extra;
        int err;
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        if ((mode < 1) || (mode > IPW_POWER_LIMIT)) {
                mode = IPW_POWER_AC;
                priv->power_mode = mode;
  
                if (err) {
                        IPW_DEBUG_WX("failed setting power mode.\n");
 -                      up(&priv->sem);
 +                      mutex_unlock(&priv->mutex);
                        return err;
                }
        }
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
        return 0;
  }
  
@@@ -9193,7 -9186,7 +9193,7 @@@ static int ipw_wx_set_wireless_mode(str
                IPW_WARNING("Attempt to set invalid wireless mode: %d\n", mode);
                return -EINVAL;
        }
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        if (priv->adapter == IPW_2915ABG) {
                priv->ieee->abg_true = 1;
                if (mode & IEEE_A) {
                if (mode & IEEE_A) {
                        IPW_WARNING("Attempt to set 2200BG into "
                                    "802.11a mode\n");
 -                      up(&priv->sem);
 +                      mutex_unlock(&priv->mutex);
                        return -EINVAL;
                }
  
        IPW_DEBUG_WX("PRIV SET MODE: %c%c%c\n",
                     mode & IEEE_A ? 'a' : '.',
                     mode & IEEE_B ? 'b' : '.', mode & IEEE_G ? 'g' : '.');
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
        return 0;
  }
  
@@@ -9251,7 -9244,7 +9251,7 @@@ static int ipw_wx_get_wireless_mode(str
                                    union iwreq_data *wrqu, char *extra)
  {
        struct ipw_priv *priv = ieee80211_priv(dev);
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        switch (priv->ieee->mode) {
        case IEEE_A:
                strncpy(extra, "802.11a (1)", MAX_WX_STRING);
        IPW_DEBUG_WX("PRIV GET MODE: %s\n", extra);
  
        wrqu->data.length = strlen(extra) + 1;
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
  
        return 0;
  }
@@@ -9293,7 -9286,7 +9293,7 @@@ static int ipw_wx_set_preamble(struct n
  {
        struct ipw_priv *priv = ieee80211_priv(dev);
        int mode = *(int *)extra;
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        /* Switching from SHORT -> LONG requires a disassociation */
        if (mode == 1) {
                if (!(priv->config & CFG_PREAMBLE_LONG)) {
                priv->config &= ~CFG_PREAMBLE_LONG;
                goto done;
        }
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
        return -EINVAL;
  
        done:
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
        return 0;
  }
  
@@@ -9325,12 -9318,12 +9325,12 @@@ static int ipw_wx_get_preamble(struct n
                               union iwreq_data *wrqu, char *extra)
  {
        struct ipw_priv *priv = ieee80211_priv(dev);
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        if (priv->config & CFG_PREAMBLE_LONG)
                snprintf(wrqu->name, IFNAMSIZ, "long (1)");
        else
                snprintf(wrqu->name, IFNAMSIZ, "auto (0)");
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
        return 0;
  }
  
@@@ -9342,7 -9335,7 +9342,7 @@@ static int ipw_wx_set_monitor(struct ne
        struct ipw_priv *priv = ieee80211_priv(dev);
        int *parms = (int *)extra;
        int enable = (parms[0] > 0);
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        IPW_DEBUG_WX("SET MONITOR: %d %d\n", enable, parms[1]);
        if (enable) {
                if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
                ipw_set_channel(priv, parms[1]);
        } else {
                if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
 -                      up(&priv->sem);
 +                      mutex_unlock(&priv->mutex);
                        return 0;
                }
                priv->net_dev->type = ARPHRD_ETHER;
                queue_work(priv->workqueue, &priv->adapter_restart);
        }
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
        return 0;
  }
  
@@@ -9393,7 -9386,7 +9393,7 @@@ static int ipw_wx_sw_reset(struct net_d
  
        IPW_DEBUG_WX("SW_RESET\n");
  
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
  
        ret = ipw_sw_reset(priv, 0);
        if (!ret) {
         * module parameter, so take appropriate action */
        ipw_radio_kill_sw(priv, priv->status & STATUS_RF_KILL_SW);
  
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
        ieee80211_wx_set_encode(priv->ieee, info, &wrqu_sec, NULL);
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
  
        if (!(priv->status & STATUS_RF_KILL_MASK)) {
                /* Configuration likely changed -- force [re]association */
                        ipw_associate(priv);
        }
  
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
  
        return 0;
  }
@@@ -9593,7 -9586,7 +9593,7 @@@ static struct iw_statistics *ipw_get_wi
  static  void init_sys_config(struct ipw_sys_config *sys_config)
  {
        memset(sys_config, 0, sizeof(struct ipw_sys_config));
 -      sys_config->bt_coexistence = 1; /* We may need to look into prvStaBtConfig */
 +      sys_config->bt_coexistence = 0;
        sys_config->answer_broadcast_ssid_probe = 0;
        sys_config->accept_all_data_frames = 0;
        sys_config->accept_non_directed_frames = 1;
@@@ -9614,11 -9607,11 +9614,11 @@@ static int ipw_net_open(struct net_devi
        struct ipw_priv *priv = ieee80211_priv(dev);
        IPW_DEBUG_INFO("dev->open\n");
        /* we should be verifying the device is ready to be opened */
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        if (!(priv->status & STATUS_RF_KILL_MASK) &&
            (priv->status & STATUS_ASSOCIATED))
                netif_start_queue(dev);
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
        return 0;
  }
  
@@@ -9897,13 -9890,13 +9897,13 @@@ static int ipw_net_set_mac_address(stru
        struct sockaddr *addr = p;
        if (!is_valid_ether_addr(addr->sa_data))
                return -EADDRNOTAVAIL;
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        priv->config |= CFG_CUSTOM_MAC;
        memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN);
        printk(KERN_INFO "%s: Setting MAC to " MAC_FMT "\n",
               priv->net_dev->name, MAC_ARG(priv->mac_addr));
        queue_work(priv->workqueue, &priv->adapter_restart);
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
        return 0;
  }
  
@@@ -9947,9 -9940,9 +9947,9 @@@ static int ipw_ethtool_get_eeprom(struc
  
        if (eeprom->offset + eeprom->len > IPW_EEPROM_IMAGE_SIZE)
                return -EINVAL;
 -      down(&p->sem);
 +      mutex_lock(&p->mutex);
        memcpy(bytes, &p->eeprom[eeprom->offset], eeprom->len);
 -      up(&p->sem);
 +      mutex_unlock(&p->mutex);
        return 0;
  }
  
@@@ -9961,12 -9954,12 +9961,12 @@@ static int ipw_ethtool_set_eeprom(struc
  
        if (eeprom->offset + eeprom->len > IPW_EEPROM_IMAGE_SIZE)
                return -EINVAL;
 -      down(&p->sem);
 +      mutex_lock(&p->mutex);
        memcpy(&p->eeprom[eeprom->offset], bytes, eeprom->len);
        for (i = IPW_EEPROM_DATA;
             i < IPW_EEPROM_DATA + IPW_EEPROM_IMAGE_SIZE; i++)
                ipw_write8(p, i, p->eeprom[i]);
 -      up(&p->sem);
 +      mutex_unlock(&p->mutex);
        return 0;
  }
  
@@@ -10061,12 -10054,12 +10061,12 @@@ static void ipw_rf_kill(void *adapter
  static void ipw_bg_rf_kill(void *data)
  {
        struct ipw_priv *priv = data;
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        ipw_rf_kill(data);
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
  }
  
 -void ipw_link_up(struct ipw_priv *priv)
 +static void ipw_link_up(struct ipw_priv *priv)
  {
        priv->last_seq_num = -1;
        priv->last_frag_num = -1;
  static void ipw_bg_link_up(void *data)
  {
        struct ipw_priv *priv = data;
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        ipw_link_up(data);
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
  }
  
 -void ipw_link_down(struct ipw_priv *priv)
 +static void ipw_link_down(struct ipw_priv *priv)
  {
        ipw_led_link_down(priv);
        netif_carrier_off(priv->net_dev);
  static void ipw_bg_link_down(void *data)
  {
        struct ipw_priv *priv = data;
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        ipw_link_down(data);
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
  }
  
  static int ipw_setup_deferred_work(struct ipw_priv *priv)
@@@ -10299,20 -10292,6 +10299,20 @@@ static int ipw_config(struct ipw_priv *
  
        /* set basic system config settings */
        init_sys_config(&priv->sys_config);
 +
 +      /* Support Bluetooth if we have BT h/w on board, and user wants to.
 +       * Does not support BT priority yet (don't abort or defer our Tx) */
 +      if (bt_coexist) {
 +              unsigned char bt_caps = priv->eeprom[EEPROM_SKU_CAPABILITY];
 +
 +              if (bt_caps & EEPROM_SKU_CAP_BT_CHANNEL_SIG)
 +                      priv->sys_config.bt_coexistence
 +                          |= CFG_BT_COEXISTENCE_SIGNAL_CHNL;
 +              if (bt_caps & EEPROM_SKU_CAP_BT_OOB)
 +                      priv->sys_config.bt_coexistence
 +                          |= CFG_BT_COEXISTENCE_OOB;
 +      }
 +
        if (priv->ieee->iw_mode == IW_MODE_ADHOC)
                priv->sys_config.answer_broadcast_ssid_probe = 1;
        else
@@@ -10803,9 -10782,9 +10803,9 @@@ static int ipw_up(struct ipw_priv *priv
  static void ipw_bg_up(void *data)
  {
        struct ipw_priv *priv = data;
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        ipw_up(data);
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
  }
  
  static void ipw_deinit(struct ipw_priv *priv)
@@@ -10874,23 -10853,23 +10874,23 @@@ static void ipw_down(struct ipw_priv *p
  static void ipw_bg_down(void *data)
  {
        struct ipw_priv *priv = data;
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
        ipw_down(data);
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
  }
  
  /* Called by register_netdev() */
  static int ipw_net_init(struct net_device *dev)
  {
        struct ipw_priv *priv = ieee80211_priv(dev);
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
  
        if (ipw_up(priv)) {
 -              up(&priv->sem);
 +              mutex_unlock(&priv->mutex);
                return -EIO;
        }
  
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
        return 0;
  }
  
@@@ -10980,7 -10959,7 +10980,7 @@@ static int ipw_pci_probe(struct pci_de
        for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++)
                INIT_LIST_HEAD(&priv->ibss_mac_hash[i]);
  
 -      init_MUTEX(&priv->sem);
 +      mutex_init(&priv->mutex);
        if (pci_enable_device(pdev)) {
                err = -ENODEV;
                goto out_free_ieee80211;
        SET_MODULE_OWNER(net_dev);
        SET_NETDEV_DEV(net_dev, &pdev->dev);
  
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
  
        priv->ieee->hard_start_xmit = ipw_net_hard_start_xmit;
        priv->ieee->set_security = shim__set_security;
        err = sysfs_create_group(&pdev->dev.kobj, &ipw_attribute_group);
        if (err) {
                IPW_ERROR("failed to create sysfs device attributes\n");
 -              up(&priv->sem);
 +              mutex_unlock(&priv->mutex);
                goto out_release_irq;
        }
  
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
        err = register_netdev(net_dev);
        if (err) {
                IPW_ERROR("failed to register network device\n");
@@@ -11112,13 -11091,13 +11112,13 @@@ static void ipw_pci_remove(struct pci_d
        if (!priv)
                return;
  
 -      down(&priv->sem);
 +      mutex_lock(&priv->mutex);
  
        priv->status |= STATUS_EXIT_PENDING;
        ipw_down(priv);
        sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group);
  
 -      up(&priv->sem);
 +      mutex_unlock(&priv->mutex);
  
        unregister_netdev(priv->net_dev);
  
@@@ -11302,18 -11281,12 +11302,18 @@@ module_param(mode, int, 0444)
  MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS)");
  #endif
  
 +module_param(bt_coexist, int, 0444);
 +MODULE_PARM_DESC(bt_coexist, "enable bluetooth coexistence (default off)");
 +
  module_param(hwcrypto, int, 0444);
 -MODULE_PARM_DESC(hwcrypto, "enable hardware crypto (default on)");
 +MODULE_PARM_DESC(hwcrypto, "enable hardware crypto (default off)");
  
  module_param(cmdlog, int, 0444);
  MODULE_PARM_DESC(cmdlog,
                 "allocate a ring buffer for logging firmware commands");
  
 +module_param(roaming, int, 0444);
 +MODULE_PARM_DESC(roaming, "enable roaming support (default on)");
 +
  module_exit(ipw_exit);
  module_init(ipw_init);