iwlwifi: add missing rcu_read_lock
[safe/jmp/linux-2.6] / drivers / net / wireless / ipw2x00 / ipw2100.c
index 2d2044d..0bd4dfa 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
@@ -174,6 +174,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"
 
+struct pm_qos_request_list *ipw2100_pm_qos_req;
+
 /* Debugging stuff */
 #ifdef CONFIG_IPW2100_DEBUG
 #define IPW2100_RX_DEBUG       /* Reception debugging */
@@ -185,7 +187,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 +197,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);
@@ -296,6 +298,33 @@ static const char *command_types[] = {
 };
 #endif
 
+#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
+};
+
+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_rates_11b)
+
 /* 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);
@@ -551,7 +580,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;
@@ -1141,6 +1170,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 +1181,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);
 }
@@ -1332,7 +1365,7 @@ static int ipw2100_power_cycle_adapter(struct ipw2100_priv *priv)
                       IPW_AUX_HOST_RESET_REG_STOP_MASTER);
 
        /* Step 2. Wait for stop Master Assert
-        *         (not more then 50us, otherwise ret error */
+        *         (not more than 50us, otherwise ret error */
        i = 5;
        do {
                udelay(IPW_WAIT_RESET_MASTER_ASSERT_COMPLETE_DELAY);
@@ -1673,7 +1706,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,
@@ -1692,7 +1725,13 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
        u32 lock;
        u32 ord_len = sizeof(lock);
 
-       /* Quite if manually disabled. */
+       /* Age scan list entries found before suspend */
+       if (priv->suspend_time) {
+               libipw_networks_age(priv->ieee, priv->suspend_time);
+               priv->suspend_time = 0;
+       }
+
+       /* Quiet if manually disabled. */
        if (priv->status & STATUS_RF_KILL_SW) {
                IPW_DEBUG_INFO("%s: Radio is disabled by Manual Disable "
                               "switch\n", priv->net_dev->name);
@@ -1702,7 +1741,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);
@@ -1746,11 +1785,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)) {
@@ -1808,13 +1847,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;
@@ -1830,7 +1862,7 @@ static void ipw2100_down(struct ipw2100_priv *priv)
                cancel_delayed_work(&priv->rf_kill);
        }
 
-       /* Kill the firmare hang check timer */
+       /* Kill the firmware hang check timer */
        if (!priv->stop_hang_check) {
                priv->stop_hang_check = 1;
                cancel_delayed_work(&priv->hang_check);
@@ -1857,8 +1889,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)
@@ -1869,6 +1900,64 @@ static void ipw2100_down(struct ipw2100_priv *priv)
        netif_stop_queue(priv->net_dev);
 }
 
+/* Called by register_netdev() */
+static int ipw2100_net_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 ret;
+       int i;
+
+       ret = ipw2100_up(priv, 1);
+       if (ret)
+               return ret;
+
+       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 =
+                       kzalloc(geo->bg_channels *
+                               sizeof(struct ieee80211_channel), GFP_KERNEL);
+               /* 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;
+       }
+
+       set_wiphy_dev(wdev->wiphy, &priv->pci_dev->dev);
+       if (wiphy_register(wdev->wiphy)) {
+               ipw2100_down(priv);
+               return -EIO;
+       }
+       return 0;
+}
+
 static void ipw2100_reset_adapter(struct work_struct *work)
 {
        struct ipw2100_priv *priv =
@@ -1910,7 +1999,8 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
 {
 
 #define MAC_ASSOCIATION_READ_DELAY (HZ)
-       int ret, len, essid_len;
+       int ret;
+       unsigned int len, essid_len;
        char essid[IW_ESSID_MAX_SIZE];
        u32 txrate;
        u32 chan;
@@ -2051,7 +2141,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);
 
@@ -2083,6 +2173,7 @@ 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 */
@@ -2333,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
  *
@@ -2355,7 +2446,7 @@ static void ipw2100_corruption_detected(struct ipw2100_priv *priv, int i)
                       i * sizeof(struct ipw2100_status));
 
 #ifdef IPW2100_DEBUG_C3
-       /* Halt the fimrware so we can get a good image */
+       /* Halt the firmware so we can get a good image */
        write_register(priv->net_dev, IPW_REG_RESET_REG,
                       IPW_AUX_HOST_RESET_REG_STOP_MASTER);
        j = 5;
@@ -2384,13 +2475,14 @@ static void ipw2100_corruption_detected(struct ipw2100_priv *priv, int i)
 #endif
 
        priv->fatal_error = IPW2100_ERR_C3_CORRUPTION;
-       priv->ieee->stats.rx_errors++;
+       priv->net_dev->stats.rx_errors++;
        schedule_reset(priv);
 }
 
 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];
        struct ipw2100_rx_packet *packet = &priv->rx_buffers[i];
 
@@ -2399,14 +2491,14 @@ static void isr_rx(struct ipw2100_priv *priv, int i,
        if (unlikely(status->frame_size > skb_tailroom(packet->skb))) {
                IPW_DEBUG_INFO("%s: frame_size (%u) > skb_tailroom (%u)!"
                               "  Dropping.\n",
-                              priv->net_dev->name,
+                              dev->name,
                               status->frame_size, skb_tailroom(packet->skb));
-               priv->ieee->stats.rx_errors++;
+               dev->stats.rx_errors++;
                return;
        }
 
-       if (unlikely(!netif_running(priv->net_dev))) {
-               priv->ieee->stats.rx_errors++;
+       if (unlikely(!netif_running(dev))) {
+               dev->stats.rx_errors++;
                priv->wstats.discard.misc++;
                IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
                return;
@@ -2427,21 +2519,21 @@ 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",
-                              priv->net_dev->name);
+                              dev->name);
                printk_buf(IPW_DL_DROP, packet_data, status->frame_size);
 #endif
-               priv->ieee->stats.rx_errors++;
+               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;
        }
@@ -2450,7 +2542,7 @@ static void isr_rx(struct ipw2100_priv *priv, int i,
        if (unlikely(ipw2100_alloc_skb(priv, packet))) {
                printk(KERN_WARNING DRV_NAME ": "
                       "%s: Unable to allocate SKB onto RBD ring - disabling "
-                      "adapter.\n", priv->net_dev->name);
+                      "adapter.\n", dev->name);
                /* TODO: schedule adapter shutdown */
                IPW_DEBUG_INFO("TODO: Shutdown adapter...\n");
        }
@@ -2462,8 +2554,9 @@ 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];
        struct ipw2100_rx_packet *packet = &priv->rx_buffers[i];
 
@@ -2481,15 +2574,15 @@ static void isr_rx_monitor(struct ipw2100_priv *priv, int i,
                                sizeof(struct ipw_rt_hdr))) {
                IPW_DEBUG_INFO("%s: frame_size (%u) > skb_tailroom (%u)!"
                               "  Dropping.\n",
-                              priv->net_dev->name,
+                              dev->name,
                               status->frame_size,
                               skb_tailroom(packet->skb));
-               priv->ieee->stats.rx_errors++;
+               dev->stats.rx_errors++;
                return;
        }
 
-       if (unlikely(!netif_running(priv->net_dev))) {
-               priv->ieee->stats.rx_errors++;
+       if (unlikely(!netif_running(dev))) {
+               dev->stats.rx_errors++;
                priv->wstats.discard.misc++;
                IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
                return;
@@ -2498,7 +2591,7 @@ static void isr_rx_monitor(struct ipw2100_priv *priv, int i,
        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++;
+               dev->stats.rx_errors++;
                return;
        }
 
@@ -2519,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)) {
-               priv->ieee->stats.rx_errors++;
+       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;
        }
@@ -2531,7 +2624,7 @@ static void isr_rx_monitor(struct ipw2100_priv *priv, int i,
        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);
+                       "adapter.\n", dev->name);
                /* TODO: schedule adapter shutdown */
                IPW_DEBUG_INFO("TODO: Shutdown adapter...\n");
        }
@@ -2606,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,
        };
 
@@ -2652,8 +2745,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],
@@ -2677,11 +2770,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;
 
@@ -2835,7 +2928,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)),
@@ -2875,7 +2968,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);
@@ -3019,7 +3112,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
@@ -3035,7 +3128,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);
                }
@@ -3053,7 +3146,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) {
@@ -3077,7 +3170,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;
 
@@ -3110,13 +3203,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);
 
@@ -3147,7 +3240,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)
@@ -3193,7 +3285,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);
        }
@@ -3321,10 +3413,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;
@@ -3333,7 +3425,7 @@ static int ipw2100_tx(struct ieee80211_txb *txb, struct net_device *dev,
 
        if (!(priv->status & STATUS_ASSOCIATED)) {
                IPW_DEBUG_INFO("Can not transmit when not connected.\n");
-               priv->ieee->stats.tx_carrier_errors++;
+               priv->net_dev->stats.tx_carrier_errors++;
                netif_stop_queue(dev);
                goto fail_unlock;
        }
@@ -3360,12 +3452,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)
@@ -3479,7 +3571,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);
 }
 
@@ -3488,7 +3580,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);
 }
 
@@ -3497,7 +3589,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);
 }
 
@@ -4058,7 +4150,7 @@ static ssize_t show_bssinfo(struct device *d, struct device_attribute *attr,
        u8 bssid[ETH_ALEN];
        u32 chan = 0;
        char *out = buf;
-       int length;
+       unsigned int length;
        int ret;
 
        if (priv->status & STATUS_RF_KILL_MASK)
@@ -4215,7 +4307,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);
@@ -4479,7 +4571,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;
                }
@@ -4518,7 +4610,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;
                }
@@ -5268,21 +5360,21 @@ static int ipw2100_set_ibss_beacon_interval(struct ipw2100_priv *priv,
        return 0;
 }
 
-void ipw2100_queues_initialize(struct ipw2100_priv *priv)
+static void ipw2100_queues_initialize(struct ipw2100_priv *priv)
 {
        ipw2100_tx_initialize(priv);
        ipw2100_rx_initialize(priv);
        ipw2100_msg_initialize(priv);
 }
 
-void ipw2100_queues_free(struct ipw2100_priv *priv)
+static void ipw2100_queues_free(struct ipw2100_priv *priv)
 {
        ipw2100_tx_free(priv);
        ipw2100_rx_free(priv);
        ipw2100_msg_free(priv);
 }
 
-int ipw2100_queues_allocate(struct ipw2100_priv *priv)
+static int ipw2100_queues_allocate(struct ipw2100_priv *priv)
 {
        if (ipw2100_tx_allocate(priv) ||
            ipw2100_rx_allocate(priv) || ipw2100_msg_allocate(priv))
@@ -5549,9 +5641,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);
@@ -5744,7 +5836,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;
 
@@ -5772,7 +5864,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");
 
@@ -5788,7 +5880,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;
@@ -5809,7 +5901,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);
@@ -5827,9 +5919,9 @@ 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);
 
-       priv->ieee->stats.tx_errors++;
+       dev->stats.tx_errors++;
 
 #ifdef CONFIG_IPW2100_MONITOR
        if (priv->ieee->iw_mode == IW_MODE_MONITOR)
@@ -5852,8 +5944,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;
@@ -5898,7 +5990,7 @@ 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);
@@ -5915,7 +6007,7 @@ static void ipw_ethtool_get_drvinfo(struct net_device *dev,
 
 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;
 }
 
@@ -5999,7 +6091,18 @@ static void ipw2100_rf_kill(struct work_struct *work)
 
 static void ipw2100_irq_tasklet(struct ipw2100_priv *priv);
 
-/* Look into using netdev destructor to shutdown ieee80211? */
+static const struct net_device_ops ipw2100_netdev_ops = {
+       .ndo_open               = ipw2100_open,
+       .ndo_stop               = ipw2100_close,
+       .ndo_start_xmit         = libipw_xmit,
+       .ndo_change_mtu         = libipw_change_mtu,
+       .ndo_init               = ipw2100_net_init,
+       .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 libipw? */
 
 static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
                                               void __iomem * base_addr,
@@ -6009,10 +6112,10 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
        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;
@@ -6023,15 +6126,11 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
        priv->ieee->perfect_rssi = -20;
        priv->ieee->worst_rssi = -85;
 
-       dev->open = ipw2100_open;
-       dev->stop = ipw2100_close;
-       dev->init = ipw2100_net_init;
+       dev->netdev_ops = &ipw2100_netdev_ops;
        dev->ethtool_ops = &ipw2100_ethtool_ops;
-       dev->tx_timeout = ipw2100_tx_timeout;
        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->set_mac_address = ipw2100_set_address;
        dev->watchdog_timeo = 3 * HZ;
        dev->irq = 0;
 
@@ -6060,7 +6159,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;
@@ -6186,12 +6285,12 @@ 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);
 
-       err = pci_set_dma_mask(pci_dev, DMA_32BIT_MASK);
+       err = pci_set_dma_mask(pci_dev, DMA_BIT_MASK(32));
        if (err) {
                printk(KERN_WARNING DRV_NAME
                       "Error calling pci_set_dma_mask.\n");
@@ -6326,7 +6425,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
                sysfs_remove_group(&pci_dev->dev.kobj,
                                   &ipw2100_attribute_group);
 
-               free_ieee80211(dev);
+               free_libipw(dev, 0);
                pci_set_drvdata(pci_dev, NULL);
        }
 
@@ -6384,7 +6483,10 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
                if (dev->base_addr)
                        iounmap((void __iomem *)dev->base_addr);
 
-               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);
@@ -6414,6 +6516,8 @@ 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);
 
+       priv->suspend_at = get_seconds();
+
        mutex_unlock(&priv->action_mutex);
 
        return 0;
@@ -6457,6 +6561,8 @@ static int ipw2100_resume(struct pci_dev *pci_dev)
         * the queue of needed */
        netif_device_attach(dev);
 
+       priv->suspend_time = get_seconds() - priv->suspend_at;
+
        /* Bring the device back up */
        if (!(priv->status & STATUS_RF_KILL_SW))
                ipw2100_up(priv, 0);
@@ -6467,9 +6573,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 */
@@ -6530,6 +6646,7 @@ static struct pci_driver ipw2100_pci_driver = {
        .suspend = ipw2100_suspend,
        .resume = ipw2100_resume,
 #endif
+       .shutdown = ipw2100_shutdown,
 };
 
 /**
@@ -6552,7 +6669,7 @@ static int __init ipw2100_init(void)
        if (ret)
                goto out;
 
-       pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY, "ipw2100",
+       ipw2100_pm_qos_req = pm_qos_add_request(PM_QOS_CPU_DMA_LATENCY,
                        PM_QOS_DEFAULT_VALUE);
 #ifdef CONFIG_IPW2100_DEBUG
        ipw2100_debug_level = debug;
@@ -6575,32 +6692,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)
@@ -6609,7 +6706,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
@@ -6623,7 +6720,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;
 
@@ -6656,7 +6753,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);
        }
 
@@ -6673,7 +6770,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;
 
@@ -6685,7 +6782,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;
 
 }
@@ -6694,10 +6791,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;
@@ -6737,7 +6834,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);
@@ -6772,7 +6869,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;
@@ -6800,7 +6897,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 */
@@ -6893,7 +6990,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[] = {
@@ -6942,7 +7039,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 */
@@ -6960,7 +7057,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;
@@ -7015,7 +7112,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
@@ -7043,7 +7140,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;
@@ -7052,7 +7149,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;
 }
@@ -7065,13 +7162,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;
 }
@@ -7080,7 +7177,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;
@@ -7110,7 +7207,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;
@@ -7120,9 +7217,9 @@ 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;
-       int len = sizeof(val);
+       unsigned int len = sizeof(val);
        int err = 0;
 
        if (!(priv->status & STATUS_ENABLED) ||
@@ -7161,7 +7258,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);
@@ -7172,7 +7269,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 */
@@ -7197,7 +7294,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;
@@ -7211,7 +7308,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 */
@@ -7219,7 +7316,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;
 }
@@ -7228,7 +7325,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))
@@ -7258,7 +7355,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);
@@ -7273,7 +7370,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;
 
@@ -7287,7 +7384,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;
 }
@@ -7300,7 +7397,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;
@@ -7317,7 +7414,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;
 }
@@ -7330,12 +7427,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;
 }
@@ -7344,7 +7441,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)
@@ -7361,14 +7458,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;
        }
@@ -7377,7 +7474,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);
@@ -7392,7 +7489,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 */
 
@@ -7411,7 +7508,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;
 }
@@ -7420,7 +7517,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);
@@ -7452,8 +7549,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);
 }
 
 /*
@@ -7467,8 +7564,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,
@@ -7479,15 +7576,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);
@@ -7536,7 +7633,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;
@@ -7560,8 +7657,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)
@@ -7595,8 +7692,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;
@@ -7617,8 +7714,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;
@@ -7662,7 +7759,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,
                        };
@@ -7710,8 +7807,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;
@@ -7772,8 +7869,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 */
@@ -7781,8 +7878,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 */
@@ -7790,7 +7887,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;
 
@@ -7821,7 +7918,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;
@@ -7852,7 +7949,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;
@@ -7864,7 +7961,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);
@@ -7892,7 +7989,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;
 
@@ -7928,7 +8025,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);
@@ -7961,7 +8058,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)");
@@ -7976,7 +8073,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);
@@ -8008,7 +8105,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)");
@@ -8159,10 +8256,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)
@@ -8245,7 +8343,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)
@@ -8297,7 +8396,7 @@ static void ipw2100_wx_event_work(struct work_struct *work)
        struct ipw2100_priv *priv =
                container_of(work, struct ipw2100_priv, wx_event_work.work);
        union iwreq_data wrqu;
-       int len = ETH_ALEN;
+       unsigned int len = ETH_ALEN;
 
        if (priv->status & STATUS_STOPPING)
                return;
@@ -8440,6 +8539,12 @@ 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)
 {