On Thu, Apr 20, 2017 at 5:31 AM, Stefan Sperling <s...@stsp.name> wrote:
> 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;

I applied the patch and compiled a new kernel using the stable branch.
11n and 11g both work now,
but with significantly worse performance than 11b. Downloads are about
40% slower.

$ curl http://download.thinkbroadband.com/200MB.zip -O
was my test.

Reply via email to