Exemple #1
0
static bool rt2800pci_txdone_release_entries(struct queue_entry *entry,
					     void *data)
{
	if (test_bit(ENTRY_DATA_STATUS_SET, &entry->flags)) {
		rt2800_txdone_entry(entry, entry->status,
				    rt2800pci_get_txwi(entry));
		return false;
	}

	/* No more frames to release */
	return true;
}
/*
 * Interrupt functions.
 */
static void rt2800pci_wakeup(struct rt2x00_dev *rt2x00dev)
{
    struct ieee80211_conf conf = { .flags = 0 };
    struct rt2x00lib_conf libconf = { .conf = &conf };

    rt2800_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS);
}

static bool rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
{
    struct data_queue *queue;
    struct queue_entry *entry;
    u32 status;
    u8 qid;
    int max_tx_done = 16;

    while (kfifo_get(&rt2x00dev->txstatus_fifo, &status)) {
        qid = rt2x00_get_field32(status, TX_STA_FIFO_PID_QUEUE);
        if (unlikely(qid >= QID_RX)) {
            /*
             * Unknown queue, this shouldn't happen. Just drop
             * this tx status.
             */
            WARNING(rt2x00dev, "Got TX status report with "
                    "unexpected pid %u, dropping\n", qid);
            break;
        }

        queue = rt2x00queue_get_tx_queue(rt2x00dev, qid);
        if (unlikely(queue == NULL)) {
            /*
             * The queue is NULL, this shouldn't happen. Stop
             * processing here and drop the tx status
             */
            WARNING(rt2x00dev, "Got TX status for an unavailable "
                    "queue %u, dropping\n", qid);
            break;
        }

        if (unlikely(rt2x00queue_empty(queue))) {
            /*
             * The queue is empty. Stop processing here
             * and drop the tx status.
             */
            WARNING(rt2x00dev, "Got TX status for an empty "
                    "queue %u, dropping\n", qid);
            break;
        }

        entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
        rt2800_txdone_entry(entry, status, rt2800pci_get_txwi(entry));

        if (--max_tx_done == 0)
            break;
    }

    return !max_tx_done;
}

static inline void rt2800pci_enable_interrupt(struct rt2x00_dev *rt2x00dev,
        struct rt2x00_field32 irq_field)
{
    u32 reg;

    /*
     * Enable a single interrupt. The interrupt mask register
     * access needs locking.
     */
    spin_lock_irq(&rt2x00dev->irqmask_lock);
    rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, &reg);
    rt2x00_set_field32(&reg, irq_field, 1);
    rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg);
    spin_unlock_irq(&rt2x00dev->irqmask_lock);
}