carl9170: fix HT peer BA session corruption

This patch adds an alternative tx status path
for BlockAck Requests as the hardware doesn't
recognize that a BlockAck Requests is usually
acked with a BlockAck and not a legacy ACK.

Without this patch, the stack would constantly
resent old and stale BARs. So, depending on the
receiver stack, this could lead to:

 - "stuck" ba sessions and package loss, as the
   stale BAR would reset the sequence each time.

 - lots of reorder releases.

 - ...

Reported-by: Sean Patrick Santos <quantheory@gmail.com>
Reported-by: Mikołaj Kuligowski <mikolaj.q@wp.pl>
Reported-by: Per-Erik Westerberg <per-erik.westerberg@bredband.net>
Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
Christian Lamparter
2012-07-07 21:13:59 +02:00
committed by John W. Linville
parent 4519a74338
commit c9122c0d63
5 changed files with 132 additions and 0 deletions

View File

@@ -289,6 +289,7 @@ struct ar9170 {
unsigned int mem_block_size;
unsigned int rx_size;
unsigned int tx_seq_table;
bool ba_filter;
} fw;
/* interface configuration combinations */
@@ -425,6 +426,10 @@ struct ar9170 {
struct sk_buff *rx_failover;
int rx_failover_missing;
/* FIFO for collecting outstanding BlockAckRequest */
struct list_head bar_list[__AR9170_NUM_TXQ];
spinlock_t bar_list_lock[__AR9170_NUM_TXQ];
#ifdef CONFIG_CARL9170_WPC
struct {
bool pbc_state;
@@ -468,6 +473,12 @@ enum carl9170_ps_off_override_reasons {
PS_OFF_BCN = BIT(1),
};
struct carl9170_bar_list_entry {
struct list_head list;
struct rcu_head head;
struct sk_buff *skb;
};
struct carl9170_ba_stats {
u8 ampdu_len;
u8 ampdu_ack_len;