Merge branch 'for-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq
[linux-3.10.git] / drivers / net / wireless / ipw2x00 / ipw2100.c
index 97e5647..534e655 100644 (file)
@@ -19,7 +19,7 @@
   file called LICENSE.
 
   Contact Information:
-  James P. Ketrenos <ipw2100-admin@linux.intel.com>
+  Intel Linux Wireless <ilw@linux.intel.com>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
   Portions of this file are based on the sample_* files provided by Wireless
@@ -63,7 +63,7 @@ When data is sent to the firmware, the first TBD is used to indicate to the
 firmware if a Command or Data is being sent.  If it is Command, all of the
 command information is contained within the physical address referred to by the
 TBD.  If it is Data, the first TBD indicates the type of data packet, number
-of fragments, etc.  The next TBD then referrs to the actual packet location.
+of fragments, etc.  The next TBD then refers to the actual packet location.
 
 The Tx flow cycle is as follows:
 
@@ -161,11 +161,12 @@ that only one external action is invoked at a time.
 #include <linux/firmware.h>
 #include <linux/acpi.h>
 #include <linux/ctype.h>
-#include <linux/pm_qos_params.h>
+#include <linux/pm_qos.h>
 
 #include <net/lib80211.h>
 
 #include "ipw2100.h"
+#include "ipw.h"
 
 #define IPW2100_VERSION "git-1.2.2"
 
@@ -174,6 +175,8 @@ that only one external action is invoked at a time.
 #define DRV_DESCRIPTION        "Intel(R) PRO/Wireless 2100 Network Driver"
 #define DRV_COPYRIGHT  "Copyright(c) 2003-2006 Intel Corporation"
 
+static struct pm_qos_request ipw2100_pm_qos_req;
+
 /* Debugging stuff */
 #ifdef CONFIG_IPW2100_DEBUG
 #define IPW2100_RX_DEBUG       /* Reception debugging */
@@ -185,7 +188,7 @@ MODULE_AUTHOR(DRV_COPYRIGHT);
 MODULE_LICENSE("GPL");
 
 static int debug = 0;
-static int mode = 0;
+static int network_mode = 0;
 static int channel = 0;
 static int associate = 0;
 static int disable = 0;
@@ -195,7 +198,7 @@ static struct ipw2100_fw ipw2100_firmware;
 
 #include <linux/moduleparam.h>
 module_param(debug, int, 0444);
-module_param(mode, int, 0444);
+module_param_named(mode, network_mode, int, 0444);
 module_param(channel, int, 0444);
 module_param(associate, int, 0444);
 module_param(disable, int, 0444);
@@ -285,7 +288,7 @@ static const char *command_types[] = {
        "unused",               /* HOST_INTERRUPT_COALESCING */
        "undefined",
        "CARD_DISABLE_PHY_OFF",
-       "MSDU_TX_RATES" "undefined",
+       "MSDU_TX_RATES",
        "undefined",
        "SET_STATION_STAT_BITS",
        "CLEAR_STATIONS_STAT_BITS",
@@ -296,6 +299,24 @@ static const char *command_types[] = {
 };
 #endif
 
+static const long ipw2100_frequencies[] = {
+       2412, 2417, 2422, 2427,
+       2432, 2437, 2442, 2447,
+       2452, 2457, 2462, 2467,
+       2472, 2484
+};
+
+#define FREQ_COUNT     ARRAY_SIZE(ipw2100_frequencies)
+
+static struct ieee80211_rate ipw2100_bg_rates[] = {
+       { .bitrate = 10 },
+       { .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+       { .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+       { .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+};
+
+#define RATE_COUNT ARRAY_SIZE(ipw2100_bg_rates)
+
 /* Pre-decl until we get the code solid and then we can clean it up */
 static void ipw2100_tx_send_commands(struct ipw2100_priv *priv);
 static void ipw2100_tx_send_data(struct ipw2100_priv *priv);
@@ -323,38 +344,50 @@ static struct iw_handler_def ipw2100_wx_handler_def;
 
 static inline void read_register(struct net_device *dev, u32 reg, u32 * val)
 {
-       *val = readl((void __iomem *)(dev->base_addr + reg));
+       struct ipw2100_priv *priv = libipw_priv(dev);
+
+       *val = ioread32(priv->ioaddr + reg);
        IPW_DEBUG_IO("r: 0x%08X => 0x%08X\n", reg, *val);
 }
 
 static inline void write_register(struct net_device *dev, u32 reg, u32 val)
 {
-       writel(val, (void __iomem *)(dev->base_addr + reg));
+       struct ipw2100_priv *priv = libipw_priv(dev);
+
+       iowrite32(val, priv->ioaddr + reg);
        IPW_DEBUG_IO("w: 0x%08X <= 0x%08X\n", reg, val);
 }
 
 static inline void read_register_word(struct net_device *dev, u32 reg,
                                      u16 * val)
 {
-       *val = readw((void __iomem *)(dev->base_addr + reg));
+       struct ipw2100_priv *priv = libipw_priv(dev);
+
+       *val = ioread16(priv->ioaddr + reg);
        IPW_DEBUG_IO("r: 0x%08X => %04X\n", reg, *val);
 }
 
 static inline void read_register_byte(struct net_device *dev, u32 reg, u8 * val)
 {
-       *val = readb((void __iomem *)(dev->base_addr + reg));
+       struct ipw2100_priv *priv = libipw_priv(dev);
+
+       *val = ioread8(priv->ioaddr + reg);
        IPW_DEBUG_IO("r: 0x%08X => %02X\n", reg, *val);
 }
 
 static inline void write_register_word(struct net_device *dev, u32 reg, u16 val)
 {
-       writew(val, (void __iomem *)(dev->base_addr + reg));
+       struct ipw2100_priv *priv = libipw_priv(dev);
+
+       iowrite16(val, priv->ioaddr + reg);
        IPW_DEBUG_IO("w: 0x%08X <= %04X\n", reg, val);
 }
 
 static inline void write_register_byte(struct net_device *dev, u32 reg, u8 val)
 {
-       writeb(val, (void __iomem *)(dev->base_addr + reg));
+       struct ipw2100_priv *priv = libipw_priv(dev);
+
+       iowrite8(val, priv->ioaddr + reg);
        IPW_DEBUG_IO("w: 0x%08X =< %02X\n", reg, val);
 }
 
@@ -486,13 +519,13 @@ static void read_nic_memory(struct net_device *dev, u32 addr, u32 len,
                read_register_byte(dev, IPW_REG_INDIRECT_ACCESS_DATA + i, buf);
 }
 
-static inline int ipw2100_hw_is_adapter_in_system(struct net_device *dev)
+static bool ipw2100_hw_is_adapter_in_system(struct net_device *dev)
 {
-       return (dev->base_addr &&
-               (readl
-                ((void __iomem *)(dev->base_addr +
-                                  IPW_REG_DOA_DEBUG_AREA_START))
-                == IPW_DATA_DOA_DEBUG_VALUE));
+       u32 dbg;
+
+       read_register(dev, IPW_REG_DOA_DEBUG_AREA_START, &dbg);
+
+       return dbg == IPW_DATA_DOA_DEBUG_VALUE;
 }
 
 static int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord,
@@ -551,7 +584,7 @@ static int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord,
                /* get number of entries */
                field_count = *(((u16 *) & field_info) + 1);
 
-               /* abort if no enought memory */
+               /* abort if no enough memory */
                total_length = field_len * field_count;
                if (total_length > *len) {
                        *len = total_length;
@@ -677,11 +710,10 @@ static void schedule_reset(struct ipw2100_priv *priv)
                netif_stop_queue(priv->net_dev);
                priv->status |= STATUS_RESET_PENDING;
                if (priv->reset_backoff)
-                       queue_delayed_work(priv->workqueue, &priv->reset_work,
-                                          priv->reset_backoff * HZ);
+                       schedule_delayed_work(&priv->reset_work,
+                                             priv->reset_backoff * HZ);
                else
-                       queue_delayed_work(priv->workqueue, &priv->reset_work,
-                                          0);
+                       schedule_delayed_work(&priv->reset_work, 0);
 
                if (priv->reset_backoff < MAX_RESET_BACKOFF)
                        priv->reset_backoff++;
@@ -1141,6 +1173,7 @@ static int rf_kill_active(struct ipw2100_priv *priv)
        int i;
 
        if (!(priv->hw_features & HW_FEATURE_RFKILL)) {
+               wiphy_rfkill_set_hw_state(priv->ieee->wdev.wiphy, false);
                priv->status &= ~STATUS_RF_KILL_HW;
                return 0;
        }
@@ -1151,10 +1184,13 @@ static int rf_kill_active(struct ipw2100_priv *priv)
                value = (value << 1) | ((reg & IPW_BIT_GPIO_RF_KILL) ? 0 : 1);
        }
 
-       if (value == 0)
+       if (value == 0) {
+               wiphy_rfkill_set_hw_state(priv->ieee->wdev.wiphy, true);
                priv->status |= STATUS_RF_KILL_HW;
-       else
+       } else {
+               wiphy_rfkill_set_hw_state(priv->ieee->wdev.wiphy, false);
                priv->status &= ~STATUS_RF_KILL_HW;
+       }
 
        return (value == 0);
 }
@@ -1364,7 +1400,7 @@ static int ipw2100_power_cycle_adapter(struct ipw2100_priv *priv)
 }
 
 /*
- * Send the CARD_DISABLE_PHY_OFF comamnd to the card to disable it
+ * Send the CARD_DISABLE_PHY_OFF command to the card to disable it
  *
  * After disabling, if the card was associated, a STATUS_ASSN_LOST will be sent.
  *
@@ -1441,7 +1477,7 @@ static int ipw2100_enable_adapter(struct ipw2100_priv *priv)
 
        if (priv->stop_hang_check) {
                priv->stop_hang_check = 0;
-               queue_delayed_work(priv->workqueue, &priv->hang_check, HZ / 2);
+               schedule_delayed_work(&priv->hang_check, HZ / 2);
        }
 
       fail_up:
@@ -1673,7 +1709,7 @@ static int ipw2100_start_scan(struct ipw2100_priv *priv)
        return err;
 }
 
-static const struct ieee80211_geo ipw_geos[] = {
+static const struct libipw_geo ipw_geos[] = {
        {                       /* Restricted */
         "---",
         .bg_channels = 14,
@@ -1694,7 +1730,7 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
 
        /* Age scan list entries found before suspend */
        if (priv->suspend_time) {
-               ieee80211_networks_age(priv->ieee, priv->suspend_time);
+               libipw_networks_age(priv->ieee, priv->suspend_time);
                priv->suspend_time = 0;
        }
 
@@ -1708,7 +1744,7 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
        /* the ipw2100 hardware really doesn't want power management delays
         * longer than 175usec
         */
-       pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY, "ipw2100", 175);
+       pm_qos_update_request(&ipw2100_pm_qos_req, 175);
 
        /* If the interrupt is enabled, turn it off... */
        spin_lock_irqsave(&priv->low_lock, flags);
@@ -1752,11 +1788,11 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
        }
 
        /* Initialize the geo */
-       if (ieee80211_set_geo(priv->ieee, &ipw_geos[0])) {
+       if (libipw_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;
+       priv->ieee->freq_band = LIBIPW_24GHZ_BAND;
 
        lock = LOCK_NONE;
        if (ipw2100_set_ordinal(priv, IPW_ORD_PERS_DB_LOCK, &lock, &ord_len)) {
@@ -1775,8 +1811,8 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
 
                if (priv->stop_rf_kill) {
                        priv->stop_rf_kill = 0;
-                       queue_delayed_work(priv->workqueue, &priv->rf_kill,
-                                          round_jiffies_relative(HZ));
+                       schedule_delayed_work(&priv->rf_kill,
+                                             round_jiffies_relative(HZ));
                }
 
                deferred = 1;
@@ -1814,13 +1850,6 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
        return rc;
 }
 
-/* Called by register_netdev() */
-static int ipw2100_net_init(struct net_device *dev)
-{
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
-       return ipw2100_up(priv, 1);
-}
-
 static void ipw2100_down(struct ipw2100_priv *priv)
 {
        unsigned long flags;
@@ -1863,8 +1892,7 @@ static void ipw2100_down(struct ipw2100_priv *priv)
        ipw2100_disable_interrupts(priv);
        spin_unlock_irqrestore(&priv->low_lock, flags);
 
-       pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY, "ipw2100",
-                       PM_QOS_DEFAULT_VALUE);
+       pm_qos_update_request(&ipw2100_pm_qos_req, PM_QOS_DEFAULT_VALUE);
 
        /* We have to signal any supplicant if we are disassociating */
        if (associated)
@@ -1875,6 +1903,63 @@ static void ipw2100_down(struct ipw2100_priv *priv)
        netif_stop_queue(priv->net_dev);
 }
 
+static int ipw2100_wdev_init(struct net_device *dev)
+{
+       struct ipw2100_priv *priv = libipw_priv(dev);
+       const struct libipw_geo *geo = libipw_get_geo(priv->ieee);
+       struct wireless_dev *wdev = &priv->ieee->wdev;
+       int i;
+
+       memcpy(wdev->wiphy->perm_addr, priv->mac_addr, ETH_ALEN);
+
+       /* fill-out priv->ieee->bg_band */
+       if (geo->bg_channels) {
+               struct ieee80211_supported_band *bg_band = &priv->ieee->bg_band;
+
+               bg_band->band = IEEE80211_BAND_2GHZ;
+               bg_band->n_channels = geo->bg_channels;
+               bg_band->channels = kcalloc(geo->bg_channels,
+                                           sizeof(struct ieee80211_channel),
+                                           GFP_KERNEL);
+               if (!bg_band->channels) {
+                       ipw2100_down(priv);
+                       return -ENOMEM;
+               }
+               /* translate geo->bg to bg_band.channels */
+               for (i = 0; i < geo->bg_channels; i++) {
+                       bg_band->channels[i].band = IEEE80211_BAND_2GHZ;
+                       bg_band->channels[i].center_freq = geo->bg[i].freq;
+                       bg_band->channels[i].hw_value = geo->bg[i].channel;
+                       bg_band->channels[i].max_power = geo->bg[i].max_power;
+                       if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY)
+                               bg_band->channels[i].flags |=
+                                       IEEE80211_CHAN_PASSIVE_SCAN;
+                       if (geo->bg[i].flags & LIBIPW_CH_NO_IBSS)
+                               bg_band->channels[i].flags |=
+                                       IEEE80211_CHAN_NO_IBSS;
+                       if (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT)
+                               bg_band->channels[i].flags |=
+                                       IEEE80211_CHAN_RADAR;
+                       /* No equivalent for LIBIPW_CH_80211H_RULES,
+                          LIBIPW_CH_UNIFORM_SPREADING, or
+                          LIBIPW_CH_B_ONLY... */
+               }
+               /* point at bitrate info */
+               bg_band->bitrates = ipw2100_bg_rates;
+               bg_band->n_bitrates = RATE_COUNT;
+
+               wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = bg_band;
+       }
+
+       wdev->wiphy->cipher_suites = ipw_cipher_suites;
+       wdev->wiphy->n_cipher_suites = ARRAY_SIZE(ipw_cipher_suites);
+
+       set_wiphy_dev(wdev->wiphy, &priv->pci_dev->dev);
+       if (wiphy_register(wdev->wiphy))
+               return -EIO;
+       return 0;
+}
+
 static void ipw2100_reset_adapter(struct work_struct *work)
 {
        struct ipw2100_priv *priv =
@@ -1957,7 +2042,8 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
                return;
        }
        len = ETH_ALEN;
-       ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID, &bssid, &len);
+       ret = ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID, bssid,
+                                 &len);
        if (ret) {
                IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
                               __LINE__);
@@ -1999,7 +2085,7 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
        priv->status |= STATUS_ASSOCIATING;
        priv->connect_start = get_seconds();
 
-       queue_delayed_work(priv->workqueue, &priv->wx_event_work, HZ / 10);
+       schedule_delayed_work(&priv->wx_event_work, HZ / 10);
 }
 
 static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid,
@@ -2058,7 +2144,7 @@ static void isr_indicate_association_lost(struct ipw2100_priv *priv, u32 status)
        DECLARE_SSID_BUF(ssid);
 
        IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC,
-                 "disassociated: '%s' %pM \n",
+                 "disassociated: '%s' %pM\n",
                  print_ssid(ssid, priv->essid, priv->essid_len),
                  priv->bssid);
 
@@ -2079,9 +2165,9 @@ static void isr_indicate_association_lost(struct ipw2100_priv *priv, u32 status)
                return;
 
        if (priv->status & STATUS_SECURITY_UPDATED)
-               queue_delayed_work(priv->workqueue, &priv->security_work, 0);
+               schedule_delayed_work(&priv->security_work, 0);
 
-       queue_delayed_work(priv->workqueue, &priv->wx_event_work, 0);
+       schedule_delayed_work(&priv->wx_event_work, 0);
 }
 
 static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status)
@@ -2090,13 +2176,12 @@ static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status)
                       priv->net_dev->name);
 
        /* RF_KILL is now enabled (else we wouldn't be here) */
+       wiphy_rfkill_set_hw_state(priv->ieee->wdev.wiphy, true);
        priv->status |= STATUS_RF_KILL_HW;
 
        /* Make sure the RF Kill check timer is running */
        priv->stop_rf_kill = 0;
-       cancel_delayed_work(&priv->rf_kill);
-       queue_delayed_work(priv->workqueue, &priv->rf_kill,
-                          round_jiffies_relative(HZ));
+       mod_delayed_work(system_wq, &priv->rf_kill, round_jiffies_relative(HZ));
 }
 
 static void send_scan_event(void *data)
@@ -2131,13 +2216,12 @@ static void isr_scan_complete(struct ipw2100_priv *priv, u32 status)
        /* Only userspace-requested scan completion events go out immediately */
        if (!priv->user_requested_scan) {
                if (!delayed_work_pending(&priv->scan_event_later))
-                       queue_delayed_work(priv->workqueue,
-                                       &priv->scan_event_later,
-                                       round_jiffies_relative(msecs_to_jiffies(4000)));
+                       schedule_delayed_work(&priv->scan_event_later,
+                                             round_jiffies_relative(msecs_to_jiffies(4000)));
        } else {
                priv->user_requested_scan = 0;
                cancel_delayed_work(&priv->scan_event_later);
-               queue_work(priv->workqueue, &priv->scan_event_now);
+               schedule_work(&priv->scan_event_now);
        }
 }
 
@@ -2340,8 +2424,8 @@ static u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 * in_buf,
  *
  * When packet is provided by the firmware, it contains the following:
  *
- * .  ieee80211_hdr
- * .  ieee80211_snap_hdr
+ * .  libipw_hdr
+ * .  libipw_snap_hdr
  *
  * The size of the constructed ethernet
  *
@@ -2396,7 +2480,7 @@ static void ipw2100_corruption_detected(struct ipw2100_priv *priv, int i)
 }
 
 static void isr_rx(struct ipw2100_priv *priv, int i,
-                         struct ieee80211_rx_stats *stats)
+                         struct libipw_rx_stats *stats)
 {
        struct net_device *dev = priv->net_dev;
        struct ipw2100_status *status = &priv->status_queue.drv[i];
@@ -2435,13 +2519,13 @@ static void isr_rx(struct ipw2100_priv *priv, int i,
 
 #ifdef IPW2100_RX_DEBUG
        /* Make a copy of the frame so we can dump it to the logs if
-        * ieee80211_rx fails */
+        * libipw_rx fails */
        skb_copy_from_linear_data(packet->skb, packet_data,
                                  min_t(u32, status->frame_size,
                                             IPW_RX_NIC_BUFFER_LENGTH));
 #endif
 
-       if (!ieee80211_rx(priv->ieee, packet->skb, stats)) {
+       if (!libipw_rx(priv->ieee, packet->skb, stats)) {
 #ifdef IPW2100_RX_DEBUG
                IPW_DEBUG_DROP("%s: Non consumed packet:\n",
                               dev->name);
@@ -2449,7 +2533,7 @@ static void isr_rx(struct ipw2100_priv *priv, int i,
 #endif
                dev->stats.rx_errors++;
 
-               /* ieee80211_rx failed, so it didn't free the SKB */
+               /* libipw_rx failed, so it didn't free the SKB */
                dev_kfree_skb_any(packet->skb);
                packet->skb = NULL;
        }
@@ -2470,7 +2554,7 @@ static void isr_rx(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 libipw_rx_stats *stats)
 {
        struct net_device *dev = priv->net_dev;
        struct ipw2100_status *status = &priv->status_queue.drv[i];
@@ -2528,10 +2612,10 @@ static void isr_rx_monitor(struct ipw2100_priv *priv, int i,
 
        skb_put(packet->skb, status->frame_size + sizeof(struct ipw_rt_hdr));
 
-       if (!ieee80211_rx(priv->ieee, packet->skb, stats)) {
+       if (!libipw_rx(priv->ieee, packet->skb, stats)) {
                dev->stats.rx_errors++;
 
-               /* ieee80211_rx failed, so it didn't free the SKB */
+               /* libipw_rx failed, so it didn't free the SKB */
                dev_kfree_skb_any(packet->skb);
                packet->skb = NULL;
        }
@@ -2615,7 +2699,7 @@ static void __ipw2100_rx_process(struct ipw2100_priv *priv)
        u16 frame_type;
        u32 r, w, i, s;
        struct ipw2100_rx *u;
-       struct ieee80211_rx_stats stats = {
+       struct libipw_rx_stats stats = {
                .mac_time = jiffies,
        };
 
@@ -2635,14 +2719,6 @@ static void __ipw2100_rx_process(struct ipw2100_priv *priv)
 
                packet = &priv->rx_buffers[i];
 
-               /* Sync the DMA for the STATUS buffer so CPU is sure to get
-                * the correct values */
-               pci_dma_sync_single_for_cpu(priv->pci_dev,
-                                           sq->nic +
-                                           sizeof(struct ipw2100_status) * i,
-                                           sizeof(struct ipw2100_status),
-                                           PCI_DMA_FROMDEVICE);
-
                /* Sync the DMA for the RX buffer so CPU is sure to get
                 * the correct values */
                pci_dma_sync_single_for_cpu(priv->pci_dev, packet->dma_addr,
@@ -2661,8 +2737,8 @@ static void __ipw2100_rx_process(struct ipw2100_priv *priv)
 
                stats.mask = 0;
                if (stats.rssi != 0)
-                       stats.mask |= IEEE80211_STATMASK_RSSI;
-               stats.freq = IEEE80211_24GHZ_BAND;
+                       stats.mask |= LIBIPW_STATMASK_RSSI;
+               stats.freq = LIBIPW_24GHZ_BAND;
 
                IPW_DEBUG_RX("%s: '%s' frame type received (%d).\n",
                             priv->net_dev->name, frame_types[frame_type],
@@ -2686,11 +2762,11 @@ static void __ipw2100_rx_process(struct ipw2100_priv *priv)
                                break;
                        }
 #endif
-                       if (stats.len < sizeof(struct ieee80211_hdr_3addr))
+                       if (stats.len < sizeof(struct libipw_hdr_3addr))
                                break;
                        switch (WLAN_FC_GET_TYPE(le16_to_cpu(u->rx_data.header.frame_ctl))) {
                        case IEEE80211_FTYPE_MGMT:
-                               ieee80211_rx_mgt(priv->ieee,
+                               libipw_rx_mgt(priv->ieee,
                                                 &u->rx_data.header, &stats);
                                break;
 
@@ -2844,7 +2920,7 @@ static int __ipw2100_tx_process(struct ipw2100_priv *priv)
 
 #ifdef CONFIG_IPW2100_DEBUG
        {
-               int i = txq->oldest;
+               i = txq->oldest;
                IPW_DEBUG_TX("TX%d V=%p P=%04X T=%04X L=%d\n", i,
                             &txq->drv[i],
                             (u32) (txq->nic + i * sizeof(struct ipw2100_bd)),
@@ -2884,7 +2960,7 @@ static int __ipw2100_tx_process(struct ipw2100_priv *priv)
                                         tbd->buf_length, PCI_DMA_TODEVICE);
                }
 
-               ieee80211_txb_free(packet->info.d_struct.txb);
+               libipw_txb_free(packet->info.d_struct.txb);
                packet->info.d_struct.txb = NULL;
 
                list_add_tail(element, &priv->tx_free_list);
@@ -2976,9 +3052,9 @@ static void ipw2100_tx_send_commands(struct ipw2100_priv *priv)
 
                packet = list_entry(element, struct ipw2100_tx_packet, list);
 
-               IPW_DEBUG_TX("using TBD at virt=%p, phys=%p\n",
+               IPW_DEBUG_TX("using TBD at virt=%p, phys=%04X\n",
                             &txq->drv[txq->next],
-                            (void *)(txq->nic + txq->next *
+                            (u32) (txq->nic + txq->next *
                                      sizeof(struct ipw2100_bd)));
 
                packet->index = txq->next;
@@ -3028,7 +3104,7 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
        int next = txq->next;
        int i = 0;
        struct ipw2100_data_header *ipw_hdr;
-       struct ieee80211_hdr_3addr *hdr;
+       struct libipw_hdr_3addr *hdr;
 
        while (!list_empty(&priv->tx_pend_list)) {
                /* if there isn't enough space in TBD queue, then
@@ -3044,7 +3120,7 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
                             IPW_MAX_BDS)) {
                        /* TODO: Support merging buffers if more than
                         * IPW_MAX_BDS are used */
-                       IPW_DEBUG_INFO("%s: Maximum BD theshold exceeded.  "
+                       IPW_DEBUG_INFO("%s: Maximum BD threshold exceeded.  "
                                       "Increase fragmentation level.\n",
                                       priv->net_dev->name);
                }
@@ -3062,7 +3138,7 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
                packet->index = txq->next;
 
                ipw_hdr = packet->info.d_struct.data;
-               hdr = (struct ieee80211_hdr_3addr *)packet->info.d_struct.txb->
+               hdr = (struct libipw_hdr_3addr *)packet->info.d_struct.txb->
                    fragments[0]->data;
 
                if (priv->ieee->iw_mode == IW_MODE_INFRA) {
@@ -3086,7 +3162,7 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
                if (packet->info.d_struct.txb->nr_frags > 1)
                        ipw_hdr->fragment_size =
                            packet->info.d_struct.txb->frag_size -
-                           IEEE80211_3ADDR_LEN;
+                           LIBIPW_3ADDR_LEN;
                else
                        ipw_hdr->fragment_size = 0;
 
@@ -3119,13 +3195,13 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
                                    IPW_BD_STATUS_TX_FRAME_NOT_LAST_FRAGMENT;
 
                        tbd->buf_length = packet->info.d_struct.txb->
-                           fragments[i]->len - IEEE80211_3ADDR_LEN;
+                           fragments[i]->len - LIBIPW_3ADDR_LEN;
 
                        tbd->host_addr = pci_map_single(priv->pci_dev,
                                                        packet->info.d_struct.
                                                        txb->fragments[i]->
                                                        data +
-                                                       IEEE80211_3ADDR_LEN,
+                                                       LIBIPW_3ADDR_LEN,
                                                        tbd->buf_length,
                                                        PCI_DMA_TODEVICE);
 
@@ -3156,7 +3232,6 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
                               IPW_MEM_HOST_SHARED_TX_QUEUE_WRITE_INDEX,
                               txq->next);
        }
-       return;
 }
 
 static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
@@ -3202,7 +3277,7 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
 
        if (inta & IPW2100_INTA_PARITY_ERROR) {
                printk(KERN_ERR DRV_NAME
-                      ": ***** PARITY ERROR INTERRUPT !!!! \n");
+                      ": ***** PARITY ERROR INTERRUPT !!!!\n");
                priv->inta_other++;
                write_register(dev, IPW_REG_INTA, IPW2100_INTA_PARITY_ERROR);
        }
@@ -3330,10 +3405,10 @@ static irqreturn_t ipw2100_interrupt(int irq, void *data)
        return IRQ_NONE;
 }
 
-static int ipw2100_tx(struct ieee80211_txb *txb, struct net_device *dev,
-                     int pri)
+static netdev_tx_t ipw2100_tx(struct libipw_txb *txb,
+                             struct net_device *dev, int pri)
 {
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
        struct list_head *element;
        struct ipw2100_tx_packet *packet;
        unsigned long flags;
@@ -3369,12 +3444,12 @@ static int ipw2100_tx(struct ieee80211_txb *txb, struct net_device *dev,
        ipw2100_tx_send_data(priv);
 
        spin_unlock_irqrestore(&priv->low_lock, flags);
-       return 0;
+       return NETDEV_TX_OK;
 
-      fail_unlock:
+fail_unlock:
        netif_stop_queue(dev);
        spin_unlock_irqrestore(&priv->low_lock, flags);
-       return 1;
+       return NETDEV_TX_BUSY;
 }
 
 static int ipw2100_msg_allocate(struct ipw2100_priv *priv)
@@ -3384,15 +3459,10 @@ static int ipw2100_msg_allocate(struct ipw2100_priv *priv)
        dma_addr_t p;
 
        priv->msg_buffers =
-           (struct ipw2100_tx_packet *)kmalloc(IPW_COMMAND_POOL_SIZE *
-                                               sizeof(struct
-                                                      ipw2100_tx_packet),
-                                               GFP_KERNEL);
-       if (!priv->msg_buffers) {
-               printk(KERN_ERR DRV_NAME ": %s: PCI alloc failed for msg "
-                      "buffers.\n", priv->net_dev->name);
+           kmalloc(IPW_COMMAND_POOL_SIZE * sizeof(struct ipw2100_tx_packet),
+                   GFP_KERNEL);
+       if (!priv->msg_buffers)
                return -ENOMEM;
-       }
 
        for (i = 0; i < IPW_COMMAND_POOL_SIZE; i++) {
                v = pci_alloc_consistent(priv->pci_dev,
@@ -3488,7 +3558,7 @@ static DEVICE_ATTR(pci, S_IRUGO, show_pci, NULL);
 static ssize_t show_cfg(struct device *d, struct device_attribute *attr,
                        char *buf)
 {
-       struct ipw2100_priv *p = d->driver_data;
+       struct ipw2100_priv *p = dev_get_drvdata(d);
        return sprintf(buf, "0x%08x\n", (int)p->config);
 }
 
@@ -3497,7 +3567,7 @@ static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL);
 static ssize_t show_status(struct device *d, struct device_attribute *attr,
                           char *buf)
 {
-       struct ipw2100_priv *p = d->driver_data;
+       struct ipw2100_priv *p = dev_get_drvdata(d);
        return sprintf(buf, "0x%08x\n", (int)p->status);
 }
 
@@ -3506,7 +3576,7 @@ static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
 static ssize_t show_capability(struct device *d, struct device_attribute *attr,
                               char *buf)
 {
-       struct ipw2100_priv *p = d->driver_data;
+       struct ipw2100_priv *p = dev_get_drvdata(d);
        return sprintf(buf, "0x%08x\n", (int)p->capability);
 }
 
@@ -3709,7 +3779,7 @@ IPW2100_ORD(STAT_TX_HOST_REQUESTS, "requested Host Tx's (MSDU)"),
            IPW2100_ORD(COUNTRY_CODE,
                                "IEEE country code as recv'd from beacon"),
            IPW2100_ORD(COUNTRY_CHANNELS,
-                               "channels suported by country"),
+                               "channels supported by country"),
            IPW2100_ORD(RESET_CNT, "adapter resets (warm)"),
            IPW2100_ORD(BEACON_INTERVAL, "Beacon interval"),
            IPW2100_ORD(ANTENNA_DIVERSITY,
@@ -3998,7 +4068,7 @@ static int ipw2100_switch_mode(struct ipw2100_priv *priv, u32 mode)
        ipw2100_firmware.version = 0;
 #endif
 
-       printk(KERN_INFO "%s: Reseting on mode change.\n", priv->net_dev->name);
+       printk(KERN_INFO "%s: Resetting on mode change.\n", priv->net_dev->name);
        priv->reset_backoff = 0;
        schedule_reset(priv);
 
@@ -4224,7 +4294,7 @@ static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr,
           1 - SW based RF kill active (sysfs)
           2 - HW based RF kill active
           3 - Both HW and SW baed RF kill active */
-       struct ipw2100_priv *priv = (struct ipw2100_priv *)d->driver_data;
+       struct ipw2100_priv *priv = dev_get_drvdata(d);
        int val = ((priv->status & STATUS_RF_KILL_SW) ? 0x1 : 0x0) |
            (rf_kill_active(priv) ? 0x2 : 0x0);
        return sprintf(buf, "%i\n", val);
@@ -4251,9 +4321,8 @@ static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio)
                                          "disabled by HW switch\n");
                        /* Make sure the RF_KILL check timer is running */
                        priv->stop_rf_kill = 0;
-                       cancel_delayed_work(&priv->rf_kill);
-                       queue_delayed_work(priv->workqueue, &priv->rf_kill,
-                                          round_jiffies_relative(HZ));
+                       mod_delayed_work(system_wq, &priv->rf_kill,
+                                        round_jiffies_relative(HZ));
                } else
                        schedule_reset(priv);
        }
@@ -4384,20 +4453,17 @@ static void bd_queue_initialize(struct ipw2100_priv *priv,
        IPW_DEBUG_INFO("exit\n");
 }
 
-static void ipw2100_kill_workqueue(struct ipw2100_priv *priv)
+static void ipw2100_kill_works(struct ipw2100_priv *priv)
 {
-       if (priv->workqueue) {
-               priv->stop_rf_kill = 1;
-               priv->stop_hang_check = 1;
-               cancel_delayed_work(&priv->reset_work);
-               cancel_delayed_work(&priv->security_work);
-               cancel_delayed_work(&priv->wx_event_work);
-               cancel_delayed_work(&priv->hang_check);
-               cancel_delayed_work(&priv->rf_kill);
-               cancel_delayed_work(&priv->scan_event_later);
-               destroy_workqueue(priv->workqueue);
-               priv->workqueue = NULL;
-       }
+       priv->stop_rf_kill = 1;
+       priv->stop_hang_check = 1;
+       cancel_delayed_work_sync(&priv->reset_work);
+       cancel_delayed_work_sync(&priv->security_work);
+       cancel_delayed_work_sync(&priv->wx_event_work);
+       cancel_delayed_work_sync(&priv->hang_check);
+       cancel_delayed_work_sync(&priv->rf_kill);
+       cancel_work_sync(&priv->scan_event_now);
+       cancel_delayed_work_sync(&priv->scan_event_later);
 }
 
 static int ipw2100_tx_allocate(struct ipw2100_priv *priv)
@@ -4416,10 +4482,8 @@ static int ipw2100_tx_allocate(struct ipw2100_priv *priv)
        }
 
        priv->tx_buffers =
-           (struct ipw2100_tx_packet *)kmalloc(TX_PENDED_QUEUE_LENGTH *
-                                               sizeof(struct
-                                                      ipw2100_tx_packet),
-                                               GFP_ATOMIC);
+           kmalloc(TX_PENDED_QUEUE_LENGTH * sizeof(struct ipw2100_tx_packet),
+                   GFP_ATOMIC);
        if (!priv->tx_buffers) {
                printk(KERN_ERR DRV_NAME
                       ": %s: alloc failed form tx buffers.\n",
@@ -4488,7 +4552,7 @@ static void ipw2100_tx_initialize(struct ipw2100_priv *priv)
                /* We simply drop any SKBs that have been queued for
                 * transmit */
                if (priv->tx_buffers[i].info.d_struct.txb) {
-                       ieee80211_txb_free(priv->tx_buffers[i].info.d_struct.
+                       libipw_txb_free(priv->tx_buffers[i].info.d_struct.
                                           txb);
                        priv->tx_buffers[i].info.d_struct.txb = NULL;
                }
@@ -4527,7 +4591,7 @@ static void ipw2100_tx_free(struct ipw2100_priv *priv)
 
        for (i = 0; i < TX_PENDED_QUEUE_LENGTH; i++) {
                if (priv->tx_buffers[i].info.d_struct.txb) {
-                       ieee80211_txb_free(priv->tx_buffers[i].info.d_struct.
+                       libipw_txb_free(priv->tx_buffers[i].info.d_struct.
                                           txb);
                        priv->tx_buffers[i].info.d_struct.txb = NULL;
                }
@@ -4568,9 +4632,9 @@ static int ipw2100_rx_allocate(struct ipw2100_priv *priv)
        /*
         * allocate packets
         */
-       priv->rx_buffers = (struct ipw2100_rx_packet *)
-           kmalloc(RX_QUEUE_LENGTH * sizeof(struct ipw2100_rx_packet),
-                   GFP_KERNEL);
+       priv->rx_buffers = kmalloc(RX_QUEUE_LENGTH *
+                                  sizeof(struct ipw2100_rx_packet),
+                                  GFP_KERNEL);
        if (!priv->rx_buffers) {
                IPW_DEBUG_INFO("can't allocate rx packet buffer table\n");
 
@@ -5150,7 +5214,7 @@ struct security_info_params {
        u8 auth_mode;
        u8 replay_counters_number;
        u8 unicast_using_group;
-} __attribute__ ((packed));
+} __packed;
 
 static int ipw2100_set_security_information(struct ipw2100_priv *priv,
                                            int auth_mode,
@@ -5558,9 +5622,9 @@ static void ipw2100_security_work(struct work_struct *work)
 }
 
 static void shim__set_security(struct net_device *dev,
-                              struct ieee80211_security *sec)
+                              struct libipw_security *sec)
 {
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
        int i, force_update = 0;
 
        mutex_lock(&priv->action_mutex);
@@ -5753,7 +5817,7 @@ static int ipw2100_adapter_setup(struct ipw2100_priv *priv)
  * method as well) to talk to the firmware */
 static int ipw2100_set_address(struct net_device *dev, void *p)
 {
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
        struct sockaddr *addr = p;
        int err = 0;
 
@@ -5781,7 +5845,7 @@ static int ipw2100_set_address(struct net_device *dev, void *p)
 
 static int ipw2100_open(struct net_device *dev)
 {
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
        unsigned long flags;
        IPW_DEBUG_INFO("dev->open\n");
 
@@ -5797,7 +5861,7 @@ static int ipw2100_open(struct net_device *dev)
 
 static int ipw2100_close(struct net_device *dev)
 {
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
        unsigned long flags;
        struct list_head *element;
        struct ipw2100_tx_packet *packet;
@@ -5818,7 +5882,7 @@ static int ipw2100_close(struct net_device *dev)
                list_del(element);
                DEC_STAT(&priv->tx_pend_stat);
 
-               ieee80211_txb_free(packet->info.d_struct.txb);
+               libipw_txb_free(packet->info.d_struct.txb);
                packet->info.d_struct.txb = NULL;
 
                list_add_tail(element, &priv->tx_free_list);
@@ -5836,7 +5900,7 @@ static int ipw2100_close(struct net_device *dev)
  */
 static void ipw2100_tx_timeout(struct net_device *dev)
 {
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
 
        dev->stats.tx_errors++;
 
@@ -5861,8 +5925,8 @@ static int ipw2100_wpa_enable(struct ipw2100_priv *priv, int value)
 static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value)
 {
 
-       struct ieee80211_device *ieee = priv->ieee;
-       struct ieee80211_security sec = {
+       struct libipw_device *ieee = priv->ieee;
+       struct libipw_security sec = {
                .flags = SEC_AUTH_MODE,
        };
        int ret = 0;
@@ -5907,11 +5971,11 @@ static void ipw2100_wpa_assoc_frame(struct ipw2100_priv *priv,
 static void ipw_ethtool_get_drvinfo(struct net_device *dev,
                                    struct ethtool_drvinfo *info)
 {
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
        char fw_ver[64], ucode_ver[64];
 
-       strcpy(info->driver, DRV_NAME);
-       strcpy(info->version, DRV_VERSION);
+       strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
+       strlcpy(info->version, DRV_VERSION, sizeof(info->version));
 
        ipw2100_get_fwversion(priv, fw_ver, sizeof(fw_ver));
        ipw2100_get_ucodeversion(priv, ucode_ver, sizeof(ucode_ver));
@@ -5919,12 +5983,13 @@ static void ipw_ethtool_get_drvinfo(struct net_device *dev,
        snprintf(info->fw_version, sizeof(info->fw_version), "%s:%d:%s",
                 fw_ver, priv->eeprom_version, ucode_ver);
 
-       strcpy(info->bus_info, pci_name(priv->pci_dev));
+       strlcpy(info->bus_info, pci_name(priv->pci_dev),
+               sizeof(info->bus_info));
 }
 
 static u32 ipw2100_ethtool_get_link(struct net_device *dev)
 {
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
        return (priv->status & STATUS_ASSOCIATED) ? 1 : 0;
 }
 
@@ -5971,7 +6036,7 @@ static void ipw2100_hang_check(struct work_struct *work)
        priv->last_rtc = rtc;
 
        if (!priv->stop_hang_check)
-               queue_delayed_work(priv->workqueue, &priv->hang_check, HZ / 2);
+               schedule_delayed_work(&priv->hang_check, HZ / 2);
 
        spin_unlock_irqrestore(&priv->low_lock, flags);
 }
@@ -5987,8 +6052,8 @@ static void ipw2100_rf_kill(struct work_struct *work)
        if (rf_kill_active(priv)) {
                IPW_DEBUG_RF_KILL("RF Kill active, rescheduling GPIO check\n");
                if (!priv->stop_rf_kill)
-                       queue_delayed_work(priv->workqueue, &priv->rf_kill,
-                                          round_jiffies_relative(HZ));
+                       schedule_delayed_work(&priv->rf_kill,
+                                             round_jiffies_relative(HZ));
                goto exit_unlock;
        }
 
@@ -6011,31 +6076,29 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv);
 static const struct net_device_ops ipw2100_netdev_ops = {
        .ndo_open               = ipw2100_open,
        .ndo_stop               = ipw2100_close,
-       .ndo_start_xmit         = ieee80211_xmit,
-       .ndo_change_mtu         = ieee80211_change_mtu,
-       .ndo_init               = ipw2100_net_init,
+       .ndo_start_xmit         = libipw_xmit,
+       .ndo_change_mtu         = libipw_change_mtu,
        .ndo_tx_timeout         = ipw2100_tx_timeout,
        .ndo_set_mac_address    = ipw2100_set_address,
        .ndo_validate_addr      = eth_validate_addr,
 };
 
-/* Look into using netdev destructor to shutdown ieee80211? */
+/* Look into using netdev destructor to shutdown libipw? */
 
 static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
-                                              void __iomem * base_addr,
-                                              unsigned long mem_start,
-                                              unsigned long mem_len)
+                                              void __iomem * ioaddr)
 {
        struct ipw2100_priv *priv;
        struct net_device *dev;
 
-       dev = alloc_ieee80211(sizeof(struct ipw2100_priv));
+       dev = alloc_libipw(sizeof(struct ipw2100_priv), 0);
        if (!dev)
                return NULL;
-       priv = ieee80211_priv(dev);
+       priv = libipw_priv(dev);
        priv->ieee = netdev_priv(dev);
        priv->pci_dev = pci_dev;
        priv->net_dev = dev;
+       priv->ioaddr = ioaddr;
 
        priv->ieee->hard_start_xmit = ipw2100_tx;
        priv->ieee->set_security = shim__set_security;
@@ -6046,15 +6109,11 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
        dev->netdev_ops = &ipw2100_netdev_ops;
        dev->ethtool_ops = &ipw2100_ethtool_ops;
        dev->wireless_handlers = &ipw2100_wx_handler_def;
-       priv->wireless_data.ieee80211 = priv->ieee;
+       priv->wireless_data.libipw = priv->ieee;
        dev->wireless_data = &priv->wireless_data;
        dev->watchdog_timeo = 3 * HZ;
        dev->irq = 0;
 
-       dev->base_addr = (unsigned long)base_addr;
-       dev->mem_start = mem_start;
-       dev->mem_end = dev->mem_start + mem_len - 1;
-
        /* NOTE: We don't use the wireless_handlers hook
         * in dev as the system will start throwing WX requests
         * to us before we're actually initialized and it just
@@ -6076,7 +6135,7 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
        priv->ieee->ieee802_1x = 1;
 
        /* Set module parameters */
-       switch (mode) {
+       switch (network_mode) {
        case 1:
                priv->ieee->iw_mode = IW_MODE_ADHOC;
                break;
@@ -6134,8 +6193,6 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
        INIT_LIST_HEAD(&priv->fw_pend_list);
        INIT_STAT(&priv->fw_pend_stat);
 
-       priv->workqueue = create_workqueue(DRV_NAME);
-
        INIT_DELAYED_WORK(&priv->reset_work, ipw2100_reset_adapter);
        INIT_DELAYED_WORK(&priv->security_work, ipw2100_security_work);
        INIT_DELAYED_WORK(&priv->wx_event_work, ipw2100_wx_event_work);
@@ -6157,8 +6214,7 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
 static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
                                const struct pci_device_id *ent)
 {
-       unsigned long mem_start, mem_len, mem_flags;
-       void __iomem *base_addr = NULL;
+       void __iomem *ioaddr;
        struct net_device *dev = NULL;
        struct ipw2100_priv *priv = NULL;
        int err = 0;
@@ -6167,18 +6223,14 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
 
        IPW_DEBUG_INFO("enter\n");
 
-       mem_start = pci_resource_start(pci_dev, 0);
-       mem_len = pci_resource_len(pci_dev, 0);
-       mem_flags = pci_resource_flags(pci_dev, 0);
-
-       if ((mem_flags & IORESOURCE_MEM) != IORESOURCE_MEM) {
+       if (!(pci_resource_flags(pci_dev, 0) & IORESOURCE_MEM)) {
                IPW_DEBUG_INFO("weird - resource type is not memory\n");
                err = -ENODEV;
-               goto fail;
+               goto out;
        }
 
-       base_addr = ioremap_nocache(mem_start, mem_len);
-       if (!base_addr) {
+       ioaddr = pci_iomap(pci_dev, 0, 0);
+       if (!ioaddr) {
                printk(KERN_WARNING DRV_NAME
                       "Error calling ioremap_nocache.\n");
                err = -EIO;
@@ -6186,7 +6238,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
        }
 
        /* allocate and initialize our net_device */
-       dev = ipw2100_alloc_device(pci_dev, base_addr, mem_start, mem_len);
+       dev = ipw2100_alloc_device(pci_dev, ioaddr);
        if (!dev) {
                printk(KERN_WARNING DRV_NAME
                       "Error calling ipw2100_alloc_device.\n");
@@ -6202,7 +6254,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
                return err;
        }
 
-       priv = ieee80211_priv(dev);
+       priv = libipw_priv(dev);
 
        pci_set_master(pci_dev);
        pci_set_drvdata(pci_dev, priv);
@@ -6267,25 +6319,29 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
        printk(KERN_INFO DRV_NAME
               ": Detected Intel PRO/Wireless 2100 Network Connection\n");
 
+       err = ipw2100_up(priv, 1);
+       if (err)
+               goto fail;
+
+       err = ipw2100_wdev_init(dev);
+       if (err)
+               goto fail;
+       registered = 1;
+
        /* Bring up the interface.  Pre 0.46, after we registered the
         * network device we would call ipw2100_up.  This introduced a race
         * condition with newer hotplug configurations (network was coming
         * up and making calls before the device was initialized).
-        *
-        * If we called ipw2100_up before we registered the device, then the
-        * device name wasn't registered.  So, we instead use the net_dev->init
-        * 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 */
+        */
        err = register_netdev(dev);
        if (err) {
                printk(KERN_WARNING DRV_NAME
                       "Error calling register_netdev.\n");
                goto fail;
        }
+       registered = 2;
 
        mutex_lock(&priv->action_mutex);
-       registered = 1;
 
        IPW_DEBUG_INFO("%s: Bound to %s\n", dev->name, pci_name(pci_dev));
 
@@ -6317,17 +6373,21 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
        priv->status |= STATUS_INITIALIZED;
 
        mutex_unlock(&priv->action_mutex);
-
-       return 0;
+out:
+       return err;
 
       fail_unlock:
        mutex_unlock(&priv->action_mutex);
-
       fail:
        if (dev) {
-               if (registered)
+               if (registered >= 2)
                        unregister_netdev(dev);
 
+               if (registered) {
+                       wiphy_unregister(priv->ieee->wdev.wiphy);
+                       kfree(priv->ieee->bg_band.channels);
+               }
+
                ipw2100_hw_stop_adapter(priv);
 
                ipw2100_disable_interrupts(priv);
@@ -6335,73 +6395,67 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
                if (dev->irq)
                        free_irq(dev->irq, priv);
 
-               ipw2100_kill_workqueue(priv);
+               ipw2100_kill_works(priv);
 
                /* These are safe to call even if they weren't allocated */
                ipw2100_queues_free(priv);
                sysfs_remove_group(&pci_dev->dev.kobj,
                                   &ipw2100_attribute_group);
 
-               free_ieee80211(dev);
+               free_libipw(dev, 0);
                pci_set_drvdata(pci_dev, NULL);
        }
 
-       if (base_addr)
-               iounmap(base_addr);
+       pci_iounmap(pci_dev, ioaddr);
 
        pci_release_regions(pci_dev);
        pci_disable_device(pci_dev);
-
-       return err;
+       goto out;
 }
 
 static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
 {
        struct ipw2100_priv *priv = pci_get_drvdata(pci_dev);
-       struct net_device *dev;
+       struct net_device *dev = priv->net_dev;
 
-       if (priv) {
-               mutex_lock(&priv->action_mutex);
+       mutex_lock(&priv->action_mutex);
 
-               priv->status &= ~STATUS_INITIALIZED;
+       priv->status &= ~STATUS_INITIALIZED;
 
-               dev = priv->net_dev;
-               sysfs_remove_group(&pci_dev->dev.kobj,
-                                  &ipw2100_attribute_group);
+       sysfs_remove_group(&pci_dev->dev.kobj, &ipw2100_attribute_group);
 
 #ifdef CONFIG_PM
-               if (ipw2100_firmware.version)
-                       ipw2100_release_firmware(priv, &ipw2100_firmware);
+       if (ipw2100_firmware.version)
+               ipw2100_release_firmware(priv, &ipw2100_firmware);
 #endif
-               /* Take down the hardware */
-               ipw2100_down(priv);
+       /* Take down the hardware */
+       ipw2100_down(priv);
 
-               /* Release the mutex so that the network subsystem can
-                * complete any needed calls into the driver... */
-               mutex_unlock(&priv->action_mutex);
+       /* Release the mutex so that the network subsystem can
+        * complete any needed calls into the driver... */
+       mutex_unlock(&priv->action_mutex);
 
-               /* Unregister the device first - this results in close()
-                * being called if the device is open.  If we free storage
-                * first, then close() will crash. */
-               unregister_netdev(dev);
+       /* Unregister the device first - this results in close()
+        * being called if the device is open.  If we free storage
+        * first, then close() will crash.
+        * FIXME: remove the comment above. */
+       unregister_netdev(dev);
 
-               /* ipw2100_down will ensure that there is no more pending work
-                * in the workqueue's, so we can safely remove them now. */
-               ipw2100_kill_workqueue(priv);
+       ipw2100_kill_works(priv);
 
-               ipw2100_queues_free(priv);
+       ipw2100_queues_free(priv);
 
-               /* Free potential debugging firmware snapshot */
-               ipw2100_snapshot_free(priv);
+       /* Free potential debugging firmware snapshot */
+       ipw2100_snapshot_free(priv);
 
-               if (dev->irq)
-                       free_irq(dev->irq, priv);
+       free_irq(dev->irq, priv);
 
-               if (dev->base_addr)
-                       iounmap((void __iomem *)dev->base_addr);
+       pci_iounmap(pci_dev, priv->ioaddr);
 
-               free_ieee80211(dev);
-       }
+       /* wiphy_unregister needs to be here, before free_libipw */
+       wiphy_unregister(priv->ieee->wdev.wiphy);
+       kfree(priv->ieee->bg_band.channels);
+       free_libipw(dev, 0);
 
        pci_release_regions(pci_dev);
        pci_disable_device(pci_dev);
@@ -6487,9 +6541,19 @@ static int ipw2100_resume(struct pci_dev *pci_dev)
 }
 #endif
 
+static void ipw2100_shutdown(struct pci_dev *pci_dev)
+{
+       struct ipw2100_priv *priv = pci_get_drvdata(pci_dev);
+
+       /* Take down the device; powers it off, etc. */
+       ipw2100_down(priv);
+
+       pci_disable_device(pci_dev);
+}
+
 #define IPW2100_DEV_ID(x) { PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, x }
 
-static struct pci_device_id ipw2100_pci_id_table[] __devinitdata = {
+static DEFINE_PCI_DEVICE_TABLE(ipw2100_pci_id_table) = {
        IPW2100_DEV_ID(0x2520), /* IN 2100A mPCI 3A */
        IPW2100_DEV_ID(0x2521), /* IN 2100A mPCI 3B */
        IPW2100_DEV_ID(0x2524), /* IN 2100A mPCI 3B */
@@ -6550,6 +6614,7 @@ static struct pci_driver ipw2100_pci_driver = {
        .suspend = ipw2100_suspend,
        .resume = ipw2100_resume,
 #endif
+       .shutdown = ipw2100_shutdown,
 };
 
 /**
@@ -6568,12 +6633,13 @@ static int __init ipw2100_init(void)
        printk(KERN_INFO DRV_NAME ": %s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
        printk(KERN_INFO DRV_NAME ": %s\n", DRV_COPYRIGHT);
 
+       pm_qos_add_request(&ipw2100_pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
+                          PM_QOS_DEFAULT_VALUE);
+
        ret = pci_register_driver(&ipw2100_pci_driver);
        if (ret)
                goto out;
 
-       pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY, "ipw2100",
-                       PM_QOS_DEFAULT_VALUE);
 #ifdef CONFIG_IPW2100_DEBUG
        ipw2100_debug_level = debug;
        ret = driver_create_file(&ipw2100_pci_driver.driver,
@@ -6595,32 +6661,12 @@ static void __exit ipw2100_exit(void)
                           &driver_attr_debug_level);
 #endif
        pci_unregister_driver(&ipw2100_pci_driver);
-       pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY, "ipw2100");
+       pm_qos_remove_request(&ipw2100_pm_qos_req);
 }
 
 module_init(ipw2100_init);
 module_exit(ipw2100_exit);
 
-#define WEXT_USECHANNELS 1
-
-static const long ipw2100_frequencies[] = {
-       2412, 2417, 2422, 2427,
-       2432, 2437, 2442, 2447,
-       2452, 2457, 2462, 2467,
-       2472, 2484
-};
-
-#define FREQ_COUNT     ARRAY_SIZE(ipw2100_frequencies)
-
-static const long ipw2100_rates_11b[] = {
-       1000000,
-       2000000,
-       5500000,
-       11000000
-};
-
-#define RATE_COUNT ARRAY_SIZE(ipw2100_rates_11b)
-
 static int ipw2100_wx_get_name(struct net_device *dev,
                               struct iw_request_info *info,
                               union iwreq_data *wrqu, char *extra)
@@ -6629,7 +6675,7 @@ static int ipw2100_wx_get_name(struct net_device *dev,
         * This can be called at any time.  No action lock required
         */
 
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
        if (!(priv->status & STATUS_ASSOCIATED))
                strcpy(wrqu->name, "unassociated");
        else
@@ -6643,7 +6689,7 @@ static int ipw2100_wx_set_freq(struct net_device *dev,
                               struct iw_request_info *info,
                               union iwreq_data *wrqu, char *extra)
 {
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
        struct iw_freq *fwrq = &wrqu->freq;
        int err = 0;
 
@@ -6676,7 +6722,7 @@ static int ipw2100_wx_set_freq(struct net_device *dev,
                err = -EOPNOTSUPP;
                goto done;
        } else {                /* Set the channel */
-               IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m);
+               IPW_DEBUG_WX("SET Freq/Channel -> %d\n", fwrq->m);
                err = ipw2100_set_channel(priv, fwrq->m, 0);
        }
 
@@ -6693,7 +6739,7 @@ static int ipw2100_wx_get_freq(struct net_device *dev,
         * This can be called at any time.  No action lock required
         */
 
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
 
        wrqu->freq.e = 0;
 
@@ -6705,7 +6751,7 @@ static int ipw2100_wx_get_freq(struct net_device *dev,
        else
                wrqu->freq.m = 0;
 
-       IPW_DEBUG_WX("GET Freq/Channel -> %d \n", priv->channel);
+       IPW_DEBUG_WX("GET Freq/Channel -> %d\n", priv->channel);
        return 0;
 
 }
@@ -6714,10 +6760,10 @@ static int ipw2100_wx_set_mode(struct net_device *dev,
                               struct iw_request_info *info,
                               union iwreq_data *wrqu, char *extra)
 {
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
        int err = 0;
 
-       IPW_DEBUG_WX("SET Mode -> %d \n", wrqu->mode);
+       IPW_DEBUG_WX("SET Mode -> %d\n", wrqu->mode);
 
        if (wrqu->mode == priv->ieee->iw_mode)
                return 0;
@@ -6757,7 +6803,7 @@ static int ipw2100_wx_get_mode(struct net_device *dev,
         * This can be called at any time.  No action lock required
         */
 
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
 
        wrqu->mode = priv->ieee->iw_mode;
        IPW_DEBUG_WX("GET Mode -> %d\n", wrqu->mode);
@@ -6792,7 +6838,7 @@ static int ipw2100_wx_get_range(struct net_device *dev,
         * This can be called at any time.  No action lock required
         */
 
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
        struct iw_range *range = (struct iw_range *)extra;
        u16 val;
        int i, level;
@@ -6820,7 +6866,7 @@ static int ipw2100_wx_get_range(struct net_device *dev,
        range->max_qual.updated = 7;    /* Updated all three */
 
        range->avg_qual.qual = 70;      /* > 8% missed beacons is 'bad' */
-       /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
+       /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
        range->avg_qual.level = 20 + IPW2100_RSSI_TO_DBM;
        range->avg_qual.noise = 0;
        range->avg_qual.updated = 7;    /* Updated all three */
@@ -6828,7 +6874,7 @@ static int ipw2100_wx_get_range(struct net_device *dev,
        range->num_bitrates = RATE_COUNT;
 
        for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
-               range->bitrate[i] = ipw2100_rates_11b[i];
+               range->bitrate[i] = ipw2100_bg_rates[i].bitrate * 100 * 1000;
        }
 
        range->min_rts = MIN_RTS_THRESHOLD;
@@ -6913,7 +6959,7 @@ static int ipw2100_wx_set_wap(struct net_device *dev,
                              struct iw_request_info *info,
                              union iwreq_data *wrqu, char *extra)
 {
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
        int err = 0;
 
        static const unsigned char any[] = {
@@ -6962,7 +7008,7 @@ static int ipw2100_wx_get_wap(struct net_device *dev,
         * This can be called at any time.  No action lock required
         */
 
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
 
        /* If we are associated, trying to associate, or have a statically
         * configured BSSID then return that; otherwise return ANY */
@@ -6980,7 +7026,7 @@ static int ipw2100_wx_set_essid(struct net_device *dev,
                                struct iw_request_info *info,
                                union iwreq_data *wrqu, char *extra)
 {
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
        char *essid = "";       /* ANY */
        int length = 0;
        int err = 0;
@@ -7035,7 +7081,7 @@ static int ipw2100_wx_get_essid(struct net_device *dev,
         * This can be called at any time.  No action lock required
         */
 
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
        DECLARE_SSID_BUF(ssid);
 
        /* If we are associated, trying to associate, or have a statically
@@ -7063,7 +7109,7 @@ static int ipw2100_wx_set_nick(struct net_device *dev,
         * This can be called at any time.  No action lock required
         */
 
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
 
        if (wrqu->data.length > IW_ESSID_MAX_SIZE)
                return -E2BIG;
@@ -7072,7 +7118,7 @@ static int ipw2100_wx_set_nick(struct net_device *dev,
        memset(priv->nick, 0, sizeof(priv->nick));
        memcpy(priv->nick, extra, wrqu->data.length);
 
-       IPW_DEBUG_WX("SET Nickname -> %s \n", priv->nick);
+       IPW_DEBUG_WX("SET Nickname -> %s\n", priv->nick);
 
        return 0;
 }
@@ -7085,13 +7131,13 @@ static int ipw2100_wx_get_nick(struct net_device *dev,
         * This can be called at any time.  No action lock required
         */
 
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
 
        wrqu->data.length = strlen(priv->nick);
        memcpy(extra, priv->nick, wrqu->data.length);
        wrqu->data.flags = 1;   /* active */
 
-       IPW_DEBUG_WX("GET Nickname -> %s \n", extra);
+       IPW_DEBUG_WX("GET Nickname -> %s\n", extra);
 
        return 0;
 }
@@ -7100,7 +7146,7 @@ static int ipw2100_wx_set_rate(struct net_device *dev,
                               struct iw_request_info *info,
                               union iwreq_data *wrqu, char *extra)
 {
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
        u32 target_rate = wrqu->bitrate.value;
        u32 rate;
        int err = 0;
@@ -7130,7 +7176,7 @@ static int ipw2100_wx_set_rate(struct net_device *dev,
 
        err = ipw2100_set_tx_rates(priv, rate, 0);
 
-       IPW_DEBUG_WX("SET Rate -> %04X \n", rate);
+       IPW_DEBUG_WX("SET Rate -> %04X\n", rate);
       done:
        mutex_unlock(&priv->action_mutex);
        return err;
@@ -7140,7 +7186,7 @@ static int ipw2100_wx_get_rate(struct net_device *dev,
                               struct iw_request_info *info,
                               union iwreq_data *wrqu, char *extra)
 {
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
        int val;
        unsigned int len = sizeof(val);
        int err = 0;
@@ -7181,7 +7227,7 @@ static int ipw2100_wx_get_rate(struct net_device *dev,
                wrqu->bitrate.value = 0;
        }
 
-       IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value);
+       IPW_DEBUG_WX("GET Rate -> %d\n", wrqu->bitrate.value);
 
       done:
        mutex_unlock(&priv->action_mutex);
@@ -7192,7 +7238,7 @@ static int ipw2100_wx_set_rts(struct net_device *dev,
                              struct iw_request_info *info,
                              union iwreq_data *wrqu, char *extra)
 {
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
        int value, err;
 
        /* Auto RTS not yet supported */
@@ -7217,7 +7263,7 @@ static int ipw2100_wx_set_rts(struct net_device *dev,
 
        err = ipw2100_set_rts_threshold(priv, value);
 
-       IPW_DEBUG_WX("SET RTS Threshold -> 0x%08X \n", value);
+       IPW_DEBUG_WX("SET RTS Threshold -> 0x%08X\n", value);
       done:
        mutex_unlock(&priv->action_mutex);
        return err;
@@ -7231,7 +7277,7 @@ static int ipw2100_wx_get_rts(struct net_device *dev,
         * This can be called at any time.  No action lock required
         */
 
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
 
        wrqu->rts.value = priv->rts_threshold & ~RTS_DISABLED;
        wrqu->rts.fixed = 1;    /* no auto select */
@@ -7239,7 +7285,7 @@ static int ipw2100_wx_get_rts(struct net_device *dev,
        /* If RTS is set to the default value, then it is disabled */
        wrqu->rts.disabled = (priv->rts_threshold & RTS_DISABLED) ? 1 : 0;
 
-       IPW_DEBUG_WX("GET RTS Threshold -> 0x%08X \n", wrqu->rts.value);
+       IPW_DEBUG_WX("GET RTS Threshold -> 0x%08X\n", wrqu->rts.value);
 
        return 0;
 }
@@ -7248,7 +7294,7 @@ static int ipw2100_wx_set_txpow(struct net_device *dev,
                                struct iw_request_info *info,
                                union iwreq_data *wrqu, char *extra)
 {
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
        int err = 0, value;
        
        if (ipw_radio_kill_sw(priv, wrqu->txpower.disabled))
@@ -7278,7 +7324,7 @@ static int ipw2100_wx_set_txpow(struct net_device *dev,
 
        err = ipw2100_set_tx_power(priv, value);
 
-       IPW_DEBUG_WX("SET TX Power -> %d \n", value);
+       IPW_DEBUG_WX("SET TX Power -> %d\n", value);
 
       done:
        mutex_unlock(&priv->action_mutex);
@@ -7293,7 +7339,7 @@ static int ipw2100_wx_get_txpow(struct net_device *dev,
         * This can be called at any time.  No action lock required
         */
 
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
 
        wrqu->txpower.disabled = (priv->status & STATUS_RF_KILL_MASK) ? 1 : 0;
 
@@ -7307,7 +7353,7 @@ static int ipw2100_wx_get_txpow(struct net_device *dev,
 
        wrqu->txpower.flags = IW_TXPOW_DBM;
 
-       IPW_DEBUG_WX("GET TX Power -> %d \n", wrqu->txpower.value);
+       IPW_DEBUG_WX("GET TX Power -> %d\n", wrqu->txpower.value);
 
        return 0;
 }
@@ -7320,7 +7366,7 @@ static int ipw2100_wx_set_frag(struct net_device *dev,
         * This can be called at any time.  No action lock required
         */
 
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
 
        if (!wrqu->frag.fixed)
                return -EINVAL;
@@ -7337,7 +7383,7 @@ static int ipw2100_wx_set_frag(struct net_device *dev,
                priv->frag_threshold = priv->ieee->fts;
        }
 
-       IPW_DEBUG_WX("SET Frag Threshold -> %d \n", priv->ieee->fts);
+       IPW_DEBUG_WX("SET Frag Threshold -> %d\n", priv->ieee->fts);
 
        return 0;
 }
@@ -7350,12 +7396,12 @@ static int ipw2100_wx_get_frag(struct net_device *dev,
         * This can be called at any time.  No action lock required
         */
 
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
        wrqu->frag.value = priv->frag_threshold & ~FRAG_DISABLED;
        wrqu->frag.fixed = 0;   /* no auto select */
        wrqu->frag.disabled = (priv->frag_threshold & FRAG_DISABLED) ? 1 : 0;
 
-       IPW_DEBUG_WX("GET Frag Threshold -> %d \n", wrqu->frag.value);
+       IPW_DEBUG_WX("GET Frag Threshold -> %d\n", wrqu->frag.value);
 
        return 0;
 }
@@ -7364,7 +7410,7 @@ static int ipw2100_wx_set_retry(struct net_device *dev,
                                struct iw_request_info *info,
                                union iwreq_data *wrqu, char *extra)
 {
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
        int err = 0;
 
        if (wrqu->retry.flags & IW_RETRY_LIFETIME || wrqu->retry.disabled)
@@ -7381,14 +7427,14 @@ static int ipw2100_wx_set_retry(struct net_device *dev,
 
        if (wrqu->retry.flags & IW_RETRY_SHORT) {
                err = ipw2100_set_short_retry(priv, wrqu->retry.value);
-               IPW_DEBUG_WX("SET Short Retry Limit -> %d \n",
+               IPW_DEBUG_WX("SET Short Retry Limit -> %d\n",
                             wrqu->retry.value);
                goto done;
        }
 
        if (wrqu->retry.flags & IW_RETRY_LONG) {
                err = ipw2100_set_long_retry(priv, wrqu->retry.value);
-               IPW_DEBUG_WX("SET Long Retry Limit -> %d \n",
+               IPW_DEBUG_WX("SET Long Retry Limit -> %d\n",
                             wrqu->retry.value);
                goto done;
        }
@@ -7397,7 +7443,7 @@ static int ipw2100_wx_set_retry(struct net_device *dev,
        if (!err)
                err = ipw2100_set_long_retry(priv, wrqu->retry.value);
 
-       IPW_DEBUG_WX("SET Both Retry Limits -> %d \n", wrqu->retry.value);
+       IPW_DEBUG_WX("SET Both Retry Limits -> %d\n", wrqu->retry.value);
 
       done:
        mutex_unlock(&priv->action_mutex);
@@ -7412,7 +7458,7 @@ static int ipw2100_wx_get_retry(struct net_device *dev,
         * This can be called at any time.  No action lock required
         */
 
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
 
        wrqu->retry.disabled = 0;       /* can't be disabled */
 
@@ -7431,7 +7477,7 @@ static int ipw2100_wx_get_retry(struct net_device *dev,
                wrqu->retry.value = priv->short_retry_limit;
        }
 
-       IPW_DEBUG_WX("GET Retry -> %d \n", wrqu->retry.value);
+       IPW_DEBUG_WX("GET Retry -> %d\n", wrqu->retry.value);
 
        return 0;
 }
@@ -7440,7 +7486,7 @@ static int ipw2100_wx_set_scan(struct net_device *dev,
                               struct iw_request_info *info,
                               union iwreq_data *wrqu, char *extra)
 {
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
        int err = 0;
 
        mutex_lock(&priv->action_mutex);
@@ -7472,8 +7518,8 @@ static int ipw2100_wx_get_scan(struct net_device *dev,
         * This can be called at any time.  No action lock required
         */
 
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
-       return ieee80211_wx_get_scan(priv->ieee, info, wrqu, extra);
+       struct ipw2100_priv *priv = libipw_priv(dev);
+       return libipw_wx_get_scan(priv->ieee, info, wrqu, extra);
 }
 
 /*
@@ -7487,8 +7533,8 @@ static int ipw2100_wx_set_encode(struct net_device *dev,
         * No check of STATUS_INITIALIZED required
         */
 
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
-       return ieee80211_wx_set_encode(priv->ieee, info, wrqu, key);
+       struct ipw2100_priv *priv = libipw_priv(dev);
+       return libipw_wx_set_encode(priv->ieee, info, wrqu, key);
 }
 
 static int ipw2100_wx_get_encode(struct net_device *dev,
@@ -7499,15 +7545,15 @@ static int ipw2100_wx_get_encode(struct net_device *dev,
         * This can be called at any time.  No action lock required
         */
 
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
-       return ieee80211_wx_get_encode(priv->ieee, info, wrqu, key);
+       struct ipw2100_priv *priv = libipw_priv(dev);
+       return libipw_wx_get_encode(priv->ieee, info, wrqu, key);
 }
 
 static int ipw2100_wx_set_power(struct net_device *dev,
                                struct iw_request_info *info,
                                union iwreq_data *wrqu, char *extra)
 {
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
        int err = 0;
 
        mutex_lock(&priv->action_mutex);
@@ -7556,7 +7602,7 @@ static int ipw2100_wx_get_power(struct net_device *dev,
         * This can be called at any time.  No action lock required
         */
 
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
 
        if (!(priv->power_mode & IPW_POWER_ENABLED))
                wrqu->power.disabled = 1;
@@ -7580,8 +7626,8 @@ static int ipw2100_wx_set_genie(struct net_device *dev,
                                union iwreq_data *wrqu, char *extra)
 {
 
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
-       struct ieee80211_device *ieee = priv->ieee;
+       struct ipw2100_priv *priv = libipw_priv(dev);
+       struct libipw_device *ieee = priv->ieee;
        u8 *buf;
 
        if (!ieee->wpa_enabled)
@@ -7615,8 +7661,8 @@ static int ipw2100_wx_get_genie(struct net_device *dev,
                                struct iw_request_info *info,
                                union iwreq_data *wrqu, char *extra)
 {
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
-       struct ieee80211_device *ieee = priv->ieee;
+       struct ipw2100_priv *priv = libipw_priv(dev);
+       struct libipw_device *ieee = priv->ieee;
 
        if (ieee->wpa_ie_len == 0 || ieee->wpa_ie == NULL) {
                wrqu->data.length = 0;
@@ -7637,8 +7683,8 @@ static int ipw2100_wx_set_auth(struct net_device *dev,
                               struct iw_request_info *info,
                               union iwreq_data *wrqu, char *extra)
 {
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
-       struct ieee80211_device *ieee = priv->ieee;
+       struct ipw2100_priv *priv = libipw_priv(dev);
+       struct libipw_device *ieee = priv->ieee;
        struct iw_param *param = &wrqu->param;
        struct lib80211_crypt_data *crypt;
        unsigned long flags;
@@ -7682,7 +7728,7 @@ static int ipw2100_wx_set_auth(struct net_device *dev,
                         * can use this to determine if the CAP_PRIVACY_ON bit should
                         * be set.
                         */
-                       struct ieee80211_security sec = {
+                       struct libipw_security sec = {
                                .flags = SEC_ENABLED,
                                .enabled = param->value,
                        };
@@ -7730,8 +7776,8 @@ static int ipw2100_wx_get_auth(struct net_device *dev,
                               struct iw_request_info *info,
                               union iwreq_data *wrqu, char *extra)
 {
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
-       struct ieee80211_device *ieee = priv->ieee;
+       struct ipw2100_priv *priv = libipw_priv(dev);
+       struct libipw_device *ieee = priv->ieee;
        struct lib80211_crypt_data *crypt;
        struct iw_param *param = &wrqu->param;
        int ret = 0;
@@ -7792,8 +7838,8 @@ static int ipw2100_wx_set_encodeext(struct net_device *dev,
                                    struct iw_request_info *info,
                                    union iwreq_data *wrqu, char *extra)
 {
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
-       return ieee80211_wx_set_encodeext(priv->ieee, info, wrqu, extra);
+       struct ipw2100_priv *priv = libipw_priv(dev);
+       return libipw_wx_set_encodeext(priv->ieee, info, wrqu, extra);
 }
 
 /* SIOCGIWENCODEEXT */
@@ -7801,8 +7847,8 @@ static int ipw2100_wx_get_encodeext(struct net_device *dev,
                                    struct iw_request_info *info,
                                    union iwreq_data *wrqu, char *extra)
 {
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
-       return ieee80211_wx_get_encodeext(priv->ieee, info, wrqu, extra);
+       struct ipw2100_priv *priv = libipw_priv(dev);
+       return libipw_wx_get_encodeext(priv->ieee, info, wrqu, extra);
 }
 
 /* SIOCSIWMLME */
@@ -7810,7 +7856,7 @@ static int ipw2100_wx_set_mlme(struct net_device *dev,
                               struct iw_request_info *info,
                               union iwreq_data *wrqu, char *extra)
 {
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
        struct iw_mlme *mlme = (struct iw_mlme *)extra;
        __le16 reason;
 
@@ -7841,7 +7887,7 @@ static int ipw2100_wx_set_promisc(struct net_device *dev,
                                  struct iw_request_info *info,
                                  union iwreq_data *wrqu, char *extra)
 {
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
        int *parms = (int *)extra;
        int enable = (parms[0] > 0);
        int err = 0;
@@ -7872,7 +7918,7 @@ static int ipw2100_wx_reset(struct net_device *dev,
                            struct iw_request_info *info,
                            union iwreq_data *wrqu, char *extra)
 {
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
        if (priv->status & STATUS_INITIALIZED)
                schedule_reset(priv);
        return 0;
@@ -7884,7 +7930,7 @@ static int ipw2100_wx_set_powermode(struct net_device *dev,
                                    struct iw_request_info *info,
                                    union iwreq_data *wrqu, char *extra)
 {
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
        int err = 0, mode = *(int *)extra;
 
        mutex_lock(&priv->action_mutex);
@@ -7912,7 +7958,7 @@ static int ipw2100_wx_get_powermode(struct net_device *dev,
         * This can be called at any time.  No action lock required
         */
 
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
        int level = IPW_POWER_LEVEL(priv->power_mode);
        s32 timeout, period;
 
@@ -7948,7 +7994,7 @@ static int ipw2100_wx_set_preamble(struct net_device *dev,
                                   struct iw_request_info *info,
                                   union iwreq_data *wrqu, char *extra)
 {
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
        int err, mode = *(int *)extra;
 
        mutex_lock(&priv->action_mutex);
@@ -7981,7 +8027,7 @@ static int ipw2100_wx_get_preamble(struct net_device *dev,
         * This can be called at any time.  No action lock required
         */
 
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
 
        if (priv->config & CFG_LONG_PREAMBLE)
                snprintf(wrqu->name, IFNAMSIZ, "long (1)");
@@ -7996,7 +8042,7 @@ static int ipw2100_wx_set_crc_check(struct net_device *dev,
                                    struct iw_request_info *info,
                                    union iwreq_data *wrqu, char *extra)
 {
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
        int err, mode = *(int *)extra;
 
        mutex_lock(&priv->action_mutex);
@@ -8028,7 +8074,7 @@ static int ipw2100_wx_get_crc_check(struct net_device *dev,
         * This can be called at any time.  No action lock required
         */
 
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
 
        if (priv->config & CFG_CRC_CHECK)
                snprintf(wrqu->name, IFNAMSIZ, "CRC checked (1)");
@@ -8040,61 +8086,41 @@ static int ipw2100_wx_get_crc_check(struct net_device *dev,
 #endif                         /* CONFIG_IPW2100_MONITOR */
 
 static iw_handler ipw2100_wx_handlers[] = {
-       NULL,                   /* SIOCSIWCOMMIT */
-       ipw2100_wx_get_name,    /* SIOCGIWNAME */
-       NULL,                   /* SIOCSIWNWID */
-       NULL,                   /* SIOCGIWNWID */
-       ipw2100_wx_set_freq,    /* SIOCSIWFREQ */
-       ipw2100_wx_get_freq,    /* SIOCGIWFREQ */
-       ipw2100_wx_set_mode,    /* SIOCSIWMODE */
-       ipw2100_wx_get_mode,    /* SIOCGIWMODE */
-       NULL,                   /* SIOCSIWSENS */
-       NULL,                   /* SIOCGIWSENS */
-       NULL,                   /* SIOCSIWRANGE */
-       ipw2100_wx_get_range,   /* SIOCGIWRANGE */
-       NULL,                   /* SIOCSIWPRIV */
-       NULL,                   /* SIOCGIWPRIV */
-       NULL,                   /* SIOCSIWSTATS */
-       NULL,                   /* SIOCGIWSTATS */
-       NULL,                   /* SIOCSIWSPY */
-       NULL,                   /* SIOCGIWSPY */
-       NULL,                   /* SIOCGIWTHRSPY */
-       NULL,                   /* SIOCWIWTHRSPY */
-       ipw2100_wx_set_wap,     /* SIOCSIWAP */
-       ipw2100_wx_get_wap,     /* SIOCGIWAP */
-       ipw2100_wx_set_mlme,    /* SIOCSIWMLME */
-       NULL,                   /* SIOCGIWAPLIST -- deprecated */
-       ipw2100_wx_set_scan,    /* SIOCSIWSCAN */
-       ipw2100_wx_get_scan,    /* SIOCGIWSCAN */
-       ipw2100_wx_set_essid,   /* SIOCSIWESSID */
-       ipw2100_wx_get_essid,   /* SIOCGIWESSID */
-       ipw2100_wx_set_nick,    /* SIOCSIWNICKN */
-       ipw2100_wx_get_nick,    /* SIOCGIWNICKN */
-       NULL,                   /* -- hole -- */
-       NULL,                   /* -- hole -- */
-       ipw2100_wx_set_rate,    /* SIOCSIWRATE */
-       ipw2100_wx_get_rate,    /* SIOCGIWRATE */
-       ipw2100_wx_set_rts,     /* SIOCSIWRTS */
-       ipw2100_wx_get_rts,     /* SIOCGIWRTS */
-       ipw2100_wx_set_frag,    /* SIOCSIWFRAG */
-       ipw2100_wx_get_frag,    /* SIOCGIWFRAG */
-       ipw2100_wx_set_txpow,   /* SIOCSIWTXPOW */
-       ipw2100_wx_get_txpow,   /* SIOCGIWTXPOW */
-       ipw2100_wx_set_retry,   /* SIOCSIWRETRY */
-       ipw2100_wx_get_retry,   /* SIOCGIWRETRY */
-       ipw2100_wx_set_encode,  /* SIOCSIWENCODE */
-       ipw2100_wx_get_encode,  /* SIOCGIWENCODE */
-       ipw2100_wx_set_power,   /* SIOCSIWPOWER */
-       ipw2100_wx_get_power,   /* SIOCGIWPOWER */
-       NULL,                   /* -- hole -- */
-       NULL,                   /* -- hole -- */
-       ipw2100_wx_set_genie,   /* SIOCSIWGENIE */
-       ipw2100_wx_get_genie,   /* SIOCGIWGENIE */
-       ipw2100_wx_set_auth,    /* SIOCSIWAUTH */
-       ipw2100_wx_get_auth,    /* SIOCGIWAUTH */
-       ipw2100_wx_set_encodeext,       /* SIOCSIWENCODEEXT */
-       ipw2100_wx_get_encodeext,       /* SIOCGIWENCODEEXT */
-       NULL,                   /* SIOCSIWPMKSA */
+       IW_HANDLER(SIOCGIWNAME, ipw2100_wx_get_name),
+       IW_HANDLER(SIOCSIWFREQ, ipw2100_wx_set_freq),
+       IW_HANDLER(SIOCGIWFREQ, ipw2100_wx_get_freq),
+       IW_HANDLER(SIOCSIWMODE, ipw2100_wx_set_mode),
+       IW_HANDLER(SIOCGIWMODE, ipw2100_wx_get_mode),
+       IW_HANDLER(SIOCGIWRANGE, ipw2100_wx_get_range),
+       IW_HANDLER(SIOCSIWAP, ipw2100_wx_set_wap),
+       IW_HANDLER(SIOCGIWAP, ipw2100_wx_get_wap),
+       IW_HANDLER(SIOCSIWMLME, ipw2100_wx_set_mlme),
+       IW_HANDLER(SIOCSIWSCAN, ipw2100_wx_set_scan),
+       IW_HANDLER(SIOCGIWSCAN, ipw2100_wx_get_scan),
+       IW_HANDLER(SIOCSIWESSID, ipw2100_wx_set_essid),
+       IW_HANDLER(SIOCGIWESSID, ipw2100_wx_get_essid),
+       IW_HANDLER(SIOCSIWNICKN, ipw2100_wx_set_nick),
+       IW_HANDLER(SIOCGIWNICKN, ipw2100_wx_get_nick),
+       IW_HANDLER(SIOCSIWRATE, ipw2100_wx_set_rate),
+       IW_HANDLER(SIOCGIWRATE, ipw2100_wx_get_rate),
+       IW_HANDLER(SIOCSIWRTS, ipw2100_wx_set_rts),
+       IW_HANDLER(SIOCGIWRTS, ipw2100_wx_get_rts),
+       IW_HANDLER(SIOCSIWFRAG, ipw2100_wx_set_frag),
+       IW_HANDLER(SIOCGIWFRAG, ipw2100_wx_get_frag),
+       IW_HANDLER(SIOCSIWTXPOW, ipw2100_wx_set_txpow),
+       IW_HANDLER(SIOCGIWTXPOW, ipw2100_wx_get_txpow),
+       IW_HANDLER(SIOCSIWRETRY, ipw2100_wx_set_retry),
+       IW_HANDLER(SIOCGIWRETRY, ipw2100_wx_get_retry),
+       IW_HANDLER(SIOCSIWENCODE, ipw2100_wx_set_encode),
+       IW_HANDLER(SIOCGIWENCODE, ipw2100_wx_get_encode),
+       IW_HANDLER(SIOCSIWPOWER, ipw2100_wx_set_power),
+       IW_HANDLER(SIOCGIWPOWER, ipw2100_wx_get_power),
+       IW_HANDLER(SIOCSIWGENIE, ipw2100_wx_set_genie),
+       IW_HANDLER(SIOCGIWGENIE, ipw2100_wx_get_genie),
+       IW_HANDLER(SIOCSIWAUTH, ipw2100_wx_set_auth),
+       IW_HANDLER(SIOCGIWAUTH, ipw2100_wx_get_auth),
+       IW_HANDLER(SIOCSIWENCODEEXT, ipw2100_wx_set_encodeext),
+       IW_HANDLER(SIOCGIWENCODEEXT, ipw2100_wx_get_encodeext),
 };
 
 #define IPW2100_PRIV_SET_MONITOR       SIOCIWFIRSTPRIV
@@ -8179,10 +8205,11 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device *dev)
        int rssi_qual;
        int tx_qual;
        int beacon_qual;
+       int quality;
 
-       struct ipw2100_priv *priv = ieee80211_priv(dev);
+       struct ipw2100_priv *priv = libipw_priv(dev);
        struct iw_statistics *wstats;
-       u32 rssi, quality, tx_retries, missed_beacons, tx_failures;
+       u32 rssi, tx_retries, missed_beacons, tx_failures;
        u32 ord_len = sizeof(u32);
 
        if (!priv)
@@ -8265,7 +8292,8 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device *dev)
                        beacon_qual = (20 - missed_beacons) *
                            (PERFECT - VERY_GOOD) / 20 + VERY_GOOD;
 
-               quality = min(beacon_qual, min(tx_qual, rssi_qual));
+               quality = min(tx_qual, rssi_qual);
+               quality = min(beacon_qual, quality);
 
 #ifdef CONFIG_IPW2100_DEBUG
                if (beacon_qual == quality)
@@ -8396,7 +8424,7 @@ struct ipw2100_fw_header {
        short mode;
        unsigned int fw_size;
        unsigned int uc_size;
-} __attribute__ ((packed));
+} __packed;
 
 static int ipw2100_mod_firmware_load(struct ipw2100_fw *fw)
 {
@@ -8460,12 +8488,17 @@ static int ipw2100_get_firmware(struct ipw2100_priv *priv,
        return 0;
 }
 
+MODULE_FIRMWARE(IPW2100_FW_NAME("-i"));
+#ifdef CONFIG_IPW2100_MONITOR
+MODULE_FIRMWARE(IPW2100_FW_NAME("-p"));
+#endif
+MODULE_FIRMWARE(IPW2100_FW_NAME(""));
+
 static void ipw2100_release_firmware(struct ipw2100_priv *priv,
                                     struct ipw2100_fw *fw)
 {
        fw->version = 0;
-       if (fw->fw_entry)
-               release_firmware(fw->fw_entry);
+       release_firmware(fw->fw_entry);
        fw->fw_entry = NULL;
 }
 
@@ -8565,7 +8598,7 @@ static int ipw2100_ucode_download(struct ipw2100_priv *priv,
        struct net_device *dev = priv->net_dev;
        const unsigned char *microcode_data = fw->uc.data;
        unsigned int microcode_data_left = fw->uc.size;
-       void __iomem *reg = (void __iomem *)dev->base_addr;
+       void __iomem *reg = priv->ioaddr;
 
        struct symbol_alive_response response;
        int i, j;