mac80211: fix peer HT capabilities

I noticed yesterday, because Jeff had noticed
a speed regression, cf. bug
http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=2138
that the SM PS settings for peers were wrong.
Instead of overwriting the SM PS settings with
the local bits, we need to keep the remote bits.

The bug was part of the original HT code from
over two years ago, but unfortunately nobody
noticed that it makes no sense -- we shouldn't
be overwriting the peer's setting with our own
but rather keep it intact when masking the peer
capabilities with our own.

While fixing that, I noticed that the masking of
capabilities is completely useless for most of
the bits, so also fix those other bits.

Finally, I also noticed that PSMP_SUPPORT no
longer exists in the final 802.11n version, so
also remove that.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
Johannes Berg 2009-12-17 13:55:48 +01:00 committed by John W. Linville
parent 8585c2b896
commit 9a418af5df
3 changed files with 24 additions and 6 deletions

View File

@ -2080,8 +2080,7 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_20 |
IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_40 |
IEEE80211_HT_CAP_TX_STBC | IEEE80211_HT_CAP_TX_STBC |
IEEE80211_HT_CAP_RX_STBC | IEEE80211_HT_CAP_RX_STBC;
IEEE80211_HT_CAP_PSMP_SUPPORT;
spec->ht.ampdu_factor = 3; spec->ht.ampdu_factor = 3;
spec->ht.ampdu_density = 4; spec->ht.ampdu_density = 4;
spec->ht.mcs.tx_params = spec->ht.mcs.tx_params =

View File

@ -832,7 +832,7 @@ struct ieee80211_ht_cap {
#define IEEE80211_HT_CAP_DELAY_BA 0x0400 #define IEEE80211_HT_CAP_DELAY_BA 0x0400
#define IEEE80211_HT_CAP_MAX_AMSDU 0x0800 #define IEEE80211_HT_CAP_MAX_AMSDU 0x0800
#define IEEE80211_HT_CAP_DSSSCCK40 0x1000 #define IEEE80211_HT_CAP_DSSSCCK40 0x1000
#define IEEE80211_HT_CAP_PSMP_SUPPORT 0x2000 #define IEEE80211_HT_CAP_RESERVED 0x2000
#define IEEE80211_HT_CAP_40MHZ_INTOLERANT 0x4000 #define IEEE80211_HT_CAP_40MHZ_INTOLERANT 0x4000
#define IEEE80211_HT_CAP_LSIG_TXOP_PROT 0x8000 #define IEEE80211_HT_CAP_LSIG_TXOP_PROT 0x8000

View File

@ -34,9 +34,28 @@ void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband,
ht_cap->ht_supported = true; ht_cap->ht_supported = true;
ht_cap->cap = le16_to_cpu(ht_cap_ie->cap_info) & sband->ht_cap.cap; /*
ht_cap->cap &= ~IEEE80211_HT_CAP_SM_PS; * The bits listed in this expression should be
ht_cap->cap |= sband->ht_cap.cap & IEEE80211_HT_CAP_SM_PS; * the same for the peer and us, if the station
* advertises more then we can't use those thus
* we mask them out.
*/
ht_cap->cap = le16_to_cpu(ht_cap_ie->cap_info) &
(sband->ht_cap.cap |
~(IEEE80211_HT_CAP_LDPC_CODING |
IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
IEEE80211_HT_CAP_GRN_FLD |
IEEE80211_HT_CAP_SGI_20 |
IEEE80211_HT_CAP_SGI_40 |
IEEE80211_HT_CAP_DSSSCCK40));
/*
* The STBC bits are asymmetric -- if we don't have
* TX then mask out the peer's RX and vice versa.
*/
if (!(sband->ht_cap.cap & IEEE80211_HT_CAP_TX_STBC))
ht_cap->cap &= ~IEEE80211_HT_CAP_RX_STBC;
if (!(sband->ht_cap.cap & IEEE80211_HT_CAP_RX_STBC))
ht_cap->cap &= ~IEEE80211_HT_CAP_TX_STBC;
ampdu_info = ht_cap_ie->ampdu_params_info; ampdu_info = ht_cap_ie->ampdu_params_info;
ht_cap->ampdu_factor = ht_cap->ampdu_factor =