aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSenthil Balasubramanian <senthilkumar@atheros.com>2010-11-10 08:03:16 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-11-16 16:37:07 -0500
commit6ee63f55c7754462a45315ac93027a1df60667c9 (patch)
tree09052fbf006e186f8d0a37a47ce08f97c71bae9a
parent39ec2997c374b528cdbf65099b6d6b8593a67f7f (diff)
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>
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.c28
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h3
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h1
4 files changed, 33 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,
410static void ar9003_hw_set11n_aggr_first(struct ath_hw *ah, void *ds, 410static void ar9003_hw_set11n_aggr_first(struct ath_hw *ah, void *ds,
411 u32 aggrLen) 411 u32 aggrLen)
412{ 412{
413#define FIRST_DESC_NDELIMS 60
413 struct ar9003_txc *ads = (struct ar9003_txc *) ds; 414 struct ar9003_txc *ads = (struct ar9003_txc *) ds;
414 415
415 ads->ctl12 |= (AR_IsAggr | AR_MoreAggr); 416 ads->ctl12 |= (AR_IsAggr | AR_MoreAggr);
416 417
417 ads->ctl17 &= ~AR_AggrLen; 418 if (ah->ent_mode & AR_ENT_OTP_MPSD) {
418 ads->ctl17 |= SM(aggrLen, AR_AggrLen); 419 u32 ctl17, ndelim;
420 /*
421 * Add delimiter when using RTS/CTS with aggregation
422 * and non enterprise AR9003 card
423 */
424 ctl17 = ads->ctl17;
425 ndelim = MS(ctl17, AR_PadDelim);
426
427 if (ndelim < FIRST_DESC_NDELIMS) {
428 aggrLen += (FIRST_DESC_NDELIMS - ndelim) * 4;
429 ndelim = FIRST_DESC_NDELIMS;
430 }
431
432 ctl17 &= ~AR_AggrLen;
433 ctl17 |= SM(aggrLen, AR_AggrLen);
434
435 ctl17 &= ~AR_PadDelim;
436 ctl17 |= SM(ndelim, AR_PadDelim);
437
438 ads->ctl17 = ctl17;
439 } else {
440 ads->ctl17 &= ~AR_AggrLen;
441 ads->ctl17 |= SM(aggrLen, AR_AggrLen);
442 }
419} 443}
420 444
421static void ar9003_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds, 445static void ar9003_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds,
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index e75d8e8cf4d2..75e23632b968 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1952,6 +1952,9 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
1952 if (AR_SREV_9300_20_OR_LATER(ah)) 1952 if (AR_SREV_9300_20_OR_LATER(ah))
1953 pCap->hw_caps |= ATH9K_HW_CAP_RAC_SUPPORTED; 1953 pCap->hw_caps |= ATH9K_HW_CAP_RAC_SUPPORTED;
1954 1954
1955 if (AR_SREV_9300_20_OR_LATER(ah))
1956 ah->ent_mode = REG_READ(ah, AR_ENT_OTP);
1957
1955 if (AR_SREV_9287_11_OR_LATER(ah) || AR_SREV_9271(ah)) 1958 if (AR_SREV_9287_11_OR_LATER(ah) || AR_SREV_9271(ah))
1956 pCap->hw_caps |= ATH9K_HW_CAP_SGI_20; 1959 pCap->hw_caps |= ATH9K_HW_CAP_SGI_20;
1957 1960
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index f821a28bcda3..15f51c8943a1 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -803,6 +803,9 @@ struct ath_hw {
803 * this register when in sleep states. 803 * this register when in sleep states.
804 */ 804 */
805 u32 WARegVal; 805 u32 WARegVal;
806
807 /* Enterprise mode cap */
808 u32 ent_mode;
806}; 809};
807 810
808static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah) 811static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah)
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index ac6a13e27352..60826b82f4a2 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -1067,6 +1067,7 @@ enum {
1067#define AR_INTR_PRIO_ASYNC_ENABLE 0x40d4 1067#define AR_INTR_PRIO_ASYNC_ENABLE 0x40d4
1068#define AR_ENT_OTP 0x40d8 1068#define AR_ENT_OTP 0x40d8
1069#define AR_ENT_OTP_CHAIN2_DISABLE 0x00020000 1069#define AR_ENT_OTP_CHAIN2_DISABLE 0x00020000
1070#define AR_ENT_OTP_MPSD 0x00800000
1070 1071
1071#define AR_RTC_9300_PLL_DIV 0x000003ff 1072#define AR_RTC_9300_PLL_DIV 0x000003ff
1072#define AR_RTC_9300_PLL_DIV_S 0 1073#define AR_RTC_9300_PLL_DIV_S 0