On Mon, Jun 2, 2014 at 11:53 AM, Emmanuel Grumbach <egrumbach@xxxxxxxxx> wrote: > >>>>> >>>>> Anyway, I don't buy the theory that this is caused by the firmware >>>>> going out to lunch. The queues files in debugfs show the rx queue >>>>> chugging along and all of the tx queues have read_ptr == write_ptr. >>>>> Wireshark shows incoming broadcast traffic, too. I'd guess that the >>>>> problem is more likely to be that the card is failing to wake up and >>>>> notice pending data in the TIM. >>> >>> Well... I might have been unclear here (I never know how much detail I should share with the recipient :)). >>> From your log it appears that the NIC is in power save. So we can't increment the write pointer of the Tx ring (add a packet for transmission). So we simply remember that we need to do so (increment the write pointer) and request a wakeup so that we will update the write pointer in the wakeup interrupt... which doesn't happen. >>> No power save - no need for wakeup interrupt. >> >> I'm still unconvinced. One of the tx queues actually has a both >> read_ptr and write_ptr incrementing once or twice per second even when >> I can't ping the gateway. Can you point me at the right code or log >> stuff to look at? > > drivers/net/wireless/iwlwifi/pcie/tx.c: > static void iwl_pcie_txq_inc_wr_ptr(struct iwl_trans *trans, > struct iwl_txq *txq) > [snip] > > if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { > IWL_DEBUG_INFO(trans, "Tx queue %d requesting wakeup, GP1 = 0x%x\n", > txq_id, reg); > iwl_set_bit(trans, CSR_GP_CNTRL, > CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); > txq->need_update = true; > return; > } > [snip] > } > > ISR - drivers/net/wireless/iwlwifi/pcie/tx.c: > irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id) > { > [snip] > /* uCode wakes up after power-down sleep */ > if (inta & CSR_INT_BIT_WAKEUP) { > IWL_DEBUG_ISR(trans, "Wakeup interrupt\n"); > iwl_pcie_rxq_check_wrptr(trans); > iwl_pcie_txq_check_wrptrs(trans); > > isr_stats->wakeup++; > > handled |= CSR_INT_BIT_WAKEUP; > } > [snip] > } > > drivers/net/wireless/iwlwifi/pcie/tx.c: > void iwl_pcie_txq_check_wrptrs(struct iwl_trans *trans) > { > struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); > int i; > > for (i = 0; i < trans->cfg->base_params->num_of_queues; i++) { > struct iwl_txq *txq = &trans_pcie->txq[i]; > > spin_lock_bh(&txq->lock); > if (trans_pcie->txq[i].need_update) { > iwl_pcie_txq_inc_wr_ptr(trans, txq); > trans_pcie->txq[i].need_update = false; > } > spin_unlock_bh(&txq->lock); > } > } > > Note that the CMD queue (9 or 4 depending on your configuration) - uses another mechanism that is safer but consumes more power. This queue is intended for commands and not for real Tx packets. If that's queue 4 in the debugfs tx_queues file, then I think that that's the queue that keeps moving when the card is dead. I'll see if I can improve the tx_queues file to show pending updates. Yay troubleshooting old hardware. --Andy -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html