diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/pcie/tx.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/pcie/tx.c | 68 |
1 files changed, 32 insertions, 36 deletions
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 254126447c68..3b0c72c10054 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c | |||
@@ -207,7 +207,7 @@ static void iwl_pcie_txq_stuck_timer(unsigned long data) | |||
207 | IWL_ERR(trans, "scratch %d = 0x%08x\n", i, | 207 | IWL_ERR(trans, "scratch %d = 0x%08x\n", i, |
208 | le32_to_cpu(txq->scratchbufs[i].scratch)); | 208 | le32_to_cpu(txq->scratchbufs[i].scratch)); |
209 | 209 | ||
210 | iwl_trans_fw_error(trans); | 210 | iwl_write_prph(trans, DEVICE_SET_NMI_REG, 1); |
211 | } | 211 | } |
212 | 212 | ||
213 | /* | 213 | /* |
@@ -296,43 +296,38 @@ void iwl_pcie_txq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_txq *txq) | |||
296 | if (txq->need_update == 0) | 296 | if (txq->need_update == 0) |
297 | return; | 297 | return; |
298 | 298 | ||
299 | if (trans->cfg->base_params->shadow_reg_enable || | 299 | /* |
300 | txq_id == trans_pcie->cmd_queue) { | 300 | * explicitly wake up the NIC if: |
301 | /* shadow register enabled */ | 301 | * 1. shadow registers aren't enabled |
302 | iwl_write32(trans, HBUS_TARG_WRPTR, | 302 | * 2. NIC is woken up for CMD regardless of shadow outside this function |
303 | txq->q.write_ptr | (txq_id << 8)); | 303 | * 3. there is a chance that the NIC is asleep |
304 | } else { | 304 | */ |
305 | /* if we're trying to save power */ | 305 | if (!trans->cfg->base_params->shadow_reg_enable && |
306 | if (test_bit(STATUS_TPOWER_PMI, &trans->status)) { | 306 | txq_id != trans_pcie->cmd_queue && |
307 | /* wake up nic if it's powered down ... | 307 | test_bit(STATUS_TPOWER_PMI, &trans->status)) { |
308 | * uCode will wake up, and interrupt us again, so next | ||
309 | * time we'll skip this part. */ | ||
310 | reg = iwl_read32(trans, CSR_UCODE_DRV_GP1); | ||
311 | |||
312 | if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { | ||
313 | IWL_DEBUG_INFO(trans, | ||
314 | "Tx queue %d requesting wakeup," | ||
315 | " GP1 = 0x%x\n", txq_id, reg); | ||
316 | iwl_set_bit(trans, CSR_GP_CNTRL, | ||
317 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
318 | return; | ||
319 | } | ||
320 | |||
321 | IWL_DEBUG_TX(trans, "Q:%d WR: 0x%x\n", txq_id, | ||
322 | txq->q.write_ptr); | ||
323 | |||
324 | iwl_write_direct32(trans, HBUS_TARG_WRPTR, | ||
325 | txq->q.write_ptr | (txq_id << 8)); | ||
326 | |||
327 | /* | 308 | /* |
328 | * else not in power-save mode, | 309 | * wake up nic if it's powered down ... |
329 | * uCode will never sleep when we're | 310 | * uCode will wake up, and interrupt us again, so next |
330 | * trying to tx (during RFKILL, we're not trying to tx). | 311 | * time we'll skip this part. |
331 | */ | 312 | */ |
332 | } else | 313 | reg = iwl_read32(trans, CSR_UCODE_DRV_GP1); |
333 | iwl_write32(trans, HBUS_TARG_WRPTR, | 314 | |
334 | txq->q.write_ptr | (txq_id << 8)); | 315 | if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { |
316 | IWL_DEBUG_INFO(trans, "Tx queue %d requesting wakeup, GP1 = 0x%x\n", | ||
317 | txq_id, reg); | ||
318 | iwl_set_bit(trans, CSR_GP_CNTRL, | ||
319 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
320 | return; | ||
321 | } | ||
335 | } | 322 | } |
323 | |||
324 | /* | ||
325 | * if not in power-save mode, uCode will never sleep when we're | ||
326 | * trying to tx (during RFKILL, we're not trying to tx). | ||
327 | */ | ||
328 | IWL_DEBUG_TX(trans, "Q:%d WR: 0x%x\n", txq_id, txq->q.write_ptr); | ||
329 | iwl_write32(trans, HBUS_TARG_WRPTR, txq->q.write_ptr | (txq_id << 8)); | ||
330 | |||
336 | txq->need_update = 0; | 331 | txq->need_update = 0; |
337 | } | 332 | } |
338 | 333 | ||
@@ -1029,7 +1024,7 @@ static void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx) | |||
1029 | if (nfreed++ > 0) { | 1024 | if (nfreed++ > 0) { |
1030 | IWL_ERR(trans, "HCMD skipped: index (%d) %d %d\n", | 1025 | IWL_ERR(trans, "HCMD skipped: index (%d) %d %d\n", |
1031 | idx, q->write_ptr, q->read_ptr); | 1026 | idx, q->write_ptr, q->read_ptr); |
1032 | iwl_trans_fw_error(trans); | 1027 | iwl_write_prph(trans, DEVICE_SET_NMI_REG, 1); |
1033 | } | 1028 | } |
1034 | } | 1029 | } |
1035 | 1030 | ||
@@ -1588,6 +1583,7 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans, | |||
1588 | get_cmd_string(trans_pcie, cmd->id)); | 1583 | get_cmd_string(trans_pcie, cmd->id)); |
1589 | ret = -ETIMEDOUT; | 1584 | ret = -ETIMEDOUT; |
1590 | 1585 | ||
1586 | iwl_write_prph(trans, DEVICE_SET_NMI_REG, 1); | ||
1591 | iwl_trans_fw_error(trans); | 1587 | iwl_trans_fw_error(trans); |
1592 | 1588 | ||
1593 | goto cancel; | 1589 | goto cancel; |