Ejemplo n.º 1
0
/*
 * 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 void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
{
	struct data_queue *queue;
	struct queue_entry *entry;
	u32 status;
	u8 qid;

	while (kfifo_get(&rt2x00dev->txstatus_fifo, &status)) {
		qid = rt2x00_get_field32(status, TX_STA_FIFO_PID_QUEUE);
		if (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_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 (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);
	}
}

static void rt2800pci_txstatus_tasklet(unsigned long data)
{
	rt2800pci_txdone((struct rt2x00_dev *)data);
}
Ejemplo n.º 2
0
/*
 * 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_entry_check(struct queue_entry *entry, u32 status)
{
	__le32 *txwi;
	u32 word;
	int wcid, tx_wcid;

	wcid = rt2x00_get_field32(status, TX_STA_FIFO_WCID);

	txwi = rt2800_drv_get_txwi(entry);
	rt2x00_desc_read(txwi, 1, &word);
	tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID);

	return (tx_wcid == wcid);
}
Ejemplo n.º 3
0
/*
 * 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);
}