diff --git a/sys/dev/iwm/if_iwm_phy_ctxt.c b/sys/dev/iwm/if_iwm_phy_ctxt.c index 5d8d7d24059..242e3abc388 100644 --- a/sys/dev/iwm/if_iwm_phy_ctxt.c +++ b/sys/dev/iwm/if_iwm_phy_ctxt.c @@ -218,6 +218,18 @@ iwm_mvm_phy_ctxt_cmd_data(struct iwm_softc *sc, idle_cnt = chains_static; active_cnt = chains_dynamic; + /* In scenarios where we only ever use a single-stream rates, + * i.e. legacy 11b/g/a associations, single-stream APs or even + * static SMPS, enable both chains to get diversity, improving + * the case where we're far enough from the AP that attenuation + * between the two antennas is sufficiently different to impact + * performance. + */ + if (active_cnt == 1 && iwm_mvm_rx_diversity_allowed(sc)) { + idle_cnt = 2; + active_cnt = 2; + } + cmd->rxchain_info = htole32(iwm_mvm_get_valid_rx_ant(sc) << IWM_PHY_RX_CHAIN_VALID_POS); cmd->rxchain_info |= htole32(idle_cnt << IWM_PHY_RX_CHAIN_CNT_POS); diff --git a/sys/dev/iwm/if_iwm_util.c b/sys/dev/iwm/if_iwm_util.c index 4ce9c8a6db5..4744fa16340 100644 --- a/sys/dev/iwm/if_iwm_util.c +++ b/sys/dev/iwm/if_iwm_util.c @@ -153,6 +153,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -487,3 +488,17 @@ iwm_dma_contig_free(struct iwm_dma_info *dma) dma->tag = NULL; } } + +boolean_t +iwm_mvm_rx_diversity_allowed(struct iwm_softc *sc) +{ + if (num_of_ant(iwm_mvm_get_valid_rx_ant(sc)) == 1) + return FALSE; + + /* + * XXX Also return FALSE when SMPS (Spatial Multiplexing Powersave) + * is used on any vap (in the future). + */ + + return TRUE; +} diff --git a/sys/dev/iwm/if_iwm_util.h b/sys/dev/iwm/if_iwm_util.h index 460c660877c..f2109d4798a 100644 --- a/sys/dev/iwm/if_iwm_util.h +++ b/sys/dev/iwm/if_iwm_util.h @@ -120,6 +120,8 @@ extern int iwm_dma_contig_alloc(bus_dma_tag_t tag, struct iwm_dma_info *dma, bus_size_t size, bus_size_t alignment); extern void iwm_dma_contig_free(struct iwm_dma_info *); +extern boolean_t iwm_mvm_rx_diversity_allowed(struct iwm_softc *sc); + extern uint8_t iwm_ridx2rate(struct ieee80211_rateset *rs, int ridx); static inline uint8_t