diff options
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/pcie')
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 31 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/pcie/internal.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 111 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 29 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 21 |
5 files changed, 114 insertions, 81 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index de42066..a588b05 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -493,19 +493,20 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x24FD, 0x8130, iwl8265_2ac_cfg)}, /* 9000 Series */ - {IWL_PCI_DEVICE(0x9DF0, 0x0A10, iwl9560_2ac_cfg)}, - {IWL_PCI_DEVICE(0x9DF0, 0x0010, iwl9560_2ac_cfg)}, - {IWL_PCI_DEVICE(0x9DF0, 0x2A10, iwl5165_2ac_cfg)}, - {IWL_PCI_DEVICE(0x9DF0, 0x2010, iwl5165_2ac_cfg)}, - {IWL_PCI_DEVICE(0x2526, 0x1420, iwl5165_2ac_cfg)}, - {IWL_PCI_DEVICE(0x2526, 0x0010, iwl5165_2ac_cfg)}, - {IWL_PCI_DEVICE(0x9DF0, 0x0000, iwl5165_2ac_cfg)}, + {IWL_PCI_DEVICE(0x2526, 0x0000, iwl9260_2ac_cfg)}, + {IWL_PCI_DEVICE(0x2526, 0x0010, iwl9260_2ac_cfg)}, + {IWL_PCI_DEVICE(0x9DF0, 0x0A10, iwl9260_2ac_cfg)}, + {IWL_PCI_DEVICE(0x9DF0, 0x0010, iwl9260_2ac_cfg)}, + {IWL_PCI_DEVICE(0x9DF0, 0x0210, iwl9260_2ac_cfg)}, + {IWL_PCI_DEVICE(0x9DF0, 0x0410, iwl9260_2ac_cfg)}, + {IWL_PCI_DEVICE(0x9DF0, 0x0610, iwl9260_2ac_cfg)}, {IWL_PCI_DEVICE(0x9DF0, 0x0310, iwl5165_2ac_cfg)}, + {IWL_PCI_DEVICE(0x9DF0, 0x0000, iwl5165_2ac_cfg)}, {IWL_PCI_DEVICE(0x9DF0, 0x0510, iwl5165_2ac_cfg)}, + {IWL_PCI_DEVICE(0x9DF0, 0x2010, iwl5165_2ac_cfg)}, + {IWL_PCI_DEVICE(0x2526, 0x1420, iwl5165_2ac_cfg)}, {IWL_PCI_DEVICE(0x9DF0, 0x0710, iwl5165_2ac_cfg)}, - {IWL_PCI_DEVICE(0x9DF0, 0x0210, iwl9560_2ac_cfg)}, - {IWL_PCI_DEVICE(0x9DF0, 0x0410, iwl9560_2ac_cfg)}, - {IWL_PCI_DEVICE(0x9DF0, 0x0610, iwl9560_2ac_cfg)}, + {IWL_PCI_DEVICE(0x9DF0, 0x2A10, iwl5165_2ac_cfg)}, #endif /* CONFIG_IWLMVM */ {0} @@ -595,6 +596,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { const struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); const struct iwl_cfg *cfg_7265d __maybe_unused = NULL; + const struct iwl_cfg *cfg_9260lc __maybe_unused = NULL; struct iwl_trans *iwl_trans; struct iwl_trans_pcie *trans_pcie; int ret; @@ -622,6 +624,15 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) cfg = cfg_7265d; iwl_trans->cfg = cfg_7265d; } + + if (iwl_trans->cfg->rf_id) { + if (cfg == &iwl9260_2ac_cfg) + cfg_9260lc = &iwl9260lc_2ac_cfg; + if (cfg_9260lc && iwl_trans->hw_rf_id == CSR_HW_RF_ID_TYPE_LC) { + cfg = cfg_9260lc; + iwl_trans->cfg = cfg_9260lc; + } + } #endif pci_set_drvdata(pdev, iwl_trans); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h index 9ce4ec6..de6974f 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h @@ -481,9 +481,6 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn, struct sk_buff_head *skbs); void iwl_trans_pcie_tx_reset(struct iwl_trans *trans); -void iwl_trans_pcie_ref(struct iwl_trans *trans); -void iwl_trans_pcie_unref(struct iwl_trans *trans); - static inline u16 iwl_pcie_tfd_tb_get_len(struct iwl_tfd *tfd, u8 idx) { struct iwl_tfd_tb *tb = &tfd->tbs[idx]; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c index 7f8a232..0a4a3c5 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c @@ -161,10 +161,11 @@ static inline __le32 iwl_pcie_dma_addr2rbd_ptr(dma_addr_t dma_addr) return cpu_to_le32((u32)(dma_addr >> 8)); } -static void iwl_pcie_write_prph_64(struct iwl_trans *trans, u64 ofs, u64 val) +static void iwl_pcie_write_prph_64_no_grab(struct iwl_trans *trans, u64 ofs, + u64 val) { - iwl_write_prph(trans, ofs, val & 0xffffffff); - iwl_write_prph(trans, ofs + 4, val >> 32); + iwl_write_prph_no_grab(trans, ofs, val & 0xffffffff); + iwl_write_prph_no_grab(trans, ofs + 4, val >> 32); } /* @@ -208,8 +209,8 @@ static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans, rxq->write_actual = round_down(rxq->write, 8); if (trans->cfg->mq_rx_supported) - iwl_write_prph(trans, RFH_Q_FRBDCB_WIDX(rxq->id), - rxq->write_actual); + iwl_write32(trans, RFH_Q_FRBDCB_WIDX_TRG(rxq->id), + rxq->write_actual); /* * write to FH_RSCSR_CHNL0_WPTR register even in MQ as a W/A to * hardware shadow registers bug - writing to RFH_Q_FRBDCB_WIDX will @@ -698,6 +699,7 @@ static void iwl_pcie_rx_hw_init(struct iwl_trans *trans, struct iwl_rxq *rxq) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); u32 rb_size; + unsigned long flags; const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */ switch (trans_pcie->rx_buf_size) { @@ -715,23 +717,26 @@ static void iwl_pcie_rx_hw_init(struct iwl_trans *trans, struct iwl_rxq *rxq) rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K; } + if (!iwl_trans_grab_nic_access(trans, &flags)) + return; + /* Stop Rx DMA */ - iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); + iwl_write32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); /* reset and flush pointers */ - iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_RBDCB_WPTR, 0); - iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_FLUSH_RB_REQ, 0); - iwl_write_direct32(trans, FH_RSCSR_CHNL0_RDPTR, 0); + iwl_write32(trans, FH_MEM_RCSR_CHNL0_RBDCB_WPTR, 0); + iwl_write32(trans, FH_MEM_RCSR_CHNL0_FLUSH_RB_REQ, 0); + iwl_write32(trans, FH_RSCSR_CHNL0_RDPTR, 0); /* Reset driver's Rx queue write index */ - iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0); + iwl_write32(trans, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0); /* Tell device where to find RBD circular buffer in DRAM */ - iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_BASE_REG, - (u32)(rxq->bd_dma >> 8)); + iwl_write32(trans, FH_RSCSR_CHNL0_RBDCB_BASE_REG, + (u32)(rxq->bd_dma >> 8)); /* Tell device where in DRAM to update its Rx status */ - iwl_write_direct32(trans, FH_RSCSR_CHNL0_STTS_WPTR_REG, - rxq->rb_stts_dma >> 4); + iwl_write32(trans, FH_RSCSR_CHNL0_STTS_WPTR_REG, + rxq->rb_stts_dma >> 4); /* Enable Rx DMA * FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY is set because of HW bug in @@ -741,13 +746,15 @@ static void iwl_pcie_rx_hw_init(struct iwl_trans *trans, struct iwl_rxq *rxq) * RB timeout 0x10 * 256 RBDs */ - iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, - FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL | - FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY | - FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL | - rb_size| - (RX_RB_TIMEOUT << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)| - (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS)); + iwl_write32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, + FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL | + FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY | + FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL | + rb_size | + (RX_RB_TIMEOUT << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS) | + (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS)); + + iwl_trans_release_nic_access(trans, &flags); /* Set interrupt coalescing timer to default (2048 usecs) */ iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF); @@ -761,6 +768,7 @@ static void iwl_pcie_rx_mq_hw_init(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); u32 rb_size, enabled = 0; + unsigned long flags; int i; switch (trans_pcie->rx_buf_size) { @@ -778,25 +786,31 @@ static void iwl_pcie_rx_mq_hw_init(struct iwl_trans *trans) rb_size = RFH_RXF_DMA_RB_SIZE_4K; } + if (!iwl_trans_grab_nic_access(trans, &flags)) + return; + /* Stop Rx DMA */ - iwl_write_prph(trans, RFH_RXF_DMA_CFG, 0); + iwl_write_prph_no_grab(trans, RFH_RXF_DMA_CFG, 0); /* disable free amd used rx queue operation */ - iwl_write_prph(trans, RFH_RXF_RXQ_ACTIVE, 0); + iwl_write_prph_no_grab(trans, RFH_RXF_RXQ_ACTIVE, 0); for (i = 0; i < trans->num_rx_queues; i++) { /* Tell device where to find RBD free table in DRAM */ - iwl_pcie_write_prph_64(trans, RFH_Q_FRBDCB_BA_LSB(i), - (u64)(trans_pcie->rxq[i].bd_dma)); + iwl_pcie_write_prph_64_no_grab(trans, + RFH_Q_FRBDCB_BA_LSB(i), + trans_pcie->rxq[i].bd_dma); /* Tell device where to find RBD used table in DRAM */ - iwl_pcie_write_prph_64(trans, RFH_Q_URBDCB_BA_LSB(i), - (u64)(trans_pcie->rxq[i].used_bd_dma)); + iwl_pcie_write_prph_64_no_grab(trans, + RFH_Q_URBDCB_BA_LSB(i), + trans_pcie->rxq[i].used_bd_dma); /* Tell device where in DRAM to update its Rx status */ - iwl_pcie_write_prph_64(trans, RFH_Q_URBD_STTS_WPTR_LSB(i), - trans_pcie->rxq[i].rb_stts_dma); + iwl_pcie_write_prph_64_no_grab(trans, + RFH_Q_URBD_STTS_WPTR_LSB(i), + trans_pcie->rxq[i].rb_stts_dma); /* Reset device indice tables */ - iwl_write_prph(trans, RFH_Q_FRBDCB_WIDX(i), 0); - iwl_write_prph(trans, RFH_Q_FRBDCB_RIDX(i), 0); - iwl_write_prph(trans, RFH_Q_URBDCB_WIDX(i), 0); + iwl_write_prph_no_grab(trans, RFH_Q_FRBDCB_WIDX(i), 0); + iwl_write_prph_no_grab(trans, RFH_Q_FRBDCB_RIDX(i), 0); + iwl_write_prph_no_grab(trans, RFH_Q_URBDCB_WIDX(i), 0); enabled |= BIT(i) | BIT(i + 16); } @@ -812,23 +826,26 @@ static void iwl_pcie_rx_mq_hw_init(struct iwl_trans *trans) * Drop frames that exceed RB size * 512 RBDs */ - iwl_write_prph(trans, RFH_RXF_DMA_CFG, - RFH_DMA_EN_ENABLE_VAL | - rb_size | RFH_RXF_DMA_SINGLE_FRAME_MASK | - RFH_RXF_DMA_MIN_RB_4_8 | - RFH_RXF_DMA_DROP_TOO_LARGE_MASK | - RFH_RXF_DMA_RBDCB_SIZE_512); + iwl_write_prph_no_grab(trans, RFH_RXF_DMA_CFG, + RFH_DMA_EN_ENABLE_VAL | + rb_size | RFH_RXF_DMA_SINGLE_FRAME_MASK | + RFH_RXF_DMA_MIN_RB_4_8 | + RFH_RXF_DMA_DROP_TOO_LARGE_MASK | + RFH_RXF_DMA_RBDCB_SIZE_512); /* * Activate DMA snooping. * Set RX DMA chunk size to 64B * Default queue is 0 */ - iwl_write_prph(trans, RFH_GEN_CFG, RFH_GEN_CFG_RFH_DMA_SNOOP | - (DEFAULT_RXQ_NUM << RFH_GEN_CFG_DEFAULT_RXQ_NUM_POS) | - RFH_GEN_CFG_SERVICE_DMA_SNOOP); + iwl_write_prph_no_grab(trans, RFH_GEN_CFG, RFH_GEN_CFG_RFH_DMA_SNOOP | + (DEFAULT_RXQ_NUM << + RFH_GEN_CFG_DEFAULT_RXQ_NUM_POS) | + RFH_GEN_CFG_SERVICE_DMA_SNOOP); /* Enable the relevant rx queues */ - iwl_write_prph(trans, RFH_RXF_RXQ_ACTIVE, enabled); + iwl_write_prph_no_grab(trans, RFH_RXF_RXQ_ACTIVE, enabled); + + iwl_trans_release_nic_access(trans, &flags); /* Set interrupt coalescing timer to default (2048 usecs) */ iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF); @@ -1298,7 +1315,7 @@ static inline void iwl_pcie_clear_irq(struct iwl_trans *trans, * write 1 clear (W1C) register, meaning that it's being clear * by writing 1 to the bit. */ - iwl_write_direct32(trans, CSR_MSIX_AUTOMASK_ST_AD, BIT(entry->entry)); + iwl_write32(trans, CSR_MSIX_AUTOMASK_ST_AD, BIT(entry->entry)); } /* @@ -1817,13 +1834,13 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id) lock_map_acquire(&trans->sync_cmd_lockdep_map); spin_lock(&trans_pcie->irq_lock); - inta_fh = iwl_read_direct32(trans, CSR_MSIX_FH_INT_CAUSES_AD); - inta_hw = iwl_read_direct32(trans, CSR_MSIX_HW_INT_CAUSES_AD); + inta_fh = iwl_read32(trans, CSR_MSIX_FH_INT_CAUSES_AD); + inta_hw = iwl_read32(trans, CSR_MSIX_HW_INT_CAUSES_AD); /* * Clear causes registers to avoid being handling the same cause. */ - iwl_write_direct32(trans, CSR_MSIX_FH_INT_CAUSES_AD, inta_fh); - iwl_write_direct32(trans, CSR_MSIX_HW_INT_CAUSES_AD, inta_hw); + iwl_write32(trans, CSR_MSIX_FH_INT_CAUSES_AD, inta_fh); + iwl_write32(trans, CSR_MSIX_HW_INT_CAUSES_AD, inta_hw); spin_unlock(&trans_pcie->irq_lock); if (unlikely(!(inta_fh | inta_hw))) { diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index ee081c2..f603d78 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -269,9 +269,8 @@ static int iwl_pcie_apm_init(struct iwl_trans *trans) iwl_pcie_apm_config(trans); /* Configure analog phase-lock-loop before activating to D0A */ - if (trans->cfg->base_params->pll_cfg_val) - iwl_set_bit(trans, CSR_ANA_PLL_CFG, - trans->cfg->base_params->pll_cfg_val); + if (trans->cfg->base_params->pll_cfg) + iwl_set_bit(trans, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL); /* * Set "initialization complete" bit to move adapter from @@ -361,8 +360,7 @@ static void iwl_pcie_apm_lp_xtal_enable(struct iwl_trans *trans) /* Reset entire device - do controller reset (results in SHRD_HW_RST) */ iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); - - udelay(10); + usleep_range(1000, 2000); /* * Set "initialization complete" bit to move adapter from @@ -408,8 +406,7 @@ static void iwl_pcie_apm_lp_xtal_enable(struct iwl_trans *trans) * SHRD_HW_RST). Turn MAC off before proceeding. */ iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); - - udelay(10); + usleep_range(1000, 2000); /* Enable LP XTAL by indirect access through CSR */ apmg_gp1_reg = iwl_trans_pcie_read_shr(trans, SHR_APMG_GP1_REG); @@ -506,8 +503,7 @@ static void iwl_pcie_apm_stop(struct iwl_trans *trans, bool op_mode_leave) /* Reset the entire device */ iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); - - udelay(10); + usleep_range(1000, 2000); /* * Clear "initialization complete" bit to move adapter from @@ -586,7 +582,7 @@ static int iwl_pcie_prepare_card_hw(struct iwl_trans *trans) iwl_set_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG, CSR_RESET_LINK_PWR_MGMT_DISABLED); - msleep(1); + usleep_range(1000, 2000); for (iter = 0; iter < 10; iter++) { /* If HW is not ready, prepare the conditions to check again */ @@ -1074,7 +1070,7 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power) /* stop and reset the on-board processor */ iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); - udelay(20); + usleep_range(1000, 2000); /* * Upon stop, the APM issues an interrupt if HW RF kill is set. @@ -1526,8 +1522,7 @@ static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power) /* Reset the entire device */ iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); - - usleep_range(10, 15); + usleep_range(1000, 2000); iwl_pcie_apm_init(trans); @@ -1950,7 +1945,7 @@ static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans, u32 txq_bm) "WR pointer moved while flushing %d -> %d\n", wr_ptr, write_ptr)) return -ETIMEDOUT; - msleep(1); + usleep_range(1000, 2000); } if (q->read_ptr != q->write_ptr) { @@ -2013,7 +2008,7 @@ static void iwl_trans_pcie_set_bits_mask(struct iwl_trans *trans, u32 reg, spin_unlock_irqrestore(&trans_pcie->reg_lock, flags); } -void iwl_trans_pcie_ref(struct iwl_trans *trans) +static void iwl_trans_pcie_ref(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); @@ -2028,7 +2023,7 @@ void iwl_trans_pcie_ref(struct iwl_trans *trans) #endif /* CONFIG_PM */ } -void iwl_trans_pcie_unref(struct iwl_trans *trans) +static void iwl_trans_pcie_unref(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); @@ -2907,6 +2902,8 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, } } + trans->hw_rf_id = iwl_read32(trans, CSR_HW_RF_ID); + iwl_pcie_set_interrupt_capa(pdev, trans); trans->hw_id = (pdev->device << 16) + pdev->subsystem_device; snprintf(trans->hw_id_str, sizeof(trans->hw_id_str), diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c index e1f7a3f..d6beac9 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c @@ -32,6 +32,7 @@ #include <linux/ieee80211.h> #include <linux/slab.h> #include <linux/sched.h> +#include <linux/pm_runtime.h> #include <net/ip6_checksum.h> #include <net/tso.h> @@ -605,7 +606,7 @@ static void iwl_pcie_clear_cmd_in_flight(struct iwl_trans *trans) if (trans_pcie->ref_cmd_in_flight) { trans_pcie->ref_cmd_in_flight = false; IWL_DEBUG_RPM(trans, "clear ref_cmd_in_flight - unref\n"); - iwl_trans_pcie_unref(trans); + iwl_trans_unref(trans); } if (!trans->cfg->base_params->apmg_wake_up_wa) @@ -650,7 +651,7 @@ static void iwl_pcie_txq_unmap(struct iwl_trans *trans, int txq_id) if (txq_id != trans_pcie->cmd_queue) { IWL_DEBUG_RPM(trans, "Q %d - last tx freed\n", q->id); - iwl_trans_pcie_unref(trans); + iwl_trans_unref(trans); } else { iwl_pcie_clear_cmd_in_flight(trans); } @@ -1134,7 +1135,7 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn, if (q->read_ptr == q->write_ptr) { IWL_DEBUG_RPM(trans, "Q %d - last tx reclaimed\n", q->id); - iwl_trans_pcie_unref(trans); + iwl_trans_unref(trans); } out: @@ -1153,7 +1154,7 @@ static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans, !trans_pcie->ref_cmd_in_flight) { trans_pcie->ref_cmd_in_flight = true; IWL_DEBUG_RPM(trans, "set ref_cmd_in_flight - ref\n"); - iwl_trans_pcie_ref(trans); + iwl_trans_ref(trans); } /* @@ -1799,6 +1800,16 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans, IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n", iwl_get_cmd_string(trans, cmd->id)); + if (pm_runtime_suspended(&trans_pcie->pci_dev->dev)) { + ret = wait_event_timeout(trans_pcie->d0i3_waitq, + pm_runtime_active(&trans_pcie->pci_dev->dev), + msecs_to_jiffies(IWL_TRANS_IDLE_TIMEOUT)); + if (!ret) { + IWL_ERR(trans, "Timeout exiting D0i3 before hcmd\n"); + return -ETIMEDOUT; + } + } + cmd_idx = iwl_pcie_enqueue_hcmd(trans, cmd); if (cmd_idx < 0) { ret = cmd_idx; @@ -2362,7 +2373,7 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, txq->frozen_expiry_remainder = txq->wd_timeout; } IWL_DEBUG_RPM(trans, "Q: %d first tx - take ref\n", q->id); - iwl_trans_pcie_ref(trans); + iwl_trans_ref(trans); } /* Tell device the write index *just past* this latest filled TFD */ |