aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwifiex
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-04-02 23:53:45 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-04-02 23:53:45 -0400
commitcd6362befe4cc7bf589a5236d2a780af2d47bcc9 (patch)
tree3bd4e13ec3f92a00dc4f6c3d65e820b54dbfe46e /drivers/net/wireless/mwifiex
parent0f1b1e6d73cb989ce2c071edc57deade3b084dfe (diff)
parentb1586f099ba897542ece36e8a23c1a62907261ef (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking updates from David Miller: "Here is my initial pull request for the networking subsystem during this merge window: 1) Support for ESN in AH (RFC 4302) from Fan Du. 2) Add full kernel doc for ethtool command structures, from Ben Hutchings. 3) Add BCM7xxx PHY driver, from Florian Fainelli. 4) Export computed TCP rate information in netlink socket dumps, from Eric Dumazet. 5) Allow IPSEC SA to be dumped partially using a filter, from Nicolas Dichtel. 6) Convert many drivers to pci_enable_msix_range(), from Alexander Gordeev. 7) Record SKB timestamps more efficiently, from Eric Dumazet. 8) Switch to microsecond resolution for TCP round trip times, also from Eric Dumazet. 9) Clean up and fix 6lowpan fragmentation handling by making use of the existing inet_frag api for it's implementation. 10) Add TX grant mapping to xen-netback driver, from Zoltan Kiss. 11) Auto size SKB lengths when composing netlink messages based upon past message sizes used, from Eric Dumazet. 12) qdisc dumps can take a long time, add a cond_resched(), From Eric Dumazet. 13) Sanitize netpoll core and drivers wrt. SKB handling semantics. Get rid of never-used-in-tree netpoll RX handling. From Eric W Biederman. 14) Support inter-address-family and namespace changing in VTI tunnel driver(s). From Steffen Klassert. 15) Add Altera TSE driver, from Vince Bridgers. 16) Optimizing csum_replace2() so that it doesn't adjust the checksum by checksumming the entire header, from Eric Dumazet. 17) Expand BPF internal implementation for faster interpreting, more direct translations into JIT'd code, and much cleaner uses of BPF filtering in non-socket ocntexts. From Daniel Borkmann and Alexei Starovoitov" * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1976 commits) netpoll: Use skb_irq_freeable to make zap_completion_queue safe. net: Add a test to see if a skb is freeable in irq context qlcnic: Fix build failure due to undefined reference to `vxlan_get_rx_port' net: ptp: move PTP classifier in its own file net: sxgbe: make "core_ops" static net: sxgbe: fix logical vs bitwise operation net: sxgbe: sxgbe_mdio_register() frees the bus Call efx_set_channels() before efx->type->dimension_resources() xen-netback: disable rogue vif in kthread context net/mlx4: Set proper build dependancy with vxlan be2net: fix build dependency on VxLAN mac802154: make csma/cca parameters per-wpan mac802154: allow only one WPAN to be up at any given time net: filter: minor: fix kdoc in __sk_run_filter netlink: don't compare the nul-termination in nla_strcmp can: c_can: Avoid led toggling for every packet. can: c_can: Simplify TX interrupt cleanup can: c_can: Store dlc private can: c_can: Reduce register access can: c_can: Make the code readable ...
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.c161
-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.c10
-rw-r--r--drivers/net/wireless/mwifiex/main.h112
-rw-r--r--drivers/net/wireless/mwifiex/pcie.c180
-rw-r--r--drivers/net/wireless/mwifiex/pcie.h5
-rw-r--r--drivers/net/wireless/mwifiex/scan.c615
-rw-r--r--drivers/net/wireless/mwifiex/sdio.c11
-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.c164
-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.c11
-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, 3844 insertions, 1145 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..1062c918a7bf 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
@@ -276,11 +277,11 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter)
276 277
277 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); 278 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
278 279
280 adapter->seq_num++;
279 sleep_cfm_buf->seq_num = 281 sleep_cfm_buf->seq_num =
280 cpu_to_le16((HostCmd_SET_SEQ_NO_BSS_INFO 282 cpu_to_le16((HostCmd_SET_SEQ_NO_BSS_INFO
281 (adapter->seq_num, priv->bss_num, 283 (adapter->seq_num, priv->bss_num,
282 priv->bss_type))); 284 priv->bss_type)));
283 adapter->seq_num++;
284 285
285 if (adapter->iface_type == MWIFIEX_USB) { 286 if (adapter->iface_type == MWIFIEX_USB) {
286 sleep_cfm_tmp = 287 sleep_cfm_tmp =
@@ -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;
@@ -529,11 +509,21 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no,
529 return -1; 509 return -1;
530 } 510 }
531 511
512 if (adapter->hs_enabling && cmd_no != HostCmd_CMD_802_11_HS_CFG_ENH) {
513 dev_err(adapter->dev, "PREP_CMD: host entering sleep state\n");
514 return -1;
515 }
516
532 if (adapter->surprise_removed) { 517 if (adapter->surprise_removed) {
533 dev_err(adapter->dev, "PREP_CMD: card is removed\n"); 518 dev_err(adapter->dev, "PREP_CMD: card is removed\n");
534 return -1; 519 return -1;
535 } 520 }
536 521
522 if (adapter->is_cmd_timedout) {
523 dev_err(adapter->dev, "PREP_CMD: FW is in bad state\n");
524 return -1;
525 }
526
537 if (adapter->hw_status == MWIFIEX_HW_STATUS_RESET) { 527 if (adapter->hw_status == MWIFIEX_HW_STATUS_RESET) {
538 if (cmd_no != HostCmd_CMD_FUNC_INIT) { 528 if (cmd_no != HostCmd_CMD_FUNC_INIT) {
539 dev_err(adapter->dev, "PREP_CMD: FW in reset state\n"); 529 dev_err(adapter->dev, "PREP_CMD: FW in reset state\n");
@@ -550,7 +540,7 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no,
550 } 540 }
551 541
552 /* Initialize the command node */ 542 /* Initialize the command node */
553 mwifiex_init_cmd_node(priv, cmd_node, cmd_oid, data_buf); 543 mwifiex_init_cmd_node(priv, cmd_node, cmd_oid, data_buf, sync);
554 544
555 if (!cmd_node->cmd_skb) { 545 if (!cmd_node->cmd_skb) {
556 dev_err(adapter->dev, "PREP_CMD: no free cmd buf\n"); 546 dev_err(adapter->dev, "PREP_CMD: no free cmd buf\n");
@@ -595,7 +585,8 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no,
595 } 585 }
596 586
597 /* Send command */ 587 /* Send command */
598 if (cmd_no == HostCmd_CMD_802_11_SCAN) { 588 if (cmd_no == HostCmd_CMD_802_11_SCAN ||
589 cmd_no == HostCmd_CMD_802_11_SCAN_EXT) {
599 mwifiex_queue_scan_cmd(priv, cmd_node); 590 mwifiex_queue_scan_cmd(priv, cmd_node);
600 } else { 591 } else {
601 mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true); 592 mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true);
@@ -785,7 +776,7 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
785 unsigned long flags; 776 unsigned long flags;
786 777
787 /* Now we got response from FW, cancel the command timer */ 778 /* Now we got response from FW, cancel the command timer */
788 del_timer(&adapter->cmd_timer); 779 del_timer_sync(&adapter->cmd_timer);
789 780
790 if (!adapter->curr_cmd || !adapter->curr_cmd->resp_skb) { 781 if (!adapter->curr_cmd || !adapter->curr_cmd->resp_skb) {
791 resp = (struct host_cmd_ds_command *) adapter->upld_buf; 782 resp = (struct host_cmd_ds_command *) adapter->upld_buf;
@@ -794,7 +785,7 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
794 return -1; 785 return -1;
795 } 786 }
796 787
797 adapter->num_cmd_timeout = 0; 788 adapter->is_cmd_timedout = 0;
798 789
799 resp = (struct host_cmd_ds_command *) adapter->curr_cmd->resp_skb->data; 790 resp = (struct host_cmd_ds_command *) adapter->curr_cmd->resp_skb->data;
800 if (adapter->curr_cmd->cmd_flag & CMD_F_CANCELED) { 791 if (adapter->curr_cmd->cmd_flag & CMD_F_CANCELED) {
@@ -905,8 +896,7 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
905 struct cmd_ctrl_node *cmd_node; 896 struct cmd_ctrl_node *cmd_node;
906 struct timeval tstamp; 897 struct timeval tstamp;
907 898
908 adapter->num_cmd_timeout++; 899 adapter->is_cmd_timedout = 1;
909 adapter->dbg.num_cmd_timeout++;
910 if (!adapter->curr_cmd) { 900 if (!adapter->curr_cmd) {
911 dev_dbg(adapter->dev, "cmd: empty curr_cmd\n"); 901 dev_dbg(adapter->dev, "cmd: empty curr_cmd\n");
912 return; 902 return;
@@ -929,8 +919,8 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
929 dev_err(adapter->dev, "num_cmd_h2c_failure = %d\n", 919 dev_err(adapter->dev, "num_cmd_h2c_failure = %d\n",
930 adapter->dbg.num_cmd_host_to_card_failure); 920 adapter->dbg.num_cmd_host_to_card_failure);
931 921
932 dev_err(adapter->dev, "num_cmd_timeout = %d\n", 922 dev_err(adapter->dev, "is_cmd_timedout = %d\n",
933 adapter->dbg.num_cmd_timeout); 923 adapter->is_cmd_timedout);
934 dev_err(adapter->dev, "num_tx_timeout = %d\n", 924 dev_err(adapter->dev, "num_tx_timeout = %d\n",
935 adapter->dbg.num_tx_timeout); 925 adapter->dbg.num_tx_timeout);
936 926
@@ -987,13 +977,14 @@ void
987mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter) 977mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
988{ 978{
989 struct cmd_ctrl_node *cmd_node = NULL, *tmp_node; 979 struct cmd_ctrl_node *cmd_node = NULL, *tmp_node;
990 unsigned long flags; 980 unsigned long flags, cmd_flags;
981 struct mwifiex_private *priv;
982 int i;
991 983
984 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
992 /* Cancel current cmd */ 985 /* Cancel current cmd */
993 if ((adapter->curr_cmd) && (adapter->curr_cmd->wait_q_enabled)) { 986 if ((adapter->curr_cmd) && (adapter->curr_cmd->wait_q_enabled)) {
994 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
995 adapter->curr_cmd->wait_q_enabled = false; 987 adapter->curr_cmd->wait_q_enabled = false;
996 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
997 adapter->cmd_wait_q.status = -1; 988 adapter->cmd_wait_q.status = -1;
998 mwifiex_complete_cmd(adapter, adapter->curr_cmd); 989 mwifiex_complete_cmd(adapter, adapter->curr_cmd);
999 } 990 }
@@ -1013,6 +1004,7 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
1013 spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags); 1004 spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
1014 } 1005 }
1015 spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags); 1006 spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
1007 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
1016 1008
1017 /* Cancel all pending scan command */ 1009 /* Cancel all pending scan command */
1018 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); 1010 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
@@ -1027,9 +1019,21 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
1027 } 1019 }
1028 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); 1020 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
1029 1021
1030 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); 1022 if (adapter->scan_processing) {
1031 adapter->scan_processing = false; 1023 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
1032 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); 1024 adapter->scan_processing = false;
1025 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
1026 for (i = 0; i < adapter->priv_num; i++) {
1027 priv = adapter->priv[i];
1028 if (!priv)
1029 continue;
1030 if (priv->scan_request) {
1031 dev_dbg(adapter->dev, "info: aborting scan\n");
1032 cfg80211_scan_done(priv->scan_request, 1);
1033 priv->scan_request = NULL;
1034 }
1035 }
1036 }
1033} 1037}
1034 1038
1035/* 1039/*
@@ -1048,7 +1052,8 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter)
1048 struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL; 1052 struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL;
1049 unsigned long cmd_flags; 1053 unsigned long cmd_flags;
1050 unsigned long scan_pending_q_flags; 1054 unsigned long scan_pending_q_flags;
1051 bool cancel_scan_cmd = false; 1055 struct mwifiex_private *priv;
1056 int i;
1052 1057
1053 if ((adapter->curr_cmd) && 1058 if ((adapter->curr_cmd) &&
1054 (adapter->curr_cmd->wait_q_enabled)) { 1059 (adapter->curr_cmd->wait_q_enabled)) {
@@ -1074,15 +1079,24 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter)
1074 mwifiex_insert_cmd_to_free_q(adapter, cmd_node); 1079 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
1075 spin_lock_irqsave(&adapter->scan_pending_q_lock, 1080 spin_lock_irqsave(&adapter->scan_pending_q_lock,
1076 scan_pending_q_flags); 1081 scan_pending_q_flags);
1077 cancel_scan_cmd = true;
1078 } 1082 }
1079 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, 1083 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1080 scan_pending_q_flags); 1084 scan_pending_q_flags);
1081 1085
1082 if (cancel_scan_cmd) { 1086 if (adapter->scan_processing) {
1083 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags); 1087 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
1084 adapter->scan_processing = false; 1088 adapter->scan_processing = false;
1085 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); 1089 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
1090 for (i = 0; i < adapter->priv_num; i++) {
1091 priv = adapter->priv[i];
1092 if (!priv)
1093 continue;
1094 if (priv->scan_request) {
1095 dev_dbg(adapter->dev, "info: aborting scan\n");
1096 cfg80211_scan_done(priv->scan_request, 1);
1097 priv->scan_request = NULL;
1098 }
1099 }
1086 } 1100 }
1087 adapter->cmd_wait_q.status = -1; 1101 adapter->cmd_wait_q.status = -1;
1088} 1102}
@@ -1454,7 +1468,10 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
1454{ 1468{
1455 struct host_cmd_ds_get_hw_spec *hw_spec = &resp->params.hw_spec; 1469 struct host_cmd_ds_get_hw_spec *hw_spec = &resp->params.hw_spec;
1456 struct mwifiex_adapter *adapter = priv->adapter; 1470 struct mwifiex_adapter *adapter = priv->adapter;
1457 int i; 1471 struct mwifiex_ie_types_header *tlv;
1472 struct hw_spec_fw_api_rev *api_rev;
1473 u16 resp_size, api_id;
1474 int i, left_len, parsed_len = 0;
1458 1475
1459 adapter->fw_cap_info = le32_to_cpu(hw_spec->fw_cap_info); 1476 adapter->fw_cap_info = le32_to_cpu(hw_spec->fw_cap_info);
1460 1477
@@ -1490,6 +1507,7 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
1490 } 1507 }
1491 1508
1492 adapter->fw_release_number = le32_to_cpu(hw_spec->fw_release_number); 1509 adapter->fw_release_number = le32_to_cpu(hw_spec->fw_release_number);
1510 adapter->fw_api_ver = (adapter->fw_release_number >> 16) & 0xff;
1493 adapter->number_of_antenna = le16_to_cpu(hw_spec->number_of_antenna); 1511 adapter->number_of_antenna = le16_to_cpu(hw_spec->number_of_antenna);
1494 1512
1495 if (le32_to_cpu(hw_spec->dot_11ac_dev_cap)) { 1513 if (le32_to_cpu(hw_spec->dot_11ac_dev_cap)) {
@@ -1498,8 +1516,10 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
1498 /* Copy 11AC cap */ 1516 /* Copy 11AC cap */
1499 adapter->hw_dot_11ac_dev_cap = 1517 adapter->hw_dot_11ac_dev_cap =
1500 le32_to_cpu(hw_spec->dot_11ac_dev_cap); 1518 le32_to_cpu(hw_spec->dot_11ac_dev_cap);
1501 adapter->usr_dot_11ac_dev_cap_bg = adapter->hw_dot_11ac_dev_cap; 1519 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; 1520 & ~MWIFIEX_DEF_11AC_CAP_BF_RESET_MASK;
1521 adapter->usr_dot_11ac_dev_cap_a = adapter->hw_dot_11ac_dev_cap
1522 & ~MWIFIEX_DEF_11AC_CAP_BF_RESET_MASK;
1503 1523
1504 /* Copy 11AC mcs */ 1524 /* Copy 11AC mcs */
1505 adapter->hw_dot_11ac_mcs_support = 1525 adapter->hw_dot_11ac_mcs_support =
@@ -1510,6 +1530,46 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
1510 adapter->is_hw_11ac_capable = false; 1530 adapter->is_hw_11ac_capable = false;
1511 } 1531 }
1512 1532
1533 resp_size = le16_to_cpu(resp->size) - S_DS_GEN;
1534 if (resp_size > sizeof(struct host_cmd_ds_get_hw_spec)) {
1535 /* we have variable HW SPEC information */
1536 left_len = resp_size - sizeof(struct host_cmd_ds_get_hw_spec);
1537 while (left_len > sizeof(struct mwifiex_ie_types_header)) {
1538 tlv = (void *)&hw_spec->tlvs + parsed_len;
1539 switch (le16_to_cpu(tlv->type)) {
1540 case TLV_TYPE_FW_API_REV:
1541 api_rev = (struct hw_spec_fw_api_rev *)tlv;
1542 api_id = le16_to_cpu(api_rev->api_id);
1543 switch (api_id) {
1544 case KEY_API_VER_ID:
1545 adapter->fw_key_api_major_ver =
1546 api_rev->major_ver;
1547 adapter->fw_key_api_minor_ver =
1548 api_rev->minor_ver;
1549 dev_dbg(adapter->dev,
1550 "fw_key_api v%d.%d\n",
1551 adapter->fw_key_api_major_ver,
1552 adapter->fw_key_api_minor_ver);
1553 break;
1554 default:
1555 dev_warn(adapter->dev,
1556 "Unknown FW api_id: %d\n",
1557 api_id);
1558 break;
1559 }
1560 break;
1561 default:
1562 dev_warn(adapter->dev,
1563 "Unknown GET_HW_SPEC TLV type: %#x\n",
1564 le16_to_cpu(tlv->type));
1565 break;
1566 }
1567 parsed_len += le16_to_cpu(tlv->len) +
1568 sizeof(struct mwifiex_ie_types_header);
1569 left_len -= parsed_len;
1570 }
1571 }
1572
1513 dev_dbg(adapter->dev, "info: GET_HW_SPEC: fw_release_number- %#x\n", 1573 dev_dbg(adapter->dev, "info: GET_HW_SPEC: fw_release_number- %#x\n",
1514 adapter->fw_release_number); 1574 adapter->fw_release_number);
1515 dev_dbg(adapter->dev, "info: GET_HW_SPEC: permanent addr: %pM\n", 1575 dev_dbg(adapter->dev, "info: GET_HW_SPEC: permanent addr: %pM\n",
@@ -1538,6 +1598,7 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
1538 1598
1539 adapter->hw_dot_11n_dev_cap = le32_to_cpu(hw_spec->dot_11n_dev_cap); 1599 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; 1600 adapter->hw_dev_mcs_support = hw_spec->dev_mcs_support;
1601 adapter->user_dev_mcs_support = adapter->hw_dev_mcs_support;
1541 1602
1542 if (adapter->if_ops.update_mp_end_port) 1603 if (adapter->if_ops.update_mp_end_port)
1543 adapter->if_ops.update_mp_end_port(adapter, 1604 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..77db0886c6e2 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -38,7 +38,8 @@ static void scan_delay_timer_fn(unsigned long data)
38 if (adapter->surprise_removed) 38 if (adapter->surprise_removed)
39 return; 39 return;
40 40
41 if (adapter->scan_delay_cnt == MWIFIEX_MAX_SCAN_DELAY_CNT) { 41 if (adapter->scan_delay_cnt == MWIFIEX_MAX_SCAN_DELAY_CNT ||
42 !adapter->scan_processing) {
42 /* 43 /*
43 * Abort scan operation by cancelling all pending scan 44 * Abort scan operation by cancelling all pending scan
44 * commands 45 * commands
@@ -194,7 +195,7 @@ static int mwifiex_unregister(struct mwifiex_adapter *adapter)
194 if (adapter->if_ops.cleanup_if) 195 if (adapter->if_ops.cleanup_if)
195 adapter->if_ops.cleanup_if(adapter); 196 adapter->if_ops.cleanup_if(adapter);
196 197
197 del_timer(&adapter->cmd_timer); 198 del_timer_sync(&adapter->cmd_timer);
198 199
199 /* Free private structures */ 200 /* Free private structures */
200 for (i = 0; i < adapter->priv_num; i++) { 201 for (i = 0; i < adapter->priv_num; i++) {
@@ -678,8 +679,8 @@ mwifiex_set_mac_address(struct net_device *dev, void *addr)
678 memcpy(priv->curr_addr, hw_addr->sa_data, ETH_ALEN); 679 memcpy(priv->curr_addr, hw_addr->sa_data, ETH_ALEN);
679 680
680 /* Send request to firmware */ 681 /* Send request to firmware */
681 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_MAC_ADDRESS, 682 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_MAC_ADDRESS,
682 HostCmd_ACT_GEN_SET, 0, NULL); 683 HostCmd_ACT_GEN_SET, 0, NULL, true);
683 684
684 if (!ret) 685 if (!ret)
685 memcpy(priv->netdev->dev_addr, priv->curr_addr, ETH_ALEN); 686 memcpy(priv->netdev->dev_addr, priv->curr_addr, ETH_ALEN);
@@ -871,7 +872,6 @@ mwifiex_add_card(void *card, struct semaphore *sem,
871 adapter->is_suspended = false; 872 adapter->is_suspended = false;
872 adapter->hs_activated = false; 873 adapter->hs_activated = false;
873 init_waitqueue_head(&adapter->hs_activate_wait_q); 874 init_waitqueue_head(&adapter->hs_activate_wait_q);
874 adapter->cmd_wait_q_required = false;
875 init_waitqueue_head(&adapter->cmd_wait_q.wait); 875 init_waitqueue_head(&adapter->cmd_wait_q.wait);
876 adapter->cmd_wait_q.status = 0; 876 adapter->cmd_wait_q.status = 0;
877 adapter->scan_wait_q_woken = false; 877 adapter->scan_wait_q_woken = false;
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index d8ad554ce39f..d53e1e8c9467 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;
@@ -722,15 +774,16 @@ struct mwifiex_adapter {
722 u16 hs_activate_wait_q_woken; 774 u16 hs_activate_wait_q_woken;
723 wait_queue_head_t hs_activate_wait_q; 775 wait_queue_head_t hs_activate_wait_q;
724 bool is_suspended; 776 bool is_suspended;
777 bool hs_enabling;
725 u8 event_body[MAX_EVENT_SIZE]; 778 u8 event_body[MAX_EVENT_SIZE];
726 u32 hw_dot_11n_dev_cap; 779 u32 hw_dot_11n_dev_cap;
727 u8 hw_dev_mcs_support; 780 u8 hw_dev_mcs_support;
781 u8 user_dev_mcs_support;
728 u8 adhoc_11n_enabled; 782 u8 adhoc_11n_enabled;
729 u8 sec_chan_offset; 783 u8 sec_chan_offset;
730 struct mwifiex_dbg dbg; 784 struct mwifiex_dbg dbg;
731 u8 arp_filter[ARP_FILTER_MAX_BUF_SIZE]; 785 u8 arp_filter[ARP_FILTER_MAX_BUF_SIZE];
732 u32 arp_filter_size; 786 u32 arp_filter_size;
733 u16 cmd_wait_q_required;
734 struct mwifiex_wait_queue cmd_wait_q; 787 struct mwifiex_wait_queue cmd_wait_q;
735 u8 scan_wait_q_woken; 788 u8 scan_wait_q_woken;
736 spinlock_t queue_lock; /* lock for tx queues */ 789 spinlock_t queue_lock; /* lock for tx queues */
@@ -753,6 +806,9 @@ struct mwifiex_adapter {
753 atomic_t is_tx_received; 806 atomic_t is_tx_received;
754 atomic_t pending_bridged_pkts; 807 atomic_t pending_bridged_pkts;
755 struct semaphore *card_sem; 808 struct semaphore *card_sem;
809 bool ext_scan;
810 u8 fw_api_ver;
811 u8 fw_key_api_major_ver, fw_key_api_minor_ver;
756}; 812};
757 813
758int mwifiex_init_lock_list(struct mwifiex_adapter *adapter); 814int mwifiex_init_lock_list(struct mwifiex_adapter *adapter);
@@ -788,11 +844,8 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter);
788int mwifiex_complete_cmd(struct mwifiex_adapter *adapter, 844int mwifiex_complete_cmd(struct mwifiex_adapter *adapter,
789 struct cmd_ctrl_node *cmd_node); 845 struct cmd_ctrl_node *cmd_node);
790 846
791int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no, 847int mwifiex_send_cmd(struct mwifiex_private *priv, u16 cmd_no,
792 u16 cmd_action, u32 cmd_oid, void *data_buf); 848 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 849
797void mwifiex_cmd_timeout_func(unsigned long function_context); 850void mwifiex_cmd_timeout_func(unsigned long function_context);
798 851
@@ -880,6 +933,7 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
880void mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason); 933void mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason);
881u8 mwifiex_band_to_radio_type(u8 band); 934u8 mwifiex_band_to_radio_type(u8 band);
882int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac); 935int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac);
936void mwifiex_deauthenticate_all(struct mwifiex_adapter *adapter);
883int mwifiex_adhoc_start(struct mwifiex_private *priv, 937int mwifiex_adhoc_start(struct mwifiex_private *priv,
884 struct cfg80211_ssid *adhoc_ssid); 938 struct cfg80211_ssid *adhoc_ssid);
885int mwifiex_adhoc_join(struct mwifiex_private *priv, 939int mwifiex_adhoc_join(struct mwifiex_private *priv,
@@ -938,6 +992,12 @@ mwifiex_set_wmm_params(struct mwifiex_private *priv,
938 struct cfg80211_ap_settings *params); 992 struct cfg80211_ap_settings *params);
939void mwifiex_set_ba_params(struct mwifiex_private *priv); 993void mwifiex_set_ba_params(struct mwifiex_private *priv);
940void mwifiex_set_11ac_ba_params(struct mwifiex_private *priv); 994void mwifiex_set_11ac_ba_params(struct mwifiex_private *priv);
995int mwifiex_cmd_802_11_scan_ext(struct mwifiex_private *priv,
996 struct host_cmd_ds_command *cmd,
997 void *data_buf);
998int mwifiex_ret_802_11_scan_ext(struct mwifiex_private *priv);
999int mwifiex_handle_event_ext_scan_report(struct mwifiex_private *priv,
1000 void *buf);
941 1001
942/* 1002/*
943 * This function checks if the queuing is RA based or not. 1003 * This function checks if the queuing is RA based or not.
@@ -1078,7 +1138,7 @@ int mwifiex_set_encode(struct mwifiex_private *priv, struct key_params *kp,
1078 const u8 *key, int key_len, u8 key_index, 1138 const u8 *key, int key_len, u8 key_index,
1079 const u8 *mac_addr, int disable); 1139 const u8 *mac_addr, int disable);
1080 1140
1081int mwifiex_set_gen_ie(struct mwifiex_private *priv, u8 *ie, int ie_len); 1141int mwifiex_set_gen_ie(struct mwifiex_private *priv, const u8 *ie, int ie_len);
1082 1142
1083int mwifiex_get_ver_ext(struct mwifiex_private *priv); 1143int mwifiex_get_ver_ext(struct mwifiex_private *priv);
1084 1144
@@ -1159,6 +1219,32 @@ void mwifiex_dnld_txpwr_table(struct mwifiex_private *priv);
1159 1219
1160extern const struct ethtool_ops mwifiex_ethtool_ops; 1220extern const struct ethtool_ops mwifiex_ethtool_ops;
1161 1221
1222void mwifiex_del_all_sta_list(struct mwifiex_private *priv);
1223void mwifiex_del_sta_entry(struct mwifiex_private *priv, u8 *mac);
1224void
1225mwifiex_set_sta_ht_cap(struct mwifiex_private *priv, const u8 *ies,
1226 int ies_len, struct mwifiex_sta_node *node);
1227struct mwifiex_sta_node *
1228mwifiex_add_sta_entry(struct mwifiex_private *priv, u8 *mac);
1229struct mwifiex_sta_node *
1230mwifiex_get_sta_entry(struct mwifiex_private *priv, u8 *mac);
1231int mwifiex_send_tdls_data_frame(struct mwifiex_private *priv, u8 *peer,
1232 u8 action_code, u8 dialog_token,
1233 u16 status_code, const u8 *extra_ies,
1234 size_t extra_ies_len);
1235int mwifiex_send_tdls_action_frame(struct mwifiex_private *priv,
1236 u8 *peer, u8 action_code, u8 dialog_token,
1237 u16 status_code, const u8 *extra_ies,
1238 size_t extra_ies_len);
1239void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
1240 u8 *buf, int len);
1241int mwifiex_tdls_oper(struct mwifiex_private *priv, u8 *peer, u8 action);
1242int mwifiex_get_tdls_link_status(struct mwifiex_private *priv, u8 *mac);
1243void mwifiex_disable_all_tdls_links(struct mwifiex_private *priv);
1244bool mwifiex_is_bss_in_11ac_mode(struct mwifiex_private *priv);
1245u8 mwifiex_get_center_freq_index(struct mwifiex_private *priv, u8 band,
1246 u32 pri_chan, u8 chan_bw);
1247
1162#ifdef CONFIG_DEBUG_FS 1248#ifdef CONFIG_DEBUG_FS
1163void mwifiex_debugfs_init(void); 1249void mwifiex_debugfs_init(void);
1164void mwifiex_debugfs_remove(void); 1250void mwifiex_debugfs_remove(void);
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index 7fe7b53fb17a..a7e8b96b2d90 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 */
@@ -109,6 +120,7 @@ static int mwifiex_pcie_suspend(struct device *dev)
109 120
110 /* Indicate device suspended */ 121 /* Indicate device suspended */
111 adapter->is_suspended = true; 122 adapter->is_suspended = true;
123 adapter->hs_enabling = false;
112 124
113 return 0; 125 return 0;
114} 126}
@@ -179,6 +191,7 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev,
179 card->pcie.firmware = data->firmware; 191 card->pcie.firmware = data->firmware;
180 card->pcie.reg = data->reg; 192 card->pcie.reg = data->reg;
181 card->pcie.blksz_fw_dl = data->blksz_fw_dl; 193 card->pcie.blksz_fw_dl = data->blksz_fw_dl;
194 card->pcie.tx_buf_size = data->tx_buf_size;
182 } 195 }
183 196
184 if (mwifiex_add_card(card, &add_remove_card_sem, &pcie_ops, 197 if (mwifiex_add_card(card, &add_remove_card_sem, &pcie_ops,
@@ -199,7 +212,6 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev)
199 struct pcie_service_card *card; 212 struct pcie_service_card *card;
200 struct mwifiex_adapter *adapter; 213 struct mwifiex_adapter *adapter;
201 struct mwifiex_private *priv; 214 struct mwifiex_private *priv;
202 int i;
203 215
204 card = pci_get_drvdata(pdev); 216 card = pci_get_drvdata(pdev);
205 if (!card) 217 if (!card)
@@ -218,11 +230,7 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev)
218 mwifiex_pcie_resume(&pdev->dev); 230 mwifiex_pcie_resume(&pdev->dev);
219#endif 231#endif
220 232
221 for (i = 0; i < adapter->priv_num; i++) 233 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 234
227 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); 235 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
228 236
@@ -320,6 +328,30 @@ static void mwifiex_pcie_dev_wakeup_delay(struct mwifiex_adapter *adapter)
320 return; 328 return;
321} 329}
322 330
331static void mwifiex_delay_for_sleep_cookie(struct mwifiex_adapter *adapter,
332 u32 max_delay_loop_cnt)
333{
334 struct pcie_service_card *card = adapter->card;
335 u8 *buffer;
336 u32 sleep_cookie, count;
337
338 for (count = 0; count < max_delay_loop_cnt; count++) {
339 buffer = card->cmdrsp_buf->data - INTF_HEADER_LEN;
340 sleep_cookie = *(u32 *)buffer;
341
342 if (sleep_cookie == MWIFIEX_DEF_SLEEP_COOKIE) {
343 dev_dbg(adapter->dev,
344 "sleep cookie found at count %d\n", count);
345 break;
346 }
347 usleep_range(20, 30);
348 }
349
350 if (count >= max_delay_loop_cnt)
351 dev_dbg(adapter->dev,
352 "max count reached while accessing sleep cookie\n");
353}
354
323/* This function wakes up the card by reading fw_status register. */ 355/* This function wakes up the card by reading fw_status register. */
324static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter) 356static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
325{ 357{
@@ -456,7 +488,7 @@ static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter)
456 PCI_DMA_FROMDEVICE)) 488 PCI_DMA_FROMDEVICE))
457 return -1; 489 return -1;
458 490
459 MWIFIEX_SKB_PACB(skb, &buf_pa); 491 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
460 492
461 dev_dbg(adapter->dev, 493 dev_dbg(adapter->dev,
462 "info: RX ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n", 494 "info: RX ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n",
@@ -513,7 +545,7 @@ static int mwifiex_pcie_init_evt_ring(struct mwifiex_adapter *adapter)
513 PCI_DMA_FROMDEVICE)) 545 PCI_DMA_FROMDEVICE))
514 return -1; 546 return -1;
515 547
516 MWIFIEX_SKB_PACB(skb, &buf_pa); 548 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
517 549
518 dev_dbg(adapter->dev, 550 dev_dbg(adapter->dev,
519 "info: EVT ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n", 551 "info: EVT ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n",
@@ -549,8 +581,8 @@ static void mwifiex_cleanup_txq_ring(struct mwifiex_adapter *adapter)
549 desc2 = card->txbd_ring[i]; 581 desc2 = card->txbd_ring[i];
550 if (card->tx_buf_list[i]) { 582 if (card->tx_buf_list[i]) {
551 skb = card->tx_buf_list[i]; 583 skb = card->tx_buf_list[i];
552 pci_unmap_single(card->dev, desc2->paddr, 584 mwifiex_unmap_pci_memory(adapter, skb,
553 skb->len, PCI_DMA_TODEVICE); 585 PCI_DMA_TODEVICE);
554 dev_kfree_skb_any(skb); 586 dev_kfree_skb_any(skb);
555 } 587 }
556 memset(desc2, 0, sizeof(*desc2)); 588 memset(desc2, 0, sizeof(*desc2));
@@ -558,8 +590,8 @@ static void mwifiex_cleanup_txq_ring(struct mwifiex_adapter *adapter)
558 desc = card->txbd_ring[i]; 590 desc = card->txbd_ring[i];
559 if (card->tx_buf_list[i]) { 591 if (card->tx_buf_list[i]) {
560 skb = card->tx_buf_list[i]; 592 skb = card->tx_buf_list[i];
561 pci_unmap_single(card->dev, desc->paddr, 593 mwifiex_unmap_pci_memory(adapter, skb,
562 skb->len, PCI_DMA_TODEVICE); 594 PCI_DMA_TODEVICE);
563 dev_kfree_skb_any(skb); 595 dev_kfree_skb_any(skb);
564 } 596 }
565 memset(desc, 0, sizeof(*desc)); 597 memset(desc, 0, sizeof(*desc));
@@ -587,8 +619,8 @@ static void mwifiex_cleanup_rxq_ring(struct mwifiex_adapter *adapter)
587 desc2 = card->rxbd_ring[i]; 619 desc2 = card->rxbd_ring[i];
588 if (card->rx_buf_list[i]) { 620 if (card->rx_buf_list[i]) {
589 skb = card->rx_buf_list[i]; 621 skb = card->rx_buf_list[i];
590 pci_unmap_single(card->dev, desc2->paddr, 622 mwifiex_unmap_pci_memory(adapter, skb,
591 skb->len, PCI_DMA_FROMDEVICE); 623 PCI_DMA_FROMDEVICE);
592 dev_kfree_skb_any(skb); 624 dev_kfree_skb_any(skb);
593 } 625 }
594 memset(desc2, 0, sizeof(*desc2)); 626 memset(desc2, 0, sizeof(*desc2));
@@ -596,8 +628,8 @@ static void mwifiex_cleanup_rxq_ring(struct mwifiex_adapter *adapter)
596 desc = card->rxbd_ring[i]; 628 desc = card->rxbd_ring[i];
597 if (card->rx_buf_list[i]) { 629 if (card->rx_buf_list[i]) {
598 skb = card->rx_buf_list[i]; 630 skb = card->rx_buf_list[i];
599 pci_unmap_single(card->dev, desc->paddr, 631 mwifiex_unmap_pci_memory(adapter, skb,
600 skb->len, PCI_DMA_FROMDEVICE); 632 PCI_DMA_FROMDEVICE);
601 dev_kfree_skb_any(skb); 633 dev_kfree_skb_any(skb);
602 } 634 }
603 memset(desc, 0, sizeof(*desc)); 635 memset(desc, 0, sizeof(*desc));
@@ -622,8 +654,8 @@ static void mwifiex_cleanup_evt_ring(struct mwifiex_adapter *adapter)
622 desc = card->evtbd_ring[i]; 654 desc = card->evtbd_ring[i];
623 if (card->evt_buf_list[i]) { 655 if (card->evt_buf_list[i]) {
624 skb = card->evt_buf_list[i]; 656 skb = card->evt_buf_list[i];
625 pci_unmap_single(card->dev, desc->paddr, MAX_EVENT_SIZE, 657 mwifiex_unmap_pci_memory(adapter, skb,
626 PCI_DMA_FROMDEVICE); 658 PCI_DMA_FROMDEVICE);
627 dev_kfree_skb_any(skb); 659 dev_kfree_skb_any(skb);
628 } 660 }
629 card->evt_buf_list[i] = NULL; 661 card->evt_buf_list[i] = NULL;
@@ -861,7 +893,6 @@ static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter)
861static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter) 893static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter)
862{ 894{
863 struct pcie_service_card *card; 895 struct pcie_service_card *card;
864 dma_addr_t buf_pa;
865 896
866 if (!adapter) 897 if (!adapter)
867 return 0; 898 return 0;
@@ -869,16 +900,14 @@ static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter)
869 card = adapter->card; 900 card = adapter->card;
870 901
871 if (card && card->cmdrsp_buf) { 902 if (card && card->cmdrsp_buf) {
872 MWIFIEX_SKB_PACB(card->cmdrsp_buf, &buf_pa); 903 mwifiex_unmap_pci_memory(adapter, card->cmdrsp_buf,
873 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE, 904 PCI_DMA_FROMDEVICE);
874 PCI_DMA_FROMDEVICE);
875 dev_kfree_skb_any(card->cmdrsp_buf); 905 dev_kfree_skb_any(card->cmdrsp_buf);
876 } 906 }
877 907
878 if (card && card->cmd_buf) { 908 if (card && card->cmd_buf) {
879 MWIFIEX_SKB_PACB(card->cmd_buf, &buf_pa); 909 mwifiex_unmap_pci_memory(adapter, card->cmd_buf,
880 pci_unmap_single(card->dev, buf_pa, card->cmd_buf->len, 910 PCI_DMA_TODEVICE);
881 PCI_DMA_TODEVICE);
882 } 911 }
883 return 0; 912 return 0;
884} 913}
@@ -956,7 +985,6 @@ static int mwifiex_clean_pcie_ring_buf(struct mwifiex_adapter *adapter)
956static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter) 985static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter)
957{ 986{
958 struct sk_buff *skb; 987 struct sk_buff *skb;
959 dma_addr_t buf_pa;
960 u32 wrdoneidx, rdptr, num_tx_buffs, unmap_count = 0; 988 u32 wrdoneidx, rdptr, num_tx_buffs, unmap_count = 0;
961 struct mwifiex_pcie_buf_desc *desc; 989 struct mwifiex_pcie_buf_desc *desc;
962 struct mwifiex_pfu_buf_desc *desc2; 990 struct mwifiex_pfu_buf_desc *desc2;
@@ -986,13 +1014,13 @@ static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter)
986 reg->tx_start_ptr; 1014 reg->tx_start_ptr;
987 1015
988 skb = card->tx_buf_list[wrdoneidx]; 1016 skb = card->tx_buf_list[wrdoneidx];
1017
989 if (skb) { 1018 if (skb) {
990 dev_dbg(adapter->dev, 1019 dev_dbg(adapter->dev,
991 "SEND COMP: Detach skb %p at txbd_rdidx=%d\n", 1020 "SEND COMP: Detach skb %p at txbd_rdidx=%d\n",
992 skb, wrdoneidx); 1021 skb, wrdoneidx);
993 MWIFIEX_SKB_PACB(skb, &buf_pa); 1022 mwifiex_unmap_pci_memory(adapter, skb,
994 pci_unmap_single(card->dev, buf_pa, skb->len, 1023 PCI_DMA_TODEVICE);
995 PCI_DMA_TODEVICE);
996 1024
997 unmap_count++; 1025 unmap_count++;
998 1026
@@ -1006,7 +1034,7 @@ static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter)
1006 card->tx_buf_list[wrdoneidx] = NULL; 1034 card->tx_buf_list[wrdoneidx] = NULL;
1007 1035
1008 if (reg->pfu_enabled) { 1036 if (reg->pfu_enabled) {
1009 desc2 = (void *)card->txbd_ring[wrdoneidx]; 1037 desc2 = card->txbd_ring[wrdoneidx];
1010 memset(desc2, 0, sizeof(*desc2)); 1038 memset(desc2, 0, sizeof(*desc2));
1011 } else { 1039 } else {
1012 desc = card->txbd_ring[wrdoneidx]; 1040 desc = card->txbd_ring[wrdoneidx];
@@ -1082,16 +1110,16 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb,
1082 tmp = (__le16 *)&payload[2]; 1110 tmp = (__le16 *)&payload[2];
1083 *tmp = cpu_to_le16(MWIFIEX_TYPE_DATA); 1111 *tmp = cpu_to_le16(MWIFIEX_TYPE_DATA);
1084 1112
1085 if (mwifiex_map_pci_memory(adapter, skb, skb->len , 1113 if (mwifiex_map_pci_memory(adapter, skb, skb->len,
1086 PCI_DMA_TODEVICE)) 1114 PCI_DMA_TODEVICE))
1087 return -1; 1115 return -1;
1088 1116
1089 wrindx = (card->txbd_wrptr & reg->tx_mask) >> reg->tx_start_ptr; 1117 wrindx = (card->txbd_wrptr & reg->tx_mask) >> reg->tx_start_ptr;
1090 MWIFIEX_SKB_PACB(skb, &buf_pa); 1118 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
1091 card->tx_buf_list[wrindx] = skb; 1119 card->tx_buf_list[wrindx] = skb;
1092 1120
1093 if (reg->pfu_enabled) { 1121 if (reg->pfu_enabled) {
1094 desc2 = (void *)card->txbd_ring[wrindx]; 1122 desc2 = card->txbd_ring[wrindx];
1095 desc2->paddr = buf_pa; 1123 desc2->paddr = buf_pa;
1096 desc2->len = (u16)skb->len; 1124 desc2->len = (u16)skb->len;
1097 desc2->frag_len = (u16)skb->len; 1125 desc2->frag_len = (u16)skb->len;
@@ -1162,8 +1190,7 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb,
1162 1190
1163 return -EINPROGRESS; 1191 return -EINPROGRESS;
1164done_unmap: 1192done_unmap:
1165 MWIFIEX_SKB_PACB(skb, &buf_pa); 1193 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; 1194 card->tx_buf_list[wrindx] = NULL;
1168 if (reg->pfu_enabled) 1195 if (reg->pfu_enabled)
1169 memset(desc2, 0, sizeof(*desc2)); 1196 memset(desc2, 0, sizeof(*desc2));
@@ -1217,9 +1244,7 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
1217 if (!skb_data) 1244 if (!skb_data)
1218 return -ENOMEM; 1245 return -ENOMEM;
1219 1246
1220 MWIFIEX_SKB_PACB(skb_data, &buf_pa); 1247 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; 1248 card->rx_buf_list[rd_index] = NULL;
1224 1249
1225 /* Get data length from interface header - 1250 /* Get data length from interface header -
@@ -1246,7 +1271,7 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
1246 PCI_DMA_FROMDEVICE)) 1271 PCI_DMA_FROMDEVICE))
1247 return -1; 1272 return -1;
1248 1273
1249 MWIFIEX_SKB_PACB(skb_tmp, &buf_pa); 1274 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb_tmp);
1250 1275
1251 dev_dbg(adapter->dev, 1276 dev_dbg(adapter->dev,
1252 "RECV DATA: Attach new sk_buff %p at rxbd_rdidx=%d\n", 1277 "RECV DATA: Attach new sk_buff %p at rxbd_rdidx=%d\n",
@@ -1254,7 +1279,7 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
1254 card->rx_buf_list[rd_index] = skb_tmp; 1279 card->rx_buf_list[rd_index] = skb_tmp;
1255 1280
1256 if (reg->pfu_enabled) { 1281 if (reg->pfu_enabled) {
1257 desc2 = (void *)card->rxbd_ring[rd_index]; 1282 desc2 = card->rxbd_ring[rd_index];
1258 desc2->paddr = buf_pa; 1283 desc2->paddr = buf_pa;
1259 desc2->len = skb_tmp->len; 1284 desc2->len = skb_tmp->len;
1260 desc2->frag_len = skb_tmp->len; 1285 desc2->frag_len = skb_tmp->len;
@@ -1322,7 +1347,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)) 1347 if (mwifiex_map_pci_memory(adapter, skb, skb->len , PCI_DMA_TODEVICE))
1323 return -1; 1348 return -1;
1324 1349
1325 MWIFIEX_SKB_PACB(skb, &buf_pa); 1350 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
1326 1351
1327 /* Write the lower 32bits of the physical address to low command 1352 /* Write the lower 32bits of the physical address to low command
1328 * address scratch register 1353 * address scratch register
@@ -1331,8 +1356,7 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1331 dev_err(adapter->dev, 1356 dev_err(adapter->dev,
1332 "%s: failed to write download command to boot code.\n", 1357 "%s: failed to write download command to boot code.\n",
1333 __func__); 1358 __func__);
1334 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE, 1359 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
1335 PCI_DMA_TODEVICE);
1336 return -1; 1360 return -1;
1337 } 1361 }
1338 1362
@@ -1344,8 +1368,7 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1344 dev_err(adapter->dev, 1368 dev_err(adapter->dev,
1345 "%s: failed to write download command to boot code.\n", 1369 "%s: failed to write download command to boot code.\n",
1346 __func__); 1370 __func__);
1347 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE, 1371 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
1348 PCI_DMA_TODEVICE);
1349 return -1; 1372 return -1;
1350 } 1373 }
1351 1374
@@ -1354,8 +1377,7 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1354 dev_err(adapter->dev, 1377 dev_err(adapter->dev,
1355 "%s: failed to write command len to cmd_size scratch reg\n", 1378 "%s: failed to write command len to cmd_size scratch reg\n",
1356 __func__); 1379 __func__);
1357 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE, 1380 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
1358 PCI_DMA_TODEVICE);
1359 return -1; 1381 return -1;
1360 } 1382 }
1361 1383
@@ -1364,8 +1386,7 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1364 CPU_INTR_DOOR_BELL)) { 1386 CPU_INTR_DOOR_BELL)) {
1365 dev_err(adapter->dev, 1387 dev_err(adapter->dev,
1366 "%s: failed to assert door-bell intr\n", __func__); 1388 "%s: failed to assert door-bell intr\n", __func__);
1367 pci_unmap_single(card->dev, buf_pa, 1389 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
1368 MWIFIEX_UPLD_SIZE, PCI_DMA_TODEVICE);
1369 return -1; 1390 return -1;
1370 } 1391 }
1371 1392
@@ -1439,7 +1460,7 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1439 */ 1460 */
1440 1461
1441 if (card->cmdrsp_buf) { 1462 if (card->cmdrsp_buf) {
1442 MWIFIEX_SKB_PACB(card->cmdrsp_buf, &cmdrsp_buf_pa); 1463 cmdrsp_buf_pa = MWIFIEX_SKB_DMA_ADDR(card->cmdrsp_buf);
1443 /* Write the lower 32bits of the cmdrsp buffer physical 1464 /* Write the lower 32bits of the cmdrsp buffer physical
1444 address */ 1465 address */
1445 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo, 1466 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo,
@@ -1460,7 +1481,7 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1460 } 1481 }
1461 } 1482 }
1462 1483
1463 MWIFIEX_SKB_PACB(card->cmd_buf, &cmd_buf_pa); 1484 cmd_buf_pa = MWIFIEX_SKB_DMA_ADDR(card->cmd_buf);
1464 /* Write the lower 32bits of the physical address to reg->cmd_addr_lo */ 1485 /* Write the lower 32bits of the physical address to reg->cmd_addr_lo */
1465 if (mwifiex_write_reg(adapter, reg->cmd_addr_lo, 1486 if (mwifiex_write_reg(adapter, reg->cmd_addr_lo,
1466 (u32)cmd_buf_pa)) { 1487 (u32)cmd_buf_pa)) {
@@ -1514,13 +1535,17 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
1514 int count = 0; 1535 int count = 0;
1515 u16 rx_len; 1536 u16 rx_len;
1516 __le16 pkt_len; 1537 __le16 pkt_len;
1517 dma_addr_t buf_pa;
1518 1538
1519 dev_dbg(adapter->dev, "info: Rx CMD Response\n"); 1539 dev_dbg(adapter->dev, "info: Rx CMD Response\n");
1520 1540
1521 MWIFIEX_SKB_PACB(skb, &buf_pa); 1541 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_FROMDEVICE);
1522 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE, 1542
1523 PCI_DMA_FROMDEVICE); 1543 /* Unmap the command as a response has been received. */
1544 if (card->cmd_buf) {
1545 mwifiex_unmap_pci_memory(adapter, card->cmd_buf,
1546 PCI_DMA_TODEVICE);
1547 card->cmd_buf = NULL;
1548 }
1524 1549
1525 pkt_len = *((__le16 *)skb->data); 1550 pkt_len = *((__le16 *)skb->data);
1526 rx_len = le16_to_cpu(pkt_len); 1551 rx_len = le16_to_cpu(pkt_len);
@@ -1539,6 +1564,8 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
1539 "Write register failed\n"); 1564 "Write register failed\n");
1540 return -1; 1565 return -1;
1541 } 1566 }
1567 mwifiex_delay_for_sleep_cookie(adapter,
1568 MWIFIEX_MAX_DELAY_COUNT);
1542 while (reg->sleep_cookie && (count++ < 10) && 1569 while (reg->sleep_cookie && (count++ < 10) &&
1543 mwifiex_pcie_ok_to_access_hw(adapter)) 1570 mwifiex_pcie_ok_to_access_hw(adapter))
1544 usleep_range(50, 60); 1571 usleep_range(50, 60);
@@ -1552,8 +1579,6 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
1552 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE, 1579 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
1553 PCI_DMA_FROMDEVICE)) 1580 PCI_DMA_FROMDEVICE))
1554 return -1; 1581 return -1;
1555
1556 MWIFIEX_SKB_PACB(skb, &buf_pa);
1557 } else if (mwifiex_pcie_ok_to_access_hw(adapter)) { 1582 } else if (mwifiex_pcie_ok_to_access_hw(adapter)) {
1558 adapter->curr_cmd->resp_skb = skb; 1583 adapter->curr_cmd->resp_skb = skb;
1559 adapter->cmd_resp_received = true; 1584 adapter->cmd_resp_received = true;
@@ -1588,8 +1613,6 @@ static int mwifiex_pcie_cmdrsp_complete(struct mwifiex_adapter *adapter,
1588 struct sk_buff *skb) 1613 struct sk_buff *skb)
1589{ 1614{
1590 struct pcie_service_card *card = adapter->card; 1615 struct pcie_service_card *card = adapter->card;
1591 dma_addr_t buf_pa;
1592 struct sk_buff *skb_tmp;
1593 1616
1594 if (skb) { 1617 if (skb) {
1595 card->cmdrsp_buf = skb; 1618 card->cmdrsp_buf = skb;
@@ -1599,14 +1622,6 @@ static int mwifiex_pcie_cmdrsp_complete(struct mwifiex_adapter *adapter,
1599 return -1; 1622 return -1;
1600 } 1623 }
1601 1624
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; 1625 return 0;
1611} 1626}
1612 1627
@@ -1619,7 +1634,6 @@ static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter)
1619 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; 1634 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
1620 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK; 1635 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
1621 u32 wrptr, event; 1636 u32 wrptr, event;
1622 dma_addr_t buf_pa;
1623 struct mwifiex_evt_buf_desc *desc; 1637 struct mwifiex_evt_buf_desc *desc;
1624 1638
1625 if (!mwifiex_pcie_ok_to_access_hw(adapter)) 1639 if (!mwifiex_pcie_ok_to_access_hw(adapter))
@@ -1655,9 +1669,7 @@ static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter)
1655 1669
1656 dev_dbg(adapter->dev, "info: Read Index: %d\n", rdptr); 1670 dev_dbg(adapter->dev, "info: Read Index: %d\n", rdptr);
1657 skb_cmd = card->evt_buf_list[rdptr]; 1671 skb_cmd = card->evt_buf_list[rdptr];
1658 MWIFIEX_SKB_PACB(skb_cmd, &buf_pa); 1672 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 1673
1662 /* Take the pointer and set it to event pointer in adapter 1674 /* Take the pointer and set it to event pointer in adapter
1663 and will return back after event handling callback */ 1675 and will return back after event handling callback */
@@ -1703,7 +1715,6 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter,
1703 int ret = 0; 1715 int ret = 0;
1704 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK; 1716 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
1705 u32 wrptr; 1717 u32 wrptr;
1706 dma_addr_t buf_pa;
1707 struct mwifiex_evt_buf_desc *desc; 1718 struct mwifiex_evt_buf_desc *desc;
1708 1719
1709 if (!skb) 1720 if (!skb)
@@ -1728,11 +1739,9 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter,
1728 MAX_EVENT_SIZE, 1739 MAX_EVENT_SIZE,
1729 PCI_DMA_FROMDEVICE)) 1740 PCI_DMA_FROMDEVICE))
1730 return -1; 1741 return -1;
1731 MWIFIEX_SKB_PACB(skb, &buf_pa);
1732 card->evt_buf_list[rdptr] = skb; 1742 card->evt_buf_list[rdptr] = skb;
1733 MWIFIEX_SKB_PACB(skb, &buf_pa);
1734 desc = card->evtbd_ring[rdptr]; 1743 desc = card->evtbd_ring[rdptr];
1735 desc->paddr = buf_pa; 1744 desc->paddr = MWIFIEX_SKB_DMA_ADDR(skb);
1736 desc->len = (u16)skb->len; 1745 desc->len = (u16)skb->len;
1737 desc->flags = 0; 1746 desc->flags = 0;
1738 skb = NULL; 1747 skb = NULL;
@@ -1782,7 +1791,6 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
1782 struct sk_buff *skb; 1791 struct sk_buff *skb;
1783 u32 txlen, tx_blocks = 0, tries, len; 1792 u32 txlen, tx_blocks = 0, tries, len;
1784 u32 block_retry_cnt = 0; 1793 u32 block_retry_cnt = 0;
1785 dma_addr_t buf_pa;
1786 struct pcie_service_card *card = adapter->card; 1794 struct pcie_service_card *card = adapter->card;
1787 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; 1795 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
1788 1796
@@ -1880,8 +1888,6 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
1880 goto done; 1888 goto done;
1881 } 1889 }
1882 1890
1883 MWIFIEX_SKB_PACB(skb, &buf_pa);
1884
1885 /* Wait for the command done interrupt */ 1891 /* Wait for the command done interrupt */
1886 do { 1892 do {
1887 if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS, 1893 if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS,
@@ -1889,16 +1895,15 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
1889 dev_err(adapter->dev, "%s: Failed to read " 1895 dev_err(adapter->dev, "%s: Failed to read "
1890 "interrupt status during fw dnld.\n", 1896 "interrupt status during fw dnld.\n",
1891 __func__); 1897 __func__);
1892 pci_unmap_single(card->dev, buf_pa, skb->len, 1898 mwifiex_unmap_pci_memory(adapter, skb,
1893 PCI_DMA_TODEVICE); 1899 PCI_DMA_TODEVICE);
1894 ret = -1; 1900 ret = -1;
1895 goto done; 1901 goto done;
1896 } 1902 }
1897 } while ((ireg_intr & CPU_INTR_DOOR_BELL) == 1903 } while ((ireg_intr & CPU_INTR_DOOR_BELL) ==
1898 CPU_INTR_DOOR_BELL); 1904 CPU_INTR_DOOR_BELL);
1899 1905
1900 pci_unmap_single(card->dev, buf_pa, skb->len, 1906 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
1901 PCI_DMA_TODEVICE);
1902 1907
1903 offset += txlen; 1908 offset += txlen;
1904 } while (true); 1909 } while (true);
@@ -2338,6 +2343,7 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
2338 } 2343 }
2339 2344
2340 adapter->dev = &pdev->dev; 2345 adapter->dev = &pdev->dev;
2346 adapter->tx_buf_size = card->pcie.tx_buf_size;
2341 strcpy(adapter->fw_name, card->pcie.firmware); 2347 strcpy(adapter->fw_name, card->pcie.firmware);
2342 2348
2343 return 0; 2349 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..7b3af3d29ded 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -591,11 +591,13 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv,
591 *chan_tlv_out, 591 *chan_tlv_out,
592 struct mwifiex_chan_scan_param_set *scan_chan_list) 592 struct mwifiex_chan_scan_param_set *scan_chan_list)
593{ 593{
594 struct mwifiex_adapter *adapter = priv->adapter;
594 int ret = 0; 595 int ret = 0;
595 struct mwifiex_chan_scan_param_set *tmp_chan_list; 596 struct mwifiex_chan_scan_param_set *tmp_chan_list;
596 struct mwifiex_chan_scan_param_set *start_chan; 597 struct mwifiex_chan_scan_param_set *start_chan;
597 598 struct cmd_ctrl_node *cmd_node, *tmp_node;
598 u32 tlv_idx, rates_size; 599 unsigned long flags;
600 u32 tlv_idx, rates_size, cmd_no;
599 u32 total_scan_time; 601 u32 total_scan_time;
600 u32 done_early; 602 u32 done_early;
601 u8 radio_type; 603 u8 radio_type;
@@ -733,9 +735,13 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv,
733 735
734 /* Send the scan command to the firmware with the specified 736 /* Send the scan command to the firmware with the specified
735 cfg */ 737 cfg */
736 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_SCAN, 738 if (priv->adapter->ext_scan)
737 HostCmd_ACT_GEN_SET, 0, 739 cmd_no = HostCmd_CMD_802_11_SCAN_EXT;
738 scan_cfg_out); 740 else
741 cmd_no = HostCmd_CMD_802_11_SCAN;
742
743 ret = mwifiex_send_cmd(priv, cmd_no, HostCmd_ACT_GEN_SET,
744 0, scan_cfg_out, false);
739 745
740 /* rate IE is updated per scan command but same starting 746 /* rate IE is updated per scan command but same starting
741 * pointer is used each time so that rate IE from earlier 747 * pointer is used each time so that rate IE from earlier
@@ -744,8 +750,19 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv,
744 scan_cfg_out->tlv_buf_len -= 750 scan_cfg_out->tlv_buf_len -=
745 sizeof(struct mwifiex_ie_types_header) + rates_size; 751 sizeof(struct mwifiex_ie_types_header) + rates_size;
746 752
747 if (ret) 753 if (ret) {
754 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
755 list_for_each_entry_safe(cmd_node, tmp_node,
756 &adapter->scan_pending_q,
757 list) {
758 list_del(&cmd_node->list);
759 cmd_node->wait_q_enabled = false;
760 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
761 }
762 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
763 flags);
748 break; 764 break;
765 }
749 } 766 }
750 767
751 if (ret) 768 if (ret)
@@ -786,6 +803,7 @@ mwifiex_config_scan(struct mwifiex_private *priv,
786 struct mwifiex_adapter *adapter = priv->adapter; 803 struct mwifiex_adapter *adapter = priv->adapter;
787 struct mwifiex_ie_types_num_probes *num_probes_tlv; 804 struct mwifiex_ie_types_num_probes *num_probes_tlv;
788 struct mwifiex_ie_types_wildcard_ssid_params *wildcard_ssid_tlv; 805 struct mwifiex_ie_types_wildcard_ssid_params *wildcard_ssid_tlv;
806 struct mwifiex_ie_types_bssid_list *bssid_tlv;
789 u8 *tlv_pos; 807 u8 *tlv_pos;
790 u32 num_probes; 808 u32 num_probes;
791 u32 ssid_len; 809 u32 ssid_len;
@@ -848,6 +866,17 @@ mwifiex_config_scan(struct mwifiex_private *priv,
848 user_scan_in->specific_bssid, 866 user_scan_in->specific_bssid,
849 sizeof(scan_cfg_out->specific_bssid)); 867 sizeof(scan_cfg_out->specific_bssid));
850 868
869 if (adapter->ext_scan &&
870 !is_zero_ether_addr(scan_cfg_out->specific_bssid)) {
871 bssid_tlv =
872 (struct mwifiex_ie_types_bssid_list *)tlv_pos;
873 bssid_tlv->header.type = cpu_to_le16(TLV_TYPE_BSSID);
874 bssid_tlv->header.len = cpu_to_le16(ETH_ALEN);
875 memcpy(bssid_tlv->bssid, user_scan_in->specific_bssid,
876 ETH_ALEN);
877 tlv_pos += sizeof(struct mwifiex_ie_types_bssid_list);
878 }
879
851 for (i = 0; i < user_scan_in->num_ssids; i++) { 880 for (i = 0; i < user_scan_in->num_ssids; i++) {
852 ssid_len = user_scan_in->ssid_list[i].ssid_len; 881 ssid_len = user_scan_in->ssid_list[i].ssid_len;
853 882
@@ -941,7 +970,7 @@ mwifiex_config_scan(struct mwifiex_private *priv,
941 cpu_to_le16(sizeof(struct ieee80211_ht_cap)); 970 cpu_to_le16(sizeof(struct ieee80211_ht_cap));
942 radio_type = 971 radio_type =
943 mwifiex_band_to_radio_type(priv->adapter->config_bands); 972 mwifiex_band_to_radio_type(priv->adapter->config_bands);
944 mwifiex_fill_cap_info(priv, radio_type, ht_cap); 973 mwifiex_fill_cap_info(priv, radio_type, &ht_cap->ht_cap);
945 tlv_pos += sizeof(struct mwifiex_ie_types_htcap); 974 tlv_pos += sizeof(struct mwifiex_ie_types_htcap);
946 } 975 }
947 976
@@ -1576,6 +1605,228 @@ done:
1576 return 0; 1605 return 0;
1577} 1606}
1578 1607
1608static int
1609mwifiex_parse_single_response_buf(struct mwifiex_private *priv, u8 **bss_info,
1610 u32 *bytes_left, u64 fw_tsf, u8 *radio_type,
1611 bool ext_scan, s32 rssi_val)
1612{
1613 struct mwifiex_adapter *adapter = priv->adapter;
1614 struct mwifiex_chan_freq_power *cfp;
1615 struct cfg80211_bss *bss;
1616 u8 bssid[ETH_ALEN];
1617 s32 rssi;
1618 const u8 *ie_buf;
1619 size_t ie_len;
1620 u16 channel = 0;
1621 u16 beacon_size = 0;
1622 u32 curr_bcn_bytes;
1623 u32 freq;
1624 u16 beacon_period;
1625 u16 cap_info_bitmap;
1626 u8 *current_ptr;
1627 u64 timestamp;
1628 struct mwifiex_fixed_bcn_param *bcn_param;
1629 struct mwifiex_bss_priv *bss_priv;
1630
1631 if (*bytes_left >= sizeof(beacon_size)) {
1632 /* Extract & convert beacon size from command buffer */
1633 memcpy(&beacon_size, *bss_info, sizeof(beacon_size));
1634 *bytes_left -= sizeof(beacon_size);
1635 *bss_info += sizeof(beacon_size);
1636 }
1637
1638 if (!beacon_size || beacon_size > *bytes_left) {
1639 *bss_info += *bytes_left;
1640 *bytes_left = 0;
1641 return -EFAULT;
1642 }
1643
1644 /* Initialize the current working beacon pointer for this BSS
1645 * iteration
1646 */
1647 current_ptr = *bss_info;
1648
1649 /* Advance the return beacon pointer past the current beacon */
1650 *bss_info += beacon_size;
1651 *bytes_left -= beacon_size;
1652
1653 curr_bcn_bytes = beacon_size;
1654
1655 /* First 5 fields are bssid, RSSI(for legacy scan only),
1656 * time stamp, beacon interval, and capability information
1657 */
1658 if (curr_bcn_bytes < ETH_ALEN + sizeof(u8) +
1659 sizeof(struct mwifiex_fixed_bcn_param)) {
1660 dev_err(adapter->dev, "InterpretIE: not enough bytes left\n");
1661 return -EFAULT;
1662 }
1663
1664 memcpy(bssid, current_ptr, ETH_ALEN);
1665 current_ptr += ETH_ALEN;
1666 curr_bcn_bytes -= ETH_ALEN;
1667
1668 if (!ext_scan) {
1669 rssi = (s32) *current_ptr;
1670 rssi = (-rssi) * 100; /* Convert dBm to mBm */
1671 current_ptr += sizeof(u8);
1672 curr_bcn_bytes -= sizeof(u8);
1673 dev_dbg(adapter->dev, "info: InterpretIE: RSSI=%d\n", rssi);
1674 } else {
1675 rssi = rssi_val;
1676 }
1677
1678 bcn_param = (struct mwifiex_fixed_bcn_param *)current_ptr;
1679 current_ptr += sizeof(*bcn_param);
1680 curr_bcn_bytes -= sizeof(*bcn_param);
1681
1682 timestamp = le64_to_cpu(bcn_param->timestamp);
1683 beacon_period = le16_to_cpu(bcn_param->beacon_period);
1684
1685 cap_info_bitmap = le16_to_cpu(bcn_param->cap_info_bitmap);
1686 dev_dbg(adapter->dev, "info: InterpretIE: capabilities=0x%X\n",
1687 cap_info_bitmap);
1688
1689 /* Rest of the current buffer are IE's */
1690 ie_buf = current_ptr;
1691 ie_len = curr_bcn_bytes;
1692 dev_dbg(adapter->dev, "info: InterpretIE: IELength for this AP = %d\n",
1693 curr_bcn_bytes);
1694
1695 while (curr_bcn_bytes >= sizeof(struct ieee_types_header)) {
1696 u8 element_id, element_len;
1697
1698 element_id = *current_ptr;
1699 element_len = *(current_ptr + 1);
1700 if (curr_bcn_bytes < element_len +
1701 sizeof(struct ieee_types_header)) {
1702 dev_err(adapter->dev,
1703 "%s: bytes left < IE length\n", __func__);
1704 return -EFAULT;
1705 }
1706 if (element_id == WLAN_EID_DS_PARAMS) {
1707 channel = *(current_ptr +
1708 sizeof(struct ieee_types_header));
1709 break;
1710 }
1711
1712 current_ptr += element_len + sizeof(struct ieee_types_header);
1713 curr_bcn_bytes -= element_len +
1714 sizeof(struct ieee_types_header);
1715 }
1716
1717 if (channel) {
1718 struct ieee80211_channel *chan;
1719 u8 band;
1720
1721 /* Skip entry if on csa closed channel */
1722 if (channel == priv->csa_chan) {
1723 dev_dbg(adapter->dev,
1724 "Dropping entry on csa closed channel\n");
1725 return 0;
1726 }
1727
1728 band = BAND_G;
1729 if (radio_type)
1730 band = mwifiex_radio_type_to_band(*radio_type &
1731 (BIT(0) | BIT(1)));
1732
1733 cfp = mwifiex_get_cfp(priv, band, channel, 0);
1734
1735 freq = cfp ? cfp->freq : 0;
1736
1737 chan = ieee80211_get_channel(priv->wdev->wiphy, freq);
1738
1739 if (chan && !(chan->flags & IEEE80211_CHAN_DISABLED)) {
1740 bss = cfg80211_inform_bss(priv->wdev->wiphy,
1741 chan, bssid, timestamp,
1742 cap_info_bitmap, beacon_period,
1743 ie_buf, ie_len, rssi, GFP_KERNEL);
1744 bss_priv = (struct mwifiex_bss_priv *)bss->priv;
1745 bss_priv->band = band;
1746 bss_priv->fw_tsf = fw_tsf;
1747 if (priv->media_connected &&
1748 !memcmp(bssid, priv->curr_bss_params.bss_descriptor
1749 .mac_address, ETH_ALEN))
1750 mwifiex_update_curr_bss_params(priv, bss);
1751 cfg80211_put_bss(priv->wdev->wiphy, bss);
1752 }
1753 } else {
1754 dev_dbg(adapter->dev, "missing BSS channel IE\n");
1755 }
1756
1757 return 0;
1758}
1759
1760static void mwifiex_check_next_scan_command(struct mwifiex_private *priv)
1761{
1762 struct mwifiex_adapter *adapter = priv->adapter;
1763 struct cmd_ctrl_node *cmd_node;
1764 unsigned long flags;
1765
1766 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
1767 if (list_empty(&adapter->scan_pending_q)) {
1768 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
1769 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
1770 adapter->scan_processing = false;
1771 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
1772
1773 /* Need to indicate IOCTL complete */
1774 if (adapter->curr_cmd->wait_q_enabled) {
1775 adapter->cmd_wait_q.status = 0;
1776 if (!priv->scan_request) {
1777 dev_dbg(adapter->dev,
1778 "complete internal scan\n");
1779 mwifiex_complete_cmd(adapter,
1780 adapter->curr_cmd);
1781 }
1782 }
1783 if (priv->report_scan_result)
1784 priv->report_scan_result = false;
1785
1786 if (priv->scan_request) {
1787 dev_dbg(adapter->dev, "info: notifying scan done\n");
1788 cfg80211_scan_done(priv->scan_request, 0);
1789 priv->scan_request = NULL;
1790 } else {
1791 priv->scan_aborting = false;
1792 dev_dbg(adapter->dev, "info: scan already aborted\n");
1793 }
1794 } else {
1795 if ((priv->scan_aborting && !priv->scan_request) ||
1796 priv->scan_block) {
1797 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1798 flags);
1799 adapter->scan_delay_cnt = MWIFIEX_MAX_SCAN_DELAY_CNT;
1800 mod_timer(&priv->scan_delay_timer, jiffies);
1801 dev_dbg(priv->adapter->dev,
1802 "info: %s: triggerring scan abort\n", __func__);
1803 } else if (!mwifiex_wmm_lists_empty(adapter) &&
1804 (priv->scan_request && (priv->scan_request->flags &
1805 NL80211_SCAN_FLAG_LOW_PRIORITY))) {
1806 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1807 flags);
1808 adapter->scan_delay_cnt = 1;
1809 mod_timer(&priv->scan_delay_timer, jiffies +
1810 msecs_to_jiffies(MWIFIEX_SCAN_DELAY_MSEC));
1811 dev_dbg(priv->adapter->dev,
1812 "info: %s: deferring scan\n", __func__);
1813 } else {
1814 /* Get scan command from scan_pending_q and put to
1815 * cmd_pending_q
1816 */
1817 cmd_node = list_first_entry(&adapter->scan_pending_q,
1818 struct cmd_ctrl_node, list);
1819 list_del(&cmd_node->list);
1820 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1821 flags);
1822 mwifiex_insert_cmd_to_pending_q(adapter, cmd_node,
1823 true);
1824 }
1825 }
1826
1827 return;
1828}
1829
1579/* 1830/*
1580 * This function handles the command response of scan. 1831 * This function handles the command response of scan.
1581 * 1832 *
@@ -1600,7 +1851,6 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
1600{ 1851{
1601 int ret = 0; 1852 int ret = 0;
1602 struct mwifiex_adapter *adapter = priv->adapter; 1853 struct mwifiex_adapter *adapter = priv->adapter;
1603 struct cmd_ctrl_node *cmd_node;
1604 struct host_cmd_ds_802_11_scan_rsp *scan_rsp; 1854 struct host_cmd_ds_802_11_scan_rsp *scan_rsp;
1605 struct mwifiex_ie_types_data *tlv_data; 1855 struct mwifiex_ie_types_data *tlv_data;
1606 struct mwifiex_ie_types_tsf_timestamp *tsf_tlv; 1856 struct mwifiex_ie_types_tsf_timestamp *tsf_tlv;
@@ -1609,12 +1859,11 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
1609 u32 bytes_left; 1859 u32 bytes_left;
1610 u32 idx; 1860 u32 idx;
1611 u32 tlv_buf_size; 1861 u32 tlv_buf_size;
1612 struct mwifiex_chan_freq_power *cfp;
1613 struct mwifiex_ie_types_chan_band_list_param_set *chan_band_tlv; 1862 struct mwifiex_ie_types_chan_band_list_param_set *chan_band_tlv;
1614 struct chan_band_param_set *chan_band; 1863 struct chan_band_param_set *chan_band;
1615 u8 is_bgscan_resp; 1864 u8 is_bgscan_resp;
1616 unsigned long flags; 1865 __le64 fw_tsf = 0;
1617 struct cfg80211_bss *bss; 1866 u8 *radio_type;
1618 1867
1619 is_bgscan_resp = (le16_to_cpu(resp->command) 1868 is_bgscan_resp = (le16_to_cpu(resp->command)
1620 == HostCmd_CMD_802_11_BG_SCAN_QUERY); 1869 == HostCmd_CMD_802_11_BG_SCAN_QUERY);
@@ -1676,220 +1925,194 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
1676 &chan_band_tlv); 1925 &chan_band_tlv);
1677 1926
1678 for (idx = 0; idx < scan_rsp->number_of_sets && bytes_left; idx++) { 1927 for (idx = 0; idx < scan_rsp->number_of_sets && bytes_left; idx++) {
1679 u8 bssid[ETH_ALEN]; 1928 /*
1680 s32 rssi; 1929 * If the TSF TLV was appended to the scan results, save this
1681 const u8 *ie_buf; 1930 * entry's TSF value in the fw_tsf field. It is the firmware's
1682 size_t ie_len; 1931 * TSF value at the time the beacon or probe response was
1683 u16 channel = 0; 1932 * received.
1684 __le64 fw_tsf = 0; 1933 */
1685 u16 beacon_size = 0; 1934 if (tsf_tlv)
1686 u32 curr_bcn_bytes; 1935 memcpy(&fw_tsf, &tsf_tlv->tsf_data[idx * TSF_DATA_SIZE],
1687 u32 freq; 1936 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 1937
1702 if (!beacon_size || beacon_size > bytes_left) { 1938 if (chan_band_tlv) {
1703 bss_info += bytes_left; 1939 chan_band = &chan_band_tlv->chan_band_param[idx];
1704 bytes_left = 0; 1940 radio_type = &chan_band->radio_type;
1705 ret = -1; 1941 } else {
1706 goto check_next_scan; 1942 radio_type = NULL;
1707 } 1943 }
1708 1944
1709 /* Initialize the current working beacon pointer for this BSS 1945 ret = mwifiex_parse_single_response_buf(priv, &bss_info,
1710 * iteration */ 1946 &bytes_left,
1711 current_ptr = bss_info; 1947 le64_to_cpu(fw_tsf),
1948 radio_type, false, 0);
1949 if (ret)
1950 goto check_next_scan;
1951 }
1712 1952
1713 /* Advance the return beacon pointer past the current beacon */ 1953check_next_scan:
1714 bss_info += beacon_size; 1954 mwifiex_check_next_scan_command(priv);
1715 bytes_left -= beacon_size; 1955 return ret;
1956}
1716 1957
1717 curr_bcn_bytes = beacon_size; 1958/*
1959 * This function prepares an extended scan command to be sent to the firmware
1960 *
1961 * This uses the scan command configuration sent to the command processing
1962 * module in command preparation stage to configure a extended scan command
1963 * structure to send to firmware.
1964 */
1965int mwifiex_cmd_802_11_scan_ext(struct mwifiex_private *priv,
1966 struct host_cmd_ds_command *cmd,
1967 void *data_buf)
1968{
1969 struct host_cmd_ds_802_11_scan_ext *ext_scan = &cmd->params.ext_scan;
1970 struct mwifiex_scan_cmd_config *scan_cfg = data_buf;
1718 1971
1719 /* 1972 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 1973
1732 memcpy(bssid, bcn_param->bssid, ETH_ALEN); 1974 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_SCAN_EXT);
1733 1975
1734 rssi = (s32) bcn_param->rssi; 1976 /* Size is equal to the sizeof(fixed portions) + the TLV len + header */
1735 rssi = (-rssi) * 100; /* Convert dBm to mBm */ 1977 cmd->size = cpu_to_le16((u16)(sizeof(ext_scan->reserved)
1736 dev_dbg(adapter->dev, "info: InterpretIE: RSSI=%d\n", rssi); 1978 + scan_cfg->tlv_buf_len + S_DS_GEN));
1737 1979
1738 timestamp = le64_to_cpu(bcn_param->timestamp); 1980 return 0;
1739 beacon_period = le16_to_cpu(bcn_param->beacon_period); 1981}
1740 1982
1741 cap_info_bitmap = le16_to_cpu(bcn_param->cap_info_bitmap); 1983/* This function handles the command response of extended scan */
1742 dev_dbg(adapter->dev, "info: InterpretIE: capabilities=0x%X\n", 1984int mwifiex_ret_802_11_scan_ext(struct mwifiex_private *priv)
1743 cap_info_bitmap); 1985{
1986 dev_dbg(priv->adapter->dev, "info: EXT scan returns successfully\n");
1987 return 0;
1988}
1744 1989
1745 /* Rest of the current buffer are IE's */ 1990/* This function This function handles the event extended scan report. It
1746 ie_buf = current_ptr; 1991 * parses extended scan results and informs to cfg80211 stack.
1747 ie_len = curr_bcn_bytes; 1992 */
1748 dev_dbg(adapter->dev, 1993int mwifiex_handle_event_ext_scan_report(struct mwifiex_private *priv,
1749 "info: InterpretIE: IELength for this AP = %d\n", 1994 void *buf)
1750 curr_bcn_bytes); 1995{
1996 int ret = 0;
1997 struct mwifiex_adapter *adapter = priv->adapter;
1998 u8 *bss_info;
1999 u32 bytes_left, bytes_left_for_tlv, idx;
2000 u16 type, len;
2001 struct mwifiex_ie_types_data *tlv;
2002 struct mwifiex_ie_types_bss_scan_rsp *scan_rsp_tlv;
2003 struct mwifiex_ie_types_bss_scan_info *scan_info_tlv;
2004 u8 *radio_type;
2005 u64 fw_tsf = 0;
2006 s32 rssi = 0;
2007 struct mwifiex_event_scan_result *event_scan = buf;
2008 u8 num_of_set = event_scan->num_of_set;
2009 u8 *scan_resp = buf + sizeof(struct mwifiex_event_scan_result);
2010 u16 scan_resp_size = le16_to_cpu(event_scan->buf_size);
2011
2012 if (num_of_set > MWIFIEX_MAX_AP) {
2013 dev_err(adapter->dev,
2014 "EXT_SCAN: Invalid number of AP returned (%d)!!\n",
2015 num_of_set);
2016 ret = -1;
2017 goto check_next_scan;
2018 }
1751 2019
1752 while (curr_bcn_bytes >= sizeof(struct ieee_types_header)) { 2020 bytes_left = scan_resp_size;
1753 u8 element_id, element_len; 2021 dev_dbg(adapter->dev,
2022 "EXT_SCAN: size %d, returned %d APs...",
2023 scan_resp_size, num_of_set);
1754 2024
1755 element_id = *current_ptr; 2025 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 2026
1769 current_ptr += element_len + 2027 for (idx = 0; idx < num_of_set && bytes_left; idx++) {
1770 sizeof(struct ieee_types_header); 2028 type = le16_to_cpu(tlv->header.type);
1771 curr_bcn_bytes -= element_len + 2029 len = le16_to_cpu(tlv->header.len);
1772 sizeof(struct ieee_types_header); 2030 if (bytes_left < sizeof(struct mwifiex_ie_types_header) + len) {
2031 dev_err(adapter->dev, "EXT_SCAN: Error bytes left < TLV length\n");
2032 break;
1773 } 2033 }
2034 scan_rsp_tlv = NULL;
2035 scan_info_tlv = NULL;
2036 bytes_left_for_tlv = bytes_left;
1774 2037
1775 /* 2038 /* BSS response TLV with beacon or probe response buffer
1776 * If the TSF TLV was appended to the scan results, save this 2039 * 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 */ 2040 */
1781 if (tsf_tlv) 2041 if (type != TLV_TYPE_BSS_SCAN_RSP)
1782 memcpy(&fw_tsf, &tsf_tlv->tsf_data[idx * TSF_DATA_SIZE], 2042 break;
1783 sizeof(fw_tsf));
1784
1785 if (channel) {
1786 struct ieee80211_channel *chan;
1787 u8 band;
1788 2043
1789 /* Skip entry if on csa closed channel */ 2044 bss_info = (u8 *)tlv;
1790 if (channel == priv->csa_chan) { 2045 scan_rsp_tlv = (struct mwifiex_ie_types_bss_scan_rsp *)tlv;
1791 dev_dbg(adapter->dev, 2046 tlv = (struct mwifiex_ie_types_data *)(tlv->data + len);
1792 "Dropping entry on csa closed channel\n"); 2047 bytes_left_for_tlv -=
2048 (len + sizeof(struct mwifiex_ie_types_header));
2049
2050 while (bytes_left_for_tlv >=
2051 sizeof(struct mwifiex_ie_types_header) &&
2052 le16_to_cpu(tlv->header.type) != TLV_TYPE_BSS_SCAN_RSP) {
2053 type = le16_to_cpu(tlv->header.type);
2054 len = le16_to_cpu(tlv->header.len);
2055 if (bytes_left_for_tlv <
2056 sizeof(struct mwifiex_ie_types_header) + len) {
2057 dev_err(adapter->dev,
2058 "EXT_SCAN: Error in processing TLV, bytes left < TLV length\n");
2059 scan_rsp_tlv = NULL;
2060 bytes_left_for_tlv = 0;
1793 continue; 2061 continue;
1794 } 2062 }
1795 2063 switch (type) {
1796 band = BAND_G; 2064 case TLV_TYPE_BSS_SCAN_INFO:
1797 if (chan_band_tlv) { 2065 scan_info_tlv =
1798 chan_band = 2066 (struct mwifiex_ie_types_bss_scan_info *)tlv;
1799 &chan_band_tlv->chan_band_param[idx]; 2067 if (len !=
1800 band = mwifiex_radio_type_to_band( 2068 sizeof(struct mwifiex_ie_types_bss_scan_info) -
1801 chan_band->radio_type 2069 sizeof(struct mwifiex_ie_types_header)) {
1802 & (BIT(0) | BIT(1))); 2070 bytes_left_for_tlv = 0;
1803 } 2071 continue;
1804 2072 }
1805 cfp = mwifiex_get_cfp(priv, band, channel, 0); 2073 break;
1806 2074 default:
1807 freq = cfp ? cfp->freq : 0; 2075 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 } 2076 }
1827 } else { 2077 tlv = (struct mwifiex_ie_types_data *)(tlv->data + len);
1828 dev_dbg(adapter->dev, "missing BSS channel IE\n"); 2078 bytes_left -=
2079 (len + sizeof(struct mwifiex_ie_types_header));
2080 bytes_left_for_tlv -=
2081 (len + sizeof(struct mwifiex_ie_types_header));
1829 } 2082 }
1830 }
1831 2083
1832check_next_scan: 2084 if (!scan_rsp_tlv)
1833 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); 2085 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 2086
1840 /* Need to indicate IOCTL complete */ 2087 /* Advance pointer to the beacon buffer length and
1841 if (adapter->curr_cmd->wait_q_enabled) { 2088 * update the bytes count so that the function
1842 adapter->cmd_wait_q.status = 0; 2089 * wlan_interpret_bss_desc_with_ie() can handle the
1843 if (!priv->scan_request) { 2090 * scan buffer withut any change
1844 dev_dbg(adapter->dev, 2091 */
1845 "complete internal scan\n"); 2092 bss_info += sizeof(u16);
1846 mwifiex_complete_cmd(adapter, 2093 bytes_left -= sizeof(u16);
1847 adapter->curr_cmd);
1848 }
1849 }
1850 if (priv->report_scan_result)
1851 priv->report_scan_result = false;
1852 2094
1853 if (priv->scan_request) { 2095 if (scan_info_tlv) {
1854 dev_dbg(adapter->dev, "info: notifying scan done\n"); 2096 rssi = (s32)(s16)(le16_to_cpu(scan_info_tlv->rssi));
1855 cfg80211_scan_done(priv->scan_request, 0); 2097 rssi *= 100; /* Convert dBm to mBm */
1856 priv->scan_request = NULL; 2098 dev_dbg(adapter->dev,
1857 } else { 2099 "info: InterpretIE: RSSI=%d\n", rssi);
1858 priv->scan_aborting = false; 2100 fw_tsf = le64_to_cpu(scan_info_tlv->tsf);
1859 dev_dbg(adapter->dev, "info: scan already aborted\n"); 2101 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 { 2102 } else {
1881 /* Get scan command from scan_pending_q and put to 2103 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 } 2104 }
2105 ret = mwifiex_parse_single_response_buf(priv, &bss_info,
2106 &bytes_left, fw_tsf,
2107 radio_type, true, rssi);
2108 if (ret)
2109 goto check_next_scan;
1891 } 2110 }
1892 2111
2112check_next_scan:
2113 if (!event_scan->more_event)
2114 mwifiex_check_next_scan_command(priv);
2115
1893 return ret; 2116 return ret;
1894} 2117}
1895 2118
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index b44a31523461..d206f04d4994 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);
@@ -241,6 +237,7 @@ static int mwifiex_sdio_suspend(struct device *dev)
241 /* Enable the Host Sleep */ 237 /* Enable the Host Sleep */
242 if (!mwifiex_enable_hs(adapter)) { 238 if (!mwifiex_enable_hs(adapter)) {
243 dev_err(adapter->dev, "cmd: failed to suspend\n"); 239 dev_err(adapter->dev, "cmd: failed to suspend\n");
240 adapter->hs_enabling = false;
244 return -EFAULT; 241 return -EFAULT;
245 } 242 }
246 243
@@ -249,6 +246,7 @@ static int mwifiex_sdio_suspend(struct device *dev)
249 246
250 /* Indicate device suspended */ 247 /* Indicate device suspended */
251 adapter->is_suspended = true; 248 adapter->is_suspended = true;
249 adapter->hs_enabling = false;
252 250
253 return ret; 251 return ret;
254} 252}
@@ -1760,6 +1758,7 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
1760 1758
1761 /* save adapter pointer in card */ 1759 /* save adapter pointer in card */
1762 card->adapter = adapter; 1760 card->adapter = adapter;
1761 adapter->tx_buf_size = card->tx_buf_size;
1763 1762
1764 sdio_claim_host(func); 1763 sdio_claim_host(func);
1765 1764
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..894270611f2c 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -64,6 +64,7 @@ int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter,
64 *(cmd_queued->condition)); 64 *(cmd_queued->condition));
65 if (status) { 65 if (status) {
66 dev_err(adapter->dev, "cmd_wait_q terminated: %d\n", status); 66 dev_err(adapter->dev, "cmd_wait_q terminated: %d\n", status);
67 mwifiex_cancel_all_pending_cmd(adapter);
67 return status; 68 return status;
68 } 69 }
69 70
@@ -108,19 +109,19 @@ int mwifiex_request_set_multicast_list(struct mwifiex_private *priv,
108 "info: Set multicast list=%d\n", 109 "info: Set multicast list=%d\n",
109 mcast_list->num_multicast_addr); 110 mcast_list->num_multicast_addr);
110 /* Send multicast addresses to firmware */ 111 /* Send multicast addresses to firmware */
111 ret = mwifiex_send_cmd_async(priv, 112 ret = mwifiex_send_cmd(priv,
112 HostCmd_CMD_MAC_MULTICAST_ADR, 113 HostCmd_CMD_MAC_MULTICAST_ADR,
113 HostCmd_ACT_GEN_SET, 0, 114 HostCmd_ACT_GEN_SET, 0,
114 mcast_list); 115 mcast_list, false);
115 } 116 }
116 } 117 }
117 dev_dbg(priv->adapter->dev, 118 dev_dbg(priv->adapter->dev,
118 "info: old_pkt_filter=%#x, curr_pkt_filter=%#x\n", 119 "info: old_pkt_filter=%#x, curr_pkt_filter=%#x\n",
119 old_pkt_filter, priv->curr_pkt_filter); 120 old_pkt_filter, priv->curr_pkt_filter);
120 if (old_pkt_filter != priv->curr_pkt_filter) { 121 if (old_pkt_filter != priv->curr_pkt_filter) {
121 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, 122 ret = mwifiex_send_cmd(priv, HostCmd_CMD_MAC_CONTROL,
122 HostCmd_ACT_GEN_SET, 123 HostCmd_ACT_GEN_SET,
123 0, &priv->curr_pkt_filter); 124 0, &priv->curr_pkt_filter, false);
124 } 125 }
125 126
126 return ret; 127 return ret;
@@ -237,8 +238,8 @@ static int mwifiex_process_country_ie(struct mwifiex_private *priv,
237 238
238 rcu_read_unlock(); 239 rcu_read_unlock();
239 240
240 if (mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11D_DOMAIN_INFO, 241 if (mwifiex_send_cmd(priv, HostCmd_CMD_802_11D_DOMAIN_INFO,
241 HostCmd_ACT_GEN_SET, 0, NULL)) { 242 HostCmd_ACT_GEN_SET, 0, NULL, false)) {
242 wiphy_err(priv->adapter->wiphy, 243 wiphy_err(priv->adapter->wiphy,
243 "11D: setting domain info in FW\n"); 244 "11D: setting domain info in FW\n");
244 return -1; 245 return -1;
@@ -290,7 +291,7 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
290 291
291 if (mwifiex_band_to_radio_type(bss_desc->bss_band) == 292 if (mwifiex_band_to_radio_type(bss_desc->bss_band) ==
292 HostCmd_SCAN_RADIO_TYPE_BG) 293 HostCmd_SCAN_RADIO_TYPE_BG)
293 config_bands = BAND_B | BAND_G | BAND_GN | BAND_GAC; 294 config_bands = BAND_B | BAND_G | BAND_GN;
294 else 295 else
295 config_bands = BAND_A | BAND_AN | BAND_AAC; 296 config_bands = BAND_A | BAND_AN | BAND_AAC;
296 297
@@ -429,16 +430,13 @@ static int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action,
429 status = -1; 430 status = -1;
430 break; 431 break;
431 } 432 }
432 if (cmd_type == MWIFIEX_SYNC_CMD) 433
433 status = mwifiex_send_cmd_sync(priv, 434 status = mwifiex_send_cmd(priv,
434 HostCmd_CMD_802_11_HS_CFG_ENH, 435 HostCmd_CMD_802_11_HS_CFG_ENH,
435 HostCmd_ACT_GEN_SET, 0, 436 HostCmd_ACT_GEN_SET, 0,
436 &adapter->hs_cfg); 437 &adapter->hs_cfg,
437 else 438 cmd_type == MWIFIEX_SYNC_CMD);
438 status = mwifiex_send_cmd_async(priv, 439
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) 440 if (hs_cfg->conditions == HS_CFG_CANCEL)
443 /* Restore previous condition */ 441 /* Restore previous condition */
444 adapter->hs_cfg.conditions = 442 adapter->hs_cfg.conditions =
@@ -511,6 +509,9 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter)
511 memset(&hscfg, 0, sizeof(struct mwifiex_ds_hs_cfg)); 509 memset(&hscfg, 0, sizeof(struct mwifiex_ds_hs_cfg));
512 hscfg.is_invoke_hostcmd = true; 510 hscfg.is_invoke_hostcmd = true;
513 511
512 adapter->hs_enabling = true;
513 mwifiex_cancel_all_pending_cmd(adapter);
514
514 if (mwifiex_set_hs_params(mwifiex_get_priv(adapter, 515 if (mwifiex_set_hs_params(mwifiex_get_priv(adapter,
515 MWIFIEX_BSS_ROLE_STA), 516 MWIFIEX_BSS_ROLE_STA),
516 HostCmd_ACT_GEN_SET, MWIFIEX_SYNC_CMD, 517 HostCmd_ACT_GEN_SET, MWIFIEX_SYNC_CMD,
@@ -519,8 +520,9 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter)
519 return false; 520 return false;
520 } 521 }
521 522
522 if (wait_event_interruptible(adapter->hs_activate_wait_q, 523 if (wait_event_interruptible_timeout(adapter->hs_activate_wait_q,
523 adapter->hs_activate_wait_q_woken)) { 524 adapter->hs_activate_wait_q_woken,
525 (10 * HZ)) <= 0) {
524 dev_err(adapter->dev, "hs_activate_wait_q terminated\n"); 526 dev_err(adapter->dev, "hs_activate_wait_q terminated\n");
525 return false; 527 return false;
526 } 528 }
@@ -586,8 +588,8 @@ int mwifiex_disable_auto_ds(struct mwifiex_private *priv)
586 588
587 auto_ds.auto_ds = DEEP_SLEEP_OFF; 589 auto_ds.auto_ds = DEEP_SLEEP_OFF;
588 590
589 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_PS_MODE_ENH, 591 return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_PS_MODE_ENH,
590 DIS_AUTO_PS, BITMAP_AUTO_DS, &auto_ds); 592 DIS_AUTO_PS, BITMAP_AUTO_DS, &auto_ds, true);
591} 593}
592EXPORT_SYMBOL_GPL(mwifiex_disable_auto_ds); 594EXPORT_SYMBOL_GPL(mwifiex_disable_auto_ds);
593 595
@@ -601,8 +603,8 @@ int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, u32 *rate)
601{ 603{
602 int ret; 604 int ret;
603 605
604 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_TX_RATE_QUERY, 606 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_TX_RATE_QUERY,
605 HostCmd_ACT_GEN_GET, 0, NULL); 607 HostCmd_ACT_GEN_GET, 0, NULL, true);
606 608
607 if (!ret) { 609 if (!ret) {
608 if (priv->is_data_rate_auto) 610 if (priv->is_data_rate_auto)
@@ -698,8 +700,8 @@ int mwifiex_set_tx_power(struct mwifiex_private *priv,
698 pg->power_max = (s8) dbm; 700 pg->power_max = (s8) dbm;
699 pg->ht_bandwidth = HT_BW_40; 701 pg->ht_bandwidth = HT_BW_40;
700 } 702 }
701 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_TXPWR_CFG, 703 ret = mwifiex_send_cmd(priv, HostCmd_CMD_TXPWR_CFG,
702 HostCmd_ACT_GEN_SET, 0, buf); 704 HostCmd_ACT_GEN_SET, 0, buf, true);
703 705
704 kfree(buf); 706 kfree(buf);
705 return ret; 707 return ret;
@@ -722,12 +724,11 @@ int mwifiex_drv_set_power(struct mwifiex_private *priv, u32 *ps_mode)
722 else 724 else
723 adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM; 725 adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM;
724 sub_cmd = (*ps_mode) ? EN_AUTO_PS : DIS_AUTO_PS; 726 sub_cmd = (*ps_mode) ? EN_AUTO_PS : DIS_AUTO_PS;
725 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_PS_MODE_ENH, 727 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_PS_MODE_ENH,
726 sub_cmd, BITMAP_STA_PS, NULL); 728 sub_cmd, BITMAP_STA_PS, NULL, true);
727 if ((!ret) && (sub_cmd == DIS_AUTO_PS)) 729 if ((!ret) && (sub_cmd == DIS_AUTO_PS))
728 ret = mwifiex_send_cmd_async(priv, 730 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_PS_MODE_ENH,
729 HostCmd_CMD_802_11_PS_MODE_ENH, 731 GET_PS, 0, NULL, false);
730 GET_PS, 0, NULL);
731 732
732 return ret; 733 return ret;
733} 734}
@@ -851,9 +852,9 @@ static int mwifiex_sec_ioctl_set_wapi_key(struct mwifiex_private *priv,
851 struct mwifiex_ds_encrypt_key *encrypt_key) 852 struct mwifiex_ds_encrypt_key *encrypt_key)
852{ 853{
853 854
854 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_KEY_MATERIAL, 855 return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL,
855 HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, 856 HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED,
856 encrypt_key); 857 encrypt_key, true);
857} 858}
858 859
859/* 860/*
@@ -865,6 +866,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, 866static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_private *priv,
866 struct mwifiex_ds_encrypt_key *encrypt_key) 867 struct mwifiex_ds_encrypt_key *encrypt_key)
867{ 868{
869 struct mwifiex_adapter *adapter = priv->adapter;
868 int ret; 870 int ret;
869 struct mwifiex_wep_key *wep_key; 871 struct mwifiex_wep_key *wep_key;
870 int index; 872 int index;
@@ -879,10 +881,17 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_private *priv,
879 /* Copy the required key as the current key */ 881 /* Copy the required key as the current key */
880 wep_key = &priv->wep_key[index]; 882 wep_key = &priv->wep_key[index];
881 if (!wep_key->key_length) { 883 if (!wep_key->key_length) {
882 dev_err(priv->adapter->dev, 884 dev_err(adapter->dev,
883 "key not set, so cannot enable it\n"); 885 "key not set, so cannot enable it\n");
884 return -1; 886 return -1;
885 } 887 }
888
889 if (adapter->fw_key_api_major_ver == FW_KEY_API_VER_MAJOR_V2) {
890 memcpy(encrypt_key->key_material,
891 wep_key->key_material, wep_key->key_length);
892 encrypt_key->key_len = wep_key->key_length;
893 }
894
886 priv->wep_key_curr_index = (u16) index; 895 priv->wep_key_curr_index = (u16) index;
887 priv->sec_info.wep_enabled = 1; 896 priv->sec_info.wep_enabled = 1;
888 } else { 897 } else {
@@ -897,21 +906,32 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_private *priv,
897 priv->sec_info.wep_enabled = 1; 906 priv->sec_info.wep_enabled = 1;
898 } 907 }
899 if (wep_key->key_length) { 908 if (wep_key->key_length) {
909 void *enc_key;
910
911 if (encrypt_key->key_disable)
912 memset(&priv->wep_key[index], 0,
913 sizeof(struct mwifiex_wep_key));
914
915 if (adapter->fw_key_api_major_ver == FW_KEY_API_VER_MAJOR_V2)
916 enc_key = encrypt_key;
917 else
918 enc_key = NULL;
919
900 /* Send request to firmware */ 920 /* Send request to firmware */
901 ret = mwifiex_send_cmd_async(priv, 921 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL,
902 HostCmd_CMD_802_11_KEY_MATERIAL, 922 HostCmd_ACT_GEN_SET, 0, enc_key, false);
903 HostCmd_ACT_GEN_SET, 0, NULL);
904 if (ret) 923 if (ret)
905 return ret; 924 return ret;
906 } 925 }
926
907 if (priv->sec_info.wep_enabled) 927 if (priv->sec_info.wep_enabled)
908 priv->curr_pkt_filter |= HostCmd_ACT_MAC_WEP_ENABLE; 928 priv->curr_pkt_filter |= HostCmd_ACT_MAC_WEP_ENABLE;
909 else 929 else
910 priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE; 930 priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE;
911 931
912 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_MAC_CONTROL, 932 ret = mwifiex_send_cmd(priv, HostCmd_CMD_MAC_CONTROL,
913 HostCmd_ACT_GEN_SET, 0, 933 HostCmd_ACT_GEN_SET, 0,
914 &priv->curr_pkt_filter); 934 &priv->curr_pkt_filter, true);
915 935
916 return ret; 936 return ret;
917} 937}
@@ -946,10 +966,9 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_private *priv,
946 */ 966 */
947 /* Send the key as PTK to firmware */ 967 /* Send the key as PTK to firmware */
948 encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST; 968 encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST;
949 ret = mwifiex_send_cmd_async(priv, 969 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL,
950 HostCmd_CMD_802_11_KEY_MATERIAL, 970 HostCmd_ACT_GEN_SET,
951 HostCmd_ACT_GEN_SET, 971 KEY_INFO_ENABLED, encrypt_key, false);
952 KEY_INFO_ENABLED, encrypt_key);
953 if (ret) 972 if (ret)
954 return ret; 973 return ret;
955 974
@@ -973,15 +992,13 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_private *priv,
973 encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST; 992 encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST;
974 993
975 if (remove_key) 994 if (remove_key)
976 ret = mwifiex_send_cmd_sync(priv, 995 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL,
977 HostCmd_CMD_802_11_KEY_MATERIAL, 996 HostCmd_ACT_GEN_SET,
978 HostCmd_ACT_GEN_SET, 997 !KEY_INFO_ENABLED, encrypt_key, true);
979 !KEY_INFO_ENABLED, encrypt_key);
980 else 998 else
981 ret = mwifiex_send_cmd_sync(priv, 999 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL,
982 HostCmd_CMD_802_11_KEY_MATERIAL, 1000 HostCmd_ACT_GEN_SET,
983 HostCmd_ACT_GEN_SET, 1001 KEY_INFO_ENABLED, encrypt_key, true);
984 KEY_INFO_ENABLED, encrypt_key);
985 1002
986 return ret; 1003 return ret;
987} 1004}
@@ -1044,19 +1061,27 @@ int mwifiex_set_encode(struct mwifiex_private *priv, struct key_params *kp,
1044 1061
1045 memset(&encrypt_key, 0, sizeof(struct mwifiex_ds_encrypt_key)); 1062 memset(&encrypt_key, 0, sizeof(struct mwifiex_ds_encrypt_key));
1046 encrypt_key.key_len = key_len; 1063 encrypt_key.key_len = key_len;
1064 encrypt_key.key_index = key_index;
1047 1065
1048 if (kp && kp->cipher == WLAN_CIPHER_SUITE_AES_CMAC) 1066 if (kp && kp->cipher == WLAN_CIPHER_SUITE_AES_CMAC)
1049 encrypt_key.is_igtk_key = true; 1067 encrypt_key.is_igtk_key = true;
1050 1068
1051 if (!disable) { 1069 if (!disable) {
1052 encrypt_key.key_index = key_index;
1053 if (key_len) 1070 if (key_len)
1054 memcpy(encrypt_key.key_material, key, key_len); 1071 memcpy(encrypt_key.key_material, key, key_len);
1072 else
1073 encrypt_key.is_current_wep_key = true;
1074
1055 if (mac_addr) 1075 if (mac_addr)
1056 memcpy(encrypt_key.mac_addr, mac_addr, ETH_ALEN); 1076 memcpy(encrypt_key.mac_addr, mac_addr, ETH_ALEN);
1057 if (kp && kp->seq && kp->seq_len) 1077 if (kp && kp->seq && kp->seq_len) {
1058 memcpy(encrypt_key.pn, kp->seq, kp->seq_len); 1078 memcpy(encrypt_key.pn, kp->seq, kp->seq_len);
1079 encrypt_key.pn_len = kp->seq_len;
1080 encrypt_key.is_rx_seq_valid = true;
1081 }
1059 } else { 1082 } else {
1083 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP)
1084 return 0;
1060 encrypt_key.key_disable = true; 1085 encrypt_key.key_disable = true;
1061 if (mac_addr) 1086 if (mac_addr)
1062 memcpy(encrypt_key.mac_addr, mac_addr, ETH_ALEN); 1087 memcpy(encrypt_key.mac_addr, mac_addr, ETH_ALEN);
@@ -1077,8 +1102,8 @@ mwifiex_get_ver_ext(struct mwifiex_private *priv)
1077 struct mwifiex_ver_ext ver_ext; 1102 struct mwifiex_ver_ext ver_ext;
1078 1103
1079 memset(&ver_ext, 0, sizeof(struct host_cmd_ds_version_ext)); 1104 memset(&ver_ext, 0, sizeof(struct host_cmd_ds_version_ext));
1080 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_VERSION_EXT, 1105 if (mwifiex_send_cmd(priv, HostCmd_CMD_VERSION_EXT,
1081 HostCmd_ACT_GEN_GET, 0, &ver_ext)) 1106 HostCmd_ACT_GEN_GET, 0, &ver_ext, true))
1082 return -1; 1107 return -1;
1083 1108
1084 return 0; 1109 return 0;
@@ -1103,8 +1128,8 @@ mwifiex_remain_on_chan_cfg(struct mwifiex_private *priv, u16 action,
1103 ieee80211_frequency_to_channel(chan->center_freq); 1128 ieee80211_frequency_to_channel(chan->center_freq);
1104 roc_cfg.duration = cpu_to_le32(duration); 1129 roc_cfg.duration = cpu_to_le32(duration);
1105 } 1130 }
1106 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_REMAIN_ON_CHAN, 1131 if (mwifiex_send_cmd(priv, HostCmd_CMD_REMAIN_ON_CHAN,
1107 action, 0, &roc_cfg)) { 1132 action, 0, &roc_cfg, true)) {
1108 dev_err(priv->adapter->dev, "failed to remain on channel\n"); 1133 dev_err(priv->adapter->dev, "failed to remain on channel\n");
1109 return -1; 1134 return -1;
1110 } 1135 }
@@ -1136,8 +1161,8 @@ mwifiex_set_bss_role(struct mwifiex_private *priv, u8 bss_role)
1136 break; 1161 break;
1137 } 1162 }
1138 1163
1139 mwifiex_send_cmd_sync(priv, HostCmd_CMD_SET_BSS_MODE, 1164 mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
1140 HostCmd_ACT_GEN_SET, 0, NULL); 1165 HostCmd_ACT_GEN_SET, 0, NULL, true);
1141 1166
1142 return mwifiex_sta_init_cmd(priv, false); 1167 return mwifiex_sta_init_cmd(priv, false);
1143} 1168}
@@ -1152,8 +1177,8 @@ int
1152mwifiex_get_stats_info(struct mwifiex_private *priv, 1177mwifiex_get_stats_info(struct mwifiex_private *priv,
1153 struct mwifiex_ds_get_stats *log) 1178 struct mwifiex_ds_get_stats *log)
1154{ 1179{
1155 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_GET_LOG, 1180 return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_GET_LOG,
1156 HostCmd_ACT_GEN_GET, 0, log); 1181 HostCmd_ACT_GEN_GET, 0, log, true);
1157} 1182}
1158 1183
1159/* 1184/*
@@ -1195,8 +1220,7 @@ static int mwifiex_reg_mem_ioctl_reg_rw(struct mwifiex_private *priv,
1195 return -1; 1220 return -1;
1196 } 1221 }
1197 1222
1198 return mwifiex_send_cmd_sync(priv, cmd_no, action, 0, reg_rw); 1223 return mwifiex_send_cmd(priv, cmd_no, action, 0, reg_rw, true);
1199
1200} 1224}
1201 1225
1202/* 1226/*
@@ -1261,8 +1285,8 @@ mwifiex_eeprom_read(struct mwifiex_private *priv, u16 offset, u16 bytes,
1261 rd_eeprom.byte_count = cpu_to_le16((u16) bytes); 1285 rd_eeprom.byte_count = cpu_to_le16((u16) bytes);
1262 1286
1263 /* Send request to firmware */ 1287 /* Send request to firmware */
1264 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_EEPROM_ACCESS, 1288 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_EEPROM_ACCESS,
1265 HostCmd_ACT_GEN_GET, 0, &rd_eeprom); 1289 HostCmd_ACT_GEN_GET, 0, &rd_eeprom, true);
1266 1290
1267 if (!ret) 1291 if (!ret)
1268 memcpy(value, rd_eeprom.value, MAX_EEPROM_DATA); 1292 memcpy(value, rd_eeprom.value, MAX_EEPROM_DATA);
@@ -1391,7 +1415,7 @@ static int mwifiex_misc_ioctl_gen_ie(struct mwifiex_private *priv,
1391 * with requisite parameters and calls the IOCTL handler. 1415 * with requisite parameters and calls the IOCTL handler.
1392 */ 1416 */
1393int 1417int
1394mwifiex_set_gen_ie(struct mwifiex_private *priv, u8 *ie, int ie_len) 1418mwifiex_set_gen_ie(struct mwifiex_private *priv, const u8 *ie, int ie_len)
1395{ 1419{
1396 struct mwifiex_ds_misc_gen_ie gen_ie; 1420 struct mwifiex_ds_misc_gen_ie gen_ie;
1397 1421
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..97662a1ba58c
--- /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 (*(buf + sizeof(struct ethhdr)) != WLAN_TDLS_SNAP_RFTYPE)
734 return;
735 if (*(buf + sizeof(struct ethhdr) + 1) != WLAN_CATEGORY_TDLS)
736 return;
737
738 peer = buf + ETH_ALEN;
739 action = *(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..edbe4aff00d8 100644
--- a/drivers/net/wireless/mwifiex/usb.c
+++ b/drivers/net/wireless/mwifiex/usb.c
@@ -459,6 +459,7 @@ static int mwifiex_usb_suspend(struct usb_interface *intf, pm_message_t message)
459 * 'suspended' state and a 'disconnect' one. 459 * 'suspended' state and a 'disconnect' one.
460 */ 460 */
461 adapter->is_suspended = true; 461 adapter->is_suspended = true;
462 adapter->hs_enabling = false;
462 463
463 if (atomic_read(&card->rx_cmd_urb_pending) && card->rx_cmd.urb) 464 if (atomic_read(&card->rx_cmd_urb_pending) && card->rx_cmd.urb)
464 usb_kill_urb(card->rx_cmd.urb); 465 usb_kill_urb(card->rx_cmd.urb);
@@ -766,11 +767,13 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
766 switch (le16_to_cpu(card->udev->descriptor.idProduct)) { 767 switch (le16_to_cpu(card->udev->descriptor.idProduct)) {
767 case USB8897_PID_1: 768 case USB8897_PID_1:
768 case USB8897_PID_2: 769 case USB8897_PID_2:
770 adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K;
769 strcpy(adapter->fw_name, USB8897_DEFAULT_FW_NAME); 771 strcpy(adapter->fw_name, USB8897_DEFAULT_FW_NAME);
770 break; 772 break;
771 case USB8797_PID_1: 773 case USB8797_PID_1:
772 case USB8797_PID_2: 774 case USB8797_PID_2:
773 default: 775 default:
776 adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
774 strcpy(adapter->fw_name, USB8797_DEFAULT_FW_NAME); 777 strcpy(adapter->fw_name, USB8797_DEFAULT_FW_NAME);
775 break; 778 break;
776 } 779 }
@@ -1024,7 +1027,6 @@ static void mwifiex_usb_cleanup_module(void)
1024 1027
1025 if (usb_card && usb_card->adapter) { 1028 if (usb_card && usb_card->adapter) {
1026 struct mwifiex_adapter *adapter = usb_card->adapter; 1029 struct mwifiex_adapter *adapter = usb_card->adapter;
1027 int i;
1028 1030
1029 /* In case driver is removed when asynchronous FW downloading is 1031 /* In case driver is removed when asynchronous FW downloading is
1030 * in progress 1032 * in progress
@@ -1035,11 +1037,8 @@ static void mwifiex_usb_cleanup_module(void)
1035 if (adapter->is_suspended) 1037 if (adapter->is_suspended)
1036 mwifiex_usb_resume(usb_card->intf); 1038 mwifiex_usb_resume(usb_card->intf);
1037#endif 1039#endif
1038 for (i = 0; i < adapter->priv_num; i++) 1040
1039 if ((GET_BSS_ROLE(adapter->priv[i]) == 1041 mwifiex_deauthenticate_all(adapter);
1040 MWIFIEX_BSS_ROLE_STA) &&
1041 adapter->priv[i]->media_connected)
1042 mwifiex_deauthenticate(adapter->priv[i], NULL);
1043 1042
1044 mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter, 1043 mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter,
1045 MWIFIEX_BSS_ROLE_ANY), 1044 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_ */