Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 214278
b: refs/heads/master
c: 652a9dd
h: refs/heads/master
v: v3
  • Loading branch information
Ivo van Doorn authored and John W. Linville committed Aug 31, 2010
1 parent 52baa84 commit d8cc808
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 15 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0e3afe5b20c4ccdeff5178c62b557a917945a828
refs/heads/master: 652a9dd2a0c07251e328519cc23f1316ab13ed51
1 change: 1 addition & 0 deletions trunk/drivers/net/wireless/rt2x00/rt2x00.h
Original file line number Diff line number Diff line change
Expand Up @@ -1070,6 +1070,7 @@ static inline void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
*/
void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev);
void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev);
void rt2x00lib_dmadone(struct queue_entry *entry);
void rt2x00lib_txdone(struct queue_entry *entry,
struct txdone_entry_desc *txdesc);
void rt2x00lib_txdone_noinfo(struct queue_entry *entry, u32 status);
Expand Down
5 changes: 3 additions & 2 deletions trunk/drivers/net/wireless/rt2x00/rt2x00debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,14 +338,15 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file,
return -ENOMEM;

temp = data +
sprintf(data, "qid\tcount\tlimit\tlength\tindex\tdone\n");
sprintf(data, "qid\tcount\tlimit\tlength\tindex\tdma done\tdone\n");

queue_for_each(intf->rt2x00dev, queue) {
spin_lock_irqsave(&queue->lock, irqflags);

temp += sprintf(temp, "%d\t%d\t%d\t%d\t%d\t%d\n", queue->qid,
temp += sprintf(temp, "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", queue->qid,
queue->count, queue->limit, queue->length,
queue->index[Q_INDEX],
queue->index[Q_INDEX_DMA_DONE],
queue->index[Q_INDEX_DONE]);

spin_unlock_irqrestore(&queue->lock, irqflags);
Expand Down
6 changes: 6 additions & 0 deletions trunk/drivers/net/wireless/rt2x00/rt2x00dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,12 @@ void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev)
}
EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt);

void rt2x00lib_dmadone(struct queue_entry *entry)
{
rt2x00queue_index_inc(entry->queue, Q_INDEX_DMA_DONE);
}
EXPORT_SYMBOL_GPL(rt2x00lib_dmadone);

void rt2x00lib_txdone(struct queue_entry *entry,
struct txdone_entry_desc *txdesc)
{
Expand Down
13 changes: 8 additions & 5 deletions trunk/drivers/net/wireless/rt2x00/rt2x00queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -731,13 +731,13 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index)
if (queue->index[index] >= queue->limit)
queue->index[index] = 0;

queue->last_action[index] = jiffies;

if (index == Q_INDEX) {
queue->length++;
queue->last_index = jiffies;
} else if (index == Q_INDEX_DONE) {
queue->length--;
queue->count++;
queue->last_index_done = jiffies;
}

spin_unlock_irqrestore(&queue->lock, irqflags);
Expand All @@ -746,14 +746,17 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index)
static void rt2x00queue_reset(struct data_queue *queue)
{
unsigned long irqflags;
unsigned int i;

spin_lock_irqsave(&queue->lock, irqflags);

queue->count = 0;
queue->length = 0;
queue->last_index = jiffies;
queue->last_index_done = jiffies;
memset(queue->index, 0, sizeof(queue->index));

for (i = 0; i < Q_INDEX_MAX; i++) {
queue->index[i] = 0;
queue->last_action[i] = jiffies;
}

spin_unlock_irqrestore(&queue->lock, irqflags);
}
Expand Down
21 changes: 17 additions & 4 deletions trunk/drivers/net/wireless/rt2x00/rt2x00queue.h
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,8 @@ struct queue_entry {
*
* @Q_INDEX: Index pointer to the current entry in the queue, if this entry is
* owned by the hardware then the queue is considered to be full.
* @Q_INDEX_DMA_DONE: Index pointer for the next entry which will have been
* transfered to the hardware.
* @Q_INDEX_DONE: Index pointer to the next entry which will be completed by
* the hardware and for which we need to run the txdone handler. If this
* entry is not owned by the hardware the queue is considered to be empty.
Expand All @@ -409,6 +411,7 @@ struct queue_entry {
*/
enum queue_index {
Q_INDEX,
Q_INDEX_DMA_DONE,
Q_INDEX_DONE,
Q_INDEX_MAX,
};
Expand Down Expand Up @@ -445,13 +448,12 @@ struct data_queue {
enum data_queue_qid qid;

spinlock_t lock;
unsigned long last_index;
unsigned long last_index_done;
unsigned int count;
unsigned short limit;
unsigned short threshold;
unsigned short length;
unsigned short index[Q_INDEX_MAX];
unsigned long last_action[Q_INDEX_MAX];

unsigned short txop;
unsigned short aifs;
Expand Down Expand Up @@ -616,12 +618,23 @@ static inline int rt2x00queue_threshold(struct data_queue *queue)
}

/**
* rt2x00queue_timeout - Check if a timeout occured for this queue
* rt2x00queue_timeout - Check if a timeout occured for STATUS reorts
* @queue: Queue to check.
*/
static inline int rt2x00queue_timeout(struct data_queue *queue)
{
return time_after(queue->last_index, queue->last_index_done + (HZ / 10));
return time_after(queue->last_action[Q_INDEX_DMA_DONE],
queue->last_action[Q_INDEX_DONE] + (HZ / 10));
}

/**
* rt2x00queue_timeout - Check if a timeout occured for DMA transfers
* @queue: Queue to check.
*/
static inline int rt2x00queue_dma_timeout(struct data_queue *queue)
{
return time_after(queue->last_action[Q_INDEX],
queue->last_action[Q_INDEX_DMA_DONE] + (HZ / 10));
}

/**
Expand Down
27 changes: 24 additions & 3 deletions trunk/drivers/net/wireless/rt2x00/rt2x00usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,11 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
!__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
return;

/*
* Report the frame as DMA done
*/
rt2x00lib_dmadone(entry);

/*
* Check if the frame was correctly uploaded
*/
Expand Down Expand Up @@ -283,13 +288,14 @@ void rt2x00usb_kill_tx_queue(struct data_queue *queue)
}
EXPORT_SYMBOL_GPL(rt2x00usb_kill_tx_queue);

static void rt2x00usb_watchdog_reset_tx(struct data_queue *queue)
static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue)
{
struct queue_entry *entry;
struct queue_entry_priv_usb *entry_priv;
unsigned short threshold = queue->threshold;

WARNING(queue->rt2x00dev, "TX queue %d timed out, invoke reset", queue->qid);
WARNING(queue->rt2x00dev, "TX queue %d DMA timed out,"
" invoke forced forced reset", queue->qid);

/*
* Temporarily disable the TX queue, this will force mac80211
Expand Down Expand Up @@ -331,13 +337,23 @@ static void rt2x00usb_watchdog_reset_tx(struct data_queue *queue)
ieee80211_wake_queue(queue->rt2x00dev->hw, queue->qid);
}

static void rt2x00usb_watchdog_tx_status(struct data_queue *queue)
{
WARNING(queue->rt2x00dev, "TX queue %d status timed out,"
" invoke forced tx handler", queue->qid);

ieee80211_queue_work(queue->rt2x00dev->hw, &queue->rt2x00dev->txdone_work);
}

void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev)
{
struct data_queue *queue;

tx_queue_for_each(rt2x00dev, queue) {
if (rt2x00queue_dma_timeout(queue))
rt2x00usb_watchdog_tx_dma(queue);
if (rt2x00queue_timeout(queue))
rt2x00usb_watchdog_reset_tx(queue);
rt2x00usb_watchdog_tx_status(queue);
}
}
EXPORT_SYMBOL_GPL(rt2x00usb_watchdog);
Expand Down Expand Up @@ -382,6 +398,11 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
!__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
return;

/*
* Report the frame as DMA done
*/
rt2x00lib_dmadone(entry);

/*
* Check if the received data is simply too small
* to be actually valid, or if the urb is signaling
Expand Down

0 comments on commit d8cc808

Please sign in to comment.