示例#1
0
/*
 * 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));
}
示例#2
0
/*
 * 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);
}