headers: remove sched.h from interrupt.h
[safe/jmp/linux-2.6] / drivers / net / wireless / iwlwifi / iwl-agn.c
index 3ebf80f..313d3e5 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
+#include <linux/sched.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
 #include <linux/wireless.h>
@@ -171,7 +172,7 @@ int iwl_commit_rxon(struct iwl_priv *priv)
                       le16_to_cpu(priv->staging_rxon.channel),
                       priv->staging_rxon.bssid_addr);
 
-       iwl_set_rxon_hwcrypto(priv, !priv->hw_params.sw_crypto);
+       iwl_set_rxon_hwcrypto(priv, !priv->cfg->mod_params->sw_crypto);
 
        /* Apply the new configuration
         * RXON unassoc clears the station table in uCode, send it before
@@ -188,10 +189,9 @@ int iwl_commit_rxon(struct iwl_priv *priv)
                memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
        }
 
-       priv->cfg->ops->smgmt->clear_station_table(priv);
+       iwl_clear_stations_table(priv);
 
-       if (!priv->error_recovering)
-               priv->start_calib = 0;
+       priv->start_calib = 0;
 
        /* Add the broadcast address so we can send broadcast frames */
        if (iwl_rxon_add_station(priv, iwl_bcast_addr, 0) ==
@@ -443,8 +443,8 @@ void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
        /* Unmap tx_cmd */
        if (num_tbs)
                pci_unmap_single(dev,
-                               pci_unmap_addr(&txq->cmd[index]->meta, mapping),
-                               pci_unmap_len(&txq->cmd[index]->meta, len),
+                               pci_unmap_addr(&txq->meta[index], mapping),
+                               pci_unmap_len(&txq->meta[index], len),
                                PCI_DMA_BIDIRECTIONAL);
 
        /* Unmap chunks, if any. */
@@ -504,90 +504,15 @@ int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
 int iwl_hw_tx_queue_init(struct iwl_priv *priv,
                         struct iwl_tx_queue *txq)
 {
-       int ret;
-       unsigned long flags;
        int txq_id = txq->q.id;
 
-       spin_lock_irqsave(&priv->lock, flags);
-       ret = iwl_grab_nic_access(priv);
-       if (ret) {
-               spin_unlock_irqrestore(&priv->lock, flags);
-               return ret;
-       }
-
        /* Circular buffer (TFD queue in DRAM) physical base address */
        iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id),
                             txq->q.dma_addr >> 8);
 
-       iwl_release_nic_access(priv);
-       spin_unlock_irqrestore(&priv->lock, flags);
-
        return 0;
 }
 
-
-/******************************************************************************
- *
- * Misc. internal state and helper functions
- *
- ******************************************************************************/
-
-#define MAX_UCODE_BEACON_INTERVAL      4096
-
-static u16 iwl_adjust_beacon_interval(u16 beacon_val)
-{
-       u16 new_val = 0;
-       u16 beacon_factor = 0;
-
-       beacon_factor = (beacon_val + MAX_UCODE_BEACON_INTERVAL)
-                                       / MAX_UCODE_BEACON_INTERVAL;
-       new_val = beacon_val / beacon_factor;
-
-       if (!new_val)
-               new_val = MAX_UCODE_BEACON_INTERVAL;
-
-       return new_val;
-}
-
-static void iwl_setup_rxon_timing(struct iwl_priv *priv)
-{
-       u64 tsf;
-       s32 interval_tm, rem;
-       unsigned long flags;
-       struct ieee80211_conf *conf = NULL;
-       u16 beacon_int = 0;
-
-       conf = ieee80211_get_hw_conf(priv->hw);
-
-       spin_lock_irqsave(&priv->lock, flags);
-       priv->rxon_timing.timestamp = cpu_to_le64(priv->timestamp);
-       priv->rxon_timing.listen_interval = cpu_to_le16(conf->listen_interval);
-
-       if (priv->iw_mode == NL80211_IFTYPE_STATION) {
-               beacon_int = iwl_adjust_beacon_interval(priv->beacon_int);
-               priv->rxon_timing.atim_window = 0;
-       } else {
-               beacon_int = iwl_adjust_beacon_interval(conf->beacon_int);
-
-               /* TODO: we need to get atim_window from upper stack
-                * for now we set to 0 */
-               priv->rxon_timing.atim_window = 0;
-       }
-
-       priv->rxon_timing.beacon_interval = cpu_to_le16(beacon_int);
-
-       tsf = priv->timestamp; /* tsf is modifed by do_div: copy it */
-       interval_tm = beacon_int * 1024;
-       rem = do_div(tsf, interval_tm);
-       priv->rxon_timing.beacon_init_val = cpu_to_le32(interval_tm - rem);
-
-       spin_unlock_irqrestore(&priv->lock, flags);
-       IWL_DEBUG_ASSOC(priv, "beacon interval %d beacon timer %d beacon tim %d\n",
-                       le16_to_cpu(priv->rxon_timing.beacon_interval),
-                       le32_to_cpu(priv->rxon_timing.beacon_init_val),
-                       le16_to_cpu(priv->rxon_timing.atim_window));
-}
-
 /******************************************************************************
  *
  * Generic RX handler implementations
@@ -720,34 +645,20 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
                iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
                            CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
 
-               if (!iwl_grab_nic_access(priv)) {
-                       iwl_write_direct32(
-                               priv, HBUS_TARG_MBX_C,
-                               HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
-
-                       iwl_release_nic_access(priv);
-               }
+               iwl_write_direct32(priv, HBUS_TARG_MBX_C,
+                                       HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
 
                if (!(flags & RXON_CARD_DISABLED)) {
                        iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
                                    CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
-                       if (!iwl_grab_nic_access(priv)) {
-                               iwl_write_direct32(
-                                       priv, HBUS_TARG_MBX_C,
+                       iwl_write_direct32(priv, HBUS_TARG_MBX_C,
                                        HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
-
-                               iwl_release_nic_access(priv);
-                       }
-               }
-
-               if (flags & RF_CARD_DISABLED) {
-                       iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
-                                   CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
-                       iwl_read32(priv, CSR_UCODE_DRV_GP1);
-                       if (!iwl_grab_nic_access(priv))
-                               iwl_release_nic_access(priv);
                }
+               if (flags & RF_CARD_DISABLED)
+                       iwl_tt_enter_ct_kill(priv);
        }
+       if (!(flags & RF_CARD_DISABLED))
+               iwl_tt_exit_ct_kill(priv);
 
        if (flags & HW_CARD_DISABLED)
                set_bit(STATUS_RF_KILL_HW, &priv->status);
@@ -755,33 +666,19 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
                clear_bit(STATUS_RF_KILL_HW, &priv->status);
 
 
-       if (flags & SW_CARD_DISABLED)
-               set_bit(STATUS_RF_KILL_SW, &priv->status);
-       else
-               clear_bit(STATUS_RF_KILL_SW, &priv->status);
-
        if (!(flags & RXON_CARD_DISABLED))
                iwl_scan_cancel(priv);
 
        if ((test_bit(STATUS_RF_KILL_HW, &status) !=
-            test_bit(STATUS_RF_KILL_HW, &priv->status)) ||
-           (test_bit(STATUS_RF_KILL_SW, &status) !=
-            test_bit(STATUS_RF_KILL_SW, &priv->status)))
-               queue_work(priv->workqueue, &priv->rf_kill);
+            test_bit(STATUS_RF_KILL_HW, &priv->status)))
+               wiphy_rfkill_set_hw_state(priv->hw->wiphy,
+                       test_bit(STATUS_RF_KILL_HW, &priv->status));
        else
                wake_up_interruptible(&priv->wait_command_queue);
 }
 
 int iwl_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
 {
-       int ret;
-       unsigned long flags;
-
-       spin_lock_irqsave(&priv->lock, flags);
-       ret = iwl_grab_nic_access(priv);
-       if (ret)
-               goto err;
-
        if (src == IWL_PWR_SRC_VAUX) {
                if (pci_pme_capable(priv->pci_dev, PCI_D3cold))
                        iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
@@ -793,10 +690,7 @@ int iwl_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
                                       ~APMG_PS_CTRL_MSK_PWR_SRC);
        }
 
-       iwl_release_nic_access(priv);
-err:
-       spin_unlock_irqrestore(&priv->lock, flags);
-       return ret;
+       return 0;
 }
 
 /**
@@ -860,6 +754,7 @@ void iwl_rx_handle(struct iwl_priv *priv)
        unsigned long flags;
        u8 fill_rx = 0;
        u32 count = 8;
+       int total_empty;
 
        /* uCode's read index (stored in shared DRAM) indicates the last Rx
         * buffer that the driver may process (last buffer filled by ucode). */
@@ -870,7 +765,12 @@ void iwl_rx_handle(struct iwl_priv *priv)
        if (i == r)
                IWL_DEBUG_RX(priv, "r = %d, i = %d\n", r, i);
 
-       if (iwl_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2))
+       /* calculate total frames need to be restock after handling RX */
+       total_empty = r - priv->rxq.write_actual;
+       if (total_empty < 0)
+               total_empty += RX_QUEUE_SIZE;
+
+       if (total_empty > (RX_QUEUE_SIZE / 2))
                fill_rx = 1;
 
        while (i != r) {
@@ -883,11 +783,9 @@ void iwl_rx_handle(struct iwl_priv *priv)
 
                rxq->queue[i] = NULL;
 
-               dma_sync_single_range_for_cpu(
-                               &priv->pci_dev->dev, rxb->real_dma_addr,
-                               rxb->aligned_dma_addr - rxb->real_dma_addr,
-                               priv->hw_params.rx_buf_size,
-                               PCI_DMA_FROMDEVICE);
+               pci_unmap_single(priv->pci_dev, rxb->real_dma_addr,
+                                priv->hw_params.rx_buf_size + 256,
+                                PCI_DMA_FROMDEVICE);
                pkt = (struct iwl_rx_packet *)rxb->skb->data;
 
                /* Reclaim a command buffer only if this packet is a response
@@ -911,6 +809,7 @@ void iwl_rx_handle(struct iwl_priv *priv)
                        IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r,
                                i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
                        priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
+                       priv->isr_stats.rx_handlers[pkt->hdr.cmd]++;
                } else {
                        /* No handling needed */
                        IWL_DEBUG_RX(priv,
@@ -938,9 +837,6 @@ void iwl_rx_handle(struct iwl_priv *priv)
                        rxb->skb = NULL;
                }
 
-               pci_unmap_single(priv->pci_dev, rxb->real_dma_addr,
-                                priv->hw_params.rx_buf_size + 256,
-                                PCI_DMA_FROMDEVICE);
                spin_lock_irqsave(&rxq->lock, flags);
                list_add_tail(&rxb->list, &priv->rxq.rx_used);
                spin_unlock_irqrestore(&rxq->lock, flags);
@@ -951,7 +847,7 @@ void iwl_rx_handle(struct iwl_priv *priv)
                        count++;
                        if (count >= 8) {
                                priv->rxq.read = i;
-                               iwl_rx_queue_restock(priv);
+                               iwl_rx_replenish_now(priv);
                                count = 0;
                        }
                }
@@ -959,7 +855,10 @@ void iwl_rx_handle(struct iwl_priv *priv)
 
        /* Backtrack one entry */
        priv->rxq.read = i;
-       iwl_rx_queue_restock(priv);
+       if (fill_rx)
+               iwl_rx_replenish_now(priv);
+       else
+               iwl_rx_queue_restock(priv);
 }
 
 /* call this function to flush any scheduled tasklet */
@@ -970,24 +869,7 @@ static inline void iwl_synchronize_irq(struct iwl_priv *priv)
        tasklet_kill(&priv->irq_tasklet);
 }
 
-static void iwl_error_recovery(struct iwl_priv *priv)
-{
-       unsigned long flags;
-
-       memcpy(&priv->staging_rxon, &priv->recovery_rxon,
-              sizeof(priv->staging_rxon));
-       priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-       iwlcore_commit_rxon(priv);
-
-       iwl_rxon_add_station(priv, priv->bssid, 1);
-
-       spin_lock_irqsave(&priv->lock, flags);
-       priv->assoc_id = le16_to_cpu(priv->staging_rxon.assoc_id);
-       priv->error_recovering = 0;
-       spin_unlock_irqrestore(&priv->lock, flags);
-}
-
-static void iwl_irq_tasklet(struct iwl_priv *priv)
+static void iwl_irq_tasklet_legacy(struct iwl_priv *priv)
 {
        u32 inta, handled = 0;
        u32 inta_fh;
@@ -1011,7 +893,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
        iwl_write32(priv, CSR_FH_INT_STATUS, inta_fh);
 
 #ifdef CONFIG_IWLWIFI_DEBUG
-       if (priv->debug_level & IWL_DL_ISR) {
+       if (iwl_get_debug_level(priv) & IWL_DL_ISR) {
                /* just for debug */
                inta_mask = iwl_read32(priv, CSR_INT_MASK);
                IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
@@ -1030,11 +912,12 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
 
        /* Now service all interrupt bits discovered above. */
        if (inta & CSR_INT_BIT_HW_ERR) {
-               IWL_ERR(priv, "Microcode HW error detected.  Restarting.\n");
+               IWL_ERR(priv, "Hardware error detected.  Restarting.\n");
 
                /* Tell the device to stop sending interrupts */
                iwl_disable_interrupts(priv);
 
+               priv->isr_stats.hw++;
                iwl_irq_handle_error(priv);
 
                handled |= CSR_INT_BIT_HW_ERR;
@@ -1045,15 +928,19 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
        }
 
 #ifdef CONFIG_IWLWIFI_DEBUG
-       if (priv->debug_level & (IWL_DL_ISR)) {
+       if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) {
                /* NIC fires this, but we don't use it, redundant with WAKEUP */
-               if (inta & CSR_INT_BIT_SCD)
+               if (inta & CSR_INT_BIT_SCD) {
                        IWL_DEBUG_ISR(priv, "Scheduler finished to transmit "
                                      "the frame/frames.\n");
+                       priv->isr_stats.sch++;
+               }
 
                /* Alive notification via Rx interrupt will do the real work */
-               if (inta & CSR_INT_BIT_ALIVE)
+               if (inta & CSR_INT_BIT_ALIVE) {
                        IWL_DEBUG_ISR(priv, "Alive interrupt\n");
+                       priv->isr_stats.alive++;
+               }
        }
 #endif
        /* Safely ignore these bits for debug checks below */
@@ -1066,9 +953,11 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
                                CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
                        hw_rf_kill = 1;
 
-               IWL_DEBUG_RF_KILL(priv, "RF_KILL bit toggled to %s.\n",
+               IWL_WARN(priv, "RF_KILL bit toggled to %s.\n",
                                hw_rf_kill ? "disable radio" : "enable radio");
 
+               priv->isr_stats.rfkill++;
+
                /* driver only loads ucode once setting the interface up.
                 * the driver allows loading the ucode even if the radio
                 * is killed. Hence update the killswitch state here. The
@@ -1079,7 +968,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
                                set_bit(STATUS_RF_KILL_HW, &priv->status);
                        else
                                clear_bit(STATUS_RF_KILL_HW, &priv->status);
-                       queue_work(priv->workqueue, &priv->rf_kill);
+                       wiphy_rfkill_set_hw_state(priv->hw->wiphy, hw_rf_kill);
                }
 
                handled |= CSR_INT_BIT_RF_KILL;
@@ -1088,6 +977,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
        /* Chip got too hot and stopped itself */
        if (inta & CSR_INT_BIT_CT_KILL) {
                IWL_ERR(priv, "Microcode CT kill error detected.\n");
+               priv->isr_stats.ctkill++;
                handled |= CSR_INT_BIT_CT_KILL;
        }
 
@@ -1095,6 +985,8 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
        if (inta & CSR_INT_BIT_SW_ERR) {
                IWL_ERR(priv, "Microcode SW error detected. "
                        " Restarting 0x%X.\n", inta);
+               priv->isr_stats.sw++;
+               priv->isr_stats.sw_err = inta;
                iwl_irq_handle_error(priv);
                handled |= CSR_INT_BIT_SW_ERR;
        }
@@ -1110,6 +1002,8 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
                iwl_txq_update_write_ptr(priv, &priv->txq[4]);
                iwl_txq_update_write_ptr(priv, &priv->txq[5]);
 
+               priv->isr_stats.wakeup++;
+
                handled |= CSR_INT_BIT_WAKEUP;
        }
 
@@ -1118,23 +1012,27 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
         * notifications from uCode come through here*/
        if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) {
                iwl_rx_handle(priv);
+               priv->isr_stats.rx++;
                handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX);
        }
 
        if (inta & CSR_INT_BIT_FH_TX) {
                IWL_DEBUG_ISR(priv, "Tx interrupt\n");
+               priv->isr_stats.tx++;
                handled |= CSR_INT_BIT_FH_TX;
                /* FH finished to write, send event */
                priv->ucode_write_complete = 1;
                wake_up_interruptible(&priv->wait_command_queue);
        }
 
-       if (inta & ~handled)
+       if (inta & ~handled) {
                IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled);
+               priv->isr_stats.unhandled++;
+       }
 
-       if (inta & ~CSR_INI_SET_MASK) {
+       if (inta & ~(priv->inta_mask)) {
                IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n",
-                        inta & ~CSR_INI_SET_MASK);
+                        inta & ~priv->inta_mask);
                IWL_WARN(priv, "   with FH_INT = 0x%08x\n", inta_fh);
        }
 
@@ -1144,7 +1042,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
                iwl_enable_interrupts(priv);
 
 #ifdef CONFIG_IWLWIFI_DEBUG
-       if (priv->debug_level & (IWL_DL_ISR)) {
+       if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) {
                inta = iwl_read32(priv, CSR_INT);
                inta_mask = iwl_read32(priv, CSR_INT_MASK);
                inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
@@ -1155,6 +1053,200 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
        spin_unlock_irqrestore(&priv->lock, flags);
 }
 
+/* tasklet for iwlagn interrupt */
+static void iwl_irq_tasklet(struct iwl_priv *priv)
+{
+       u32 inta = 0;
+       u32 handled = 0;
+       unsigned long flags;
+#ifdef CONFIG_IWLWIFI_DEBUG
+       u32 inta_mask;
+#endif
+
+       spin_lock_irqsave(&priv->lock, flags);
+
+       /* Ack/clear/reset pending uCode interrupts.
+        * Note:  Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS,
+        */
+       iwl_write32(priv, CSR_INT, priv->inta);
+
+       inta = priv->inta;
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+       if (iwl_get_debug_level(priv) & IWL_DL_ISR) {
+               /* just for debug */
+               inta_mask = iwl_read32(priv, CSR_INT_MASK);
+               IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x\n ",
+                               inta, inta_mask);
+       }
+#endif
+       /* saved interrupt in inta variable now we can reset priv->inta */
+       priv->inta = 0;
+
+       /* Now service all interrupt bits discovered above. */
+       if (inta & CSR_INT_BIT_HW_ERR) {
+               IWL_ERR(priv, "Hardware error detected.  Restarting.\n");
+
+               /* Tell the device to stop sending interrupts */
+               iwl_disable_interrupts(priv);
+
+               priv->isr_stats.hw++;
+               iwl_irq_handle_error(priv);
+
+               handled |= CSR_INT_BIT_HW_ERR;
+
+               spin_unlock_irqrestore(&priv->lock, flags);
+
+               return;
+       }
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+       if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) {
+               /* NIC fires this, but we don't use it, redundant with WAKEUP */
+               if (inta & CSR_INT_BIT_SCD) {
+                       IWL_DEBUG_ISR(priv, "Scheduler finished to transmit "
+                                     "the frame/frames.\n");
+                       priv->isr_stats.sch++;
+               }
+
+               /* Alive notification via Rx interrupt will do the real work */
+               if (inta & CSR_INT_BIT_ALIVE) {
+                       IWL_DEBUG_ISR(priv, "Alive interrupt\n");
+                       priv->isr_stats.alive++;
+               }
+       }
+#endif
+       /* Safely ignore these bits for debug checks below */
+       inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE);
+
+       /* HW RF KILL switch toggled */
+       if (inta & CSR_INT_BIT_RF_KILL) {
+               int hw_rf_kill = 0;
+               if (!(iwl_read32(priv, CSR_GP_CNTRL) &
+                               CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
+                       hw_rf_kill = 1;
+
+               IWL_WARN(priv, "RF_KILL bit toggled to %s.\n",
+                               hw_rf_kill ? "disable radio" : "enable radio");
+
+               priv->isr_stats.rfkill++;
+
+               /* driver only loads ucode once setting the interface up.
+                * the driver allows loading the ucode even if the radio
+                * is killed. Hence update the killswitch state here. The
+                * rfkill handler will care about restarting if needed.
+                */
+               if (!test_bit(STATUS_ALIVE, &priv->status)) {
+                       if (hw_rf_kill)
+                               set_bit(STATUS_RF_KILL_HW, &priv->status);
+                       else
+                               clear_bit(STATUS_RF_KILL_HW, &priv->status);
+                       wiphy_rfkill_set_hw_state(priv->hw->wiphy, hw_rf_kill);
+               }
+
+               handled |= CSR_INT_BIT_RF_KILL;
+       }
+
+       /* Chip got too hot and stopped itself */
+       if (inta & CSR_INT_BIT_CT_KILL) {
+               IWL_ERR(priv, "Microcode CT kill error detected.\n");
+               priv->isr_stats.ctkill++;
+               handled |= CSR_INT_BIT_CT_KILL;
+       }
+
+       /* Error detected by uCode */
+       if (inta & CSR_INT_BIT_SW_ERR) {
+               IWL_ERR(priv, "Microcode SW error detected. "
+                       " Restarting 0x%X.\n", inta);
+               priv->isr_stats.sw++;
+               priv->isr_stats.sw_err = inta;
+               iwl_irq_handle_error(priv);
+               handled |= CSR_INT_BIT_SW_ERR;
+       }
+
+       /* uCode wakes up after power-down sleep */
+       if (inta & CSR_INT_BIT_WAKEUP) {
+               IWL_DEBUG_ISR(priv, "Wakeup interrupt\n");
+               iwl_rx_queue_update_write_ptr(priv, &priv->rxq);
+               iwl_txq_update_write_ptr(priv, &priv->txq[0]);
+               iwl_txq_update_write_ptr(priv, &priv->txq[1]);
+               iwl_txq_update_write_ptr(priv, &priv->txq[2]);
+               iwl_txq_update_write_ptr(priv, &priv->txq[3]);
+               iwl_txq_update_write_ptr(priv, &priv->txq[4]);
+               iwl_txq_update_write_ptr(priv, &priv->txq[5]);
+
+               priv->isr_stats.wakeup++;
+
+               handled |= CSR_INT_BIT_WAKEUP;
+       }
+
+       /* All uCode command responses, including Tx command responses,
+        * Rx "responses" (frame-received notification), and other
+        * notifications from uCode come through here*/
+       if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX |
+                       CSR_INT_BIT_RX_PERIODIC)) {
+               IWL_DEBUG_ISR(priv, "Rx interrupt\n");
+               if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) {
+                       handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX);
+                       iwl_write32(priv, CSR_FH_INT_STATUS,
+                                       CSR49_FH_INT_RX_MASK);
+               }
+               if (inta & CSR_INT_BIT_RX_PERIODIC) {
+                       handled |= CSR_INT_BIT_RX_PERIODIC;
+                       iwl_write32(priv, CSR_INT, CSR_INT_BIT_RX_PERIODIC);
+               }
+               /* Sending RX interrupt require many steps to be done in the
+                * the device:
+                * 1- write interrupt to current index in ICT table.
+                * 2- dma RX frame.
+                * 3- update RX shared data to indicate last write index.
+                * 4- send interrupt.
+                * This could lead to RX race, driver could receive RX interrupt
+                * but the shared data changes does not reflect this.
+                * this could lead to RX race, RX periodic will solve this race
+                */
+               iwl_write32(priv, CSR_INT_PERIODIC_REG,
+                           CSR_INT_PERIODIC_DIS);
+               iwl_rx_handle(priv);
+               /* Only set RX periodic if real RX is received. */
+               if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX))
+                       iwl_write32(priv, CSR_INT_PERIODIC_REG,
+                                   CSR_INT_PERIODIC_ENA);
+
+               priv->isr_stats.rx++;
+       }
+
+       if (inta & CSR_INT_BIT_FH_TX) {
+               iwl_write32(priv, CSR_FH_INT_STATUS, CSR49_FH_INT_TX_MASK);
+               IWL_DEBUG_ISR(priv, "Tx interrupt\n");
+               priv->isr_stats.tx++;
+               handled |= CSR_INT_BIT_FH_TX;
+               /* FH finished to write, send event */
+               priv->ucode_write_complete = 1;
+               wake_up_interruptible(&priv->wait_command_queue);
+       }
+
+       if (inta & ~handled) {
+               IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled);
+               priv->isr_stats.unhandled++;
+       }
+
+       if (inta & ~(priv->inta_mask)) {
+               IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n",
+                        inta & ~priv->inta_mask);
+       }
+
+
+       /* Re-enable all interrupts */
+       /* only Re-enable if diabled by irq */
+       if (test_bit(STATUS_INT_ENABLED, &priv->status))
+               iwl_enable_interrupts(priv);
+
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+}
+
+
 /******************************************************************************
  *
  * uCode download functions
@@ -1185,7 +1277,7 @@ static void iwl_nic_start(struct iwl_priv *priv)
  */
 static int iwl_read_ucode(struct iwl_priv *priv)
 {
-       struct iwl_ucode *ucode;
+       struct iwl_ucode_header *ucode;
        int ret = -EINVAL, index;
        const struct firmware *ucode_raw;
        const char *name_pre = priv->cfg->fw_name_pre;
@@ -1194,7 +1286,9 @@ static int iwl_read_ucode(struct iwl_priv *priv)
        char buf[25];
        u8 *src;
        size_t len;
-       u32 api_ver, inst_size, data_size, init_size, init_data_size, boot_size;
+       u32 api_ver, build;
+       u32 inst_size, data_size, init_size, init_data_size, boot_size;
+       u16 eeprom_ver;
 
        /* Ask kernel firmware_class module to get the boot firmware off disk.
         * request_firmware() is synchronous, file is in memory on return. */
@@ -1224,23 +1318,26 @@ static int iwl_read_ucode(struct iwl_priv *priv)
        if (ret < 0)
                goto error;
 
-       /* Make sure that we got at least our header! */
-       if (ucode_raw->size < sizeof(*ucode)) {
+       /* Make sure that we got at least the v1 header! */
+       if (ucode_raw->size < priv->cfg->ops->ucode->get_header_size(1)) {
                IWL_ERR(priv, "File size way too small!\n");
                ret = -EINVAL;
                goto err_release;
        }
 
        /* Data from ucode file:  header followed by uCode images */
-       ucode = (void *)ucode_raw->data;
+       ucode = (struct iwl_ucode_header *)ucode_raw->data;
 
        priv->ucode_ver = le32_to_cpu(ucode->ver);
        api_ver = IWL_UCODE_API(priv->ucode_ver);
-       inst_size = le32_to_cpu(ucode->inst_size);
-       data_size = le32_to_cpu(ucode->data_size);
-       init_size = le32_to_cpu(ucode->init_size);
-       init_data_size = le32_to_cpu(ucode->init_data_size);
-       boot_size = le32_to_cpu(ucode->boot_size);
+       build = priv->cfg->ops->ucode->get_build(ucode, api_ver);
+       inst_size = priv->cfg->ops->ucode->get_inst_size(ucode, api_ver);
+       data_size = priv->cfg->ops->ucode->get_data_size(ucode, api_ver);
+       init_size = priv->cfg->ops->ucode->get_init_size(ucode, api_ver);
+       init_data_size =
+               priv->cfg->ops->ucode->get_init_data_size(ucode, api_ver);
+       boot_size = priv->cfg->ops->ucode->get_boot_size(ucode, api_ver);
+       src = priv->cfg->ops->ucode->get_data(ucode, api_ver);
 
        /* api_ver should match the api version forming part of the
         * firmware filename ... but we don't check for that and only rely
@@ -1266,6 +1363,14 @@ static int iwl_read_ucode(struct iwl_priv *priv)
               IWL_UCODE_API(priv->ucode_ver),
               IWL_UCODE_SERIAL(priv->ucode_ver));
 
+       if (build)
+               IWL_DEBUG_INFO(priv, "Build %u\n", build);
+
+       eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
+       IWL_DEBUG_INFO(priv, "NVM Type: %s, version: 0x%x\n",
+                      (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
+                      ? "OTP" : "EEPROM", eeprom_ver);
+
        IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n",
                       priv->ucode_ver);
        IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %u\n",
@@ -1280,12 +1385,14 @@ static int iwl_read_ucode(struct iwl_priv *priv)
                       boot_size);
 
        /* Verify size of file vs. image size info in file's header */
-       if (ucode_raw->size < sizeof(*ucode) +
+       if (ucode_raw->size !=
+               priv->cfg->ops->ucode->get_header_size(api_ver) +
                inst_size + data_size + init_size +
                init_data_size + boot_size) {
 
-               IWL_DEBUG_INFO(priv, "uCode file size %d too small\n",
-                              (int)ucode_raw->size);
+               IWL_DEBUG_INFO(priv,
+                       "uCode file size %d does not match expected size\n",
+                       (int)ucode_raw->size);
                ret = -EINVAL;
                goto err_release;
        }
@@ -1365,42 +1472,42 @@ static int iwl_read_ucode(struct iwl_priv *priv)
        /* Copy images into buffers for card's bus-master reads ... */
 
        /* Runtime instructions (first block of data in file) */
-       src = &ucode->data[0];
-       len = priv->ucode_code.len;
+       len = inst_size;
        IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode instr len %Zd\n", len);
        memcpy(priv->ucode_code.v_addr, src, len);
+       src += len;
+
        IWL_DEBUG_INFO(priv, "uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n",
                priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr);
 
        /* Runtime data (2nd block)
         * NOTE:  Copy into backup buffer will be done in iwl_up()  */
-       src = &ucode->data[inst_size];
-       len = priv->ucode_data.len;
+       len = data_size;
        IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode data len %Zd\n", len);
        memcpy(priv->ucode_data.v_addr, src, len);
        memcpy(priv->ucode_data_backup.v_addr, src, len);
+       src += len;
 
        /* Initialization instructions (3rd block) */
        if (init_size) {
-               src = &ucode->data[inst_size + data_size];
-               len = priv->ucode_init.len;
+               len = init_size;
                IWL_DEBUG_INFO(priv, "Copying (but not loading) init instr len %Zd\n",
                                len);
                memcpy(priv->ucode_init.v_addr, src, len);
+               src += len;
        }
 
        /* Initialization data (4th block) */
        if (init_data_size) {
-               src = &ucode->data[inst_size + data_size + init_size];
-               len = priv->ucode_init_data.len;
+               len = init_data_size;
                IWL_DEBUG_INFO(priv, "Copying (but not loading) init data len %Zd\n",
                               len);
                memcpy(priv->ucode_init_data.v_addr, src, len);
+               src += len;
        }
 
        /* Bootstrap instructions (5th block) */
-       src = &ucode->data[inst_size + data_size + init_size + init_data_size];
-       len = priv->ucode_boot.len;
+       len = boot_size;
        IWL_DEBUG_INFO(priv, "Copying (but not loading) boot instr len %Zd\n", len);
        memcpy(priv->ucode_boot.v_addr, src, len);
 
@@ -1420,6 +1527,191 @@ static int iwl_read_ucode(struct iwl_priv *priv)
        return ret;
 }
 
+#ifdef CONFIG_IWLWIFI_DEBUG
+static const char *desc_lookup_text[] = {
+       "OK",
+       "FAIL",
+       "BAD_PARAM",
+       "BAD_CHECKSUM",
+       "NMI_INTERRUPT_WDG",
+       "SYSASSERT",
+       "FATAL_ERROR",
+       "BAD_COMMAND",
+       "HW_ERROR_TUNE_LOCK",
+       "HW_ERROR_TEMPERATURE",
+       "ILLEGAL_CHAN_FREQ",
+       "VCC_NOT_STABLE",
+       "FH_ERROR",
+       "NMI_INTERRUPT_HOST",
+       "NMI_INTERRUPT_ACTION_PT",
+       "NMI_INTERRUPT_UNKNOWN",
+       "UCODE_VERSION_MISMATCH",
+       "HW_ERROR_ABS_LOCK",
+       "HW_ERROR_CAL_LOCK_FAIL",
+       "NMI_INTERRUPT_INST_ACTION_PT",
+       "NMI_INTERRUPT_DATA_ACTION_PT",
+       "NMI_TRM_HW_ER",
+       "NMI_INTERRUPT_TRM",
+       "NMI_INTERRUPT_BREAK_POINT"
+       "DEBUG_0",
+       "DEBUG_1",
+       "DEBUG_2",
+       "DEBUG_3",
+       "UNKNOWN"
+};
+
+static const char *desc_lookup(int i)
+{
+       int max = ARRAY_SIZE(desc_lookup_text) - 1;
+
+       if (i < 0 || i > max)
+               i = max;
+
+       return desc_lookup_text[i];
+}
+
+#define ERROR_START_OFFSET  (1 * sizeof(u32))
+#define ERROR_ELEM_SIZE     (7 * sizeof(u32))
+
+void iwl_dump_nic_error_log(struct iwl_priv *priv)
+{
+       u32 data2, line;
+       u32 desc, time, count, base, data1;
+       u32 blink1, blink2, ilink1, ilink2;
+
+       if (priv->ucode_type == UCODE_INIT)
+               base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr);
+       else
+               base = le32_to_cpu(priv->card_alive.error_event_table_ptr);
+
+       if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
+               IWL_ERR(priv, "Not valid error log pointer 0x%08X\n", base);
+               return;
+       }
+
+       count = iwl_read_targ_mem(priv, base);
+
+       if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
+               IWL_ERR(priv, "Start IWL Error Log Dump:\n");
+               IWL_ERR(priv, "Status: 0x%08lX, count: %d\n",
+                       priv->status, count);
+       }
+
+       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_ERR(priv, "Desc                               Time       "
+               "data1      data2      line\n");
+       IWL_ERR(priv, "%-28s (#%02d) %010u 0x%08X 0x%08X %u\n",
+               desc_lookup(desc), desc, time, data1, data2, line);
+       IWL_ERR(priv, "blink1  blink2  ilink1  ilink2\n");
+       IWL_ERR(priv, "0x%05X 0x%05X 0x%05X 0x%05X\n", blink1, blink2,
+               ilink1, ilink2);
+
+}
+
+#define EVENT_START_OFFSET  (4 * sizeof(u32))
+
+/**
+ * iwl_print_event_log - Dump error event log to syslog
+ *
+ */
+static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
+                               u32 num_events, u32 mode)
+{
+       u32 i;
+       u32 base;       /* SRAM byte address of event log header */
+       u32 event_size; /* 2 u32s, or 3 u32s if timestamp recorded */
+       u32 ptr;        /* SRAM byte address of log data */
+       u32 ev, time, data; /* event log data */
+
+       if (num_events == 0)
+               return;
+       if (priv->ucode_type == UCODE_INIT)
+               base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
+       else
+               base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
+
+       if (mode == 0)
+               event_size = 2 * sizeof(u32);
+       else
+               event_size = 3 * sizeof(u32);
+
+       ptr = base + EVENT_START_OFFSET + (start_idx * event_size);
+
+       /* "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 = iwl_read_targ_mem(priv, ptr);
+               ptr += sizeof(u32);
+               time = iwl_read_targ_mem(priv, ptr);
+               ptr += sizeof(u32);
+               if (mode == 0) {
+                       /* data, ev */
+                       IWL_ERR(priv, "EVT_LOG:0x%08x:%04u\n", time, ev);
+               } else {
+                       data = iwl_read_targ_mem(priv, ptr);
+                       ptr += sizeof(u32);
+                       IWL_ERR(priv, "EVT_LOGT:%010u:0x%08x:%04u\n",
+                                       time, data, ev);
+               }
+       }
+}
+
+void iwl_dump_nic_event_log(struct iwl_priv *priv)
+{
+       u32 base;       /* SRAM byte address of event log header */
+       u32 capacity;   /* event log capacity in # entries */
+       u32 mode;       /* 0 - no timestamp, 1 - timestamp recorded */
+       u32 num_wraps;  /* # times uCode wrapped to top of log */
+       u32 next_entry; /* index of next entry to be written by uCode */
+       u32 size;       /* # entries that we'll print */
+
+       if (priv->ucode_type == UCODE_INIT)
+               base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
+       else
+               base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
+
+       if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
+               IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base);
+               return;
+       }
+
+       /* event log header */
+       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_ERR(priv, "Start IWL Event Log Dump: nothing in log\n");
+               return;
+       }
+
+       IWL_ERR(priv, "Start IWL Event Log Dump: display count %d, wraps %d\n",
+                       size, num_wraps);
+
+       /* if uCode has wrapped back to top of log, start at the oldest entry,
+        * i.e the next one that uCode would fill. */
+       if (num_wraps)
+               iwl_print_event_log(priv, next_entry,
+                                       capacity - next_entry, mode);
+       /* (then/else) start at top of log */
+       iwl_print_event_log(priv, 0, next_entry, mode);
+
+}
+#endif
+
 /**
  * iwl_alive_start - called after REPLY_ALIVE notification received
  *                   from protocol/runtime uCode (initialization uCode's
@@ -1448,7 +1740,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
                goto restart;
        }
 
-       priv->cfg->ops->smgmt->clear_station_table(priv);
+       iwl_clear_stations_table(priv);
        ret = priv->cfg->ops->lib->alive_notify(priv);
        if (ret) {
                IWL_WARN(priv,
@@ -1500,10 +1792,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
        set_bit(STATUS_READY, &priv->status);
        wake_up_interruptible(&priv->wait_command_queue);
 
-       if (priv->error_recovering)
-               iwl_error_recovery(priv);
-
-       iwl_power_update_mode(priv, 1);
+       iwl_power_update_mode(priv, true);
 
        /* reassociate for ADHOC mode */
        if (priv->vif && (priv->iw_mode == NL80211_IFTYPE_ADHOC)) {
@@ -1537,7 +1826,7 @@ static void __iwl_down(struct iwl_priv *priv)
 
        iwl_leds_unregister(priv);
 
-       priv->cfg->ops->smgmt->clear_station_table(priv);
+       iwl_clear_stations_table(priv);
 
        /* Unblock any waiting calls */
        wake_up_interruptible_all(&priv->wait_command_queue);
@@ -1560,12 +1849,10 @@ static void __iwl_down(struct iwl_priv *priv)
                ieee80211_stop_queues(priv->hw);
 
        /* If we have not previously called iwl_init() then
-        * clear all bits but the RF Kill bits and return */
+        * clear all bits but the RF Kill bit and return */
        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) <<
-                                       STATUS_RF_KILL_SW |
                               test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
                                        STATUS_GEO_CONFIGURED |
                               test_bit(STATUS_EXIT_PENDING, &priv->status) <<
@@ -1574,11 +1861,9 @@ static void __iwl_down(struct iwl_priv *priv)
        }
 
        /* ...otherwise clear out all the status bits but the RF Kill
-        * bits and continue taking the NIC down. */
+        * bit and continue taking the NIC down. */
        priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) <<
                                STATUS_RF_KILL_HW |
-                       test_bit(STATUS_RF_KILL_SW, &priv->status) <<
-                               STATUS_RF_KILL_SW |
                        test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
                                STATUS_GEO_CONFIGURED |
                        test_bit(STATUS_FW_ERROR, &priv->status) <<
@@ -1586,6 +1871,8 @@ static void __iwl_down(struct iwl_priv *priv)
                       test_bit(STATUS_EXIT_PENDING, &priv->status) <<
                                STATUS_EXIT_PENDING;
 
+       /* device going down, Stop using ICT table */
+       iwl_disable_ict(priv);
        spin_lock_irqsave(&priv->lock, flags);
        iwl_clear_bit(priv, CSR_GP_CNTRL,
                         CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
@@ -1594,13 +1881,8 @@ static void __iwl_down(struct iwl_priv *priv)
        iwl_txq_ctx_stop(priv);
        iwl_rxq_stop(priv);
 
-       spin_lock_irqsave(&priv->lock, flags);
-       if (!iwl_grab_nic_access(priv)) {
-               iwl_write_prph(priv, APMG_CLK_DIS_REG,
-                                        APMG_CLK_VAL_DMA_CLK_RQT);
-               iwl_release_nic_access(priv);
-       }
-       spin_unlock_irqrestore(&priv->lock, flags);
+       iwl_write_prph(priv, APMG_CLK_DIS_REG,
+                               APMG_CLK_VAL_DMA_CLK_RQT);
 
        udelay(5);
 
@@ -1629,6 +1911,55 @@ static void iwl_down(struct iwl_priv *priv)
        iwl_cancel_deferred_work(priv);
 }
 
+#define HW_READY_TIMEOUT (50)
+
+static int iwl_set_hw_ready(struct iwl_priv *priv)
+{
+       int ret = 0;
+
+       iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+               CSR_HW_IF_CONFIG_REG_BIT_NIC_READY);
+
+       /* See if we got it */
+       ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
+                               CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
+                               CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
+                               HW_READY_TIMEOUT);
+       if (ret != -ETIMEDOUT)
+               priv->hw_ready = true;
+       else
+               priv->hw_ready = false;
+
+       IWL_DEBUG_INFO(priv, "hardware %s\n",
+                     (priv->hw_ready == 1) ? "ready" : "not ready");
+       return ret;
+}
+
+static int iwl_prepare_card_hw(struct iwl_priv *priv)
+{
+       int ret = 0;
+
+       IWL_DEBUG_INFO(priv, "iwl_prepare_card_hw enter \n");
+
+       ret = iwl_set_hw_ready(priv);
+       if (priv->hw_ready)
+               return ret;
+
+       /* If HW is not ready, prepare the conditions to check again */
+       iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+                       CSR_HW_IF_CONFIG_REG_PREPARE);
+
+       ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
+                       ~CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE,
+                       CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, 150000);
+
+       /* HW should be ready by now, check again. */
+       if (ret != -ETIMEDOUT)
+               iwl_set_hw_ready(priv);
+
+       return ret;
+}
+
 #define MAX_HW_RESTARTS 5
 
 static int __iwl_up(struct iwl_priv *priv)
@@ -1646,6 +1977,13 @@ static int __iwl_up(struct iwl_priv *priv)
                return -EIO;
        }
 
+       iwl_prepare_card_hw(priv);
+
+       if (!priv->hw_ready) {
+               IWL_WARN(priv, "Exit HW not ready\n");
+               return -EIO;
+       }
+
        /* If platform's RF_KILL switch is NOT set to KILL */
        if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
                clear_bit(STATUS_RF_KILL_HW, &priv->status);
@@ -1653,9 +1991,10 @@ static int __iwl_up(struct iwl_priv *priv)
                set_bit(STATUS_RF_KILL_HW, &priv->status);
 
        if (iwl_is_rfkill(priv)) {
+               wiphy_rfkill_set_hw_state(priv->hw->wiphy, true);
+
                iwl_enable_interrupts(priv);
-               IWL_WARN(priv, "Radio disabled by %s RF Kill switch\n",
-                   test_bit(STATUS_RF_KILL_HW, &priv->status) ? "HW" : "SW");
+               IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n");
                return 0;
        }
 
@@ -1688,7 +2027,7 @@ static int __iwl_up(struct iwl_priv *priv)
 
        for (i = 0; i < MAX_HW_RESTARTS; i++) {
 
-               priv->cfg->ops->smgmt->clear_station_table(priv);
+               iwl_clear_stations_table(priv);
 
                /* load bootstrap state machine,
                 * load bootstrap program into processor's memory,
@@ -1701,9 +2040,6 @@ static int __iwl_up(struct iwl_priv *priv)
                        continue;
                }
 
-               /* Clear out the uCode error bit if it is set */
-               clear_bit(STATUS_FW_ERROR, &priv->status);
-
                /* start card; "initialize" will load runtime ucode */
                iwl_nic_start(priv);
 
@@ -1750,6 +2086,9 @@ static void iwl_bg_alive_start(struct work_struct *data)
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
+       /* enable dram interrupt */
+       iwl_reset_ict(priv);
+
        mutex_lock(&priv->mutex);
        iwl_alive_start(priv);
        mutex_unlock(&priv->mutex);
@@ -1788,7 +2127,6 @@ static void iwl_bg_up(struct work_struct *data)
        mutex_lock(&priv->mutex);
        __iwl_up(priv);
        mutex_unlock(&priv->mutex);
-       iwl_rfkill_set_hw_state(priv);
 }
 
 static void iwl_bg_restart(struct work_struct *data)
@@ -1798,8 +2136,17 @@ static void iwl_bg_restart(struct work_struct *data)
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
-       iwl_down(priv);
-       queue_work(priv->workqueue, &priv->up);
+       if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) {
+               mutex_lock(&priv->mutex);
+               priv->vif = NULL;
+               priv->is_open = 0;
+               mutex_unlock(&priv->mutex);
+               iwl_down(priv);
+               ieee80211_restart_hw(priv->hw);
+       } else {
+               iwl_down(priv);
+               queue_work(priv->workqueue, &priv->up);
+       }
 }
 
 static void iwl_bg_rx_replenish(struct work_struct *data)
@@ -1839,7 +2186,6 @@ void iwl_post_associate(struct iwl_priv *priv)
        if (!priv->vif || !priv->is_open)
                return;
 
-       iwl_power_cancel_timeout(priv);
        iwl_scan_cancel_timeout(priv, 200);
 
        conf = ieee80211_get_hw_conf(priv->hw);
@@ -1915,7 +2261,7 @@ void iwl_post_associate(struct iwl_priv *priv)
         * If chain noise has already been run, then we need to enable
         * power management here */
        if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE)
-               iwl_power_enable_management(priv);
+               iwl_power_update_mode(priv, false);
 
        /* Enable Rx differential gain and sensitivity calibrations */
        iwl_chain_noise_reset(priv);
@@ -1941,7 +2287,6 @@ static int iwl_mac_start(struct ieee80211_hw *hw)
        /* we should be verifying the device is ready to be opened */
        mutex_lock(&priv->mutex);
 
-       memset(&priv->staging_rxon, 0, sizeof(struct iwl_rxon_cmd));
        /* fetch ucode file from disk, alloc and copy to bus-master buffers ...
         * ucode filename and max sizes are card-specific. */
 
@@ -1958,8 +2303,6 @@ static int iwl_mac_start(struct ieee80211_hw *hw)
 
        mutex_unlock(&priv->mutex);
 
-       iwl_rfkill_set_hw_state(priv);
-
        if (ret)
                return ret;
 
@@ -1993,14 +2336,12 @@ static void iwl_mac_stop(struct ieee80211_hw *hw)
 
        IWL_DEBUG_MAC80211(priv, "enter\n");
 
-       if (!priv->is_open) {
-               IWL_DEBUG_MAC80211(priv, "leave - skip\n");
+       if (!priv->is_open)
                return;
-       }
 
        priv->is_open = 0;
 
-       if (iwl_is_ready_rf(priv)) {
+       if (iwl_is_ready_rf(priv) || test_bit(STATUS_SCAN_HW, &priv->status)) {
                /* stop mac, cancel any scan request and clear
                 * RXON_FILTER_ASSOC_MSK BIT
                 */
@@ -2125,12 +2466,12 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 
        IWL_DEBUG_MAC80211(priv, "enter\n");
 
-       if (priv->hw_params.sw_crypto) {
+       if (priv->cfg->mod_params->sw_crypto) {
                IWL_DEBUG_MAC80211(priv, "leave - hwcrypto disabled\n");
                return -EOPNOTSUPP;
        }
        addr = sta ? sta->addr : iwl_bcast_addr;
-       sta_id = priv->cfg->ops->smgmt->find_station(priv, addr);
+       sta_id = iwl_find_station(priv, addr);
        if (sta_id == IWL_INVALID_STATION) {
                IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n",
                                   addr);
@@ -2235,81 +2576,6 @@ static int iwl_mac_get_stats(struct ieee80211_hw *hw,
        return 0;
 }
 
-static void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
-{
-       struct iwl_priv *priv = hw->priv;
-       unsigned long flags;
-
-       mutex_lock(&priv->mutex);
-       IWL_DEBUG_MAC80211(priv, "enter\n");
-
-       spin_lock_irqsave(&priv->lock, flags);
-       memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info));
-       spin_unlock_irqrestore(&priv->lock, flags);
-
-       iwl_reset_qos(priv);
-
-       spin_lock_irqsave(&priv->lock, flags);
-       priv->assoc_id = 0;
-       priv->assoc_capability = 0;
-       priv->assoc_station_added = 0;
-
-       /* new association get rid of ibss beacon skb */
-       if (priv->ibss_beacon)
-               dev_kfree_skb(priv->ibss_beacon);
-
-       priv->ibss_beacon = NULL;
-
-       priv->beacon_int = priv->hw->conf.beacon_int;
-       priv->timestamp = 0;
-       if ((priv->iw_mode == NL80211_IFTYPE_STATION))
-               priv->beacon_int = 0;
-
-       spin_unlock_irqrestore(&priv->lock, flags);
-
-       if (!iwl_is_ready_rf(priv)) {
-               IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
-               mutex_unlock(&priv->mutex);
-               return;
-       }
-
-       /* we are restarting association process
-        * clear RXON_FILTER_ASSOC_MSK bit
-        */
-       if (priv->iw_mode != NL80211_IFTYPE_AP) {
-               iwl_scan_cancel_timeout(priv, 100);
-               priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-               iwlcore_commit_rxon(priv);
-       }
-
-       iwl_power_update_mode(priv, 0);
-
-       /* Per mac80211.h: This is only used in IBSS mode... */
-       if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
-
-               /* switch to CAM during association period.
-                * the ucode will block any association/authentication
-                * frome during assiciation period if it can not hear
-                * the AP because of PM. the timer enable PM back is
-                * association do not complete
-                */
-               if (priv->hw->conf.channel->flags & (IEEE80211_CHAN_PASSIVE_SCAN |
-                                                    IEEE80211_CHAN_RADAR))
-                               iwl_power_disable_management(priv, 3000);
-
-               IWL_DEBUG_MAC80211(priv, "leave - not in IBSS\n");
-               mutex_unlock(&priv->mutex);
-               return;
-       }
-
-       iwl_set_rate(priv);
-
-       mutex_unlock(&priv->mutex);
-
-       IWL_DEBUG_MAC80211(priv, "leave\n");
-}
-
-
 /*****************************************************************************
  *
  * sysfs attributes
@@ -2324,29 +2590,34 @@ static void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
  * used for controlling the debug level.
  *
  * See the level definitions in iwl for details.
+ *
+ * The debug_level being managed using sysfs below is a per device debug
+ * level that is used instead of the global debug level if it (the per
+ * device debug level) is set.
  */
-
 static ssize_t show_debug_level(struct device *d,
                                struct device_attribute *attr, char *buf)
 {
-       struct iwl_priv *priv = d->driver_data;
-
-       return sprintf(buf, "0x%08X\n", priv->debug_level);
+       struct iwl_priv *priv = dev_get_drvdata(d);
+       return sprintf(buf, "0x%08X\n", iwl_get_debug_level(priv));
 }
 static ssize_t store_debug_level(struct device *d,
                                struct device_attribute *attr,
                                 const char *buf, size_t count)
 {
-       struct iwl_priv *priv = d->driver_data;
+       struct iwl_priv *priv = dev_get_drvdata(d);
        unsigned long val;
        int ret;
 
        ret = strict_strtoul(buf, 0, &val);
        if (ret)
                IWL_ERR(priv, "%s is not in hex or decimal form.\n", buf);
-       else
+       else {
                priv->debug_level = val;
-
+               if (iwl_alloc_traffic_mem(priv))
+                       IWL_ERR(priv,
+                               "Not enough memory to generate traffic log\n");
+       }
        return strnlen(buf, count);
 }
 
@@ -2357,41 +2628,10 @@ static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO,
 #endif /* CONFIG_IWLWIFI_DEBUG */
 
 
-static ssize_t show_version(struct device *d,
-                               struct device_attribute *attr, char *buf)
-{
-       struct iwl_priv *priv = d->driver_data;
-       struct iwl_alive_resp *palive = &priv->card_alive;
-       ssize_t pos = 0;
-       u16 eeprom_ver;
-
-       if (palive->is_valid)
-               pos += sprintf(buf + pos,
-                               "fw version: 0x%01X.0x%01X.0x%01X.0x%01X\n"
-                               "fw type: 0x%01X 0x%01X\n",
-                               palive->ucode_major, palive->ucode_minor,
-                               palive->sw_rev[0], palive->sw_rev[1],
-                               palive->ver_type, palive->ver_subtype);
-       else
-               pos += sprintf(buf + pos, "fw not loaded\n");
-
-       if (priv->eeprom) {
-               eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
-               pos += sprintf(buf + pos, "EEPROM version: 0x%x\n",
-                                eeprom_ver);
-       } else {
-               pos += sprintf(buf + pos, "EEPROM not initialzed\n");
-       }
-
-       return pos;
-}
-
-static DEVICE_ATTR(version, S_IWUSR | S_IRUGO, show_version, NULL);
-
 static ssize_t show_temperature(struct device *d,
                                struct device_attribute *attr, char *buf)
 {
-       struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+       struct iwl_priv *priv = dev_get_drvdata(d);
 
        if (!iwl_is_alive(priv))
                return -EAGAIN;
@@ -2404,7 +2644,7 @@ static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL);
 static ssize_t show_tx_power(struct device *d,
                             struct device_attribute *attr, char *buf)
 {
-       struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+       struct iwl_priv *priv = dev_get_drvdata(d);
 
        if (!iwl_is_ready_rf(priv))
                return sprintf(buf, "off\n");
@@ -2416,17 +2656,22 @@ static ssize_t store_tx_power(struct device *d,
                              struct device_attribute *attr,
                              const char *buf, size_t count)
 {
-       struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+       struct iwl_priv *priv = dev_get_drvdata(d);
        unsigned long val;
        int ret;
 
        ret = strict_strtoul(buf, 10, &val);
        if (ret)
                IWL_INFO(priv, "%s is not in decimal form.\n", buf);
-       else
-               iwl_set_tx_power(priv, val, false);
-
-       return count;
+       else {
+               ret = iwl_set_tx_power(priv, val, false);
+               if (ret)
+                       IWL_ERR(priv, "failed setting tx power (0x%d).\n",
+                               ret);
+               else
+                       ret = count;
+       }
+       return ret;
 }
 
 static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power);
@@ -2434,7 +2679,7 @@ static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power);
 static ssize_t show_flags(struct device *d,
                          struct device_attribute *attr, char *buf)
 {
-       struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+       struct iwl_priv *priv = dev_get_drvdata(d);
 
        return sprintf(buf, "0x%04X\n", priv->active_rxon.flags);
 }
@@ -2443,7 +2688,7 @@ static ssize_t store_flags(struct device *d,
                           struct device_attribute *attr,
                           const char *buf, size_t count)
 {
-       struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+       struct iwl_priv *priv = dev_get_drvdata(d);
        unsigned long val;
        u32 flags;
        int ret = strict_strtoul(buf, 0, &val);
@@ -2472,7 +2717,7 @@ static DEVICE_ATTR(flags, S_IWUSR | S_IRUGO, show_flags, store_flags);
 static ssize_t show_filter_flags(struct device *d,
                                 struct device_attribute *attr, char *buf)
 {
-       struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+       struct iwl_priv *priv = dev_get_drvdata(d);
 
        return sprintf(buf, "0x%04X\n",
                le32_to_cpu(priv->active_rxon.filter_flags));
@@ -2482,7 +2727,7 @@ static ssize_t store_filter_flags(struct device *d,
                                  struct device_attribute *attr,
                                  const char *buf, size_t count)
 {
-       struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+       struct iwl_priv *priv = dev_get_drvdata(d);
        unsigned long val;
        u32 filter_flags;
        int ret = strict_strtoul(buf, 0, &val);
@@ -2511,64 +2756,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 store_power_level(struct device *d,
-                                struct device_attribute *attr,
-                                const char *buf, size_t count)
-{
-       struct iwl_priv *priv = dev_get_drvdata(d);
-       int ret;
-       unsigned long mode;
-
-
-       mutex_lock(&priv->mutex);
-
-       ret = strict_strtoul(buf, 10, &mode);
-       if (ret)
-               goto out;
-
-       ret = iwl_power_set_user_mode(priv, mode);
-       if (ret) {
-               IWL_DEBUG_MAC80211(priv, "failed setting power mode.\n");
-               goto out;
-       }
-       ret = count;
-
- out:
-       mutex_unlock(&priv->mutex);
-       return ret;
-}
-
-static ssize_t show_power_level(struct device *d,
-                               struct device_attribute *attr, char *buf)
-{
-       struct iwl_priv *priv = dev_get_drvdata(d);
-       int mode = priv->power_data.user_power_setting;
-       int system = priv->power_data.system_power_setting;
-       int level = priv->power_data.power_mode;
-       char *p = buf;
-
-       switch (system) {
-       case IWL_POWER_SYS_AUTO:
-               p += sprintf(p, "SYSTEM:auto");
-               break;
-       case IWL_POWER_SYS_AC:
-               p += sprintf(p, "SYSTEM:ac");
-               break;
-       case IWL_POWER_SYS_BATTERY:
-               p += sprintf(p, "SYSTEM:battery");
-               break;
-       }
-
-       p += sprintf(p, "\tMODE:%s", (mode < IWL_POWER_AUTO) ?
-                       "fixed" : "auto");
-       p += sprintf(p, "\tINDEX:%d", level);
-       p += sprintf(p, "\n");
-       return p - buf + 1;
-}
-
-static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level,
-                  store_power_level);
-
 
 static ssize_t show_statistics(struct device *d,
                               struct device_attribute *attr, char *buf)
@@ -2624,14 +2811,12 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
        INIT_WORK(&priv->up, iwl_bg_up);
        INIT_WORK(&priv->restart, iwl_bg_restart);
        INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish);
-       INIT_WORK(&priv->rf_kill, iwl_bg_rf_kill);
        INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update);
        INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work);
        INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start);
        INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start);
 
        iwl_setup_scan_deferred_work(priv);
-       iwl_setup_power_deferred_work(priv);
 
        if (priv->cfg->ops->lib->setup_deferred_work)
                priv->cfg->ops->lib->setup_deferred_work(priv);
@@ -2640,8 +2825,12 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
        priv->statistics_periodic.data = (unsigned long)priv;
        priv->statistics_periodic.function = iwl_bg_statistics_periodic;
 
-       tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
-                    iwl_irq_tasklet, (unsigned long)priv);
+       if (!priv->cfg->use_isr_legacy)
+               tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
+                       iwl_irq_tasklet, (unsigned long)priv);
+       else
+               tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
+                       iwl_irq_tasklet_legacy, (unsigned long)priv);
 }
 
 static void iwl_cancel_deferred_work(struct iwl_priv *priv)
@@ -2651,7 +2840,6 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
 
        cancel_delayed_work_sync(&priv->init_alive_start);
        cancel_delayed_work(&priv->scan_check);
-       cancel_delayed_work_sync(&priv->set_power_save);
        cancel_delayed_work(&priv->alive_start);
        cancel_work_sync(&priv->beacon_update);
        del_timer_sync(&priv->statistics_periodic);
@@ -2660,15 +2848,12 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
 static struct attribute *iwl_sysfs_entries[] = {
        &dev_attr_flags.attr,
        &dev_attr_filter_flags.attr,
-       &dev_attr_power_level.attr,
        &dev_attr_statistics.attr,
        &dev_attr_temperature.attr,
        &dev_attr_tx_power.attr,
 #ifdef CONFIG_IWLWIFI_DEBUG
        &dev_attr_debug_level.attr,
 #endif
-       &dev_attr_version.attr,
-
        NULL
 };
 
@@ -2684,7 +2869,6 @@ static struct ieee80211_ops iwl_hw_ops = {
        .add_interface = iwl_mac_add_interface,
        .remove_interface = iwl_mac_remove_interface,
        .config = iwl_mac_config,
-       .config_interface = iwl_mac_config_interface,
        .configure_filter = iwl_configure_filter,
        .set_key = iwl_mac_set_key,
        .update_tkip_key = iwl_mac_update_tkip_key,
@@ -2713,7 +2897,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        /* Disabling hardware scan means that mac80211 will perform scans
         * "the hard way", rather than using device's scan. */
        if (cfg->mod_params->disable_hw_scan) {
-               if (cfg->mod_params->debug & IWL_DL_INFO)
+               if (iwl_debug_level & IWL_DL_INFO)
                        dev_printk(KERN_DEBUG, &(pdev->dev),
                                   "Disabling hw_scan\n");
                iwl_hw_ops.hw_scan = NULL;
@@ -2732,11 +2916,13 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n");
        priv->cfg = cfg;
        priv->pci_dev = pdev;
+       priv->inta_mask = CSR_INI_SET_MASK;
 
 #ifdef CONFIG_IWLWIFI_DEBUG
-       priv->debug_level = priv->cfg->mod_params->debug;
        atomic_set(&priv->restrict_refcnt, 0);
 #endif
+       if (iwl_alloc_traffic_mem(priv))
+               IWL_ERR(priv, "Not enough memory to generate traffic log\n");
 
        /**************************
         * 2. Initializing PCI bus
@@ -2782,6 +2968,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                (unsigned long long) pci_resource_len(pdev, 0));
        IWL_DEBUG_INFO(priv, "pci_resource_base = %p\n", priv->hw_base);
 
+       /* this spin lock will be used in apm_ops.init and EEPROM access
+        * we should init now
+        */
+       spin_lock_init(&priv->reg_lock);
        iwl_hw_detect(priv);
        IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s REV=0x%X\n",
                priv->cfg->name, priv->hw_rev);
@@ -2790,6 +2980,12 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
         * PCI Tx retries from interfering with C3 CPU state */
        pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
 
+       iwl_prepare_card_hw(priv);
+       if (!priv->hw_ready) {
+               IWL_WARN(priv, "Failed, HW not ready\n");
+               goto out_iounmap;
+       }
+
        /* amp init */
        err = priv->cfg->ops->lib->apm_ops.init(priv);
        if (err < 0) {
@@ -2831,18 +3027,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                goto out_free_eeprom;
        /* At this point both hw and priv are initialized. */
 
-       /**********************************
-        * 7. Initialize module parameters
-        **********************************/
-
-       /* Disable radio (SW RF KILL) via parameter when loading driver */
-       if (priv->cfg->mod_params->disable) {
-               set_bit(STATUS_RF_KILL_SW, &priv->status);
-               IWL_DEBUG_INFO(priv, "Radio disabled.\n");
-       }
-
        /********************
-        * 8. Setup services
+        * 7. Setup services
         ********************/
        spin_lock_irqsave(&priv->lock, flags);
        iwl_disable_interrupts(priv);
@@ -2850,8 +3036,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        pci_enable_msi(priv->pci_dev);
 
-       err = request_irq(priv->pci_dev->irq, iwl_isr, IRQF_SHARED,
-                         DRV_NAME, priv);
+       iwl_alloc_isr_ict(priv);
+       err = request_irq(priv->pci_dev->irq, priv->cfg->ops->lib->isr,
+                         IRQF_SHARED, DRV_NAME, priv);
        if (err) {
                IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq);
                goto out_disable_msi;
@@ -2866,7 +3053,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        iwl_setup_rx_handlers(priv);
 
        /**********************************
-        * 9. Setup and register mac80211
+        * 8. Setup and register mac80211
         **********************************/
 
        /* enable interrupts if needed: hw bug w/a */
@@ -2884,7 +3071,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        err = iwl_dbgfs_register(priv, DRV_NAME);
        if (err)
-               IWL_ERR(priv, "failed to create debugfs files\n");
+               IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
 
        /* If platform's RF_KILL switch is NOT set to KILL */
        if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
@@ -2892,14 +3079,11 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        else
                set_bit(STATUS_RF_KILL_HW, &priv->status);
 
-       err = iwl_rfkill_init(priv);
-       if (err)
-               IWL_ERR(priv, "Unable to initialize RFKILL system. "
-                                 "Ignoring error: %d\n", err);
-       else
-               iwl_rfkill_set_hw_state(priv);
+       wiphy_rfkill_set_hw_state(priv->hw->wiphy,
+               test_bit(STATUS_RF_KILL_HW, &priv->status));
 
        iwl_power_initialize(priv);
+       iwl_tt_initialize(priv);
        return 0;
 
  out_remove_sysfs:
@@ -2908,6 +3092,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        sysfs_remove_group(&pdev->dev.kobj, &iwl_attribute_group);
  out_free_irq:
        free_irq(priv->pci_dev->irq, priv);
+       iwl_free_isr_ict(priv);
  out_disable_msi:
        pci_disable_msi(priv->pci_dev);
        iwl_uninit_drv(priv);
@@ -2922,6 +3107,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        pci_disable_device(pdev);
  out_ieee80211_free_hw:
        ieee80211_free_hw(priv->hw);
+       iwl_free_traffic_mem(priv);
  out:
        return err;
 }
@@ -2951,6 +3137,8 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
                iwl_down(priv);
        }
 
+       iwl_tt_exit(priv);
+
        /* make sure we flush any pending irq or
         * tasklet for the driver
         */
@@ -2960,14 +3148,13 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
 
        iwl_synchronize_irq(priv);
 
-       iwl_rfkill_unregister(priv);
        iwl_dealloc_ucode_pci(priv);
 
        if (priv->rxq.bd)
                iwl_rx_queue_free(priv, &priv->rxq);
        iwl_hw_txq_ctx_free(priv);
 
-       priv->cfg->ops->smgmt->clear_station_table(priv);
+       iwl_clear_stations_table(priv);
        iwl_eeprom_free(priv);
 
 
@@ -2979,6 +3166,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
         * until now... */
        destroy_workqueue(priv->workqueue);
        priv->workqueue = NULL;
+       iwl_free_traffic_mem(priv);
 
        free_irq(priv->pci_dev->irq, priv);
        pci_disable_msi(priv->pci_dev);
@@ -2989,6 +3177,8 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
 
        iwl_uninit_drv(priv);
 
+       iwl_free_isr_ict(priv);
+
        if (priv->ibss_beacon)
                dev_kfree_skb(priv->ibss_beacon);
 
@@ -3027,13 +3217,12 @@ static struct pci_device_id iwl_hw_card_ids[] = {
        {IWL_PCI_DEVICE(0x423C, PCI_ANY_ID, iwl5150_agn_cfg)},
        {IWL_PCI_DEVICE(0x423D, PCI_ANY_ID, iwl5150_agn_cfg)},
 /* 6000/6050 Series */
-       {IWL_PCI_DEVICE(0x0082, 0x1102, iwl6000_2ag_cfg)},
-       {IWL_PCI_DEVICE(0x0085, 0x1112, iwl6000_2ag_cfg)},
-       {IWL_PCI_DEVICE(0x0082, 0x1122, iwl6000_2ag_cfg)},
+       {IWL_PCI_DEVICE(0x008D, PCI_ANY_ID, iwl6000h_2agn_cfg)},
+       {IWL_PCI_DEVICE(0x008E, PCI_ANY_ID, iwl6000h_2agn_cfg)},
        {IWL_PCI_DEVICE(0x422B, PCI_ANY_ID, iwl6000_3agn_cfg)},
+       {IWL_PCI_DEVICE(0x422C, PCI_ANY_ID, iwl6000i_2agn_cfg)},
        {IWL_PCI_DEVICE(0x4238, PCI_ANY_ID, iwl6000_3agn_cfg)},
-       {IWL_PCI_DEVICE(0x0082, PCI_ANY_ID, iwl6000_2agn_cfg)},
-       {IWL_PCI_DEVICE(0x0085, PCI_ANY_ID, iwl6000_3agn_cfg)},
+       {IWL_PCI_DEVICE(0x4239, PCI_ANY_ID, iwl6000i_2agn_cfg)},
        {IWL_PCI_DEVICE(0x0086, PCI_ANY_ID, iwl6050_3agn_cfg)},
        {IWL_PCI_DEVICE(0x0087, PCI_ANY_ID, iwl6050_2agn_cfg)},
        {IWL_PCI_DEVICE(0x0088, PCI_ANY_ID, iwl6050_3agn_cfg)},
@@ -3093,3 +3282,11 @@ static void __exit iwl_exit(void)
 
 module_exit(iwl_exit);
 module_init(iwl_init);
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+module_param_named(debug50, iwl_debug_level, uint, 0444);
+MODULE_PARM_DESC(debug50, "50XX debug output mask (deprecated)");
+module_param_named(debug, iwl_debug_level, uint, 0644);
+MODULE_PARM_DESC(debug, "debug output mask");
+#endif
+