On Wed, Apr 19, 2017 at 10:08:01AM +0200, Stefan Sperling wrote: > On Tue, Apr 18, 2017 at 11:29:22PM -0500, Colton Lewis wrote: > > > Can you show me a dmesg please, specifically the lines which are > > > related to your wifi card? > > > athn0 at pci6 dev 0 function 0 "Atheros AR9281" rev 0x01: apic 8 int 17 > > athn0: AR9280 rev 2 (1T2R), ROM rev 11, address 00:15:af:cd:f2:4f > > Thank you! This confirms my suspicion that your wifi card is a weird one. > It can receive MIMO but cannot send MIMO (2 Rx chains but only 1 Tx chain). > > Likely there's a bug in the code which fails to account for this situation. > AFAIK this kind of device has not been tested before. > > I'll take a look.
Please try this patch. This patch makes unequal numbers of Tx and Rx streams work in 11n mode. I have tested this patch by artificially limiting iwm(4) to one Tx stream. This works as expected (AP sends with two streams, iwm(4) sends with one). I still cannot explain why 11g mode became worse for you such that only 11b mode works. I cannot recall any change which would make a difference between 6.0 and 6.1 in that regard. Are you sure you were testing 11g mode correctly? When you switched your athn client to 11g mode, did your AP follow this change or did it continue treating your client as 11n capable? A quirk like that would explain this discrepancy. Index: sys/net80211/ieee80211.h =================================================================== RCS file: /cvs/src/sys/net80211/ieee80211.h,v retrieving revision 1.58 diff -u -p -r1.58 ieee80211.h --- sys/net80211/ieee80211.h 12 May 2016 18:18:48 -0000 1.58 +++ sys/net80211/ieee80211.h 19 Apr 2017 13:47:13 -0000 @@ -612,8 +612,8 @@ enum { /* Bits 96-100: Tx MCS set */ #define IEEE80211_TX_MCS_SET_DEFINED 0x01 #define IEEE80211_TX_RX_MCS_NOT_EQUAL 0x02 -#define IEEE80211_TX_SPATIAL_STREAMS 0x18 -#define IEEE80211_TX_UNEQUAL_MODULATION 0x20 +#define IEEE80211_TX_SPATIAL_STREAMS 0x0c +#define IEEE80211_TX_UNEQUAL_MODULATION 0x10 /* Bits 101-127: Reserved */ /* Index: sys/net80211/ieee80211_mira.c =================================================================== RCS file: /cvs/src/sys/net80211/ieee80211_mira.c,v retrieving revision 1.10 diff -u -p -r1.10 ieee80211_mira.c --- sys/net80211/ieee80211_mira.c 28 Jan 2017 16:01:36 -0000 1.10 +++ sys/net80211/ieee80211_mira.c 20 Apr 2017 09:37:53 -0000 @@ -81,6 +81,7 @@ int ieee80211_mira_check_probe_timers(st struct ieee80211_node *); void ieee80211_mira_probe_next_rate(struct ieee80211_mira_node *, struct ieee80211_node *); +int ieee80211_mira_valid_tx_mcs(struct ieee80211com *, int); uint32_t ieee80211_mira_valid_rates(struct ieee80211com *, struct ieee80211_node *); uint32_t ieee80211_mira_mcs_below(struct ieee80211_mira_node *, int); @@ -991,6 +992,21 @@ ieee80211_mira_probe_next_rate(struct ie ni->ni_txmcs = ieee80211_mira_next_mcs(mn, ni); } +int +ieee80211_mira_valid_tx_mcs(struct ieee80211com *ic, int mcs) +{ + uint32_t ntxstreams = 1; + static const int max_mcs[] = { 7, 15, 23, 31 }; + + if ((ic->ic_tx_mcs_set & IEEE80211_TX_RX_MCS_NOT_EQUAL) == 0) + return isset(ic->ic_sup_mcs, mcs); + + ntxstreams += ((ic->ic_tx_mcs_set & IEEE80211_TX_SPATIAL_STREAMS) >> 2); + if (ntxstreams < 1 || ntxstreams > 4) + panic("invalid number of Tx streams: %u", ntxstreams); + return (mcs <= max_mcs[ntxstreams - 1] && isset(ic->ic_sup_mcs, mcs)); +} + uint32_t ieee80211_mira_valid_rates(struct ieee80211com *ic, struct ieee80211_node *ni) { @@ -999,8 +1015,11 @@ ieee80211_mira_valid_rates(struct ieee80 for (i = 0; i < MIN(IEEE80211_MIRA_NUM_MCS, IEEE80211_HT_NUM_MCS); i++) { - if (isset(ic->ic_sup_mcs, i) && isset(ni->ni_rxmcs, i)) - valid_mcs |= (1 << i); + if (!isset(ni->ni_rxmcs, i)) + continue; + if (!ieee80211_mira_valid_tx_mcs(ic, i)) + continue; + valid_mcs |= (1 << i); } return valid_mcs;