diff options
Diffstat (limited to 'drivers/net/wireless/mwifiex')
-rw-r--r-- | drivers/net/wireless/mwifiex/11ac.c | 261 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/11ac.h | 26 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/11n.c | 7 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/11n.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/Makefile | 1 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/cfg80211.c | 177 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/cfp.c | 159 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/cmdevt.c | 19 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/fw.h | 127 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/ioctl.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/join.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/main.h | 23 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/scan.c | 48 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/sta_cmd.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/sta_cmdresp.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/sta_ioctl.c | 5 |
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 | */ | ||
29 | static u16 | ||
30 | mwifiex_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 | |||
95 | static void | ||
96 | mwifiex_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 | |||
109 | static void | ||
110 | mwifiex_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 | |||
166 | int 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 | |||
23 | int 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 | */ |
253 | int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd, u16 cmd_action, | 253 | int 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); |
29 | int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv, | 29 | int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv, |
30 | struct host_cmd_ds_command *resp); | 30 | struct host_cmd_ds_command *resp); |
31 | int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd, u16 cmd_action, | 31 | int 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 | |||
34 | int mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, | 34 | int 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 | |||
23 | mwifiex-y += txrx.o | 23 | mwifiex-y += txrx.o |
24 | mwifiex-y += wmm.o | 24 | mwifiex-y += wmm.o |
25 | mwifiex-y += 11n.o | 25 | mwifiex-y += 11n.o |
26 | mwifiex-y += 11ac.o | ||
26 | mwifiex-y += 11n_aggr.o | 27 | mwifiex-y += 11n_aggr.o |
27 | mwifiex-y += 11n_rxreorder.o | 28 | mwifiex-y += 11n_rxreorder.o |
28 | mwifiex-y += scan.o | 29 | mwifiex-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 | ||
837 | static void | ||
838 | mwifiex_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(¶ms->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(¶ms->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 | ||
1933 | static 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 | */ |
109 | u32 mwifiex_index_to_data_rate(struct mwifiex_private *priv, u8 index, | 109 | u32 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 | */ | ||
252 | u32 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 | ||
686 | struct host_cmd_ds_802_11_rssi_info { | 754 | struct 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 | ||
857 | struct ieee_types_oper_mode_ntf { | ||
858 | u8 element_id; | ||
859 | u8 len; | ||
860 | u8 oper_mode; | ||
861 | } __packed; | ||
862 | |||
789 | struct host_cmd_ds_802_11_ad_hoc_start { | 863 | struct 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 */ | ||
924 | enum _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 | |||
849 | struct host_cmd_ds_tx_rate_query { | 931 | struct 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 | ||
1101 | struct host_cmd_ds_txbuf_cfg { | 1192 | struct 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 | ||
1277 | struct mwifiex_ie_types_vhtcap { | ||
1278 | struct mwifiex_ie_types_header header; | ||
1279 | struct ieee80211_vht_cap vht_cap; | ||
1280 | } __packed; | ||
1281 | |||
1282 | struct mwifiex_ie_types_oper_mode_ntf { | ||
1283 | struct mwifiex_ie_types_header header; | ||
1284 | u8 oper_mode; | ||
1285 | } __packed; | ||
1286 | |||
1287 | /* VHT Operations IE */ | ||
1288 | struct 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 | |||
1186 | struct mwifiex_ie_types_wmmcap { | 1297 | struct 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 { | |||
272 | struct mwifiex_ds_11n_tx_cfg { | 275 | struct 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 | ||
277 | struct mwifiex_ds_11n_amsdu_aggr_ctrl { | 281 | struct 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, | |||
864 | int mwifiex_cmd_802_11_bg_scan_query(struct host_cmd_ds_command *cmd); | 881 | int mwifiex_cmd_802_11_bg_scan_query(struct host_cmd_ds_command *cmd); |
865 | struct mwifiex_chan_freq_power *mwifiex_get_cfp(struct mwifiex_private *priv, | 882 | struct 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); |
867 | u32 mwifiex_index_to_data_rate(struct mwifiex_private *priv, u8 index, | 884 | u32 mwifiex_index_to_data_rate(struct mwifiex_private *priv, |
868 | u8 ht_info); | 885 | u8 index, u8 ht_info); |
886 | u32 mwifiex_index_to_acs_data_rate(struct mwifiex_private *priv, | ||
887 | u8 index, u8 ht_info); | ||
869 | u32 mwifiex_find_freq_from_band_chan(u8, u8); | 888 | u32 mwifiex_find_freq_from_band_chan(u8, u8); |
870 | int mwifiex_cmd_append_vsie_tlv(struct mwifiex_private *priv, u16 vsie_mask, | 889 | int 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)) |