/* * Interrupt routines. * rt2x00_interrupt_txdone processes all transmitted packetss results. * rt2x00_interrupt_rxdone processes all received rx packets. */ static void rt2x00_interrupt_txdone(struct _data_ring * ring) { struct rtwlan_device * rtwlan = rtnetdev_priv(ring->device->rtnet_dev); struct _txd *txd = NULL; u8 tx_result = 0x00; /* u8 retry_count = 0x00; */ do{ txd = DESC_ADDR_DONE(ring); if(rt2x00_get_field32(txd->word0, TXD_W0_OWNER_NIC) || !rt2x00_get_field32(txd->word0, TXD_W0_VALID)) break; if(ring->ring_type == RING_TX){ tx_result = rt2x00_get_field32(txd->word0, TXD_W0_RESULT); /* retry_count = rt2x00_get_field32(txd->word0, TXD_W0_RETRY_COUNT); */ switch(tx_result) { case TX_SUCCESS: rtwlan->stats.tx_packets++; break; case TX_SUCCESS_RETRY: rtwlan->stats.tx_retry++; break; case TX_FAIL_RETRY: DEBUG("TX_FAIL_RETRY.\n"); break; case TX_FAIL_INVALID: DEBUG("TX_FAIL_INVALID.\n"); break; case TX_FAIL_OTHER: DEBUG("TX_FAIL_OTHER.\n"); break; default: DEBUG("Unknown tx result.\n"); } } rt2x00_set_field32(&txd->word0, TXD_W0_VALID, 0); rt2x00_ring_index_done_inc(ring); }while(!rt2x00_ring_empty(ring)); }
/* * Interrupt functions. */ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, const int queue) { struct data_ring *ring = rt2x00lib_get_ring(rt2x00dev, queue); struct data_entry *entry; struct data_desc *txd; u32 word; int tx_status; int retry; while (!rt2x00_ring_empty(ring)) { entry = rt2x00_get_data_entry_done(ring); txd = entry->priv; rt2x00_desc_read(txd, 0, &word); if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) || !rt2x00_get_field32(word, TXD_W0_VALID)) break; /* * Obtain the status about this packet. */ tx_status = rt2x00_get_field32(word, TXD_W0_RESULT); retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); rt2x00lib_txdone(entry, tx_status, retry); /* * Make this entry available for reuse. */ entry->flags = 0; rt2x00_set_field32(&word, TXD_W0_VALID, 0); rt2x00_desc_write(txd, 0, word); rt2x00_ring_index_done_inc(ring); } /* * If the data ring was full before the txdone handler * we must make sure the packet queue in the mac80211 stack * is reenabled when the txdone handler has finished. */ entry = ring->entry; if (!rt2x00_ring_full(ring)) ieee80211_wake_queue(rt2x00dev->hw, entry->tx_status.control.queue); }