aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>2014-04-08 04:36:18 -0400
committerJohn W. Linville <linville@tuxdriver.com>2014-04-22 15:06:29 -0400
commitc888cdd41fdb76f3b179564e41ec2646463d058a (patch)
tree876b4e52abc27b480eedb5ac0e70c4e1a9adf44e
parent6c2faf09394ceaef4efed1e44721830579f16115 (diff)
wil6210: relaxed check for BACK start sequence
Sometimes, due to the race between Rx path and WMI_BA_STATUS_EVENTID WMI event, few frames may be passed to the stack before reorder buffer allocated. Then, after BACK establishment, it start getting frames with sequence number ahead of SSN, and it get interpreted as missing frames. Then, BACK mechanism will wait for missing frames; data traffic will be stopped. In case of interface configured for DHCP, this data delay causes DHCP failure. Relax checking for sequence number; use sequence of 1-st frame handled by the buffer as SSN for this buffer. This is work-around, real fix should be done when proper BACK mechanism implemented. Signed-off-by: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/ath/wil6210/rx_reorder.c17
-rw-r--r--drivers/net/wireless/ath/wil6210/wil6210.h1
2 files changed, 18 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/wil6210/rx_reorder.c b/drivers/net/wireless/ath/wil6210/rx_reorder.c
index d04629fe053f..ec29954bd44d 100644
--- a/drivers/net/wireless/ath/wil6210/rx_reorder.c
+++ b/drivers/net/wireless/ath/wil6210/rx_reorder.c
@@ -91,6 +91,22 @@ void wil_rx_reorder(struct wil6210_priv *wil, struct sk_buff *skb)
91 91
92 spin_lock(&r->reorder_lock); 92 spin_lock(&r->reorder_lock);
93 93
94 /** Due to the race between WMI events, where BACK establishment
95 * reported, and data Rx, few packets may be pass up before reorder
96 * buffer get allocated. Catch up by pretending SSN is what we
97 * see in the 1-st Rx packet
98 */
99 if (r->first_time) {
100 r->first_time = false;
101 if (seq != r->head_seq_num) {
102 wil_err(wil, "Error: 1-st frame with wrong sequence"
103 " %d, should be %d. Fixing...\n", seq,
104 r->head_seq_num);
105 r->head_seq_num = seq;
106 r->ssn = seq;
107 }
108 }
109
94 /* frame with out of date sequence number */ 110 /* frame with out of date sequence number */
95 if (seq_less(seq, r->head_seq_num)) { 111 if (seq_less(seq, r->head_seq_num)) {
96 dev_kfree_skb(skb); 112 dev_kfree_skb(skb);
@@ -162,6 +178,7 @@ struct wil_tid_ampdu_rx *wil_tid_ampdu_rx_alloc(struct wil6210_priv *wil,
162 r->head_seq_num = ssn; 178 r->head_seq_num = ssn;
163 r->buf_size = size; 179 r->buf_size = size;
164 r->stored_mpdu_num = 0; 180 r->stored_mpdu_num = 0;
181 r->first_time = true;
165 return r; 182 return r;
166} 183}
167 184
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index 2a2dec75f026..f881aee6319d 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -301,6 +301,7 @@ struct wil_tid_ampdu_rx {
301 u16 buf_size; 301 u16 buf_size;
302 u16 timeout; 302 u16 timeout;
303 u8 dialog_token; 303 u8 dialog_token;
304 bool first_time; /* is it 1-st time this buffer used? */
304}; 305};
305 306
306struct wil6210_stats { 307struct wil6210_stats {