Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0b7fde54 authored by Ivo van Doorn's avatar Ivo van Doorn Committed by John W. Linville
Browse files

rt2x00: Protect queue control with mutex



Add wrapper functions in rt2x00queue.c to
start & stop queues. This control must be protected
using a mutex.

Queues can also be paused which will halt the flow
of packets between the driver and mac80211. This doesn't
require a mutex protection.

Signed-off-by: default avatarIvo van Doorn <IvDoorn@gmail.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent dbba306f
Loading
Loading
Loading
Loading
+52 −0
Original line number Diff line number Diff line
@@ -1073,6 +1073,58 @@ struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev,
struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue,
					  enum queue_index index);

/**
 * rt2x00queue_pause_queue - Pause a data queue
 * @queue: Pointer to &struct data_queue.
 *
 * This function will pause the data queue locally, preventing
 * new frames to be added to the queue (while the hardware is
 * still allowed to run).
 */
void rt2x00queue_pause_queue(struct data_queue *queue);

/**
 * rt2x00queue_unpause_queue - unpause a data queue
 * @queue: Pointer to &struct data_queue.
 *
 * This function will unpause the data queue locally, allowing
 * new frames to be added to the queue again.
 */
void rt2x00queue_unpause_queue(struct data_queue *queue);

/**
 * rt2x00queue_start_queue - Start a data queue
 * @queue: Pointer to &struct data_queue.
 *
 * This function will start handling all pending frames in the queue.
 */
void rt2x00queue_start_queue(struct data_queue *queue);

/**
 * rt2x00queue_stop_queue - Halt a data queue
 * @queue: Pointer to &struct data_queue.
 *
 * This function will stop all pending frames in the queue.
 */
void rt2x00queue_stop_queue(struct data_queue *queue);

/**
 * rt2x00queue_start_queues - Start all data queues
 * @rt2x00dev: Pointer to &struct rt2x00_dev.
 *
 * This function will loop through all available queues to start them
 */
void rt2x00queue_start_queues(struct rt2x00_dev *rt2x00dev);

/**
 * rt2x00queue_stop_queues - Halt all data queues
 * @rt2x00dev: Pointer to &struct rt2x00_dev.
 *
 * This function will loop through all available queues to stop
 * any pending frames.
 */
void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev);

/*
 * Debugfs handlers.
 */
+2 −2
Original line number Diff line number Diff line
@@ -146,7 +146,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
	 * else the changes will be ignored by the device.
	 */
	if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
		rt2x00dev->ops->lib->stop_queue(rt2x00dev->rx);
		rt2x00queue_stop_queue(rt2x00dev->rx);

	/*
	 * Write new antenna setup to device and reset the link tuner.
@@ -160,7 +160,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
	memcpy(active, &config, sizeof(config));

	if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
		rt2x00dev->ops->lib->start_queue(rt2x00dev->rx);
		rt2x00queue_start_queue(rt2x00dev->rx);
}

void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
+3 −2
Original line number Diff line number Diff line
@@ -339,12 +339,13 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file,
		return -ENOMEM;

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

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

		temp += sprintf(temp, "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", queue->qid,
		temp += sprintf(temp, "%d\t0x%.8x\t%d\t%d\t%d\t%d\t%d\t\t%d\n",
				queue->qid, (unsigned int)queue->flags,
				queue->count, queue->limit, queue->length,
				queue->index[Q_INDEX],
				queue->index[Q_INDEX_DMA_DONE],
+5 −17
Original line number Diff line number Diff line
@@ -66,9 +66,9 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)
	set_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags);

	/*
	 * Enable RX.
	 * Enable queues.
	 */
	rt2x00dev->ops->lib->start_queue(rt2x00dev->rx);
	rt2x00queue_start_queues(rt2x00dev);
	rt2x00link_start_tuner(rt2x00dev);

	/*
@@ -76,11 +76,6 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)
	 */
	rt2x00link_start_watchdog(rt2x00dev);

	/*
	 * Start the TX queues.
	 */
	ieee80211_wake_queues(rt2x00dev->hw);

	return 0;
}

@@ -89,22 +84,16 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev)
	if (!test_and_clear_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
		return;

	/*
	 * Stop the TX queues in mac80211.
	 */
	ieee80211_stop_queues(rt2x00dev->hw);
	rt2x00queue_stop_queues(rt2x00dev);

	/*
	 * Stop watchdog monitoring.
	 */
	rt2x00link_stop_watchdog(rt2x00dev);

	/*
	 * Disable RX.
	 * Stop all queues
	 */
	rt2x00link_stop_tuner(rt2x00dev);
	rt2x00dev->ops->lib->stop_queue(rt2x00dev->rx);
	rt2x00queue_stop_queues(rt2x00dev);

	/*
	 * Disable radio.
@@ -249,7 +238,6 @@ void rt2x00lib_txdone(struct queue_entry *entry,
	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
	enum data_queue_qid qid = skb_get_queue_mapping(entry->skb);
	unsigned int header_length, i;
	u8 rate_idx, rate_flags, retry_rates;
	u8 skbdesc_flags = skbdesc->flags;
@@ -403,7 +391,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
	 * is reenabled when the txdone handler has finished.
	 */
	if (!rt2x00queue_threshold(entry->queue))
		ieee80211_wake_queue(rt2x00dev->hw, qid);
		rt2x00queue_unpause_queue(entry->queue);
}
EXPORT_SYMBOL_GPL(rt2x00lib_txdone);

+0 −9
Original line number Diff line number Diff line
@@ -177,15 +177,6 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
 */
void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index);

/**
 * rt2x00queue_stop_queues - Halt all data queues
 * @rt2x00dev: Pointer to &struct rt2x00_dev.
 *
 * This function will loop through all available queues to stop
 * any pending outgoing frames.
 */
void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev);

/**
 * rt2x00queue_init_queues - Initialize all data queues
 * @rt2x00dev: Pointer to &struct rt2x00_dev.
Loading