summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/ath/ath9k/ar9003_mac.c
diff options
context:
space:
mode:
authorSenthil Balasubramanian <senthilkumar@atheros.com>2010-11-10 16:03:16 +0300
committerJohn W. Linville <linville@tuxdriver.com>2010-11-17 00:37:07 +0300
commit6ee63f55c7754462a45315ac93027a1df60667c9 (patch)
tree09052fbf006e186f8d0a37a47ce08f97c71bae9a /drivers/net/wireless/ath/ath9k/ar9003_mac.c
parent39ec2997c374b528cdbf65099b6d6b8593a67f7f (diff)
downloadlinux-6ee63f55c7754462a45315ac93027a1df60667c9.tar.xz
ath9k_hw: Fix low throughput issue with AR93xx
TX underruns were noticed when RTS/CTS preceded aggregates. This issue was noticed in ar93xx family of chipsets only. The workaround involves padding the RTS or CTS length up to the min packet length of 256 bytes required by the hardware by adding delimiters to the fist descriptor of the aggregate. Signed-off-by: Senthil Balasubramanian <senthilkumar@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/ar9003_mac.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.c28
1 files changed, 26 insertions, 2 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index 10c812e353a6..f5896aa30005 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -410,12 +410,36 @@ static void ar9003_hw_set11n_ratescenario(struct ath_hw *ah, void *ds,
static void ar9003_hw_set11n_aggr_first(struct ath_hw *ah, void *ds,
u32 aggrLen)
{
+#define FIRST_DESC_NDELIMS 60
struct ar9003_txc *ads = (struct ar9003_txc *) ds;
ads->ctl12 |= (AR_IsAggr | AR_MoreAggr);
- ads->ctl17 &= ~AR_AggrLen;
- ads->ctl17 |= SM(aggrLen, AR_AggrLen);
+ if (ah->ent_mode & AR_ENT_OTP_MPSD) {
+ u32 ctl17, ndelim;
+ /*
+ * Add delimiter when using RTS/CTS with aggregation
+ * and non enterprise AR9003 card
+ */
+ ctl17 = ads->ctl17;
+ ndelim = MS(ctl17, AR_PadDelim);
+
+ if (ndelim < FIRST_DESC_NDELIMS) {
+ aggrLen += (FIRST_DESC_NDELIMS - ndelim) * 4;
+ ndelim = FIRST_DESC_NDELIMS;
+ }
+
+ ctl17 &= ~AR_AggrLen;
+ ctl17 |= SM(aggrLen, AR_AggrLen);
+
+ ctl17 &= ~AR_PadDelim;
+ ctl17 |= SM(ndelim, AR_PadDelim);
+
+ ads->ctl17 = ctl17;
+ } else {
+ ads->ctl17 &= ~AR_AggrLen;
+ ads->ctl17 |= SM(aggrLen, AR_AggrLen);
+ }
}
static void ar9003_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds,