iwlwifi: remove a parameter (dest) from *_fill_beacon_frame() methods.
[safe/jmp/linux-2.6] / drivers / net / wireless / iwlwifi / iwl3945-base.c
index 05121f3..d9c6baf 100644 (file)
  * 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
  *
  *****************************************************************************/
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
@@ -42,6 +41,7 @@
 #include <linux/if_arp.h>
 
 #include <net/ieee80211_radiotap.h>
+#include <net/lib80211.h>
 #include <net/mac80211.h>
 
 #include <asm/div64.h>
@@ -69,7 +69,6 @@ static int iwl3945_param_debug;    /* def: 0 = minimal debug log messages */
 static int iwl3945_param_disable;  /* def: 0 = enable radio */
 static int iwl3945_param_antenna;  /* def: 0 = both antennas (use diversity) */
 int iwl3945_param_hwcrypto;        /* def: 0 = use software encryption */
-static int iwl3945_param_qos_enable = 1; /* def: 1 = use quality of service */
 int iwl3945_param_queues_num = IWL39_MAX_NUM_QUEUES; /* def: 8 Tx queues */
 
 /*
@@ -94,12 +93,13 @@ int iwl3945_param_queues_num = IWL39_MAX_NUM_QUEUES; /* def: 8 Tx queues */
 
 #define IWLWIFI_VERSION "1.2.26k" VD VS
 #define DRV_COPYRIGHT  "Copyright(c) 2003-2008 Intel Corporation"
+#define DRV_AUTHOR     "<ilw@linux.intel.com>"
 #define DRV_VERSION     IWLWIFI_VERSION
 
 
 MODULE_DESCRIPTION(DRV_DESCRIPTION);
 MODULE_VERSION(DRV_VERSION);
-MODULE_AUTHOR(DRV_COPYRIGHT);
+MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
 MODULE_LICENSE("GPL");
 
 static const struct ieee80211_supported_band *iwl3945_get_band(
@@ -108,46 +108,6 @@ static const struct ieee80211_supported_band *iwl3945_get_band(
        return priv->hw->wiphy->bands[band];
 }
 
-static int iwl3945_is_empty_essid(const char *essid, int essid_len)
-{
-       /* Single white space is for Linksys APs */
-       if (essid_len == 1 && essid[0] == ' ')
-               return 1;
-
-       /* Otherwise, if the entire essid is 0, we assume it is hidden */
-       while (essid_len) {
-               essid_len--;
-               if (essid[essid_len] != '\0')
-                       return 0;
-       }
-
-       return 1;
-}
-
-static const char *iwl3945_escape_essid(const char *essid, u8 essid_len)
-{
-       static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
-       const char *s = essid;
-       char *d = escaped;
-
-       if (iwl3945_is_empty_essid(essid, essid_len)) {
-               memcpy(escaped, "<hidden>", sizeof("<hidden>"));
-               return escaped;
-       }
-
-       essid_len = min(essid_len, (u8) IW_ESSID_MAX_SIZE);
-       while (essid_len--) {
-               if (*s == '\0') {
-                       *d++ = '\\';
-                       *d++ = '0';
-                       s++;
-               } else
-                       *d++ = *s++;
-       }
-       *d = '\0';
-       return escaped;
-}
-
 /*************** DMA-QUEUE-GENERAL-FUNCTIONS  *****
  * DMA services
  *
@@ -275,10 +235,8 @@ static int iwl3945_tx_queue_alloc(struct iwl3945_priv *priv,
        return 0;
 
  error:
-       if (txq->txb) {
-               kfree(txq->txb);
-               txq->txb = NULL;
-       }
+       kfree(txq->txb);
+       txq->txb = NULL;
 
        return -ENOMEM;
 }
@@ -365,10 +323,8 @@ void iwl3945_tx_queue_free(struct iwl3945_priv *priv, struct iwl3945_tx_queue *t
                                    txq->q.n_bd, txq->bd, txq->q.dma_addr);
 
        /* De-alloc array of per-TFD driver data */
-       if (txq->txb) {
-               kfree(txq->txb);
-               txq->txb = NULL;
-       }
+       kfree(txq->txb);
+       txq->txb = NULL;
 
        /* 0-fill queue descriptor structure */
        memset(txq, 0, sizeof(*txq));
@@ -451,7 +407,6 @@ u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap, u8
        int index = IWL_INVALID_STATION;
        struct iwl3945_station_entry *station;
        unsigned long flags_spin;
-       DECLARE_MAC_BUF(mac);
        u8 rate;
 
        spin_lock_irqsave(&priv->sta_lock, flags_spin);
@@ -485,7 +440,7 @@ u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap, u8
                return index;
        }
 
-       IWL_DEBUG_ASSOC("Add STA ID %d: %s\n", index, print_mac(mac, addr));
+       IWL_DEBUG_ASSOC("Add STA ID %d: %pM\n", index, addr);
        station = &priv->stations[index];
        station->used = 1;
        priv->num_stations++;
@@ -564,7 +519,7 @@ static inline int iwl3945_is_ready_rf(struct iwl3945_priv *priv)
 
 /*************** HOST COMMAND QUEUE FUNCTIONS   *****/
 
-#define IWL_CMD(x) case x : return #x
+#define IWL_CMD(x) case x: return #x
 
 static const char *get_cmd_string(u8 cmd)
 {
@@ -1068,7 +1023,6 @@ static int iwl3945_commit_rxon(struct iwl3945_priv *priv)
        /* cast away the const for active_rxon in this function */
        struct iwl3945_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
        int rc = 0;
-       DECLARE_MAC_BUF(mac);
 
        if (!iwl3945_is_alive(priv))
                return -1;
@@ -1129,11 +1083,11 @@ static int iwl3945_commit_rxon(struct iwl3945_priv *priv)
        IWL_DEBUG_INFO("Sending RXON\n"
                       "* with%s RXON_FILTER_ASSOC_MSK\n"
                       "* channel = %d\n"
-                      "* bssid = %s\n",
+                      "* bssid = %pM\n",
                       ((priv->staging_rxon.filter_flags &
                         RXON_FILTER_ASSOC_MSK) ? "" : "out"),
                       le16_to_cpu(priv->staging_rxon.channel),
-                      print_mac(mac, priv->staging_rxon.bssid_addr));
+                      priv->staging_rxon.bssid_addr);
 
        /* Apply the new configuration */
        rc = iwl3945_send_cmd_pdu(priv, REPLY_RXON,
@@ -1165,7 +1119,7 @@ static int iwl3945_commit_rxon(struct iwl3945_priv *priv)
        /* If we have set the ASSOC_MSK and we are in BSS mode then
         * add the IWL_AP_ID to the station rate table */
        if (iwl3945_is_associated(priv) &&
-           (priv->iw_mode == IEEE80211_IF_TYPE_STA))
+           (priv->iw_mode == NL80211_IFTYPE_STATION))
                if (iwl3945_add_station(priv, priv->active_rxon.bssid_addr, 1, 0)
                    == IWL_INVALID_STATION) {
                        IWL_ERROR("Error adding AP address for transmit.\n");
@@ -1448,12 +1402,12 @@ static void iwl3945_free_frame(struct iwl3945_priv *priv, struct iwl3945_frame *
 
 unsigned int iwl3945_fill_beacon_frame(struct iwl3945_priv *priv,
                                struct ieee80211_hdr *hdr,
-                               const u8 *dest, int left)
+                               int left)
 {
 
        if (!iwl3945_is_associated(priv) || !priv->ibss_beacon ||
-           ((priv->iw_mode != IEEE80211_IF_TYPE_IBSS) &&
-            (priv->iw_mode != IEEE80211_IF_TYPE_AP)))
+           ((priv->iw_mode != NL80211_IFTYPE_ADHOC) &&
+            (priv->iw_mode != NL80211_IFTYPE_AP)))
                return 0;
 
        if (priv->ibss_beacon->len > left)
@@ -1464,9 +1418,16 @@ unsigned int iwl3945_fill_beacon_frame(struct iwl3945_priv *priv,
        return priv->ibss_beacon->len;
 }
 
-static u8 iwl3945_rate_get_lowest_plcp(int rate_mask)
+static u8 iwl3945_rate_get_lowest_plcp(struct iwl3945_priv *priv)
 {
        u8 i;
+       int rate_mask;
+
+       /* Set rate mask*/
+       if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
+               rate_mask = priv->active_rate_basic & IWL_CCK_RATES_MASK;
+       else
+               rate_mask = priv->active_rate_basic & IWL_OFDM_RATES_MASK;
 
        for (i = IWL_RATE_1M_INDEX; i != IWL_RATE_INVALID;
             i = iwl3945_rates[i].next_ieee) {
@@ -1474,7 +1435,11 @@ static u8 iwl3945_rate_get_lowest_plcp(int rate_mask)
                        return iwl3945_rates[i].plcp;
        }
 
-       return IWL_RATE_INVALID;
+       /* No valid rate was found. Assign the lowest one */
+       if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
+               return IWL_RATE_1M_PLCP;
+       else
+               return IWL_RATE_6M_PLCP;
 }
 
 static int iwl3945_send_beacon_cmd(struct iwl3945_priv *priv)
@@ -1492,16 +1457,7 @@ static int iwl3945_send_beacon_cmd(struct iwl3945_priv *priv)
                return -ENOMEM;
        }
 
-       if (!(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)) {
-               rate = iwl3945_rate_get_lowest_plcp(priv->active_rate_basic &
-                                               0xFF0);
-               if (rate == IWL_INVALID_RATE)
-                       rate = IWL_RATE_6M_PLCP;
-       } else {
-               rate = iwl3945_rate_get_lowest_plcp(priv->active_rate_basic & 0xF);
-               if (rate == IWL_INVALID_RATE)
-                       rate = IWL_RATE_1M_PLCP;
-       }
+       rate = iwl3945_rate_get_lowest_plcp(priv);
 
        frame_size = iwl3945_hw_get_beacon_cmd(priv, frame, rate);
 
@@ -1549,10 +1505,8 @@ int iwl3945_eeprom_init(struct iwl3945_priv *priv)
 {
        u16 *e = (u16 *)&priv->eeprom;
        u32 gp = iwl3945_read32(priv, CSR_EEPROM_GP);
-       u32 r;
        int sz = sizeof(priv->eeprom);
-       int rc;
-       int i;
+       int ret;
        u16 addr;
 
        /* The EEPROM structure has several padding buffers within it
@@ -1562,34 +1516,33 @@ int iwl3945_eeprom_init(struct iwl3945_priv *priv)
        BUILD_BUG_ON(sizeof(priv->eeprom) != IWL_EEPROM_IMAGE_SIZE);
 
        if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) {
-               IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x", gp);
+               IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x\n", gp);
                return -ENOENT;
        }
 
        /* Make sure driver (instead of uCode) is allowed to read EEPROM */
-       rc = iwl3945_eeprom_acquire_semaphore(priv);
-       if (rc < 0) {
+       ret = iwl3945_eeprom_acquire_semaphore(priv);
+       if (ret < 0) {
                IWL_ERROR("Failed to acquire EEPROM semaphore.\n");
                return -ENOENT;
        }
 
        /* eeprom is an array of 16bit values */
        for (addr = 0; addr < sz; addr += sizeof(u16)) {
-               _iwl3945_write32(priv, CSR_EEPROM_REG, addr << 1);
-               _iwl3945_clear_bit(priv, CSR_EEPROM_REG, CSR_EEPROM_REG_BIT_CMD);
+               u32 r;
 
-               for (i = 0; i < IWL_EEPROM_ACCESS_TIMEOUT;
-                                       i += IWL_EEPROM_ACCESS_DELAY) {
-                       r = _iwl3945_read_direct32(priv, CSR_EEPROM_REG);
-                       if (r & CSR_EEPROM_REG_READ_VALID_MSK)
-                               break;
-                       udelay(IWL_EEPROM_ACCESS_DELAY);
+               _iwl3945_write32(priv, CSR_EEPROM_REG,
+                                CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
+               _iwl3945_clear_bit(priv, CSR_EEPROM_REG, CSR_EEPROM_REG_BIT_CMD);
+               ret = iwl3945_poll_direct_bit(priv, CSR_EEPROM_REG,
+                                             CSR_EEPROM_REG_READ_VALID_MSK,
+                                             IWL_EEPROM_ACCESS_TIMEOUT);
+               if (ret < 0) {
+                       IWL_ERROR("Time out reading EEPROM[%d]\n", addr);
+                       return ret;
                }
 
-               if (!(r & CSR_EEPROM_REG_READ_VALID_MSK)) {
-                       IWL_ERROR("Time out reading EEPROM[%d]", addr);
-                       return -ETIMEDOUT;
-               }
+               r = _iwl3945_read_direct32(priv, CSR_EEPROM_REG);
                e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
        }
 
@@ -1639,7 +1592,7 @@ static u16 iwl3945_supported_rate_to_ie(u8 *ie, u16 supported_rate,
  */
 static u16 iwl3945_fill_probe_req(struct iwl3945_priv *priv,
                              struct ieee80211_mgmt *frame,
-                             int left, int is_direct)
+                             int left)
 {
        int len = 0;
        u8 *pos = NULL;
@@ -1669,20 +1622,6 @@ static u16 iwl3945_fill_probe_req(struct iwl3945_priv *priv,
        *pos++ = WLAN_EID_SSID;
        *pos++ = 0;
 
-       /* fill in our direct SSID IE... */
-       if (is_direct) {
-               /* ...next IE... */
-               left -= 2 + priv->essid_len;
-               if (left < 0)
-                       return 0;
-               /* ... fill it in... */
-               *pos++ = WLAN_EID_SSID;
-               *pos++ = priv->essid_len;
-               memcpy(pos, priv->essid, priv->essid_len);
-               pos += priv->essid_len;
-               len += 2 + priv->essid_len;
-       }
-
        /* fill in supported rate */
        /* ...next IE... */
        left -= 2;
@@ -1751,17 +1690,21 @@ static void iwl3945_reset_qos(struct iwl3945_priv *priv)
        spin_lock_irqsave(&priv->lock, flags);
        priv->qos_data.qos_active = 0;
 
-       if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS) {
-               if (priv->qos_data.qos_enable)
-                       priv->qos_data.qos_active = 1;
-               if (!(priv->active_rate & 0xfff0)) {
-                       cw_min = 31;
-                       is_legacy = 1;
-               }
-       } else if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
-               if (priv->qos_data.qos_enable)
-                       priv->qos_data.qos_active = 1;
-       } else if (!(priv->staging_rxon.flags & RXON_FLG_SHORT_SLOT_MSK)) {
+       /* QoS always active in AP and ADHOC mode
+        * In STA mode wait for association
+        */
+       if (priv->iw_mode == NL80211_IFTYPE_ADHOC ||
+           priv->iw_mode == NL80211_IFTYPE_AP)
+               priv->qos_data.qos_active = 1;
+       else
+               priv->qos_data.qos_active = 0;
+
+
+       /* check for legacy mode */
+       if ((priv->iw_mode == NL80211_IFTYPE_ADHOC &&
+            (priv->active_rate & IWL_OFDM_RATES_MASK) == 0) ||
+           (priv->iw_mode == NL80211_IFTYPE_STATION &&
+            (priv->staging_rxon.flags & RXON_FLG_SHORT_SLOT_MSK) == 0)) {
                cw_min = 31;
                is_legacy = 1;
        }
@@ -1833,9 +1776,6 @@ static void iwl3945_activate_qos(struct iwl3945_priv *priv, u8 force)
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
-       if (!priv->qos_data.qos_enable)
-               return;
-
        spin_lock_irqsave(&priv->lock, flags);
        priv->qos_data.def_qos_parm.qos_flags = 0;
 
@@ -1851,7 +1791,7 @@ static void iwl3945_activate_qos(struct iwl3945_priv *priv, u8 force)
        spin_unlock_irqrestore(&priv->lock, flags);
 
        if (force || iwl3945_is_associated(priv)) {
-               IWL_DEBUG_QOS("send QoS cmd with Qos active %d \n",
+               IWL_DEBUG_QOS("send QoS cmd with QoS active %d \n",
                              priv->qos_data.qos_active);
 
                iwl3945_send_qos_params_command(priv,
@@ -1875,7 +1815,7 @@ static void iwl3945_activate_qos(struct iwl3945_priv *priv, u8 force)
 
 
 /* default power management (not Tx power) table values */
-/* for tim  0-10 */
+/* for TIM  0-10 */
 static struct iwl3945_power_vec_entry range_0[IWL_POWER_AC] = {
        {{NOSLP, SLP_TIMEOUT(0), SLP_TIMEOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
        {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0},
@@ -1885,7 +1825,7 @@ static struct iwl3945_power_vec_entry range_0[IWL_POWER_AC] = {
        {{SLP, SLP_TIMEOUT(25), SLP_TIMEOUT(25), SLP_VEC(4, 7, 10, 10, 10)}, 1}
 };
 
-/* for tim > 10 */
+/* for TIM > 10 */
 static struct iwl3945_power_vec_entry range_1[IWL_POWER_AC] = {
        {{NOSLP, SLP_TIMEOUT(0), SLP_TIMEOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
        {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(500),
@@ -2125,7 +2065,7 @@ static void iwl3945_setup_rxon_timing(struct iwl3945_priv *priv)
        beacon_int = priv->beacon_int;
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       if (priv->iw_mode == IEEE80211_IF_TYPE_STA) {
+       if (priv->iw_mode == NL80211_IFTYPE_STATION) {
                if (beacon_int == 0) {
                        priv->rxon_timing.beacon_interval = cpu_to_le16(100);
                        priv->rxon_timing.beacon_init_val = cpu_to_le32(102400);
@@ -2161,11 +2101,6 @@ static void iwl3945_setup_rxon_timing(struct iwl3945_priv *priv)
 
 static int iwl3945_scan_initiate(struct iwl3945_priv *priv)
 {
-       if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
-               IWL_ERROR("APs don't scan.\n");
-               return 0;
-       }
-
        if (!iwl3945_is_ready_rf(priv)) {
                IWL_DEBUG_SCAN("Aborting scan due to not ready.\n");
                return -EIO;
@@ -2223,7 +2158,7 @@ static void iwl3945_set_flags_for_phymode(struct iwl3945_priv *priv,
                else
                        priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
 
-               if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS)
+               if (priv->iw_mode == NL80211_IFTYPE_ADHOC)
                        priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
 
                priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK;
@@ -2235,36 +2170,37 @@ static void iwl3945_set_flags_for_phymode(struct iwl3945_priv *priv,
 /*
  * initialize rxon structure with default values from eeprom
  */
-static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv)
+static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv,
+                                             int mode)
 {
        const struct iwl3945_channel_info *ch_info;
 
        memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon));
 
-       switch (priv->iw_mode) {
-       case IEEE80211_IF_TYPE_AP:
+       switch (mode) {
+       case NL80211_IFTYPE_AP:
                priv->staging_rxon.dev_type = RXON_DEV_TYPE_AP;
                break;
 
-       case IEEE80211_IF_TYPE_STA:
+       case NL80211_IFTYPE_STATION:
                priv->staging_rxon.dev_type = RXON_DEV_TYPE_ESS;
                priv->staging_rxon.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;
                break;
 
-       case IEEE80211_IF_TYPE_IBSS:
+       case NL80211_IFTYPE_ADHOC:
                priv->staging_rxon.dev_type = RXON_DEV_TYPE_IBSS;
                priv->staging_rxon.flags = RXON_FLG_SHORT_PREAMBLE_MSK;
                priv->staging_rxon.filter_flags = RXON_FILTER_BCON_AWARE_MSK |
                                                  RXON_FILTER_ACCEPT_GRP_MSK;
                break;
 
-       case IEEE80211_IF_TYPE_MNTR:
+       case NL80211_IFTYPE_MONITOR:
                priv->staging_rxon.dev_type = RXON_DEV_TYPE_SNIFFER;
                priv->staging_rxon.filter_flags = RXON_FILTER_PROMISC_MSK |
                    RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_ACCEPT_GRP_MSK;
                break;
        default:
-               IWL_ERROR("Unsupported interface type %d\n", priv->iw_mode);
+               IWL_ERROR("Unsupported interface type %d\n", mode);
                break;
        }
 
@@ -2287,8 +2223,7 @@ static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv)
         * in some case A channels are all non IBSS
         * in this case force B/G channel
         */
-       if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) &&
-           !(is_channel_ibss(ch_info)))
+       if ((mode == NL80211_IFTYPE_ADHOC) && !(is_channel_ibss(ch_info)))
                ch_info = &priv->channel_info[0];
 
        priv->staging_rxon.channel = cpu_to_le16(ch_info->channel);
@@ -2307,7 +2242,7 @@ static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv)
 
 static int iwl3945_set_mode(struct iwl3945_priv *priv, int mode)
 {
-       if (mode == IEEE80211_IF_TYPE_IBSS) {
+       if (mode == NL80211_IFTYPE_ADHOC) {
                const struct iwl3945_channel_info *ch_info;
 
                ch_info = iwl3945_get_channel_info(priv,
@@ -2321,14 +2256,12 @@ static int iwl3945_set_mode(struct iwl3945_priv *priv, int mode)
                }
        }
 
-       priv->iw_mode = mode;
-
-       iwl3945_connection_init_rx_config(priv);
+       iwl3945_connection_init_rx_config(priv, mode);
        memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
 
        iwl3945_clear_stations_table(priv);
 
-       /* dont commit rxon if rf-kill is on*/
+       /* don't commit rxon if rf-kill is on*/
        if (!iwl3945_is_ready_rf(priv))
                return -EAGAIN;
 
@@ -2357,7 +2290,7 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl3945_priv *priv,
        case ALG_CCMP:
                cmd->cmd.tx.sec_ctl = TX_CMD_SEC_CCM;
                memcpy(cmd->cmd.tx.key, keyinfo->key, keyinfo->keylen);
-               IWL_DEBUG_TX("tx_cmd with aes hwcrypto\n");
+               IWL_DEBUG_TX("tx_cmd with AES hwcrypto\n");
                break;
 
        case ALG_TKIP:
@@ -2402,6 +2335,7 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv,
 {
        __le16 fc = hdr->frame_control;
        __le32 tx_flags = cmd->cmd.tx.tx_flags;
+       u8 rc_flags = info->control.rates[0].flags;
 
        cmd->cmd.tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
        if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
@@ -2428,10 +2362,10 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv,
                tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
        }
 
-       if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) {
+       if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
                tx_flags |= TX_CMD_FLG_RTS_MSK;
                tx_flags &= ~TX_CMD_FLG_CTS_MSK;
-       } else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) {
+       } else if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
                tx_flags &= ~TX_CMD_FLG_RTS_MSK;
                tx_flags |= TX_CMD_FLG_CTS_MSK;
        }
@@ -2474,11 +2408,11 @@ static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *h
 
        /* If we are a client station in a BSS network, use the special
         * AP station entry (that's the only station we communicate with) */
-       case IEEE80211_IF_TYPE_STA:
+       case NL80211_IFTYPE_STATION:
                return IWL_AP_ID;
 
        /* If we are an AP, then find the station, or use BCAST */
-       case IEEE80211_IF_TYPE_AP:
+       case NL80211_IFTYPE_AP:
                sta_id = iwl3945_hw_find_station(priv, hdr->addr1);
                if (sta_id != IWL_INVALID_STATION)
                        return sta_id;
@@ -2486,9 +2420,7 @@ static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *h
 
        /* If this frame is going out to an IBSS network, find the station,
         * or create a new station table entry */
-       case IEEE80211_IF_TYPE_IBSS: {
-               DECLARE_MAC_BUF(mac);
-
+       case NL80211_IFTYPE_ADHOC: {
                /* Create new station table entry */
                sta_id = iwl3945_hw_find_station(priv, hdr->addr1);
                if (sta_id != IWL_INVALID_STATION)
@@ -2499,19 +2431,19 @@ static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *h
                if (sta_id != IWL_INVALID_STATION)
                        return sta_id;
 
-               IWL_DEBUG_DROP("Station %s not in station map. "
+               IWL_DEBUG_DROP("Station %pM not in station map. "
                               "Defaulting to broadcast...\n",
-                              print_mac(mac, hdr->addr1));
+                              hdr->addr1);
                iwl3945_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr));
                return priv->hw_setting.bcast_sta_id;
        }
        /* If we are in monitor mode, use BCAST. This is required for
         * packet injection. */
-       case IEEE80211_IF_TYPE_MNTR:
+       case NL80211_IFTYPE_MONITOR:
                return priv->hw_setting.bcast_sta_id;
 
        default:
-               IWL_WARNING("Unknown mode of operation: %d", priv->iw_mode);
+               IWL_WARNING("Unknown mode of operation: %d\n", priv->iw_mode);
                return priv->hw_setting.bcast_sta_id;
        }
 }
@@ -2570,24 +2502,22 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
 
        /* drop all data frame if we are not associated */
        if (ieee80211_is_data(fc) &&
-           (priv->iw_mode != IEEE80211_IF_TYPE_MNTR) && /* packet injection */
+           (priv->iw_mode != NL80211_IFTYPE_MONITOR) && /* packet injection */
            (!iwl3945_is_associated(priv) ||
-            ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id))) {
+            ((priv->iw_mode == NL80211_IFTYPE_STATION) && !priv->assoc_id))) {
                IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n");
                goto drop_unlock;
        }
 
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       hdr_len = ieee80211_get_hdrlen(le16_to_cpu(fc));
+       hdr_len = ieee80211_hdrlen(fc);
 
        /* Find (or create) index into station table for destination station */
        sta_id = iwl3945_get_sta_id(priv, hdr);
        if (sta_id == IWL_INVALID_STATION) {
-               DECLARE_MAC_BUF(mac);
-
-               IWL_DEBUG_DROP("Dropping - INVALID STATION: %s\n",
-                              print_mac(mac, hdr->addr1));
+               IWL_DEBUG_DROP("Dropping - INVALID STATION: %pM\n",
+                              hdr->addr1);
                goto drop;
        }
 
@@ -2595,7 +2525,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
 
        if (ieee80211_is_data_qos(fc)) {
                qc = ieee80211_get_qos_ctl(hdr);
-               tid = qc[0] & 0xf;
+               tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
                seq_number = priv->stations[sta_id].tid[tid].seq_number &
                                IEEE80211_SCTL_SEQ;
                hdr->seq_ctrl = cpu_to_le16(seq_number) |
@@ -2667,7 +2597,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
         * first entry */
        iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len);
 
-       if (!(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT))
+       if (info->control.hw_key)
                iwl3945_build_tx_cmd_hwcrypto(priv, info, out_cmd, skb, 0);
 
        /* Set up TFD's 2nd entry to point directly to remainder of skb,
@@ -2703,9 +2633,8 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
 
        if (!ieee80211_has_morefrags(hdr->frame_control)) {
                txq->need_update = 1;
-               if (qc) {
+               if (qc)
                        priv->stations[sta_id].tid[tid].seq_number = seq_number;
-               }
        } else {
                wait_write_ptr = 1;
                txq->need_update = 0;
@@ -2715,7 +2644,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
                           sizeof(out_cmd->cmd.tx));
 
        iwl3945_print_hex_dump(IWL_DL_TX, (u8 *)out_cmd->cmd.tx.hdr,
-                          ieee80211_get_hdrlen(le16_to_cpu(fc)));
+                          ieee80211_hdrlen(fc));
 
        /* Tell device the write index *just past* this latest filled TFD */
        q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
@@ -2812,7 +2741,7 @@ static void iwl3945_radio_kill_sw(struct iwl3945_priv *priv, int disable_radio)
        if (disable_radio) {
                iwl3945_scan_cancel(priv);
                /* FIXME: This is a workaround for AP */
-               if (priv->iw_mode != IEEE80211_IF_TYPE_AP) {
+               if (priv->iw_mode != NL80211_IFTYPE_AP) {
                        spin_lock_irqsave(&priv->lock, flags);
                        iwl3945_write32(priv, CSR_UCODE_DRV_GP1_SET,
                                    CSR_UCODE_SW_BIT_RFKILL);
@@ -3167,7 +3096,7 @@ static void iwl3945_rx_beacon_notif(struct iwl3945_priv *priv,
                le32_to_cpu(beacon->low_tsf), rate);
 #endif
 
-       if ((priv->iw_mode == IEEE80211_IF_TYPE_AP) &&
+       if ((priv->iw_mode == NL80211_IFTYPE_AP) &&
            (!test_bit(STATUS_EXIT_PENDING, &priv->status)))
                queue_work(priv->workqueue, &priv->beacon_update);
 }
@@ -3813,7 +3742,7 @@ int iwl3945_calc_db_from_ratio(int sig_ratio)
        /* 100:1 or higher, divide by 10 and use table,
         *   add 20 dB to make up for divide by 10 */
        if (sig_ratio >= 100)
-               return (20 + (int)ratio2dB[sig_ratio/10]);
+               return 20 + (int)ratio2dB[sig_ratio/10];
 
        /* We shouldn't see this */
        if (sig_ratio < 1)
@@ -4025,8 +3954,6 @@ static int iwl3945_tx_queue_update_write_ptr(struct iwl3945_priv *priv,
 #ifdef CONFIG_IWL3945_DEBUG
 static void iwl3945_print_rx_config_cmd(struct iwl3945_rxon_cmd *rxon)
 {
-       DECLARE_MAC_BUF(mac);
-
        IWL_DEBUG_RADIO("RX CONFIG:\n");
        iwl3945_print_hex_dump(IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon));
        IWL_DEBUG_RADIO("u16 channel: 0x%x\n", le16_to_cpu(rxon->channel));
@@ -4037,10 +3964,8 @@ static void iwl3945_print_rx_config_cmd(struct iwl3945_rxon_cmd *rxon)
        IWL_DEBUG_RADIO("u8 ofdm_basic_rates: 0x%02x\n",
                        rxon->ofdm_basic_rates);
        IWL_DEBUG_RADIO("u8 cck_basic_rates: 0x%02x\n", rxon->cck_basic_rates);
-       IWL_DEBUG_RADIO("u8[6] node_addr: %s\n",
-                       print_mac(mac, rxon->node_addr));
-       IWL_DEBUG_RADIO("u8[6] bssid_addr: %s\n",
-                       print_mac(mac, rxon->bssid_addr));
+       IWL_DEBUG_RADIO("u8[6] node_addr: %pM\n", rxon->node_addr);
+       IWL_DEBUG_RADIO("u8[6] bssid_addr: %pM\n", rxon->bssid_addr);
        IWL_DEBUG_RADIO("u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id));
 }
 #endif
@@ -4056,7 +3981,7 @@ static void iwl3945_enable_interrupts(struct iwl3945_priv *priv)
 /* call this function to flush any scheduled tasklet */
 static inline void iwl_synchronize_irq(struct iwl3945_priv *priv)
 {
-       /* wait to make sure we flush pedding tasklet*/
+       /* wait to make sure we flush pending tasklet*/
        synchronize_irq(priv->pci_dev->irq);
        tasklet_kill(&priv->irq_tasklet);
 }
@@ -4379,35 +4304,6 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
        /* Safely ignore these bits for debug checks below */
        inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE);
 
-       /* HW RF KILL switch toggled (4965 only) */
-       if (inta & CSR_INT_BIT_RF_KILL) {
-               int hw_rf_kill = 0;
-               if (!(iwl3945_read32(priv, CSR_GP_CNTRL) &
-                               CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
-                       hw_rf_kill = 1;
-
-               IWL_DEBUG(IWL_DL_INFO | IWL_DL_RF_KILL | IWL_DL_ISR,
-                               "RF_KILL bit toggled to %s.\n",
-                               hw_rf_kill ? "disable radio":"enable radio");
-
-               /* Queue restart only if RF_KILL switch was set to "kill"
-                *   when we loaded driver, and is now set to "enable".
-                * After we're Alive, RF_KILL gets handled by
-                *   iwl3945_rx_card_state_notif() */
-               if (!hw_rf_kill && !test_bit(STATUS_ALIVE, &priv->status)) {
-                       clear_bit(STATUS_RF_KILL_HW, &priv->status);
-                       queue_work(priv->workqueue, &priv->restart);
-               }
-
-               handled |= CSR_INT_BIT_RF_KILL;
-       }
-
-       /* Chip got too hot and stopped itself (4965 only) */
-       if (inta & CSR_INT_BIT_CT_KILL) {
-               IWL_ERROR("Microcode CT kill error detected.\n");
-               handled |= CSR_INT_BIT_CT_KILL;
-       }
-
        /* Error detected by uCode */
        if (inta & CSR_INT_BIT_SW_ERR) {
                IWL_ERROR("Microcode SW error detected.  Restarting 0x%X.\n",
@@ -4508,7 +4404,7 @@ static irqreturn_t iwl3945_isr(int irq, void *data)
 
        if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) {
                /* Hardware disappeared */
-               IWL_WARNING("HARDWARE GONE?? INTA == 0x%080x\n", inta);
+               IWL_WARNING("HARDWARE GONE?? INTA == 0x%08x\n", inta);
                goto unplugged;
        }
 
@@ -4788,8 +4684,11 @@ static void iwl3945_free_channel_map(struct iwl3945_priv *priv)
 /* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after
  * sending probe req.  This should be set long enough to hear probe responses
  * from more than one AP.  */
-#define IWL_ACTIVE_DWELL_TIME_24    (20)       /* all times in msec */
-#define IWL_ACTIVE_DWELL_TIME_52    (10)
+#define IWL_ACTIVE_DWELL_TIME_24    (30)       /* all times in msec */
+#define IWL_ACTIVE_DWELL_TIME_52    (20)
+
+#define IWL_ACTIVE_DWELL_FACTOR_24GHZ (3)
+#define IWL_ACTIVE_DWELL_FACTOR_52GHZ (2)
 
 /* For faster active scanning, scan will move to the next channel if fewer than
  * PLCP_QUIET_THRESH packets are heard on this channel within
@@ -4798,7 +4697,7 @@ static void iwl3945_free_channel_map(struct iwl3945_priv *priv)
  * no other traffic).
  * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */
 #define IWL_PLCP_QUIET_THRESH       __constant_cpu_to_le16(1)  /* packets */
-#define IWL_ACTIVE_QUIET_TIME       __constant_cpu_to_le16(5)  /* msec */
+#define IWL_ACTIVE_QUIET_TIME       __constant_cpu_to_le16(10) /* msec */
 
 /* For passive scan, listen PASSIVE_DWELL_TIME (msec) on each channel.
  * Must be set longer than active dwell time.
@@ -4808,19 +4707,23 @@ static void iwl3945_free_channel_map(struct iwl3945_priv *priv)
 #define IWL_PASSIVE_DWELL_BASE      (100)
 #define IWL_CHANNEL_TUNE_TIME       5
 
+#define IWL_SCAN_PROBE_MASK(n)  (BIT(n) | (BIT(n) - BIT(1)))
+
 static inline u16 iwl3945_get_active_dwell_time(struct iwl3945_priv *priv,
-                                               enum ieee80211_band band)
+                                               enum ieee80211_band band,
+                                               u8 n_probes)
 {
        if (band == IEEE80211_BAND_5GHZ)
-               return IWL_ACTIVE_DWELL_TIME_52;
+               return IWL_ACTIVE_DWELL_TIME_52 +
+                       IWL_ACTIVE_DWELL_FACTOR_52GHZ * (n_probes + 1);
        else
-               return IWL_ACTIVE_DWELL_TIME_24;
+               return IWL_ACTIVE_DWELL_TIME_24 +
+                       IWL_ACTIVE_DWELL_FACTOR_24GHZ * (n_probes + 1);
 }
 
 static u16 iwl3945_get_passive_dwell_time(struct iwl3945_priv *priv,
                                          enum ieee80211_band band)
 {
-       u16 active = iwl3945_get_active_dwell_time(priv, band);
        u16 passive = (band == IEEE80211_BAND_2GHZ) ?
            IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 :
            IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52;
@@ -4835,15 +4738,12 @@ static u16 iwl3945_get_passive_dwell_time(struct iwl3945_priv *priv,
                passive = (passive * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2;
        }
 
-       if (passive <= active)
-               passive = active + 1;
-
        return passive;
 }
 
 static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv,
                                         enum ieee80211_band band,
-                                    u8 is_active, u8 direct_mask,
+                                    u8 is_active, u8 n_probes,
                                     struct iwl3945_scan_channel *scan_ch)
 {
        const struct ieee80211_channel *channels = NULL;
@@ -4859,9 +4759,12 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv,
 
        channels = sband->channels;
 
-       active_dwell = iwl3945_get_active_dwell_time(priv, band);
+       active_dwell = iwl3945_get_active_dwell_time(priv, band, n_probes);
        passive_dwell = iwl3945_get_passive_dwell_time(priv, band);
 
+       if (passive_dwell <= active_dwell)
+               passive_dwell = active_dwell + 1;
+
        for (i = 0, added = 0; i < sband->n_channels; i++) {
                if (channels[i].flags & IEEE80211_CHAN_DISABLED)
                        continue;
@@ -4875,17 +4778,33 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv,
                        continue;
                }
 
+               scan_ch->active_dwell = cpu_to_le16(active_dwell);
+               scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
+               /* If passive , set up for auto-switch
+                *  and use long active_dwell time.
+                */
                if (!is_active || is_channel_passive(ch_info) ||
-                   (channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN))
+                   (channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN)) {
                        scan_ch->type = 0;      /* passive */
-               else
+                       if (IWL_UCODE_API(priv->ucode_ver) == 1)
+                               scan_ch->active_dwell = cpu_to_le16(passive_dwell - 1);
+               } else {
                        scan_ch->type = 1;      /* active */
+               }
 
-               if (scan_ch->type & 1)
-                       scan_ch->type |= (direct_mask << 1);
-
-               scan_ch->active_dwell = cpu_to_le16(active_dwell);
-               scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
+               /* Set direct probe bits. These may be used both for active
+                * scan channels (probes gets sent right away),
+                * or for passive channels (probes get se sent only after
+                * hearing clear Rx packet).*/
+               if (IWL_UCODE_API(priv->ucode_ver) >= 2) {
+                       if (n_probes)
+                               scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes);
+               } else {
+                       /* uCode v1 does not allow setting direct probe bits on
+                        * passive channel. */
+                       if ((scan_ch->type & 1) && n_probes)
+                               scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes);
+               }
 
                /* Set txpower levels to defaults */
                scan_ch->tpc.dsp_atten = 110;
@@ -5088,7 +5007,7 @@ static void iwl3945_dealloc_ucode_pci(struct iwl3945_priv *priv)
  * iwl3945_verify_inst_full - verify runtime uCode image in card vs. host,
  *     looking at all data.
  */
-static int iwl3945_verify_inst_full(struct iwl3945_priv *priv, __le32 * image, u32 len)
+static int iwl3945_verify_inst_full(struct iwl3945_priv *priv, __le32 *image, u32 len)
 {
        u32 val;
        u32 save_len = len;
@@ -5237,7 +5156,7 @@ static int iwl3945_verify_bsm(struct iwl3945_priv *priv)
        val = iwl3945_read_prph(priv, BSM_WR_DWCOUNT_REG);
        for (reg = BSM_SRAM_LOWER_BOUND;
             reg < BSM_SRAM_LOWER_BOUND + len;
-            reg += sizeof(u32), image ++) {
+            reg += sizeof(u32), image++) {
                val = iwl3945_read_prph(priv, reg);
                if (val != le32_to_cpu(*image)) {
                        IWL_ERROR("BSM uCode verification failed at "
@@ -5386,25 +5305,41 @@ static void iwl3945_nic_start(struct iwl3945_priv *priv)
 static int iwl3945_read_ucode(struct iwl3945_priv *priv)
 {
        struct iwl3945_ucode *ucode;
-       int ret = 0;
+       int ret = -EINVAL, index;
        const struct firmware *ucode_raw;
        /* firmware file name contains uCode/driver compatibility version */
-       const char *name = priv->cfg->fw_name;
+       const char *name_pre = priv->cfg->fw_name_pre;
+       const unsigned int api_max = priv->cfg->ucode_api_max;
+       const unsigned int api_min = priv->cfg->ucode_api_min;
+       char buf[25];
        u8 *src;
        size_t len;
-       u32 ver, inst_size, data_size, init_size, init_data_size, boot_size;
+       u32 api_ver, inst_size, data_size, init_size, init_data_size, boot_size;
 
        /* Ask kernel firmware_class module to get the boot firmware off disk.
         * request_firmware() is synchronous, file is in memory on return. */
-       ret = request_firmware(&ucode_raw, name, &priv->pci_dev->dev);
-       if (ret < 0) {
-               IWL_ERROR("%s firmware file req failed: Reason %d\n",
-                               name, ret);
-               goto error;
+       for (index = api_max; index >= api_min; index--) {
+               sprintf(buf, "%s%u%s", name_pre, index, ".ucode");
+               ret = request_firmware(&ucode_raw, buf, &priv->pci_dev->dev);
+               if (ret < 0) {
+                       IWL_ERROR("%s firmware file req failed: Reason %d\n",
+                                 buf, ret);
+                       if (ret == -ENOENT)
+                               continue;
+                       else
+                               goto error;
+               } else {
+                       if (index < api_max)
+                               IWL_ERROR("Loaded firmware %s, which is deprecated. Please use API v%u instead.\n",
+                                         buf, api_max);
+                       IWL_DEBUG_INFO("Got firmware '%s' file (%zd bytes) from disk\n",
+                                      buf, ucode_raw->size);
+                       break;
+               }
        }
 
-       IWL_DEBUG_INFO("Got firmware '%s' file (%zd bytes) from disk\n",
-                      name, ucode_raw->size);
+       if (ret < 0)
+               goto error;
 
        /* Make sure that we got at least our header! */
        if (ucode_raw->size < sizeof(*ucode)) {
@@ -5416,20 +5351,46 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)
        /* Data from ucode file:  header followed by uCode images */
        ucode = (void *)ucode_raw->data;
 
-       ver = le32_to_cpu(ucode->ver);
+       priv->ucode_ver = le32_to_cpu(ucode->ver);
+       api_ver = IWL_UCODE_API(priv->ucode_ver);
        inst_size = le32_to_cpu(ucode->inst_size);
        data_size = le32_to_cpu(ucode->data_size);
        init_size = le32_to_cpu(ucode->init_size);
        init_data_size = le32_to_cpu(ucode->init_data_size);
        boot_size = le32_to_cpu(ucode->boot_size);
 
-       IWL_DEBUG_INFO("f/w package hdr ucode version = 0x%x\n", ver);
+       /* api_ver should match the api version forming part of the
+        * firmware filename ... but we don't check for that and only rely
+        * on the API version read from firware header from here on forward */
+
+       if (api_ver < api_min || api_ver > api_max) {
+               IWL_ERROR("Driver unable to support your firmware API. "
+                         "Driver supports v%u, firmware is v%u.\n",
+                         api_max, api_ver);
+               priv->ucode_ver = 0;
+               ret = -EINVAL;
+               goto err_release;
+       }
+       if (api_ver != api_max)
+               IWL_ERROR("Firmware has old API version. Expected %u, "
+                         "got %u. New firmware can be obtained "
+                         "from http://www.intellinuxwireless.org.\n",
+                         api_max, api_ver);
+
+       printk(KERN_INFO DRV_NAME " loaded firmware version %u.%u.%u.%u\n",
+                      IWL_UCODE_MAJOR(priv->ucode_ver),
+                      IWL_UCODE_MINOR(priv->ucode_ver),
+                      IWL_UCODE_API(priv->ucode_ver),
+                      IWL_UCODE_SERIAL(priv->ucode_ver));
+       IWL_DEBUG_INFO("f/w package hdr ucode version raw = 0x%x\n",
+                      priv->ucode_ver);
        IWL_DEBUG_INFO("f/w package hdr runtime inst size = %u\n", inst_size);
        IWL_DEBUG_INFO("f/w package hdr runtime data size = %u\n", data_size);
        IWL_DEBUG_INFO("f/w package hdr init inst size = %u\n", init_size);
        IWL_DEBUG_INFO("f/w package hdr init data size = %u\n", init_data_size);
        IWL_DEBUG_INFO("f/w package hdr boot inst size = %u\n", boot_size);
 
+
        /* Verify size of file vs. image size info in file's header */
        if (ucode_raw->size < sizeof(*ucode) +
                inst_size + data_size + init_size +
@@ -5606,7 +5567,7 @@ static int iwl3945_set_ucode_ptrs(struct iwl3945_priv *priv)
        iwl3945_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG,
                                 priv->ucode_data.len);
 
-       /* Inst bytecount must be last to set up, bit 31 signals uCode
+       /* Inst byte count must be last to set up, bit 31 signals uCode
         *   that all new ptr/size info is in place */
        iwl3945_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG,
                                 priv->ucode_code.len | BSM_DRAM_INST_LOAD);
@@ -5664,6 +5625,10 @@ static void iwl3945_init_alive_start(struct iwl3945_priv *priv)
 }
 
 
+/* temporary */
+static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw,
+                                    struct sk_buff *skb);
+
 /**
  * iwl3945_alive_start - called after REPLY_ALIVE notification received
  *                   from protocol/runtime uCode (initialization uCode's
@@ -5698,7 +5663,7 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
 
        rc = iwl3945_grab_nic_access(priv);
        if (rc) {
-               IWL_WARNING("Can not read rfkill status from adapter\n");
+               IWL_WARNING("Can not read RFKILL status from adapter\n");
                return;
        }
 
@@ -5708,7 +5673,7 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
 
        if (rfkill & 0x1) {
                clear_bit(STATUS_RF_KILL_HW, &priv->status);
-               /* if rfkill is not on, then wait for thermal
+               /* if RFKILL is not on, then wait for thermal
                 * sensor in adapter to kick in */
                while (iwl3945_hw_get_temperature(priv) == 0) {
                        thermal_spin++;
@@ -5746,7 +5711,7 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
                active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
        } else {
                /* Initialize our rx_config data */
-               iwl3945_connection_init_rx_config(priv);
+               iwl3945_connection_init_rx_config(priv, priv->iw_mode);
                memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
        }
 
@@ -5767,7 +5732,14 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
        if (priv->error_recovering)
                iwl3945_error_recovery(priv);
 
-       ieee80211_notify_mac(priv->hw, IEEE80211_NOTIFY_RE_ASSOC);
+       /* reassociate for ADHOC mode */
+       if (priv->vif && (priv->iw_mode == NL80211_IFTYPE_ADHOC)) {
+               struct sk_buff *beacon = ieee80211_beacon_get(priv->hw,
+                                                               priv->vif);
+               if (beacon)
+                       iwl3945_mac_beacon_update(priv->hw, beacon);
+       }
+
        return;
 
  restart:
@@ -5902,7 +5874,7 @@ static int __iwl3945_up(struct iwl3945_priv *priv)
        }
 
        if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) {
-               IWL_ERROR("ucode not available for device bringup\n");
+               IWL_ERROR("ucode not available for device bring up\n");
                return -EIO;
        }
 
@@ -6046,24 +6018,6 @@ static void iwl3945_bg_rf_kill(struct work_struct *work)
        iwl3945_rfkill_set_hw_state(priv);
 }
 
-static void iwl3945_bg_set_monitor(struct work_struct *work)
-{
-       struct iwl3945_priv *priv = container_of(work,
-                               struct iwl3945_priv, set_monitor);
-
-       IWL_DEBUG(IWL_DL_STATE, "setting monitor mode\n");
-
-       mutex_lock(&priv->mutex);
-
-       if (!iwl3945_is_ready(priv))
-               IWL_DEBUG(IWL_DL_STATE, "leave - not ready\n");
-       else
-               if (iwl3945_set_mode(priv, IEEE80211_IF_TYPE_MNTR) != 0)
-                       IWL_ERROR("iwl3945_set_mode() failed\n");
-
-       mutex_unlock(&priv->mutex);
-}
-
 #define IWL_SCAN_CHECK_WATCHDOG (7 * HZ)
 
 static void iwl3945_bg_scan_check(struct work_struct *data)
@@ -6099,8 +6053,9 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
        int rc = 0;
        struct iwl3945_scan_cmd *scan;
        struct ieee80211_conf *conf = NULL;
-       u8 direct_mask;
+       u8 n_probes = 2;
        enum ieee80211_band band;
+       DECLARE_SSID_BUF(ssid);
 
        conf = ieee80211_get_hw_conf(priv->hw);
 
@@ -6111,7 +6066,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
                goto done;
        }
 
-       /* Make sure the scan wasn't cancelled before this queued work
+       /* Make sure the scan wasn't canceled before this queued work
         * was given the chance to run... */
        if (!test_bit(STATUS_SCANNING, &priv->status))
                goto done;
@@ -6201,31 +6156,21 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
        if (priv->one_direct_scan) {
                IWL_DEBUG_SCAN
                    ("Kicking off one direct scan for '%s'\n",
-                    iwl3945_escape_essid(priv->direct_ssid,
-                                     priv->direct_ssid_len));
+                    print_ssid(ssid, priv->direct_ssid,
+                               priv->direct_ssid_len));
                scan->direct_scan[0].id = WLAN_EID_SSID;
                scan->direct_scan[0].len = priv->direct_ssid_len;
                memcpy(scan->direct_scan[0].ssid,
                       priv->direct_ssid, priv->direct_ssid_len);
-               direct_mask = 1;
-       } else if (!iwl3945_is_associated(priv) && priv->essid_len) {
-               IWL_DEBUG_SCAN
-                 ("Kicking off one direct scan for '%s' when not associated\n",
-                  iwl3945_escape_essid(priv->essid, priv->essid_len));
-               scan->direct_scan[0].id = WLAN_EID_SSID;
-               scan->direct_scan[0].len = priv->essid_len;
-               memcpy(scan->direct_scan[0].ssid, priv->essid, priv->essid_len);
-               direct_mask = 1;
-       } else {
+               n_probes++;
+       } else
                IWL_DEBUG_SCAN("Kicking off one indirect scan.\n");
-               direct_mask = 0;
-       }
 
        /* We don't build a direct scan probe request; the uCode will do
         * that based on the direct_mask added to each channel entry */
        scan->tx_cmd.len = cpu_to_le16(
                iwl3945_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data,
-                       IWL_MAX_SCAN_SIZE - sizeof(*scan), 0));
+                       IWL_MAX_SCAN_SIZE - sizeof(*scan)));
        scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
        scan->tx_cmd.sta_id = priv->hw_setting.bcast_sta_id;
        scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
@@ -6249,21 +6194,18 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
        /* select Rx antennas */
        scan->flags |= iwl3945_get_antenna_flags(priv);
 
-       if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR)
+       if (priv->iw_mode == NL80211_IFTYPE_MONITOR)
                scan->filter_flags = RXON_FILTER_PROMISC_MSK;
 
-       if (direct_mask)
-               scan->channel_count =
-                       iwl3945_get_channels_for_scan(
-                               priv, band, 1, /* active */
-                               direct_mask,
-                               (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
-       else
-               scan->channel_count =
-                       iwl3945_get_channels_for_scan(
-                               priv, band, 0, /* passive */
-                               direct_mask,
-                               (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
+       scan->channel_count =
+               iwl3945_get_channels_for_scan(priv, band, 1, /* active */
+                                             n_probes,
+                       (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
+
+       if (scan->channel_count == 0) {
+               IWL_DEBUG_SCAN("channel count %d\n", scan->channel_count);
+               goto done;
+       }
 
        cmd.len += le16_to_cpu(scan->tx_cmd.len) +
            scan->channel_count * sizeof(struct iwl3945_scan_channel);
@@ -6282,6 +6224,14 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
        return;
 
  done:
+       /* can not perform scan make sure we clear scanning
+        * bits from status so next scan request can be performed.
+        * if we dont clear scanning status bit here all next scan
+        * will fail
+       */
+       clear_bit(STATUS_SCAN_HW, &priv->status);
+       clear_bit(STATUS_SCANNING, &priv->status);
+
        /* inform mac80211 scan aborted */
        queue_work(priv->workqueue, &priv->scan_completed);
        mutex_unlock(&priv->mutex);
@@ -6326,34 +6276,26 @@ static void iwl3945_bg_rx_replenish(struct work_struct *data)
 
 #define IWL_DELAY_NEXT_SCAN (HZ*2)
 
-static void iwl3945_bg_post_associate(struct work_struct *data)
+static void iwl3945_post_associate(struct iwl3945_priv *priv)
 {
-       struct iwl3945_priv *priv = container_of(data, struct iwl3945_priv,
-                                            post_associate.work);
-
        int rc = 0;
        struct ieee80211_conf *conf = NULL;
-       DECLARE_MAC_BUF(mac);
 
-       if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
-               IWL_ERROR("%s Should not be called in AP mode\n", __FUNCTION__);
+       if (priv->iw_mode == NL80211_IFTYPE_AP) {
+               IWL_ERROR("%s Should not be called in AP mode\n", __func__);
                return;
        }
 
 
-       IWL_DEBUG_ASSOC("Associated as %d to: %s\n",
-                       priv->assoc_id,
-                       print_mac(mac, priv->active_rxon.bssid_addr));
+       IWL_DEBUG_ASSOC("Associated as %d to: %pM\n",
+                       priv->assoc_id, priv->active_rxon.bssid_addr);
 
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
-       mutex_lock(&priv->mutex);
-
-       if (!priv->vif || !priv->is_open) {
-               mutex_unlock(&priv->mutex);
+       if (!priv->vif || !priv->is_open)
                return;
-       }
+
        iwl3945_scan_cancel_timeout(priv, 200);
 
        conf = ieee80211_get_hw_conf(priv->hw);
@@ -6387,7 +6329,7 @@ static void iwl3945_bg_post_associate(struct work_struct *data)
                else
                        priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
 
-               if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS)
+               if (priv->iw_mode == NL80211_IFTYPE_ADHOC)
                        priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
 
        }
@@ -6395,16 +6337,13 @@ static void iwl3945_bg_post_associate(struct work_struct *data)
        iwl3945_commit_rxon(priv);
 
        switch (priv->iw_mode) {
-       case IEEE80211_IF_TYPE_STA:
+       case NL80211_IFTYPE_STATION:
                iwl3945_rate_scale_init(priv->hw, IWL_AP_ID);
                break;
 
-       case IEEE80211_IF_TYPE_IBSS:
+       case NL80211_IFTYPE_ADHOC:
 
-               /* clear out the station table */
-               iwl3945_clear_stations_table(priv);
-
-               iwl3945_add_station(priv, iwl3945_broadcast_addr, 0, 0);
+               priv->assoc_id = 1;
                iwl3945_add_station(priv, priv->bssid, 0, 0);
                iwl3945_sync_sta(priv, IWL_STA_ID,
                                 (priv->band == IEEE80211_BAND_5GHZ) ?
@@ -6417,7 +6356,7 @@ static void iwl3945_bg_post_associate(struct work_struct *data)
 
        default:
                 IWL_ERROR("%s Should not be called in %d mode\n",
-                          __FUNCTION__, priv->iw_mode);
+                          __func__, priv->iw_mode);
                break;
        }
 
@@ -6425,7 +6364,6 @@ static void iwl3945_bg_post_associate(struct work_struct *data)
 
        /* we have just associated, don't start scan too early */
        priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN;
-       mutex_unlock(&priv->mutex);
 }
 
 static void iwl3945_bg_abort_scan(struct work_struct *work)
@@ -6443,7 +6381,7 @@ static void iwl3945_bg_abort_scan(struct work_struct *work)
        mutex_unlock(&priv->mutex);
 }
 
-static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf);
+static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed);
 
 static void iwl3945_bg_scan_completed(struct work_struct *work)
 {
@@ -6456,7 +6394,7 @@ static void iwl3945_bg_scan_completed(struct work_struct *work)
                return;
 
        if (test_bit(STATUS_CONF_PENDING, &priv->status))
-               iwl3945_mac_config(priv->hw, ieee80211_get_hw_conf(priv->hw));
+               iwl3945_mac_config(priv->hw, 0);
 
        ieee80211_scan_completed(priv->hw);
 
@@ -6573,7 +6511,6 @@ static void iwl3945_mac_stop(struct ieee80211_hw *hw)
                 */
                mutex_lock(&priv->mutex);
                iwl3945_scan_cancel_timeout(priv, 100);
-               cancel_delayed_work(&priv->post_associate);
                mutex_unlock(&priv->mutex);
        }
 
@@ -6594,12 +6531,6 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 
        IWL_DEBUG_MAC80211("enter\n");
 
-       if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) {
-               IWL_DEBUG_MAC80211("leave - monitor\n");
-               dev_kfree_skb_any(skb);
-               return 0;
-       }
-
        IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
                     ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate);
 
@@ -6615,7 +6546,6 @@ static int iwl3945_mac_add_interface(struct ieee80211_hw *hw,
 {
        struct iwl3945_priv *priv = hw->priv;
        unsigned long flags;
-       DECLARE_MAC_BUF(mac);
 
        IWL_DEBUG_MAC80211("enter: type %d\n", conf->type);
 
@@ -6626,13 +6556,14 @@ static int iwl3945_mac_add_interface(struct ieee80211_hw *hw,
 
        spin_lock_irqsave(&priv->lock, flags);
        priv->vif = conf->vif;
+       priv->iw_mode = conf->type;
 
        spin_unlock_irqrestore(&priv->lock, flags);
 
        mutex_lock(&priv->mutex);
 
        if (conf->mac_addr) {
-               IWL_DEBUG_MAC80211("Set: %s\n", print_mac(mac, conf->mac_addr));
+               IWL_DEBUG_MAC80211("Set: %pM\n", conf->mac_addr);
                memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
        }
 
@@ -6652,18 +6583,17 @@ static int iwl3945_mac_add_interface(struct ieee80211_hw *hw,
  * be set inappropriately and the driver currently sets the hardware up to
  * use it whenever needed.
  */
-static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
+static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed)
 {
        struct iwl3945_priv *priv = hw->priv;
        const struct iwl3945_channel_info *ch_info;
+       struct ieee80211_conf *conf = &hw->conf;
        unsigned long flags;
        int ret = 0;
 
        mutex_lock(&priv->mutex);
        IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel->hw_value);
 
-       priv->add_radiotap = !!(conf->flags & IEEE80211_CONF_RADIOTAP);
-
        if (!iwl3945_is_ready(priv)) {
                IWL_DEBUG_MAC80211("leave - not ready\n");
                ret = -EIO;
@@ -6779,7 +6709,7 @@ static void iwl3945_config_ap(struct iwl3945_priv *priv)
                                priv->staging_rxon.flags &=
                                        ~RXON_FLG_SHORT_SLOT_MSK;
 
-                       if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS)
+                       if (priv->iw_mode == NL80211_IFTYPE_ADHOC)
                                priv->staging_rxon.flags &=
                                        ~RXON_FLG_SHORT_SLOT_MSK;
                }
@@ -6795,16 +6725,11 @@ static void iwl3945_config_ap(struct iwl3945_priv *priv)
         * clear sta table, add BCAST sta... */
 }
 
-/* temporary */
-static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb);
-
 static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
                                        struct ieee80211_vif *vif,
                                    struct ieee80211_if_conf *conf)
 {
        struct iwl3945_priv *priv = hw->priv;
-       DECLARE_MAC_BUF(mac);
-       unsigned long flags;
        int rc;
 
        if (conf == NULL)
@@ -6816,33 +6741,25 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
        }
 
        /* handle this temporarily here */
-       if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS &&
+       if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
            conf->changed & IEEE80211_IFCC_BEACON) {
                struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
                if (!beacon)
                        return -ENOMEM;
+               mutex_lock(&priv->mutex);
                rc = iwl3945_mac_beacon_update(hw, beacon);
+               mutex_unlock(&priv->mutex);
                if (rc)
                        return rc;
        }
 
-       /* XXX: this MUST use conf->mac_addr */
-
-       if ((priv->iw_mode == IEEE80211_IF_TYPE_AP) &&
-           (!conf->ssid_len)) {
-               IWL_DEBUG_MAC80211
-                   ("Leaving in AP mode because HostAPD is not ready.\n");
-               return 0;
-       }
-
        if (!iwl3945_is_alive(priv))
                return -EAGAIN;
 
        mutex_lock(&priv->mutex);
 
        if (conf->bssid)
-               IWL_DEBUG_MAC80211("bssid: %s\n",
-                                  print_mac(mac, conf->bssid));
+               IWL_DEBUG_MAC80211("bssid: %pM\n", conf->bssid);
 
 /*
  * very dubious code was here; the probe filtering flag is never set:
@@ -6851,12 +6768,12 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
            !(priv->hw->flags & IEEE80211_HW_NO_PROBE_FILTERING)) {
  */
 
-       if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
+       if (priv->iw_mode == NL80211_IFTYPE_AP) {
                if (!conf->bssid) {
                        conf->bssid = priv->mac_addr;
                        memcpy(priv->bssid, priv->mac_addr, ETH_ALEN);
-                       IWL_DEBUG_MAC80211("bssid was set to: %s\n",
-                                          print_mac(mac, conf->bssid));
+                       IWL_DEBUG_MAC80211("bssid was set to: %pM\n",
+                                          conf->bssid);
                }
                if (priv->ibss_beacon)
                        dev_kfree_skb(priv->ibss_beacon);
@@ -6886,11 +6803,11 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
                 * to verify) - jpk */
                memcpy(priv->bssid, conf->bssid, ETH_ALEN);
 
-               if (priv->iw_mode == IEEE80211_IF_TYPE_AP)
+               if (priv->iw_mode == NL80211_IFTYPE_AP)
                        iwl3945_config_ap(priv);
                else {
                        rc = iwl3945_commit_rxon(priv);
-                       if ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && rc)
+                       if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc)
                                iwl3945_add_station(priv,
                                        priv->active_rxon.bssid_addr, 1, 0);
                }
@@ -6902,15 +6819,6 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
        }
 
  done:
-       spin_lock_irqsave(&priv->lock, flags);
-       if (!conf->ssid_len)
-               memset(priv->essid, 0, IW_ESSID_MAX_SIZE);
-       else
-               memcpy(priv->essid, conf->ssid, conf->ssid_len);
-
-       priv->essid_len = conf->ssid_len;
-       spin_unlock_irqrestore(&priv->lock, flags);
-
        IWL_DEBUG_MAC80211("leave\n");
        mutex_unlock(&priv->mutex);
 
@@ -6923,16 +6831,43 @@ static void iwl3945_configure_filter(struct ieee80211_hw *hw,
                                 int mc_count, struct dev_addr_list *mc_list)
 {
        struct iwl3945_priv *priv = hw->priv;
+       __le32 *filter_flags = &priv->staging_rxon.filter_flags;
+
+       IWL_DEBUG_MAC80211("Enter: changed: 0x%x, total: 0x%x\n",
+                       changed_flags, *total_flags);
 
-       if (changed_flags & (*total_flags) & FIF_OTHER_BSS) {
-               IWL_DEBUG_MAC80211("Enter: type %d (0x%x, 0x%x)\n",
-                                  IEEE80211_IF_TYPE_MNTR,
-                                  changed_flags, *total_flags);
-               /* queue work 'cuz mac80211 is holding a lock which
-                * prevents us from issuing (synchronous) f/w cmds */
-               queue_work(priv->workqueue, &priv->set_monitor);
+       if (changed_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS)) {
+               if (*total_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS))
+                       *filter_flags |= RXON_FILTER_PROMISC_MSK;
+               else
+                       *filter_flags &= ~RXON_FILTER_PROMISC_MSK;
+       }
+       if (changed_flags & FIF_ALLMULTI) {
+               if (*total_flags & FIF_ALLMULTI)
+                       *filter_flags |= RXON_FILTER_ACCEPT_GRP_MSK;
+               else
+                       *filter_flags &= ~RXON_FILTER_ACCEPT_GRP_MSK;
        }
-       *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI |
+       if (changed_flags & FIF_CONTROL) {
+               if (*total_flags & FIF_CONTROL)
+                       *filter_flags |= RXON_FILTER_CTL2HOST_MSK;
+               else
+                       *filter_flags &= ~RXON_FILTER_CTL2HOST_MSK;
+       }
+       if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
+               if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
+                       *filter_flags |= RXON_FILTER_BCON_AWARE_MSK;
+               else
+                       *filter_flags &= ~RXON_FILTER_BCON_AWARE_MSK;
+       }
+
+       /* We avoid iwl_commit_rxon here to commit the new filter flags
+        * since mac80211 will call ieee80211_hw_config immediately.
+        * (mc_list is not supported at this time). Otherwise, we need to
+        * queue a background iwl_commit_rxon work.
+        */
+
+       *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS |
                        FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
 }
 
@@ -6947,26 +6882,81 @@ static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw,
 
        if (iwl3945_is_ready_rf(priv)) {
                iwl3945_scan_cancel_timeout(priv, 100);
-               cancel_delayed_work(&priv->post_associate);
                priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
                iwl3945_commit_rxon(priv);
        }
        if (priv->vif == conf->vif) {
                priv->vif = NULL;
                memset(priv->bssid, 0, ETH_ALEN);
-               memset(priv->essid, 0, IW_ESSID_MAX_SIZE);
-               priv->essid_len = 0;
        }
        mutex_unlock(&priv->mutex);
 
        IWL_DEBUG_MAC80211("leave\n");
 }
 
+#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
+
+static void iwl3945_bss_info_changed(struct ieee80211_hw *hw,
+                                    struct ieee80211_vif *vif,
+                                    struct ieee80211_bss_conf *bss_conf,
+                                    u32 changes)
+{
+       struct iwl3945_priv *priv = hw->priv;
+
+       IWL_DEBUG_MAC80211("changes = 0x%X\n", changes);
+
+       if (changes & BSS_CHANGED_ERP_PREAMBLE) {
+               IWL_DEBUG_MAC80211("ERP_PREAMBLE %d\n",
+                                  bss_conf->use_short_preamble);
+               if (bss_conf->use_short_preamble)
+                       priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+               else
+                       priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+       }
+
+       if (changes & BSS_CHANGED_ERP_CTS_PROT) {
+               IWL_DEBUG_MAC80211("ERP_CTS %d\n", bss_conf->use_cts_prot);
+               if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
+                       priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK;
+               else
+                       priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
+       }
+
+       if (changes & BSS_CHANGED_ASSOC) {
+               IWL_DEBUG_MAC80211("ASSOC %d\n", bss_conf->assoc);
+               /* This should never happen as this function should
+                * never be called from interrupt context. */
+               if (WARN_ON_ONCE(in_interrupt()))
+                       return;
+               if (bss_conf->assoc) {
+                       priv->assoc_id = bss_conf->aid;
+                       priv->beacon_int = bss_conf->beacon_int;
+                       priv->timestamp0 = bss_conf->timestamp & 0xFFFFFFFF;
+                       priv->timestamp1 = (bss_conf->timestamp >> 32) &
+                                            0xFFFFFFFF;
+                       priv->assoc_capability = bss_conf->assoc_capability;
+                       priv->next_scan_jiffies = jiffies +
+                                       IWL_DELAY_NEXT_SCAN_AFTER_ASSOC;
+                       mutex_lock(&priv->mutex);
+                       iwl3945_post_associate(priv);
+                       mutex_unlock(&priv->mutex);
+               } else {
+                       priv->assoc_id = 0;
+                       IWL_DEBUG_MAC80211("DISASSOC %d\n", bss_conf->assoc);
+               }
+       } else if (changes && iwl3945_is_associated(priv) && priv->assoc_id) {
+                       IWL_DEBUG_MAC80211("Associated Changes %d\n", changes);
+                       iwl3945_send_rxon_assoc(priv);
+       }
+
+}
+
 static int iwl3945_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
 {
        int rc = 0;
        unsigned long flags;
        struct iwl3945_priv *priv = hw->priv;
+       DECLARE_SSID_BUF(ssid_buf);
 
        IWL_DEBUG_MAC80211("enter\n");
 
@@ -6979,12 +6969,6 @@ static int iwl3945_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
                goto out_unlock;
        }
 
-       if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {    /* APs don't scan */
-               rc = -EIO;
-               IWL_ERROR("ERROR: APs don't scan\n");
-               goto out_unlock;
-       }
-
        /* we don't schedule scan within next_scan_jiffies period */
        if (priv->next_scan_jiffies &&
                        time_after(priv->next_scan_jiffies, jiffies)) {
@@ -7000,7 +6984,7 @@ static int iwl3945_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
        }
        if (len) {
                IWL_DEBUG_SCAN("direct scan for %s [%d]\n ",
-                              iwl3945_escape_essid(ssid, len), (int)len);
+                              print_ssid(ssid_buf, ssid, len), (int)len);
 
                priv->one_direct_scan = 1;
                priv->direct_ssid_len = (u8)
@@ -7041,10 +7025,8 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 
        sta_id = iwl3945_hw_find_station(priv, addr);
        if (sta_id == IWL_INVALID_STATION) {
-               DECLARE_MAC_BUF(mac);
-
-               IWL_DEBUG_MAC80211("leave - %s not in station map.\n",
-                                  print_mac(mac, addr));
+               IWL_DEBUG_MAC80211("leave - %pM not in station map.\n",
+                                  addr);
                return -EINVAL;
        }
 
@@ -7100,11 +7082,6 @@ static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
                return 0;
        }
 
-       if (!priv->qos_data.qos_enable) {
-               priv->qos_data.qos_active = 0;
-               IWL_DEBUG_MAC80211("leave - qos not enabled\n");
-               return 0;
-       }
        q = AC_NUM - 1 - queue;
 
        spin_lock_irqsave(&priv->lock, flags);
@@ -7121,7 +7098,7 @@ static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
        spin_unlock_irqrestore(&priv->lock, flags);
 
        mutex_lock(&priv->mutex);
-       if (priv->iw_mode == IEEE80211_IF_TYPE_AP)
+       if (priv->iw_mode == NL80211_IFTYPE_AP)
                iwl3945_activate_qos(priv, 1);
        else if (priv->assoc_id && iwl3945_is_associated(priv))
                iwl3945_activate_qos(priv, 0);
@@ -7176,14 +7153,6 @@ static int iwl3945_mac_get_stats(struct ieee80211_hw *hw,
        return 0;
 }
 
-static u64 iwl3945_mac_get_tsf(struct ieee80211_hw *hw)
-{
-       IWL_DEBUG_MAC80211("enter\n");
-       IWL_DEBUG_MAC80211("leave\n");
-
-       return 0;
-}
-
 static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw)
 {
        struct iwl3945_priv *priv = hw->priv;
@@ -7194,8 +7163,6 @@ static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw)
 
        iwl3945_reset_qos(priv);
 
-       cancel_delayed_work(&priv->post_associate);
-
        spin_lock_irqsave(&priv->lock, flags);
        priv->assoc_id = 0;
        priv->assoc_capability = 0;
@@ -7210,7 +7177,7 @@ static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw)
        priv->beacon_int = priv->hw->conf.beacon_int;
        priv->timestamp1 = 0;
        priv->timestamp0 = 0;
-       if ((priv->iw_mode == IEEE80211_IF_TYPE_STA))
+       if ((priv->iw_mode == NL80211_IFTYPE_STATION))
                priv->beacon_int = 0;
 
        spin_unlock_irqrestore(&priv->lock, flags);
@@ -7224,14 +7191,14 @@ static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw)
        /* we are restarting association process
         * clear RXON_FILTER_ASSOC_MSK bit
        */
-       if (priv->iw_mode != IEEE80211_IF_TYPE_AP) {
+       if (priv->iw_mode != NL80211_IFTYPE_AP) {
                iwl3945_scan_cancel_timeout(priv, 100);
                priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
                iwl3945_commit_rxon(priv);
        }
 
        /* Per mac80211.h: This is only used in IBSS mode... */
-       if (priv->iw_mode != IEEE80211_IF_TYPE_IBSS) {
+       if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
 
                IWL_DEBUG_MAC80211("leave - not in IBSS\n");
                mutex_unlock(&priv->mutex);
@@ -7251,18 +7218,15 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
        struct iwl3945_priv *priv = hw->priv;
        unsigned long flags;
 
-       mutex_lock(&priv->mutex);
        IWL_DEBUG_MAC80211("enter\n");
 
        if (!iwl3945_is_ready_rf(priv)) {
                IWL_DEBUG_MAC80211("leave - RF not ready\n");
-               mutex_unlock(&priv->mutex);
                return -EIO;
        }
 
-       if (priv->iw_mode != IEEE80211_IF_TYPE_IBSS) {
+       if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
                IWL_DEBUG_MAC80211("leave - not IBSS\n");
-               mutex_unlock(&priv->mutex);
                return -EIO;
        }
 
@@ -7280,9 +7244,8 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
 
        iwl3945_reset_qos(priv);
 
-       queue_work(priv->workqueue, &priv->post_associate.work);
+       iwl3945_post_associate(priv);
 
-       mutex_unlock(&priv->mutex);
 
        return 0;
 }
@@ -7341,15 +7304,6 @@ static ssize_t show_temperature(struct device *d,
 
 static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL);
 
-static ssize_t show_rs_window(struct device *d,
-                             struct device_attribute *attr,
-                             char *buf)
-{
-       struct iwl3945_priv *priv = d->driver_data;
-       return iwl3945_fill_rs_info(priv->hw, buf, IWL_AP_ID);
-}
-static DEVICE_ATTR(rs_window, S_IRUGO, show_rs_window, NULL);
-
 static ssize_t show_tx_power(struct device *d,
                             struct device_attribute *attr, char *buf)
 {
@@ -7456,7 +7410,7 @@ static ssize_t show_measurement(struct device *d,
        struct iwl3945_priv *priv = dev_get_drvdata(d);
        struct iwl3945_spectrum_notification measure_report;
        u32 size = sizeof(measure_report), len = 0, ofs = 0;
-       u8 *data = (u8 *) & measure_report;
+       u8 *data = (u8 *)&measure_report;
        unsigned long flags;
 
        spin_lock_irqsave(&priv->lock, flags);
@@ -7627,7 +7581,7 @@ static ssize_t show_power_level(struct device *d,
        else
                p += sprintf(p, " \n");
 
-       return (p - buf + 1);
+       return p - buf + 1;
 
 }
 
@@ -7649,7 +7603,7 @@ static ssize_t show_statistics(struct device *d,
        struct iwl3945_priv *priv = dev_get_drvdata(d);
        u32 size = sizeof(struct iwl3945_notif_statistics);
        u32 len = 0, ofs = 0;
-       u8 *data = (u8 *) & priv->statistics;
+       u8 *data = (u8 *)&priv->statistics;
        int rc = 0;
 
        if (!iwl3945_is_alive(priv))
@@ -7760,7 +7714,7 @@ static DEVICE_ATTR(dump_events, S_IWUSR, NULL, dump_event_log);
 
 /*****************************************************************************
  *
- * driver setup and teardown
+ * driver setup and tear down
  *
  *****************************************************************************/
 
@@ -7778,8 +7732,6 @@ static void iwl3945_setup_deferred_work(struct iwl3945_priv *priv)
        INIT_WORK(&priv->abort_scan, iwl3945_bg_abort_scan);
        INIT_WORK(&priv->rf_kill, iwl3945_bg_rf_kill);
        INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update);
-       INIT_WORK(&priv->set_monitor, iwl3945_bg_set_monitor);
-       INIT_DELAYED_WORK(&priv->post_associate, iwl3945_bg_post_associate);
        INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start);
        INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start);
        INIT_DELAYED_WORK(&priv->scan_check, iwl3945_bg_scan_check);
@@ -7797,7 +7749,6 @@ static void iwl3945_cancel_deferred_work(struct iwl3945_priv *priv)
        cancel_delayed_work_sync(&priv->init_alive_start);
        cancel_delayed_work(&priv->scan_check);
        cancel_delayed_work(&priv->alive_start);
-       cancel_delayed_work(&priv->post_associate);
        cancel_work_sync(&priv->beacon_update);
 }
 
@@ -7813,7 +7764,6 @@ static struct attribute *iwl3945_sysfs_entries[] = {
 #endif
        &dev_attr_power_level.attr,
        &dev_attr_retry_rate.attr,
-       &dev_attr_rs_window.attr,
        &dev_attr_statistics.attr,
        &dev_attr_status.attr,
        &dev_attr_temperature.attr,
@@ -7840,8 +7790,8 @@ static struct ieee80211_ops iwl3945_hw_ops = {
        .get_stats = iwl3945_mac_get_stats,
        .get_tx_stats = iwl3945_mac_get_tx_stats,
        .conf_tx = iwl3945_mac_conf_tx,
-       .get_tsf = iwl3945_mac_get_tsf,
        .reset_tsf = iwl3945_mac_reset_tsf,
+       .bss_info_changed = iwl3945_bss_info_changed,
        .hw_scan = iwl3945_mac_hw_scan
 };
 
@@ -7852,7 +7802,10 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
        struct ieee80211_hw *hw;
        struct iwl_3945_cfg *cfg = (struct iwl_3945_cfg *)(ent->driver_data);
        unsigned long flags;
-       DECLARE_MAC_BUF(mac);
+
+       /***********************
+        * 1. Allocating HW data
+        * ********************/
 
        /* Disabling hardware scan means that mac80211 will perform scans
         * "the hard way", rather than using device's scan. */
@@ -7877,42 +7830,41 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
                err = -ENOMEM;
                goto out;
        }
-       SET_IEEE80211_DEV(hw, &pdev->dev);
 
-       hw->rate_control_algorithm = "iwl-3945-rs";
+       SET_IEEE80211_DEV(hw, &pdev->dev);
 
-       IWL_DEBUG_INFO("*** LOAD DRIVER ***\n");
        priv = hw->priv;
        priv->hw = hw;
-
        priv->pci_dev = pdev;
        priv->cfg = cfg;
 
+       IWL_DEBUG_INFO("*** LOAD DRIVER ***\n");
+       hw->rate_control_algorithm = "iwl-3945-rs";
+       hw->sta_data_size = sizeof(struct iwl3945_sta_priv);
+
        /* Select antenna (may be helpful if only one antenna is connected) */
        priv->antenna = (enum iwl3945_antenna)iwl3945_param_antenna;
 #ifdef CONFIG_IWL3945_DEBUG
        iwl3945_debug_level = iwl3945_param_debug;
        atomic_set(&priv->restrict_refcnt, 0);
 #endif
-       priv->retry_rate = 1;
-
-       priv->ibss_beacon = NULL;
 
        /* Tell mac80211 our characteristics */
        hw->flags = IEEE80211_HW_SIGNAL_DBM |
                    IEEE80211_HW_NOISE_DBM;
 
-       /* 4 EDCA QOS priorities */
-       hw->queues = 4;
+       hw->wiphy->interface_modes =
+               BIT(NL80211_IFTYPE_STATION) |
+               BIT(NL80211_IFTYPE_ADHOC);
 
-       spin_lock_init(&priv->lock);
-       spin_lock_init(&priv->power_data.lock);
-       spin_lock_init(&priv->sta_lock);
-       spin_lock_init(&priv->hcmd_lock);
+       hw->wiphy->fw_handles_regulatory = true;
 
-       INIT_LIST_HEAD(&priv->free_frames);
+       /* 4 EDCA QOS priorities */
+       hw->queues = 4;
 
-       mutex_init(&priv->mutex);
+       /***************************
+        * 2. Initializing PCI bus
+        * *************************/
        if (pci_enable_device(pdev)) {
                err = -ENODEV;
                goto out_ieee80211_free_hw;
@@ -7920,14 +7872,6 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
 
        pci_set_master(pdev);
 
-       /* Clear the driver's (not device's) station table */
-       iwl3945_clear_stations_table(priv);
-
-       priv->data_retry_limit = -1;
-       priv->ieee_channels = NULL;
-       priv->ieee_rates = NULL;
-       priv->band = IEEE80211_BAND_2GHZ;
-
        err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
        if (!err)
                err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
@@ -7941,10 +7885,9 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
        if (err)
                goto out_pci_disable_device;
 
-       /* We disable the RETRY_TIMEOUT register (0x41) to keep
-        * PCI Tx retries from interfering with C3 CPU state */
-       pci_write_config_byte(pdev, 0x41, 0x00);
-
+       /***********************
+        * 3. Read REV Register
+        * ********************/
        priv->hw_base = pci_iomap(pdev, 0, 0);
        if (!priv->hw_base) {
                err = -ENODEV;
@@ -7955,97 +7898,144 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
                        (unsigned long long) pci_resource_len(pdev, 0));
        IWL_DEBUG_INFO("pci_resource_base = %p\n", priv->hw_base);
 
-       /* Initialize module parameter values here */
+       /* We disable the RETRY_TIMEOUT register (0x41) to keep
+        * PCI Tx retries from interfering with C3 CPU state */
+       pci_write_config_byte(pdev, 0x41, 0x00);
 
-       /* Disable radio (SW RF KILL) via parameter when loading driver */
-       if (iwl3945_param_disable) {
-               set_bit(STATUS_RF_KILL_SW, &priv->status);
-               IWL_DEBUG_INFO("Radio disabled.\n");
-       }
+       /* nic init */
+       iwl3945_set_bit(priv, CSR_GIO_CHICKEN_BITS,
+                       CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
 
-       priv->iw_mode = IEEE80211_IF_TYPE_STA;
+       iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+       err = iwl3945_poll_direct_bit(priv, CSR_GP_CNTRL,
+                               CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
+       if (err < 0) {
+               IWL_DEBUG_INFO("Failed to init the card\n");
+               goto out_remove_sysfs;
+       }
 
-       printk(KERN_INFO DRV_NAME
-               ": Detected Intel Wireless WiFi Link %s\n", priv->cfg->name);
+       /***********************
+        * 4. Read EEPROM
+        * ********************/
+       /* Read the EEPROM */
+       err = iwl3945_eeprom_init(priv);
+       if (err) {
+               IWL_ERROR("Unable to init EEPROM\n");
+               goto out_remove_sysfs;
+       }
+       /* MAC Address location in EEPROM same for 3945/4965 */
+       get_eeprom_mac(priv, priv->mac_addr);
+       IWL_DEBUG_INFO("MAC address: %pM\n", priv->mac_addr);
+       SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
 
+       /***********************
+        * 5. Setup HW Constants
+        * ********************/
        /* Device-specific setup */
        if (iwl3945_hw_set_hw_setting(priv)) {
                IWL_ERROR("failed to set hw settings\n");
                goto out_iounmap;
        }
 
-       if (iwl3945_param_qos_enable)
-               priv->qos_data.qos_enable = 1;
+       /***********************
+        * 6. Setup priv
+        * ********************/
+       priv->retry_rate = 1;
+       priv->ibss_beacon = NULL;
+
+       spin_lock_init(&priv->lock);
+       spin_lock_init(&priv->power_data.lock);
+       spin_lock_init(&priv->sta_lock);
+       spin_lock_init(&priv->hcmd_lock);
+
+       INIT_LIST_HEAD(&priv->free_frames);
+       mutex_init(&priv->mutex);
+
+       /* Clear the driver's (not device's) station table */
+       iwl3945_clear_stations_table(priv);
+
+       priv->data_retry_limit = -1;
+       priv->ieee_channels = NULL;
+       priv->ieee_rates = NULL;
+       priv->band = IEEE80211_BAND_2GHZ;
+
+       priv->iw_mode = NL80211_IFTYPE_STATION;
 
        iwl3945_reset_qos(priv);
 
        priv->qos_data.qos_active = 0;
        priv->qos_data.qos_cap.val = 0;
 
-       iwl3945_set_rxon_channel(priv, IEEE80211_BAND_2GHZ, 6);
-       iwl3945_setup_deferred_work(priv);
-       iwl3945_setup_rx_handlers(priv);
 
        priv->rates_mask = IWL_RATES_MASK;
        /* If power management is turned on, default to AC mode */
        priv->power_mode = IWL_POWER_AC;
        priv->user_txpower_limit = IWL_DEFAULT_TX_POWER;
 
-       spin_lock_irqsave(&priv->lock, flags);
-       iwl3945_disable_interrupts(priv);
-       spin_unlock_irqrestore(&priv->lock, flags);
-
-       err = sysfs_create_group(&pdev->dev.kobj, &iwl3945_attribute_group);
+       err = iwl3945_init_channel_map(priv);
        if (err) {
-               IWL_ERROR("failed to create sysfs device attributes\n");
+               IWL_ERROR("initializing regulatory failed: %d\n", err);
                goto out_release_irq;
        }
 
-       /* nic init */
-       iwl3945_set_bit(priv, CSR_GIO_CHICKEN_BITS,
-                    CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
-
-        iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
-        err = iwl3945_poll_bit(priv, CSR_GP_CNTRL,
-                          CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
-                          CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
-        if (err < 0) {
-                IWL_DEBUG_INFO("Failed to init the card\n");
-               goto out_remove_sysfs;
-        }
-       /* Read the EEPROM */
-       err = iwl3945_eeprom_init(priv);
+       err = iwl3945_init_geos(priv);
        if (err) {
-               IWL_ERROR("Unable to init EEPROM\n");
-               goto out_remove_sysfs;
+               IWL_ERROR("initializing geos failed: %d\n", err);
+               goto out_free_channel_map;
        }
-       /* MAC Address location in EEPROM same for 3945/4965 */
-       get_eeprom_mac(priv, priv->mac_addr);
-       IWL_DEBUG_INFO("MAC address: %s\n", print_mac(mac, priv->mac_addr));
-       SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
 
-       err = iwl3945_init_channel_map(priv);
-       if (err) {
-               IWL_ERROR("initializing regulatory failed: %d\n", err);
-               goto out_remove_sysfs;
+       printk(KERN_INFO DRV_NAME
+               ": Detected Intel Wireless WiFi Link %s\n", priv->cfg->name);
+
+       /***********************************
+        * 7. Initialize Module Parameters
+        * **********************************/
+
+       /* Initialize module parameter values here */
+       /* Disable radio (SW RF KILL) via parameter when loading driver */
+       if (iwl3945_param_disable) {
+               set_bit(STATUS_RF_KILL_SW, &priv->status);
+               IWL_DEBUG_INFO("Radio disabled.\n");
        }
 
-       err = iwl3945_init_geos(priv);
+
+       /***********************
+        * 8. Setup Services
+        * ********************/
+
+       spin_lock_irqsave(&priv->lock, flags);
+       iwl3945_disable_interrupts(priv);
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       err = sysfs_create_group(&pdev->dev.kobj, &iwl3945_attribute_group);
        if (err) {
-               IWL_ERROR("initializing geos failed: %d\n", err);
-               goto out_free_channel_map;
+               IWL_ERROR("failed to create sysfs device attributes\n");
+               goto out_free_geos;
        }
 
+       iwl3945_set_rxon_channel(priv, IEEE80211_BAND_2GHZ, 6);
+       iwl3945_setup_deferred_work(priv);
+       iwl3945_setup_rx_handlers(priv);
+
+       /***********************
+        * 9. Conclude
+        * ********************/
+       pci_save_state(pdev);
+       pci_disable_device(pdev);
+
+       /*********************************
+        * 10. Setup and Register mac80211
+        * *******************************/
+
        err = ieee80211_register_hw(priv->hw);
        if (err) {
                IWL_ERROR("Failed to register network device (error %d)\n", err);
-               goto out_free_geos;
+               goto  out_remove_sysfs;
        }
 
        priv->hw->conf.beacon_int = 100;
        priv->mac80211_registered = 1;
-       pci_save_state(pdev);
-       pci_disable_device(pdev);
+
 
        err = iwl3945_rfkill_init(priv);
        if (err)
@@ -8054,12 +8044,13 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
 
        return 0;
 
+ out_remove_sysfs:
+       sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group);
  out_free_geos:
        iwl3945_free_geos(priv);
  out_free_channel_map:
        iwl3945_free_channel_map(priv);
- out_remove_sysfs:
-       sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group);
+
 
  out_release_irq:
        destroy_workqueue(priv->workqueue);
@@ -8114,9 +8105,8 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
        iwl3945_unset_hw_setting(priv);
        iwl3945_clear_stations_table(priv);
 
-       if (priv->mac80211_registered) {
+       if (priv->mac80211_registered)
                ieee80211_unregister_hw(priv->hw);
-       }
 
        /*netif_stop_queue(dev); */
        flush_workqueue(priv->workqueue);
@@ -8187,7 +8177,7 @@ static int iwl3945_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return 0;
 
-       IWL_DEBUG_RF_KILL("we recieved soft RFKILL set to state %d\n", state);
+       IWL_DEBUG_RF_KILL("we received soft RFKILL set to state %d\n", state);
        mutex_lock(&priv->mutex);
 
        switch (state) {
@@ -8202,7 +8192,7 @@ static int iwl3945_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
                iwl3945_radio_kill_sw(priv, 1);
                break;
        default:
-               IWL_WARNING("we recieved unexpected RFKILL state %d\n", state);
+               IWL_WARNING("we received unexpected RFKILL state %d\n", state);
                break;
        }
 out_unlock:
@@ -8344,6 +8334,8 @@ static void __exit iwl3945_exit(void)
        iwl3945_rate_control_unregister();
 }
 
+MODULE_FIRMWARE(IWL3945_MODULE_FIRMWARE(IWL3945_UCODE_API_MAX));
+
 module_param_named(antenna, iwl3945_param_antenna, int, 0444);
 MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])");
 module_param_named(disable, iwl3945_param_disable, int, 0444);
@@ -8359,9 +8351,5 @@ MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)");
 module_param_named(queues_num, iwl3945_param_queues_num, int, 0444);
 MODULE_PARM_DESC(queues_num, "number of hw queues.");
 
-/* QoS */
-module_param_named(qos_enable, iwl3945_param_qos_enable, int, 0444);
-MODULE_PARM_DESC(qos_enable, "enable all QoS functionality");
-
 module_exit(iwl3945_exit);
 module_init(iwl3945_init);