diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath6kl/txrx.c')
| -rw-r--r-- | drivers/net/wireless/ath/ath6kl/txrx.c | 48 | 
1 files changed, 24 insertions, 24 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c index 67206aedea6..7dfa0fd86d7 100644 --- a/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/drivers/net/wireless/ath/ath6kl/txrx.c @@ -1036,6 +1036,7 @@ static void aggr_deque_frms(struct aggr_info_conn *agg_conn, u8 tid,  	rxtid = &agg_conn->rx_tid[tid];  	stats = &agg_conn->stat[tid]; +	spin_lock_bh(&rxtid->lock);  	idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz);  	/* @@ -1054,8 +1055,6 @@ static void aggr_deque_frms(struct aggr_info_conn *agg_conn, u8 tid,  	seq_end = seq_no ? seq_no : rxtid->seq_next;  	idx_end = AGGR_WIN_IDX(seq_end, rxtid->hold_q_sz); -	spin_lock_bh(&rxtid->lock); -  	do {  		node = &rxtid->hold_q[idx];  		if ((order == 1) && (!node->skb)) @@ -1127,11 +1126,13 @@ static bool aggr_process_recv_frm(struct aggr_info_conn *agg_conn, u8 tid,  		    ((end > extended_end) && (cur > extended_end) &&  		     (cur < end))) {  			aggr_deque_frms(agg_conn, tid, 0, 0); +			spin_lock_bh(&rxtid->lock);  			if (cur >= rxtid->hold_q_sz - 1)  				rxtid->seq_next = cur - (rxtid->hold_q_sz - 1);  			else  				rxtid->seq_next = ATH6KL_MAX_SEQ_NO -  						  (rxtid->hold_q_sz - 2 - cur); +			spin_unlock_bh(&rxtid->lock);  		} else {  			/*  			 * Dequeue only those frames that are outside the @@ -1185,25 +1186,25 @@ static bool aggr_process_recv_frm(struct aggr_info_conn *agg_conn, u8 tid,  	aggr_deque_frms(agg_conn, tid, 0, 1);  	if (agg_conn->timer_scheduled) -		rxtid->progress = true; -	else -		for (idx = 0 ; idx < rxtid->hold_q_sz; idx++) { -			if (rxtid->hold_q[idx].skb) { -				/* -				 * There is a frame in the queue and no -				 * timer so start a timer to ensure that -				 * the frame doesn't remain stuck -				 * forever. -				 */ -				agg_conn->timer_scheduled = true; -				mod_timer(&agg_conn->timer, -					  (jiffies + -					   HZ * (AGGR_RX_TIMEOUT) / 1000)); -				rxtid->progress = false; -				rxtid->timer_mon = true; -				break; -			} +		return is_queued; + +	spin_lock_bh(&rxtid->lock); +	for (idx = 0 ; idx < rxtid->hold_q_sz; idx++) { +		if (rxtid->hold_q[idx].skb) { +			/* +			 * There is a frame in the queue and no +			 * timer so start a timer to ensure that +			 * the frame doesn't remain stuck +			 * forever. +			 */ +			agg_conn->timer_scheduled = true; +			mod_timer(&agg_conn->timer, +				  (jiffies + (HZ * AGGR_RX_TIMEOUT) / 1000)); +			rxtid->timer_mon = true; +			break;  		} +	} +	spin_unlock_bh(&rxtid->lock);  	return is_queued;  } @@ -1608,7 +1609,7 @@ static void aggr_timeout(unsigned long arg)  		rxtid = &aggr_conn->rx_tid[i];  		stats = &aggr_conn->stat[i]; -		if (!rxtid->aggr || !rxtid->timer_mon || rxtid->progress) +		if (!rxtid->aggr || !rxtid->timer_mon)  			continue;  		stats->num_timeouts++; @@ -1626,14 +1627,15 @@ static void aggr_timeout(unsigned long arg)  		rxtid = &aggr_conn->rx_tid[i];  		if (rxtid->aggr && rxtid->hold_q) { +			spin_lock_bh(&rxtid->lock);  			for (j = 0; j < rxtid->hold_q_sz; j++) {  				if (rxtid->hold_q[j].skb) {  					aggr_conn->timer_scheduled = true;  					rxtid->timer_mon = true; -					rxtid->progress = false;  					break;  				}  			} +			spin_unlock_bh(&rxtid->lock);  			if (j >= rxtid->hold_q_sz)  				rxtid->timer_mon = false; @@ -1660,7 +1662,6 @@ static void aggr_delete_tid_state(struct aggr_info_conn *aggr_conn, u8 tid)  		aggr_deque_frms(aggr_conn, tid, 0, 0);  	rxtid->aggr = false; -	rxtid->progress = false;  	rxtid->timer_mon = false;  	rxtid->win_sz = 0;  	rxtid->seq_next = 0; @@ -1739,7 +1740,6 @@ void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info *aggr_info,  	for (i = 0; i < NUM_OF_TIDS; i++) {  		rxtid = &aggr_conn->rx_tid[i];  		rxtid->aggr = false; -		rxtid->progress = false;  		rxtid->timer_mon = false;  		skb_queue_head_init(&rxtid->q);  		spin_lock_init(&rxtid->lock);  |