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.c192
-rw-r--r--drivers/net/wireless/mwifiex/11ac.h2
-rw-r--r--drivers/net/wireless/mwifiex/11h.c4
-rw-r--r--drivers/net/wireless/mwifiex/11n.c106
-rw-r--r--drivers/net/wireless/mwifiex/11n.h58
-rw-r--r--drivers/net/wireless/mwifiex/11n_rxreorder.c203
-rw-r--r--drivers/net/wireless/mwifiex/11n_rxreorder.h3
-rw-r--r--drivers/net/wireless/mwifiex/Makefile1
-rw-r--r--drivers/net/wireless/mwifiex/README2
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c403
-rw-r--r--drivers/net/wireless/mwifiex/cfp.c205
-rw-r--r--drivers/net/wireless/mwifiex/cmdevt.c150
-rw-r--r--drivers/net/wireless/mwifiex/debugfs.c8
-rw-r--r--drivers/net/wireless/mwifiex/decl.h23
-rw-r--r--drivers/net/wireless/mwifiex/fw.h202
-rw-r--r--drivers/net/wireless/mwifiex/ie.c6
-rw-r--r--drivers/net/wireless/mwifiex/init.c8
-rw-r--r--drivers/net/wireless/mwifiex/ioctl.h25
-rw-r--r--drivers/net/wireless/mwifiex/join.c66
-rw-r--r--drivers/net/wireless/mwifiex/main.c7
-rw-r--r--drivers/net/wireless/mwifiex/main.h111
-rw-r--r--drivers/net/wireless/mwifiex/pcie.c173
-rw-r--r--drivers/net/wireless/mwifiex/pcie.h5
-rw-r--r--drivers/net/wireless/mwifiex/scan.c598
-rw-r--r--drivers/net/wireless/mwifiex/sdio.c9
-rw-r--r--drivers/net/wireless/mwifiex/sdio.h6
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmd.c471
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmdresp.c130
-rw-r--r--drivers/net/wireless/mwifiex/sta_event.c52
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c155
-rw-r--r--drivers/net/wireless/mwifiex/sta_rx.c34
-rw-r--r--drivers/net/wireless/mwifiex/sta_tx.c3
-rw-r--r--drivers/net/wireless/mwifiex/tdls.c1044
-rw-r--r--drivers/net/wireless/mwifiex/uap_cmd.c24
-rw-r--r--drivers/net/wireless/mwifiex/uap_event.c130
-rw-r--r--drivers/net/wireless/mwifiex/uap_txrx.c22
-rw-r--r--drivers/net/wireless/mwifiex/usb.c10
-rw-r--r--drivers/net/wireless/mwifiex/util.c118
-rw-r--r--drivers/net/wireless/mwifiex/util.h20
-rw-r--r--drivers/net/wireless/mwifiex/wmm.c131
-rw-r--r--drivers/net/wireless/mwifiex/wmm.h18
41 files changed, 3804 insertions, 1134 deletions
diff --git a/drivers/net/wireless/mwifiex/11ac.c b/drivers/net/wireless/mwifiex/11ac.c
index 5d9a8084665d..c92f27aa71ed 100644
--- a/drivers/net/wireless/mwifiex/11ac.c
+++ b/drivers/net/wireless/mwifiex/11ac.c
@@ -23,6 +23,31 @@
23#include "main.h" 23#include "main.h"
24#include "11ac.h" 24#include "11ac.h"
25 25
26/* Tables of the MCS map to the highest data rate (in Mbps) supported
27 * for long GI.
28 */
29static const u16 max_rate_lgi_80MHZ[8][3] = {
30 {0x124, 0x15F, 0x186}, /* NSS = 1 */
31 {0x249, 0x2BE, 0x30C}, /* NSS = 2 */
32 {0x36D, 0x41D, 0x492}, /* NSS = 3 */
33 {0x492, 0x57C, 0x618}, /* NSS = 4 */
34 {0x5B6, 0x6DB, 0x79E}, /* NSS = 5 */
35 {0x6DB, 0x83A, 0x0}, /* NSS = 6 */
36 {0x7FF, 0x999, 0xAAA}, /* NSS = 7 */
37 {0x924, 0xAF8, 0xC30} /* NSS = 8 */
38};
39
40static const u16 max_rate_lgi_160MHZ[8][3] = {
41 {0x249, 0x2BE, 0x30C}, /* NSS = 1 */
42 {0x492, 0x57C, 0x618}, /* NSS = 2 */
43 {0x6DB, 0x83A, 0x0}, /* NSS = 3 */
44 {0x924, 0xAF8, 0xC30}, /* NSS = 4 */
45 {0xB6D, 0xDB6, 0xF3C}, /* NSS = 5 */
46 {0xDB6, 0x1074, 0x1248}, /* NSS = 6 */
47 {0xFFF, 0x1332, 0x1554}, /* NSS = 7 */
48 {0x1248, 0x15F0, 0x1860} /* NSS = 8 */
49};
50
26/* This function converts the 2-bit MCS map to the highest long GI 51/* This function converts the 2-bit MCS map to the highest long GI
27 * VHT data rate. 52 * VHT data rate.
28 */ 53 */
@@ -30,33 +55,10 @@ static u16
30mwifiex_convert_mcsmap_to_maxrate(struct mwifiex_private *priv, 55mwifiex_convert_mcsmap_to_maxrate(struct mwifiex_private *priv,
31 u8 bands, u16 mcs_map) 56 u8 bands, u16 mcs_map)
32{ 57{
33 u8 i, nss, max_mcs; 58 u8 i, nss, mcs;
34 u16 max_rate = 0; 59 u16 max_rate = 0;
35 u32 usr_vht_cap_info = 0; 60 u32 usr_vht_cap_info = 0;
36 struct mwifiex_adapter *adapter = priv->adapter; 61 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 62
61 if (bands & BAND_AAC) 63 if (bands & BAND_AAC)
62 usr_vht_cap_info = adapter->usr_dot_11ac_dev_cap_a; 64 usr_vht_cap_info = adapter->usr_dot_11ac_dev_cap_a;
@@ -64,29 +66,29 @@ mwifiex_convert_mcsmap_to_maxrate(struct mwifiex_private *priv,
64 usr_vht_cap_info = adapter->usr_dot_11ac_dev_cap_bg; 66 usr_vht_cap_info = adapter->usr_dot_11ac_dev_cap_bg;
65 67
66 /* find the max NSS supported */ 68 /* find the max NSS supported */
67 nss = 0; 69 nss = 1;
68 for (i = 0; i < 8; i++) { 70 for (i = 1; i <= 8; i++) {
69 max_mcs = (mcs_map >> (2 * i)) & 0x3; 71 mcs = GET_VHTNSSMCS(mcs_map, i);
70 if (max_mcs < 3) 72 if (mcs < IEEE80211_VHT_MCS_NOT_SUPPORTED)
71 nss = i; 73 nss = i;
72 } 74 }
73 max_mcs = (mcs_map >> (2 * nss)) & 0x3; 75 mcs = GET_VHTNSSMCS(mcs_map, nss);
74 76
75 /* if max_mcs is 3, nss must be 0 (SS = 1). Thus, max mcs is MCS 9 */ 77 /* if mcs is 3, nss must be 1 (NSS = 1). Default mcs to MCS 0~9 */
76 if (max_mcs >= 3) 78 if (mcs == IEEE80211_VHT_MCS_NOT_SUPPORTED)
77 max_mcs = 2; 79 mcs = IEEE80211_VHT_MCS_SUPPORT_0_9;
78 80
79 if (GET_VHTCAP_CHWDSET(usr_vht_cap_info)) { 81 if (GET_VHTCAP_CHWDSET(usr_vht_cap_info)) {
80 /* support 160 MHz */ 82 /* support 160 MHz */
81 max_rate = max_rate_lgi_160MHZ[nss][max_mcs]; 83 max_rate = max_rate_lgi_160MHZ[nss - 1][mcs];
82 if (!max_rate) 84 if (!max_rate)
83 /* MCS9 is not supported in NSS6 */ 85 /* MCS9 is not supported in NSS6 */
84 max_rate = max_rate_lgi_160MHZ[nss][max_mcs - 1]; 86 max_rate = max_rate_lgi_160MHZ[nss - 1][mcs - 1];
85 } else { 87 } else {
86 max_rate = max_rate_lgi_80MHZ[nss][max_mcs]; 88 max_rate = max_rate_lgi_80MHZ[nss - 1][mcs];
87 if (!max_rate) 89 if (!max_rate)
88 /* MCS9 is not supported in NSS3 */ 90 /* MCS9 is not supported in NSS3 */
89 max_rate = max_rate_lgi_80MHZ[nss][max_mcs - 1]; 91 max_rate = max_rate_lgi_80MHZ[nss - 1][mcs - 1];
90 } 92 }
91 93
92 return max_rate; 94 return max_rate;
@@ -94,21 +96,20 @@ mwifiex_convert_mcsmap_to_maxrate(struct mwifiex_private *priv,
94 96
95static void 97static void
96mwifiex_fill_vht_cap_info(struct mwifiex_private *priv, 98mwifiex_fill_vht_cap_info(struct mwifiex_private *priv,
97 struct mwifiex_ie_types_vhtcap *vht_cap, u8 bands) 99 struct ieee80211_vht_cap *vht_cap, u8 bands)
98{ 100{
99 struct mwifiex_adapter *adapter = priv->adapter; 101 struct mwifiex_adapter *adapter = priv->adapter;
100 102
101 if (bands & BAND_A) 103 if (bands & BAND_A)
102 vht_cap->vht_cap.vht_cap_info = 104 vht_cap->vht_cap_info =
103 cpu_to_le32(adapter->usr_dot_11ac_dev_cap_a); 105 cpu_to_le32(adapter->usr_dot_11ac_dev_cap_a);
104 else 106 else
105 vht_cap->vht_cap.vht_cap_info = 107 vht_cap->vht_cap_info =
106 cpu_to_le32(adapter->usr_dot_11ac_dev_cap_bg); 108 cpu_to_le32(adapter->usr_dot_11ac_dev_cap_bg);
107} 109}
108 110
109static void 111void mwifiex_fill_vht_cap_tlv(struct mwifiex_private *priv,
110mwifiex_fill_vht_cap_tlv(struct mwifiex_private *priv, 112 struct ieee80211_vht_cap *vht_cap, u8 bands)
111 struct mwifiex_ie_types_vhtcap *vht_cap, u8 bands)
112{ 113{
113 struct mwifiex_adapter *adapter = priv->adapter; 114 struct mwifiex_adapter *adapter = priv->adapter;
114 u16 mcs_map_user, mcs_map_resp, mcs_map_result; 115 u16 mcs_map_user, mcs_map_resp, mcs_map_result;
@@ -119,46 +120,48 @@ mwifiex_fill_vht_cap_tlv(struct mwifiex_private *priv,
119 120
120 /* rx MCS Set: find the minimum of the user rx mcs and ap rx mcs */ 121 /* 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_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_resp = le16_to_cpu(vht_cap->supp_mcs.rx_mcs_map);
123 mcs_map_result = 0; 124 mcs_map_result = 0;
124 125
125 for (nss = 1; nss <= 8; nss++) { 126 for (nss = 1; nss <= 8; nss++) {
126 mcs_user = GET_VHTNSSMCS(mcs_map_user, nss); 127 mcs_user = GET_VHTNSSMCS(mcs_map_user, nss);
127 mcs_resp = GET_VHTNSSMCS(mcs_map_resp, nss); 128 mcs_resp = GET_VHTNSSMCS(mcs_map_resp, nss);
128 129
129 if ((mcs_user == NO_NSS_SUPPORT) || 130 if ((mcs_user == IEEE80211_VHT_MCS_NOT_SUPPORTED) ||
130 (mcs_resp == NO_NSS_SUPPORT)) 131 (mcs_resp == IEEE80211_VHT_MCS_NOT_SUPPORTED))
131 SET_VHTNSSMCS(mcs_map_result, nss, NO_NSS_SUPPORT); 132 SET_VHTNSSMCS(mcs_map_result, nss,
133 IEEE80211_VHT_MCS_NOT_SUPPORTED);
132 else 134 else
133 SET_VHTNSSMCS(mcs_map_result, nss, 135 SET_VHTNSSMCS(mcs_map_result, nss,
134 min(mcs_user, mcs_resp)); 136 min(mcs_user, mcs_resp));
135 } 137 }
136 138
137 vht_cap->vht_cap.supp_mcs.rx_mcs_map = cpu_to_le16(mcs_map_result); 139 vht_cap->supp_mcs.rx_mcs_map = cpu_to_le16(mcs_map_result);
138 140
139 tmp = mwifiex_convert_mcsmap_to_maxrate(priv, bands, mcs_map_result); 141 tmp = mwifiex_convert_mcsmap_to_maxrate(priv, bands, mcs_map_result);
140 vht_cap->vht_cap.supp_mcs.rx_highest = cpu_to_le16(tmp); 142 vht_cap->supp_mcs.rx_highest = cpu_to_le16(tmp);
141 143
142 /* tx MCS Set: find the minimum of the user tx mcs and ap tx mcs */ 144 /* 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); 145 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); 146 mcs_map_resp = le16_to_cpu(vht_cap->supp_mcs.tx_mcs_map);
145 mcs_map_result = 0; 147 mcs_map_result = 0;
146 148
147 for (nss = 1; nss <= 8; nss++) { 149 for (nss = 1; nss <= 8; nss++) {
148 mcs_user = GET_VHTNSSMCS(mcs_map_user, nss); 150 mcs_user = GET_VHTNSSMCS(mcs_map_user, nss);
149 mcs_resp = GET_VHTNSSMCS(mcs_map_resp, nss); 151 mcs_resp = GET_VHTNSSMCS(mcs_map_resp, nss);
150 if ((mcs_user == NO_NSS_SUPPORT) || 152 if ((mcs_user == IEEE80211_VHT_MCS_NOT_SUPPORTED) ||
151 (mcs_resp == NO_NSS_SUPPORT)) 153 (mcs_resp == IEEE80211_VHT_MCS_NOT_SUPPORTED))
152 SET_VHTNSSMCS(mcs_map_result, nss, NO_NSS_SUPPORT); 154 SET_VHTNSSMCS(mcs_map_result, nss,
155 IEEE80211_VHT_MCS_NOT_SUPPORTED);
153 else 156 else
154 SET_VHTNSSMCS(mcs_map_result, nss, 157 SET_VHTNSSMCS(mcs_map_result, nss,
155 min(mcs_user, mcs_resp)); 158 min(mcs_user, mcs_resp));
156 } 159 }
157 160
158 vht_cap->vht_cap.supp_mcs.tx_mcs_map = cpu_to_le16(mcs_map_result); 161 vht_cap->supp_mcs.tx_mcs_map = cpu_to_le16(mcs_map_result);
159 162
160 tmp = mwifiex_convert_mcsmap_to_maxrate(priv, bands, mcs_map_result); 163 tmp = mwifiex_convert_mcsmap_to_maxrate(priv, bands, mcs_map_result);
161 vht_cap->vht_cap.supp_mcs.tx_highest = cpu_to_le16(tmp); 164 vht_cap->supp_mcs.tx_highest = cpu_to_le16(tmp);
162 165
163 return; 166 return;
164} 167}
@@ -192,7 +195,8 @@ int mwifiex_cmd_append_11ac_tlv(struct mwifiex_private *priv,
192 (u8 *)bss_desc->bcn_vht_cap, 195 (u8 *)bss_desc->bcn_vht_cap,
193 le16_to_cpu(vht_cap->header.len)); 196 le16_to_cpu(vht_cap->header.len));
194 197
195 mwifiex_fill_vht_cap_tlv(priv, vht_cap, bss_desc->bss_band); 198 mwifiex_fill_vht_cap_tlv(priv, &vht_cap->vht_cap,
199 bss_desc->bss_band);
196 *buffer += sizeof(*vht_cap); 200 *buffer += sizeof(*vht_cap);
197 ret_len += sizeof(*vht_cap); 201 ret_len += sizeof(*vht_cap);
198 } 202 }
@@ -299,3 +303,81 @@ void mwifiex_set_11ac_ba_params(struct mwifiex_private *priv)
299 303
300 return; 304 return;
301} 305}
306
307bool mwifiex_is_bss_in_11ac_mode(struct mwifiex_private *priv)
308{
309 struct mwifiex_bssdescriptor *bss_desc;
310 struct ieee80211_vht_operation *vht_oper;
311
312 bss_desc = &priv->curr_bss_params.bss_descriptor;
313 vht_oper = bss_desc->bcn_vht_oper;
314
315 if (!bss_desc->bcn_vht_cap || !vht_oper)
316 return false;
317
318 if (vht_oper->chan_width == IEEE80211_VHT_CHANWIDTH_USE_HT)
319 return false;
320
321 return true;
322}
323
324u8 mwifiex_get_center_freq_index(struct mwifiex_private *priv, u8 band,
325 u32 pri_chan, u8 chan_bw)
326{
327 u8 center_freq_idx = 0;
328
329 if (band & BAND_AAC) {
330 switch (pri_chan) {
331 case 36:
332 case 40:
333 case 44:
334 case 48:
335 if (chan_bw == IEEE80211_VHT_CHANWIDTH_80MHZ)
336 center_freq_idx = 42;
337 break;
338 case 52:
339 case 56:
340 case 60:
341 case 64:
342 if (chan_bw == IEEE80211_VHT_CHANWIDTH_80MHZ)
343 center_freq_idx = 58;
344 else if (chan_bw == IEEE80211_VHT_CHANWIDTH_160MHZ)
345 center_freq_idx = 50;
346 break;
347 case 100:
348 case 104:
349 case 108:
350 case 112:
351 if (chan_bw == IEEE80211_VHT_CHANWIDTH_80MHZ)
352 center_freq_idx = 106;
353 break;
354 case 116:
355 case 120:
356 case 124:
357 case 128:
358 if (chan_bw == IEEE80211_VHT_CHANWIDTH_80MHZ)
359 center_freq_idx = 122;
360 else if (chan_bw == IEEE80211_VHT_CHANWIDTH_160MHZ)
361 center_freq_idx = 114;
362 break;
363 case 132:
364 case 136:
365 case 140:
366 case 144:
367 if (chan_bw == IEEE80211_VHT_CHANWIDTH_80MHZ)
368 center_freq_idx = 138;
369 break;
370 case 149:
371 case 153:
372 case 157:
373 case 161:
374 if (chan_bw == IEEE80211_VHT_CHANWIDTH_80MHZ)
375 center_freq_idx = 155;
376 break;
377 default:
378 center_freq_idx = 42;
379 }
380 }
381
382 return center_freq_idx;
383}
diff --git a/drivers/net/wireless/mwifiex/11ac.h b/drivers/net/wireless/mwifiex/11ac.h
index 7c2c69b5b3eb..0b02cb6cfcb4 100644
--- a/drivers/net/wireless/mwifiex/11ac.h
+++ b/drivers/net/wireless/mwifiex/11ac.h
@@ -40,4 +40,6 @@ int mwifiex_cmd_append_11ac_tlv(struct mwifiex_private *priv,
40int mwifiex_cmd_11ac_cfg(struct mwifiex_private *priv, 40int mwifiex_cmd_11ac_cfg(struct mwifiex_private *priv,
41 struct host_cmd_ds_command *cmd, u16 cmd_action, 41 struct host_cmd_ds_command *cmd, u16 cmd_action,
42 struct mwifiex_11ac_vht_cfg *cfg); 42 struct mwifiex_11ac_vht_cfg *cfg);
43void mwifiex_fill_vht_cap_tlv(struct mwifiex_private *priv,
44 struct ieee80211_vht_cap *vht_cap, u8 bands);
43#endif /* _MWIFIEX_11AC_H_ */ 45#endif /* _MWIFIEX_11AC_H_ */
diff --git a/drivers/net/wireless/mwifiex/11h.c b/drivers/net/wireless/mwifiex/11h.c
index 8d683070bdb3..e76b0db4e3e6 100644
--- a/drivers/net/wireless/mwifiex/11h.c
+++ b/drivers/net/wireless/mwifiex/11h.c
@@ -73,8 +73,8 @@ static int mwifiex_11h_activate(struct mwifiex_private *priv, bool flag)
73{ 73{
74 u32 enable = flag; 74 u32 enable = flag;
75 75
76 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, 76 return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
77 HostCmd_ACT_GEN_SET, DOT11H_I, &enable); 77 HostCmd_ACT_GEN_SET, DOT11H_I, &enable, true);
78} 78}
79 79
80/* This functions processes TLV buffer for a pending BSS Join command. 80/* This functions processes TLV buffer for a pending BSS Join command.
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c
index 7db1a89fdd95..d14ead8beca8 100644
--- a/drivers/net/wireless/mwifiex/11n.c
+++ b/drivers/net/wireless/mwifiex/11n.c
@@ -34,22 +34,26 @@
34 * 34 *
35 * RD responder bit to set to clear in the extended capability header. 35 * RD responder bit to set to clear in the extended capability header.
36 */ 36 */
37void 37int mwifiex_fill_cap_info(struct mwifiex_private *priv, u8 radio_type,
38mwifiex_fill_cap_info(struct mwifiex_private *priv, u8 radio_type, 38 struct ieee80211_ht_cap *ht_cap)
39 struct mwifiex_ie_types_htcap *ht_cap)
40{ 39{
41 uint16_t ht_ext_cap = le16_to_cpu(ht_cap->ht_cap.extended_ht_cap_info); 40 uint16_t ht_ext_cap = le16_to_cpu(ht_cap->extended_ht_cap_info);
42 struct ieee80211_supported_band *sband = 41 struct ieee80211_supported_band *sband =
43 priv->wdev->wiphy->bands[radio_type]; 42 priv->wdev->wiphy->bands[radio_type];
44 43
45 ht_cap->ht_cap.ampdu_params_info = 44 if (WARN_ON_ONCE(!sband)) {
45 dev_err(priv->adapter->dev, "Invalid radio type!\n");
46 return -EINVAL;
47 }
48
49 ht_cap->ampdu_params_info =
46 (sband->ht_cap.ampdu_factor & 50 (sband->ht_cap.ampdu_factor &
47 IEEE80211_HT_AMPDU_PARM_FACTOR) | 51 IEEE80211_HT_AMPDU_PARM_FACTOR) |
48 ((sband->ht_cap.ampdu_density << 52 ((sband->ht_cap.ampdu_density <<
49 IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT) & 53 IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT) &
50 IEEE80211_HT_AMPDU_PARM_DENSITY); 54 IEEE80211_HT_AMPDU_PARM_DENSITY);
51 55
52 memcpy((u8 *) &ht_cap->ht_cap.mcs, &sband->ht_cap.mcs, 56 memcpy((u8 *)&ht_cap->mcs, &sband->ht_cap.mcs,
53 sizeof(sband->ht_cap.mcs)); 57 sizeof(sband->ht_cap.mcs));
54 58
55 if (priv->bss_mode == NL80211_IFTYPE_STATION || 59 if (priv->bss_mode == NL80211_IFTYPE_STATION ||
@@ -57,13 +61,18 @@ mwifiex_fill_cap_info(struct mwifiex_private *priv, u8 radio_type,
57 (priv->adapter->sec_chan_offset != 61 (priv->adapter->sec_chan_offset !=
58 IEEE80211_HT_PARAM_CHA_SEC_NONE))) 62 IEEE80211_HT_PARAM_CHA_SEC_NONE)))
59 /* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */ 63 /* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */
60 SETHT_MCS32(ht_cap->ht_cap.mcs.rx_mask); 64 SETHT_MCS32(ht_cap->mcs.rx_mask);
61 65
62 /* Clear RD responder bit */ 66 /* Clear RD responder bit */
63 ht_ext_cap &= ~IEEE80211_HT_EXT_CAP_RD_RESPONDER; 67 ht_ext_cap &= ~IEEE80211_HT_EXT_CAP_RD_RESPONDER;
64 68
65 ht_cap->ht_cap.cap_info = cpu_to_le16(sband->ht_cap.cap); 69 ht_cap->cap_info = cpu_to_le16(sband->ht_cap.cap);
66 ht_cap->ht_cap.extended_ht_cap_info = cpu_to_le16(ht_ext_cap); 70 ht_cap->extended_ht_cap_info = cpu_to_le16(ht_ext_cap);
71
72 if (ISSUPP_BEAMFORMING(priv->adapter->hw_dot_11n_dev_cap))
73 ht_cap->tx_BF_cap_info = cpu_to_le32(MWIFIEX_DEF_11N_TX_BF_CAP);
74
75 return 0;
67} 76}
68 77
69/* 78/*
@@ -150,28 +159,34 @@ int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv,
150 int tid; 159 int tid;
151 struct host_cmd_ds_11n_addba_rsp *add_ba_rsp = &resp->params.add_ba_rsp; 160 struct host_cmd_ds_11n_addba_rsp *add_ba_rsp = &resp->params.add_ba_rsp;
152 struct mwifiex_tx_ba_stream_tbl *tx_ba_tbl; 161 struct mwifiex_tx_ba_stream_tbl *tx_ba_tbl;
162 u16 block_ack_param_set = le16_to_cpu(add_ba_rsp->block_ack_param_set);
153 163
154 add_ba_rsp->ssn = cpu_to_le16((le16_to_cpu(add_ba_rsp->ssn)) 164 add_ba_rsp->ssn = cpu_to_le16((le16_to_cpu(add_ba_rsp->ssn))
155 & SSN_MASK); 165 & SSN_MASK);
156 166
157 tid = (le16_to_cpu(add_ba_rsp->block_ack_param_set) 167 tid = (block_ack_param_set & IEEE80211_ADDBA_PARAM_TID_MASK)
158 & IEEE80211_ADDBA_PARAM_TID_MASK) 168 >> BLOCKACKPARAM_TID_POS;
159 >> BLOCKACKPARAM_TID_POS; 169 if (le16_to_cpu(add_ba_rsp->status_code) != BA_RESULT_SUCCESS) {
160 if (le16_to_cpu(add_ba_rsp->status_code) == BA_RESULT_SUCCESS) {
161 tx_ba_tbl = mwifiex_get_ba_tbl(priv, tid,
162 add_ba_rsp->peer_mac_addr);
163 if (tx_ba_tbl) {
164 dev_dbg(priv->adapter->dev, "info: BA stream complete\n");
165 tx_ba_tbl->ba_status = BA_SETUP_COMPLETE;
166 } else {
167 dev_err(priv->adapter->dev, "BA stream not created\n");
168 }
169 } else {
170 mwifiex_del_ba_tbl(priv, tid, add_ba_rsp->peer_mac_addr, 170 mwifiex_del_ba_tbl(priv, tid, add_ba_rsp->peer_mac_addr,
171 TYPE_DELBA_SENT, true); 171 TYPE_DELBA_SENT, true);
172 if (add_ba_rsp->add_rsp_result != BA_RESULT_TIMEOUT) 172 if (add_ba_rsp->add_rsp_result != BA_RESULT_TIMEOUT)
173 priv->aggr_prio_tbl[tid].ampdu_ap = 173 priv->aggr_prio_tbl[tid].ampdu_ap =
174 BA_STREAM_NOT_ALLOWED; 174 BA_STREAM_NOT_ALLOWED;
175 return 0;
176 }
177
178 tx_ba_tbl = mwifiex_get_ba_tbl(priv, tid, add_ba_rsp->peer_mac_addr);
179 if (tx_ba_tbl) {
180 dev_dbg(priv->adapter->dev, "info: BA stream complete\n");
181 tx_ba_tbl->ba_status = BA_SETUP_COMPLETE;
182 if ((block_ack_param_set & BLOCKACKPARAM_AMSDU_SUPP_MASK) &&
183 priv->add_ba_param.tx_amsdu &&
184 (priv->aggr_prio_tbl[tid].amsdu != BA_STREAM_NOT_ALLOWED))
185 tx_ba_tbl->amsdu = true;
186 else
187 tx_ba_tbl->amsdu = false;
188 } else {
189 dev_err(priv->adapter->dev, "BA stream not created\n");
175 } 190 }
176 191
177 return 0; 192 return 0;
@@ -311,7 +326,7 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv,
311 (u8 *)bss_desc->bcn_ht_cap, 326 (u8 *)bss_desc->bcn_ht_cap,
312 le16_to_cpu(ht_cap->header.len)); 327 le16_to_cpu(ht_cap->header.len));
313 328
314 mwifiex_fill_cap_info(priv, radio_type, ht_cap); 329 mwifiex_fill_cap_info(priv, radio_type, &ht_cap->ht_cap);
315 330
316 *buffer += sizeof(struct mwifiex_ie_types_htcap); 331 *buffer += sizeof(struct mwifiex_ie_types_htcap);
317 ret_len += sizeof(struct mwifiex_ie_types_htcap); 332 ret_len += sizeof(struct mwifiex_ie_types_htcap);
@@ -527,16 +542,39 @@ void mwifiex_create_ba_tbl(struct mwifiex_private *priv, u8 *ra, int tid,
527int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac) 542int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac)
528{ 543{
529 struct host_cmd_ds_11n_addba_req add_ba_req; 544 struct host_cmd_ds_11n_addba_req add_ba_req;
545 struct mwifiex_sta_node *sta_ptr;
546 u32 tx_win_size = priv->add_ba_param.tx_win_size;
530 static u8 dialog_tok; 547 static u8 dialog_tok;
531 int ret; 548 int ret;
549 u16 block_ack_param_set;
532 550
533 dev_dbg(priv->adapter->dev, "cmd: %s: tid %d\n", __func__, tid); 551 dev_dbg(priv->adapter->dev, "cmd: %s: tid %d\n", __func__, tid);
534 552
535 add_ba_req.block_ack_param_set = cpu_to_le16( 553 if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
536 (u16) ((tid << BLOCKACKPARAM_TID_POS) | 554 ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info) &&
537 (priv->add_ba_param. 555 priv->adapter->is_hw_11ac_capable &&
538 tx_win_size << BLOCKACKPARAM_WINSIZE_POS) | 556 memcmp(priv->cfg_bssid, peer_mac, ETH_ALEN)) {
539 IMMEDIATE_BLOCK_ACK)); 557 sta_ptr = mwifiex_get_sta_entry(priv, peer_mac);
558 if (!sta_ptr) {
559 dev_warn(priv->adapter->dev,
560 "BA setup with unknown TDLS peer %pM!\n",
561 peer_mac);
562 return -1;
563 }
564 if (sta_ptr->is_11ac_enabled)
565 tx_win_size = MWIFIEX_11AC_STA_AMPDU_DEF_TXWINSIZE;
566 }
567
568 block_ack_param_set = (u16)((tid << BLOCKACKPARAM_TID_POS) |
569 tx_win_size << BLOCKACKPARAM_WINSIZE_POS |
570 IMMEDIATE_BLOCK_ACK);
571
572 /* enable AMSDU inside AMPDU */
573 if (priv->add_ba_param.tx_amsdu &&
574 (priv->aggr_prio_tbl[tid].amsdu != BA_STREAM_NOT_ALLOWED))
575 block_ack_param_set |= BLOCKACKPARAM_AMSDU_SUPP_MASK;
576
577 add_ba_req.block_ack_param_set = cpu_to_le16(block_ack_param_set);
540 add_ba_req.block_ack_tmo = cpu_to_le16((u16)priv->add_ba_param.timeout); 578 add_ba_req.block_ack_tmo = cpu_to_le16((u16)priv->add_ba_param.timeout);
541 579
542 ++dialog_tok; 580 ++dialog_tok;
@@ -548,8 +586,8 @@ int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac)
548 memcpy(&add_ba_req.peer_mac_addr, peer_mac, ETH_ALEN); 586 memcpy(&add_ba_req.peer_mac_addr, peer_mac, ETH_ALEN);
549 587
550 /* We don't wait for the response of this command */ 588 /* We don't wait for the response of this command */
551 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_ADDBA_REQ, 589 ret = mwifiex_send_cmd(priv, HostCmd_CMD_11N_ADDBA_REQ,
552 0, 0, &add_ba_req); 590 0, 0, &add_ba_req, false);
553 591
554 return ret; 592 return ret;
555} 593}
@@ -576,8 +614,8 @@ int mwifiex_send_delba(struct mwifiex_private *priv, int tid, u8 *peer_mac,
576 memcpy(&delba.peer_mac_addr, peer_mac, ETH_ALEN); 614 memcpy(&delba.peer_mac_addr, peer_mac, ETH_ALEN);
577 615
578 /* We don't wait for the response of this command */ 616 /* We don't wait for the response of this command */
579 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_DELBA, 617 ret = mwifiex_send_cmd(priv, HostCmd_CMD_11N_DELBA,
580 HostCmd_ACT_GEN_SET, 0, &delba); 618 HostCmd_ACT_GEN_SET, 0, &delba, false);
581 619
582 return ret; 620 return ret;
583} 621}
@@ -651,6 +689,7 @@ int mwifiex_get_tx_ba_stream_tbl(struct mwifiex_private *priv,
651 dev_dbg(priv->adapter->dev, "data: %s tid=%d\n", 689 dev_dbg(priv->adapter->dev, "data: %s tid=%d\n",
652 __func__, rx_reo_tbl->tid); 690 __func__, rx_reo_tbl->tid);
653 memcpy(rx_reo_tbl->ra, tx_ba_tsr_tbl->ra, ETH_ALEN); 691 memcpy(rx_reo_tbl->ra, tx_ba_tsr_tbl->ra, ETH_ALEN);
692 rx_reo_tbl->amsdu = tx_ba_tsr_tbl->amsdu;
654 rx_reo_tbl++; 693 rx_reo_tbl++;
655 count++; 694 count++;
656 if (count >= MWIFIEX_MAX_TX_BASTREAM_SUPPORTED) 695 if (count >= MWIFIEX_MAX_TX_BASTREAM_SUPPORTED)
@@ -706,5 +745,8 @@ void mwifiex_set_ba_params(struct mwifiex_private *priv)
706 MWIFIEX_STA_AMPDU_DEF_RXWINSIZE; 745 MWIFIEX_STA_AMPDU_DEF_RXWINSIZE;
707 } 746 }
708 747
748 priv->add_ba_param.tx_amsdu = true;
749 priv->add_ba_param.rx_amsdu = true;
750
709 return; 751 return;
710} 752}
diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h
index 375db01442bf..40b007a00f4b 100644
--- a/drivers/net/wireless/mwifiex/11n.h
+++ b/drivers/net/wireless/mwifiex/11n.h
@@ -34,8 +34,8 @@ int mwifiex_cmd_11n_cfg(struct mwifiex_private *priv,
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);
37void mwifiex_fill_cap_info(struct mwifiex_private *, u8 radio_type, 37int mwifiex_fill_cap_info(struct mwifiex_private *, u8 radio_type,
38 struct mwifiex_ie_types_htcap *); 38 struct ieee80211_ht_cap *);
39int mwifiex_set_get_11n_htcap_cfg(struct mwifiex_private *priv, 39int mwifiex_set_get_11n_htcap_cfg(struct mwifiex_private *priv,
40 u16 action, int *htcap_cfg); 40 u16 action, int *htcap_cfg);
41void mwifiex_11n_delete_tx_ba_stream_tbl_entry(struct mwifiex_private *priv, 41void mwifiex_11n_delete_tx_ba_stream_tbl_entry(struct mwifiex_private *priv,
@@ -64,14 +64,46 @@ int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd,
64 struct mwifiex_ds_11n_amsdu_aggr_ctrl *aa_ctrl); 64 struct mwifiex_ds_11n_amsdu_aggr_ctrl *aa_ctrl);
65void mwifiex_del_tx_ba_stream_tbl_by_ra(struct mwifiex_private *priv, u8 *ra); 65void mwifiex_del_tx_ba_stream_tbl_by_ra(struct mwifiex_private *priv, u8 *ra);
66 66
67/*
68 * This function checks whether AMPDU is allowed or not for a particular TID.
69 */
70static inline u8 67static inline u8
71mwifiex_is_ampdu_allowed(struct mwifiex_private *priv, int tid) 68mwifiex_is_station_ampdu_allowed(struct mwifiex_private *priv,
69 struct mwifiex_ra_list_tbl *ptr, int tid)
72{ 70{
73 return ((priv->aggr_prio_tbl[tid].ampdu_ap != BA_STREAM_NOT_ALLOWED) 71 struct mwifiex_sta_node *node = mwifiex_get_sta_entry(priv, ptr->ra);
74 ? true : false); 72
73 if (unlikely(!node))
74 return false;
75
76 return (node->ampdu_sta[tid] != BA_STREAM_NOT_ALLOWED) ? true : false;
77}
78
79/* This function checks whether AMSDU is allowed for BA stream. */
80static inline u8
81mwifiex_is_amsdu_in_ampdu_allowed(struct mwifiex_private *priv,
82 struct mwifiex_ra_list_tbl *ptr, int tid)
83{
84 struct mwifiex_tx_ba_stream_tbl *tx_tbl;
85
86 tx_tbl = mwifiex_get_ba_tbl(priv, tid, ptr->ra);
87 if (tx_tbl)
88 return tx_tbl->amsdu;
89
90 return false;
91}
92
93/* This function checks whether AMPDU is allowed or not for a particular TID. */
94static inline u8
95mwifiex_is_ampdu_allowed(struct mwifiex_private *priv,
96 struct mwifiex_ra_list_tbl *ptr, int tid)
97{
98 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) {
99 return mwifiex_is_station_ampdu_allowed(priv, ptr, tid);
100 } else {
101 if (ptr->tdls_link)
102 return mwifiex_is_station_ampdu_allowed(priv, ptr, tid);
103
104 return (priv->aggr_prio_tbl[tid].ampdu_ap !=
105 BA_STREAM_NOT_ALLOWED) ? true : false;
106 }
75} 107}
76 108
77/* 109/*
@@ -165,4 +197,14 @@ static inline int mwifiex_is_sta_11n_enabled(struct mwifiex_private *priv,
165 197
166 return node->is_11n_enabled; 198 return node->is_11n_enabled;
167} 199}
200
201static inline u8
202mwifiex_tdls_peer_11n_enabled(struct mwifiex_private *priv, u8 *ra)
203{
204 struct mwifiex_sta_node *node = mwifiex_get_sta_entry(priv, ra);
205 if (node)
206 return node->is_11n_enabled;
207
208 return false;
209}
168#endif /* !_MWIFIEX_11N_H_ */ 210#endif /* !_MWIFIEX_11N_H_ */
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c
index ada809f576fe..0c3571f830b0 100644
--- a/drivers/net/wireless/mwifiex/11n_rxreorder.c
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c
@@ -26,6 +26,56 @@
26#include "11n.h" 26#include "11n.h"
27#include "11n_rxreorder.h" 27#include "11n_rxreorder.h"
28 28
29/* This function will dispatch amsdu packet and forward it to kernel/upper
30 * layer.
31 */
32static int mwifiex_11n_dispatch_amsdu_pkt(struct mwifiex_private *priv,
33 struct sk_buff *skb)
34{
35 struct rxpd *local_rx_pd = (struct rxpd *)(skb->data);
36 int ret;
37
38 if (le16_to_cpu(local_rx_pd->rx_pkt_type) == PKT_TYPE_AMSDU) {
39 struct sk_buff_head list;
40 struct sk_buff *rx_skb;
41
42 __skb_queue_head_init(&list);
43
44 skb_pull(skb, le16_to_cpu(local_rx_pd->rx_pkt_offset));
45 skb_trim(skb, le16_to_cpu(local_rx_pd->rx_pkt_length));
46
47 ieee80211_amsdu_to_8023s(skb, &list, priv->curr_addr,
48 priv->wdev->iftype, 0, false);
49
50 while (!skb_queue_empty(&list)) {
51 rx_skb = __skb_dequeue(&list);
52 ret = mwifiex_recv_packet(priv, rx_skb);
53 if (ret == -1)
54 dev_err(priv->adapter->dev,
55 "Rx of A-MSDU failed");
56 }
57 return 0;
58 }
59
60 return -1;
61}
62
63/* This function will process the rx packet and forward it to kernel/upper
64 * layer.
65 */
66static int mwifiex_11n_dispatch_pkt(struct mwifiex_private *priv, void *payload)
67{
68 int ret = mwifiex_11n_dispatch_amsdu_pkt(priv, payload);
69
70 if (!ret)
71 return 0;
72
73 if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP)
74 return mwifiex_handle_uap_rx_forward(priv, payload);
75
76 return mwifiex_process_rx_packet(priv, payload);
77}
78
29/* 79/*
30 * This function dispatches all packets in the Rx reorder table until the 80 * This function dispatches all packets in the Rx reorder table until the
31 * start window. 81 * start window.
@@ -35,8 +85,9 @@
35 * circular buffer. 85 * circular buffer.
36 */ 86 */
37static void 87static void
38mwifiex_11n_dispatch_pkt(struct mwifiex_private *priv, 88mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv,
39 struct mwifiex_rx_reorder_tbl *tbl, int start_win) 89 struct mwifiex_rx_reorder_tbl *tbl,
90 int start_win)
40{ 91{
41 int pkt_to_send, i; 92 int pkt_to_send, i;
42 void *rx_tmp_ptr; 93 void *rx_tmp_ptr;
@@ -54,12 +105,8 @@ mwifiex_11n_dispatch_pkt(struct mwifiex_private *priv,
54 tbl->rx_reorder_ptr[i] = NULL; 105 tbl->rx_reorder_ptr[i] = NULL;
55 } 106 }
56 spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); 107 spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);
57 if (rx_tmp_ptr) { 108 if (rx_tmp_ptr)
58 if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP) 109 mwifiex_11n_dispatch_pkt(priv, rx_tmp_ptr);
59 mwifiex_handle_uap_rx_forward(priv, rx_tmp_ptr);
60 else
61 mwifiex_process_rx_packet(priv, rx_tmp_ptr);
62 }
63 } 110 }
64 111
65 spin_lock_irqsave(&priv->rx_pkt_lock, flags); 112 spin_lock_irqsave(&priv->rx_pkt_lock, flags);
@@ -101,11 +148,7 @@ mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv,
101 rx_tmp_ptr = tbl->rx_reorder_ptr[i]; 148 rx_tmp_ptr = tbl->rx_reorder_ptr[i];
102 tbl->rx_reorder_ptr[i] = NULL; 149 tbl->rx_reorder_ptr[i] = NULL;
103 spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); 150 spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);
104 151 mwifiex_11n_dispatch_pkt(priv, rx_tmp_ptr);
105 if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP)
106 mwifiex_handle_uap_rx_forward(priv, rx_tmp_ptr);
107 else
108 mwifiex_process_rx_packet(priv, rx_tmp_ptr);
109 } 152 }
110 153
111 spin_lock_irqsave(&priv->rx_pkt_lock, flags); 154 spin_lock_irqsave(&priv->rx_pkt_lock, flags);
@@ -135,14 +178,15 @@ mwifiex_del_rx_reorder_entry(struct mwifiex_private *priv,
135 struct mwifiex_rx_reorder_tbl *tbl) 178 struct mwifiex_rx_reorder_tbl *tbl)
136{ 179{
137 unsigned long flags; 180 unsigned long flags;
181 int start_win;
138 182
139 if (!tbl) 183 if (!tbl)
140 return; 184 return;
141 185
142 mwifiex_11n_dispatch_pkt(priv, tbl, (tbl->start_win + tbl->win_size) & 186 start_win = (tbl->start_win + tbl->win_size) & (MAX_TID_VALUE - 1);
143 (MAX_TID_VALUE - 1)); 187 mwifiex_11n_dispatch_pkt_until_start_win(priv, tbl, start_win);
144 188
145 del_timer(&tbl->timer_context.timer); 189 del_timer_sync(&tbl->timer_context.timer);
146 190
147 spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); 191 spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
148 list_del(&tbl->list); 192 list_del(&tbl->list);
@@ -228,17 +272,17 @@ mwifiex_flush_data(unsigned long context)
228{ 272{
229 struct reorder_tmr_cnxt *ctx = 273 struct reorder_tmr_cnxt *ctx =
230 (struct reorder_tmr_cnxt *) context; 274 (struct reorder_tmr_cnxt *) context;
231 int start_win; 275 int start_win, seq_num;
232 276
233 start_win = mwifiex_11n_find_last_seq_num(ctx->ptr); 277 seq_num = mwifiex_11n_find_last_seq_num(ctx->ptr);
234 278
235 if (start_win < 0) 279 if (seq_num < 0)
236 return; 280 return;
237 281
238 dev_dbg(ctx->priv->adapter->dev, "info: flush data %d\n", start_win); 282 dev_dbg(ctx->priv->adapter->dev, "info: flush data %d\n", seq_num);
239 mwifiex_11n_dispatch_pkt(ctx->priv, ctx->ptr, 283 start_win = (ctx->ptr->start_win + seq_num + 1) & (MAX_TID_VALUE - 1);
240 (ctx->ptr->start_win + start_win + 1) & 284 mwifiex_11n_dispatch_pkt_until_start_win(ctx->priv, ctx->ptr,
241 (MAX_TID_VALUE - 1)); 285 start_win);
242} 286}
243 287
244/* 288/*
@@ -267,7 +311,7 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
267 */ 311 */
268 tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid, ta); 312 tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid, ta);
269 if (tbl) { 313 if (tbl) {
270 mwifiex_11n_dispatch_pkt(priv, tbl, seq_num); 314 mwifiex_11n_dispatch_pkt_until_start_win(priv, tbl, seq_num);
271 return; 315 return;
272 } 316 }
273 /* if !tbl then create one */ 317 /* if !tbl then create one */
@@ -279,6 +323,8 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
279 new_node->tid = tid; 323 new_node->tid = tid;
280 memcpy(new_node->ta, ta, ETH_ALEN); 324 memcpy(new_node->ta, ta, ETH_ALEN);
281 new_node->start_win = seq_num; 325 new_node->start_win = seq_num;
326 new_node->init_win = seq_num;
327 new_node->flags = 0;
282 328
283 if (mwifiex_queuing_ra_based(priv)) { 329 if (mwifiex_queuing_ra_based(priv)) {
284 dev_dbg(priv->adapter->dev, 330 dev_dbg(priv->adapter->dev,
@@ -290,15 +336,20 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
290 last_seq = node->rx_seq[tid]; 336 last_seq = node->rx_seq[tid];
291 } 337 }
292 } else { 338 } else {
293 last_seq = priv->rx_seq[tid]; 339 node = mwifiex_get_sta_entry(priv, ta);
340 if (node)
341 last_seq = node->rx_seq[tid];
342 else
343 last_seq = priv->rx_seq[tid];
294 } 344 }
295 345
296 if (last_seq != MWIFIEX_DEF_11N_RX_SEQ_NUM && 346 if (last_seq != MWIFIEX_DEF_11N_RX_SEQ_NUM &&
297 last_seq >= new_node->start_win) 347 last_seq >= new_node->start_win) {
298 new_node->start_win = last_seq + 1; 348 new_node->start_win = last_seq + 1;
349 new_node->flags |= RXREOR_INIT_WINDOW_SHIFT;
350 }
299 351
300 new_node->win_size = win_size; 352 new_node->win_size = win_size;
301 new_node->flags = 0;
302 353
303 new_node->rx_reorder_ptr = kzalloc(sizeof(void *) * win_size, 354 new_node->rx_reorder_ptr = kzalloc(sizeof(void *) * win_size,
304 GFP_KERNEL); 355 GFP_KERNEL);
@@ -358,10 +409,28 @@ int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv,
358 *cmd_addba_req) 409 *cmd_addba_req)
359{ 410{
360 struct host_cmd_ds_11n_addba_rsp *add_ba_rsp = &cmd->params.add_ba_rsp; 411 struct host_cmd_ds_11n_addba_rsp *add_ba_rsp = &cmd->params.add_ba_rsp;
412 struct mwifiex_sta_node *sta_ptr;
413 u32 rx_win_size = priv->add_ba_param.rx_win_size;
361 u8 tid; 414 u8 tid;
362 int win_size; 415 int win_size;
363 uint16_t block_ack_param_set; 416 uint16_t block_ack_param_set;
364 417
418 if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
419 ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info) &&
420 priv->adapter->is_hw_11ac_capable &&
421 memcmp(priv->cfg_bssid, cmd_addba_req->peer_mac_addr, ETH_ALEN)) {
422 sta_ptr = mwifiex_get_sta_entry(priv,
423 cmd_addba_req->peer_mac_addr);
424 if (!sta_ptr) {
425 dev_warn(priv->adapter->dev,
426 "BA setup with unknown TDLS peer %pM!\n",
427 cmd_addba_req->peer_mac_addr);
428 return -1;
429 }
430 if (sta_ptr->is_11ac_enabled)
431 rx_win_size = MWIFIEX_11AC_STA_AMPDU_DEF_RXWINSIZE;
432 }
433
365 cmd->command = cpu_to_le16(HostCmd_CMD_11N_ADDBA_RSP); 434 cmd->command = cpu_to_le16(HostCmd_CMD_11N_ADDBA_RSP);
366 cmd->size = cpu_to_le16(sizeof(*add_ba_rsp) + S_DS_GEN); 435 cmd->size = cpu_to_le16(sizeof(*add_ba_rsp) + S_DS_GEN);
367 436
@@ -376,10 +445,12 @@ int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv,
376 >> BLOCKACKPARAM_TID_POS; 445 >> BLOCKACKPARAM_TID_POS;
377 add_ba_rsp->status_code = cpu_to_le16(ADDBA_RSP_STATUS_ACCEPT); 446 add_ba_rsp->status_code = cpu_to_le16(ADDBA_RSP_STATUS_ACCEPT);
378 block_ack_param_set &= ~IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK; 447 block_ack_param_set &= ~IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
379 /* We donot support AMSDU inside AMPDU, hence reset the bit */ 448
380 block_ack_param_set &= ~BLOCKACKPARAM_AMSDU_SUPP_MASK; 449 /* If we don't support AMSDU inside AMPDU, reset the bit */
381 block_ack_param_set |= (priv->add_ba_param.rx_win_size << 450 if (!priv->add_ba_param.rx_amsdu ||
382 BLOCKACKPARAM_WINSIZE_POS); 451 (priv->aggr_prio_tbl[tid].amsdu == BA_STREAM_NOT_ALLOWED))
452 block_ack_param_set &= ~BLOCKACKPARAM_AMSDU_SUPP_MASK;
453 block_ack_param_set |= rx_win_size << BLOCKACKPARAM_WINSIZE_POS;
383 add_ba_rsp->block_ack_param_set = cpu_to_le16(block_ack_param_set); 454 add_ba_rsp->block_ack_param_set = cpu_to_le16(block_ack_param_set);
384 win_size = (le16_to_cpu(add_ba_rsp->block_ack_param_set) 455 win_size = (le16_to_cpu(add_ba_rsp->block_ack_param_set)
385 & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) 456 & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK)
@@ -431,33 +502,46 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv,
431 struct mwifiex_rx_reorder_tbl *tbl; 502 struct mwifiex_rx_reorder_tbl *tbl;
432 int start_win, end_win, win_size; 503 int start_win, end_win, win_size;
433 u16 pkt_index; 504 u16 pkt_index;
505 bool init_window_shift = false;
434 506
435 tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid, ta); 507 tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid, ta);
436 if (!tbl) { 508 if (!tbl) {
437 if (pkt_type != PKT_TYPE_BAR) { 509 if (pkt_type != PKT_TYPE_BAR)
438 if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP) 510 mwifiex_11n_dispatch_pkt(priv, payload);
439 mwifiex_handle_uap_rx_forward(priv, payload);
440 else
441 mwifiex_process_rx_packet(priv, payload);
442 }
443 return 0; 511 return 0;
444 } 512 }
513
514 if ((pkt_type == PKT_TYPE_AMSDU) && !tbl->amsdu) {
515 mwifiex_11n_dispatch_pkt(priv, payload);
516 return 0;
517 }
518
445 start_win = tbl->start_win; 519 start_win = tbl->start_win;
446 win_size = tbl->win_size; 520 win_size = tbl->win_size;
447 end_win = ((start_win + win_size) - 1) & (MAX_TID_VALUE - 1); 521 end_win = ((start_win + win_size) - 1) & (MAX_TID_VALUE - 1);
448 del_timer(&tbl->timer_context.timer); 522 if (tbl->flags & RXREOR_INIT_WINDOW_SHIFT) {
523 init_window_shift = true;
524 tbl->flags &= ~RXREOR_INIT_WINDOW_SHIFT;
525 }
449 mod_timer(&tbl->timer_context.timer, 526 mod_timer(&tbl->timer_context.timer,
450 jiffies + msecs_to_jiffies(MIN_FLUSH_TIMER_MS * win_size)); 527 jiffies + msecs_to_jiffies(MIN_FLUSH_TIMER_MS * win_size));
451 528
452 /*
453 * If seq_num is less then starting win then ignore and drop the
454 * packet
455 */
456 if (tbl->flags & RXREOR_FORCE_NO_DROP) { 529 if (tbl->flags & RXREOR_FORCE_NO_DROP) {
457 dev_dbg(priv->adapter->dev, 530 dev_dbg(priv->adapter->dev,
458 "RXREOR_FORCE_NO_DROP when HS is activated\n"); 531 "RXREOR_FORCE_NO_DROP when HS is activated\n");
459 tbl->flags &= ~RXREOR_FORCE_NO_DROP; 532 tbl->flags &= ~RXREOR_FORCE_NO_DROP;
533 } else if (init_window_shift && seq_num < start_win &&
534 seq_num >= tbl->init_win) {
535 dev_dbg(priv->adapter->dev,
536 "Sender TID sequence number reset %d->%d for SSN %d\n",
537 start_win, seq_num, tbl->init_win);
538 tbl->start_win = start_win = seq_num;
539 end_win = ((start_win + win_size) - 1) & (MAX_TID_VALUE - 1);
460 } else { 540 } else {
541 /*
542 * If seq_num is less then starting win then ignore and drop
543 * the packet
544 */
461 if ((start_win + TWOPOW11) > (MAX_TID_VALUE - 1)) { 545 if ((start_win + TWOPOW11) > (MAX_TID_VALUE - 1)) {
462 if (seq_num >= ((start_win + TWOPOW11) & 546 if (seq_num >= ((start_win + TWOPOW11) &
463 (MAX_TID_VALUE - 1)) && 547 (MAX_TID_VALUE - 1)) &&
@@ -485,7 +569,7 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv,
485 start_win = (end_win - win_size) + 1; 569 start_win = (end_win - win_size) + 1;
486 else 570 else
487 start_win = (MAX_TID_VALUE - (win_size - seq_num)) + 1; 571 start_win = (MAX_TID_VALUE - (win_size - seq_num)) + 1;
488 mwifiex_11n_dispatch_pkt(priv, tbl, start_win); 572 mwifiex_11n_dispatch_pkt_until_start_win(priv, tbl, start_win);
489 } 573 }
490 574
491 if (pkt_type != PKT_TYPE_BAR) { 575 if (pkt_type != PKT_TYPE_BAR) {
@@ -576,16 +660,7 @@ int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv,
576 * Check if we had rejected the ADDBA, if yes then do not create 660 * Check if we had rejected the ADDBA, if yes then do not create
577 * the stream 661 * the stream
578 */ 662 */
579 if (le16_to_cpu(add_ba_rsp->status_code) == BA_RESULT_SUCCESS) { 663 if (le16_to_cpu(add_ba_rsp->status_code) != BA_RESULT_SUCCESS) {
580 win_size = (block_ack_param_set &
581 IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK)
582 >> BLOCKACKPARAM_WINSIZE_POS;
583
584 dev_dbg(priv->adapter->dev,
585 "cmd: ADDBA RSP: %pM tid=%d ssn=%d win_size=%d\n",
586 add_ba_rsp->peer_mac_addr, tid,
587 add_ba_rsp->ssn, win_size);
588 } else {
589 dev_err(priv->adapter->dev, "ADDBA RSP: failed %pM tid=%d)\n", 664 dev_err(priv->adapter->dev, "ADDBA RSP: failed %pM tid=%d)\n",
590 add_ba_rsp->peer_mac_addr, tid); 665 add_ba_rsp->peer_mac_addr, tid);
591 666
@@ -593,8 +668,28 @@ int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv,
593 add_ba_rsp->peer_mac_addr); 668 add_ba_rsp->peer_mac_addr);
594 if (tbl) 669 if (tbl)
595 mwifiex_del_rx_reorder_entry(priv, tbl); 670 mwifiex_del_rx_reorder_entry(priv, tbl);
671
672 return 0;
596 } 673 }
597 674
675 win_size = (block_ack_param_set & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK)
676 >> BLOCKACKPARAM_WINSIZE_POS;
677
678 tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid,
679 add_ba_rsp->peer_mac_addr);
680 if (tbl) {
681 if ((block_ack_param_set & BLOCKACKPARAM_AMSDU_SUPP_MASK) &&
682 priv->add_ba_param.rx_amsdu &&
683 (priv->aggr_prio_tbl[tid].amsdu != BA_STREAM_NOT_ALLOWED))
684 tbl->amsdu = true;
685 else
686 tbl->amsdu = false;
687 }
688
689 dev_dbg(priv->adapter->dev,
690 "cmd: ADDBA RSP: %pM tid=%d ssn=%d win_size=%d\n",
691 add_ba_rsp->peer_mac_addr, tid, add_ba_rsp->ssn, win_size);
692
598 return 0; 693 return 0;
599} 694}
600 695
@@ -615,7 +710,7 @@ void mwifiex_11n_ba_stream_timeout(struct mwifiex_private *priv,
615 delba.del_ba_param_set |= cpu_to_le16( 710 delba.del_ba_param_set |= cpu_to_le16(
616 (u16) event->origninator << DELBA_INITIATOR_POS); 711 (u16) event->origninator << DELBA_INITIATOR_POS);
617 delba.reason_code = cpu_to_le16(WLAN_REASON_QSTA_TIMEOUT); 712 delba.reason_code = cpu_to_le16(WLAN_REASON_QSTA_TIMEOUT);
618 mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_DELBA, 0, 0, &delba); 713 mwifiex_send_cmd(priv, HostCmd_CMD_11N_DELBA, 0, 0, &delba, false);
619} 714}
620 715
621/* 716/*
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.h b/drivers/net/wireless/mwifiex/11n_rxreorder.h
index 4064041ac852..0fc76e4a60f8 100644
--- a/drivers/net/wireless/mwifiex/11n_rxreorder.h
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.h
@@ -42,7 +42,8 @@
42#define BA_SETUP_PACKET_OFFSET 16 42#define BA_SETUP_PACKET_OFFSET 16
43 43
44enum mwifiex_rxreor_flags { 44enum mwifiex_rxreor_flags {
45 RXREOR_FORCE_NO_DROP = 1<<0, 45 RXREOR_FORCE_NO_DROP = 1<<0,
46 RXREOR_INIT_WINDOW_SHIFT = 1<<1,
46}; 47};
47 48
48static inline void mwifiex_reset_11n_rx_seq_num(struct mwifiex_private *priv) 49static inline void mwifiex_reset_11n_rx_seq_num(struct mwifiex_private *priv)
diff --git a/drivers/net/wireless/mwifiex/Makefile b/drivers/net/wireless/mwifiex/Makefile
index a42a506fd32b..2aa208ffbe23 100644
--- a/drivers/net/wireless/mwifiex/Makefile
+++ b/drivers/net/wireless/mwifiex/Makefile
@@ -41,6 +41,7 @@ mwifiex-y += uap_txrx.o
41mwifiex-y += cfg80211.o 41mwifiex-y += cfg80211.o
42mwifiex-y += ethtool.o 42mwifiex-y += ethtool.o
43mwifiex-y += 11h.o 43mwifiex-y += 11h.o
44mwifiex-y += tdls.o
44mwifiex-$(CONFIG_DEBUG_FS) += debugfs.o 45mwifiex-$(CONFIG_DEBUG_FS) += debugfs.o
45obj-$(CONFIG_MWIFIEX) += mwifiex.o 46obj-$(CONFIG_MWIFIEX) += mwifiex.o
46 47
diff --git a/drivers/net/wireless/mwifiex/README b/drivers/net/wireless/mwifiex/README
index 3d64613ebb29..b9242c3dca43 100644
--- a/drivers/net/wireless/mwifiex/README
+++ b/drivers/net/wireless/mwifiex/README
@@ -131,7 +131,7 @@ info
131 hs_configured = <0/1, host sleep not configured/configured> 131 hs_configured = <0/1, host sleep not configured/configured>
132 hs_activated = <0/1, extended host sleep not activated/activated> 132 hs_activated = <0/1, extended host sleep not activated/activated>
133 num_tx_timeout = <number of Tx timeout> 133 num_tx_timeout = <number of Tx timeout>
134 num_cmd_timeout = <number of timeout commands> 134 is_cmd_timedout = <0/1 command timeout not occurred/occurred>
135 timeout_cmd_id = <command id of the last timeout command> 135 timeout_cmd_id = <command id of the last timeout command>
136 timeout_cmd_act = <command action of the last timeout command> 136 timeout_cmd_act = <command action of the last timeout command>
137 last_cmd_id = <command id of the last several commands sent to device> 137 last_cmd_id = <command id of the last several commands sent to device>
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 8bfc07cd330e..21ee27ab7b74 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -252,9 +252,9 @@ mwifiex_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
252 252
253 if (mask != priv->mgmt_frame_mask) { 253 if (mask != priv->mgmt_frame_mask) {
254 priv->mgmt_frame_mask = mask; 254 priv->mgmt_frame_mask = mask;
255 mwifiex_send_cmd_async(priv, HostCmd_CMD_MGMT_FRAME_REG, 255 mwifiex_send_cmd(priv, HostCmd_CMD_MGMT_FRAME_REG,
256 HostCmd_ACT_GEN_SET, 0, 256 HostCmd_ACT_GEN_SET, 0,
257 &priv->mgmt_frame_mask); 257 &priv->mgmt_frame_mask, false);
258 wiphy_dbg(wiphy, "info: mgmt frame registered\n"); 258 wiphy_dbg(wiphy, "info: mgmt frame registered\n");
259 } 259 }
260} 260}
@@ -515,8 +515,8 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy)
515 515
516 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); 516 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
517 517
518 if (mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11D_DOMAIN_INFO, 518 if (mwifiex_send_cmd(priv, HostCmd_CMD_802_11D_DOMAIN_INFO,
519 HostCmd_ACT_GEN_SET, 0, NULL)) { 519 HostCmd_ACT_GEN_SET, 0, NULL, false)) {
520 wiphy_err(wiphy, "11D: setting domain info in FW\n"); 520 wiphy_err(wiphy, "11D: setting domain info in FW\n");
521 return -1; 521 return -1;
522 } 522 }
@@ -580,9 +580,9 @@ mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr)
580 frag_thr > MWIFIEX_FRAG_MAX_VALUE) 580 frag_thr > MWIFIEX_FRAG_MAX_VALUE)
581 frag_thr = MWIFIEX_FRAG_MAX_VALUE; 581 frag_thr = MWIFIEX_FRAG_MAX_VALUE;
582 582
583 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, 583 return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
584 HostCmd_ACT_GEN_SET, FRAG_THRESH_I, 584 HostCmd_ACT_GEN_SET, FRAG_THRESH_I,
585 &frag_thr); 585 &frag_thr, true);
586} 586}
587 587
588/* 588/*
@@ -597,9 +597,9 @@ mwifiex_set_rts(struct mwifiex_private *priv, u32 rts_thr)
597 if (rts_thr < MWIFIEX_RTS_MIN_VALUE || rts_thr > MWIFIEX_RTS_MAX_VALUE) 597 if (rts_thr < MWIFIEX_RTS_MIN_VALUE || rts_thr > MWIFIEX_RTS_MAX_VALUE)
598 rts_thr = MWIFIEX_RTS_MAX_VALUE; 598 rts_thr = MWIFIEX_RTS_MAX_VALUE;
599 599
600 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, 600 return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
601 HostCmd_ACT_GEN_SET, RTS_THRESH_I, 601 HostCmd_ACT_GEN_SET, RTS_THRESH_I,
602 &rts_thr); 602 &rts_thr, true);
603} 603}
604 604
605/* 605/*
@@ -637,20 +637,19 @@ mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
637 637
638 bss_started = priv->bss_started; 638 bss_started = priv->bss_started;
639 639
640 ret = mwifiex_send_cmd_sync(priv, 640 ret = mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_STOP,
641 HostCmd_CMD_UAP_BSS_STOP, 641 HostCmd_ACT_GEN_SET, 0,
642 HostCmd_ACT_GEN_SET, 0, 642 NULL, true);
643 NULL);
644 if (ret) { 643 if (ret) {
645 wiphy_err(wiphy, "Failed to stop the BSS\n"); 644 wiphy_err(wiphy, "Failed to stop the BSS\n");
646 kfree(bss_cfg); 645 kfree(bss_cfg);
647 return ret; 646 return ret;
648 } 647 }
649 648
650 ret = mwifiex_send_cmd_async(priv, 649 ret = mwifiex_send_cmd(priv, HostCmd_CMD_UAP_SYS_CONFIG,
651 HostCmd_CMD_UAP_SYS_CONFIG, 650 HostCmd_ACT_GEN_SET,
652 HostCmd_ACT_GEN_SET, 651 UAP_BSS_PARAMS_I, bss_cfg,
653 UAP_BSS_PARAMS_I, bss_cfg); 652 false);
654 653
655 kfree(bss_cfg); 654 kfree(bss_cfg);
656 655
@@ -662,10 +661,9 @@ mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
662 if (!bss_started) 661 if (!bss_started)
663 break; 662 break;
664 663
665 ret = mwifiex_send_cmd_async(priv, 664 ret = mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_START,
666 HostCmd_CMD_UAP_BSS_START, 665 HostCmd_ACT_GEN_SET, 0,
667 HostCmd_ACT_GEN_SET, 0, 666 NULL, false);
668 NULL);
669 if (ret) { 667 if (ret) {
670 wiphy_err(wiphy, "Failed to start BSS\n"); 668 wiphy_err(wiphy, "Failed to start BSS\n");
671 return ret; 669 return ret;
@@ -700,8 +698,8 @@ mwifiex_cfg80211_deinit_p2p(struct mwifiex_private *priv)
700 if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA) 698 if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA)
701 mwifiex_set_bss_role(priv, MWIFIEX_BSS_ROLE_STA); 699 mwifiex_set_bss_role(priv, MWIFIEX_BSS_ROLE_STA);
702 700
703 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_P2P_MODE_CFG, 701 if (mwifiex_send_cmd(priv, HostCmd_CMD_P2P_MODE_CFG,
704 HostCmd_ACT_GEN_SET, 0, &mode)) 702 HostCmd_ACT_GEN_SET, 0, &mode, true))
705 return -1; 703 return -1;
706 704
707 return 0; 705 return 0;
@@ -721,13 +719,13 @@ mwifiex_cfg80211_init_p2p_client(struct mwifiex_private *priv)
721 return -1; 719 return -1;
722 720
723 mode = P2P_MODE_DEVICE; 721 mode = P2P_MODE_DEVICE;
724 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_P2P_MODE_CFG, 722 if (mwifiex_send_cmd(priv, HostCmd_CMD_P2P_MODE_CFG,
725 HostCmd_ACT_GEN_SET, 0, &mode)) 723 HostCmd_ACT_GEN_SET, 0, &mode, true))
726 return -1; 724 return -1;
727 725
728 mode = P2P_MODE_CLIENT; 726 mode = P2P_MODE_CLIENT;
729 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_P2P_MODE_CFG, 727 if (mwifiex_send_cmd(priv, HostCmd_CMD_P2P_MODE_CFG,
730 HostCmd_ACT_GEN_SET, 0, &mode)) 728 HostCmd_ACT_GEN_SET, 0, &mode, true))
731 return -1; 729 return -1;
732 730
733 return 0; 731 return 0;
@@ -747,13 +745,13 @@ mwifiex_cfg80211_init_p2p_go(struct mwifiex_private *priv)
747 return -1; 745 return -1;
748 746
749 mode = P2P_MODE_DEVICE; 747 mode = P2P_MODE_DEVICE;
750 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_P2P_MODE_CFG, 748 if (mwifiex_send_cmd(priv, HostCmd_CMD_P2P_MODE_CFG,
751 HostCmd_ACT_GEN_SET, 0, &mode)) 749 HostCmd_ACT_GEN_SET, 0, &mode, true))
752 return -1; 750 return -1;
753 751
754 mode = P2P_MODE_GO; 752 mode = P2P_MODE_GO;
755 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_P2P_MODE_CFG, 753 if (mwifiex_send_cmd(priv, HostCmd_CMD_P2P_MODE_CFG,
756 HostCmd_ACT_GEN_SET, 0, &mode)) 754 HostCmd_ACT_GEN_SET, 0, &mode, true))
757 return -1; 755 return -1;
758 756
759 if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_UAP) 757 if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_UAP)
@@ -853,8 +851,8 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
853 851
854 priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM; 852 priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM;
855 853
856 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_SET_BSS_MODE, 854 ret = mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
857 HostCmd_ACT_GEN_SET, 0, NULL); 855 HostCmd_ACT_GEN_SET, 0, NULL, true);
858 856
859 return ret; 857 return ret;
860} 858}
@@ -942,8 +940,8 @@ mwifiex_dump_station_info(struct mwifiex_private *priv,
942 STATION_INFO_SIGNAL | STATION_INFO_SIGNAL_AVG; 940 STATION_INFO_SIGNAL | STATION_INFO_SIGNAL_AVG;
943 941
944 /* Get signal information from the firmware */ 942 /* Get signal information from the firmware */
945 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_RSSI_INFO, 943 if (mwifiex_send_cmd(priv, HostCmd_CMD_RSSI_INFO,
946 HostCmd_ACT_GEN_GET, 0, NULL)) { 944 HostCmd_ACT_GEN_GET, 0, NULL, true)) {
947 dev_err(priv->adapter->dev, "failed to get signal information\n"); 945 dev_err(priv->adapter->dev, "failed to get signal information\n");
948 return -EFAULT; 946 return -EFAULT;
949 } 947 }
@@ -954,9 +952,9 @@ mwifiex_dump_station_info(struct mwifiex_private *priv,
954 } 952 }
955 953
956 /* Get DTIM period information from firmware */ 954 /* Get DTIM period information from firmware */
957 mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, 955 mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
958 HostCmd_ACT_GEN_GET, DTIM_PERIOD_I, 956 HostCmd_ACT_GEN_GET, DTIM_PERIOD_I,
959 &priv->dtim_period); 957 &priv->dtim_period, true);
960 958
961 mwifiex_parse_htinfo(priv, priv->tx_htinfo, &sinfo->txrate); 959 mwifiex_parse_htinfo(priv, priv->tx_htinfo, &sinfo->txrate);
962 960
@@ -1160,9 +1158,10 @@ static int mwifiex_cfg80211_set_bitrate_mask(struct wiphy *wiphy,
1160 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 1158 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
1161 u16 bitmap_rates[MAX_BITMAP_RATES_SIZE]; 1159 u16 bitmap_rates[MAX_BITMAP_RATES_SIZE];
1162 enum ieee80211_band band; 1160 enum ieee80211_band band;
1161 struct mwifiex_adapter *adapter = priv->adapter;
1163 1162
1164 if (!priv->media_connected) { 1163 if (!priv->media_connected) {
1165 dev_err(priv->adapter->dev, 1164 dev_err(adapter->dev,
1166 "Can not set Tx data rate in disconnected state\n"); 1165 "Can not set Tx data rate in disconnected state\n");
1167 return -EINVAL; 1166 return -EINVAL;
1168 } 1167 }
@@ -1183,11 +1182,18 @@ static int mwifiex_cfg80211_set_bitrate_mask(struct wiphy *wiphy,
1183 1182
1184 /* Fill HT MCS rates */ 1183 /* Fill HT MCS rates */
1185 bitmap_rates[2] = mask->control[band].ht_mcs[0]; 1184 bitmap_rates[2] = mask->control[band].ht_mcs[0];
1186 if (priv->adapter->hw_dev_mcs_support == HT_STREAM_2X2) 1185 if (adapter->hw_dev_mcs_support == HT_STREAM_2X2)
1187 bitmap_rates[2] |= mask->control[band].ht_mcs[1] << 8; 1186 bitmap_rates[2] |= mask->control[band].ht_mcs[1] << 8;
1188 1187
1189 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_TX_RATE_CFG, 1188 /* Fill VHT MCS rates */
1190 HostCmd_ACT_GEN_SET, 0, bitmap_rates); 1189 if (adapter->fw_api_ver == MWIFIEX_FW_V15) {
1190 bitmap_rates[10] = mask->control[band].vht_mcs[0];
1191 if (adapter->hw_dev_mcs_support == HT_STREAM_2X2)
1192 bitmap_rates[11] = mask->control[band].vht_mcs[1];
1193 }
1194
1195 return mwifiex_send_cmd(priv, HostCmd_CMD_TX_RATE_CFG,
1196 HostCmd_ACT_GEN_SET, 0, bitmap_rates, true);
1191} 1197}
1192 1198
1193/* 1199/*
@@ -1216,14 +1222,14 @@ static int mwifiex_cfg80211_set_cqm_rssi_config(struct wiphy *wiphy,
1216 subsc_evt.bcn_h_rssi_cfg.abs_value = abs(rssi_thold); 1222 subsc_evt.bcn_h_rssi_cfg.abs_value = abs(rssi_thold);
1217 subsc_evt.bcn_l_rssi_cfg.evt_freq = 1; 1223 subsc_evt.bcn_l_rssi_cfg.evt_freq = 1;
1218 subsc_evt.bcn_h_rssi_cfg.evt_freq = 1; 1224 subsc_evt.bcn_h_rssi_cfg.evt_freq = 1;
1219 return mwifiex_send_cmd_sync(priv, 1225 return mwifiex_send_cmd(priv,
1220 HostCmd_CMD_802_11_SUBSCRIBE_EVENT, 1226 HostCmd_CMD_802_11_SUBSCRIBE_EVENT,
1221 0, 0, &subsc_evt); 1227 0, 0, &subsc_evt, true);
1222 } else { 1228 } else {
1223 subsc_evt.action = HostCmd_ACT_BITWISE_CLR; 1229 subsc_evt.action = HostCmd_ACT_BITWISE_CLR;
1224 return mwifiex_send_cmd_sync(priv, 1230 return mwifiex_send_cmd(priv,
1225 HostCmd_CMD_802_11_SUBSCRIBE_EVENT, 1231 HostCmd_CMD_802_11_SUBSCRIBE_EVENT,
1226 0, 0, &subsc_evt); 1232 0, 0, &subsc_evt, true);
1227 } 1233 }
1228 1234
1229 return 0; 1235 return 0;
@@ -1276,10 +1282,9 @@ mwifiex_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev,
1276 if (!mac || is_broadcast_ether_addr(mac)) { 1282 if (!mac || is_broadcast_ether_addr(mac)) {
1277 wiphy_dbg(wiphy, "%s: NULL/broadcast mac address\n", __func__); 1283 wiphy_dbg(wiphy, "%s: NULL/broadcast mac address\n", __func__);
1278 list_for_each_entry(sta_node, &priv->sta_list, list) { 1284 list_for_each_entry(sta_node, &priv->sta_list, list) {
1279 if (mwifiex_send_cmd_sync(priv, 1285 if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_STA_DEAUTH,
1280 HostCmd_CMD_UAP_STA_DEAUTH, 1286 HostCmd_ACT_GEN_SET, 0,
1281 HostCmd_ACT_GEN_SET, 0, 1287 sta_node->mac_addr, true))
1282 sta_node->mac_addr))
1283 return -1; 1288 return -1;
1284 mwifiex_uap_del_sta_data(priv, sta_node); 1289 mwifiex_uap_del_sta_data(priv, sta_node);
1285 } 1290 }
@@ -1289,10 +1294,9 @@ mwifiex_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev,
1289 sta_node = mwifiex_get_sta_entry(priv, mac); 1294 sta_node = mwifiex_get_sta_entry(priv, mac);
1290 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags); 1295 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
1291 if (sta_node) { 1296 if (sta_node) {
1292 if (mwifiex_send_cmd_sync(priv, 1297 if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_STA_DEAUTH,
1293 HostCmd_CMD_UAP_STA_DEAUTH, 1298 HostCmd_ACT_GEN_SET, 0,
1294 HostCmd_ACT_GEN_SET, 0, 1299 sta_node->mac_addr, true))
1295 sta_node->mac_addr))
1296 return -1; 1300 return -1;
1297 mwifiex_uap_del_sta_data(priv, sta_node); 1301 mwifiex_uap_del_sta_data(priv, sta_node);
1298 } 1302 }
@@ -1328,13 +1332,40 @@ mwifiex_cfg80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant)
1328 tx_ant = RF_ANTENNA_AUTO; 1332 tx_ant = RF_ANTENNA_AUTO;
1329 rx_ant = RF_ANTENNA_AUTO; 1333 rx_ant = RF_ANTENNA_AUTO;
1330 } 1334 }
1335 } else {
1336 struct ieee80211_sta_ht_cap *ht_info;
1337 int rx_mcs_supp;
1338 enum ieee80211_band band;
1339
1340 if ((tx_ant == 0x1 && rx_ant == 0x1)) {
1341 adapter->user_dev_mcs_support = HT_STREAM_1X1;
1342 if (adapter->is_hw_11ac_capable)
1343 adapter->usr_dot_11ac_mcs_support =
1344 MWIFIEX_11AC_MCS_MAP_1X1;
1345 } else {
1346 adapter->user_dev_mcs_support = HT_STREAM_2X2;
1347 if (adapter->is_hw_11ac_capable)
1348 adapter->usr_dot_11ac_mcs_support =
1349 MWIFIEX_11AC_MCS_MAP_2X2;
1350 }
1351
1352 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
1353 if (!adapter->wiphy->bands[band])
1354 continue;
1355
1356 ht_info = &adapter->wiphy->bands[band]->ht_cap;
1357 rx_mcs_supp =
1358 GET_RXMCSSUPP(adapter->user_dev_mcs_support);
1359 memset(&ht_info->mcs, 0, adapter->number_of_antenna);
1360 memset(&ht_info->mcs, 0xff, rx_mcs_supp);
1361 }
1331 } 1362 }
1332 1363
1333 ant_cfg.tx_ant = tx_ant; 1364 ant_cfg.tx_ant = tx_ant;
1334 ant_cfg.rx_ant = rx_ant; 1365 ant_cfg.rx_ant = rx_ant;
1335 1366
1336 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_RF_ANTENNA, 1367 return mwifiex_send_cmd(priv, HostCmd_CMD_RF_ANTENNA,
1337 HostCmd_ACT_GEN_SET, 0, &ant_cfg); 1368 HostCmd_ACT_GEN_SET, 0, &ant_cfg, true);
1338} 1369}
1339 1370
1340/* cfg80211 operation handler for stop ap. 1371/* cfg80211 operation handler for stop ap.
@@ -1349,8 +1380,8 @@ static int mwifiex_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
1349 1380
1350 priv->ap_11n_enabled = 0; 1381 priv->ap_11n_enabled = 0;
1351 1382
1352 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_UAP_BSS_STOP, 1383 if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_STOP,
1353 HostCmd_ACT_GEN_SET, 0, NULL)) { 1384 HostCmd_ACT_GEN_SET, 0, NULL, true)) {
1354 wiphy_err(wiphy, "Failed to stop the BSS\n"); 1385 wiphy_err(wiphy, "Failed to stop the BSS\n");
1355 return -1; 1386 return -1;
1356 } 1387 }
@@ -1416,9 +1447,6 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
1416 1447
1417 if (params->chandef.width > NL80211_CHAN_WIDTH_20_NOHT) 1448 if (params->chandef.width > NL80211_CHAN_WIDTH_20_NOHT)
1418 config_bands |= BAND_GN; 1449 config_bands |= BAND_GN;
1419
1420 if (params->chandef.width > NL80211_CHAN_WIDTH_40)
1421 config_bands |= BAND_GAC;
1422 } else { 1450 } else {
1423 bss_cfg->band_cfg = BAND_CONFIG_A; 1451 bss_cfg->band_cfg = BAND_CONFIG_A;
1424 config_bands = BAND_A; 1452 config_bands = BAND_A;
@@ -1464,16 +1492,16 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
1464 bss_cfg->ps_sta_ao_timer = 10 * params->inactivity_timeout; 1492 bss_cfg->ps_sta_ao_timer = 10 * params->inactivity_timeout;
1465 } 1493 }
1466 1494
1467 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_UAP_BSS_STOP, 1495 if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_STOP,
1468 HostCmd_ACT_GEN_SET, 0, NULL)) { 1496 HostCmd_ACT_GEN_SET, 0, NULL, true)) {
1469 wiphy_err(wiphy, "Failed to stop the BSS\n"); 1497 wiphy_err(wiphy, "Failed to stop the BSS\n");
1470 kfree(bss_cfg); 1498 kfree(bss_cfg);
1471 return -1; 1499 return -1;
1472 } 1500 }
1473 1501
1474 if (mwifiex_send_cmd_async(priv, HostCmd_CMD_UAP_SYS_CONFIG, 1502 if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_SYS_CONFIG,
1475 HostCmd_ACT_GEN_SET, 1503 HostCmd_ACT_GEN_SET,
1476 UAP_BSS_PARAMS_I, bss_cfg)) { 1504 UAP_BSS_PARAMS_I, bss_cfg, false)) {
1477 wiphy_err(wiphy, "Failed to set the SSID\n"); 1505 wiphy_err(wiphy, "Failed to set the SSID\n");
1478 kfree(bss_cfg); 1506 kfree(bss_cfg);
1479 return -1; 1507 return -1;
@@ -1481,8 +1509,8 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
1481 1509
1482 kfree(bss_cfg); 1510 kfree(bss_cfg);
1483 1511
1484 if (mwifiex_send_cmd_async(priv, HostCmd_CMD_UAP_BSS_START, 1512 if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_START,
1485 HostCmd_ACT_GEN_SET, 0, NULL)) { 1513 HostCmd_ACT_GEN_SET, 0, NULL, false)) {
1486 wiphy_err(wiphy, "Failed to start the BSS\n"); 1514 wiphy_err(wiphy, "Failed to start the BSS\n");
1487 return -1; 1515 return -1;
1488 } 1516 }
@@ -1492,9 +1520,9 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
1492 else 1520 else
1493 priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE; 1521 priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE;
1494 1522
1495 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_MAC_CONTROL, 1523 if (mwifiex_send_cmd(priv, HostCmd_CMD_MAC_CONTROL,
1496 HostCmd_ACT_GEN_SET, 0, 1524 HostCmd_ACT_GEN_SET, 0,
1497 &priv->curr_pkt_filter)) 1525 &priv->curr_pkt_filter, true))
1498 return -1; 1526 return -1;
1499 1527
1500 return 0; 1528 return 0;
@@ -1583,8 +1611,9 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv)
1583 * the function notifies the CFG802.11 subsystem of the new BSS connection. 1611 * the function notifies the CFG802.11 subsystem of the new BSS connection.
1584 */ 1612 */
1585static int 1613static int
1586mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, 1614mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len,
1587 u8 *bssid, int mode, struct ieee80211_channel *channel, 1615 const u8 *ssid, const u8 *bssid, int mode,
1616 struct ieee80211_channel *channel,
1588 struct cfg80211_connect_params *sme, bool privacy) 1617 struct cfg80211_connect_params *sme, bool privacy)
1589{ 1618{
1590 struct cfg80211_ssid req_ssid; 1619 struct cfg80211_ssid req_ssid;
@@ -1881,7 +1910,8 @@ mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1881 params->privacy); 1910 params->privacy);
1882done: 1911done:
1883 if (!ret) { 1912 if (!ret) {
1884 cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid, GFP_KERNEL); 1913 cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid,
1914 params->chandef.chan, GFP_KERNEL);
1885 dev_dbg(priv->adapter->dev, 1915 dev_dbg(priv->adapter->dev,
1886 "info: joined/created adhoc network with bssid" 1916 "info: joined/created adhoc network with bssid"
1887 " %pM successfully\n", priv->cfg_bssid); 1917 " %pM successfully\n", priv->cfg_bssid);
@@ -2070,10 +2100,10 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info,
2070 else 2100 else
2071 ht_info->cap &= ~IEEE80211_HT_CAP_SGI_40; 2101 ht_info->cap &= ~IEEE80211_HT_CAP_SGI_40;
2072 2102
2073 if (ISSUPP_RXSTBC(adapter->hw_dot_11n_dev_cap)) 2103 if (adapter->user_dev_mcs_support == HT_STREAM_2X2)
2074 ht_info->cap |= 1 << IEEE80211_HT_CAP_RX_STBC_SHIFT; 2104 ht_info->cap |= 3 << IEEE80211_HT_CAP_RX_STBC_SHIFT;
2075 else 2105 else
2076 ht_info->cap &= ~(3 << IEEE80211_HT_CAP_RX_STBC_SHIFT); 2106 ht_info->cap |= 1 << IEEE80211_HT_CAP_RX_STBC_SHIFT;
2077 2107
2078 if (ISSUPP_TXSTBC(adapter->hw_dot_11n_dev_cap)) 2108 if (ISSUPP_TXSTBC(adapter->hw_dot_11n_dev_cap))
2079 ht_info->cap |= IEEE80211_HT_CAP_TX_STBC; 2109 ht_info->cap |= IEEE80211_HT_CAP_TX_STBC;
@@ -2098,8 +2128,8 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info,
2098 ht_info->cap &= ~IEEE80211_HT_CAP_MAX_AMSDU; 2128 ht_info->cap &= ~IEEE80211_HT_CAP_MAX_AMSDU;
2099 ht_info->cap |= IEEE80211_HT_CAP_SM_PS; 2129 ht_info->cap |= IEEE80211_HT_CAP_SM_PS;
2100 2130
2101 rx_mcs_supp = GET_RXMCSSUPP(adapter->hw_dev_mcs_support); 2131 rx_mcs_supp = GET_RXMCSSUPP(adapter->user_dev_mcs_support);
2102 /* Set MCS for 1x1 */ 2132 /* Set MCS for 1x1/2x2 */
2103 memset(mcs, 0xff, rx_mcs_supp); 2133 memset(mcs, 0xff, rx_mcs_supp);
2104 /* Clear all the other values */ 2134 /* Clear all the other values */
2105 memset(&mcs[rx_mcs_supp], 0, 2135 memset(&mcs[rx_mcs_supp], 0,
@@ -2460,9 +2490,8 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
2460 MWIFIEX_CRITERIA_UNICAST | 2490 MWIFIEX_CRITERIA_UNICAST |
2461 MWIFIEX_CRITERIA_MULTICAST; 2491 MWIFIEX_CRITERIA_MULTICAST;
2462 2492
2463 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_MEF_CFG, 2493 ret = mwifiex_send_cmd(priv, HostCmd_CMD_MEF_CFG,
2464 HostCmd_ACT_GEN_SET, 0, 2494 HostCmd_ACT_GEN_SET, 0, &mef_cfg, true);
2465 &mef_cfg);
2466 2495
2467 kfree(mef_entry); 2496 kfree(mef_entry);
2468 return ret; 2497 return ret;
@@ -2574,9 +2603,9 @@ static int mwifiex_cfg80211_set_coalesce(struct wiphy *wiphy,
2574 if (!coalesce) { 2603 if (!coalesce) {
2575 dev_dbg(adapter->dev, 2604 dev_dbg(adapter->dev,
2576 "Disable coalesce and reset all previous rules\n"); 2605 "Disable coalesce and reset all previous rules\n");
2577 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_COALESCE_CFG, 2606 return mwifiex_send_cmd(priv, HostCmd_CMD_COALESCE_CFG,
2578 HostCmd_ACT_GEN_SET, 0, 2607 HostCmd_ACT_GEN_SET, 0,
2579 &coalesce_cfg); 2608 &coalesce_cfg, true);
2580 } 2609 }
2581 2610
2582 coalesce_cfg.num_of_rules = coalesce->n_rules; 2611 coalesce_cfg.num_of_rules = coalesce->n_rules;
@@ -2591,8 +2620,172 @@ static int mwifiex_cfg80211_set_coalesce(struct wiphy *wiphy,
2591 } 2620 }
2592 } 2621 }
2593 2622
2594 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_COALESCE_CFG, 2623 return mwifiex_send_cmd(priv, HostCmd_CMD_COALESCE_CFG,
2595 HostCmd_ACT_GEN_SET, 0, &coalesce_cfg); 2624 HostCmd_ACT_GEN_SET, 0, &coalesce_cfg, true);
2625}
2626
2627/* cfg80211 ops handler for tdls_mgmt.
2628 * Function prepares TDLS action frame packets and forwards them to FW
2629 */
2630static int
2631mwifiex_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
2632 u8 *peer, u8 action_code, u8 dialog_token,
2633 u16 status_code, u32 peer_capability,
2634 const u8 *extra_ies, size_t extra_ies_len)
2635{
2636 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
2637 int ret;
2638
2639 if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS))
2640 return -ENOTSUPP;
2641
2642 /* make sure we are in station mode and connected */
2643 if (!(priv->bss_type == MWIFIEX_BSS_TYPE_STA && priv->media_connected))
2644 return -ENOTSUPP;
2645
2646 switch (action_code) {
2647 case WLAN_TDLS_SETUP_REQUEST:
2648 dev_dbg(priv->adapter->dev,
2649 "Send TDLS Setup Request to %pM status_code=%d\n", peer,
2650 status_code);
2651 ret = mwifiex_send_tdls_data_frame(priv, peer, action_code,
2652 dialog_token, status_code,
2653 extra_ies, extra_ies_len);
2654 break;
2655 case WLAN_TDLS_SETUP_RESPONSE:
2656 dev_dbg(priv->adapter->dev,
2657 "Send TDLS Setup Response to %pM status_code=%d\n",
2658 peer, status_code);
2659 ret = mwifiex_send_tdls_data_frame(priv, peer, action_code,
2660 dialog_token, status_code,
2661 extra_ies, extra_ies_len);
2662 break;
2663 case WLAN_TDLS_SETUP_CONFIRM:
2664 dev_dbg(priv->adapter->dev,
2665 "Send TDLS Confirm to %pM status_code=%d\n", peer,
2666 status_code);
2667 ret = mwifiex_send_tdls_data_frame(priv, peer, action_code,
2668 dialog_token, status_code,
2669 extra_ies, extra_ies_len);
2670 break;
2671 case WLAN_TDLS_TEARDOWN:
2672 dev_dbg(priv->adapter->dev, "Send TDLS Tear down to %pM\n",
2673 peer);
2674 ret = mwifiex_send_tdls_data_frame(priv, peer, action_code,
2675 dialog_token, status_code,
2676 extra_ies, extra_ies_len);
2677 break;
2678 case WLAN_TDLS_DISCOVERY_REQUEST:
2679 dev_dbg(priv->adapter->dev,
2680 "Send TDLS Discovery Request to %pM\n", peer);
2681 ret = mwifiex_send_tdls_data_frame(priv, peer, action_code,
2682 dialog_token, status_code,
2683 extra_ies, extra_ies_len);
2684 break;
2685 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
2686 dev_dbg(priv->adapter->dev,
2687 "Send TDLS Discovery Response to %pM\n", peer);
2688 ret = mwifiex_send_tdls_action_frame(priv, peer, action_code,
2689 dialog_token, status_code,
2690 extra_ies, extra_ies_len);
2691 break;
2692 default:
2693 dev_warn(priv->adapter->dev,
2694 "Unknown TDLS mgmt/action frame %pM\n", peer);
2695 ret = -EINVAL;
2696 break;
2697 }
2698
2699 return ret;
2700}
2701
2702static int
2703mwifiex_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
2704 u8 *peer, enum nl80211_tdls_operation action)
2705{
2706 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
2707
2708 if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
2709 !(wiphy->flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP))
2710 return -ENOTSUPP;
2711
2712 /* make sure we are in station mode and connected */
2713 if (!(priv->bss_type == MWIFIEX_BSS_TYPE_STA && priv->media_connected))
2714 return -ENOTSUPP;
2715
2716 dev_dbg(priv->adapter->dev,
2717 "TDLS peer=%pM, oper=%d\n", peer, action);
2718
2719 switch (action) {
2720 case NL80211_TDLS_ENABLE_LINK:
2721 action = MWIFIEX_TDLS_ENABLE_LINK;
2722 break;
2723 case NL80211_TDLS_DISABLE_LINK:
2724 action = MWIFIEX_TDLS_DISABLE_LINK;
2725 break;
2726 case NL80211_TDLS_TEARDOWN:
2727 /* shouldn't happen!*/
2728 dev_warn(priv->adapter->dev,
2729 "tdls_oper: teardown from driver not supported\n");
2730 return -EINVAL;
2731 case NL80211_TDLS_SETUP:
2732 /* shouldn't happen!*/
2733 dev_warn(priv->adapter->dev,
2734 "tdls_oper: setup from driver not supported\n");
2735 return -EINVAL;
2736 case NL80211_TDLS_DISCOVERY_REQ:
2737 /* shouldn't happen!*/
2738 dev_warn(priv->adapter->dev,
2739 "tdls_oper: discovery from driver not supported\n");
2740 return -EINVAL;
2741 default:
2742 dev_err(priv->adapter->dev,
2743 "tdls_oper: operation not supported\n");
2744 return -ENOTSUPP;
2745 }
2746
2747 return mwifiex_tdls_oper(priv, peer, action);
2748}
2749
2750static int
2751mwifiex_cfg80211_add_station(struct wiphy *wiphy,
2752 struct net_device *dev,
2753 u8 *mac, struct station_parameters *params)
2754{
2755 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
2756
2757 if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
2758 return -ENOTSUPP;
2759
2760 /* make sure we are in station mode and connected */
2761 if ((priv->bss_type != MWIFIEX_BSS_TYPE_STA) || !priv->media_connected)
2762 return -ENOTSUPP;
2763
2764 return mwifiex_tdls_oper(priv, mac, MWIFIEX_TDLS_CREATE_LINK);
2765}
2766
2767static int
2768mwifiex_cfg80211_change_station(struct wiphy *wiphy,
2769 struct net_device *dev,
2770 u8 *mac, struct station_parameters *params)
2771{
2772 int ret;
2773 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
2774
2775 /* we support change_station handler only for TDLS peers*/
2776 if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
2777 return -ENOTSUPP;
2778
2779 /* make sure we are in station mode and connected */
2780 if ((priv->bss_type != MWIFIEX_BSS_TYPE_STA) || !priv->media_connected)
2781 return -ENOTSUPP;
2782
2783 priv->sta_params = params;
2784
2785 ret = mwifiex_tdls_oper(priv, mac, MWIFIEX_TDLS_CONFIG_LINK);
2786 priv->sta_params = NULL;
2787
2788 return ret;
2596} 2789}
2597 2790
2598/* station cfg80211 operations */ 2791/* station cfg80211 operations */
@@ -2630,6 +2823,10 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
2630 .set_wakeup = mwifiex_cfg80211_set_wakeup, 2823 .set_wakeup = mwifiex_cfg80211_set_wakeup,
2631#endif 2824#endif
2632 .set_coalesce = mwifiex_cfg80211_set_coalesce, 2825 .set_coalesce = mwifiex_cfg80211_set_coalesce,
2826 .tdls_mgmt = mwifiex_cfg80211_tdls_mgmt,
2827 .tdls_oper = mwifiex_cfg80211_tdls_oper,
2828 .add_station = mwifiex_cfg80211_add_station,
2829 .change_station = mwifiex_cfg80211_change_station,
2633}; 2830};
2634 2831
2635#ifdef CONFIG_PM 2832#ifdef CONFIG_PM
@@ -2715,6 +2912,11 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
2715 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD | 2912 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
2716 WIPHY_FLAG_AP_UAPSD | 2913 WIPHY_FLAG_AP_UAPSD |
2717 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; 2914 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
2915
2916 if (ISSUPP_TDLS_ENABLED(adapter->fw_cap_info))
2917 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS |
2918 WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
2919
2718 wiphy->regulatory_flags |= 2920 wiphy->regulatory_flags |=
2719 REGULATORY_CUSTOM_REG | 2921 REGULATORY_CUSTOM_REG |
2720 REGULATORY_STRICT_REG; 2922 REGULATORY_STRICT_REG;
@@ -2736,7 +2938,8 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
2736 2938
2737 wiphy->features |= NL80211_FEATURE_HT_IBSS | 2939 wiphy->features |= NL80211_FEATURE_HT_IBSS |
2738 NL80211_FEATURE_INACTIVITY_TIMER | 2940 NL80211_FEATURE_INACTIVITY_TIMER |
2739 NL80211_FEATURE_LOW_PRIORITY_SCAN; 2941 NL80211_FEATURE_LOW_PRIORITY_SCAN |
2942 NL80211_FEATURE_NEED_OBSS_SCAN;
2740 2943
2741 /* Reserve space for mwifiex specific private data for BSS */ 2944 /* Reserve space for mwifiex specific private data for BSS */
2742 wiphy->bss_priv_size = sizeof(struct mwifiex_bss_priv); 2945 wiphy->bss_priv_size = sizeof(struct mwifiex_bss_priv);
@@ -2767,17 +2970,17 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
2767 country_code); 2970 country_code);
2768 } 2971 }
2769 2972
2770 mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, 2973 mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
2771 HostCmd_ACT_GEN_GET, FRAG_THRESH_I, &thr); 2974 HostCmd_ACT_GEN_GET, FRAG_THRESH_I, &thr, true);
2772 wiphy->frag_threshold = thr; 2975 wiphy->frag_threshold = thr;
2773 mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, 2976 mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
2774 HostCmd_ACT_GEN_GET, RTS_THRESH_I, &thr); 2977 HostCmd_ACT_GEN_GET, RTS_THRESH_I, &thr, true);
2775 wiphy->rts_threshold = thr; 2978 wiphy->rts_threshold = thr;
2776 mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, 2979 mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
2777 HostCmd_ACT_GEN_GET, SHORT_RETRY_LIM_I, &retry); 2980 HostCmd_ACT_GEN_GET, SHORT_RETRY_LIM_I, &retry, true);
2778 wiphy->retry_short = (u8) retry; 2981 wiphy->retry_short = (u8) retry;
2779 mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, 2982 mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
2780 HostCmd_ACT_GEN_GET, LONG_RETRY_LIM_I, &retry); 2983 HostCmd_ACT_GEN_GET, LONG_RETRY_LIM_I, &retry, true);
2781 wiphy->retry_long = (u8) retry; 2984 wiphy->retry_long = (u8) retry;
2782 2985
2783 adapter->wiphy = wiphy; 2986 adapter->wiphy = wiphy;
diff --git a/drivers/net/wireless/mwifiex/cfp.c b/drivers/net/wireless/mwifiex/cfp.c
index 9eefacbc844b..0ddec3d4b059 100644
--- a/drivers/net/wireless/mwifiex/cfp.c
+++ b/drivers/net/wireless/mwifiex/cfp.c
@@ -71,6 +71,95 @@ u16 region_code_index[MWIFIEX_MAX_REGION_CODE] = { 0x10, 0x20, 0x30,
71 71
72static u8 supported_rates_n[N_SUPPORTED_RATES] = { 0x02, 0x04, 0 }; 72static u8 supported_rates_n[N_SUPPORTED_RATES] = { 0x02, 0x04, 0 };
73 73
74/* For every mcs_rate line, the first 8 bytes are for stream 1x1,
75 * and all 16 bytes are for stream 2x2.
76 */
77static const u16 mcs_rate[4][16] = {
78 /* LGI 40M */
79 { 0x1b, 0x36, 0x51, 0x6c, 0xa2, 0xd8, 0xf3, 0x10e,
80 0x36, 0x6c, 0xa2, 0xd8, 0x144, 0x1b0, 0x1e6, 0x21c },
81
82 /* SGI 40M */
83 { 0x1e, 0x3c, 0x5a, 0x78, 0xb4, 0xf0, 0x10e, 0x12c,
84 0x3c, 0x78, 0xb4, 0xf0, 0x168, 0x1e0, 0x21c, 0x258 },
85
86 /* LGI 20M */
87 { 0x0d, 0x1a, 0x27, 0x34, 0x4e, 0x68, 0x75, 0x82,
88 0x1a, 0x34, 0x4e, 0x68, 0x9c, 0xd0, 0xea, 0x104 },
89
90 /* SGI 20M */
91 { 0x0e, 0x1c, 0x2b, 0x39, 0x56, 0x73, 0x82, 0x90,
92 0x1c, 0x39, 0x56, 0x73, 0xad, 0xe7, 0x104, 0x120 }
93};
94
95/* AC rates */
96static const u16 ac_mcs_rate_nss1[8][10] = {
97 /* LG 160M */
98 { 0x75, 0xEA, 0x15F, 0x1D4, 0x2BE, 0x3A8, 0x41D,
99 0x492, 0x57C, 0x618 },
100
101 /* SG 160M */
102 { 0x82, 0x104, 0x186, 0x208, 0x30C, 0x410, 0x492,
103 0x514, 0x618, 0x6C6 },
104
105 /* LG 80M */
106 { 0x3B, 0x75, 0xB0, 0xEA, 0x15F, 0x1D4, 0x20F,
107 0x249, 0x2BE, 0x30C },
108
109 /* SG 80M */
110 { 0x41, 0x82, 0xC3, 0x104, 0x186, 0x208, 0x249,
111 0x28A, 0x30C, 0x363 },
112
113 /* LG 40M */
114 { 0x1B, 0x36, 0x51, 0x6C, 0xA2, 0xD8, 0xF3,
115 0x10E, 0x144, 0x168 },
116
117 /* SG 40M */
118 { 0x1E, 0x3C, 0x5A, 0x78, 0xB4, 0xF0, 0x10E,
119 0x12C, 0x168, 0x190 },
120
121 /* LG 20M */
122 { 0xD, 0x1A, 0x27, 0x34, 0x4E, 0x68, 0x75, 0x82, 0x9C, 0x00 },
123
124 /* SG 20M */
125 { 0xF, 0x1D, 0x2C, 0x3A, 0x57, 0x74, 0x82, 0x91, 0xAE, 0x00 },
126};
127
128/* NSS2 note: the value in the table is 2 multiplier of the actual rate */
129static const u16 ac_mcs_rate_nss2[8][10] = {
130 /* LG 160M */
131 { 0xEA, 0x1D4, 0x2BE, 0x3A8, 0x57C, 0x750, 0x83A,
132 0x924, 0xAF8, 0xC30 },
133
134 /* SG 160M */
135 { 0x104, 0x208, 0x30C, 0x410, 0x618, 0x820, 0x924,
136 0xA28, 0xC30, 0xD8B },
137
138 /* LG 80M */
139 { 0x75, 0xEA, 0x15F, 0x1D4, 0x2BE, 0x3A8, 0x41D,
140 0x492, 0x57C, 0x618 },
141
142 /* SG 80M */
143 { 0x82, 0x104, 0x186, 0x208, 0x30C, 0x410, 0x492,
144 0x514, 0x618, 0x6C6 },
145
146 /* LG 40M */
147 { 0x36, 0x6C, 0xA2, 0xD8, 0x144, 0x1B0, 0x1E6,
148 0x21C, 0x288, 0x2D0 },
149
150 /* SG 40M */
151 { 0x3C, 0x78, 0xB4, 0xF0, 0x168, 0x1E0, 0x21C,
152 0x258, 0x2D0, 0x320 },
153
154 /* LG 20M */
155 { 0x1A, 0x34, 0x4A, 0x68, 0x9C, 0xD0, 0xEA, 0x104,
156 0x138, 0x00 },
157
158 /* SG 20M */
159 { 0x1D, 0x3A, 0x57, 0x74, 0xAE, 0xE6, 0x104, 0x121,
160 0x15B, 0x00 },
161};
162
74struct region_code_mapping { 163struct region_code_mapping {
75 u8 code; 164 u8 code;
76 u8 region[IEEE80211_COUNTRY_STRING_LEN]; 165 u8 region[IEEE80211_COUNTRY_STRING_LEN];
@@ -109,95 +198,6 @@ u8 *mwifiex_11d_code_2_region(u8 code)
109u32 mwifiex_index_to_acs_data_rate(struct mwifiex_private *priv, 198u32 mwifiex_index_to_acs_data_rate(struct mwifiex_private *priv,
110 u8 index, u8 ht_info) 199 u8 index, u8 ht_info)
111{ 200{
112 /*
113 * For every mcs_rate line, the first 8 bytes are for stream 1x1,
114 * and all 16 bytes are for stream 2x2.
115 */
116 u16 mcs_rate[4][16] = {
117 /* LGI 40M */
118 { 0x1b, 0x36, 0x51, 0x6c, 0xa2, 0xd8, 0xf3, 0x10e,
119 0x36, 0x6c, 0xa2, 0xd8, 0x144, 0x1b0, 0x1e6, 0x21c },
120
121 /* SGI 40M */
122 { 0x1e, 0x3c, 0x5a, 0x78, 0xb4, 0xf0, 0x10e, 0x12c,
123 0x3c, 0x78, 0xb4, 0xf0, 0x168, 0x1e0, 0x21c, 0x258 },
124
125 /* LGI 20M */
126 { 0x0d, 0x1a, 0x27, 0x34, 0x4e, 0x68, 0x75, 0x82,
127 0x1a, 0x34, 0x4e, 0x68, 0x9c, 0xd0, 0xea, 0x104 },
128
129 /* SGI 20M */
130 { 0x0e, 0x1c, 0x2b, 0x39, 0x56, 0x73, 0x82, 0x90,
131 0x1c, 0x39, 0x56, 0x73, 0xad, 0xe7, 0x104, 0x120 }
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; 201 u32 rate = 0;
202 u8 mcs_index = 0; 202 u8 mcs_index = 0;
203 u8 bw = 0; 203 u8 bw = 0;
@@ -252,28 +252,8 @@ u32 mwifiex_index_to_acs_data_rate(struct mwifiex_private *priv,
252u32 mwifiex_index_to_data_rate(struct mwifiex_private *priv, 252u32 mwifiex_index_to_data_rate(struct mwifiex_private *priv,
253 u8 index, u8 ht_info) 253 u8 index, u8 ht_info)
254{ 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 };
275 u32 mcs_num_supp = 255 u32 mcs_num_supp =
276 (priv->adapter->hw_dev_mcs_support == HT_STREAM_2X2) ? 16 : 8; 256 (priv->adapter->user_dev_mcs_support == HT_STREAM_2X2) ? 16 : 8;
277 u32 rate; 257 u32 rate;
278 258
279 if (priv->adapter->is_hw_11ac_capable) 259 if (priv->adapter->is_hw_11ac_capable)
@@ -458,7 +438,6 @@ u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates)
458 break; 438 break;
459 case BAND_G: 439 case BAND_G:
460 case BAND_G | BAND_GN: 440 case BAND_G | BAND_GN:
461 case BAND_G | BAND_GN | BAND_GAC:
462 dev_dbg(adapter->dev, "info: infra band=%d " 441 dev_dbg(adapter->dev, "info: infra band=%d "
463 "supported_rates_g\n", adapter->config_bands); 442 "supported_rates_g\n", adapter->config_bands);
464 k = mwifiex_copy_rates(rates, k, supported_rates_g, 443 k = mwifiex_copy_rates(rates, k, supported_rates_g,
@@ -469,10 +448,7 @@ u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates)
469 case BAND_A | BAND_B: 448 case BAND_A | BAND_B:
470 case BAND_A | BAND_B | BAND_G | BAND_GN | BAND_AN: 449 case BAND_A | BAND_B | BAND_G | BAND_GN | BAND_AN:
471 case BAND_A | BAND_B | BAND_G | BAND_GN | BAND_AN | BAND_AAC: 450 case BAND_A | BAND_B | BAND_G | BAND_GN | BAND_AN | BAND_AAC:
472 case BAND_A | BAND_B | BAND_G | BAND_GN | BAND_AN |
473 BAND_AAC | BAND_GAC:
474 case BAND_B | BAND_G | BAND_GN: 451 case BAND_B | BAND_G | BAND_GN:
475 case BAND_B | BAND_G | BAND_GN | BAND_GAC:
476 dev_dbg(adapter->dev, "info: infra band=%d " 452 dev_dbg(adapter->dev, "info: infra band=%d "
477 "supported_rates_bg\n", adapter->config_bands); 453 "supported_rates_bg\n", adapter->config_bands);
478 k = mwifiex_copy_rates(rates, k, supported_rates_bg, 454 k = mwifiex_copy_rates(rates, k, supported_rates_bg,
@@ -496,7 +472,6 @@ u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates)
496 sizeof(supported_rates_a)); 472 sizeof(supported_rates_a));
497 break; 473 break;
498 case BAND_GN: 474 case BAND_GN:
499 case BAND_GN | BAND_GAC:
500 dev_dbg(adapter->dev, "info: infra band=%d " 475 dev_dbg(adapter->dev, "info: infra band=%d "
501 "supported_rates_n\n", adapter->config_bands); 476 "supported_rates_n\n", adapter->config_bands);
502 k = mwifiex_copy_rates(rates, k, supported_rates_n, 477 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 1ddc8b2e3722..b41155829220 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -37,13 +37,12 @@
37static void 37static void
38mwifiex_init_cmd_node(struct mwifiex_private *priv, 38mwifiex_init_cmd_node(struct mwifiex_private *priv,
39 struct cmd_ctrl_node *cmd_node, 39 struct cmd_ctrl_node *cmd_node,
40 u32 cmd_oid, void *data_buf) 40 u32 cmd_oid, void *data_buf, bool sync)
41{ 41{
42 cmd_node->priv = priv; 42 cmd_node->priv = priv;
43 cmd_node->cmd_oid = cmd_oid; 43 cmd_node->cmd_oid = cmd_oid;
44 if (priv->adapter->cmd_wait_q_required) { 44 if (sync) {
45 cmd_node->wait_q_enabled = priv->adapter->cmd_wait_q_required; 45 cmd_node->wait_q_enabled = true;
46 priv->adapter->cmd_wait_q_required = false;
47 cmd_node->cmd_wait_q_woken = false; 46 cmd_node->cmd_wait_q_woken = false;
48 cmd_node->condition = &cmd_node->cmd_wait_q_woken; 47 cmd_node->condition = &cmd_node->cmd_wait_q_woken;
49 } 48 }
@@ -166,8 +165,10 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
166 dev_err(adapter->dev, 165 dev_err(adapter->dev,
167 "DNLD_CMD: FW in reset state, ignore cmd %#x\n", 166 "DNLD_CMD: FW in reset state, ignore cmd %#x\n",
168 cmd_code); 167 cmd_code);
169 mwifiex_complete_cmd(adapter, cmd_node); 168 if (cmd_node->wait_q_enabled)
169 mwifiex_complete_cmd(adapter, cmd_node);
170 mwifiex_recycle_cmd_node(adapter, cmd_node); 170 mwifiex_recycle_cmd_node(adapter, cmd_node);
171 queue_work(adapter->workqueue, &adapter->main_work);
171 return -1; 172 return -1;
172 } 173 }
173 174
@@ -480,28 +481,7 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter)
480} 481}
481 482
482/* 483/*
483 * This function is used to send synchronous command to the firmware. 484 * This function prepares a command and send it to the firmware.
484 *
485 * it allocates a wait queue for the command and wait for the command
486 * response.
487 */
488int mwifiex_send_cmd_sync(struct mwifiex_private *priv, uint16_t cmd_no,
489 u16 cmd_action, u32 cmd_oid, void *data_buf)
490{
491 int ret = 0;
492 struct mwifiex_adapter *adapter = priv->adapter;
493
494 adapter->cmd_wait_q_required = true;
495
496 ret = mwifiex_send_cmd_async(priv, cmd_no, cmd_action, cmd_oid,
497 data_buf);
498
499 return ret;
500}
501
502
503/*
504 * This function prepares a command and asynchronously send it to the firmware.
505 * 485 *
506 * Preparation includes - 486 * Preparation includes -
507 * - Sanity tests to make sure the card is still present or the FW 487 * - Sanity tests to make sure the card is still present or the FW
@@ -511,8 +491,8 @@ int mwifiex_send_cmd_sync(struct mwifiex_private *priv, uint16_t cmd_no,
511 * - Fill up the non-default parameters and buffer pointers 491 * - Fill up the non-default parameters and buffer pointers
512 * - Add the command to pending queue 492 * - Add the command to pending queue
513 */ 493 */
514int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no, 494int mwifiex_send_cmd(struct mwifiex_private *priv, u16 cmd_no,
515 u16 cmd_action, u32 cmd_oid, void *data_buf) 495 u16 cmd_action, u32 cmd_oid, void *data_buf, bool sync)
516{ 496{
517 int ret; 497 int ret;
518 struct mwifiex_adapter *adapter = priv->adapter; 498 struct mwifiex_adapter *adapter = priv->adapter;
@@ -534,6 +514,11 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no,
534 return -1; 514 return -1;
535 } 515 }
536 516
517 if (adapter->is_cmd_timedout) {
518 dev_err(adapter->dev, "PREP_CMD: FW is in bad state\n");
519 return -1;
520 }
521
537 if (adapter->hw_status == MWIFIEX_HW_STATUS_RESET) { 522 if (adapter->hw_status == MWIFIEX_HW_STATUS_RESET) {
538 if (cmd_no != HostCmd_CMD_FUNC_INIT) { 523 if (cmd_no != HostCmd_CMD_FUNC_INIT) {
539 dev_err(adapter->dev, "PREP_CMD: FW in reset state\n"); 524 dev_err(adapter->dev, "PREP_CMD: FW in reset state\n");
@@ -550,7 +535,7 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no,
550 } 535 }
551 536
552 /* Initialize the command node */ 537 /* Initialize the command node */
553 mwifiex_init_cmd_node(priv, cmd_node, cmd_oid, data_buf); 538 mwifiex_init_cmd_node(priv, cmd_node, cmd_oid, data_buf, sync);
554 539
555 if (!cmd_node->cmd_skb) { 540 if (!cmd_node->cmd_skb) {
556 dev_err(adapter->dev, "PREP_CMD: no free cmd buf\n"); 541 dev_err(adapter->dev, "PREP_CMD: no free cmd buf\n");
@@ -595,7 +580,8 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no,
595 } 580 }
596 581
597 /* Send command */ 582 /* Send command */
598 if (cmd_no == HostCmd_CMD_802_11_SCAN) { 583 if (cmd_no == HostCmd_CMD_802_11_SCAN ||
584 cmd_no == HostCmd_CMD_802_11_SCAN_EXT) {
599 mwifiex_queue_scan_cmd(priv, cmd_node); 585 mwifiex_queue_scan_cmd(priv, cmd_node);
600 } else { 586 } else {
601 mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true); 587 mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true);
@@ -785,7 +771,7 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
785 unsigned long flags; 771 unsigned long flags;
786 772
787 /* Now we got response from FW, cancel the command timer */ 773 /* Now we got response from FW, cancel the command timer */
788 del_timer(&adapter->cmd_timer); 774 del_timer_sync(&adapter->cmd_timer);
789 775
790 if (!adapter->curr_cmd || !adapter->curr_cmd->resp_skb) { 776 if (!adapter->curr_cmd || !adapter->curr_cmd->resp_skb) {
791 resp = (struct host_cmd_ds_command *) adapter->upld_buf; 777 resp = (struct host_cmd_ds_command *) adapter->upld_buf;
@@ -794,7 +780,7 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
794 return -1; 780 return -1;
795 } 781 }
796 782
797 adapter->num_cmd_timeout = 0; 783 adapter->is_cmd_timedout = 0;
798 784
799 resp = (struct host_cmd_ds_command *) adapter->curr_cmd->resp_skb->data; 785 resp = (struct host_cmd_ds_command *) adapter->curr_cmd->resp_skb->data;
800 if (adapter->curr_cmd->cmd_flag & CMD_F_CANCELED) { 786 if (adapter->curr_cmd->cmd_flag & CMD_F_CANCELED) {
@@ -905,8 +891,7 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
905 struct cmd_ctrl_node *cmd_node; 891 struct cmd_ctrl_node *cmd_node;
906 struct timeval tstamp; 892 struct timeval tstamp;
907 893
908 adapter->num_cmd_timeout++; 894 adapter->is_cmd_timedout = 1;
909 adapter->dbg.num_cmd_timeout++;
910 if (!adapter->curr_cmd) { 895 if (!adapter->curr_cmd) {
911 dev_dbg(adapter->dev, "cmd: empty curr_cmd\n"); 896 dev_dbg(adapter->dev, "cmd: empty curr_cmd\n");
912 return; 897 return;
@@ -929,8 +914,8 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
929 dev_err(adapter->dev, "num_cmd_h2c_failure = %d\n", 914 dev_err(adapter->dev, "num_cmd_h2c_failure = %d\n",
930 adapter->dbg.num_cmd_host_to_card_failure); 915 adapter->dbg.num_cmd_host_to_card_failure);
931 916
932 dev_err(adapter->dev, "num_cmd_timeout = %d\n", 917 dev_err(adapter->dev, "is_cmd_timedout = %d\n",
933 adapter->dbg.num_cmd_timeout); 918 adapter->is_cmd_timedout);
934 dev_err(adapter->dev, "num_tx_timeout = %d\n", 919 dev_err(adapter->dev, "num_tx_timeout = %d\n",
935 adapter->dbg.num_tx_timeout); 920 adapter->dbg.num_tx_timeout);
936 921
@@ -987,7 +972,9 @@ void
987mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter) 972mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
988{ 973{
989 struct cmd_ctrl_node *cmd_node = NULL, *tmp_node; 974 struct cmd_ctrl_node *cmd_node = NULL, *tmp_node;
990 unsigned long flags; 975 unsigned long flags, cmd_flags;
976 struct mwifiex_private *priv;
977 int i;
991 978
992 /* Cancel current cmd */ 979 /* Cancel current cmd */
993 if ((adapter->curr_cmd) && (adapter->curr_cmd->wait_q_enabled)) { 980 if ((adapter->curr_cmd) && (adapter->curr_cmd->wait_q_enabled)) {
@@ -1027,9 +1014,21 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
1027 } 1014 }
1028 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); 1015 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
1029 1016
1030 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); 1017 if (adapter->scan_processing) {
1031 adapter->scan_processing = false; 1018 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
1032 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); 1019 adapter->scan_processing = false;
1020 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
1021 for (i = 0; i < adapter->priv_num; i++) {
1022 priv = adapter->priv[i];
1023 if (!priv)
1024 continue;
1025 if (priv->scan_request) {
1026 dev_dbg(adapter->dev, "info: aborting scan\n");
1027 cfg80211_scan_done(priv->scan_request, 1);
1028 priv->scan_request = NULL;
1029 }
1030 }
1031 }
1033} 1032}
1034 1033
1035/* 1034/*
@@ -1048,7 +1047,8 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter)
1048 struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL; 1047 struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL;
1049 unsigned long cmd_flags; 1048 unsigned long cmd_flags;
1050 unsigned long scan_pending_q_flags; 1049 unsigned long scan_pending_q_flags;
1051 bool cancel_scan_cmd = false; 1050 struct mwifiex_private *priv;
1051 int i;
1052 1052
1053 if ((adapter->curr_cmd) && 1053 if ((adapter->curr_cmd) &&
1054 (adapter->curr_cmd->wait_q_enabled)) { 1054 (adapter->curr_cmd->wait_q_enabled)) {
@@ -1074,15 +1074,24 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter)
1074 mwifiex_insert_cmd_to_free_q(adapter, cmd_node); 1074 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
1075 spin_lock_irqsave(&adapter->scan_pending_q_lock, 1075 spin_lock_irqsave(&adapter->scan_pending_q_lock,
1076 scan_pending_q_flags); 1076 scan_pending_q_flags);
1077 cancel_scan_cmd = true;
1078 } 1077 }
1079 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, 1078 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1080 scan_pending_q_flags); 1079 scan_pending_q_flags);
1081 1080
1082 if (cancel_scan_cmd) { 1081 if (adapter->scan_processing) {
1083 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags); 1082 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
1084 adapter->scan_processing = false; 1083 adapter->scan_processing = false;
1085 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); 1084 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
1085 for (i = 0; i < adapter->priv_num; i++) {
1086 priv = adapter->priv[i];
1087 if (!priv)
1088 continue;
1089 if (priv->scan_request) {
1090 dev_dbg(adapter->dev, "info: aborting scan\n");
1091 cfg80211_scan_done(priv->scan_request, 1);
1092 priv->scan_request = NULL;
1093 }
1094 }
1086 } 1095 }
1087 adapter->cmd_wait_q.status = -1; 1096 adapter->cmd_wait_q.status = -1;
1088} 1097}
@@ -1454,7 +1463,10 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
1454{ 1463{
1455 struct host_cmd_ds_get_hw_spec *hw_spec = &resp->params.hw_spec; 1464 struct host_cmd_ds_get_hw_spec *hw_spec = &resp->params.hw_spec;
1456 struct mwifiex_adapter *adapter = priv->adapter; 1465 struct mwifiex_adapter *adapter = priv->adapter;
1457 int i; 1466 struct mwifiex_ie_types_header *tlv;
1467 struct hw_spec_fw_api_rev *api_rev;
1468 u16 resp_size, api_id;
1469 int i, left_len, parsed_len = 0;
1458 1470
1459 adapter->fw_cap_info = le32_to_cpu(hw_spec->fw_cap_info); 1471 adapter->fw_cap_info = le32_to_cpu(hw_spec->fw_cap_info);
1460 1472
@@ -1490,6 +1502,7 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
1490 } 1502 }
1491 1503
1492 adapter->fw_release_number = le32_to_cpu(hw_spec->fw_release_number); 1504 adapter->fw_release_number = le32_to_cpu(hw_spec->fw_release_number);
1505 adapter->fw_api_ver = (adapter->fw_release_number >> 16) & 0xff;
1493 adapter->number_of_antenna = le16_to_cpu(hw_spec->number_of_antenna); 1506 adapter->number_of_antenna = le16_to_cpu(hw_spec->number_of_antenna);
1494 1507
1495 if (le32_to_cpu(hw_spec->dot_11ac_dev_cap)) { 1508 if (le32_to_cpu(hw_spec->dot_11ac_dev_cap)) {
@@ -1498,8 +1511,10 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
1498 /* Copy 11AC cap */ 1511 /* Copy 11AC cap */
1499 adapter->hw_dot_11ac_dev_cap = 1512 adapter->hw_dot_11ac_dev_cap =
1500 le32_to_cpu(hw_spec->dot_11ac_dev_cap); 1513 le32_to_cpu(hw_spec->dot_11ac_dev_cap);
1501 adapter->usr_dot_11ac_dev_cap_bg = adapter->hw_dot_11ac_dev_cap; 1514 adapter->usr_dot_11ac_dev_cap_bg = adapter->hw_dot_11ac_dev_cap
1502 adapter->usr_dot_11ac_dev_cap_a = adapter->hw_dot_11ac_dev_cap; 1515 & ~MWIFIEX_DEF_11AC_CAP_BF_RESET_MASK;
1516 adapter->usr_dot_11ac_dev_cap_a = adapter->hw_dot_11ac_dev_cap
1517 & ~MWIFIEX_DEF_11AC_CAP_BF_RESET_MASK;
1503 1518
1504 /* Copy 11AC mcs */ 1519 /* Copy 11AC mcs */
1505 adapter->hw_dot_11ac_mcs_support = 1520 adapter->hw_dot_11ac_mcs_support =
@@ -1510,6 +1525,46 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
1510 adapter->is_hw_11ac_capable = false; 1525 adapter->is_hw_11ac_capable = false;
1511 } 1526 }
1512 1527
1528 resp_size = le16_to_cpu(resp->size) - S_DS_GEN;
1529 if (resp_size > sizeof(struct host_cmd_ds_get_hw_spec)) {
1530 /* we have variable HW SPEC information */
1531 left_len = resp_size - sizeof(struct host_cmd_ds_get_hw_spec);
1532 while (left_len > sizeof(struct mwifiex_ie_types_header)) {
1533 tlv = (void *)&hw_spec->tlvs + parsed_len;
1534 switch (le16_to_cpu(tlv->type)) {
1535 case TLV_TYPE_FW_API_REV:
1536 api_rev = (struct hw_spec_fw_api_rev *)tlv;
1537 api_id = le16_to_cpu(api_rev->api_id);
1538 switch (api_id) {
1539 case KEY_API_VER_ID:
1540 adapter->fw_key_api_major_ver =
1541 api_rev->major_ver;
1542 adapter->fw_key_api_minor_ver =
1543 api_rev->minor_ver;
1544 dev_dbg(adapter->dev,
1545 "fw_key_api v%d.%d\n",
1546 adapter->fw_key_api_major_ver,
1547 adapter->fw_key_api_minor_ver);
1548 break;
1549 default:
1550 dev_warn(adapter->dev,
1551 "Unknown FW api_id: %d\n",
1552 api_id);
1553 break;
1554 }
1555 break;
1556 default:
1557 dev_warn(adapter->dev,
1558 "Unknown GET_HW_SPEC TLV type: %#x\n",
1559 le16_to_cpu(tlv->type));
1560 break;
1561 }
1562 parsed_len += le16_to_cpu(tlv->len) +
1563 sizeof(struct mwifiex_ie_types_header);
1564 left_len -= parsed_len;
1565 }
1566 }
1567
1513 dev_dbg(adapter->dev, "info: GET_HW_SPEC: fw_release_number- %#x\n", 1568 dev_dbg(adapter->dev, "info: GET_HW_SPEC: fw_release_number- %#x\n",
1514 adapter->fw_release_number); 1569 adapter->fw_release_number);
1515 dev_dbg(adapter->dev, "info: GET_HW_SPEC: permanent addr: %pM\n", 1570 dev_dbg(adapter->dev, "info: GET_HW_SPEC: permanent addr: %pM\n",
@@ -1538,6 +1593,7 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
1538 1593
1539 adapter->hw_dot_11n_dev_cap = le32_to_cpu(hw_spec->dot_11n_dev_cap); 1594 adapter->hw_dot_11n_dev_cap = le32_to_cpu(hw_spec->dot_11n_dev_cap);
1540 adapter->hw_dev_mcs_support = hw_spec->dev_mcs_support; 1595 adapter->hw_dev_mcs_support = hw_spec->dev_mcs_support;
1596 adapter->user_dev_mcs_support = adapter->hw_dev_mcs_support;
1541 1597
1542 if (adapter->if_ops.update_mp_end_port) 1598 if (adapter->if_ops.update_mp_end_port)
1543 adapter->if_ops.update_mp_end_port(adapter, 1599 adapter->if_ops.update_mp_end_port(adapter,
diff --git a/drivers/net/wireless/mwifiex/debugfs.c b/drivers/net/wireless/mwifiex/debugfs.c
index a5f9875cfd6e..b8a49aad12fd 100644
--- a/drivers/net/wireless/mwifiex/debugfs.c
+++ b/drivers/net/wireless/mwifiex/debugfs.c
@@ -85,8 +85,8 @@ static struct mwifiex_debug_data items[] = {
85 item_addr(hs_activated), 1}, 85 item_addr(hs_activated), 1},
86 {"num_tx_timeout", item_size(num_tx_timeout), 86 {"num_tx_timeout", item_size(num_tx_timeout),
87 item_addr(num_tx_timeout), 1}, 87 item_addr(num_tx_timeout), 1},
88 {"num_cmd_timeout", item_size(num_cmd_timeout), 88 {"is_cmd_timedout", item_size(is_cmd_timedout),
89 item_addr(num_cmd_timeout), 1}, 89 item_addr(is_cmd_timedout), 1},
90 {"timeout_cmd_id", item_size(timeout_cmd_id), 90 {"timeout_cmd_id", item_size(timeout_cmd_id),
91 item_addr(timeout_cmd_id), 1}, 91 item_addr(timeout_cmd_id), 1},
92 {"timeout_cmd_act", item_size(timeout_cmd_act), 92 {"timeout_cmd_act", item_size(timeout_cmd_act),
@@ -493,7 +493,7 @@ mwifiex_regrdwr_write(struct file *file,
493{ 493{
494 unsigned long addr = get_zeroed_page(GFP_KERNEL); 494 unsigned long addr = get_zeroed_page(GFP_KERNEL);
495 char *buf = (char *) addr; 495 char *buf = (char *) addr;
496 size_t buf_size = min(count, (size_t) (PAGE_SIZE - 1)); 496 size_t buf_size = min_t(size_t, count, PAGE_SIZE - 1);
497 int ret; 497 int ret;
498 u32 reg_type = 0, reg_offset = 0, reg_value = UINT_MAX; 498 u32 reg_type = 0, reg_offset = 0, reg_value = UINT_MAX;
499 499
@@ -594,7 +594,7 @@ mwifiex_rdeeprom_write(struct file *file,
594{ 594{
595 unsigned long addr = get_zeroed_page(GFP_KERNEL); 595 unsigned long addr = get_zeroed_page(GFP_KERNEL);
596 char *buf = (char *) addr; 596 char *buf = (char *) addr;
597 size_t buf_size = min(count, (size_t) (PAGE_SIZE - 1)); 597 size_t buf_size = min_t(size_t, count, PAGE_SIZE - 1);
598 int ret = 0; 598 int ret = 0;
599 int offset = -1, bytes = -1; 599 int offset = -1, bytes = -1;
600 600
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index 3a21bd03d6db..e7b3e16e5d34 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -75,10 +75,16 @@
75 75
76#define MWIFIEX_BUF_FLAG_REQUEUED_PKT BIT(0) 76#define MWIFIEX_BUF_FLAG_REQUEUED_PKT BIT(0)
77#define MWIFIEX_BUF_FLAG_BRIDGED_PKT BIT(1) 77#define MWIFIEX_BUF_FLAG_BRIDGED_PKT BIT(1)
78#define MWIFIEX_BUF_FLAG_TDLS_PKT BIT(2)
78 79
79#define MWIFIEX_BRIDGED_PKTS_THR_HIGH 1024 80#define MWIFIEX_BRIDGED_PKTS_THR_HIGH 1024
80#define MWIFIEX_BRIDGED_PKTS_THR_LOW 128 81#define MWIFIEX_BRIDGED_PKTS_THR_LOW 128
81 82
83#define MWIFIEX_TDLS_DISABLE_LINK 0x00
84#define MWIFIEX_TDLS_ENABLE_LINK 0x01
85#define MWIFIEX_TDLS_CREATE_LINK 0x02
86#define MWIFIEX_TDLS_CONFIG_LINK 0x03
87
82enum mwifiex_bss_type { 88enum mwifiex_bss_type {
83 MWIFIEX_BSS_TYPE_STA = 0, 89 MWIFIEX_BSS_TYPE_STA = 0,
84 MWIFIEX_BSS_TYPE_UAP = 1, 90 MWIFIEX_BSS_TYPE_UAP = 1,
@@ -92,6 +98,23 @@ enum mwifiex_bss_role {
92 MWIFIEX_BSS_ROLE_ANY = 0xff, 98 MWIFIEX_BSS_ROLE_ANY = 0xff,
93}; 99};
94 100
101enum mwifiex_tdls_status {
102 TDLS_NOT_SETUP = 0,
103 TDLS_SETUP_INPROGRESS,
104 TDLS_SETUP_COMPLETE,
105 TDLS_SETUP_FAILURE,
106 TDLS_LINK_TEARDOWN,
107};
108
109enum mwifiex_tdls_error_code {
110 TDLS_ERR_NO_ERROR = 0,
111 TDLS_ERR_INTERNAL_ERROR,
112 TDLS_ERR_MAX_LINKS_EST,
113 TDLS_ERR_LINK_EXISTS,
114 TDLS_ERR_LINK_NONEXISTENT,
115 TDLS_ERR_PEER_STA_UNREACHABLE = 25,
116};
117
95#define BSS_ROLE_BIT_MASK BIT(0) 118#define BSS_ROLE_BIT_MASK BIT(0)
96 119
97#define GET_BSS_ROLE(priv) ((priv)->bss_role & BSS_ROLE_BIT_MASK) 120#define GET_BSS_ROLE(priv) ((priv)->bss_role & BSS_ROLE_BIT_MASK)
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index 5fa932d5f905..b485dc1ae5eb 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -50,21 +50,23 @@ struct tx_packet_hdr {
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 BAND_AN | BAND_AAC)
54 54
55#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)) 56 BIT(13))
57#define IS_SUPPORT_MULTI_BANDS(adapter) \ 57#define IS_SUPPORT_MULTI_BANDS(adapter) \
58 (adapter->fw_cap_info & FW_MULTI_BANDS_SUPPORT) 58 (adapter->fw_cap_info & FW_MULTI_BANDS_SUPPORT)
59 59
60/* shift bit 12 and bit 13 in fw_cap_info from the firmware to bit 13 and 14 60/* bit 13: 11ac BAND_AAC
61 * for 11ac so that bit 11 is for GN, bit 12 for AN, bit 13 for GAC, and bit 61 * bit 12: reserved for lab testing, will be reused for BAND_AN
62 * bit 14 for AAC, in order to be compatible with the band capability 62 * bit 11: 11n BAND_GN
63 * defined in the driver after right shift of 8 bits. 63 * bit 10: 11a BAND_A
64 * bit 9: 11g BAND_G
65 * bit 8: 11b BAND_B
66 * Map these bits to band capability by right shifting 8 bits.
64 */ 67 */
65#define GET_FW_DEFAULT_BANDS(adapter) \ 68#define GET_FW_DEFAULT_BANDS(adapter) \
66 (((((adapter->fw_cap_info & 0x3000) << 1) | \ 69 (((adapter->fw_cap_info & 0x2f00) >> 8) & \
67 (adapter->fw_cap_info & ~0xF000)) >> 8) & \
68 ALL_802_11_BANDS) 70 ALL_802_11_BANDS)
69 71
70#define HostCmd_WEP_KEY_INDEX_MASK 0x3fff 72#define HostCmd_WEP_KEY_INDEX_MASK 0x3fff
@@ -77,12 +79,21 @@ enum KEY_TYPE_ID {
77 KEY_TYPE_ID_WAPI, 79 KEY_TYPE_ID_WAPI,
78 KEY_TYPE_ID_AES_CMAC, 80 KEY_TYPE_ID_AES_CMAC,
79}; 81};
82
83#define WPA_PN_SIZE 8
84#define KEY_PARAMS_FIXED_LEN 10
85#define KEY_INDEX_MASK 0xf
86#define FW_KEY_API_VER_MAJOR_V2 2
87
80#define KEY_MCAST BIT(0) 88#define KEY_MCAST BIT(0)
81#define KEY_UNICAST BIT(1) 89#define KEY_UNICAST BIT(1)
82#define KEY_ENABLED BIT(2) 90#define KEY_ENABLED BIT(2)
91#define KEY_DEFAULT BIT(3)
92#define KEY_TX_KEY BIT(4)
93#define KEY_RX_KEY BIT(5)
83#define KEY_IGTK BIT(10) 94#define KEY_IGTK BIT(10)
84 95
85#define WAPI_KEY_LEN 50 96#define WAPI_KEY_LEN (WLAN_KEY_LEN_SMS4 + PN_LEN + 2)
86 97
87#define MAX_POLL_TRIES 100 98#define MAX_POLL_TRIES 100
88#define MAX_FIRMWARE_POLL_TRIES 100 99#define MAX_FIRMWARE_POLL_TRIES 100
@@ -130,6 +141,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
130#define TLV_TYPE_RSSI_HIGH (PROPRIETARY_TLV_BASE_ID + 22) 141#define TLV_TYPE_RSSI_HIGH (PROPRIETARY_TLV_BASE_ID + 22)
131#define TLV_TYPE_AUTH_TYPE (PROPRIETARY_TLV_BASE_ID + 31) 142#define TLV_TYPE_AUTH_TYPE (PROPRIETARY_TLV_BASE_ID + 31)
132#define TLV_TYPE_STA_MAC_ADDR (PROPRIETARY_TLV_BASE_ID + 32) 143#define TLV_TYPE_STA_MAC_ADDR (PROPRIETARY_TLV_BASE_ID + 32)
144#define TLV_TYPE_BSSID (PROPRIETARY_TLV_BASE_ID + 35)
133#define TLV_TYPE_CHANNELBANDLIST (PROPRIETARY_TLV_BASE_ID + 42) 145#define TLV_TYPE_CHANNELBANDLIST (PROPRIETARY_TLV_BASE_ID + 42)
134#define TLV_TYPE_UAP_BEACON_PERIOD (PROPRIETARY_TLV_BASE_ID + 44) 146#define TLV_TYPE_UAP_BEACON_PERIOD (PROPRIETARY_TLV_BASE_ID + 44)
135#define TLV_TYPE_UAP_DTIM_PERIOD (PROPRIETARY_TLV_BASE_ID + 45) 147#define TLV_TYPE_UAP_DTIM_PERIOD (PROPRIETARY_TLV_BASE_ID + 45)
@@ -144,6 +156,8 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
144#define TLV_TYPE_RATE_DROP_CONTROL (PROPRIETARY_TLV_BASE_ID + 82) 156#define TLV_TYPE_RATE_DROP_CONTROL (PROPRIETARY_TLV_BASE_ID + 82)
145#define TLV_TYPE_RATE_SCOPE (PROPRIETARY_TLV_BASE_ID + 83) 157#define TLV_TYPE_RATE_SCOPE (PROPRIETARY_TLV_BASE_ID + 83)
146#define TLV_TYPE_POWER_GROUP (PROPRIETARY_TLV_BASE_ID + 84) 158#define TLV_TYPE_POWER_GROUP (PROPRIETARY_TLV_BASE_ID + 84)
159#define TLV_TYPE_BSS_SCAN_RSP (PROPRIETARY_TLV_BASE_ID + 86)
160#define TLV_TYPE_BSS_SCAN_INFO (PROPRIETARY_TLV_BASE_ID + 87)
147#define TLV_TYPE_UAP_RETRY_LIMIT (PROPRIETARY_TLV_BASE_ID + 93) 161#define TLV_TYPE_UAP_RETRY_LIMIT (PROPRIETARY_TLV_BASE_ID + 93)
148#define TLV_TYPE_WAPI_IE (PROPRIETARY_TLV_BASE_ID + 94) 162#define TLV_TYPE_WAPI_IE (PROPRIETARY_TLV_BASE_ID + 94)
149#define TLV_TYPE_UAP_MGMT_FRAME (PROPRIETARY_TLV_BASE_ID + 104) 163#define TLV_TYPE_UAP_MGMT_FRAME (PROPRIETARY_TLV_BASE_ID + 104)
@@ -154,6 +168,8 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
154#define TLV_TYPE_PWK_CIPHER (PROPRIETARY_TLV_BASE_ID + 145) 168#define TLV_TYPE_PWK_CIPHER (PROPRIETARY_TLV_BASE_ID + 145)
155#define TLV_TYPE_GWK_CIPHER (PROPRIETARY_TLV_BASE_ID + 146) 169#define TLV_TYPE_GWK_CIPHER (PROPRIETARY_TLV_BASE_ID + 146)
156#define TLV_TYPE_COALESCE_RULE (PROPRIETARY_TLV_BASE_ID + 154) 170#define TLV_TYPE_COALESCE_RULE (PROPRIETARY_TLV_BASE_ID + 154)
171#define TLV_TYPE_KEY_PARAM_V2 (PROPRIETARY_TLV_BASE_ID + 156)
172#define TLV_TYPE_FW_API_REV (PROPRIETARY_TLV_BASE_ID + 199)
157 173
158#define MWIFIEX_TX_DATA_BUF_SIZE_2K 2048 174#define MWIFIEX_TX_DATA_BUF_SIZE_2K 2048
159 175
@@ -176,13 +192,21 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
176#define MWIFIEX_TX_DATA_BUF_SIZE_8K 8192 192#define MWIFIEX_TX_DATA_BUF_SIZE_8K 8192
177 193
178#define ISSUPP_11NENABLED(FwCapInfo) (FwCapInfo & BIT(11)) 194#define ISSUPP_11NENABLED(FwCapInfo) (FwCapInfo & BIT(11))
195#define ISSUPP_TDLS_ENABLED(FwCapInfo) (FwCapInfo & BIT(14))
179 196
180#define MWIFIEX_DEF_HT_CAP (IEEE80211_HT_CAP_DSSSCCK40 | \ 197#define MWIFIEX_DEF_HT_CAP (IEEE80211_HT_CAP_DSSSCCK40 | \
181 (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT) | \ 198 (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT) | \
182 IEEE80211_HT_CAP_SM_PS) 199 IEEE80211_HT_CAP_SM_PS)
183 200
201#define MWIFIEX_DEF_11N_TX_BF_CAP 0x09E1E008
202
184#define MWIFIEX_DEF_AMPDU IEEE80211_HT_AMPDU_PARM_FACTOR 203#define MWIFIEX_DEF_AMPDU IEEE80211_HT_AMPDU_PARM_FACTOR
185 204
205#define GET_RXSTBC(x) (x & IEEE80211_HT_CAP_RX_STBC)
206#define MWIFIEX_RX_STBC1 0x0100
207#define MWIFIEX_RX_STBC12 0x0200
208#define MWIFIEX_RX_STBC123 0x0300
209
186/* dev_cap bitmap 210/* dev_cap bitmap
187 * BIT 211 * BIT
188 * 0-16 reserved 212 * 0-16 reserved
@@ -204,6 +228,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
204#define ISSUPP_GREENFIELD(Dot11nDevCap) (Dot11nDevCap & BIT(29)) 228#define ISSUPP_GREENFIELD(Dot11nDevCap) (Dot11nDevCap & BIT(29))
205#define ISENABLED_40MHZ_INTOLERANT(Dot11nDevCap) (Dot11nDevCap & BIT(8)) 229#define ISENABLED_40MHZ_INTOLERANT(Dot11nDevCap) (Dot11nDevCap & BIT(8))
206#define ISSUPP_RXLDPC(Dot11nDevCap) (Dot11nDevCap & BIT(22)) 230#define ISSUPP_RXLDPC(Dot11nDevCap) (Dot11nDevCap & BIT(22))
231#define ISSUPP_BEAMFORMING(Dot11nDevCap) (Dot11nDevCap & BIT(30))
207 232
208/* httxcfg bitmap 233/* httxcfg bitmap
209 * 0 reserved 234 * 0 reserved
@@ -216,8 +241,21 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
216 */ 241 */
217#define MWIFIEX_FW_DEF_HTTXCFG (BIT(1) | BIT(4) | BIT(5) | BIT(6)) 242#define MWIFIEX_FW_DEF_HTTXCFG (BIT(1) | BIT(4) | BIT(5) | BIT(6))
218 243
244/* 11AC Tx and Rx MCS map for 1x1 mode:
245 * IEEE80211_VHT_MCS_SUPPORT_0_9 for stream 1
246 * IEEE80211_VHT_MCS_NOT_SUPPORTED for remaining 7 streams
247 */
248#define MWIFIEX_11AC_MCS_MAP_1X1 0xfffefffe
249
250/* 11AC Tx and Rx MCS map for 2x2 mode:
251 * IEEE80211_VHT_MCS_SUPPORT_0_9 for stream 1 and 2
252 * IEEE80211_VHT_MCS_NOT_SUPPORTED for remaining 6 streams
253 */
254#define MWIFIEX_11AC_MCS_MAP_2X2 0xfffafffa
255
219#define GET_RXMCSSUPP(DevMCSSupported) (DevMCSSupported & 0x0f) 256#define GET_RXMCSSUPP(DevMCSSupported) (DevMCSSupported & 0x0f)
220#define SETHT_MCS32(x) (x[4] |= 1) 257#define SETHT_MCS32(x) (x[4] |= 1)
258#define HT_STREAM_1X1 0x11
221#define HT_STREAM_2X2 0x22 259#define HT_STREAM_2X2 0x22
222 260
223#define SET_SECONDARYCHAN(RadioType, SECCHAN) (RadioType |= (SECCHAN << 4)) 261#define SET_SECONDARYCHAN(RadioType, SECCHAN) (RadioType |= (SECCHAN << 4))
@@ -226,17 +264,24 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
226 264
227/* HW_SPEC fw_cap_info */ 265/* HW_SPEC fw_cap_info */
228 266
229#define ISSUPP_11ACENABLED(fw_cap_info) (fw_cap_info & (BIT(12)|BIT(13))) 267#define ISSUPP_11ACENABLED(fw_cap_info) (fw_cap_info & BIT(13))
230 268
231#define GET_VHTCAP_CHWDSET(vht_cap_info) ((vht_cap_info >> 2) & 0x3) 269#define GET_VHTCAP_CHWDSET(vht_cap_info) ((vht_cap_info >> 2) & 0x3)
232#define GET_VHTNSSMCS(mcs_mapset, nss) ((mcs_mapset >> (2 * (nss - 1))) & 0x3) 270#define GET_VHTNSSMCS(mcs_mapset, nss) ((mcs_mapset >> (2 * (nss - 1))) & 0x3)
233#define SET_VHTNSSMCS(mcs_mapset, nss, value) (mcs_mapset |= (value & 0x3) << \ 271#define SET_VHTNSSMCS(mcs_mapset, nss, value) (mcs_mapset |= (value & 0x3) << \
234 (2 * (nss - 1))) 272 (2 * (nss - 1)))
235#define NO_NSS_SUPPORT 0x3
236
237#define GET_DEVTXMCSMAP(dev_mcs_map) (dev_mcs_map >> 16) 273#define GET_DEVTXMCSMAP(dev_mcs_map) (dev_mcs_map >> 16)
238#define GET_DEVRXMCSMAP(dev_mcs_map) (dev_mcs_map & 0xFFFF) 274#define GET_DEVRXMCSMAP(dev_mcs_map) (dev_mcs_map & 0xFFFF)
239 275
276/* Clear SU Beanformer, MU beanformer, MU beanformee and
277 * sounding dimensions bits
278 */
279#define MWIFIEX_DEF_11AC_CAP_BF_RESET_MASK \
280 (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE | \
281 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE | \
282 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE | \
283 IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK)
284
240#define MOD_CLASS_HR_DSSS 0x03 285#define MOD_CLASS_HR_DSSS 0x03
241#define MOD_CLASS_OFDM 0x07 286#define MOD_CLASS_OFDM 0x07
242#define MOD_CLASS_HT 0x08 287#define MOD_CLASS_HT 0x08
@@ -295,10 +340,12 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
295#define HostCmd_CMD_CAU_REG_ACCESS 0x00ed 340#define HostCmd_CMD_CAU_REG_ACCESS 0x00ed
296#define HostCmd_CMD_SET_BSS_MODE 0x00f7 341#define HostCmd_CMD_SET_BSS_MODE 0x00f7
297#define HostCmd_CMD_PCIE_DESC_DETAILS 0x00fa 342#define HostCmd_CMD_PCIE_DESC_DETAILS 0x00fa
343#define HostCmd_CMD_802_11_SCAN_EXT 0x0107
298#define HostCmd_CMD_COALESCE_CFG 0x010a 344#define HostCmd_CMD_COALESCE_CFG 0x010a
299#define HostCmd_CMD_MGMT_FRAME_REG 0x010c 345#define HostCmd_CMD_MGMT_FRAME_REG 0x010c
300#define HostCmd_CMD_REMAIN_ON_CHAN 0x010d 346#define HostCmd_CMD_REMAIN_ON_CHAN 0x010d
301#define HostCmd_CMD_11AC_CFG 0x0112 347#define HostCmd_CMD_11AC_CFG 0x0112
348#define HostCmd_CMD_TDLS_OPER 0x0122
302 349
303#define PROTOCOL_NO_SECURITY 0x01 350#define PROTOCOL_NO_SECURITY 0x01
304#define PROTOCOL_STATIC_WEP 0x02 351#define PROTOCOL_STATIC_WEP 0x02
@@ -440,6 +487,7 @@ enum P2P_MODES {
440#define EVENT_UAP_MIC_COUNTERMEASURES 0x0000004c 487#define EVENT_UAP_MIC_COUNTERMEASURES 0x0000004c
441#define EVENT_HOSTWAKE_STAIE 0x0000004d 488#define EVENT_HOSTWAKE_STAIE 0x0000004d
442#define EVENT_CHANNEL_SWITCH_ANN 0x00000050 489#define EVENT_CHANNEL_SWITCH_ANN 0x00000050
490#define EVENT_EXT_SCAN_REPORT 0x00000058
443#define EVENT_REMAIN_ON_CHAN_EXPIRED 0x0000005f 491#define EVENT_REMAIN_ON_CHAN_EXPIRED 0x0000005f
444 492
445#define EVENT_ID_MASK 0xffff 493#define EVENT_ID_MASK 0xffff
@@ -468,6 +516,12 @@ enum P2P_MODES {
468#define MWIFIEX_CRITERIA_UNICAST BIT(1) 516#define MWIFIEX_CRITERIA_UNICAST BIT(1)
469#define MWIFIEX_CRITERIA_MULTICAST BIT(3) 517#define MWIFIEX_CRITERIA_MULTICAST BIT(3)
470 518
519#define ACT_TDLS_DELETE 0x00
520#define ACT_TDLS_CREATE 0x01
521#define ACT_TDLS_CONFIG 0x02
522
523#define MWIFIEX_FW_V15 15
524
471struct mwifiex_ie_types_header { 525struct mwifiex_ie_types_header {
472 __le16 type; 526 __le16 type;
473 __le16 len; 527 __le16 len;
@@ -480,6 +534,7 @@ struct mwifiex_ie_types_data {
480 534
481#define MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET 0x01 535#define MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET 0x01
482#define MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET 0x08 536#define MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET 0x08
537#define MWIFIEX_TXPD_FLAGS_TDLS_PACKET 0x10
483 538
484struct txpd { 539struct txpd {
485 u8 bss_type; 540 u8 bss_type;
@@ -676,6 +731,56 @@ struct mwifiex_cmac_param {
676 u8 key[WLAN_KEY_LEN_AES_CMAC]; 731 u8 key[WLAN_KEY_LEN_AES_CMAC];
677} __packed; 732} __packed;
678 733
734struct mwifiex_wep_param {
735 __le16 key_len;
736 u8 key[WLAN_KEY_LEN_WEP104];
737} __packed;
738
739struct mwifiex_tkip_param {
740 u8 pn[WPA_PN_SIZE];
741 __le16 key_len;
742 u8 key[WLAN_KEY_LEN_TKIP];
743} __packed;
744
745struct mwifiex_aes_param {
746 u8 pn[WPA_PN_SIZE];
747 __le16 key_len;
748 u8 key[WLAN_KEY_LEN_CCMP];
749} __packed;
750
751struct mwifiex_wapi_param {
752 u8 pn[PN_LEN];
753 __le16 key_len;
754 u8 key[WLAN_KEY_LEN_SMS4];
755} __packed;
756
757struct mwifiex_cmac_aes_param {
758 u8 ipn[IGTK_PN_LEN];
759 __le16 key_len;
760 u8 key[WLAN_KEY_LEN_AES_CMAC];
761} __packed;
762
763struct mwifiex_ie_type_key_param_set_v2 {
764 __le16 type;
765 __le16 len;
766 u8 mac_addr[ETH_ALEN];
767 u8 key_idx;
768 u8 key_type;
769 __le16 key_info;
770 union {
771 struct mwifiex_wep_param wep;
772 struct mwifiex_tkip_param tkip;
773 struct mwifiex_aes_param aes;
774 struct mwifiex_wapi_param wapi;
775 struct mwifiex_cmac_aes_param cmac_aes;
776 } key_params;
777} __packed;
778
779struct host_cmd_ds_802_11_key_material_v2 {
780 __le16 action;
781 struct mwifiex_ie_type_key_param_set_v2 key_param_set;
782} __packed;
783
679struct host_cmd_ds_802_11_key_material { 784struct host_cmd_ds_802_11_key_material {
680 __le16 action; 785 __le16 action;
681 struct mwifiex_ie_type_key_param_set key_param_set; 786 struct mwifiex_ie_type_key_param_set key_param_set;
@@ -727,6 +832,17 @@ struct host_cmd_ds_802_11_ps_mode_enh {
727 } params; 832 } params;
728} __packed; 833} __packed;
729 834
835enum FW_API_VER_ID {
836 KEY_API_VER_ID = 1,
837};
838
839struct hw_spec_fw_api_rev {
840 struct mwifiex_ie_types_header header;
841 __le16 api_id;
842 u8 major_ver;
843 u8 minor_ver;
844} __packed;
845
730struct host_cmd_ds_get_hw_spec { 846struct host_cmd_ds_get_hw_spec {
731 __le16 hw_if_version; 847 __le16 hw_if_version;
732 __le16 version; 848 __le16 version;
@@ -748,6 +864,7 @@ struct host_cmd_ds_get_hw_spec {
748 __le32 reserved_6; 864 __le32 reserved_6;
749 __le32 dot_11ac_dev_cap; 865 __le32 dot_11ac_dev_cap;
750 __le32 dot_11ac_mcs_support; 866 __le32 dot_11ac_mcs_support;
867 u8 tlvs[0];
751} __packed; 868} __packed;
752 869
753struct host_cmd_ds_802_11_rssi_info { 870struct host_cmd_ds_802_11_rssi_info {
@@ -993,6 +1110,7 @@ struct mwifiex_rate_scope {
993 __le16 hr_dsss_rate_bitmap; 1110 __le16 hr_dsss_rate_bitmap;
994 __le16 ofdm_rate_bitmap; 1111 __le16 ofdm_rate_bitmap;
995 __le16 ht_mcs_rate_bitmap[8]; 1112 __le16 ht_mcs_rate_bitmap[8];
1113 __le16 vht_mcs_rate_bitmap[8];
996} __packed; 1114} __packed;
997 1115
998struct mwifiex_rate_drop_pattern { 1116struct mwifiex_rate_drop_pattern {
@@ -1047,14 +1165,28 @@ struct host_cmd_ds_rf_ant_siso {
1047 __le16 ant_mode; 1165 __le16 ant_mode;
1048}; 1166};
1049 1167
1050struct mwifiex_bcn_param { 1168struct host_cmd_ds_tdls_oper {
1051 u8 bssid[ETH_ALEN]; 1169 __le16 tdls_action;
1052 u8 rssi; 1170 __le16 reason;
1171 u8 peer_mac[ETH_ALEN];
1172} __packed;
1173
1174struct mwifiex_fixed_bcn_param {
1053 __le64 timestamp; 1175 __le64 timestamp;
1054 __le16 beacon_period; 1176 __le16 beacon_period;
1055 __le16 cap_info_bitmap; 1177 __le16 cap_info_bitmap;
1056} __packed; 1178} __packed;
1057 1179
1180struct mwifiex_event_scan_result {
1181 __le16 event_id;
1182 u8 bss_index;
1183 u8 bss_type;
1184 u8 more_event;
1185 u8 reserved[3];
1186 __le16 buf_size;
1187 u8 num_of_set;
1188} __packed;
1189
1058#define MWIFIEX_USER_SCAN_CHAN_MAX 50 1190#define MWIFIEX_USER_SCAN_CHAN_MAX 50
1059 1191
1060#define MWIFIEX_MAX_SSID_LIST_LENGTH 10 1192#define MWIFIEX_MAX_SSID_LIST_LENGTH 10
@@ -1124,6 +1256,28 @@ struct host_cmd_ds_802_11_scan_rsp {
1124 u8 bss_desc_and_tlv_buffer[1]; 1256 u8 bss_desc_and_tlv_buffer[1];
1125} __packed; 1257} __packed;
1126 1258
1259struct host_cmd_ds_802_11_scan_ext {
1260 u32 reserved;
1261 u8 tlv_buffer[1];
1262} __packed;
1263
1264struct mwifiex_ie_types_bss_scan_rsp {
1265 struct mwifiex_ie_types_header header;
1266 u8 bssid[ETH_ALEN];
1267 u8 frame_body[1];
1268} __packed;
1269
1270struct mwifiex_ie_types_bss_scan_info {
1271 struct mwifiex_ie_types_header header;
1272 __le16 rssi;
1273 __le16 anpi;
1274 u8 cca_busy_fraction;
1275 u8 radio_type;
1276 u8 channel;
1277 u8 reserved;
1278 __le64 tsf;
1279} __packed;
1280
1127struct host_cmd_ds_802_11_bg_scan_query { 1281struct host_cmd_ds_802_11_bg_scan_query {
1128 u8 flush; 1282 u8 flush;
1129} __packed; 1283} __packed;
@@ -1296,6 +1450,11 @@ struct mwifiex_ie_types_vhtcap {
1296 struct ieee80211_vht_cap vht_cap; 1450 struct ieee80211_vht_cap vht_cap;
1297} __packed; 1451} __packed;
1298 1452
1453struct mwifiex_ie_types_aid {
1454 struct mwifiex_ie_types_header header;
1455 __le16 aid;
1456} __packed;
1457
1299struct mwifiex_ie_types_oper_mode_ntf { 1458struct mwifiex_ie_types_oper_mode_ntf {
1300 struct mwifiex_ie_types_header header; 1459 struct mwifiex_ie_types_header header;
1301 u8 oper_mode; 1460 u8 oper_mode;
@@ -1331,6 +1490,11 @@ struct mwifiex_ie_types_extcap {
1331 u8 ext_capab[0]; 1490 u8 ext_capab[0];
1332} __packed; 1491} __packed;
1333 1492
1493struct mwifiex_ie_types_qos_info {
1494 struct mwifiex_ie_types_header header;
1495 u8 qos_info;
1496} __packed;
1497
1334struct host_cmd_ds_mac_reg_access { 1498struct host_cmd_ds_mac_reg_access {
1335 __le16 action; 1499 __le16 action;
1336 __le16 offset; 1500 __le16 offset;
@@ -1441,6 +1605,11 @@ struct host_cmd_tlv_rates {
1441 u8 rates[0]; 1605 u8 rates[0];
1442} __packed; 1606} __packed;
1443 1607
1608struct mwifiex_ie_types_bssid_list {
1609 struct mwifiex_ie_types_header header;
1610 u8 bssid[ETH_ALEN];
1611} __packed;
1612
1444struct host_cmd_tlv_bcast_ssid { 1613struct host_cmd_tlv_bcast_ssid {
1445 struct mwifiex_ie_types_header header; 1614 struct mwifiex_ie_types_header header;
1446 u8 bcast_ctl; 1615 u8 bcast_ctl;
@@ -1634,6 +1803,7 @@ struct host_cmd_ds_command {
1634 struct host_cmd_ds_802_11_ps_mode_enh psmode_enh; 1803 struct host_cmd_ds_802_11_ps_mode_enh psmode_enh;
1635 struct host_cmd_ds_802_11_hs_cfg_enh opt_hs_cfg; 1804 struct host_cmd_ds_802_11_hs_cfg_enh opt_hs_cfg;
1636 struct host_cmd_ds_802_11_scan scan; 1805 struct host_cmd_ds_802_11_scan scan;
1806 struct host_cmd_ds_802_11_scan_ext ext_scan;
1637 struct host_cmd_ds_802_11_scan_rsp scan_resp; 1807 struct host_cmd_ds_802_11_scan_rsp scan_resp;
1638 struct host_cmd_ds_802_11_bg_scan_query bg_scan_query; 1808 struct host_cmd_ds_802_11_bg_scan_query bg_scan_query;
1639 struct host_cmd_ds_802_11_bg_scan_query_rsp bg_scan_query_resp; 1809 struct host_cmd_ds_802_11_bg_scan_query_rsp bg_scan_query_resp;
@@ -1653,6 +1823,7 @@ struct host_cmd_ds_command {
1653 struct host_cmd_ds_11n_cfg htcfg; 1823 struct host_cmd_ds_11n_cfg htcfg;
1654 struct host_cmd_ds_wmm_get_status get_wmm_status; 1824 struct host_cmd_ds_wmm_get_status get_wmm_status;
1655 struct host_cmd_ds_802_11_key_material key_material; 1825 struct host_cmd_ds_802_11_key_material key_material;
1826 struct host_cmd_ds_802_11_key_material_v2 key_material_v2;
1656 struct host_cmd_ds_version_ext verext; 1827 struct host_cmd_ds_version_ext verext;
1657 struct host_cmd_ds_mgmt_frame_reg reg_mask; 1828 struct host_cmd_ds_mgmt_frame_reg reg_mask;
1658 struct host_cmd_ds_remain_on_chan roc_cfg; 1829 struct host_cmd_ds_remain_on_chan roc_cfg;
@@ -1671,6 +1842,7 @@ struct host_cmd_ds_command {
1671 struct host_cmd_ds_sta_deauth sta_deauth; 1842 struct host_cmd_ds_sta_deauth sta_deauth;
1672 struct host_cmd_11ac_vht_cfg vht_cfg; 1843 struct host_cmd_11ac_vht_cfg vht_cfg;
1673 struct host_cmd_ds_coalesce_cfg coalesce_cfg; 1844 struct host_cmd_ds_coalesce_cfg coalesce_cfg;
1845 struct host_cmd_ds_tdls_oper tdls_oper;
1674 } params; 1846 } params;
1675} __packed; 1847} __packed;
1676 1848
diff --git a/drivers/net/wireless/mwifiex/ie.c b/drivers/net/wireless/mwifiex/ie.c
index 81ac001ee741..3bf3d58bbc02 100644
--- a/drivers/net/wireless/mwifiex/ie.c
+++ b/drivers/net/wireless/mwifiex/ie.c
@@ -138,9 +138,9 @@ mwifiex_update_autoindex_ies(struct mwifiex_private *priv,
138 } 138 }
139 139
140 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) 140 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP)
141 return mwifiex_send_cmd_async(priv, HostCmd_CMD_UAP_SYS_CONFIG, 141 return mwifiex_send_cmd(priv, HostCmd_CMD_UAP_SYS_CONFIG,
142 HostCmd_ACT_GEN_SET, 142 HostCmd_ACT_GEN_SET,
143 UAP_CUSTOM_IE_I, ie_list); 143 UAP_CUSTOM_IE_I, ie_list, false);
144 144
145 return 0; 145 return 0;
146} 146}
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 1d0a817f2bf0..4ecd0b208ac6 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -137,6 +137,7 @@ int mwifiex_init_priv(struct mwifiex_private *priv)
137 priv->csa_expire_time = 0; 137 priv->csa_expire_time = 0;
138 priv->del_list_idx = 0; 138 priv->del_list_idx = 0;
139 priv->hs2_enabled = false; 139 priv->hs2_enabled = false;
140 memcpy(priv->tos_to_tid_inv, tos_to_tid_inv, MAX_NUM_TID);
140 141
141 return mwifiex_add_bss_prio_tbl(priv); 142 return mwifiex_add_bss_prio_tbl(priv);
142} 143}
@@ -233,7 +234,6 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
233 234
234 adapter->pm_wakeup_fw_try = false; 235 adapter->pm_wakeup_fw_try = false;
235 236
236 adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
237 adapter->curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K; 237 adapter->curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
238 238
239 adapter->is_hs_configured = false; 239 adapter->is_hs_configured = false;
@@ -281,6 +281,9 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
281 adapter->arp_filter_size = 0; 281 adapter->arp_filter_size = 0;
282 adapter->max_mgmt_ie_index = MAX_MGMT_IE_INDEX; 282 adapter->max_mgmt_ie_index = MAX_MGMT_IE_INDEX;
283 adapter->empty_tx_q_cnt = 0; 283 adapter->empty_tx_q_cnt = 0;
284 adapter->ext_scan = true;
285 adapter->fw_key_api_major_ver = 0;
286 adapter->fw_key_api_minor_ver = 0;
284} 287}
285 288
286/* 289/*
@@ -450,6 +453,7 @@ int mwifiex_init_lock_list(struct mwifiex_adapter *adapter)
450 INIT_LIST_HEAD(&priv->tx_ba_stream_tbl_ptr); 453 INIT_LIST_HEAD(&priv->tx_ba_stream_tbl_ptr);
451 INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr); 454 INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr);
452 INIT_LIST_HEAD(&priv->sta_list); 455 INIT_LIST_HEAD(&priv->sta_list);
456 skb_queue_head_init(&priv->tdls_txq);
453 457
454 spin_lock_init(&priv->tx_ba_stream_tbl_lock); 458 spin_lock_init(&priv->tx_ba_stream_tbl_lock);
455 spin_lock_init(&priv->rx_reorder_tbl_lock); 459 spin_lock_init(&priv->rx_reorder_tbl_lock);
@@ -615,7 +619,7 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
615 /* cancel current command */ 619 /* cancel current command */
616 if (adapter->curr_cmd) { 620 if (adapter->curr_cmd) {
617 dev_warn(adapter->dev, "curr_cmd is still in processing\n"); 621 dev_warn(adapter->dev, "curr_cmd is still in processing\n");
618 del_timer(&adapter->cmd_timer); 622 del_timer_sync(&adapter->cmd_timer);
619 mwifiex_recycle_cmd_node(adapter, adapter->curr_cmd); 623 mwifiex_recycle_cmd_node(adapter, adapter->curr_cmd);
620 adapter->curr_cmd = NULL; 624 adapter->curr_cmd = NULL;
621 } 625 }
diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h
index 00a95f4c6a6c..ee494db54060 100644
--- a/drivers/net/wireless/mwifiex/ioctl.h
+++ b/drivers/net/wireless/mwifiex/ioctl.h
@@ -60,8 +60,7 @@ 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, 63 BAND_AAC = 32,
64 BAND_AAC = 64,
65}; 64};
66 65
67#define MWIFIEX_WPA_PASSHPHRASE_LEN 64 66#define MWIFIEX_WPA_PASSHPHRASE_LEN 64
@@ -86,6 +85,10 @@ struct wep_key {
86#define BAND_CONFIG_A 0x01 85#define BAND_CONFIG_A 0x01
87#define MWIFIEX_SUPPORTED_RATES 14 86#define MWIFIEX_SUPPORTED_RATES 14
88#define MWIFIEX_SUPPORTED_RATES_EXT 32 87#define MWIFIEX_SUPPORTED_RATES_EXT 32
88#define MWIFIEX_TDLS_SUPPORTED_RATES 8
89#define MWIFIEX_TDLS_DEF_QOS_CAPAB 0xf
90#define MWIFIEX_PRIO_BK 2
91#define MWIFIEX_PRIO_VI 5
89 92
90struct mwifiex_uap_bss_param { 93struct mwifiex_uap_bss_param {
91 u8 channel; 94 u8 channel;
@@ -174,6 +177,7 @@ struct mwifiex_ds_rx_reorder_tbl {
174struct mwifiex_ds_tx_ba_stream_tbl { 177struct mwifiex_ds_tx_ba_stream_tbl {
175 u16 tid; 178 u16 tid;
176 u8 ra[ETH_ALEN]; 179 u8 ra[ETH_ALEN];
180 u8 amsdu;
177}; 181};
178 182
179#define DBG_CMD_NUM 5 183#define DBG_CMD_NUM 5
@@ -206,7 +210,7 @@ struct mwifiex_debug_info {
206 u32 num_cmd_assoc_success; 210 u32 num_cmd_assoc_success;
207 u32 num_cmd_assoc_failure; 211 u32 num_cmd_assoc_failure;
208 u32 num_tx_timeout; 212 u32 num_tx_timeout;
209 u32 num_cmd_timeout; 213 u8 is_cmd_timedout;
210 u16 timeout_cmd_id; 214 u16 timeout_cmd_id;
211 u16 timeout_cmd_act; 215 u16 timeout_cmd_act;
212 u16 last_cmd_id[DBG_CMD_NUM]; 216 u16 last_cmd_id[DBG_CMD_NUM];
@@ -233,7 +237,10 @@ struct mwifiex_ds_encrypt_key {
233 u8 mac_addr[ETH_ALEN]; 237 u8 mac_addr[ETH_ALEN];
234 u32 is_wapi_key; 238 u32 is_wapi_key;
235 u8 pn[PN_LEN]; /* packet number */ 239 u8 pn[PN_LEN]; /* packet number */
240 u8 pn_len;
236 u8 is_igtk_key; 241 u8 is_igtk_key;
242 u8 is_current_wep_key;
243 u8 is_rx_seq_valid;
237}; 244};
238 245
239struct mwifiex_power_cfg { 246struct mwifiex_power_cfg {
@@ -432,4 +439,16 @@ struct mwifiex_ds_coalesce_cfg {
432 struct mwifiex_coalesce_rule rule[MWIFIEX_COALESCE_MAX_RULES]; 439 struct mwifiex_coalesce_rule rule[MWIFIEX_COALESCE_MAX_RULES];
433}; 440};
434 441
442struct mwifiex_ds_tdls_oper {
443 u16 tdls_action;
444 u8 peer_mac[ETH_ALEN];
445 u16 capability;
446 u8 qos_info;
447 u8 *ext_capab;
448 u8 ext_capab_len;
449 u8 *supp_rates;
450 u8 supp_rates_len;
451 u8 *ht_capab;
452};
453
435#endif /* !_MWIFIEX_IOCTL_H_ */ 454#endif /* !_MWIFIEX_IOCTL_H_ */
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c
index 4e4686e6ac09..89dc62a467f4 100644
--- a/drivers/net/wireless/mwifiex/join.c
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -515,8 +515,7 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
515 515
516 if (ISSUPP_11ACENABLED(priv->adapter->fw_cap_info) && 516 if (ISSUPP_11ACENABLED(priv->adapter->fw_cap_info) &&
517 !bss_desc->disable_11n && !bss_desc->disable_11ac && 517 !bss_desc->disable_11n && !bss_desc->disable_11ac &&
518 (priv->adapter->config_bands & BAND_GAC || 518 priv->adapter->config_bands & BAND_AAC)
519 priv->adapter->config_bands & BAND_AAC))
520 mwifiex_cmd_append_11ac_tlv(priv, bss_desc, &pos); 519 mwifiex_cmd_append_11ac_tlv(priv, bss_desc, &pos);
521 520
522 /* Append vendor specific IE TLV */ 521 /* Append vendor specific IE TLV */
@@ -902,9 +901,9 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
902 mwifiex_get_active_data_rates(priv, adhoc_start->data_rate); 901 mwifiex_get_active_data_rates(priv, adhoc_start->data_rate);
903 if ((adapter->adhoc_start_band & BAND_G) && 902 if ((adapter->adhoc_start_band & BAND_G) &&
904 (priv->curr_pkt_filter & HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON)) { 903 (priv->curr_pkt_filter & HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON)) {
905 if (mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, 904 if (mwifiex_send_cmd(priv, HostCmd_CMD_MAC_CONTROL,
906 HostCmd_ACT_GEN_SET, 0, 905 HostCmd_ACT_GEN_SET, 0,
907 &priv->curr_pkt_filter)) { 906 &priv->curr_pkt_filter, false)) {
908 dev_err(adapter->dev, 907 dev_err(adapter->dev,
909 "ADHOC_S_CMD: G Protection config failed\n"); 908 "ADHOC_S_CMD: G Protection config failed\n");
910 return -1; 909 return -1;
@@ -983,7 +982,7 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
983 cpu_to_le16(sizeof(struct ieee80211_ht_cap)); 982 cpu_to_le16(sizeof(struct ieee80211_ht_cap));
984 radio_type = mwifiex_band_to_radio_type( 983 radio_type = mwifiex_band_to_radio_type(
985 priv->adapter->config_bands); 984 priv->adapter->config_bands);
986 mwifiex_fill_cap_info(priv, radio_type, ht_cap); 985 mwifiex_fill_cap_info(priv, radio_type, &ht_cap->ht_cap);
987 986
988 if (adapter->sec_chan_offset == 987 if (adapter->sec_chan_offset ==
989 IEEE80211_HT_PARAM_CHA_SEC_NONE) { 988 IEEE80211_HT_PARAM_CHA_SEC_NONE) {
@@ -1074,9 +1073,9 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv,
1074 priv-> 1073 priv->
1075 curr_pkt_filter | HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON; 1074 curr_pkt_filter | HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON;
1076 1075
1077 if (mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, 1076 if (mwifiex_send_cmd(priv, HostCmd_CMD_MAC_CONTROL,
1078 HostCmd_ACT_GEN_SET, 0, 1077 HostCmd_ACT_GEN_SET, 0,
1079 &curr_pkt_filter)) { 1078 &curr_pkt_filter, false)) {
1080 dev_err(priv->adapter->dev, 1079 dev_err(priv->adapter->dev,
1081 "ADHOC_J_CMD: G Protection config failed\n"); 1080 "ADHOC_J_CMD: G Protection config failed\n");
1082 return -1; 1081 return -1;
@@ -1300,8 +1299,7 @@ int mwifiex_associate(struct mwifiex_private *priv,
1300 1299
1301 if (ISSUPP_11ACENABLED(priv->adapter->fw_cap_info) && 1300 if (ISSUPP_11ACENABLED(priv->adapter->fw_cap_info) &&
1302 !bss_desc->disable_11n && !bss_desc->disable_11ac && 1301 !bss_desc->disable_11n && !bss_desc->disable_11ac &&
1303 (priv->adapter->config_bands & BAND_GAC || 1302 priv->adapter->config_bands & BAND_AAC)
1304 priv->adapter->config_bands & BAND_AAC))
1305 mwifiex_set_11ac_ba_params(priv); 1303 mwifiex_set_11ac_ba_params(priv);
1306 else 1304 else
1307 mwifiex_set_ba_params(priv); 1305 mwifiex_set_ba_params(priv);
@@ -1314,8 +1312,8 @@ int mwifiex_associate(struct mwifiex_private *priv,
1314 retrieval */ 1312 retrieval */
1315 priv->assoc_rsp_size = 0; 1313 priv->assoc_rsp_size = 0;
1316 1314
1317 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_ASSOCIATE, 1315 return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_ASSOCIATE,
1318 HostCmd_ACT_GEN_SET, 0, bss_desc); 1316 HostCmd_ACT_GEN_SET, 0, bss_desc, true);
1319} 1317}
1320 1318
1321/* 1319/*
@@ -1335,14 +1333,13 @@ mwifiex_adhoc_start(struct mwifiex_private *priv,
1335 priv->curr_bss_params.band); 1333 priv->curr_bss_params.band);
1336 1334
1337 if (ISSUPP_11ACENABLED(priv->adapter->fw_cap_info) && 1335 if (ISSUPP_11ACENABLED(priv->adapter->fw_cap_info) &&
1338 (priv->adapter->config_bands & BAND_GAC || 1336 priv->adapter->config_bands & BAND_AAC)
1339 priv->adapter->config_bands & BAND_AAC))
1340 mwifiex_set_11ac_ba_params(priv); 1337 mwifiex_set_11ac_ba_params(priv);
1341 else 1338 else
1342 mwifiex_set_ba_params(priv); 1339 mwifiex_set_ba_params(priv);
1343 1340
1344 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_START, 1341 return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_AD_HOC_START,
1345 HostCmd_ACT_GEN_SET, 0, adhoc_ssid); 1342 HostCmd_ACT_GEN_SET, 0, adhoc_ssid, true);
1346} 1343}
1347 1344
1348/* 1345/*
@@ -1376,8 +1373,7 @@ int mwifiex_adhoc_join(struct mwifiex_private *priv,
1376 1373
1377 if (ISSUPP_11ACENABLED(priv->adapter->fw_cap_info) && 1374 if (ISSUPP_11ACENABLED(priv->adapter->fw_cap_info) &&
1378 !bss_desc->disable_11n && !bss_desc->disable_11ac && 1375 !bss_desc->disable_11n && !bss_desc->disable_11ac &&
1379 (priv->adapter->config_bands & BAND_GAC || 1376 priv->adapter->config_bands & BAND_AAC)
1380 priv->adapter->config_bands & BAND_AAC))
1381 mwifiex_set_11ac_ba_params(priv); 1377 mwifiex_set_11ac_ba_params(priv);
1382 else 1378 else
1383 mwifiex_set_ba_params(priv); 1379 mwifiex_set_ba_params(priv);
@@ -1387,8 +1383,8 @@ int mwifiex_adhoc_join(struct mwifiex_private *priv,
1387 dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %c\n", 1383 dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %c\n",
1388 priv->curr_bss_params.band); 1384 priv->curr_bss_params.band);
1389 1385
1390 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_JOIN, 1386 return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_AD_HOC_JOIN,
1391 HostCmd_ACT_GEN_SET, 0, bss_desc); 1387 HostCmd_ACT_GEN_SET, 0, bss_desc, true);
1392} 1388}
1393 1389
1394/* 1390/*
@@ -1407,8 +1403,8 @@ static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, u8 *mac)
1407 else 1403 else
1408 memcpy(mac_address, mac, ETH_ALEN); 1404 memcpy(mac_address, mac, ETH_ALEN);
1409 1405
1410 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_DEAUTHENTICATE, 1406 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_DEAUTHENTICATE,
1411 HostCmd_ACT_GEN_SET, 0, mac_address); 1407 HostCmd_ACT_GEN_SET, 0, mac_address, true);
1412 1408
1413 return ret; 1409 return ret;
1414} 1410}
@@ -1436,19 +1432,31 @@ int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac)
1436 GFP_KERNEL); 1432 GFP_KERNEL);
1437 break; 1433 break;
1438 case NL80211_IFTYPE_ADHOC: 1434 case NL80211_IFTYPE_ADHOC:
1439 return mwifiex_send_cmd_sync(priv, 1435 return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_AD_HOC_STOP,
1440 HostCmd_CMD_802_11_AD_HOC_STOP, 1436 HostCmd_ACT_GEN_SET, 0, NULL, true);
1441 HostCmd_ACT_GEN_SET, 0, NULL);
1442 case NL80211_IFTYPE_AP: 1437 case NL80211_IFTYPE_AP:
1443 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_UAP_BSS_STOP, 1438 return mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_STOP,
1444 HostCmd_ACT_GEN_SET, 0, NULL); 1439 HostCmd_ACT_GEN_SET, 0, NULL, true);
1445 default: 1440 default:
1446 break; 1441 break;
1447 } 1442 }
1448 1443
1449 return ret; 1444 return ret;
1450} 1445}
1451EXPORT_SYMBOL_GPL(mwifiex_deauthenticate); 1446
1447/* This function deauthenticates/disconnects from all BSS. */
1448void mwifiex_deauthenticate_all(struct mwifiex_adapter *adapter)
1449{
1450 struct mwifiex_private *priv;
1451 int i;
1452
1453 for (i = 0; i < adapter->priv_num; i++) {
1454 priv = adapter->priv[i];
1455 if (priv)
1456 mwifiex_deauthenticate(priv, NULL);
1457 }
1458}
1459EXPORT_SYMBOL_GPL(mwifiex_deauthenticate_all);
1452 1460
1453/* 1461/*
1454 * This function converts band to radio type used in channel TLV. 1462 * This function converts band to radio type used in channel TLV.
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 9d3d2758ec35..7b4502fefec3 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -194,7 +194,7 @@ static int mwifiex_unregister(struct mwifiex_adapter *adapter)
194 if (adapter->if_ops.cleanup_if) 194 if (adapter->if_ops.cleanup_if)
195 adapter->if_ops.cleanup_if(adapter); 195 adapter->if_ops.cleanup_if(adapter);
196 196
197 del_timer(&adapter->cmd_timer); 197 del_timer_sync(&adapter->cmd_timer);
198 198
199 /* Free private structures */ 199 /* Free private structures */
200 for (i = 0; i < adapter->priv_num; i++) { 200 for (i = 0; i < adapter->priv_num; i++) {
@@ -678,8 +678,8 @@ mwifiex_set_mac_address(struct net_device *dev, void *addr)
678 memcpy(priv->curr_addr, hw_addr->sa_data, ETH_ALEN); 678 memcpy(priv->curr_addr, hw_addr->sa_data, ETH_ALEN);
679 679
680 /* Send request to firmware */ 680 /* Send request to firmware */
681 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_MAC_ADDRESS, 681 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_MAC_ADDRESS,
682 HostCmd_ACT_GEN_SET, 0, NULL); 682 HostCmd_ACT_GEN_SET, 0, NULL, true);
683 683
684 if (!ret) 684 if (!ret)
685 memcpy(priv->netdev->dev_addr, priv->curr_addr, ETH_ALEN); 685 memcpy(priv->netdev->dev_addr, priv->curr_addr, ETH_ALEN);
@@ -871,7 +871,6 @@ mwifiex_add_card(void *card, struct semaphore *sem,
871 adapter->is_suspended = false; 871 adapter->is_suspended = false;
872 adapter->hs_activated = false; 872 adapter->hs_activated = false;
873 init_waitqueue_head(&adapter->hs_activate_wait_q); 873 init_waitqueue_head(&adapter->hs_activate_wait_q);
874 adapter->cmd_wait_q_required = false;
875 init_waitqueue_head(&adapter->cmd_wait_q.wait); 874 init_waitqueue_head(&adapter->cmd_wait_q.wait);
876 adapter->cmd_wait_q.status = 0; 875 adapter->cmd_wait_q.status = 0;
877 adapter->scan_wait_q_woken = false; 876 adapter->scan_wait_q_woken = false;
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index d8ad554ce39f..a67f7da12b30 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -59,7 +59,7 @@ enum {
59 59
60#define MWIFIEX_UPLD_SIZE (2312) 60#define MWIFIEX_UPLD_SIZE (2312)
61 61
62#define MAX_EVENT_SIZE 1024 62#define MAX_EVENT_SIZE 2048
63 63
64#define ARP_FILTER_MAX_BUF_SIZE 68 64#define ARP_FILTER_MAX_BUF_SIZE 68
65 65
@@ -116,7 +116,7 @@ enum {
116#define MWIFIEX_TYPE_DATA 0 116#define MWIFIEX_TYPE_DATA 0
117#define MWIFIEX_TYPE_EVENT 3 117#define MWIFIEX_TYPE_EVENT 3
118 118
119#define MAX_BITMAP_RATES_SIZE 10 119#define MAX_BITMAP_RATES_SIZE 18
120 120
121#define MAX_CHANNEL_BAND_BG 14 121#define MAX_CHANNEL_BAND_BG 14
122#define MAX_CHANNEL_BAND_A 165 122#define MAX_CHANNEL_BAND_A 165
@@ -145,7 +145,6 @@ struct mwifiex_dbg {
145 u32 num_cmd_assoc_success; 145 u32 num_cmd_assoc_success;
146 u32 num_cmd_assoc_failure; 146 u32 num_cmd_assoc_failure;
147 u32 num_tx_timeout; 147 u32 num_tx_timeout;
148 u32 num_cmd_timeout;
149 u16 timeout_cmd_id; 148 u16 timeout_cmd_id;
150 u16 timeout_cmd_act; 149 u16 timeout_cmd_act;
151 u16 last_cmd_id[DBG_CMD_NUM]; 150 u16 last_cmd_id[DBG_CMD_NUM];
@@ -193,6 +192,8 @@ struct mwifiex_add_ba_param {
193 u32 tx_win_size; 192 u32 tx_win_size;
194 u32 rx_win_size; 193 u32 rx_win_size;
195 u32 timeout; 194 u32 timeout;
195 u8 tx_amsdu;
196 u8 rx_amsdu;
196}; 197};
197 198
198struct mwifiex_tx_aggr { 199struct mwifiex_tx_aggr {
@@ -210,6 +211,7 @@ struct mwifiex_ra_list_tbl {
210 u16 ba_pkt_count; 211 u16 ba_pkt_count;
211 u8 ba_packet_thr; 212 u8 ba_packet_thr;
212 u16 total_pkt_count; 213 u16 total_pkt_count;
214 bool tdls_link;
213}; 215};
214 216
215struct mwifiex_tid_tbl { 217struct mwifiex_tid_tbl {
@@ -262,6 +264,31 @@ struct ieee_types_generic {
262 u8 data[IEEE_MAX_IE_SIZE - sizeof(struct ieee_types_header)]; 264 u8 data[IEEE_MAX_IE_SIZE - sizeof(struct ieee_types_header)];
263} __packed; 265} __packed;
264 266
267struct ieee_types_bss_co_2040 {
268 struct ieee_types_header ieee_hdr;
269 u8 bss_2040co;
270} __packed;
271
272struct ieee_types_extcap {
273 struct ieee_types_header ieee_hdr;
274 u8 ext_capab[8];
275} __packed;
276
277struct ieee_types_vht_cap {
278 struct ieee_types_header ieee_hdr;
279 struct ieee80211_vht_cap vhtcap;
280} __packed;
281
282struct ieee_types_vht_oper {
283 struct ieee_types_header ieee_hdr;
284 struct ieee80211_vht_operation vhtoper;
285} __packed;
286
287struct ieee_types_aid {
288 struct ieee_types_header ieee_hdr;
289 u16 aid;
290} __packed;
291
265struct mwifiex_bssdescriptor { 292struct mwifiex_bssdescriptor {
266 u8 mac_address[ETH_ALEN]; 293 u8 mac_address[ETH_ALEN];
267 struct cfg80211_ssid ssid; 294 struct cfg80211_ssid ssid;
@@ -443,6 +470,7 @@ struct mwifiex_private {
443 u8 wpa_ie_len; 470 u8 wpa_ie_len;
444 u8 wpa_is_gtk_set; 471 u8 wpa_is_gtk_set;
445 struct host_cmd_ds_802_11_key_material aes_key; 472 struct host_cmd_ds_802_11_key_material aes_key;
473 struct host_cmd_ds_802_11_key_material_v2 aes_key_v2;
446 u8 wapi_ie[256]; 474 u8 wapi_ie[256];
447 u8 wapi_ie_len; 475 u8 wapi_ie_len;
448 u8 *wps_ie; 476 u8 *wps_ie;
@@ -461,6 +489,7 @@ struct mwifiex_private {
461 struct mwifiex_tx_aggr aggr_prio_tbl[MAX_NUM_TID]; 489 struct mwifiex_tx_aggr aggr_prio_tbl[MAX_NUM_TID];
462 struct mwifiex_add_ba_param add_ba_param; 490 struct mwifiex_add_ba_param add_ba_param;
463 u16 rx_seq[MAX_NUM_TID]; 491 u16 rx_seq[MAX_NUM_TID];
492 u8 tos_to_tid_inv[MAX_NUM_TID];
464 struct list_head rx_reorder_tbl_ptr; 493 struct list_head rx_reorder_tbl_ptr;
465 /* spin lock for rx_reorder_tbl_ptr queue */ 494 /* spin lock for rx_reorder_tbl_ptr queue */
466 spinlock_t rx_reorder_tbl_lock; 495 spinlock_t rx_reorder_tbl_lock;
@@ -518,6 +547,8 @@ struct mwifiex_private {
518 unsigned long csa_expire_time; 547 unsigned long csa_expire_time;
519 u8 del_list_idx; 548 u8 del_list_idx;
520 bool hs2_enabled; 549 bool hs2_enabled;
550 struct station_parameters *sta_params;
551 struct sk_buff_head tdls_txq;
521}; 552};
522 553
523enum mwifiex_ba_status { 554enum mwifiex_ba_status {
@@ -531,6 +562,7 @@ struct mwifiex_tx_ba_stream_tbl {
531 int tid; 562 int tid;
532 u8 ra[ETH_ALEN]; 563 u8 ra[ETH_ALEN];
533 enum mwifiex_ba_status ba_status; 564 enum mwifiex_ba_status ba_status;
565 u8 amsdu;
534}; 566};
535 567
536struct mwifiex_rx_reorder_tbl; 568struct mwifiex_rx_reorder_tbl;
@@ -545,10 +577,12 @@ struct mwifiex_rx_reorder_tbl {
545 struct list_head list; 577 struct list_head list;
546 int tid; 578 int tid;
547 u8 ta[ETH_ALEN]; 579 u8 ta[ETH_ALEN];
580 int init_win;
548 int start_win; 581 int start_win;
549 int win_size; 582 int win_size;
550 void **rx_reorder_ptr; 583 void **rx_reorder_ptr;
551 struct reorder_tmr_cnxt timer_context; 584 struct reorder_tmr_cnxt timer_context;
585 u8 amsdu;
552 u8 flags; 586 u8 flags;
553}; 587};
554 588
@@ -583,17 +617,35 @@ struct mwifiex_bss_priv {
583 u64 fw_tsf; 617 u64 fw_tsf;
584}; 618};
585 619
586/* This is AP specific structure which stores information 620struct mwifiex_tdls_capab {
587 * about associated STA 621 __le16 capab;
622 u8 rates[32];
623 u8 rates_len;
624 u8 qos_info;
625 u8 coex_2040;
626 u16 aid;
627 struct ieee80211_ht_cap ht_capb;
628 struct ieee80211_ht_operation ht_oper;
629 struct ieee_types_extcap extcap;
630 struct ieee_types_generic rsn_ie;
631 struct ieee80211_vht_cap vhtcap;
632 struct ieee80211_vht_operation vhtoper;
633};
634
635/* This is AP/TDLS specific structure which stores information
636 * about associated/peer STA
588 */ 637 */
589struct mwifiex_sta_node { 638struct mwifiex_sta_node {
590 struct list_head list; 639 struct list_head list;
591 u8 mac_addr[ETH_ALEN]; 640 u8 mac_addr[ETH_ALEN];
592 u8 is_wmm_enabled; 641 u8 is_wmm_enabled;
593 u8 is_11n_enabled; 642 u8 is_11n_enabled;
643 u8 is_11ac_enabled;
594 u8 ampdu_sta[MAX_NUM_TID]; 644 u8 ampdu_sta[MAX_NUM_TID];
595 u16 rx_seq[MAX_NUM_TID]; 645 u16 rx_seq[MAX_NUM_TID];
596 u16 max_amsdu; 646 u16 max_amsdu;
647 u8 tdls_status;
648 struct mwifiex_tdls_capab tdls_cap;
597}; 649};
598 650
599struct mwifiex_if_ops { 651struct mwifiex_if_ops {
@@ -671,7 +723,7 @@ struct mwifiex_adapter {
671 struct cmd_ctrl_node *curr_cmd; 723 struct cmd_ctrl_node *curr_cmd;
672 /* spin lock for command */ 724 /* spin lock for command */
673 spinlock_t mwifiex_cmd_lock; 725 spinlock_t mwifiex_cmd_lock;
674 u32 num_cmd_timeout; 726 u8 is_cmd_timedout;
675 u16 last_init_cmd; 727 u16 last_init_cmd;
676 struct timer_list cmd_timer; 728 struct timer_list cmd_timer;
677 struct list_head cmd_free_q; 729 struct list_head cmd_free_q;
@@ -725,12 +777,12 @@ struct mwifiex_adapter {
725 u8 event_body[MAX_EVENT_SIZE]; 777 u8 event_body[MAX_EVENT_SIZE];
726 u32 hw_dot_11n_dev_cap; 778 u32 hw_dot_11n_dev_cap;
727 u8 hw_dev_mcs_support; 779 u8 hw_dev_mcs_support;
780 u8 user_dev_mcs_support;
728 u8 adhoc_11n_enabled; 781 u8 adhoc_11n_enabled;
729 u8 sec_chan_offset; 782 u8 sec_chan_offset;
730 struct mwifiex_dbg dbg; 783 struct mwifiex_dbg dbg;
731 u8 arp_filter[ARP_FILTER_MAX_BUF_SIZE]; 784 u8 arp_filter[ARP_FILTER_MAX_BUF_SIZE];
732 u32 arp_filter_size; 785 u32 arp_filter_size;
733 u16 cmd_wait_q_required;
734 struct mwifiex_wait_queue cmd_wait_q; 786 struct mwifiex_wait_queue cmd_wait_q;
735 u8 scan_wait_q_woken; 787 u8 scan_wait_q_woken;
736 spinlock_t queue_lock; /* lock for tx queues */ 788 spinlock_t queue_lock; /* lock for tx queues */
@@ -753,6 +805,9 @@ struct mwifiex_adapter {
753 atomic_t is_tx_received; 805 atomic_t is_tx_received;
754 atomic_t pending_bridged_pkts; 806 atomic_t pending_bridged_pkts;
755 struct semaphore *card_sem; 807 struct semaphore *card_sem;
808 bool ext_scan;
809 u8 fw_api_ver;
810 u8 fw_key_api_major_ver, fw_key_api_minor_ver;
756}; 811};
757 812
758int mwifiex_init_lock_list(struct mwifiex_adapter *adapter); 813int mwifiex_init_lock_list(struct mwifiex_adapter *adapter);
@@ -788,11 +843,8 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter);
788int mwifiex_complete_cmd(struct mwifiex_adapter *adapter, 843int mwifiex_complete_cmd(struct mwifiex_adapter *adapter,
789 struct cmd_ctrl_node *cmd_node); 844 struct cmd_ctrl_node *cmd_node);
790 845
791int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no, 846int mwifiex_send_cmd(struct mwifiex_private *priv, u16 cmd_no,
792 u16 cmd_action, u32 cmd_oid, void *data_buf); 847 u16 cmd_action, u32 cmd_oid, void *data_buf, bool sync);
793
794int mwifiex_send_cmd_sync(struct mwifiex_private *priv, uint16_t cmd_no,
795 u16 cmd_action, u32 cmd_oid, void *data_buf);
796 848
797void mwifiex_cmd_timeout_func(unsigned long function_context); 849void mwifiex_cmd_timeout_func(unsigned long function_context);
798 850
@@ -880,6 +932,7 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
880void mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason); 932void mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason);
881u8 mwifiex_band_to_radio_type(u8 band); 933u8 mwifiex_band_to_radio_type(u8 band);
882int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac); 934int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac);
935void mwifiex_deauthenticate_all(struct mwifiex_adapter *adapter);
883int mwifiex_adhoc_start(struct mwifiex_private *priv, 936int mwifiex_adhoc_start(struct mwifiex_private *priv,
884 struct cfg80211_ssid *adhoc_ssid); 937 struct cfg80211_ssid *adhoc_ssid);
885int mwifiex_adhoc_join(struct mwifiex_private *priv, 938int mwifiex_adhoc_join(struct mwifiex_private *priv,
@@ -938,6 +991,12 @@ mwifiex_set_wmm_params(struct mwifiex_private *priv,
938 struct cfg80211_ap_settings *params); 991 struct cfg80211_ap_settings *params);
939void mwifiex_set_ba_params(struct mwifiex_private *priv); 992void mwifiex_set_ba_params(struct mwifiex_private *priv);
940void mwifiex_set_11ac_ba_params(struct mwifiex_private *priv); 993void mwifiex_set_11ac_ba_params(struct mwifiex_private *priv);
994int mwifiex_cmd_802_11_scan_ext(struct mwifiex_private *priv,
995 struct host_cmd_ds_command *cmd,
996 void *data_buf);
997int mwifiex_ret_802_11_scan_ext(struct mwifiex_private *priv);
998int mwifiex_handle_event_ext_scan_report(struct mwifiex_private *priv,
999 void *buf);
941 1000
942/* 1001/*
943 * This function checks if the queuing is RA based or not. 1002 * This function checks if the queuing is RA based or not.
@@ -1078,7 +1137,7 @@ int mwifiex_set_encode(struct mwifiex_private *priv, struct key_params *kp,
1078 const u8 *key, int key_len, u8 key_index, 1137 const u8 *key, int key_len, u8 key_index,
1079 const u8 *mac_addr, int disable); 1138 const u8 *mac_addr, int disable);
1080 1139
1081int mwifiex_set_gen_ie(struct mwifiex_private *priv, u8 *ie, int ie_len); 1140int mwifiex_set_gen_ie(struct mwifiex_private *priv, const u8 *ie, int ie_len);
1082 1141
1083int mwifiex_get_ver_ext(struct mwifiex_private *priv); 1142int mwifiex_get_ver_ext(struct mwifiex_private *priv);
1084 1143
@@ -1159,6 +1218,32 @@ void mwifiex_dnld_txpwr_table(struct mwifiex_private *priv);
1159 1218
1160extern const struct ethtool_ops mwifiex_ethtool_ops; 1219extern const struct ethtool_ops mwifiex_ethtool_ops;
1161 1220
1221void mwifiex_del_all_sta_list(struct mwifiex_private *priv);
1222void mwifiex_del_sta_entry(struct mwifiex_private *priv, u8 *mac);
1223void
1224mwifiex_set_sta_ht_cap(struct mwifiex_private *priv, const u8 *ies,
1225 int ies_len, struct mwifiex_sta_node *node);
1226struct mwifiex_sta_node *
1227mwifiex_add_sta_entry(struct mwifiex_private *priv, u8 *mac);
1228struct mwifiex_sta_node *
1229mwifiex_get_sta_entry(struct mwifiex_private *priv, u8 *mac);
1230int mwifiex_send_tdls_data_frame(struct mwifiex_private *priv, u8 *peer,
1231 u8 action_code, u8 dialog_token,
1232 u16 status_code, const u8 *extra_ies,
1233 size_t extra_ies_len);
1234int mwifiex_send_tdls_action_frame(struct mwifiex_private *priv,
1235 u8 *peer, u8 action_code, u8 dialog_token,
1236 u16 status_code, const u8 *extra_ies,
1237 size_t extra_ies_len);
1238void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
1239 u8 *buf, int len);
1240int mwifiex_tdls_oper(struct mwifiex_private *priv, u8 *peer, u8 action);
1241int mwifiex_get_tdls_link_status(struct mwifiex_private *priv, u8 *mac);
1242void mwifiex_disable_all_tdls_links(struct mwifiex_private *priv);
1243bool mwifiex_is_bss_in_11ac_mode(struct mwifiex_private *priv);
1244u8 mwifiex_get_center_freq_index(struct mwifiex_private *priv, u8 band,
1245 u32 pri_chan, u8 chan_bw);
1246
1162#ifdef CONFIG_DEBUG_FS 1247#ifdef CONFIG_DEBUG_FS
1163void mwifiex_debugfs_init(void); 1248void mwifiex_debugfs_init(void);
1164void mwifiex_debugfs_remove(void); 1249void mwifiex_debugfs_remove(void);
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index 7fe7b53fb17a..57c353a94b29 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -39,20 +39,31 @@ static struct semaphore add_remove_card_sem;
39 39
40static int 40static int
41mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb, 41mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb,
42 int size, int flags) 42 size_t size, int flags)
43{ 43{
44 struct pcie_service_card *card = adapter->card; 44 struct pcie_service_card *card = adapter->card;
45 dma_addr_t buf_pa; 45 struct mwifiex_dma_mapping mapping;
46 46
47 buf_pa = pci_map_single(card->dev, skb->data, size, flags); 47 mapping.addr = pci_map_single(card->dev, skb->data, size, flags);
48 if (pci_dma_mapping_error(card->dev, buf_pa)) { 48 if (pci_dma_mapping_error(card->dev, mapping.addr)) {
49 dev_err(adapter->dev, "failed to map pci memory!\n"); 49 dev_err(adapter->dev, "failed to map pci memory!\n");
50 return -1; 50 return -1;
51 } 51 }
52 memcpy(skb->cb, &buf_pa, sizeof(dma_addr_t)); 52 mapping.len = size;
53 memcpy(skb->cb, &mapping, sizeof(mapping));
53 return 0; 54 return 0;
54} 55}
55 56
57static void mwifiex_unmap_pci_memory(struct mwifiex_adapter *adapter,
58 struct sk_buff *skb, int flags)
59{
60 struct pcie_service_card *card = adapter->card;
61 struct mwifiex_dma_mapping mapping;
62
63 MWIFIEX_SKB_PACB(skb, &mapping);
64 pci_unmap_single(card->dev, mapping.addr, mapping.len, flags);
65}
66
56/* 67/*
57 * This function reads sleep cookie and checks if FW is ready 68 * This function reads sleep cookie and checks if FW is ready
58 */ 69 */
@@ -179,6 +190,7 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev,
179 card->pcie.firmware = data->firmware; 190 card->pcie.firmware = data->firmware;
180 card->pcie.reg = data->reg; 191 card->pcie.reg = data->reg;
181 card->pcie.blksz_fw_dl = data->blksz_fw_dl; 192 card->pcie.blksz_fw_dl = data->blksz_fw_dl;
193 card->pcie.tx_buf_size = data->tx_buf_size;
182 } 194 }
183 195
184 if (mwifiex_add_card(card, &add_remove_card_sem, &pcie_ops, 196 if (mwifiex_add_card(card, &add_remove_card_sem, &pcie_ops,
@@ -199,7 +211,6 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev)
199 struct pcie_service_card *card; 211 struct pcie_service_card *card;
200 struct mwifiex_adapter *adapter; 212 struct mwifiex_adapter *adapter;
201 struct mwifiex_private *priv; 213 struct mwifiex_private *priv;
202 int i;
203 214
204 card = pci_get_drvdata(pdev); 215 card = pci_get_drvdata(pdev);
205 if (!card) 216 if (!card)
@@ -218,11 +229,7 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev)
218 mwifiex_pcie_resume(&pdev->dev); 229 mwifiex_pcie_resume(&pdev->dev);
219#endif 230#endif
220 231
221 for (i = 0; i < adapter->priv_num; i++) 232 mwifiex_deauthenticate_all(adapter);
222 if ((GET_BSS_ROLE(adapter->priv[i]) ==
223 MWIFIEX_BSS_ROLE_STA) &&
224 adapter->priv[i]->media_connected)
225 mwifiex_deauthenticate(adapter->priv[i], NULL);
226 233
227 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); 234 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
228 235
@@ -320,6 +327,30 @@ static void mwifiex_pcie_dev_wakeup_delay(struct mwifiex_adapter *adapter)
320 return; 327 return;
321} 328}
322 329
330static void mwifiex_delay_for_sleep_cookie(struct mwifiex_adapter *adapter,
331 u32 max_delay_loop_cnt)
332{
333 struct pcie_service_card *card = adapter->card;
334 u8 *buffer;
335 u32 sleep_cookie, count;
336
337 for (count = 0; count < max_delay_loop_cnt; count++) {
338 buffer = card->cmdrsp_buf->data - INTF_HEADER_LEN;
339 sleep_cookie = *(u32 *)buffer;
340
341 if (sleep_cookie == MWIFIEX_DEF_SLEEP_COOKIE) {
342 dev_dbg(adapter->dev,
343 "sleep cookie found at count %d\n", count);
344 break;
345 }
346 usleep_range(20, 30);
347 }
348
349 if (count >= max_delay_loop_cnt)
350 dev_dbg(adapter->dev,
351 "max count reached while accessing sleep cookie\n");
352}
353
323/* This function wakes up the card by reading fw_status register. */ 354/* This function wakes up the card by reading fw_status register. */
324static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter) 355static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
325{ 356{
@@ -456,7 +487,7 @@ static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter)
456 PCI_DMA_FROMDEVICE)) 487 PCI_DMA_FROMDEVICE))
457 return -1; 488 return -1;
458 489
459 MWIFIEX_SKB_PACB(skb, &buf_pa); 490 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
460 491
461 dev_dbg(adapter->dev, 492 dev_dbg(adapter->dev,
462 "info: RX ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n", 493 "info: RX ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n",
@@ -513,7 +544,7 @@ static int mwifiex_pcie_init_evt_ring(struct mwifiex_adapter *adapter)
513 PCI_DMA_FROMDEVICE)) 544 PCI_DMA_FROMDEVICE))
514 return -1; 545 return -1;
515 546
516 MWIFIEX_SKB_PACB(skb, &buf_pa); 547 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
517 548
518 dev_dbg(adapter->dev, 549 dev_dbg(adapter->dev,
519 "info: EVT ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n", 550 "info: EVT ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n",
@@ -549,8 +580,8 @@ static void mwifiex_cleanup_txq_ring(struct mwifiex_adapter *adapter)
549 desc2 = card->txbd_ring[i]; 580 desc2 = card->txbd_ring[i];
550 if (card->tx_buf_list[i]) { 581 if (card->tx_buf_list[i]) {
551 skb = card->tx_buf_list[i]; 582 skb = card->tx_buf_list[i];
552 pci_unmap_single(card->dev, desc2->paddr, 583 mwifiex_unmap_pci_memory(adapter, skb,
553 skb->len, PCI_DMA_TODEVICE); 584 PCI_DMA_TODEVICE);
554 dev_kfree_skb_any(skb); 585 dev_kfree_skb_any(skb);
555 } 586 }
556 memset(desc2, 0, sizeof(*desc2)); 587 memset(desc2, 0, sizeof(*desc2));
@@ -558,8 +589,8 @@ static void mwifiex_cleanup_txq_ring(struct mwifiex_adapter *adapter)
558 desc = card->txbd_ring[i]; 589 desc = card->txbd_ring[i];
559 if (card->tx_buf_list[i]) { 590 if (card->tx_buf_list[i]) {
560 skb = card->tx_buf_list[i]; 591 skb = card->tx_buf_list[i];
561 pci_unmap_single(card->dev, desc->paddr, 592 mwifiex_unmap_pci_memory(adapter, skb,
562 skb->len, PCI_DMA_TODEVICE); 593 PCI_DMA_TODEVICE);
563 dev_kfree_skb_any(skb); 594 dev_kfree_skb_any(skb);
564 } 595 }
565 memset(desc, 0, sizeof(*desc)); 596 memset(desc, 0, sizeof(*desc));
@@ -587,8 +618,8 @@ static void mwifiex_cleanup_rxq_ring(struct mwifiex_adapter *adapter)
587 desc2 = card->rxbd_ring[i]; 618 desc2 = card->rxbd_ring[i];
588 if (card->rx_buf_list[i]) { 619 if (card->rx_buf_list[i]) {
589 skb = card->rx_buf_list[i]; 620 skb = card->rx_buf_list[i];
590 pci_unmap_single(card->dev, desc2->paddr, 621 mwifiex_unmap_pci_memory(adapter, skb,
591 skb->len, PCI_DMA_FROMDEVICE); 622 PCI_DMA_FROMDEVICE);
592 dev_kfree_skb_any(skb); 623 dev_kfree_skb_any(skb);
593 } 624 }
594 memset(desc2, 0, sizeof(*desc2)); 625 memset(desc2, 0, sizeof(*desc2));
@@ -596,8 +627,8 @@ static void mwifiex_cleanup_rxq_ring(struct mwifiex_adapter *adapter)
596 desc = card->rxbd_ring[i]; 627 desc = card->rxbd_ring[i];
597 if (card->rx_buf_list[i]) { 628 if (card->rx_buf_list[i]) {
598 skb = card->rx_buf_list[i]; 629 skb = card->rx_buf_list[i];
599 pci_unmap_single(card->dev, desc->paddr, 630 mwifiex_unmap_pci_memory(adapter, skb,
600 skb->len, PCI_DMA_FROMDEVICE); 631 PCI_DMA_FROMDEVICE);
601 dev_kfree_skb_any(skb); 632 dev_kfree_skb_any(skb);
602 } 633 }
603 memset(desc, 0, sizeof(*desc)); 634 memset(desc, 0, sizeof(*desc));
@@ -622,8 +653,8 @@ static void mwifiex_cleanup_evt_ring(struct mwifiex_adapter *adapter)
622 desc = card->evtbd_ring[i]; 653 desc = card->evtbd_ring[i];
623 if (card->evt_buf_list[i]) { 654 if (card->evt_buf_list[i]) {
624 skb = card->evt_buf_list[i]; 655 skb = card->evt_buf_list[i];
625 pci_unmap_single(card->dev, desc->paddr, MAX_EVENT_SIZE, 656 mwifiex_unmap_pci_memory(adapter, skb,
626 PCI_DMA_FROMDEVICE); 657 PCI_DMA_FROMDEVICE);
627 dev_kfree_skb_any(skb); 658 dev_kfree_skb_any(skb);
628 } 659 }
629 card->evt_buf_list[i] = NULL; 660 card->evt_buf_list[i] = NULL;
@@ -861,7 +892,6 @@ static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter)
861static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter) 892static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter)
862{ 893{
863 struct pcie_service_card *card; 894 struct pcie_service_card *card;
864 dma_addr_t buf_pa;
865 895
866 if (!adapter) 896 if (!adapter)
867 return 0; 897 return 0;
@@ -869,16 +899,14 @@ static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter)
869 card = adapter->card; 899 card = adapter->card;
870 900
871 if (card && card->cmdrsp_buf) { 901 if (card && card->cmdrsp_buf) {
872 MWIFIEX_SKB_PACB(card->cmdrsp_buf, &buf_pa); 902 mwifiex_unmap_pci_memory(adapter, card->cmdrsp_buf,
873 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE, 903 PCI_DMA_FROMDEVICE);
874 PCI_DMA_FROMDEVICE);
875 dev_kfree_skb_any(card->cmdrsp_buf); 904 dev_kfree_skb_any(card->cmdrsp_buf);
876 } 905 }
877 906
878 if (card && card->cmd_buf) { 907 if (card && card->cmd_buf) {
879 MWIFIEX_SKB_PACB(card->cmd_buf, &buf_pa); 908 mwifiex_unmap_pci_memory(adapter, card->cmd_buf,
880 pci_unmap_single(card->dev, buf_pa, card->cmd_buf->len, 909 PCI_DMA_TODEVICE);
881 PCI_DMA_TODEVICE);
882 } 910 }
883 return 0; 911 return 0;
884} 912}
@@ -956,7 +984,6 @@ static int mwifiex_clean_pcie_ring_buf(struct mwifiex_adapter *adapter)
956static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter) 984static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter)
957{ 985{
958 struct sk_buff *skb; 986 struct sk_buff *skb;
959 dma_addr_t buf_pa;
960 u32 wrdoneidx, rdptr, num_tx_buffs, unmap_count = 0; 987 u32 wrdoneidx, rdptr, num_tx_buffs, unmap_count = 0;
961 struct mwifiex_pcie_buf_desc *desc; 988 struct mwifiex_pcie_buf_desc *desc;
962 struct mwifiex_pfu_buf_desc *desc2; 989 struct mwifiex_pfu_buf_desc *desc2;
@@ -986,13 +1013,13 @@ static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter)
986 reg->tx_start_ptr; 1013 reg->tx_start_ptr;
987 1014
988 skb = card->tx_buf_list[wrdoneidx]; 1015 skb = card->tx_buf_list[wrdoneidx];
1016
989 if (skb) { 1017 if (skb) {
990 dev_dbg(adapter->dev, 1018 dev_dbg(adapter->dev,
991 "SEND COMP: Detach skb %p at txbd_rdidx=%d\n", 1019 "SEND COMP: Detach skb %p at txbd_rdidx=%d\n",
992 skb, wrdoneidx); 1020 skb, wrdoneidx);
993 MWIFIEX_SKB_PACB(skb, &buf_pa); 1021 mwifiex_unmap_pci_memory(adapter, skb,
994 pci_unmap_single(card->dev, buf_pa, skb->len, 1022 PCI_DMA_TODEVICE);
995 PCI_DMA_TODEVICE);
996 1023
997 unmap_count++; 1024 unmap_count++;
998 1025
@@ -1082,12 +1109,12 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb,
1082 tmp = (__le16 *)&payload[2]; 1109 tmp = (__le16 *)&payload[2];
1083 *tmp = cpu_to_le16(MWIFIEX_TYPE_DATA); 1110 *tmp = cpu_to_le16(MWIFIEX_TYPE_DATA);
1084 1111
1085 if (mwifiex_map_pci_memory(adapter, skb, skb->len , 1112 if (mwifiex_map_pci_memory(adapter, skb, skb->len,
1086 PCI_DMA_TODEVICE)) 1113 PCI_DMA_TODEVICE))
1087 return -1; 1114 return -1;
1088 1115
1089 wrindx = (card->txbd_wrptr & reg->tx_mask) >> reg->tx_start_ptr; 1116 wrindx = (card->txbd_wrptr & reg->tx_mask) >> reg->tx_start_ptr;
1090 MWIFIEX_SKB_PACB(skb, &buf_pa); 1117 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
1091 card->tx_buf_list[wrindx] = skb; 1118 card->tx_buf_list[wrindx] = skb;
1092 1119
1093 if (reg->pfu_enabled) { 1120 if (reg->pfu_enabled) {
@@ -1162,8 +1189,7 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb,
1162 1189
1163 return -EINPROGRESS; 1190 return -EINPROGRESS;
1164done_unmap: 1191done_unmap:
1165 MWIFIEX_SKB_PACB(skb, &buf_pa); 1192 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
1166 pci_unmap_single(card->dev, buf_pa, skb->len, PCI_DMA_TODEVICE);
1167 card->tx_buf_list[wrindx] = NULL; 1193 card->tx_buf_list[wrindx] = NULL;
1168 if (reg->pfu_enabled) 1194 if (reg->pfu_enabled)
1169 memset(desc2, 0, sizeof(*desc2)); 1195 memset(desc2, 0, sizeof(*desc2));
@@ -1217,9 +1243,7 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
1217 if (!skb_data) 1243 if (!skb_data)
1218 return -ENOMEM; 1244 return -ENOMEM;
1219 1245
1220 MWIFIEX_SKB_PACB(skb_data, &buf_pa); 1246 mwifiex_unmap_pci_memory(adapter, skb_data, PCI_DMA_FROMDEVICE);
1221 pci_unmap_single(card->dev, buf_pa, MWIFIEX_RX_DATA_BUF_SIZE,
1222 PCI_DMA_FROMDEVICE);
1223 card->rx_buf_list[rd_index] = NULL; 1247 card->rx_buf_list[rd_index] = NULL;
1224 1248
1225 /* Get data length from interface header - 1249 /* Get data length from interface header -
@@ -1246,7 +1270,7 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
1246 PCI_DMA_FROMDEVICE)) 1270 PCI_DMA_FROMDEVICE))
1247 return -1; 1271 return -1;
1248 1272
1249 MWIFIEX_SKB_PACB(skb_tmp, &buf_pa); 1273 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb_tmp);
1250 1274
1251 dev_dbg(adapter->dev, 1275 dev_dbg(adapter->dev,
1252 "RECV DATA: Attach new sk_buff %p at rxbd_rdidx=%d\n", 1276 "RECV DATA: Attach new sk_buff %p at rxbd_rdidx=%d\n",
@@ -1322,7 +1346,7 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1322 if (mwifiex_map_pci_memory(adapter, skb, skb->len , PCI_DMA_TODEVICE)) 1346 if (mwifiex_map_pci_memory(adapter, skb, skb->len , PCI_DMA_TODEVICE))
1323 return -1; 1347 return -1;
1324 1348
1325 MWIFIEX_SKB_PACB(skb, &buf_pa); 1349 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
1326 1350
1327 /* Write the lower 32bits of the physical address to low command 1351 /* Write the lower 32bits of the physical address to low command
1328 * address scratch register 1352 * address scratch register
@@ -1331,8 +1355,7 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1331 dev_err(adapter->dev, 1355 dev_err(adapter->dev,
1332 "%s: failed to write download command to boot code.\n", 1356 "%s: failed to write download command to boot code.\n",
1333 __func__); 1357 __func__);
1334 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE, 1358 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
1335 PCI_DMA_TODEVICE);
1336 return -1; 1359 return -1;
1337 } 1360 }
1338 1361
@@ -1344,8 +1367,7 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1344 dev_err(adapter->dev, 1367 dev_err(adapter->dev,
1345 "%s: failed to write download command to boot code.\n", 1368 "%s: failed to write download command to boot code.\n",
1346 __func__); 1369 __func__);
1347 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE, 1370 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
1348 PCI_DMA_TODEVICE);
1349 return -1; 1371 return -1;
1350 } 1372 }
1351 1373
@@ -1354,8 +1376,7 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1354 dev_err(adapter->dev, 1376 dev_err(adapter->dev,
1355 "%s: failed to write command len to cmd_size scratch reg\n", 1377 "%s: failed to write command len to cmd_size scratch reg\n",
1356 __func__); 1378 __func__);
1357 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE, 1379 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
1358 PCI_DMA_TODEVICE);
1359 return -1; 1380 return -1;
1360 } 1381 }
1361 1382
@@ -1364,8 +1385,7 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1364 CPU_INTR_DOOR_BELL)) { 1385 CPU_INTR_DOOR_BELL)) {
1365 dev_err(adapter->dev, 1386 dev_err(adapter->dev,
1366 "%s: failed to assert door-bell intr\n", __func__); 1387 "%s: failed to assert door-bell intr\n", __func__);
1367 pci_unmap_single(card->dev, buf_pa, 1388 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
1368 MWIFIEX_UPLD_SIZE, PCI_DMA_TODEVICE);
1369 return -1; 1389 return -1;
1370 } 1390 }
1371 1391
@@ -1439,7 +1459,7 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1439 */ 1459 */
1440 1460
1441 if (card->cmdrsp_buf) { 1461 if (card->cmdrsp_buf) {
1442 MWIFIEX_SKB_PACB(card->cmdrsp_buf, &cmdrsp_buf_pa); 1462 cmdrsp_buf_pa = MWIFIEX_SKB_DMA_ADDR(card->cmdrsp_buf);
1443 /* Write the lower 32bits of the cmdrsp buffer physical 1463 /* Write the lower 32bits of the cmdrsp buffer physical
1444 address */ 1464 address */
1445 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo, 1465 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo,
@@ -1460,7 +1480,7 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1460 } 1480 }
1461 } 1481 }
1462 1482
1463 MWIFIEX_SKB_PACB(card->cmd_buf, &cmd_buf_pa); 1483 cmd_buf_pa = MWIFIEX_SKB_DMA_ADDR(card->cmd_buf);
1464 /* Write the lower 32bits of the physical address to reg->cmd_addr_lo */ 1484 /* Write the lower 32bits of the physical address to reg->cmd_addr_lo */
1465 if (mwifiex_write_reg(adapter, reg->cmd_addr_lo, 1485 if (mwifiex_write_reg(adapter, reg->cmd_addr_lo,
1466 (u32)cmd_buf_pa)) { 1486 (u32)cmd_buf_pa)) {
@@ -1514,13 +1534,17 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
1514 int count = 0; 1534 int count = 0;
1515 u16 rx_len; 1535 u16 rx_len;
1516 __le16 pkt_len; 1536 __le16 pkt_len;
1517 dma_addr_t buf_pa;
1518 1537
1519 dev_dbg(adapter->dev, "info: Rx CMD Response\n"); 1538 dev_dbg(adapter->dev, "info: Rx CMD Response\n");
1520 1539
1521 MWIFIEX_SKB_PACB(skb, &buf_pa); 1540 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_FROMDEVICE);
1522 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE, 1541
1523 PCI_DMA_FROMDEVICE); 1542 /* Unmap the command as a response has been received. */
1543 if (card->cmd_buf) {
1544 mwifiex_unmap_pci_memory(adapter, card->cmd_buf,
1545 PCI_DMA_TODEVICE);
1546 card->cmd_buf = NULL;
1547 }
1524 1548
1525 pkt_len = *((__le16 *)skb->data); 1549 pkt_len = *((__le16 *)skb->data);
1526 rx_len = le16_to_cpu(pkt_len); 1550 rx_len = le16_to_cpu(pkt_len);
@@ -1539,6 +1563,8 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
1539 "Write register failed\n"); 1563 "Write register failed\n");
1540 return -1; 1564 return -1;
1541 } 1565 }
1566 mwifiex_delay_for_sleep_cookie(adapter,
1567 MWIFIEX_MAX_DELAY_COUNT);
1542 while (reg->sleep_cookie && (count++ < 10) && 1568 while (reg->sleep_cookie && (count++ < 10) &&
1543 mwifiex_pcie_ok_to_access_hw(adapter)) 1569 mwifiex_pcie_ok_to_access_hw(adapter))
1544 usleep_range(50, 60); 1570 usleep_range(50, 60);
@@ -1552,8 +1578,6 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
1552 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE, 1578 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
1553 PCI_DMA_FROMDEVICE)) 1579 PCI_DMA_FROMDEVICE))
1554 return -1; 1580 return -1;
1555
1556 MWIFIEX_SKB_PACB(skb, &buf_pa);
1557 } else if (mwifiex_pcie_ok_to_access_hw(adapter)) { 1581 } else if (mwifiex_pcie_ok_to_access_hw(adapter)) {
1558 adapter->curr_cmd->resp_skb = skb; 1582 adapter->curr_cmd->resp_skb = skb;
1559 adapter->cmd_resp_received = true; 1583 adapter->cmd_resp_received = true;
@@ -1588,8 +1612,6 @@ static int mwifiex_pcie_cmdrsp_complete(struct mwifiex_adapter *adapter,
1588 struct sk_buff *skb) 1612 struct sk_buff *skb)
1589{ 1613{
1590 struct pcie_service_card *card = adapter->card; 1614 struct pcie_service_card *card = adapter->card;
1591 dma_addr_t buf_pa;
1592 struct sk_buff *skb_tmp;
1593 1615
1594 if (skb) { 1616 if (skb) {
1595 card->cmdrsp_buf = skb; 1617 card->cmdrsp_buf = skb;
@@ -1599,14 +1621,6 @@ static int mwifiex_pcie_cmdrsp_complete(struct mwifiex_adapter *adapter,
1599 return -1; 1621 return -1;
1600 } 1622 }
1601 1623
1602 skb_tmp = card->cmd_buf;
1603 if (skb_tmp) {
1604 MWIFIEX_SKB_PACB(skb_tmp, &buf_pa);
1605 pci_unmap_single(card->dev, buf_pa, skb_tmp->len,
1606 PCI_DMA_FROMDEVICE);
1607 card->cmd_buf = NULL;
1608 }
1609
1610 return 0; 1624 return 0;
1611} 1625}
1612 1626
@@ -1619,7 +1633,6 @@ static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter)
1619 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; 1633 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
1620 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK; 1634 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
1621 u32 wrptr, event; 1635 u32 wrptr, event;
1622 dma_addr_t buf_pa;
1623 struct mwifiex_evt_buf_desc *desc; 1636 struct mwifiex_evt_buf_desc *desc;
1624 1637
1625 if (!mwifiex_pcie_ok_to_access_hw(adapter)) 1638 if (!mwifiex_pcie_ok_to_access_hw(adapter))
@@ -1655,9 +1668,7 @@ static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter)
1655 1668
1656 dev_dbg(adapter->dev, "info: Read Index: %d\n", rdptr); 1669 dev_dbg(adapter->dev, "info: Read Index: %d\n", rdptr);
1657 skb_cmd = card->evt_buf_list[rdptr]; 1670 skb_cmd = card->evt_buf_list[rdptr];
1658 MWIFIEX_SKB_PACB(skb_cmd, &buf_pa); 1671 mwifiex_unmap_pci_memory(adapter, skb_cmd, PCI_DMA_FROMDEVICE);
1659 pci_unmap_single(card->dev, buf_pa, MAX_EVENT_SIZE,
1660 PCI_DMA_FROMDEVICE);
1661 1672
1662 /* Take the pointer and set it to event pointer in adapter 1673 /* Take the pointer and set it to event pointer in adapter
1663 and will return back after event handling callback */ 1674 and will return back after event handling callback */
@@ -1703,7 +1714,6 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter,
1703 int ret = 0; 1714 int ret = 0;
1704 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK; 1715 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
1705 u32 wrptr; 1716 u32 wrptr;
1706 dma_addr_t buf_pa;
1707 struct mwifiex_evt_buf_desc *desc; 1717 struct mwifiex_evt_buf_desc *desc;
1708 1718
1709 if (!skb) 1719 if (!skb)
@@ -1728,11 +1738,9 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter,
1728 MAX_EVENT_SIZE, 1738 MAX_EVENT_SIZE,
1729 PCI_DMA_FROMDEVICE)) 1739 PCI_DMA_FROMDEVICE))
1730 return -1; 1740 return -1;
1731 MWIFIEX_SKB_PACB(skb, &buf_pa);
1732 card->evt_buf_list[rdptr] = skb; 1741 card->evt_buf_list[rdptr] = skb;
1733 MWIFIEX_SKB_PACB(skb, &buf_pa);
1734 desc = card->evtbd_ring[rdptr]; 1742 desc = card->evtbd_ring[rdptr];
1735 desc->paddr = buf_pa; 1743 desc->paddr = MWIFIEX_SKB_DMA_ADDR(skb);
1736 desc->len = (u16)skb->len; 1744 desc->len = (u16)skb->len;
1737 desc->flags = 0; 1745 desc->flags = 0;
1738 skb = NULL; 1746 skb = NULL;
@@ -1782,7 +1790,6 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
1782 struct sk_buff *skb; 1790 struct sk_buff *skb;
1783 u32 txlen, tx_blocks = 0, tries, len; 1791 u32 txlen, tx_blocks = 0, tries, len;
1784 u32 block_retry_cnt = 0; 1792 u32 block_retry_cnt = 0;
1785 dma_addr_t buf_pa;
1786 struct pcie_service_card *card = adapter->card; 1793 struct pcie_service_card *card = adapter->card;
1787 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; 1794 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
1788 1795
@@ -1880,8 +1887,6 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
1880 goto done; 1887 goto done;
1881 } 1888 }
1882 1889
1883 MWIFIEX_SKB_PACB(skb, &buf_pa);
1884
1885 /* Wait for the command done interrupt */ 1890 /* Wait for the command done interrupt */
1886 do { 1891 do {
1887 if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS, 1892 if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS,
@@ -1889,16 +1894,15 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
1889 dev_err(adapter->dev, "%s: Failed to read " 1894 dev_err(adapter->dev, "%s: Failed to read "
1890 "interrupt status during fw dnld.\n", 1895 "interrupt status during fw dnld.\n",
1891 __func__); 1896 __func__);
1892 pci_unmap_single(card->dev, buf_pa, skb->len, 1897 mwifiex_unmap_pci_memory(adapter, skb,
1893 PCI_DMA_TODEVICE); 1898 PCI_DMA_TODEVICE);
1894 ret = -1; 1899 ret = -1;
1895 goto done; 1900 goto done;
1896 } 1901 }
1897 } while ((ireg_intr & CPU_INTR_DOOR_BELL) == 1902 } while ((ireg_intr & CPU_INTR_DOOR_BELL) ==
1898 CPU_INTR_DOOR_BELL); 1903 CPU_INTR_DOOR_BELL);
1899 1904
1900 pci_unmap_single(card->dev, buf_pa, skb->len, 1905 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
1901 PCI_DMA_TODEVICE);
1902 1906
1903 offset += txlen; 1907 offset += txlen;
1904 } while (true); 1908 } while (true);
@@ -2338,6 +2342,7 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
2338 } 2342 }
2339 2343
2340 adapter->dev = &pdev->dev; 2344 adapter->dev = &pdev->dev;
2345 adapter->tx_buf_size = card->pcie.tx_buf_size;
2341 strcpy(adapter->fw_name, card->pcie.firmware); 2346 strcpy(adapter->fw_name, card->pcie.firmware);
2342 2347
2343 return 0; 2348 return 0;
diff --git a/drivers/net/wireless/mwifiex/pcie.h b/drivers/net/wireless/mwifiex/pcie.h
index d322ab8604ea..e8ec561f8a64 100644
--- a/drivers/net/wireless/mwifiex/pcie.h
+++ b/drivers/net/wireless/mwifiex/pcie.h
@@ -97,6 +97,8 @@
97#define MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD 256 97#define MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD 256
98/* FW awake cookie after FW ready */ 98/* FW awake cookie after FW ready */
99#define FW_AWAKE_COOKIE (0xAA55AA55) 99#define FW_AWAKE_COOKIE (0xAA55AA55)
100#define MWIFIEX_DEF_SLEEP_COOKIE 0xBEEFBEEF
101#define MWIFIEX_MAX_DELAY_COUNT 5
100 102
101struct mwifiex_pcie_card_reg { 103struct mwifiex_pcie_card_reg {
102 u16 cmd_addr_lo; 104 u16 cmd_addr_lo;
@@ -195,18 +197,21 @@ struct mwifiex_pcie_device {
195 const char *firmware; 197 const char *firmware;
196 const struct mwifiex_pcie_card_reg *reg; 198 const struct mwifiex_pcie_card_reg *reg;
197 u16 blksz_fw_dl; 199 u16 blksz_fw_dl;
200 u16 tx_buf_size;
198}; 201};
199 202
200static const struct mwifiex_pcie_device mwifiex_pcie8766 = { 203static const struct mwifiex_pcie_device mwifiex_pcie8766 = {
201 .firmware = PCIE8766_DEFAULT_FW_NAME, 204 .firmware = PCIE8766_DEFAULT_FW_NAME,
202 .reg = &mwifiex_reg_8766, 205 .reg = &mwifiex_reg_8766,
203 .blksz_fw_dl = MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD, 206 .blksz_fw_dl = MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD,
207 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,
204}; 208};
205 209
206static const struct mwifiex_pcie_device mwifiex_pcie8897 = { 210static const struct mwifiex_pcie_device mwifiex_pcie8897 = {
207 .firmware = PCIE8897_DEFAULT_FW_NAME, 211 .firmware = PCIE8897_DEFAULT_FW_NAME,
208 .reg = &mwifiex_reg_8897, 212 .reg = &mwifiex_reg_8897,
209 .blksz_fw_dl = MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD, 213 .blksz_fw_dl = MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD,
214 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K,
210}; 215};
211 216
212struct mwifiex_evt_buf_desc { 217struct mwifiex_evt_buf_desc {
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index 668547c2de84..f13924447a2c 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -595,7 +595,7 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv,
595 struct mwifiex_chan_scan_param_set *tmp_chan_list; 595 struct mwifiex_chan_scan_param_set *tmp_chan_list;
596 struct mwifiex_chan_scan_param_set *start_chan; 596 struct mwifiex_chan_scan_param_set *start_chan;
597 597
598 u32 tlv_idx, rates_size; 598 u32 tlv_idx, rates_size, cmd_no;
599 u32 total_scan_time; 599 u32 total_scan_time;
600 u32 done_early; 600 u32 done_early;
601 u8 radio_type; 601 u8 radio_type;
@@ -733,9 +733,13 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv,
733 733
734 /* Send the scan command to the firmware with the specified 734 /* Send the scan command to the firmware with the specified
735 cfg */ 735 cfg */
736 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_SCAN, 736 if (priv->adapter->ext_scan)
737 HostCmd_ACT_GEN_SET, 0, 737 cmd_no = HostCmd_CMD_802_11_SCAN_EXT;
738 scan_cfg_out); 738 else
739 cmd_no = HostCmd_CMD_802_11_SCAN;
740
741 ret = mwifiex_send_cmd(priv, cmd_no, HostCmd_ACT_GEN_SET,
742 0, scan_cfg_out, false);
739 743
740 /* rate IE is updated per scan command but same starting 744 /* rate IE is updated per scan command but same starting
741 * pointer is used each time so that rate IE from earlier 745 * pointer is used each time so that rate IE from earlier
@@ -786,6 +790,7 @@ mwifiex_config_scan(struct mwifiex_private *priv,
786 struct mwifiex_adapter *adapter = priv->adapter; 790 struct mwifiex_adapter *adapter = priv->adapter;
787 struct mwifiex_ie_types_num_probes *num_probes_tlv; 791 struct mwifiex_ie_types_num_probes *num_probes_tlv;
788 struct mwifiex_ie_types_wildcard_ssid_params *wildcard_ssid_tlv; 792 struct mwifiex_ie_types_wildcard_ssid_params *wildcard_ssid_tlv;
793 struct mwifiex_ie_types_bssid_list *bssid_tlv;
789 u8 *tlv_pos; 794 u8 *tlv_pos;
790 u32 num_probes; 795 u32 num_probes;
791 u32 ssid_len; 796 u32 ssid_len;
@@ -848,6 +853,17 @@ mwifiex_config_scan(struct mwifiex_private *priv,
848 user_scan_in->specific_bssid, 853 user_scan_in->specific_bssid,
849 sizeof(scan_cfg_out->specific_bssid)); 854 sizeof(scan_cfg_out->specific_bssid));
850 855
856 if (adapter->ext_scan &&
857 !is_zero_ether_addr(scan_cfg_out->specific_bssid)) {
858 bssid_tlv =
859 (struct mwifiex_ie_types_bssid_list *)tlv_pos;
860 bssid_tlv->header.type = cpu_to_le16(TLV_TYPE_BSSID);
861 bssid_tlv->header.len = cpu_to_le16(ETH_ALEN);
862 memcpy(bssid_tlv->bssid, user_scan_in->specific_bssid,
863 ETH_ALEN);
864 tlv_pos += sizeof(struct mwifiex_ie_types_bssid_list);
865 }
866
851 for (i = 0; i < user_scan_in->num_ssids; i++) { 867 for (i = 0; i < user_scan_in->num_ssids; i++) {
852 ssid_len = user_scan_in->ssid_list[i].ssid_len; 868 ssid_len = user_scan_in->ssid_list[i].ssid_len;
853 869
@@ -941,7 +957,7 @@ mwifiex_config_scan(struct mwifiex_private *priv,
941 cpu_to_le16(sizeof(struct ieee80211_ht_cap)); 957 cpu_to_le16(sizeof(struct ieee80211_ht_cap));
942 radio_type = 958 radio_type =
943 mwifiex_band_to_radio_type(priv->adapter->config_bands); 959 mwifiex_band_to_radio_type(priv->adapter->config_bands);
944 mwifiex_fill_cap_info(priv, radio_type, ht_cap); 960 mwifiex_fill_cap_info(priv, radio_type, &ht_cap->ht_cap);
945 tlv_pos += sizeof(struct mwifiex_ie_types_htcap); 961 tlv_pos += sizeof(struct mwifiex_ie_types_htcap);
946 } 962 }
947 963
@@ -1576,6 +1592,228 @@ done:
1576 return 0; 1592 return 0;
1577} 1593}
1578 1594
1595static int
1596mwifiex_parse_single_response_buf(struct mwifiex_private *priv, u8 **bss_info,
1597 u32 *bytes_left, u64 fw_tsf, u8 *radio_type,
1598 bool ext_scan, s32 rssi_val)
1599{
1600 struct mwifiex_adapter *adapter = priv->adapter;
1601 struct mwifiex_chan_freq_power *cfp;
1602 struct cfg80211_bss *bss;
1603 u8 bssid[ETH_ALEN];
1604 s32 rssi;
1605 const u8 *ie_buf;
1606 size_t ie_len;
1607 u16 channel = 0;
1608 u16 beacon_size = 0;
1609 u32 curr_bcn_bytes;
1610 u32 freq;
1611 u16 beacon_period;
1612 u16 cap_info_bitmap;
1613 u8 *current_ptr;
1614 u64 timestamp;
1615 struct mwifiex_fixed_bcn_param *bcn_param;
1616 struct mwifiex_bss_priv *bss_priv;
1617
1618 if (*bytes_left >= sizeof(beacon_size)) {
1619 /* Extract & convert beacon size from command buffer */
1620 memcpy(&beacon_size, *bss_info, sizeof(beacon_size));
1621 *bytes_left -= sizeof(beacon_size);
1622 *bss_info += sizeof(beacon_size);
1623 }
1624
1625 if (!beacon_size || beacon_size > *bytes_left) {
1626 *bss_info += *bytes_left;
1627 *bytes_left = 0;
1628 return -EFAULT;
1629 }
1630
1631 /* Initialize the current working beacon pointer for this BSS
1632 * iteration
1633 */
1634 current_ptr = *bss_info;
1635
1636 /* Advance the return beacon pointer past the current beacon */
1637 *bss_info += beacon_size;
1638 *bytes_left -= beacon_size;
1639
1640 curr_bcn_bytes = beacon_size;
1641
1642 /* First 5 fields are bssid, RSSI(for legacy scan only),
1643 * time stamp, beacon interval, and capability information
1644 */
1645 if (curr_bcn_bytes < ETH_ALEN + sizeof(u8) +
1646 sizeof(struct mwifiex_fixed_bcn_param)) {
1647 dev_err(adapter->dev, "InterpretIE: not enough bytes left\n");
1648 return -EFAULT;
1649 }
1650
1651 memcpy(bssid, current_ptr, ETH_ALEN);
1652 current_ptr += ETH_ALEN;
1653 curr_bcn_bytes -= ETH_ALEN;
1654
1655 if (!ext_scan) {
1656 rssi = (s32) *(u8 *)current_ptr;
1657 rssi = (-rssi) * 100; /* Convert dBm to mBm */
1658 current_ptr += sizeof(u8);
1659 curr_bcn_bytes -= sizeof(u8);
1660 dev_dbg(adapter->dev, "info: InterpretIE: RSSI=%d\n", rssi);
1661 } else {
1662 rssi = rssi_val;
1663 }
1664
1665 bcn_param = (struct mwifiex_fixed_bcn_param *)current_ptr;
1666 current_ptr += sizeof(*bcn_param);
1667 curr_bcn_bytes -= sizeof(*bcn_param);
1668
1669 timestamp = le64_to_cpu(bcn_param->timestamp);
1670 beacon_period = le16_to_cpu(bcn_param->beacon_period);
1671
1672 cap_info_bitmap = le16_to_cpu(bcn_param->cap_info_bitmap);
1673 dev_dbg(adapter->dev, "info: InterpretIE: capabilities=0x%X\n",
1674 cap_info_bitmap);
1675
1676 /* Rest of the current buffer are IE's */
1677 ie_buf = current_ptr;
1678 ie_len = curr_bcn_bytes;
1679 dev_dbg(adapter->dev, "info: InterpretIE: IELength for this AP = %d\n",
1680 curr_bcn_bytes);
1681
1682 while (curr_bcn_bytes >= sizeof(struct ieee_types_header)) {
1683 u8 element_id, element_len;
1684
1685 element_id = *current_ptr;
1686 element_len = *(current_ptr + 1);
1687 if (curr_bcn_bytes < element_len +
1688 sizeof(struct ieee_types_header)) {
1689 dev_err(adapter->dev,
1690 "%s: bytes left < IE length\n", __func__);
1691 return -EFAULT;
1692 }
1693 if (element_id == WLAN_EID_DS_PARAMS) {
1694 channel = *(current_ptr +
1695 sizeof(struct ieee_types_header));
1696 break;
1697 }
1698
1699 current_ptr += element_len + sizeof(struct ieee_types_header);
1700 curr_bcn_bytes -= element_len +
1701 sizeof(struct ieee_types_header);
1702 }
1703
1704 if (channel) {
1705 struct ieee80211_channel *chan;
1706 u8 band;
1707
1708 /* Skip entry if on csa closed channel */
1709 if (channel == priv->csa_chan) {
1710 dev_dbg(adapter->dev,
1711 "Dropping entry on csa closed channel\n");
1712 return 0;
1713 }
1714
1715 band = BAND_G;
1716 if (radio_type)
1717 band = mwifiex_radio_type_to_band(*radio_type &
1718 (BIT(0) | BIT(1)));
1719
1720 cfp = mwifiex_get_cfp(priv, band, channel, 0);
1721
1722 freq = cfp ? cfp->freq : 0;
1723
1724 chan = ieee80211_get_channel(priv->wdev->wiphy, freq);
1725
1726 if (chan && !(chan->flags & IEEE80211_CHAN_DISABLED)) {
1727 bss = cfg80211_inform_bss(priv->wdev->wiphy,
1728 chan, bssid, timestamp,
1729 cap_info_bitmap, beacon_period,
1730 ie_buf, ie_len, rssi, GFP_KERNEL);
1731 bss_priv = (struct mwifiex_bss_priv *)bss->priv;
1732 bss_priv->band = band;
1733 bss_priv->fw_tsf = fw_tsf;
1734 if (priv->media_connected &&
1735 !memcmp(bssid, priv->curr_bss_params.bss_descriptor
1736 .mac_address, ETH_ALEN))
1737 mwifiex_update_curr_bss_params(priv, bss);
1738 cfg80211_put_bss(priv->wdev->wiphy, bss);
1739 }
1740 } else {
1741 dev_dbg(adapter->dev, "missing BSS channel IE\n");
1742 }
1743
1744 return 0;
1745}
1746
1747static void mwifiex_check_next_scan_command(struct mwifiex_private *priv)
1748{
1749 struct mwifiex_adapter *adapter = priv->adapter;
1750 struct cmd_ctrl_node *cmd_node;
1751 unsigned long flags;
1752
1753 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
1754 if (list_empty(&adapter->scan_pending_q)) {
1755 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
1756 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
1757 adapter->scan_processing = false;
1758 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
1759
1760 /* Need to indicate IOCTL complete */
1761 if (adapter->curr_cmd->wait_q_enabled) {
1762 adapter->cmd_wait_q.status = 0;
1763 if (!priv->scan_request) {
1764 dev_dbg(adapter->dev,
1765 "complete internal scan\n");
1766 mwifiex_complete_cmd(adapter,
1767 adapter->curr_cmd);
1768 }
1769 }
1770 if (priv->report_scan_result)
1771 priv->report_scan_result = false;
1772
1773 if (priv->scan_request) {
1774 dev_dbg(adapter->dev, "info: notifying scan done\n");
1775 cfg80211_scan_done(priv->scan_request, 0);
1776 priv->scan_request = NULL;
1777 } else {
1778 priv->scan_aborting = false;
1779 dev_dbg(adapter->dev, "info: scan already aborted\n");
1780 }
1781 } else {
1782 if ((priv->scan_aborting && !priv->scan_request) ||
1783 priv->scan_block) {
1784 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1785 flags);
1786 adapter->scan_delay_cnt = MWIFIEX_MAX_SCAN_DELAY_CNT;
1787 mod_timer(&priv->scan_delay_timer, jiffies);
1788 dev_dbg(priv->adapter->dev,
1789 "info: %s: triggerring scan abort\n", __func__);
1790 } else if (!mwifiex_wmm_lists_empty(adapter) &&
1791 (priv->scan_request && (priv->scan_request->flags &
1792 NL80211_SCAN_FLAG_LOW_PRIORITY))) {
1793 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1794 flags);
1795 adapter->scan_delay_cnt = 1;
1796 mod_timer(&priv->scan_delay_timer, jiffies +
1797 msecs_to_jiffies(MWIFIEX_SCAN_DELAY_MSEC));
1798 dev_dbg(priv->adapter->dev,
1799 "info: %s: deferring scan\n", __func__);
1800 } else {
1801 /* Get scan command from scan_pending_q and put to
1802 * cmd_pending_q
1803 */
1804 cmd_node = list_first_entry(&adapter->scan_pending_q,
1805 struct cmd_ctrl_node, list);
1806 list_del(&cmd_node->list);
1807 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1808 flags);
1809 mwifiex_insert_cmd_to_pending_q(adapter, cmd_node,
1810 true);
1811 }
1812 }
1813
1814 return;
1815}
1816
1579/* 1817/*
1580 * This function handles the command response of scan. 1818 * This function handles the command response of scan.
1581 * 1819 *
@@ -1600,7 +1838,6 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
1600{ 1838{
1601 int ret = 0; 1839 int ret = 0;
1602 struct mwifiex_adapter *adapter = priv->adapter; 1840 struct mwifiex_adapter *adapter = priv->adapter;
1603 struct cmd_ctrl_node *cmd_node;
1604 struct host_cmd_ds_802_11_scan_rsp *scan_rsp; 1841 struct host_cmd_ds_802_11_scan_rsp *scan_rsp;
1605 struct mwifiex_ie_types_data *tlv_data; 1842 struct mwifiex_ie_types_data *tlv_data;
1606 struct mwifiex_ie_types_tsf_timestamp *tsf_tlv; 1843 struct mwifiex_ie_types_tsf_timestamp *tsf_tlv;
@@ -1609,12 +1846,11 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
1609 u32 bytes_left; 1846 u32 bytes_left;
1610 u32 idx; 1847 u32 idx;
1611 u32 tlv_buf_size; 1848 u32 tlv_buf_size;
1612 struct mwifiex_chan_freq_power *cfp;
1613 struct mwifiex_ie_types_chan_band_list_param_set *chan_band_tlv; 1849 struct mwifiex_ie_types_chan_band_list_param_set *chan_band_tlv;
1614 struct chan_band_param_set *chan_band; 1850 struct chan_band_param_set *chan_band;
1615 u8 is_bgscan_resp; 1851 u8 is_bgscan_resp;
1616 unsigned long flags; 1852 __le64 fw_tsf = 0;
1617 struct cfg80211_bss *bss; 1853 u8 *radio_type;
1618 1854
1619 is_bgscan_resp = (le16_to_cpu(resp->command) 1855 is_bgscan_resp = (le16_to_cpu(resp->command)
1620 == HostCmd_CMD_802_11_BG_SCAN_QUERY); 1856 == HostCmd_CMD_802_11_BG_SCAN_QUERY);
@@ -1676,220 +1912,194 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
1676 &chan_band_tlv); 1912 &chan_band_tlv);
1677 1913
1678 for (idx = 0; idx < scan_rsp->number_of_sets && bytes_left; idx++) { 1914 for (idx = 0; idx < scan_rsp->number_of_sets && bytes_left; idx++) {
1679 u8 bssid[ETH_ALEN]; 1915 /*
1680 s32 rssi; 1916 * If the TSF TLV was appended to the scan results, save this
1681 const u8 *ie_buf; 1917 * entry's TSF value in the fw_tsf field. It is the firmware's
1682 size_t ie_len; 1918 * TSF value at the time the beacon or probe response was
1683 u16 channel = 0; 1919 * received.
1684 __le64 fw_tsf = 0; 1920 */
1685 u16 beacon_size = 0; 1921 if (tsf_tlv)
1686 u32 curr_bcn_bytes; 1922 memcpy(&fw_tsf, &tsf_tlv->tsf_data[idx * TSF_DATA_SIZE],
1687 u32 freq; 1923 sizeof(fw_tsf));
1688 u16 beacon_period;
1689 u16 cap_info_bitmap;
1690 u8 *current_ptr;
1691 u64 timestamp;
1692 struct mwifiex_bcn_param *bcn_param;
1693 struct mwifiex_bss_priv *bss_priv;
1694
1695 if (bytes_left >= sizeof(beacon_size)) {
1696 /* Extract & convert beacon size from command buffer */
1697 memcpy(&beacon_size, bss_info, sizeof(beacon_size));
1698 bytes_left -= sizeof(beacon_size);
1699 bss_info += sizeof(beacon_size);
1700 }
1701 1924
1702 if (!beacon_size || beacon_size > bytes_left) { 1925 if (chan_band_tlv) {
1703 bss_info += bytes_left; 1926 chan_band = &chan_band_tlv->chan_band_param[idx];
1704 bytes_left = 0; 1927 radio_type = &chan_band->radio_type;
1705 ret = -1; 1928 } else {
1706 goto check_next_scan; 1929 radio_type = NULL;
1707 } 1930 }
1708 1931
1709 /* Initialize the current working beacon pointer for this BSS 1932 ret = mwifiex_parse_single_response_buf(priv, &bss_info,
1710 * iteration */ 1933 &bytes_left,
1711 current_ptr = bss_info; 1934 le64_to_cpu(fw_tsf),
1935 radio_type, false, 0);
1936 if (ret)
1937 goto check_next_scan;
1938 }
1712 1939
1713 /* Advance the return beacon pointer past the current beacon */ 1940check_next_scan:
1714 bss_info += beacon_size; 1941 mwifiex_check_next_scan_command(priv);
1715 bytes_left -= beacon_size; 1942 return ret;
1943}
1716 1944
1717 curr_bcn_bytes = beacon_size; 1945/*
1946 * This function prepares an extended scan command to be sent to the firmware
1947 *
1948 * This uses the scan command configuration sent to the command processing
1949 * module in command preparation stage to configure a extended scan command
1950 * structure to send to firmware.
1951 */
1952int mwifiex_cmd_802_11_scan_ext(struct mwifiex_private *priv,
1953 struct host_cmd_ds_command *cmd,
1954 void *data_buf)
1955{
1956 struct host_cmd_ds_802_11_scan_ext *ext_scan = &cmd->params.ext_scan;
1957 struct mwifiex_scan_cmd_config *scan_cfg = data_buf;
1718 1958
1719 /* 1959 memcpy(ext_scan->tlv_buffer, scan_cfg->tlv_buf, scan_cfg->tlv_buf_len);
1720 * First 5 fields are bssid, RSSI, time stamp, beacon interval,
1721 * and capability information
1722 */
1723 if (curr_bcn_bytes < sizeof(struct mwifiex_bcn_param)) {
1724 dev_err(adapter->dev,
1725 "InterpretIE: not enough bytes left\n");
1726 continue;
1727 }
1728 bcn_param = (struct mwifiex_bcn_param *)current_ptr;
1729 current_ptr += sizeof(*bcn_param);
1730 curr_bcn_bytes -= sizeof(*bcn_param);
1731 1960
1732 memcpy(bssid, bcn_param->bssid, ETH_ALEN); 1961 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_SCAN_EXT);
1733 1962
1734 rssi = (s32) bcn_param->rssi; 1963 /* Size is equal to the sizeof(fixed portions) + the TLV len + header */
1735 rssi = (-rssi) * 100; /* Convert dBm to mBm */ 1964 cmd->size = cpu_to_le16((u16)(sizeof(ext_scan->reserved)
1736 dev_dbg(adapter->dev, "info: InterpretIE: RSSI=%d\n", rssi); 1965 + scan_cfg->tlv_buf_len + S_DS_GEN));
1737 1966
1738 timestamp = le64_to_cpu(bcn_param->timestamp); 1967 return 0;
1739 beacon_period = le16_to_cpu(bcn_param->beacon_period); 1968}
1740 1969
1741 cap_info_bitmap = le16_to_cpu(bcn_param->cap_info_bitmap); 1970/* This function handles the command response of extended scan */
1742 dev_dbg(adapter->dev, "info: InterpretIE: capabilities=0x%X\n", 1971int mwifiex_ret_802_11_scan_ext(struct mwifiex_private *priv)
1743 cap_info_bitmap); 1972{
1973 dev_dbg(priv->adapter->dev, "info: EXT scan returns successfully\n");
1974 return 0;
1975}
1744 1976
1745 /* Rest of the current buffer are IE's */ 1977/* This function This function handles the event extended scan report. It
1746 ie_buf = current_ptr; 1978 * parses extended scan results and informs to cfg80211 stack.
1747 ie_len = curr_bcn_bytes; 1979 */
1748 dev_dbg(adapter->dev, 1980int mwifiex_handle_event_ext_scan_report(struct mwifiex_private *priv,
1749 "info: InterpretIE: IELength for this AP = %d\n", 1981 void *buf)
1750 curr_bcn_bytes); 1982{
1983 int ret = 0;
1984 struct mwifiex_adapter *adapter = priv->adapter;
1985 u8 *bss_info;
1986 u32 bytes_left, bytes_left_for_tlv, idx;
1987 u16 type, len;
1988 struct mwifiex_ie_types_data *tlv;
1989 struct mwifiex_ie_types_bss_scan_rsp *scan_rsp_tlv;
1990 struct mwifiex_ie_types_bss_scan_info *scan_info_tlv;
1991 u8 *radio_type;
1992 u64 fw_tsf = 0;
1993 s32 rssi = 0;
1994 struct mwifiex_event_scan_result *event_scan = buf;
1995 u8 num_of_set = event_scan->num_of_set;
1996 u8 *scan_resp = buf + sizeof(struct mwifiex_event_scan_result);
1997 u16 scan_resp_size = le16_to_cpu(event_scan->buf_size);
1998
1999 if (num_of_set > MWIFIEX_MAX_AP) {
2000 dev_err(adapter->dev,
2001 "EXT_SCAN: Invalid number of AP returned (%d)!!\n",
2002 num_of_set);
2003 ret = -1;
2004 goto check_next_scan;
2005 }
1751 2006
1752 while (curr_bcn_bytes >= sizeof(struct ieee_types_header)) { 2007 bytes_left = scan_resp_size;
1753 u8 element_id, element_len; 2008 dev_dbg(adapter->dev,
2009 "EXT_SCAN: size %d, returned %d APs...",
2010 scan_resp_size, num_of_set);
1754 2011
1755 element_id = *current_ptr; 2012 tlv = (struct mwifiex_ie_types_data *)scan_resp;
1756 element_len = *(current_ptr + 1);
1757 if (curr_bcn_bytes < element_len +
1758 sizeof(struct ieee_types_header)) {
1759 dev_err(priv->adapter->dev,
1760 "%s: bytes left < IE length\n",
1761 __func__);
1762 goto check_next_scan;
1763 }
1764 if (element_id == WLAN_EID_DS_PARAMS) {
1765 channel = *(current_ptr + sizeof(struct ieee_types_header));
1766 break;
1767 }
1768 2013
1769 current_ptr += element_len + 2014 for (idx = 0; idx < num_of_set && bytes_left; idx++) {
1770 sizeof(struct ieee_types_header); 2015 type = le16_to_cpu(tlv->header.type);
1771 curr_bcn_bytes -= element_len + 2016 len = le16_to_cpu(tlv->header.len);
1772 sizeof(struct ieee_types_header); 2017 if (bytes_left < sizeof(struct mwifiex_ie_types_header) + len) {
2018 dev_err(adapter->dev, "EXT_SCAN: Error bytes left < TLV length\n");
2019 break;
1773 } 2020 }
2021 scan_rsp_tlv = NULL;
2022 scan_info_tlv = NULL;
2023 bytes_left_for_tlv = bytes_left;
1774 2024
1775 /* 2025 /* BSS response TLV with beacon or probe response buffer
1776 * If the TSF TLV was appended to the scan results, save this 2026 * at the initial position of each descriptor
1777 * entry's TSF value in the fw_tsf field. It is the firmware's
1778 * TSF value at the time the beacon or probe response was
1779 * received.
1780 */ 2027 */
1781 if (tsf_tlv) 2028 if (type != TLV_TYPE_BSS_SCAN_RSP)
1782 memcpy(&fw_tsf, &tsf_tlv->tsf_data[idx * TSF_DATA_SIZE], 2029 break;
1783 sizeof(fw_tsf));
1784
1785 if (channel) {
1786 struct ieee80211_channel *chan;
1787 u8 band;
1788 2030
1789 /* Skip entry if on csa closed channel */ 2031 bss_info = (u8 *)tlv;
1790 if (channel == priv->csa_chan) { 2032 scan_rsp_tlv = (struct mwifiex_ie_types_bss_scan_rsp *)tlv;
1791 dev_dbg(adapter->dev, 2033 tlv = (struct mwifiex_ie_types_data *)(tlv->data + len);
1792 "Dropping entry on csa closed channel\n"); 2034 bytes_left_for_tlv -=
2035 (len + sizeof(struct mwifiex_ie_types_header));
2036
2037 while (bytes_left_for_tlv >=
2038 sizeof(struct mwifiex_ie_types_header) &&
2039 le16_to_cpu(tlv->header.type) != TLV_TYPE_BSS_SCAN_RSP) {
2040 type = le16_to_cpu(tlv->header.type);
2041 len = le16_to_cpu(tlv->header.len);
2042 if (bytes_left_for_tlv <
2043 sizeof(struct mwifiex_ie_types_header) + len) {
2044 dev_err(adapter->dev,
2045 "EXT_SCAN: Error in processing TLV, bytes left < TLV length\n");
2046 scan_rsp_tlv = NULL;
2047 bytes_left_for_tlv = 0;
1793 continue; 2048 continue;
1794 } 2049 }
1795 2050 switch (type) {
1796 band = BAND_G; 2051 case TLV_TYPE_BSS_SCAN_INFO:
1797 if (chan_band_tlv) { 2052 scan_info_tlv =
1798 chan_band = 2053 (struct mwifiex_ie_types_bss_scan_info *)tlv;
1799 &chan_band_tlv->chan_band_param[idx]; 2054 if (len !=
1800 band = mwifiex_radio_type_to_band( 2055 sizeof(struct mwifiex_ie_types_bss_scan_info) -
1801 chan_band->radio_type 2056 sizeof(struct mwifiex_ie_types_header)) {
1802 & (BIT(0) | BIT(1))); 2057 bytes_left_for_tlv = 0;
1803 } 2058 continue;
1804 2059 }
1805 cfp = mwifiex_get_cfp(priv, band, channel, 0); 2060 break;
1806 2061 default:
1807 freq = cfp ? cfp->freq : 0; 2062 break;
1808
1809 chan = ieee80211_get_channel(priv->wdev->wiphy, freq);
1810
1811 if (chan && !(chan->flags & IEEE80211_CHAN_DISABLED)) {
1812 bss = cfg80211_inform_bss(priv->wdev->wiphy,
1813 chan, bssid, timestamp,
1814 cap_info_bitmap, beacon_period,
1815 ie_buf, ie_len, rssi, GFP_KERNEL);
1816 bss_priv = (struct mwifiex_bss_priv *)bss->priv;
1817 bss_priv->band = band;
1818 bss_priv->fw_tsf = le64_to_cpu(fw_tsf);
1819 if (priv->media_connected &&
1820 !memcmp(bssid,
1821 priv->curr_bss_params.bss_descriptor
1822 .mac_address, ETH_ALEN))
1823 mwifiex_update_curr_bss_params(priv,
1824 bss);
1825 cfg80211_put_bss(priv->wdev->wiphy, bss);
1826 } 2063 }
1827 } else { 2064 tlv = (struct mwifiex_ie_types_data *)(tlv->data + len);
1828 dev_dbg(adapter->dev, "missing BSS channel IE\n"); 2065 bytes_left -=
2066 (len + sizeof(struct mwifiex_ie_types_header));
2067 bytes_left_for_tlv -=
2068 (len + sizeof(struct mwifiex_ie_types_header));
1829 } 2069 }
1830 }
1831 2070
1832check_next_scan: 2071 if (!scan_rsp_tlv)
1833 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); 2072 break;
1834 if (list_empty(&adapter->scan_pending_q)) {
1835 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
1836 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
1837 adapter->scan_processing = false;
1838 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
1839 2073
1840 /* Need to indicate IOCTL complete */ 2074 /* Advance pointer to the beacon buffer length and
1841 if (adapter->curr_cmd->wait_q_enabled) { 2075 * update the bytes count so that the function
1842 adapter->cmd_wait_q.status = 0; 2076 * wlan_interpret_bss_desc_with_ie() can handle the
1843 if (!priv->scan_request) { 2077 * scan buffer withut any change
1844 dev_dbg(adapter->dev, 2078 */
1845 "complete internal scan\n"); 2079 bss_info += sizeof(u16);
1846 mwifiex_complete_cmd(adapter, 2080 bytes_left -= sizeof(u16);
1847 adapter->curr_cmd);
1848 }
1849 }
1850 if (priv->report_scan_result)
1851 priv->report_scan_result = false;
1852 2081
1853 if (priv->scan_request) { 2082 if (scan_info_tlv) {
1854 dev_dbg(adapter->dev, "info: notifying scan done\n"); 2083 rssi = (s32)(s16)(le16_to_cpu(scan_info_tlv->rssi));
1855 cfg80211_scan_done(priv->scan_request, 0); 2084 rssi *= 100; /* Convert dBm to mBm */
1856 priv->scan_request = NULL; 2085 dev_dbg(adapter->dev,
1857 } else { 2086 "info: InterpretIE: RSSI=%d\n", rssi);
1858 priv->scan_aborting = false; 2087 fw_tsf = le64_to_cpu(scan_info_tlv->tsf);
1859 dev_dbg(adapter->dev, "info: scan already aborted\n"); 2088 radio_type = &scan_info_tlv->radio_type;
1860 }
1861 } else {
1862 if ((priv->scan_aborting && !priv->scan_request) ||
1863 priv->scan_block) {
1864 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1865 flags);
1866 adapter->scan_delay_cnt = MWIFIEX_MAX_SCAN_DELAY_CNT;
1867 mod_timer(&priv->scan_delay_timer, jiffies);
1868 dev_dbg(priv->adapter->dev,
1869 "info: %s: triggerring scan abort\n", __func__);
1870 } else if (!mwifiex_wmm_lists_empty(adapter) &&
1871 (priv->scan_request && (priv->scan_request->flags &
1872 NL80211_SCAN_FLAG_LOW_PRIORITY))) {
1873 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1874 flags);
1875 adapter->scan_delay_cnt = 1;
1876 mod_timer(&priv->scan_delay_timer, jiffies +
1877 msecs_to_jiffies(MWIFIEX_SCAN_DELAY_MSEC));
1878 dev_dbg(priv->adapter->dev,
1879 "info: %s: deferring scan\n", __func__);
1880 } else { 2089 } else {
1881 /* Get scan command from scan_pending_q and put to 2090 radio_type = NULL;
1882 cmd_pending_q */
1883 cmd_node = list_first_entry(&adapter->scan_pending_q,
1884 struct cmd_ctrl_node, list);
1885 list_del(&cmd_node->list);
1886 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1887 flags);
1888 mwifiex_insert_cmd_to_pending_q(adapter, cmd_node,
1889 true);
1890 } 2091 }
2092 ret = mwifiex_parse_single_response_buf(priv, &bss_info,
2093 &bytes_left, fw_tsf,
2094 radio_type, true, rssi);
2095 if (ret)
2096 goto check_next_scan;
1891 } 2097 }
1892 2098
2099check_next_scan:
2100 if (!event_scan->more_event)
2101 mwifiex_check_next_scan_command(priv);
2102
1893 return ret; 2103 return ret;
1894} 2104}
1895 2105
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index b44a31523461..e0dcd3ed7a69 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -84,6 +84,7 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
84 card->mp_agg_pkt_limit = data->mp_agg_pkt_limit; 84 card->mp_agg_pkt_limit = data->mp_agg_pkt_limit;
85 card->supports_sdio_new_mode = data->supports_sdio_new_mode; 85 card->supports_sdio_new_mode = data->supports_sdio_new_mode;
86 card->has_control_mask = data->has_control_mask; 86 card->has_control_mask = data->has_control_mask;
87 card->tx_buf_size = data->tx_buf_size;
87 } 88 }
88 89
89 sdio_claim_host(func); 90 sdio_claim_host(func);
@@ -165,7 +166,6 @@ mwifiex_sdio_remove(struct sdio_func *func)
165 struct sdio_mmc_card *card; 166 struct sdio_mmc_card *card;
166 struct mwifiex_adapter *adapter; 167 struct mwifiex_adapter *adapter;
167 struct mwifiex_private *priv; 168 struct mwifiex_private *priv;
168 int i;
169 169
170 pr_debug("info: SDIO func num=%d\n", func->num); 170 pr_debug("info: SDIO func num=%d\n", func->num);
171 171
@@ -184,11 +184,7 @@ mwifiex_sdio_remove(struct sdio_func *func)
184 if (adapter->is_suspended) 184 if (adapter->is_suspended)
185 mwifiex_sdio_resume(adapter->dev); 185 mwifiex_sdio_resume(adapter->dev);
186 186
187 for (i = 0; i < adapter->priv_num; i++) 187 mwifiex_deauthenticate_all(adapter);
188 if ((GET_BSS_ROLE(adapter->priv[i]) ==
189 MWIFIEX_BSS_ROLE_STA) &&
190 adapter->priv[i]->media_connected)
191 mwifiex_deauthenticate(adapter->priv[i], NULL);
192 188
193 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); 189 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
194 mwifiex_disable_auto_ds(priv); 190 mwifiex_disable_auto_ds(priv);
@@ -1760,6 +1756,7 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
1760 1756
1761 /* save adapter pointer in card */ 1757 /* save adapter pointer in card */
1762 card->adapter = adapter; 1758 card->adapter = adapter;
1759 adapter->tx_buf_size = card->tx_buf_size;
1763 1760
1764 sdio_claim_host(func); 1761 sdio_claim_host(func);
1765 1762
diff --git a/drivers/net/wireless/mwifiex/sdio.h b/drivers/net/wireless/mwifiex/sdio.h
index 532ae0ac4dfb..c71201b2e2a3 100644
--- a/drivers/net/wireless/mwifiex/sdio.h
+++ b/drivers/net/wireless/mwifiex/sdio.h
@@ -233,6 +233,7 @@ struct sdio_mmc_card {
233 u8 mp_agg_pkt_limit; 233 u8 mp_agg_pkt_limit;
234 bool supports_sdio_new_mode; 234 bool supports_sdio_new_mode;
235 bool has_control_mask; 235 bool has_control_mask;
236 u16 tx_buf_size;
236 237
237 u32 mp_rd_bitmap; 238 u32 mp_rd_bitmap;
238 u32 mp_wr_bitmap; 239 u32 mp_wr_bitmap;
@@ -256,6 +257,7 @@ struct mwifiex_sdio_device {
256 u8 mp_agg_pkt_limit; 257 u8 mp_agg_pkt_limit;
257 bool supports_sdio_new_mode; 258 bool supports_sdio_new_mode;
258 bool has_control_mask; 259 bool has_control_mask;
260 u16 tx_buf_size;
259}; 261};
260 262
261static const struct mwifiex_sdio_card_reg mwifiex_reg_sd87xx = { 263static const struct mwifiex_sdio_card_reg mwifiex_reg_sd87xx = {
@@ -312,6 +314,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8786 = {
312 .mp_agg_pkt_limit = 8, 314 .mp_agg_pkt_limit = 8,
313 .supports_sdio_new_mode = false, 315 .supports_sdio_new_mode = false,
314 .has_control_mask = true, 316 .has_control_mask = true,
317 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,
315}; 318};
316 319
317static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = { 320static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = {
@@ -321,6 +324,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = {
321 .mp_agg_pkt_limit = 8, 324 .mp_agg_pkt_limit = 8,
322 .supports_sdio_new_mode = false, 325 .supports_sdio_new_mode = false,
323 .has_control_mask = true, 326 .has_control_mask = true,
327 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,
324}; 328};
325 329
326static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = { 330static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = {
@@ -330,6 +334,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = {
330 .mp_agg_pkt_limit = 8, 334 .mp_agg_pkt_limit = 8,
331 .supports_sdio_new_mode = false, 335 .supports_sdio_new_mode = false,
332 .has_control_mask = true, 336 .has_control_mask = true,
337 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,
333}; 338};
334 339
335static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = { 340static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = {
@@ -339,6 +344,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = {
339 .mp_agg_pkt_limit = 16, 344 .mp_agg_pkt_limit = 16,
340 .supports_sdio_new_mode = true, 345 .supports_sdio_new_mode = true,
341 .has_control_mask = false, 346 .has_control_mask = false,
347 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K,
342}; 348};
343 349
344/* 350/*
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index 9208a8816b80..e3cac1495cc7 100644
--- a/drivers/net/wireless/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -185,6 +185,13 @@ static int mwifiex_cmd_tx_rate_cfg(struct mwifiex_private *priv,
185 i++) 185 i++)
186 rate_scope->ht_mcs_rate_bitmap[i] = 186 rate_scope->ht_mcs_rate_bitmap[i] =
187 cpu_to_le16(pbitmap_rates[2 + i]); 187 cpu_to_le16(pbitmap_rates[2 + i]);
188 if (priv->adapter->fw_api_ver == MWIFIEX_FW_V15) {
189 for (i = 0;
190 i < ARRAY_SIZE(rate_scope->vht_mcs_rate_bitmap);
191 i++)
192 rate_scope->vht_mcs_rate_bitmap[i] =
193 cpu_to_le16(pbitmap_rates[10 + i]);
194 }
188 } else { 195 } else {
189 rate_scope->hr_dsss_rate_bitmap = 196 rate_scope->hr_dsss_rate_bitmap =
190 cpu_to_le16(priv->bitmap_rates[0]); 197 cpu_to_le16(priv->bitmap_rates[0]);
@@ -195,6 +202,13 @@ static int mwifiex_cmd_tx_rate_cfg(struct mwifiex_private *priv,
195 i++) 202 i++)
196 rate_scope->ht_mcs_rate_bitmap[i] = 203 rate_scope->ht_mcs_rate_bitmap[i] =
197 cpu_to_le16(priv->bitmap_rates[2 + i]); 204 cpu_to_le16(priv->bitmap_rates[2 + i]);
205 if (priv->adapter->fw_api_ver == MWIFIEX_FW_V15) {
206 for (i = 0;
207 i < ARRAY_SIZE(rate_scope->vht_mcs_rate_bitmap);
208 i++)
209 rate_scope->vht_mcs_rate_bitmap[i] =
210 cpu_to_le16(priv->bitmap_rates[10 + i]);
211 }
198 } 212 }
199 213
200 rate_drop = (struct mwifiex_rate_drop_pattern *) ((u8 *) rate_scope + 214 rate_drop = (struct mwifiex_rate_drop_pattern *) ((u8 *) rate_scope +
@@ -532,8 +546,228 @@ mwifiex_set_keyparamset_wep(struct mwifiex_private *priv,
532 return 0; 546 return 0;
533} 547}
534 548
549/* This function populates key material v2 command
550 * to set network key for AES & CMAC AES.
551 */
552static int mwifiex_set_aes_key_v2(struct mwifiex_private *priv,
553 struct host_cmd_ds_command *cmd,
554 struct mwifiex_ds_encrypt_key *enc_key,
555 struct host_cmd_ds_802_11_key_material_v2 *km)
556{
557 struct mwifiex_adapter *adapter = priv->adapter;
558 u16 size, len = KEY_PARAMS_FIXED_LEN;
559
560 if (enc_key->is_igtk_key) {
561 dev_dbg(adapter->dev, "%s: Set CMAC AES Key\n", __func__);
562 if (enc_key->is_rx_seq_valid)
563 memcpy(km->key_param_set.key_params.cmac_aes.ipn,
564 enc_key->pn, enc_key->pn_len);
565 km->key_param_set.key_info &= cpu_to_le16(~KEY_MCAST);
566 km->key_param_set.key_info |= cpu_to_le16(KEY_IGTK);
567 km->key_param_set.key_type = KEY_TYPE_ID_AES_CMAC;
568 km->key_param_set.key_params.cmac_aes.key_len =
569 cpu_to_le16(enc_key->key_len);
570 memcpy(km->key_param_set.key_params.cmac_aes.key,
571 enc_key->key_material, enc_key->key_len);
572 len += sizeof(struct mwifiex_cmac_aes_param);
573 } else {
574 dev_dbg(adapter->dev, "%s: Set AES Key\n", __func__);
575 if (enc_key->is_rx_seq_valid)
576 memcpy(km->key_param_set.key_params.aes.pn,
577 enc_key->pn, enc_key->pn_len);
578 km->key_param_set.key_type = KEY_TYPE_ID_AES;
579 km->key_param_set.key_params.aes.key_len =
580 cpu_to_le16(enc_key->key_len);
581 memcpy(km->key_param_set.key_params.aes.key,
582 enc_key->key_material, enc_key->key_len);
583 len += sizeof(struct mwifiex_aes_param);
584 }
585
586 km->key_param_set.len = cpu_to_le16(len);
587 size = len + sizeof(struct mwifiex_ie_types_header) +
588 sizeof(km->action) + S_DS_GEN;
589 cmd->size = cpu_to_le16(size);
590
591 return 0;
592}
593
594/* This function prepares command to set/get/reset network key(s).
595 * This function prepares key material command for V2 format.
596 * Preparation includes -
597 * - Setting command ID, action and proper size
598 * - Setting WEP keys, WAPI keys or WPA keys along with required
599 * encryption (TKIP, AES) (as required)
600 * - Ensuring correct endian-ness
601 */
602static int
603mwifiex_cmd_802_11_key_material_v2(struct mwifiex_private *priv,
604 struct host_cmd_ds_command *cmd,
605 u16 cmd_action, u32 cmd_oid,
606 struct mwifiex_ds_encrypt_key *enc_key)
607{
608 struct mwifiex_adapter *adapter = priv->adapter;
609 u8 *mac = enc_key->mac_addr;
610 u16 key_info, len = KEY_PARAMS_FIXED_LEN;
611 struct host_cmd_ds_802_11_key_material_v2 *km =
612 &cmd->params.key_material_v2;
613
614 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_KEY_MATERIAL);
615 km->action = cpu_to_le16(cmd_action);
616
617 if (cmd_action == HostCmd_ACT_GEN_GET) {
618 dev_dbg(adapter->dev, "%s: Get key\n", __func__);
619 km->key_param_set.key_idx =
620 enc_key->key_index & KEY_INDEX_MASK;
621 km->key_param_set.type = cpu_to_le16(TLV_TYPE_KEY_PARAM_V2);
622 km->key_param_set.len = cpu_to_le16(KEY_PARAMS_FIXED_LEN);
623 memcpy(km->key_param_set.mac_addr, mac, ETH_ALEN);
624
625 if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST)
626 key_info = KEY_UNICAST;
627 else
628 key_info = KEY_MCAST;
629
630 if (enc_key->is_igtk_key)
631 key_info |= KEY_IGTK;
632
633 km->key_param_set.key_info = cpu_to_le16(key_info);
634
635 cmd->size = cpu_to_le16(sizeof(struct mwifiex_ie_types_header) +
636 S_DS_GEN + KEY_PARAMS_FIXED_LEN +
637 sizeof(km->action));
638 return 0;
639 }
640
641 memset(&km->key_param_set, 0,
642 sizeof(struct mwifiex_ie_type_key_param_set_v2));
643
644 if (enc_key->key_disable) {
645 dev_dbg(adapter->dev, "%s: Remove key\n", __func__);
646 km->action = cpu_to_le16(HostCmd_ACT_GEN_REMOVE);
647 km->key_param_set.type = cpu_to_le16(TLV_TYPE_KEY_PARAM_V2);
648 km->key_param_set.len = cpu_to_le16(KEY_PARAMS_FIXED_LEN);
649 km->key_param_set.key_idx = enc_key->key_index & KEY_INDEX_MASK;
650 key_info = KEY_MCAST | KEY_UNICAST;
651 km->key_param_set.key_info = cpu_to_le16(key_info);
652 memcpy(km->key_param_set.mac_addr, mac, ETH_ALEN);
653 cmd->size = cpu_to_le16(sizeof(struct mwifiex_ie_types_header) +
654 S_DS_GEN + KEY_PARAMS_FIXED_LEN +
655 sizeof(km->action));
656 return 0;
657 }
658
659 km->action = cpu_to_le16(HostCmd_ACT_GEN_SET);
660 km->key_param_set.key_idx = enc_key->key_index & KEY_INDEX_MASK;
661 km->key_param_set.type = cpu_to_le16(TLV_TYPE_KEY_PARAM_V2);
662 key_info = KEY_ENABLED;
663 memcpy(km->key_param_set.mac_addr, mac, ETH_ALEN);
664
665 if (enc_key->key_len <= WLAN_KEY_LEN_WEP104) {
666 dev_dbg(adapter->dev, "%s: Set WEP Key\n", __func__);
667 len += sizeof(struct mwifiex_wep_param);
668 km->key_param_set.len = cpu_to_le16(len);
669 km->key_param_set.key_type = KEY_TYPE_ID_WEP;
670
671 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) {
672 key_info |= KEY_MCAST | KEY_UNICAST;
673 } else {
674 if (enc_key->is_current_wep_key) {
675 key_info |= KEY_MCAST | KEY_UNICAST;
676 if (km->key_param_set.key_idx ==
677 (priv->wep_key_curr_index & KEY_INDEX_MASK))
678 key_info |= KEY_DEFAULT;
679 } else {
680 if (mac) {
681 if (is_broadcast_ether_addr(mac))
682 key_info |= KEY_MCAST;
683 else
684 key_info |= KEY_UNICAST |
685 KEY_DEFAULT;
686 } else {
687 key_info |= KEY_MCAST;
688 }
689 }
690 }
691 km->key_param_set.key_info = cpu_to_le16(key_info);
692
693 km->key_param_set.key_params.wep.key_len =
694 cpu_to_le16(enc_key->key_len);
695 memcpy(km->key_param_set.key_params.wep.key,
696 enc_key->key_material, enc_key->key_len);
697
698 cmd->size = cpu_to_le16(sizeof(struct mwifiex_ie_types_header) +
699 len + sizeof(km->action) + S_DS_GEN);
700 return 0;
701 }
702
703 if (is_broadcast_ether_addr(mac))
704 key_info |= KEY_MCAST | KEY_RX_KEY;
705 else
706 key_info |= KEY_UNICAST | KEY_TX_KEY | KEY_RX_KEY;
707
708 if (enc_key->is_wapi_key) {
709 dev_dbg(adapter->dev, "%s: Set WAPI Key\n", __func__);
710 km->key_param_set.key_type = KEY_TYPE_ID_WAPI;
711 memcpy(km->key_param_set.key_params.wapi.pn, enc_key->pn,
712 PN_LEN);
713 km->key_param_set.key_params.wapi.key_len =
714 cpu_to_le16(enc_key->key_len);
715 memcpy(km->key_param_set.key_params.wapi.key,
716 enc_key->key_material, enc_key->key_len);
717 if (is_broadcast_ether_addr(mac))
718 priv->sec_info.wapi_key_on = true;
719
720 if (!priv->sec_info.wapi_key_on)
721 key_info |= KEY_DEFAULT;
722 km->key_param_set.key_info = cpu_to_le16(key_info);
723
724 len += sizeof(struct mwifiex_wapi_param);
725 km->key_param_set.len = cpu_to_le16(len);
726 cmd->size = cpu_to_le16(sizeof(struct mwifiex_ie_types_header) +
727 len + sizeof(km->action) + S_DS_GEN);
728 return 0;
729 }
730
731 if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
732 key_info |= KEY_DEFAULT;
733 /* Enable unicast bit for WPA-NONE/ADHOC_AES */
734 if (!priv->sec_info.wpa2_enabled &&
735 !is_broadcast_ether_addr(mac))
736 key_info |= KEY_UNICAST;
737 } else {
738 /* Enable default key for WPA/WPA2 */
739 if (!priv->wpa_is_gtk_set)
740 key_info |= KEY_DEFAULT;
741 }
742
743 km->key_param_set.key_info = cpu_to_le16(key_info);
744
745 if (enc_key->key_len == WLAN_KEY_LEN_CCMP)
746 return mwifiex_set_aes_key_v2(priv, cmd, enc_key, km);
747
748 if (enc_key->key_len == WLAN_KEY_LEN_TKIP) {
749 dev_dbg(adapter->dev, "%s: Set TKIP Key\n", __func__);
750 if (enc_key->is_rx_seq_valid)
751 memcpy(km->key_param_set.key_params.tkip.pn,
752 enc_key->pn, enc_key->pn_len);
753 km->key_param_set.key_type = KEY_TYPE_ID_TKIP;
754 km->key_param_set.key_params.tkip.key_len =
755 cpu_to_le16(enc_key->key_len);
756 memcpy(km->key_param_set.key_params.tkip.key,
757 enc_key->key_material, enc_key->key_len);
758
759 len += sizeof(struct mwifiex_tkip_param);
760 km->key_param_set.len = cpu_to_le16(len);
761 cmd->size = cpu_to_le16(sizeof(struct mwifiex_ie_types_header) +
762 len + sizeof(km->action) + S_DS_GEN);
763 }
764
765 return 0;
766}
767
535/* 768/*
536 * This function prepares command to set/get/reset network key(s). 769 * This function prepares command to set/get/reset network key(s).
770 * This function prepares key material command for V1 format.
537 * 771 *
538 * Preparation includes - 772 * Preparation includes -
539 * - Setting command ID, action and proper size 773 * - Setting command ID, action and proper size
@@ -542,10 +776,10 @@ mwifiex_set_keyparamset_wep(struct mwifiex_private *priv,
542 * - Ensuring correct endian-ness 776 * - Ensuring correct endian-ness
543 */ 777 */
544static int 778static int
545mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, 779mwifiex_cmd_802_11_key_material_v1(struct mwifiex_private *priv,
546 struct host_cmd_ds_command *cmd, 780 struct host_cmd_ds_command *cmd,
547 u16 cmd_action, u32 cmd_oid, 781 u16 cmd_action, u32 cmd_oid,
548 struct mwifiex_ds_encrypt_key *enc_key) 782 struct mwifiex_ds_encrypt_key *enc_key)
549{ 783{
550 struct host_cmd_ds_802_11_key_material *key_material = 784 struct host_cmd_ds_802_11_key_material *key_material =
551 &cmd->params.key_material; 785 &cmd->params.key_material;
@@ -724,6 +958,24 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
724 return ret; 958 return ret;
725} 959}
726 960
961/* Wrapper function for setting network key depending upon FW KEY API version */
962static int
963mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
964 struct host_cmd_ds_command *cmd,
965 u16 cmd_action, u32 cmd_oid,
966 struct mwifiex_ds_encrypt_key *enc_key)
967{
968 if (priv->adapter->fw_key_api_major_ver == FW_KEY_API_VER_MAJOR_V2)
969 return mwifiex_cmd_802_11_key_material_v2(priv, cmd,
970 cmd_action, cmd_oid,
971 enc_key);
972
973 else
974 return mwifiex_cmd_802_11_key_material_v1(priv, cmd,
975 cmd_action, cmd_oid,
976 enc_key);
977}
978
727/* 979/*
728 * This function prepares command to set/get 11d domain information. 980 * This function prepares command to set/get 11d domain information.
729 * 981 *
@@ -1173,9 +1425,9 @@ int mwifiex_dnld_dt_cfgdata(struct mwifiex_private *priv,
1173 /* property header is 6 bytes, data must fit in cmd buffer */ 1425 /* property header is 6 bytes, data must fit in cmd buffer */
1174 if (prop && prop->value && prop->length > 6 && 1426 if (prop && prop->value && prop->length > 6 &&
1175 prop->length <= MWIFIEX_SIZE_OF_CMD_BUFFER - S_DS_GEN) { 1427 prop->length <= MWIFIEX_SIZE_OF_CMD_BUFFER - S_DS_GEN) {
1176 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_CFG_DATA, 1428 ret = mwifiex_send_cmd(priv, HostCmd_CMD_CFG_DATA,
1177 HostCmd_ACT_GEN_SET, 0, 1429 HostCmd_ACT_GEN_SET, 0,
1178 prop); 1430 prop, true);
1179 if (ret) 1431 if (ret)
1180 return ret; 1432 return ret;
1181 } 1433 }
@@ -1280,6 +1532,127 @@ mwifiex_cmd_coalesce_cfg(struct mwifiex_private *priv,
1280 return 0; 1532 return 0;
1281} 1533}
1282 1534
1535static int
1536mwifiex_cmd_tdls_oper(struct mwifiex_private *priv,
1537 struct host_cmd_ds_command *cmd,
1538 void *data_buf)
1539{
1540 struct host_cmd_ds_tdls_oper *tdls_oper = &cmd->params.tdls_oper;
1541 struct mwifiex_ds_tdls_oper *oper = data_buf;
1542 struct mwifiex_sta_node *sta_ptr;
1543 struct host_cmd_tlv_rates *tlv_rates;
1544 struct mwifiex_ie_types_htcap *ht_capab;
1545 struct mwifiex_ie_types_qos_info *wmm_qos_info;
1546 struct mwifiex_ie_types_extcap *extcap;
1547 struct mwifiex_ie_types_vhtcap *vht_capab;
1548 struct mwifiex_ie_types_aid *aid;
1549 u8 *pos, qos_info;
1550 u16 config_len = 0;
1551 struct station_parameters *params = priv->sta_params;
1552
1553 cmd->command = cpu_to_le16(HostCmd_CMD_TDLS_OPER);
1554 cmd->size = cpu_to_le16(S_DS_GEN);
1555 le16_add_cpu(&cmd->size, sizeof(struct host_cmd_ds_tdls_oper));
1556
1557 tdls_oper->reason = 0;
1558 memcpy(tdls_oper->peer_mac, oper->peer_mac, ETH_ALEN);
1559 sta_ptr = mwifiex_get_sta_entry(priv, oper->peer_mac);
1560
1561 pos = (u8 *)tdls_oper + sizeof(struct host_cmd_ds_tdls_oper);
1562
1563 switch (oper->tdls_action) {
1564 case MWIFIEX_TDLS_DISABLE_LINK:
1565 tdls_oper->tdls_action = cpu_to_le16(ACT_TDLS_DELETE);
1566 break;
1567 case MWIFIEX_TDLS_CREATE_LINK:
1568 tdls_oper->tdls_action = cpu_to_le16(ACT_TDLS_CREATE);
1569 break;
1570 case MWIFIEX_TDLS_CONFIG_LINK:
1571 tdls_oper->tdls_action = cpu_to_le16(ACT_TDLS_CONFIG);
1572
1573 if (!params) {
1574 dev_err(priv->adapter->dev,
1575 "TDLS config params not available for %pM\n",
1576 oper->peer_mac);
1577 return -ENODATA;
1578 }
1579
1580 *(__le16 *)pos = cpu_to_le16(params->capability);
1581 config_len += sizeof(params->capability);
1582
1583 qos_info = params->uapsd_queues | (params->max_sp << 5);
1584 wmm_qos_info = (struct mwifiex_ie_types_qos_info *)(pos +
1585 config_len);
1586 wmm_qos_info->header.type = cpu_to_le16(WLAN_EID_QOS_CAPA);
1587 wmm_qos_info->header.len = cpu_to_le16(sizeof(qos_info));
1588 wmm_qos_info->qos_info = qos_info;
1589 config_len += sizeof(struct mwifiex_ie_types_qos_info);
1590
1591 if (params->ht_capa) {
1592 ht_capab = (struct mwifiex_ie_types_htcap *)(pos +
1593 config_len);
1594 ht_capab->header.type =
1595 cpu_to_le16(WLAN_EID_HT_CAPABILITY);
1596 ht_capab->header.len =
1597 cpu_to_le16(sizeof(struct ieee80211_ht_cap));
1598 memcpy(&ht_capab->ht_cap, params->ht_capa,
1599 sizeof(struct ieee80211_ht_cap));
1600 config_len += sizeof(struct mwifiex_ie_types_htcap);
1601 }
1602
1603 if (params->supported_rates && params->supported_rates_len) {
1604 tlv_rates = (struct host_cmd_tlv_rates *)(pos +
1605 config_len);
1606 tlv_rates->header.type =
1607 cpu_to_le16(WLAN_EID_SUPP_RATES);
1608 tlv_rates->header.len =
1609 cpu_to_le16(params->supported_rates_len);
1610 memcpy(tlv_rates->rates, params->supported_rates,
1611 params->supported_rates_len);
1612 config_len += sizeof(struct host_cmd_tlv_rates) +
1613 params->supported_rates_len;
1614 }
1615
1616 if (params->ext_capab && params->ext_capab_len) {
1617 extcap = (struct mwifiex_ie_types_extcap *)(pos +
1618 config_len);
1619 extcap->header.type =
1620 cpu_to_le16(WLAN_EID_EXT_CAPABILITY);
1621 extcap->header.len = cpu_to_le16(params->ext_capab_len);
1622 memcpy(extcap->ext_capab, params->ext_capab,
1623 params->ext_capab_len);
1624 config_len += sizeof(struct mwifiex_ie_types_extcap) +
1625 params->ext_capab_len;
1626 }
1627 if (params->vht_capa) {
1628 vht_capab = (struct mwifiex_ie_types_vhtcap *)(pos +
1629 config_len);
1630 vht_capab->header.type =
1631 cpu_to_le16(WLAN_EID_VHT_CAPABILITY);
1632 vht_capab->header.len =
1633 cpu_to_le16(sizeof(struct ieee80211_vht_cap));
1634 memcpy(&vht_capab->vht_cap, params->vht_capa,
1635 sizeof(struct ieee80211_vht_cap));
1636 config_len += sizeof(struct mwifiex_ie_types_vhtcap);
1637 }
1638 if (params->aid) {
1639 aid = (struct mwifiex_ie_types_aid *)(pos + config_len);
1640 aid->header.type = cpu_to_le16(WLAN_EID_AID);
1641 aid->header.len = cpu_to_le16(sizeof(params->aid));
1642 aid->aid = cpu_to_le16(params->aid);
1643 config_len += sizeof(struct mwifiex_ie_types_aid);
1644 }
1645
1646 break;
1647 default:
1648 dev_err(priv->adapter->dev, "Unknown TDLS operation\n");
1649 return -ENOTSUPP;
1650 }
1651
1652 le16_add_cpu(&cmd->size, config_len);
1653
1654 return 0;
1655}
1283/* 1656/*
1284 * This function prepares the commands before sending them to the firmware. 1657 * This function prepares the commands before sending them to the firmware.
1285 * 1658 *
@@ -1472,6 +1845,9 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
1472 ret = mwifiex_cmd_ibss_coalescing_status(cmd_ptr, cmd_action, 1845 ret = mwifiex_cmd_ibss_coalescing_status(cmd_ptr, cmd_action,
1473 data_buf); 1846 data_buf);
1474 break; 1847 break;
1848 case HostCmd_CMD_802_11_SCAN_EXT:
1849 ret = mwifiex_cmd_802_11_scan_ext(priv, cmd_ptr, data_buf);
1850 break;
1475 case HostCmd_CMD_MAC_REG_ACCESS: 1851 case HostCmd_CMD_MAC_REG_ACCESS:
1476 case HostCmd_CMD_BBP_REG_ACCESS: 1852 case HostCmd_CMD_BBP_REG_ACCESS:
1477 case HostCmd_CMD_RF_REG_ACCESS: 1853 case HostCmd_CMD_RF_REG_ACCESS:
@@ -1507,6 +1883,9 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
1507 ret = mwifiex_cmd_coalesce_cfg(priv, cmd_ptr, cmd_action, 1883 ret = mwifiex_cmd_coalesce_cfg(priv, cmd_ptr, cmd_action,
1508 data_buf); 1884 data_buf);
1509 break; 1885 break;
1886 case HostCmd_CMD_TDLS_OPER:
1887 ret = mwifiex_cmd_tdls_oper(priv, cmd_ptr, data_buf);
1888 break;
1510 default: 1889 default:
1511 dev_err(priv->adapter->dev, 1890 dev_err(priv->adapter->dev,
1512 "PREP_CMD: unknown cmd- %#x\n", cmd_no); 1891 "PREP_CMD: unknown cmd- %#x\n", cmd_no);
@@ -1547,15 +1926,16 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
1547 1926
1548 if (first_sta) { 1927 if (first_sta) {
1549 if (priv->adapter->iface_type == MWIFIEX_PCIE) { 1928 if (priv->adapter->iface_type == MWIFIEX_PCIE) {
1550 ret = mwifiex_send_cmd_sync(priv, 1929 ret = mwifiex_send_cmd(priv,
1551 HostCmd_CMD_PCIE_DESC_DETAILS, 1930 HostCmd_CMD_PCIE_DESC_DETAILS,
1552 HostCmd_ACT_GEN_SET, 0, NULL); 1931 HostCmd_ACT_GEN_SET, 0, NULL,
1932 true);
1553 if (ret) 1933 if (ret)
1554 return -1; 1934 return -1;
1555 } 1935 }
1556 1936
1557 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_FUNC_INIT, 1937 ret = mwifiex_send_cmd(priv, HostCmd_CMD_FUNC_INIT,
1558 HostCmd_ACT_GEN_SET, 0, NULL); 1938 HostCmd_ACT_GEN_SET, 0, NULL, true);
1559 if (ret) 1939 if (ret)
1560 return -1; 1940 return -1;
1561 1941
@@ -1573,55 +1953,57 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
1573 } 1953 }
1574 1954
1575 if (adapter->cal_data) { 1955 if (adapter->cal_data) {
1576 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_CFG_DATA, 1956 ret = mwifiex_send_cmd(priv, HostCmd_CMD_CFG_DATA,
1577 HostCmd_ACT_GEN_SET, 0, NULL); 1957 HostCmd_ACT_GEN_SET, 0, NULL,
1958 true);
1578 if (ret) 1959 if (ret)
1579 return -1; 1960 return -1;
1580 } 1961 }
1581 1962
1582 /* Read MAC address from HW */ 1963 /* Read MAC address from HW */
1583 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_GET_HW_SPEC, 1964 ret = mwifiex_send_cmd(priv, HostCmd_CMD_GET_HW_SPEC,
1584 HostCmd_ACT_GEN_GET, 0, NULL); 1965 HostCmd_ACT_GEN_GET, 0, NULL, true);
1585 if (ret) 1966 if (ret)
1586 return -1; 1967 return -1;
1587 1968
1588 /* Reconfigure tx buf size */ 1969 /* Reconfigure tx buf size */
1589 ret = mwifiex_send_cmd_sync(priv, 1970 ret = mwifiex_send_cmd(priv, HostCmd_CMD_RECONFIGURE_TX_BUFF,
1590 HostCmd_CMD_RECONFIGURE_TX_BUFF, 1971 HostCmd_ACT_GEN_SET, 0,
1591 HostCmd_ACT_GEN_SET, 0, 1972 &priv->adapter->tx_buf_size, true);
1592 &priv->adapter->tx_buf_size);
1593 if (ret) 1973 if (ret)
1594 return -1; 1974 return -1;
1595 1975
1596 if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) { 1976 if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) {
1597 /* Enable IEEE PS by default */ 1977 /* Enable IEEE PS by default */
1598 priv->adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP; 1978 priv->adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP;
1599 ret = mwifiex_send_cmd_sync( 1979 ret = mwifiex_send_cmd(priv,
1600 priv, HostCmd_CMD_802_11_PS_MODE_ENH, 1980 HostCmd_CMD_802_11_PS_MODE_ENH,
1601 EN_AUTO_PS, BITMAP_STA_PS, NULL); 1981 EN_AUTO_PS, BITMAP_STA_PS, NULL,
1982 true);
1602 if (ret) 1983 if (ret)
1603 return -1; 1984 return -1;
1604 } 1985 }
1605 } 1986 }
1606 1987
1607 /* get tx rate */ 1988 /* get tx rate */
1608 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_TX_RATE_CFG, 1989 ret = mwifiex_send_cmd(priv, HostCmd_CMD_TX_RATE_CFG,
1609 HostCmd_ACT_GEN_GET, 0, NULL); 1990 HostCmd_ACT_GEN_GET, 0, NULL, true);
1610 if (ret) 1991 if (ret)
1611 return -1; 1992 return -1;
1612 priv->data_rate = 0; 1993 priv->data_rate = 0;
1613 1994
1614 /* get tx power */ 1995 /* get tx power */
1615 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_RF_TX_PWR, 1996 ret = mwifiex_send_cmd(priv, HostCmd_CMD_RF_TX_PWR,
1616 HostCmd_ACT_GEN_GET, 0, NULL); 1997 HostCmd_ACT_GEN_GET, 0, NULL, true);
1617 if (ret) 1998 if (ret)
1618 return -1; 1999 return -1;
1619 2000
1620 if (priv->bss_type == MWIFIEX_BSS_TYPE_STA) { 2001 if (priv->bss_type == MWIFIEX_BSS_TYPE_STA) {
1621 /* set ibss coalescing_status */ 2002 /* set ibss coalescing_status */
1622 ret = mwifiex_send_cmd_sync( 2003 ret = mwifiex_send_cmd(
1623 priv, HostCmd_CMD_802_11_IBSS_COALESCING_STATUS, 2004 priv,
1624 HostCmd_ACT_GEN_SET, 0, &enable); 2005 HostCmd_CMD_802_11_IBSS_COALESCING_STATUS,
2006 HostCmd_ACT_GEN_SET, 0, &enable, true);
1625 if (ret) 2007 if (ret)
1626 return -1; 2008 return -1;
1627 } 2009 }
@@ -1629,16 +2011,16 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
1629 memset(&amsdu_aggr_ctrl, 0, sizeof(amsdu_aggr_ctrl)); 2011 memset(&amsdu_aggr_ctrl, 0, sizeof(amsdu_aggr_ctrl));
1630 amsdu_aggr_ctrl.enable = true; 2012 amsdu_aggr_ctrl.enable = true;
1631 /* Send request to firmware */ 2013 /* Send request to firmware */
1632 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_AMSDU_AGGR_CTRL, 2014 ret = mwifiex_send_cmd(priv, HostCmd_CMD_AMSDU_AGGR_CTRL,
1633 HostCmd_ACT_GEN_SET, 0, 2015 HostCmd_ACT_GEN_SET, 0,
1634 &amsdu_aggr_ctrl); 2016 &amsdu_aggr_ctrl, true);
1635 if (ret) 2017 if (ret)
1636 return -1; 2018 return -1;
1637 /* MAC Control must be the last command in init_fw */ 2019 /* MAC Control must be the last command in init_fw */
1638 /* set MAC Control */ 2020 /* set MAC Control */
1639 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_MAC_CONTROL, 2021 ret = mwifiex_send_cmd(priv, HostCmd_CMD_MAC_CONTROL,
1640 HostCmd_ACT_GEN_SET, 0, 2022 HostCmd_ACT_GEN_SET, 0,
1641 &priv->curr_pkt_filter); 2023 &priv->curr_pkt_filter, true);
1642 if (ret) 2024 if (ret)
1643 return -1; 2025 return -1;
1644 2026
@@ -1647,10 +2029,9 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
1647 /* Enable auto deep sleep */ 2029 /* Enable auto deep sleep */
1648 auto_ds.auto_ds = DEEP_SLEEP_ON; 2030 auto_ds.auto_ds = DEEP_SLEEP_ON;
1649 auto_ds.idle_time = DEEP_SLEEP_IDLE_TIME; 2031 auto_ds.idle_time = DEEP_SLEEP_IDLE_TIME;
1650 ret = mwifiex_send_cmd_sync(priv, 2032 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_PS_MODE_ENH,
1651 HostCmd_CMD_802_11_PS_MODE_ENH, 2033 EN_AUTO_PS, BITMAP_AUTO_DS,
1652 EN_AUTO_PS, BITMAP_AUTO_DS, 2034 &auto_ds, true);
1653 &auto_ds);
1654 if (ret) 2035 if (ret)
1655 return -1; 2036 return -1;
1656 } 2037 }
@@ -1658,9 +2039,9 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
1658 if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) { 2039 if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) {
1659 /* Send cmd to FW to enable/disable 11D function */ 2040 /* Send cmd to FW to enable/disable 11D function */
1660 state_11d = ENABLE_11D; 2041 state_11d = ENABLE_11D;
1661 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, 2042 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
1662 HostCmd_ACT_GEN_SET, DOT11D_I, 2043 HostCmd_ACT_GEN_SET, DOT11D_I,
1663 &state_11d); 2044 &state_11d, true);
1664 if (ret) 2045 if (ret)
1665 dev_err(priv->adapter->dev, 2046 dev_err(priv->adapter->dev,
1666 "11D: failed to enable 11D\n"); 2047 "11D: failed to enable 11D\n");
@@ -1673,8 +2054,8 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
1673 * (Short GI, Channel BW, Green field support etc.) for transmit 2054 * (Short GI, Channel BW, Green field support etc.) for transmit
1674 */ 2055 */
1675 tx_cfg.tx_htcap = MWIFIEX_FW_DEF_HTTXCFG; 2056 tx_cfg.tx_htcap = MWIFIEX_FW_DEF_HTTXCFG;
1676 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_11N_CFG, 2057 ret = mwifiex_send_cmd(priv, HostCmd_CMD_11N_CFG,
1677 HostCmd_ACT_GEN_SET, 0, &tx_cfg); 2058 HostCmd_ACT_GEN_SET, 0, &tx_cfg, true);
1678 2059
1679 ret = -EINPROGRESS; 2060 ret = -EINPROGRESS;
1680 2061
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index 24523e4015cb..bfebb0144df5 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -69,6 +69,7 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv,
69 69
70 break; 70 break;
71 case HostCmd_CMD_802_11_SCAN: 71 case HostCmd_CMD_802_11_SCAN:
72 case HostCmd_CMD_802_11_SCAN_EXT:
72 /* Cancel all pending scan command */ 73 /* Cancel all pending scan command */
73 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); 74 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
74 list_for_each_entry_safe(cmd_node, tmp_node, 75 list_for_each_entry_safe(cmd_node, tmp_node,
@@ -157,8 +158,8 @@ static int mwifiex_ret_802_11_rssi_info(struct mwifiex_private *priv,
157 158
158 priv->subsc_evt_rssi_state = EVENT_HANDLED; 159 priv->subsc_evt_rssi_state = EVENT_HANDLED;
159 160
160 mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_SUBSCRIBE_EVENT, 161 mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SUBSCRIBE_EVENT,
161 0, 0, subsc_evt); 162 0, 0, subsc_evt, false);
162 163
163 return 0; 164 return 0;
164} 165}
@@ -303,6 +304,15 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv,
303 priv->bitmap_rates[2 + i] = 304 priv->bitmap_rates[2 + i] =
304 le16_to_cpu(rate_scope-> 305 le16_to_cpu(rate_scope->
305 ht_mcs_rate_bitmap[i]); 306 ht_mcs_rate_bitmap[i]);
307
308 if (priv->adapter->fw_api_ver == MWIFIEX_FW_V15) {
309 for (i = 0; i < ARRAY_SIZE(rate_scope->
310 vht_mcs_rate_bitmap);
311 i++)
312 priv->bitmap_rates[10 + i] =
313 le16_to_cpu(rate_scope->
314 vht_mcs_rate_bitmap[i]);
315 }
306 break; 316 break;
307 /* Add RATE_DROP tlv here */ 317 /* Add RATE_DROP tlv here */
308 } 318 }
@@ -316,9 +326,8 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv,
316 if (priv->is_data_rate_auto) 326 if (priv->is_data_rate_auto)
317 priv->data_rate = 0; 327 priv->data_rate = 0;
318 else 328 else
319 return mwifiex_send_cmd_async(priv, 329 return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_TX_RATE_QUERY,
320 HostCmd_CMD_802_11_TX_RATE_QUERY, 330 HostCmd_ACT_GEN_GET, 0, NULL, false);
321 HostCmd_ACT_GEN_GET, 0, NULL);
322 331
323 return 0; 332 return 0;
324} 333}
@@ -561,13 +570,13 @@ static int mwifiex_ret_802_11_ad_hoc_stop(struct mwifiex_private *priv,
561} 570}
562 571
563/* 572/*
564 * This function handles the command response of set/get key material. 573 * This function handles the command response of set/get v1 key material.
565 * 574 *
566 * Handling includes updating the driver parameters to reflect the 575 * Handling includes updating the driver parameters to reflect the
567 * changes. 576 * changes.
568 */ 577 */
569static int mwifiex_ret_802_11_key_material(struct mwifiex_private *priv, 578static int mwifiex_ret_802_11_key_material_v1(struct mwifiex_private *priv,
570 struct host_cmd_ds_command *resp) 579 struct host_cmd_ds_command *resp)
571{ 580{
572 struct host_cmd_ds_802_11_key_material *key = 581 struct host_cmd_ds_802_11_key_material *key =
573 &resp->params.key_material; 582 &resp->params.key_material;
@@ -590,6 +599,51 @@ static int mwifiex_ret_802_11_key_material(struct mwifiex_private *priv,
590} 599}
591 600
592/* 601/*
602 * This function handles the command response of set/get v2 key material.
603 *
604 * Handling includes updating the driver parameters to reflect the
605 * changes.
606 */
607static int mwifiex_ret_802_11_key_material_v2(struct mwifiex_private *priv,
608 struct host_cmd_ds_command *resp)
609{
610 struct host_cmd_ds_802_11_key_material_v2 *key_v2;
611 __le16 len;
612
613 key_v2 = &resp->params.key_material_v2;
614 if (le16_to_cpu(key_v2->action) == HostCmd_ACT_GEN_SET) {
615 if ((le16_to_cpu(key_v2->key_param_set.key_info) & KEY_MCAST)) {
616 dev_dbg(priv->adapter->dev, "info: key: GTK is set\n");
617 priv->wpa_is_gtk_set = true;
618 priv->scan_block = false;
619 }
620 }
621
622 if (key_v2->key_param_set.key_type != KEY_TYPE_ID_AES)
623 return 0;
624
625 memset(priv->aes_key_v2.key_param_set.key_params.aes.key, 0,
626 WLAN_KEY_LEN_CCMP);
627 priv->aes_key_v2.key_param_set.key_params.aes.key_len =
628 key_v2->key_param_set.key_params.aes.key_len;
629 len = priv->aes_key_v2.key_param_set.key_params.aes.key_len;
630 memcpy(priv->aes_key_v2.key_param_set.key_params.aes.key,
631 key_v2->key_param_set.key_params.aes.key, le16_to_cpu(len));
632
633 return 0;
634}
635
636/* Wrapper function for processing response of key material command */
637static int mwifiex_ret_802_11_key_material(struct mwifiex_private *priv,
638 struct host_cmd_ds_command *resp)
639{
640 if (priv->adapter->fw_key_api_major_ver == FW_KEY_API_VER_MAJOR_V2)
641 return mwifiex_ret_802_11_key_material_v2(priv, resp);
642 else
643 return mwifiex_ret_802_11_key_material_v1(priv, resp);
644}
645
646/*
593 * This function handles the command response of get 11d domain information. 647 * This function handles the command response of get 11d domain information.
594 */ 648 */
595static int mwifiex_ret_802_11d_domain_info(struct mwifiex_private *priv, 649static int mwifiex_ret_802_11d_domain_info(struct mwifiex_private *priv,
@@ -800,7 +854,60 @@ static int mwifiex_ret_ibss_coalescing_status(struct mwifiex_private *priv,
800 854
801 return 0; 855 return 0;
802} 856}
857static int mwifiex_ret_tdls_oper(struct mwifiex_private *priv,
858 struct host_cmd_ds_command *resp)
859{
860 struct host_cmd_ds_tdls_oper *cmd_tdls_oper = &resp->params.tdls_oper;
861 u16 reason = le16_to_cpu(cmd_tdls_oper->reason);
862 u16 action = le16_to_cpu(cmd_tdls_oper->tdls_action);
863 struct mwifiex_sta_node *node =
864 mwifiex_get_sta_entry(priv, cmd_tdls_oper->peer_mac);
803 865
866 switch (action) {
867 case ACT_TDLS_DELETE:
868 if (reason)
869 dev_err(priv->adapter->dev,
870 "TDLS link delete for %pM failed: reason %d\n",
871 cmd_tdls_oper->peer_mac, reason);
872 else
873 dev_dbg(priv->adapter->dev,
874 "TDLS link config for %pM successful\n",
875 cmd_tdls_oper->peer_mac);
876 break;
877 case ACT_TDLS_CREATE:
878 if (reason) {
879 dev_err(priv->adapter->dev,
880 "TDLS link creation for %pM failed: reason %d",
881 cmd_tdls_oper->peer_mac, reason);
882 if (node && reason != TDLS_ERR_LINK_EXISTS)
883 node->tdls_status = TDLS_SETUP_FAILURE;
884 } else {
885 dev_dbg(priv->adapter->dev,
886 "TDLS link creation for %pM successful",
887 cmd_tdls_oper->peer_mac);
888 }
889 break;
890 case ACT_TDLS_CONFIG:
891 if (reason) {
892 dev_err(priv->adapter->dev,
893 "TDLS link config for %pM failed, reason %d\n",
894 cmd_tdls_oper->peer_mac, reason);
895 if (node)
896 node->tdls_status = TDLS_SETUP_FAILURE;
897 } else {
898 dev_dbg(priv->adapter->dev,
899 "TDLS link config for %pM successful\n",
900 cmd_tdls_oper->peer_mac);
901 }
902 break;
903 default:
904 dev_err(priv->adapter->dev,
905 "Unknown TDLS command action respnse %d", action);
906 return -1;
907 }
908
909 return 0;
910}
804/* 911/*
805 * This function handles the command response for subscribe event command. 912 * This function handles the command response for subscribe event command.
806 */ 913 */
@@ -871,6 +978,10 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
871 ret = mwifiex_ret_802_11_scan(priv, resp); 978 ret = mwifiex_ret_802_11_scan(priv, resp);
872 adapter->curr_cmd->wait_q_enabled = false; 979 adapter->curr_cmd->wait_q_enabled = false;
873 break; 980 break;
981 case HostCmd_CMD_802_11_SCAN_EXT:
982 ret = mwifiex_ret_802_11_scan_ext(priv);
983 adapter->curr_cmd->wait_q_enabled = false;
984 break;
874 case HostCmd_CMD_802_11_BG_SCAN_QUERY: 985 case HostCmd_CMD_802_11_BG_SCAN_QUERY:
875 ret = mwifiex_ret_802_11_scan(priv, resp); 986 ret = mwifiex_ret_802_11_scan(priv, resp);
876 dev_dbg(adapter->dev, 987 dev_dbg(adapter->dev,
@@ -999,6 +1110,9 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
999 break; 1110 break;
1000 case HostCmd_CMD_COALESCE_CFG: 1111 case HostCmd_CMD_COALESCE_CFG:
1001 break; 1112 break;
1113 case HostCmd_CMD_TDLS_OPER:
1114 ret = mwifiex_ret_tdls_oper(priv, resp);
1115 break;
1002 default: 1116 default:
1003 dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n", 1117 dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n",
1004 resp->command); 1118 resp->command);
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
index 8c351f71f72f..368450cc56c7 100644
--- a/drivers/net/wireless/mwifiex/sta_event.c
+++ b/drivers/net/wireless/mwifiex/sta_event.c
@@ -54,6 +54,10 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason_code)
54 54
55 priv->scan_block = false; 55 priv->scan_block = false;
56 56
57 if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
58 ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info))
59 mwifiex_disable_all_tdls_links(priv);
60
57 /* Free Tx and Rx packets, report disconnect to upper layer */ 61 /* Free Tx and Rx packets, report disconnect to upper layer */
58 mwifiex_clean_txrx(priv); 62 mwifiex_clean_txrx(priv);
59 63
@@ -112,7 +116,7 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason_code)
112 adapter->tx_lock_flag = false; 116 adapter->tx_lock_flag = false;
113 adapter->pps_uapsd_mode = false; 117 adapter->pps_uapsd_mode = false;
114 118
115 if (adapter->num_cmd_timeout && adapter->curr_cmd) 119 if (adapter->is_cmd_timedout && adapter->curr_cmd)
116 return; 120 return;
117 priv->media_connected = false; 121 priv->media_connected = false;
118 dev_dbg(adapter->dev, 122 dev_dbg(adapter->dev,
@@ -289,9 +293,8 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
289 293
290 case EVENT_HS_ACT_REQ: 294 case EVENT_HS_ACT_REQ:
291 dev_dbg(adapter->dev, "event: HS_ACT_REQ\n"); 295 dev_dbg(adapter->dev, "event: HS_ACT_REQ\n");
292 ret = mwifiex_send_cmd_async(priv, 296 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_HS_CFG_ENH,
293 HostCmd_CMD_802_11_HS_CFG_ENH, 297 0, 0, NULL, false);
294 0, 0, NULL);
295 break; 298 break;
296 299
297 case EVENT_MIC_ERR_UNICAST: 300 case EVENT_MIC_ERR_UNICAST:
@@ -322,27 +325,34 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
322 325
323 case EVENT_BG_SCAN_REPORT: 326 case EVENT_BG_SCAN_REPORT:
324 dev_dbg(adapter->dev, "event: BGS_REPORT\n"); 327 dev_dbg(adapter->dev, "event: BGS_REPORT\n");
325 ret = mwifiex_send_cmd_async(priv, 328 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_BG_SCAN_QUERY,
326 HostCmd_CMD_802_11_BG_SCAN_QUERY, 329 HostCmd_ACT_GEN_GET, 0, NULL, false);
327 HostCmd_ACT_GEN_GET, 0, NULL);
328 break; 330 break;
329 331
330 case EVENT_PORT_RELEASE: 332 case EVENT_PORT_RELEASE:
331 dev_dbg(adapter->dev, "event: PORT RELEASE\n"); 333 dev_dbg(adapter->dev, "event: PORT RELEASE\n");
332 break; 334 break;
333 335
336 case EVENT_EXT_SCAN_REPORT:
337 dev_dbg(adapter->dev, "event: EXT_SCAN Report\n");
338 if (adapter->ext_scan)
339 ret = mwifiex_handle_event_ext_scan_report(priv,
340 adapter->event_skb->data);
341
342 break;
343
334 case EVENT_WMM_STATUS_CHANGE: 344 case EVENT_WMM_STATUS_CHANGE:
335 dev_dbg(adapter->dev, "event: WMM status changed\n"); 345 dev_dbg(adapter->dev, "event: WMM status changed\n");
336 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_WMM_GET_STATUS, 346 ret = mwifiex_send_cmd(priv, HostCmd_CMD_WMM_GET_STATUS,
337 0, 0, NULL); 347 0, 0, NULL, false);
338 break; 348 break;
339 349
340 case EVENT_RSSI_LOW: 350 case EVENT_RSSI_LOW:
341 cfg80211_cqm_rssi_notify(priv->netdev, 351 cfg80211_cqm_rssi_notify(priv->netdev,
342 NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW, 352 NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
343 GFP_KERNEL); 353 GFP_KERNEL);
344 mwifiex_send_cmd_async(priv, HostCmd_CMD_RSSI_INFO, 354 mwifiex_send_cmd(priv, HostCmd_CMD_RSSI_INFO,
345 HostCmd_ACT_GEN_GET, 0, NULL); 355 HostCmd_ACT_GEN_GET, 0, NULL, false);
346 priv->subsc_evt_rssi_state = RSSI_LOW_RECVD; 356 priv->subsc_evt_rssi_state = RSSI_LOW_RECVD;
347 dev_dbg(adapter->dev, "event: Beacon RSSI_LOW\n"); 357 dev_dbg(adapter->dev, "event: Beacon RSSI_LOW\n");
348 break; 358 break;
@@ -356,8 +366,8 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
356 cfg80211_cqm_rssi_notify(priv->netdev, 366 cfg80211_cqm_rssi_notify(priv->netdev,
357 NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH, 367 NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
358 GFP_KERNEL); 368 GFP_KERNEL);
359 mwifiex_send_cmd_async(priv, HostCmd_CMD_RSSI_INFO, 369 mwifiex_send_cmd(priv, HostCmd_CMD_RSSI_INFO,
360 HostCmd_ACT_GEN_GET, 0, NULL); 370 HostCmd_ACT_GEN_GET, 0, NULL, false);
361 priv->subsc_evt_rssi_state = RSSI_HIGH_RECVD; 371 priv->subsc_evt_rssi_state = RSSI_HIGH_RECVD;
362 dev_dbg(adapter->dev, "event: Beacon RSSI_HIGH\n"); 372 dev_dbg(adapter->dev, "event: Beacon RSSI_HIGH\n");
363 break; 373 break;
@@ -384,15 +394,15 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
384 break; 394 break;
385 case EVENT_IBSS_COALESCED: 395 case EVENT_IBSS_COALESCED:
386 dev_dbg(adapter->dev, "event: IBSS_COALESCED\n"); 396 dev_dbg(adapter->dev, "event: IBSS_COALESCED\n");
387 ret = mwifiex_send_cmd_async(priv, 397 ret = mwifiex_send_cmd(priv,
388 HostCmd_CMD_802_11_IBSS_COALESCING_STATUS, 398 HostCmd_CMD_802_11_IBSS_COALESCING_STATUS,
389 HostCmd_ACT_GEN_GET, 0, NULL); 399 HostCmd_ACT_GEN_GET, 0, NULL, false);
390 break; 400 break;
391 case EVENT_ADDBA: 401 case EVENT_ADDBA:
392 dev_dbg(adapter->dev, "event: ADDBA Request\n"); 402 dev_dbg(adapter->dev, "event: ADDBA Request\n");
393 mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_ADDBA_RSP, 403 mwifiex_send_cmd(priv, HostCmd_CMD_11N_ADDBA_RSP,
394 HostCmd_ACT_GEN_SET, 0, 404 HostCmd_ACT_GEN_SET, 0,
395 adapter->event_body); 405 adapter->event_body, false);
396 break; 406 break;
397 case EVENT_DELBA: 407 case EVENT_DELBA:
398 dev_dbg(adapter->dev, "event: DELBA Request\n"); 408 dev_dbg(adapter->dev, "event: DELBA Request\n");
@@ -443,10 +453,10 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
443 priv->csa_expire_time = 453 priv->csa_expire_time =
444 jiffies + msecs_to_jiffies(DFS_CHAN_MOVE_TIME); 454 jiffies + msecs_to_jiffies(DFS_CHAN_MOVE_TIME);
445 priv->csa_chan = priv->curr_bss_params.bss_descriptor.channel; 455 priv->csa_chan = priv->curr_bss_params.bss_descriptor.channel;
446 ret = mwifiex_send_cmd_async(priv, 456 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_DEAUTHENTICATE,
447 HostCmd_CMD_802_11_DEAUTHENTICATE,
448 HostCmd_ACT_GEN_SET, 0, 457 HostCmd_ACT_GEN_SET, 0,
449 priv->curr_bss_params.bss_descriptor.mac_address); 458 priv->curr_bss_params.bss_descriptor.mac_address,
459 false);
450 break; 460 break;
451 461
452 default: 462 default:
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index c5cb2ed19ec2..33170af150f6 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -108,19 +108,19 @@ int mwifiex_request_set_multicast_list(struct mwifiex_private *priv,
108 "info: Set multicast list=%d\n", 108 "info: Set multicast list=%d\n",
109 mcast_list->num_multicast_addr); 109 mcast_list->num_multicast_addr);
110 /* Send multicast addresses to firmware */ 110 /* Send multicast addresses to firmware */
111 ret = mwifiex_send_cmd_async(priv, 111 ret = mwifiex_send_cmd(priv,
112 HostCmd_CMD_MAC_MULTICAST_ADR, 112 HostCmd_CMD_MAC_MULTICAST_ADR,
113 HostCmd_ACT_GEN_SET, 0, 113 HostCmd_ACT_GEN_SET, 0,
114 mcast_list); 114 mcast_list, false);
115 } 115 }
116 } 116 }
117 dev_dbg(priv->adapter->dev, 117 dev_dbg(priv->adapter->dev,
118 "info: old_pkt_filter=%#x, curr_pkt_filter=%#x\n", 118 "info: old_pkt_filter=%#x, curr_pkt_filter=%#x\n",
119 old_pkt_filter, priv->curr_pkt_filter); 119 old_pkt_filter, priv->curr_pkt_filter);
120 if (old_pkt_filter != priv->curr_pkt_filter) { 120 if (old_pkt_filter != priv->curr_pkt_filter) {
121 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, 121 ret = mwifiex_send_cmd(priv, HostCmd_CMD_MAC_CONTROL,
122 HostCmd_ACT_GEN_SET, 122 HostCmd_ACT_GEN_SET,
123 0, &priv->curr_pkt_filter); 123 0, &priv->curr_pkt_filter, false);
124 } 124 }
125 125
126 return ret; 126 return ret;
@@ -237,8 +237,8 @@ static int mwifiex_process_country_ie(struct mwifiex_private *priv,
237 237
238 rcu_read_unlock(); 238 rcu_read_unlock();
239 239
240 if (mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11D_DOMAIN_INFO, 240 if (mwifiex_send_cmd(priv, HostCmd_CMD_802_11D_DOMAIN_INFO,
241 HostCmd_ACT_GEN_SET, 0, NULL)) { 241 HostCmd_ACT_GEN_SET, 0, NULL, false)) {
242 wiphy_err(priv->adapter->wiphy, 242 wiphy_err(priv->adapter->wiphy,
243 "11D: setting domain info in FW\n"); 243 "11D: setting domain info in FW\n");
244 return -1; 244 return -1;
@@ -290,7 +290,7 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
290 290
291 if (mwifiex_band_to_radio_type(bss_desc->bss_band) == 291 if (mwifiex_band_to_radio_type(bss_desc->bss_band) ==
292 HostCmd_SCAN_RADIO_TYPE_BG) 292 HostCmd_SCAN_RADIO_TYPE_BG)
293 config_bands = BAND_B | BAND_G | BAND_GN | BAND_GAC; 293 config_bands = BAND_B | BAND_G | BAND_GN;
294 else 294 else
295 config_bands = BAND_A | BAND_AN | BAND_AAC; 295 config_bands = BAND_A | BAND_AN | BAND_AAC;
296 296
@@ -429,16 +429,13 @@ static int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action,
429 status = -1; 429 status = -1;
430 break; 430 break;
431 } 431 }
432 if (cmd_type == MWIFIEX_SYNC_CMD) 432
433 status = mwifiex_send_cmd_sync(priv, 433 status = mwifiex_send_cmd(priv,
434 HostCmd_CMD_802_11_HS_CFG_ENH, 434 HostCmd_CMD_802_11_HS_CFG_ENH,
435 HostCmd_ACT_GEN_SET, 0, 435 HostCmd_ACT_GEN_SET, 0,
436 &adapter->hs_cfg); 436 &adapter->hs_cfg,
437 else 437 cmd_type == MWIFIEX_SYNC_CMD);
438 status = mwifiex_send_cmd_async(priv, 438
439 HostCmd_CMD_802_11_HS_CFG_ENH,
440 HostCmd_ACT_GEN_SET, 0,
441 &adapter->hs_cfg);
442 if (hs_cfg->conditions == HS_CFG_CANCEL) 439 if (hs_cfg->conditions == HS_CFG_CANCEL)
443 /* Restore previous condition */ 440 /* Restore previous condition */
444 adapter->hs_cfg.conditions = 441 adapter->hs_cfg.conditions =
@@ -586,8 +583,8 @@ int mwifiex_disable_auto_ds(struct mwifiex_private *priv)
586 583
587 auto_ds.auto_ds = DEEP_SLEEP_OFF; 584 auto_ds.auto_ds = DEEP_SLEEP_OFF;
588 585
589 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_PS_MODE_ENH, 586 return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_PS_MODE_ENH,
590 DIS_AUTO_PS, BITMAP_AUTO_DS, &auto_ds); 587 DIS_AUTO_PS, BITMAP_AUTO_DS, &auto_ds, true);
591} 588}
592EXPORT_SYMBOL_GPL(mwifiex_disable_auto_ds); 589EXPORT_SYMBOL_GPL(mwifiex_disable_auto_ds);
593 590
@@ -601,8 +598,8 @@ int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, u32 *rate)
601{ 598{
602 int ret; 599 int ret;
603 600
604 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_TX_RATE_QUERY, 601 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_TX_RATE_QUERY,
605 HostCmd_ACT_GEN_GET, 0, NULL); 602 HostCmd_ACT_GEN_GET, 0, NULL, true);
606 603
607 if (!ret) { 604 if (!ret) {
608 if (priv->is_data_rate_auto) 605 if (priv->is_data_rate_auto)
@@ -698,8 +695,8 @@ int mwifiex_set_tx_power(struct mwifiex_private *priv,
698 pg->power_max = (s8) dbm; 695 pg->power_max = (s8) dbm;
699 pg->ht_bandwidth = HT_BW_40; 696 pg->ht_bandwidth = HT_BW_40;
700 } 697 }
701 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_TXPWR_CFG, 698 ret = mwifiex_send_cmd(priv, HostCmd_CMD_TXPWR_CFG,
702 HostCmd_ACT_GEN_SET, 0, buf); 699 HostCmd_ACT_GEN_SET, 0, buf, true);
703 700
704 kfree(buf); 701 kfree(buf);
705 return ret; 702 return ret;
@@ -722,12 +719,11 @@ int mwifiex_drv_set_power(struct mwifiex_private *priv, u32 *ps_mode)
722 else 719 else
723 adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM; 720 adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM;
724 sub_cmd = (*ps_mode) ? EN_AUTO_PS : DIS_AUTO_PS; 721 sub_cmd = (*ps_mode) ? EN_AUTO_PS : DIS_AUTO_PS;
725 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_PS_MODE_ENH, 722 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_PS_MODE_ENH,
726 sub_cmd, BITMAP_STA_PS, NULL); 723 sub_cmd, BITMAP_STA_PS, NULL, true);
727 if ((!ret) && (sub_cmd == DIS_AUTO_PS)) 724 if ((!ret) && (sub_cmd == DIS_AUTO_PS))
728 ret = mwifiex_send_cmd_async(priv, 725 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_PS_MODE_ENH,
729 HostCmd_CMD_802_11_PS_MODE_ENH, 726 GET_PS, 0, NULL, false);
730 GET_PS, 0, NULL);
731 727
732 return ret; 728 return ret;
733} 729}
@@ -851,9 +847,9 @@ static int mwifiex_sec_ioctl_set_wapi_key(struct mwifiex_private *priv,
851 struct mwifiex_ds_encrypt_key *encrypt_key) 847 struct mwifiex_ds_encrypt_key *encrypt_key)
852{ 848{
853 849
854 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_KEY_MATERIAL, 850 return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL,
855 HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, 851 HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED,
856 encrypt_key); 852 encrypt_key, true);
857} 853}
858 854
859/* 855/*
@@ -865,6 +861,7 @@ static int mwifiex_sec_ioctl_set_wapi_key(struct mwifiex_private *priv,
865static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_private *priv, 861static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_private *priv,
866 struct mwifiex_ds_encrypt_key *encrypt_key) 862 struct mwifiex_ds_encrypt_key *encrypt_key)
867{ 863{
864 struct mwifiex_adapter *adapter = priv->adapter;
868 int ret; 865 int ret;
869 struct mwifiex_wep_key *wep_key; 866 struct mwifiex_wep_key *wep_key;
870 int index; 867 int index;
@@ -879,10 +876,17 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_private *priv,
879 /* Copy the required key as the current key */ 876 /* Copy the required key as the current key */
880 wep_key = &priv->wep_key[index]; 877 wep_key = &priv->wep_key[index];
881 if (!wep_key->key_length) { 878 if (!wep_key->key_length) {
882 dev_err(priv->adapter->dev, 879 dev_err(adapter->dev,
883 "key not set, so cannot enable it\n"); 880 "key not set, so cannot enable it\n");
884 return -1; 881 return -1;
885 } 882 }
883
884 if (adapter->fw_key_api_major_ver == FW_KEY_API_VER_MAJOR_V2) {
885 memcpy(encrypt_key->key_material,
886 wep_key->key_material, wep_key->key_length);
887 encrypt_key->key_len = wep_key->key_length;
888 }
889
886 priv->wep_key_curr_index = (u16) index; 890 priv->wep_key_curr_index = (u16) index;
887 priv->sec_info.wep_enabled = 1; 891 priv->sec_info.wep_enabled = 1;
888 } else { 892 } else {
@@ -897,21 +901,32 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_private *priv,
897 priv->sec_info.wep_enabled = 1; 901 priv->sec_info.wep_enabled = 1;
898 } 902 }
899 if (wep_key->key_length) { 903 if (wep_key->key_length) {
904 void *enc_key;
905
906 if (encrypt_key->key_disable)
907 memset(&priv->wep_key[index], 0,
908 sizeof(struct mwifiex_wep_key));
909
910 if (adapter->fw_key_api_major_ver == FW_KEY_API_VER_MAJOR_V2)
911 enc_key = encrypt_key;
912 else
913 enc_key = NULL;
914
900 /* Send request to firmware */ 915 /* Send request to firmware */
901 ret = mwifiex_send_cmd_async(priv, 916 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL,
902 HostCmd_CMD_802_11_KEY_MATERIAL, 917 HostCmd_ACT_GEN_SET, 0, enc_key, false);
903 HostCmd_ACT_GEN_SET, 0, NULL);
904 if (ret) 918 if (ret)
905 return ret; 919 return ret;
906 } 920 }
921
907 if (priv->sec_info.wep_enabled) 922 if (priv->sec_info.wep_enabled)
908 priv->curr_pkt_filter |= HostCmd_ACT_MAC_WEP_ENABLE; 923 priv->curr_pkt_filter |= HostCmd_ACT_MAC_WEP_ENABLE;
909 else 924 else
910 priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE; 925 priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE;
911 926
912 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_MAC_CONTROL, 927 ret = mwifiex_send_cmd(priv, HostCmd_CMD_MAC_CONTROL,
913 HostCmd_ACT_GEN_SET, 0, 928 HostCmd_ACT_GEN_SET, 0,
914 &priv->curr_pkt_filter); 929 &priv->curr_pkt_filter, true);
915 930
916 return ret; 931 return ret;
917} 932}
@@ -946,10 +961,9 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_private *priv,
946 */ 961 */
947 /* Send the key as PTK to firmware */ 962 /* Send the key as PTK to firmware */
948 encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST; 963 encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST;
949 ret = mwifiex_send_cmd_async(priv, 964 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL,
950 HostCmd_CMD_802_11_KEY_MATERIAL, 965 HostCmd_ACT_GEN_SET,
951 HostCmd_ACT_GEN_SET, 966 KEY_INFO_ENABLED, encrypt_key, false);
952 KEY_INFO_ENABLED, encrypt_key);
953 if (ret) 967 if (ret)
954 return ret; 968 return ret;
955 969
@@ -973,15 +987,13 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_private *priv,
973 encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST; 987 encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST;
974 988
975 if (remove_key) 989 if (remove_key)
976 ret = mwifiex_send_cmd_sync(priv, 990 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL,
977 HostCmd_CMD_802_11_KEY_MATERIAL, 991 HostCmd_ACT_GEN_SET,
978 HostCmd_ACT_GEN_SET, 992 !KEY_INFO_ENABLED, encrypt_key, true);
979 !KEY_INFO_ENABLED, encrypt_key);
980 else 993 else
981 ret = mwifiex_send_cmd_sync(priv, 994 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL,
982 HostCmd_CMD_802_11_KEY_MATERIAL, 995 HostCmd_ACT_GEN_SET,
983 HostCmd_ACT_GEN_SET, 996 KEY_INFO_ENABLED, encrypt_key, true);
984 KEY_INFO_ENABLED, encrypt_key);
985 997
986 return ret; 998 return ret;
987} 999}
@@ -1044,19 +1056,27 @@ int mwifiex_set_encode(struct mwifiex_private *priv, struct key_params *kp,
1044 1056
1045 memset(&encrypt_key, 0, sizeof(struct mwifiex_ds_encrypt_key)); 1057 memset(&encrypt_key, 0, sizeof(struct mwifiex_ds_encrypt_key));
1046 encrypt_key.key_len = key_len; 1058 encrypt_key.key_len = key_len;
1059 encrypt_key.key_index = key_index;
1047 1060
1048 if (kp && kp->cipher == WLAN_CIPHER_SUITE_AES_CMAC) 1061 if (kp && kp->cipher == WLAN_CIPHER_SUITE_AES_CMAC)
1049 encrypt_key.is_igtk_key = true; 1062 encrypt_key.is_igtk_key = true;
1050 1063
1051 if (!disable) { 1064 if (!disable) {
1052 encrypt_key.key_index = key_index;
1053 if (key_len) 1065 if (key_len)
1054 memcpy(encrypt_key.key_material, key, key_len); 1066 memcpy(encrypt_key.key_material, key, key_len);
1067 else
1068 encrypt_key.is_current_wep_key = true;
1069
1055 if (mac_addr) 1070 if (mac_addr)
1056 memcpy(encrypt_key.mac_addr, mac_addr, ETH_ALEN); 1071 memcpy(encrypt_key.mac_addr, mac_addr, ETH_ALEN);
1057 if (kp && kp->seq && kp->seq_len) 1072 if (kp && kp->seq && kp->seq_len) {
1058 memcpy(encrypt_key.pn, kp->seq, kp->seq_len); 1073 memcpy(encrypt_key.pn, kp->seq, kp->seq_len);
1074 encrypt_key.pn_len = kp->seq_len;
1075 encrypt_key.is_rx_seq_valid = true;
1076 }
1059 } else { 1077 } else {
1078 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP)
1079 return 0;
1060 encrypt_key.key_disable = true; 1080 encrypt_key.key_disable = true;
1061 if (mac_addr) 1081 if (mac_addr)
1062 memcpy(encrypt_key.mac_addr, mac_addr, ETH_ALEN); 1082 memcpy(encrypt_key.mac_addr, mac_addr, ETH_ALEN);
@@ -1077,8 +1097,8 @@ mwifiex_get_ver_ext(struct mwifiex_private *priv)
1077 struct mwifiex_ver_ext ver_ext; 1097 struct mwifiex_ver_ext ver_ext;
1078 1098
1079 memset(&ver_ext, 0, sizeof(struct host_cmd_ds_version_ext)); 1099 memset(&ver_ext, 0, sizeof(struct host_cmd_ds_version_ext));
1080 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_VERSION_EXT, 1100 if (mwifiex_send_cmd(priv, HostCmd_CMD_VERSION_EXT,
1081 HostCmd_ACT_GEN_GET, 0, &ver_ext)) 1101 HostCmd_ACT_GEN_GET, 0, &ver_ext, true))
1082 return -1; 1102 return -1;
1083 1103
1084 return 0; 1104 return 0;
@@ -1103,8 +1123,8 @@ mwifiex_remain_on_chan_cfg(struct mwifiex_private *priv, u16 action,
1103 ieee80211_frequency_to_channel(chan->center_freq); 1123 ieee80211_frequency_to_channel(chan->center_freq);
1104 roc_cfg.duration = cpu_to_le32(duration); 1124 roc_cfg.duration = cpu_to_le32(duration);
1105 } 1125 }
1106 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_REMAIN_ON_CHAN, 1126 if (mwifiex_send_cmd(priv, HostCmd_CMD_REMAIN_ON_CHAN,
1107 action, 0, &roc_cfg)) { 1127 action, 0, &roc_cfg, true)) {
1108 dev_err(priv->adapter->dev, "failed to remain on channel\n"); 1128 dev_err(priv->adapter->dev, "failed to remain on channel\n");
1109 return -1; 1129 return -1;
1110 } 1130 }
@@ -1136,8 +1156,8 @@ mwifiex_set_bss_role(struct mwifiex_private *priv, u8 bss_role)
1136 break; 1156 break;
1137 } 1157 }
1138 1158
1139 mwifiex_send_cmd_sync(priv, HostCmd_CMD_SET_BSS_MODE, 1159 mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
1140 HostCmd_ACT_GEN_SET, 0, NULL); 1160 HostCmd_ACT_GEN_SET, 0, NULL, true);
1141 1161
1142 return mwifiex_sta_init_cmd(priv, false); 1162 return mwifiex_sta_init_cmd(priv, false);
1143} 1163}
@@ -1152,8 +1172,8 @@ int
1152mwifiex_get_stats_info(struct mwifiex_private *priv, 1172mwifiex_get_stats_info(struct mwifiex_private *priv,
1153 struct mwifiex_ds_get_stats *log) 1173 struct mwifiex_ds_get_stats *log)
1154{ 1174{
1155 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_GET_LOG, 1175 return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_GET_LOG,
1156 HostCmd_ACT_GEN_GET, 0, log); 1176 HostCmd_ACT_GEN_GET, 0, log, true);
1157} 1177}
1158 1178
1159/* 1179/*
@@ -1195,8 +1215,7 @@ static int mwifiex_reg_mem_ioctl_reg_rw(struct mwifiex_private *priv,
1195 return -1; 1215 return -1;
1196 } 1216 }
1197 1217
1198 return mwifiex_send_cmd_sync(priv, cmd_no, action, 0, reg_rw); 1218 return mwifiex_send_cmd(priv, cmd_no, action, 0, reg_rw, true);
1199
1200} 1219}
1201 1220
1202/* 1221/*
@@ -1261,8 +1280,8 @@ mwifiex_eeprom_read(struct mwifiex_private *priv, u16 offset, u16 bytes,
1261 rd_eeprom.byte_count = cpu_to_le16((u16) bytes); 1280 rd_eeprom.byte_count = cpu_to_le16((u16) bytes);
1262 1281
1263 /* Send request to firmware */ 1282 /* Send request to firmware */
1264 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_EEPROM_ACCESS, 1283 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_EEPROM_ACCESS,
1265 HostCmd_ACT_GEN_GET, 0, &rd_eeprom); 1284 HostCmd_ACT_GEN_GET, 0, &rd_eeprom, true);
1266 1285
1267 if (!ret) 1286 if (!ret)
1268 memcpy(value, rd_eeprom.value, MAX_EEPROM_DATA); 1287 memcpy(value, rd_eeprom.value, MAX_EEPROM_DATA);
@@ -1391,7 +1410,7 @@ static int mwifiex_misc_ioctl_gen_ie(struct mwifiex_private *priv,
1391 * with requisite parameters and calls the IOCTL handler. 1410 * with requisite parameters and calls the IOCTL handler.
1392 */ 1411 */
1393int 1412int
1394mwifiex_set_gen_ie(struct mwifiex_private *priv, u8 *ie, int ie_len) 1413mwifiex_set_gen_ie(struct mwifiex_private *priv, const u8 *ie, int ie_len)
1395{ 1414{
1396 struct mwifiex_ds_misc_gen_ie gen_ie; 1415 struct mwifiex_ds_misc_gen_ie gen_ie;
1397 1416
diff --git a/drivers/net/wireless/mwifiex/sta_rx.c b/drivers/net/wireless/mwifiex/sta_rx.c
index 4651d676df38..ed26387eccf5 100644
--- a/drivers/net/wireless/mwifiex/sta_rx.c
+++ b/drivers/net/wireless/mwifiex/sta_rx.c
@@ -88,11 +88,14 @@ int mwifiex_process_rx_packet(struct mwifiex_private *priv,
88 struct rxpd *local_rx_pd; 88 struct rxpd *local_rx_pd;
89 int hdr_chop; 89 int hdr_chop;
90 struct ethhdr *eth; 90 struct ethhdr *eth;
91 u16 rx_pkt_off, rx_pkt_len;
92 u8 *offset;
91 93
92 local_rx_pd = (struct rxpd *) (skb->data); 94 local_rx_pd = (struct rxpd *) (skb->data);
93 95
94 rx_pkt_hdr = (void *)local_rx_pd + 96 rx_pkt_off = le16_to_cpu(local_rx_pd->rx_pkt_offset);
95 le16_to_cpu(local_rx_pd->rx_pkt_offset); 97 rx_pkt_len = le16_to_cpu(local_rx_pd->rx_pkt_length);
98 rx_pkt_hdr = (void *)local_rx_pd + rx_pkt_off;
96 99
97 if ((!memcmp(&rx_pkt_hdr->rfc1042_hdr, bridge_tunnel_header, 100 if ((!memcmp(&rx_pkt_hdr->rfc1042_hdr, bridge_tunnel_header,
98 sizeof(bridge_tunnel_header))) || 101 sizeof(bridge_tunnel_header))) ||
@@ -142,6 +145,12 @@ int mwifiex_process_rx_packet(struct mwifiex_private *priv,
142 return 0; 145 return 0;
143 } 146 }
144 147
148 if (ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info) &&
149 ntohs(rx_pkt_hdr->eth803_hdr.h_proto) == ETH_P_TDLS) {
150 offset = (u8 *)local_rx_pd + rx_pkt_off;
151 mwifiex_process_tdls_action_frame(priv, offset, rx_pkt_len);
152 }
153
145 priv->rxpd_rate = local_rx_pd->rx_rate; 154 priv->rxpd_rate = local_rx_pd->rx_rate;
146 155
147 priv->rxpd_htinfo = local_rx_pd->ht_info; 156 priv->rxpd_htinfo = local_rx_pd->ht_info;
@@ -192,26 +201,7 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_private *priv,
192 return ret; 201 return ret;
193 } 202 }
194 203
195 if (rx_pkt_type == PKT_TYPE_AMSDU) { 204 if (rx_pkt_type == PKT_TYPE_MGMT) {
196 struct sk_buff_head list;
197 struct sk_buff *rx_skb;
198
199 __skb_queue_head_init(&list);
200
201 skb_pull(skb, rx_pkt_offset);
202 skb_trim(skb, rx_pkt_length);
203
204 ieee80211_amsdu_to_8023s(skb, &list, priv->curr_addr,
205 priv->wdev->iftype, 0, false);
206
207 while (!skb_queue_empty(&list)) {
208 rx_skb = __skb_dequeue(&list);
209 ret = mwifiex_recv_packet(priv, rx_skb);
210 if (ret == -1)
211 dev_err(adapter->dev, "Rx of A-MSDU failed");
212 }
213 return 0;
214 } else if (rx_pkt_type == PKT_TYPE_MGMT) {
215 ret = mwifiex_process_mgmt_packet(priv, skb); 205 ret = mwifiex_process_mgmt_packet(priv, skb);
216 if (ret) 206 if (ret)
217 dev_err(adapter->dev, "Rx of mgmt packet failed"); 207 dev_err(adapter->dev, "Rx of mgmt packet failed");
diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c
index 354d64c9606f..1236a5de7bca 100644
--- a/drivers/net/wireless/mwifiex/sta_tx.c
+++ b/drivers/net/wireless/mwifiex/sta_tx.c
@@ -95,6 +95,9 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv,
95 } 95 }
96 } 96 }
97 97
98 if (tx_info->flags & MWIFIEX_BUF_FLAG_TDLS_PKT)
99 local_tx_pd->flags |= MWIFIEX_TXPD_FLAGS_TDLS_PACKET;
100
98 /* Offset of actual data */ 101 /* Offset of actual data */
99 pkt_offset = sizeof(struct txpd) + pad; 102 pkt_offset = sizeof(struct txpd) + pad;
100 if (pkt_type == PKT_TYPE_MGMT) { 103 if (pkt_type == PKT_TYPE_MGMT) {
diff --git a/drivers/net/wireless/mwifiex/tdls.c b/drivers/net/wireless/mwifiex/tdls.c
new file mode 100644
index 000000000000..8cec6e4ba8c4
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/tdls.c
@@ -0,0 +1,1044 @@
1/* Marvell Wireless LAN device driver: TDLS handling
2 *
3 * Copyright (C) 2014, Marvell International Ltd.
4 *
5 * This software file (the "File") is distributed by Marvell International
6 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
7 * (the "License"). You may use, redistribute and/or modify this File in
8 * accordance with the terms and conditions of the License, a copy of which
9 * is available on the worldwide web at
10 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
11 *
12 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
13 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
14 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
15 * this warranty disclaimer.
16 */
17
18#include "main.h"
19#include "wmm.h"
20#include "11n.h"
21#include "11n_rxreorder.h"
22#include "11ac.h"
23
24#define TDLS_REQ_FIX_LEN 6
25#define TDLS_RESP_FIX_LEN 8
26#define TDLS_CONFIRM_FIX_LEN 6
27
28static void
29mwifiex_restore_tdls_packets(struct mwifiex_private *priv, u8 *mac, u8 status)
30{
31 struct mwifiex_ra_list_tbl *ra_list;
32 struct list_head *tid_list;
33 struct sk_buff *skb, *tmp;
34 struct mwifiex_txinfo *tx_info;
35 unsigned long flags;
36 u32 tid;
37 u8 tid_down;
38
39 dev_dbg(priv->adapter->dev, "%s: %pM\n", __func__, mac);
40 spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags);
41
42 skb_queue_walk_safe(&priv->tdls_txq, skb, tmp) {
43 if (!ether_addr_equal(mac, skb->data))
44 continue;
45
46 __skb_unlink(skb, &priv->tdls_txq);
47 tx_info = MWIFIEX_SKB_TXCB(skb);
48 tid = skb->priority;
49 tid_down = mwifiex_wmm_downgrade_tid(priv, tid);
50
51 if (status == TDLS_SETUP_COMPLETE) {
52 ra_list = mwifiex_wmm_get_queue_raptr(priv, tid, mac);
53 ra_list->tdls_link = true;
54 tx_info->flags |= MWIFIEX_BUF_FLAG_TDLS_PKT;
55 } else {
56 tid_list = &priv->wmm.tid_tbl_ptr[tid_down].ra_list;
57 if (!list_empty(tid_list))
58 ra_list = list_first_entry(tid_list,
59 struct mwifiex_ra_list_tbl, list);
60 else
61 ra_list = NULL;
62 tx_info->flags &= ~MWIFIEX_BUF_FLAG_TDLS_PKT;
63 }
64
65 if (!ra_list) {
66 mwifiex_write_data_complete(priv->adapter, skb, 0, -1);
67 continue;
68 }
69
70 skb_queue_tail(&ra_list->skb_head, skb);
71
72 ra_list->ba_pkt_count++;
73 ra_list->total_pkt_count++;
74
75 if (atomic_read(&priv->wmm.highest_queued_prio) <
76 tos_to_tid_inv[tid_down])
77 atomic_set(&priv->wmm.highest_queued_prio,
78 tos_to_tid_inv[tid_down]);
79
80 atomic_inc(&priv->wmm.tx_pkts_queued);
81 }
82
83 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
84 return;
85}
86
87static void mwifiex_hold_tdls_packets(struct mwifiex_private *priv, u8 *mac)
88{
89 struct mwifiex_ra_list_tbl *ra_list;
90 struct list_head *ra_list_head;
91 struct sk_buff *skb, *tmp;
92 unsigned long flags;
93 int i;
94
95 dev_dbg(priv->adapter->dev, "%s: %pM\n", __func__, mac);
96 spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags);
97
98 for (i = 0; i < MAX_NUM_TID; i++) {
99 if (!list_empty(&priv->wmm.tid_tbl_ptr[i].ra_list)) {
100 ra_list_head = &priv->wmm.tid_tbl_ptr[i].ra_list;
101 list_for_each_entry(ra_list, ra_list_head, list) {
102 skb_queue_walk_safe(&ra_list->skb_head, skb,
103 tmp) {
104 if (!ether_addr_equal(mac, skb->data))
105 continue;
106 __skb_unlink(skb, &ra_list->skb_head);
107 atomic_dec(&priv->wmm.tx_pkts_queued);
108 ra_list->total_pkt_count--;
109 skb_queue_tail(&priv->tdls_txq, skb);
110 }
111 }
112 }
113 }
114
115 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
116 return;
117}
118
119/* This function appends rate TLV to scan config command. */
120static int
121mwifiex_tdls_append_rates_ie(struct mwifiex_private *priv,
122 struct sk_buff *skb)
123{
124 u8 rates[MWIFIEX_SUPPORTED_RATES], *pos;
125 u16 rates_size, supp_rates_size, ext_rates_size;
126
127 memset(rates, 0, sizeof(rates));
128 rates_size = mwifiex_get_supported_rates(priv, rates);
129
130 supp_rates_size = min_t(u16, rates_size, MWIFIEX_TDLS_SUPPORTED_RATES);
131
132 if (skb_tailroom(skb) < rates_size + 4) {
133 dev_err(priv->adapter->dev,
134 "Insuffient space while adding rates\n");
135 return -ENOMEM;
136 }
137
138 pos = skb_put(skb, supp_rates_size + 2);
139 *pos++ = WLAN_EID_SUPP_RATES;
140 *pos++ = supp_rates_size;
141 memcpy(pos, rates, supp_rates_size);
142
143 if (rates_size > MWIFIEX_TDLS_SUPPORTED_RATES) {
144 ext_rates_size = rates_size - MWIFIEX_TDLS_SUPPORTED_RATES;
145 pos = skb_put(skb, ext_rates_size + 2);
146 *pos++ = WLAN_EID_EXT_SUPP_RATES;
147 *pos++ = ext_rates_size;
148 memcpy(pos, rates + MWIFIEX_TDLS_SUPPORTED_RATES,
149 ext_rates_size);
150 }
151
152 return 0;
153}
154
155static void mwifiex_tdls_add_aid(struct mwifiex_private *priv,
156 struct sk_buff *skb)
157{
158 struct ieee_types_assoc_rsp *assoc_rsp;
159 u8 *pos;
160
161 assoc_rsp = (struct ieee_types_assoc_rsp *)&priv->assoc_rsp_buf;
162 pos = (void *)skb_put(skb, 4);
163 *pos++ = WLAN_EID_AID;
164 *pos++ = 2;
165 *pos++ = le16_to_cpu(assoc_rsp->a_id);
166
167 return;
168}
169
170static int mwifiex_tdls_add_vht_capab(struct mwifiex_private *priv,
171 struct sk_buff *skb)
172{
173 struct ieee80211_vht_cap vht_cap;
174 u8 *pos;
175
176 pos = (void *)skb_put(skb, sizeof(struct ieee80211_vht_cap) + 2);
177 *pos++ = WLAN_EID_VHT_CAPABILITY;
178 *pos++ = sizeof(struct ieee80211_vht_cap);
179
180 memset(&vht_cap, 0, sizeof(struct ieee80211_vht_cap));
181
182 mwifiex_fill_vht_cap_tlv(priv, &vht_cap, priv->curr_bss_params.band);
183 memcpy(pos, &vht_cap, sizeof(vht_cap));
184
185 return 0;
186}
187
188static int mwifiex_tdls_add_vht_oper(struct mwifiex_private *priv,
189 u8 *mac, struct sk_buff *skb)
190{
191 struct mwifiex_bssdescriptor *bss_desc;
192 struct ieee80211_vht_operation *vht_oper;
193 struct ieee80211_vht_cap *vht_cap, *ap_vht_cap = NULL;
194 struct mwifiex_sta_node *sta_ptr;
195 struct mwifiex_adapter *adapter = priv->adapter;
196 u8 supp_chwd_set, peer_supp_chwd_set;
197 u8 *pos, ap_supp_chwd_set, chan_bw;
198 u16 mcs_map_user, mcs_map_resp, mcs_map_result;
199 u16 mcs_user, mcs_resp, nss;
200 u32 usr_vht_cap_info;
201
202 bss_desc = &priv->curr_bss_params.bss_descriptor;
203
204 sta_ptr = mwifiex_get_sta_entry(priv, mac);
205 if (unlikely(!sta_ptr)) {
206 dev_warn(adapter->dev, "TDLS peer station not found in list\n");
207 return -1;
208 }
209
210 if (!mwifiex_is_bss_in_11ac_mode(priv)) {
211 if (sta_ptr->tdls_cap.extcap.ext_capab[7] &
212 WLAN_EXT_CAPA8_TDLS_WIDE_BW_ENABLED) {
213 dev_dbg(adapter->dev,
214 "TDLS peer doesn't support wider bandwitdh\n");
215 return 0;
216 }
217 } else {
218 ap_vht_cap = bss_desc->bcn_vht_cap;
219 }
220
221 pos = (void *)skb_put(skb, sizeof(struct ieee80211_vht_operation) + 2);
222 *pos++ = WLAN_EID_VHT_OPERATION;
223 *pos++ = sizeof(struct ieee80211_vht_operation);
224 vht_oper = (struct ieee80211_vht_operation *)pos;
225
226 if (bss_desc->bss_band & BAND_A)
227 usr_vht_cap_info = adapter->usr_dot_11ac_dev_cap_a;
228 else
229 usr_vht_cap_info = adapter->usr_dot_11ac_dev_cap_bg;
230
231 /* find the minmum bandwith between AP/TDLS peers */
232 vht_cap = &sta_ptr->tdls_cap.vhtcap;
233 supp_chwd_set = GET_VHTCAP_CHWDSET(usr_vht_cap_info);
234 peer_supp_chwd_set =
235 GET_VHTCAP_CHWDSET(le32_to_cpu(vht_cap->vht_cap_info));
236 supp_chwd_set = min_t(u8, supp_chwd_set, peer_supp_chwd_set);
237
238 /* We need check AP's bandwidth when TDLS_WIDER_BANDWIDTH is off */
239
240 if (ap_vht_cap && sta_ptr->tdls_cap.extcap.ext_capab[7] &
241 WLAN_EXT_CAPA8_TDLS_WIDE_BW_ENABLED) {
242 ap_supp_chwd_set =
243 GET_VHTCAP_CHWDSET(le32_to_cpu(ap_vht_cap->vht_cap_info));
244 supp_chwd_set = min_t(u8, supp_chwd_set, ap_supp_chwd_set);
245 }
246
247 switch (supp_chwd_set) {
248 case IEEE80211_VHT_CHANWIDTH_80MHZ:
249 vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80MHZ;
250 break;
251 case IEEE80211_VHT_CHANWIDTH_160MHZ:
252 vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_160MHZ;
253 break;
254 case IEEE80211_VHT_CHANWIDTH_80P80MHZ:
255 vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80P80MHZ;
256 break;
257 default:
258 vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_USE_HT;
259 break;
260 }
261
262 mcs_map_user = GET_DEVRXMCSMAP(adapter->usr_dot_11ac_mcs_support);
263 mcs_map_resp = le16_to_cpu(vht_cap->supp_mcs.rx_mcs_map);
264 mcs_map_result = 0;
265
266 for (nss = 1; nss <= 8; nss++) {
267 mcs_user = GET_VHTNSSMCS(mcs_map_user, nss);
268 mcs_resp = GET_VHTNSSMCS(mcs_map_resp, nss);
269
270 if ((mcs_user == IEEE80211_VHT_MCS_NOT_SUPPORTED) ||
271 (mcs_resp == IEEE80211_VHT_MCS_NOT_SUPPORTED))
272 SET_VHTNSSMCS(mcs_map_result, nss,
273 IEEE80211_VHT_MCS_NOT_SUPPORTED);
274 else
275 SET_VHTNSSMCS(mcs_map_result, nss,
276 min_t(u16, mcs_user, mcs_resp));
277 }
278
279 vht_oper->basic_mcs_set = cpu_to_le16(mcs_map_result);
280
281 switch (vht_oper->chan_width) {
282 case IEEE80211_VHT_CHANWIDTH_80MHZ:
283 chan_bw = IEEE80211_VHT_CHANWIDTH_80MHZ;
284 break;
285 case IEEE80211_VHT_CHANWIDTH_160MHZ:
286 chan_bw = IEEE80211_VHT_CHANWIDTH_160MHZ;
287 break;
288 case IEEE80211_VHT_CHANWIDTH_80P80MHZ:
289 chan_bw = IEEE80211_VHT_CHANWIDTH_80MHZ;
290 break;
291 default:
292 chan_bw = IEEE80211_VHT_CHANWIDTH_USE_HT;
293 break;
294 }
295 vht_oper->center_freq_seg1_idx =
296 mwifiex_get_center_freq_index(priv, BAND_AAC,
297 bss_desc->channel,
298 chan_bw);
299
300 return 0;
301}
302
303static void mwifiex_tdls_add_ext_capab(struct mwifiex_private *priv,
304 struct sk_buff *skb)
305{
306 struct ieee_types_extcap *extcap;
307
308 extcap = (void *)skb_put(skb, sizeof(struct ieee_types_extcap));
309 extcap->ieee_hdr.element_id = WLAN_EID_EXT_CAPABILITY;
310 extcap->ieee_hdr.len = 8;
311 memset(extcap->ext_capab, 0, 8);
312 extcap->ext_capab[4] |= WLAN_EXT_CAPA5_TDLS_ENABLED;
313
314 if (priv->adapter->is_hw_11ac_capable)
315 extcap->ext_capab[7] |= WLAN_EXT_CAPA8_TDLS_WIDE_BW_ENABLED;
316}
317
318static void mwifiex_tdls_add_qos_capab(struct sk_buff *skb)
319{
320 u8 *pos = (void *)skb_put(skb, 3);
321
322 *pos++ = WLAN_EID_QOS_CAPA;
323 *pos++ = 1;
324 *pos++ = MWIFIEX_TDLS_DEF_QOS_CAPAB;
325}
326
327static int mwifiex_prep_tdls_encap_data(struct mwifiex_private *priv,
328 u8 *peer, u8 action_code, u8 dialog_token,
329 u16 status_code, struct sk_buff *skb)
330{
331 struct ieee80211_tdls_data *tf;
332 int ret;
333 u16 capab;
334 struct ieee80211_ht_cap *ht_cap;
335 u8 radio, *pos;
336
337 capab = priv->curr_bss_params.bss_descriptor.cap_info_bitmap;
338
339 tf = (void *)skb_put(skb, offsetof(struct ieee80211_tdls_data, u));
340 memcpy(tf->da, peer, ETH_ALEN);
341 memcpy(tf->sa, priv->curr_addr, ETH_ALEN);
342 tf->ether_type = cpu_to_be16(ETH_P_TDLS);
343 tf->payload_type = WLAN_TDLS_SNAP_RFTYPE;
344
345 switch (action_code) {
346 case WLAN_TDLS_SETUP_REQUEST:
347 tf->category = WLAN_CATEGORY_TDLS;
348 tf->action_code = WLAN_TDLS_SETUP_REQUEST;
349 skb_put(skb, sizeof(tf->u.setup_req));
350 tf->u.setup_req.dialog_token = dialog_token;
351 tf->u.setup_req.capability = cpu_to_le16(capab);
352 ret = mwifiex_tdls_append_rates_ie(priv, skb);
353 if (ret) {
354 dev_kfree_skb_any(skb);
355 return ret;
356 }
357
358 pos = (void *)skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
359 *pos++ = WLAN_EID_HT_CAPABILITY;
360 *pos++ = sizeof(struct ieee80211_ht_cap);
361 ht_cap = (void *)pos;
362 radio = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
363 ret = mwifiex_fill_cap_info(priv, radio, ht_cap);
364 if (ret) {
365 dev_kfree_skb_any(skb);
366 return ret;
367 }
368
369 if (priv->adapter->is_hw_11ac_capable) {
370 ret = mwifiex_tdls_add_vht_capab(priv, skb);
371 if (ret) {
372 dev_kfree_skb_any(skb);
373 return ret;
374 }
375 mwifiex_tdls_add_aid(priv, skb);
376 }
377
378 mwifiex_tdls_add_ext_capab(priv, skb);
379 mwifiex_tdls_add_qos_capab(skb);
380 break;
381
382 case WLAN_TDLS_SETUP_RESPONSE:
383 tf->category = WLAN_CATEGORY_TDLS;
384 tf->action_code = WLAN_TDLS_SETUP_RESPONSE;
385 skb_put(skb, sizeof(tf->u.setup_resp));
386 tf->u.setup_resp.status_code = cpu_to_le16(status_code);
387 tf->u.setup_resp.dialog_token = dialog_token;
388 tf->u.setup_resp.capability = cpu_to_le16(capab);
389 ret = mwifiex_tdls_append_rates_ie(priv, skb);
390 if (ret) {
391 dev_kfree_skb_any(skb);
392 return ret;
393 }
394
395 pos = (void *)skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
396 *pos++ = WLAN_EID_HT_CAPABILITY;
397 *pos++ = sizeof(struct ieee80211_ht_cap);
398 ht_cap = (void *)pos;
399 radio = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
400 ret = mwifiex_fill_cap_info(priv, radio, ht_cap);
401 if (ret) {
402 dev_kfree_skb_any(skb);
403 return ret;
404 }
405
406 if (priv->adapter->is_hw_11ac_capable) {
407 ret = mwifiex_tdls_add_vht_capab(priv, skb);
408 if (ret) {
409 dev_kfree_skb_any(skb);
410 return ret;
411 }
412 mwifiex_tdls_add_aid(priv, skb);
413 }
414
415 mwifiex_tdls_add_ext_capab(priv, skb);
416 mwifiex_tdls_add_qos_capab(skb);
417 break;
418
419 case WLAN_TDLS_SETUP_CONFIRM:
420 tf->category = WLAN_CATEGORY_TDLS;
421 tf->action_code = WLAN_TDLS_SETUP_CONFIRM;
422 skb_put(skb, sizeof(tf->u.setup_cfm));
423 tf->u.setup_cfm.status_code = cpu_to_le16(status_code);
424 tf->u.setup_cfm.dialog_token = dialog_token;
425 if (priv->adapter->is_hw_11ac_capable) {
426 ret = mwifiex_tdls_add_vht_oper(priv, peer, skb);
427 if (ret) {
428 dev_kfree_skb_any(skb);
429 return ret;
430 }
431 }
432 break;
433
434 case WLAN_TDLS_TEARDOWN:
435 tf->category = WLAN_CATEGORY_TDLS;
436 tf->action_code = WLAN_TDLS_TEARDOWN;
437 skb_put(skb, sizeof(tf->u.teardown));
438 tf->u.teardown.reason_code = cpu_to_le16(status_code);
439 break;
440
441 case WLAN_TDLS_DISCOVERY_REQUEST:
442 tf->category = WLAN_CATEGORY_TDLS;
443 tf->action_code = WLAN_TDLS_DISCOVERY_REQUEST;
444 skb_put(skb, sizeof(tf->u.discover_req));
445 tf->u.discover_req.dialog_token = dialog_token;
446 break;
447 default:
448 dev_err(priv->adapter->dev, "Unknown TDLS frame type.\n");
449 return -EINVAL;
450 }
451
452 return 0;
453}
454
455static void
456mwifiex_tdls_add_link_ie(struct sk_buff *skb, u8 *src_addr, u8 *peer, u8 *bssid)
457{
458 struct ieee80211_tdls_lnkie *lnkid;
459
460 lnkid = (void *)skb_put(skb, sizeof(struct ieee80211_tdls_lnkie));
461 lnkid->ie_type = WLAN_EID_LINK_ID;
462 lnkid->ie_len = sizeof(struct ieee80211_tdls_lnkie) -
463 sizeof(struct ieee_types_header);
464
465 memcpy(lnkid->bssid, bssid, ETH_ALEN);
466 memcpy(lnkid->init_sta, src_addr, ETH_ALEN);
467 memcpy(lnkid->resp_sta, peer, ETH_ALEN);
468}
469
470int mwifiex_send_tdls_data_frame(struct mwifiex_private *priv,
471 u8 *peer, u8 action_code, u8 dialog_token,
472 u16 status_code, const u8 *extra_ies,
473 size_t extra_ies_len)
474{
475 struct sk_buff *skb;
476 struct mwifiex_txinfo *tx_info;
477 struct timeval tv;
478 int ret;
479 u16 skb_len;
480
481 skb_len = MWIFIEX_MIN_DATA_HEADER_LEN +
482 max(sizeof(struct ieee80211_mgmt),
483 sizeof(struct ieee80211_tdls_data)) +
484 MWIFIEX_MGMT_FRAME_HEADER_SIZE +
485 MWIFIEX_SUPPORTED_RATES +
486 3 + /* Qos Info */
487 sizeof(struct ieee_types_extcap) +
488 sizeof(struct ieee80211_ht_cap) +
489 sizeof(struct ieee_types_bss_co_2040) +
490 sizeof(struct ieee80211_ht_operation) +
491 sizeof(struct ieee80211_tdls_lnkie) +
492 extra_ies_len;
493
494 if (priv->adapter->is_hw_11ac_capable)
495 skb_len += sizeof(struct ieee_types_vht_cap) +
496 sizeof(struct ieee_types_vht_oper) +
497 sizeof(struct ieee_types_aid);
498
499 skb = dev_alloc_skb(skb_len);
500 if (!skb) {
501 dev_err(priv->adapter->dev,
502 "allocate skb failed for management frame\n");
503 return -ENOMEM;
504 }
505 skb_reserve(skb, MWIFIEX_MIN_DATA_HEADER_LEN);
506
507 switch (action_code) {
508 case WLAN_TDLS_SETUP_REQUEST:
509 case WLAN_TDLS_SETUP_CONFIRM:
510 case WLAN_TDLS_TEARDOWN:
511 case WLAN_TDLS_DISCOVERY_REQUEST:
512 ret = mwifiex_prep_tdls_encap_data(priv, peer, action_code,
513 dialog_token, status_code,
514 skb);
515 if (ret) {
516 dev_kfree_skb_any(skb);
517 return ret;
518 }
519 if (extra_ies_len)
520 memcpy(skb_put(skb, extra_ies_len), extra_ies,
521 extra_ies_len);
522 mwifiex_tdls_add_link_ie(skb, priv->curr_addr, peer,
523 priv->cfg_bssid);
524 break;
525 case WLAN_TDLS_SETUP_RESPONSE:
526 ret = mwifiex_prep_tdls_encap_data(priv, peer, action_code,
527 dialog_token, status_code,
528 skb);
529 if (ret) {
530 dev_kfree_skb_any(skb);
531 return ret;
532 }
533 if (extra_ies_len)
534 memcpy(skb_put(skb, extra_ies_len), extra_ies,
535 extra_ies_len);
536 mwifiex_tdls_add_link_ie(skb, peer, priv->curr_addr,
537 priv->cfg_bssid);
538 break;
539 }
540
541 switch (action_code) {
542 case WLAN_TDLS_SETUP_REQUEST:
543 case WLAN_TDLS_SETUP_RESPONSE:
544 skb->priority = MWIFIEX_PRIO_BK;
545 break;
546 default:
547 skb->priority = MWIFIEX_PRIO_VI;
548 break;
549 }
550
551 tx_info = MWIFIEX_SKB_TXCB(skb);
552 tx_info->bss_num = priv->bss_num;
553 tx_info->bss_type = priv->bss_type;
554
555 do_gettimeofday(&tv);
556 skb->tstamp = timeval_to_ktime(tv);
557 mwifiex_queue_tx_pkt(priv, skb);
558
559 return 0;
560}
561
562static int
563mwifiex_construct_tdls_action_frame(struct mwifiex_private *priv, u8 *peer,
564 u8 action_code, u8 dialog_token,
565 u16 status_code, struct sk_buff *skb)
566{
567 struct ieee80211_mgmt *mgmt;
568 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
569 int ret;
570 u16 capab;
571 struct ieee80211_ht_cap *ht_cap;
572 u8 radio, *pos;
573
574 capab = priv->curr_bss_params.bss_descriptor.cap_info_bitmap;
575
576 mgmt = (void *)skb_put(skb, offsetof(struct ieee80211_mgmt, u));
577
578 memset(mgmt, 0, 24);
579 memcpy(mgmt->da, peer, ETH_ALEN);
580 memcpy(mgmt->sa, priv->curr_addr, ETH_ALEN);
581 memcpy(mgmt->bssid, priv->cfg_bssid, ETH_ALEN);
582 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
583 IEEE80211_STYPE_ACTION);
584
585 /* add address 4 */
586 pos = skb_put(skb, ETH_ALEN);
587
588 switch (action_code) {
589 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
590 skb_put(skb, sizeof(mgmt->u.action.u.tdls_discover_resp) + 1);
591 mgmt->u.action.category = WLAN_CATEGORY_PUBLIC;
592 mgmt->u.action.u.tdls_discover_resp.action_code =
593 WLAN_PUB_ACTION_TDLS_DISCOVER_RES;
594 mgmt->u.action.u.tdls_discover_resp.dialog_token =
595 dialog_token;
596 mgmt->u.action.u.tdls_discover_resp.capability =
597 cpu_to_le16(capab);
598 /* move back for addr4 */
599 memmove(pos + ETH_ALEN, &mgmt->u.action.category,
600 sizeof(mgmt->u.action.u.tdls_discover_resp));
601 /* init address 4 */
602 memcpy(pos, bc_addr, ETH_ALEN);
603
604 ret = mwifiex_tdls_append_rates_ie(priv, skb);
605 if (ret) {
606 dev_kfree_skb_any(skb);
607 return ret;
608 }
609
610 pos = (void *)skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
611 *pos++ = WLAN_EID_HT_CAPABILITY;
612 *pos++ = sizeof(struct ieee80211_ht_cap);
613 ht_cap = (void *)pos;
614 radio = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
615 ret = mwifiex_fill_cap_info(priv, radio, ht_cap);
616 if (ret) {
617 dev_kfree_skb_any(skb);
618 return ret;
619 }
620
621 if (priv->adapter->is_hw_11ac_capable) {
622 ret = mwifiex_tdls_add_vht_capab(priv, skb);
623 if (ret) {
624 dev_kfree_skb_any(skb);
625 return ret;
626 }
627 mwifiex_tdls_add_aid(priv, skb);
628 }
629
630 mwifiex_tdls_add_ext_capab(priv, skb);
631 mwifiex_tdls_add_qos_capab(skb);
632 break;
633 default:
634 dev_err(priv->adapter->dev, "Unknown TDLS action frame type\n");
635 return -EINVAL;
636 }
637
638 return 0;
639}
640
641int mwifiex_send_tdls_action_frame(struct mwifiex_private *priv,
642 u8 *peer, u8 action_code, u8 dialog_token,
643 u16 status_code, const u8 *extra_ies,
644 size_t extra_ies_len)
645{
646 struct sk_buff *skb;
647 struct mwifiex_txinfo *tx_info;
648 struct timeval tv;
649 u8 *pos;
650 u32 pkt_type, tx_control;
651 u16 pkt_len, skb_len;
652
653 skb_len = MWIFIEX_MIN_DATA_HEADER_LEN +
654 max(sizeof(struct ieee80211_mgmt),
655 sizeof(struct ieee80211_tdls_data)) +
656 MWIFIEX_MGMT_FRAME_HEADER_SIZE +
657 MWIFIEX_SUPPORTED_RATES +
658 sizeof(struct ieee_types_extcap) +
659 sizeof(struct ieee80211_ht_cap) +
660 sizeof(struct ieee_types_bss_co_2040) +
661 sizeof(struct ieee80211_ht_operation) +
662 sizeof(struct ieee80211_tdls_lnkie) +
663 extra_ies_len +
664 3 + /* Qos Info */
665 ETH_ALEN; /* Address4 */
666
667 if (priv->adapter->is_hw_11ac_capable)
668 skb_len += sizeof(struct ieee_types_vht_cap) +
669 sizeof(struct ieee_types_vht_oper) +
670 sizeof(struct ieee_types_aid);
671
672 skb = dev_alloc_skb(skb_len);
673 if (!skb) {
674 dev_err(priv->adapter->dev,
675 "allocate skb failed for management frame\n");
676 return -ENOMEM;
677 }
678
679 skb_reserve(skb, MWIFIEX_MIN_DATA_HEADER_LEN);
680
681 pkt_type = PKT_TYPE_MGMT;
682 tx_control = 0;
683 pos = skb_put(skb, MWIFIEX_MGMT_FRAME_HEADER_SIZE + sizeof(pkt_len));
684 memset(pos, 0, MWIFIEX_MGMT_FRAME_HEADER_SIZE + sizeof(pkt_len));
685 memcpy(pos, &pkt_type, sizeof(pkt_type));
686 memcpy(pos + sizeof(pkt_type), &tx_control, sizeof(tx_control));
687
688 if (mwifiex_construct_tdls_action_frame(priv, peer, action_code,
689 dialog_token, status_code,
690 skb)) {
691 dev_kfree_skb_any(skb);
692 return -EINVAL;
693 }
694
695 if (extra_ies_len)
696 memcpy(skb_put(skb, extra_ies_len), extra_ies, extra_ies_len);
697
698 /* the TDLS link IE is always added last we are the responder */
699
700 mwifiex_tdls_add_link_ie(skb, peer, priv->curr_addr,
701 priv->cfg_bssid);
702
703 skb->priority = MWIFIEX_PRIO_VI;
704
705 tx_info = MWIFIEX_SKB_TXCB(skb);
706 tx_info->bss_num = priv->bss_num;
707 tx_info->bss_type = priv->bss_type;
708 tx_info->flags |= MWIFIEX_BUF_FLAG_TDLS_PKT;
709
710 pkt_len = skb->len - MWIFIEX_MGMT_FRAME_HEADER_SIZE - sizeof(pkt_len);
711 memcpy(skb->data + MWIFIEX_MGMT_FRAME_HEADER_SIZE, &pkt_len,
712 sizeof(pkt_len));
713 do_gettimeofday(&tv);
714 skb->tstamp = timeval_to_ktime(tv);
715 mwifiex_queue_tx_pkt(priv, skb);
716
717 return 0;
718}
719
720/* This function process tdls action frame from peer.
721 * Peer capabilities are stored into station node structure.
722 */
723void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
724 u8 *buf, int len)
725{
726 struct mwifiex_sta_node *sta_ptr;
727 u8 *peer, *pos, *end;
728 u8 i, action, basic;
729 int ie_len = 0;
730
731 if (len < (sizeof(struct ethhdr) + 3))
732 return;
733 if (*(u8 *)(buf + sizeof(struct ethhdr)) != WLAN_TDLS_SNAP_RFTYPE)
734 return;
735 if (*(u8 *)(buf + sizeof(struct ethhdr) + 1) != WLAN_CATEGORY_TDLS)
736 return;
737
738 peer = buf + ETH_ALEN;
739 action = *(u8 *)(buf + sizeof(struct ethhdr) + 2);
740
741 /* just handle TDLS setup request/response/confirm */
742 if (action > WLAN_TDLS_SETUP_CONFIRM)
743 return;
744
745 dev_dbg(priv->adapter->dev,
746 "rx:tdls action: peer=%pM, action=%d\n", peer, action);
747
748 sta_ptr = mwifiex_add_sta_entry(priv, peer);
749 if (!sta_ptr)
750 return;
751
752 switch (action) {
753 case WLAN_TDLS_SETUP_REQUEST:
754 if (len < (sizeof(struct ethhdr) + TDLS_REQ_FIX_LEN))
755 return;
756
757 pos = buf + sizeof(struct ethhdr) + 4;
758 /* payload 1+ category 1 + action 1 + dialog 1 */
759 sta_ptr->tdls_cap.capab = cpu_to_le16(*(u16 *)pos);
760 ie_len = len - sizeof(struct ethhdr) - TDLS_REQ_FIX_LEN;
761 pos += 2;
762 break;
763
764 case WLAN_TDLS_SETUP_RESPONSE:
765 if (len < (sizeof(struct ethhdr) + TDLS_RESP_FIX_LEN))
766 return;
767 /* payload 1+ category 1 + action 1 + dialog 1 + status code 2*/
768 pos = buf + sizeof(struct ethhdr) + 6;
769 sta_ptr->tdls_cap.capab = cpu_to_le16(*(u16 *)pos);
770 ie_len = len - sizeof(struct ethhdr) - TDLS_RESP_FIX_LEN;
771 pos += 2;
772 break;
773
774 case WLAN_TDLS_SETUP_CONFIRM:
775 if (len < (sizeof(struct ethhdr) + TDLS_CONFIRM_FIX_LEN))
776 return;
777 pos = buf + sizeof(struct ethhdr) + TDLS_CONFIRM_FIX_LEN;
778 ie_len = len - sizeof(struct ethhdr) - TDLS_CONFIRM_FIX_LEN;
779 break;
780 default:
781 dev_warn(priv->adapter->dev, "Unknown TDLS frame type.\n");
782 return;
783 }
784
785 for (end = pos + ie_len; pos + 1 < end; pos += 2 + pos[1]) {
786 if (pos + 2 + pos[1] > end)
787 break;
788
789 switch (*pos) {
790 case WLAN_EID_SUPP_RATES:
791 sta_ptr->tdls_cap.rates_len = pos[1];
792 for (i = 0; i < pos[1]; i++)
793 sta_ptr->tdls_cap.rates[i] = pos[i + 2];
794 break;
795
796 case WLAN_EID_EXT_SUPP_RATES:
797 basic = sta_ptr->tdls_cap.rates_len;
798 for (i = 0; i < pos[1]; i++)
799 sta_ptr->tdls_cap.rates[basic + i] = pos[i + 2];
800 sta_ptr->tdls_cap.rates_len += pos[1];
801 break;
802 case WLAN_EID_HT_CAPABILITY:
803 memcpy((u8 *)&sta_ptr->tdls_cap.ht_capb, pos,
804 sizeof(struct ieee80211_ht_cap));
805 sta_ptr->is_11n_enabled = 1;
806 break;
807 case WLAN_EID_HT_OPERATION:
808 memcpy(&sta_ptr->tdls_cap.ht_oper, pos,
809 sizeof(struct ieee80211_ht_operation));
810 break;
811 case WLAN_EID_BSS_COEX_2040:
812 sta_ptr->tdls_cap.coex_2040 = pos[2];
813 break;
814 case WLAN_EID_EXT_CAPABILITY:
815 memcpy((u8 *)&sta_ptr->tdls_cap.extcap, pos,
816 sizeof(struct ieee_types_header) +
817 min_t(u8, pos[1], 8));
818 break;
819 case WLAN_EID_RSN:
820 memcpy((u8 *)&sta_ptr->tdls_cap.rsn_ie, pos,
821 sizeof(struct ieee_types_header) + pos[1]);
822 break;
823 case WLAN_EID_QOS_CAPA:
824 sta_ptr->tdls_cap.qos_info = pos[2];
825 break;
826 case WLAN_EID_VHT_OPERATION:
827 if (priv->adapter->is_hw_11ac_capable)
828 memcpy(&sta_ptr->tdls_cap.vhtoper, pos,
829 sizeof(struct ieee80211_vht_operation));
830 break;
831 case WLAN_EID_VHT_CAPABILITY:
832 if (priv->adapter->is_hw_11ac_capable) {
833 memcpy((u8 *)&sta_ptr->tdls_cap.vhtcap, pos,
834 sizeof(struct ieee80211_vht_cap));
835 sta_ptr->is_11ac_enabled = 1;
836 }
837 break;
838 case WLAN_EID_AID:
839 if (priv->adapter->is_hw_11ac_capable)
840 sta_ptr->tdls_cap.aid =
841 le16_to_cpu(*(__le16 *)(pos + 2));
842 default:
843 break;
844 }
845 }
846
847 return;
848}
849
850static int
851mwifiex_tdls_process_config_link(struct mwifiex_private *priv, u8 *peer)
852{
853 struct mwifiex_sta_node *sta_ptr;
854 struct mwifiex_ds_tdls_oper tdls_oper;
855
856 memset(&tdls_oper, 0, sizeof(struct mwifiex_ds_tdls_oper));
857 sta_ptr = mwifiex_get_sta_entry(priv, peer);
858
859 if (!sta_ptr || sta_ptr->tdls_status == TDLS_SETUP_FAILURE) {
860 dev_err(priv->adapter->dev,
861 "link absent for peer %pM; cannot config\n", peer);
862 return -EINVAL;
863 }
864
865 memcpy(&tdls_oper.peer_mac, peer, ETH_ALEN);
866 tdls_oper.tdls_action = MWIFIEX_TDLS_CONFIG_LINK;
867 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_OPER,
868 HostCmd_ACT_GEN_SET, 0, &tdls_oper, true);
869}
870
871static int
872mwifiex_tdls_process_create_link(struct mwifiex_private *priv, u8 *peer)
873{
874 struct mwifiex_sta_node *sta_ptr;
875 struct mwifiex_ds_tdls_oper tdls_oper;
876
877 memset(&tdls_oper, 0, sizeof(struct mwifiex_ds_tdls_oper));
878 sta_ptr = mwifiex_get_sta_entry(priv, peer);
879
880 if (sta_ptr && sta_ptr->tdls_status == TDLS_SETUP_INPROGRESS) {
881 dev_dbg(priv->adapter->dev,
882 "Setup already in progress for peer %pM\n", peer);
883 return 0;
884 }
885
886 sta_ptr = mwifiex_add_sta_entry(priv, peer);
887 if (!sta_ptr)
888 return -ENOMEM;
889
890 sta_ptr->tdls_status = TDLS_SETUP_INPROGRESS;
891 mwifiex_hold_tdls_packets(priv, peer);
892 memcpy(&tdls_oper.peer_mac, peer, ETH_ALEN);
893 tdls_oper.tdls_action = MWIFIEX_TDLS_CREATE_LINK;
894 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_OPER,
895 HostCmd_ACT_GEN_SET, 0, &tdls_oper, true);
896}
897
898static int
899mwifiex_tdls_process_disable_link(struct mwifiex_private *priv, u8 *peer)
900{
901 struct mwifiex_sta_node *sta_ptr;
902 struct mwifiex_ds_tdls_oper tdls_oper;
903 unsigned long flags;
904
905 memset(&tdls_oper, 0, sizeof(struct mwifiex_ds_tdls_oper));
906 sta_ptr = mwifiex_get_sta_entry(priv, peer);
907
908 if (sta_ptr) {
909 if (sta_ptr->is_11n_enabled) {
910 mwifiex_11n_cleanup_reorder_tbl(priv);
911 spin_lock_irqsave(&priv->wmm.ra_list_spinlock,
912 flags);
913 mwifiex_11n_delete_all_tx_ba_stream_tbl(priv);
914 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
915 flags);
916 }
917 mwifiex_del_sta_entry(priv, peer);
918 }
919
920 mwifiex_restore_tdls_packets(priv, peer, TDLS_LINK_TEARDOWN);
921 memcpy(&tdls_oper.peer_mac, peer, ETH_ALEN);
922 tdls_oper.tdls_action = MWIFIEX_TDLS_DISABLE_LINK;
923 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_OPER,
924 HostCmd_ACT_GEN_SET, 0, &tdls_oper, true);
925}
926
927static int
928mwifiex_tdls_process_enable_link(struct mwifiex_private *priv, u8 *peer)
929{
930 struct mwifiex_sta_node *sta_ptr;
931 struct ieee80211_mcs_info mcs;
932 unsigned long flags;
933 int i;
934
935 sta_ptr = mwifiex_get_sta_entry(priv, peer);
936
937 if (sta_ptr && (sta_ptr->tdls_status != TDLS_SETUP_FAILURE)) {
938 dev_dbg(priv->adapter->dev,
939 "tdls: enable link %pM success\n", peer);
940
941 sta_ptr->tdls_status = TDLS_SETUP_COMPLETE;
942
943 mcs = sta_ptr->tdls_cap.ht_capb.mcs;
944 if (mcs.rx_mask[0] != 0xff)
945 sta_ptr->is_11n_enabled = true;
946 if (sta_ptr->is_11n_enabled) {
947 if (le16_to_cpu(sta_ptr->tdls_cap.ht_capb.cap_info) &
948 IEEE80211_HT_CAP_MAX_AMSDU)
949 sta_ptr->max_amsdu =
950 MWIFIEX_TX_DATA_BUF_SIZE_8K;
951 else
952 sta_ptr->max_amsdu =
953 MWIFIEX_TX_DATA_BUF_SIZE_4K;
954
955 for (i = 0; i < MAX_NUM_TID; i++)
956 sta_ptr->ampdu_sta[i] =
957 priv->aggr_prio_tbl[i].ampdu_user;
958 } else {
959 for (i = 0; i < MAX_NUM_TID; i++)
960 sta_ptr->ampdu_sta[i] = BA_STREAM_NOT_ALLOWED;
961 }
962
963 memset(sta_ptr->rx_seq, 0xff, sizeof(sta_ptr->rx_seq));
964 mwifiex_restore_tdls_packets(priv, peer, TDLS_SETUP_COMPLETE);
965 } else {
966 dev_dbg(priv->adapter->dev,
967 "tdls: enable link %pM failed\n", peer);
968 if (sta_ptr) {
969 mwifiex_11n_cleanup_reorder_tbl(priv);
970 spin_lock_irqsave(&priv->wmm.ra_list_spinlock,
971 flags);
972 mwifiex_11n_delete_all_tx_ba_stream_tbl(priv);
973 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
974 flags);
975 mwifiex_del_sta_entry(priv, peer);
976 }
977 mwifiex_restore_tdls_packets(priv, peer, TDLS_LINK_TEARDOWN);
978
979 return -1;
980 }
981
982 return 0;
983}
984
985int mwifiex_tdls_oper(struct mwifiex_private *priv, u8 *peer, u8 action)
986{
987 switch (action) {
988 case MWIFIEX_TDLS_ENABLE_LINK:
989 return mwifiex_tdls_process_enable_link(priv, peer);
990 case MWIFIEX_TDLS_DISABLE_LINK:
991 return mwifiex_tdls_process_disable_link(priv, peer);
992 case MWIFIEX_TDLS_CREATE_LINK:
993 return mwifiex_tdls_process_create_link(priv, peer);
994 case MWIFIEX_TDLS_CONFIG_LINK:
995 return mwifiex_tdls_process_config_link(priv, peer);
996 }
997 return 0;
998}
999
1000int mwifiex_get_tdls_link_status(struct mwifiex_private *priv, u8 *mac)
1001{
1002 struct mwifiex_sta_node *sta_ptr;
1003
1004 sta_ptr = mwifiex_get_sta_entry(priv, mac);
1005 if (sta_ptr)
1006 return sta_ptr->tdls_status;
1007
1008 return TDLS_NOT_SETUP;
1009}
1010
1011void mwifiex_disable_all_tdls_links(struct mwifiex_private *priv)
1012{
1013 struct mwifiex_sta_node *sta_ptr;
1014 struct mwifiex_ds_tdls_oper tdls_oper;
1015 unsigned long flags;
1016
1017 if (list_empty(&priv->sta_list))
1018 return;
1019
1020 list_for_each_entry(sta_ptr, &priv->sta_list, list) {
1021 memset(&tdls_oper, 0, sizeof(struct mwifiex_ds_tdls_oper));
1022
1023 if (sta_ptr->is_11n_enabled) {
1024 mwifiex_11n_cleanup_reorder_tbl(priv);
1025 spin_lock_irqsave(&priv->wmm.ra_list_spinlock,
1026 flags);
1027 mwifiex_11n_delete_all_tx_ba_stream_tbl(priv);
1028 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
1029 flags);
1030 }
1031
1032 mwifiex_restore_tdls_packets(priv, sta_ptr->mac_addr,
1033 TDLS_LINK_TEARDOWN);
1034 memcpy(&tdls_oper.peer_mac, sta_ptr->mac_addr, ETH_ALEN);
1035 tdls_oper.tdls_action = MWIFIEX_TDLS_DISABLE_LINK;
1036 if (mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_OPER,
1037 HostCmd_ACT_GEN_SET, 0, &tdls_oper, false))
1038 dev_warn(priv->adapter->dev,
1039 "Disable link failed for TDLS peer %pM",
1040 sta_ptr->mac_addr);
1041 }
1042
1043 mwifiex_del_all_sta_list(priv);
1044}
diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c
index 64424c81b44f..9be6544bdded 100644
--- a/drivers/net/wireless/mwifiex/uap_cmd.c
+++ b/drivers/net/wireless/mwifiex/uap_cmd.c
@@ -159,6 +159,7 @@ mwifiex_set_ht_params(struct mwifiex_private *priv,
159 struct cfg80211_ap_settings *params) 159 struct cfg80211_ap_settings *params)
160{ 160{
161 const u8 *ht_ie; 161 const u8 *ht_ie;
162 u16 cap_info;
162 163
163 if (!ISSUPP_11NENABLED(priv->adapter->fw_cap_info)) 164 if (!ISSUPP_11NENABLED(priv->adapter->fw_cap_info))
164 return; 165 return;
@@ -168,6 +169,25 @@ mwifiex_set_ht_params(struct mwifiex_private *priv,
168 if (ht_ie) { 169 if (ht_ie) {
169 memcpy(&bss_cfg->ht_cap, ht_ie + 2, 170 memcpy(&bss_cfg->ht_cap, ht_ie + 2,
170 sizeof(struct ieee80211_ht_cap)); 171 sizeof(struct ieee80211_ht_cap));
172 cap_info = le16_to_cpu(bss_cfg->ht_cap.cap_info);
173 memset(&bss_cfg->ht_cap.mcs, 0,
174 priv->adapter->number_of_antenna);
175 switch (GET_RXSTBC(cap_info)) {
176 case MWIFIEX_RX_STBC1:
177 /* HT_CAP 1X1 mode */
178 memset(&bss_cfg->ht_cap.mcs, 0xff, 1);
179 break;
180 case MWIFIEX_RX_STBC12: /* fall through */
181 case MWIFIEX_RX_STBC123:
182 /* HT_CAP 2X2 mode */
183 memset(&bss_cfg->ht_cap.mcs, 0xff, 2);
184 break;
185 default:
186 dev_warn(priv->adapter->dev,
187 "Unsupported RX-STBC, default to 2x2\n");
188 memset(&bss_cfg->ht_cap.mcs, 0xff, 2);
189 break;
190 }
171 priv->ap_11n_enabled = 1; 191 priv->ap_11n_enabled = 1;
172 } else { 192 } else {
173 memset(&bss_cfg->ht_cap , 0, sizeof(struct ieee80211_ht_cap)); 193 memset(&bss_cfg->ht_cap , 0, sizeof(struct ieee80211_ht_cap));
@@ -226,8 +246,8 @@ void mwifiex_set_vht_width(struct mwifiex_private *priv,
226 if (ap_11ac_enable && width >= NL80211_CHAN_WIDTH_80) 246 if (ap_11ac_enable && width >= NL80211_CHAN_WIDTH_80)
227 vht_cfg.misc_config |= VHT_BW_80_160_80P80; 247 vht_cfg.misc_config |= VHT_BW_80_160_80P80;
228 248
229 mwifiex_send_cmd_sync(priv, HostCmd_CMD_11AC_CFG, 249 mwifiex_send_cmd(priv, HostCmd_CMD_11AC_CFG,
230 HostCmd_ACT_GEN_SET, 0, &vht_cfg); 250 HostCmd_ACT_GEN_SET, 0, &vht_cfg, true);
231 251
232 return; 252 return;
233} 253}
diff --git a/drivers/net/wireless/mwifiex/uap_event.c b/drivers/net/wireless/mwifiex/uap_event.c
index 718066577c6c..92e77a398ecf 100644
--- a/drivers/net/wireless/mwifiex/uap_event.c
+++ b/drivers/net/wireless/mwifiex/uap_event.c
@@ -21,126 +21,8 @@
21#include "main.h" 21#include "main.h"
22#include "11n.h" 22#include "11n.h"
23 23
24/*
25 * This function will return the pointer to station entry in station list
26 * table which matches specified mac address.
27 * This function should be called after acquiring RA list spinlock.
28 * NULL is returned if station entry is not found in associated STA list.
29 */
30struct mwifiex_sta_node *
31mwifiex_get_sta_entry(struct mwifiex_private *priv, u8 *mac)
32{
33 struct mwifiex_sta_node *node;
34
35 if (!mac)
36 return NULL;
37
38 list_for_each_entry(node, &priv->sta_list, list) {
39 if (!memcmp(node->mac_addr, mac, ETH_ALEN))
40 return node;
41 }
42
43 return NULL;
44}
45
46/*
47 * This function will add a sta_node entry to associated station list
48 * table with the given mac address.
49 * If entry exist already, existing entry is returned.
50 * If received mac address is NULL, NULL is returned.
51 */
52static struct mwifiex_sta_node *
53mwifiex_add_sta_entry(struct mwifiex_private *priv, u8 *mac)
54{
55 struct mwifiex_sta_node *node;
56 unsigned long flags;
57
58 if (!mac)
59 return NULL;
60
61 spin_lock_irqsave(&priv->sta_list_spinlock, flags);
62 node = mwifiex_get_sta_entry(priv, mac);
63 if (node)
64 goto done;
65
66 node = kzalloc(sizeof(struct mwifiex_sta_node), GFP_ATOMIC);
67 if (!node)
68 goto done;
69
70 memcpy(node->mac_addr, mac, ETH_ALEN);
71 list_add_tail(&node->list, &priv->sta_list);
72
73done:
74 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
75 return node;
76}
77
78/*
79 * This function will search for HT IE in association request IEs
80 * and set station HT parameters accordingly.
81 */
82static void
83mwifiex_set_sta_ht_cap(struct mwifiex_private *priv, const u8 *ies,
84 int ies_len, struct mwifiex_sta_node *node)
85{
86 const struct ieee80211_ht_cap *ht_cap;
87
88 if (!ies)
89 return;
90 24
91 ht_cap = (void *)cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, ies, ies_len);
92 if (ht_cap) {
93 node->is_11n_enabled = 1;
94 node->max_amsdu = le16_to_cpu(ht_cap->cap_info) &
95 IEEE80211_HT_CAP_MAX_AMSDU ?
96 MWIFIEX_TX_DATA_BUF_SIZE_8K :
97 MWIFIEX_TX_DATA_BUF_SIZE_4K;
98 } else {
99 node->is_11n_enabled = 0;
100 }
101 25
102 return;
103}
104
105/*
106 * This function will delete a station entry from station list
107 */
108static void mwifiex_del_sta_entry(struct mwifiex_private *priv, u8 *mac)
109{
110 struct mwifiex_sta_node *node;
111 unsigned long flags;
112
113 spin_lock_irqsave(&priv->sta_list_spinlock, flags);
114
115 node = mwifiex_get_sta_entry(priv, mac);
116 if (node) {
117 list_del(&node->list);
118 kfree(node);
119 }
120
121 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
122 return;
123}
124
125/*
126 * This function will delete all stations from associated station list.
127 */
128static void mwifiex_del_all_sta_list(struct mwifiex_private *priv)
129{
130 struct mwifiex_sta_node *node, *tmp;
131 unsigned long flags;
132
133 spin_lock_irqsave(&priv->sta_list_spinlock, flags);
134
135 list_for_each_entry_safe(node, tmp, &priv->sta_list, list) {
136 list_del(&node->list);
137 kfree(node);
138 }
139
140 INIT_LIST_HEAD(&priv->sta_list);
141 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
142 return;
143}
144 26
145/* 27/*
146 * This function handles AP interface specific events generated by firmware. 28 * This function handles AP interface specific events generated by firmware.
@@ -268,9 +150,9 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv)
268 case EVENT_ADDBA: 150 case EVENT_ADDBA:
269 dev_dbg(adapter->dev, "event: ADDBA Request\n"); 151 dev_dbg(adapter->dev, "event: ADDBA Request\n");
270 if (priv->media_connected) 152 if (priv->media_connected)
271 mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_ADDBA_RSP, 153 mwifiex_send_cmd(priv, HostCmd_CMD_11N_ADDBA_RSP,
272 HostCmd_ACT_GEN_SET, 0, 154 HostCmd_ACT_GEN_SET, 0,
273 adapter->event_body); 155 adapter->event_body, false);
274 break; 156 break;
275 case EVENT_DELBA: 157 case EVENT_DELBA:
276 dev_dbg(adapter->dev, "event: DELBA Request\n"); 158 dev_dbg(adapter->dev, "event: DELBA Request\n");
@@ -284,6 +166,12 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv)
284 mwifiex_11n_ba_stream_timeout(priv, ba_timeout); 166 mwifiex_11n_ba_stream_timeout(priv, ba_timeout);
285 } 167 }
286 break; 168 break;
169 case EVENT_EXT_SCAN_REPORT:
170 dev_dbg(adapter->dev, "event: EXT_SCAN Report\n");
171 if (adapter->ext_scan)
172 return mwifiex_handle_event_ext_scan_report(priv,
173 adapter->event_skb->data);
174 break;
287 default: 175 default:
288 dev_dbg(adapter->dev, "event: unknown event id: %#x\n", 176 dev_dbg(adapter->dev, "event: unknown event id: %#x\n",
289 eventcause); 177 eventcause);
diff --git a/drivers/net/wireless/mwifiex/uap_txrx.c b/drivers/net/wireless/mwifiex/uap_txrx.c
index 3c74eb254927..9a56bc61cb1d 100644
--- a/drivers/net/wireless/mwifiex/uap_txrx.c
+++ b/drivers/net/wireless/mwifiex/uap_txrx.c
@@ -284,27 +284,7 @@ int mwifiex_process_uap_rx_packet(struct mwifiex_private *priv,
284 return 0; 284 return 0;
285 } 285 }
286 286
287 if (le16_to_cpu(uap_rx_pd->rx_pkt_type) == PKT_TYPE_AMSDU) { 287 if (rx_pkt_type == PKT_TYPE_MGMT) {
288 struct sk_buff_head list;
289 struct sk_buff *rx_skb;
290
291 __skb_queue_head_init(&list);
292 skb_pull(skb, le16_to_cpu(uap_rx_pd->rx_pkt_offset));
293 skb_trim(skb, le16_to_cpu(uap_rx_pd->rx_pkt_length));
294
295 ieee80211_amsdu_to_8023s(skb, &list, priv->curr_addr,
296 priv->wdev->iftype, 0, false);
297
298 while (!skb_queue_empty(&list)) {
299 rx_skb = __skb_dequeue(&list);
300 ret = mwifiex_recv_packet(priv, rx_skb);
301 if (ret)
302 dev_err(adapter->dev,
303 "AP:Rx A-MSDU failed");
304 }
305
306 return 0;
307 } else if (rx_pkt_type == PKT_TYPE_MGMT) {
308 ret = mwifiex_process_mgmt_packet(priv, skb); 288 ret = mwifiex_process_mgmt_packet(priv, skb);
309 if (ret) 289 if (ret)
310 dev_err(adapter->dev, "Rx of mgmt packet failed"); 290 dev_err(adapter->dev, "Rx of mgmt packet failed");
diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c
index 208748804a55..ae30c390ebd3 100644
--- a/drivers/net/wireless/mwifiex/usb.c
+++ b/drivers/net/wireless/mwifiex/usb.c
@@ -766,11 +766,13 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
766 switch (le16_to_cpu(card->udev->descriptor.idProduct)) { 766 switch (le16_to_cpu(card->udev->descriptor.idProduct)) {
767 case USB8897_PID_1: 767 case USB8897_PID_1:
768 case USB8897_PID_2: 768 case USB8897_PID_2:
769 adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K;
769 strcpy(adapter->fw_name, USB8897_DEFAULT_FW_NAME); 770 strcpy(adapter->fw_name, USB8897_DEFAULT_FW_NAME);
770 break; 771 break;
771 case USB8797_PID_1: 772 case USB8797_PID_1:
772 case USB8797_PID_2: 773 case USB8797_PID_2:
773 default: 774 default:
775 adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
774 strcpy(adapter->fw_name, USB8797_DEFAULT_FW_NAME); 776 strcpy(adapter->fw_name, USB8797_DEFAULT_FW_NAME);
775 break; 777 break;
776 } 778 }
@@ -1024,7 +1026,6 @@ static void mwifiex_usb_cleanup_module(void)
1024 1026
1025 if (usb_card && usb_card->adapter) { 1027 if (usb_card && usb_card->adapter) {
1026 struct mwifiex_adapter *adapter = usb_card->adapter; 1028 struct mwifiex_adapter *adapter = usb_card->adapter;
1027 int i;
1028 1029
1029 /* In case driver is removed when asynchronous FW downloading is 1030 /* In case driver is removed when asynchronous FW downloading is
1030 * in progress 1031 * in progress
@@ -1035,11 +1036,8 @@ static void mwifiex_usb_cleanup_module(void)
1035 if (adapter->is_suspended) 1036 if (adapter->is_suspended)
1036 mwifiex_usb_resume(usb_card->intf); 1037 mwifiex_usb_resume(usb_card->intf);
1037#endif 1038#endif
1038 for (i = 0; i < adapter->priv_num; i++) 1039
1039 if ((GET_BSS_ROLE(adapter->priv[i]) == 1040 mwifiex_deauthenticate_all(adapter);
1040 MWIFIEX_BSS_ROLE_STA) &&
1041 adapter->priv[i]->media_connected)
1042 mwifiex_deauthenticate(adapter->priv[i], NULL);
1043 1041
1044 mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter, 1042 mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter,
1045 MWIFIEX_BSS_ROLE_ANY), 1043 MWIFIEX_BSS_ROLE_ANY),
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c
index 9b82e225880c..c3824e37f3f2 100644
--- a/drivers/net/wireless/mwifiex/util.c
+++ b/drivers/net/wireless/mwifiex/util.c
@@ -72,7 +72,7 @@ int mwifiex_init_shutdown_fw(struct mwifiex_private *priv,
72 return -1; 72 return -1;
73 } 73 }
74 74
75 return mwifiex_send_cmd_sync(priv, cmd, HostCmd_ACT_GEN_SET, 0, NULL); 75 return mwifiex_send_cmd(priv, cmd, HostCmd_ACT_GEN_SET, 0, NULL, true);
76} 76}
77EXPORT_SYMBOL_GPL(mwifiex_init_shutdown_fw); 77EXPORT_SYMBOL_GPL(mwifiex_init_shutdown_fw);
78 78
@@ -104,6 +104,7 @@ int mwifiex_get_debug_info(struct mwifiex_private *priv,
104 info->pm_wakeup_fw_try = adapter->pm_wakeup_fw_try; 104 info->pm_wakeup_fw_try = adapter->pm_wakeup_fw_try;
105 info->is_hs_configured = adapter->is_hs_configured; 105 info->is_hs_configured = adapter->is_hs_configured;
106 info->hs_activated = adapter->hs_activated; 106 info->hs_activated = adapter->hs_activated;
107 info->is_cmd_timedout = adapter->is_cmd_timedout;
107 info->num_cmd_host_to_card_failure 108 info->num_cmd_host_to_card_failure
108 = adapter->dbg.num_cmd_host_to_card_failure; 109 = adapter->dbg.num_cmd_host_to_card_failure;
109 info->num_cmd_sleep_cfm_host_to_card_failure 110 info->num_cmd_sleep_cfm_host_to_card_failure
@@ -119,7 +120,6 @@ int mwifiex_get_debug_info(struct mwifiex_private *priv,
119 info->num_cmd_assoc_failure = 120 info->num_cmd_assoc_failure =
120 adapter->dbg.num_cmd_assoc_failure; 121 adapter->dbg.num_cmd_assoc_failure;
121 info->num_tx_timeout = adapter->dbg.num_tx_timeout; 122 info->num_tx_timeout = adapter->dbg.num_tx_timeout;
122 info->num_cmd_timeout = adapter->dbg.num_cmd_timeout;
123 info->timeout_cmd_id = adapter->dbg.timeout_cmd_id; 123 info->timeout_cmd_id = adapter->dbg.timeout_cmd_id;
124 info->timeout_cmd_act = adapter->dbg.timeout_cmd_act; 124 info->timeout_cmd_act = adapter->dbg.timeout_cmd_act;
125 memcpy(info->last_cmd_id, adapter->dbg.last_cmd_id, 125 memcpy(info->last_cmd_id, adapter->dbg.last_cmd_id,
@@ -252,3 +252,117 @@ int mwifiex_complete_cmd(struct mwifiex_adapter *adapter,
252 252
253 return 0; 253 return 0;
254} 254}
255
256/* This function will return the pointer to station entry in station list
257 * table which matches specified mac address.
258 * This function should be called after acquiring RA list spinlock.
259 * NULL is returned if station entry is not found in associated STA list.
260 */
261struct mwifiex_sta_node *
262mwifiex_get_sta_entry(struct mwifiex_private *priv, u8 *mac)
263{
264 struct mwifiex_sta_node *node;
265
266 if (!mac)
267 return NULL;
268
269 list_for_each_entry(node, &priv->sta_list, list) {
270 if (!memcmp(node->mac_addr, mac, ETH_ALEN))
271 return node;
272 }
273
274 return NULL;
275}
276
277/* This function will add a sta_node entry to associated station list
278 * table with the given mac address.
279 * If entry exist already, existing entry is returned.
280 * If received mac address is NULL, NULL is returned.
281 */
282struct mwifiex_sta_node *
283mwifiex_add_sta_entry(struct mwifiex_private *priv, u8 *mac)
284{
285 struct mwifiex_sta_node *node;
286 unsigned long flags;
287
288 if (!mac)
289 return NULL;
290
291 spin_lock_irqsave(&priv->sta_list_spinlock, flags);
292 node = mwifiex_get_sta_entry(priv, mac);
293 if (node)
294 goto done;
295
296 node = kzalloc(sizeof(*node), GFP_ATOMIC);
297 if (!node)
298 goto done;
299
300 memcpy(node->mac_addr, mac, ETH_ALEN);
301 list_add_tail(&node->list, &priv->sta_list);
302
303done:
304 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
305 return node;
306}
307
308/* This function will search for HT IE in association request IEs
309 * and set station HT parameters accordingly.
310 */
311void
312mwifiex_set_sta_ht_cap(struct mwifiex_private *priv, const u8 *ies,
313 int ies_len, struct mwifiex_sta_node *node)
314{
315 const struct ieee80211_ht_cap *ht_cap;
316
317 if (!ies)
318 return;
319
320 ht_cap = (void *)cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, ies, ies_len);
321 if (ht_cap) {
322 node->is_11n_enabled = 1;
323 node->max_amsdu = le16_to_cpu(ht_cap->cap_info) &
324 IEEE80211_HT_CAP_MAX_AMSDU ?
325 MWIFIEX_TX_DATA_BUF_SIZE_8K :
326 MWIFIEX_TX_DATA_BUF_SIZE_4K;
327 } else {
328 node->is_11n_enabled = 0;
329 }
330
331 return;
332}
333
334/* This function will delete a station entry from station list */
335void mwifiex_del_sta_entry(struct mwifiex_private *priv, u8 *mac)
336{
337 struct mwifiex_sta_node *node;
338 unsigned long flags;
339
340 spin_lock_irqsave(&priv->sta_list_spinlock, flags);
341
342 node = mwifiex_get_sta_entry(priv, mac);
343 if (node) {
344 list_del(&node->list);
345 kfree(node);
346 }
347
348 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
349 return;
350}
351
352/* This function will delete all stations from associated station list. */
353void mwifiex_del_all_sta_list(struct mwifiex_private *priv)
354{
355 struct mwifiex_sta_node *node, *tmp;
356 unsigned long flags;
357
358 spin_lock_irqsave(&priv->sta_list_spinlock, flags);
359
360 list_for_each_entry_safe(node, tmp, &priv->sta_list, list) {
361 list_del(&node->list);
362 kfree(node);
363 }
364
365 INIT_LIST_HEAD(&priv->sta_list);
366 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
367 return;
368}
diff --git a/drivers/net/wireless/mwifiex/util.h b/drivers/net/wireless/mwifiex/util.h
index cb2d0582bd36..ddae57021397 100644
--- a/drivers/net/wireless/mwifiex/util.h
+++ b/drivers/net/wireless/mwifiex/util.h
@@ -30,8 +30,24 @@ static inline struct mwifiex_txinfo *MWIFIEX_SKB_TXCB(struct sk_buff *skb)
30 return (struct mwifiex_txinfo *)(skb->cb + sizeof(dma_addr_t)); 30 return (struct mwifiex_txinfo *)(skb->cb + sizeof(dma_addr_t));
31} 31}
32 32
33static inline void MWIFIEX_SKB_PACB(struct sk_buff *skb, dma_addr_t *buf_pa) 33struct mwifiex_dma_mapping {
34 dma_addr_t addr;
35 size_t len;
36};
37
38static inline void MWIFIEX_SKB_PACB(struct sk_buff *skb,
39 struct mwifiex_dma_mapping *mapping)
34{ 40{
35 memcpy(buf_pa, skb->cb, sizeof(dma_addr_t)); 41 memcpy(mapping, skb->cb, sizeof(*mapping));
36} 42}
43
44static inline dma_addr_t MWIFIEX_SKB_DMA_ADDR(struct sk_buff *skb)
45{
46 struct mwifiex_dma_mapping mapping;
47
48 MWIFIEX_SKB_PACB(skb, &mapping);
49
50 return mapping.addr;
51}
52
37#endif /* !_MWIFIEX_UTIL_H_ */ 53#endif /* !_MWIFIEX_UTIL_H_ */
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index 981cf6e7c73b..0a7cc742aed7 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -37,8 +37,8 @@
37/* Offset for TOS field in the IP header */ 37/* Offset for TOS field in the IP header */
38#define IPTOS_OFFSET 5 38#define IPTOS_OFFSET 5
39 39
40static bool enable_tx_amsdu; 40static bool disable_tx_amsdu;
41module_param(enable_tx_amsdu, bool, 0644); 41module_param(disable_tx_amsdu, bool, 0644);
42 42
43/* WMM information IE */ 43/* WMM information IE */
44static const u8 wmm_info_ie[] = { WLAN_EID_VENDOR_SPECIFIC, 0x07, 44static const u8 wmm_info_ie[] = { WLAN_EID_VENDOR_SPECIFIC, 0x07,
@@ -64,21 +64,6 @@ static u8 tos_to_tid[] = {
64 0x07 /* 1 1 1 AC_VO */ 64 0x07 /* 1 1 1 AC_VO */
65}; 65};
66 66
67/*
68 * This table inverses the tos_to_tid operation to get a priority
69 * which is in sequential order, and can be compared.
70 * Use this to compare the priority of two different TIDs.
71 */
72static u8 tos_to_tid_inv[] = {
73 0x02, /* from tos_to_tid[2] = 0 */
74 0x00, /* from tos_to_tid[0] = 1 */
75 0x01, /* from tos_to_tid[1] = 2 */
76 0x03,
77 0x04,
78 0x05,
79 0x06,
80 0x07};
81
82static u8 ac_to_tid[4][2] = { {1, 2}, {0, 3}, {4, 5}, {6, 7} }; 67static u8 ac_to_tid[4][2] = { {1, 2}, {0, 3}, {4, 5}, {6, 7} };
83 68
84/* 69/*
@@ -175,8 +160,15 @@ mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra)
175 break; 160 break;
176 161
177 ra_list->is_11n_enabled = 0; 162 ra_list->is_11n_enabled = 0;
163 ra_list->tdls_link = false;
178 if (!mwifiex_queuing_ra_based(priv)) { 164 if (!mwifiex_queuing_ra_based(priv)) {
179 ra_list->is_11n_enabled = IS_11N_ENABLED(priv); 165 if (mwifiex_get_tdls_link_status(priv, ra) ==
166 TDLS_SETUP_COMPLETE) {
167 ra_list->is_11n_enabled =
168 mwifiex_tdls_peer_11n_enabled(priv, ra);
169 } else {
170 ra_list->is_11n_enabled = IS_11N_ENABLED(priv);
171 }
180 } else { 172 } else {
181 ra_list->is_11n_enabled = 173 ra_list->is_11n_enabled =
182 mwifiex_is_sta_11n_enabled(priv, node); 174 mwifiex_is_sta_11n_enabled(priv, node);
@@ -213,8 +205,9 @@ static void mwifiex_wmm_default_queue_priorities(struct mwifiex_private *priv)
213 * This function map ACs to TIDs. 205 * This function map ACs to TIDs.
214 */ 206 */
215static void 207static void
216mwifiex_wmm_queue_priorities_tid(struct mwifiex_wmm_desc *wmm) 208mwifiex_wmm_queue_priorities_tid(struct mwifiex_private *priv)
217{ 209{
210 struct mwifiex_wmm_desc *wmm = &priv->wmm;
218 u8 *queue_priority = wmm->queue_priority; 211 u8 *queue_priority = wmm->queue_priority;
219 int i; 212 int i;
220 213
@@ -224,7 +217,7 @@ mwifiex_wmm_queue_priorities_tid(struct mwifiex_wmm_desc *wmm)
224 } 217 }
225 218
226 for (i = 0; i < MAX_NUM_TID; ++i) 219 for (i = 0; i < MAX_NUM_TID; ++i)
227 tos_to_tid_inv[tos_to_tid[i]] = (u8)i; 220 priv->tos_to_tid_inv[tos_to_tid[i]] = (u8)i;
228 221
229 atomic_set(&wmm->highest_queued_prio, HIGH_PRIO_TID); 222 atomic_set(&wmm->highest_queued_prio, HIGH_PRIO_TID);
230} 223}
@@ -285,7 +278,7 @@ mwifiex_wmm_setup_queue_priorities(struct mwifiex_private *priv,
285 } 278 }
286 } 279 }
287 280
288 mwifiex_wmm_queue_priorities_tid(&priv->wmm); 281 mwifiex_wmm_queue_priorities_tid(priv);
289} 282}
290 283
291/* 284/*
@@ -388,8 +381,7 @@ mwifiex_wmm_convert_tos_to_ac(struct mwifiex_adapter *adapter, u32 tos)
388 * AP is disabled (due to call admission control (ACM bit). Mapping 381 * AP is disabled (due to call admission control (ACM bit). Mapping
389 * of TID to AC is taken care of internally. 382 * of TID to AC is taken care of internally.
390 */ 383 */
391static u8 384u8 mwifiex_wmm_downgrade_tid(struct mwifiex_private *priv, u32 tid)
392mwifiex_wmm_downgrade_tid(struct mwifiex_private *priv, u32 tid)
393{ 385{
394 enum mwifiex_wmm_ac_e ac, ac_down; 386 enum mwifiex_wmm_ac_e ac, ac_down;
395 u8 new_tid; 387 u8 new_tid;
@@ -421,9 +413,17 @@ mwifiex_wmm_init(struct mwifiex_adapter *adapter)
421 continue; 413 continue;
422 414
423 for (i = 0; i < MAX_NUM_TID; ++i) { 415 for (i = 0; i < MAX_NUM_TID; ++i) {
424 priv->aggr_prio_tbl[i].amsdu = tos_to_tid_inv[i]; 416 if (!disable_tx_amsdu &&
425 priv->aggr_prio_tbl[i].ampdu_ap = tos_to_tid_inv[i]; 417 adapter->tx_buf_size > MWIFIEX_TX_DATA_BUF_SIZE_2K)
426 priv->aggr_prio_tbl[i].ampdu_user = tos_to_tid_inv[i]; 418 priv->aggr_prio_tbl[i].amsdu =
419 priv->tos_to_tid_inv[i];
420 else
421 priv->aggr_prio_tbl[i].amsdu =
422 BA_STREAM_NOT_ALLOWED;
423 priv->aggr_prio_tbl[i].ampdu_ap =
424 priv->tos_to_tid_inv[i];
425 priv->aggr_prio_tbl[i].ampdu_user =
426 priv->tos_to_tid_inv[i];
427 } 427 }
428 428
429 priv->aggr_prio_tbl[6].amsdu 429 priv->aggr_prio_tbl[6].amsdu
@@ -546,6 +546,7 @@ void
546mwifiex_clean_txrx(struct mwifiex_private *priv) 546mwifiex_clean_txrx(struct mwifiex_private *priv)
547{ 547{
548 unsigned long flags; 548 unsigned long flags;
549 struct sk_buff *skb, *tmp;
549 550
550 mwifiex_11n_cleanup_reorder_tbl(priv); 551 mwifiex_11n_cleanup_reorder_tbl(priv);
551 spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags); 552 spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags);
@@ -563,6 +564,9 @@ mwifiex_clean_txrx(struct mwifiex_private *priv)
563 !priv->adapter->surprise_removed) 564 !priv->adapter->surprise_removed)
564 priv->adapter->if_ops.clean_pcie_ring(priv->adapter); 565 priv->adapter->if_ops.clean_pcie_ring(priv->adapter);
565 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); 566 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
567
568 skb_queue_walk_safe(&priv->tdls_txq, skb, tmp)
569 mwifiex_write_data_complete(priv->adapter, skb, 0, -1);
566} 570}
567 571
568/* 572/*
@@ -591,7 +595,7 @@ mwifiex_wmm_get_ralist_node(struct mwifiex_private *priv, u8 tid,
591 * If no such node is found, a new node is added first and then 595 * If no such node is found, a new node is added first and then
592 * retrieved. 596 * retrieved.
593 */ 597 */
594static struct mwifiex_ra_list_tbl * 598struct mwifiex_ra_list_tbl *
595mwifiex_wmm_get_queue_raptr(struct mwifiex_private *priv, u8 tid, u8 *ra_addr) 599mwifiex_wmm_get_queue_raptr(struct mwifiex_private *priv, u8 tid, u8 *ra_addr)
596{ 600{
597 struct mwifiex_ra_list_tbl *ra_list; 601 struct mwifiex_ra_list_tbl *ra_list;
@@ -641,6 +645,21 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv,
641 struct mwifiex_ra_list_tbl *ra_list; 645 struct mwifiex_ra_list_tbl *ra_list;
642 u8 ra[ETH_ALEN], tid_down; 646 u8 ra[ETH_ALEN], tid_down;
643 unsigned long flags; 647 unsigned long flags;
648 struct list_head list_head;
649 int tdls_status = TDLS_NOT_SETUP;
650 struct ethhdr *eth_hdr = (struct ethhdr *)skb->data;
651 struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb);
652
653 memcpy(ra, eth_hdr->h_dest, ETH_ALEN);
654
655 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA &&
656 ISSUPP_TDLS_ENABLED(adapter->fw_cap_info)) {
657 if (ntohs(eth_hdr->h_proto) == ETH_P_TDLS)
658 dev_dbg(adapter->dev,
659 "TDLS setup packet for %pM. Don't block\n", ra);
660 else
661 tdls_status = mwifiex_get_tdls_link_status(priv, ra);
662 }
644 663
645 if (!priv->media_connected && !mwifiex_is_skb_mgmt_frame(skb)) { 664 if (!priv->media_connected && !mwifiex_is_skb_mgmt_frame(skb)) {
646 dev_dbg(adapter->dev, "data: drop packet in disconnect\n"); 665 dev_dbg(adapter->dev, "data: drop packet in disconnect\n");
@@ -659,12 +678,27 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv,
659 have only 1 raptr for a tid in case of infra */ 678 have only 1 raptr for a tid in case of infra */
660 if (!mwifiex_queuing_ra_based(priv) && 679 if (!mwifiex_queuing_ra_based(priv) &&
661 !mwifiex_is_skb_mgmt_frame(skb)) { 680 !mwifiex_is_skb_mgmt_frame(skb)) {
662 if (!list_empty(&priv->wmm.tid_tbl_ptr[tid_down].ra_list)) 681 switch (tdls_status) {
663 ra_list = list_first_entry( 682 case TDLS_SETUP_COMPLETE:
664 &priv->wmm.tid_tbl_ptr[tid_down].ra_list, 683 ra_list = mwifiex_wmm_get_queue_raptr(priv, tid_down,
665 struct mwifiex_ra_list_tbl, list); 684 ra);
666 else 685 tx_info->flags |= MWIFIEX_BUF_FLAG_TDLS_PKT;
667 ra_list = NULL; 686 break;
687 case TDLS_SETUP_INPROGRESS:
688 skb_queue_tail(&priv->tdls_txq, skb);
689 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
690 flags);
691 return;
692 default:
693 list_head = priv->wmm.tid_tbl_ptr[tid_down].ra_list;
694 if (!list_empty(&list_head))
695 ra_list = list_first_entry(
696 &list_head, struct mwifiex_ra_list_tbl,
697 list);
698 else
699 ra_list = NULL;
700 break;
701 }
668 } else { 702 } else {
669 memcpy(ra, skb->data, ETH_ALEN); 703 memcpy(ra, skb->data, ETH_ALEN);
670 if (ra[0] & 0x01 || mwifiex_is_skb_mgmt_frame(skb)) 704 if (ra[0] & 0x01 || mwifiex_is_skb_mgmt_frame(skb))
@@ -684,9 +718,9 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv,
684 ra_list->total_pkt_count++; 718 ra_list->total_pkt_count++;
685 719
686 if (atomic_read(&priv->wmm.highest_queued_prio) < 720 if (atomic_read(&priv->wmm.highest_queued_prio) <
687 tos_to_tid_inv[tid_down]) 721 priv->tos_to_tid_inv[tid_down])
688 atomic_set(&priv->wmm.highest_queued_prio, 722 atomic_set(&priv->wmm.highest_queued_prio,
689 tos_to_tid_inv[tid_down]); 723 priv->tos_to_tid_inv[tid_down]);
690 724
691 atomic_inc(&priv->wmm.tx_pkts_queued); 725 atomic_inc(&priv->wmm.tx_pkts_queued);
692 726
@@ -1219,15 +1253,24 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter)
1219 1253
1220 if (!ptr->is_11n_enabled || 1254 if (!ptr->is_11n_enabled ||
1221 mwifiex_is_ba_stream_setup(priv, ptr, tid) || 1255 mwifiex_is_ba_stream_setup(priv, ptr, tid) ||
1222 priv->wps.session_enable || 1256 priv->wps.session_enable) {
1223 ((priv->sec_info.wpa_enabled || 1257 if (ptr->is_11n_enabled &&
1224 priv->sec_info.wpa2_enabled) && 1258 mwifiex_is_ba_stream_setup(priv, ptr, tid) &&
1225 !priv->wpa_is_gtk_set)) { 1259 mwifiex_is_amsdu_in_ampdu_allowed(priv, ptr, tid) &&
1226 mwifiex_send_single_packet(priv, ptr, ptr_index, flags); 1260 mwifiex_is_amsdu_allowed(priv, tid) &&
1227 /* ra_list_spinlock has been freed in 1261 mwifiex_is_11n_aggragation_possible(priv, ptr,
1228 mwifiex_send_single_packet() */ 1262 adapter->tx_buf_size))
1263 mwifiex_11n_aggregate_pkt(priv, ptr, ptr_index, flags);
1264 /* ra_list_spinlock has been freed in
1265 * mwifiex_11n_aggregate_pkt()
1266 */
1267 else
1268 mwifiex_send_single_packet(priv, ptr, ptr_index, flags);
1269 /* ra_list_spinlock has been freed in
1270 * mwifiex_send_single_packet()
1271 */
1229 } else { 1272 } else {
1230 if (mwifiex_is_ampdu_allowed(priv, tid) && 1273 if (mwifiex_is_ampdu_allowed(priv, ptr, tid) &&
1231 ptr->ba_pkt_count > ptr->ba_packet_thr) { 1274 ptr->ba_pkt_count > ptr->ba_packet_thr) {
1232 if (mwifiex_space_avail_for_new_ba_stream(adapter)) { 1275 if (mwifiex_space_avail_for_new_ba_stream(adapter)) {
1233 mwifiex_create_ba_tbl(priv, ptr->ra, tid, 1276 mwifiex_create_ba_tbl(priv, ptr->ra, tid,
@@ -1240,7 +1283,7 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter)
1240 mwifiex_send_delba(priv, tid_del, ra, 1); 1283 mwifiex_send_delba(priv, tid_del, ra, 1);
1241 } 1284 }
1242 } 1285 }
1243 if (enable_tx_amsdu && mwifiex_is_amsdu_allowed(priv, tid) && 1286 if (mwifiex_is_amsdu_allowed(priv, tid) &&
1244 mwifiex_is_11n_aggragation_possible(priv, ptr, 1287 mwifiex_is_11n_aggragation_possible(priv, ptr,
1245 adapter->tx_buf_size)) 1288 adapter->tx_buf_size))
1246 mwifiex_11n_aggregate_pkt(priv, ptr, ptr_index, flags); 1289 mwifiex_11n_aggregate_pkt(priv, ptr, ptr_index, flags);
diff --git a/drivers/net/wireless/mwifiex/wmm.h b/drivers/net/wireless/mwifiex/wmm.h
index 0f129d498fb1..83e42083ebff 100644
--- a/drivers/net/wireless/mwifiex/wmm.h
+++ b/drivers/net/wireless/mwifiex/wmm.h
@@ -34,6 +34,21 @@ enum ieee_types_wmm_ecw_bitmasks {
34static const u16 mwifiex_1d_to_wmm_queue[8] = { 1, 0, 0, 1, 2, 2, 3, 3 }; 34static const u16 mwifiex_1d_to_wmm_queue[8] = { 1, 0, 0, 1, 2, 2, 3, 3 };
35 35
36/* 36/*
37 * This table inverses the tos_to_tid operation to get a priority
38 * which is in sequential order, and can be compared.
39 * Use this to compare the priority of two different TIDs.
40 */
41static const u8 tos_to_tid_inv[] = {
42 0x02, /* from tos_to_tid[2] = 0 */
43 0x00, /* from tos_to_tid[0] = 1 */
44 0x01, /* from tos_to_tid[1] = 2 */
45 0x03,
46 0x04,
47 0x05,
48 0x06,
49 0x07};
50
51/*
37 * This function retrieves the TID of the given RA list. 52 * This function retrieves the TID of the given RA list.
38 */ 53 */
39static inline int 54static inline int
@@ -107,5 +122,8 @@ void mwifiex_wmm_setup_queue_priorities(struct mwifiex_private *priv,
107void mwifiex_wmm_setup_ac_downgrade(struct mwifiex_private *priv); 122void mwifiex_wmm_setup_ac_downgrade(struct mwifiex_private *priv);
108int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv, 123int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv,
109 const struct host_cmd_ds_command *resp); 124 const struct host_cmd_ds_command *resp);
125struct mwifiex_ra_list_tbl *
126mwifiex_wmm_get_queue_raptr(struct mwifiex_private *priv, u8 tid, u8 *ra_addr);
127u8 mwifiex_wmm_downgrade_tid(struct mwifiex_private *priv, u32 tid);
110 128
111#endif /* !_MWIFIEX_WMM_H_ */ 129#endif /* !_MWIFIEX_WMM_H_ */