static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance) { struct rt2x00_dev *rt2x00dev = dev_instance; u32 reg; /* Read status and ACK all interrupts */ rt2800_register_read(rt2x00dev, INT_SOURCE_CSR, ®); rt2800_register_write(rt2x00dev, INT_SOURCE_CSR, reg); if (!reg) return IRQ_NONE; if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) return IRQ_HANDLED; /* * 1 - Rx ring done interrupt. */ if (rt2x00_get_field32(reg, INT_SOURCE_CSR_RX_DONE)) rt2x00pci_rxdone(rt2x00dev); if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) rt2800pci_txdone(rt2x00dev); return IRQ_HANDLED; }
/* * 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); }
static void rt2800pci_txstatus_tasklet(unsigned long data) { rt2800pci_txdone((struct rt2x00_dev *)data); /* * No need to enable the tx status interrupt here as we always * leave it enabled to minimize the possibility of a tx status * register overflow. See comment in interrupt handler. */ }