mac80211: notify mac from low level driver (iwlwifi)
[deliverable/linux.git] / drivers / net / wireless / iwlwifi / iwl4965-base.c
index 44cfd02749761194efdc0eab056d24d872430378..06e44dad5f02026244801f576b4ddfc1446b2181 100644 (file)
@@ -46,8 +46,9 @@
 #include <asm/div64.h>
 
 #include "iwl-eeprom.h"
-#include "iwl-core.h"
 #include "iwl-4965.h"
+#include "iwl-core.h"
+#include "iwl-io.h"
 #include "iwl-helpers.h"
 
 static int iwl4965_tx_queue_update_write_ptr(struct iwl_priv *priv,
@@ -495,41 +496,7 @@ u8 iwl4965_add_station_flags(struct iwl_priv *priv, const u8 *addr,
 
 }
 
-/*************** DRIVER STATUS FUNCTIONS   *****/
-
-static inline int iwl4965_is_ready(struct iwl_priv *priv)
-{
-       /* The adapter is 'ready' if READY and GEO_CONFIGURED bits are
-        * set but EXIT_PENDING is not */
-       return test_bit(STATUS_READY, &priv->status) &&
-              test_bit(STATUS_GEO_CONFIGURED, &priv->status) &&
-              !test_bit(STATUS_EXIT_PENDING, &priv->status);
-}
-
-static inline int iwl4965_is_alive(struct iwl_priv *priv)
-{
-       return test_bit(STATUS_ALIVE, &priv->status);
-}
-
-static inline int iwl4965_is_init(struct iwl_priv *priv)
-{
-       return test_bit(STATUS_INIT, &priv->status);
-}
 
-static inline int iwl4965_is_rfkill(struct iwl_priv *priv)
-{
-       return test_bit(STATUS_RF_KILL_HW, &priv->status) ||
-              test_bit(STATUS_RF_KILL_SW, &priv->status);
-}
-
-static inline int iwl4965_is_ready_rf(struct iwl_priv *priv)
-{
-
-       if (iwl4965_is_rfkill(priv))
-               return 0;
-
-       return iwl4965_is_ready(priv);
-}
 
 /*************** HOST COMMAND QUEUE FUNCTIONS   *****/
 
@@ -561,7 +528,7 @@ int iwl4965_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
        BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) &&
               !(cmd->meta.flags & CMD_SIZE_HUGE));
 
-       if (iwl4965_is_rfkill(priv)) {
+       if (iwl_is_rfkill(priv)) {
                IWL_DEBUG_INFO("Not sending command - RF KILL");
                return -EIO;
        }
@@ -857,7 +824,7 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv)
        DECLARE_MAC_BUF(mac);
        int rc = 0;
 
-       if (!iwl4965_is_alive(priv))
+       if (!iwl_is_alive(priv))
                return -1;
 
        /* always get timestamp with Rx frame */
@@ -900,7 +867,7 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv)
         * an RXON_ASSOC and the new config wants the associated mask enabled,
         * we must clear the associated from the active configuration
         * before we apply the new config */
-       if (iwl4965_is_associated(priv) &&
+       if (iwl_is_associated(priv) &&
            (priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK)) {
                IWL_DEBUG_INFO("Toggling associated bit on current RXON\n");
                active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
@@ -966,7 +933,7 @@ static int iwl4965_commit_rxon(struct iwl_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 (iwl4965_is_associated(priv) &&
+       if (iwl_is_associated(priv) &&
            (priv->iw_mode == IEEE80211_IF_TYPE_STA)) {
                if (iwl4965_rxon_add_station(priv, priv->active_rxon.bssid_addr, 1)
                    == IWL_INVALID_STATION) {
@@ -1318,7 +1285,7 @@ unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv,
                                const u8 *dest, int left)
 {
 
-       if (!iwl4965_is_associated(priv) || !priv->ibss_beacon ||
+       if (!iwl_is_associated(priv) || !priv->ibss_beacon ||
            ((priv->iw_mode != IEEE80211_IF_TYPE_IBSS) &&
             (priv->iw_mode != IEEE80211_IF_TYPE_AP)))
                return 0;
@@ -1581,7 +1548,7 @@ static void iwl4965_activate_qos(struct iwl_priv *priv, u8 force)
 
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       if (force || iwl4965_is_associated(priv)) {
+       if (force || iwl_is_associated(priv)) {
                IWL_DEBUG_QOS("send QoS cmd with Qos active=%d FLAGS=0x%X\n",
                                priv->qos_data.qos_active,
                                priv->qos_data.def_qos_parm.qos_flags);
@@ -1792,6 +1759,8 @@ int iwl4965_is_network_packet(struct iwl_priv *priv, struct ieee80211_hdr *heade
                        return !compare_ether_addr(header->addr2, priv->bssid);
                /* packets to our adapter go through */
                return !compare_ether_addr(header->addr1, priv->mac_addr);
+       default:
+               break;
        }
 
        return 1;
@@ -1918,13 +1887,13 @@ static void iwl4965_setup_rxon_timing(struct iwl_priv *priv)
        conf = ieee80211_get_hw_conf(priv->hw);
 
        spin_lock_irqsave(&priv->lock, flags);
-       priv->rxon_timing.timestamp.dw[1] = cpu_to_le32(priv->timestamp1);
-       priv->rxon_timing.timestamp.dw[0] = cpu_to_le32(priv->timestamp0);
+       priv->rxon_timing.timestamp.dw[1] = cpu_to_le32(priv->timestamp >> 32);
+       priv->rxon_timing.timestamp.dw[0] =
+                               cpu_to_le32(priv->timestamp & 0xFFFFFFFF);
 
        priv->rxon_timing.listen_interval = INTEL_CONN_LISTEN_INTERVAL;
 
-       tsf = priv->timestamp1;
-       tsf = ((tsf << 32) | priv->timestamp0);
+       tsf = priv->timestamp;
 
        beacon_int = priv->beacon_int;
        spin_unlock_irqrestore(&priv->lock, flags);
@@ -1970,7 +1939,7 @@ static int iwl4965_scan_initiate(struct iwl_priv *priv)
                return 0;
        }
 
-       if (!iwl4965_is_ready_rf(priv)) {
+       if (!iwl_is_ready_rf(priv)) {
                IWL_DEBUG_SCAN("Aborting scan due to not ready.\n");
                return -EIO;
        }
@@ -2053,6 +2022,9 @@ static void iwl4965_connection_init_rx_config(struct iwl_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
@@ -2121,7 +2093,7 @@ static int iwl4965_set_mode(struct iwl_priv *priv, int mode)
        iwlcore_clear_stations_table(priv);
 
        /* dont commit rxon if rf-kill is on*/
-       if (!iwl4965_is_ready_rf(priv))
+       if (!iwl_is_ready_rf(priv))
                return -EAGAIN;
 
        cancel_delayed_work(&priv->scan_check);
@@ -2238,8 +2210,9 @@ static void iwl4965_build_tx_cmd_basic(struct iwl_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;
+       }
 
        cmd->cmd.tx.driver_txop = 0;
        cmd->cmd.tx.tx_flags = tx_flags;
@@ -2336,7 +2309,7 @@ static int iwl4965_tx_skb(struct iwl_priv *priv,
        int rc;
 
        spin_lock_irqsave(&priv->lock, flags);
-       if (iwl4965_is_rfkill(priv)) {
+       if (iwl_is_rfkill(priv)) {
                IWL_DEBUG_DROP("Dropping - RF KILL\n");
                goto drop_unlock;
        }
@@ -2367,10 +2340,10 @@ static int iwl4965_tx_skb(struct iwl_priv *priv,
 
        /* drop all data frame if we are not associated */
        if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) &&
-          (!iwl4965_is_associated(priv) ||
+          (!iwl_is_associated(priv) ||
            ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id) ||
            !priv->assoc_station_added)) {
-               IWL_DEBUG_DROP("Dropping - !iwl4965_is_associated\n");
+               IWL_DEBUG_DROP("Dropping - !iwl_is_associated\n");
                goto drop_unlock;
        }
 
@@ -2600,7 +2573,7 @@ static void iwl4965_set_rate(struct iwl_priv *priv)
                   (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
 }
 
-static void iwl4965_radio_kill_sw(struct iwl_priv *priv, int disable_radio)
+void iwl4965_radio_kill_sw(struct iwl_priv *priv, int disable_radio)
 {
        unsigned long flags;
 
@@ -2615,17 +2588,25 @@ static void iwl4965_radio_kill_sw(struct iwl_priv *priv, int disable_radio)
                /* FIXME: This is a workaround for AP */
                if (priv->iw_mode != IEEE80211_IF_TYPE_AP) {
                        spin_lock_irqsave(&priv->lock, flags);
-                       iwl4965_write32(priv, CSR_UCODE_DRV_GP1_SET,
+                       iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
                                    CSR_UCODE_SW_BIT_RFKILL);
                        spin_unlock_irqrestore(&priv->lock, flags);
-                       iwl4965_send_card_state(priv, CARD_STATE_CMD_DISABLE, 0);
+                       /* call the host command only if no hw rf-kill set */
+                       if (!test_bit(STATUS_RF_KILL_HW, &priv->status))
+                               iwl4965_send_card_state(priv,
+                                                       CARD_STATE_CMD_DISABLE,
+                                                       0);
                        set_bit(STATUS_RF_KILL_SW, &priv->status);
+
+                       /* make sure mac80211 stop sending Tx frame */
+                       if (priv->mac80211_registered)
+                               ieee80211_stop_queues(priv->hw);
                }
                return;
        }
 
        spin_lock_irqsave(&priv->lock, flags);
-       iwl4965_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+       iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
 
        clear_bit(STATUS_RF_KILL_SW, &priv->status);
        spin_unlock_irqrestore(&priv->lock, flags);
@@ -2634,9 +2615,9 @@ static void iwl4965_radio_kill_sw(struct iwl_priv *priv, int disable_radio)
        msleep(10);
 
        spin_lock_irqsave(&priv->lock, flags);
-       iwl4965_read32(priv, CSR_UCODE_DRV_GP1);
-       if (!iwl4965_grab_nic_access(priv))
-               iwl4965_release_nic_access(priv);
+       iwl_read32(priv, CSR_UCODE_DRV_GP1);
+       if (!iwl_grab_nic_access(priv))
+               iwl_release_nic_access(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
 
        if (test_bit(STATUS_RF_KILL_HW, &priv->status)) {
@@ -2823,7 +2804,7 @@ static int iwl4965_get_measurement(struct iwl_priv *priv,
        int spectrum_resp_status;
        int duration = le16_to_cpu(params->duration);
 
-       if (iwl4965_is_associated(priv))
+       if (iwl_is_associated(priv))
                add_time =
                    iwl4965_usecs_to_beacons(
                        le64_to_cpu(params->start_time) - priv->last_tsf,
@@ -2838,7 +2819,7 @@ static int iwl4965_get_measurement(struct iwl_priv *priv,
        cmd.len = sizeof(spectrum);
        spectrum.len = cpu_to_le16(cmd.len - sizeof(spectrum.len));
 
-       if (iwl4965_is_associated(priv))
+       if (iwl_is_associated(priv))
                spectrum.start_time =
                    iwl4965_add_beacon_time(priv->last_beacon_time,
                                add_time,
@@ -3104,7 +3085,7 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
                agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);
                IWL_DEBUG_TX_REPLY("Frames %d start_idx=%d bitmap=0x%llx\n",
                                   agg->frame_count, agg->start_idx,
-                                  agg->bitmap);
+                                  (unsigned long long)agg->bitmap);
 
                if (bitmap)
                        agg->wait_for_ba = 1;
@@ -3513,35 +3494,35 @@ static void iwl4965_rx_card_state_notif(struct iwl_priv *priv,
        if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED |
                     RF_CARD_DISABLED)) {
 
-               iwl4965_write32(priv, CSR_UCODE_DRV_GP1_SET,
+               iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
                            CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
 
-               if (!iwl4965_grab_nic_access(priv)) {
-                       iwl4965_write_direct32(
+               if (!iwl_grab_nic_access(priv)) {
+                       iwl_write_direct32(
                                priv, HBUS_TARG_MBX_C,
                                HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
 
-                       iwl4965_release_nic_access(priv);
+                       iwl_release_nic_access(priv);
                }
 
                if (!(flags & RXON_CARD_DISABLED)) {
-                       iwl4965_write32(priv, CSR_UCODE_DRV_GP1_CLR,
+                       iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
                                    CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
-                       if (!iwl4965_grab_nic_access(priv)) {
-                               iwl4965_write_direct32(
+                       if (!iwl_grab_nic_access(priv)) {
+                               iwl_write_direct32(
                                        priv, HBUS_TARG_MBX_C,
                                        HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
 
-                               iwl4965_release_nic_access(priv);
+                               iwl_release_nic_access(priv);
                        }
                }
 
                if (flags & RF_CARD_DISABLED) {
-                       iwl4965_write32(priv, CSR_UCODE_DRV_GP1_SET,
+                       iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
                                    CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
-                       iwl4965_read32(priv, CSR_UCODE_DRV_GP1);
-                       if (!iwl4965_grab_nic_access(priv))
-                               iwl4965_release_nic_access(priv);
+                       iwl_read32(priv, CSR_UCODE_DRV_GP1);
+                       if (!iwl_grab_nic_access(priv))
+                               iwl_release_nic_access(priv);
                }
        }
 
@@ -3755,27 +3736,27 @@ int iwl4965_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl4965_rx_q
 
        /* If power-saving is in use, make sure device is awake */
        if (test_bit(STATUS_POWER_PMI, &priv->status)) {
-               reg = iwl4965_read32(priv, CSR_UCODE_DRV_GP1);
+               reg = iwl_read32(priv, CSR_UCODE_DRV_GP1);
 
                if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
-                       iwl4965_set_bit(priv, CSR_GP_CNTRL,
+                       iwl_set_bit(priv, CSR_GP_CNTRL,
                                    CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
                        goto exit_unlock;
                }
 
-               rc = iwl4965_grab_nic_access(priv);
+               rc = iwl_grab_nic_access(priv);
                if (rc)
                        goto exit_unlock;
 
                /* Device expects a multiple of 8 */
-               iwl4965_write_direct32(priv, FH_RSCSR_CHNL0_WPTR,
+               iwl_write_direct32(priv, FH_RSCSR_CHNL0_WPTR,
                                     q->write & ~0x7);
-               iwl4965_release_nic_access(priv);
+               iwl_release_nic_access(priv);
 
        /* Else device is assumed to be awake */
        } else
                /* Device expects a multiple of 8 */
-               iwl4965_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write & ~0x7);
+               iwl_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write & ~0x7);
 
 
        q->need_update = 0;
@@ -4212,27 +4193,27 @@ static int iwl4965_tx_queue_update_write_ptr(struct iwl_priv *priv,
                /* wake up nic if it's powered down ...
                 * uCode will wake up, and interrupt us again, so next
                 * time we'll skip this part. */
-               reg = iwl4965_read32(priv, CSR_UCODE_DRV_GP1);
+               reg = iwl_read32(priv, CSR_UCODE_DRV_GP1);
 
                if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
                        IWL_DEBUG_INFO("Requesting wakeup, GP1 = 0x%x\n", reg);
-                       iwl4965_set_bit(priv, CSR_GP_CNTRL,
+                       iwl_set_bit(priv, CSR_GP_CNTRL,
                                    CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
                        return rc;
                }
 
                /* restore this queue's parameters in nic hardware. */
-               rc = iwl4965_grab_nic_access(priv);
+               rc = iwl_grab_nic_access(priv);
                if (rc)
                        return rc;
-               iwl4965_write_direct32(priv, HBUS_TARG_WRPTR,
+               iwl_write_direct32(priv, HBUS_TARG_WRPTR,
                                     txq->q.write_ptr | (txq_id << 8));
-               iwl4965_release_nic_access(priv);
+               iwl_release_nic_access(priv);
 
        /* else not in power-save mode, uCode will never sleep when we're
         * trying to tx (during RFKILL, we're not trying to tx). */
        } else
-               iwl4965_write32(priv, HBUS_TARG_WRPTR,
+               iwl_write32(priv, HBUS_TARG_WRPTR,
                            txq->q.write_ptr | (txq_id << 8));
 
        txq->need_update = 0;
@@ -4267,7 +4248,15 @@ static void iwl4965_enable_interrupts(struct iwl_priv *priv)
 {
        IWL_DEBUG_ISR("Enabling interrupts\n");
        set_bit(STATUS_INT_ENABLED, &priv->status);
-       iwl4965_write32(priv, CSR_INT_MASK, CSR_INI_SET_MASK);
+       iwl_write32(priv, CSR_INT_MASK, CSR_INI_SET_MASK);
+}
+
+/* call this function to flush any scheduled tasklet */
+static inline void iwl_synchronize_irq(struct iwl_priv *priv)
+{
+       /* wait to make sure we flush pedding tasklet*/
+       synchronize_irq(priv->pci_dev->irq);
+       tasklet_kill(&priv->irq_tasklet);
 }
 
 static inline void iwl4965_disable_interrupts(struct iwl_priv *priv)
@@ -4275,12 +4264,12 @@ static inline void iwl4965_disable_interrupts(struct iwl_priv *priv)
        clear_bit(STATUS_INT_ENABLED, &priv->status);
 
        /* disable interrupts from uCode/NIC to host */
-       iwl4965_write32(priv, CSR_INT_MASK, 0x00000000);
+       iwl_write32(priv, CSR_INT_MASK, 0x00000000);
 
        /* acknowledge/clear/reset any interrupts still pending
         * from uCode or flow handler (Rx/Tx DMA) */
-       iwl4965_write32(priv, CSR_INT, 0xffffffff);
-       iwl4965_write32(priv, CSR_FH_INT_STATUS, 0xffffffff);
+       iwl_write32(priv, CSR_INT, 0xffffffff);
+       iwl_write32(priv, CSR_FH_INT_STATUS, 0xffffffff);
        IWL_DEBUG_ISR("Disabled interrupts\n");
 }
 
@@ -4321,28 +4310,28 @@ static void iwl4965_dump_nic_error_log(struct iwl_priv *priv)
                return;
        }
 
-       rc = iwl4965_grab_nic_access(priv);
+       rc = iwl_grab_nic_access(priv);
        if (rc) {
                IWL_WARNING("Can not read from adapter at this time.\n");
                return;
        }
 
-       count = iwl4965_read_targ_mem(priv, base);
+       count = iwl_read_targ_mem(priv, base);
 
        if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
                IWL_ERROR("Start IWL Error Log Dump:\n");
                IWL_ERROR("Status: 0x%08lX, count: %d\n", priv->status, count);
        }
 
-       desc = iwl4965_read_targ_mem(priv, base + 1 * sizeof(u32));
-       blink1 = iwl4965_read_targ_mem(priv, base + 3 * sizeof(u32));
-       blink2 = iwl4965_read_targ_mem(priv, base + 4 * sizeof(u32));
-       ilink1 = iwl4965_read_targ_mem(priv, base + 5 * sizeof(u32));
-       ilink2 = iwl4965_read_targ_mem(priv, base + 6 * sizeof(u32));
-       data1 = iwl4965_read_targ_mem(priv, base + 7 * sizeof(u32));
-       data2 = iwl4965_read_targ_mem(priv, base + 8 * sizeof(u32));
-       line = iwl4965_read_targ_mem(priv, base + 9 * sizeof(u32));
-       time = iwl4965_read_targ_mem(priv, base + 11 * sizeof(u32));
+       desc = iwl_read_targ_mem(priv, base + 1 * sizeof(u32));
+       blink1 = iwl_read_targ_mem(priv, base + 3 * sizeof(u32));
+       blink2 = iwl_read_targ_mem(priv, base + 4 * sizeof(u32));
+       ilink1 = iwl_read_targ_mem(priv, base + 5 * sizeof(u32));
+       ilink2 = iwl_read_targ_mem(priv, base + 6 * sizeof(u32));
+       data1 = iwl_read_targ_mem(priv, base + 7 * sizeof(u32));
+       data2 = iwl_read_targ_mem(priv, base + 8 * sizeof(u32));
+       line = iwl_read_targ_mem(priv, base + 9 * sizeof(u32));
+       time = iwl_read_targ_mem(priv, base + 11 * sizeof(u32));
 
        IWL_ERROR("Desc               Time       "
                  "data1      data2      line\n");
@@ -4352,7 +4341,7 @@ static void iwl4965_dump_nic_error_log(struct iwl_priv *priv)
        IWL_ERROR("0x%05X 0x%05X 0x%05X 0x%05X\n", blink1, blink2,
                  ilink1, ilink2);
 
-       iwl4965_release_nic_access(priv);
+       iwl_release_nic_access(priv);
 }
 
 #define EVENT_START_OFFSET  (4 * sizeof(u32))
@@ -4360,7 +4349,7 @@ static void iwl4965_dump_nic_error_log(struct iwl_priv *priv)
 /**
  * iwl4965_print_event_log - Dump error event log to syslog
  *
- * NOTE: Must be called with iwl4965_grab_nic_access() already obtained!
+ * NOTE: Must be called with iwl_grab_nic_access() already obtained!
  */
 static void iwl4965_print_event_log(struct iwl_priv *priv, u32 start_idx,
                                u32 num_events, u32 mode)
@@ -4386,14 +4375,14 @@ static void iwl4965_print_event_log(struct iwl_priv *priv, u32 start_idx,
        /* "time" is actually "data" for mode 0 (no timestamp).
         * place event id # at far right for easier visual parsing. */
        for (i = 0; i < num_events; i++) {
-               ev = iwl4965_read_targ_mem(priv, ptr);
+               ev = iwl_read_targ_mem(priv, ptr);
                ptr += sizeof(u32);
-               time = iwl4965_read_targ_mem(priv, ptr);
+               time = iwl_read_targ_mem(priv, ptr);
                ptr += sizeof(u32);
                if (mode == 0)
                        IWL_ERROR("0x%08x\t%04u\n", time, ev); /* data, ev */
                else {
-                       data = iwl4965_read_targ_mem(priv, ptr);
+                       data = iwl_read_targ_mem(priv, ptr);
                        ptr += sizeof(u32);
                        IWL_ERROR("%010u\t0x%08x\t%04u\n", time, data, ev);
                }
@@ -4416,24 +4405,24 @@ static void iwl4965_dump_nic_event_log(struct iwl_priv *priv)
                return;
        }
 
-       rc = iwl4965_grab_nic_access(priv);
+       rc = iwl_grab_nic_access(priv);
        if (rc) {
                IWL_WARNING("Can not read from adapter at this time.\n");
                return;
        }
 
        /* event log header */
-       capacity = iwl4965_read_targ_mem(priv, base);
-       mode = iwl4965_read_targ_mem(priv, base + (1 * sizeof(u32)));
-       num_wraps = iwl4965_read_targ_mem(priv, base + (2 * sizeof(u32)));
-       next_entry = iwl4965_read_targ_mem(priv, base + (3 * sizeof(u32)));
+       capacity = iwl_read_targ_mem(priv, base);
+       mode = iwl_read_targ_mem(priv, base + (1 * sizeof(u32)));
+       num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32)));
+       next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32)));
 
        size = num_wraps ? capacity : next_entry;
 
        /* bail out if nothing in log */
        if (size == 0) {
                IWL_ERROR("Start IWL Event Log Dump: nothing in log\n");
-               iwl4965_release_nic_access(priv);
+               iwl_release_nic_access(priv);
                return;
        }
 
@@ -4449,7 +4438,7 @@ static void iwl4965_dump_nic_event_log(struct iwl_priv *priv)
        /* (then/else) start at top of log */
        iwl4965_print_event_log(priv, 0, next_entry, mode);
 
-       iwl4965_release_nic_access(priv);
+       iwl_release_nic_access(priv);
 }
 
 /**
@@ -4481,7 +4470,7 @@ static void iwl4965_irq_handle_error(struct iwl_priv *priv)
                IWL_DEBUG(IWL_DL_INFO | IWL_DL_FW_ERRORS,
                          "Restarting adapter due to uCode error.\n");
 
-               if (iwl4965_is_associated(priv)) {
+               if (iwl_is_associated(priv)) {
                        memcpy(&priv->recovery_rxon, &priv->active_rxon,
                               sizeof(priv->recovery_rxon));
                        priv->error_recovering = 1;
@@ -4521,19 +4510,19 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv)
        /* Ack/clear/reset pending uCode interrupts.
         * Note:  Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS,
         *  and will clear only when CSR_FH_INT_STATUS gets cleared. */
-       inta = iwl4965_read32(priv, CSR_INT);
-       iwl4965_write32(priv, CSR_INT, inta);
+       inta = iwl_read32(priv, CSR_INT);
+       iwl_write32(priv, CSR_INT, inta);
 
        /* Ack/clear/reset pending flow-handler (DMA) interrupts.
         * Any new interrupts that happen after this, either while we're
         * in this tasklet, or later, will show up in next ISR/tasklet. */
-       inta_fh = iwl4965_read32(priv, CSR_FH_INT_STATUS);
-       iwl4965_write32(priv, CSR_FH_INT_STATUS, inta_fh);
+       inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
+       iwl_write32(priv, CSR_FH_INT_STATUS, inta_fh);
 
 #ifdef CONFIG_IWLWIFI_DEBUG
        if (iwl_debug_level & IWL_DL_ISR) {
                /* just for debug */
-               inta_mask = iwl4965_read32(priv, CSR_INT_MASK);
+               inta_mask = iwl_read32(priv, CSR_INT_MASK);
                IWL_DEBUG_ISR("inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
                              inta, inta_mask, inta_fh);
        }
@@ -4582,7 +4571,7 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv)
        /* HW RF KILL switch toggled */
        if (inta & CSR_INT_BIT_RF_KILL) {
                int hw_rf_kill = 0;
-               if (!(iwl4965_read32(priv, CSR_GP_CNTRL) &
+               if (!(iwl_read32(priv, CSR_GP_CNTRL) &
                                CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
                        hw_rf_kill = 1;
 
@@ -4653,13 +4642,15 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv)
        }
 
        /* Re-enable all interrupts */
-       iwl4965_enable_interrupts(priv);
+       /* only Re-enable if diabled by irq */
+       if (test_bit(STATUS_INT_ENABLED, &priv->status))
+               iwl4965_enable_interrupts(priv);
 
 #ifdef CONFIG_IWLWIFI_DEBUG
        if (iwl_debug_level & (IWL_DL_ISR)) {
-               inta = iwl4965_read32(priv, CSR_INT);
-               inta_mask = iwl4965_read32(priv, CSR_INT_MASK);
-               inta_fh = iwl4965_read32(priv, CSR_FH_INT_STATUS);
+               inta = iwl_read32(priv, CSR_INT);
+               inta_mask = iwl_read32(priv, CSR_INT_MASK);
+               inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
                IWL_DEBUG_ISR("End inta 0x%08x, enabled 0x%08x, fh 0x%08x, "
                        "flags 0x%08lx\n", inta, inta_mask, inta_fh, flags);
        }
@@ -4681,12 +4672,12 @@ static irqreturn_t iwl4965_isr(int irq, void *data)
         *    back-to-back ISRs and sporadic interrupts from our NIC.
         * If we have something to service, the tasklet will re-enable ints.
         * If we *don't* have something, we'll re-enable before leaving here. */
-       inta_mask = iwl4965_read32(priv, CSR_INT_MASK);  /* just for debug */
-       iwl4965_write32(priv, CSR_INT_MASK, 0x00000000);
+       inta_mask = iwl_read32(priv, CSR_INT_MASK);  /* just for debug */
+       iwl_write32(priv, CSR_INT_MASK, 0x00000000);
 
        /* Discover which interrupts are active/pending */
-       inta = iwl4965_read32(priv, CSR_INT);
-       inta_fh = iwl4965_read32(priv, CSR_FH_INT_STATUS);
+       inta = iwl_read32(priv, CSR_INT);
+       inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
 
        /* Ignore interrupt if there's nothing in NIC to service.
         * This may be due to IRQ shared with another device,
@@ -4718,7 +4709,9 @@ static irqreturn_t iwl4965_isr(int irq, void *data)
 
  none:
        /* re-enable interrupts here since we don't have anything to service. */
-       iwl4965_enable_interrupts(priv);
+       /* only Re-enable if diabled by irq */
+       if (test_bit(STATUS_INT_ENABLED, &priv->status))
+               iwl4965_enable_interrupts(priv);
        spin_unlock(&priv->lock);
        return IRQ_NONE;
 }
@@ -4763,7 +4756,7 @@ static u16 iwl4965_get_passive_dwell_time(struct iwl_priv *priv,
            IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 :
            IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52;
 
-       if (iwl4965_is_associated(priv)) {
+       if (iwl_is_associated(priv)) {
                /* If we're associated, we clamp the maximum passive
                 * dwell time to be 98% of the beacon interval (minus
                 * 2 * channel tune time) */
@@ -4801,9 +4794,12 @@ static int iwl4965_get_channels_for_scan(struct iwl_priv *priv,
        passive_dwell = iwl4965_get_passive_dwell_time(priv, band);
 
        for (i = 0, added = 0; i < sband->n_channels; i++) {
+               if (channels[i].flags & IEEE80211_CHAN_DISABLED)
+                       continue;
+
                if (ieee80211_frequency_to_channel(channels[i].center_freq) ==
                    le16_to_cpu(priv->active_rxon.channel)) {
-                       if (iwl4965_is_associated(priv)) {
+                       if (iwl_is_associated(priv)) {
                                IWL_DEBUG_SCAN
                                    ("Skipping current channel %d\n",
                                     le16_to_cpu(priv->active_rxon.channel));
@@ -5001,8 +4997,12 @@ int iwl4965_init_geos(struct iwl_priv *priv)
               priv->bands[IEEE80211_BAND_2GHZ].n_channels,
               priv->bands[IEEE80211_BAND_5GHZ].n_channels);
 
-       priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->bands[IEEE80211_BAND_2GHZ];
-       priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &priv->bands[IEEE80211_BAND_5GHZ];
+       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];
 
        set_bit(STATUS_GEO_CONFIGURED, &priv->status);
 
@@ -5049,18 +5049,18 @@ static int iwl4965_verify_inst_full(struct iwl_priv *priv, __le32 *image,
 
        IWL_DEBUG_INFO("ucode inst image size is %u\n", len);
 
-       rc = iwl4965_grab_nic_access(priv);
+       rc = iwl_grab_nic_access(priv);
        if (rc)
                return rc;
 
-       iwl4965_write_direct32(priv, HBUS_TARG_MEM_RADDR, RTC_INST_LOWER_BOUND);
+       iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, RTC_INST_LOWER_BOUND);
 
        errcnt = 0;
        for (; len > 0; len -= sizeof(u32), image++) {
                /* read data comes through single port, auto-incr addr */
                /* NOTE: Use the debugless read so we don't flood kernel log
                 * if IWL_DL_IO is set */
-               val = _iwl4965_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+               val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
                if (val != le32_to_cpu(*image)) {
                        IWL_ERROR("uCode INST section is invalid at "
                                  "offset 0x%x, is 0x%x, s/b 0x%x\n",
@@ -5072,7 +5072,7 @@ static int iwl4965_verify_inst_full(struct iwl_priv *priv, __le32 *image,
                }
        }
 
-       iwl4965_release_nic_access(priv);
+       iwl_release_nic_access(priv);
 
        if (!errcnt)
                IWL_DEBUG_INFO
@@ -5096,7 +5096,7 @@ static int iwl4965_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32
 
        IWL_DEBUG_INFO("ucode inst image size is %u\n", len);
 
-       rc = iwl4965_grab_nic_access(priv);
+       rc = iwl_grab_nic_access(priv);
        if (rc)
                return rc;
 
@@ -5104,9 +5104,9 @@ static int iwl4965_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32
                /* read data comes through single port, auto-incr addr */
                /* NOTE: Use the debugless read so we don't flood kernel log
                 * if IWL_DL_IO is set */
-               iwl4965_write_direct32(priv, HBUS_TARG_MEM_RADDR,
+               iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
                        i + RTC_INST_LOWER_BOUND);
-               val = _iwl4965_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+               val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
                if (val != le32_to_cpu(*image)) {
 #if 0 /* Enable this if you want to see details */
                        IWL_ERROR("uCode INST section is invalid at "
@@ -5120,7 +5120,7 @@ static int iwl4965_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32
                }
        }
 
-       iwl4965_release_nic_access(priv);
+       iwl_release_nic_access(priv);
 
        return rc;
 }
@@ -5187,11 +5187,11 @@ static int iwl4965_verify_bsm(struct iwl_priv *priv)
        IWL_DEBUG_INFO("Begin verify bsm\n");
 
        /* verify BSM SRAM contents */
-       val = iwl4965_read_prph(priv, BSM_WR_DWCOUNT_REG);
+       val = iwl_read_prph(priv, BSM_WR_DWCOUNT_REG);
        for (reg = BSM_SRAM_LOWER_BOUND;
             reg < BSM_SRAM_LOWER_BOUND + len;
             reg += sizeof(u32), image ++) {
-               val = iwl4965_read_prph(priv, reg);
+               val = iwl_read_prph(priv, reg);
                if (val != le32_to_cpu(*image)) {
                        IWL_ERROR("BSM uCode verification failed at "
                                  "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n",
@@ -5268,42 +5268,42 @@ static int iwl4965_load_bsm(struct iwl_priv *priv)
        inst_len = priv->ucode_init.len;
        data_len = priv->ucode_init_data.len;
 
-       rc = iwl4965_grab_nic_access(priv);
+       rc = iwl_grab_nic_access(priv);
        if (rc)
                return rc;
 
-       iwl4965_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
-       iwl4965_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
-       iwl4965_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len);
-       iwl4965_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len);
+       iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
+       iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
+       iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len);
+       iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len);
 
        /* Fill BSM memory with bootstrap instructions */
        for (reg_offset = BSM_SRAM_LOWER_BOUND;
             reg_offset < BSM_SRAM_LOWER_BOUND + len;
             reg_offset += sizeof(u32), image++)
-               _iwl4965_write_prph(priv, reg_offset,
+               _iwl_write_prph(priv, reg_offset,
                                          le32_to_cpu(*image));
 
        rc = iwl4965_verify_bsm(priv);
        if (rc) {
-               iwl4965_release_nic_access(priv);
+               iwl_release_nic_access(priv);
                return rc;
        }
 
        /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */
-       iwl4965_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0);
-       iwl4965_write_prph(priv, BSM_WR_MEM_DST_REG,
+       iwl_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0);
+       iwl_write_prph(priv, BSM_WR_MEM_DST_REG,
                                 RTC_INST_LOWER_BOUND);
-       iwl4965_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32));
+       iwl_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32));
 
        /* Load bootstrap code into instruction SRAM now,
         *   to prepare to load "initialize" uCode */
-       iwl4965_write_prph(priv, BSM_WR_CTRL_REG,
+       iwl_write_prph(priv, BSM_WR_CTRL_REG,
                BSM_WR_CTRL_REG_BIT_START);
 
        /* Wait for load of bootstrap uCode to finish */
        for (i = 0; i < 100; i++) {
-               done = iwl4965_read_prph(priv, BSM_WR_CTRL_REG);
+               done = iwl_read_prph(priv, BSM_WR_CTRL_REG);
                if (!(done & BSM_WR_CTRL_REG_BIT_START))
                        break;
                udelay(10);
@@ -5317,10 +5317,10 @@ static int iwl4965_load_bsm(struct iwl_priv *priv)
 
        /* Enable future boot loads whenever power management unit triggers it
         *   (e.g. when powering back up after power-save shutdown) */
-       iwl4965_write_prph(priv, BSM_WR_CTRL_REG,
+       iwl_write_prph(priv, BSM_WR_CTRL_REG,
                BSM_WR_CTRL_REG_BIT_START_EN);
 
-       iwl4965_release_nic_access(priv);
+       iwl_release_nic_access(priv);
 
        return 0;
 }
@@ -5328,7 +5328,7 @@ static int iwl4965_load_bsm(struct iwl_priv *priv)
 static void iwl4965_nic_start(struct iwl_priv *priv)
 {
        /* Remove all resets to allow NIC to operate */
-       iwl4965_write32(priv, CSR_RESET, 0);
+       iwl_write32(priv, CSR_RESET, 0);
 }
 
 
@@ -5550,24 +5550,24 @@ static int iwl4965_set_ucode_ptrs(struct iwl_priv *priv)
        pdata = priv->ucode_data_backup.p_addr >> 4;
 
        spin_lock_irqsave(&priv->lock, flags);
-       rc = iwl4965_grab_nic_access(priv);
+       rc = iwl_grab_nic_access(priv);
        if (rc) {
                spin_unlock_irqrestore(&priv->lock, flags);
                return rc;
        }
 
        /* Tell bootstrap uCode where to find image to load */
-       iwl4965_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
-       iwl4965_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
-       iwl4965_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG,
+       iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
+       iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
+       iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG,
                                 priv->ucode_data.len);
 
        /* Inst bytecount must be last to set up, bit 31 signals uCode
         *   that all new ptr/size info is in place */
-       iwl4965_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG,
+       iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG,
                                 priv->ucode_code.len | BSM_DRAM_INST_LOAD);
 
-       iwl4965_release_nic_access(priv);
+       iwl_release_nic_access(priv);
 
        spin_unlock_irqrestore(&priv->lock, flags);
 
@@ -5670,7 +5670,7 @@ static void iwl4965_alive_start(struct iwl_priv *priv)
        /* Clear out the uCode error bit if it is set */
        clear_bit(STATUS_FW_ERROR, &priv->status);
 
-       if (iwl4965_is_rfkill(priv))
+       if (iwl_is_rfkill(priv))
                return;
 
        ieee80211_start_queues(priv->hw);
@@ -5680,7 +5680,7 @@ static void iwl4965_alive_start(struct iwl_priv *priv)
 
        iwl4965_send_power_mode(priv, IWL_POWER_LEVEL(priv->power_mode));
 
-       if (iwl4965_is_associated(priv)) {
+       if (iwl_is_associated(priv)) {
                struct iwl4965_rxon_cmd *active_rxon =
                                (struct iwl4965_rxon_cmd *)(&priv->active_rxon);
 
@@ -5701,16 +5701,20 @@ static void iwl4965_alive_start(struct iwl_priv *priv)
 
        /* At this point, the NIC is initialized and operational */
        priv->notif_missed_beacons = 0;
-       set_bit(STATUS_READY, &priv->status);
 
        iwl4965_rf_kill_ct_config(priv);
 
+       iwl_leds_register(priv);
+
        IWL_DEBUG_INFO("ALIVE processing complete.\n");
+       set_bit(STATUS_READY, &priv->status);
        wake_up_interruptible(&priv->wait_command_queue);
 
        if (priv->error_recovering)
                iwl4965_error_recovery(priv);
 
+       iwlcore_low_level_notify(priv, IWLCORE_START_EVT);
+       ieee80211_notify_mac(priv->hw, IEEE80211_NOTIFY_RE_ASSOC);
        return;
 
  restart:
@@ -5732,6 +5736,10 @@ static void __iwl4965_down(struct iwl_priv *priv)
        if (!exit_pending)
                set_bit(STATUS_EXIT_PENDING, &priv->status);
 
+       iwl_leds_unregister(priv);
+
+       iwlcore_low_level_notify(priv, IWLCORE_STOP_EVT);
+
        iwlcore_clear_stations_table(priv);
 
        /* Unblock any waiting calls */
@@ -5743,17 +5751,20 @@ static void __iwl4965_down(struct iwl_priv *priv)
                clear_bit(STATUS_EXIT_PENDING, &priv->status);
 
        /* stop and reset the on-board processor */
-       iwl4965_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
+       iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
 
        /* tell the device to stop sending interrupts */
+       spin_lock_irqsave(&priv->lock, flags);
        iwl4965_disable_interrupts(priv);
+       spin_unlock_irqrestore(&priv->lock, flags);
+       iwl_synchronize_irq(priv);
 
        if (priv->mac80211_registered)
                ieee80211_stop_queues(priv->hw);
 
        /* If we have not previously called iwl4965_init() then
         * clear all bits but the RF Kill and SUSPEND bits and return */
-       if (!iwl4965_is_init(priv)) {
+       if (!iwl_is_init(priv)) {
                priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) <<
                                        STATUS_RF_KILL_HW |
                               test_bit(STATUS_RF_KILL_SW, &priv->status) <<
@@ -5779,7 +5790,7 @@ static void __iwl4965_down(struct iwl_priv *priv)
                                STATUS_FW_ERROR;
 
        spin_lock_irqsave(&priv->lock, flags);
-       iwl4965_clear_bit(priv, CSR_GP_CNTRL,
+       iwl_clear_bit(priv, CSR_GP_CNTRL,
                         CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
        spin_unlock_irqrestore(&priv->lock, flags);
 
@@ -5787,17 +5798,17 @@ static void __iwl4965_down(struct iwl_priv *priv)
        iwl4965_hw_rxq_stop(priv);
 
        spin_lock_irqsave(&priv->lock, flags);
-       if (!iwl4965_grab_nic_access(priv)) {
-               iwl4965_write_prph(priv, APMG_CLK_DIS_REG,
+       if (!iwl_grab_nic_access(priv)) {
+               iwl_write_prph(priv, APMG_CLK_DIS_REG,
                                         APMG_CLK_VAL_DMA_CLK_RQT);
-               iwl4965_release_nic_access(priv);
+               iwl_release_nic_access(priv);
        }
        spin_unlock_irqrestore(&priv->lock, flags);
 
        udelay(5);
 
        iwl4965_hw_nic_stop_master(priv);
-       iwl4965_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
+       iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
        iwl4965_hw_nic_reset(priv);
 
  exit:
@@ -5834,6 +5845,7 @@ static int __iwl4965_up(struct iwl_priv *priv)
        if (test_bit(STATUS_RF_KILL_SW, &priv->status)) {
                IWL_WARNING("Radio disabled by SW RF kill (module "
                            "parameter)\n");
+               iwl_rfkill_set_hw_state(priv);
                return -ENODEV;
        }
 
@@ -5843,18 +5855,20 @@ static int __iwl4965_up(struct iwl_priv *priv)
        }
 
        /* If platform's RF_KILL switch is NOT set to KILL */
-       if (iwl4965_read32(priv, CSR_GP_CNTRL) &
+       if (iwl_read32(priv, CSR_GP_CNTRL) &
                                CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
                clear_bit(STATUS_RF_KILL_HW, &priv->status);
        else {
                set_bit(STATUS_RF_KILL_HW, &priv->status);
                if (!test_bit(STATUS_IN_SUSPEND, &priv->status)) {
+                       iwl_rfkill_set_hw_state(priv);
                        IWL_WARNING("Radio disabled by HW RF Kill switch\n");
                        return -ENODEV;
                }
        }
 
-       iwl4965_write32(priv, CSR_INT, 0xFFFFFFFF);
+       iwl_rfkill_set_hw_state(priv);
+       iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
 
        rc = iwl4965_hw_nic_init(priv);
        if (rc) {
@@ -5863,17 +5877,17 @@ static int __iwl4965_up(struct iwl_priv *priv)
        }
 
        /* make sure rfkill handshake bits are cleared */
-       iwl4965_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
-       iwl4965_write32(priv, CSR_UCODE_DRV_GP1_CLR,
+       iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+       iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
                    CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
 
        /* clear (again), then enable host interrupts */
-       iwl4965_write32(priv, CSR_INT, 0xFFFFFFFF);
+       iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
        iwl4965_enable_interrupts(priv);
 
        /* really make sure rfkill handshake bits are cleared */
-       iwl4965_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
-       iwl4965_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+       iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+       iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
 
        /* Copy original ucode data image from disk into backup cache.
         * This will be used to initialize the on-board processor's
@@ -5960,13 +5974,16 @@ static void iwl4965_bg_rf_kill(struct work_struct *work)
 
        mutex_lock(&priv->mutex);
 
-       if (!iwl4965_is_rfkill(priv)) {
+       if (!iwl_is_rfkill(priv)) {
                IWL_DEBUG(IWL_DL_INFO | IWL_DL_RF_KILL,
                          "HW and/or SW RF Kill no longer active, restarting "
                          "device\n");
                if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
                        queue_work(priv->workqueue, &priv->restart);
        } else {
+               /* make sure mac80211 stop sending Tx frame */
+               if (priv->mac80211_registered)
+                       ieee80211_stop_queues(priv->hw);
 
                if (!test_bit(STATUS_RF_KILL_HW, &priv->status))
                        IWL_DEBUG_RF_KILL("Can not turn radio back on - "
@@ -5976,6 +5993,8 @@ static void iwl4965_bg_rf_kill(struct work_struct *work)
                                    "Kill switch must be turned off for "
                                    "wireless networking to work.\n");
        }
+       iwl_rfkill_set_hw_state(priv);
+
        mutex_unlock(&priv->mutex);
 }
 
@@ -6022,7 +6041,7 @@ static void iwl4965_bg_request_scan(struct work_struct *data)
 
        mutex_lock(&priv->mutex);
 
-       if (!iwl4965_is_ready(priv)) {
+       if (!iwl_is_ready(priv)) {
                IWL_WARNING("request scan called when driver not ready.\n");
                goto done;
        }
@@ -6051,7 +6070,7 @@ static void iwl4965_bg_request_scan(struct work_struct *data)
                goto done;
        }
 
-       if (iwl4965_is_rfkill(priv)) {
+       if (iwl_is_rfkill(priv)) {
                IWL_DEBUG_HC("Aborting scan due to RF Kill activation\n");
                goto done;
        }
@@ -6080,7 +6099,7 @@ static void iwl4965_bg_request_scan(struct work_struct *data)
        scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
        scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
 
-       if (iwl4965_is_associated(priv)) {
+       if (iwl_is_associated(priv)) {
                u16 interval = 0;
                u32 extra;
                u32 suspend_time = 100;
@@ -6117,7 +6136,7 @@ static void iwl4965_bg_request_scan(struct work_struct *data)
                memcpy(scan->direct_scan[0].ssid,
                       priv->direct_ssid, priv->direct_ssid_len);
                direct_mask = 1;
-       } else if (!iwl4965_is_associated(priv) && priv->essid_len) {
+       } else if (!iwl_is_associated(priv) && 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);
@@ -6370,7 +6389,7 @@ static void iwl4965_bg_abort_scan(struct work_struct *work)
 {
        struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan);
 
-       if (!iwl4965_is_ready(priv))
+       if (!iwl_is_ready(priv))
                return;
 
        mutex_lock(&priv->mutex);
@@ -6503,7 +6522,7 @@ static void iwl4965_mac_stop(struct ieee80211_hw *hw)
 
        priv->is_open = 0;
 
-       if (iwl4965_is_ready_rf(priv)) {
+       if (iwl_is_ready_rf(priv)) {
                /* stop mac, cancel any scan request and clear
                 * RXON_FILTER_ASSOC_MSK BIT
                 */
@@ -6572,7 +6591,7 @@ static int iwl4965_mac_add_interface(struct ieee80211_hw *hw,
                memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
        }
 
-       if (iwl4965_is_ready(priv))
+       if (iwl_is_ready(priv))
                iwl4965_set_mode(priv, conf->type);
 
        mutex_unlock(&priv->mutex);
@@ -6600,7 +6619,7 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
 
        priv->add_radiotap = !!(conf->flags & IEEE80211_CONF_RADIOTAP);
 
-       if (!iwl4965_is_ready(priv)) {
+       if (!iwl_is_ready(priv)) {
                IWL_DEBUG_MAC80211("leave - not ready\n");
                ret = -EIO;
                goto out;
@@ -6656,14 +6675,15 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
        }
 #endif
 
-       iwl4965_radio_kill_sw(priv, !conf->radio_enabled);
+       if (priv->cfg->ops->lib->radio_kill_sw)
+               priv->cfg->ops->lib->radio_kill_sw(priv, !conf->radio_enabled);
 
        if (!conf->radio_enabled) {
                IWL_DEBUG_MAC80211("leave - radio disabled\n");
                goto out;
        }
 
-       if (iwl4965_is_rfkill(priv)) {
+       if (iwl_is_rfkill(priv)) {
                IWL_DEBUG_MAC80211("leave - RF kill\n");
                ret = -EIO;
                goto out;
@@ -6770,7 +6790,7 @@ static int iwl4965_mac_config_interface(struct ieee80211_hw *hw,
                return 0;
        }
 
-       if (!iwl4965_is_alive(priv))
+       if (!iwl_is_alive(priv))
                return -EAGAIN;
 
        mutex_lock(&priv->mutex);
@@ -6799,7 +6819,7 @@ static int iwl4965_mac_config_interface(struct ieee80211_hw *hw,
                priv->ibss_beacon = conf->beacon;
        }
 
-       if (iwl4965_is_rfkill(priv))
+       if (iwl_is_rfkill(priv))
                goto done;
 
        if (conf->bssid && !is_zero_ether_addr(conf->bssid) &&
@@ -6873,7 +6893,7 @@ static void iwl4965_mac_remove_interface(struct ieee80211_hw *hw,
 
        mutex_lock(&priv->mutex);
 
-       if (iwl4965_is_ready_rf(priv)) {
+       if (iwl_is_ready_rf(priv)) {
                iwl4965_scan_cancel_timeout(priv, 100);
                cancel_delayed_work(&priv->post_associate);
                priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
@@ -6891,6 +6911,65 @@ static void iwl4965_mac_remove_interface(struct ieee80211_hw *hw,
 
 }
 
+
+#ifdef CONFIG_IWL4965_HT
+static void iwl4965_ht_conf(struct iwl_priv *priv,
+                           struct ieee80211_bss_conf *bss_conf)
+{
+       struct ieee80211_ht_info *ht_conf = bss_conf->ht_conf;
+       struct ieee80211_ht_bss_info *ht_bss_conf = bss_conf->ht_bss_conf;
+       struct iwl_ht_info *iwl_conf = &priv->current_ht_config;
+
+       IWL_DEBUG_MAC80211("enter: \n");
+
+       iwl_conf->is_ht = bss_conf->assoc_ht;
+
+       if (!iwl_conf->is_ht)
+               return;
+
+       priv->ps_mode = (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2);
+
+       if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20)
+               iwl_conf->sgf |= 0x1;
+       if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40)
+               iwl_conf->sgf |= 0x2;
+
+       iwl_conf->is_green_field = !!(ht_conf->cap & IEEE80211_HT_CAP_GRN_FLD);
+       iwl_conf->max_amsdu_size =
+               !!(ht_conf->cap & IEEE80211_HT_CAP_MAX_AMSDU);
+
+       iwl_conf->supported_chan_width =
+               !!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH);
+       iwl_conf->extension_chan_offset =
+               ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_SEC_OFFSET;
+       /* If no above or below channel supplied disable FAT channel */
+       if (iwl_conf->extension_chan_offset != IWL_EXT_CHANNEL_OFFSET_ABOVE &&
+           iwl_conf->extension_chan_offset != IWL_EXT_CHANNEL_OFFSET_BELOW)
+               iwl_conf->supported_chan_width = 0;
+
+       iwl_conf->tx_mimo_ps_mode =
+               (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2);
+       memcpy(iwl_conf->supp_mcs_set, ht_conf->supp_mcs_set, 16);
+
+       iwl_conf->control_channel = ht_bss_conf->primary_channel;
+       iwl_conf->tx_chan_width =
+               !!(ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_WIDTH);
+       iwl_conf->ht_protection =
+               ht_bss_conf->bss_op_mode & IEEE80211_HT_IE_HT_PROTECTION;
+       iwl_conf->non_GF_STA_present =
+               !!(ht_bss_conf->bss_op_mode & IEEE80211_HT_IE_NON_GF_STA_PRSNT);
+
+       IWL_DEBUG_MAC80211("control channel %d\n", iwl_conf->control_channel);
+       IWL_DEBUG_MAC80211("leave\n");
+}
+#else
+static inline void iwl4965_ht_conf(struct iwl_priv *priv,
+                                  struct ieee80211_bss_conf *bss_conf)
+{
+}
+#endif
+
+#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
 static void iwl4965_bss_info_changed(struct ieee80211_hw *hw,
                                     struct ieee80211_vif *vif,
                                     struct ieee80211_bss_conf *bss_conf,
@@ -6898,7 +6977,11 @@ static void iwl4965_bss_info_changed(struct ieee80211_hw *hw,
 {
        struct iwl_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
@@ -6906,21 +6989,38 @@ static void iwl4965_bss_info_changed(struct ieee80211_hw *hw,
        }
 
        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_HT) {
+               IWL_DEBUG_MAC80211("HT %d\n", bss_conf->assoc_ht);
+               iwl4965_ht_conf(priv, bss_conf);
+               iwl4965_set_rxon_chain(priv);
+       }
+
        if (changes & BSS_CHANGED_ASSOC) {
-               /*
-                * TODO:
-                * do stuff instead of sniffing assoc resp
-                */
+               IWL_DEBUG_MAC80211("ASSOC %d\n", bss_conf->assoc);
+               if (bss_conf->assoc) {
+                       priv->assoc_id = bss_conf->aid;
+                       priv->beacon_int = bss_conf->beacon_int;
+                       priv->timestamp = bss_conf->timestamp;
+                       priv->assoc_capability = bss_conf->assoc_capability;
+                       priv->next_scan_jiffies = jiffies +
+                                       IWL_DELAY_NEXT_SCAN_AFTER_ASSOC;
+                       queue_work(priv->workqueue, &priv->post_associate.work);
+               } else {
+                       priv->assoc_id = 0;
+                       IWL_DEBUG_MAC80211("DISASSOC %d\n", bss_conf->assoc);
+               }
+       } else if (changes && iwl_is_associated(priv) && priv->assoc_id) {
+                       IWL_DEBUG_MAC80211("Associated Changes %d\n", changes);
+                       iwl4965_send_rxon_assoc(priv);
        }
 
-       if (iwl4965_is_associated(priv))
-               iwl4965_send_rxon_assoc(priv);
 }
 
 static int iwl4965_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
@@ -6934,7 +7034,7 @@ static int iwl4965_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
        mutex_lock(&priv->mutex);
        spin_lock_irqsave(&priv->lock, flags);
 
-       if (!iwl4965_is_ready_rf(priv)) {
+       if (!iwl_is_ready_rf(priv)) {
                rc = -EIO;
                IWL_DEBUG_MAC80211("leave - not ready or exit pending\n");
                goto out_unlock;
@@ -7053,7 +7153,7 @@ static int iwl4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 
        /* FIXME: need to differenciate between static and dynamic key
         * in the level of mac80211 */
-       static_key = !iwl4965_is_associated(priv);
+       static_key = !iwl_is_associated(priv);
 
        if (!static_key) {
                sta_id = iwl4965_hw_find_station(priv, addr);
@@ -7101,7 +7201,7 @@ static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, int queue,
 
        IWL_DEBUG_MAC80211("enter\n");
 
-       if (!iwl4965_is_ready_rf(priv)) {
+       if (!iwl_is_ready_rf(priv)) {
                IWL_DEBUG_MAC80211("leave - RF not ready\n");
                return -EIO;
        }
@@ -7134,7 +7234,7 @@ static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, int queue,
        mutex_lock(&priv->mutex);
        if (priv->iw_mode == IEEE80211_IF_TYPE_AP)
                iwl4965_activate_qos(priv, 1);
-       else if (priv->assoc_id && iwl4965_is_associated(priv))
+       else if (priv->assoc_id && iwl_is_associated(priv))
                iwl4965_activate_qos(priv, 0);
 
        mutex_unlock(&priv->mutex);
@@ -7154,7 +7254,7 @@ static int iwl4965_mac_get_tx_stats(struct ieee80211_hw *hw,
 
        IWL_DEBUG_MAC80211("enter\n");
 
-       if (!iwl4965_is_ready_rf(priv)) {
+       if (!iwl_is_ready_rf(priv)) {
                IWL_DEBUG_MAC80211("leave - RF not ready\n");
                return -EIO;
        }
@@ -7217,7 +7317,6 @@ static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw)
        spin_lock_irqsave(&priv->lock, flags);
        priv->assoc_id = 0;
        priv->assoc_capability = 0;
-       priv->call_post_assoc_from_beacon = 0;
        priv->assoc_station_added = 0;
 
        /* new association get rid of ibss beacon skb */
@@ -7227,14 +7326,13 @@ static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw)
        priv->ibss_beacon = NULL;
 
        priv->beacon_int = priv->hw->conf.beacon_int;
-       priv->timestamp1 = 0;
-       priv->timestamp0 = 0;
+       priv->timestamp = 0;
        if ((priv->iw_mode == IEEE80211_IF_TYPE_STA))
                priv->beacon_int = 0;
 
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       if (!iwl4965_is_ready_rf(priv)) {
+       if (!iwl_is_ready_rf(priv)) {
                IWL_DEBUG_MAC80211("leave - not ready\n");
                mutex_unlock(&priv->mutex);
                return;
@@ -7275,7 +7373,7 @@ static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
        mutex_lock(&priv->mutex);
        IWL_DEBUG_MAC80211("enter\n");
 
-       if (!iwl4965_is_ready_rf(priv)) {
+       if (!iwl_is_ready_rf(priv)) {
                IWL_DEBUG_MAC80211("leave - RF not ready\n");
                mutex_unlock(&priv->mutex);
                return -EIO;
@@ -7308,88 +7406,6 @@ static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
        return 0;
 }
 
-#ifdef CONFIG_IWL4965_HT
-
-static void iwl4965_ht_info_fill(struct ieee80211_conf *conf,
-                                struct iwl_priv *priv)
-{
-       struct iwl_ht_info *iwl_conf = &priv->current_ht_config;
-       struct ieee80211_ht_info *ht_conf = &conf->ht_conf;
-       struct ieee80211_ht_bss_info *ht_bss_conf = &conf->ht_bss_conf;
-
-       IWL_DEBUG_MAC80211("enter: \n");
-
-       if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)) {
-               iwl_conf->is_ht = 0;
-               return;
-       }
-
-       iwl_conf->is_ht = 1;
-       priv->ps_mode = (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2);
-
-       if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20)
-               iwl_conf->sgf |= 0x1;
-       if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40)
-               iwl_conf->sgf |= 0x2;
-
-       iwl_conf->is_green_field = !!(ht_conf->cap & IEEE80211_HT_CAP_GRN_FLD);
-       iwl_conf->max_amsdu_size =
-               !!(ht_conf->cap & IEEE80211_HT_CAP_MAX_AMSDU);
-
-       iwl_conf->supported_chan_width =
-               !!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH);
-       iwl_conf->extension_chan_offset =
-               ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_SEC_OFFSET;
-       /* If no above or below channel supplied disable FAT channel */
-       if (iwl_conf->extension_chan_offset != IWL_EXT_CHANNEL_OFFSET_ABOVE &&
-           iwl_conf->extension_chan_offset != IWL_EXT_CHANNEL_OFFSET_BELOW)
-               iwl_conf->supported_chan_width = 0;
-
-       iwl_conf->tx_mimo_ps_mode =
-               (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2);
-       memcpy(iwl_conf->supp_mcs_set, ht_conf->supp_mcs_set, 16);
-
-       iwl_conf->control_channel = ht_bss_conf->primary_channel;
-       iwl_conf->tx_chan_width =
-               !!(ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_WIDTH);
-       iwl_conf->ht_protection =
-               ht_bss_conf->bss_op_mode & IEEE80211_HT_IE_HT_PROTECTION;
-       iwl_conf->non_GF_STA_present =
-               !!(ht_bss_conf->bss_op_mode & IEEE80211_HT_IE_NON_GF_STA_PRSNT);
-
-       IWL_DEBUG_MAC80211("control channel %d\n",
-               iwl_conf->control_channel);
-       IWL_DEBUG_MAC80211("leave\n");
-}
-
-static int iwl4965_mac_conf_ht(struct ieee80211_hw *hw,
-                              struct ieee80211_conf *conf)
-{
-       struct iwl_priv *priv = hw->priv;
-
-       IWL_DEBUG_MAC80211("enter: \n");
-
-       iwl4965_ht_info_fill(conf, priv);
-       iwl4965_set_rxon_chain(priv);
-
-       if (priv && priv->assoc_id &&
-           (priv->iw_mode == IEEE80211_IF_TYPE_STA)) {
-               unsigned long flags;
-
-               spin_lock_irqsave(&priv->lock, flags);
-               if (priv->beacon_int)
-                       queue_work(priv->workqueue, &priv->post_associate.work);
-               else
-                       priv->call_post_assoc_from_beacon = 1;
-               spin_unlock_irqrestore(&priv->lock, flags);
-       }
-
-       IWL_DEBUG_MAC80211("leave:\n");
-       return 0;
-}
-
-#endif /*CONFIG_IWL4965_HT*/
-
 /*****************************************************************************
  *
  * sysfs attributes
@@ -7431,43 +7447,13 @@ static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO,
 
 #endif /* CONFIG_IWLWIFI_DEBUG */
 
-static ssize_t show_rf_kill(struct device *d,
-                           struct device_attribute *attr, char *buf)
-{
-       /*
-        * 0 - RF kill not enabled
-        * 1 - SW based RF kill active (sysfs)
-        * 2 - HW based RF kill active
-        * 3 - Both HW and SW based RF kill active
-        */
-       struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
-       int val = (test_bit(STATUS_RF_KILL_SW, &priv->status) ? 0x1 : 0x0) |
-                 (test_bit(STATUS_RF_KILL_HW, &priv->status) ? 0x2 : 0x0);
-
-       return sprintf(buf, "%i\n", val);
-}
-
-static ssize_t store_rf_kill(struct device *d,
-                            struct device_attribute *attr,
-                            const char *buf, size_t count)
-{
-       struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
-
-       mutex_lock(&priv->mutex);
-       iwl4965_radio_kill_sw(priv, buf[0] == '1');
-       mutex_unlock(&priv->mutex);
-
-       return count;
-}
-
-static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill);
 
 static ssize_t show_temperature(struct device *d,
                                struct device_attribute *attr, char *buf)
 {
        struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
 
-       if (!iwl4965_is_alive(priv))
+       if (!iwl_is_alive(priv))
                return -EAGAIN;
 
        return sprintf(buf, "%d\n", iwl4965_hw_get_temperature(priv));
@@ -7689,7 +7675,7 @@ static ssize_t store_power_level(struct device *d,
        mode = simple_strtoul(buf, NULL, 0);
        mutex_lock(&priv->mutex);
 
-       if (!iwl4965_is_ready(priv)) {
+       if (!iwl_is_ready(priv)) {
                rc = -EAGAIN;
                goto out;
        }
@@ -7786,7 +7772,7 @@ static ssize_t show_statistics(struct device *d,
        u8 *data = (u8 *) & priv->statistics;
        int rc = 0;
 
-       if (!iwl4965_is_alive(priv))
+       if (!iwl_is_alive(priv))
                return -EAGAIN;
 
        mutex_lock(&priv->mutex);
@@ -7820,7 +7806,7 @@ static ssize_t show_antenna(struct device *d,
 {
        struct iwl_priv *priv = dev_get_drvdata(d);
 
-       if (!iwl4965_is_alive(priv))
+       if (!iwl_is_alive(priv))
                return -EAGAIN;
 
        return sprintf(buf, "%d\n", priv->antenna);
@@ -7857,7 +7843,7 @@ static ssize_t show_status(struct device *d,
                           struct device_attribute *attr, char *buf)
 {
        struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
-       if (!iwl4965_is_alive(priv))
+       if (!iwl_is_alive(priv))
                return -EAGAIN;
        return sprintf(buf, "0x%08x\n", (int)priv->status);
 }
@@ -7946,7 +7932,6 @@ static struct attribute *iwl4965_sysfs_entries[] = {
 #endif
        &dev_attr_power_level.attr,
        &dev_attr_retry_rate.attr,
-       &dev_attr_rf_kill.attr,
        &dev_attr_rs_window.attr,
        &dev_attr_statistics.attr,
        &dev_attr_status.attr,
@@ -7980,7 +7965,6 @@ static struct ieee80211_ops iwl4965_hw_ops = {
        .beacon_update = iwl4965_mac_beacon_update,
        .bss_info_changed = iwl4965_bss_info_changed,
 #ifdef CONFIG_IWL4965_HT
-       .conf_ht = iwl4965_mac_conf_ht,
        .ampdu_action = iwl4965_mac_ampdu_action,
 #endif  /* CONFIG_IWL4965_HT */
        .hw_scan = iwl4965_mac_hw_scan
@@ -7992,6 +7976,7 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
        struct iwl_priv *priv;
        struct ieee80211_hw *hw;
        struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
+       unsigned long flags;
        DECLARE_MAC_BUF(mac);
 
        /************************
@@ -8073,11 +8058,11 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
         * 4. Read EEPROM
         *****************/
        /* nic init */
-       iwl4965_set_bit(priv, CSR_GIO_CHICKEN_BITS,
+       iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
                CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
 
-       iwl4965_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
-       err = iwl4965_poll_bit(priv, CSR_GP_CNTRL,
+       iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+       err = iwl_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) {
@@ -8129,7 +8114,9 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
        /********************
         * 8. Setup services
         ********************/
+       spin_lock_irqsave(&priv->lock, flags);
        iwl4965_disable_interrupts(priv);
+       spin_unlock_irqrestore(&priv->lock, flags);
 
        err = sysfs_create_group(&pdev->dev.kobj, &iwl4965_attribute_group);
        if (err) {
@@ -8152,6 +8139,8 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
        pci_save_state(pdev);
        pci_disable_device(pdev);
 
+       /* notify iwlcore to init */
+       iwlcore_low_level_notify(priv, IWLCORE_INIT_EVT);
        return 0;
 
  out_remove_sysfs:
@@ -8171,21 +8160,36 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
        return err;
 }
 
-static void iwl4965_pci_remove(struct pci_dev *pdev)
+static void __devexit iwl4965_pci_remove(struct pci_dev *pdev)
 {
        struct iwl_priv *priv = pci_get_drvdata(pdev);
        struct list_head *p, *q;
        int i;
+       unsigned long flags;
 
        if (!priv)
                return;
 
        IWL_DEBUG_INFO("*** UNLOAD DRIVER ***\n");
 
+       if (priv->mac80211_registered) {
+               ieee80211_unregister_hw(priv->hw);
+               priv->mac80211_registered = 0;
+       }
+
        set_bit(STATUS_EXIT_PENDING, &priv->status);
 
        iwl4965_down(priv);
 
+       /* make sure we flush any pending irq or
+        * tasklet for the driver
+        */
+       spin_lock_irqsave(&priv->lock, flags);
+       iwl4965_disable_interrupts(priv);
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       iwl_synchronize_irq(priv);
+
        /* Free MAC hash list for ADHOC */
        for (i = 0; i < IWL_IBSS_MAC_HASH_SIZE; i++) {
                list_for_each_safe(p, q, &priv->ibss_mac_hash[i]) {
@@ -8194,6 +8198,7 @@ static void iwl4965_pci_remove(struct pci_dev *pdev)
                }
        }
 
+       iwlcore_low_level_notify(priv, IWLCORE_REMOVE_EVT);
        iwl_dbgfs_unregister(priv);
        sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group);
 
@@ -8206,10 +8211,6 @@ static void iwl4965_pci_remove(struct pci_dev *pdev)
        iwl4965_unset_hw_setting(priv);
        iwlcore_clear_stations_table(priv);
 
-       if (priv->mac80211_registered) {
-               ieee80211_unregister_hw(priv->hw);
-               iwl4965_rate_control_unregister(priv->hw);
-       }
 
        /*netif_stop_queue(dev); */
        flush_workqueue(priv->workqueue);
@@ -8289,21 +8290,35 @@ static int __init iwl4965_init(void)
        int ret;
        printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
        printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
+
+       ret = iwl4965_rate_control_register();
+       if (ret) {
+               IWL_ERROR("Unable to register rate control algorithm: %d\n", ret);
+               return ret;
+       }
+
        ret = pci_register_driver(&iwl4965_driver);
        if (ret) {
                IWL_ERROR("Unable to initialize PCI module\n");
-               return ret;
+               goto error_register;
        }
 #ifdef CONFIG_IWLWIFI_DEBUG
        ret = driver_create_file(&iwl4965_driver.driver, &driver_attr_debug_level);
        if (ret) {
                IWL_ERROR("Unable to create driver sysfs file\n");
-               pci_unregister_driver(&iwl4965_driver);
-               return ret;
+               goto error_debug;
        }
 #endif
 
        return ret;
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+error_debug:
+       pci_unregister_driver(&iwl4965_driver);
+#endif
+error_register:
+       iwl4965_rate_control_unregister();
+       return ret;
 }
 
 static void __exit iwl4965_exit(void)
@@ -8312,6 +8327,7 @@ static void __exit iwl4965_exit(void)
        driver_remove_file(&iwl4965_driver.driver, &driver_attr_debug_level);
 #endif
        pci_unregister_driver(&iwl4965_driver);
+       iwl4965_rate_control_unregister();
 }
 
 module_exit(iwl4965_exit);
This page took 0.05178 seconds and 5 git commands to generate.