mwifiex: set HT capability based on cfg80211_ap_settings
authorAvinash Patil <patila@marvell.com>
Fri, 15 Jun 2012 19:21:53 +0000 (12:21 -0700)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 20 Jun 2012 19:14:22 +0000 (15:14 -0400)
Parse HT IE from cfg80211 and set HT capabilities accordingly
to FW. If HT IE is missing, 11n would be disabled in FW.

Signed-off-by: Avinash Patil <patila@marvell.com>
Signed-off-by: Kiran Divekar <dkiran@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/fw.h
drivers/net/wireless/mwifiex/ioctl.h
drivers/net/wireless/mwifiex/main.h
drivers/net/wireless/mwifiex/uap_cmd.c

index 7b4eaf41bfc019effcf3048b268b1ae65d16080d..5af3f97936e4638104c07da090a02fc4824730da 100644 (file)
@@ -978,6 +978,8 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
                return -1;
        }
 
+       mwifiex_set_ht_params(priv, bss_cfg, params);
+
        if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_UAP_BSS_STOP,
                                  HostCmd_ACT_GEN_SET, 0, NULL)) {
                wiphy_err(wiphy, "Failed to stop the BSS\n");
index 561452a5c818f4a3d6ea653d029cd32fdab80587..9686f6fec19a5680d1341fd77797e866e9a983b7 100644 (file)
@@ -162,6 +162,12 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
 
 #define ISSUPP_11NENABLED(FwCapInfo) (FwCapInfo & BIT(11))
 
+#define MWIFIEX_DEF_HT_CAP     (IEEE80211_HT_CAP_DSSSCCK40 | \
+                                (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT) | \
+                                IEEE80211_HT_CAP_SM_PS)
+
+#define MWIFIEX_DEF_AMPDU      IEEE80211_HT_AMPDU_PARM_FACTOR
+
 /* dev_cap bitmap
  * BIT
  * 0-16                reserved
index e6be6ee75951ca811c78d7ebacaf9f05c0240c0a..8c8e47c792a007881694398c96f2e9f67ce8b8ba 100644 (file)
@@ -90,6 +90,7 @@ struct mwifiex_uap_bss_param {
        u16 key_mgmt;
        u16 key_mgmt_operation;
        struct wpa_param wpa_cfg;
+       struct ieee80211_ht_cap ht_cap;
 };
 
 enum {
index 512481ea664e1c058fdacb7f6ee8688c26a5cf4b..0b3b5aa9830dbb4a38fe6887fbc23264ef47648f 100644 (file)
@@ -840,6 +840,9 @@ void mwifiex_init_priv_params(struct mwifiex_private *priv,
 int mwifiex_set_secure_params(struct mwifiex_private *priv,
                              struct mwifiex_uap_bss_param *bss_config,
                              struct cfg80211_ap_settings *params);
+void mwifiex_set_ht_params(struct mwifiex_private *priv,
+                          struct mwifiex_uap_bss_param *bss_cfg,
+                          struct cfg80211_ap_settings *params);
 
 /*
  * This function checks if the queuing is RA based or not.
index fb0c6cbfc2775c4fb8fec67e3eafe6305070d428..59e5ba4df02ba4fe7954f4a76258fec74b5674f7 100644 (file)
@@ -118,6 +118,33 @@ int mwifiex_set_secure_params(struct mwifiex_private *priv,
        return 0;
 }
 
+/* This function updates 11n related parameters from IE and sets them into
+ * bss_config structure.
+ */
+void
+mwifiex_set_ht_params(struct mwifiex_private *priv,
+                     struct mwifiex_uap_bss_param *bss_cfg,
+                     struct cfg80211_ap_settings *params)
+{
+       const u8 *ht_ie;
+
+       if (!ISSUPP_11NENABLED(priv->adapter->fw_cap_info))
+               return;
+
+       ht_ie = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, params->beacon.tail,
+                                params->beacon.tail_len);
+       if (ht_ie) {
+               memcpy(&bss_cfg->ht_cap, ht_ie + 2,
+                      sizeof(struct ieee80211_ht_cap));
+       } else {
+               memset(&bss_cfg->ht_cap , 0, sizeof(struct ieee80211_ht_cap));
+               bss_cfg->ht_cap.cap_info = cpu_to_le16(MWIFIEX_DEF_HT_CAP);
+               bss_cfg->ht_cap.ampdu_params_info = MWIFIEX_DEF_AMPDU;
+       }
+
+       return;
+}
+
 /* This function initializes some of mwifiex_uap_bss_param variables.
  * This helps FW in ignoring invalid values. These values may or may not
  * be get updated to valid ones at later stage.
@@ -154,6 +181,7 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
        struct host_cmd_tlv_auth_type *auth_type;
        struct host_cmd_tlv_passphrase *passphrase;
        struct host_cmd_tlv_akmp *tlv_akmp;
+       struct mwifiex_ie_types_htcap *htcap;
        struct mwifiex_uap_bss_param *bss_cfg = cmd_buf;
        u16 cmd_size = *param_size;
 
@@ -330,6 +358,25 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
                tlv += sizeof(struct host_cmd_tlv_encrypt_protocol);
        }
 
+       if (bss_cfg->ht_cap.cap_info) {
+               htcap = (struct mwifiex_ie_types_htcap *)tlv;
+               htcap->header.type = cpu_to_le16(WLAN_EID_HT_CAPABILITY);
+               htcap->header.len =
+                               cpu_to_le16(sizeof(struct ieee80211_ht_cap));
+               htcap->ht_cap.cap_info = bss_cfg->ht_cap.cap_info;
+               htcap->ht_cap.ampdu_params_info =
+                                            bss_cfg->ht_cap.ampdu_params_info;
+               memcpy(&htcap->ht_cap.mcs, &bss_cfg->ht_cap.mcs,
+                      sizeof(struct ieee80211_mcs_info));
+               htcap->ht_cap.extended_ht_cap_info =
+                                       bss_cfg->ht_cap.extended_ht_cap_info;
+               htcap->ht_cap.tx_BF_cap_info = bss_cfg->ht_cap.tx_BF_cap_info;
+               htcap->ht_cap.antenna_selection_info =
+                                       bss_cfg->ht_cap.antenna_selection_info;
+               cmd_size += sizeof(struct mwifiex_ie_types_htcap);
+               tlv += sizeof(struct mwifiex_ie_types_htcap);
+       }
+
        *param_size = cmd_size;
 
        return 0;