diff options
| author | Ivo van Doorn <ivdoorn@gmail.com> | 2010-12-13 12:35:40 +0100 | 
|---|---|---|
| committer | John W. Linville <linville@tuxdriver.com> | 2010-12-13 15:23:35 -0500 | 
| commit | 5be65609fec2e331c7d804471be3d59089a30d98 (patch) | |
| tree | 6c6967c7835d6ec3a8ce79c2c9b84bf95aefca31 /drivers/net/wireless/rt2x00/rt2x00usb.c | |
| parent | 0b7fde54f94979edc67bbf86b5adba702ebfefe8 (diff) | |
rt2x00: Add "flush" queue command
Add a new command to the queue handlers: "flush",
this moves the flush() callback from mac80211
into rt2x00queue and adds support for flushing
the RX queue as well.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Acked-by: Helmut Schaa <helmut.schaa@googlemail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00usb.c')
| -rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00usb.c | 70 | 
1 files changed, 47 insertions, 23 deletions
| diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index fca29ae57e71..cd80eec5ff51 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -366,7 +366,7 @@ void rt2x00usb_kick_queue(struct data_queue *queue)  }  EXPORT_SYMBOL_GPL(rt2x00usb_kick_queue); -static void rt2x00usb_kill_entry(struct queue_entry *entry) +static void rt2x00usb_flush_entry(struct queue_entry *entry)  {  	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;  	struct queue_entry_priv_usb *entry_priv = entry->priv_data; @@ -385,37 +385,61 @@ static void rt2x00usb_kill_entry(struct queue_entry *entry)  		usb_kill_urb(bcn_priv->guardian_urb);  } -void rt2x00usb_stop_queue(struct data_queue *queue) +void rt2x00usb_flush_queue(struct data_queue *queue)  { +	struct work_struct *completion; +	unsigned int i; +  	rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, -				   rt2x00usb_kill_entry); +				   rt2x00usb_flush_entry); + +	/* +	 * Obtain the queue completion handler +	 */ +	switch (queue->qid) { +	case QID_AC_BE: +	case QID_AC_BK: +	case QID_AC_VI: +	case QID_AC_VO: +		completion = &queue->rt2x00dev->txdone_work; +		break; +	case QID_RX: +		completion = &queue->rt2x00dev->rxdone_work; +		break; +	default: +		return; +	} + +	for (i = 0; i < 20; i++) { +		/* +		 * Check if the driver is already done, otherwise we +		 * have to sleep a little while to give the driver/hw +		 * the oppurtunity to complete interrupt process itself. +		 */ +		if (rt2x00queue_empty(queue)) +			break; + +		/* +		 * Schedule the completion handler manually, when this +		 * worker function runs, it should cleanup the queue. +		 */ +		ieee80211_queue_work(queue->rt2x00dev->hw, completion); + +		/* +		 * Wait for a little while to give the driver +		 * the oppurtunity to recover itself. +		 */ +		msleep(10); +	}  } -EXPORT_SYMBOL_GPL(rt2x00usb_stop_queue); +EXPORT_SYMBOL_GPL(rt2x00usb_flush_queue);  static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue)  { -	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; -  	WARNING(queue->rt2x00dev, "TX queue %d DMA timed out,"  		" invoke forced forced reset\n", queue->qid); -	/* -	 * Temporarily disable the TX queue, this will force mac80211 -	 * to use the other queues until this queue has been restored. -	 */ -	rt2x00queue_stop_queue(queue); - -	/* -	 * In case that a driver has overriden the txdone_work -	 * function, we invoke the TX done through there. -	 */ -	rt2x00dev->txdone_work.func(&rt2x00dev->txdone_work); - -	/* -	 * The queue has been reset, and mac80211 is allowed to use the -	 * queue again. -	 */ -	rt2x00queue_start_queue(queue); +	rt2x00queue_flush_queue(queue, true);  }  static void rt2x00usb_watchdog_tx_status(struct data_queue *queue) | 
