Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
authorJohn W. Linville <linville@tuxdriver.com>
Tue, 19 Feb 2013 19:56:34 +0000 (14:56 -0500)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 19 Feb 2013 19:56:34 +0000 (14:56 -0500)
1  2 
drivers/net/wireless/mwifiex/11n.c
drivers/net/wireless/mwifiex/cfg80211.c
drivers/net/wireless/mwifiex/cmdevt.c
drivers/net/wireless/mwifiex/scan.c
drivers/net/wireless/mwifiex/sta_ioctl.c

index 25596ab0c57656a4bc122343d317f68f9e367df5,5e4e51a18b80709a35001244609a164481009d0e..45f19716687ee2639fb80019227cddd9bd7ce64c
@@@ -250,7 -250,8 +250,8 @@@ int mwifiex_cmd_amsdu_aggr_ctrl(struct 
   *      - Setting HT Tx capability and HT Tx information fields
   *      - Ensuring correct endian-ness
   */
- int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd, u16 cmd_action,
+ int mwifiex_cmd_11n_cfg(struct mwifiex_private *priv,
+                       struct host_cmd_ds_command *cmd, u16 cmd_action,
                        struct mwifiex_ds_11n_tx_cfg *txcfg)
  {
        struct host_cmd_ds_11n_cfg *htcfg = &cmd->params.htcfg;
        htcfg->action = cpu_to_le16(cmd_action);
        htcfg->ht_tx_cap = cpu_to_le16(txcfg->tx_htcap);
        htcfg->ht_tx_info = cpu_to_le16(txcfg->tx_htinfo);
+       if (priv->adapter->is_hw_11ac_capable)
+               htcfg->misc_config = cpu_to_le16(txcfg->misc_config);
        return 0;
  }
  
@@@ -494,8 -499,11 +499,8 @@@ void mwifiex_create_ba_tbl(struct mwifi
        if (!mwifiex_get_ba_tbl(priv, tid, ra)) {
                new_node = kzalloc(sizeof(struct mwifiex_tx_ba_stream_tbl),
                                   GFP_ATOMIC);
 -              if (!new_node) {
 -                      dev_err(priv->adapter->dev,
 -                              "%s: failed to alloc new_node\n", __func__);
 +              if (!new_node)
                        return;
 -              }
  
                INIT_LIST_HEAD(&new_node->list);
  
index dc5357c0098f8046241038715a68f4a84ad61ec4,9667425362ed97a0e36e1eb0ac7c48c562cc73ae..a44023a7bd571ca228be0a4fe16f09d4fe42a1a8
@@@ -834,6 -834,66 +834,66 @@@ mwifiex_cfg80211_change_virtual_intf(st
        return ret;
  }
  
+ static void
+ mwifiex_parse_htinfo(struct mwifiex_private *priv, u8 tx_htinfo,
+                    struct rate_info *rate)
+ {
+       struct mwifiex_adapter *adapter = priv->adapter;
+       if (adapter->is_hw_11ac_capable) {
+               /* bit[1-0]: 00=LG 01=HT 10=VHT */
+               if (tx_htinfo & BIT(0)) {
+                       /* HT */
+                       rate->mcs = priv->tx_rate;
+                       rate->flags |= RATE_INFO_FLAGS_MCS;
+               }
+               if (tx_htinfo & BIT(1)) {
+                       /* VHT */
+                       rate->mcs = priv->tx_rate & 0x0F;
+                       rate->flags |= RATE_INFO_FLAGS_VHT_MCS;
+               }
+               if (tx_htinfo & (BIT(1) | BIT(0))) {
+                       /* HT or VHT */
+                       switch (tx_htinfo & (BIT(3) | BIT(2))) {
+                       case 0:
+                               /* This will be 20MHz */
+                               break;
+                       case (BIT(2)):
+                               rate->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
+                               break;
+                       case (BIT(3)):
+                               rate->flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
+                               break;
+                       case (BIT(3) | BIT(2)):
+                               rate->flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH;
+                               break;
+                       }
+                       if (tx_htinfo & BIT(4))
+                               rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
+                       if ((priv->tx_rate >> 4) == 1)
+                               rate->nss = 2;
+                       else
+                               rate->nss = 1;
+               }
+       } else {
+               /*
+                * Bit 0 in tx_htinfo indicates that current Tx rate
+                * is 11n rate. Valid MCS index values for us are 0 to 15.
+                */
+               if ((tx_htinfo & BIT(0)) && (priv->tx_rate < 16)) {
+                       rate->mcs = priv->tx_rate;
+                       rate->flags |= RATE_INFO_FLAGS_MCS;
+                       if (tx_htinfo & BIT(1))
+                               rate->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
+                       if (tx_htinfo & BIT(2))
+                               rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
+               }
+       }
+ }
  /*
   * This function dumps the station information on a buffer.
   *
@@@ -873,20 -933,7 +933,7 @@@ mwifiex_dump_station_info(struct mwifie
                              HostCmd_ACT_GEN_GET, DTIM_PERIOD_I,
                              &priv->dtim_period);
  
-       /*
-        * Bit 0 in tx_htinfo indicates that current Tx rate is 11n rate. Valid
-        * MCS index values for us are 0 to 15.
-        */
-       if ((priv->tx_htinfo & BIT(0)) && (priv->tx_rate < 16)) {
-               sinfo->txrate.mcs = priv->tx_rate;
-               sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
-               /* 40MHz rate */
-               if (priv->tx_htinfo & BIT(1))
-                       sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
-               /* SGI enabled */
-               if (priv->tx_htinfo & BIT(2))
-                       sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
-       }
+       mwifiex_parse_htinfo(priv, priv->tx_htinfo, &sinfo->txrate);
  
        sinfo->signal_avg = priv->bcn_rssi_avg;
        sinfo->rx_bytes = priv->stats.rx_bytes;
@@@ -1295,20 -1342,22 +1342,22 @@@ static int mwifiex_cfg80211_start_ap(st
        /* Set appropriate bands */
        if (params->chandef.chan->band == IEEE80211_BAND_2GHZ) {
                bss_cfg->band_cfg = BAND_CONFIG_BG;
+               config_bands = BAND_B | BAND_G;
  
-               if (cfg80211_get_chandef_type(&params->chandef) ==
-                                               NL80211_CHAN_NO_HT)
-                       config_bands = BAND_B | BAND_G;
-               else
-                       config_bands = BAND_B | BAND_G | BAND_GN;
+               if (params->chandef.width > NL80211_CHAN_WIDTH_20_NOHT)
+                       config_bands |= BAND_GN;
+               if (params->chandef.width > NL80211_CHAN_WIDTH_40)
+                       config_bands |= BAND_GAC;
        } else {
                bss_cfg->band_cfg = BAND_CONFIG_A;
+               config_bands = BAND_A;
  
-               if (cfg80211_get_chandef_type(&params->chandef) ==
-                                               NL80211_CHAN_NO_HT)
-                       config_bands = BAND_A;
-               else
-                       config_bands = BAND_AN | BAND_A;
+               if (params->chandef.width > NL80211_CHAN_WIDTH_20_NOHT)
+                       config_bands |= BAND_AN;
+               if (params->chandef.width > NL80211_CHAN_WIDTH_40)
+                       config_bands |= BAND_AAC;
        }
  
        if (!((config_bands | priv->adapter->fw_bands) &
@@@ -1820,8 -1869,10 +1869,8 @@@ mwifiex_cfg80211_scan(struct wiphy *wip
  
        priv->user_scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg),
                                      GFP_KERNEL);
 -      if (!priv->user_scan_cfg) {
 -              dev_err(priv->adapter->dev, "failed to alloc scan_req\n");
 +      if (!priv->user_scan_cfg)
                return -ENOMEM;
 -      }
  
        priv->scan_request = request;
  
        return 0;
  }
  
+ static void mwifiex_setup_vht_caps(struct ieee80211_sta_vht_cap *vht_info,
+                                  struct mwifiex_private *priv)
+ {
+       struct mwifiex_adapter *adapter = priv->adapter;
+       u32 vht_cap = 0, cap = adapter->hw_dot_11ac_dev_cap;
+       vht_info->vht_supported = true;
+       switch (GET_VHTCAP_MAXMPDULEN(cap)) {
+       case 0x00:
+               vht_cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895;
+               break;
+       case 0x01:
+               vht_cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991;
+               break;
+       case 0x10:
+               vht_cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
+           break;
+       default:
+           dev_err(adapter->dev, "unsupported MAX MPDU len\n");
+           break;
+       }
+       if (ISSUPP_11ACVHTHTCVHT(cap))
+               vht_cap |= IEEE80211_VHT_CAP_HTC_VHT;
+       if (ISSUPP_11ACVHTTXOPPS(cap))
+               vht_cap |= IEEE80211_VHT_CAP_VHT_TXOP_PS;
+       if (ISSUPP_11ACMURXBEAMFORMEE(cap))
+               vht_cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
+       if (ISSUPP_11ACMUTXBEAMFORMEE(cap))
+               vht_cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
+       if (ISSUPP_11ACSUBEAMFORMER(cap))
+               vht_cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
+       if (ISSUPP_11ACSUBEAMFORMEE(cap))
+               vht_cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
+       if (ISSUPP_11ACRXSTBC(cap))
+               vht_cap |= IEEE80211_VHT_CAP_RXSTBC_1;
+       if (ISSUPP_11ACTXSTBC(cap))
+               vht_cap |= IEEE80211_VHT_CAP_TXSTBC;
+       if (ISSUPP_11ACSGI160(cap))
+               vht_cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
+       if (ISSUPP_11ACSGI80(cap))
+               vht_cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
+       if (ISSUPP_11ACLDPC(cap))
+               vht_cap |= IEEE80211_VHT_CAP_RXLDPC;
+       if (ISSUPP_11ACBW8080(cap))
+               vht_cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
+       if (ISSUPP_11ACBW160(cap))
+               vht_cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
+       vht_info->cap = vht_cap;
+       /* Update MCS support for VHT */
+       vht_info->vht_mcs.rx_mcs_map = cpu_to_le16(
+                               adapter->hw_dot_11ac_mcs_support & 0xFFFF);
+       vht_info->vht_mcs.rx_highest = 0;
+       vht_info->vht_mcs.tx_mcs_map = cpu_to_le16(
+                               adapter->hw_dot_11ac_mcs_support >> 16);
+       vht_info->vht_mcs.tx_highest = 0;
+ }
  /*
   * This function sets up the CFG802.11 specific HT capability fields
   * with default values.
@@@ -2092,15 -2216,23 +2214,22 @@@ struct wireless_dev *mwifiex_add_virtua
        priv->netdev = dev;
  
        mwifiex_setup_ht_caps(&wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap, priv);
+       if (adapter->is_hw_11ac_capable)
+               mwifiex_setup_vht_caps(
+                       &wiphy->bands[IEEE80211_BAND_2GHZ]->vht_cap, priv);
  
        if (adapter->config_bands & BAND_A)
                mwifiex_setup_ht_caps(
                        &wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap, priv);
  
+       if ((adapter->config_bands & BAND_A) && adapter->is_hw_11ac_capable)
+               mwifiex_setup_vht_caps(
+                       &wiphy->bands[IEEE80211_BAND_5GHZ]->vht_cap, priv);
        dev_net_set(dev, wiphy_net(wiphy));
        dev->ieee80211_ptr = priv->wdev;
        dev->ieee80211_ptr->iftype = priv->bss_mode;
        memcpy(dev->dev_addr, wiphy->perm_addr, ETH_ALEN);
 -      memcpy(dev->perm_addr, wiphy->perm_addr, ETH_ALEN);
        SET_NETDEV_DEV(dev, wiphy_dev(wiphy));
  
        dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
index 2b125beecf2c63e73083c92fd4722413d96b2fbe,5019f1f2e01c51ea146c62cec0fa4b9cb4521ac3..20a6c55558737b3bc3e3968856c5fe827780c688
@@@ -24,6 -24,7 +24,7 @@@
  #include "main.h"
  #include "wmm.h"
  #include "11n.h"
+ #include "11ac.h"
  
  /*
   * This function initializes a command node.
@@@ -334,15 -335,20 +335,15 @@@ static int mwifiex_dnld_sleep_confirm_c
  int mwifiex_alloc_cmd_buffer(struct mwifiex_adapter *adapter)
  {
        struct cmd_ctrl_node *cmd_array;
 -      u32 buf_size;
        u32 i;
  
        /* Allocate and initialize struct cmd_ctrl_node */
 -      buf_size = sizeof(struct cmd_ctrl_node) * MWIFIEX_NUM_OF_CMD_BUFFER;
 -      cmd_array = kzalloc(buf_size, GFP_KERNEL);
 -      if (!cmd_array) {
 -              dev_err(adapter->dev, "%s: failed to alloc cmd_array\n",
 -                      __func__);
 +      cmd_array = kcalloc(MWIFIEX_NUM_OF_CMD_BUFFER,
 +                          sizeof(struct cmd_ctrl_node), GFP_KERNEL);
 +      if (!cmd_array)
                return -ENOMEM;
 -      }
  
        adapter->cmd_pool = cmd_array;
 -      memset(adapter->cmd_pool, 0, buf_size);
  
        /* Allocate and initialize command buffers */
        for (i = 0; i < MWIFIEX_NUM_OF_CMD_BUFFER; i++) {
@@@ -1465,6 -1471,24 +1466,24 @@@ int mwifiex_ret_get_hw_spec(struct mwif
        adapter->fw_release_number = le32_to_cpu(hw_spec->fw_release_number);
        adapter->number_of_antenna = le16_to_cpu(hw_spec->number_of_antenna);
  
+       if (le32_to_cpu(hw_spec->dot_11ac_dev_cap)) {
+               adapter->is_hw_11ac_capable = true;
+               /* Copy 11AC cap */
+               adapter->hw_dot_11ac_dev_cap =
+                                       le32_to_cpu(hw_spec->dot_11ac_dev_cap);
+               adapter->usr_dot_11ac_dev_cap_bg = adapter->hw_dot_11ac_dev_cap;
+               adapter->usr_dot_11ac_dev_cap_a = adapter->hw_dot_11ac_dev_cap;
+               /* Copy 11AC mcs */
+               adapter->hw_dot_11ac_mcs_support =
+                               le32_to_cpu(hw_spec->dot_11ac_mcs_support);
+               adapter->usr_dot_11ac_mcs_support =
+                                       adapter->hw_dot_11ac_mcs_support;
+       } else {
+               adapter->is_hw_11ac_capable = false;
+       }
        dev_dbg(adapter->dev, "info: GET_HW_SPEC: fw_release_number- %#x\n",
                adapter->fw_release_number);
        dev_dbg(adapter->dev, "info: GET_HW_SPEC: permanent addr: %pM\n",
index e0cce1b52d55635e550e926b17be7814565f5cd7,db4d5ae3ff9679570b246295aa4d1cf0bc065d5a..bb60c2754a97ea54cc8c709206ba31a861e05d2e
@@@ -1250,6 -1250,23 +1250,23 @@@ int mwifiex_update_bss_desc_with_ie(str
                                        sizeof(struct ieee_types_header) -
                                        bss_entry->beacon_buf);
                        break;
+               case WLAN_EID_VHT_CAPABILITY:
+                       bss_entry->disable_11ac = false;
+                       bss_entry->bcn_vht_cap =
+                               (void *)(current_ptr +
+                                        sizeof(struct ieee_types_header));
+                       bss_entry->vht_cap_offset =
+                                       (u16)((u8 *)bss_entry->bcn_vht_cap -
+                                             bss_entry->beacon_buf);
+                       break;
+               case WLAN_EID_VHT_OPERATION:
+                       bss_entry->bcn_vht_oper =
+                               (void *)(current_ptr +
+                                        sizeof(struct ieee_types_header));
+                       bss_entry->vht_info_offset =
+                                       (u16)((u8 *)bss_entry->bcn_vht_oper -
+                                             bss_entry->beacon_buf);
+                       break;
                case WLAN_EID_BSS_COEX_2040:
                        bss_entry->bcn_bss_co_2040 = current_ptr +
                                sizeof(struct ieee_types_header);
                                        sizeof(struct ieee_types_header) -
                                        bss_entry->beacon_buf);
                        break;
+               case WLAN_EID_OPMODE_NOTIF:
+                       bss_entry->oper_mode =
+                               (void *)(current_ptr +
+                                        sizeof(struct ieee_types_header));
+                       bss_entry->oper_mode_offset =
+                                       (u16)((u8 *)bss_entry->oper_mode -
+                                             bss_entry->beacon_buf);
+                       break;
                default:
                        break;
                }
@@@ -1309,6 -1334,7 +1334,6 @@@ int mwifiex_scan_networks(struct mwifie
        struct cmd_ctrl_node *cmd_node;
        union mwifiex_scan_cmd_config_tlv *scan_cfg_out;
        struct mwifiex_ie_types_chan_list_param_set *chan_list_out;
 -      u32 buf_size;
        struct mwifiex_chan_scan_param_set *scan_chan_list;
        u8 filtered_scan;
        u8 scan_current_chan_only;
        spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
  
        scan_cfg_out = kzalloc(sizeof(union mwifiex_scan_cmd_config_tlv),
 -                                                              GFP_KERNEL);
 +                             GFP_KERNEL);
        if (!scan_cfg_out) {
 -              dev_err(adapter->dev, "failed to alloc scan_cfg_out\n");
                ret = -ENOMEM;
                goto done;
        }
  
 -      buf_size = sizeof(struct mwifiex_chan_scan_param_set) *
 -                                              MWIFIEX_USER_SCAN_CHAN_MAX;
 -      scan_chan_list = kzalloc(buf_size, GFP_KERNEL);
 +      scan_chan_list = kcalloc(MWIFIEX_USER_SCAN_CHAN_MAX,
 +                               sizeof(struct mwifiex_chan_scan_param_set),
 +                               GFP_KERNEL);
        if (!scan_chan_list) {
 -              dev_err(adapter->dev, "failed to alloc scan_chan_list\n");
                kfree(scan_cfg_out);
                ret = -ENOMEM;
                goto done;
@@@ -1458,9 -1486,12 +1483,9 @@@ static int mwifiex_update_curr_bss_para
        unsigned long flags;
  
        /* Allocate and fill new bss descriptor */
 -      bss_desc = kzalloc(sizeof(struct mwifiex_bssdescriptor),
 -                      GFP_KERNEL);
 -      if (!bss_desc) {
 -              dev_err(priv->adapter->dev, " failed to alloc bss_desc\n");
 +      bss_desc = kzalloc(sizeof(struct mwifiex_bssdescriptor), GFP_KERNEL);
 +      if (!bss_desc)
                return -ENOMEM;
 -      }
  
        ret = mwifiex_fill_new_bss_desc(priv, bss, bss_desc);
        if (ret)
        priv->curr_bss_params.bss_descriptor.bcn_wapi_ie = NULL;
        priv->curr_bss_params.bss_descriptor.wapi_offset = 0;
        priv->curr_bss_params.bss_descriptor.bcn_ht_cap = NULL;
-       priv->curr_bss_params.bss_descriptor.ht_cap_offset =
-               0;
+       priv->curr_bss_params.bss_descriptor.ht_cap_offset = 0;
        priv->curr_bss_params.bss_descriptor.bcn_ht_oper = NULL;
-       priv->curr_bss_params.bss_descriptor.ht_info_offset =
-               0;
-       priv->curr_bss_params.bss_descriptor.bcn_bss_co_2040 =
-               NULL;
-       priv->curr_bss_params.bss_descriptor.
-               bss_co_2040_offset = 0;
+       priv->curr_bss_params.bss_descriptor.ht_info_offset = 0;
+       priv->curr_bss_params.bss_descriptor.bcn_bss_co_2040 = NULL;
+       priv->curr_bss_params.bss_descriptor.bss_co_2040_offset = 0;
        priv->curr_bss_params.bss_descriptor.bcn_ext_cap = NULL;
        priv->curr_bss_params.bss_descriptor.ext_cap_offset = 0;
        priv->curr_bss_params.bss_descriptor.beacon_buf = NULL;
-       priv->curr_bss_params.bss_descriptor.beacon_buf_size =
-               0;
+       priv->curr_bss_params.bss_descriptor.beacon_buf_size = 0;
+       priv->curr_bss_params.bss_descriptor.bcn_vht_cap = NULL;
+       priv->curr_bss_params.bss_descriptor.vht_cap_offset = 0;
+       priv->curr_bss_params.bss_descriptor.bcn_vht_oper = NULL;
+       priv->curr_bss_params.bss_descriptor.vht_info_offset = 0;
+       priv->curr_bss_params.bss_descriptor.oper_mode = NULL;
+       priv->curr_bss_params.bss_descriptor.oper_mode_offset = 0;
+       /* Disable 11ac by default. Enable it only where there
+        * exist VHT_CAP IE in AP beacon
+        */
+       priv->curr_bss_params.bss_descriptor.disable_11ac = true;
  
        /* Make a copy of current BSSID descriptor */
        memcpy(&priv->curr_bss_params.bss_descriptor, bss_desc,
@@@ -1874,8 -1911,10 +1905,8 @@@ static int mwifiex_scan_specific_ssid(s
        }
  
        scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), GFP_KERNEL);
 -      if (!scan_cfg) {
 -              dev_err(adapter->dev, "failed to alloc scan_cfg\n");
 +      if (!scan_cfg)
                return -ENOMEM;
 -      }
  
        scan_cfg->ssid_list = req_ssid;
        scan_cfg->num_ssids = 1;
@@@ -1989,8 -2028,11 +2020,8 @@@ mwifiex_save_curr_bcn(struct mwifiex_pr
                kfree(priv->curr_bcn_buf);
                priv->curr_bcn_buf = kmalloc(curr_bss->beacon_buf_size,
                                             GFP_ATOMIC);
 -              if (!priv->curr_bcn_buf) {
 -                      dev_err(priv->adapter->dev,
 -                              "failed to alloc curr_bcn_buf\n");
 +              if (!priv->curr_bcn_buf)
                        return;
 -              }
        }
  
        memcpy(priv->curr_bcn_buf, curr_bss->beacon_buf,
                        (curr_bss->beacon_buf +
                         curr_bss->ht_info_offset);
  
+       if (curr_bss->bcn_vht_cap)
+               curr_bss->bcn_ht_cap = (void *)(curr_bss->beacon_buf +
+                                               curr_bss->vht_cap_offset);
+       if (curr_bss->bcn_vht_oper)
+               curr_bss->bcn_ht_oper = (void *)(curr_bss->beacon_buf +
+                                                curr_bss->vht_info_offset);
        if (curr_bss->bcn_bss_co_2040)
                curr_bss->bcn_bss_co_2040 =
                        (curr_bss->beacon_buf + curr_bss->bss_co_2040_offset);
        if (curr_bss->bcn_ext_cap)
                curr_bss->bcn_ext_cap = curr_bss->beacon_buf +
                        curr_bss->ext_cap_offset;
+       if (curr_bss->oper_mode)
+               curr_bss->oper_mode = (void *)(curr_bss->beacon_buf +
+                                              curr_bss->oper_mode_offset);
  }
  
  /*
index 7eef74564a92f50a308c5d54d54ce02d0cdb430a,7ce72e93260d5f2581df29d8a717e79a13e07e6e..9f33c92c90f5b8dc32bf9685bd3b708171b66acc
@@@ -261,9 -261,11 +261,9 @@@ int mwifiex_bss_start(struct mwifiex_pr
  
                /* Allocate and fill new bss descriptor */
                bss_desc = kzalloc(sizeof(struct mwifiex_bssdescriptor),
 -                              GFP_KERNEL);
 -              if (!bss_desc) {
 -                      dev_err(priv->adapter->dev, " failed to alloc bss_desc\n");
 +                                 GFP_KERNEL);
 +              if (!bss_desc)
                        return -ENOMEM;
 -              }
  
                ret = mwifiex_fill_new_bss_desc(priv, bss, bss_desc);
                if (ret)
  
                        if (mwifiex_band_to_radio_type((u8) bss_desc->bss_band)
                            == HostCmd_SCAN_RADIO_TYPE_BG)
-                               config_bands = BAND_B | BAND_G | BAND_GN;
+                               config_bands = BAND_B | BAND_G | BAND_GN |
+                                              BAND_GAC;
                        else
-                               config_bands = BAND_A | BAND_AN;
+                               config_bands = BAND_A | BAND_AN | BAND_AAC;
  
                        if (!((config_bands | adapter->fw_bands) &
                              ~adapter->fw_bands))
@@@ -629,8 -632,11 +630,8 @@@ int mwifiex_set_tx_power(struct mwifiex
                }
        }
        buf = kzalloc(MWIFIEX_SIZE_OF_CMD_BUFFER, GFP_KERNEL);
 -      if (!buf) {
 -              dev_err(priv->adapter->dev, "%s: failed to alloc cmd buffer\n",
 -                      __func__);
 +      if (!buf)
                return -ENOMEM;
 -      }
  
        txp_cfg = (struct host_cmd_ds_txpwr_cfg *) buf;
        txp_cfg->action = cpu_to_le16(HostCmd_ACT_GEN_SET);