I noticed that iwm's firmware skips MIMO rates on Tx and sends frames
at the lowest fallback rate instead.

This is not visible in ifconfig or even net80211. Everything there
indicates that we were using some MCS >= 8 and all was good.

But tcpbench is much slower than it should be, and monitor mode
reveals that all frames are sent on the air with the lowest rate,
e.g. 6Mbit/s on 5 GHz.

This happens because new firmware requires flags to be set in order
to enable MIMO rates for a peer, and we don't set those flags yet.

I have also found that one of my APs advertises its supported HT rates
quite late (in the assoc response, rather than the auth response),
and that iwm doesn't pick this up yet. Applying just the first hunk
isn't enough to fix the problem with that AP. We need to give the
firmware latest info about our AP in iwm_run() as well.  

ok?
 
diff 960b1fc5c6485d1b9e9fe9d73b34986dd0a3a942 
afc0cb751528613b0fea93e24aee4f4f3a0aa9f7
blob - c6963275801e8f8b962721bcd81fd3b1a541b46f (mode 644)
blob + d2395389096f3181ff9503e07a4b9541783ab9af (mode 600)
--- sys/dev/pci/if_iwm.c
+++ sys/dev/pci/if_iwm.c
@@ -5286,6 +5286,17 @@ iwm_add_sta_cmd(struct iwm_softc *sc, struct iwm_node 
                    |= htole32(IWM_STA_FLG_MAX_AGG_SIZE_MSK |
                    IWM_STA_FLG_AGG_MPDU_DENS_MSK);
 
+               if (!sc->sc_nvm.sku_cap_mimo_disable) {
+                       if (in->in_ni.ni_rxmcs[1] != 0) {
+                               add_sta_cmd.station_flags |=
+                                   htole32(IWM_STA_FLG_MIMO_EN_MIMO2);
+                       }
+                       if (in->in_ni.ni_rxmcs[2] != 0) {
+                               add_sta_cmd.station_flags |=
+                                   htole32(IWM_STA_FLG_MIMO_EN_MIMO3);
+                       }
+               }
+
                add_sta_cmd.station_flags
                    |= htole32(IWM_STA_FLG_MAX_AGG_SIZE_64K);
                switch (ic->ic_ampdu_params & IEEE80211_AMPDU_PARAM_SS) {
@@ -6667,6 +6678,14 @@ iwm_run(struct iwm_softc *sc)
                            DEVNAME(sc));
                        return err;
                }
+       }
+
+       /* Update STA again, for HT-related settings such as MIMO. */
+       err = iwm_add_sta_cmd(sc, in, 1);
+       if (err) {
+               printf("%s: could not update STA (error %d)\n",
+                   DEVNAME(sc), err);
+               return err;
        }
 
        /* We have now been assigned an associd by the AP. */

Reply via email to