[rt2x00-users] [PATCH 2/8] rt2x00: Validate TX status results with current data entry

Gertjan van Wingerde gwingerde at gmail.com
Mon Aug 30 18:09:39 UTC 2010


On 08/30/10 19:23, Ivo van Doorn wrote:
> Instead of printing a warning when the PID, ACK, or WCID of
> an entry don't match the TX status report, we should skip the
> entry to search for the entry which actually does match
> the TX status data.
> 
> This reduces the number of watchdog errors on the TX queues
> for rt2800usb, and seems to improve the reliability of the
> TX flow a bit.
> 
> Signed-off-by: Ivo van Doorn <IvDoorn at gmail.com>

Acked-by: Gertjan van Wingerde <gwingerde at gmail.com>

> ---
>  drivers/net/wireless/rt2x00/rt2800lib.c |   73 +++++++++++++++++++++----------
>  1 files changed, 50 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
> index 967f3e5..c8af221 100644
> --- a/drivers/net/wireless/rt2x00/rt2800lib.c
> +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
> @@ -581,6 +581,49 @@ void rt2800_process_rxwi(struct queue_entry *entry,
>  }
>  EXPORT_SYMBOL_GPL(rt2800_process_rxwi);
>  
> +static bool rt2800_txdone_entry_check(struct queue_entry *entry, u32 reg)
> +{
> +	__le32 *txwi;
> +	u32 word;
> +	int wcid, ack, pid;
> +	int tx_wcid, tx_ack, tx_pid;
> +
> +	wcid	= rt2x00_get_field32(reg, TX_STA_FIFO_WCID);
> +	ack	= rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);
> +	pid	= rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE);
> +
> +	/*
> +	 * This frames has returned with an IO error,
> +	 * so the status report is not intended for this
> +	 * frame.
> +	 */
> +	if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) {
> +		rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE);
> +		return false;
> +	}
> +
> +	/*
> +	 * Validate if this TX status report is intended for
> +	 * this entry by comparing the WCID/ACK/PID fields.
> +	 */
> +	txwi = rt2800_drv_get_txwi(entry);
> +
> +	rt2x00_desc_read(txwi, 1, &word);
> +	tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID);
> +	tx_ack  = rt2x00_get_field32(word, TXWI_W1_ACK);
> +	tx_pid  = rt2x00_get_field32(word, TXWI_W1_PACKETID);
> +
> +	if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) {
> +		WARNING(entry->queue->rt2x00dev,
> +			"TX status report missed for queue %d entry %d\n",
> +		entry->queue->qid, entry->entry_idx);
> +		rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN);
> +		return false;
> +	}
> +
> +	return true;
> +}
> +
>  void rt2800_txdone(struct rt2x00_dev *rt2x00dev)
>  {
>  	struct data_queue *queue;
> @@ -589,8 +632,8 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev)
>  	struct txdone_entry_desc txdesc;
>  	u32 word;
>  	u32 reg;
> -	int wcid, ack, pid, tx_wcid, tx_ack, tx_pid;
>  	u16 mcs, real_mcs;
> +	u8 pid;
>  	int i;
>  
>  	/*
> @@ -607,18 +650,15 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev)
>  		if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID))
>  			break;
>  
> -		wcid	= rt2x00_get_field32(reg, TX_STA_FIFO_WCID);
> -		ack	= rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);
> -		pid	= rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE);
> -
>  		/*
>  		 * Skip this entry when it contains an invalid
>  		 * queue identication number.
>  		 */
> -		if (pid <= 0 || pid > QID_RX)
> +		pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE) - 1;
> +		if (pid >= QID_RX)
>  			continue;
>  
> -		queue = rt2x00queue_get_queue(rt2x00dev, pid - 1);
> +		queue = rt2x00queue_get_queue(rt2x00dev, pid);
>  		if (unlikely(!queue))
>  			continue;
>  
> @@ -627,35 +667,22 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev)
>  		 * order. We first check that the queue is not empty.
>  		 */
>  		entry = NULL;
> +		txwi = NULL;
>  		while (!rt2x00queue_empty(queue)) {
>  			entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
> -			if (!test_bit(ENTRY_DATA_IO_FAILED, &entry->flags))
> +			if (rt2800_txdone_entry_check(entry, reg))
>  				break;
> -
> -			rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE);
>  		}
>  
>  		if (!entry || rt2x00queue_empty(queue))
>  			break;
>  
> -		/*
> -		 * Check if we got a match by looking at WCID/ACK/PID
> -		 * fields
> -		 */
> -		txwi = rt2800_drv_get_txwi(entry);
> -
> -		rt2x00_desc_read(txwi, 1, &word);
> -		tx_wcid	= rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID);
> -		tx_ack	= rt2x00_get_field32(word, TXWI_W1_ACK);
> -		tx_pid	= rt2x00_get_field32(word, TXWI_W1_PACKETID);
> -
> -		if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid))
> -			WARNING(rt2x00dev, "invalid TX_STA_FIFO content");
>  
>  		/*
>  		 * Obtain the status about this packet.
>  		 */
>  		txdesc.flags = 0;
> +		txwi = rt2800_drv_get_txwi(entry);
>  		rt2x00_desc_read(txwi, 0, &word);
>  		mcs = rt2x00_get_field32(word, TXWI_W0_MCS);
>  		real_mcs = rt2x00_get_field32(reg, TX_STA_FIFO_MCS);




More information about the users mailing list