spelling fixes
[safe/jmp/linux-2.6] / drivers / net / wireless / ipw2100.c
index 23a74ac..94aeb23 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
 
-  Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
+  Copyright(c) 2003 - 2006 Intel Corporation. All rights reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2 of the GNU General Public License as
@@ -167,15 +167,15 @@ that only one external action is invoked at a time.
 
 #include "ipw2100.h"
 
-#define IPW2100_VERSION "1.1.1"
+#define IPW2100_VERSION "git-1.2.2"
 
 #define DRV_NAME       "ipw2100"
 #define DRV_VERSION    IPW2100_VERSION
 #define DRV_DESCRIPTION        "Intel(R) PRO/Wireless 2100 Network Driver"
-#define DRV_COPYRIGHT  "Copyright(c) 2003-2005 Intel Corporation"
+#define DRV_COPYRIGHT  "Copyright(c) 2003-2006 Intel Corporation"
 
 /* Debugging stuff */
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 #define CONFIG_IPW2100_RX_DEBUG        /* Reception debugging */
 #endif
 
@@ -208,7 +208,7 @@ MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])");
 
 static u32 ipw2100_debug_level = IPW_DL_NONE;
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 #define IPW_DEBUG(level, message...) \
 do { \
        if (ipw2100_debug_level & (level)) { \
@@ -219,9 +219,9 @@ do { \
 } while (0)
 #else
 #define IPW_DEBUG(level, message...) do {} while (0)
-#endif                         /* CONFIG_IPW_DEBUG */
+#endif                         /* CONFIG_IPW2100_DEBUG */
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 static const char *command_types[] = {
        "undefined",
        "unused",               /* HOST_ATTENTION */
@@ -411,7 +411,7 @@ static inline void write_nic_dword_auto_inc(struct net_device *dev, u32 val)
        write_register(dev, IPW_REG_AUTOINCREMENT_DATA, val);
 }
 
-static inline void write_nic_memory(struct net_device *dev, u32 addr, u32 len,
+static void write_nic_memory(struct net_device *dev, u32 addr, u32 len,
                                    const u8 * buf)
 {
        u32 aligned_addr;
@@ -449,7 +449,7 @@ static inline void write_nic_memory(struct net_device *dev, u32 addr, u32 len,
                                    *buf);
 }
 
-static inline void read_nic_memory(struct net_device *dev, u32 addr, u32 len,
+static void read_nic_memory(struct net_device *dev, u32 addr, u32 len,
                                   u8 * buf)
 {
        u32 aligned_addr;
@@ -657,7 +657,7 @@ static void printk_buf(int level, const u8 * data, u32 len)
 
 #define MAX_RESET_BACKOFF 10
 
-static inline void schedule_reset(struct ipw2100_priv *priv)
+static void schedule_reset(struct ipw2100_priv *priv)
 {
        unsigned long now = get_seconds();
 
@@ -1130,7 +1130,7 @@ static inline void ipw2100_hw_set_gpio(struct ipw2100_priv *priv)
        write_register(priv->net_dev, IPW_REG_GPIO, reg);
 }
 
-static inline int rf_kill_active(struct ipw2100_priv *priv)
+static int rf_kill_active(struct ipw2100_priv *priv)
 {
 #define MAX_RF_KILL_CHECKS 5
 #define RF_KILL_CHECK_DELAY 40
@@ -1418,7 +1418,7 @@ static int ipw2100_enable_adapter(struct ipw2100_priv *priv)
        if (priv->status & STATUS_ENABLED)
                return 0;
 
-       down(&priv->adapter_sem);
+       mutex_lock(&priv->adapter_mutex);
 
        if (rf_kill_active(priv)) {
                IPW_DEBUG_HC("Command aborted due to RF kill active.\n");
@@ -1444,7 +1444,7 @@ static int ipw2100_enable_adapter(struct ipw2100_priv *priv)
        }
 
       fail_up:
-       up(&priv->adapter_sem);
+       mutex_unlock(&priv->adapter_mutex);
        return err;
 }
 
@@ -1485,7 +1485,7 @@ static int ipw2100_hw_stop_adapter(struct ipw2100_priv *priv)
                 *
                 * Sending the PREPARE_FOR_POWER_DOWN will restrict the
                 * hardware from going into standby mode and will transition
-                * out of D0-standy if it is already in that state.
+                * out of D0-standby if it is already in that state.
                 *
                 * STATUS_PREPARE_POWER_DOWN_COMPLETE will be sent by the
                 * driver upon completion.  Once received, the driver can
@@ -1576,7 +1576,7 @@ static int ipw2100_disable_adapter(struct ipw2100_priv *priv)
                cancel_delayed_work(&priv->hang_check);
        }
 
-       down(&priv->adapter_sem);
+       mutex_lock(&priv->adapter_mutex);
 
        err = ipw2100_hw_send_command(priv, &cmd);
        if (err) {
@@ -1595,7 +1595,7 @@ static int ipw2100_disable_adapter(struct ipw2100_priv *priv)
        IPW_DEBUG_INFO("TODO: implement scan state machine\n");
 
       fail_up:
-       up(&priv->adapter_sem);
+       mutex_unlock(&priv->adapter_mutex);
        return err;
 }
 
@@ -1672,6 +1672,18 @@ static int ipw2100_start_scan(struct ipw2100_priv *priv)
        return err;
 }
 
+static const struct ieee80211_geo ipw_geos[] = {
+       {                       /* Restricted */
+        "---",
+        .bg_channels = 14,
+        .bg = {{2412, 1}, {2417, 2}, {2422, 3},
+               {2427, 4}, {2432, 5}, {2437, 6},
+               {2442, 7}, {2447, 8}, {2452, 9},
+               {2457, 10}, {2462, 11}, {2467, 12},
+               {2472, 13}, {2484, 14}},
+        },
+};
+
 static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
 {
        unsigned long flags;
@@ -1727,6 +1739,13 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
                goto exit;
        }
 
+       /* Initialize the geo */
+       if (ieee80211_set_geo(priv->ieee, &ipw_geos[0])) {
+               printk(KERN_WARNING DRV_NAME "Could not set geo\n");
+               return 0;
+       }
+       priv->ieee->freq_band = IEEE80211_24GHZ_BAND;
+
        lock = LOCK_NONE;
        if (ipw2100_set_ordinal(priv, IPW_ORD_PERS_DB_LOCK, &lock, &ord_len)) {
                printk(KERN_ERR DRV_NAME
@@ -1869,7 +1888,7 @@ static void ipw2100_reset_adapter(struct ipw2100_priv *priv)
        priv->status |= STATUS_RESET_PENDING;
        spin_unlock_irqrestore(&priv->low_lock, flags);
 
-       down(&priv->action_sem);
+       mutex_lock(&priv->action_mutex);
        /* stop timed checks so that they don't interfere with reset */
        priv->stop_hang_check = 1;
        cancel_delayed_work(&priv->hang_check);
@@ -1879,7 +1898,7 @@ static void ipw2100_reset_adapter(struct ipw2100_priv *priv)
                wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
 
        ipw2100_up(priv, 0);
-       up(&priv->action_sem);
+       mutex_unlock(&priv->action_mutex);
 
 }
 
@@ -2081,7 +2100,7 @@ static void isr_scan_complete(struct ipw2100_priv *priv, u32 status)
        priv->status &= ~STATUS_SCANNING;
 }
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 #define IPW2100_HANDLER(v, f) { v, f, # v }
 struct ipw2100_status_indicator {
        int status;
@@ -2094,7 +2113,7 @@ struct ipw2100_status_indicator {
        int status;
        void (*cb) (struct ipw2100_priv * priv, u32 status);
 };
-#endif                         /* CONFIG_IPW_DEBUG */
+#endif                         /* CONFIG_IPW2100_DEBUG */
 
 static void isr_indicate_scanning(struct ipw2100_priv *priv, u32 status)
 {
@@ -2149,7 +2168,7 @@ static void isr_status_change(struct ipw2100_priv *priv, int status)
 static void isr_rx_complete_command(struct ipw2100_priv *priv,
                                    struct ipw2100_cmd_header *cmd)
 {
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
        if (cmd->host_command_reg < ARRAY_SIZE(command_types)) {
                IPW_DEBUG_HC("Command completed '%s (%d)'\n",
                             command_types[cmd->host_command_reg],
@@ -2167,7 +2186,7 @@ static void isr_rx_complete_command(struct ipw2100_priv *priv,
        wake_up_interruptible(&priv->wait_command_queue);
 }
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 static const char *frame_types[] = {
        "COMMAND_STATUS_VAL",
        "STATUS_CHANGE_VAL",
@@ -2177,7 +2196,7 @@ static const char *frame_types[] = {
 };
 #endif
 
-static inline int ipw2100_alloc_skb(struct ipw2100_priv *priv,
+static int ipw2100_alloc_skb(struct ipw2100_priv *priv,
                                    struct ipw2100_rx_packet *packet)
 {
        packet->skb = dev_alloc_skb(sizeof(struct ipw2100_rx));
@@ -2201,7 +2220,18 @@ static inline int ipw2100_alloc_skb(struct ipw2100_priv *priv,
 #define SEARCH_SNAPSHOT 1
 
 #define SNAPSHOT_ADDR(ofs) (priv->snapshot[((ofs) >> 12) & 0xff] + ((ofs) & 0xfff))
-static inline int ipw2100_snapshot_alloc(struct ipw2100_priv *priv)
+static void ipw2100_snapshot_free(struct ipw2100_priv *priv)
+{
+       int i;
+       if (!priv->snapshot[0])
+               return;
+       for (i = 0; i < 0x30; i++)
+               kfree(priv->snapshot[i]);
+       priv->snapshot[0] = NULL;
+}
+
+#ifdef CONFIG_IPW2100_DEBUG_C3
+static int ipw2100_snapshot_alloc(struct ipw2100_priv *priv)
 {
        int i;
        if (priv->snapshot[0])
@@ -2221,17 +2251,7 @@ static inline int ipw2100_snapshot_alloc(struct ipw2100_priv *priv)
        return 1;
 }
 
-static inline void ipw2100_snapshot_free(struct ipw2100_priv *priv)
-{
-       int i;
-       if (!priv->snapshot[0])
-               return;
-       for (i = 0; i < 0x30; i++)
-               kfree(priv->snapshot[i]);
-       priv->snapshot[0] = NULL;
-}
-
-static inline u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 * in_buf,
+static u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 * in_buf,
                                    size_t len, int mode)
 {
        u32 i, j;
@@ -2269,6 +2289,7 @@ static inline u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 * in_buf,
 
        return ret;
 }
+#endif
 
 /*
  *
@@ -2288,9 +2309,9 @@ static inline u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 * in_buf,
 static u8 packet_data[IPW_RX_NIC_BUFFER_LENGTH];
 #endif
 
-static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv, int i)
+static void ipw2100_corruption_detected(struct ipw2100_priv *priv, int i)
 {
-#ifdef CONFIG_IPW_DEBUG_C3
+#ifdef CONFIG_IPW2100_DEBUG_C3
        struct ipw2100_status *status = &priv->status_queue.drv[i];
        u32 match, reg;
        int j;
@@ -2312,7 +2333,7 @@ static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv, int i)
        }
 #endif
 
-#ifdef CONFIG_IPW_DEBUG_C3
+#ifdef CONFIG_IPW2100_DEBUG_C3
        /* Halt the fimrware so we can get a good image */
        write_register(priv->net_dev, IPW_REG_RESET_REG,
                       IPW_AUX_HOST_RESET_REG_STOP_MASTER);
@@ -2346,7 +2367,7 @@ static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv, int i)
        schedule_reset(priv);
 }
 
-static inline void isr_rx(struct ipw2100_priv *priv, int i,
+static void isr_rx(struct ipw2100_priv *priv, int i,
                          struct ieee80211_rx_stats *stats)
 {
        struct ipw2100_status *status = &priv->status_queue.drv[i];
@@ -2369,15 +2390,6 @@ static inline void isr_rx(struct ipw2100_priv *priv, int i,
                IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
                return;
        }
-#ifdef CONFIG_IPW2100_MONITOR
-       if (unlikely(priv->ieee->iw_mode == IW_MODE_MONITOR &&
-                    priv->config & CFG_CRC_CHECK &&
-                    status->flags & IPW_STATUS_FLAG_CRC_ERROR)) {
-               IPW_DEBUG_RX("CRC error in packet.  Dropping.\n");
-               priv->ieee->stats.rx_errors++;
-               return;
-       }
-#endif
 
        if (unlikely(priv->ieee->iw_mode != IW_MODE_MONITOR &&
                     !(priv->status & STATUS_ASSOCIATED))) {
@@ -2425,7 +2437,90 @@ static inline void isr_rx(struct ipw2100_priv *priv, int i,
        priv->rx_queue.drv[i].host_addr = packet->dma_addr;
 }
 
-static inline int ipw2100_corruption_check(struct ipw2100_priv *priv, int i)
+#ifdef CONFIG_IPW2100_MONITOR
+
+static void isr_rx_monitor(struct ipw2100_priv *priv, int i,
+                  struct ieee80211_rx_stats *stats)
+{
+       struct ipw2100_status *status = &priv->status_queue.drv[i];
+       struct ipw2100_rx_packet *packet = &priv->rx_buffers[i];
+
+       /* Magic struct that slots into the radiotap header -- no reason
+        * to build this manually element by element, we can write it much
+        * more efficiently than we can parse it. ORDER MATTERS HERE */
+       struct ipw_rt_hdr {
+               struct ieee80211_radiotap_header rt_hdr;
+               s8 rt_dbmsignal; /* signal in dbM, kluged to signed */
+       } *ipw_rt;
+
+       IPW_DEBUG_RX("Handler...\n");
+
+       if (unlikely(status->frame_size > skb_tailroom(packet->skb) -
+                               sizeof(struct ipw_rt_hdr))) {
+               IPW_DEBUG_INFO("%s: frame_size (%u) > skb_tailroom (%u)!"
+                              "  Dropping.\n",
+                              priv->net_dev->name,
+                              status->frame_size,
+                              skb_tailroom(packet->skb));
+               priv->ieee->stats.rx_errors++;
+               return;
+       }
+
+       if (unlikely(!netif_running(priv->net_dev))) {
+               priv->ieee->stats.rx_errors++;
+               priv->wstats.discard.misc++;
+               IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
+               return;
+       }
+
+       if (unlikely(priv->config & CFG_CRC_CHECK &&
+                    status->flags & IPW_STATUS_FLAG_CRC_ERROR)) {
+               IPW_DEBUG_RX("CRC error in packet.  Dropping.\n");
+               priv->ieee->stats.rx_errors++;
+               return;
+       }
+
+       pci_unmap_single(priv->pci_dev, packet->dma_addr,
+                        sizeof(struct ipw2100_rx), PCI_DMA_FROMDEVICE);
+       memmove(packet->skb->data + sizeof(struct ipw_rt_hdr),
+               packet->skb->data, status->frame_size);
+
+       ipw_rt = (struct ipw_rt_hdr *) packet->skb->data;
+
+       ipw_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
+       ipw_rt->rt_hdr.it_pad = 0; /* always good to zero */
+       ipw_rt->rt_hdr.it_len = sizeof(struct ipw_rt_hdr); /* total hdr+data */
+
+       ipw_rt->rt_hdr.it_present = 1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL;
+
+       ipw_rt->rt_dbmsignal = status->rssi + IPW2100_RSSI_TO_DBM;
+
+       skb_put(packet->skb, status->frame_size + sizeof(struct ipw_rt_hdr));
+
+       if (!ieee80211_rx(priv->ieee, packet->skb, stats)) {
+               priv->ieee->stats.rx_errors++;
+
+               /* ieee80211_rx failed, so it didn't free the SKB */
+               dev_kfree_skb_any(packet->skb);
+               packet->skb = NULL;
+       }
+
+       /* We need to allocate a new SKB and attach it to the RDB. */
+       if (unlikely(ipw2100_alloc_skb(priv, packet))) {
+               IPW_DEBUG_WARNING(
+                       "%s: Unable to allocate SKB onto RBD ring - disabling "
+                       "adapter.\n", priv->net_dev->name);
+               /* TODO: schedule adapter shutdown */
+               IPW_DEBUG_INFO("TODO: Shutdown adapter...\n");
+       }
+
+       /* Update the RDB entry */
+       priv->rx_queue.drv[i].host_addr = packet->dma_addr;
+}
+
+#endif
+
+static int ipw2100_corruption_check(struct ipw2100_priv *priv, int i)
 {
        struct ipw2100_status *status = &priv->status_queue.drv[i];
        struct ipw2100_rx *u = priv->rx_buffers[i].rxp;
@@ -2481,7 +2576,7 @@ static inline int ipw2100_corruption_check(struct ipw2100_priv *priv, int i)
  * The WRITE index is cached in the variable 'priv->rx_queue.next'.
  *
  */
-static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
+static void __ipw2100_rx_process(struct ipw2100_priv *priv)
 {
        struct ipw2100_bd_queue *rxq = &priv->rx_queue;
        struct ipw2100_status_queue *sq = &priv->status_queue;
@@ -2556,7 +2651,7 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
                case P8023_DATA_VAL:
 #ifdef CONFIG_IPW2100_MONITOR
                        if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
-                               isr_rx(priv, i, &stats);
+                               isr_rx_monitor(priv, i, &stats);
                                break;
                        }
 #endif
@@ -2634,7 +2729,7 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
  * for use by future command and data packets.
  *
  */
-static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
+static int __ipw2100_tx_process(struct ipw2100_priv *priv)
 {
        struct ipw2100_bd_queue *txq = &priv->tx_queue;
        struct ipw2100_bd *tbd;
@@ -2716,7 +2811,7 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
        list_del(element);
        DEC_STAT(&priv->fw_pend_stat);
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
        {
                int i = txq->oldest;
                IPW_DEBUG_TX("TX%d V=%p P=%04X T=%04X L=%d\n", i,
@@ -2782,7 +2877,7 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
                               "something else: ids %d=%d.\n",
                               priv->net_dev->name, txq->oldest, packet->index);
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
                if (packet->info.c_struct.cmd->host_command_reg <
                    sizeof(command_types) / sizeof(*command_types))
                        IPW_DEBUG_TX("Command '%s (%d)' processed: %d.\n",
@@ -2975,7 +3070,7 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
 
                IPW_DEBUG_TX("data header tbd TX%d P=%08x L=%d\n",
                             packet->index, tbd->host_addr, tbd->buf_length);
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
                if (packet->info.d_struct.txb->nr_frags > 1)
                        IPW_DEBUG_FRAG("fragment Tx: %d frames\n",
                                       packet->info.d_struct.txb->nr_frags);
@@ -3748,6 +3843,8 @@ static ssize_t store_memory(struct device *d, struct device_attribute *attr,
        struct net_device *dev = priv->net_dev;
        const char *p = buf;
 
+       (void)dev;              /* kill unused-var warning for debug-only code */
+
        if (count < 1)
                return count;
 
@@ -3825,7 +3922,7 @@ static ssize_t show_stats(struct device *d, struct device_attribute *attr,
                       priv->rx_interrupts, priv->inta_other);
        out += sprintf(out, "firmware resets: %d\n", priv->resets);
        out += sprintf(out, "firmware hangs: %d\n", priv->hangs);
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
        out += sprintf(out, "packet mismatch image: %s\n",
                       priv->snapshot[0] ? "YES" : "NO");
 #endif
@@ -3859,7 +3956,7 @@ static int ipw2100_switch_mode(struct ipw2100_priv *priv, u32 mode)
 #ifdef CONFIG_IPW2100_MONITOR
        case IW_MODE_MONITOR:
                priv->last_mode = priv->ieee->iw_mode;
-               priv->net_dev->type = ARPHRD_IEEE80211;
+               priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
                break;
 #endif                         /* CONFIG_IPW2100_MONITOR */
        }
@@ -3980,7 +4077,7 @@ static ssize_t show_bssinfo(struct device *d, struct device_attribute *attr,
 
 static DEVICE_ATTR(bssinfo, S_IRUGO, show_bssinfo, NULL);
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 static ssize_t show_debug_level(struct device_driver *d, char *buf)
 {
        return sprintf(buf, "0x%08X\n", ipw2100_debug_level);
@@ -4009,7 +4106,7 @@ static ssize_t store_debug_level(struct device_driver *d,
 
 static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, show_debug_level,
                   store_debug_level);
-#endif                         /* CONFIG_IPW_DEBUG */
+#endif                         /* CONFIG_IPW2100_DEBUG */
 
 static ssize_t show_fatal_error(struct device *d,
                                struct device_attribute *attr, char *buf)
@@ -4066,6 +4163,8 @@ static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
        unsigned long val;
        char *p = buffer;
 
+       (void)dev;              /* kill unused-var warning for debug-only code */
+
        IPW_DEBUG_INFO("enter\n");
 
        strncpy(buffer, buf, len);
@@ -4113,7 +4212,7 @@ static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio)
        IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO  %s\n",
                          disable_radio ? "OFF" : "ON");
 
-       down(&priv->action_sem);
+       mutex_lock(&priv->action_mutex);
 
        if (disable_radio) {
                priv->status |= STATUS_RF_KILL_SW;
@@ -4131,7 +4230,7 @@ static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio)
                        schedule_reset(priv);
        }
 
-       up(&priv->action_sem);
+       mutex_unlock(&priv->action_mutex);
        return 1;
 }
 
@@ -4933,7 +5032,7 @@ static int ipw2100_set_mandatory_bssid(struct ipw2100_priv *priv, u8 * bssid,
        };
        int err;
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
        if (bssid != NULL)
                IPW_DEBUG_HC("MANDATORY_BSSID: %02X:%02X:%02X:%02X:%02X:%02X\n",
                             bssid[0], bssid[1], bssid[2], bssid[3], bssid[4],
@@ -5101,12 +5200,13 @@ static int ipw2100_set_tx_power(struct ipw2100_priv *priv, u32 tx_power)
                .host_command_length = 4
        };
        int err = 0;
+       u32 tmp = tx_power;
 
        if (tx_power != IPW_TX_POWER_DEFAULT)
-               tx_power = (tx_power - IPW_TX_POWER_MIN_DBM) * 16 /
-                   (IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM);
+               tmp = (tx_power - IPW_TX_POWER_MIN_DBM) * 16 /
+                     (IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM);
 
-       cmd.host_command_parameters[0] = tx_power;
+       cmd.host_command_parameters[0] = tmp;
 
        if (priv->ieee->iw_mode == IW_MODE_ADHOC)
                err = ipw2100_hw_send_command(priv, &cmd);
@@ -5359,9 +5459,12 @@ static int ipw2100_configure_security(struct ipw2100_priv *priv, int batch_mode)
                                                     SEC_LEVEL_0, 0, 1);
        } else {
                auth_mode = IPW_AUTH_OPEN;
-               if ((priv->ieee->sec.flags & SEC_AUTH_MODE) &&
-                   (priv->ieee->sec.auth_mode == WLAN_AUTH_SHARED_KEY))
-                       auth_mode = IPW_AUTH_SHARED;
+               if (priv->ieee->sec.flags & SEC_AUTH_MODE) {
+                       if (priv->ieee->sec.auth_mode == WLAN_AUTH_SHARED_KEY)
+                               auth_mode = IPW_AUTH_SHARED;
+                       else if (priv->ieee->sec.auth_mode == WLAN_AUTH_LEAP)
+                               auth_mode = IPW_AUTH_LEAP_CISCO_ID;
+               }
 
                sec_level = SEC_LEVEL_0;
                if (priv->ieee->sec.flags & SEC_LEVEL)
@@ -5431,7 +5534,7 @@ static void shim__set_security(struct net_device *dev,
        struct ipw2100_priv *priv = ieee80211_priv(dev);
        int i, force_update = 0;
 
-       down(&priv->action_sem);
+       mutex_lock(&priv->action_mutex);
        if (!(priv->status & STATUS_INITIALIZED))
                goto done;
 
@@ -5504,7 +5607,7 @@ static void shim__set_security(struct net_device *dev,
        if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)))
                ipw2100_configure_security(priv, 0);
       done:
-       up(&priv->action_sem);
+       mutex_unlock(&priv->action_mutex);
 }
 
 static int ipw2100_adapter_setup(struct ipw2100_priv *priv)
@@ -5628,7 +5731,7 @@ static int ipw2100_set_address(struct net_device *dev, void *p)
        if (!is_valid_ether_addr(addr->sa_data))
                return -EADDRNOTAVAIL;
 
-       down(&priv->action_sem);
+       mutex_lock(&priv->action_mutex);
 
        priv->config |= CFG_CUSTOM_MAC;
        memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN);
@@ -5638,12 +5741,12 @@ static int ipw2100_set_address(struct net_device *dev, void *p)
                goto done;
 
        priv->reset_backoff = 0;
-       up(&priv->action_sem);
+       mutex_unlock(&priv->action_mutex);
        ipw2100_reset_adapter(priv);
        return 0;
 
       done:
-       up(&priv->action_sem);
+       mutex_unlock(&priv->action_mutex);
        return err;
 }
 
@@ -5731,70 +5834,6 @@ static struct net_device_stats *ipw2100_stats(struct net_device *dev)
        return &priv->ieee->stats;
 }
 
-#if WIRELESS_EXT < 18
-/* Support for wpa_supplicant before WE-18, deprecated. */
-
-/* following definitions must match definitions in driver_ipw.c */
-
-#define IPW2100_IOCTL_WPA_SUPPLICANT           SIOCIWFIRSTPRIV+30
-
-#define IPW2100_CMD_SET_WPA_PARAM              1
-#define        IPW2100_CMD_SET_WPA_IE                  2
-#define IPW2100_CMD_SET_ENCRYPTION             3
-#define IPW2100_CMD_MLME                       4
-
-#define IPW2100_PARAM_WPA_ENABLED              1
-#define IPW2100_PARAM_TKIP_COUNTERMEASURES     2
-#define IPW2100_PARAM_DROP_UNENCRYPTED         3
-#define IPW2100_PARAM_PRIVACY_INVOKED          4
-#define IPW2100_PARAM_AUTH_ALGS                        5
-#define IPW2100_PARAM_IEEE_802_1X              6
-
-#define IPW2100_MLME_STA_DEAUTH                        1
-#define IPW2100_MLME_STA_DISASSOC              2
-
-#define IPW2100_CRYPT_ERR_UNKNOWN_ALG          2
-#define IPW2100_CRYPT_ERR_UNKNOWN_ADDR         3
-#define IPW2100_CRYPT_ERR_CRYPT_INIT_FAILED    4
-#define IPW2100_CRYPT_ERR_KEY_SET_FAILED       5
-#define IPW2100_CRYPT_ERR_TX_KEY_SET_FAILED    6
-#define IPW2100_CRYPT_ERR_CARD_CONF_FAILED     7
-
-#define        IPW2100_CRYPT_ALG_NAME_LEN              16
-
-struct ipw2100_param {
-       u32 cmd;
-       u8 sta_addr[ETH_ALEN];
-       union {
-               struct {
-                       u8 name;
-                       u32 value;
-               } wpa_param;
-               struct {
-                       u32 len;
-                       u8 reserved[32];
-                       u8 data[0];
-               } wpa_ie;
-               struct {
-                       u32 command;
-                       u32 reason_code;
-               } mlme;
-               struct {
-                       u8 alg[IPW2100_CRYPT_ALG_NAME_LEN];
-                       u8 set_tx;
-                       u32 err;
-                       u8 idx;
-                       u8 seq[8];      /* sequence counter (set: RX, get: TX) */
-                       u16 key_len;
-                       u8 key[0];
-               } crypt;
-
-       } u;
-};
-
-/* end of driver_ipw.c code */
-#endif                         /* WIRELESS_EXT < 18 */
-
 static int ipw2100_wpa_enable(struct ipw2100_priv *priv, int value)
 {
        /* This is called when wpa_supplicant loads and closes the driver
@@ -5803,11 +5842,6 @@ static int ipw2100_wpa_enable(struct ipw2100_priv *priv, int value)
        return 0;
 }
 
-#if WIRELESS_EXT < 18
-#define IW_AUTH_ALG_OPEN_SYSTEM                        0x1
-#define IW_AUTH_ALG_SHARED_KEY                 0x2
-#endif
-
 static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value)
 {
 
@@ -5823,6 +5857,9 @@ static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value)
        } 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;
 
@@ -5834,8 +5871,8 @@ static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value)
        return ret;
 }
 
-void ipw2100_wpa_assoc_frame(struct ipw2100_priv *priv,
-                            char *wpa_ie, int wpa_ie_len)
+static void ipw2100_wpa_assoc_frame(struct ipw2100_priv *priv,
+                                   char *wpa_ie, int wpa_ie_len)
 {
 
        struct ipw2100_wpa_assoc_frame frame;
@@ -5851,365 +5888,6 @@ void ipw2100_wpa_assoc_frame(struct ipw2100_priv *priv,
        ipw2100_set_wpa_ie(priv, &frame, 0);
 }
 
-#if WIRELESS_EXT < 18
-static int ipw2100_wpa_set_param(struct net_device *dev, u8 name, u32 value)
-{
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
-       struct ieee80211_crypt_data *crypt;
-       unsigned long flags;
-       int ret = 0;
-
-       switch (name) {
-       case IPW2100_PARAM_WPA_ENABLED:
-               ret = ipw2100_wpa_enable(priv, value);
-               break;
-
-       case IPW2100_PARAM_TKIP_COUNTERMEASURES:
-               crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
-               if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags) {
-                       IPW_DEBUG_WARNING("Can't set TKIP countermeasures: "
-                                         "crypt not set!\n");
-                       break;
-               }
-
-               flags = crypt->ops->get_flags(crypt->priv);
-
-               if (value)
-                       flags |= IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
-               else
-                       flags &= ~IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
-
-               crypt->ops->set_flags(flags, crypt->priv);
-
-               break;
-
-       case IPW2100_PARAM_DROP_UNENCRYPTED:{
-                       /* See IW_AUTH_DROP_UNENCRYPTED handling for details */
-                       struct ieee80211_security sec = {
-                               .flags = SEC_ENABLED,
-                               .enabled = value,
-                       };
-                       priv->ieee->drop_unencrypted = value;
-                       /* We only change SEC_LEVEL for open mode. Others
-                        * are set by ipw_wpa_set_encryption.
-                        */
-                       if (!value) {
-                               sec.flags |= SEC_LEVEL;
-                               sec.level = SEC_LEVEL_0;
-                       } else {
-                               sec.flags |= SEC_LEVEL;
-                               sec.level = SEC_LEVEL_1;
-                       }
-                       if (priv->ieee->set_security)
-                               priv->ieee->set_security(priv->ieee->dev, &sec);
-                       break;
-               }
-
-       case IPW2100_PARAM_PRIVACY_INVOKED:
-               priv->ieee->privacy_invoked = value;
-               break;
-
-       case IPW2100_PARAM_AUTH_ALGS:
-               ret = ipw2100_wpa_set_auth_algs(priv, value);
-               break;
-
-       case IPW2100_PARAM_IEEE_802_1X:
-               priv->ieee->ieee802_1x = value;
-               break;
-
-       default:
-               printk(KERN_ERR DRV_NAME ": %s: Unknown WPA param: %d\n",
-                      dev->name, name);
-               ret = -EOPNOTSUPP;
-       }
-
-       return ret;
-}
-
-static int ipw2100_wpa_mlme(struct net_device *dev, int command, int reason)
-{
-
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
-       int ret = 0;
-
-       switch (command) {
-       case IPW2100_MLME_STA_DEAUTH:
-               // silently ignore
-               break;
-
-       case IPW2100_MLME_STA_DISASSOC:
-               ipw2100_disassociate_bssid(priv);
-               break;
-
-       default:
-               printk(KERN_ERR DRV_NAME ": %s: Unknown MLME request: %d\n",
-                      dev->name, command);
-               ret = -EOPNOTSUPP;
-       }
-
-       return ret;
-}
-
-static int ipw2100_wpa_set_wpa_ie(struct net_device *dev,
-                                 struct ipw2100_param *param, int plen)
-{
-
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
-       struct ieee80211_device *ieee = priv->ieee;
-       u8 *buf;
-
-       if (!ieee->wpa_enabled)
-               return -EOPNOTSUPP;
-
-       if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
-           (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
-               return -EINVAL;
-
-       if (param->u.wpa_ie.len) {
-               buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL);
-               if (buf == NULL)
-                       return -ENOMEM;
-
-               memcpy(buf, param->u.wpa_ie.data, param->u.wpa_ie.len);
-
-               kfree(ieee->wpa_ie);
-               ieee->wpa_ie = buf;
-               ieee->wpa_ie_len = param->u.wpa_ie.len;
-
-       } else {
-               kfree(ieee->wpa_ie);
-               ieee->wpa_ie = NULL;
-               ieee->wpa_ie_len = 0;
-       }
-
-       ipw2100_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len);
-
-       return 0;
-}
-
-/* implementation borrowed from hostap driver */
-
-static int ipw2100_wpa_set_encryption(struct net_device *dev,
-                                     struct ipw2100_param *param,
-                                     int param_len)
-{
-       int ret = 0;
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
-       struct ieee80211_device *ieee = priv->ieee;
-       struct ieee80211_crypto_ops *ops;
-       struct ieee80211_crypt_data **crypt;
-
-       struct ieee80211_security sec = {
-               .flags = 0,
-       };
-
-       param->u.crypt.err = 0;
-       param->u.crypt.alg[IPW2100_CRYPT_ALG_NAME_LEN - 1] = '\0';
-
-       if (param_len !=
-           (int)((char *)param->u.crypt.key - (char *)param) +
-           param->u.crypt.key_len) {
-               IPW_DEBUG_INFO("Len mismatch %d, %d\n", param_len,
-                              param->u.crypt.key_len);
-               return -EINVAL;
-       }
-       if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
-           param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
-           param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
-               if (param->u.crypt.idx >= WEP_KEYS)
-                       return -EINVAL;
-               crypt = &ieee->crypt[param->u.crypt.idx];
-       } else {
-               return -EINVAL;
-       }
-
-       sec.flags |= SEC_ENABLED | SEC_ENCRYPT;
-       if (strcmp(param->u.crypt.alg, "none") == 0) {
-               if (crypt) {
-                       sec.enabled = 0;
-                       sec.encrypt = 0;
-                       sec.level = SEC_LEVEL_0;
-                       sec.flags |= SEC_LEVEL;
-                       ieee80211_crypt_delayed_deinit(ieee, crypt);
-               }
-               goto done;
-       }
-       sec.enabled = 1;
-       sec.encrypt = 1;
-
-       ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
-       if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
-               request_module("ieee80211_crypt_wep");
-               ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
-       } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
-               request_module("ieee80211_crypt_tkip");
-               ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
-       } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
-               request_module("ieee80211_crypt_ccmp");
-               ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
-       }
-       if (ops == NULL) {
-               IPW_DEBUG_INFO("%s: unknown crypto alg '%s'\n",
-                              dev->name, param->u.crypt.alg);
-               param->u.crypt.err = IPW2100_CRYPT_ERR_UNKNOWN_ALG;
-               ret = -EINVAL;
-               goto done;
-       }
-
-       if (*crypt == NULL || (*crypt)->ops != ops) {
-               struct ieee80211_crypt_data *new_crypt;
-
-               ieee80211_crypt_delayed_deinit(ieee, crypt);
-
-               new_crypt = (struct ieee80211_crypt_data *)
-                   kmalloc(sizeof(struct ieee80211_crypt_data), GFP_KERNEL);
-               if (new_crypt == NULL) {
-                       ret = -ENOMEM;
-                       goto done;
-               }
-               memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
-               new_crypt->ops = ops;
-               if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
-                       new_crypt->priv =
-                           new_crypt->ops->init(param->u.crypt.idx);
-
-               if (new_crypt->priv == NULL) {
-                       kfree(new_crypt);
-                       param->u.crypt.err =
-                           IPW2100_CRYPT_ERR_CRYPT_INIT_FAILED;
-                       ret = -EINVAL;
-                       goto done;
-               }
-
-               *crypt = new_crypt;
-       }
-
-       if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
-           (*crypt)->ops->set_key(param->u.crypt.key,
-                                  param->u.crypt.key_len, param->u.crypt.seq,
-                                  (*crypt)->priv) < 0) {
-               IPW_DEBUG_INFO("%s: key setting failed\n", dev->name);
-               param->u.crypt.err = IPW2100_CRYPT_ERR_KEY_SET_FAILED;
-               ret = -EINVAL;
-               goto done;
-       }
-
-       if (param->u.crypt.set_tx) {
-               ieee->tx_keyidx = param->u.crypt.idx;
-               sec.active_key = param->u.crypt.idx;
-               sec.flags |= SEC_ACTIVE_KEY;
-       }
-
-       if (ops->name != NULL) {
-
-               if (strcmp(ops->name, "WEP") == 0) {
-                       memcpy(sec.keys[param->u.crypt.idx],
-                              param->u.crypt.key, param->u.crypt.key_len);
-                       sec.key_sizes[param->u.crypt.idx] =
-                           param->u.crypt.key_len;
-                       sec.flags |= (1 << param->u.crypt.idx);
-                       sec.flags |= SEC_LEVEL;
-                       sec.level = SEC_LEVEL_1;
-               } else if (strcmp(ops->name, "TKIP") == 0) {
-                       sec.flags |= SEC_LEVEL;
-                       sec.level = SEC_LEVEL_2;
-               } else if (strcmp(ops->name, "CCMP") == 0) {
-                       sec.flags |= SEC_LEVEL;
-                       sec.level = SEC_LEVEL_3;
-               }
-       }
-      done:
-       if (ieee->set_security)
-               ieee->set_security(ieee->dev, &sec);
-
-       /* Do not reset port if card is in Managed mode since resetting will
-        * generate new IEEE 802.11 authentication which may end up in looping
-        * with IEEE 802.1X.  If your hardware requires a reset after WEP
-        * configuration (for example... Prism2), implement the reset_port in
-        * the callbacks structures used to initialize the 802.11 stack. */
-       if (ieee->reset_on_keychange &&
-           ieee->iw_mode != IW_MODE_INFRA &&
-           ieee->reset_port && ieee->reset_port(dev)) {
-               IPW_DEBUG_INFO("%s: reset_port failed\n", dev->name);
-               param->u.crypt.err = IPW2100_CRYPT_ERR_CARD_CONF_FAILED;
-               return -EINVAL;
-       }
-
-       return ret;
-}
-
-static int ipw2100_wpa_supplicant(struct net_device *dev, struct iw_point *p)
-{
-
-       struct ipw2100_param *param;
-       int ret = 0;
-
-       IPW_DEBUG_IOCTL("wpa_supplicant: len=%d\n", p->length);
-
-       if (p->length < sizeof(struct ipw2100_param) || !p->pointer)
-               return -EINVAL;
-
-       param = (struct ipw2100_param *)kmalloc(p->length, GFP_KERNEL);
-       if (param == NULL)
-               return -ENOMEM;
-
-       if (copy_from_user(param, p->pointer, p->length)) {
-               kfree(param);
-               return -EFAULT;
-       }
-
-       switch (param->cmd) {
-
-       case IPW2100_CMD_SET_WPA_PARAM:
-               ret = ipw2100_wpa_set_param(dev, param->u.wpa_param.name,
-                                           param->u.wpa_param.value);
-               break;
-
-       case IPW2100_CMD_SET_WPA_IE:
-               ret = ipw2100_wpa_set_wpa_ie(dev, param, p->length);
-               break;
-
-       case IPW2100_CMD_SET_ENCRYPTION:
-               ret = ipw2100_wpa_set_encryption(dev, param, p->length);
-               break;
-
-       case IPW2100_CMD_MLME:
-               ret = ipw2100_wpa_mlme(dev, param->u.mlme.command,
-                                      param->u.mlme.reason_code);
-               break;
-
-       default:
-               printk(KERN_ERR DRV_NAME
-                      ": %s: Unknown WPA supplicant request: %d\n", dev->name,
-                      param->cmd);
-               ret = -EOPNOTSUPP;
-
-       }
-
-       if (ret == 0 && copy_to_user(p->pointer, param, p->length))
-               ret = -EFAULT;
-
-       kfree(param);
-       return ret;
-}
-
-static int ipw2100_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-{
-       struct iwreq *wrq = (struct iwreq *)rq;
-       int ret = -1;
-       switch (cmd) {
-       case IPW2100_IOCTL_WPA_SUPPLICANT:
-               ret = ipw2100_wpa_supplicant(dev, &wrq->u.data);
-               return ret;
-
-       default:
-               return -EOPNOTSUPP;
-       }
-
-       return -EOPNOTSUPP;
-}
-#endif                         /* WIRELESS_EXT < 18 */
-
 static void ipw_ethtool_get_drvinfo(struct net_device *dev,
                                    struct ethtool_drvinfo *info)
 {
@@ -6338,14 +6016,12 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
        dev->open = ipw2100_open;
        dev->stop = ipw2100_close;
        dev->init = ipw2100_net_init;
-#if WIRELESS_EXT < 18
-       dev->do_ioctl = ipw2100_ioctl;
-#endif
        dev->get_stats = ipw2100_stats;
        dev->ethtool_ops = &ipw2100_ethtool_ops;
        dev->tx_timeout = ipw2100_tx_timeout;
        dev->wireless_handlers = &ipw2100_wx_handler_def;
-       dev->get_wireless_stats = ipw2100_wx_wireless_stats;
+       priv->wireless_data.ieee80211 = priv->ieee;
+       dev->wireless_data = &priv->wireless_data;
        dev->set_mac_address = ipw2100_set_address;
        dev->watchdog_timeo = 3 * HZ;
        dev->irq = 0;
@@ -6413,8 +6089,8 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
        strcpy(priv->nick, "ipw2100");
 
        spin_lock_init(&priv->low_lock);
-       sema_init(&priv->action_sem, 1);
-       sema_init(&priv->adapter_sem, 1);
+       mutex_init(&priv->action_mutex);
+       mutex_init(&priv->adapter_mutex);
 
        init_waitqueue_head(&priv->wait_command_queue);
 
@@ -6579,7 +6255,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
         * member to call a function that then just turns and calls ipw2100_up.
         * net_dev->init is called after name allocation but before the
         * notifier chain is called */
-       down(&priv->action_sem);
+       mutex_lock(&priv->action_mutex);
        err = register_netdev(dev);
        if (err) {
                printk(KERN_WARNING DRV_NAME
@@ -6615,12 +6291,12 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
 
        priv->status |= STATUS_INITIALIZED;
 
-       up(&priv->action_sem);
+       mutex_unlock(&priv->action_mutex);
 
        return 0;
 
       fail_unlock:
-       up(&priv->action_sem);
+       mutex_unlock(&priv->action_mutex);
 
       fail:
        if (dev) {
@@ -6660,7 +6336,7 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
        struct net_device *dev;
 
        if (priv) {
-               down(&priv->action_sem);
+               mutex_lock(&priv->action_mutex);
 
                priv->status &= ~STATUS_INITIALIZED;
 
@@ -6675,9 +6351,9 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
                /* Take down the hardware */
                ipw2100_down(priv);
 
-               /* Release the semaphore so that the network subsystem can
+               /* Release the mutex so that the network subsystem can
                 * complete any needed calls into the driver... */
-               up(&priv->action_sem);
+               mutex_unlock(&priv->action_mutex);
 
                /* Unregister the device first - this results in close()
                 * being called if the device is open.  If we free storage
@@ -6709,18 +6385,14 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
 }
 
 #ifdef CONFIG_PM
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
-static int ipw2100_suspend(struct pci_dev *pci_dev, u32 state)
-#else
 static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state)
-#endif
 {
        struct ipw2100_priv *priv = pci_get_drvdata(pci_dev);
        struct net_device *dev = priv->net_dev;
 
        IPW_DEBUG_INFO("%s: Going into suspend...\n", dev->name);
 
-       down(&priv->action_sem);
+       mutex_lock(&priv->action_mutex);
        if (priv->status & STATUS_INITIALIZED) {
                /* Take down the device; powers it off, etc. */
                ipw2100_down(priv);
@@ -6733,7 +6405,7 @@ static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state)
        pci_disable_device(pci_dev);
        pci_set_power_state(pci_dev, PCI_D3hot);
 
-       up(&priv->action_sem);
+       mutex_unlock(&priv->action_mutex);
 
        return 0;
 }
@@ -6747,7 +6419,7 @@ static int ipw2100_resume(struct pci_dev *pci_dev)
        if (IPW2100_PM_DISABLED)
                return 0;
 
-       down(&priv->action_sem);
+       mutex_lock(&priv->action_mutex);
 
        IPW_DEBUG_INFO("%s: Coming out of suspend...\n", dev->name);
 
@@ -6773,7 +6445,7 @@ static int ipw2100_resume(struct pci_dev *pci_dev)
        if (!(priv->status & STATUS_RF_KILL_SW))
                ipw2100_up(priv, 0);
 
-       up(&priv->action_sem);
+       mutex_unlock(&priv->action_mutex);
 
        return 0;
 }
@@ -6862,7 +6534,7 @@ static int __init ipw2100_init(void)
 
        ret = pci_module_init(&ipw2100_pci_driver);
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
        ipw2100_debug_level = debug;
        driver_create_file(&ipw2100_pci_driver.driver,
                           &driver_attr_debug_level);
@@ -6877,7 +6549,7 @@ static int __init ipw2100_init(void)
 static void __exit ipw2100_exit(void)
 {
        /* FIXME: IPG: check that we have no instances of the devices open */
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
        driver_remove_file(&ipw2100_pci_driver.driver,
                           &driver_attr_debug_level);
 #endif
@@ -6937,7 +6609,7 @@ static int ipw2100_wx_set_freq(struct net_device *dev,
        if (priv->ieee->iw_mode == IW_MODE_INFRA)
                return -EOPNOTSUPP;
 
-       down(&priv->action_sem);
+       mutex_lock(&priv->action_mutex);
        if (!(priv->status & STATUS_INITIALIZED)) {
                err = -EIO;
                goto done;
@@ -6968,7 +6640,7 @@ static int ipw2100_wx_set_freq(struct net_device *dev,
        }
 
       done:
-       up(&priv->action_sem);
+       mutex_unlock(&priv->action_mutex);
        return err;
 }
 
@@ -7009,7 +6681,7 @@ static int ipw2100_wx_set_mode(struct net_device *dev,
        if (wrqu->mode == priv->ieee->iw_mode)
                return 0;
 
-       down(&priv->action_sem);
+       mutex_lock(&priv->action_mutex);
        if (!(priv->status & STATUS_INITIALIZED)) {
                err = -EIO;
                goto done;
@@ -7032,7 +6704,7 @@ static int ipw2100_wx_set_mode(struct net_device *dev,
        }
 
       done:
-       up(&priv->action_sem);
+       mutex_unlock(&priv->action_mutex);
        return err;
 }
 
@@ -7157,7 +6829,7 @@ static int ipw2100_wx_get_range(struct net_device *dev,
 
        /* Set the Wireless Extension versions */
        range->we_version_compiled = WIRELESS_EXT;
-       range->we_version_source = 16;
+       range->we_version_source = 18;
 
 //      range->retry_capa;      /* What retry options are supported */
 //      range->retry_flags;     /* How to decode max/min retry limit */
@@ -7183,6 +6855,14 @@ static int ipw2100_wx_get_range(struct net_device *dev,
        }
        range->num_frequency = val;
 
+       /* 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;
@@ -7206,7 +6886,7 @@ static int ipw2100_wx_set_wap(struct net_device *dev,
        if (wrqu->ap_addr.sa_family != ARPHRD_ETHER)
                return -EINVAL;
 
-       down(&priv->action_sem);
+       mutex_lock(&priv->action_mutex);
        if (!(priv->status & STATUS_INITIALIZED)) {
                err = -EIO;
                goto done;
@@ -7235,7 +6915,7 @@ static int ipw2100_wx_set_wap(struct net_device *dev,
                     wrqu->ap_addr.sa_data[5] & 0xff);
 
       done:
-       up(&priv->action_sem);
+       mutex_unlock(&priv->action_mutex);
        return err;
 }
 
@@ -7271,7 +6951,7 @@ static int ipw2100_wx_set_essid(struct net_device *dev,
        int length = 0;
        int err = 0;
 
-       down(&priv->action_sem);
+       mutex_lock(&priv->action_mutex);
        if (!(priv->status & STATUS_INITIALIZED)) {
                err = -EIO;
                goto done;
@@ -7308,7 +6988,7 @@ static int ipw2100_wx_set_essid(struct net_device *dev,
        err = ipw2100_set_essid(priv, essid, length, 0);
 
       done:
-       up(&priv->action_sem);
+       mutex_unlock(&priv->action_mutex);
        return err;
 }
 
@@ -7389,7 +7069,7 @@ static int ipw2100_wx_set_rate(struct net_device *dev,
        u32 rate;
        int err = 0;
 
-       down(&priv->action_sem);
+       mutex_lock(&priv->action_mutex);
        if (!(priv->status & STATUS_INITIALIZED)) {
                err = -EIO;
                goto done;
@@ -7416,7 +7096,7 @@ static int ipw2100_wx_set_rate(struct net_device *dev,
 
        IPW_DEBUG_WX("SET Rate -> %04X \n", rate);
       done:
-       up(&priv->action_sem);
+       mutex_unlock(&priv->action_mutex);
        return err;
 }
 
@@ -7436,7 +7116,7 @@ static int ipw2100_wx_get_rate(struct net_device *dev,
                return 0;
        }
 
-       down(&priv->action_sem);
+       mutex_lock(&priv->action_mutex);
        if (!(priv->status & STATUS_INITIALIZED)) {
                err = -EIO;
                goto done;
@@ -7468,7 +7148,7 @@ static int ipw2100_wx_get_rate(struct net_device *dev,
        IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value);
 
       done:
-       up(&priv->action_sem);
+       mutex_unlock(&priv->action_mutex);
        return err;
 }
 
@@ -7483,7 +7163,7 @@ static int ipw2100_wx_set_rts(struct net_device *dev,
        if (wrqu->rts.fixed == 0)
                return -EINVAL;
 
-       down(&priv->action_sem);
+       mutex_lock(&priv->action_mutex);
        if (!(priv->status & STATUS_INITIALIZED)) {
                err = -EIO;
                goto done;
@@ -7503,7 +7183,7 @@ static int ipw2100_wx_set_rts(struct net_device *dev,
 
        IPW_DEBUG_WX("SET RTS Threshold -> 0x%08X \n", value);
       done:
-       up(&priv->action_sem);
+       mutex_unlock(&priv->action_mutex);
        return err;
 }
 
@@ -7534,11 +7214,17 @@ static int ipw2100_wx_set_txpow(struct net_device *dev,
 {
        struct ipw2100_priv *priv = ieee80211_priv(dev);
        int err = 0, value;
+       
+       if (ipw_radio_kill_sw(priv, wrqu->txpower.disabled))
+               return -EINPROGRESS;
 
        if (priv->ieee->iw_mode != IW_MODE_ADHOC)
+               return 0;
+
+       if ((wrqu->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM)
                return -EINVAL;
 
-       if (wrqu->txpower.disabled == 1 || wrqu->txpower.fixed == 0)
+       if (wrqu->txpower.fixed == 0)
                value = IPW_TX_POWER_DEFAULT;
        else {
                if (wrqu->txpower.value < IPW_TX_POWER_MIN_DBM ||
@@ -7548,7 +7234,7 @@ static int ipw2100_wx_set_txpow(struct net_device *dev,
                value = wrqu->txpower.value;
        }
 
-       down(&priv->action_sem);
+       mutex_lock(&priv->action_mutex);
        if (!(priv->status & STATUS_INITIALIZED)) {
                err = -EIO;
                goto done;
@@ -7559,7 +7245,7 @@ static int ipw2100_wx_set_txpow(struct net_device *dev,
        IPW_DEBUG_WX("SET TX Power -> %d \n", value);
 
       done:
-       up(&priv->action_sem);
+       mutex_unlock(&priv->action_mutex);
        return err;
 }
 
@@ -7573,24 +7259,19 @@ static int ipw2100_wx_get_txpow(struct net_device *dev,
 
        struct ipw2100_priv *priv = ieee80211_priv(dev);
 
-       if (priv->ieee->iw_mode != IW_MODE_ADHOC) {
-               wrqu->power.disabled = 1;
-               return 0;
-       }
+       wrqu->txpower.disabled = (priv->status & STATUS_RF_KILL_MASK) ? 1 : 0;
 
        if (priv->tx_power == IPW_TX_POWER_DEFAULT) {
-               wrqu->power.fixed = 0;
-               wrqu->power.value = IPW_TX_POWER_MAX_DBM;
-               wrqu->power.disabled = 1;
+               wrqu->txpower.fixed = 0;
+               wrqu->txpower.value = IPW_TX_POWER_MAX_DBM;
        } else {
-               wrqu->power.disabled = 0;
-               wrqu->power.fixed = 1;
-               wrqu->power.value = priv->tx_power;
+               wrqu->txpower.fixed = 1;
+               wrqu->txpower.value = priv->tx_power;
        }
 
-       wrqu->power.flags = IW_TXPOW_DBM;
+       wrqu->txpower.flags = IW_TXPOW_DBM;
 
-       IPW_DEBUG_WX("GET TX Power -> %d \n", wrqu->power.value);
+       IPW_DEBUG_WX("GET TX Power -> %d \n", wrqu->txpower.value);
 
        return 0;
 }
@@ -7656,7 +7337,7 @@ static int ipw2100_wx_set_retry(struct net_device *dev,
        if (!(wrqu->retry.flags & IW_RETRY_LIMIT))
                return 0;
 
-       down(&priv->action_sem);
+       mutex_lock(&priv->action_mutex);
        if (!(priv->status & STATUS_INITIALIZED)) {
                err = -EIO;
                goto done;
@@ -7683,7 +7364,7 @@ static int ipw2100_wx_set_retry(struct net_device *dev,
        IPW_DEBUG_WX("SET Both Retry Limits -> %d \n", wrqu->retry.value);
 
       done:
-       up(&priv->action_sem);
+       mutex_unlock(&priv->action_mutex);
        return err;
 }
 
@@ -7726,7 +7407,7 @@ static int ipw2100_wx_set_scan(struct net_device *dev,
        struct ipw2100_priv *priv = ieee80211_priv(dev);
        int err = 0;
 
-       down(&priv->action_sem);
+       mutex_lock(&priv->action_mutex);
        if (!(priv->status & STATUS_INITIALIZED)) {
                err = -EIO;
                goto done;
@@ -7741,7 +7422,7 @@ static int ipw2100_wx_set_scan(struct net_device *dev,
        }
 
       done:
-       up(&priv->action_sem);
+       mutex_unlock(&priv->action_mutex);
        return err;
 }
 
@@ -7791,7 +7472,7 @@ static int ipw2100_wx_set_power(struct net_device *dev,
        struct ipw2100_priv *priv = ieee80211_priv(dev);
        int err = 0;
 
-       down(&priv->action_sem);
+       mutex_lock(&priv->action_mutex);
        if (!(priv->status & STATUS_INITIALIZED)) {
                err = -EIO;
                goto done;
@@ -7824,7 +7505,7 @@ static int ipw2100_wx_set_power(struct net_device *dev,
        IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", priv->power_mode);
 
       done:
-       up(&priv->action_sem);
+       mutex_unlock(&priv->action_mutex);
        return err;
 
 }
@@ -7851,7 +7532,6 @@ static int ipw2100_wx_get_power(struct net_device *dev,
        return 0;
 }
 
-#if WIRELESS_EXT > 17
 /*
  * WE-18 WPA support
  */
@@ -7939,11 +7619,8 @@ static int ipw2100_wx_set_auth(struct net_device *dev,
 
        case IW_AUTH_TKIP_COUNTERMEASURES:
                crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
-               if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags) {
-                       IPW_DEBUG_WARNING("Can't set TKIP countermeasures: "
-                                         "crypt not set!\n");
+               if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags)
                        break;
-               }
 
                flags = crypt->ops->get_flags(crypt->priv);
 
@@ -8116,7 +7793,6 @@ static int ipw2100_wx_set_mlme(struct net_device *dev,
        }
        return 0;
 }
-#endif                         /* WIRELESS_EXT > 17 */
 
 /*
  *
@@ -8133,7 +7809,7 @@ static int ipw2100_wx_set_promisc(struct net_device *dev,
        int enable = (parms[0] > 0);
        int err = 0;
 
-       down(&priv->action_sem);
+       mutex_lock(&priv->action_mutex);
        if (!(priv->status & STATUS_INITIALIZED)) {
                err = -EIO;
                goto done;
@@ -8151,7 +7827,7 @@ static int ipw2100_wx_set_promisc(struct net_device *dev,
                        err = ipw2100_switch_mode(priv, priv->last_mode);
        }
       done:
-       up(&priv->action_sem);
+       mutex_unlock(&priv->action_mutex);
        return err;
 }
 
@@ -8174,7 +7850,7 @@ static int ipw2100_wx_set_powermode(struct net_device *dev,
        struct ipw2100_priv *priv = ieee80211_priv(dev);
        int err = 0, mode = *(int *)extra;
 
-       down(&priv->action_sem);
+       mutex_lock(&priv->action_mutex);
        if (!(priv->status & STATUS_INITIALIZED)) {
                err = -EIO;
                goto done;
@@ -8186,7 +7862,7 @@ static int ipw2100_wx_set_powermode(struct net_device *dev,
        if (priv->power_mode != mode)
                err = ipw2100_set_power_mode(priv, mode);
       done:
-       up(&priv->action_sem);
+       mutex_unlock(&priv->action_mutex);
        return err;
 }
 
@@ -8238,7 +7914,7 @@ static int ipw2100_wx_set_preamble(struct net_device *dev,
        struct ipw2100_priv *priv = ieee80211_priv(dev);
        int err, mode = *(int *)extra;
 
-       down(&priv->action_sem);
+       mutex_lock(&priv->action_mutex);
        if (!(priv->status & STATUS_INITIALIZED)) {
                err = -EIO;
                goto done;
@@ -8256,7 +7932,7 @@ static int ipw2100_wx_set_preamble(struct net_device *dev,
        err = ipw2100_system_config(priv, 0);
 
       done:
-       up(&priv->action_sem);
+       mutex_unlock(&priv->action_mutex);
        return err;
 }
 
@@ -8286,7 +7962,7 @@ static int ipw2100_wx_set_crc_check(struct net_device *dev,
        struct ipw2100_priv *priv = ieee80211_priv(dev);
        int err, mode = *(int *)extra;
 
-       down(&priv->action_sem);
+       mutex_lock(&priv->action_mutex);
        if (!(priv->status & STATUS_INITIALIZED)) {
                err = -EIO;
                goto done;
@@ -8303,7 +7979,7 @@ static int ipw2100_wx_set_crc_check(struct net_device *dev,
        err = 0;
 
       done:
-       up(&priv->action_sem);
+       mutex_unlock(&priv->action_mutex);
        return err;
 }
 
@@ -8349,11 +8025,7 @@ static iw_handler ipw2100_wx_handlers[] = {
        NULL,                   /* SIOCWIWTHRSPY */
        ipw2100_wx_set_wap,     /* SIOCSIWAP */
        ipw2100_wx_get_wap,     /* SIOCGIWAP */
-#if WIRELESS_EXT > 17
        ipw2100_wx_set_mlme,    /* SIOCSIWMLME */
-#else
-       NULL,                   /* -- hole -- */
-#endif
        NULL,                   /* SIOCGIWAPLIST -- deprecated */
        ipw2100_wx_set_scan,    /* SIOCSIWSCAN */
        ipw2100_wx_get_scan,    /* SIOCGIWSCAN */
@@ -8377,7 +8049,6 @@ static iw_handler ipw2100_wx_handlers[] = {
        ipw2100_wx_get_encode,  /* SIOCGIWENCODE */
        ipw2100_wx_set_power,   /* SIOCSIWPOWER */
        ipw2100_wx_get_power,   /* SIOCGIWPOWER */
-#if WIRELESS_EXT > 17
        NULL,                   /* -- hole -- */
        NULL,                   /* -- hole -- */
        ipw2100_wx_set_genie,   /* SIOCSIWGENIE */
@@ -8387,7 +8058,6 @@ static iw_handler ipw2100_wx_handlers[] = {
        ipw2100_wx_set_encodeext,       /* SIOCSIWENCODEEXT */
        ipw2100_wx_get_encodeext,       /* SIOCGIWENCODEEXT */
        NULL,                   /* SIOCSIWPMKSA */
-#endif
 };
 
 #define IPW2100_PRIV_SET_MONITOR       SIOCIWFIRSTPRIV
@@ -8454,16 +8124,6 @@ static iw_handler ipw2100_private_handler[] = {
 #endif                         /* CONFIG_IPW2100_MONITOR */
 };
 
-static struct iw_handler_def ipw2100_wx_handler_def = {
-       .standard = ipw2100_wx_handlers,
-       .num_standard = sizeof(ipw2100_wx_handlers) / sizeof(iw_handler),
-       .num_private = sizeof(ipw2100_private_handler) / sizeof(iw_handler),
-       .num_private_args = sizeof(ipw2100_private_args) /
-           sizeof(struct iw_priv_args),
-       .private = (iw_handler *) ipw2100_private_handler,
-       .private_args = (struct iw_priv_args *)ipw2100_private_args,
-};
-
 /*
  * Get wireless statistics.
  * Called by /proc/net/wireless
@@ -8570,7 +8230,7 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device *dev)
 
                quality = min(beacon_qual, min(tx_qual, rssi_qual));
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
                if (beacon_qual == quality)
                        IPW_DEBUG_WX("Quality clamped by Missed Beacons\n");
                else if (tx_qual == quality)
@@ -8605,6 +8265,17 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device *dev)
        return (struct iw_statistics *)NULL;
 }
 
+static struct iw_handler_def ipw2100_wx_handler_def = {
+       .standard = ipw2100_wx_handlers,
+       .num_standard = sizeof(ipw2100_wx_handlers) / sizeof(iw_handler),
+       .num_private = sizeof(ipw2100_private_handler) / sizeof(iw_handler),
+       .num_private_args = sizeof(ipw2100_private_args) /
+           sizeof(struct iw_priv_args),
+       .private = (iw_handler *) ipw2100_private_handler,
+       .private_args = (struct iw_priv_args *)ipw2100_private_args,
+       .get_wireless_stats = ipw2100_wx_wireless_stats,
+};
+
 static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
 {
        union iwreq_data wrqu;
@@ -8613,11 +8284,11 @@ static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
        if (priv->status & STATUS_STOPPING)
                return;
 
-       down(&priv->action_sem);
+       mutex_lock(&priv->action_mutex);
 
        IPW_DEBUG_WX("enter\n");
 
-       up(&priv->action_sem);
+       mutex_unlock(&priv->action_mutex);
 
        wrqu.ap_addr.sa_family = ARPHRD_ETHER;
 
@@ -8640,7 +8311,7 @@ static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
 
        if (!(priv->status & STATUS_ASSOCIATED)) {
                IPW_DEBUG_WX("Configuring ESSID\n");
-               down(&priv->action_sem);
+               mutex_lock(&priv->action_mutex);
                /* This is a disassociation event, so kick the firmware to
                 * look for another AP */
                if (priv->config & CFG_STATIC_ESSID)
@@ -8648,7 +8319,7 @@ static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
                                          0);
                else
                        ipw2100_set_essid(priv, NULL, 0, 0);
-               up(&priv->action_sem);
+               mutex_unlock(&priv->action_mutex);
        }
 
        wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);