static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue) { rt2x00_warn(queue->rt2x00dev, "TX queue %d DMA timed out, invoke forced forced reset\n", queue->qid); rt2x00queue_flush_queue(queue, true); }
static inline bool rt2800usb_entry_txstatus_timeout(struct queue_entry *entry) { bool tout; if (!test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) return false; tout = time_after(jiffies, entry->last_action + msecs_to_jiffies(100)); if (unlikely(tout)) rt2x00_warn(entry->queue->rt2x00dev, "TX status timeout for entry %d in queue %d\n", entry->entry_idx, entry->queue->qid); return tout; }
static bool rt2x00usb_kick_tx_entry(struct queue_entry *entry, void *data) { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); struct queue_entry_priv_usb *entry_priv = entry->priv_data; u32 length; int status; if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags) || test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) return false; /* * USB devices require certain padding at the end of each frame * and urb. Those paddings are not included in skbs. Pass entry * to the driver to determine what the overall length should be. */ length = rt2x00dev->ops->lib->get_tx_data_len(entry); status = skb_padto(entry->skb, length); if (unlikely(status)) { /* TODO: report something more appropriate than IO_FAILED. */ rt2x00_warn(rt2x00dev, "TX SKB padding error, out of memory\n"); set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); rt2x00lib_dmadone(entry); return false; } usb_fill_bulk_urb(entry_priv->urb, usb_dev, usb_sndbulkpipe(usb_dev, entry->queue->usb_endpoint), entry->skb->data, length, rt2x00usb_interrupt_txdone, entry); usb_anchor_urb(entry_priv->urb, rt2x00dev->anchor); status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC); if (status) { usb_unanchor_urb(entry_priv->urb); if (status == -ENODEV) clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); rt2x00lib_dmadone(entry); } return false; }
static void rt2800pci_txstatus_interrupt(struct rt2x00_dev *rt2x00dev) { u32 status; int i; /* * The TX_FIFO_STATUS interrupt needs special care. We should * read TX_STA_FIFO but we should do it immediately as otherwise * the register can overflow and we would lose status reports. * * Hence, read the TX_STA_FIFO register and copy all tx status * reports into a kernel FIFO which is handled in the txstatus * tasklet. We use a tasklet to process the tx status reports * because we can schedule the tasklet multiple times (when the * interrupt fires again during tx status processing). * * Furthermore we don't disable the TX_FIFO_STATUS * interrupt here but leave it enabled so that the TX_STA_FIFO * can also be read while the tx status tasklet gets executed. * * Since we have only one producer and one consumer we don't * need to lock the kfifo. */ for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) { rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO, &status); if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID)) break; if (!kfifo_put(&rt2x00dev->txstatus_fifo, &status)) { rt2x00_warn(rt2x00dev, "TX status FIFO overrun, drop tx status report\n"); break; } } /* Schedule the tasklet for processing the tx status. */ tasklet_schedule(&rt2x00dev->txstatus_tasklet); }
static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, struct data_queue *queue, struct sk_buff *frag_skb) { struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(frag_skb); struct ieee80211_tx_info *rts_info; struct sk_buff *skb; unsigned int data_length; int retval = 0; if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) data_length = sizeof(struct ieee80211_cts); else data_length = sizeof(struct ieee80211_rts); skb = dev_alloc_skb(data_length + rt2x00dev->hw->extra_tx_headroom); if (unlikely(!skb)) { rt2x00_warn(rt2x00dev, "Failed to create RTS/CTS frame\n"); return -ENOMEM; } skb_reserve(skb, rt2x00dev->hw->extra_tx_headroom); skb_put(skb, data_length); /* * Copy TX information over from original frame to * RTS/CTS frame. Note that we set the no encryption flag * since we don't want this frame to be encrypted. * RTS frames should be acked, while CTS-to-self frames * should not. The ready for TX flag is cleared to prevent * it being automatically send when the descriptor is * written to the hardware. */ memcpy(skb->cb, frag_skb->cb, sizeof(skb->cb)); rts_info = IEEE80211_SKB_CB(skb); rts_info->control.rates[0].flags &= ~IEEE80211_TX_RC_USE_RTS_CTS; rts_info->control.rates[0].flags &= ~IEEE80211_TX_RC_USE_CTS_PROTECT; if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) rts_info->flags |= IEEE80211_TX_CTL_NO_ACK; else rts_info->flags &= ~IEEE80211_TX_CTL_NO_ACK; /* Disable hardware encryption */ rts_info->control.hw_key = NULL; /* * RTS/CTS frame should use the length of the frame plus any * encryption overhead that will be added by the hardware. */ data_length += rt2x00crypto_tx_overhead(rt2x00dev, skb); if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) ieee80211_ctstoself_get(rt2x00dev->hw, tx_info->control.vif, frag_skb->data, data_length, tx_info, (struct ieee80211_cts *)(skb->data)); else ieee80211_rts_get(rt2x00dev->hw, tx_info->control.vif, frag_skb->data, data_length, tx_info, (struct ieee80211_rts *)(skb->data)); retval = rt2x00queue_write_tx_frame(queue, skb, NULL, true); if (retval) { dev_kfree_skb_any(skb); rt2x00_warn(rt2x00dev, "Failed to send RTS/CTS frame\n"); } return retval; }
static bool rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) { struct data_queue *queue; 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. */ rt2x00_warn(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 */ rt2x00_warn(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. */ rt2x00_warn(rt2x00dev, "Got TX status for an empty queue %u, dropping\n", qid); break; } /* * Let's associate this tx status with the first * matching frame. */ if (!rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, &status, rt2800pci_txdone_find_entry)) { /* * We cannot match the tx status to any frame, so just * use the first one. */ if (!rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, &status, rt2800pci_txdone_match_first)) { rt2x00_warn(rt2x00dev, "No frame found for TX status on queue %u, dropping\n", qid); break; } } /* * Release all frames with a valid tx status. */ rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, NULL, rt2800pci_txdone_release_entries); if (--max_tx_done == 0) break; } return !max_tx_done; }