From e4fd5aa8a25e1a98d0d8d9199d2c80a985b6cba8 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 17 Apr 2010 23:58:21 +0000 Subject: [PATCH] ath9k: enable 3-stream and MCS16-23 support SVN-Revision: 20968 --- .../patches/561-ath9k_streams_init.patch | 72 +++++++++++++++++++ .../patches/562-ath9k_4ms_limit_table.patch | 67 +++++++++++++++++ .../patches/563-ath9k_bits_per_symbol.patch | 64 +++++++++++++++++ .../patches/564-ath9k_mcs_mask_fix.patch | 11 +++ 4 files changed, 214 insertions(+) create mode 100644 package/mac80211/patches/561-ath9k_streams_init.patch create mode 100644 package/mac80211/patches/562-ath9k_4ms_limit_table.patch create mode 100644 package/mac80211/patches/563-ath9k_bits_per_symbol.patch create mode 100644 package/mac80211/patches/564-ath9k_mcs_mask_fix.patch diff --git a/package/mac80211/patches/561-ath9k_streams_init.patch b/package/mac80211/patches/561-ath9k_streams_init.patch new file mode 100644 index 0000000000..822846661f --- /dev/null +++ b/package/mac80211/patches/561-ath9k_streams_init.patch @@ -0,0 +1,72 @@ +--- a/drivers/net/wireless/ath/ath9k/init.c ++++ b/drivers/net/wireless/ath/ath9k/init.c +@@ -176,6 +176,18 @@ static const struct ath_ops ath9k_common + .write = ath9k_iowrite32, + }; + ++static int count_streams(unsigned int chainmask, int max) ++{ ++ int streams = 0; ++ ++ do { ++ if (++streams == max) ++ break; ++ } while ((chainmask = chainmask & (chainmask - 1))); ++ ++ return streams; ++} ++ + /**************************/ + /* Initialization */ + /**************************/ +@@ -183,8 +195,10 @@ static const struct ath_ops ath9k_common + static void setup_ht_cap(struct ath_softc *sc, + struct ieee80211_sta_ht_cap *ht_info) + { +- struct ath_common *common = ath9k_hw_common(sc->sc_ah); ++ struct ath_hw *ah = sc->sc_ah; ++ struct ath_common *common = ath9k_hw_common(ah); + u8 tx_streams, rx_streams; ++ int i, max_streams; + + ht_info->ht_supported = true; + ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | +@@ -198,25 +212,28 @@ static void setup_ht_cap(struct ath_soft + ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; + ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8; + ++ if (AR_SREV_9300_20_OR_LATER(ah)) ++ max_streams = 3; ++ else ++ max_streams = 2; ++ + /* set up supported mcs set */ + memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); +- tx_streams = !(common->tx_chainmask & (common->tx_chainmask - 1)) ? +- 1 : 2; +- rx_streams = !(common->rx_chainmask & (common->rx_chainmask - 1)) ? +- 1 : 2; ++ tx_streams = count_streams(common->tx_chainmask, max_streams); ++ rx_streams = count_streams(common->rx_chainmask, max_streams); ++ ++ ath_print(common, ATH_DBG_CONFIG, ++ "TX streams %d, RX streams: %d\n", ++ tx_streams, rx_streams); + + if (tx_streams != rx_streams) { +- ath_print(common, ATH_DBG_CONFIG, +- "TX streams %d, RX streams: %d\n", +- tx_streams, rx_streams); + ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF; + ht_info->mcs.tx_params |= ((tx_streams - 1) << + IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); + } + +- ht_info->mcs.rx_mask[0] = 0xff; +- if (rx_streams >= 2) +- ht_info->mcs.rx_mask[1] = 0xff; ++ for (i = 0; i < rx_streams; i++) ++ ht_info->mcs.rx_mask[i] = 0xff; + + ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED; + } diff --git a/package/mac80211/patches/562-ath9k_4ms_limit_table.patch b/package/mac80211/patches/562-ath9k_4ms_limit_table.patch new file mode 100644 index 0000000000..2eee096a23 --- /dev/null +++ b/package/mac80211/patches/562-ath9k_4ms_limit_table.patch @@ -0,0 +1,67 @@ +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -71,24 +71,36 @@ static void ath_tx_rc_status(struct ath_ + int nbad, int txok, bool update_rc); + + enum { +- MCS_DEFAULT, ++ MCS_HT20, ++ MCS_HT20_SGI, + MCS_HT40, + MCS_HT40_SGI, + }; + +-static int ath_max_4ms_framelen[3][16] = { +- [MCS_DEFAULT] = { +- 3216, 6434, 9650, 12868, 19304, 25740, 28956, 32180, +- 6430, 12860, 19300, 25736, 38600, 51472, 57890, 64320, ++static u16 ath_max_4ms_framelen[4][32] = { ++ [MCS_HT20] = { ++ 3212, 6432, 9648, 12864, 19300, 25736, 28952, 32172, ++ 6424, 12852, 19280, 25708, 38568, 51424, 57852, 64280, ++ 9628, 19260, 28896, 38528, 57792, 65532, 65532, 65532, ++ 12828, 25656, 38488, 51320, 65532, 65532, 65532, 65532, ++ }, ++ [MCS_HT20_SGI] = { ++ 3572, 7144, 10720, 14296, 21444, 28596, 32172, 35744, ++ 7140, 14284, 21428, 28568, 42856, 57144, 64288, 65532, ++ 10700, 21408, 32112, 42816, 64228, 65532, 65532, 65532, ++ 14256, 28516, 42780, 57040, 65532, 65532, 65532, 65532, + }, + [MCS_HT40] = { +- 6684, 13368, 20052, 26738, 40104, 53476, 60156, 66840, +- 13360, 26720, 40080, 53440, 80160, 106880, 120240, 133600, ++ 6680, 13360, 20044, 26724, 40092, 53456, 60140, 65532, ++ 13348, 26700, 40052, 53400, 65532, 65532, 65532, 65532, ++ 20004, 40008, 60016, 65532, 65532, 65532, 65532, 65532, ++ 26644, 53292, 65532, 65532, 65532, 65532, 65532, 65532, + }, + [MCS_HT40_SGI] = { +- /* TODO: Only MCS 7 and 15 updated, recalculate the rest */ +- 6684, 13368, 20052, 26738, 40104, 53476, 60156, 74200, +- 13360, 26720, 40080, 53440, 80160, 106880, 120240, 148400, ++ 7420, 14844, 22272, 29696, 44544, 59396, 65532, 65532, ++ 14832, 29668, 44504, 59340, 65532, 65532, 65532, 65532, ++ 22232, 44464, 65532, 65532, 65532, 65532, 65532, 65532, ++ 29616, 59232, 65532, 65532, 65532, 65532, 65532, 65532, + } + }; + +@@ -538,12 +550,13 @@ static u32 ath_lookup_rate(struct ath_so + break; + } + +- if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI) +- modeidx = MCS_HT40_SGI; +- else if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) ++ if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) + modeidx = MCS_HT40; + else +- modeidx = MCS_DEFAULT; ++ modeidx = MCS_HT20; ++ ++ if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI) ++ modeidx++; + + frmlen = ath_max_4ms_framelen[modeidx][rates[i].idx]; + max_4ms_framelen = min(max_4ms_framelen, frmlen); diff --git a/package/mac80211/patches/563-ath9k_bits_per_symbol.patch b/package/mac80211/patches/563-ath9k_bits_per_symbol.patch new file mode 100644 index 0000000000..d842e404d2 --- /dev/null +++ b/package/mac80211/patches/563-ath9k_bits_per_symbol.patch @@ -0,0 +1,64 @@ +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -34,7 +34,7 @@ + + #define OFDM_SIFS_TIME 16 + +-static u32 bits_per_symbol[][2] = { ++static u16 bits_per_symbol[][2] = { + /* 20MHz 40MHz */ + { 26, 54 }, /* 0: BPSK */ + { 52, 108 }, /* 1: QPSK 1/2 */ +@@ -44,14 +44,6 @@ static u32 bits_per_symbol[][2] = { + { 208, 432 }, /* 5: 64-QAM 2/3 */ + { 234, 486 }, /* 6: 64-QAM 3/4 */ + { 260, 540 }, /* 7: 64-QAM 5/6 */ +- { 52, 108 }, /* 8: BPSK */ +- { 104, 216 }, /* 9: QPSK 1/2 */ +- { 156, 324 }, /* 10: QPSK 3/4 */ +- { 208, 432 }, /* 11: 16-QAM 1/2 */ +- { 312, 648 }, /* 12: 16-QAM 3/4 */ +- { 416, 864 }, /* 13: 64-QAM 2/3 */ +- { 468, 972 }, /* 14: 64-QAM 3/4 */ +- { 520, 1080 }, /* 15: 64-QAM 5/6 */ + }; + + #define IS_HT_RATE(_rate) ((_rate) & 0x80) +@@ -601,7 +593,7 @@ static int ath_compute_num_delims(struct + u32 nsymbits, nsymbols; + u16 minlen; + u8 flags, rix; +- int width, half_gi, ndelim, mindelim; ++ int width, streams, half_gi, ndelim, mindelim; + + /* Select standard number of delimiters based on frame length alone */ + ndelim = ATH_AGGR_GET_NDELIM(frmlen); +@@ -641,7 +633,8 @@ static int ath_compute_num_delims(struct + if (nsymbols == 0) + nsymbols = 1; + +- nsymbits = bits_per_symbol[rix][width]; ++ streams = HT_RC_2_STREAMS(rix); ++ nsymbits = bits_per_symbol[rix % 8][width] * streams; + minlen = (nsymbols * nsymbits) / BITS_PER_BYTE; + + if (frmlen < minlen) { +@@ -1533,8 +1526,9 @@ static u32 ath_pkt_duration(struct ath_s + pktlen = bf_isaggr(bf) ? bf->bf_al : bf->bf_frmlen; + + /* find number of symbols: PLCP + data */ ++ streams = HT_RC_2_STREAMS(rix); + nbits = (pktlen << 3) + OFDM_PLCP_BITS; +- nsymbits = bits_per_symbol[rix][width]; ++ nsymbits = bits_per_symbol[rix % 8][width] * streams; + nsymbols = (nbits + nsymbits - 1) / nsymbits; + + if (!half_gi) +@@ -1543,7 +1537,6 @@ static u32 ath_pkt_duration(struct ath_s + duration = SYMBOL_TIME_HALFGI(nsymbols); + + /* addup duration for legacy/ht training and signal fields */ +- streams = HT_RC_2_STREAMS(rix); + duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams); + + return duration; diff --git a/package/mac80211/patches/564-ath9k_mcs_mask_fix.patch b/package/mac80211/patches/564-ath9k_mcs_mask_fix.patch new file mode 100644 index 0000000000..4d0ac2de1b --- /dev/null +++ b/package/mac80211/patches/564-ath9k_mcs_mask_fix.patch @@ -0,0 +1,11 @@ +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -19,7 +19,7 @@ + + #define BITS_PER_BYTE 8 + #define OFDM_PLCP_BITS 22 +-#define HT_RC_2_MCS(_rc) ((_rc) & 0x0f) ++#define HT_RC_2_MCS(_rc) ((_rc) & 0x1f) + #define HT_RC_2_STREAMS(_rc) ((((_rc) & 0x78) >> 3) + 1) + #define L_STF 8 + #define L_LTF 8 -- 2.30.2