mwifiex: parse rate info for AP
authorAvinash Patil <patila@marvell.com>
Tue, 28 Aug 2012 03:32:53 +0000 (20:32 -0700)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 7 Sep 2012 19:03:41 +0000 (15:03 -0400)
This patch adds support for parsing rates from cfg80211_ap_settings
of start_ap handler. This in turn adds support for 11a and 11b phy
configurations.

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 e57f543413de010fcf435704abfe7d915a08e03a..f7a06d2bc670d72f34e292149942294a73ad4b94 100644 (file)
@@ -969,15 +969,18 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
 
        bss_cfg->channel =
            (u8)ieee80211_frequency_to_channel(params->channel->center_freq);
-       bss_cfg->band_cfg = BAND_CONFIG_MANUAL;
 
        /* Set appropriate bands */
        if (params->channel->band == IEEE80211_BAND_2GHZ) {
+               bss_cfg->band_cfg = BAND_CONFIG_BG;
+
                if (params->channel_type == NL80211_CHAN_NO_HT)
                        config_bands = BAND_B | BAND_G;
                else
                        config_bands = BAND_B | BAND_G | BAND_GN;
        } else {
+               bss_cfg->band_cfg = BAND_CONFIG_A;
+
                if (params->channel_type == NL80211_CHAN_NO_HT)
                        config_bands = BAND_A;
                else
@@ -988,6 +991,7 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
              ~priv->adapter->fw_bands))
                priv->adapter->config_bands = config_bands;
 
+       mwifiex_set_uap_rates(bss_cfg, params);
        mwifiex_send_domain_info_cmd_fw(wiphy);
 
        if (mwifiex_set_secure_params(priv, bss_cfg, params)) {
index ae06f31c6838cbd0aed3a85c671550ca0c38bf37..1a4a694f9119b622bb171edff7f284961183437b 100644 (file)
@@ -108,6 +108,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
 #define MGMT_MASK_BEACON                       0x100
 
 #define TLV_TYPE_UAP_SSID                      0x0000
+#define TLV_TYPE_UAP_RATES                     0x0001
 
 #define PROPRIETARY_TLV_BASE_ID                 0x0100
 #define TLV_TYPE_KEY_MATERIAL       (PROPRIETARY_TLV_BASE_ID + 0)
@@ -1284,6 +1285,11 @@ struct host_cmd_tlv_ssid {
        u8 ssid[0];
 } __packed;
 
+struct host_cmd_tlv_rates {
+       struct host_cmd_tlv tlv;
+       u8 rates[0];
+} __packed;
+
 struct host_cmd_tlv_bcast_ssid {
        struct host_cmd_tlv tlv;
        u8 bcast_ctl;
index 6a5eded3be10e6e84d8d8f02dfc5b08f3b6c8b21..8688535e95eb26b2aab51ac3d6304a7d82dea180 100644 (file)
@@ -81,7 +81,11 @@ struct wep_key {
 
 #define KEY_MGMT_ON_HOST        0x03
 #define MWIFIEX_AUTH_MODE_AUTO  0xFF
-#define BAND_CONFIG_MANUAL      0x00
+#define BAND_CONFIG_BG          0x00
+#define BAND_CONFIG_A           0x01
+#define MWIFIEX_SUPPORTED_RATES                 14
+#define MWIFIEX_SUPPORTED_RATES_EXT             32
+
 struct mwifiex_uap_bss_param {
        u8 channel;
        u8 band_cfg;
@@ -100,6 +104,7 @@ struct mwifiex_uap_bss_param {
        struct wpa_param wpa_cfg;
        struct wep_key wep_cfg[NUM_WEP_KEYS];
        struct ieee80211_ht_cap ht_cap;
+       u8 rates[MWIFIEX_SUPPORTED_RATES];
 };
 
 enum {
index 994bc4fc263ef7aca64c87fe6109b5dd9548b6fe..ede0c65dcb9649343f25bd46a9010dd144065adf 100644 (file)
@@ -116,6 +116,7 @@ enum {
 #define MAX_BITMAP_RATES_SIZE                  10
 
 #define MAX_CHANNEL_BAND_BG     14
+#define MAX_CHANNEL_BAND_A      165
 
 #define MAX_FREQUENCY_BAND_BG   2484
 
@@ -249,10 +250,6 @@ struct ieee_types_header {
        u8 len;
 } __packed;
 
-#define MWIFIEX_SUPPORTED_RATES                 14
-
-#define MWIFIEX_SUPPORTED_RATES_EXT             32
-
 struct ieee_types_vendor_specific {
        struct ieee_types_vendor_header vend_hdr;
        u8 data[IEEE_MAX_IE_SIZE - sizeof(struct ieee_types_vendor_header)];
@@ -872,6 +869,8 @@ int mwifiex_set_secure_params(struct mwifiex_private *priv,
 void mwifiex_set_ht_params(struct mwifiex_private *priv,
                           struct mwifiex_uap_bss_param *bss_cfg,
                           struct cfg80211_ap_settings *params);
+void mwifiex_set_uap_rates(struct mwifiex_uap_bss_param *bss_cfg,
+                          struct cfg80211_ap_settings *params);
 
 /*
  * This function checks if the queuing is RA based or not.
index c10aac04be6ad291fc6f247da7f005067091ab52..8a627d856d18bab0aaf5cd7205a65393576da74f 100644 (file)
@@ -177,6 +177,25 @@ mwifiex_set_ht_params(struct mwifiex_private *priv,
        return;
 }
 
+/* This function finds supported rates IE from beacon parameter and sets
+ * these rates into bss_config structure.
+ */
+void
+mwifiex_set_uap_rates(struct mwifiex_uap_bss_param *bss_cfg,
+                     struct cfg80211_ap_settings *params)
+{
+       struct ieee_types_header *rate_ie;
+       int var_offset = offsetof(struct ieee80211_mgmt, u.beacon.variable);
+       const u8 *var_pos = params->beacon.head + var_offset;
+       int len = params->beacon.head_len - var_offset;
+
+       rate_ie = (void *)cfg80211_find_ie(WLAN_EID_SUPP_RATES, var_pos, len);
+       if (rate_ie)
+               memcpy(bss_cfg->rates, rate_ie + 1, rate_ie->len);
+
+       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.
@@ -323,8 +342,10 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
        struct host_cmd_tlv_retry_limit *retry_limit;
        struct host_cmd_tlv_encrypt_protocol *encrypt_protocol;
        struct host_cmd_tlv_auth_type *auth_type;
+       struct host_cmd_tlv_rates *tlv_rates;
        struct mwifiex_ie_types_htcap *htcap;
        struct mwifiex_uap_bss_param *bss_cfg = cmd_buf;
+       int i;
        u16 cmd_size = *param_size;
 
        if (bss_cfg->ssid.ssid_len) {
@@ -344,7 +365,23 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
                cmd_size += sizeof(struct host_cmd_tlv_bcast_ssid);
                tlv += sizeof(struct host_cmd_tlv_bcast_ssid);
        }
-       if (bss_cfg->channel && bss_cfg->channel <= MAX_CHANNEL_BAND_BG) {
+       if (bss_cfg->rates[0]) {
+               tlv_rates = (struct host_cmd_tlv_rates *)tlv;
+               tlv_rates->tlv.type = cpu_to_le16(TLV_TYPE_UAP_RATES);
+
+               for (i = 0; i < MWIFIEX_SUPPORTED_RATES && bss_cfg->rates[i];
+                    i++)
+                       tlv_rates->rates[i] = bss_cfg->rates[i];
+
+               tlv_rates->tlv.len = cpu_to_le16(i);
+               cmd_size += sizeof(struct host_cmd_tlv_rates) + i;
+               tlv += sizeof(struct host_cmd_tlv_rates) + i;
+       }
+       if (bss_cfg->channel &&
+           ((bss_cfg->band_cfg == BAND_CONFIG_BG &&
+             bss_cfg->channel <= MAX_CHANNEL_BAND_BG) ||
+           (bss_cfg->band_cfg == BAND_CONFIG_A &&
+            bss_cfg->channel <= MAX_CHANNEL_BAND_A))) {
                chan_band = (struct host_cmd_tlv_channel_band *)tlv;
                chan_band->tlv.type = cpu_to_le16(TLV_TYPE_CHANNELBANDLIST);
                chan_band->tlv.len =