]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
iwlwifi: remove shadow_reg_enable from hw_params
[karo-tx-linux.git] / drivers / net / wireless / iwlwifi / iwl-trans-pcie.c
index 1030a2524059f74aa760b5f6462dbe6f35c5741f..44050fa414d1d44e8a09d5483cee378dca9432b2 100644 (file)
@@ -77,6 +77,8 @@
 #include "iwl-agn-hw.h"
 #include "iwl-core.h"
 
+#define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo))))
+
 static int iwl_trans_rx_alloc(struct iwl_trans *trans)
 {
        struct iwl_trans_pcie *trans_pcie =
@@ -219,10 +221,10 @@ static int iwl_rx_init(struct iwl_trans *trans)
 
        iwl_trans_rx_hw_init(trans, rxq);
 
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
        rxq->need_update = 1;
        iwl_rx_queue_update_write_ptr(trans, rxq);
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
 
        return 0;
 }
@@ -389,6 +391,8 @@ static int iwl_trans_txq_init(struct iwl_trans *trans, struct iwl_tx_queue *txq,
        if (ret)
                return ret;
 
+       spin_lock_init(&txq->lock);
+
        /*
         * Tell nic where to find circular buffer of Tx Frame Descriptors for
         * given Tx queue, and enable the DMA channel used for that queue.
@@ -408,8 +412,6 @@ static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id)
        struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id];
        struct iwl_queue *q = &txq->q;
        enum dma_data_direction dma_dir;
-       unsigned long flags;
-       spinlock_t *lock;
 
        if (!q->n_bd)
                return;
@@ -417,22 +419,19 @@ static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id)
        /* In the command queue, all the TBs are mapped as BIDI
         * so unmap them as such.
         */
-       if (txq_id == trans->shrd->cmd_queue) {
+       if (txq_id == trans->shrd->cmd_queue)
                dma_dir = DMA_BIDIRECTIONAL;
-               lock = &trans->hcmd_lock;
-       } else {
+       else
                dma_dir = DMA_TO_DEVICE;
-               lock = &trans->shrd->sta_lock;
-       }
 
-       spin_lock_irqsave(lock, flags);
+       spin_lock_bh(&txq->lock);
        while (q->write_ptr != q->read_ptr) {
                /* The read_ptr needs to bound by q->n_window */
                iwlagn_txq_free_tfd(trans, txq, get_cmd_index(q, q->read_ptr),
                                    dma_dir);
                q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
        }
-       spin_unlock_irqrestore(lock, flags);
+       spin_unlock_bh(&txq->lock);
 }
 
 /**
@@ -585,7 +584,7 @@ static int iwl_tx_init(struct iwl_trans *trans)
                alloc = true;
        }
 
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
 
        /* Turn off all Tx DMA fifos */
        iwl_write_prph(trans, SCD_TXFACT, 0);
@@ -594,7 +593,7 @@ static int iwl_tx_init(struct iwl_trans *trans)
        iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG,
                           trans_pcie->kw.dma >> 4);
 
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
 
        /* Alloc and init all Tx queues, including the command queue (#4/#9) */
        for (txq_id = 0; txq_id < hw_params(trans).max_txq_num; txq_id++) {
@@ -633,6 +632,52 @@ static void iwl_set_pwr_vmain(struct iwl_trans *trans)
                               ~APMG_PS_CTRL_MSK_PWR_SRC);
 }
 
+/* PCI registers */
+#define PCI_CFG_RETRY_TIMEOUT  0x041
+#define PCI_CFG_LINK_CTRL_VAL_L0S_EN   0x01
+#define PCI_CFG_LINK_CTRL_VAL_L1_EN    0x02
+
+static u16 iwl_pciexp_link_ctrl(struct iwl_trans *trans)
+{
+       int pos;
+       u16 pci_lnk_ctl;
+       struct iwl_trans_pcie *trans_pcie =
+               IWL_TRANS_GET_PCIE_TRANS(trans);
+
+       struct pci_dev *pci_dev = trans_pcie->pci_dev;
+
+       pos = pci_pcie_cap(pci_dev);
+       pci_read_config_word(pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl);
+       return pci_lnk_ctl;
+}
+
+static void iwl_apm_config(struct iwl_trans *trans)
+{
+       /*
+        * HW bug W/A for instability in PCIe bus L0S->L1 transition.
+        * Check if BIOS (or OS) enabled L1-ASPM on this device.
+        * If so (likely), disable L0S, so device moves directly L0->L1;
+        *    costs negligible amount of power savings.
+        * If not (unlikely), enable L0S, so there is at least some
+        *    power savings, even without L1.
+        */
+       u16 lctl = iwl_pciexp_link_ctrl(trans);
+
+       if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) ==
+                               PCI_CFG_LINK_CTRL_VAL_L1_EN) {
+               /* L1-ASPM enabled; disable(!) L0S */
+               iwl_set_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
+               dev_printk(KERN_INFO, trans->dev,
+                          "L1 Enabled; Disabling L0S\n");
+       } else {
+               /* L1-ASPM disabled; enable(!) L0S */
+               iwl_clear_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
+               dev_printk(KERN_INFO, trans->dev,
+                          "L1 Disabled; Enabling L0S\n");
+       }
+       trans->pm_support = !(lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN);
+}
+
 /*
  * Start up NIC's basic functionality after it has been reset
  * (e.g. after platform boot, or shutdown via iwl_apm_stop())
@@ -669,7 +714,7 @@ static int iwl_apm_init(struct iwl_trans *trans)
        iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
                                    CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
 
-       bus_apm_config(bus(trans));
+       iwl_apm_config(trans);
 
        /* Configure analog phase-lock-loop before activating to D0A */
        if (cfg(trans)->base_params->pll_cfg_val)
@@ -757,17 +802,18 @@ static void iwl_apm_stop(struct iwl_trans *trans)
 
 static int iwl_nic_init(struct iwl_trans *trans)
 {
+       struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
        unsigned long flags;
 
        /* nic_init */
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
        iwl_apm_init(trans);
 
        /* Set interrupt coalescing calibration timer to default (512 usecs) */
        iwl_write8(trans, CSR_INT_COALESCING,
                IWL_HOST_INT_CALIB_TIMEOUT_DEF);
 
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
 
        iwl_set_pwr_vmain(trans);
 
@@ -782,7 +828,7 @@ static int iwl_nic_init(struct iwl_trans *trans)
        if (iwl_tx_init(trans))
                return -ENOMEM;
 
-       if (hw_params(trans).shadow_reg_enable) {
+       if (cfg(trans)->base_params->shadow_reg_enable) {
                /* enable shadow regs in HW */
                iwl_set_bit(trans, CSR_MAC_SHADOW_REG_CTRL,
                        0x800FFFFF);
@@ -900,7 +946,7 @@ static const u8 iwlagn_pan_ac_to_queue[] = {
  * ucode
  */
 static int iwl_load_section(struct iwl_trans *trans, const char *name,
-                               struct fw_desc *image, u32 dst_addr)
+                           const struct fw_desc *image, u32 dst_addr)
 {
        dma_addr_t phy_addr = image->p_addr;
        u32 byte_cnt = image->len;
@@ -948,7 +994,8 @@ static int iwl_load_section(struct iwl_trans *trans, const char *name,
        return 0;
 }
 
-static int iwl_load_given_ucode(struct iwl_trans *trans, struct fw_img *image)
+static int iwl_load_given_ucode(struct iwl_trans *trans,
+                               const struct fw_img *image)
 {
        int ret = 0;
 
@@ -968,11 +1015,13 @@ static int iwl_load_given_ucode(struct iwl_trans *trans, struct fw_img *image)
        return 0;
 }
 
-static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, struct fw_img *fw)
+static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
+                                  const struct fw_img *fw)
 {
        int ret;
        struct iwl_trans_pcie *trans_pcie =
                IWL_TRANS_GET_PCIE_TRANS(trans);
+       bool hw_rfkill;
 
        trans->shrd->ucode_owner = IWL_OWNERSHIP_DRIVER;
        trans_pcie->ac_to_queue[IWL_RXON_CTX_BSS] = iwlagn_bss_ac_to_queue;
@@ -984,21 +1033,18 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, struct fw_img *fw)
        trans_pcie->mcast_queue[IWL_RXON_CTX_BSS] = 0;
        trans_pcie->mcast_queue[IWL_RXON_CTX_PAN] = IWL_IPAN_MCAST_QUEUE;
 
-       if ((hw_params(trans).sku & EEPROM_SKU_CAP_AMT_ENABLE) &&
-            iwl_prepare_card_hw(trans)) {
+       /* This may fail if AMT took ownership of the device */
+       if (iwl_prepare_card_hw(trans)) {
                IWL_WARN(trans, "Exit HW not ready\n");
                return -EIO;
        }
 
        /* If platform's RF_KILL switch is NOT set to KILL */
-       if (iwl_read32(trans, CSR_GP_CNTRL) &
-                       CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
-               clear_bit(STATUS_RF_KILL_HW, &trans->shrd->status);
-       else
-               set_bit(STATUS_RF_KILL_HW, &trans->shrd->status);
+       hw_rfkill = !(iwl_read32(trans, CSR_GP_CNTRL) &
+                               CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW);
+       iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill);
 
-       if (iwl_is_rfkill(trans->shrd)) {
-               iwl_set_hw_rfkill_state(priv(trans), true);
+       if (hw_rfkill) {
                iwl_enable_interrupts(trans);
                return -ERFKILL;
        }
@@ -1032,10 +1078,15 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, struct fw_img *fw)
 
 /*
  * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask
- * must be called under priv->shrd->lock and mac access
+ * must be called under the irq lock and with MAC access
  */
 static void iwl_trans_txq_set_sched(struct iwl_trans *trans, u32 mask)
 {
+       struct iwl_trans_pcie __maybe_unused *trans_pcie =
+               IWL_TRANS_GET_PCIE_TRANS(trans);
+
+       lockdep_assert_held(&trans_pcie->irq_lock);
+
        iwl_write_prph(trans, SCD_TXFACT, mask);
 }
 
@@ -1049,7 +1100,7 @@ static void iwl_tx_start(struct iwl_trans *trans)
        int i, chan;
        u32 reg_val;
 
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
 
        trans_pcie->scd_base_addr =
                iwl_read_prph(trans, SCD_SRAM_BASE_ADDR);
@@ -1145,7 +1196,7 @@ static void iwl_tx_start(struct iwl_trans *trans)
                                              fifo, 0);
        }
 
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
 
        /* Enable L1-Active */
        iwl_clear_bits_prph(trans, APMG_PCIDEV_STT_REG,
@@ -1168,7 +1219,7 @@ static int iwl_trans_tx_stop(struct iwl_trans *trans)
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
 
        /* Turn off all Tx DMA fifos */
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
 
        iwl_trans_txq_set_sched(trans, 0);
 
@@ -1184,7 +1235,7 @@ static int iwl_trans_tx_stop(struct iwl_trans *trans)
                            iwl_read_direct32(trans,
                                              FH_TSSR_TX_STATUS_REG));
        }
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
 
        if (!trans_pcie->txq) {
                IWL_WARN(trans, "Stopping tx queues that aren't allocated...");
@@ -1204,9 +1255,9 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
 
        /* tell the device to stop sending interrupts */
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
        iwl_disable_interrupts(trans);
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
 
        /* device going down, Stop using ICT table */
        iwl_disable_ict(trans);
@@ -1239,18 +1290,31 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
        /* Upon stop, the APM issues an interrupt if HW RF kill is set.
         * Clean again the interrupt here
         */
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
        iwl_disable_interrupts(trans);
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
 
        /* wait to make sure we flush pending tasklet*/
        synchronize_irq(trans->irq);
        tasklet_kill(&trans_pcie->irq_tasklet);
 
+       cancel_work_sync(&trans_pcie->rx_replenish);
+
        /* stop and reset the on-board processor */
        iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
 }
 
+static void iwl_trans_pcie_wowlan_suspend(struct iwl_trans *trans)
+{
+       /* let the ucode operate on its own */
+       iwl_write32(trans, CSR_UCODE_DRV_GP1_SET,
+                   CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);
+
+       iwl_disable_interrupts(trans);
+       iwl_clear_bit(trans, CSR_GP_CNTRL,
+                     CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+}
+
 static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
                struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx,
                u8 sta_id, u8 tid)
@@ -1303,6 +1367,8 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
        txq = &trans_pcie->txq[txq_id];
        q = &txq->q;
 
+       spin_lock(&txq->lock);
+
        /* In AGG mode, the index in the ring must correspond to the WiFi
         * sequence number. This is a HW requirements to help the SCD to parse
         * the BA.
@@ -1349,7 +1415,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
                                    &dev_cmd->hdr, firstlen,
                                    DMA_BIDIRECTIONAL);
        if (unlikely(dma_mapping_error(trans->dev, txcmd_phys)))
-               return -1;
+               goto out_err;
        dma_unmap_addr_set(out_meta, mapping, txcmd_phys);
        dma_unmap_len_set(out_meta, len, firstlen);
 
@@ -1371,7 +1437,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
                                         dma_unmap_addr(out_meta, mapping),
                                         dma_unmap_len(out_meta, len),
                                         DMA_BIDIRECTIONAL);
-                       return -1;
+                       goto out_err;
                }
        }
 
@@ -1426,7 +1492,11 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
                        iwl_stop_queue(trans, txq, "Queue is full");
                }
        }
+       spin_unlock(&txq->lock);
        return 0;
+ out_err:
+       spin_unlock(&txq->lock);
+       return -1;
 }
 
 static int iwl_trans_pcie_start_hw(struct iwl_trans *trans)
@@ -1434,6 +1504,7 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans)
        struct iwl_trans_pcie *trans_pcie =
                IWL_TRANS_GET_PCIE_TRANS(trans);
        int err;
+       bool hw_rfkill;
 
        trans_pcie->inta_mask = CSR_INI_SET_MASK;
 
@@ -1458,24 +1529,19 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans)
        err = iwl_prepare_card_hw(trans);
        if (err) {
                IWL_ERR(trans, "Error while preparing HW: %d", err);
-               goto error;
+               goto err_free_irq;
        }
 
        iwl_apm_init(trans);
 
-       /* If platform's RF_KILL switch is NOT set to KILL */
-       if (iwl_read32(trans,
-                       CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
-               clear_bit(STATUS_RF_KILL_HW, &trans->shrd->status);
-       else
-               set_bit(STATUS_RF_KILL_HW, &trans->shrd->status);
-
-       iwl_set_hw_rfkill_state(priv(trans),
-                               test_bit(STATUS_RF_KILL_HW,
-                                        &trans->shrd->status));
+       hw_rfkill = !(iwl_read32(trans, CSR_GP_CNTRL) &
+                               CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW);
+       iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill);
 
        return err;
 
+err_free_irq:
+       free_irq(trans->irq, trans);
 error:
        iwl_free_isr_ict(trans);
        tasklet_kill(&trans_pcie->irq_tasklet);
@@ -1486,6 +1552,8 @@ static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans)
 {
        iwl_apm_stop(trans);
 
+       iwl_write32(trans, CSR_INT, 0xFFFFFFFF);
+
        /* Even if we stop the HW, we still want the RF kill interrupt */
        IWL_DEBUG_ISR(trans, "Enabling rfkill interrupt\n");
        iwl_write32(trans, CSR_INT_MASK, CSR_INT_BIT_RF_KILL);
@@ -1501,9 +1569,12 @@ static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid,
        int tfd_num = ssn & (txq->q.n_bd - 1);
        int freed = 0;
 
+       spin_lock(&txq->lock);
+
        txq->time_stamp = jiffies;
 
        if (unlikely(txq_id >= IWLAGN_FIRST_AMPDU_QUEUE &&
+                    tid != IWL_TID_NON_QOS &&
                     txq_id != trans_pcie->agg_txq[sta_id][tid])) {
                /*
                 * FIXME: this is a uCode bug which need to be addressed,
@@ -1514,6 +1585,7 @@ static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid,
                IWL_DEBUG_TX_QUEUES(trans, "Bad queue mapping txq_id %d, "
                        "agg_txq[sta_id[tid] %d", txq_id,
                        trans_pcie->agg_txq[sta_id][tid]);
+               spin_unlock(&txq->lock);
                return 1;
        }
 
@@ -1527,6 +1599,8 @@ static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid,
                   status != TX_STATUS_FAIL_PASSIVE_NO_RX))
                        iwl_wake_queue(trans, txq, "Packets reclaimed");
        }
+
+       spin_unlock(&txq->lock);
        return 0;
 }
 
@@ -1551,7 +1625,6 @@ static void iwl_trans_pcie_free(struct iwl_trans *trans)
        struct iwl_trans_pcie *trans_pcie =
                IWL_TRANS_GET_PCIE_TRANS(trans);
 
-       iwl_calib_free_results(trans);
        iwl_trans_pcie_tx_free(trans);
 #ifndef CONFIG_IWLWIFI_IDI
        iwl_trans_pcie_rx_free(trans);
@@ -1573,44 +1646,18 @@ static void iwl_trans_pcie_free(struct iwl_trans *trans)
 #ifdef CONFIG_PM_SLEEP
 static int iwl_trans_pcie_suspend(struct iwl_trans *trans)
 {
-       /*
-        * This function is called when system goes into suspend state
-        * mac80211 will call iwlagn_mac_stop() from the mac80211 suspend
-        * function first but since iwlagn_mac_stop() has no knowledge of
-        * who the caller is,
-        * it will not call apm_ops.stop() to stop the DMA operation.
-        * Calling apm_ops.stop here to make sure we stop the DMA.
-        *
-        * But of course ... if we have configured WoWLAN then we did other
-        * things already :-)
-        */
-       if (!trans->shrd->wowlan) {
-               iwl_apm_stop(trans);
-       } else {
-               iwl_disable_interrupts(trans);
-               iwl_clear_bit(trans, CSR_GP_CNTRL,
-                             CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
-       }
-
        return 0;
 }
 
 static int iwl_trans_pcie_resume(struct iwl_trans *trans)
 {
-       bool hw_rfkill = false;
+       bool hw_rfkill;
 
        iwl_enable_interrupts(trans);
 
-       if (!(iwl_read32(trans, CSR_GP_CNTRL) &
-                               CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
-               hw_rfkill = true;
-
-       if (hw_rfkill)
-               set_bit(STATUS_RF_KILL_HW, &trans->shrd->status);
-       else
-               clear_bit(STATUS_RF_KILL_HW, &trans->shrd->status);
-
-       iwl_set_hw_rfkill_state(priv(trans), hw_rfkill);
+       hw_rfkill = !(iwl_read32(trans, CSR_GP_CNTRL) &
+                               CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW);
+       iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill);
 
        return 0;
 }
@@ -2159,6 +2206,8 @@ const struct iwl_trans_ops trans_ops_pcie = {
        .start_fw = iwl_trans_pcie_start_fw,
        .stop_device = iwl_trans_pcie_stop_device,
 
+       .wowlan_suspend = iwl_trans_pcie_wowlan_suspend,
+
        .wake_any_queue = iwl_trans_pcie_wake_any_queue,
 
        .send_cmd = iwl_trans_pcie_send_cmd,
@@ -2187,9 +2236,6 @@ const struct iwl_trans_ops trans_ops_pcie = {
        .read32 = iwl_trans_pcie_read32,
 };
 
-/* PCI registers */
-#define PCI_CFG_RETRY_TIMEOUT  0x041
-
 struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd,
                                       struct pci_dev *pdev,
                                       const struct pci_device_id *ent)
@@ -2210,7 +2256,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd,
        trans->ops = &trans_ops_pcie;
        trans->shrd = shrd;
        trans_pcie->trans = trans;
-       spin_lock_init(&trans->hcmd_lock);
+       spin_lock_init(&trans_pcie->irq_lock);
 
        /* W/A - seems to solve weird behavior. We need to remove this if we
         * don't want to stay in L1 all the time. This wastes a lot of power */
@@ -2274,6 +2320,10 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd,
        trans->dev = &pdev->dev;
        trans->irq = pdev->irq;
        trans_pcie->pci_dev = pdev;
+       trans->hw_rev = iwl_read32(trans, CSR_HW_REV);
+       trans->hw_id = (pdev->device << 16) + pdev->subsystem_device;
+       snprintf(trans->hw_id_str, sizeof(trans->hw_id_str),
+                "PCI ID: 0x%04X:0x%04X", pdev->device, pdev->subsystem_device);
 
        /* TODO: Move this away, not needed if not MSI */
        /* enable rfkill interrupt: hw bug w/a */