static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, const enum data_queue_qid queue_idx) { struct data_queue *queue = rt2x00queue_get_tx_queue(rt2x00dev, queue_idx); struct queue_entry_priv_pci *entry_priv; struct queue_entry *entry; struct txdone_entry_desc txdesc; u32 word; while (!rt2x00queue_empty(queue)) { entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); entry_priv = entry->priv_data; rt2x00_desc_read(entry_priv->desc, 0, &word); if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) || !rt2x00_get_field32(word, TXD_W0_VALID)) break; txdesc.flags = 0; switch (rt2x00_get_field32(word, TXD_W0_RESULT)) { case 0: case 1: __set_bit(TXDONE_SUCCESS, &txdesc.flags); break; case 2: __set_bit(TXDONE_EXCESSIVE_RETRY, &txdesc.flags); default: __set_bit(TXDONE_FAILURE, &txdesc.flags); } txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); rt2x00lib_txdone(entry, &txdesc); } }
/* * TX data handlers. */ static void rt2x00usb_interrupt_txdone(struct urb *urb) { struct queue_entry *entry = (struct queue_entry *)urb->context; struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct txdone_entry_desc txdesc; if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags) || !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) return; /* * Obtain the status about this packet. * Note that when the status is 0 it does not mean the * frame was send out correctly. It only means the frame * was succesfully pushed to the hardware, we have no * way to determine the transmission status right now. * (Only indirectly by looking at the failed TX counters * in the register). */ txdesc.flags = 0; if (!urb->status) __set_bit(TXDONE_UNKNOWN, &txdesc.flags); else __set_bit(TXDONE_FAILURE, &txdesc.flags); txdesc.retry = 0; rt2x00lib_txdone(entry, &txdesc); }
void rt2x00lib_txdone_noinfo(struct queue_entry *entry, u32 status) { struct txdone_entry_desc txdesc; txdesc.flags = 0; __set_bit(status, &txdesc.flags); txdesc.retry = 0; rt2x00lib_txdone(entry, &txdesc); }
/* * 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); }
/* * TX data handlers. */ static void rt2x00usb_interrupt_txdone(struct urb *urb) { struct queue_entry *entry = (struct queue_entry *)urb->context; struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct queue_entry_priv_usb_tx *priv_tx = entry->priv_data; struct txdone_entry_desc txdesc; __le32 *txd = (__le32 *)entry->skb->data; u32 word; if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || !__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) return; rt2x00_desc_read(txd, 0, &word); /* * Remove the descriptor data from the buffer. */ skb_pull(entry->skb, entry->queue->desc_size); /* * Obtain the status about this packet. */ txdesc.status = !urb->status ? TX_SUCCESS : TX_FAIL_RETRY; txdesc.retry = 0; txdesc.control = &priv_tx->control; rt2x00lib_txdone(entry, &txdesc); /* * Make this entry available for reuse. */ entry->flags = 0; rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); /* * If the data queue 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. */ if (!rt2x00queue_full(entry->queue)) ieee80211_wake_queue(rt2x00dev->hw, priv_tx->control.queue); }
static void rt2x00usb_interrupt_txdone(struct urb *urb) { struct queue_entry *entry = (struct queue_entry *)urb->context; struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct txdone_entry_desc txdesc; if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags) || !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) return; txdesc.flags = 0; if (!urb->status) __set_bit(TXDONE_UNKNOWN, &txdesc.flags); else __set_bit(TXDONE_FAILURE, &txdesc.flags); txdesc.retry = 0; rt2x00lib_txdone(entry, &txdesc); }
/* * Interrupt functions. */ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, const enum data_queue_qid queue_idx) { struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); struct queue_entry_priv_pci *entry_priv; struct queue_entry *entry; struct txdone_entry_desc txdesc; u32 word; while (!rt2x00queue_empty(queue)) { entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); entry_priv = entry->priv_data; rt2x00_desc_read(entry_priv->desc, 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. */ txdesc.flags = 0; switch (rt2x00_get_field32(word, TXD_W0_RESULT)) { case 0: /* Success */ case 1: /* Success with retry */ __set_bit(TXDONE_SUCCESS, &txdesc.flags); break; case 2: /* Failure, excessive retries */ __set_bit(TXDONE_EXCESSIVE_RETRY, &txdesc.flags); /* Don't break, this is a failed frame! */ default: /* Failure */ __set_bit(TXDONE_FAILURE, &txdesc.flags); } txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); rt2x00lib_txdone(entry, &txdesc); } }
/* * Interrupt functions. */ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) { struct data_queue *queue; struct queue_entry *entry; struct queue_entry *entry_done; struct queue_entry_priv_pci *entry_priv; struct txdone_entry_desc txdesc; u32 word; u32 reg; u32 old_reg; unsigned int type; unsigned int index; u16 mcs, real_mcs; /* * During each loop we will compare the freshly read * TX_STA_FIFO register value with the value read from * the previous loop. If the 2 values are equal then * we should stop processing because the chance it * quite big that the device has been unplugged and * we risk going into an endless loop. */ old_reg = 0; while (1) { rt2800_register_read(rt2x00dev, TX_STA_FIFO, ®); if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID)) break; if (old_reg == reg) break; old_reg = reg; /* * Skip this entry when it contains an invalid * queue identication number. */ type = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE) - 1; if (type >= QID_RX) continue; queue = rt2x00queue_get_queue(rt2x00dev, type); if (unlikely(!queue)) continue; /* * Skip this entry when it contains an invalid * index number. */ index = rt2x00_get_field32(reg, TX_STA_FIFO_WCID) - 1; if (unlikely(index >= queue->limit)) continue; entry = &queue->entries[index]; entry_priv = entry->priv_data; rt2x00_desc_read((__le32 *)entry->skb->data, 0, &word); entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE); while (entry != entry_done) { /* * Catch up. * Just report any entries we missed as failed. */ WARNING(rt2x00dev, "TX status report missed for entry %d\n", entry_done->entry_idx); txdesc.flags = 0; __set_bit(TXDONE_UNKNOWN, &txdesc.flags); txdesc.retry = 0; rt2x00lib_txdone(entry_done, &txdesc); entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE); } /* * Obtain the status about this packet. */ txdesc.flags = 0; if (rt2x00_get_field32(reg, TX_STA_FIFO_TX_SUCCESS)) __set_bit(TXDONE_SUCCESS, &txdesc.flags); else __set_bit(TXDONE_FAILURE, &txdesc.flags); /* * Ralink has a retry mechanism using a global fallback * table. We setup this fallback table to try immediate * lower rate for all rates. In the TX_STA_FIFO, * the MCS field contains the MCS used for the successfull * transmission. If the first transmission succeed, * we have mcs == tx_mcs. On the second transmission, * we have mcs = tx_mcs - 1. So the number of * retry is (tx_mcs - mcs). */ mcs = rt2x00_get_field32(word, TXWI_W0_MCS); real_mcs = rt2x00_get_field32(reg, TX_STA_FIFO_MCS); __set_bit(TXDONE_FALLBACK, &txdesc.flags); txdesc.retry = mcs - min(mcs, real_mcs); rt2x00lib_txdone(entry, &txdesc); } }