Signed-off-by: Felix Fietkau <[email protected]>
---
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
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 <[email protected]>
---
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
On Mon, 2010-04-19 at 10:45 +0200, Felix Fietkau wrote:
> On 2010-04-19 7:57 AM, Johannes Berg wrote:
> > On Sun, 2010-04-18 at 18:05 +0200, Felix Fietkau wrote:
> >
> >> >> + * @IEEE80211_TX_CTL_STBC: tells the driver to use Space-Time Block Coding
> >> >> + * (STBC) for this frame.
> >> >> */
> >> >> enum mac80211_tx_control_flags {
> >> >> IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0),
> >> >> @@ -299,6 +301,7 @@ 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),
> >> >
> >> > What if the # of streams is different? That doesn't look sufficient.
> >
> >> Hm, you're right. I initially thought the combination of the MCS index
> >> and the STBC flag would be enough, but there are still some corner cases.
> >
> > Hm actually I guess that should be sufficient? What corner case are you
> > thinking of?
> Support for multi-rate retry and STBC with more than one stream on one
> side, using rates from both MCS0-7 and MCS8-15 in the rate series.
> Rx STBC for only one stream on the other side.
So the flag should be per rate entry instead, no?
johannes
On 2010-04-18 5:53 PM, Johannes Berg wrote:
> On Sun, 2010-04-18 at 16:56 +0200, Felix Fietkau wrote:
>> Signed-off-by: Felix Fietkau <[email protected]>
>> ---
>> include/linux/ieee80211.h | 1 +
>> include/net/mac80211.h | 3 +++
>> 2 files changed, 4 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..eadf794 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: tells the driver to use Space-Time Block Coding
>> + * (STBC) for this frame.
>> */
>> enum mac80211_tx_control_flags {
>> IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0),
>> @@ -299,6 +301,7 @@ 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),
>
> What if the # of streams is different? That doesn't look sufficient.
Hm, you're right. I initially thought the combination of the MCS index
and the STBC flag would be enough, but there are still some corner cases.
Want me to use BIT(23)|BIT(24) for this and add a shift, as with the HT
capability?
- Felix
On Sun, 2010-04-18 at 16:56 +0200, Felix Fietkau wrote:
> Signed-off-by: Felix Fietkau <[email protected]>
> ---
> include/linux/ieee80211.h | 1 +
> include/net/mac80211.h | 3 +++
> 2 files changed, 4 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..eadf794 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: tells the driver to use Space-Time Block Coding
> + * (STBC) for this frame.
> */
> enum mac80211_tx_control_flags {
> IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0),
> @@ -299,6 +301,7 @@ 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),
What if the # of streams is different? That doesn't look sufficient.
johannes
On Mon, 2010-04-19 at 12:14 +0200, Felix Fietkau wrote:
> On 2010-04-19 11:09 AM, Johannes Berg wrote:
> > On Mon, 2010-04-19 at 11:06 +0200, Felix Fietkau wrote:
> >> On 2010-04-19 10:59 AM, Johannes Berg wrote:
> >> > On Mon, 2010-04-19 at 10:45 +0200, Felix Fietkau wrote:
> >> >> On 2010-04-19 7:57 AM, Johannes Berg wrote:
> >> >> > On Sun, 2010-04-18 at 18:05 +0200, Felix Fietkau wrote:
> >> >> >
> >> >> >> >> + * @IEEE80211_TX_CTL_STBC: tells the driver to use Space-Time Block Coding
> >> >> >> >> + * (STBC) for this frame.
> >> >> >> >> */
> >> >> >> >> enum mac80211_tx_control_flags {
> >> >> >> >> IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0),
> >> >> >> >> @@ -299,6 +301,7 @@ 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),
> >> >> >> >
> >> >> >> > What if the # of streams is different? That doesn't look sufficient.
> >> >> >
> >> >> >> Hm, you're right. I initially thought the combination of the MCS index
> >> >> >> and the STBC flag would be enough, but there are still some corner cases.
> >> >> >
> >> >> > Hm actually I guess that should be sufficient? What corner case are you
> >> >> > thinking of?
> >> >> Support for multi-rate retry and STBC with more than one stream on one
> >> >> side, using rates from both MCS0-7 and MCS8-15 in the rate series.
> >> >> Rx STBC for only one stream on the other side.
> >> >
> >> > So the flag should be per rate entry instead, no?
> >
> >> Well, I think if we use two bits in the tx control flags, we don't need
> >> it to be per rate entry.
> >
> > But then you can't probe stbc properly, can you?
> I'm not sure we even need to probe STBC. In all of the drivers that I've
> looked at, it's always enabled if the peer supports it.
> I'm not aware of any situation where it would make the reception worse,
> aside from hardware damage of course ;)
Ok ... I guess two bits then so you don't have to look up sta capability
when doing the hw programming?
johannes
On Sun, 2010-04-18 at 18:05 +0200, Felix Fietkau wrote:
> >> + * @IEEE80211_TX_CTL_STBC: tells the driver to use Space-Time Block Coding
> >> + * (STBC) for this frame.
> >> */
> >> enum mac80211_tx_control_flags {
> >> IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0),
> >> @@ -299,6 +301,7 @@ 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),
> >
> > What if the # of streams is different? That doesn't look sufficient.
> Hm, you're right. I initially thought the combination of the MCS index
> and the STBC flag would be enough, but there are still some corner cases.
Hm actually I guess that should be sufficient? What corner case are you
thinking of?
johannes
Signed-off-by: Felix Fietkau <[email protected]>
---
include/linux/ieee80211.h | 1 +
include/net/mac80211.h | 3 +++
2 files changed, 4 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..eadf794 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: tells the driver to use Space-Time Block Coding
+ * (STBC) for this frame.
*/
enum mac80211_tx_control_flags {
IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0),
@@ -299,6 +301,7 @@ 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),
};
/**
--
1.6.4.2
On 2010-04-19 10:59 AM, Johannes Berg wrote:
> On Mon, 2010-04-19 at 10:45 +0200, Felix Fietkau wrote:
>> On 2010-04-19 7:57 AM, Johannes Berg wrote:
>> > On Sun, 2010-04-18 at 18:05 +0200, Felix Fietkau wrote:
>> >
>> >> >> + * @IEEE80211_TX_CTL_STBC: tells the driver to use Space-Time Block Coding
>> >> >> + * (STBC) for this frame.
>> >> >> */
>> >> >> enum mac80211_tx_control_flags {
>> >> >> IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0),
>> >> >> @@ -299,6 +301,7 @@ 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),
>> >> >
>> >> > What if the # of streams is different? That doesn't look sufficient.
>> >
>> >> Hm, you're right. I initially thought the combination of the MCS index
>> >> and the STBC flag would be enough, but there are still some corner cases.
>> >
>> > Hm actually I guess that should be sufficient? What corner case are you
>> > thinking of?
>> Support for multi-rate retry and STBC with more than one stream on one
>> side, using rates from both MCS0-7 and MCS8-15 in the rate series.
>> Rx STBC for only one stream on the other side.
>
> So the flag should be per rate entry instead, no?
Well, I think if we use two bits in the tx control flags, we don't need
it to be per rate entry.
We don't have any space left for more per rate entry flags ;)
- Felix
Signed-off-by: Felix Fietkau <[email protected]>
---
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
On 2010-04-19 12:19 PM, Johannes Berg wrote:
> On Mon, 2010-04-19 at 12:14 +0200, Felix Fietkau wrote:
>> On 2010-04-19 11:09 AM, Johannes Berg wrote:
>> > On Mon, 2010-04-19 at 11:06 +0200, Felix Fietkau wrote:
>> >> On 2010-04-19 10:59 AM, Johannes Berg wrote:
>> >> > On Mon, 2010-04-19 at 10:45 +0200, Felix Fietkau wrote:
>> >> >> On 2010-04-19 7:57 AM, Johannes Berg wrote:
>> >> >> > On Sun, 2010-04-18 at 18:05 +0200, Felix Fietkau wrote:
>> >> >> >
>> >> >> >> >> + * @IEEE80211_TX_CTL_STBC: tells the driver to use Space-Time Block Coding
>> >> >> >> >> + * (STBC) for this frame.
>> >> >> >> >> */
>> >> >> >> >> enum mac80211_tx_control_flags {
>> >> >> >> >> IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0),
>> >> >> >> >> @@ -299,6 +301,7 @@ 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),
>> >> >> >> >
>> >> >> >> > What if the # of streams is different? That doesn't look sufficient.
>> >> >> >
>> >> >> >> Hm, you're right. I initially thought the combination of the MCS index
>> >> >> >> and the STBC flag would be enough, but there are still some corner cases.
>> >> >> >
>> >> >> > Hm actually I guess that should be sufficient? What corner case are you
>> >> >> > thinking of?
>> >> >> Support for multi-rate retry and STBC with more than one stream on one
>> >> >> side, using rates from both MCS0-7 and MCS8-15 in the rate series.
>> >> >> Rx STBC for only one stream on the other side.
>> >> >
>> >> > So the flag should be per rate entry instead, no?
>> >
>> >> Well, I think if we use two bits in the tx control flags, we don't need
>> >> it to be per rate entry.
>> >
>> > But then you can't probe stbc properly, can you?
>> I'm not sure we even need to probe STBC. In all of the drivers that I've
>> looked at, it's always enabled if the peer supports it.
>> I'm not aware of any situation where it would make the reception worse,
>> aside from hardware damage of course ;)
>
> Ok ... I guess two bits then so you don't have to look up sta capability
> when doing the hw programming?
Right. I'll send a new series later.
- Felix
Signed-off-by: Felix Fietkau <[email protected]>
---
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..7f2000c 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 |= IEEE80211_TX_CTL_STBC;
+
if (is_probe) {
/* set one try for probe rates. For the
* probes don't enable rts */
--
1.6.4.2
Supported only for single stream rates by the hardware
Signed-off-by: Felix Fietkau <[email protected]>
---
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
Hi all,
Is STBC not supported on any chipsets other than AR_SREV_9280_10_OR_LATER(ah)?
/Bj?rn
On Sun, Apr 18, 2010 at 4:56 PM, Felix Fietkau <[email protected]> wrote:
> Supported only for single stream rates by the hardware
>
> Signed-off-by: Felix Fietkau <[email protected]>
> ---
> ?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
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to [email protected]
> More majordomo info at ?http://vger.kernel.org/majordomo-info.html
>
--
Venatech AB
Ideon Innovation
Ole R?mers v?g 12
SE-22370 LUND
Sweden
+46 (0) 46 286 86 20
[email protected]
http://www.venatech.se
On 2010-04-19 7:57 AM, Johannes Berg wrote:
> On Sun, 2010-04-18 at 18:05 +0200, Felix Fietkau wrote:
>
>> >> + * @IEEE80211_TX_CTL_STBC: tells the driver to use Space-Time Block Coding
>> >> + * (STBC) for this frame.
>> >> */
>> >> enum mac80211_tx_control_flags {
>> >> IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0),
>> >> @@ -299,6 +301,7 @@ 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),
>> >
>> > What if the # of streams is different? That doesn't look sufficient.
>
>> Hm, you're right. I initially thought the combination of the MCS index
>> and the STBC flag would be enough, but there are still some corner cases.
>
> Hm actually I guess that should be sufficient? What corner case are you
> thinking of?
Support for multi-rate retry and STBC with more than one stream on one
side, using rates from both MCS0-7 and MCS8-15 in the rate series.
Rx STBC for only one stream on the other side.
- Felix
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 <[email protected]>
---
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
On Mon, 2010-04-19 at 11:06 +0200, Felix Fietkau wrote:
> On 2010-04-19 10:59 AM, Johannes Berg wrote:
> > On Mon, 2010-04-19 at 10:45 +0200, Felix Fietkau wrote:
> >> On 2010-04-19 7:57 AM, Johannes Berg wrote:
> >> > On Sun, 2010-04-18 at 18:05 +0200, Felix Fietkau wrote:
> >> >
> >> >> >> + * @IEEE80211_TX_CTL_STBC: tells the driver to use Space-Time Block Coding
> >> >> >> + * (STBC) for this frame.
> >> >> >> */
> >> >> >> enum mac80211_tx_control_flags {
> >> >> >> IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0),
> >> >> >> @@ -299,6 +301,7 @@ 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),
> >> >> >
> >> >> > What if the # of streams is different? That doesn't look sufficient.
> >> >
> >> >> Hm, you're right. I initially thought the combination of the MCS index
> >> >> and the STBC flag would be enough, but there are still some corner cases.
> >> >
> >> > Hm actually I guess that should be sufficient? What corner case are you
> >> > thinking of?
> >> Support for multi-rate retry and STBC with more than one stream on one
> >> side, using rates from both MCS0-7 and MCS8-15 in the rate series.
> >> Rx STBC for only one stream on the other side.
> >
> > So the flag should be per rate entry instead, no?
> Well, I think if we use two bits in the tx control flags, we don't need
> it to be per rate entry.
But then you can't probe stbc properly, can you?
> We don't have any space left for more per rate entry flags ;)
separate problem ;)
johannes
On 19.04.2010, at 14:22, Björn Smedman <[email protected]>
wrote:
> Hi all,
>
> Is STBC not supported on any chipsets other than
> AR_SREV_9280_10_OR_LATER(ah)?
Right. AR9160 and older do not support this - at least according to
sources and datasheets.
- Felix
AR9300 based hardware can 3x3 MCS rates, this should be set in the
HT capabilities.
Signed-off-by: Felix Fietkau <[email protected]>
---
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
Signed-off-by: Felix Fietkau <[email protected]>
---
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
On 2010-04-19 11:09 AM, Johannes Berg wrote:
> On Mon, 2010-04-19 at 11:06 +0200, Felix Fietkau wrote:
>> On 2010-04-19 10:59 AM, Johannes Berg wrote:
>> > On Mon, 2010-04-19 at 10:45 +0200, Felix Fietkau wrote:
>> >> On 2010-04-19 7:57 AM, Johannes Berg wrote:
>> >> > On Sun, 2010-04-18 at 18:05 +0200, Felix Fietkau wrote:
>> >> >
>> >> >> >> + * @IEEE80211_TX_CTL_STBC: tells the driver to use Space-Time Block Coding
>> >> >> >> + * (STBC) for this frame.
>> >> >> >> */
>> >> >> >> enum mac80211_tx_control_flags {
>> >> >> >> IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0),
>> >> >> >> @@ -299,6 +301,7 @@ 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),
>> >> >> >
>> >> >> > What if the # of streams is different? That doesn't look sufficient.
>> >> >
>> >> >> Hm, you're right. I initially thought the combination of the MCS index
>> >> >> and the STBC flag would be enough, but there are still some corner cases.
>> >> >
>> >> > Hm actually I guess that should be sufficient? What corner case are you
>> >> > thinking of?
>> >> Support for multi-rate retry and STBC with more than one stream on one
>> >> side, using rates from both MCS0-7 and MCS8-15 in the rate series.
>> >> Rx STBC for only one stream on the other side.
>> >
>> > So the flag should be per rate entry instead, no?
>
>> Well, I think if we use two bits in the tx control flags, we don't need
>> it to be per rate entry.
>
> But then you can't probe stbc properly, can you?
I'm not sure we even need to probe STBC. In all of the drivers that I've
looked at, it's always enabled if the peer supports it.
I'm not aware of any situation where it would make the reception worse,
aside from hardware damage of course ;)
- Felix