linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 1/9] ath9k: check for specific rx stuck conditions and recover from them
@ 2010-04-19 17:57 Felix Fietkau
  2010-04-19 17:57 ` [PATCH v2 2/9] ath9k: clean up tx buffer handling Felix Fietkau
  2010-04-19 19:04 ` [PATCH v2 1/9] ath9k: check for specific rx stuck conditions and recover from them Pavel Roskin
  0 siblings, 2 replies; 11+ messages in thread
From: Felix Fietkau @ 2010-04-19 17:57 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, lrodriguez

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/hw.c   |   28 ++++++++++++++++++++++++++++
 drivers/net/wireless/ath/ath9k/hw.h   |    1 +
 drivers/net/wireless/ath/ath9k/main.c |    3 ++-
 3 files changed, 31 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 9aa40df..5a29048 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1160,6 +1160,34 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
 	return true;
 }
 
+bool ath9k_hw_check_alive(struct ath_hw *ah)
+{
+	int count = 50;
+	u32 reg;
+
+	if (AR_SREV_9285_10_OR_LATER(ah))
+		return true;
+
+	do {
+		reg = REG_READ(ah, AR_OBS_BUS_1);
+
+		if ((reg & 0x7E7FFFEF) == 0x00702400)
+			continue;
+
+		switch (reg & 0x7E000B00) {
+		case 0x1E000000:
+		case 0x52000B00:
+		case 0x18000B00:
+			continue;
+		default:
+			return true;
+		}
+	} while (count-- > 0);
+
+	return false;
+}
+EXPORT_SYMBOL(ath9k_hw_check_alive);
+
 int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 		    bool bChannelChange)
 {
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 8158e8e..a78e09b 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -869,6 +869,7 @@ void ath9k_hw_set11nmac2040(struct ath_hw *ah);
 void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period);
 void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
 				    const struct ath9k_beacon_state *bs);
+bool ath9k_hw_check_alive(struct ath_hw *ah);
 
 bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode);
 
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 1f4ea74..0246e7a 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -405,7 +405,8 @@ void ath9k_tasklet(unsigned long data)
 
 	ath9k_ps_wakeup(sc);
 
-	if (status & ATH9K_INT_FATAL) {
+	if ((status & ATH9K_INT_FATAL) ||
+	    !ath9k_hw_check_alive(ah)) {
 		ath_reset(sc, false);
 		ath9k_ps_restore(sc);
 		return;
-- 
1.6.4.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 2/9] ath9k: clean up tx buffer handling
  2010-04-19 17:57 [PATCH v2 1/9] ath9k: check for specific rx stuck conditions and recover from them Felix Fietkau
@ 2010-04-19 17:57 ` Felix Fietkau
  2010-04-19 17:57   ` [PATCH v2 3/9] ath9k: update the MCS mask for MCS16 and above Felix Fietkau
  2010-04-19 19:04 ` [PATCH v2 1/9] ath9k: check for specific rx stuck conditions and recover from them Pavel Roskin
  1 sibling, 1 reply; 11+ messages in thread
From: Felix Fietkau @ 2010-04-19 17:57 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, lrodriguez

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/xmit.c |   67 ++++++++++++++++-----------------
 1 files changed, 32 insertions(+), 35 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index cac178a..fcbb4a8 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -261,19 +261,40 @@ static void ath_tx_set_retry(struct ath_softc *sc, struct ath_txq *txq,
 	hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_RETRY);
 }
 
-static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf)
+static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc)
 {
-	struct ath_buf *tbf;
+	struct ath_buf *bf = NULL;
 
 	spin_lock_bh(&sc->tx.txbuflock);
-	if (WARN_ON(list_empty(&sc->tx.txbuf))) {
+
+	if (unlikely(list_empty(&sc->tx.txbuf))) {
 		spin_unlock_bh(&sc->tx.txbuflock);
 		return NULL;
 	}
-	tbf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
-	list_del(&tbf->list);
+
+	bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
+	list_del(&bf->list);
+
 	spin_unlock_bh(&sc->tx.txbuflock);
 
+	return bf;
+}
+
+static void ath_tx_return_buffer(struct ath_softc *sc, struct ath_buf *bf)
+{
+	spin_lock_bh(&sc->tx.txbuflock);
+	list_add_tail(&bf->list, &sc->tx.txbuf);
+	spin_unlock_bh(&sc->tx.txbuflock);
+}
+
+static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf)
+{
+	struct ath_buf *tbf;
+
+	tbf = ath_tx_get_buffer(sc);
+	if (WARN_ON(!tbf))
+		return NULL;
+
 	ATH_TXBUF_RESET(tbf);
 
 	tbf->aphy = bf->aphy;
@@ -1081,9 +1102,7 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
 				list_del(&bf->list);
 				spin_unlock_bh(&txq->axq_lock);
 
-				spin_lock_bh(&sc->tx.txbuflock);
-				list_add_tail(&bf->list, &sc->tx.txbuf);
-				spin_unlock_bh(&sc->tx.txbuflock);
+				ath_tx_return_buffer(sc, bf);
 				continue;
 			}
 		}
@@ -1325,25 +1344,6 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
 	txq->axq_depth++;
 }
 
-static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc)
-{
-	struct ath_buf *bf = NULL;
-
-	spin_lock_bh(&sc->tx.txbuflock);
-
-	if (unlikely(list_empty(&sc->tx.txbuf))) {
-		spin_unlock_bh(&sc->tx.txbuflock);
-		return NULL;
-	}
-
-	bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
-	list_del(&bf->list);
-
-	spin_unlock_bh(&sc->tx.txbuflock);
-
-	return bf;
-}
-
 static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
 			      struct list_head *bf_head,
 			      struct ath_tx_control *txctl)
@@ -1825,9 +1825,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
 		}
 		spin_unlock_bh(&txq->axq_lock);
 
-		spin_lock_bh(&sc->tx.txbuflock);
-		list_add_tail(&bf->list, &sc->tx.txbuf);
-		spin_unlock_bh(&sc->tx.txbuflock);
+		ath_tx_return_buffer(sc, bf);
 
 		return r;
 	}
@@ -2141,13 +2139,12 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
 		txq->axq_depth--;
 		txok = !(ts.ts_status & ATH9K_TXERR_MASK);
 		txq->axq_tx_inprogress = false;
+		if (bf_held)
+			list_del(&bf_held->list);
 		spin_unlock_bh(&txq->axq_lock);
 
-		if (bf_held) {
-			spin_lock_bh(&sc->tx.txbuflock);
-			list_move_tail(&bf_held->list, &sc->tx.txbuf);
-			spin_unlock_bh(&sc->tx.txbuflock);
-		}
+		if (bf_held)
+			ath_tx_return_buffer(sc, bf_held);
 
 		if (!bf_isampdu(bf)) {
 			/*
-- 
1.6.4.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 3/9] ath9k: update the MCS mask for MCS16 and above
  2010-04-19 17:57 ` [PATCH v2 2/9] ath9k: clean up tx buffer handling Felix Fietkau
@ 2010-04-19 17:57   ` Felix Fietkau
  2010-04-19 17:57     ` [PATCH v2 4/9] ath9k: update the ath_max_4ms_framelen table Felix Fietkau
  0 siblings, 1 reply; 11+ messages in thread
From: Felix Fietkau @ 2010-04-19 17:57 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, lrodriguez

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/xmit.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index fcbb4a8..5d3d563 100644
--- 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
-- 
1.6.4.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 4/9] ath9k: update the ath_max_4ms_framelen table
  2010-04-19 17:57   ` [PATCH v2 3/9] ath9k: update the MCS mask for MCS16 and above Felix Fietkau
@ 2010-04-19 17:57     ` Felix Fietkau
  2010-04-19 17:57       ` [PATCH v2 5/9] ath9k: reduce the bits_per_symbol table size, support more streams Felix Fietkau
  0 siblings, 1 reply; 11+ messages in thread
From: Felix Fietkau @ 2010-04-19 17:57 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, lrodriguez

Include MCS0-31 and also add SGI for HT20. This makes it
possible to support more different rate combinations with
newer hardware.

Based on a patch by Selvam. T.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/xmit.c |   41 +++++++++++++++++++++-----------
 1 files changed, 27 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 5d3d563..4078982 100644
--- 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_buf *bf, struct ath_tx_status *ts,
 			     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 int 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_softc *sc, struct ath_buf *bf,
 				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);
-- 
1.6.4.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 5/9] ath9k: reduce the bits_per_symbol table size, support more streams
  2010-04-19 17:57     ` [PATCH v2 4/9] ath9k: update the ath_max_4ms_framelen table Felix Fietkau
@ 2010-04-19 17:57       ` Felix Fietkau
  2010-04-19 17:57         ` [PATCH v2 6/9] ath9k: initialize the number of tx/rx streams correctly Felix Fietkau
  0 siblings, 1 reply; 11+ messages in thread
From: Felix Fietkau @ 2010-04-19 17:57 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, lrodriguez

Instead of increasing bits_per_symbol for supporting more streams, keep
it single-stream only and multiply the values by the numer of streams.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/xmit.c |   19 ++++++-------------
 1 files changed, 6 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 4078982..2237658 100644
--- 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 ath_softc *sc, struct ath_atx_tid *tid,
 	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 ath_softc *sc, struct ath_atx_tid *tid,
 	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_softc *sc, u8 rix, struct ath_buf *bf,
 	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_softc *sc, u8 rix, struct ath_buf *bf,
 		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;
-- 
1.6.4.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 6/9] ath9k: initialize the number of tx/rx streams correctly
  2010-04-19 17:57       ` [PATCH v2 5/9] ath9k: reduce the bits_per_symbol table size, support more streams Felix Fietkau
@ 2010-04-19 17:57         ` Felix Fietkau
  2010-04-19 17:57           ` [PATCH v2 7/9] mac80211: add flags for STBC (Space-Time Block Coding) Felix Fietkau
  0 siblings, 1 reply; 11+ messages in thread
From: Felix Fietkau @ 2010-04-19 17:57 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, lrodriguez

AR9300 based hardware can 3x3 MCS rates, this should be set in the
HT capabilities.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/init.c |   39 +++++++++++++++++++++++---------
 1 files changed, 28 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index ca6e781..2c0630e 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -175,6 +175,18 @@ static const struct ath_ops ath9k_common_ops = {
 	.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     */
 /**************************/
@@ -182,8 +194,10 @@ static const struct ath_ops ath9k_common_ops = {
 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 |
@@ -197,25 +211,28 @@ static void setup_ht_cap(struct ath_softc *sc,
 	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;
 }
-- 
1.6.4.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 7/9] mac80211: add flags for STBC (Space-Time Block Coding)
  2010-04-19 17:57         ` [PATCH v2 6/9] ath9k: initialize the number of tx/rx streams correctly Felix Fietkau
@ 2010-04-19 17:57           ` Felix Fietkau
  2010-04-19 17:57             ` [PATCH v2 8/9] ath9k: add support for Tx and Rx STBC Felix Fietkau
  0 siblings, 1 reply; 11+ messages in thread
From: Felix Fietkau @ 2010-04-19 17:57 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, lrodriguez

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 include/linux/ieee80211.h |    1 +
 include/net/mac80211.h    |    4 ++++
 2 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 1252ba1..97b2eae 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -876,6 +876,7 @@ struct ieee80211_ht_cap {
 #define IEEE80211_HT_CAP_SGI_40			0x0040
 #define IEEE80211_HT_CAP_TX_STBC		0x0080
 #define IEEE80211_HT_CAP_RX_STBC		0x0300
+#define		IEEE80211_HT_CAP_RX_STBC_SHIFT	8
 #define IEEE80211_HT_CAP_DELAY_BA		0x0400
 #define IEEE80211_HT_CAP_MAX_AMSDU		0x0800
 #define IEEE80211_HT_CAP_DSSSCCK40		0x1000
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 75056dd..3d85b0a 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -275,6 +275,8 @@ struct ieee80211_bss_conf {
  *	MLME command (internal to mac80211 to figure out whether to send TX
  *	status to user space)
  * @IEEE80211_TX_CTL_LDPC: tells the driver to use LDPC for this frame
+ * @IEEE80211_TX_CTL_STBC: Enables Space-Time Block Coding (STBC) for this 
+ *	frame and selects the maximum number of streams that it can use.
  */
 enum mac80211_tx_control_flags {
 	IEEE80211_TX_CTL_REQ_TX_STATUS		= BIT(0),
@@ -299,6 +301,8 @@ enum mac80211_tx_control_flags {
 	IEEE80211_TX_INTFL_HAS_RADIOTAP		= BIT(20),
 	IEEE80211_TX_INTFL_NL80211_FRAME_TX	= BIT(21),
 	IEEE80211_TX_CTL_LDPC			= BIT(22),
+	IEEE80211_TX_CTL_STBC			= BIT(23) | BIT(24),
+#define IEEE80211_TX_CTL_STBC_SHIFT		23
 };
 
 /**
-- 
1.6.4.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 8/9] ath9k: add support for Tx and Rx STBC
  2010-04-19 17:57           ` [PATCH v2 7/9] mac80211: add flags for STBC (Space-Time Block Coding) Felix Fietkau
@ 2010-04-19 17:57             ` Felix Fietkau
  2010-04-19 17:57               ` [PATCH v2 9/9] ath9k: set the STBC flag in rate control if the peer supports it Felix Fietkau
  0 siblings, 1 reply; 11+ messages in thread
From: Felix Fietkau @ 2010-04-19 17:57 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, lrodriguez

Supported only for single stream rates by the hardware

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/init.c |    6 ++++++
 drivers/net/wireless/ath/ath9k/mac.h  |    8 +++++++-
 drivers/net/wireless/ath/ath9k/xmit.c |    2 ++
 3 files changed, 15 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 2c0630e..8c79548 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -216,6 +216,12 @@ static void setup_ht_cap(struct ath_softc *sc,
 	else
 		max_streams = 2;
 
+	if (AR_SREV_9280_10_OR_LATER(ah)) {
+		if (max_streams >= 2)
+			ht_info->cap |= IEEE80211_HT_CAP_TX_STBC;
+		ht_info->cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
+	}
+
 	/* set up supported mcs set */
 	memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
 	tx_streams = count_streams(common->tx_chainmask, max_streams);
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index 66d0d5e..00f3e0c 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -37,6 +37,8 @@
 	  AR_2040_##_index : 0)						\
 	 |((_series)[_index].RateFlags & ATH9K_RATESERIES_HALFGI ?	\
 	   AR_GI##_index : 0)						\
+	 |((_series)[_index].RateFlags & ATH9K_RATESERIES_STBC ?	\
+	   AR_STBC##_index : 0)						\
 	 |SM((_series)[_index].ChSel, AR_ChainSel##_index))
 
 #define CCK_SIFS_TIME        10
@@ -434,7 +436,10 @@ struct ar5416_desc {
 #define AR_ChainSel3_S      17
 #define AR_RTSCTSRate       0x0ff00000
 #define AR_RTSCTSRate_S     20
-#define AR_TxCtlRsvd70      0xf0000000
+#define AR_STBC0            0x10000000
+#define AR_STBC1            0x20000000
+#define AR_STBC2            0x40000000
+#define AR_STBC3            0x80000000
 
 #define AR_TxRSSIAnt00      0x000000ff
 #define AR_TxRSSIAnt00_S    0
@@ -647,6 +652,7 @@ enum ath9k_rx_filter {
 #define ATH9K_RATESERIES_RTS_CTS  0x0001
 #define ATH9K_RATESERIES_2040     0x0002
 #define ATH9K_RATESERIES_HALFGI   0x0004
+#define ATH9K_RATESERIES_STBC     0x0008
 
 struct ath9k_11n_rate_series {
 	u32 Tries;
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 2237658..b0d345a 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1607,6 +1607,8 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
 			series[i].Rate = rix | 0x80;
 			series[i].PktDuration = ath_pkt_duration(sc, rix, bf,
 				 is_40, is_sgi, is_sp);
+			if (rix < 8 && (tx_info->flags & IEEE80211_TX_CTL_STBC))
+				series[i].RateFlags |= ATH9K_RATESERIES_STBC;
 			continue;
 		}
 
-- 
1.6.4.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 9/9] ath9k: set the STBC flag in rate control if the peer supports it
  2010-04-19 17:57             ` [PATCH v2 8/9] ath9k: add support for Tx and Rx STBC Felix Fietkau
@ 2010-04-19 17:57               ` Felix Fietkau
  0 siblings, 0 replies; 11+ messages in thread
From: Felix Fietkau @ 2010-04-19 17:57 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, lrodriguez

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/rc.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index bf3ad7a..8519452 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -700,6 +700,10 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
 	    (sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING))
 		tx_info->flags |= IEEE80211_TX_CTL_LDPC;
 
+	if (conf_is_ht(&sc->hw->conf) &&
+	    (sta->ht_cap.cap & IEEE80211_HT_CAP_TX_STBC))
+		tx_info->flags |= (1 << IEEE80211_TX_CTL_STBC_SHIFT);
+
 	if (is_probe) {
 		/* set one try for probe rates. For the
 		 * probes don't enable rts */
-- 
1.6.4.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 1/9] ath9k: check for specific rx stuck conditions and recover from them
  2010-04-19 17:57 [PATCH v2 1/9] ath9k: check for specific rx stuck conditions and recover from them Felix Fietkau
  2010-04-19 17:57 ` [PATCH v2 2/9] ath9k: clean up tx buffer handling Felix Fietkau
@ 2010-04-19 19:04 ` Pavel Roskin
  2010-04-19 19:07   ` Felix Fietkau
  1 sibling, 1 reply; 11+ messages in thread
From: Pavel Roskin @ 2010-04-19 19:04 UTC (permalink / raw)
  To: Felix Fietkau; +Cc: linux-wireless, linville, lrodriguez

On Mon, 2010-04-19 at 19:57 +0200, Felix Fietkau wrote:
> +		if ((reg & 0x7E7FFFEF) == 0x00702400)
> +			continue;
> +
> +		switch (reg & 0x7E000B00) {
> +		case 0x1E000000:
> +		case 0x52000B00:
> +		case 0x18000B00:
> +			continue;

Where did you get all that magic?  If it's from Atheros documentation,
maybe you could give those numbers descriptive names?

-- 
Regards,
Pavel Roskin

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 1/9] ath9k: check for specific rx stuck conditions and recover from them
  2010-04-19 19:04 ` [PATCH v2 1/9] ath9k: check for specific rx stuck conditions and recover from them Pavel Roskin
@ 2010-04-19 19:07   ` Felix Fietkau
  0 siblings, 0 replies; 11+ messages in thread
From: Felix Fietkau @ 2010-04-19 19:07 UTC (permalink / raw)
  To: Pavel Roskin; +Cc: linux-wireless, linville, lrodriguez

On 2010-04-19 9:04 PM, Pavel Roskin wrote:
> On Mon, 2010-04-19 at 19:57 +0200, Felix Fietkau wrote:
>> +		if ((reg & 0x7E7FFFEF) == 0x00702400)
>> +			continue;
>> +
>> +		switch (reg & 0x7E000B00) {
>> +		case 0x1E000000:
>> +		case 0x52000B00:
>> +		case 0x18000B00:
>> +			continue;
> 
> Where did you get all that magic?  If it's from Atheros documentation,
> maybe you could give those numbers descriptive names?
I don't have any names for that. It's stuff from a debugging register -
adapted from Atheros code...

- Felix

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2010-04-19 19:07 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-04-19 17:57 [PATCH v2 1/9] ath9k: check for specific rx stuck conditions and recover from them Felix Fietkau
2010-04-19 17:57 ` [PATCH v2 2/9] ath9k: clean up tx buffer handling Felix Fietkau
2010-04-19 17:57   ` [PATCH v2 3/9] ath9k: update the MCS mask for MCS16 and above Felix Fietkau
2010-04-19 17:57     ` [PATCH v2 4/9] ath9k: update the ath_max_4ms_framelen table Felix Fietkau
2010-04-19 17:57       ` [PATCH v2 5/9] ath9k: reduce the bits_per_symbol table size, support more streams Felix Fietkau
2010-04-19 17:57         ` [PATCH v2 6/9] ath9k: initialize the number of tx/rx streams correctly Felix Fietkau
2010-04-19 17:57           ` [PATCH v2 7/9] mac80211: add flags for STBC (Space-Time Block Coding) Felix Fietkau
2010-04-19 17:57             ` [PATCH v2 8/9] ath9k: add support for Tx and Rx STBC Felix Fietkau
2010-04-19 17:57               ` [PATCH v2 9/9] ath9k: set the STBC flag in rate control if the peer supports it Felix Fietkau
2010-04-19 19:04 ` [PATCH v2 1/9] ath9k: check for specific rx stuck conditions and recover from them Pavel Roskin
2010-04-19 19:07   ` Felix Fietkau

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).