Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[safe/jmp/linux-2.6] / drivers / net / wireless / iwlwifi / iwl3945-base.c
index cbaeaf1..ab635dc 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project, as well
  * as portions of the ieee80211 subsystem header files.
@@ -46,6 +46,7 @@
 
 #include <asm/div64.h>
 
+#include "iwl-3945-core.h"
 #include "iwl-3945.h"
 #include "iwl-helpers.h"
 
@@ -91,15 +92,10 @@ int iwl3945_param_queues_num = IWL_MAX_NUM_QUEUES; /* def: 8 Tx queues */
 #define VS
 #endif
 
-#define IWLWIFI_VERSION "1.2.23k" VD VS
-#define DRV_COPYRIGHT  "Copyright(c) 2003-2007 Intel Corporation"
+#define IWLWIFI_VERSION "1.2.26k" VD VS
+#define DRV_COPYRIGHT  "Copyright(c) 2003-2008 Intel Corporation"
 #define DRV_VERSION     IWLWIFI_VERSION
 
-/* Change firmware file name, using "-" and incrementing number,
- *   *only* when uCode interface or architecture changes so that it
- *   is not compatible with earlier drivers.
- * This number will also appear in << 8 position of 1st dword of uCode file */
-#define IWL3945_UCODE_API "-1"
 
 MODULE_DESCRIPTION(DRV_DESCRIPTION);
 MODULE_VERSION(DRV_VERSION);
@@ -116,16 +112,10 @@ static __le16 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr)
        return NULL;
 }
 
-static const struct ieee80211_hw_mode *iwl3945_get_hw_mode(
-               struct iwl3945_priv *priv, int mode)
+static const struct ieee80211_supported_band *iwl3945_get_band(
+               struct iwl3945_priv *priv, enum ieee80211_band band)
 {
-       int i;
-
-       for (i = 0; i < 3; i++)
-               if (priv->modes[i].mode == mode)
-                       return &priv->modes[i];
-
-       return NULL;
+       return priv->hw->wiphy->bands[band];
 }
 
 static int iwl3945_is_empty_essid(const char *essid, int essid_len)
@@ -168,17 +158,6 @@ static const char *iwl3945_escape_essid(const char *essid, u8 essid_len)
        return escaped;
 }
 
-static void iwl3945_print_hex_dump(int level, void *p, u32 len)
-{
-#ifdef CONFIG_IWL3945_DEBUG
-       if (!(iwl3945_debug_level & level))
-               return;
-
-       print_hex_dump(KERN_DEBUG, "iwl data: ", DUMP_PREFIX_OFFSET, 16, 1,
-                       p, len, 1);
-#endif
-}
-
 /*************** DMA-QUEUE-GENERAL-FUNCTIONS  *****
  * DMA services
  *
@@ -204,7 +183,7 @@ static void iwl3945_print_hex_dump(int level, void *p, u32 len)
  * (#0-3) for data tx via EDCA.  An additional 2 HCCA queues are unused.
  ***************************************************/
 
-static int iwl3945_queue_space(const struct iwl3945_queue *q)
+int iwl3945_queue_space(const struct iwl3945_queue *q)
 {
        int s = q->read_ptr - q->write_ptr;
 
@@ -220,33 +199,14 @@ static int iwl3945_queue_space(const struct iwl3945_queue *q)
        return s;
 }
 
-/**
- * iwl3945_queue_inc_wrap - increment queue index, wrap back to beginning
- * @index -- current index
- * @n_bd -- total number of entries in queue (must be power of 2)
- */
-static inline int iwl3945_queue_inc_wrap(int index, int n_bd)
-{
-       return ++index & (n_bd - 1);
-}
-
-/**
- * iwl3945_queue_dec_wrap - increment queue index, wrap back to end
- * @index -- current index
- * @n_bd -- total number of entries in queue (must be power of 2)
- */
-static inline int iwl3945_queue_dec_wrap(int index, int n_bd)
-{
-       return --index & (n_bd - 1);
-}
-
-static inline int x2_queue_used(const struct iwl3945_queue *q, int i)
+int iwl3945_x2_queue_used(const struct iwl3945_queue *q, int i)
 {
        return q->write_ptr > q->read_ptr ?
                (i >= q->read_ptr && i < q->write_ptr) :
                !(i < q->read_ptr && i >= q->write_ptr);
 }
 
+
 static inline u8 get_cmd_index(struct iwl3945_queue *q, u32 index, int is_huge)
 {
        /* This is for scan command, the big buffer at end of command array */
@@ -267,8 +227,8 @@ static int iwl3945_queue_init(struct iwl3945_priv *priv, struct iwl3945_queue *q
        q->n_window = slots_num;
        q->id = id;
 
-       /* count must be power-of-two size, otherwise iwl3945_queue_inc_wrap
-        * and iwl3945_queue_dec_wrap are broken. */
+       /* count must be power-of-two size, otherwise iwl_queue_inc_wrap
+        * and iwl_queue_dec_wrap are broken. */
        BUG_ON(!is_power_of_2(count));
 
        /* slots_num must be power-of-two size, otherwise
@@ -368,7 +328,7 @@ int iwl3945_tx_queue_init(struct iwl3945_priv *priv,
        txq->need_update = 0;
 
        /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
-        * iwl3945_queue_inc_wrap and iwl3945_queue_dec_wrap are broken. */
+        * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */
        BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1));
 
        /* Initialize queue high/low-water, head/tail indexes */
@@ -399,7 +359,7 @@ void iwl3945_tx_queue_free(struct iwl3945_priv *priv, struct iwl3945_tx_queue *t
 
        /* first, empty all BD's */
        for (; q->write_ptr != q->read_ptr;
-            q->read_ptr = iwl3945_queue_inc_wrap(q->read_ptr, q->n_bd))
+            q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd))
                iwl3945_hw_txq_free_tfd(priv, txq);
 
        len = sizeof(struct iwl3945_cmd) * q->n_window;
@@ -547,7 +507,7 @@ u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap, u8
        station->sta.sta.sta_id = index;
        station->sta.station_flags = 0;
 
-       if (priv->phymode == MODE_IEEE80211A)
+       if (priv->band == IEEE80211_BAND_5GHZ)
                rate = IWL_RATE_6M_PLCP;
        else
                rate =  IWL_RATE_1M_PLCP;
@@ -738,7 +698,7 @@ static int iwl3945_enqueue_hcmd(struct iwl3945_priv *priv, struct iwl3945_host_c
        txq->need_update = 1;
 
        /* Increment and update queue's write index */
-       q->write_ptr = iwl3945_queue_inc_wrap(q->write_ptr, q->n_bd);
+       q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
        ret = iwl3945_tx_queue_update_write_ptr(priv, txq);
 
        spin_unlock_irqrestore(&priv->hcmd_lock, flags);
@@ -894,35 +854,37 @@ int iwl3945_send_statistics_request(struct iwl3945_priv *priv)
 
 /**
  * iwl3945_set_rxon_channel - Set the phymode and channel values in staging RXON
- * @phymode: MODE_IEEE80211A sets to 5.2GHz; all else set to 2.4GHz
- * @channel: Any channel valid for the requested phymode
+ * @band: 2.4 or 5 GHz band
+ * @channel: Any channel valid for the requested band
 
- * In addition to setting the staging RXON, priv->phymode is also set.
+ * In addition to setting the staging RXON, priv->band is also set.
  *
  * NOTE:  Does not commit to the hardware; it sets appropriate bit fields
- * in the staging RXON flag structure based on the phymode
+ * in the staging RXON flag structure based on the band
  */
-static int iwl3945_set_rxon_channel(struct iwl3945_priv *priv, u8 phymode, u16 channel)
+static int iwl3945_set_rxon_channel(struct iwl3945_priv *priv,
+                                   enum ieee80211_band band,
+                                   u16 channel)
 {
-       if (!iwl3945_get_channel_info(priv, phymode, channel)) {
+       if (!iwl3945_get_channel_info(priv, band, channel)) {
                IWL_DEBUG_INFO("Could not set channel to %d [%d]\n",
-                              channel, phymode);
+                              channel, band);
                return -EINVAL;
        }
 
        if ((le16_to_cpu(priv->staging_rxon.channel) == channel) &&
-           (priv->phymode == phymode))
+           (priv->band == band))
                return 0;
 
        priv->staging_rxon.channel = cpu_to_le16(channel);
-       if (phymode == MODE_IEEE80211A)
+       if (band == IEEE80211_BAND_5GHZ)
                priv->staging_rxon.flags &= ~RXON_FLG_BAND_24G_MSK;
        else
                priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK;
 
-       priv->phymode = phymode;
+       priv->band = band;
 
-       IWL_DEBUG_INFO("Staging channel set to %d [%d]\n", channel, phymode);
+       IWL_DEBUG_INFO("Staging channel set to %d [%d]\n", channel, band);
 
        return 0;
 }
@@ -1210,8 +1172,7 @@ static int iwl3945_commit_rxon(struct iwl3945_priv *priv)
                        return -EIO;
                }
 
-       /* Init the hardware's rate fallback order based on the
-        * phymode */
+       /* Init the hardware's rate fallback order based on the band */
        rc = iwl3945_init_hw_rate_table(priv);
        if (rc) {
                IWL_ERROR("Error setting HW rate table: %02X\n", rc);
@@ -1635,151 +1596,6 @@ int iwl3945_eeprom_init(struct iwl3945_priv *priv)
        return 0;
 }
 
-/******************************************************************************
- *
- * Misc. internal state and helper functions
- *
- ******************************************************************************/
-#ifdef CONFIG_IWL3945_DEBUG
-
-/**
- * iwl3945_report_frame - dump frame to syslog during debug sessions
- *
- * You may hack this function to show different aspects of received frames,
- * including selective frame dumps.
- * group100 parameter selects whether to show 1 out of 100 good frames.
- */
-void iwl3945_report_frame(struct iwl3945_priv *priv,
-                     struct iwl3945_rx_packet *pkt,
-                     struct ieee80211_hdr *header, int group100)
-{
-       u32 to_us;
-       u32 print_summary = 0;
-       u32 print_dump = 0;     /* set to 1 to dump all frames' contents */
-       u32 hundred = 0;
-       u32 dataframe = 0;
-       u16 fc;
-       u16 seq_ctl;
-       u16 channel;
-       u16 phy_flags;
-       int rate_sym;
-       u16 length;
-       u16 status;
-       u16 bcn_tmr;
-       u32 tsf_low;
-       u64 tsf;
-       u8 rssi;
-       u8 agc;
-       u16 sig_avg;
-       u16 noise_diff;
-       struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt);
-       struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
-       struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt);
-       u8 *data = IWL_RX_DATA(pkt);
-
-       /* MAC header */
-       fc = le16_to_cpu(header->frame_control);
-       seq_ctl = le16_to_cpu(header->seq_ctrl);
-
-       /* metadata */
-       channel = le16_to_cpu(rx_hdr->channel);
-       phy_flags = le16_to_cpu(rx_hdr->phy_flags);
-       rate_sym = rx_hdr->rate;
-       length = le16_to_cpu(rx_hdr->len);
-
-       /* end-of-frame status and timestamp */
-       status = le32_to_cpu(rx_end->status);
-       bcn_tmr = le32_to_cpu(rx_end->beacon_timestamp);
-       tsf_low = le64_to_cpu(rx_end->timestamp) & 0x0ffffffff;
-       tsf = le64_to_cpu(rx_end->timestamp);
-
-       /* signal statistics */
-       rssi = rx_stats->rssi;
-       agc = rx_stats->agc;
-       sig_avg = le16_to_cpu(rx_stats->sig_avg);
-       noise_diff = le16_to_cpu(rx_stats->noise_diff);
-
-       to_us = !compare_ether_addr(header->addr1, priv->mac_addr);
-
-       /* if data frame is to us and all is good,
-        *   (optionally) print summary for only 1 out of every 100 */
-       if (to_us && (fc & ~IEEE80211_FCTL_PROTECTED) ==
-           (IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) {
-               dataframe = 1;
-               if (!group100)
-                       print_summary = 1;      /* print each frame */
-               else if (priv->framecnt_to_us < 100) {
-                       priv->framecnt_to_us++;
-                       print_summary = 0;
-               } else {
-                       priv->framecnt_to_us = 0;
-                       print_summary = 1;
-                       hundred = 1;
-               }
-       } else {
-               /* print summary for all other frames */
-               print_summary = 1;
-       }
-
-       if (print_summary) {
-               char *title;
-               u32 rate;
-
-               if (hundred)
-                       title = "100Frames";
-               else if (fc & IEEE80211_FCTL_RETRY)
-                       title = "Retry";
-               else if (ieee80211_is_assoc_response(fc))
-                       title = "AscRsp";
-               else if (ieee80211_is_reassoc_response(fc))
-                       title = "RasRsp";
-               else if (ieee80211_is_probe_response(fc)) {
-                       title = "PrbRsp";
-                       print_dump = 1; /* dump frame contents */
-               } else if (ieee80211_is_beacon(fc)) {
-                       title = "Beacon";
-                       print_dump = 1; /* dump frame contents */
-               } else if (ieee80211_is_atim(fc))
-                       title = "ATIM";
-               else if (ieee80211_is_auth(fc))
-                       title = "Auth";
-               else if (ieee80211_is_deauth(fc))
-                       title = "DeAuth";
-               else if (ieee80211_is_disassoc(fc))
-                       title = "DisAssoc";
-               else
-                       title = "Frame";
-
-               rate = iwl3945_rate_index_from_plcp(rate_sym);
-               if (rate == -1)
-                       rate = 0;
-               else
-                       rate = iwl3945_rates[rate].ieee / 2;
-
-               /* print frame summary.
-                * MAC addresses show just the last byte (for brevity),
-                *    but you can hack it to show more, if you'd like to. */
-               if (dataframe)
-                       IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, "
-                                    "len=%u, rssi=%d, chnl=%d, rate=%u, \n",
-                                    title, fc, header->addr1[5],
-                                    length, rssi, channel, rate);
-               else {
-                       /* src/dst addresses assume managed mode */
-                       IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, "
-                                    "src=0x%02x, rssi=%u, tim=%lu usec, "
-                                    "phy=0x%02x, chnl=%d\n",
-                                    title, fc, header->addr1[5],
-                                    header->addr3[5], rssi,
-                                    tsf_low - priv->scan_start_tsf,
-                                    phy_flags, channel);
-               }
-       }
-       if (print_dump)
-               iwl3945_print_hex_dump(IWL_DL_RX, data, length);
-}
-#endif
-
 static void iwl3945_unset_hw_setting(struct iwl3945_priv *priv)
 {
        if (priv->hw_setting.shared_virt)
@@ -1915,7 +1731,6 @@ static u16 iwl3945_fill_probe_req(struct iwl3945_priv *priv,
 /*
  * QoS  support
 */
-#ifdef CONFIG_IWL3945_QOS
 static int iwl3945_send_qos_params_command(struct iwl3945_priv *priv,
                                       struct iwl3945_qosparam_cmd *qos)
 {
@@ -2044,7 +1859,6 @@ static void iwl3945_activate_qos(struct iwl3945_priv *priv, u8 force)
        }
 }
 
-#endif /* CONFIG_IWL3945_QOS */
 /*
  * Power management (not Tx power!) functions
  */
@@ -2244,39 +2058,13 @@ int iwl3945_is_network_packet(struct iwl3945_priv *priv, struct ieee80211_hdr *h
                        return !compare_ether_addr(header->addr2, priv->bssid);
                /* packets to our adapter go through */
                return !compare_ether_addr(header->addr1, priv->mac_addr);
+       default:
+               return 1;
        }
 
        return 1;
 }
 
-#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
-
-static const char *iwl3945_get_tx_fail_reason(u32 status)
-{
-       switch (status & TX_STATUS_MSK) {
-       case TX_STATUS_SUCCESS:
-               return "SUCCESS";
-               TX_STATUS_ENTRY(SHORT_LIMIT);
-               TX_STATUS_ENTRY(LONG_LIMIT);
-               TX_STATUS_ENTRY(FIFO_UNDERRUN);
-               TX_STATUS_ENTRY(MGMNT_ABORT);
-               TX_STATUS_ENTRY(NEXT_FRAG);
-               TX_STATUS_ENTRY(LIFE_EXPIRE);
-               TX_STATUS_ENTRY(DEST_PS);
-               TX_STATUS_ENTRY(ABORTED);
-               TX_STATUS_ENTRY(BT_RETRY);
-               TX_STATUS_ENTRY(STA_INVALID);
-               TX_STATUS_ENTRY(FRAG_DROPPED);
-               TX_STATUS_ENTRY(TID_DISABLE);
-               TX_STATUS_ENTRY(FRAME_FLUSHED);
-               TX_STATUS_ENTRY(INSUFFICIENT_CF_POLL);
-               TX_STATUS_ENTRY(TX_LOCKED);
-               TX_STATUS_ENTRY(NO_BEACON_ON_RADAR);
-       }
-
-       return "UNKNOWN";
-}
-
 /**
  * iwl3945_scan_cancel - Cancel any currently executing HW scan
  *
@@ -2461,9 +2249,10 @@ static int iwl3945_set_rxon_hwcrypto(struct iwl3945_priv *priv, int hw_decrypt)
        return 0;
 }
 
-static void iwl3945_set_flags_for_phymode(struct iwl3945_priv *priv, u8 phymode)
+static void iwl3945_set_flags_for_phymode(struct iwl3945_priv *priv,
+                                         enum ieee80211_band band)
 {
-       if (phymode == MODE_IEEE80211A) {
+       if (band == IEEE80211_BAND_5GHZ) {
                priv->staging_rxon.flags &=
                    ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK
                      | RXON_FLG_CCK_MSK);
@@ -2515,6 +2304,9 @@ static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv)
                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);
+               break;
        }
 
 #if 0
@@ -2526,7 +2318,7 @@ static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv)
                priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
 #endif
 
-       ch_info = iwl3945_get_channel_info(priv, priv->phymode,
+       ch_info = iwl3945_get_channel_info(priv, priv->band,
                                       le16_to_cpu(priv->staging_rxon.channel));
 
        if (!ch_info)
@@ -2542,11 +2334,11 @@ static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv)
 
        priv->staging_rxon.channel = cpu_to_le16(ch_info->channel);
        if (is_channel_a_band(ch_info))
-               priv->phymode = MODE_IEEE80211A;
+               priv->band = IEEE80211_BAND_5GHZ;
        else
-               priv->phymode = MODE_IEEE80211G;
+               priv->band = IEEE80211_BAND_2GHZ;
 
-       iwl3945_set_flags_for_phymode(priv, priv->phymode);
+       iwl3945_set_flags_for_phymode(priv, priv->band);
 
        priv->staging_rxon.ofdm_basic_rates =
            (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
@@ -2560,7 +2352,7 @@ static int iwl3945_set_mode(struct iwl3945_priv *priv, int mode)
                const struct iwl3945_channel_info *ch_info;
 
                ch_info = iwl3945_get_channel_info(priv,
-                       priv->phymode,
+                       priv->band,
                        le16_to_cpu(priv->staging_rxon.channel));
 
                if (!ch_info || !is_channel_ibss(ch_info)) {
@@ -2694,8 +2486,12 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv,
                        cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(3);
                else
                        cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(2);
-       } else
+       } else {
                cmd->cmd.tx.timeout.pm_frame_timeout = 0;
+#ifdef CONFIG_IWL3945_LEDS
+               priv->rxtxpackets += le16_to_cpu(cmd->cmd.tx.len);
+#endif
+       }
 
        cmd->cmd.tx.driver_txop = 0;
        cmd->cmd.tx.tx_flags = tx_flags;
@@ -2792,7 +2588,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv,
                goto drop_unlock;
        }
 
-       if ((ctl->tx_rate & 0xFF) == IWL_INVALID_RATE) {
+       if ((ctl->tx_rate->hw_value & 0xFF) == IWL_INVALID_RATE) {
                IWL_ERROR("ERROR: No TX rate available.\n");
                goto drop_unlock;
        }
@@ -2963,7 +2759,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv,
                           ieee80211_get_hdrlen(fc));
 
        /* Tell device the write index *just past* this latest filled TFD */
-       q->write_ptr = iwl3945_queue_inc_wrap(q->write_ptr, q->n_bd);
+       q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
        rc = iwl3945_tx_queue_update_write_ptr(priv, txq);
        spin_unlock_irqrestore(&priv->lock, flags);
 
@@ -2992,12 +2788,12 @@ drop:
 
 static void iwl3945_set_rate(struct iwl3945_priv *priv)
 {
-       const struct ieee80211_hw_mode *hw = NULL;
+       const struct ieee80211_supported_band *sband = NULL;
        struct ieee80211_rate *rate;
        int i;
 
-       hw = iwl3945_get_hw_mode(priv, priv->phymode);
-       if (!hw) {
+       sband = iwl3945_get_band(priv, priv->band);
+       if (!sband) {
                IWL_ERROR("Failed to set rate: unable to get hw mode\n");
                return;
        }
@@ -3005,24 +2801,17 @@ static void iwl3945_set_rate(struct iwl3945_priv *priv)
        priv->active_rate = 0;
        priv->active_rate_basic = 0;
 
-       IWL_DEBUG_RATE("Setting rates for 802.11%c\n",
-                      hw->mode == MODE_IEEE80211A ?
-                      'a' : ((hw->mode == MODE_IEEE80211B) ? 'b' : 'g'));
-
-       for (i = 0; i < hw->num_rates; i++) {
-               rate = &(hw->rates[i]);
-               if ((rate->val < IWL_RATE_COUNT) &&
-                   (rate->flags & IEEE80211_RATE_SUPPORTED)) {
-                       IWL_DEBUG_RATE("Adding rate index %d (plcp %d)%s\n",
-                                      rate->val, iwl3945_rates[rate->val].plcp,
-                                      (rate->flags & IEEE80211_RATE_BASIC) ?
-                                      "*" : "");
-                       priv->active_rate |= (1 << rate->val);
-                       if (rate->flags & IEEE80211_RATE_BASIC)
-                               priv->active_rate_basic |= (1 << rate->val);
-               } else
-                       IWL_DEBUG_RATE("Not adding rate %d (plcp %d)\n",
-                                      rate->val, iwl3945_rates[rate->val].plcp);
+       IWL_DEBUG_RATE("Setting rates for %s GHz\n",
+                      sband->band == IEEE80211_BAND_2GHZ ? "2.4" : "5");
+
+       for (i = 0; i < sband->n_bitrates; i++) {
+               rate = &sband->bitrates[i];
+               if ((rate->hw_value < IWL_RATE_COUNT) &&
+                   !(rate->flags & IEEE80211_CHAN_DISABLED)) {
+                       IWL_DEBUG_RATE("Adding rate index %d (plcp %d)\n",
+                                      rate->hw_value, iwl3945_rates[rate->hw_value].plcp);
+                       priv->active_rate |= (1 << rate->hw_value);
+               }
        }
 
        IWL_DEBUG_RATE("Set active_rate = %0x, active_rate_basic = %0x\n",
@@ -3330,127 +3119,6 @@ static int iwl3945_get_measurement(struct iwl3945_priv *priv,
 }
 #endif
 
-static void iwl3945_txstatus_to_ieee(struct iwl3945_priv *priv,
-                                struct iwl3945_tx_info *tx_sta)
-{
-
-       tx_sta->status.ack_signal = 0;
-       tx_sta->status.excessive_retries = 0;
-       tx_sta->status.queue_length = 0;
-       tx_sta->status.queue_number = 0;
-
-       if (in_interrupt())
-               ieee80211_tx_status_irqsafe(priv->hw,
-                                           tx_sta->skb[0], &(tx_sta->status));
-       else
-               ieee80211_tx_status(priv->hw,
-                                   tx_sta->skb[0], &(tx_sta->status));
-
-       tx_sta->skb[0] = NULL;
-}
-
-/**
- * iwl3945_tx_queue_reclaim - Reclaim Tx queue entries already Tx'd
- *
- * When FW advances 'R' index, all entries between old and new 'R' index
- * need to be reclaimed. As result, some free space forms. If there is
- * enough free space (> low mark), wake the stack that feeds us.
- */
-static int iwl3945_tx_queue_reclaim(struct iwl3945_priv *priv, int txq_id, int index)
-{
-       struct iwl3945_tx_queue *txq = &priv->txq[txq_id];
-       struct iwl3945_queue *q = &txq->q;
-       int nfreed = 0;
-
-       if ((index >= q->n_bd) || (x2_queue_used(q, index) == 0)) {
-               IWL_ERROR("Read index for DMA queue txq id (%d), index %d, "
-                         "is out of range [0-%d] %d %d.\n", txq_id,
-                         index, q->n_bd, q->write_ptr, q->read_ptr);
-               return 0;
-       }
-
-       for (index = iwl3945_queue_inc_wrap(index, q->n_bd);
-               q->read_ptr != index;
-               q->read_ptr = iwl3945_queue_inc_wrap(q->read_ptr, q->n_bd)) {
-               if (txq_id != IWL_CMD_QUEUE_NUM) {
-                       iwl3945_txstatus_to_ieee(priv,
-                                       &(txq->txb[txq->q.read_ptr]));
-                       iwl3945_hw_txq_free_tfd(priv, txq);
-               } else if (nfreed > 1) {
-                       IWL_ERROR("HCMD skipped: index (%d) %d %d\n", index,
-                                       q->write_ptr, q->read_ptr);
-                       queue_work(priv->workqueue, &priv->restart);
-               }
-               nfreed++;
-       }
-
-       if (iwl3945_queue_space(q) > q->low_mark && (txq_id >= 0) &&
-                       (txq_id != IWL_CMD_QUEUE_NUM) &&
-                       priv->mac80211_registered)
-               ieee80211_wake_queue(priv->hw, txq_id);
-
-
-       return nfreed;
-}
-
-static int iwl3945_is_tx_success(u32 status)
-{
-       return (status & 0xFF) == 0x1;
-}
-
-/******************************************************************************
- *
- * Generic RX handler implementations
- *
- ******************************************************************************/
-/**
- * iwl3945_rx_reply_tx - Handle Tx response
- */
-static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv,
-                           struct iwl3945_rx_mem_buffer *rxb)
-{
-       struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
-       u16 sequence = le16_to_cpu(pkt->hdr.sequence);
-       int txq_id = SEQ_TO_QUEUE(sequence);
-       int index = SEQ_TO_INDEX(sequence);
-       struct iwl3945_tx_queue *txq = &priv->txq[txq_id];
-       struct ieee80211_tx_status *tx_status;
-       struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
-       u32  status = le32_to_cpu(tx_resp->status);
-
-       if ((index >= txq->q.n_bd) || (x2_queue_used(&txq->q, index) == 0)) {
-               IWL_ERROR("Read index for DMA queue txq_id (%d) index %d "
-                         "is out of range [0-%d] %d %d\n", txq_id,
-                         index, txq->q.n_bd, txq->q.write_ptr,
-                         txq->q.read_ptr);
-               return;
-       }
-
-       tx_status = &(txq->txb[txq->q.read_ptr].status);
-
-       tx_status->retry_count = tx_resp->failure_frame;
-       tx_status->queue_number = status;
-       tx_status->queue_length = tx_resp->bt_kill_count;
-       tx_status->queue_length |= tx_resp->failure_rts;
-
-       tx_status->flags =
-           iwl3945_is_tx_success(status) ? IEEE80211_TX_STATUS_ACK : 0;
-
-       tx_status->control.tx_rate = iwl3945_rate_index_from_plcp(tx_resp->rate);
-
-       IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) plcp rate %d retries %d\n",
-                       txq_id, iwl3945_get_tx_fail_reason(status), status,
-                       tx_resp->rate, tx_resp->failure_frame);
-
-       IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);
-       if (index != -1)
-               iwl3945_tx_queue_reclaim(priv, txq_id, index);
-
-       if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
-               IWL_ERROR("TODO:  Implement Tx ABORT REQUIRED!!!\n");
-}
-
-
 static void iwl3945_rx_reply_alive(struct iwl3945_priv *priv,
                               struct iwl3945_rx_mem_buffer *rxb)
 {
@@ -3797,13 +3465,44 @@ static void iwl3945_setup_rx_handlers(struct iwl3945_priv *priv)
        priv->rx_handlers[SCAN_COMPLETE_NOTIFICATION] =
            iwl3945_rx_scan_complete_notif;
        priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl3945_rx_card_state_notif;
-       priv->rx_handlers[REPLY_TX] = iwl3945_rx_reply_tx;
 
        /* Set up hardware specific Rx handlers */
        iwl3945_hw_rx_handler_setup(priv);
 }
 
 /**
+ * iwl3945_cmd_queue_reclaim - Reclaim CMD queue entries
+ * When FW advances 'R' index, all entries between old and new 'R' index
+ * need to be reclaimed.
+ */
+static void iwl3945_cmd_queue_reclaim(struct iwl3945_priv *priv,
+                                     int txq_id, int index)
+{
+       struct iwl3945_tx_queue *txq = &priv->txq[txq_id];
+       struct iwl3945_queue *q = &txq->q;
+       int nfreed = 0;
+
+       if ((index >= q->n_bd) || (iwl3945_x2_queue_used(q, index) == 0)) {
+               IWL_ERROR("Read index for DMA queue txq id (%d), index %d, "
+                         "is out of range [0-%d] %d %d.\n", txq_id,
+                         index, q->n_bd, q->write_ptr, q->read_ptr);
+               return;
+       }
+
+       for (index = iwl_queue_inc_wrap(index, q->n_bd); q->read_ptr != index;
+               q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
+               if (nfreed > 1) {
+                       IWL_ERROR("HCMD skipped: index (%d) %d %d\n", index,
+                                       q->write_ptr, q->read_ptr);
+                       queue_work(priv->workqueue, &priv->restart);
+                       break;
+               }
+               nfreed++;
+       }
+}
+
+
+/**
  * iwl3945_tx_cmd_complete - Pull unused buffers off the queue and reclaim them
  * @rxb: Rx buffer to reclaim
  *
@@ -3822,12 +3521,6 @@ static void iwl3945_tx_cmd_complete(struct iwl3945_priv *priv,
        int cmd_index;
        struct iwl3945_cmd *cmd;
 
-       /* If a Tx command is being handled and it isn't in the actual
-        * command queue then there a command routing bug has been introduced
-        * in the queue management code. */
-       if (txq_id != IWL_CMD_QUEUE_NUM)
-               IWL_ERROR("Error wrong command queue %d command id 0x%X\n",
-                         txq_id, pkt->hdr.cmd);
        BUG_ON(txq_id != IWL_CMD_QUEUE_NUM);
 
        cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge);
@@ -3841,7 +3534,7 @@ static void iwl3945_tx_cmd_complete(struct iwl3945_priv *priv,
                   !cmd->meta.u.callback(priv, cmd, rxb->skb))
                rxb->skb = NULL;
 
-       iwl3945_tx_queue_reclaim(priv, txq_id, index);
+       iwl3945_cmd_queue_reclaim(priv, txq_id, index);
 
        if (!(cmd->meta.flags & CMD_ASYNC)) {
                clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
@@ -4521,8 +4214,7 @@ static void iwl3945_dump_nic_error_log(struct iwl3945_priv *priv)
 
        if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
                IWL_ERROR("Start IWL Error Log Dump:\n");
-               IWL_ERROR("Status: 0x%08lX, Config: %08X count: %d\n",
-                         priv->status, priv->config, count);
+               IWL_ERROR("Status: 0x%08lX, count: %d\n", priv->status, count);
        }
 
        IWL_ERROR("Desc       Time       asrtPC  blink2 "
@@ -4742,9 +4434,9 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
         * atomic, make sure that inta covers all the interrupts that
         * we've discovered, even if FH interrupt came in just after
         * reading CSR_INT. */
-       if (inta_fh & CSR_FH_INT_RX_MASK)
+       if (inta_fh & CSR39_FH_INT_RX_MASK)
                inta |= CSR_INT_BIT_FH_RX;
-       if (inta_fh & CSR_FH_INT_TX_MASK)
+       if (inta_fh & CSR39_FH_INT_TX_MASK)
                inta |= CSR_INT_BIT_FH_TX;
 
        /* Now service all interrupt bits discovered above. */
@@ -4792,7 +4484,7 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
                /* 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
-                *   iwl_rx_card_state_notif() */
+                *   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);
@@ -5026,24 +4718,24 @@ static void iwl3945_init_band_reference(const struct iwl3945_priv *priv, int ban
  * Based on band and channel number.
  */
 const struct iwl3945_channel_info *iwl3945_get_channel_info(const struct iwl3945_priv *priv,
-                                                   int phymode, u16 channel)
+                                                   enum ieee80211_band band, u16 channel)
 {
        int i;
 
-       switch (phymode) {
-       case MODE_IEEE80211A:
+       switch (band) {
+       case IEEE80211_BAND_5GHZ:
                for (i = 14; i < priv->channel_count; i++) {
                        if (priv->channel_info[i].channel == channel)
                                return &priv->channel_info[i];
                }
                break;
 
-       case MODE_IEEE80211B:
-       case MODE_IEEE80211G:
+       case IEEE80211_BAND_2GHZ:
                if (channel >= 1 && channel <= 14)
                        return &priv->channel_info[channel - 1];
                break;
-
+       case IEEE80211_NUM_BANDS:
+               WARN_ON(1);
        }
 
        return NULL;
@@ -5106,8 +4798,8 @@ static int iwl3945_init_channel_map(struct iwl3945_priv *priv)
                /* Loop through each band adding each of the channels */
                for (ch = 0; ch < eeprom_ch_count; ch++) {
                        ch_info->channel = eeprom_ch_index[ch];
-                       ch_info->phymode = (band == 1) ? MODE_IEEE80211B :
-                           MODE_IEEE80211A;
+                       ch_info->band = (band == 1) ? IEEE80211_BAND_2GHZ :
+                           IEEE80211_BAND_5GHZ;
 
                        /* permanently store EEPROM's channel regulatory flags
                         *   and max power in channel info database. */
@@ -5134,11 +4826,12 @@ static int iwl3945_init_channel_map(struct iwl3945_priv *priv)
                        ch_info->scan_power = eeprom_ch_info[ch].max_power_avg;
                        ch_info->min_power = 0;
 
-                       IWL_DEBUG_INFO("Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x"
+                       IWL_DEBUG_INFO("Ch. %d [%sGHz] %s%s%s%s%s%s%s(0x%02x"
                                       " %ddBm): Ad-Hoc %ssupported\n",
                                       ch_info->channel,
                                       is_channel_a_band(ch_info) ?
                                       "5.2" : "2.4",
+                                      CHECK_AND_PRINT(VALID),
                                       CHECK_AND_PRINT(IBSS),
                                       CHECK_AND_PRINT(ACTIVE),
                                       CHECK_AND_PRINT(RADAR),
@@ -5203,18 +4896,20 @@ static void iwl3945_free_channel_map(struct iwl3945_priv *priv)
 #define IWL_PASSIVE_DWELL_BASE      (100)
 #define IWL_CHANNEL_TUNE_TIME       5
 
-static inline u16 iwl3945_get_active_dwell_time(struct iwl3945_priv *priv, int phymode)
+static inline u16 iwl3945_get_active_dwell_time(struct iwl3945_priv *priv,
+                                               enum ieee80211_band band)
 {
-       if (phymode == MODE_IEEE80211A)
+       if (band == IEEE80211_BAND_5GHZ)
                return IWL_ACTIVE_DWELL_TIME_52;
        else
                return IWL_ACTIVE_DWELL_TIME_24;
 }
 
-static u16 iwl3945_get_passive_dwell_time(struct iwl3945_priv *priv, int phymode)
+static u16 iwl3945_get_passive_dwell_time(struct iwl3945_priv *priv,
+                                         enum ieee80211_band band)
 {
-       u16 active = iwl3945_get_active_dwell_time(priv, phymode);
-       u16 passive = (phymode != MODE_IEEE80211A) ?
+       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;
 
@@ -5234,28 +4929,29 @@ static u16 iwl3945_get_passive_dwell_time(struct iwl3945_priv *priv, int phymode
        return passive;
 }
 
-static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, int phymode,
+static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv,
+                                        enum ieee80211_band band,
                                     u8 is_active, u8 direct_mask,
                                     struct iwl3945_scan_channel *scan_ch)
 {
        const struct ieee80211_channel *channels = NULL;
-       const struct ieee80211_hw_mode *hw_mode;
+       const struct ieee80211_supported_band *sband;
        const struct iwl3945_channel_info *ch_info;
        u16 passive_dwell = 0;
        u16 active_dwell = 0;
        int added, i;
 
-       hw_mode = iwl3945_get_hw_mode(priv, phymode);
-       if (!hw_mode)
+       sband = iwl3945_get_band(priv, band);
+       if (!sband)
                return 0;
 
-       channels = hw_mode->channels;
+       channels = sband->channels;
 
-       active_dwell = iwl3945_get_active_dwell_time(priv, phymode);
-       passive_dwell = iwl3945_get_passive_dwell_time(priv, phymode);
+       active_dwell = iwl3945_get_active_dwell_time(priv, band);
+       passive_dwell = iwl3945_get_passive_dwell_time(priv, band);
 
-       for (i = 0, added = 0; i < hw_mode->num_channels; i++) {
-               if (channels[i].chan ==
+       for (i = 0, added = 0; i < sband->n_channels; i++) {
+               if (channels[i].hw_value ==
                    le16_to_cpu(priv->active_rxon.channel)) {
                        if (iwl3945_is_associated(priv)) {
                                IWL_DEBUG_SCAN
@@ -5266,9 +4962,9 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, int phymode,
                } else if (priv->only_active_channel)
                        continue;
 
-               scan_ch->channel = channels[i].chan;
+               scan_ch->channel = channels[i].hw_value;
 
-               ch_info = iwl3945_get_channel_info(priv, phymode, scan_ch->channel);
+               ch_info = iwl3945_get_channel_info(priv, band, scan_ch->channel);
                if (!is_channel_valid(ch_info)) {
                        IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n",
                                       scan_ch->channel);
@@ -5276,7 +4972,7 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, int phymode,
                }
 
                if (!is_active || is_channel_passive(ch_info) ||
-                   !(channels[i].flag & IEEE80211_CHAN_W_ACTIVE_SCAN))
+                   (channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN))
                        scan_ch->type = 0;      /* passive */
                else
                        scan_ch->type = 1;      /* active */
@@ -5295,7 +4991,7 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, int phymode,
                /* scan_pwr_info->tpc.dsp_atten; */
 
                /*scan_pwr_info->tpc.tx_gain; */
-               if (phymode == MODE_IEEE80211A)
+               if (band == IEEE80211_BAND_5GHZ)
                        scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3;
                else {
                        scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3));
@@ -5319,41 +5015,23 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, int phymode,
        return added;
 }
 
-static void iwl3945_reset_channel_flag(struct iwl3945_priv *priv)
-{
-       int i, j;
-       for (i = 0; i < 3; i++) {
-               struct ieee80211_hw_mode *hw_mode = (void *)&priv->modes[i];
-               for (j = 0; j < hw_mode->num_channels; j++)
-                       hw_mode->channels[j].flag = hw_mode->channels[j].val;
-       }
-}
-
 static void iwl3945_init_hw_rates(struct iwl3945_priv *priv,
                              struct ieee80211_rate *rates)
 {
        int i;
 
        for (i = 0; i < IWL_RATE_COUNT; i++) {
-               rates[i].rate = iwl3945_rates[i].ieee * 5;
-               rates[i].val = i; /* Rate scaling will work on indexes */
-               rates[i].val2 = i;
-               rates[i].flags = IEEE80211_RATE_SUPPORTED;
-               /* Only OFDM have the bits-per-symbol set */
-               if ((i <= IWL_LAST_OFDM_RATE) && (i >= IWL_FIRST_OFDM_RATE))
-                       rates[i].flags |= IEEE80211_RATE_OFDM;
-               else {
+               rates[i].bitrate = iwl3945_rates[i].ieee * 5;
+               rates[i].hw_value = i; /* Rate scaling will work on indexes */
+               rates[i].hw_value_short = i;
+               rates[i].flags = 0;
+               if ((i > IWL_LAST_OFDM_RATE) || (i < IWL_FIRST_OFDM_RATE)) {
                        /*
-                        * If CCK 1M then set rate flag to CCK else CCK_2
-                        * which is CCK | PREAMBLE2
+                        * If CCK != 1M then set short preamble rate flag.
                         */
                        rates[i].flags |= (iwl3945_rates[i].plcp == 10) ?
-                               IEEE80211_RATE_CCK : IEEE80211_RATE_CCK_2;
+                               0 : IEEE80211_RATE_SHORT_PREAMBLE;
                }
-
-               /* Set up which ones are basic rates... */
-               if (IWL_BASIC_RATES_MASK & (1 << i))
-                       rates[i].flags |= IEEE80211_RATE_BASIC;
        }
 }
 
@@ -5363,143 +5041,117 @@ static void iwl3945_init_hw_rates(struct iwl3945_priv *priv,
 static int iwl3945_init_geos(struct iwl3945_priv *priv)
 {
        struct iwl3945_channel_info *ch;
-       struct ieee80211_hw_mode *modes;
+       struct ieee80211_supported_band *sband;
        struct ieee80211_channel *channels;
        struct ieee80211_channel *geo_ch;
        struct ieee80211_rate *rates;
        int i = 0;
-       enum {
-               A = 0,
-               B = 1,
-               G = 2,
-       };
-       int mode_count = 3;
 
-       if (priv->modes) {
+       if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates ||
+           priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) {
                IWL_DEBUG_INFO("Geography modes already initialized.\n");
                set_bit(STATUS_GEO_CONFIGURED, &priv->status);
                return 0;
        }
 
-       modes = kzalloc(sizeof(struct ieee80211_hw_mode) * mode_count,
-                       GFP_KERNEL);
-       if (!modes)
-               return -ENOMEM;
-
        channels = kzalloc(sizeof(struct ieee80211_channel) *
                           priv->channel_count, GFP_KERNEL);
-       if (!channels) {
-               kfree(modes);
+       if (!channels)
                return -ENOMEM;
-       }
 
-       rates = kzalloc((sizeof(struct ieee80211_rate) * (IWL_MAX_RATES + 1)),
+       rates = kzalloc((sizeof(struct ieee80211_rate) * (IWL_RATE_COUNT + 1)),
                        GFP_KERNEL);
        if (!rates) {
-               kfree(modes);
                kfree(channels);
                return -ENOMEM;
        }
 
-       /* 0 = 802.11a
-        * 1 = 802.11b
-        * 2 = 802.11g
-        */
-
        /* 5.2GHz channels start after the 2.4GHz channels */
-       modes[A].mode = MODE_IEEE80211A;
-       modes[A].channels = &channels[ARRAY_SIZE(iwl3945_eeprom_band_1)];
-       modes[A].rates = &rates[4];
-       modes[A].num_rates = 8; /* just OFDM */
-       modes[A].num_channels = 0;
-
-       modes[B].mode = MODE_IEEE80211B;
-       modes[B].channels = channels;
-       modes[B].rates = rates;
-       modes[B].num_rates = 4; /* just CCK */
-       modes[B].num_channels = 0;
-
-       modes[G].mode = MODE_IEEE80211G;
-       modes[G].channels = channels;
-       modes[G].rates = rates;
-       modes[G].num_rates = 12;        /* OFDM & CCK */
-       modes[G].num_channels = 0;
+       sband = &priv->bands[IEEE80211_BAND_5GHZ];
+       sband->channels = &channels[ARRAY_SIZE(iwl3945_eeprom_band_1)];
+       /* just OFDM */
+       sband->bitrates = &rates[IWL_FIRST_OFDM_RATE];
+       sband->n_bitrates = IWL_RATE_COUNT - IWL_FIRST_OFDM_RATE;
+
+       sband = &priv->bands[IEEE80211_BAND_2GHZ];
+       sband->channels = channels;
+       /* OFDM & CCK */
+       sband->bitrates = rates;
+       sband->n_bitrates = IWL_RATE_COUNT;
 
        priv->ieee_channels = channels;
        priv->ieee_rates = rates;
 
        iwl3945_init_hw_rates(priv, rates);
 
-       for (i = 0, geo_ch = channels; i < priv->channel_count; i++) {
+       for (i = 0 i < priv->channel_count; i++) {
                ch = &priv->channel_info[i];
 
-               if (!is_channel_valid(ch)) {
-                       IWL_DEBUG_INFO("Channel %d [%sGHz] is restricted -- "
-                                   "skipping.\n",
-                                   ch->channel, is_channel_a_band(ch) ?
-                                   "5.2" : "2.4");
+               /* FIXME: might be removed if scan is OK*/
+               if (!is_channel_valid(ch))
                        continue;
-               }
 
                if (is_channel_a_band(ch))
-                       geo_ch = &modes[A].channels[modes[A].num_channels++];
-               else {
-                       geo_ch = &modes[B].channels[modes[B].num_channels++];
-                       modes[G].num_channels++;
-               }
+                       sband =  &priv->bands[IEEE80211_BAND_5GHZ];
+               else
+                       sband =  &priv->bands[IEEE80211_BAND_2GHZ];
+
+               geo_ch = &sband->channels[sband->n_channels++];
 
-               geo_ch->freq = ieee80211chan2mhz(ch->channel);
-               geo_ch->chan = ch->channel;
-               geo_ch->power_level = ch->max_power_avg;
-               geo_ch->antenna_max = 0xff;
+               geo_ch->center_freq = ieee80211_channel_to_frequency(ch->channel);
+               geo_ch->max_power = ch->max_power_avg;
+               geo_ch->max_antenna_gain = 0xff;
+               geo_ch->hw_value = ch->channel;
 
                if (is_channel_valid(ch)) {
-                       geo_ch->flag = IEEE80211_CHAN_W_SCAN;
-                       if (ch->flags & EEPROM_CHANNEL_IBSS)
-                               geo_ch->flag |= IEEE80211_CHAN_W_IBSS;
+                       if (!(ch->flags & EEPROM_CHANNEL_IBSS))
+                               geo_ch->flags |= IEEE80211_CHAN_NO_IBSS;
 
-                       if (ch->flags & EEPROM_CHANNEL_ACTIVE)
-                               geo_ch->flag |= IEEE80211_CHAN_W_ACTIVE_SCAN;
+                       if (!(ch->flags & EEPROM_CHANNEL_ACTIVE))
+                               geo_ch->flags |= IEEE80211_CHAN_PASSIVE_SCAN;
 
                        if (ch->flags & EEPROM_CHANNEL_RADAR)
-                               geo_ch->flag |= IEEE80211_CHAN_W_RADAR_DETECT;
+                               geo_ch->flags |= IEEE80211_CHAN_RADAR;
 
                        if (ch->max_power_avg > priv->max_channel_txpower_limit)
                                priv->max_channel_txpower_limit =
                                    ch->max_power_avg;
+               } else {
+                       geo_ch->flags |= IEEE80211_CHAN_DISABLED;
                }
 
-               geo_ch->val = geo_ch->flag;
+               /* Save flags for reg domain usage */
+               geo_ch->orig_flags = geo_ch->flags;
+
+               IWL_DEBUG_INFO("Channel %d Freq=%d[%sGHz] %s flag=0%X\n",
+                               ch->channel, geo_ch->center_freq,
+                               is_channel_a_band(ch) ?  "5.2" : "2.4",
+                               geo_ch->flags & IEEE80211_CHAN_DISABLED ?
+                               "restricted" : "valid",
+                                geo_ch->flags);
        }
 
-       if ((modes[A].num_channels == 0) && priv->is_abg) {
+       if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) &&
+            priv->cfg->sku & IWL_SKU_A) {
                printk(KERN_INFO DRV_NAME
                       ": Incorrectly detected BG card as ABG.  Please send "
                       "your PCI ID 0x%04X:0x%04X to maintainer.\n",
                       priv->pci_dev->device, priv->pci_dev->subsystem_device);
-               priv->is_abg = 0;
+                priv->cfg->sku &= ~IWL_SKU_A;
        }
 
        printk(KERN_INFO DRV_NAME
               ": Tunable channels: %d 802.11bg, %d 802.11a channels\n",
-              modes[G].num_channels, modes[A].num_channels);
+              priv->bands[IEEE80211_BAND_2GHZ].n_channels,
+              priv->bands[IEEE80211_BAND_5GHZ].n_channels);
 
-       /*
-        * NOTE:  We register these in preference of order -- the
-        * stack doesn't currently (as of 7.0.6 / Apr 24 '07) pick
-        * a phymode based on rates or AP capabilities but seems to
-        * configure it purely on if the channel being configured
-        * is supported by a mode -- and the first match is taken
-        */
-
-       if (modes[G].num_channels)
-               ieee80211_register_hwmode(priv->hw, &modes[G]);
-       if (modes[B].num_channels)
-               ieee80211_register_hwmode(priv->hw, &modes[B]);
-       if (modes[A].num_channels)
-               ieee80211_register_hwmode(priv->hw, &modes[A]);
+       if (priv->bands[IEEE80211_BAND_2GHZ].n_channels)
+               priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
+                       &priv->bands[IEEE80211_BAND_2GHZ];
+       if (priv->bands[IEEE80211_BAND_5GHZ].n_channels)
+               priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
+                       &priv->bands[IEEE80211_BAND_5GHZ];
 
-       priv->modes = modes;
        set_bit(STATUS_GEO_CONFIGURED, &priv->status);
 
        return 0;
@@ -5510,7 +5162,6 @@ static int iwl3945_init_geos(struct iwl3945_priv *priv)
  */
 static void iwl3945_free_geos(struct iwl3945_priv *priv)
 {
-       kfree(priv->modes);
        kfree(priv->ieee_channels);
        kfree(priv->ieee_rates);
        clear_bit(STATUS_GEO_CONFIGURED, &priv->status);
@@ -5837,7 +5488,7 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)
        int ret = 0;
        const struct firmware *ucode_raw;
        /* firmware file name contains uCode/driver compatibility version */
-       const char *name = "iwlwifi-3945" IWL3945_UCODE_API ".ucode";
+       const char *name = priv->cfg->fw_name;
        u8 *src;
        size_t len;
        u32 ver, inst_size, data_size, init_size, init_data_size, boot_size;
@@ -6213,6 +5864,8 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
        set_bit(STATUS_READY, &priv->status);
        wake_up_interruptible(&priv->wait_command_queue);
 
+       iwl3945_led_register(priv);
+
        if (priv->error_recovering)
                iwl3945_error_recovery(priv);
 
@@ -6237,6 +5890,7 @@ static void __iwl3945_down(struct iwl3945_priv *priv)
        if (!exit_pending)
                set_bit(STATUS_EXIT_PENDING, &priv->status);
 
+       iwl3945_led_unregister(priv);
        iwl3945_clear_stations_table(priv);
 
        /* Unblock any waiting calls */
@@ -6519,7 +6173,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
        struct iwl3945_scan_cmd *scan;
        struct ieee80211_conf *conf = NULL;
        u8 direct_mask;
-       int phymode;
+       enum ieee80211_band band;
 
        conf = ieee80211_get_hw_conf(priv->hw);
 
@@ -6651,13 +6305,13 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
                scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
                scan->tx_cmd.rate = IWL_RATE_1M_PLCP;
                scan->good_CRC_th = 0;
-               phymode = MODE_IEEE80211G;
+               band = IEEE80211_BAND_2GHZ;
                break;
 
        case 1:
                scan->tx_cmd.rate = IWL_RATE_6M_PLCP;
                scan->good_CRC_th = IWL_GOOD_CRC_TH;
-               phymode = MODE_IEEE80211A;
+               band = IEEE80211_BAND_5GHZ;
                break;
 
        default:
@@ -6671,18 +6325,23 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
        if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR)
                scan->filter_flags = RXON_FILTER_PROMISC_MSK;
 
-       if (direct_mask)
+       if (direct_mask) {
                IWL_DEBUG_SCAN
                    ("Initiating direct scan for %s.\n",
                     iwl3945_escape_essid(priv->essid, priv->essid_len));
-       else
+               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 {
                IWL_DEBUG_SCAN("Initiating indirect scan.\n");
-
-       scan->channel_count =
-               iwl3945_get_channels_for_scan(
-                       priv, phymode, 1, /* active */
-                       direct_mask,
-                       (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
+               scan->channel_count =
+                       iwl3945_get_channels_for_scan(
+                               priv, band, 0, /* passive */
+                               direct_mask,
+                               (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
+       }
 
        cmd.len += le16_to_cpu(scan->tx_cmd.len) +
            scan->channel_count * sizeof(struct iwl3945_scan_channel);
@@ -6825,7 +6484,7 @@ static void iwl3945_bg_post_associate(struct work_struct *data)
                iwl3945_add_station(priv, iwl3945_broadcast_addr, 0, 0);
                iwl3945_add_station(priv, priv->bssid, 0, 0);
                iwl3945_sync_sta(priv, IWL_STA_ID,
-                                (priv->phymode == MODE_IEEE80211A)?
+                                (priv->band == IEEE80211_BAND_5GHZ) ?
                                 IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP,
                                 CMD_ASYNC);
                iwl3945_rate_scale_init(priv->hw, IWL_STA_ID);
@@ -6841,9 +6500,8 @@ static void iwl3945_bg_post_associate(struct work_struct *data)
 
        iwl3945_sequence_reset(priv);
 
-#ifdef CONFIG_IWL3945_QOS
        iwl3945_activate_qos(priv, 0);
-#endif /* CONFIG_IWL3945_QOS */
+
        /* we have just associated, don't start scan too early */
        priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN;
        mutex_unlock(&priv->mutex);
@@ -7020,7 +6678,7 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
        }
 
        IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
-                    ctl->tx_rate);
+                    ctl->tx_rate->bitrate);
 
        if (iwl3945_tx_skb(priv, skb, ctl))
                dev_kfree_skb_any(skb);
@@ -7079,7 +6737,7 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
        int ret = 0;
 
        mutex_lock(&priv->mutex);
-       IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel);
+       IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel->hw_value);
 
        priv->add_radiotap = !!(conf->flags & IEEE80211_CONF_RADIOTAP);
 
@@ -7099,19 +6757,20 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
 
        spin_lock_irqsave(&priv->lock, flags);
 
-       ch_info = iwl3945_get_channel_info(priv, conf->phymode, conf->channel);
+       ch_info = iwl3945_get_channel_info(priv, conf->channel->band,
+                                          conf->channel->hw_value);
        if (!is_channel_valid(ch_info)) {
                IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this SKU.\n",
-                              conf->channel, conf->phymode);
+                              conf->channel->hw_value, conf->channel->band);
                IWL_DEBUG_MAC80211("leave - invalid channel\n");
                spin_unlock_irqrestore(&priv->lock, flags);
                ret = -EINVAL;
                goto out;
        }
 
-       iwl3945_set_rxon_channel(priv, conf->phymode, conf->channel);
+       iwl3945_set_rxon_channel(priv, conf->channel->band, conf->channel->hw_value);
 
-       iwl3945_set_flags_for_phymode(priv, conf->phymode);
+       iwl3945_set_flags_for_phymode(priv, conf->channel->band);
 
        /* The list of supported rates and rate mask can be different
         * for each phymode; since the phymode may have changed, reset
@@ -7225,6 +6884,12 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
        if (conf == NULL)
                return -EIO;
 
+       if (priv->vif != vif) {
+               IWL_DEBUG_MAC80211("leave - priv->vif != vif\n");
+               mutex_unlock(&priv->mutex);
+               return 0;
+       }
+
        /* XXX: this MUST use conf->mac_addr */
 
        if ((priv->iw_mode == IEEE80211_IF_TYPE_AP) &&
@@ -7249,17 +6914,6 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
        if (unlikely(test_bit(STATUS_SCANNING, &priv->status)) &&
            !(priv->hw->flags & IEEE80211_HW_NO_PROBE_FILTERING)) {
  */
-       if (unlikely(test_bit(STATUS_SCANNING, &priv->status))) {
-               IWL_DEBUG_MAC80211("leave - scanning\n");
-               mutex_unlock(&priv->mutex);
-               return 0;
-       }
-
-       if (priv->vif != vif) {
-               IWL_DEBUG_MAC80211("leave - priv->vif != vif\n");
-               mutex_unlock(&priv->mutex);
-               return 0;
-       }
 
        if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
                if (!conf->bssid) {
@@ -7487,10 +7141,8 @@ static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, int queue,
                           const struct ieee80211_tx_queue_params *params)
 {
        struct iwl3945_priv *priv = hw->priv;
-#ifdef CONFIG_IWL3945_QOS
        unsigned long flags;
        int q;
-#endif /* CONFIG_IWL3945_QOS */
 
        IWL_DEBUG_MAC80211("enter\n");
 
@@ -7504,7 +7156,6 @@ static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, int queue,
                return 0;
        }
 
-#ifdef CONFIG_IWL3945_QOS
        if (!priv->qos_data.qos_enable) {
                priv->qos_data.qos_active = 0;
                IWL_DEBUG_MAC80211("leave - qos not enabled\n");
@@ -7518,7 +7169,7 @@ static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, int queue,
        priv->qos_data.def_qos_parm.ac[q].cw_max = cpu_to_le16(params->cw_max);
        priv->qos_data.def_qos_parm.ac[q].aifsn = params->aifs;
        priv->qos_data.def_qos_parm.ac[q].edca_txop =
-                       cpu_to_le16((params->burst_time * 100));
+                       cpu_to_le16((params->txop * 32));
 
        priv->qos_data.def_qos_parm.ac[q].reserved1 = 0;
        priv->qos_data.qos_active = 1;
@@ -7533,8 +7184,6 @@ static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, int queue,
 
        mutex_unlock(&priv->mutex);
 
-#endif /*CONFIG_IWL3945_QOS */
-
        IWL_DEBUG_MAC80211("leave\n");
        return 0;
 }
@@ -7599,9 +7248,8 @@ static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw)
        mutex_lock(&priv->mutex);
        IWL_DEBUG_MAC80211("enter\n");
 
-#ifdef CONFIG_IWL3945_QOS
        iwl3945_reset_qos(priv);
-#endif
+
        cancel_delayed_work(&priv->post_associate);
 
        spin_lock_irqsave(&priv->lock, flags);
@@ -7689,9 +7337,7 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
        IWL_DEBUG_MAC80211("leave\n");
        spin_unlock_irqrestore(&priv->lock, flags);
 
-#ifdef CONFIG_IWL3945_QOS
        iwl3945_reset_qos(priv);
-#endif
 
        queue_work(priv->workqueue, &priv->post_associate.work);
 
@@ -7892,65 +7538,6 @@ static ssize_t store_filter_flags(struct device *d,
 static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags,
                   store_filter_flags);
 
-static ssize_t show_tune(struct device *d,
-                        struct device_attribute *attr, char *buf)
-{
-       struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
-
-       return sprintf(buf, "0x%04X\n",
-                      (priv->phymode << 8) |
-                       le16_to_cpu(priv->active_rxon.channel));
-}
-
-static void iwl3945_set_flags_for_phymode(struct iwl3945_priv *priv, u8 phymode);
-
-static ssize_t store_tune(struct device *d,
-                         struct device_attribute *attr,
-                         const char *buf, size_t count)
-{
-       struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
-       char *p = (char *)buf;
-       u16 tune = simple_strtoul(p, &p, 0);
-       u8 phymode = (tune >> 8) & 0xff;
-       u16 channel = tune & 0xff;
-
-       IWL_DEBUG_INFO("Tune request to:%d channel:%d\n", phymode, channel);
-
-       mutex_lock(&priv->mutex);
-       if ((le16_to_cpu(priv->staging_rxon.channel) != channel) ||
-           (priv->phymode != phymode)) {
-               const struct iwl3945_channel_info *ch_info;
-
-               ch_info = iwl3945_get_channel_info(priv, phymode, channel);
-               if (!ch_info) {
-                       IWL_WARNING("Requested invalid phymode/channel "
-                                   "combination: %d %d\n", phymode, channel);
-                       mutex_unlock(&priv->mutex);
-                       return -EINVAL;
-               }
-
-               /* Cancel any currently running scans... */
-               if (iwl3945_scan_cancel_timeout(priv, 100))
-                       IWL_WARNING("Could not cancel scan.\n");
-               else {
-                       IWL_DEBUG_INFO("Committing phymode and "
-                                      "rxon.channel = %d %d\n",
-                                      phymode, channel);
-
-                       iwl3945_set_rxon_channel(priv, phymode, channel);
-                       iwl3945_set_flags_for_phymode(priv, phymode);
-
-                       iwl3945_set_rate(priv);
-                       iwl3945_commit_rxon(priv);
-               }
-       }
-       mutex_unlock(&priv->mutex);
-
-       return count;
-}
-
-static DEVICE_ATTR(tune, S_IWUSR | S_IRUGO, show_tune, store_tune);
-
 #ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
 
 static ssize_t show_measurement(struct device *d,
@@ -8024,31 +7611,6 @@ static DEVICE_ATTR(measurement, S_IRUSR | S_IWUSR,
                   show_measurement, store_measurement);
 #endif /* CONFIG_IWL3945_SPECTRUM_MEASUREMENT */
 
-static ssize_t show_rate(struct device *d,
-                        struct device_attribute *attr, char *buf)
-{
-       struct iwl3945_priv *priv = dev_get_drvdata(d);
-       unsigned long flags;
-       int i;
-
-       spin_lock_irqsave(&priv->sta_lock, flags);
-       if (priv->iw_mode == IEEE80211_IF_TYPE_STA)
-               i = priv->stations[IWL_AP_ID].current_rate.s.rate;
-       else
-               i = priv->stations[IWL_STA_ID].current_rate.s.rate;
-       spin_unlock_irqrestore(&priv->sta_lock, flags);
-
-       i = iwl3945_rate_index_from_plcp(i);
-       if (i == -1)
-               return sprintf(buf, "0\n");
-
-       return sprintf(buf, "%d%s\n",
-                      (iwl3945_rates[i].ieee >> 1),
-                      (iwl3945_rates[i].ieee & 0x1) ? ".5" : "");
-}
-
-static DEVICE_ATTR(rate, S_IRUSR, show_rate, NULL);
-
 static ssize_t store_retry_rate(struct device *d,
                                struct device_attribute *attr,
                                const char *buf, size_t count)
@@ -8165,73 +7727,8 @@ static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level,
 static ssize_t show_channels(struct device *d,
                             struct device_attribute *attr, char *buf)
 {
-       struct iwl3945_priv *priv = dev_get_drvdata(d);
-       int len = 0, i;
-       struct ieee80211_channel *channels = NULL;
-       const struct ieee80211_hw_mode *hw_mode = NULL;
-       int count = 0;
-
-       if (!iwl3945_is_ready(priv))
-               return -EAGAIN;
-
-       hw_mode = iwl3945_get_hw_mode(priv, MODE_IEEE80211G);
-       if (!hw_mode)
-               hw_mode = iwl3945_get_hw_mode(priv, MODE_IEEE80211B);
-       if (hw_mode) {
-               channels = hw_mode->channels;
-               count = hw_mode->num_channels;
-       }
-
-       len +=
-           sprintf(&buf[len],
-                   "Displaying %d channels in 2.4GHz band "
-                   "(802.11bg):\n", count);
-
-       for (i = 0; i < count; i++)
-               len += sprintf(&buf[len], "%d: %ddBm: BSS%s%s, %s.\n",
-                              channels[i].chan,
-                              channels[i].power_level,
-                              channels[i].
-                              flag & IEEE80211_CHAN_W_RADAR_DETECT ?
-                              " (IEEE 802.11h required)" : "",
-                              (!(channels[i].flag & IEEE80211_CHAN_W_IBSS)
-                               || (channels[i].
-                                   flag &
-                                   IEEE80211_CHAN_W_RADAR_DETECT)) ? "" :
-                              ", IBSS",
-                              channels[i].
-                              flag & IEEE80211_CHAN_W_ACTIVE_SCAN ?
-                              "active/passive" : "passive only");
-
-       hw_mode = iwl3945_get_hw_mode(priv, MODE_IEEE80211A);
-       if (hw_mode) {
-               channels = hw_mode->channels;
-               count = hw_mode->num_channels;
-       } else {
-               channels = NULL;
-               count = 0;
-       }
-
-       len += sprintf(&buf[len], "Displaying %d channels in 5.2GHz band "
-                      "(802.11a):\n", count);
-
-       for (i = 0; i < count; i++)
-               len += sprintf(&buf[len], "%d: %ddBm: BSS%s%s, %s.\n",
-                              channels[i].chan,
-                              channels[i].power_level,
-                              channels[i].
-                              flag & IEEE80211_CHAN_W_RADAR_DETECT ?
-                              " (IEEE 802.11h required)" : "",
-                              (!(channels[i].flag & IEEE80211_CHAN_W_IBSS)
-                               || (channels[i].
-                                   flag &
-                                   IEEE80211_CHAN_W_RADAR_DETECT)) ? "" :
-                              ", IBSS",
-                              channels[i].
-                              flag & IEEE80211_CHAN_W_ACTIVE_SCAN ?
-                              "active/passive" : "passive only");
-
-       return len;
+       /* all this shit doesn't belong into sysfs anyway */
+       return 0;
 }
 
 static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL);
@@ -8404,14 +7901,12 @@ static struct attribute *iwl3945_sysfs_entries[] = {
        &dev_attr_measurement.attr,
 #endif
        &dev_attr_power_level.attr,
-       &dev_attr_rate.attr,
        &dev_attr_retry_rate.attr,
        &dev_attr_rf_kill.attr,
        &dev_attr_rs_window.attr,
        &dev_attr_statistics.attr,
        &dev_attr_status.attr,
        &dev_attr_temperature.attr,
-       &dev_attr_tune.attr,
        &dev_attr_tx_power.attr,
 
        NULL
@@ -8444,9 +7939,9 @@ static struct ieee80211_ops iwl3945_hw_ops = {
 static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        int err = 0;
-       u32 pci_id;
        struct iwl3945_priv *priv;
        struct ieee80211_hw *hw;
+       struct iwl_3945_cfg *cfg = (struct iwl_3945_cfg *)(ent->driver_data);
        int i;
        DECLARE_MAC_BUF(mac);
 
@@ -8482,6 +7977,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
        priv->hw = hw;
 
        priv->pci_dev = pdev;
+       priv->cfg = cfg;
 
        /* Select antenna (may be helpful if only one antenna is connected) */
        priv->antenna = (enum iwl3945_antenna)iwl3945_param_antenna;
@@ -8532,7 +8028,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
        priv->data_retry_limit = -1;
        priv->ieee_channels = NULL;
        priv->ieee_rates = NULL;
-       priv->phymode = -1;
+       priv->band = IEEE80211_BAND_2GHZ;
 
        err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
        if (!err)
@@ -8571,32 +8067,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
 
        priv->iw_mode = IEEE80211_IF_TYPE_STA;
 
-       pci_id =
-           (priv->pci_dev->device << 16) | priv->pci_dev->subsystem_device;
-
-       switch (pci_id) {
-       case 0x42221005:        /* 0x4222 0x8086 0x1005 is BG SKU */
-       case 0x42221034:        /* 0x4222 0x8086 0x1034 is BG SKU */
-       case 0x42271014:        /* 0x4227 0x8086 0x1014 is BG SKU */
-       case 0x42221044:        /* 0x4222 0x8086 0x1044 is BG SKU */
-               priv->is_abg = 0;
-               break;
-
-       /*
-        * Rest are assumed ABG SKU -- if this is not the
-        * case then the card will get the wrong 'Detected'
-        * line in the kernel log however the code that
-        * initializes the GEO table will detect no A-band
-        * channels and remove the is_abg mask.
-        */
-       default:
-               priv->is_abg = 1;
-               break;
-       }
-
        printk(KERN_INFO DRV_NAME
-              ": Detected Intel PRO/Wireless 3945%sBG Network Connection\n",
-              priv->is_abg ? "A" : "");
+               ": Detected Intel Wireless WiFi Link %s\n", priv->cfg->name);
 
        /* Device-specific setup */
        if (iwl3945_hw_set_hw_setting(priv)) {
@@ -8604,7 +8076,6 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
                goto out_iounmap;
        }
 
-#ifdef CONFIG_IWL3945_QOS
        if (iwl3945_param_qos_enable)
                priv->qos_data.qos_enable = 1;
 
@@ -8612,9 +8083,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
 
        priv->qos_data.qos_active = 0;
        priv->qos_data.qos_cap.val = 0;
-#endif /* CONFIG_IWL3945_QOS */
 
-       iwl3945_set_rxon_channel(priv, MODE_IEEE80211G, 6);
+       iwl3945_set_rxon_channel(priv, IEEE80211_BAND_2GHZ, 6);
        iwl3945_setup_deferred_work(priv);
        iwl3945_setup_rx_handlers(priv);
 
@@ -8665,7 +8135,6 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
                IWL_ERROR("initializing geos failed: %d\n", err);
                goto out_free_channel_map;
        }
-       iwl3945_reset_channel_flag(priv);
 
        iwl3945_rate_control_register(priv->hw);
        err = ieee80211_register_hw(priv->hw);