Browse Source

ath9k: enable 3-stream and MCS16-23 support

SVN-Revision: 20968
Felix Fietkau 16 years ago
parent
commit
e4fd5aa8a2

+ 72 - 0
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;
+ }

+ 67 - 0
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);

+ 64 - 0
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;

+ 11 - 0
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