static bool is_single_rx_stream(struct iwl_priv *priv)
 {
        return !priv->current_ht_config.is_ht ||
-              ((priv->current_ht_config.mcs.rx_mask[1] == 0) &&
-               (priv->current_ht_config.mcs.rx_mask[2] == 0));
+              priv->current_ht_config.single_chain_sufficient;
 }
 
 static u8 iwl_is_channel_extension(struct iwl_priv *priv,
        if (priv->cfg->ops->hcmd->set_rxon_chain)
                priv->cfg->ops->hcmd->set_rxon_chain(priv);
 
-       IWL_DEBUG_ASSOC(priv, "supported HT rate 0x%X 0x%X 0x%X "
-                       "rxon flags 0x%X operation mode :0x%X "
+       IWL_DEBUG_ASSOC(priv, "rxon flags 0x%X operation mode :0x%X "
                        "extension channel offset 0x%x\n",
-                       ht_conf->mcs.rx_mask[0],
-                       ht_conf->mcs.rx_mask[1],
-                       ht_conf->mcs.rx_mask[2],
                        le32_to_cpu(rxon->flags), ht_conf->ht_protection,
                        ht_conf->extension_chan_offset);
        return;
  */
 static int iwl_get_active_rx_chain_count(struct iwl_priv *priv)
 {
-       bool is_single = is_single_rx_stream(priv);
-       bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status);
-
        /* # of Rx chains to use when expecting MIMO. */
-       if (is_single || (!is_cam && (priv->current_ht_config.sm_ps ==
-                                                WLAN_HT_CAP_SM_PS_STATIC)))
+       if (is_single_rx_stream(priv))
                return IWL_NUM_RX_CHAINS_SINGLE;
        else
                return IWL_NUM_RX_CHAINS_MULTIPLE;
 
 static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
 {
-       int idle_cnt;
        bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status);
+
        /* # Rx chains when idling and maybe trying to save power */
-       switch (priv->current_ht_config.sm_ps) {
-       case WLAN_HT_CAP_SM_PS_STATIC:
-       case WLAN_HT_CAP_SM_PS_DYNAMIC:
-               idle_cnt = (is_cam) ? IWL_NUM_IDLE_CHAINS_DUAL :
-                                       IWL_NUM_IDLE_CHAINS_SINGLE;
-               break;
-       case WLAN_HT_CAP_SM_PS_DISABLED:
-               idle_cnt = (is_cam) ? active_cnt : IWL_NUM_IDLE_CHAINS_SINGLE;
-               break;
-       case WLAN_HT_CAP_SM_PS_INVALID:
-       default:
-               IWL_ERR(priv, "invalid mimo ps mode %d\n",
-                          priv->current_ht_config.sm_ps);
-               WARN_ON(1);
-               idle_cnt = -1;
-               break;
-       }
-       return idle_cnt;
+
+       /*
+        * XXX: this is incorrect!!
+        *      we always indicate to the AP that
+        *      our SM PS mode is "disabled"
+        */
+
+       return is_cam ? active_cnt : IWL_NUM_IDLE_CHAINS_SINGLE;
 }
 
 /* up to 4 chains */
 
        priv->iw_mode = NL80211_IFTYPE_STATION;
 
-       priv->current_ht_config.sm_ps = WLAN_HT_CAP_SM_PS_DISABLED;
-
        /* Choose which receivers/antennas to use */
        if (priv->cfg->ops->hcmd->set_rxon_chain)
                priv->cfg->ops->hcmd->set_rxon_chain(priv);
 EXPORT_SYMBOL(iwl_mac_conf_tx);
 
 static void iwl_ht_conf(struct iwl_priv *priv,
-                           struct ieee80211_bss_conf *bss_conf)
+                       struct ieee80211_bss_conf *bss_conf)
 {
        struct iwl_ht_config *ht_conf = &priv->current_ht_config;
-       struct ieee80211_sta_ht_cap *ht_cap;
        struct ieee80211_sta *sta;
 
        IWL_DEBUG_MAC80211(priv, "enter: \n");
        if (!ht_conf->is_ht)
                return;
 
-
-       /*
-        * It is totally wrong to base global information on something
-        * that is valid only when associated, alas, this driver works
-        * that way and I don't know how to fix it.
-        */
-
-       rcu_read_lock();
-       sta = ieee80211_find_sta(priv->hw, priv->bssid);
-       if (!sta) {
-               rcu_read_unlock();
-               return;
-       }
-       ht_cap = &sta->ht_cap;
-
-       ht_conf->sm_ps = (u8)((ht_cap->cap & IEEE80211_HT_CAP_SM_PS) >> 2);
-
-       memcpy(&ht_conf->mcs, &ht_cap->mcs, 16);
-
        ht_conf->ht_protection =
                bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION;
        ht_conf->non_GF_STA_present =
                !!(bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
 
-       rcu_read_unlock();
+       ht_conf->single_chain_sufficient = false;
+
+       switch (priv->iw_mode) {
+       case NL80211_IFTYPE_STATION:
+               rcu_read_lock();
+               sta = ieee80211_find_sta(priv->hw, priv->bssid);
+               if (sta) {
+                       struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
+                       int maxstreams;
+
+                       maxstreams = (ht_cap->mcs.tx_params &
+                                     IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK)
+                                       >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
+                       maxstreams += 1;
+
+                       if ((ht_cap->mcs.rx_mask[1] == 0) &&
+                           (ht_cap->mcs.rx_mask[2] == 0))
+                               ht_conf->single_chain_sufficient = true;
+                       if (maxstreams <= 1)
+                               ht_conf->single_chain_sufficient = true;
+               } else {
+                       /*
+                        * If at all, this can only happen through a race
+                        * when the AP disconnects us while we're still
+                        * setting up the connection, in that case mac80211
+                        * will soon tell us about that.
+                        */
+                       ht_conf->single_chain_sufficient = true;
+               }
+               rcu_read_unlock();
+               break;
+       case NL80211_IFTYPE_ADHOC:
+               ht_conf->single_chain_sufficient = true;
+               break;
+       default:
+               break;
+       }
 
        IWL_DEBUG_MAC80211(priv, "leave\n");
 }