>>>> >>>> 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. > >> >>> >>> OTOH, with iwlwifi.11n_disable=4 (no rx A-MPDU), I seem to be doing >>> pretty well. I'll test a stock kernel configured like that for the >>> next few days. >>> >> >> That's interesting... > > --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