mwifiex: update MCS information as per antenna settings
authorAmitkumar Karwar <akarwar@marvell.com>
Fri, 28 Feb 2014 03:35:18 +0000 (19:35 -0800)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 28 Feb 2014 19:33:48 +0000 (14:33 -0500)
Even if the device is changed to 1X1 mode, data is sent with
higher MCS rates after association.

This patch fixes the problem by updating MCS information field
in HT capability when antenna setting changes so that correct
information will be advertised in association and probe request.

Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/mwifiex/cfg80211.c
drivers/net/wireless/mwifiex/cfp.c
drivers/net/wireless/mwifiex/cmdevt.c
drivers/net/wireless/mwifiex/fw.h
drivers/net/wireless/mwifiex/main.h

index bfe9316e196cc4451bbb2350ca93e2b709cfba8e..51ce99cfcfb97f633028ceb045fb5b3b17d4494a 100644 (file)
@@ -1324,6 +1324,33 @@ mwifiex_cfg80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant)
                        tx_ant = RF_ANTENNA_AUTO;
                        rx_ant = RF_ANTENNA_AUTO;
                }
+       } else {
+               struct ieee80211_sta_ht_cap *ht_info;
+               int rx_mcs_supp;
+               enum ieee80211_band band;
+
+               if ((tx_ant == 0x1 && rx_ant == 0x1)) {
+                       adapter->user_dev_mcs_support = HT_STREAM_1X1;
+                       if (adapter->is_hw_11ac_capable)
+                               adapter->usr_dot_11ac_mcs_support =
+                                               MWIFIEX_11AC_MCS_MAP_1X1;
+               } else {
+                       adapter->user_dev_mcs_support = HT_STREAM_2X2;
+                       if (adapter->is_hw_11ac_capable)
+                               adapter->usr_dot_11ac_mcs_support =
+                                               MWIFIEX_11AC_MCS_MAP_2X2;
+               }
+
+               for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+                       if (!adapter->wiphy->bands[band])
+                               continue;
+
+                       ht_info = &adapter->wiphy->bands[band]->ht_cap;
+                       rx_mcs_supp =
+                               GET_RXMCSSUPP(adapter->user_dev_mcs_support);
+                       memset(&ht_info->mcs, 0, adapter->number_of_antenna);
+                       memset(&ht_info->mcs, 0xff, rx_mcs_supp);
+               }
        }
 
        ant_cfg.tx_ant = tx_ant;
@@ -2093,8 +2120,8 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info,
        ht_info->cap &= ~IEEE80211_HT_CAP_MAX_AMSDU;
        ht_info->cap |= IEEE80211_HT_CAP_SM_PS;
 
-       rx_mcs_supp = GET_RXMCSSUPP(adapter->hw_dev_mcs_support);
-       /* Set MCS for 1x1 */
+       rx_mcs_supp = GET_RXMCSSUPP(adapter->user_dev_mcs_support);
+       /* Set MCS for 1x1/2x2 */
        memset(mcs, 0xff, rx_mcs_supp);
        /* Clear all the other values */
        memset(&mcs[rx_mcs_supp], 0,
index 2c3226bf86f89302716cd30178d76ba54697d869..0ddec3d4b059cbd7d03221578035d5b1721db9b2 100644 (file)
@@ -253,7 +253,7 @@ u32 mwifiex_index_to_data_rate(struct mwifiex_private *priv,
                               u8 index, u8 ht_info)
 {
        u32 mcs_num_supp =
-               (priv->adapter->hw_dev_mcs_support == HT_STREAM_2X2) ? 16 : 8;
+               (priv->adapter->user_dev_mcs_support == HT_STREAM_2X2) ? 16 : 8;
        u32 rate;
 
        if (priv->adapter->is_hw_11ac_capable)
index b4d28edaf8aa8ed45b741b02c3fd344245f2b1a8..14e05c9f4663dadcef536a3aa1ca3777ee0bd0aa 100644 (file)
@@ -1592,6 +1592,7 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
 
        adapter->hw_dot_11n_dev_cap = le32_to_cpu(hw_spec->dot_11n_dev_cap);
        adapter->hw_dev_mcs_support = hw_spec->dev_mcs_support;
+       adapter->user_dev_mcs_support = adapter->hw_dev_mcs_support;
 
        if (adapter->if_ops.update_mp_end_port)
                adapter->if_ops.update_mp_end_port(adapter,
index aa8abef583498a594da6a2fc01fc1013a1dfc1f0..39cb3542f79cdf777ccc9528e4ddb76768e5c89a 100644 (file)
@@ -236,8 +236,21 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
  */
 #define MWIFIEX_FW_DEF_HTTXCFG (BIT(1) | BIT(4) | BIT(5) | BIT(6))
 
+/* 11AC Tx and Rx MCS map for 1x1 mode:
+ * IEEE80211_VHT_MCS_SUPPORT_0_9 for stream 1
+ * IEEE80211_VHT_MCS_NOT_SUPPORTED for remaining 7 streams
+ */
+#define MWIFIEX_11AC_MCS_MAP_1X1       0xfffefffe
+
+/* 11AC Tx and Rx MCS map for 2x2 mode:
+ * IEEE80211_VHT_MCS_SUPPORT_0_9 for stream 1 and 2
+ * IEEE80211_VHT_MCS_NOT_SUPPORTED for remaining 6 streams
+ */
+#define MWIFIEX_11AC_MCS_MAP_2X2       0xfffafffa
+
 #define GET_RXMCSSUPP(DevMCSSupported) (DevMCSSupported & 0x0f)
 #define SETHT_MCS32(x) (x[4] |= 1)
+#define HT_STREAM_1X1  0x11
 #define HT_STREAM_2X2  0x22
 
 #define SET_SECONDARYCHAN(RadioType, SECCHAN) (RadioType |= (SECCHAN << 4))
index 51ac9e3355a236d1cd31de9daa374accf50318b8..f0289c12e041a066ea68f9153787e135c64a0376 100644 (file)
@@ -773,6 +773,7 @@ struct mwifiex_adapter {
        u8 event_body[MAX_EVENT_SIZE];
        u32 hw_dot_11n_dev_cap;
        u8 hw_dev_mcs_support;
+       u8 user_dev_mcs_support;
        u8 adhoc_11n_enabled;
        u8 sec_chan_offset;
        struct mwifiex_dbg dbg;