Commit 7940bad5 authored by Vasanthakumar Thiagarajan's avatar Vasanthakumar Thiagarajan Committed by Kalle Valo

ath6kl: Fix unstable downlink throughput

There is frequent downlink throughput drop to 0 when operating
at the signal level between -42dBm to -53dBm. This has been root
caused to the delay in releasing pending a-mpdu subframes in
reorder buffer. Right now the timeout value is 400ms, there
is also a race condition where timeout handler can be delayed
to run at an extra timeout interval. This patch reduces the
timout interval to reasonable 100ms and makes sure releasing
pending frames are not skipped in the timeout handler by removing
the flag (rxtid->progress) which can delay the timeout logic.
Reported-by: default avatarYu Yanzhi <yanzhiy@qca.qualcomm.com>
Signed-off-by: default avatarVasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com>
Signed-off-by: default avatarKalle Valo <kvalo@qca.qualcomm.com>
parent 0faf7458
...@@ -215,7 +215,7 @@ enum ath6kl_hw_flags { ...@@ -215,7 +215,7 @@ enum ath6kl_hw_flags {
#define AGGR_NUM_OF_FREE_NETBUFS 16 #define AGGR_NUM_OF_FREE_NETBUFS 16
#define AGGR_RX_TIMEOUT 400 /* in ms */ #define AGGR_RX_TIMEOUT 100 /* in ms */
#define WMI_TIMEOUT (2 * HZ) #define WMI_TIMEOUT (2 * HZ)
...@@ -264,7 +264,6 @@ struct skb_hold_q { ...@@ -264,7 +264,6 @@ struct skb_hold_q {
struct rxtid { struct rxtid {
bool aggr; bool aggr;
bool progress;
bool timer_mon; bool timer_mon;
u16 win_sz; u16 win_sz;
u16 seq_next; u16 seq_next;
......
...@@ -1186,8 +1186,8 @@ static bool aggr_process_recv_frm(struct aggr_info_conn *agg_conn, u8 tid, ...@@ -1186,8 +1186,8 @@ static bool aggr_process_recv_frm(struct aggr_info_conn *agg_conn, u8 tid,
aggr_deque_frms(agg_conn, tid, 0, 1); aggr_deque_frms(agg_conn, tid, 0, 1);
if (agg_conn->timer_scheduled) if (agg_conn->timer_scheduled)
rxtid->progress = true; return is_queued;
else {
spin_lock_bh(&rxtid->lock); spin_lock_bh(&rxtid->lock);
for (idx = 0 ; idx < rxtid->hold_q_sz; idx++) { for (idx = 0 ; idx < rxtid->hold_q_sz; idx++) {
if (rxtid->hold_q[idx].skb) { if (rxtid->hold_q[idx].skb) {
...@@ -1199,15 +1199,12 @@ static bool aggr_process_recv_frm(struct aggr_info_conn *agg_conn, u8 tid, ...@@ -1199,15 +1199,12 @@ static bool aggr_process_recv_frm(struct aggr_info_conn *agg_conn, u8 tid,
*/ */
agg_conn->timer_scheduled = true; agg_conn->timer_scheduled = true;
mod_timer(&agg_conn->timer, mod_timer(&agg_conn->timer,
(jiffies + (jiffies + (HZ * AGGR_RX_TIMEOUT) / 1000));
HZ * (AGGR_RX_TIMEOUT) / 1000));
rxtid->progress = false;
rxtid->timer_mon = true; rxtid->timer_mon = true;
break; break;
} }
} }
spin_unlock_bh(&rxtid->lock); spin_unlock_bh(&rxtid->lock);
}
return is_queued; return is_queued;
} }
...@@ -1612,7 +1609,7 @@ static void aggr_timeout(unsigned long arg) ...@@ -1612,7 +1609,7 @@ static void aggr_timeout(unsigned long arg)
rxtid = &aggr_conn->rx_tid[i]; rxtid = &aggr_conn->rx_tid[i];
stats = &aggr_conn->stat[i]; stats = &aggr_conn->stat[i];
if (!rxtid->aggr || !rxtid->timer_mon || rxtid->progress) if (!rxtid->aggr || !rxtid->timer_mon)
continue; continue;
stats->num_timeouts++; stats->num_timeouts++;
...@@ -1635,7 +1632,6 @@ static void aggr_timeout(unsigned long arg) ...@@ -1635,7 +1632,6 @@ static void aggr_timeout(unsigned long arg)
if (rxtid->hold_q[j].skb) { if (rxtid->hold_q[j].skb) {
aggr_conn->timer_scheduled = true; aggr_conn->timer_scheduled = true;
rxtid->timer_mon = true; rxtid->timer_mon = true;
rxtid->progress = false;
break; break;
} }
} }
...@@ -1666,7 +1662,6 @@ static void aggr_delete_tid_state(struct aggr_info_conn *aggr_conn, u8 tid) ...@@ -1666,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); aggr_deque_frms(aggr_conn, tid, 0, 0);
rxtid->aggr = false; rxtid->aggr = false;
rxtid->progress = false;
rxtid->timer_mon = false; rxtid->timer_mon = false;
rxtid->win_sz = 0; rxtid->win_sz = 0;
rxtid->seq_next = 0; rxtid->seq_next = 0;
...@@ -1745,7 +1740,6 @@ void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info *aggr_info, ...@@ -1745,7 +1740,6 @@ void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info *aggr_info,
for (i = 0; i < NUM_OF_TIDS; i++) { for (i = 0; i < NUM_OF_TIDS; i++) {
rxtid = &aggr_conn->rx_tid[i]; rxtid = &aggr_conn->rx_tid[i];
rxtid->aggr = false; rxtid->aggr = false;
rxtid->progress = false;
rxtid->timer_mon = false; rxtid->timer_mon = false;
skb_queue_head_init(&rxtid->q); skb_queue_head_init(&rxtid->q);
spin_lock_init(&rxtid->lock); spin_lock_init(&rxtid->lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment