aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwifiex
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/mwifiex')
-rw-r--r--drivers/net/wireless/mwifiex/11ac.c261
-rw-r--r--drivers/net/wireless/mwifiex/11ac.h26
-rw-r--r--drivers/net/wireless/mwifiex/11n.c7
-rw-r--r--drivers/net/wireless/mwifiex/11n.h4
-rw-r--r--drivers/net/wireless/mwifiex/Makefile1
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c177
-rw-r--r--drivers/net/wireless/mwifiex/cfp.c159
-rw-r--r--drivers/net/wireless/mwifiex/cmdevt.c19
-rw-r--r--drivers/net/wireless/mwifiex/fw.h127
-rw-r--r--drivers/net/wireless/mwifiex/ioctl.h4
-rw-r--r--drivers/net/wireless/mwifiex/join.c8
-rw-r--r--drivers/net/wireless/mwifiex/main.h23
-rw-r--r--drivers/net/wireless/mwifiex/scan.c48
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmd.c2
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmdresp.c1
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c5
16 files changed, 830 insertions, 42 deletions
diff --git a/drivers/net/wireless/mwifiex/11ac.c b/drivers/net/wireless/mwifiex/11ac.c
new file mode 100644
index 000000000000..cf43b3c29250
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/11ac.c
@@ -0,0 +1,261 @@
1/*
2 * Marvell Wireless LAN device driver: 802.11ac
3 *
4 * Copyright (C) 2013, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#include "decl.h"
21#include "ioctl.h"
22#include "fw.h"
23#include "main.h"
24#include "11ac.h"
25
26/* This function converts the 2-bit MCS map to the highest long GI
27 * VHT data rate.
28 */
29static u16
30mwifiex_convert_mcsmap_to_maxrate(struct mwifiex_private *priv,
31 u8 bands, u16 mcs_map)
32{
33 u8 i, nss, max_mcs;
34 u16 max_rate = 0;
35 u32 usr_vht_cap_info = 0;
36 struct mwifiex_adapter *adapter = priv->adapter;
37 /* tables of the MCS map to the highest data rate (in Mbps)
38 * supported for long GI
39 */
40 u16 max_rate_lgi_80MHZ[8][3] = {
41 {0x124, 0x15F, 0x186}, /* NSS = 1 */
42 {0x249, 0x2BE, 0x30C}, /* NSS = 2 */
43 {0x36D, 0x41D, 0x492}, /* NSS = 3 */
44 {0x492, 0x57C, 0x618}, /* NSS = 4 */
45 {0x5B6, 0x6DB, 0x79E}, /* NSS = 5 */
46 {0x6DB, 0x83A, 0x0}, /* NSS = 6 */
47 {0x7FF, 0x999, 0xAAA}, /* NSS = 7 */
48 {0x924, 0xAF8, 0xC30} /* NSS = 8 */
49 };
50 u16 max_rate_lgi_160MHZ[8][3] = {
51 {0x249, 0x2BE, 0x30C}, /* NSS = 1 */
52 {0x492, 0x57C, 0x618}, /* NSS = 2 */
53 {0x6DB, 0x83A, 0x0}, /* NSS = 3 */
54 {0x924, 0xAF8, 0xC30}, /* NSS = 4 */
55 {0xB6D, 0xDB6, 0xF3C}, /* NSS = 5 */
56 {0xDB6, 0x1074, 0x1248}, /* NSS = 6 */
57 {0xFFF, 0x1332, 0x1554}, /* NSS = 7 */
58 {0x1248, 0x15F0, 0x1860} /* NSS = 8 */
59 };
60
61 if (bands & BAND_AAC)
62 usr_vht_cap_info = adapter->usr_dot_11ac_dev_cap_a;
63 else
64 usr_vht_cap_info = adapter->usr_dot_11ac_dev_cap_bg;
65
66 /* find the max NSS supported */
67 nss = 0;
68 for (i = 0; i < 8; i++) {
69 max_mcs = (mcs_map >> (2 * i)) & 0x3;
70 if (max_mcs < 3)
71 nss = i;
72 }
73 max_mcs = (mcs_map >> (2 * nss)) & 0x3;
74
75 /* if max_mcs is 3, nss must be 0 (SS = 1). Thus, max mcs is MCS 9 */
76 if (max_mcs >= 3)
77 max_mcs = 2;
78
79 if (GET_VHTCAP_CHWDSET(usr_vht_cap_info)) {
80 /* support 160 MHz */
81 max_rate = max_rate_lgi_160MHZ[nss][max_mcs];
82 if (!max_rate)
83 /* MCS9 is not supported in NSS6 */
84 max_rate = max_rate_lgi_160MHZ[nss][max_mcs - 1];
85 } else {
86 max_rate = max_rate_lgi_80MHZ[nss][max_mcs];
87 if (!max_rate)
88 /* MCS9 is not supported in NSS3 */
89 max_rate = max_rate_lgi_80MHZ[nss][max_mcs - 1];
90 }
91
92 return max_rate;
93}
94
95static void
96mwifiex_fill_vht_cap_info(struct mwifiex_private *priv,
97 struct mwifiex_ie_types_vhtcap *vht_cap, u8 bands)
98{
99 struct mwifiex_adapter *adapter = priv->adapter;
100
101 if (bands & BAND_A)
102 vht_cap->vht_cap.vht_cap_info =
103 cpu_to_le32(adapter->usr_dot_11ac_dev_cap_a);
104 else
105 vht_cap->vht_cap.vht_cap_info =
106 cpu_to_le32(adapter->usr_dot_11ac_dev_cap_bg);
107}
108
109static void
110mwifiex_fill_vht_cap_tlv(struct mwifiex_private *priv,
111 struct mwifiex_ie_types_vhtcap *vht_cap, u8 bands)
112{
113 struct mwifiex_adapter *adapter = priv->adapter;
114 u16 mcs_map_user, mcs_map_resp, mcs_map_result;
115 u16 mcs_user, mcs_resp, nss, tmp;
116
117 /* Fill VHT cap info */
118 mwifiex_fill_vht_cap_info(priv, vht_cap, bands);
119
120 /* rx MCS Set: find the minimum of the user rx mcs and ap rx mcs */
121 mcs_map_user = GET_DEVRXMCSMAP(adapter->usr_dot_11ac_mcs_support);
122 mcs_map_resp = le16_to_cpu(vht_cap->vht_cap.supp_mcs.rx_mcs_map);
123 mcs_map_result = 0;
124
125 for (nss = 1; nss <= 8; nss++) {
126 mcs_user = GET_VHTNSSMCS(mcs_map_user, nss);
127 mcs_resp = GET_VHTNSSMCS(mcs_map_resp, nss);
128
129 if ((mcs_user == NO_NSS_SUPPORT) ||
130 (mcs_resp == NO_NSS_SUPPORT))
131 SET_VHTNSSMCS(mcs_map_result, nss, NO_NSS_SUPPORT);
132 else
133 SET_VHTNSSMCS(mcs_map_result, nss,
134 min(mcs_user, mcs_resp));
135 }
136
137 vht_cap->vht_cap.supp_mcs.rx_mcs_map = cpu_to_le16(mcs_map_result);
138
139 tmp = mwifiex_convert_mcsmap_to_maxrate(priv, bands, mcs_map_result);
140 vht_cap->vht_cap.supp_mcs.rx_highest = cpu_to_le16(tmp);
141
142 /* tx MCS Set: find the minimum of the user tx mcs and ap tx mcs */
143 mcs_map_user = GET_DEVTXMCSMAP(adapter->usr_dot_11ac_mcs_support);
144 mcs_map_resp = le16_to_cpu(vht_cap->vht_cap.supp_mcs.tx_mcs_map);
145 mcs_map_result = 0;
146
147 for (nss = 1; nss <= 8; nss++) {
148 mcs_user = GET_VHTNSSMCS(mcs_map_user, nss);
149 mcs_resp = GET_VHTNSSMCS(mcs_map_resp, nss);
150 if ((mcs_user == NO_NSS_SUPPORT) ||
151 (mcs_resp == NO_NSS_SUPPORT))
152 SET_VHTNSSMCS(mcs_map_result, nss, NO_NSS_SUPPORT);
153 else
154 SET_VHTNSSMCS(mcs_map_result, nss,
155 min(mcs_user, mcs_resp));
156 }
157
158 vht_cap->vht_cap.supp_mcs.tx_mcs_map = cpu_to_le16(mcs_map_result);
159
160 tmp = mwifiex_convert_mcsmap_to_maxrate(priv, bands, mcs_map_result);
161 vht_cap->vht_cap.supp_mcs.tx_highest = cpu_to_le16(tmp);
162
163 return;
164}
165
166int mwifiex_cmd_append_11ac_tlv(struct mwifiex_private *priv,
167 struct mwifiex_bssdescriptor *bss_desc,
168 u8 **buffer)
169{
170 struct mwifiex_ie_types_vhtcap *vht_cap;
171 struct mwifiex_ie_types_oper_mode_ntf *oper_ntf;
172 struct ieee_types_oper_mode_ntf *ieee_oper_ntf;
173 struct mwifiex_ie_types_vht_oper *vht_op;
174 struct mwifiex_adapter *adapter = priv->adapter;
175 u8 supp_chwd_set;
176 u32 usr_vht_cap_info;
177 int ret_len = 0;
178
179 if (bss_desc->bss_band & BAND_A)
180 usr_vht_cap_info = adapter->usr_dot_11ac_dev_cap_a;
181 else
182 usr_vht_cap_info = adapter->usr_dot_11ac_dev_cap_bg;
183
184 /* VHT Capabilities IE */
185 if (bss_desc->bcn_vht_cap) {
186 vht_cap = (struct mwifiex_ie_types_vhtcap *)*buffer;
187 memset(vht_cap, 0, sizeof(*vht_cap));
188 vht_cap->header.type = cpu_to_le16(WLAN_EID_VHT_CAPABILITY);
189 vht_cap->header.len =
190 cpu_to_le16(sizeof(struct ieee80211_vht_cap));
191 memcpy((u8 *)vht_cap + sizeof(struct mwifiex_ie_types_header),
192 (u8 *)bss_desc->bcn_vht_cap +
193 sizeof(struct ieee_types_header),
194 le16_to_cpu(vht_cap->header.len));
195
196 mwifiex_fill_vht_cap_tlv(priv, vht_cap, bss_desc->bss_band);
197 *buffer += sizeof(*vht_cap);
198 ret_len += sizeof(*vht_cap);
199 }
200
201 /* VHT Operation IE */
202 if (bss_desc->bcn_vht_oper) {
203 if (priv->bss_mode == HostCmd_BSS_MODE_IBSS) {
204 vht_op = (struct mwifiex_ie_types_vht_oper *)*buffer;
205 memset(vht_op, 0, sizeof(*vht_op));
206 vht_op->header.type =
207 cpu_to_le16(WLAN_EID_VHT_OPERATION);
208 vht_op->header.len = cpu_to_le16(sizeof(*vht_op) -
209 sizeof(struct mwifiex_ie_types_header));
210 memcpy((u8 *)vht_op +
211 sizeof(struct mwifiex_ie_types_header),
212 (u8 *)bss_desc->bcn_vht_oper +
213 sizeof(struct ieee_types_header),
214 le16_to_cpu(vht_op->header.len));
215
216 /* negotiate the channel width and central freq
217 * and keep the central freq as the peer suggests
218 */
219 supp_chwd_set = GET_VHTCAP_CHWDSET(usr_vht_cap_info);
220
221 switch (supp_chwd_set) {
222 case 0:
223 vht_op->chan_width =
224 min_t(u8, IEEE80211_VHT_CHANWIDTH_80MHZ,
225 bss_desc->bcn_vht_oper->chan_width);
226 break;
227 case 1:
228 vht_op->chan_width =
229 min_t(u8, IEEE80211_VHT_CHANWIDTH_160MHZ,
230 bss_desc->bcn_vht_oper->chan_width);
231 break;
232 case 2:
233 vht_op->chan_width =
234 min_t(u8, IEEE80211_VHT_CHANWIDTH_80P80MHZ,
235 bss_desc->bcn_vht_oper->chan_width);
236 break;
237 default:
238 vht_op->chan_width =
239 IEEE80211_VHT_CHANWIDTH_USE_HT;
240 break;
241 }
242
243 *buffer += sizeof(*vht_op);
244 ret_len += sizeof(*vht_op);
245 }
246 }
247
248 /* Operating Mode Notification IE */
249 if (bss_desc->oper_mode) {
250 ieee_oper_ntf = bss_desc->oper_mode;
251 oper_ntf = (void *)*buffer;
252 memset(oper_ntf, 0, sizeof(*oper_ntf));
253 oper_ntf->header.type = cpu_to_le16(WLAN_EID_OPMODE_NOTIF);
254 oper_ntf->header.len = cpu_to_le16(sizeof(u8));
255 oper_ntf->oper_mode = ieee_oper_ntf->oper_mode;
256 *buffer += sizeof(*oper_ntf);
257 ret_len += sizeof(*oper_ntf);
258 }
259
260 return ret_len;
261}
diff --git a/drivers/net/wireless/mwifiex/11ac.h b/drivers/net/wireless/mwifiex/11ac.h
new file mode 100644
index 000000000000..80fd1ba46200
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/11ac.h
@@ -0,0 +1,26 @@
1/*
2 * Marvell Wireless LAN device driver: 802.11ac
3 *
4 * Copyright (C) 2013, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#ifndef _MWIFIEX_11AC_H_
21#define _MWIFIEX_11AC_H_
22
23int mwifiex_cmd_append_11ac_tlv(struct mwifiex_private *priv,
24 struct mwifiex_bssdescriptor *bss_desc,
25 u8 **buffer);
26#endif /* _MWIFIEX_11AC_H_ */
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c
index 48cc46bc152f..5e4e51a18b80 100644
--- a/drivers/net/wireless/mwifiex/11n.c
+++ b/drivers/net/wireless/mwifiex/11n.c
@@ -250,7 +250,8 @@ int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd,
250 * - Setting HT Tx capability and HT Tx information fields 250 * - Setting HT Tx capability and HT Tx information fields
251 * - Ensuring correct endian-ness 251 * - Ensuring correct endian-ness
252 */ 252 */
253int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd, u16 cmd_action, 253int mwifiex_cmd_11n_cfg(struct mwifiex_private *priv,
254 struct host_cmd_ds_command *cmd, u16 cmd_action,
254 struct mwifiex_ds_11n_tx_cfg *txcfg) 255 struct mwifiex_ds_11n_tx_cfg *txcfg)
255{ 256{
256 struct host_cmd_ds_11n_cfg *htcfg = &cmd->params.htcfg; 257 struct host_cmd_ds_11n_cfg *htcfg = &cmd->params.htcfg;
@@ -260,6 +261,10 @@ int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd, u16 cmd_action,
260 htcfg->action = cpu_to_le16(cmd_action); 261 htcfg->action = cpu_to_le16(cmd_action);
261 htcfg->ht_tx_cap = cpu_to_le16(txcfg->tx_htcap); 262 htcfg->ht_tx_cap = cpu_to_le16(txcfg->tx_htcap);
262 htcfg->ht_tx_info = cpu_to_le16(txcfg->tx_htinfo); 263 htcfg->ht_tx_info = cpu_to_le16(txcfg->tx_htinfo);
264
265 if (priv->adapter->is_hw_11ac_capable)
266 htcfg->misc_config = cpu_to_le16(txcfg->misc_config);
267
263 return 0; 268 return 0;
264} 269}
265 270
diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h
index 29a4c02479d6..375db01442bf 100644
--- a/drivers/net/wireless/mwifiex/11n.h
+++ b/drivers/net/wireless/mwifiex/11n.h
@@ -28,9 +28,9 @@ int mwifiex_ret_11n_delba(struct mwifiex_private *priv,
28 struct host_cmd_ds_command *resp); 28 struct host_cmd_ds_command *resp);
29int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv, 29int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv,
30 struct host_cmd_ds_command *resp); 30 struct host_cmd_ds_command *resp);
31int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd, u16 cmd_action, 31int mwifiex_cmd_11n_cfg(struct mwifiex_private *priv,
32 struct host_cmd_ds_command *cmd, u16 cmd_action,
32 struct mwifiex_ds_11n_tx_cfg *txcfg); 33 struct mwifiex_ds_11n_tx_cfg *txcfg);
33
34int mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, 34int mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv,
35 struct mwifiex_bssdescriptor *bss_desc, 35 struct mwifiex_bssdescriptor *bss_desc,
36 u8 **buffer); 36 u8 **buffer);
diff --git a/drivers/net/wireless/mwifiex/Makefile b/drivers/net/wireless/mwifiex/Makefile
index dd0410d2d465..97b245cbafd8 100644
--- a/drivers/net/wireless/mwifiex/Makefile
+++ b/drivers/net/wireless/mwifiex/Makefile
@@ -23,6 +23,7 @@ mwifiex-y += util.o
23mwifiex-y += txrx.o 23mwifiex-y += txrx.o
24mwifiex-y += wmm.o 24mwifiex-y += wmm.o
25mwifiex-y += 11n.o 25mwifiex-y += 11n.o
26mwifiex-y += 11ac.o
26mwifiex-y += 11n_aggr.o 27mwifiex-y += 11n_aggr.o
27mwifiex-y += 11n_rxreorder.o 28mwifiex-y += 11n_rxreorder.o
28mwifiex-y += scan.o 29mwifiex-y += scan.o
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 81c84a29308f..9667425362ed 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -834,6 +834,66 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
834 return ret; 834 return ret;
835} 835}
836 836
837static void
838mwifiex_parse_htinfo(struct mwifiex_private *priv, u8 tx_htinfo,
839 struct rate_info *rate)
840{
841 struct mwifiex_adapter *adapter = priv->adapter;
842
843 if (adapter->is_hw_11ac_capable) {
844 /* bit[1-0]: 00=LG 01=HT 10=VHT */
845 if (tx_htinfo & BIT(0)) {
846 /* HT */
847 rate->mcs = priv->tx_rate;
848 rate->flags |= RATE_INFO_FLAGS_MCS;
849 }
850 if (tx_htinfo & BIT(1)) {
851 /* VHT */
852 rate->mcs = priv->tx_rate & 0x0F;
853 rate->flags |= RATE_INFO_FLAGS_VHT_MCS;
854 }
855
856 if (tx_htinfo & (BIT(1) | BIT(0))) {
857 /* HT or VHT */
858 switch (tx_htinfo & (BIT(3) | BIT(2))) {
859 case 0:
860 /* This will be 20MHz */
861 break;
862 case (BIT(2)):
863 rate->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
864 break;
865 case (BIT(3)):
866 rate->flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
867 break;
868 case (BIT(3) | BIT(2)):
869 rate->flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH;
870 break;
871 }
872
873 if (tx_htinfo & BIT(4))
874 rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
875
876 if ((priv->tx_rate >> 4) == 1)
877 rate->nss = 2;
878 else
879 rate->nss = 1;
880 }
881 } else {
882 /*
883 * Bit 0 in tx_htinfo indicates that current Tx rate
884 * is 11n rate. Valid MCS index values for us are 0 to 15.
885 */
886 if ((tx_htinfo & BIT(0)) && (priv->tx_rate < 16)) {
887 rate->mcs = priv->tx_rate;
888 rate->flags |= RATE_INFO_FLAGS_MCS;
889 if (tx_htinfo & BIT(1))
890 rate->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
891 if (tx_htinfo & BIT(2))
892 rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
893 }
894 }
895}
896
837/* 897/*
838 * This function dumps the station information on a buffer. 898 * This function dumps the station information on a buffer.
839 * 899 *
@@ -873,20 +933,7 @@ mwifiex_dump_station_info(struct mwifiex_private *priv,
873 HostCmd_ACT_GEN_GET, DTIM_PERIOD_I, 933 HostCmd_ACT_GEN_GET, DTIM_PERIOD_I,
874 &priv->dtim_period); 934 &priv->dtim_period);
875 935
876 /* 936 mwifiex_parse_htinfo(priv, priv->tx_htinfo, &sinfo->txrate);
877 * Bit 0 in tx_htinfo indicates that current Tx rate is 11n rate. Valid
878 * MCS index values for us are 0 to 15.
879 */
880 if ((priv->tx_htinfo & BIT(0)) && (priv->tx_rate < 16)) {
881 sinfo->txrate.mcs = priv->tx_rate;
882 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
883 /* 40MHz rate */
884 if (priv->tx_htinfo & BIT(1))
885 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
886 /* SGI enabled */
887 if (priv->tx_htinfo & BIT(2))
888 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
889 }
890 937
891 sinfo->signal_avg = priv->bcn_rssi_avg; 938 sinfo->signal_avg = priv->bcn_rssi_avg;
892 sinfo->rx_bytes = priv->stats.rx_bytes; 939 sinfo->rx_bytes = priv->stats.rx_bytes;
@@ -1295,20 +1342,22 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
1295 /* Set appropriate bands */ 1342 /* Set appropriate bands */
1296 if (params->chandef.chan->band == IEEE80211_BAND_2GHZ) { 1343 if (params->chandef.chan->band == IEEE80211_BAND_2GHZ) {
1297 bss_cfg->band_cfg = BAND_CONFIG_BG; 1344 bss_cfg->band_cfg = BAND_CONFIG_BG;
1345 config_bands = BAND_B | BAND_G;
1298 1346
1299 if (cfg80211_get_chandef_type(&params->chandef) == 1347 if (params->chandef.width > NL80211_CHAN_WIDTH_20_NOHT)
1300 NL80211_CHAN_NO_HT) 1348 config_bands |= BAND_GN;
1301 config_bands = BAND_B | BAND_G; 1349
1302 else 1350 if (params->chandef.width > NL80211_CHAN_WIDTH_40)
1303 config_bands = BAND_B | BAND_G | BAND_GN; 1351 config_bands |= BAND_GAC;
1304 } else { 1352 } else {
1305 bss_cfg->band_cfg = BAND_CONFIG_A; 1353 bss_cfg->band_cfg = BAND_CONFIG_A;
1354 config_bands = BAND_A;
1306 1355
1307 if (cfg80211_get_chandef_type(&params->chandef) == 1356 if (params->chandef.width > NL80211_CHAN_WIDTH_20_NOHT)
1308 NL80211_CHAN_NO_HT) 1357 config_bands |= BAND_AN;
1309 config_bands = BAND_A; 1358
1310 else 1359 if (params->chandef.width > NL80211_CHAN_WIDTH_40)
1311 config_bands = BAND_AN | BAND_A; 1360 config_bands |= BAND_AAC;
1312 } 1361 }
1313 1362
1314 if (!((config_bands | priv->adapter->fw_bands) & 1363 if (!((config_bands | priv->adapter->fw_bands) &
@@ -1881,6 +1930,79 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
1881 return 0; 1930 return 0;
1882} 1931}
1883 1932
1933static void mwifiex_setup_vht_caps(struct ieee80211_sta_vht_cap *vht_info,
1934 struct mwifiex_private *priv)
1935{
1936 struct mwifiex_adapter *adapter = priv->adapter;
1937 u32 vht_cap = 0, cap = adapter->hw_dot_11ac_dev_cap;
1938
1939 vht_info->vht_supported = true;
1940
1941 switch (GET_VHTCAP_MAXMPDULEN(cap)) {
1942 case 0x00:
1943 vht_cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895;
1944 break;
1945 case 0x01:
1946 vht_cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991;
1947 break;
1948 case 0x10:
1949 vht_cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
1950 break;
1951 default:
1952 dev_err(adapter->dev, "unsupported MAX MPDU len\n");
1953 break;
1954 }
1955
1956 if (ISSUPP_11ACVHTHTCVHT(cap))
1957 vht_cap |= IEEE80211_VHT_CAP_HTC_VHT;
1958
1959 if (ISSUPP_11ACVHTTXOPPS(cap))
1960 vht_cap |= IEEE80211_VHT_CAP_VHT_TXOP_PS;
1961
1962 if (ISSUPP_11ACMURXBEAMFORMEE(cap))
1963 vht_cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
1964
1965 if (ISSUPP_11ACMUTXBEAMFORMEE(cap))
1966 vht_cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
1967
1968 if (ISSUPP_11ACSUBEAMFORMER(cap))
1969 vht_cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
1970
1971 if (ISSUPP_11ACSUBEAMFORMEE(cap))
1972 vht_cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
1973
1974 if (ISSUPP_11ACRXSTBC(cap))
1975 vht_cap |= IEEE80211_VHT_CAP_RXSTBC_1;
1976
1977 if (ISSUPP_11ACTXSTBC(cap))
1978 vht_cap |= IEEE80211_VHT_CAP_TXSTBC;
1979
1980 if (ISSUPP_11ACSGI160(cap))
1981 vht_cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
1982
1983 if (ISSUPP_11ACSGI80(cap))
1984 vht_cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
1985
1986 if (ISSUPP_11ACLDPC(cap))
1987 vht_cap |= IEEE80211_VHT_CAP_RXLDPC;
1988
1989 if (ISSUPP_11ACBW8080(cap))
1990 vht_cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
1991
1992 if (ISSUPP_11ACBW160(cap))
1993 vht_cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
1994
1995 vht_info->cap = vht_cap;
1996
1997 /* Update MCS support for VHT */
1998 vht_info->vht_mcs.rx_mcs_map = cpu_to_le16(
1999 adapter->hw_dot_11ac_mcs_support & 0xFFFF);
2000 vht_info->vht_mcs.rx_highest = 0;
2001 vht_info->vht_mcs.tx_mcs_map = cpu_to_le16(
2002 adapter->hw_dot_11ac_mcs_support >> 16);
2003 vht_info->vht_mcs.tx_highest = 0;
2004}
2005
1884/* 2006/*
1885 * This function sets up the CFG802.11 specific HT capability fields 2007 * This function sets up the CFG802.11 specific HT capability fields
1886 * with default values. 2008 * with default values.
@@ -2094,11 +2216,18 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
2094 priv->netdev = dev; 2216 priv->netdev = dev;
2095 2217
2096 mwifiex_setup_ht_caps(&wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap, priv); 2218 mwifiex_setup_ht_caps(&wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap, priv);
2219 if (adapter->is_hw_11ac_capable)
2220 mwifiex_setup_vht_caps(
2221 &wiphy->bands[IEEE80211_BAND_2GHZ]->vht_cap, priv);
2097 2222
2098 if (adapter->config_bands & BAND_A) 2223 if (adapter->config_bands & BAND_A)
2099 mwifiex_setup_ht_caps( 2224 mwifiex_setup_ht_caps(
2100 &wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap, priv); 2225 &wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap, priv);
2101 2226
2227 if ((adapter->config_bands & BAND_A) && adapter->is_hw_11ac_capable)
2228 mwifiex_setup_vht_caps(
2229 &wiphy->bands[IEEE80211_BAND_5GHZ]->vht_cap, priv);
2230
2102 dev_net_set(dev, wiphy_net(wiphy)); 2231 dev_net_set(dev, wiphy_net(wiphy));
2103 dev->ieee80211_ptr = priv->wdev; 2232 dev->ieee80211_ptr = priv->wdev;
2104 dev->ieee80211_ptr->iftype = priv->bss_mode; 2233 dev->ieee80211_ptr->iftype = priv->bss_mode;
diff --git a/drivers/net/wireless/mwifiex/cfp.c b/drivers/net/wireless/mwifiex/cfp.c
index f69300f93f42..988552dece75 100644
--- a/drivers/net/wireless/mwifiex/cfp.c
+++ b/drivers/net/wireless/mwifiex/cfp.c
@@ -106,8 +106,8 @@ u8 *mwifiex_11d_code_2_region(u8 code)
106 * This function maps an index in supported rates table into 106 * This function maps an index in supported rates table into
107 * the corresponding data rate. 107 * the corresponding data rate.
108 */ 108 */
109u32 mwifiex_index_to_data_rate(struct mwifiex_private *priv, u8 index, 109u32 mwifiex_index_to_acs_data_rate(struct mwifiex_private *priv,
110 u8 ht_info) 110 u8 index, u8 ht_info)
111{ 111{
112 /* 112 /*
113 * For every mcs_rate line, the first 8 bytes are for stream 1x1, 113 * For every mcs_rate line, the first 8 bytes are for stream 1x1,
@@ -130,10 +130,155 @@ u32 mwifiex_index_to_data_rate(struct mwifiex_private *priv, u8 index,
130 { 0x0e, 0x1c, 0x2b, 0x39, 0x56, 0x73, 0x82, 0x90, 130 { 0x0e, 0x1c, 0x2b, 0x39, 0x56, 0x73, 0x82, 0x90,
131 0x1c, 0x39, 0x56, 0x73, 0xad, 0xe7, 0x104, 0x120 } 131 0x1c, 0x39, 0x56, 0x73, 0xad, 0xe7, 0x104, 0x120 }
132 }; 132 };
133 /* AC rates */
134 u16 ac_mcs_rate_nss1[8][10] = {
135 /* LG 160M */
136 { 0x75, 0xEA, 0x15F, 0x1D4, 0x2BE, 0x3A8, 0x41D,
137 0x492, 0x57C, 0x618 },
138
139 /* SG 160M */
140 { 0x82, 0x104, 0x186, 0x208, 0x30C, 0x410, 0x492,
141 0x514, 0x618, 0x6C6 },
142
143 /* LG 80M */
144 { 0x3B, 0x75, 0xB0, 0xEA, 0x15F, 0x1D4, 0x20F,
145 0x249, 0x2BE, 0x30C },
146
147 /* SG 80M */
148 { 0x41, 0x82, 0xC3, 0x104, 0x186, 0x208, 0x249,
149 0x28A, 0x30C, 0x363 },
150
151 /* LG 40M */
152 { 0x1B, 0x36, 0x51, 0x6C, 0xA2, 0xD8, 0xF3,
153 0x10E, 0x144, 0x168 },
154
155 /* SG 40M */
156 { 0x1E, 0x3C, 0x5A, 0x78, 0xB4, 0xF0, 0x10E,
157 0x12C, 0x168, 0x190 },
158
159 /* LG 20M */
160 { 0xD, 0x1A, 0x27, 0x34, 0x4E, 0x68, 0x75, 0x82, 0x9C, 0x00 },
161
162 /* SG 20M */
163 { 0xF, 0x1D, 0x2C, 0x3A, 0x57, 0x74, 0x82, 0x91, 0xAE, 0x00 },
164 };
165 /* NSS2 note: the value in the table is 2 multiplier of the actual
166 * rate
167 */
168 u16 ac_mcs_rate_nss2[8][10] = {
169 /* LG 160M */
170 { 0xEA, 0x1D4, 0x2BE, 0x3A8, 0x57C, 0x750, 0x83A,
171 0x924, 0xAF8, 0xC30 },
172
173 /* SG 160M */
174 { 0x104, 0x208, 0x30C, 0x410, 0x618, 0x820, 0x924,
175 0xA28, 0xC30, 0xD8B },
176
177 /* LG 80M */
178 { 0x75, 0xEA, 0x15F, 0x1D4, 0x2BE, 0x3A8, 0x41D,
179 0x492, 0x57C, 0x618 },
180
181 /* SG 80M */
182 { 0x82, 0x104, 0x186, 0x208, 0x30C, 0x410, 0x492,
183 0x514, 0x618, 0x6C6 },
184
185 /* LG 40M */
186 { 0x36, 0x6C, 0xA2, 0xD8, 0x144, 0x1B0, 0x1E6,
187 0x21C, 0x288, 0x2D0 },
188
189 /* SG 40M */
190 { 0x3C, 0x78, 0xB4, 0xF0, 0x168, 0x1E0, 0x21C,
191 0x258, 0x2D0, 0x320 },
192
193 /* LG 20M */
194 { 0x1A, 0x34, 0x4A, 0x68, 0x9C, 0xD0, 0xEA, 0x104,
195 0x138, 0x00 },
196
197 /* SG 20M */
198 { 0x1D, 0x3A, 0x57, 0x74, 0xAE, 0xE6, 0x104, 0x121,
199 0x15B, 0x00 },
200 };
201 u32 rate = 0;
202 u8 mcs_index = 0;
203 u8 bw = 0;
204 u8 gi = 0;
205
206 if ((ht_info & 0x3) == MWIFIEX_RATE_FORMAT_VHT) {
207 mcs_index = min(index & 0xF, 9);
208
209 /* 20M: bw=0, 40M: bw=1, 80M: bw=2, 160M: bw=3 */
210 bw = (ht_info & 0xC) >> 2;
211
212 /* LGI: gi =0, SGI: gi = 1 */
213 gi = (ht_info & 0x10) >> 4;
214
215 if ((index >> 4) == 1) /* NSS = 2 */
216 rate = ac_mcs_rate_nss2[2 * (3 - bw) + gi][mcs_index];
217 else /* NSS = 1 */
218 rate = ac_mcs_rate_nss1[2 * (3 - bw) + gi][mcs_index];
219 } else if ((ht_info & 0x3) == MWIFIEX_RATE_FORMAT_HT) {
220 /* 20M: bw=0, 40M: bw=1 */
221 bw = (ht_info & 0xC) >> 2;
222
223 /* LGI: gi =0, SGI: gi = 1 */
224 gi = (ht_info & 0x10) >> 4;
225
226 if (index == MWIFIEX_RATE_BITMAP_MCS0) {
227 if (gi == 1)
228 rate = 0x0D; /* MCS 32 SGI rate */
229 else
230 rate = 0x0C; /* MCS 32 LGI rate */
231 } else if (index < 16) {
232 if ((bw == 1) || (bw == 0))
233 rate = mcs_rate[2 * (1 - bw) + gi][index];
234 else
235 rate = mwifiex_data_rates[0];
236 } else {
237 rate = mwifiex_data_rates[0];
238 }
239 } else {
240 /* 11n non-HT rates */
241 if (index >= MWIFIEX_SUPPORTED_RATES_EXT)
242 index = 0;
243 rate = mwifiex_data_rates[index];
244 }
245
246 return rate;
247}
248
249/* This function maps an index in supported rates table into
250 * the corresponding data rate.
251 */
252u32 mwifiex_index_to_data_rate(struct mwifiex_private *priv,
253 u8 index, u8 ht_info)
254{
255 /* For every mcs_rate line, the first 8 bytes are for stream 1x1,
256 * and all 16 bytes are for stream 2x2.
257 */
258 u16 mcs_rate[4][16] = {
259 /* LGI 40M */
260 { 0x1b, 0x36, 0x51, 0x6c, 0xa2, 0xd8, 0xf3, 0x10e,
261 0x36, 0x6c, 0xa2, 0xd8, 0x144, 0x1b0, 0x1e6, 0x21c },
262
263 /* SGI 40M */
264 { 0x1e, 0x3c, 0x5a, 0x78, 0xb4, 0xf0, 0x10e, 0x12c,
265 0x3c, 0x78, 0xb4, 0xf0, 0x168, 0x1e0, 0x21c, 0x258 },
266
267 /* LGI 20M */
268 { 0x0d, 0x1a, 0x27, 0x34, 0x4e, 0x68, 0x75, 0x82,
269 0x1a, 0x34, 0x4e, 0x68, 0x9c, 0xd0, 0xea, 0x104 },
270
271 /* SGI 20M */
272 { 0x0e, 0x1c, 0x2b, 0x39, 0x56, 0x73, 0x82, 0x90,
273 0x1c, 0x39, 0x56, 0x73, 0xad, 0xe7, 0x104, 0x120 }
274 };
133 u32 mcs_num_supp = 275 u32 mcs_num_supp =
134 (priv->adapter->hw_dev_mcs_support == HT_STREAM_2X2) ? 16 : 8; 276 (priv->adapter->hw_dev_mcs_support == HT_STREAM_2X2) ? 16 : 8;
135 u32 rate; 277 u32 rate;
136 278
279 if (priv->adapter->is_hw_11ac_capable)
280 return mwifiex_index_to_acs_data_rate(priv, index, ht_info);
281
137 if (ht_info & BIT(0)) { 282 if (ht_info & BIT(0)) {
138 if (index == MWIFIEX_RATE_BITMAP_MCS0) { 283 if (index == MWIFIEX_RATE_BITMAP_MCS0) {
139 if (ht_info & BIT(2)) 284 if (ht_info & BIT(2))
@@ -269,6 +414,7 @@ u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates)
269{ 414{
270 u32 k = 0; 415 u32 k = 0;
271 struct mwifiex_adapter *adapter = priv->adapter; 416 struct mwifiex_adapter *adapter = priv->adapter;
417
272 if (priv->bss_mode == NL80211_IFTYPE_STATION) { 418 if (priv->bss_mode == NL80211_IFTYPE_STATION) {
273 switch (adapter->config_bands) { 419 switch (adapter->config_bands) {
274 case BAND_B: 420 case BAND_B:
@@ -279,6 +425,7 @@ u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates)
279 break; 425 break;
280 case BAND_G: 426 case BAND_G:
281 case BAND_G | BAND_GN: 427 case BAND_G | BAND_GN:
428 case BAND_G | BAND_GN | BAND_GAC:
282 dev_dbg(adapter->dev, "info: infra band=%d " 429 dev_dbg(adapter->dev, "info: infra band=%d "
283 "supported_rates_g\n", adapter->config_bands); 430 "supported_rates_g\n", adapter->config_bands);
284 k = mwifiex_copy_rates(rates, k, supported_rates_g, 431 k = mwifiex_copy_rates(rates, k, supported_rates_g,
@@ -288,7 +435,11 @@ u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates)
288 case BAND_A | BAND_B | BAND_G: 435 case BAND_A | BAND_B | BAND_G:
289 case BAND_A | BAND_B: 436 case BAND_A | BAND_B:
290 case BAND_A | BAND_B | BAND_G | BAND_GN | BAND_AN: 437 case BAND_A | BAND_B | BAND_G | BAND_GN | BAND_AN:
438 case BAND_A | BAND_B | BAND_G | BAND_GN | BAND_AN | BAND_AAC:
439 case BAND_A | BAND_B | BAND_G | BAND_GN | BAND_AN |
440 BAND_AAC | BAND_GAC:
291 case BAND_B | BAND_G | BAND_GN: 441 case BAND_B | BAND_G | BAND_GN:
442 case BAND_B | BAND_G | BAND_GN | BAND_GAC:
292 dev_dbg(adapter->dev, "info: infra band=%d " 443 dev_dbg(adapter->dev, "info: infra band=%d "
293 "supported_rates_bg\n", adapter->config_bands); 444 "supported_rates_bg\n", adapter->config_bands);
294 k = mwifiex_copy_rates(rates, k, supported_rates_bg, 445 k = mwifiex_copy_rates(rates, k, supported_rates_bg,
@@ -301,14 +452,18 @@ u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates)
301 k = mwifiex_copy_rates(rates, k, supported_rates_a, 452 k = mwifiex_copy_rates(rates, k, supported_rates_a,
302 sizeof(supported_rates_a)); 453 sizeof(supported_rates_a));
303 break; 454 break;
455 case BAND_AN:
304 case BAND_A | BAND_AN: 456 case BAND_A | BAND_AN:
457 case BAND_A | BAND_AN | BAND_AAC:
305 case BAND_A | BAND_G | BAND_AN | BAND_GN: 458 case BAND_A | BAND_G | BAND_AN | BAND_GN:
459 case BAND_A | BAND_G | BAND_AN | BAND_GN | BAND_AAC:
306 dev_dbg(adapter->dev, "info: infra band=%d " 460 dev_dbg(adapter->dev, "info: infra band=%d "
307 "supported_rates_a\n", adapter->config_bands); 461 "supported_rates_a\n", adapter->config_bands);
308 k = mwifiex_copy_rates(rates, k, supported_rates_a, 462 k = mwifiex_copy_rates(rates, k, supported_rates_a,
309 sizeof(supported_rates_a)); 463 sizeof(supported_rates_a));
310 break; 464 break;
311 case BAND_GN: 465 case BAND_GN:
466 case BAND_GN | BAND_GAC:
312 dev_dbg(adapter->dev, "info: infra band=%d " 467 dev_dbg(adapter->dev, "info: infra band=%d "
313 "supported_rates_n\n", adapter->config_bands); 468 "supported_rates_n\n", adapter->config_bands);
314 k = mwifiex_copy_rates(rates, k, supported_rates_n, 469 k = mwifiex_copy_rates(rates, k, supported_rates_n,
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index 5f438e6c2155..5019f1f2e01c 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -24,6 +24,7 @@
24#include "main.h" 24#include "main.h"
25#include "wmm.h" 25#include "wmm.h"
26#include "11n.h" 26#include "11n.h"
27#include "11ac.h"
27 28
28/* 29/*
29 * This function initializes a command node. 30 * This function initializes a command node.
@@ -1470,6 +1471,24 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
1470 adapter->fw_release_number = le32_to_cpu(hw_spec->fw_release_number); 1471 adapter->fw_release_number = le32_to_cpu(hw_spec->fw_release_number);
1471 adapter->number_of_antenna = le16_to_cpu(hw_spec->number_of_antenna); 1472 adapter->number_of_antenna = le16_to_cpu(hw_spec->number_of_antenna);
1472 1473
1474 if (le32_to_cpu(hw_spec->dot_11ac_dev_cap)) {
1475 adapter->is_hw_11ac_capable = true;
1476
1477 /* Copy 11AC cap */
1478 adapter->hw_dot_11ac_dev_cap =
1479 le32_to_cpu(hw_spec->dot_11ac_dev_cap);
1480 adapter->usr_dot_11ac_dev_cap_bg = adapter->hw_dot_11ac_dev_cap;
1481 adapter->usr_dot_11ac_dev_cap_a = adapter->hw_dot_11ac_dev_cap;
1482
1483 /* Copy 11AC mcs */
1484 adapter->hw_dot_11ac_mcs_support =
1485 le32_to_cpu(hw_spec->dot_11ac_mcs_support);
1486 adapter->usr_dot_11ac_mcs_support =
1487 adapter->hw_dot_11ac_mcs_support;
1488 } else {
1489 adapter->is_hw_11ac_capable = false;
1490 }
1491
1473 dev_dbg(adapter->dev, "info: GET_HW_SPEC: fw_release_number- %#x\n", 1492 dev_dbg(adapter->dev, "info: GET_HW_SPEC: fw_release_number- %#x\n",
1474 adapter->fw_release_number); 1493 adapter->fw_release_number);
1475 dev_dbg(adapter->dev, "info: GET_HW_SPEC: permanent addr: %pM\n", 1494 dev_dbg(adapter->dev, "info: GET_HW_SPEC: permanent addr: %pM\n",
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index ebe2f6a7984c..25acb0682c56 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -49,13 +49,23 @@ struct tx_packet_hdr {
49#define A_SUPPORTED_RATES 9 49#define A_SUPPORTED_RATES 9
50#define HOSTCMD_SUPPORTED_RATES 14 50#define HOSTCMD_SUPPORTED_RATES 14
51#define N_SUPPORTED_RATES 3 51#define N_SUPPORTED_RATES 3
52#define ALL_802_11_BANDS (BAND_A | BAND_B | BAND_G | BAND_GN) 52#define ALL_802_11_BANDS (BAND_A | BAND_B | BAND_G | BAND_GN | \
53 BAND_AN | BAND_GAC | BAND_AAC)
53 54
54#define FW_MULTI_BANDS_SUPPORT (BIT(8) | BIT(9) | BIT(10) | BIT(11)) 55#define FW_MULTI_BANDS_SUPPORT (BIT(8) | BIT(9) | BIT(10) | BIT(11) | \
56 BIT(12) | BIT(13))
55#define IS_SUPPORT_MULTI_BANDS(adapter) \ 57#define IS_SUPPORT_MULTI_BANDS(adapter) \
56 (adapter->fw_cap_info & FW_MULTI_BANDS_SUPPORT) 58 (adapter->fw_cap_info & FW_MULTI_BANDS_SUPPORT)
59
60/* shift bit 12 and bit 13 in fw_cap_info from the firmware to bit 13 and 14
61 * for 11ac so that bit 11 is for GN, bit 12 for AN, bit 13 for GAC, and bit
62 * bit 14 for AAC, in order to be compatible with the band capability
63 * defined in the driver after right shift of 8 bits.
64 */
57#define GET_FW_DEFAULT_BANDS(adapter) \ 65#define GET_FW_DEFAULT_BANDS(adapter) \
58 ((adapter->fw_cap_info >> 8) & ALL_802_11_BANDS) 66 (((((adapter->fw_cap_info & 0x3000) << 1) | \
67 (adapter->fw_cap_info & ~0xF000)) >> 8) & \
68 ALL_802_11_BANDS)
59 69
60#define HostCmd_WEP_KEY_INDEX_MASK 0x3fff 70#define HostCmd_WEP_KEY_INDEX_MASK 0x3fff
61 71
@@ -216,6 +226,47 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
216 226
217#define LLC_SNAP_LEN 8 227#define LLC_SNAP_LEN 8
218 228
229/* HW_SPEC fw_cap_info */
230
231#define ISSUPP_11ACENABLED(fw_cap_info) (fw_cap_info & (BIT(13)|BIT(14)))
232
233#define GET_VHTCAP_MAXMPDULEN(vht_cap_info) (vht_cap_info & 0x3)
234#define GET_VHTCAP_CHWDSET(vht_cap_info) ((vht_cap_info >> 2) & 0x3)
235#define GET_VHTNSSMCS(mcs_mapset, nss) ((mcs_mapset >> (2 * (nss - 1))) & 0x3)
236#define SET_VHTNSSMCS(mcs_mapset, nss, value) (mcs_mapset |= (value & 0x3) << \
237 (2 * (nss - 1)))
238#define NO_NSS_SUPPORT 0x3
239
240/* HW_SPEC: HTC-VHT supported */
241#define ISSUPP_11ACVHTHTCVHT(Dot11acDevCap) (Dot11acDevCap & BIT(22))
242/* HW_SPEC: VHT TXOP PS support */
243#define ISSUPP_11ACVHTTXOPPS(Dot11acDevCap) (Dot11acDevCap & BIT(21))
244/* HW_SPEC: MU RX beamformee support */
245#define ISSUPP_11ACMURXBEAMFORMEE(Dot11acDevCap) (Dot11acDevCap & BIT(20))
246/* HW_SPEC: MU TX beamformee support */
247#define ISSUPP_11ACMUTXBEAMFORMEE(Dot11acDevCap) (Dot11acDevCap & BIT(19))
248/* HW_SPEC: SU Beamformee support */
249#define ISSUPP_11ACSUBEAMFORMEE(Dot11acDevCap) (Dot11acDevCap & BIT(10))
250/* HW_SPEC: SU Beamformer support */
251#define ISSUPP_11ACSUBEAMFORMER(Dot11acDevCap) (Dot11acDevCap & BIT(9))
252/* HW_SPEC: Rx STBC support */
253#define ISSUPP_11ACRXSTBC(Dot11acDevCap) (Dot11acDevCap & BIT(8))
254/* HW_SPEC: Tx STBC support */
255#define ISSUPP_11ACTXSTBC(Dot11acDevCap) (Dot11acDevCap & BIT(7))
256/* HW_SPEC: Short GI support for 160MHz BW */
257#define ISSUPP_11ACSGI160(Dot11acDevCap) (Dot11acDevCap & BIT(6))
258/* HW_SPEC: Short GI support for 80MHz BW */
259#define ISSUPP_11ACSGI80(Dot11acDevCap) (Dot11acDevCap & BIT(5))
260/* HW_SPEC: LDPC coding support */
261#define ISSUPP_11ACLDPC(Dot11acDevCap) (Dot11acDevCap & BIT(4))
262/* HW_SPEC: Channel BW 20/40/80/160/80+80 MHz support */
263#define ISSUPP_11ACBW8080(Dot11acDevCap) (Dot11acDevCap & BIT(3))
264/* HW_SPEC: Channel BW 20/40/80/160 MHz support */
265#define ISSUPP_11ACBW160(Dot11acDevCap) (Dot11acDevCap & BIT(2))
266
267#define GET_DEVTXMCSMAP(dev_mcs_map) (dev_mcs_map >> 16)
268#define GET_DEVRXMCSMAP(dev_mcs_map) (dev_mcs_map & 0xFFFF)
269
219#define MOD_CLASS_HR_DSSS 0x03 270#define MOD_CLASS_HR_DSSS 0x03
220#define MOD_CLASS_OFDM 0x07 271#define MOD_CLASS_OFDM 0x07
221#define MOD_CLASS_HT 0x08 272#define MOD_CLASS_HT 0x08
@@ -455,9 +506,22 @@ struct rxpd {
455 u8 rx_rate; 506 u8 rx_rate;
456 s8 snr; 507 s8 snr;
457 s8 nf; 508 s8 nf;
458 /* Ht Info [Bit 0] RxRate format: LG=0, HT=1 509
510 /* For: Non-802.11 AC cards
511 *
512 * Ht Info [Bit 0] RxRate format: LG=0, HT=1
459 * [Bit 1] HT Bandwidth: BW20 = 0, BW40 = 1 513 * [Bit 1] HT Bandwidth: BW20 = 0, BW40 = 1
460 * [Bit 2] HT Guard Interval: LGI = 0, SGI = 1 */ 514 * [Bit 2] HT Guard Interval: LGI = 0, SGI = 1
515 *
516 * For: 802.11 AC cards
517 * [Bit 1] [Bit 0] RxRate format: legacy rate = 00 HT = 01 VHT = 10
518 * [Bit 3] [Bit 2] HT/VHT Bandwidth BW20 = 00 BW40 = 01
519 * BW80 = 10 BW160 = 11
520 * [Bit 4] HT/VHT Guard interval LGI = 0 SGI = 1
521 * [Bit 5] STBC support Enabled = 1
522 * [Bit 6] LDPC support Enabled = 1
523 * [Bit 7] Reserved
524 */
461 u8 ht_info; 525 u8 ht_info;
462 u8 reserved; 526 u8 reserved;
463} __packed; 527} __packed;
@@ -680,7 +744,11 @@ struct host_cmd_ds_get_hw_spec {
680 __le32 dot_11n_dev_cap; 744 __le32 dot_11n_dev_cap;
681 u8 dev_mcs_support; 745 u8 dev_mcs_support;
682 __le16 mp_end_port; /* SDIO only, reserved for other interfacces */ 746 __le16 mp_end_port; /* SDIO only, reserved for other interfacces */
683 __le16 reserved_4; 747 __le16 mgmt_buf_count; /* mgmt IE buffer count */
748 __le32 reserved_5;
749 __le32 reserved_6;
750 __le32 dot_11ac_dev_cap;
751 __le32 dot_11ac_mcs_support;
684} __packed; 752} __packed;
685 753
686struct host_cmd_ds_802_11_rssi_info { 754struct host_cmd_ds_802_11_rssi_info {
@@ -786,6 +854,12 @@ union ieee_types_phy_param_set {
786 struct ieee_types_ds_param_set ds_param_set; 854 struct ieee_types_ds_param_set ds_param_set;
787} __packed; 855} __packed;
788 856
857struct ieee_types_oper_mode_ntf {
858 u8 element_id;
859 u8 len;
860 u8 oper_mode;
861} __packed;
862
789struct host_cmd_ds_802_11_ad_hoc_start { 863struct host_cmd_ds_802_11_ad_hoc_start {
790 u8 ssid[IEEE80211_MAX_SSID_LEN]; 864 u8 ssid[IEEE80211_MAX_SSID_LEN];
791 u8 bss_mode; 865 u8 bss_mode;
@@ -846,11 +920,27 @@ struct host_cmd_ds_802_11_get_log {
846 __le32 wep_icv_err_cnt[4]; 920 __le32 wep_icv_err_cnt[4];
847}; 921};
848 922
923/* Enumeration for rate format */
924enum _mwifiex_rate_format {
925 MWIFIEX_RATE_FORMAT_LG = 0,
926 MWIFIEX_RATE_FORMAT_HT,
927 MWIFIEX_RATE_FORMAT_VHT,
928 MWIFIEX_RATE_FORMAT_AUTO = 0xFF,
929};
930
849struct host_cmd_ds_tx_rate_query { 931struct host_cmd_ds_tx_rate_query {
850 u8 tx_rate; 932 u8 tx_rate;
851 /* Ht Info [Bit 0] RxRate format: LG=0, HT=1 933 /* Tx Rate Info: For 802.11 AC cards
934 *
935 * [Bit 0-1] tx rate formate: LG = 0, HT = 1, VHT = 2
936 * [Bit 2-3] HT/VHT Bandwidth: BW20 = 0, BW40 = 1, BW80 = 2, BW160 = 3
937 * [Bit 4] HT/VHT Guard Interval: LGI = 0, SGI = 1
938 *
939 * For non-802.11 AC cards
940 * Ht Info [Bit 0] RxRate format: LG=0, HT=1
852 * [Bit 1] HT Bandwidth: BW20 = 0, BW40 = 1 941 * [Bit 1] HT Bandwidth: BW20 = 0, BW40 = 1
853 * [Bit 2] HT Guard Interval: LGI = 0, SGI = 1 */ 942 * [Bit 2] HT Guard Interval: LGI = 0, SGI = 1
943 */
854 u8 ht_info; 944 u8 ht_info;
855} __packed; 945} __packed;
856 946
@@ -1096,6 +1186,7 @@ struct host_cmd_ds_11n_cfg {
1096 __le16 action; 1186 __le16 action;
1097 __le16 ht_tx_cap; 1187 __le16 ht_tx_cap;
1098 __le16 ht_tx_info; 1188 __le16 ht_tx_info;
1189 __le16 misc_config; /* Needed for 802.11AC cards only */
1099} __packed; 1190} __packed;
1100 1191
1101struct host_cmd_ds_txbuf_cfg { 1192struct host_cmd_ds_txbuf_cfg {
@@ -1183,6 +1274,26 @@ struct mwifiex_ie_types_htcap {
1183 struct ieee80211_ht_cap ht_cap; 1274 struct ieee80211_ht_cap ht_cap;
1184} __packed; 1275} __packed;
1185 1276
1277struct mwifiex_ie_types_vhtcap {
1278 struct mwifiex_ie_types_header header;
1279 struct ieee80211_vht_cap vht_cap;
1280} __packed;
1281
1282struct mwifiex_ie_types_oper_mode_ntf {
1283 struct mwifiex_ie_types_header header;
1284 u8 oper_mode;
1285} __packed;
1286
1287/* VHT Operations IE */
1288struct mwifiex_ie_types_vht_oper {
1289 struct mwifiex_ie_types_header header;
1290 u8 chan_width;
1291 u8 chan_center_freq_1;
1292 u8 chan_center_freq_2;
1293 /* Basic MCS set map, each 2 bits stands for a NSS */
1294 u16 basic_mcs_map;
1295} __packed;
1296
1186struct mwifiex_ie_types_wmmcap { 1297struct mwifiex_ie_types_wmmcap {
1187 struct mwifiex_ie_types_header header; 1298 struct mwifiex_ie_types_header header;
1188 struct mwifiex_types_wmm_info wmm_info; 1299 struct mwifiex_types_wmm_info wmm_info;
diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h
index f3d9d0445529..d85e6eb1f58a 100644
--- a/drivers/net/wireless/mwifiex/ioctl.h
+++ b/drivers/net/wireless/mwifiex/ioctl.h
@@ -60,6 +60,8 @@ enum {
60 BAND_A = 4, 60 BAND_A = 4,
61 BAND_GN = 8, 61 BAND_GN = 8,
62 BAND_AN = 16, 62 BAND_AN = 16,
63 BAND_GAC = 32,
64 BAND_AAC = 64,
63}; 65};
64 66
65#define MWIFIEX_WPA_PASSHPHRASE_LEN 64 67#define MWIFIEX_WPA_PASSHPHRASE_LEN 64
@@ -103,6 +105,7 @@ struct mwifiex_uap_bss_param {
103 struct wpa_param wpa_cfg; 105 struct wpa_param wpa_cfg;
104 struct wep_key wep_cfg[NUM_WEP_KEYS]; 106 struct wep_key wep_cfg[NUM_WEP_KEYS];
105 struct ieee80211_ht_cap ht_cap; 107 struct ieee80211_ht_cap ht_cap;
108 struct ieee80211_vht_cap vht_cap;
106 u8 rates[MWIFIEX_SUPPORTED_RATES]; 109 u8 rates[MWIFIEX_SUPPORTED_RATES];
107 u32 sta_ao_timer; 110 u32 sta_ao_timer;
108 u32 ps_sta_ao_timer; 111 u32 ps_sta_ao_timer;
@@ -272,6 +275,7 @@ struct mwifiex_ds_pm_cfg {
272struct mwifiex_ds_11n_tx_cfg { 275struct mwifiex_ds_11n_tx_cfg {
273 u16 tx_htcap; 276 u16 tx_htcap;
274 u16 tx_htinfo; 277 u16 tx_htinfo;
278 u16 misc_config; /* Needed for 802.11AC cards only */
275}; 279};
276 280
277struct mwifiex_ds_11n_amsdu_aggr_ctrl { 281struct mwifiex_ds_11n_amsdu_aggr_ctrl {
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c
index a537297866c6..246aa62a4817 100644
--- a/drivers/net/wireless/mwifiex/join.c
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -24,6 +24,7 @@
24#include "main.h" 24#include "main.h"
25#include "wmm.h" 25#include "wmm.h"
26#include "11n.h" 26#include "11n.h"
27#include "11ac.h"
27 28
28#define CAPINFO_MASK (~(BIT(15) | BIT(14) | BIT(12) | BIT(11) | BIT(9))) 29#define CAPINFO_MASK (~(BIT(15) | BIT(14) | BIT(12) | BIT(11) | BIT(9)))
29 30
@@ -512,6 +513,12 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
512 priv->adapter->config_bands & BAND_AN)) 513 priv->adapter->config_bands & BAND_AN))
513 mwifiex_cmd_append_11n_tlv(priv, bss_desc, &pos); 514 mwifiex_cmd_append_11n_tlv(priv, bss_desc, &pos);
514 515
516 if (ISSUPP_11ACENABLED(priv->adapter->fw_cap_info) &&
517 !bss_desc->disable_11n && !bss_desc->disable_11ac &&
518 (priv->adapter->config_bands & BAND_GAC ||
519 priv->adapter->config_bands & BAND_AAC))
520 mwifiex_cmd_append_11ac_tlv(priv, bss_desc, &pos);
521
515 /* Append vendor specific IE TLV */ 522 /* Append vendor specific IE TLV */
516 mwifiex_cmd_append_vsie_tlv(priv, MWIFIEX_VSIE_MASK_ASSOC, &pos); 523 mwifiex_cmd_append_vsie_tlv(priv, MWIFIEX_VSIE_MASK_ASSOC, &pos);
517 524
@@ -1421,6 +1428,7 @@ mwifiex_band_to_radio_type(u8 band)
1421 case BAND_A: 1428 case BAND_A:
1422 case BAND_AN: 1429 case BAND_AN:
1423 case BAND_A | BAND_AN: 1430 case BAND_A | BAND_AN:
1431 case BAND_A | BAND_AN | BAND_AAC:
1424 return HostCmd_SCAN_RADIO_TYPE_A; 1432 return HostCmd_SCAN_RADIO_TYPE_A;
1425 case BAND_B: 1433 case BAND_B:
1426 case BAND_G: 1434 case BAND_G:
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index ac799a046eb7..553adfb0aa81 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -295,6 +295,13 @@ struct mwifiex_bssdescriptor {
295 u16 bss_co_2040_offset; 295 u16 bss_co_2040_offset;
296 u8 *bcn_ext_cap; 296 u8 *bcn_ext_cap;
297 u16 ext_cap_offset; 297 u16 ext_cap_offset;
298 struct ieee80211_vht_cap *bcn_vht_cap;
299 u16 vht_cap_offset;
300 struct ieee80211_vht_operation *bcn_vht_oper;
301 u16 vht_info_offset;
302 struct ieee_types_oper_mode_ntf *oper_mode;
303 u16 oper_mode_offset;
304 u8 disable_11ac;
298 struct ieee_types_vendor_specific *bcn_wpa_ie; 305 struct ieee_types_vendor_specific *bcn_wpa_ie;
299 u16 wpa_offset; 306 u16 wpa_offset;
300 struct ieee_types_generic *bcn_rsn_ie; 307 struct ieee_types_generic *bcn_rsn_ie;
@@ -499,6 +506,7 @@ struct mwifiex_private {
499 u16 rsn_idx; 506 u16 rsn_idx;
500 struct timer_list scan_delay_timer; 507 struct timer_list scan_delay_timer;
501 u8 ap_11n_enabled; 508 u8 ap_11n_enabled;
509 u8 ap_11ac_enabled;
502 u32 mgmt_frame_mask; 510 u32 mgmt_frame_mask;
503 struct mwifiex_roc_cfg roc_cfg; 511 struct mwifiex_roc_cfg roc_cfg;
504}; 512};
@@ -722,6 +730,15 @@ struct mwifiex_adapter {
722 u16 max_mgmt_ie_index; 730 u16 max_mgmt_ie_index;
723 u8 scan_delay_cnt; 731 u8 scan_delay_cnt;
724 u8 empty_tx_q_cnt; 732 u8 empty_tx_q_cnt;
733
734 /* 11AC */
735 u32 is_hw_11ac_capable;
736 u32 hw_dot_11ac_dev_cap;
737 u32 hw_dot_11ac_mcs_support;
738 u32 usr_dot_11ac_dev_cap_bg;
739 u32 usr_dot_11ac_dev_cap_a;
740 u32 usr_dot_11ac_mcs_support;
741
725 atomic_t is_tx_received; 742 atomic_t is_tx_received;
726 atomic_t pending_bridged_pkts; 743 atomic_t pending_bridged_pkts;
727}; 744};
@@ -864,8 +881,10 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv,
864int mwifiex_cmd_802_11_bg_scan_query(struct host_cmd_ds_command *cmd); 881int mwifiex_cmd_802_11_bg_scan_query(struct host_cmd_ds_command *cmd);
865struct mwifiex_chan_freq_power *mwifiex_get_cfp(struct mwifiex_private *priv, 882struct mwifiex_chan_freq_power *mwifiex_get_cfp(struct mwifiex_private *priv,
866 u8 band, u16 channel, u32 freq); 883 u8 band, u16 channel, u32 freq);
867u32 mwifiex_index_to_data_rate(struct mwifiex_private *priv, u8 index, 884u32 mwifiex_index_to_data_rate(struct mwifiex_private *priv,
868 u8 ht_info); 885 u8 index, u8 ht_info);
886u32 mwifiex_index_to_acs_data_rate(struct mwifiex_private *priv,
887 u8 index, u8 ht_info);
869u32 mwifiex_find_freq_from_band_chan(u8, u8); 888u32 mwifiex_find_freq_from_band_chan(u8, u8);
870int mwifiex_cmd_append_vsie_tlv(struct mwifiex_private *priv, u16 vsie_mask, 889int mwifiex_cmd_append_vsie_tlv(struct mwifiex_private *priv, u16 vsie_mask,
871 u8 **buffer); 890 u8 **buffer);
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index e275aec5a17a..db4d5ae3ff96 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -1250,6 +1250,23 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
1250 sizeof(struct ieee_types_header) - 1250 sizeof(struct ieee_types_header) -
1251 bss_entry->beacon_buf); 1251 bss_entry->beacon_buf);
1252 break; 1252 break;
1253 case WLAN_EID_VHT_CAPABILITY:
1254 bss_entry->disable_11ac = false;
1255 bss_entry->bcn_vht_cap =
1256 (void *)(current_ptr +
1257 sizeof(struct ieee_types_header));
1258 bss_entry->vht_cap_offset =
1259 (u16)((u8 *)bss_entry->bcn_vht_cap -
1260 bss_entry->beacon_buf);
1261 break;
1262 case WLAN_EID_VHT_OPERATION:
1263 bss_entry->bcn_vht_oper =
1264 (void *)(current_ptr +
1265 sizeof(struct ieee_types_header));
1266 bss_entry->vht_info_offset =
1267 (u16)((u8 *)bss_entry->bcn_vht_oper -
1268 bss_entry->beacon_buf);
1269 break;
1253 case WLAN_EID_BSS_COEX_2040: 1270 case WLAN_EID_BSS_COEX_2040:
1254 bss_entry->bcn_bss_co_2040 = current_ptr + 1271 bss_entry->bcn_bss_co_2040 = current_ptr +
1255 sizeof(struct ieee_types_header); 1272 sizeof(struct ieee_types_header);
@@ -1264,6 +1281,14 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
1264 sizeof(struct ieee_types_header) - 1281 sizeof(struct ieee_types_header) -
1265 bss_entry->beacon_buf); 1282 bss_entry->beacon_buf);
1266 break; 1283 break;
1284 case WLAN_EID_OPMODE_NOTIF:
1285 bss_entry->oper_mode =
1286 (void *)(current_ptr +
1287 sizeof(struct ieee_types_header));
1288 bss_entry->oper_mode_offset =
1289 (u16)((u8 *)bss_entry->oper_mode -
1290 bss_entry->beacon_buf);
1291 break;
1267 default: 1292 default:
1268 break; 1293 break;
1269 } 1294 }
@@ -1494,6 +1519,17 @@ static int mwifiex_update_curr_bss_params(struct mwifiex_private *priv,
1494 priv->curr_bss_params.bss_descriptor.ext_cap_offset = 0; 1519 priv->curr_bss_params.bss_descriptor.ext_cap_offset = 0;
1495 priv->curr_bss_params.bss_descriptor.beacon_buf = NULL; 1520 priv->curr_bss_params.bss_descriptor.beacon_buf = NULL;
1496 priv->curr_bss_params.bss_descriptor.beacon_buf_size = 0; 1521 priv->curr_bss_params.bss_descriptor.beacon_buf_size = 0;
1522 priv->curr_bss_params.bss_descriptor.bcn_vht_cap = NULL;
1523 priv->curr_bss_params.bss_descriptor.vht_cap_offset = 0;
1524 priv->curr_bss_params.bss_descriptor.bcn_vht_oper = NULL;
1525 priv->curr_bss_params.bss_descriptor.vht_info_offset = 0;
1526 priv->curr_bss_params.bss_descriptor.oper_mode = NULL;
1527 priv->curr_bss_params.bss_descriptor.oper_mode_offset = 0;
1528
1529 /* Disable 11ac by default. Enable it only where there
1530 * exist VHT_CAP IE in AP beacon
1531 */
1532 priv->curr_bss_params.bss_descriptor.disable_11ac = true;
1497 1533
1498 /* Make a copy of current BSSID descriptor */ 1534 /* Make a copy of current BSSID descriptor */
1499 memcpy(&priv->curr_bss_params.bss_descriptor, bss_desc, 1535 memcpy(&priv->curr_bss_params.bss_descriptor, bss_desc,
@@ -2028,6 +2064,14 @@ mwifiex_save_curr_bcn(struct mwifiex_private *priv)
2028 (curr_bss->beacon_buf + 2064 (curr_bss->beacon_buf +
2029 curr_bss->ht_info_offset); 2065 curr_bss->ht_info_offset);
2030 2066
2067 if (curr_bss->bcn_vht_cap)
2068 curr_bss->bcn_ht_cap = (void *)(curr_bss->beacon_buf +
2069 curr_bss->vht_cap_offset);
2070
2071 if (curr_bss->bcn_vht_oper)
2072 curr_bss->bcn_ht_oper = (void *)(curr_bss->beacon_buf +
2073 curr_bss->vht_info_offset);
2074
2031 if (curr_bss->bcn_bss_co_2040) 2075 if (curr_bss->bcn_bss_co_2040)
2032 curr_bss->bcn_bss_co_2040 = 2076 curr_bss->bcn_bss_co_2040 =
2033 (curr_bss->beacon_buf + curr_bss->bss_co_2040_offset); 2077 (curr_bss->beacon_buf + curr_bss->bss_co_2040_offset);
@@ -2035,6 +2079,10 @@ mwifiex_save_curr_bcn(struct mwifiex_private *priv)
2035 if (curr_bss->bcn_ext_cap) 2079 if (curr_bss->bcn_ext_cap)
2036 curr_bss->bcn_ext_cap = curr_bss->beacon_buf + 2080 curr_bss->bcn_ext_cap = curr_bss->beacon_buf +
2037 curr_bss->ext_cap_offset; 2081 curr_bss->ext_cap_offset;
2082
2083 if (curr_bss->oper_mode)
2084 curr_bss->oper_mode = (void *)(curr_bss->beacon_buf +
2085 curr_bss->oper_mode_offset);
2038} 2086}
2039 2087
2040/* 2088/*
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index c4607859d59d..c55c5bb93134 100644
--- a/drivers/net/wireless/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -1230,7 +1230,7 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
1230 data_buf); 1230 data_buf);
1231 break; 1231 break;
1232 case HostCmd_CMD_11N_CFG: 1232 case HostCmd_CMD_11N_CFG:
1233 ret = mwifiex_cmd_11n_cfg(cmd_ptr, cmd_action, data_buf); 1233 ret = mwifiex_cmd_11n_cfg(priv, cmd_ptr, cmd_action, data_buf);
1234 break; 1234 break;
1235 case HostCmd_CMD_WMM_GET_STATUS: 1235 case HostCmd_CMD_WMM_GET_STATUS:
1236 dev_dbg(priv->adapter->dev, 1236 dev_dbg(priv->adapter->dev,
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index 847056415ac9..4669f8d9389f 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -24,6 +24,7 @@
24#include "main.h" 24#include "main.h"
25#include "wmm.h" 25#include "wmm.h"
26#include "11n.h" 26#include "11n.h"
27#include "11ac.h"
27 28
28 29
29/* 30/*
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index 0d018460daf9..7ce72e93260d 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -283,9 +283,10 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
283 283
284 if (mwifiex_band_to_radio_type((u8) bss_desc->bss_band) 284 if (mwifiex_band_to_radio_type((u8) bss_desc->bss_band)
285 == HostCmd_SCAN_RADIO_TYPE_BG) 285 == HostCmd_SCAN_RADIO_TYPE_BG)
286 config_bands = BAND_B | BAND_G | BAND_GN; 286 config_bands = BAND_B | BAND_G | BAND_GN |
287 BAND_GAC;
287 else 288 else
288 config_bands = BAND_A | BAND_AN; 289 config_bands = BAND_A | BAND_AN | BAND_AAC;
289 290
290 if (!((config_bands | adapter->fw_bands) & 291 if (!((config_bands | adapter->fw_bands) &
291 ~adapter->fw_bands)) 292 ~adapter->fw_bands))