blob: 94f1dadac2fa067f72ff4d0540a745b48340d8e5 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +053026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Kiet Lama7f454d2014-07-24 12:04:06 -070030
31
Jeff Johnson295189b2012-06-20 16:38:30 -070032/**========================================================================
33
34 \file wlan_hdd_cfg80211.c
35
36 \brief WLAN Host Device Driver implementation
37
Jeff Johnson295189b2012-06-20 16:38:30 -070038 ========================================================================*/
39
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070041
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070042 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070045 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070049 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070053 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070054 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070055
56 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070057 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070058 ==========================================================================*/
59
Jeff Johnson295189b2012-06-20 16:38:30 -070060
61#include <linux/version.h>
62#include <linux/module.h>
63#include <linux/kernel.h>
64#include <linux/init.h>
65#include <linux/wireless.h>
66#include <wlan_hdd_includes.h>
67#include <net/arp.h>
68#include <net/cfg80211.h>
69#include <linux/wireless.h>
70#include <wlan_hdd_wowl.h>
71#include <aniGlobal.h>
72#include "ccmApi.h"
73#include "sirParams.h"
74#include "dot11f.h"
75#include "wlan_hdd_assoc.h"
76#include "wlan_hdd_wext.h"
77#include "sme_Api.h"
78#include "wlan_hdd_p2p.h"
79#include "wlan_hdd_cfg80211.h"
80#include "wlan_hdd_hostapd.h"
81#include "sapInternal.h"
82#include "wlan_hdd_softap_tx_rx.h"
83#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053084#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053085#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053086#include "wlan_hdd_trace.h"
87#include "vos_types.h"
88#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070089#ifdef WLAN_BTAMP_FEATURE
90#include "bap_hdd_misc.h"
91#endif
92#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080093#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053094#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053095#include "wlan_qct_wda.h"
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053096#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070097#include "wlan_hdd_dev_pwr.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +053098#include "qwlan_version.h"
c_manjeecfd1efb2015-09-25 19:32:34 +053099#include "wlan_logging_sock_svc.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +0530100
Jeff Johnson295189b2012-06-20 16:38:30 -0700101
102#define g_mode_rates_size (12)
103#define a_mode_rates_size (8)
104#define FREQ_BASE_80211G (2407)
105#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700106#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530107#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700108#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800109 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700110
111#define HDD2GHZCHAN(freq, chan, flag) { \
112 .band = IEEE80211_BAND_2GHZ, \
113 .center_freq = (freq), \
114 .hw_value = (chan),\
115 .flags = (flag), \
116 .max_antenna_gain = 0 ,\
117 .max_power = 30, \
118}
119
120#define HDD5GHZCHAN(freq, chan, flag) { \
121 .band = IEEE80211_BAND_5GHZ, \
122 .center_freq = (freq), \
123 .hw_value = (chan),\
124 .flags = (flag), \
125 .max_antenna_gain = 0 ,\
126 .max_power = 30, \
127}
128
129#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
130{\
131 .bitrate = rate, \
132 .hw_value = rate_id, \
133 .flags = flag, \
134}
135
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530136#ifdef WLAN_FEATURE_VOWIFI_11R
137#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
138#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
139#endif
140
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530141#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530142#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530143
Sunil Duttc69bccb2014-05-26 21:30:20 +0530144#ifdef WLAN_FEATURE_LINK_LAYER_STATS
145/*
146 * Used to allocate the size of 4096 for the link layer stats.
147 * The size of 4096 is considered assuming that all data per
148 * respective event fit with in the limit.Please take a call
149 * on the limit based on the data requirements on link layer
150 * statistics.
151 */
152#define LL_STATS_EVENT_BUF_SIZE 4096
153#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530154#ifdef WLAN_FEATURE_EXTSCAN
155/*
156 * Used to allocate the size of 4096 for the EXTScan NL data.
157 * The size of 4096 is considered assuming that all data per
158 * respective event fit with in the limit.Please take a call
159 * on the limit based on the data requirements.
160 */
161
162#define EXTSCAN_EVENT_BUF_SIZE 4096
163#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
164#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530165
Atul Mittal115287b2014-07-08 13:26:33 +0530166/*EXT TDLS*/
167/*
168 * Used to allocate the size of 4096 for the TDLS.
169 * The size of 4096 is considered assuming that all data per
170 * respective event fit with in the limit.Please take a call
171 * on the limit based on the data requirements on link layer
172 * statistics.
173 */
174#define EXTTDLS_EVENT_BUF_SIZE 4096
175
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530176/*
177 * Values for Mac spoofing feature
178 *
179 */
180#define MAC_ADDR_SPOOFING_FW_HOST_DISABLE 0
181#define MAC_ADDR_SPOOFING_FW_HOST_ENABLE 1
182#define MAC_ADDR_SPOOFING_FW_ENABLE_HOST_DISABLE 2
183
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530184static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700185{
186 WLAN_CIPHER_SUITE_WEP40,
187 WLAN_CIPHER_SUITE_WEP104,
188 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800189#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700190#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
191 WLAN_CIPHER_SUITE_KRK,
192 WLAN_CIPHER_SUITE_CCMP,
193#else
194 WLAN_CIPHER_SUITE_CCMP,
195#endif
196#ifdef FEATURE_WLAN_WAPI
197 WLAN_CIPHER_SUITE_SMS4,
198#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700199#ifdef WLAN_FEATURE_11W
200 WLAN_CIPHER_SUITE_AES_CMAC,
201#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700202};
203
204static inline int is_broadcast_ether_addr(const u8 *addr)
205{
206 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
207 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
208}
209
210static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530211{
Jeff Johnson295189b2012-06-20 16:38:30 -0700212 HDD2GHZCHAN(2412, 1, 0) ,
213 HDD2GHZCHAN(2417, 2, 0) ,
214 HDD2GHZCHAN(2422, 3, 0) ,
215 HDD2GHZCHAN(2427, 4, 0) ,
216 HDD2GHZCHAN(2432, 5, 0) ,
217 HDD2GHZCHAN(2437, 6, 0) ,
218 HDD2GHZCHAN(2442, 7, 0) ,
219 HDD2GHZCHAN(2447, 8, 0) ,
220 HDD2GHZCHAN(2452, 9, 0) ,
221 HDD2GHZCHAN(2457, 10, 0) ,
222 HDD2GHZCHAN(2462, 11, 0) ,
223 HDD2GHZCHAN(2467, 12, 0) ,
224 HDD2GHZCHAN(2472, 13, 0) ,
225 HDD2GHZCHAN(2484, 14, 0) ,
226};
227
Jeff Johnson295189b2012-06-20 16:38:30 -0700228static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
229{
230 HDD2GHZCHAN(2412, 1, 0) ,
231 HDD2GHZCHAN(2437, 6, 0) ,
232 HDD2GHZCHAN(2462, 11, 0) ,
233};
Jeff Johnson295189b2012-06-20 16:38:30 -0700234
235static struct ieee80211_channel hdd_channels_5_GHZ[] =
236{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700237 HDD5GHZCHAN(4920, 240, 0) ,
238 HDD5GHZCHAN(4940, 244, 0) ,
239 HDD5GHZCHAN(4960, 248, 0) ,
240 HDD5GHZCHAN(4980, 252, 0) ,
241 HDD5GHZCHAN(5040, 208, 0) ,
242 HDD5GHZCHAN(5060, 212, 0) ,
243 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700244 HDD5GHZCHAN(5180, 36, 0) ,
245 HDD5GHZCHAN(5200, 40, 0) ,
246 HDD5GHZCHAN(5220, 44, 0) ,
247 HDD5GHZCHAN(5240, 48, 0) ,
248 HDD5GHZCHAN(5260, 52, 0) ,
249 HDD5GHZCHAN(5280, 56, 0) ,
250 HDD5GHZCHAN(5300, 60, 0) ,
251 HDD5GHZCHAN(5320, 64, 0) ,
252 HDD5GHZCHAN(5500,100, 0) ,
253 HDD5GHZCHAN(5520,104, 0) ,
254 HDD5GHZCHAN(5540,108, 0) ,
255 HDD5GHZCHAN(5560,112, 0) ,
256 HDD5GHZCHAN(5580,116, 0) ,
257 HDD5GHZCHAN(5600,120, 0) ,
258 HDD5GHZCHAN(5620,124, 0) ,
259 HDD5GHZCHAN(5640,128, 0) ,
260 HDD5GHZCHAN(5660,132, 0) ,
261 HDD5GHZCHAN(5680,136, 0) ,
262 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800263#ifdef FEATURE_WLAN_CH144
264 HDD5GHZCHAN(5720,144, 0) ,
265#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700266 HDD5GHZCHAN(5745,149, 0) ,
267 HDD5GHZCHAN(5765,153, 0) ,
268 HDD5GHZCHAN(5785,157, 0) ,
269 HDD5GHZCHAN(5805,161, 0) ,
270 HDD5GHZCHAN(5825,165, 0) ,
271};
272
273static struct ieee80211_rate g_mode_rates[] =
274{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530275 HDD_G_MODE_RATETAB(10, 0x1, 0),
276 HDD_G_MODE_RATETAB(20, 0x2, 0),
277 HDD_G_MODE_RATETAB(55, 0x4, 0),
278 HDD_G_MODE_RATETAB(110, 0x8, 0),
279 HDD_G_MODE_RATETAB(60, 0x10, 0),
280 HDD_G_MODE_RATETAB(90, 0x20, 0),
281 HDD_G_MODE_RATETAB(120, 0x40, 0),
282 HDD_G_MODE_RATETAB(180, 0x80, 0),
283 HDD_G_MODE_RATETAB(240, 0x100, 0),
284 HDD_G_MODE_RATETAB(360, 0x200, 0),
285 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700286 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530287};
Jeff Johnson295189b2012-06-20 16:38:30 -0700288
289static struct ieee80211_rate a_mode_rates[] =
290{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530291 HDD_G_MODE_RATETAB(60, 0x10, 0),
292 HDD_G_MODE_RATETAB(90, 0x20, 0),
293 HDD_G_MODE_RATETAB(120, 0x40, 0),
294 HDD_G_MODE_RATETAB(180, 0x80, 0),
295 HDD_G_MODE_RATETAB(240, 0x100, 0),
296 HDD_G_MODE_RATETAB(360, 0x200, 0),
297 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700298 HDD_G_MODE_RATETAB(540, 0x800, 0),
299};
300
301static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
302{
303 .channels = hdd_channels_2_4_GHZ,
304 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
305 .band = IEEE80211_BAND_2GHZ,
306 .bitrates = g_mode_rates,
307 .n_bitrates = g_mode_rates_size,
308 .ht_cap.ht_supported = 1,
309 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
310 | IEEE80211_HT_CAP_GRN_FLD
311 | IEEE80211_HT_CAP_DSSSCCK40
312 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
313 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
314 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
315 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
316 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
317 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
318};
319
Jeff Johnson295189b2012-06-20 16:38:30 -0700320static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
321{
322 .channels = hdd_social_channels_2_4_GHZ,
323 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
324 .band = IEEE80211_BAND_2GHZ,
325 .bitrates = g_mode_rates,
326 .n_bitrates = g_mode_rates_size,
327 .ht_cap.ht_supported = 1,
328 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
329 | IEEE80211_HT_CAP_GRN_FLD
330 | IEEE80211_HT_CAP_DSSSCCK40
331 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
332 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
333 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
334 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
335 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
336 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
337};
Jeff Johnson295189b2012-06-20 16:38:30 -0700338
339static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
340{
341 .channels = hdd_channels_5_GHZ,
342 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
343 .band = IEEE80211_BAND_5GHZ,
344 .bitrates = a_mode_rates,
345 .n_bitrates = a_mode_rates_size,
346 .ht_cap.ht_supported = 1,
347 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
348 | IEEE80211_HT_CAP_GRN_FLD
349 | IEEE80211_HT_CAP_DSSSCCK40
350 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
351 | IEEE80211_HT_CAP_SGI_40
352 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
353 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
354 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
355 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
356 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
357 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
358};
359
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530360/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700361 TX/RX direction for each kind of interface */
362static const struct ieee80211_txrx_stypes
363wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
364 [NL80211_IFTYPE_STATION] = {
365 .tx = 0xffff,
366 .rx = BIT(SIR_MAC_MGMT_ACTION) |
367 BIT(SIR_MAC_MGMT_PROBE_REQ),
368 },
369 [NL80211_IFTYPE_AP] = {
370 .tx = 0xffff,
371 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
372 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
373 BIT(SIR_MAC_MGMT_PROBE_REQ) |
374 BIT(SIR_MAC_MGMT_DISASSOC) |
375 BIT(SIR_MAC_MGMT_AUTH) |
376 BIT(SIR_MAC_MGMT_DEAUTH) |
377 BIT(SIR_MAC_MGMT_ACTION),
378 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700379 [NL80211_IFTYPE_ADHOC] = {
380 .tx = 0xffff,
381 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
382 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
383 BIT(SIR_MAC_MGMT_PROBE_REQ) |
384 BIT(SIR_MAC_MGMT_DISASSOC) |
385 BIT(SIR_MAC_MGMT_AUTH) |
386 BIT(SIR_MAC_MGMT_DEAUTH) |
387 BIT(SIR_MAC_MGMT_ACTION),
388 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700389 [NL80211_IFTYPE_P2P_CLIENT] = {
390 .tx = 0xffff,
391 .rx = BIT(SIR_MAC_MGMT_ACTION) |
392 BIT(SIR_MAC_MGMT_PROBE_REQ),
393 },
394 [NL80211_IFTYPE_P2P_GO] = {
395 /* This is also same as for SoftAP */
396 .tx = 0xffff,
397 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
398 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
399 BIT(SIR_MAC_MGMT_PROBE_REQ) |
400 BIT(SIR_MAC_MGMT_DISASSOC) |
401 BIT(SIR_MAC_MGMT_AUTH) |
402 BIT(SIR_MAC_MGMT_DEAUTH) |
403 BIT(SIR_MAC_MGMT_ACTION),
404 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700405};
406
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800407#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800408static const struct ieee80211_iface_limit
409wlan_hdd_iface_limit[] = {
410 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800411 /* max = 3 ; Our driver create two interfaces during driver init
412 * wlan0 and p2p0 interfaces. p2p0 is considered as station
413 * interface until a group is formed. In JB architecture, once the
414 * group is formed, interface type of p2p0 is changed to P2P GO or
415 * Client.
416 * When supplicant remove the group, it first issue a set interface
417 * cmd to change the mode back to Station. In JB this works fine as
418 * we advertize two station type interface during driver init.
419 * Some vendors create separate interface for P2P GO/Client,
420 * after group formation(Third one). But while group remove
421 * supplicant first tries to change the mode(3rd interface) to STATION
422 * But as we advertized only two sta type interfaces nl80211 was
423 * returning error for the third one which was leading to failure in
424 * delete interface. Ideally while removing the group, supplicant
425 * should not try to change the 3rd interface mode to Station type.
426 * Till we get a fix in wpa_supplicant, we advertize max STA
427 * interface type to 3
428 */
429 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800430 .types = BIT(NL80211_IFTYPE_STATION),
431 },
432 {
433 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700434 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800435 },
436 {
437 .max = 1,
438 .types = BIT(NL80211_IFTYPE_P2P_GO) |
439 BIT(NL80211_IFTYPE_P2P_CLIENT),
440 },
441};
442
443/* By default, only single channel concurrency is allowed */
444static struct ieee80211_iface_combination
445wlan_hdd_iface_combination = {
446 .limits = wlan_hdd_iface_limit,
447 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800448 /*
449 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
450 * and p2p0 interfaces during driver init
451 * Some vendors create separate interface for P2P operations.
452 * wlan0: STA interface
453 * p2p0: P2P Device interface, action frames goes
454 * through this interface.
455 * p2p-xx: P2P interface, After GO negotiation this interface is
456 * created for p2p operations(GO/CLIENT interface).
457 */
458 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800459 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
460 .beacon_int_infra_match = false,
461};
462#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800463
Jeff Johnson295189b2012-06-20 16:38:30 -0700464static struct cfg80211_ops wlan_hdd_cfg80211_ops;
465
466/* Data rate 100KBPS based on IE Index */
467struct index_data_rate_type
468{
469 v_U8_t beacon_rate_index;
470 v_U16_t supported_rate[4];
471};
472
473/* 11B, 11G Rate table include Basic rate and Extended rate
474 The IDX field is the rate index
475 The HI field is the rate when RSSI is strong or being ignored
476 (in this case we report actual rate)
477 The MID field is the rate when RSSI is moderate
478 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
479 The LO field is the rate when RSSI is low
480 (in this case we don't report rates, actual current rate used)
481 */
482static const struct
483{
484 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700485 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700486} supported_data_rate[] =
487{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700488/* IDX HI HM LM LO (RSSI-based index */
489 {2, { 10, 10, 10, 0}},
490 {4, { 20, 20, 10, 0}},
491 {11, { 55, 20, 10, 0}},
492 {12, { 60, 55, 20, 0}},
493 {18, { 90, 55, 20, 0}},
494 {22, {110, 55, 20, 0}},
495 {24, {120, 90, 60, 0}},
496 {36, {180, 120, 60, 0}},
497 {44, {220, 180, 60, 0}},
498 {48, {240, 180, 90, 0}},
499 {66, {330, 180, 90, 0}},
500 {72, {360, 240, 90, 0}},
501 {96, {480, 240, 120, 0}},
502 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700503};
504
505/* MCS Based rate table */
506static struct index_data_rate_type supported_mcs_rate[] =
507{
508/* MCS L20 L40 S20 S40 */
509 {0, {65, 135, 72, 150}},
510 {1, {130, 270, 144, 300}},
511 {2, {195, 405, 217, 450}},
512 {3, {260, 540, 289, 600}},
513 {4, {390, 810, 433, 900}},
514 {5, {520, 1080, 578, 1200}},
515 {6, {585, 1215, 650, 1350}},
516 {7, {650, 1350, 722, 1500}}
517};
518
Leo Chang6f8870f2013-03-26 18:11:36 -0700519#ifdef WLAN_FEATURE_11AC
520
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530521#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700522
523struct index_vht_data_rate_type
524{
525 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530526 v_U16_t supported_VHT80_rate[2];
527 v_U16_t supported_VHT40_rate[2];
528 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700529};
530
531typedef enum
532{
533 DATA_RATE_11AC_MAX_MCS_7,
534 DATA_RATE_11AC_MAX_MCS_8,
535 DATA_RATE_11AC_MAX_MCS_9,
536 DATA_RATE_11AC_MAX_MCS_NA
537} eDataRate11ACMaxMcs;
538
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530539/* SSID broadcast type */
540typedef enum eSSIDBcastType
541{
542 eBCAST_UNKNOWN = 0,
543 eBCAST_NORMAL = 1,
544 eBCAST_HIDDEN = 2,
545} tSSIDBcastType;
546
Leo Chang6f8870f2013-03-26 18:11:36 -0700547/* MCS Based VHT rate table */
548static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
549{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530550/* MCS L80 S80 L40 S40 L20 S40*/
551 {0, {293, 325}, {135, 150}, {65, 72}},
552 {1, {585, 650}, {270, 300}, {130, 144}},
553 {2, {878, 975}, {405, 450}, {195, 217}},
554 {3, {1170, 1300}, {540, 600}, {260, 289}},
555 {4, {1755, 1950}, {810, 900}, {390, 433}},
556 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
557 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
558 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
559 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
560 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700561};
562#endif /* WLAN_FEATURE_11AC */
563
c_hpothu79aab322014-07-14 21:11:01 +0530564/*array index points to MCS and array value points respective rssi*/
565static int rssiMcsTbl[][10] =
566{
567/*MCS 0 1 2 3 4 5 6 7 8 9*/
568 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
569 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
570 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
571};
572
Jeff Johnson295189b2012-06-20 16:38:30 -0700573extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530574#ifdef FEATURE_WLAN_SCAN_PNO
575static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
576#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700577
Leo Chang9056f462013-08-01 19:21:11 -0700578#ifdef WLAN_NL80211_TESTMODE
579enum wlan_hdd_tm_attr
580{
581 WLAN_HDD_TM_ATTR_INVALID = 0,
582 WLAN_HDD_TM_ATTR_CMD = 1,
583 WLAN_HDD_TM_ATTR_DATA = 2,
584 WLAN_HDD_TM_ATTR_TYPE = 3,
585 /* keep last */
586 WLAN_HDD_TM_ATTR_AFTER_LAST,
587 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
588};
589
590enum wlan_hdd_tm_cmd
591{
592 WLAN_HDD_TM_CMD_WLAN_HB = 1,
593};
594
595#define WLAN_HDD_TM_DATA_MAX_LEN 5000
596
597static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
598{
599 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
600 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
601 .len = WLAN_HDD_TM_DATA_MAX_LEN },
602};
603#endif /* WLAN_NL80211_TESTMODE */
604
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800605#ifdef FEATURE_WLAN_CH_AVOID
606/*
607 * FUNCTION: wlan_hdd_send_avoid_freq_event
608 * This is called when wlan driver needs to send vendor specific
609 * avoid frequency range event to userspace
610 */
611int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
612 tHddAvoidFreqList *pAvoidFreqList)
613{
614 struct sk_buff *vendor_event;
615
616 ENTER();
617
618 if (!pHddCtx)
619 {
620 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
621 "%s: HDD context is null", __func__);
622 return -1;
623 }
624
625 if (!pAvoidFreqList)
626 {
627 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
628 "%s: pAvoidFreqList is null", __func__);
629 return -1;
630 }
631
632 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530633#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
634 NULL,
635#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800636 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530637 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800638 GFP_KERNEL);
639 if (!vendor_event)
640 {
641 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
642 "%s: cfg80211_vendor_event_alloc failed", __func__);
643 return -1;
644 }
645
646 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
647 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
648
649 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
650
651 EXIT();
652 return 0;
653}
654#endif /* FEATURE_WLAN_CH_AVOID */
655
Srinivas Dasari030bad32015-02-18 23:23:54 +0530656/*
657 * FUNCTION: __wlan_hdd_cfg80211_nan_request
658 * This is called when wlan driver needs to send vendor specific
659 * nan request event.
660 */
661static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
662 struct wireless_dev *wdev,
663 const void *data, int data_len)
664{
665 tNanRequestReq nan_req;
666 VOS_STATUS status;
667 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530668 struct net_device *dev = wdev->netdev;
669 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
670 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530671 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
672
673 if (0 == data_len)
674 {
675 hddLog(VOS_TRACE_LEVEL_ERROR,
676 FL("NAN - Invalid Request, length = 0"));
677 return ret_val;
678 }
679
680 if (NULL == data)
681 {
682 hddLog(VOS_TRACE_LEVEL_ERROR,
683 FL("NAN - Invalid Request, data is NULL"));
684 return ret_val;
685 }
686
687 status = wlan_hdd_validate_context(pHddCtx);
688 if (0 != status)
689 {
690 hddLog(VOS_TRACE_LEVEL_ERROR,
691 FL("HDD context is not valid"));
692 return -EINVAL;
693 }
694
695 hddLog(LOG1, FL("Received NAN command"));
696 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
697 (tANI_U8 *)data, data_len);
698
699 /* check the NAN Capability */
700 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
701 {
702 hddLog(VOS_TRACE_LEVEL_ERROR,
703 FL("NAN is not supported by Firmware"));
704 return -EINVAL;
705 }
706
707 nan_req.request_data_len = data_len;
708 nan_req.request_data = data;
709
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530710 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530711 if (VOS_STATUS_SUCCESS == status)
712 {
713 ret_val = 0;
714 }
715 return ret_val;
716}
717
718/*
719 * FUNCTION: wlan_hdd_cfg80211_nan_request
720 * Wrapper to protect the nan vendor command from ssr
721 */
722static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
723 struct wireless_dev *wdev,
724 const void *data, int data_len)
725{
726 int ret;
727
728 vos_ssr_protect(__func__);
729 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
730 vos_ssr_unprotect(__func__);
731
732 return ret;
733}
734
735/*
736 * FUNCTION: wlan_hdd_cfg80211_nan_callback
737 * This is a callback function and it gets called
738 * when we need to report nan response event to
739 * upper layers.
740 */
741static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
742{
743 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
744 struct sk_buff *vendor_event;
745 int status;
746 tSirNanEvent *data;
747
748 ENTER();
749 if (NULL == msg)
750 {
751 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
752 FL(" msg received here is null"));
753 return;
754 }
755 data = msg;
756
757 status = wlan_hdd_validate_context(pHddCtx);
758
759 if (0 != status)
760 {
761 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
762 FL("HDD context is not valid"));
763 return;
764 }
765
766 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530767#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
768 NULL,
769#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530770 data->event_data_len +
771 NLMSG_HDRLEN,
772 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
773 GFP_KERNEL);
774
775 if (!vendor_event)
776 {
777 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
778 FL("cfg80211_vendor_event_alloc failed"));
779 return;
780 }
781 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
782 data->event_data_len, data->event_data))
783 {
784 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
785 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
786 kfree_skb(vendor_event);
787 return;
788 }
789 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
790 EXIT();
791}
792
793/*
794 * FUNCTION: wlan_hdd_cfg80211_nan_init
795 * This function is called to register the callback to sme layer
796 */
797inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
798{
799 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
800}
801
802
Sunil Duttc69bccb2014-05-26 21:30:20 +0530803#ifdef WLAN_FEATURE_LINK_LAYER_STATS
804
805static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
806 struct sk_buff *vendor_event)
807{
808 if (nla_put_u8(vendor_event,
809 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
810 stats->rate.preamble) ||
811 nla_put_u8(vendor_event,
812 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
813 stats->rate.nss) ||
814 nla_put_u8(vendor_event,
815 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
816 stats->rate.bw) ||
817 nla_put_u8(vendor_event,
818 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
819 stats->rate.rateMcsIdx) ||
820 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
821 stats->rate.bitrate ) ||
822 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
823 stats->txMpdu ) ||
824 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
825 stats->rxMpdu ) ||
826 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
827 stats->mpduLost ) ||
828 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
829 stats->retries) ||
830 nla_put_u32(vendor_event,
831 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
832 stats->retriesShort ) ||
833 nla_put_u32(vendor_event,
834 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
835 stats->retriesLong))
836 {
837 hddLog(VOS_TRACE_LEVEL_ERROR,
838 FL("QCA_WLAN_VENDOR_ATTR put fail"));
839 return FALSE;
840 }
841 return TRUE;
842}
843
844static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
845 struct sk_buff *vendor_event)
846{
847 u32 i = 0;
848 struct nlattr *rateInfo;
849 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
850 stats->type) ||
851 nla_put(vendor_event,
852 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
853 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
854 nla_put_u32(vendor_event,
855 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
856 stats->capabilities) ||
857 nla_put_u32(vendor_event,
858 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
859 stats->numRate))
860 {
861 hddLog(VOS_TRACE_LEVEL_ERROR,
862 FL("QCA_WLAN_VENDOR_ATTR put fail"));
863 goto error;
864 }
865
866 rateInfo = nla_nest_start(vendor_event,
867 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530868 if(!rateInfo)
869 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530870 for (i = 0; i < stats->numRate; i++)
871 {
872 struct nlattr *rates;
873 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
874 stats->rateStats +
875 (i * sizeof(tSirWifiRateStat)));
876 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530877 if(!rates)
878 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530879
880 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
881 {
882 hddLog(VOS_TRACE_LEVEL_ERROR,
883 FL("QCA_WLAN_VENDOR_ATTR put fail"));
884 return FALSE;
885 }
886 nla_nest_end(vendor_event, rates);
887 }
888 nla_nest_end(vendor_event, rateInfo);
889
890 return TRUE;
891error:
892 return FALSE;
893}
894
895static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
896 struct sk_buff *vendor_event)
897{
898 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
899 stats->ac ) ||
900 nla_put_u32(vendor_event,
901 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
902 stats->txMpdu ) ||
903 nla_put_u32(vendor_event,
904 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
905 stats->rxMpdu ) ||
906 nla_put_u32(vendor_event,
907 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
908 stats->txMcast ) ||
909 nla_put_u32(vendor_event,
910 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
911 stats->rxMcast ) ||
912 nla_put_u32(vendor_event,
913 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
914 stats->rxAmpdu ) ||
915 nla_put_u32(vendor_event,
916 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
917 stats->txAmpdu ) ||
918 nla_put_u32(vendor_event,
919 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
920 stats->mpduLost )||
921 nla_put_u32(vendor_event,
922 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
923 stats->retries ) ||
924 nla_put_u32(vendor_event,
925 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
926 stats->retriesShort ) ||
927 nla_put_u32(vendor_event,
928 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
929 stats->retriesLong ) ||
930 nla_put_u32(vendor_event,
931 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
932 stats->contentionTimeMin ) ||
933 nla_put_u32(vendor_event,
934 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
935 stats->contentionTimeMax ) ||
936 nla_put_u32(vendor_event,
937 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
938 stats->contentionTimeAvg ) ||
939 nla_put_u32(vendor_event,
940 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
941 stats->contentionNumSamples ))
942 {
943 hddLog(VOS_TRACE_LEVEL_ERROR,
944 FL("QCA_WLAN_VENDOR_ATTR put fail") );
945 return FALSE;
946 }
947 return TRUE;
948}
949
950static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
951 struct sk_buff *vendor_event)
952{
Dino Myclec8f3f332014-07-21 16:48:27 +0530953 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530954 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
955 nla_put(vendor_event,
956 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
957 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
958 nla_put_u32(vendor_event,
959 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
960 stats->state ) ||
961 nla_put_u32(vendor_event,
962 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
963 stats->roaming ) ||
964 nla_put_u32(vendor_event,
965 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
966 stats->capabilities ) ||
967 nla_put(vendor_event,
968 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
969 strlen(stats->ssid), stats->ssid) ||
970 nla_put(vendor_event,
971 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
972 WNI_CFG_BSSID_LEN, stats->bssid) ||
973 nla_put(vendor_event,
974 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
975 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
976 nla_put(vendor_event,
977 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
978 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
979 )
980 {
981 hddLog(VOS_TRACE_LEVEL_ERROR,
982 FL("QCA_WLAN_VENDOR_ATTR put fail") );
983 return FALSE;
984 }
985 return TRUE;
986}
987
Dino Mycle3b9536d2014-07-09 22:05:24 +0530988static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
989 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530990 struct sk_buff *vendor_event)
991{
992 int i = 0;
993 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530994 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
995 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530996 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530997
Sunil Duttc69bccb2014-05-26 21:30:20 +0530998 if (FALSE == put_wifi_interface_info(
999 &pWifiIfaceStat->info,
1000 vendor_event))
1001 {
1002 hddLog(VOS_TRACE_LEVEL_ERROR,
1003 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1004 return FALSE;
1005
1006 }
Dino Mycle3b9536d2014-07-09 22:05:24 +05301007 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
1008 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
1009 if (NULL == pWifiIfaceStatTL)
1010 {
1011 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
1012 return FALSE;
1013 }
1014
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05301015 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
1016 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
1017 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
1018 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
1019
1020 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
1021 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
1022 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
1023 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301024
1025 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1026 {
1027 if (VOS_STATUS_SUCCESS ==
1028 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1029 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1030 {
1031 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1032 * obtained from TL structure
1033 */
1034
1035 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1036 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301037 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1038
Srinivas Dasari98947432014-11-07 19:41:24 +05301039 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1040 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1041 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1042 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1043 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1044 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1045 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1046 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301047
Srinivas Dasari98947432014-11-07 19:41:24 +05301048 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1049 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1050 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1051 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1052 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1053 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1054 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1055 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301056
Srinivas Dasari98947432014-11-07 19:41:24 +05301057 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1058 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1059 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1060 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1061 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1062 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1063 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1064 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301065 }
1066 else
1067 {
1068 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
1069 }
1070
Dino Mycle3b9536d2014-07-09 22:05:24 +05301071 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
1072 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
1073 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
1074 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
1075 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
1076 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
1077 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
1078 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
1079 }
1080 else
1081 {
1082 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
1083 }
1084
1085
Sunil Duttc69bccb2014-05-26 21:30:20 +05301086
1087 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301088 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1089 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
1090 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301091 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
1092 pWifiIfaceStat->beaconRx) ||
1093 nla_put_u32(vendor_event,
1094 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
1095 pWifiIfaceStat->mgmtRx) ||
1096 nla_put_u32(vendor_event,
1097 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
1098 pWifiIfaceStat->mgmtActionRx) ||
1099 nla_put_u32(vendor_event,
1100 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
1101 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301102 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301103 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
1104 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301105 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301106 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
1107 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301108 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301109 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
1110 pWifiIfaceStat->rssiAck))
1111 {
1112 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301113 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1114 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301115 return FALSE;
1116 }
1117
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301118#ifdef FEATURE_EXT_LL_STAT
1119 /*
1120 * Ensure when EXT_LL_STAT is supported by both host and fwr,
1121 * then host should send Leaky AP stats to upper layer,
1122 * otherwise no need to send these stats.
1123 */
1124 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
1125 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
1126 )
1127 {
1128 hddLog(VOS_TRACE_LEVEL_INFO,
1129 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
1130 pWifiIfaceStat->leakyApStat.is_leaky_ap,
1131 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
1132 pWifiIfaceStat->leakyApStat.rx_leak_window,
1133 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
1134 if (nla_put_u32(vendor_event,
1135 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
1136 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
1137 nla_put_u32(vendor_event,
1138 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
1139 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
1140 nla_put_u32(vendor_event,
1141 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
1142 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
1143 nla_put_u64(vendor_event,
1144 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
1145 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
1146 {
1147 hddLog(VOS_TRACE_LEVEL_ERROR,
1148 FL("EXT_LL_STAT put fail"));
1149 vos_mem_free(pWifiIfaceStatTL);
1150 return FALSE;
1151 }
1152 }
1153#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05301154 wmmInfo = nla_nest_start(vendor_event,
1155 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301156 if(!wmmInfo)
1157 {
1158 vos_mem_free(pWifiIfaceStatTL);
1159 return FALSE;
1160 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301161 for (i = 0; i < WIFI_AC_MAX; i++)
1162 {
1163 struct nlattr *wmmStats;
1164 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301165 if(!wmmStats)
1166 {
1167 vos_mem_free(pWifiIfaceStatTL);
1168 return FALSE;
1169 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301170 if (FALSE == put_wifi_wmm_ac_stat(
1171 &pWifiIfaceStat->AccessclassStats[i],
1172 vendor_event))
1173 {
1174 hddLog(VOS_TRACE_LEVEL_ERROR,
1175 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301176 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301177 return FALSE;
1178 }
1179
1180 nla_nest_end(vendor_event, wmmStats);
1181 }
1182 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301183 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301184 return TRUE;
1185}
1186
1187static tSirWifiInterfaceMode
1188 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1189{
1190 switch (deviceMode)
1191 {
1192 case WLAN_HDD_INFRA_STATION:
1193 return WIFI_INTERFACE_STA;
1194 case WLAN_HDD_SOFTAP:
1195 return WIFI_INTERFACE_SOFTAP;
1196 case WLAN_HDD_P2P_CLIENT:
1197 return WIFI_INTERFACE_P2P_CLIENT;
1198 case WLAN_HDD_P2P_GO:
1199 return WIFI_INTERFACE_P2P_GO;
1200 case WLAN_HDD_IBSS:
1201 return WIFI_INTERFACE_IBSS;
1202 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301203 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301204 }
1205}
1206
1207static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1208 tpSirWifiInterfaceInfo pInfo)
1209{
1210 v_U8_t *staMac = NULL;
1211 hdd_station_ctx_t *pHddStaCtx;
1212 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1213 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1214
1215 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1216
1217 vos_mem_copy(pInfo->macAddr,
1218 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1219
1220 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1221 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1222 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1223 {
1224 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1225 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1226 {
1227 pInfo->state = WIFI_DISCONNECTED;
1228 }
1229 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1230 {
1231 hddLog(VOS_TRACE_LEVEL_ERROR,
1232 "%s: Session ID %d, Connection is in progress", __func__,
1233 pAdapter->sessionId);
1234 pInfo->state = WIFI_ASSOCIATING;
1235 }
1236 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1237 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1238 {
1239 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1240 hddLog(VOS_TRACE_LEVEL_ERROR,
1241 "%s: client " MAC_ADDRESS_STR
1242 " is in the middle of WPS/EAPOL exchange.", __func__,
1243 MAC_ADDR_ARRAY(staMac));
1244 pInfo->state = WIFI_AUTHENTICATING;
1245 }
1246 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1247 {
1248 pInfo->state = WIFI_ASSOCIATED;
1249 vos_mem_copy(pInfo->bssid,
1250 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1251 vos_mem_copy(pInfo->ssid,
1252 pHddStaCtx->conn_info.SSID.SSID.ssId,
1253 pHddStaCtx->conn_info.SSID.SSID.length);
1254 //NULL Terminate the string.
1255 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1256 }
1257 }
1258 vos_mem_copy(pInfo->countryStr,
1259 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1260
1261 vos_mem_copy(pInfo->apCountryStr,
1262 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1263
1264 return TRUE;
1265}
1266
1267/*
1268 * hdd_link_layer_process_peer_stats () - This function is called after
1269 * receiving Link Layer Peer statistics from FW.This function converts
1270 * the firmware data to the NL data and sends the same to the kernel/upper
1271 * layers.
1272 */
1273static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1274 v_VOID_t *pData)
1275{
1276 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301277 tpSirWifiPeerStat pWifiPeerStat;
1278 tpSirWifiPeerInfo pWifiPeerInfo;
1279 struct nlattr *peerInfo;
1280 struct sk_buff *vendor_event;
1281 int status, i;
1282
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301283 ENTER();
1284
Sunil Duttc69bccb2014-05-26 21:30:20 +05301285 status = wlan_hdd_validate_context(pHddCtx);
1286 if (0 != status)
1287 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301288 return;
1289 }
1290
1291 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1292
1293 hddLog(VOS_TRACE_LEVEL_INFO,
1294 "LL_STATS_PEER_ALL : numPeers %u",
1295 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301296 /*
1297 * Allocate a size of 4096 for the peer stats comprising
1298 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1299 * sizeof (tSirWifiRateStat).Each field is put with an
1300 * NL attribute.The size of 4096 is considered assuming
1301 * that number of rates shall not exceed beyond 50 with
1302 * the sizeof (tSirWifiRateStat) being 32.
1303 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301304 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1305 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301306 if (!vendor_event)
1307 {
1308 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301309 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301310 __func__);
1311 return;
1312 }
1313 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301314 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1315 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
1316 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301317 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1318 pWifiPeerStat->numPeers))
1319 {
1320 hddLog(VOS_TRACE_LEVEL_ERROR,
1321 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1322 kfree_skb(vendor_event);
1323 return;
1324 }
1325
1326 peerInfo = nla_nest_start(vendor_event,
1327 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301328 if(!peerInfo)
1329 {
1330 hddLog(VOS_TRACE_LEVEL_ERROR,
1331 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1332 __func__);
1333 kfree_skb(vendor_event);
1334 return;
1335 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301336
1337 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1338 pWifiPeerStat->peerInfo);
1339
1340 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1341 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301342 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301343 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301344
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301345 if(!peers)
1346 {
1347 hddLog(VOS_TRACE_LEVEL_ERROR,
1348 "%s: peer stats put fail",
1349 __func__);
1350 kfree_skb(vendor_event);
1351 return;
1352 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301353 if (FALSE == put_wifi_peer_info(
1354 pWifiPeerInfo, vendor_event))
1355 {
1356 hddLog(VOS_TRACE_LEVEL_ERROR,
1357 "%s: put_wifi_peer_info put fail", __func__);
1358 kfree_skb(vendor_event);
1359 return;
1360 }
1361
1362 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1363 pWifiPeerStat->peerInfo +
1364 (i * sizeof(tSirWifiPeerInfo)) +
1365 (numRate * sizeof (tSirWifiRateStat)));
1366 nla_nest_end(vendor_event, peers);
1367 }
1368 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301369 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301370 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301371}
1372
1373/*
1374 * hdd_link_layer_process_iface_stats () - This function is called after
1375 * receiving Link Layer Interface statistics from FW.This function converts
1376 * the firmware data to the NL data and sends the same to the kernel/upper
1377 * layers.
1378 */
1379static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1380 v_VOID_t *pData)
1381{
1382 tpSirWifiIfaceStat pWifiIfaceStat;
1383 struct sk_buff *vendor_event;
1384 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1385 int status;
1386
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301387 ENTER();
1388
Sunil Duttc69bccb2014-05-26 21:30:20 +05301389 status = wlan_hdd_validate_context(pHddCtx);
1390 if (0 != status)
1391 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301392 return;
1393 }
1394 /*
1395 * Allocate a size of 4096 for the interface stats comprising
1396 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1397 * assuming that all these fit with in the limit.Please take
1398 * a call on the limit based on the data requirements on
1399 * interface statistics.
1400 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301401 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1402 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301403 if (!vendor_event)
1404 {
1405 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301406 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301407 return;
1408 }
1409
1410 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1411
Dino Mycle3b9536d2014-07-09 22:05:24 +05301412
1413 if (FALSE == hdd_get_interface_info( pAdapter,
1414 &pWifiIfaceStat->info))
1415 {
1416 hddLog(VOS_TRACE_LEVEL_ERROR,
1417 FL("hdd_get_interface_info get fail") );
1418 kfree_skb(vendor_event);
1419 return;
1420 }
1421
1422 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1423 vendor_event))
1424 {
1425 hddLog(VOS_TRACE_LEVEL_ERROR,
1426 FL("put_wifi_iface_stats fail") );
1427 kfree_skb(vendor_event);
1428 return;
1429 }
1430
Sunil Duttc69bccb2014-05-26 21:30:20 +05301431 hddLog(VOS_TRACE_LEVEL_INFO,
1432 "WMI_LINK_STATS_IFACE Data");
1433
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301434 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301435
1436 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301437}
1438
1439/*
1440 * hdd_link_layer_process_radio_stats () - This function is called after
1441 * receiving Link Layer Radio statistics from FW.This function converts
1442 * the firmware data to the NL data and sends the same to the kernel/upper
1443 * layers.
1444 */
1445static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1446 v_VOID_t *pData)
1447{
1448 int status, i;
1449 tpSirWifiRadioStat pWifiRadioStat;
1450 tpSirWifiChannelStats pWifiChannelStats;
1451 struct sk_buff *vendor_event;
1452 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1453 struct nlattr *chList;
1454
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301455 ENTER();
1456
Sunil Duttc69bccb2014-05-26 21:30:20 +05301457 status = wlan_hdd_validate_context(pHddCtx);
1458 if (0 != status)
1459 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301460 return;
1461 }
1462 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1463
1464 hddLog(VOS_TRACE_LEVEL_INFO,
1465 "LL_STATS_RADIO"
1466 " radio is %d onTime is %u "
1467 " txTime is %u rxTime is %u "
1468 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301469 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301470 " onTimePnoScan is %u onTimeHs20 is %u "
1471 " numChannels is %u",
1472 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1473 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1474 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301475 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301476 pWifiRadioStat->onTimeRoamScan,
1477 pWifiRadioStat->onTimePnoScan,
1478 pWifiRadioStat->onTimeHs20,
1479 pWifiRadioStat->numChannels);
1480 /*
1481 * Allocate a size of 4096 for the Radio stats comprising
1482 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1483 * (tSirWifiChannelStats).Each channel data is put with an
1484 * NL attribute.The size of 4096 is considered assuming that
1485 * number of channels shall not exceed beyond 60 with the
1486 * sizeof (tSirWifiChannelStats) being 24 bytes.
1487 */
1488
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301489 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1490 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301491 if (!vendor_event)
1492 {
1493 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301494 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301495 return;
1496 }
1497
1498 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301499 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1500 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
1501 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301502 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1503 pWifiRadioStat->radio) ||
1504 nla_put_u32(vendor_event,
1505 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1506 pWifiRadioStat->onTime) ||
1507 nla_put_u32(vendor_event,
1508 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1509 pWifiRadioStat->txTime) ||
1510 nla_put_u32(vendor_event,
1511 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1512 pWifiRadioStat->rxTime) ||
1513 nla_put_u32(vendor_event,
1514 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1515 pWifiRadioStat->onTimeScan) ||
1516 nla_put_u32(vendor_event,
1517 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1518 pWifiRadioStat->onTimeNbd) ||
1519 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301520 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1521 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301522 nla_put_u32(vendor_event,
1523 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1524 pWifiRadioStat->onTimeRoamScan) ||
1525 nla_put_u32(vendor_event,
1526 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1527 pWifiRadioStat->onTimePnoScan) ||
1528 nla_put_u32(vendor_event,
1529 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1530 pWifiRadioStat->onTimeHs20) ||
1531 nla_put_u32(vendor_event,
1532 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1533 pWifiRadioStat->numChannels))
1534 {
1535 hddLog(VOS_TRACE_LEVEL_ERROR,
1536 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1537 kfree_skb(vendor_event);
1538 return ;
1539 }
1540
1541 chList = nla_nest_start(vendor_event,
1542 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301543 if(!chList)
1544 {
1545 hddLog(VOS_TRACE_LEVEL_ERROR,
1546 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1547 __func__);
1548 kfree_skb(vendor_event);
1549 return;
1550 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301551 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1552 {
1553 struct nlattr *chInfo;
1554
1555 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1556 pWifiRadioStat->channels +
1557 (i * sizeof(tSirWifiChannelStats)));
1558
Sunil Duttc69bccb2014-05-26 21:30:20 +05301559 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301560 if(!chInfo)
1561 {
1562 hddLog(VOS_TRACE_LEVEL_ERROR,
1563 "%s: failed to put chInfo",
1564 __func__);
1565 kfree_skb(vendor_event);
1566 return;
1567 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301568
1569 if (nla_put_u32(vendor_event,
1570 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1571 pWifiChannelStats->channel.width) ||
1572 nla_put_u32(vendor_event,
1573 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1574 pWifiChannelStats->channel.centerFreq) ||
1575 nla_put_u32(vendor_event,
1576 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1577 pWifiChannelStats->channel.centerFreq0) ||
1578 nla_put_u32(vendor_event,
1579 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1580 pWifiChannelStats->channel.centerFreq1) ||
1581 nla_put_u32(vendor_event,
1582 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1583 pWifiChannelStats->onTime) ||
1584 nla_put_u32(vendor_event,
1585 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1586 pWifiChannelStats->ccaBusyTime))
1587 {
1588 hddLog(VOS_TRACE_LEVEL_ERROR,
1589 FL("cfg80211_vendor_event_alloc failed") );
1590 kfree_skb(vendor_event);
1591 return ;
1592 }
1593 nla_nest_end(vendor_event, chInfo);
1594 }
1595 nla_nest_end(vendor_event, chList);
1596
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301597 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301598
1599 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301600 return;
1601}
1602
1603/*
1604 * hdd_link_layer_stats_ind_callback () - This function is called after
1605 * receiving Link Layer indications from FW.This callback converts the firmware
1606 * data to the NL data and send the same to the kernel/upper layers.
1607 */
1608static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1609 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301610 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301611{
Dino Mycled3d50022014-07-07 12:58:25 +05301612 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1613 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301614 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05301615 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301616 int status;
1617
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301618 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301619
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301620 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301621 if (0 != status)
1622 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301623 return;
1624 }
1625
Dino Mycled3d50022014-07-07 12:58:25 +05301626 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1627 if (NULL == pAdapter)
1628 {
1629 hddLog(VOS_TRACE_LEVEL_ERROR,
1630 FL(" MAC address %pM does not exist with host"),
1631 macAddr);
1632 return;
1633 }
1634
Sunil Duttc69bccb2014-05-26 21:30:20 +05301635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301636 "%s: Interface: %s LLStats indType: %d", __func__,
1637 pAdapter->dev->name, indType);
1638
Sunil Duttc69bccb2014-05-26 21:30:20 +05301639 switch (indType)
1640 {
1641 case SIR_HAL_LL_STATS_RESULTS_RSP:
1642 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301643 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301644 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
1645 "respId = %u, moreResultToFollow = %u",
1646 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
1647 macAddr, linkLayerStatsResults->respId,
1648 linkLayerStatsResults->moreResultToFollow);
1649
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301650 spin_lock(&hdd_context_lock);
1651 context = &pHddCtx->ll_stats_context;
1652 /* validate response received from target */
1653 if ((context->request_id != linkLayerStatsResults->respId) ||
1654 !(context->request_bitmap & linkLayerStatsResults->paramId))
1655 {
1656 spin_unlock(&hdd_context_lock);
1657 hddLog(LOGE,
1658 FL("Error : Request id %d response id %d request bitmap 0x%x"
1659 "response bitmap 0x%x"),
1660 context->request_id, linkLayerStatsResults->respId,
1661 context->request_bitmap, linkLayerStatsResults->paramId);
1662 return;
1663 }
1664 spin_unlock(&hdd_context_lock);
1665
Sunil Duttc69bccb2014-05-26 21:30:20 +05301666 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1667 {
1668 hdd_link_layer_process_radio_stats(pAdapter,
1669 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301670 spin_lock(&hdd_context_lock);
1671 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
1672 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301673 }
1674 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1675 {
1676 hdd_link_layer_process_iface_stats(pAdapter,
1677 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301678 spin_lock(&hdd_context_lock);
1679 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
1680 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301681 }
1682 else if ( linkLayerStatsResults->paramId &
1683 WMI_LINK_STATS_ALL_PEER )
1684 {
1685 hdd_link_layer_process_peer_stats(pAdapter,
1686 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301687 spin_lock(&hdd_context_lock);
1688 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
1689 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301690 } /* WMI_LINK_STATS_ALL_PEER */
1691 else
1692 {
1693 hddLog(VOS_TRACE_LEVEL_ERROR,
1694 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1695 }
1696
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301697 spin_lock(&hdd_context_lock);
1698 /* complete response event if all requests are completed */
1699 if (0 == context->request_bitmap)
1700 complete(&context->response_event);
1701 spin_unlock(&hdd_context_lock);
1702
Sunil Duttc69bccb2014-05-26 21:30:20 +05301703 break;
1704 }
1705 default:
1706 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1707 break;
1708 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301709
1710 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301711 return;
1712}
1713
1714const struct
1715nla_policy
1716qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1717{
1718 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1719 { .type = NLA_U32 },
1720 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1721 { .type = NLA_U32 },
1722};
1723
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301724static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1725 struct wireless_dev *wdev,
1726 const void *data,
1727 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301728{
1729 int status;
1730 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301731 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301732 struct net_device *dev = wdev->netdev;
1733 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1734 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1735
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301736 ENTER();
1737
Sunil Duttc69bccb2014-05-26 21:30:20 +05301738 status = wlan_hdd_validate_context(pHddCtx);
1739 if (0 != status)
1740 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301741 return -EINVAL;
1742 }
1743
1744 if (NULL == pAdapter)
1745 {
1746 hddLog(VOS_TRACE_LEVEL_ERROR,
1747 FL("HDD adapter is Null"));
1748 return -ENODEV;
1749 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301750 /* check the LLStats Capability */
1751 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1752 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1753 {
1754 hddLog(VOS_TRACE_LEVEL_ERROR,
1755 FL("Link Layer Statistics not supported by Firmware"));
1756 return -EINVAL;
1757 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301758
1759 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1760 (struct nlattr *)data,
1761 data_len, qca_wlan_vendor_ll_set_policy))
1762 {
1763 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1764 return -EINVAL;
1765 }
1766 if (!tb_vendor
1767 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1768 {
1769 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1770 return -EINVAL;
1771 }
1772 if (!tb_vendor[
1773 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1774 {
1775 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1776 return -EINVAL;
1777 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301778 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301779 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301780
Dino Mycledf0a5d92014-07-04 09:41:55 +05301781 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301782 nla_get_u32(
1783 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1784
Dino Mycledf0a5d92014-07-04 09:41:55 +05301785 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301786 nla_get_u32(
1787 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1788
Dino Mycled3d50022014-07-07 12:58:25 +05301789 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1790 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301791
1792
1793 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301794 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
1795 "Statistics Gathering = %d ",
1796 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
1797 linkLayerStatsSetReq.mpduSizeThreshold,
1798 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301799
1800 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1801 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301802 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301803 {
1804 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1805 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301806 return -EINVAL;
1807
1808 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301809
Sunil Duttc69bccb2014-05-26 21:30:20 +05301810 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301811 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301812 {
1813 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1814 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301815 return -EINVAL;
1816 }
1817
1818 pAdapter->isLinkLayerStatsSet = 1;
1819
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301820 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301821 return 0;
1822}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301823static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1824 struct wireless_dev *wdev,
1825 const void *data,
1826 int data_len)
1827{
1828 int ret = 0;
1829
1830 vos_ssr_protect(__func__);
1831 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1832 vos_ssr_unprotect(__func__);
1833
1834 return ret;
1835}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301836
1837const struct
1838nla_policy
1839qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1840{
1841 /* Unsigned 32bit value provided by the caller issuing the GET stats
1842 * command. When reporting
1843 * the stats results, the driver uses the same value to indicate
1844 * which GET request the results
1845 * correspond to.
1846 */
1847 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1848
1849 /* Unsigned 32bit value . bit mask to identify what statistics are
1850 requested for retrieval */
1851 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1852};
1853
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301854static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1855 struct wireless_dev *wdev,
1856 const void *data,
1857 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301858{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301859 unsigned long rc;
1860 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301861 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1862 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301863 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301864 struct net_device *dev = wdev->netdev;
1865 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05301866 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301867 int status;
1868
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301869 ENTER();
1870
Sunil Duttc69bccb2014-05-26 21:30:20 +05301871 status = wlan_hdd_validate_context(pHddCtx);
1872 if (0 != status)
1873 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301874 return -EINVAL ;
1875 }
1876
1877 if (NULL == pAdapter)
1878 {
1879 hddLog(VOS_TRACE_LEVEL_FATAL,
1880 "%s: HDD adapter is Null", __func__);
1881 return -ENODEV;
1882 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05301883
1884 if (pHddStaCtx == NULL)
1885 {
1886 hddLog(VOS_TRACE_LEVEL_FATAL,
1887 "%s: HddStaCtx is Null", __func__);
1888 return -ENODEV;
1889 }
1890
Dino Mycledf0a5d92014-07-04 09:41:55 +05301891 /* check the LLStats Capability */
1892 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1893 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1894 {
1895 hddLog(VOS_TRACE_LEVEL_ERROR,
1896 FL("Link Layer Statistics not supported by Firmware"));
1897 return -EINVAL;
1898 }
1899
Sunil Duttc69bccb2014-05-26 21:30:20 +05301900
1901 if (!pAdapter->isLinkLayerStatsSet)
1902 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05301903 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301904 "%s: isLinkLayerStatsSet : %d",
1905 __func__, pAdapter->isLinkLayerStatsSet);
1906 return -EINVAL;
1907 }
1908
Mukul Sharma10313ba2015-07-29 19:14:39 +05301909 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
1910 {
1911 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1912 "%s: Roaming in progress, so unable to proceed this request", __func__);
1913 return -EBUSY;
1914 }
1915
Sunil Duttc69bccb2014-05-26 21:30:20 +05301916 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1917 (struct nlattr *)data,
1918 data_len, qca_wlan_vendor_ll_get_policy))
1919 {
1920 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1921 return -EINVAL;
1922 }
1923
1924 if (!tb_vendor
1925 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1926 {
1927 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1928 return -EINVAL;
1929 }
1930
1931 if (!tb_vendor
1932 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1933 {
1934 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1935 return -EINVAL;
1936 }
1937
Sunil Duttc69bccb2014-05-26 21:30:20 +05301938
Dino Mycledf0a5d92014-07-04 09:41:55 +05301939 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301940 nla_get_u32( tb_vendor[
1941 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301942 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301943 nla_get_u32( tb_vendor[
1944 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1945
Dino Mycled3d50022014-07-07 12:58:25 +05301946 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1947 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301948
1949 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301950 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
1951 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301952 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301953
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301954 spin_lock(&hdd_context_lock);
1955 context = &pHddCtx->ll_stats_context;
1956 context->request_id = linkLayerStatsGetReq.reqId;
1957 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
1958 INIT_COMPLETION(context->response_event);
1959 spin_unlock(&hdd_context_lock);
1960
Sunil Duttc69bccb2014-05-26 21:30:20 +05301961 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301962 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301963 {
1964 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1965 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301966 return -EINVAL;
1967 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301968
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301969 rc = wait_for_completion_timeout(&context->response_event,
1970 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
1971 if (!rc)
1972 {
1973 hddLog(LOGE,
1974 FL("Target response timed out request id %d request bitmap 0x%x"),
1975 context->request_id, context->request_bitmap);
1976 return -ETIMEDOUT;
1977 }
1978
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301979 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301980 return 0;
1981}
1982
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301983static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1984 struct wireless_dev *wdev,
1985 const void *data,
1986 int data_len)
1987{
1988 int ret = 0;
1989
1990 vos_ssr_protect(__func__);
1991 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
1992 vos_ssr_unprotect(__func__);
1993
1994 return ret;
1995}
1996
Sunil Duttc69bccb2014-05-26 21:30:20 +05301997const struct
1998nla_policy
1999qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
2000{
2001 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
2002 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
2003 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
2004 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
2005};
2006
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302007static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2008 struct wireless_dev *wdev,
2009 const void *data,
2010 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302011{
2012 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2013 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302014 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302015 struct net_device *dev = wdev->netdev;
2016 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2017 u32 statsClearReqMask;
2018 u8 stopReq;
2019 int status;
2020
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302021 ENTER();
2022
Sunil Duttc69bccb2014-05-26 21:30:20 +05302023 status = wlan_hdd_validate_context(pHddCtx);
2024 if (0 != status)
2025 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302026 return -EINVAL;
2027 }
2028
2029 if (NULL == pAdapter)
2030 {
2031 hddLog(VOS_TRACE_LEVEL_FATAL,
2032 "%s: HDD adapter is Null", __func__);
2033 return -ENODEV;
2034 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302035 /* check the LLStats Capability */
2036 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2037 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2038 {
2039 hddLog(VOS_TRACE_LEVEL_ERROR,
2040 FL("Enable LLStats Capability"));
2041 return -EINVAL;
2042 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302043
2044 if (!pAdapter->isLinkLayerStatsSet)
2045 {
2046 hddLog(VOS_TRACE_LEVEL_FATAL,
2047 "%s: isLinkLayerStatsSet : %d",
2048 __func__, pAdapter->isLinkLayerStatsSet);
2049 return -EINVAL;
2050 }
2051
2052 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2053 (struct nlattr *)data,
2054 data_len, qca_wlan_vendor_ll_clr_policy))
2055 {
2056 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2057 return -EINVAL;
2058 }
2059
2060 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2061
2062 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2063 {
2064 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2065 return -EINVAL;
2066
2067 }
2068
Sunil Duttc69bccb2014-05-26 21:30:20 +05302069
Dino Mycledf0a5d92014-07-04 09:41:55 +05302070 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302071 nla_get_u32(
2072 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2073
Dino Mycledf0a5d92014-07-04 09:41:55 +05302074 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302075 nla_get_u8(
2076 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2077
2078 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302079 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302080
Dino Mycled3d50022014-07-07 12:58:25 +05302081 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2082 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302083
2084 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302085 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
2086 "statsClearReqMask = 0x%X, stopReq = %d",
2087 linkLayerStatsClearReq.reqId,
2088 linkLayerStatsClearReq.macAddr,
2089 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302090 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302091
2092 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302093 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302094 {
2095 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302096 hdd_station_ctx_t *pHddStaCtx;
2097
2098 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2099 if (VOS_STATUS_SUCCESS !=
2100 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2101 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2102 {
2103 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2104 "WLANTL_ClearInterfaceStats Failed", __func__);
2105 return -EINVAL;
2106 }
2107 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2108 (statsClearReqMask & WIFI_STATS_IFACE)) {
2109 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2110 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2111 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2112 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2113 }
2114
Sunil Duttc69bccb2014-05-26 21:30:20 +05302115 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2116 2 * sizeof(u32) +
2117 NLMSG_HDRLEN);
2118
2119 if (temp_skbuff != NULL)
2120 {
2121
2122 if (nla_put_u32(temp_skbuff,
2123 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2124 statsClearReqMask) ||
2125 nla_put_u32(temp_skbuff,
2126 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2127 stopReq))
2128 {
2129 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2130 kfree_skb(temp_skbuff);
2131 return -EINVAL;
2132 }
2133 /* If the ask is to stop the stats collection as part of clear
2134 * (stopReq = 1) , ensure that no further requests of get
2135 * go to the firmware by having isLinkLayerStatsSet set to 0.
2136 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302137 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302138 * case the firmware is just asked to clear the statistics.
2139 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302140 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302141 pAdapter->isLinkLayerStatsSet = 0;
2142 return cfg80211_vendor_cmd_reply(temp_skbuff);
2143 }
2144 return -ENOMEM;
2145 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302146
2147 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302148 return -EINVAL;
2149}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302150static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2151 struct wireless_dev *wdev,
2152 const void *data,
2153 int data_len)
2154{
2155 int ret = 0;
2156
2157 vos_ssr_protect(__func__);
2158 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2159 vos_ssr_unprotect(__func__);
2160
2161 return ret;
2162
2163
2164}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302165#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2166
Dino Mycle6fb96c12014-06-10 11:52:40 +05302167#ifdef WLAN_FEATURE_EXTSCAN
2168static const struct nla_policy
2169wlan_hdd_extscan_config_policy
2170 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2171{
2172 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2173 { .type = NLA_U32 },
2174 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2175 { .type = NLA_U32 },
2176 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2177 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2178 { .type = NLA_U32 },
2179 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2180 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2181
2182 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2183 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2184 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2185 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2186 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302187 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
2188 { .type = NLA_U32 },
2189 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
2190 { .type = NLA_U32 },
2191 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
2192 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302193 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2194 { .type = NLA_U32 },
2195 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2196 { .type = NLA_U32 },
2197 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2198 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302199 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
2200 { .type = NLA_U8 },
2201 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302202 { .type = NLA_U8 },
2203 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2204 { .type = NLA_U8 },
2205 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2206 { .type = NLA_U8 },
2207
2208 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2209 { .type = NLA_U32 },
2210 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2211 { .type = NLA_UNSPEC },
2212 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2213 { .type = NLA_S32 },
2214 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2215 { .type = NLA_S32 },
2216 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2217 { .type = NLA_U32 },
2218 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2219 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302220 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
2221 { .type = NLA_U32 },
2222 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
2223 { .type = NLA_BINARY,
2224 .len = IEEE80211_MAX_SSID_LEN + 1 },
2225 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302226 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302227 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
2228 { .type = NLA_U32 },
2229 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
2230 { .type = NLA_U8 },
2231 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
2232 { .type = NLA_S32 },
2233 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
2234 { .type = NLA_S32 },
2235 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
2236 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302237};
2238
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302239/**
2240 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
2241 * @ctx: hdd global context
2242 * @data: capabilities data
2243 *
2244 * Return: none
2245 */
2246static void
2247wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05302248{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302249 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302250 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302251 tSirEXTScanCapabilitiesEvent *data =
2252 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302253
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302254 ENTER();
2255
2256 if (wlan_hdd_validate_context(pHddCtx))
2257 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302258 return;
2259 }
2260
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302261 if (!pMsg)
2262 {
2263 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2264 return;
2265 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302266
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302267 vos_spin_lock_acquire(&hdd_context_lock);
2268
2269 context = &pHddCtx->ext_scan_context;
2270 /* validate response received from target*/
2271 if (context->request_id != data->requestId)
2272 {
2273 vos_spin_lock_release(&hdd_context_lock);
2274 hddLog(LOGE,
2275 FL("Target response id did not match: request_id %d resposne_id %d"),
2276 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302277 return;
2278 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302279 else
2280 {
2281 context->capability_response = *data;
2282 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302283 }
2284
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302285 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302286
Dino Mycle6fb96c12014-06-10 11:52:40 +05302287 return;
2288}
2289
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302290/*
2291 * define short names for the global vendor params
2292 * used by wlan_hdd_send_ext_scan_capability()
2293 */
2294#define PARAM_REQUEST_ID \
2295 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
2296#define PARAM_STATUS \
2297 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
2298#define MAX_SCAN_CACHE_SIZE \
2299 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
2300#define MAX_SCAN_BUCKETS \
2301 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
2302#define MAX_AP_CACHE_PER_SCAN \
2303 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
2304#define MAX_RSSI_SAMPLE_SIZE \
2305 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
2306#define MAX_SCAN_RPT_THRHOLD \
2307 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
2308#define MAX_HOTLIST_BSSIDS \
2309 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
2310#define MAX_BSSID_HISTORY_ENTRIES \
2311 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
2312#define MAX_HOTLIST_SSIDS \
2313 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302314#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
2315 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302316
2317static int wlan_hdd_send_ext_scan_capability(void *ctx)
2318{
2319 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2320 struct sk_buff *skb = NULL;
2321 int ret;
2322 tSirEXTScanCapabilitiesEvent *data;
2323 tANI_U32 nl_buf_len;
2324
2325 ret = wlan_hdd_validate_context(pHddCtx);
2326 if (0 != ret)
2327 {
2328 return ret;
2329 }
2330
2331 data = &(pHddCtx->ext_scan_context.capability_response);
2332
2333 nl_buf_len = NLMSG_HDRLEN;
2334 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
2335 (sizeof(data->status) + NLA_HDRLEN) +
2336 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
2337 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
2338 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
2339 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
2340 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
2341 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
2342 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
2343 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
2344
2345 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
2346
2347 if (!skb)
2348 {
2349 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
2350 return -ENOMEM;
2351 }
2352
2353 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
2354 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
2355 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
2356 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
2357 data->maxRssiSampleSize, data->maxScanReportingThreshold);
2358 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
2359 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
2360 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
2361
2362 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
2363 nla_put_u32(skb, PARAM_STATUS, data->status) ||
2364 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
2365 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
2366 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
2367 data->maxApPerScan) ||
2368 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
2369 data->maxRssiSampleSize) ||
2370 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
2371 data->maxScanReportingThreshold) ||
2372 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
2373 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
2374 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302375 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
2376 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302377 {
2378 hddLog(LOGE, FL("nla put fail"));
2379 goto nla_put_failure;
2380 }
2381
2382 cfg80211_vendor_cmd_reply(skb);
2383 return 0;
2384
2385nla_put_failure:
2386 kfree_skb(skb);
2387 return -EINVAL;;
2388}
2389
2390/*
2391 * done with short names for the global vendor params
2392 * used by wlan_hdd_send_ext_scan_capability()
2393 */
2394#undef PARAM_REQUEST_ID
2395#undef PARAM_STATUS
2396#undef MAX_SCAN_CACHE_SIZE
2397#undef MAX_SCAN_BUCKETS
2398#undef MAX_AP_CACHE_PER_SCAN
2399#undef MAX_RSSI_SAMPLE_SIZE
2400#undef MAX_SCAN_RPT_THRHOLD
2401#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302402#undef MAX_BSSID_HISTORY_ENTRIES
2403#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05302404
2405static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2406{
2407 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2408 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302409 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302410 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302411
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302412 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302413
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302414 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302415 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302416
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302417 if (!pMsg)
2418 {
2419 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302420 return;
2421 }
2422
Dino Mycle6fb96c12014-06-10 11:52:40 +05302423 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2424 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2425
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302426 context = &pHddCtx->ext_scan_context;
2427 spin_lock(&hdd_context_lock);
2428 if (context->request_id == pData->requestId) {
2429 context->response_status = pData->status ? -EINVAL : 0;
2430 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302431 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302432 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302433
2434 /*
2435 * Store the Request ID for comparing with the requestID obtained
2436 * in other requests.HDD shall return a failure is the extscan_stop
2437 * request is issued with a different requestId as that of the
2438 * extscan_start request. Also, This requestId shall be used while
2439 * indicating the full scan results to the upper layers.
2440 * The requestId is stored with the assumption that the firmware
2441 * shall return the ext scan start request's requestId in ext scan
2442 * start response.
2443 */
2444 if (pData->status == 0)
2445 pMac->sme.extScanStartReqId = pData->requestId;
2446
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302447 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302448 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302449}
2450
2451
2452static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2453{
2454 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2455 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302456 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302457
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302458 ENTER();
2459
2460 if (wlan_hdd_validate_context(pHddCtx)){
2461 return;
2462 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302463
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302464 if (!pMsg)
2465 {
2466 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302467 return;
2468 }
2469
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302470 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2471 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302472
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302473 context = &pHddCtx->ext_scan_context;
2474 spin_lock(&hdd_context_lock);
2475 if (context->request_id == pData->requestId) {
2476 context->response_status = pData->status ? -EINVAL : 0;
2477 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302478 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302479 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302480
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302481 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302482 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302483}
2484
Dino Mycle6fb96c12014-06-10 11:52:40 +05302485static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2486 void *pMsg)
2487{
2488 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302489 tpSirEXTScanSetBssidHotListRspParams pData =
2490 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302491 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302492
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302493 ENTER();
2494
2495 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302496 return;
2497 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302498
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302499 if (!pMsg)
2500 {
2501 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2502 return;
2503 }
2504
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302505 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2506 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302507
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302508 context = &pHddCtx->ext_scan_context;
2509 spin_lock(&hdd_context_lock);
2510 if (context->request_id == pData->requestId) {
2511 context->response_status = pData->status ? -EINVAL : 0;
2512 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302513 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302514 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302515
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302516 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302517 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302518}
2519
2520static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2521 void *pMsg)
2522{
2523 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302524 tpSirEXTScanResetBssidHotlistRspParams pData =
2525 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302526 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302527
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302528 ENTER();
2529
2530 if (wlan_hdd_validate_context(pHddCtx)) {
2531 return;
2532 }
2533 if (!pMsg)
2534 {
2535 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302536 return;
2537 }
2538
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302539 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2540 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302541
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302542 context = &pHddCtx->ext_scan_context;
2543 spin_lock(&hdd_context_lock);
2544 if (context->request_id == pData->requestId) {
2545 context->response_status = pData->status ? -EINVAL : 0;
2546 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302547 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302548 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302549
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302550 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302551 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302552}
2553
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05302554static void wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(void *ctx,
2555 void *pMsg)
2556{
2557 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2558 tpSirEXTScanSetSsidHotListRspParams pData =
2559 (tpSirEXTScanSetSsidHotListRspParams) pMsg;
2560 struct hdd_ext_scan_context *context;
2561
2562 if (wlan_hdd_validate_context(pHddCtx)){
2563 return;
2564 }
2565
2566 if (!pMsg)
2567 {
2568 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2569 return;
2570 }
2571
2572 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2573 pData->status);
2574
2575 context = &pHddCtx->ext_scan_context;
2576 spin_lock(&hdd_context_lock);
2577 if (context->request_id == pData->requestId) {
2578 context->response_status = pData->status ? -EINVAL : 0;
2579 complete(&context->response_event);
2580 }
2581 spin_unlock(&hdd_context_lock);
2582
2583 return;
2584}
2585
2586static void wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(void *ctx,
2587 void *pMsg)
2588{
2589 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2590 tpSirEXTScanResetSsidHotlistRspParams pData =
2591 (tpSirEXTScanResetSsidHotlistRspParams) pMsg;
2592 struct hdd_ext_scan_context *context;
2593
2594 if (wlan_hdd_validate_context(pHddCtx)) {
2595 return;
2596 }
2597 if (!pMsg)
2598 {
2599 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2600 return;
2601 }
2602
2603 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2604 pData->status);
2605
2606 context = &pHddCtx->ext_scan_context;
2607 spin_lock(&hdd_context_lock);
2608 if (context->request_id == pData->requestId) {
2609 context->response_status = pData->status ? -EINVAL : 0;
2610 complete(&context->response_event);
2611 }
2612 spin_unlock(&hdd_context_lock);
2613
2614 return;
2615}
2616
2617
Dino Mycle6fb96c12014-06-10 11:52:40 +05302618static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2619 void *pMsg)
2620{
2621 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2622 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302623 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302624 tANI_S32 totalResults;
2625 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302626 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
2627 struct hdd_ext_scan_context *context;
2628 bool ignore_cached_results = false;
2629 tExtscanCachedScanResult *result;
2630 struct nlattr *nla_results;
2631 tANI_U16 ieLength= 0;
2632 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302633
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302634 ENTER();
2635
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302636 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302637 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302638
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302639 if (!pMsg)
2640 {
2641 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2642 return;
2643 }
2644
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302645 spin_lock(&hdd_context_lock);
2646 context = &pHddCtx->ext_scan_context;
2647 ignore_cached_results = context->ignore_cached_results;
2648 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302649
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302650 if (ignore_cached_results) {
2651 hddLog(LOGE,
2652 FL("Ignore the cached results received after timeout"));
2653 return;
2654 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302655
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302656 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
2657 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302658
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302659 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302660
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302661 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
2662 scan_id_index++) {
2663 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302664
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302665 totalResults = result->num_results;
2666 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
2667 result->scan_id, result->flags, totalResults);
2668 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302669
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302670 do{
2671 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2672 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2673 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302674
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302675 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2676 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
2677
2678 if (!skb) {
2679 hddLog(VOS_TRACE_LEVEL_ERROR,
2680 FL("cfg80211_vendor_event_alloc failed"));
2681 return;
2682 }
2683
2684 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2685
2686 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2687 pData->requestId) ||
2688 nla_put_u32(skb,
2689 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2690 resultsPerEvent)) {
2691 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2692 goto fail;
2693 }
2694 if (nla_put_u8(skb,
2695 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2696 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302697 {
2698 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2699 goto fail;
2700 }
2701
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302702 if (nla_put_u32(skb,
2703 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2704 result->scan_id)) {
2705 hddLog(LOGE, FL("put fail"));
2706 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302707 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302708
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302709 nla_results = nla_nest_start(skb,
2710 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
2711 if (!nla_results)
2712 goto fail;
2713
2714 if (resultsPerEvent) {
2715 struct nlattr *aps;
2716 struct nlattr *nla_result;
2717
2718 nla_result = nla_nest_start(skb, scan_id_index);
2719 if(!nla_result)
2720 goto fail;
2721
2722 if (nla_put_u32(skb,
2723 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2724 result->scan_id) ||
2725 nla_put_u32(skb,
2726 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
2727 result->flags) ||
2728 nla_put_u32(skb,
2729 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2730 totalResults)) {
2731 hddLog(LOGE, FL("put fail"));
2732 goto fail;
2733 }
2734
2735 aps = nla_nest_start(skb,
2736 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2737 if (!aps)
2738 {
2739 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2740 goto fail;
2741 }
2742
2743 head_ptr = (tpSirWifiScanResult) &(result->ap);
2744
2745 for (j = 0; j < resultsPerEvent; j++, i++) {
2746 struct nlattr *ap;
2747 pSirWifiScanResult = head_ptr + i;
2748
2749 /*
2750 * Firmware returns timestamp from WiFi turn ON till
2751 * BSSID was cached (in seconds). Add this with
2752 * time gap between system boot up to WiFi turn ON
2753 * to derive the time since boot when the
2754 * BSSID was cached.
2755 */
2756 pSirWifiScanResult->ts += pHddCtx->wifi_turn_on_time_since_boot;
2757 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2758 "Ssid (%s)"
2759 "Bssid: %pM "
2760 "Channel (%u)"
2761 "Rssi (%d)"
2762 "RTT (%u)"
2763 "RTT_SD (%u)"
2764 "Beacon Period %u"
2765 "Capability 0x%x "
2766 "Ie length %d",
2767 i,
2768 pSirWifiScanResult->ts,
2769 pSirWifiScanResult->ssid,
2770 pSirWifiScanResult->bssid,
2771 pSirWifiScanResult->channel,
2772 pSirWifiScanResult->rssi,
2773 pSirWifiScanResult->rtt,
2774 pSirWifiScanResult->rtt_sd,
2775 pSirWifiScanResult->beaconPeriod,
2776 pSirWifiScanResult->capability,
2777 ieLength);
2778
2779 ap = nla_nest_start(skb, j + 1);
2780 if (!ap)
2781 {
2782 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2783 goto fail;
2784 }
2785
2786 if (nla_put_u64(skb,
2787 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2788 pSirWifiScanResult->ts) )
2789 {
2790 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2791 goto fail;
2792 }
2793 if (nla_put(skb,
2794 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2795 sizeof(pSirWifiScanResult->ssid),
2796 pSirWifiScanResult->ssid) )
2797 {
2798 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2799 goto fail;
2800 }
2801 if (nla_put(skb,
2802 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2803 sizeof(pSirWifiScanResult->bssid),
2804 pSirWifiScanResult->bssid) )
2805 {
2806 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2807 goto fail;
2808 }
2809 if (nla_put_u32(skb,
2810 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2811 pSirWifiScanResult->channel) )
2812 {
2813 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2814 goto fail;
2815 }
2816 if (nla_put_s32(skb,
2817 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2818 pSirWifiScanResult->rssi) )
2819 {
2820 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2821 goto fail;
2822 }
2823 if (nla_put_u32(skb,
2824 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2825 pSirWifiScanResult->rtt) )
2826 {
2827 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2828 goto fail;
2829 }
2830 if (nla_put_u32(skb,
2831 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2832 pSirWifiScanResult->rtt_sd))
2833 {
2834 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2835 goto fail;
2836 }
2837 if (nla_put_u32(skb,
2838 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2839 pSirWifiScanResult->beaconPeriod))
2840 {
2841 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2842 goto fail;
2843 }
2844 if (nla_put_u32(skb,
2845 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2846 pSirWifiScanResult->capability))
2847 {
2848 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2849 goto fail;
2850 }
2851 if (nla_put_u32(skb,
2852 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2853 ieLength))
2854 {
2855 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2856 goto fail;
2857 }
2858
2859 if (ieLength)
2860 if (nla_put(skb,
2861 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2862 ieLength, ie)) {
2863 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2864 goto fail;
2865 }
2866
2867 nla_nest_end(skb, ap);
2868 }
2869 nla_nest_end(skb, aps);
2870 nla_nest_end(skb, nla_result);
2871 }
2872
2873 nla_nest_end(skb, nla_results);
2874
2875 cfg80211_vendor_cmd_reply(skb);
2876
2877 } while (totalResults > 0);
2878 }
2879
2880 if (!pData->moreData) {
2881 spin_lock(&hdd_context_lock);
2882 context->response_status = 0;
2883 complete(&context->response_event);
2884 spin_unlock(&hdd_context_lock);
2885 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302886
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302887 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302888 return;
2889fail:
2890 kfree_skb(skb);
2891 return;
2892}
2893
2894static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2895 void *pMsg)
2896{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302897 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302898 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2899 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302900 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302901
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302902 ENTER();
2903
2904 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302905 hddLog(LOGE,
2906 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302907 return;
2908 }
2909 if (!pMsg)
2910 {
2911 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302912 return;
2913 }
2914
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302915 if (pData->bss_found)
2916 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
2917 else
2918 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
2919
Dino Mycle6fb96c12014-06-10 11:52:40 +05302920 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302921#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2922 NULL,
2923#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302924 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302925 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302926
2927 if (!skb) {
2928 hddLog(VOS_TRACE_LEVEL_ERROR,
2929 FL("cfg80211_vendor_event_alloc failed"));
2930 return;
2931 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302932
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302933 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2934 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
2935 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2936 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
2937
2938 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302939 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2940 "Ssid (%s) "
2941 "Bssid (" MAC_ADDRESS_STR ") "
2942 "Channel (%u) "
2943 "Rssi (%d) "
2944 "RTT (%u) "
2945 "RTT_SD (%u) ",
2946 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302947 pData->bssHotlist[i].ts,
2948 pData->bssHotlist[i].ssid,
2949 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
2950 pData->bssHotlist[i].channel,
2951 pData->bssHotlist[i].rssi,
2952 pData->bssHotlist[i].rtt,
2953 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302954 }
2955
2956 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2957 pData->requestId) ||
2958 nla_put_u32(skb,
2959 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302960 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302961 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2962 goto fail;
2963 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302964 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302965 struct nlattr *aps;
2966
2967 aps = nla_nest_start(skb,
2968 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2969 if (!aps)
2970 goto fail;
2971
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302972 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302973 struct nlattr *ap;
2974
2975 ap = nla_nest_start(skb, i + 1);
2976 if (!ap)
2977 goto fail;
2978
2979 if (nla_put_u64(skb,
2980 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302981 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302982 nla_put(skb,
2983 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302984 sizeof(pData->bssHotlist[i].ssid),
2985 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302986 nla_put(skb,
2987 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302988 sizeof(pData->bssHotlist[i].bssid),
2989 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302990 nla_put_u32(skb,
2991 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302992 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302993 nla_put_s32(skb,
2994 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302995 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302996 nla_put_u32(skb,
2997 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302998 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302999 nla_put_u32(skb,
3000 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303001 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303002 goto fail;
3003
3004 nla_nest_end(skb, ap);
3005 }
3006 nla_nest_end(skb, aps);
3007
3008 if (nla_put_u8(skb,
3009 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3010 pData->moreData))
3011 goto fail;
3012 }
3013
3014 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303015 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303016 return;
3017
3018fail:
3019 kfree_skb(skb);
3020 return;
3021
3022}
Dino Mycle6fb96c12014-06-10 11:52:40 +05303023
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303024/**
3025 * wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind() -
3026 * Handle an SSID hotlist match event
3027 * @ctx: HDD context registered with SME
3028 * @event: The SSID hotlist match event
3029 *
3030 * This function will take an SSID match event that was generated by
3031 * firmware and will convert it into a cfg80211 vendor event which is
3032 * sent to userspace.
3033 *
3034 * Return: none
3035 */
3036static void
3037wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(void *ctx,
3038 void *pMsg)
3039{
3040 hdd_context_t *hdd_ctx = ctx;
3041 struct sk_buff *skb;
3042 tANI_U32 i, index;
3043 tpSirEXTScanSsidHotlistMatch pData = (tpSirEXTScanSsidHotlistMatch) pMsg;
3044
3045 ENTER();
3046
3047 if (wlan_hdd_validate_context(hdd_ctx)) {
3048 hddLog(LOGE,
3049 FL("HDD context is not valid or response"));
3050 return;
3051 }
3052 if (!pMsg)
3053 {
3054 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3055 return;
3056 }
3057
3058 if (pData->ssid_found) {
3059 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX;
3060 hddLog(LOG1, "SSID hotlist found");
3061 } else {
3062 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX;
3063 hddLog(LOG1, "SSID hotlist lost");
3064 }
3065
3066 skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
3067#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3068 NULL,
3069#endif
3070 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3071 index, GFP_KERNEL);
3072
3073 if (!skb) {
3074 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
3075 return;
3076 }
3077 hddLog(LOG1, "Req Id %u, Num of SSIDs %u, More Data (%u)",
3078 pData->requestId, pData->numHotlistSsid, pData->moreData);
3079
3080 for (i = 0; i < pData->numHotlistSsid; i++) {
3081 hddLog(LOG1, "[i=%d] Timestamp %llu "
3082 "Ssid: %s "
3083 "Bssid (" MAC_ADDRESS_STR ") "
3084 "Channel %u "
3085 "Rssi %d "
3086 "RTT %u "
3087 "RTT_SD %u",
3088 i,
3089 pData->ssidHotlist[i].ts,
3090 pData->ssidHotlist[i].ssid,
3091 MAC_ADDR_ARRAY(pData->ssidHotlist[i].bssid),
3092 pData->ssidHotlist[i].channel,
3093 pData->ssidHotlist[i].rssi,
3094 pData->ssidHotlist[i].rtt,
3095 pData->ssidHotlist[i].rtt_sd);
3096 }
3097
3098 if (nla_put_u32(skb,
3099 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3100 pData->requestId) ||
3101 nla_put_u32(skb,
3102 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3103 pData->numHotlistSsid)) {
3104 hddLog(LOGE, FL("put fail"));
3105 goto fail;
3106 }
3107
3108 if (pData->numHotlistSsid) {
3109 struct nlattr *aps;
3110 aps = nla_nest_start(skb,
3111 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3112 if (!aps) {
3113 hddLog(LOGE, FL("nest fail"));
3114 goto fail;
3115 }
3116
3117 for (i = 0; i < pData->numHotlistSsid; i++) {
3118 struct nlattr *ap;
3119
3120 ap = nla_nest_start(skb, i);
3121 if (!ap) {
3122 hddLog(LOGE, FL("nest fail"));
3123 goto fail;
3124 }
3125
3126 if (nla_put_u64(skb,
3127 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3128 pData->ssidHotlist[i].ts) ||
3129 nla_put(skb,
3130 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3131 sizeof(pData->ssidHotlist[i].ssid),
3132 pData->ssidHotlist[i].ssid) ||
3133 nla_put(skb,
3134 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3135 sizeof(pData->ssidHotlist[i].bssid),
3136 pData->ssidHotlist[i].bssid) ||
3137 nla_put_u32(skb,
3138 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3139 pData->ssidHotlist[i].channel) ||
3140 nla_put_s32(skb,
3141 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3142 pData->ssidHotlist[i].rssi) ||
3143 nla_put_u32(skb,
3144 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3145 pData->ssidHotlist[i].rtt) ||
3146 nla_put_u32(skb,
3147 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3148 pData->ssidHotlist[i].rtt_sd)) {
3149 hddLog(LOGE, FL("put fail"));
3150 goto fail;
3151 }
3152 nla_nest_end(skb, ap);
3153 }
3154 nla_nest_end(skb, aps);
3155
3156 if (nla_put_u8(skb,
3157 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3158 pData->moreData)) {
3159 hddLog(LOGE, FL("put fail"));
3160 goto fail;
3161 }
3162 }
3163
3164 cfg80211_vendor_event(skb, GFP_KERNEL);
3165 return;
3166
3167fail:
3168 kfree_skb(skb);
3169 return;
3170
3171}
3172
3173
Dino Mycle6fb96c12014-06-10 11:52:40 +05303174static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3175 void *pMsg)
3176{
3177 struct sk_buff *skb;
3178 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3179 tpSirWifiFullScanResultEvent pData =
3180 (tpSirWifiFullScanResultEvent) (pMsg);
3181
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303182 ENTER();
3183
3184 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303185 hddLog(LOGE,
3186 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303187 return;
3188 }
3189 if (!pMsg)
3190 {
3191 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303192 return;
3193 }
3194
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303195 /*
3196 * If the full scan result including IE data exceeds NL 4K size
3197 * limitation, drop that beacon/probe rsp frame.
3198 */
3199 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
3200 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
3201 return;
3202 }
3203
Dino Mycle6fb96c12014-06-10 11:52:40 +05303204 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303205#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3206 NULL,
3207#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303208 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3209 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3210 GFP_KERNEL);
3211
3212 if (!skb) {
3213 hddLog(VOS_TRACE_LEVEL_ERROR,
3214 FL("cfg80211_vendor_event_alloc failed"));
3215 return;
3216 }
3217
Dino Mycle6fb96c12014-06-10 11:52:40 +05303218 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3219 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3220 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3221 "Ssid (%s)"
3222 "Bssid (" MAC_ADDRESS_STR ")"
3223 "Channel (%u)"
3224 "Rssi (%d)"
3225 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303226 "RTT_SD (%u)"
3227 "Bcn Period %d"
3228 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303229 pData->ap.ts,
3230 pData->ap.ssid,
3231 MAC_ADDR_ARRAY(pData->ap.bssid),
3232 pData->ap.channel,
3233 pData->ap.rssi,
3234 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303235 pData->ap.rtt_sd,
3236 pData->ap.beaconPeriod,
3237 pData->ap.capability);
3238
Dino Mycle6fb96c12014-06-10 11:52:40 +05303239 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3240 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3241 pData->requestId) ||
3242 nla_put_u64(skb,
3243 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3244 pData->ap.ts) ||
3245 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3246 sizeof(pData->ap.ssid),
3247 pData->ap.ssid) ||
3248 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3249 WNI_CFG_BSSID_LEN,
3250 pData->ap.bssid) ||
3251 nla_put_u32(skb,
3252 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3253 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303254 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303255 pData->ap.rssi) ||
3256 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3257 pData->ap.rtt) ||
3258 nla_put_u32(skb,
3259 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3260 pData->ap.rtt_sd) ||
3261 nla_put_u16(skb,
3262 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3263 pData->ap.beaconPeriod) ||
3264 nla_put_u16(skb,
3265 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3266 pData->ap.capability) ||
3267 nla_put_u32(skb,
3268 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303269 pData->ieLength) ||
3270 nla_put_u8(skb,
3271 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3272 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303273 {
3274 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3275 goto nla_put_failure;
3276 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303277
3278 if (pData->ieLength) {
3279 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3280 pData->ieLength,
3281 pData->ie))
3282 {
3283 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3284 goto nla_put_failure;
3285 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303286 }
3287
3288 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303289 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303290 return;
3291
3292nla_put_failure:
3293 kfree_skb(skb);
3294 return;
3295}
3296
3297static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3298 void *pMsg)
3299{
3300 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3301 struct sk_buff *skb = NULL;
3302 tpSirEXTScanResultsAvailableIndParams pData =
3303 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3304
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303305 ENTER();
3306
3307 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303308 hddLog(LOGE,
3309 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303310 return;
3311 }
3312 if (!pMsg)
3313 {
3314 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303315 return;
3316 }
3317
3318 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303319#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3320 NULL,
3321#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303322 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3323 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3324 GFP_KERNEL);
3325
3326 if (!skb) {
3327 hddLog(VOS_TRACE_LEVEL_ERROR,
3328 FL("cfg80211_vendor_event_alloc failed"));
3329 return;
3330 }
3331
Dino Mycle6fb96c12014-06-10 11:52:40 +05303332 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3333 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3334 pData->numResultsAvailable);
3335 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3336 pData->requestId) ||
3337 nla_put_u32(skb,
3338 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3339 pData->numResultsAvailable)) {
3340 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3341 goto nla_put_failure;
3342 }
3343
3344 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303345 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303346 return;
3347
3348nla_put_failure:
3349 kfree_skb(skb);
3350 return;
3351}
3352
3353static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3354{
3355 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3356 struct sk_buff *skb = NULL;
3357 tpSirEXTScanProgressIndParams pData =
3358 (tpSirEXTScanProgressIndParams) pMsg;
3359
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303360 ENTER();
3361
3362 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303363 hddLog(LOGE,
3364 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303365 return;
3366 }
3367 if (!pMsg)
3368 {
3369 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303370 return;
3371 }
3372
3373 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303374#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3375 NULL,
3376#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303377 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3378 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3379 GFP_KERNEL);
3380
3381 if (!skb) {
3382 hddLog(VOS_TRACE_LEVEL_ERROR,
3383 FL("cfg80211_vendor_event_alloc failed"));
3384 return;
3385 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303386 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303387 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3388 pData->extScanEventType);
3389 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3390 pData->status);
3391
3392 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3393 pData->extScanEventType) ||
3394 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303395 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3396 pData->requestId) ||
3397 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303398 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3399 pData->status)) {
3400 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3401 goto nla_put_failure;
3402 }
3403
3404 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303405 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303406 return;
3407
3408nla_put_failure:
3409 kfree_skb(skb);
3410 return;
3411}
3412
3413void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3414 void *pMsg)
3415{
3416 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3417
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303418 ENTER();
3419
Dino Mycle6fb96c12014-06-10 11:52:40 +05303420 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303421 return;
3422 }
3423
3424 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3425
3426
3427 switch(evType) {
3428 case SIR_HAL_EXTSCAN_START_RSP:
3429 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3430 break;
3431
3432 case SIR_HAL_EXTSCAN_STOP_RSP:
3433 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3434 break;
3435 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3436 /* There is no need to send this response to upper layer
3437 Just log the message */
3438 hddLog(VOS_TRACE_LEVEL_INFO,
3439 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3440 break;
3441 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3442 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3443 break;
3444
3445 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3446 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3447 break;
3448
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303449 case SIR_HAL_EXTSCAN_SET_SSID_HOTLIST_RSP:
3450 wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(ctx, pMsg);
3451 break;
3452
3453 case SIR_HAL_EXTSCAN_RESET_SSID_HOTLIST_RSP:
3454 wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(ctx, pMsg);
3455 break;
3456
Dino Mycle6fb96c12014-06-10 11:52:40 +05303457 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303458 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303459 break;
3460 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3461 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3462 break;
3463 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3464 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3465 break;
3466 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3467 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3468 break;
3469 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3470 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3471 break;
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303472 case SIR_HAL_EXTSCAN_SSID_HOTLIST_MATCH_IND:
3473 wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(ctx, pMsg);
3474 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303475 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3476 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3477 break;
3478 default:
3479 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3480 break;
3481 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303482 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303483}
3484
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303485static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3486 struct wireless_dev *wdev,
3487 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303488{
Dino Myclee8843b32014-07-04 14:21:45 +05303489 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303490 struct net_device *dev = wdev->netdev;
3491 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3492 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3493 struct nlattr
3494 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3495 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303496 struct hdd_ext_scan_context *context;
3497 unsigned long rc;
3498 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303499
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303500 ENTER();
3501
Dino Mycle6fb96c12014-06-10 11:52:40 +05303502 status = wlan_hdd_validate_context(pHddCtx);
3503 if (0 != status)
3504 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303505 return -EINVAL;
3506 }
Dino Myclee8843b32014-07-04 14:21:45 +05303507 /* check the EXTScan Capability */
3508 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303509 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3510 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303511 {
3512 hddLog(VOS_TRACE_LEVEL_ERROR,
3513 FL("EXTScan not enabled/supported by Firmware"));
3514 return -EINVAL;
3515 }
3516
Dino Mycle6fb96c12014-06-10 11:52:40 +05303517 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3518 data, dataLen,
3519 wlan_hdd_extscan_config_policy)) {
3520 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3521 return -EINVAL;
3522 }
3523
3524 /* Parse and fetch request Id */
3525 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3526 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3527 return -EINVAL;
3528 }
3529
Dino Myclee8843b32014-07-04 14:21:45 +05303530 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303531 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303532 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303533
Dino Myclee8843b32014-07-04 14:21:45 +05303534 reqMsg.sessionId = pAdapter->sessionId;
3535 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303536
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303537 vos_spin_lock_acquire(&hdd_context_lock);
3538 context = &pHddCtx->ext_scan_context;
3539 context->request_id = reqMsg.requestId;
3540 INIT_COMPLETION(context->response_event);
3541 vos_spin_lock_release(&hdd_context_lock);
3542
Dino Myclee8843b32014-07-04 14:21:45 +05303543 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303544 if (!HAL_STATUS_SUCCESS(status)) {
3545 hddLog(VOS_TRACE_LEVEL_ERROR,
3546 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303547 return -EINVAL;
3548 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303549
3550 rc = wait_for_completion_timeout(&context->response_event,
3551 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3552 if (!rc) {
3553 hddLog(LOGE, FL("Target response timed out"));
3554 return -ETIMEDOUT;
3555 }
3556
3557 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
3558 if (ret)
3559 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
3560
3561 return ret;
3562
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303563 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303564 return 0;
3565}
3566
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303567static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3568 struct wireless_dev *wdev,
3569 const void *data, int dataLen)
3570{
3571 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303572
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303573 vos_ssr_protect(__func__);
3574 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3575 vos_ssr_unprotect(__func__);
3576
3577 return ret;
3578}
3579
3580static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3581 struct wireless_dev *wdev,
3582 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303583{
Dino Myclee8843b32014-07-04 14:21:45 +05303584 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303585 struct net_device *dev = wdev->netdev;
3586 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3587 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3588 struct nlattr
3589 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3590 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303591 struct hdd_ext_scan_context *context;
3592 unsigned long rc;
3593 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303594
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303595 ENTER();
3596
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303597 if (VOS_FTM_MODE == hdd_get_conparam()) {
3598 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3599 return -EINVAL;
3600 }
3601
Dino Mycle6fb96c12014-06-10 11:52:40 +05303602 status = wlan_hdd_validate_context(pHddCtx);
3603 if (0 != status)
3604 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303605 return -EINVAL;
3606 }
Dino Myclee8843b32014-07-04 14:21:45 +05303607 /* check the EXTScan Capability */
3608 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303609 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3610 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303611 {
3612 hddLog(VOS_TRACE_LEVEL_ERROR,
3613 FL("EXTScan not enabled/supported by Firmware"));
3614 return -EINVAL;
3615 }
3616
Dino Mycle6fb96c12014-06-10 11:52:40 +05303617 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3618 data, dataLen,
3619 wlan_hdd_extscan_config_policy)) {
3620 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3621 return -EINVAL;
3622 }
3623 /* Parse and fetch request Id */
3624 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3625 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3626 return -EINVAL;
3627 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303628
Dino Myclee8843b32014-07-04 14:21:45 +05303629 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303630 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3631
Dino Myclee8843b32014-07-04 14:21:45 +05303632 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303633
Dino Myclee8843b32014-07-04 14:21:45 +05303634 reqMsg.sessionId = pAdapter->sessionId;
3635 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303636
3637 /* Parse and fetch flush parameter */
3638 if (!tb
3639 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3640 {
3641 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3642 goto failed;
3643 }
Dino Myclee8843b32014-07-04 14:21:45 +05303644 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303645 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3646
Dino Myclee8843b32014-07-04 14:21:45 +05303647 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303648
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303649 spin_lock(&hdd_context_lock);
3650 context = &pHddCtx->ext_scan_context;
3651 context->request_id = reqMsg.requestId;
3652 context->ignore_cached_results = false;
3653 INIT_COMPLETION(context->response_event);
3654 spin_unlock(&hdd_context_lock);
3655
Dino Myclee8843b32014-07-04 14:21:45 +05303656 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303657 if (!HAL_STATUS_SUCCESS(status)) {
3658 hddLog(VOS_TRACE_LEVEL_ERROR,
3659 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303660 return -EINVAL;
3661 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303662
3663 rc = wait_for_completion_timeout(&context->response_event,
3664 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3665 if (!rc) {
3666 hddLog(LOGE, FL("Target response timed out"));
3667 retval = -ETIMEDOUT;
3668 spin_lock(&hdd_context_lock);
3669 context->ignore_cached_results = true;
3670 spin_unlock(&hdd_context_lock);
3671 } else {
3672 spin_lock(&hdd_context_lock);
3673 retval = context->response_status;
3674 spin_unlock(&hdd_context_lock);
3675 }
3676
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303677 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303678 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303679
3680failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303681 return -EINVAL;
3682}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303683static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3684 struct wireless_dev *wdev,
3685 const void *data, int dataLen)
3686{
3687 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303688
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303689 vos_ssr_protect(__func__);
3690 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3691 vos_ssr_unprotect(__func__);
3692
3693 return ret;
3694}
3695
3696static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303697 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303698 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303699{
3700 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3701 struct net_device *dev = wdev->netdev;
3702 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3703 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3704 struct nlattr
3705 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3706 struct nlattr
3707 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3708 struct nlattr *apTh;
3709 eHalStatus status;
3710 tANI_U8 i = 0;
3711 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303712 struct hdd_ext_scan_context *context;
3713 tANI_U32 request_id;
3714 unsigned long rc;
3715 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303716
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303717 ENTER();
3718
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303719 if (VOS_FTM_MODE == hdd_get_conparam()) {
3720 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3721 return -EINVAL;
3722 }
3723
Dino Mycle6fb96c12014-06-10 11:52:40 +05303724 status = wlan_hdd_validate_context(pHddCtx);
3725 if (0 != status)
3726 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303727 return -EINVAL;
3728 }
Dino Myclee8843b32014-07-04 14:21:45 +05303729 /* check the EXTScan Capability */
3730 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303731 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3732 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303733 {
3734 hddLog(VOS_TRACE_LEVEL_ERROR,
3735 FL("EXTScan not enabled/supported by Firmware"));
3736 return -EINVAL;
3737 }
3738
Dino Mycle6fb96c12014-06-10 11:52:40 +05303739 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3740 data, dataLen,
3741 wlan_hdd_extscan_config_policy)) {
3742 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3743 return -EINVAL;
3744 }
3745
3746 /* Parse and fetch request Id */
3747 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3748 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3749 return -EINVAL;
3750 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303751 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3752 vos_mem_malloc(sizeof(*pReqMsg));
3753 if (!pReqMsg) {
3754 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3755 return -ENOMEM;
3756 }
3757
Dino Myclee8843b32014-07-04 14:21:45 +05303758
Dino Mycle6fb96c12014-06-10 11:52:40 +05303759 pReqMsg->requestId = nla_get_u32(
3760 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3761 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3762
3763 /* Parse and fetch number of APs */
3764 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3765 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3766 goto fail;
3767 }
3768
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303769 /* Parse and fetch lost ap sample size */
3770 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
3771 hddLog(LOGE, FL("attr lost ap sample size failed"));
3772 goto fail;
3773 }
3774
3775 pReqMsg->lostBssidSampleSize = nla_get_u32(
3776 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
3777 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
3778
Dino Mycle6fb96c12014-06-10 11:52:40 +05303779 pReqMsg->sessionId = pAdapter->sessionId;
3780 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3781
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303782 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303783 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303784 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303785
3786 nla_for_each_nested(apTh,
3787 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3788 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3789 nla_data(apTh), nla_len(apTh),
3790 NULL)) {
3791 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3792 goto fail;
3793 }
3794
3795 /* Parse and fetch MAC address */
3796 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3797 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3798 goto fail;
3799 }
3800 memcpy(pReqMsg->ap[i].bssid, nla_data(
3801 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3802 sizeof(tSirMacAddr));
3803 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3804
3805 /* Parse and fetch low RSSI */
3806 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3807 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3808 goto fail;
3809 }
3810 pReqMsg->ap[i].low = nla_get_s32(
3811 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3812 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3813
3814 /* Parse and fetch high RSSI */
3815 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3816 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3817 goto fail;
3818 }
3819 pReqMsg->ap[i].high = nla_get_s32(
3820 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3821 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3822 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303823 i++;
3824 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303825
3826 context = &pHddCtx->ext_scan_context;
3827 spin_lock(&hdd_context_lock);
3828 INIT_COMPLETION(context->response_event);
3829 context->request_id = request_id = pReqMsg->requestId;
3830 spin_unlock(&hdd_context_lock);
3831
Dino Mycle6fb96c12014-06-10 11:52:40 +05303832 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3833 if (!HAL_STATUS_SUCCESS(status)) {
3834 hddLog(VOS_TRACE_LEVEL_ERROR,
3835 FL("sme_SetBssHotlist failed(err=%d)"), status);
3836 vos_mem_free(pReqMsg);
3837 return -EINVAL;
3838 }
3839
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303840 /* request was sent -- wait for the response */
3841 rc = wait_for_completion_timeout(&context->response_event,
3842 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3843
3844 if (!rc) {
3845 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
3846 retval = -ETIMEDOUT;
3847 } else {
3848 spin_lock(&hdd_context_lock);
3849 if (context->request_id == request_id)
3850 retval = context->response_status;
3851 else
3852 retval = -EINVAL;
3853 spin_unlock(&hdd_context_lock);
3854 }
3855
Dino Myclee8843b32014-07-04 14:21:45 +05303856 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303857 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303858 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303859
3860fail:
3861 vos_mem_free(pReqMsg);
3862 return -EINVAL;
3863}
3864
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303865static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3866 struct wireless_dev *wdev,
3867 const void *data, int dataLen)
3868{
3869 int ret = 0;
3870
3871 vos_ssr_protect(__func__);
3872 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3873 dataLen);
3874 vos_ssr_unprotect(__func__);
3875
3876 return ret;
3877}
3878
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303879/*
3880 * define short names for the global vendor params
3881 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
3882 */
3883#define PARAM_MAX \
3884QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
3885#define PARAM_REQUEST_ID \
3886QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3887#define PARAMS_LOST_SSID_SAMPLE_SIZE \
3888QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE
3889#define PARAMS_NUM_SSID \
3890QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID
3891#define THRESHOLD_PARAM \
3892QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM
3893#define PARAM_SSID \
3894QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID
3895#define PARAM_BAND \
3896QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND
3897#define PARAM_RSSI_LOW \
3898QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW
3899#define PARAM_RSSI_HIGH \
3900QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH
3901
3902/**
3903 * __wlan_hdd_cfg80211_extscan_set_ssid_hotlist() - set ssid hot list
3904 * @wiphy: Pointer to wireless phy
3905 * @wdev: Pointer to wireless device
3906 * @data: Pointer to data
3907 * @data_len: Data length
3908 *
3909 * Return: 0 on success, negative errno on failure
3910 */
3911static int
3912__wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
3913 struct wireless_dev *wdev,
3914 const void *data,
3915 int data_len)
3916{
3917 tSirEXTScanSetSsidHotListReqParams *request;
3918 struct net_device *dev = wdev->netdev;
3919 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3920 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
3921 struct nlattr *tb[PARAM_MAX + 1];
3922 struct nlattr *tb2[PARAM_MAX + 1];
3923 struct nlattr *ssids;
3924 struct hdd_ext_scan_context *context;
3925 uint32_t request_id;
3926 char ssid_string[SIR_MAC_MAX_SSID_LENGTH + 1] = {'\0'};
3927 int ssid_len;
3928 eHalStatus status;
3929 int i, rem, retval;
3930 unsigned long rc;
3931
3932 ENTER();
3933
3934 if (VOS_FTM_MODE == hdd_get_conparam()) {
3935 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3936 return -EINVAL;
3937 }
3938
3939 retval = wlan_hdd_validate_context(hdd_ctx);
3940 if (0 != retval) {
3941 hddLog(LOGE, FL("HDD context is not valid"));
3942 return -EINVAL;
3943 }
3944
3945 /* check the EXTScan Capability */
3946 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303947 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3948 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303949 {
3950 hddLog(VOS_TRACE_LEVEL_ERROR,
3951 FL("EXTScan not enabled/supported by Firmware"));
3952 return -EINVAL;
3953 }
3954
3955 if (nla_parse(tb, PARAM_MAX,
3956 data, data_len,
3957 wlan_hdd_extscan_config_policy)) {
3958 hddLog(LOGE, FL("Invalid ATTR"));
3959 return -EINVAL;
3960 }
3961
3962 request = vos_mem_malloc(sizeof(*request));
3963 if (!request) {
3964 hddLog(LOGE, FL("vos_mem_malloc failed"));
3965 return -ENOMEM;
3966 }
3967
3968 /* Parse and fetch request Id */
3969 if (!tb[PARAM_REQUEST_ID]) {
3970 hddLog(LOGE, FL("attr request id failed"));
3971 goto fail;
3972 }
3973
3974 request->request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
3975 hddLog(LOG1, FL("Request Id %d"), request->request_id);
3976
3977 /* Parse and fetch lost SSID sample size */
3978 if (!tb[PARAMS_LOST_SSID_SAMPLE_SIZE]) {
3979 hddLog(LOGE, FL("attr number of Ssid failed"));
3980 goto fail;
3981 }
3982 request->lost_ssid_sample_size =
3983 nla_get_u32(tb[PARAMS_LOST_SSID_SAMPLE_SIZE]);
3984 hddLog(LOG1, FL("Lost SSID Sample Size %d"),
3985 request->lost_ssid_sample_size);
3986
3987 /* Parse and fetch number of hotlist SSID */
3988 if (!tb[PARAMS_NUM_SSID]) {
3989 hddLog(LOGE, FL("attr number of Ssid failed"));
3990 goto fail;
3991 }
3992 request->ssid_count = nla_get_u32(tb[PARAMS_NUM_SSID]);
3993 hddLog(LOG1, FL("Number of SSID %d"), request->ssid_count);
3994
3995 request->session_id = adapter->sessionId;
3996 hddLog(LOG1, FL("Session Id (%d)"), request->session_id);
3997
3998 i = 0;
3999 nla_for_each_nested(ssids, tb[THRESHOLD_PARAM], rem) {
4000 if (i >= WLAN_EXTSCAN_MAX_HOTLIST_SSIDS) {
4001 hddLog(LOGE,
4002 FL("Too Many SSIDs, %d exceeds %d"),
4003 i, WLAN_EXTSCAN_MAX_HOTLIST_SSIDS);
4004 break;
4005 }
4006 if (nla_parse(tb2, PARAM_MAX,
4007 nla_data(ssids), nla_len(ssids),
4008 wlan_hdd_extscan_config_policy)) {
4009 hddLog(LOGE, FL("nla_parse failed"));
4010 goto fail;
4011 }
4012
4013 /* Parse and fetch SSID */
4014 if (!tb2[PARAM_SSID]) {
4015 hddLog(LOGE, FL("attr ssid failed"));
4016 goto fail;
4017 }
4018 nla_memcpy(ssid_string,
4019 tb2[PARAM_SSID],
4020 sizeof(ssid_string));
4021 hddLog(LOG1, FL("SSID %s"),
4022 ssid_string);
4023 ssid_len = strlen(ssid_string);
4024 memcpy(request->ssid[i].ssid.ssId, ssid_string, ssid_len);
4025 request->ssid[i].ssid.length = ssid_len;
4026 request->ssid[i].ssid.ssId[ssid_len] = '\0';
4027 hddLog(LOG1, FL("After copying SSID %s"),
4028 request->ssid[i].ssid.ssId);
4029 hddLog(LOG1, FL("After copying length: %d"),
4030 ssid_len);
4031
4032 /* Parse and fetch low RSSI */
4033 if (!tb2[PARAM_BAND]) {
4034 hddLog(LOGE, FL("attr band failed"));
4035 goto fail;
4036 }
4037 request->ssid[i].band = nla_get_u8(tb2[PARAM_BAND]);
4038 hddLog(LOG1, FL("band %d"), request->ssid[i].band);
4039
4040 /* Parse and fetch low RSSI */
4041 if (!tb2[PARAM_RSSI_LOW]) {
4042 hddLog(LOGE, FL("attr low RSSI failed"));
4043 goto fail;
4044 }
4045 request->ssid[i].rssi_low = nla_get_s32(tb2[PARAM_RSSI_LOW]);
4046 hddLog(LOG1, FL("RSSI low %d"), request->ssid[i].rssi_low);
4047
4048 /* Parse and fetch high RSSI */
4049 if (!tb2[PARAM_RSSI_HIGH]) {
4050 hddLog(LOGE, FL("attr high RSSI failed"));
4051 goto fail;
4052 }
4053 request->ssid[i].rssi_high = nla_get_u32(tb2[PARAM_RSSI_HIGH]);
4054 hddLog(LOG1, FL("RSSI high %d"), request->ssid[i].rssi_high);
4055 i++;
4056 }
4057
4058 context = &hdd_ctx->ext_scan_context;
4059 spin_lock(&hdd_context_lock);
4060 INIT_COMPLETION(context->response_event);
4061 context->request_id = request_id = request->request_id;
4062 spin_unlock(&hdd_context_lock);
4063
4064 status = sme_set_ssid_hotlist(hdd_ctx->hHal, request);
4065 if (!HAL_STATUS_SUCCESS(status)) {
4066 hddLog(LOGE,
4067 FL("sme_set_ssid_hotlist failed(err=%d)"), status);
4068 goto fail;
4069 }
4070
4071 vos_mem_free(request);
4072
4073 /* request was sent -- wait for the response */
4074 rc = wait_for_completion_timeout(&context->response_event,
4075 msecs_to_jiffies
4076 (WLAN_WAIT_TIME_EXTSCAN));
4077 if (!rc) {
4078 hddLog(LOGE, FL("sme_set_ssid_hotlist timed out"));
4079 retval = -ETIMEDOUT;
4080 } else {
4081 spin_lock(&hdd_context_lock);
4082 if (context->request_id == request_id)
4083 retval = context->response_status;
4084 else
4085 retval = -EINVAL;
4086 spin_unlock(&hdd_context_lock);
4087 }
4088
4089 return retval;
4090
4091fail:
4092 vos_mem_free(request);
4093 return -EINVAL;
4094}
4095
4096/*
4097 * done with short names for the global vendor params
4098 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
4099 */
4100#undef PARAM_MAX
4101#undef PARAM_REQUEST_ID
4102#undef PARAMS_NUM_SSID
4103#undef THRESHOLD_PARAM
4104#undef PARAM_SSID
4105#undef PARAM_BAND
4106#undef PARAM_RSSI_LOW
4107#undef PARAM_RSSI_HIGH
4108
4109static int wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
4110 struct wireless_dev *wdev,
4111 const void *data, int dataLen)
4112{
4113 int ret = 0;
4114
4115 vos_ssr_protect(__func__);
4116 ret = __wlan_hdd_cfg80211_extscan_set_ssid_hotlist(wiphy, wdev, data,
4117 dataLen);
4118 vos_ssr_unprotect(__func__);
4119
4120 return ret;
4121}
4122
4123static int
4124__wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4125 struct wireless_dev *wdev,
4126 const void *data,
4127 int data_len)
4128{
4129 tSirEXTScanResetSsidHotlistReqParams request;
4130 struct net_device *dev = wdev->netdev;
4131 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
4132 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
4133 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4134 struct hdd_ext_scan_context *context;
4135 uint32_t request_id;
4136 eHalStatus status;
4137 int retval;
4138 unsigned long rc;
4139
4140 ENTER();
4141
4142 if (VOS_FTM_MODE == hdd_get_conparam()) {
4143 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4144 return -EINVAL;
4145 }
4146
4147 retval = wlan_hdd_validate_context(hdd_ctx);
4148 if (0 != retval) {
4149 hddLog(LOGE, FL("HDD context is not valid"));
4150 return -EINVAL;
4151 }
4152
4153 /* check the EXTScan Capability */
4154 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304155 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4156 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05304157 {
4158 hddLog(LOGE,
4159 FL("EXTScan not enabled/supported by Firmware"));
4160 return -EINVAL;
4161 }
4162
4163 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4164 data, data_len,
4165 wlan_hdd_extscan_config_policy)) {
4166 hddLog(LOGE, FL("Invalid ATTR"));
4167 return -EINVAL;
4168 }
4169
4170 /* Parse and fetch request Id */
4171 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4172 hddLog(LOGE, FL("attr request id failed"));
4173 return -EINVAL;
4174 }
4175
4176 request.requestId = nla_get_u32(
4177 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4178 request.sessionId = adapter->sessionId;
4179 hddLog(LOG1, FL("Request Id %d Session Id %d"), request.requestId,
4180 request.sessionId);
4181
4182 context = &hdd_ctx->ext_scan_context;
4183 spin_lock(&hdd_context_lock);
4184 INIT_COMPLETION(context->response_event);
4185 context->request_id = request_id = request.requestId;
4186 spin_unlock(&hdd_context_lock);
4187
4188 status = sme_reset_ssid_hotlist(hdd_ctx->hHal, &request);
4189 if (!HAL_STATUS_SUCCESS(status)) {
4190 hddLog(LOGE,
4191 FL("sme_reset_ssid_hotlist failed(err=%d)"), status);
4192 return -EINVAL;
4193 }
4194
4195 /* request was sent -- wait for the response */
4196 rc = wait_for_completion_timeout(&context->response_event,
4197 msecs_to_jiffies
4198 (WLAN_WAIT_TIME_EXTSCAN));
4199 if (!rc) {
4200 hddLog(LOGE, FL("sme_reset_ssid_hotlist timed out"));
4201 retval = -ETIMEDOUT;
4202 } else {
4203 spin_lock(&hdd_context_lock);
4204 if (context->request_id == request_id)
4205 retval = context->response_status;
4206 else
4207 retval = -EINVAL;
4208 spin_unlock(&hdd_context_lock);
4209 }
4210
4211 return retval;
4212}
4213
4214static int
4215wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4216 struct wireless_dev *wdev,
4217 const void *data,
4218 int data_len)
4219{
4220 int ret;
4221
4222 vos_ssr_protect(__func__);
4223 ret = __wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(wiphy, wdev,
4224 data, data_len);
4225 vos_ssr_unprotect(__func__);
4226
4227 return ret;
4228}
4229
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304230static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304231 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304232 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304233{
4234 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4235 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4236 tANI_U8 numChannels = 0;
4237 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304238 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304239 tWifiBand wifiBand;
4240 eHalStatus status;
4241 struct sk_buff *replySkb;
4242 tANI_U8 i;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304243 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304244
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304245 ENTER();
4246
Dino Mycle6fb96c12014-06-10 11:52:40 +05304247 status = wlan_hdd_validate_context(pHddCtx);
4248 if (0 != status)
4249 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304250 return -EINVAL;
4251 }
Dino Myclee8843b32014-07-04 14:21:45 +05304252
Dino Mycle6fb96c12014-06-10 11:52:40 +05304253 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4254 data, dataLen,
4255 wlan_hdd_extscan_config_policy)) {
4256 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4257 return -EINVAL;
4258 }
4259
4260 /* Parse and fetch request Id */
4261 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4262 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4263 return -EINVAL;
4264 }
4265 requestId = nla_get_u32(
4266 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4267 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4268
4269 /* Parse and fetch wifi band */
4270 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4271 {
4272 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4273 return -EINVAL;
4274 }
4275 wifiBand = nla_get_u32(
4276 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4277 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4278
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304279 /* Parse and fetch max channels */
4280 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4281 {
4282 hddLog(LOGE, FL("attr max channels failed"));
4283 return -EINVAL;
4284 }
4285 maxChannels = nla_get_u32(
4286 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4287 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4288
Dino Mycle6fb96c12014-06-10 11:52:40 +05304289 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
4290 wifiBand, ChannelList,
4291 &numChannels);
4292 if (eHAL_STATUS_SUCCESS != status) {
4293 hddLog(VOS_TRACE_LEVEL_ERROR,
4294 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4295 return -EINVAL;
4296 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304297
4298 numChannels = VOS_MIN(numChannels, maxChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304299 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304300
Dino Mycle6fb96c12014-06-10 11:52:40 +05304301 for (i = 0; i < numChannels; i++)
4302 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
4303
4304 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
4305 sizeof(u32) * numChannels +
4306 NLMSG_HDRLEN);
4307
4308 if (!replySkb) {
4309 hddLog(VOS_TRACE_LEVEL_ERROR,
4310 FL("valid channels: buffer alloc fail"));
4311 return -EINVAL;
4312 }
4313 if (nla_put_u32(replySkb,
4314 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
4315 numChannels) ||
4316 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
4317 sizeof(u32) * numChannels, ChannelList)) {
4318
4319 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4320 kfree_skb(replySkb);
4321 return -EINVAL;
4322 }
4323
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304324 ret = cfg80211_vendor_cmd_reply(replySkb);
4325
4326 EXIT();
4327 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304328}
4329
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304330static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4331 struct wireless_dev *wdev,
4332 const void *data, int dataLen)
4333{
4334 int ret = 0;
4335
4336 vos_ssr_protect(__func__);
4337 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4338 dataLen);
4339 vos_ssr_unprotect(__func__);
4340
4341 return ret;
4342}
4343
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304344static int hdd_extscan_start_fill_bucket_channel_spec(
4345 hdd_context_t *pHddCtx,
4346 tpSirEXTScanStartReqParams pReqMsg,
4347 struct nlattr **tb)
4348{
4349 struct nlattr *bucket[
4350 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4351 struct nlattr *channel[
4352 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4353 struct nlattr *buckets;
4354 struct nlattr *channels;
4355 int rem1, rem2;
4356 eHalStatus status;
4357 tANI_U8 bktIndex, j, numChannels;
4358 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4359 tANI_U32 passive_max_chn_time, active_max_chn_time;
4360
4361 bktIndex = 0;
4362
4363 nla_for_each_nested(buckets,
4364 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
4365 if (nla_parse(bucket,
4366 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4367 nla_data(buckets), nla_len(buckets), NULL)) {
4368 hddLog(LOGE, FL("nla_parse failed"));
4369 return -EINVAL;
4370 }
4371
4372 /* Parse and fetch bucket spec */
4373 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4374 hddLog(LOGE, FL("attr bucket index failed"));
4375 return -EINVAL;
4376 }
4377 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4378 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4379 hddLog(LOG1, FL("Bucket spec Index %d"),
4380 pReqMsg->buckets[bktIndex].bucket);
4381
4382 /* Parse and fetch wifi band */
4383 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4384 hddLog(LOGE, FL("attr wifi band failed"));
4385 return -EINVAL;
4386 }
4387 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4388 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4389 hddLog(LOG1, FL("Wifi band %d"),
4390 pReqMsg->buckets[bktIndex].band);
4391
4392 /* Parse and fetch period */
4393 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4394 hddLog(LOGE, FL("attr period failed"));
4395 return -EINVAL;
4396 }
4397 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4398 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4399 hddLog(LOG1, FL("period %d"),
4400 pReqMsg->buckets[bktIndex].period);
4401
4402 /* Parse and fetch report events */
4403 if (!bucket[
4404 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4405 hddLog(LOGE, FL("attr report events failed"));
4406 return -EINVAL;
4407 }
4408 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4409 bucket[
4410 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4411 hddLog(LOG1, FL("report events %d"),
4412 pReqMsg->buckets[bktIndex].reportEvents);
4413
4414 /* Parse and fetch max period */
4415 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4416 hddLog(LOGE, FL("attr max period failed"));
4417 return -EINVAL;
4418 }
4419 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4420 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4421 hddLog(LOG1, FL("max period %u"),
4422 pReqMsg->buckets[bktIndex].max_period);
4423
4424 /* Parse and fetch exponent */
4425 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4426 hddLog(LOGE, FL("attr exponent failed"));
4427 return -EINVAL;
4428 }
4429 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4430 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4431 hddLog(LOG1, FL("exponent %u"),
4432 pReqMsg->buckets[bktIndex].exponent);
4433
4434 /* Parse and fetch step count */
4435 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4436 hddLog(LOGE, FL("attr step count failed"));
4437 return -EINVAL;
4438 }
4439 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4440 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4441 hddLog(LOG1, FL("Step count %u"),
4442 pReqMsg->buckets[bktIndex].step_count);
4443
4444 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4445 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4446
4447 /* Framework shall pass the channel list if the input WiFi band is
4448 * WIFI_BAND_UNSPECIFIED.
4449 * If the input WiFi band is specified (any value other than
4450 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4451 */
4452 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4453 numChannels = 0;
4454 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4455 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4456 pReqMsg->buckets[bktIndex].band,
4457 chanList, &numChannels);
4458 if (!HAL_STATUS_SUCCESS(status)) {
4459 hddLog(LOGE,
4460 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4461 status);
4462 return -EINVAL;
4463 }
4464
4465 pReqMsg->buckets[bktIndex].numChannels =
4466 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4467 hddLog(LOG1, FL("Num channels %d"),
4468 pReqMsg->buckets[bktIndex].numChannels);
4469
4470 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4471 j++) {
4472 pReqMsg->buckets[bktIndex].channels[j].channel =
4473 chanList[j];
4474 pReqMsg->buckets[bktIndex].channels[j].
4475 chnlClass = 0;
4476 if (CSR_IS_CHANNEL_DFS(
4477 vos_freq_to_chan(chanList[j]))) {
4478 pReqMsg->buckets[bktIndex].channels[j].
4479 passive = 1;
4480 pReqMsg->buckets[bktIndex].channels[j].
4481 dwellTimeMs = passive_max_chn_time;
4482 } else {
4483 pReqMsg->buckets[bktIndex].channels[j].
4484 passive = 0;
4485 pReqMsg->buckets[bktIndex].channels[j].
4486 dwellTimeMs = active_max_chn_time;
4487 }
4488
4489 hddLog(LOG1,
4490 "Channel %u Passive %u Dwell time %u ms",
4491 pReqMsg->buckets[bktIndex].channels[j].channel,
4492 pReqMsg->buckets[bktIndex].channels[j].passive,
4493 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4494 }
4495
4496 bktIndex++;
4497 continue;
4498 }
4499
4500 /* Parse and fetch number of channels */
4501 if (!bucket[
4502 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4503 hddLog(LOGE, FL("attr num channels failed"));
4504 return -EINVAL;
4505 }
4506
4507 pReqMsg->buckets[bktIndex].numChannels =
4508 nla_get_u32(bucket[
4509 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4510 hddLog(LOG1, FL("num channels %d"),
4511 pReqMsg->buckets[bktIndex].numChannels);
4512
4513 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4514 hddLog(LOGE, FL("attr channel spec failed"));
4515 return -EINVAL;
4516 }
4517
4518 j = 0;
4519 nla_for_each_nested(channels,
4520 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4521 if (nla_parse(channel,
4522 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4523 nla_data(channels), nla_len(channels),
4524 wlan_hdd_extscan_config_policy)) {
4525 hddLog(LOGE, FL("nla_parse failed"));
4526 return -EINVAL;
4527 }
4528
4529 /* Parse and fetch channel */
4530 if (!channel[
4531 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4532 hddLog(LOGE, FL("attr channel failed"));
4533 return -EINVAL;
4534 }
4535 pReqMsg->buckets[bktIndex].channels[j].channel =
4536 nla_get_u32(channel[
4537 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4538 hddLog(LOG1, FL("channel %u"),
4539 pReqMsg->buckets[bktIndex].channels[j].channel);
4540
4541 /* Parse and fetch dwell time */
4542 if (!channel[
4543 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4544 hddLog(LOGE, FL("attr dwelltime failed"));
4545 return -EINVAL;
4546 }
4547 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4548 nla_get_u32(channel[
4549 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4550
4551 hddLog(LOG1, FL("Dwell time (%u ms)"),
4552 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4553
4554
4555 /* Parse and fetch channel spec passive */
4556 if (!channel[
4557 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4558 hddLog(LOGE,
4559 FL("attr channel spec passive failed"));
4560 return -EINVAL;
4561 }
4562 pReqMsg->buckets[bktIndex].channels[j].passive =
4563 nla_get_u8(channel[
4564 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4565 hddLog(LOG1, FL("Chnl spec passive %u"),
4566 pReqMsg->buckets[bktIndex].channels[j].passive);
4567
4568 j++;
4569 }
4570
4571 bktIndex++;
4572 }
4573
4574 return 0;
4575}
4576
4577
4578/*
4579 * define short names for the global vendor params
4580 * used by wlan_hdd_cfg80211_extscan_start()
4581 */
4582#define PARAM_MAX \
4583QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4584#define PARAM_REQUEST_ID \
4585QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4586#define PARAM_BASE_PERIOD \
4587QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4588#define PARAM_MAX_AP_PER_SCAN \
4589QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4590#define PARAM_RPT_THRHLD_PERCENT \
4591QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
4592#define PARAM_RPT_THRHLD_NUM_SCANS \
4593QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
4594#define PARAM_NUM_BUCKETS \
4595QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
4596
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304597static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304598 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304599 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304600{
Dino Myclee8843b32014-07-04 14:21:45 +05304601 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304602 struct net_device *dev = wdev->netdev;
4603 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4604 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4605 struct nlattr *tb[PARAM_MAX + 1];
4606 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304607 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304608 tANI_U32 request_id;
4609 struct hdd_ext_scan_context *context;
4610 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304611
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304612 ENTER();
4613
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304614 if (VOS_FTM_MODE == hdd_get_conparam()) {
4615 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4616 return -EINVAL;
4617 }
4618
Dino Mycle6fb96c12014-06-10 11:52:40 +05304619 status = wlan_hdd_validate_context(pHddCtx);
4620 if (0 != status)
4621 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304622 return -EINVAL;
4623 }
Dino Myclee8843b32014-07-04 14:21:45 +05304624 /* check the EXTScan Capability */
4625 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304626 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4627 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304628 {
4629 hddLog(VOS_TRACE_LEVEL_ERROR,
4630 FL("EXTScan not enabled/supported by Firmware"));
4631 return -EINVAL;
4632 }
4633
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304634 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304635 data, dataLen,
4636 wlan_hdd_extscan_config_policy)) {
4637 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4638 return -EINVAL;
4639 }
4640
4641 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304642 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304643 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4644 return -EINVAL;
4645 }
4646
Dino Myclee8843b32014-07-04 14:21:45 +05304647 pReqMsg = (tpSirEXTScanStartReqParams)
4648 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304649 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304650 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4651 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304652 }
4653
4654 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304655 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304656 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4657
4658 pReqMsg->sessionId = pAdapter->sessionId;
4659 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4660
4661 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304662 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304663 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4664 goto fail;
4665 }
4666 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304667 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304668 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4669 pReqMsg->basePeriod);
4670
4671 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304672 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304673 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4674 goto fail;
4675 }
4676 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304677 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304678 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4679 pReqMsg->maxAPperScan);
4680
4681 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304682 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304683 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4684 goto fail;
4685 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304686 pReqMsg->reportThresholdPercent = nla_get_u8(
4687 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304688 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304689 pReqMsg->reportThresholdPercent);
4690
4691 /* Parse and fetch report threshold num scans */
4692 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
4693 hddLog(LOGE, FL("attr report_threshold num scans failed"));
4694 goto fail;
4695 }
4696 pReqMsg->reportThresholdNumScans = nla_get_u8(
4697 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
4698 hddLog(LOG1, FL("Report Threshold num scans %d"),
4699 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304700
4701 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304702 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304703 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4704 goto fail;
4705 }
4706 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304707 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304708 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4709 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4710 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4711 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4712 }
4713 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4714 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304715
Dino Mycle6fb96c12014-06-10 11:52:40 +05304716 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4717 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4718 goto fail;
4719 }
4720
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304721 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304722
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304723 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
4724 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304725
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304726 context = &pHddCtx->ext_scan_context;
4727 spin_lock(&hdd_context_lock);
4728 INIT_COMPLETION(context->response_event);
4729 context->request_id = request_id = pReqMsg->requestId;
4730 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304731
Dino Mycle6fb96c12014-06-10 11:52:40 +05304732 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4733 if (!HAL_STATUS_SUCCESS(status)) {
4734 hddLog(VOS_TRACE_LEVEL_ERROR,
4735 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304736 goto fail;
4737 }
4738
4739 /* request was sent -- wait for the response */
4740 rc = wait_for_completion_timeout(&context->response_event,
4741 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4742
4743 if (!rc) {
4744 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
4745 retval = -ETIMEDOUT;
4746 } else {
4747 spin_lock(&hdd_context_lock);
4748 if (context->request_id == request_id)
4749 retval = context->response_status;
4750 else
4751 retval = -EINVAL;
4752 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304753 }
4754
Dino Myclee8843b32014-07-04 14:21:45 +05304755 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304756 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304757 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304758
4759fail:
4760 vos_mem_free(pReqMsg);
4761 return -EINVAL;
4762}
4763
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304764/*
4765 * done with short names for the global vendor params
4766 * used by wlan_hdd_cfg80211_extscan_start()
4767 */
4768#undef PARAM_MAX
4769#undef PARAM_REQUEST_ID
4770#undef PARAM_BASE_PERIOD
4771#undef PARAMS_MAX_AP_PER_SCAN
4772#undef PARAMS_RPT_THRHLD_PERCENT
4773#undef PARAMS_RPT_THRHLD_NUM_SCANS
4774#undef PARAMS_NUM_BUCKETS
4775
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304776static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4777 struct wireless_dev *wdev,
4778 const void *data, int dataLen)
4779{
4780 int ret = 0;
4781
4782 vos_ssr_protect(__func__);
4783 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4784 vos_ssr_unprotect(__func__);
4785
4786 return ret;
4787}
4788
4789static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304790 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304791 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304792{
Dino Myclee8843b32014-07-04 14:21:45 +05304793 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304794 struct net_device *dev = wdev->netdev;
4795 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4796 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4797 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4798 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304799 int retval;
4800 unsigned long rc;
4801 struct hdd_ext_scan_context *context;
4802 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304803
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304804 ENTER();
4805
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304806 if (VOS_FTM_MODE == hdd_get_conparam()) {
4807 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4808 return -EINVAL;
4809 }
4810
Dino Mycle6fb96c12014-06-10 11:52:40 +05304811 status = wlan_hdd_validate_context(pHddCtx);
4812 if (0 != status)
4813 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304814 return -EINVAL;
4815 }
Dino Myclee8843b32014-07-04 14:21:45 +05304816 /* check the EXTScan Capability */
4817 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304818 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4819 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304820 {
4821 hddLog(VOS_TRACE_LEVEL_ERROR,
4822 FL("EXTScan not enabled/supported by Firmware"));
4823 return -EINVAL;
4824 }
4825
Dino Mycle6fb96c12014-06-10 11:52:40 +05304826 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4827 data, dataLen,
4828 wlan_hdd_extscan_config_policy)) {
4829 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4830 return -EINVAL;
4831 }
4832
4833 /* Parse and fetch request Id */
4834 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4835 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4836 return -EINVAL;
4837 }
4838
Dino Myclee8843b32014-07-04 14:21:45 +05304839 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304840 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304841 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304842
Dino Myclee8843b32014-07-04 14:21:45 +05304843 reqMsg.sessionId = pAdapter->sessionId;
4844 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304845
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304846 context = &pHddCtx->ext_scan_context;
4847 spin_lock(&hdd_context_lock);
4848 INIT_COMPLETION(context->response_event);
4849 context->request_id = request_id = reqMsg.sessionId;
4850 spin_unlock(&hdd_context_lock);
4851
Dino Myclee8843b32014-07-04 14:21:45 +05304852 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304853 if (!HAL_STATUS_SUCCESS(status)) {
4854 hddLog(VOS_TRACE_LEVEL_ERROR,
4855 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304856 return -EINVAL;
4857 }
4858
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304859 /* request was sent -- wait for the response */
4860 rc = wait_for_completion_timeout(&context->response_event,
4861 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4862
4863 if (!rc) {
4864 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
4865 retval = -ETIMEDOUT;
4866 } else {
4867 spin_lock(&hdd_context_lock);
4868 if (context->request_id == request_id)
4869 retval = context->response_status;
4870 else
4871 retval = -EINVAL;
4872 spin_unlock(&hdd_context_lock);
4873 }
4874
4875 return retval;
4876
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304877 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304878 return 0;
4879}
4880
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304881static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4882 struct wireless_dev *wdev,
4883 const void *data, int dataLen)
4884{
4885 int ret = 0;
4886
4887 vos_ssr_protect(__func__);
4888 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4889 vos_ssr_unprotect(__func__);
4890
4891 return ret;
4892}
4893
4894static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304895 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304896 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304897{
Dino Myclee8843b32014-07-04 14:21:45 +05304898 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304899 struct net_device *dev = wdev->netdev;
4900 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4901 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4902 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4903 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304904 struct hdd_ext_scan_context *context;
4905 tANI_U32 request_id;
4906 unsigned long rc;
4907 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304908
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304909 ENTER();
4910
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304911 if (VOS_FTM_MODE == hdd_get_conparam()) {
4912 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4913 return -EINVAL;
4914 }
4915
Dino Mycle6fb96c12014-06-10 11:52:40 +05304916 status = wlan_hdd_validate_context(pHddCtx);
4917 if (0 != status)
4918 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304919 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304920 return -EINVAL;
4921 }
Dino Myclee8843b32014-07-04 14:21:45 +05304922 /* check the EXTScan Capability */
4923 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304924 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4925 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304926 {
4927 hddLog(VOS_TRACE_LEVEL_ERROR,
4928 FL("EXTScan not enabled/supported by Firmware"));
4929 return -EINVAL;
4930 }
4931
Dino Mycle6fb96c12014-06-10 11:52:40 +05304932 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4933 data, dataLen,
4934 wlan_hdd_extscan_config_policy)) {
4935 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4936 return -EINVAL;
4937 }
4938
4939 /* Parse and fetch request Id */
4940 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4941 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4942 return -EINVAL;
4943 }
4944
Dino Myclee8843b32014-07-04 14:21:45 +05304945 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304946 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304947 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304948
Dino Myclee8843b32014-07-04 14:21:45 +05304949 reqMsg.sessionId = pAdapter->sessionId;
4950 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304951
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304952 context = &pHddCtx->ext_scan_context;
4953 spin_lock(&hdd_context_lock);
4954 INIT_COMPLETION(context->response_event);
4955 context->request_id = request_id = reqMsg.requestId;
4956 spin_unlock(&hdd_context_lock);
4957
Dino Myclee8843b32014-07-04 14:21:45 +05304958 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304959 if (!HAL_STATUS_SUCCESS(status)) {
4960 hddLog(VOS_TRACE_LEVEL_ERROR,
4961 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304962 return -EINVAL;
4963 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304964
4965 /* request was sent -- wait for the response */
4966 rc = wait_for_completion_timeout(&context->response_event,
4967 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4968 if (!rc) {
4969 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
4970 retval = -ETIMEDOUT;
4971 } else {
4972 spin_lock(&hdd_context_lock);
4973 if (context->request_id == request_id)
4974 retval = context->response_status;
4975 else
4976 retval = -EINVAL;
4977 spin_unlock(&hdd_context_lock);
4978 }
4979
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304980 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304981 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304982}
4983
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304984static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4985 struct wireless_dev *wdev,
4986 const void *data, int dataLen)
4987{
4988 int ret = 0;
4989
4990 vos_ssr_protect(__func__);
4991 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4992 vos_ssr_unprotect(__func__);
4993
4994 return ret;
4995}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304996#endif /* WLAN_FEATURE_EXTSCAN */
4997
Atul Mittal115287b2014-07-08 13:26:33 +05304998/*EXT TDLS*/
4999static const struct nla_policy
5000wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
5001{
5002 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
5003 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5004 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5005 {.type = NLA_S32 },
5006 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5007 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5008
5009};
5010
5011static const struct nla_policy
5012wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5013{
5014 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
5015
5016};
5017
5018static const struct nla_policy
5019wlan_hdd_tdls_config_state_change_policy[
5020 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5021{
5022 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
5023 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5024 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305025 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5026 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5027 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305028
5029};
5030
5031static const struct nla_policy
5032wlan_hdd_tdls_config_get_status_policy[
5033 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5034{
5035 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
5036 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5037 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305038 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5039 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5040 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305041
5042};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305043
5044static const struct nla_policy
5045wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5046{
5047 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
5048};
5049
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305050static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305051 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305052 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305053 int data_len)
5054{
5055
5056 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5057 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5058
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305059 ENTER();
5060
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305061 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305062 return -EINVAL;
5063 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305064 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305065 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305066 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305067 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305068 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305069 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305070 return -ENOTSUPP;
5071 }
5072
5073 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5074 data, data_len, wlan_hdd_mac_config)) {
5075 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5076 return -EINVAL;
5077 }
5078
5079 /* Parse and fetch mac address */
5080 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5081 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5082 return -EINVAL;
5083 }
5084
5085 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5086 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5087 VOS_MAC_ADDR_LAST_3_BYTES);
5088
Siddharth Bhal76972212014-10-15 16:22:51 +05305089 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5090
5091 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305092 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5093 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305094 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5095 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5096 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5097 {
5098 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5099 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5100 VOS_MAC_ADDRESS_LEN);
5101 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305102 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305103
Siddharth Bhal76972212014-10-15 16:22:51 +05305104 if (VOS_STATUS_SUCCESS != hdd_processSpoofMacAddrRequest(pHddCtx))
5105 {
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305106 hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
5107 }
5108
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305109 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305110 return 0;
5111}
5112
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305113static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5114 struct wireless_dev *wdev,
5115 const void *data,
5116 int data_len)
5117{
5118 int ret = 0;
5119
5120 vos_ssr_protect(__func__);
5121 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5122 vos_ssr_unprotect(__func__);
5123
5124 return ret;
5125}
5126
5127static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305128 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305129 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305130 int data_len)
5131{
5132 u8 peer[6] = {0};
5133 struct net_device *dev = wdev->netdev;
5134 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5135 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5136 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5137 eHalStatus ret;
5138 tANI_S32 state;
5139 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305140 tANI_S32 global_operating_class = 0;
5141 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305142 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305143 int retVal;
5144
5145 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305146
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305147 if (!pAdapter) {
5148 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5149 return -EINVAL;
5150 }
5151
Atul Mittal115287b2014-07-08 13:26:33 +05305152 ret = wlan_hdd_validate_context(pHddCtx);
5153 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305154 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305155 return -EINVAL;
5156 }
5157 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305158 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305159 return -ENOTSUPP;
5160 }
5161 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5162 data, data_len,
5163 wlan_hdd_tdls_config_get_status_policy)) {
5164 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5165 return -EINVAL;
5166 }
5167
5168 /* Parse and fetch mac address */
5169 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5170 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5171 return -EINVAL;
5172 }
5173
5174 memcpy(peer, nla_data(
5175 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5176 sizeof(peer));
5177 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5178
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305179 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305180
Atul Mittal115287b2014-07-08 13:26:33 +05305181 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305182 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305183 NLMSG_HDRLEN);
5184
5185 if (!skb) {
5186 hddLog(VOS_TRACE_LEVEL_ERROR,
5187 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5188 return -EINVAL;
5189 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305190 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reason (%d) Status (%d) class (%d) channel (%d) peer" MAC_ADDRESS_STR),
Atul Mittal115287b2014-07-08 13:26:33 +05305191 reason,
5192 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305193 global_operating_class,
5194 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305195 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305196 if (nla_put_s32(skb,
5197 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5198 state) ||
5199 nla_put_s32(skb,
5200 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5201 reason) ||
5202 nla_put_s32(skb,
5203 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5204 global_operating_class) ||
5205 nla_put_s32(skb,
5206 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5207 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305208
5209 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5210 goto nla_put_failure;
5211 }
5212
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305213 retVal = cfg80211_vendor_cmd_reply(skb);
5214 EXIT();
5215 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305216
5217nla_put_failure:
5218 kfree_skb(skb);
5219 return -EINVAL;
5220}
5221
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305222static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5223 struct wireless_dev *wdev,
5224 const void *data,
5225 int data_len)
5226{
5227 int ret = 0;
5228
5229 vos_ssr_protect(__func__);
5230 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5231 vos_ssr_unprotect(__func__);
5232
5233 return ret;
5234}
5235
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305236static int wlan_hdd_cfg80211_exttdls_callback(
5237#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5238 const tANI_U8* mac,
5239#else
5240 tANI_U8* mac,
5241#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305242 tANI_S32 state,
5243 tANI_S32 reason,
5244 void *ctx)
5245{
5246 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305247 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305248 tANI_S32 global_operating_class = 0;
5249 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305250 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305251
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305252 ENTER();
5253
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305254 if (!pAdapter) {
5255 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5256 return -EINVAL;
5257 }
5258
5259 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305260 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305261 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305262 return -EINVAL;
5263 }
5264
5265 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305266 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305267 return -ENOTSUPP;
5268 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305269 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5270#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5271 NULL,
5272#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305273 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5274 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5275 GFP_KERNEL);
5276
5277 if (!skb) {
5278 hddLog(VOS_TRACE_LEVEL_ERROR,
5279 FL("cfg80211_vendor_event_alloc failed"));
5280 return -EINVAL;
5281 }
5282 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305283 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5284 reason,
5285 state,
5286 global_operating_class,
5287 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305288 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5289 MAC_ADDR_ARRAY(mac));
5290
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305291 if (nla_put(skb,
5292 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5293 VOS_MAC_ADDR_SIZE, mac) ||
5294 nla_put_s32(skb,
5295 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5296 state) ||
5297 nla_put_s32(skb,
5298 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5299 reason) ||
5300 nla_put_s32(skb,
5301 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5302 channel) ||
5303 nla_put_s32(skb,
5304 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5305 global_operating_class)
5306 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305307 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5308 goto nla_put_failure;
5309 }
5310
5311 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305312 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305313 return (0);
5314
5315nla_put_failure:
5316 kfree_skb(skb);
5317 return -EINVAL;
5318}
5319
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305320static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305321 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305322 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305323 int data_len)
5324{
5325 u8 peer[6] = {0};
5326 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305327 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5328 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5329 eHalStatus status;
5330 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305331 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305332 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305333
5334 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305335
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305336 if (!dev) {
5337 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5338 return -EINVAL;
5339 }
5340
5341 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5342 if (!pAdapter) {
5343 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5344 return -EINVAL;
5345 }
5346
Atul Mittal115287b2014-07-08 13:26:33 +05305347 status = wlan_hdd_validate_context(pHddCtx);
5348 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305349 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305350 return -EINVAL;
5351 }
5352 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305353 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305354 return -ENOTSUPP;
5355 }
5356 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5357 data, data_len,
5358 wlan_hdd_tdls_config_enable_policy)) {
5359 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5360 return -EINVAL;
5361 }
5362
5363 /* Parse and fetch mac address */
5364 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5365 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5366 return -EINVAL;
5367 }
5368
5369 memcpy(peer, nla_data(
5370 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5371 sizeof(peer));
5372 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5373
5374 /* Parse and fetch channel */
5375 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5376 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5377 return -EINVAL;
5378 }
5379 pReqMsg.channel = nla_get_s32(
5380 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5381 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5382
5383 /* Parse and fetch global operating class */
5384 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5385 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5386 return -EINVAL;
5387 }
5388 pReqMsg.global_operating_class = nla_get_s32(
5389 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5390 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5391 pReqMsg.global_operating_class);
5392
5393 /* Parse and fetch latency ms */
5394 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5395 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5396 return -EINVAL;
5397 }
5398 pReqMsg.max_latency_ms = nla_get_s32(
5399 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5400 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5401 pReqMsg.max_latency_ms);
5402
5403 /* Parse and fetch required bandwidth kbps */
5404 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5405 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5406 return -EINVAL;
5407 }
5408
5409 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5410 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5411 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5412 pReqMsg.min_bandwidth_kbps);
5413
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305414 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305415 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305416 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305417 wlan_hdd_cfg80211_exttdls_callback);
5418
5419 EXIT();
5420 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305421}
5422
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305423static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5424 struct wireless_dev *wdev,
5425 const void *data,
5426 int data_len)
5427{
5428 int ret = 0;
5429
5430 vos_ssr_protect(__func__);
5431 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5432 vos_ssr_unprotect(__func__);
5433
5434 return ret;
5435}
5436
5437static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305438 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305439 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305440 int data_len)
5441{
5442 u8 peer[6] = {0};
5443 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305444 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5445 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5446 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305447 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305448 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305449
5450 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305451
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305452 if (!dev) {
5453 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5454 return -EINVAL;
5455 }
5456
5457 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5458 if (!pAdapter) {
5459 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5460 return -EINVAL;
5461 }
5462
Atul Mittal115287b2014-07-08 13:26:33 +05305463 status = wlan_hdd_validate_context(pHddCtx);
5464 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305465 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305466 return -EINVAL;
5467 }
5468 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305469 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305470 return -ENOTSUPP;
5471 }
5472 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5473 data, data_len,
5474 wlan_hdd_tdls_config_disable_policy)) {
5475 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5476 return -EINVAL;
5477 }
5478 /* Parse and fetch mac address */
5479 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5480 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5481 return -EINVAL;
5482 }
5483
5484 memcpy(peer, nla_data(
5485 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5486 sizeof(peer));
5487 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5488
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305489 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5490
5491 EXIT();
5492 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305493}
5494
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305495static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5496 struct wireless_dev *wdev,
5497 const void *data,
5498 int data_len)
5499{
5500 int ret = 0;
5501
5502 vos_ssr_protect(__func__);
5503 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5504 vos_ssr_unprotect(__func__);
5505
5506 return ret;
5507}
5508
Dasari Srinivas7875a302014-09-26 17:50:57 +05305509static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305510__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305511 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305512 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305513{
5514 struct net_device *dev = wdev->netdev;
5515 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5516 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5517 struct sk_buff *skb = NULL;
5518 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305519 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305520
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305521 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305522
5523 ret = wlan_hdd_validate_context(pHddCtx);
5524 if (0 != ret)
5525 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305526 return ret;
5527 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305528 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5529 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5530 fset |= WIFI_FEATURE_INFRA;
5531 }
5532
5533 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5534 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5535 fset |= WIFI_FEATURE_INFRA_5G;
5536 }
5537
5538#ifdef WLAN_FEATURE_P2P
5539 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5540 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5541 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5542 fset |= WIFI_FEATURE_P2P;
5543 }
5544#endif
5545
5546 /* Soft-AP is supported currently by default */
5547 fset |= WIFI_FEATURE_SOFT_AP;
5548
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305549 /* HOTSPOT is a supplicant feature, enable it by default */
5550 fset |= WIFI_FEATURE_HOTSPOT;
5551
Dasari Srinivas7875a302014-09-26 17:50:57 +05305552#ifdef WLAN_FEATURE_EXTSCAN
5553 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305554 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
5555 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
5556 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305557 fset |= WIFI_FEATURE_EXTSCAN;
5558 }
5559#endif
5560
Dasari Srinivas7875a302014-09-26 17:50:57 +05305561 if (sme_IsFeatureSupportedByFW(NAN)) {
5562 hddLog(LOG1, FL("NAN is supported by firmware"));
5563 fset |= WIFI_FEATURE_NAN;
5564 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305565
5566 /* D2D RTT is not supported currently by default */
5567 if (sme_IsFeatureSupportedByFW(RTT)) {
5568 hddLog(LOG1, FL("RTT is supported by firmware"));
5569 fset |= WIFI_FEATURE_D2AP_RTT;
5570 }
5571
5572#ifdef FEATURE_WLAN_BATCH_SCAN
5573 if (fset & WIFI_FEATURE_EXTSCAN) {
5574 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5575 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5576 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5577 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5578 fset |= WIFI_FEATURE_BATCH_SCAN;
5579 }
5580#endif
5581
5582#ifdef FEATURE_WLAN_SCAN_PNO
5583 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5584 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5585 hddLog(LOG1, FL("PNO is supported by firmware"));
5586 fset |= WIFI_FEATURE_PNO;
5587 }
5588#endif
5589
5590 /* STA+STA is supported currently by default */
5591 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5592
5593#ifdef FEATURE_WLAN_TDLS
5594 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5595 sme_IsFeatureSupportedByFW(TDLS)) {
5596 hddLog(LOG1, FL("TDLS is supported by firmware"));
5597 fset |= WIFI_FEATURE_TDLS;
5598 }
5599
5600 /* TDLS_OFFCHANNEL is not supported currently by default */
5601#endif
5602
5603#ifdef WLAN_AP_STA_CONCURRENCY
5604 /* AP+STA concurrency is supported currently by default */
5605 fset |= WIFI_FEATURE_AP_STA;
5606#endif
5607
Mukul Sharma5add0532015-08-17 15:57:47 +05305608#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5609 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
5610 hddLog(LOG1, FL("Link layer stats is supported by driver"));
5611#endif
5612
Dasari Srinivas7875a302014-09-26 17:50:57 +05305613 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5614 NLMSG_HDRLEN);
5615
5616 if (!skb) {
5617 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5618 return -EINVAL;
5619 }
5620 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5621
5622 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5623 hddLog(LOGE, FL("nla put fail"));
5624 goto nla_put_failure;
5625 }
5626
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305627 ret = cfg80211_vendor_cmd_reply(skb);
5628 EXIT();
5629 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305630
5631nla_put_failure:
5632 kfree_skb(skb);
5633 return -EINVAL;
5634}
5635
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305636static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305637wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5638 struct wireless_dev *wdev,
5639 const void *data, int data_len)
5640{
5641 int ret = 0;
5642
5643 vos_ssr_protect(__func__);
5644 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5645 vos_ssr_unprotect(__func__);
5646
5647 return ret;
5648}
5649
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305650
5651static const struct
5652nla_policy
5653qca_wlan_vendor_wifi_logger_get_ring_data_policy
5654[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
5655 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
5656 = {.type = NLA_U32 },
5657};
5658
5659static int
5660 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5661 struct wireless_dev *wdev,
5662 const void *data,
5663 int data_len)
5664{
5665 int ret;
5666 VOS_STATUS status;
5667 uint32_t ring_id;
5668 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5669 struct nlattr *tb
5670 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
5671
5672 ENTER();
5673
5674 ret = wlan_hdd_validate_context(hdd_ctx);
5675 if (0 != ret) {
5676 return ret;
5677 }
5678
5679 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
5680 data, data_len,
5681 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
5682 hddLog(LOGE, FL("Invalid attribute"));
5683 return -EINVAL;
5684 }
5685
5686 /* Parse and fetch ring id */
5687 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
5688 hddLog(LOGE, FL("attr ATTR failed"));
5689 return -EINVAL;
5690 }
5691
5692 ring_id = nla_get_u32(
5693 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
5694
5695 hddLog(LOG1, FL("Bug report triggered by framework"));
5696
5697 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
5698 WLAN_LOG_INDICATOR_FRAMEWORK,
5699 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05305700 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305701 );
5702 if (VOS_STATUS_SUCCESS != status) {
5703 hddLog(LOGE, FL("Failed to trigger bug report"));
5704
5705 return -EINVAL;
5706 }
5707
5708 return 0;
5709
5710
5711}
5712
5713
5714static int
5715 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5716 struct wireless_dev *wdev,
5717 const void *data,
5718 int data_len)
5719{
5720 int ret = 0;
5721
5722 vos_ssr_protect(__func__);
5723 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
5724 wdev, data, data_len);
5725 vos_ssr_unprotect(__func__);
5726
5727 return ret;
5728
5729}
5730
5731
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305732static int
5733__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305734 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305735 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305736{
5737 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5738 uint8_t i, feature_sets, max_feature_sets;
5739 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5740 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305741 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5742 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305743
5744 ENTER();
5745
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305746 ret = wlan_hdd_validate_context(pHddCtx);
5747 if (0 != ret)
5748 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305749 return ret;
5750 }
5751
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305752 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5753 data, data_len, NULL)) {
5754 hddLog(LOGE, FL("Invalid ATTR"));
5755 return -EINVAL;
5756 }
5757
5758 /* Parse and fetch max feature set */
5759 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5760 hddLog(LOGE, FL("Attr max feature set size failed"));
5761 return -EINVAL;
5762 }
5763 max_feature_sets = nla_get_u32(
5764 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5765 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5766
5767 /* Fill feature combination matrix */
5768 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305769 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5770 WIFI_FEATURE_P2P;
5771
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305772 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5773 WIFI_FEATURE_SOFT_AP;
5774
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305775 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5776 WIFI_FEATURE_SOFT_AP;
5777
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305778 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5779 WIFI_FEATURE_SOFT_AP |
5780 WIFI_FEATURE_P2P;
5781
5782 /* Add more feature combinations here */
5783
5784 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5785 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5786 hddLog(LOG1, "Feature set matrix");
5787 for (i = 0; i < feature_sets; i++)
5788 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5789
5790 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5791 sizeof(u32) * feature_sets +
5792 NLMSG_HDRLEN);
5793
5794 if (reply_skb) {
5795 if (nla_put_u32(reply_skb,
5796 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5797 feature_sets) ||
5798 nla_put(reply_skb,
5799 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5800 sizeof(u32) * feature_sets, feature_set_matrix)) {
5801 hddLog(LOGE, FL("nla put fail"));
5802 kfree_skb(reply_skb);
5803 return -EINVAL;
5804 }
5805
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305806 ret = cfg80211_vendor_cmd_reply(reply_skb);
5807 EXIT();
5808 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305809 }
5810 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5811 return -ENOMEM;
5812
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305813}
5814
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305815static int
5816wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5817 struct wireless_dev *wdev,
5818 const void *data, int data_len)
5819{
5820 int ret = 0;
5821
5822 vos_ssr_protect(__func__);
5823 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5824 data_len);
5825 vos_ssr_unprotect(__func__);
5826
5827 return ret;
5828}
5829
c_manjeecfd1efb2015-09-25 19:32:34 +05305830
5831static int
5832__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5833 struct wireless_dev *wdev,
5834 const void *data, int data_len)
5835{
5836 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5837 int ret;
5838 ENTER();
5839
5840 ret = wlan_hdd_validate_context(pHddCtx);
5841 if (0 != ret)
5842 {
5843 return ret;
5844 }
5845
5846 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
5847 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
5848 {
5849 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
5850 return -EINVAL;
5851 }
5852 /*call common API for FW mem dump req*/
5853 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
5854
c_manjee04b4c5c2015-10-13 18:35:01 +05305855 if (true == ret)
5856 {
5857 /*indicate to userspace the status of fw mem dump */
5858 wlan_indicate_mem_dump_complete(true);
5859 }
5860 else
5861 {
5862 /*else send failure to userspace */
5863 wlan_indicate_mem_dump_complete(false);
5864 }
c_manjeecfd1efb2015-09-25 19:32:34 +05305865 EXIT();
5866 return ret;
5867}
5868
5869/**
5870 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
5871 * @wiphy: pointer to wireless wiphy structure.
5872 * @wdev: pointer to wireless_dev structure.
5873 * @data: Pointer to the NL data.
5874 * @data_len:Length of @data
5875 *
5876 * This is called when wlan driver needs to get the firmware memory dump
5877 * via vendor specific command.
5878 *
5879 * Return: 0 on success, error number otherwise.
5880 */
5881
5882static int
5883wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5884 struct wireless_dev *wdev,
5885 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05305886{
5887 int ret = 0;
5888 vos_ssr_protect(__func__);
5889 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
5890 data_len);
5891 vos_ssr_unprotect(__func__);
5892 return ret;
5893}
c_manjeecfd1efb2015-09-25 19:32:34 +05305894
Sushant Kaushik8e644982015-09-23 12:18:54 +05305895static const struct
5896nla_policy
5897qca_wlan_vendor_wifi_logger_start_policy
5898[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
5899 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
5900 = {.type = NLA_U32 },
5901 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
5902 = {.type = NLA_U32 },
5903 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
5904 = {.type = NLA_U32 },
5905};
5906
5907/**
5908 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
5909 * or disable the collection of packet statistics from the firmware
5910 * @wiphy: WIPHY structure pointer
5911 * @wdev: Wireless device structure pointer
5912 * @data: Pointer to the data received
5913 * @data_len: Length of the data received
5914 *
5915 * This function is used to enable or disable the collection of packet
5916 * statistics from the firmware
5917 *
5918 * Return: 0 on success and errno on failure
5919 */
5920static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5921 struct wireless_dev *wdev,
5922 const void *data,
5923 int data_len)
5924{
5925 eHalStatus status;
5926 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5927 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
5928 tAniWifiStartLog start_log;
5929
5930 status = wlan_hdd_validate_context(hdd_ctx);
5931 if (0 != status) {
5932 return -EINVAL;
5933 }
5934
5935 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
5936 data, data_len,
5937 qca_wlan_vendor_wifi_logger_start_policy)) {
5938 hddLog(LOGE, FL("Invalid attribute"));
5939 return -EINVAL;
5940 }
5941
5942 /* Parse and fetch ring id */
5943 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
5944 hddLog(LOGE, FL("attr ATTR failed"));
5945 return -EINVAL;
5946 }
5947 start_log.ringId = nla_get_u32(
5948 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
5949 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
5950
5951 /* Parse and fetch verbose level */
5952 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
5953 hddLog(LOGE, FL("attr verbose_level failed"));
5954 return -EINVAL;
5955 }
5956 start_log.verboseLevel = nla_get_u32(
5957 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
5958 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
5959
5960 /* Parse and fetch flag */
5961 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
5962 hddLog(LOGE, FL("attr flag failed"));
5963 return -EINVAL;
5964 }
5965 start_log.flag = nla_get_u32(
5966 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
5967 hddLog(LOG1, FL("flag=%d"), start_log.flag);
5968
5969 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05305970 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
5971 !vos_isPktStatsEnabled()))
5972
Sushant Kaushik8e644982015-09-23 12:18:54 +05305973 {
5974 hddLog(LOGE, FL("per pkt stats not enabled"));
5975 return -EINVAL;
5976 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05305977
Sushant Kaushik33200572015-08-05 16:46:20 +05305978 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305979 return 0;
5980}
5981
5982/**
5983 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
5984 * or disable the collection of packet statistics from the firmware
5985 * @wiphy: WIPHY structure pointer
5986 * @wdev: Wireless device structure pointer
5987 * @data: Pointer to the data received
5988 * @data_len: Length of the data received
5989 *
5990 * This function is used to enable or disable the collection of packet
5991 * statistics from the firmware
5992 *
5993 * Return: 0 on success and errno on failure
5994 */
5995static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5996 struct wireless_dev *wdev,
5997 const void *data,
5998 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05305999{
6000 int ret = 0;
6001
6002 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306003
6004 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6005 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306006 vos_ssr_unprotect(__func__);
6007
6008 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306009}
6010
6011
Agarwal Ashish738843c2014-09-25 12:27:56 +05306012static const struct nla_policy
6013wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6014 +1] =
6015{
6016 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6017};
6018
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306019static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306020 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306021 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306022 int data_len)
6023{
6024 struct net_device *dev = wdev->netdev;
6025 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6026 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6027 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6028 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6029 eHalStatus status;
6030 u32 dfsFlag = 0;
6031
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306032 ENTER();
6033
Agarwal Ashish738843c2014-09-25 12:27:56 +05306034 status = wlan_hdd_validate_context(pHddCtx);
6035 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306036 return -EINVAL;
6037 }
6038 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6039 data, data_len,
6040 wlan_hdd_set_no_dfs_flag_config_policy)) {
6041 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6042 return -EINVAL;
6043 }
6044
6045 /* Parse and fetch required bandwidth kbps */
6046 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6047 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6048 return -EINVAL;
6049 }
6050
6051 dfsFlag = nla_get_u32(
6052 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6053 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6054 dfsFlag);
6055
6056 pHddCtx->disable_dfs_flag = dfsFlag;
6057
6058 sme_disable_dfs_channel(hHal, dfsFlag);
6059 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306060
6061 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306062 return 0;
6063}
Atul Mittal115287b2014-07-08 13:26:33 +05306064
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306065static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6066 struct wireless_dev *wdev,
6067 const void *data,
6068 int data_len)
6069{
6070 int ret = 0;
6071
6072 vos_ssr_protect(__func__);
6073 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6074 vos_ssr_unprotect(__func__);
6075
6076 return ret;
6077
6078}
6079
Mukul Sharma2a271632014-10-13 14:59:01 +05306080const struct
6081nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6082{
6083 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
6084 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
6085};
6086
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306087static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306088 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306089{
6090
6091 u8 bssid[6] = {0};
6092 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6093 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6094 eHalStatus status = eHAL_STATUS_SUCCESS;
6095 v_U32_t isFwrRoamEnabled = FALSE;
6096 int ret;
6097
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306098 ENTER();
6099
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306100 ret = wlan_hdd_validate_context(pHddCtx);
6101 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306102 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306103 }
6104
6105 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6106 data, data_len,
6107 qca_wlan_vendor_attr);
6108 if (ret){
6109 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6110 return -EINVAL;
6111 }
6112
6113 /* Parse and fetch Enable flag */
6114 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6115 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6116 return -EINVAL;
6117 }
6118
6119 isFwrRoamEnabled = nla_get_u32(
6120 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6121
6122 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6123
6124 /* Parse and fetch bssid */
6125 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6126 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6127 return -EINVAL;
6128 }
6129
6130 memcpy(bssid, nla_data(
6131 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6132 sizeof(bssid));
6133 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6134
6135 //Update roaming
6136 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306137 EXIT();
Mukul Sharma2a271632014-10-13 14:59:01 +05306138 return status;
6139}
6140
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306141static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6142 struct wireless_dev *wdev, const void *data, int data_len)
6143{
6144 int ret = 0;
6145
6146 vos_ssr_protect(__func__);
6147 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6148 vos_ssr_unprotect(__func__);
6149
6150 return ret;
6151}
6152
Sushant Kaushik847890c2015-09-28 16:05:17 +05306153static const struct
6154nla_policy
6155qca_wlan_vendor_get_wifi_info_policy[
6156 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6157 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6158 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6159};
6160
6161
6162/**
6163 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6164 * @wiphy: pointer to wireless wiphy structure.
6165 * @wdev: pointer to wireless_dev structure.
6166 * @data: Pointer to the data to be passed via vendor interface
6167 * @data_len:Length of the data to be passed
6168 *
6169 * This is called when wlan driver needs to send wifi driver related info
6170 * (driver/fw version) to the user space application upon request.
6171 *
6172 * Return: Return the Success or Failure code.
6173 */
6174static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6175 struct wireless_dev *wdev,
6176 const void *data, int data_len)
6177{
6178 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6179 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6180 tSirVersionString version;
6181 uint32 version_len;
6182 uint8 attr;
6183 int status;
6184 struct sk_buff *reply_skb = NULL;
6185
6186 if (VOS_FTM_MODE == hdd_get_conparam()) {
6187 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6188 return -EINVAL;
6189 }
6190
6191 status = wlan_hdd_validate_context(hdd_ctx);
6192 if (0 != status) {
6193 hddLog(LOGE, FL("HDD context is not valid"));
6194 return -EINVAL;
6195 }
6196
6197 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6198 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6199 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6200 return -EINVAL;
6201 }
6202
6203 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6204 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6205 QWLAN_VERSIONSTR);
6206 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6207 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6208 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6209 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6210 hdd_ctx->fw_Version);
6211 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6212 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6213 } else {
6214 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6215 return -EINVAL;
6216 }
6217
6218 version_len = strlen(version);
6219 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6220 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6221 if (!reply_skb) {
6222 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6223 return -ENOMEM;
6224 }
6225
6226 if (nla_put(reply_skb, attr, version_len, version)) {
6227 hddLog(LOGE, FL("nla put fail"));
6228 kfree_skb(reply_skb);
6229 return -EINVAL;
6230 }
6231
6232 return cfg80211_vendor_cmd_reply(reply_skb);
6233}
6234
6235/**
6236 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6237 * @wiphy: pointer to wireless wiphy structure.
6238 * @wdev: pointer to wireless_dev structure.
6239 * @data: Pointer to the data to be passed via vendor interface
6240 * @data_len:Length of the data to be passed
6241 * @data_len: Length of the data received
6242 *
6243 * This function is used to enable or disable the collection of packet
6244 * statistics from the firmware
6245 *
6246 * Return: 0 on success and errno on failure
6247 */
6248
6249static int
6250wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6251 struct wireless_dev *wdev,
6252 const void *data, int data_len)
6253
6254
6255{
6256 int ret = 0;
6257
6258 vos_ssr_protect(__func__);
6259 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6260 wdev, data, data_len);
6261 vos_ssr_unprotect(__func__);
6262
6263 return ret;
6264}
6265
6266
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306267/*
6268 * define short names for the global vendor params
6269 * used by __wlan_hdd_cfg80211_monitor_rssi()
6270 */
6271#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6272#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6273#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6274#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6275#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6276
6277/**---------------------------------------------------------------------------
6278
6279 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6280 monitor start is completed successfully.
6281
6282 \return - None
6283
6284 --------------------------------------------------------------------------*/
6285void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6286{
6287 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6288
6289 if (NULL == pHddCtx)
6290 {
6291 hddLog(VOS_TRACE_LEVEL_ERROR,
6292 "%s: HDD context is NULL",__func__);
6293 return;
6294 }
6295
6296 if (VOS_STATUS_SUCCESS == status)
6297 {
6298 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6299 }
6300 else
6301 {
6302 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6303 }
6304
6305 return;
6306}
6307
6308/**---------------------------------------------------------------------------
6309
6310 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6311 stop is completed successfully.
6312
6313 \return - None
6314
6315 --------------------------------------------------------------------------*/
6316void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6317{
6318 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6319
6320 if (NULL == pHddCtx)
6321 {
6322 hddLog(VOS_TRACE_LEVEL_ERROR,
6323 "%s: HDD context is NULL",__func__);
6324 return;
6325 }
6326
6327 if (VOS_STATUS_SUCCESS == status)
6328 {
6329 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6330 }
6331 else
6332 {
6333 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6334 }
6335
6336 return;
6337}
6338
6339/**
6340 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6341 * @wiphy: Pointer to wireless phy
6342 * @wdev: Pointer to wireless device
6343 * @data: Pointer to data
6344 * @data_len: Data length
6345 *
6346 * Return: 0 on success, negative errno on failure
6347 */
6348
6349static int
6350__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6351 struct wireless_dev *wdev,
6352 const void *data,
6353 int data_len)
6354{
6355 struct net_device *dev = wdev->netdev;
6356 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6357 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6358 hdd_station_ctx_t *pHddStaCtx;
6359 struct nlattr *tb[PARAM_MAX + 1];
6360 tpSirRssiMonitorReq pReq;
6361 eHalStatus status;
6362 int ret;
6363 uint32_t control;
6364 static const struct nla_policy policy[PARAM_MAX + 1] = {
6365 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6366 [PARAM_CONTROL] = { .type = NLA_U32 },
6367 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6368 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6369 };
6370
6371 ENTER();
6372
6373 ret = wlan_hdd_validate_context(hdd_ctx);
6374 if (0 != ret) {
6375 return -EINVAL;
6376 }
6377
6378 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6379 hddLog(LOGE, FL("Not in Connected state!"));
6380 return -ENOTSUPP;
6381 }
6382
6383 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6384 hddLog(LOGE, FL("Invalid ATTR"));
6385 return -EINVAL;
6386 }
6387
6388 if (!tb[PARAM_REQUEST_ID]) {
6389 hddLog(LOGE, FL("attr request id failed"));
6390 return -EINVAL;
6391 }
6392
6393 if (!tb[PARAM_CONTROL]) {
6394 hddLog(LOGE, FL("attr control failed"));
6395 return -EINVAL;
6396 }
6397
6398 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6399
6400 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6401 if(NULL == pReq)
6402 {
6403 hddLog(LOGE,
6404 FL("vos_mem_alloc failed "));
6405 return eHAL_STATUS_FAILED_ALLOC;
6406 }
6407 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6408
6409 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6410 pReq->sessionId = pAdapter->sessionId;
6411 pReq->rssiMonitorCbContext = hdd_ctx;
6412 control = nla_get_u32(tb[PARAM_CONTROL]);
6413 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6414
6415 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6416 pReq->requestId, pReq->sessionId, control);
6417
6418 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6419 if (!tb[PARAM_MIN_RSSI]) {
6420 hddLog(LOGE, FL("attr min rssi failed"));
6421 return -EINVAL;
6422 }
6423
6424 if (!tb[PARAM_MAX_RSSI]) {
6425 hddLog(LOGE, FL("attr max rssi failed"));
6426 return -EINVAL;
6427 }
6428
6429 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6430 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6431 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6432
6433 if (!(pReq->minRssi < pReq->maxRssi)) {
6434 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6435 pReq->minRssi, pReq->maxRssi);
6436 return -EINVAL;
6437 }
6438 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6439 pReq->minRssi, pReq->maxRssi);
6440 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6441
6442 }
6443 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6444 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6445 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6446 }
6447 else {
6448 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
6449 return -EINVAL;
6450 }
6451
6452 if (!HAL_STATUS_SUCCESS(status)) {
6453 hddLog(LOGE,
6454 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
6455 return -EINVAL;
6456 }
6457
6458 return 0;
6459}
6460
6461/*
6462 * done with short names for the global vendor params
6463 * used by __wlan_hdd_cfg80211_monitor_rssi()
6464 */
6465#undef PARAM_MAX
6466#undef PARAM_CONTROL
6467#undef PARAM_REQUEST_ID
6468#undef PARAM_MAX_RSSI
6469#undef PARAM_MIN_RSSI
6470
6471/**
6472 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
6473 * @wiphy: wiphy structure pointer
6474 * @wdev: Wireless device structure pointer
6475 * @data: Pointer to the data received
6476 * @data_len: Length of @data
6477 *
6478 * Return: 0 on success; errno on failure
6479 */
6480static int
6481wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
6482 const void *data, int data_len)
6483{
6484 int ret;
6485
6486 vos_ssr_protect(__func__);
6487 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
6488 vos_ssr_unprotect(__func__);
6489
6490 return ret;
6491}
6492
6493/**
6494 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
6495 * @hddctx: HDD context
6496 * @data: rssi breached event data
6497 *
6498 * This function reads the rssi breached event %data and fill in the skb with
6499 * NL attributes and send up the NL event.
6500 * This callback execute in atomic context and must not invoke any
6501 * blocking calls.
6502 *
6503 * Return: none
6504 */
6505void hdd_rssi_threshold_breached_cb(void *hddctx,
6506 struct rssi_breach_event *data)
6507{
6508 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
6509 int status;
6510 struct sk_buff *skb;
6511
6512 ENTER();
6513 status = wlan_hdd_validate_context(pHddCtx);
6514
6515 if (0 != status) {
6516 return;
6517 }
6518
6519 if (!data) {
6520 hddLog(LOGE, FL("data is null"));
6521 return;
6522 }
6523
6524 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
6525#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6526 NULL,
6527#endif
6528 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
6529 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
6530 GFP_KERNEL);
6531
6532 if (!skb) {
6533 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
6534 return;
6535 }
6536
6537 hddLog(LOG1, "Req Id: %u Current rssi: %d",
6538 data->request_id, data->curr_rssi);
6539 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
6540 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
6541
6542 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
6543 data->request_id) ||
6544 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
6545 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
6546 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
6547 data->curr_rssi)) {
6548 hddLog(LOGE, FL("nla put fail"));
6549 goto fail;
6550 }
6551
6552 cfg80211_vendor_event(skb, GFP_KERNEL);
6553 return;
6554
6555fail:
6556 kfree_skb(skb);
6557 return;
6558}
6559
6560
6561
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306562/**
6563 * __wlan_hdd_cfg80211_setband() - set band
6564 * @wiphy: Pointer to wireless phy
6565 * @wdev: Pointer to wireless device
6566 * @data: Pointer to data
6567 * @data_len: Data length
6568 *
6569 * Return: 0 on success, negative errno on failure
6570 */
6571static int
6572__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6573 struct wireless_dev *wdev,
6574 const void *data,
6575 int data_len)
6576{
6577 struct net_device *dev = wdev->netdev;
6578 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6579 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6580 int ret;
6581 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
6582 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
6583
6584 ENTER();
6585
6586 ret = wlan_hdd_validate_context(hdd_ctx);
6587 if (0 != ret) {
6588 hddLog(LOGE, FL("HDD context is not valid"));
6589 return ret;
6590 }
6591
6592 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
6593 policy)) {
6594 hddLog(LOGE, FL("Invalid ATTR"));
6595 return -EINVAL;
6596 }
6597
6598 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
6599 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
6600 return -EINVAL;
6601 }
6602
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306603 hdd_ctx->isSetBandByNL = TRUE;
6604 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306605 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306606 hdd_ctx->isSetBandByNL = FALSE;
6607
6608 EXIT();
6609 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306610}
6611
6612/**
6613 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
6614 * @wiphy: wiphy structure pointer
6615 * @wdev: Wireless device structure pointer
6616 * @data: Pointer to the data received
6617 * @data_len: Length of @data
6618 *
6619 * Return: 0 on success; errno on failure
6620 */
6621static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6622 struct wireless_dev *wdev,
6623 const void *data,
6624 int data_len)
6625{
6626 int ret = 0;
6627
6628 vos_ssr_protect(__func__);
6629 ret = __wlan_hdd_cfg80211_setband(wiphy,
6630 wdev, data, data_len);
6631 vos_ssr_unprotect(__func__);
6632
6633 return ret;
6634}
6635
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306636#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
6637/**
6638 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
6639 * @hdd_ctx: HDD context
6640 * @request_id: [input] request id
6641 * @pattern_id: [output] pattern id
6642 *
6643 * This function loops through request id to pattern id array
6644 * if the slot is available, store the request id and return pattern id
6645 * if entry exists, return the pattern id
6646 *
6647 * Return: 0 on success and errno on failure
6648 */
6649static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6650 uint32_t request_id,
6651 uint8_t *pattern_id)
6652{
6653 uint32_t i;
6654
6655 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6656 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6657 {
6658 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
6659 {
6660 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
6661 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6662 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6663 return 0;
6664 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
6665 request_id) {
6666 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6667 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6668 return 0;
6669 }
6670 }
6671 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6672 return -EINVAL;
6673}
6674
6675/**
6676 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
6677 * @hdd_ctx: HDD context
6678 * @request_id: [input] request id
6679 * @pattern_id: [output] pattern id
6680 *
6681 * This function loops through request id to pattern id array
6682 * reset request id to 0 (slot available again) and
6683 * return pattern id
6684 *
6685 * Return: 0 on success and errno on failure
6686 */
6687static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6688 uint32_t request_id,
6689 uint8_t *pattern_id)
6690{
6691 uint32_t i;
6692
6693 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6694 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6695 {
6696 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
6697 {
6698 hdd_ctx->op_ctx.op_table[i].request_id = 0;
6699 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6700 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6701 return 0;
6702 }
6703 }
6704 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6705 return -EINVAL;
6706}
6707
6708
6709/*
6710 * define short names for the global vendor params
6711 * used by __wlan_hdd_cfg80211_offloaded_packets()
6712 */
6713#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
6714#define PARAM_REQUEST_ID \
6715 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
6716#define PARAM_CONTROL \
6717 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
6718#define PARAM_IP_PACKET \
6719 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
6720#define PARAM_SRC_MAC_ADDR \
6721 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
6722#define PARAM_DST_MAC_ADDR \
6723 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
6724#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
6725
6726/**
6727 * wlan_hdd_add_tx_ptrn() - add tx pattern
6728 * @adapter: adapter pointer
6729 * @hdd_ctx: hdd context
6730 * @tb: nl attributes
6731 *
6732 * This function reads the NL attributes and forms a AddTxPtrn message
6733 * posts it to SME.
6734 *
6735 */
6736static int
6737wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6738 struct nlattr **tb)
6739{
6740 struct sSirAddPeriodicTxPtrn *add_req;
6741 eHalStatus status;
6742 uint32_t request_id, ret, len;
6743 uint8_t pattern_id = 0;
6744 v_MACADDR_t dst_addr;
6745 uint16_t eth_type = htons(ETH_P_IP);
6746
6747 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
6748 {
6749 hddLog(LOGE, FL("Not in Connected state!"));
6750 return -ENOTSUPP;
6751 }
6752
6753 add_req = vos_mem_malloc(sizeof(*add_req));
6754 if (!add_req)
6755 {
6756 hddLog(LOGE, FL("memory allocation failed"));
6757 return -ENOMEM;
6758 }
6759
6760 /* Parse and fetch request Id */
6761 if (!tb[PARAM_REQUEST_ID])
6762 {
6763 hddLog(LOGE, FL("attr request id failed"));
6764 goto fail;
6765 }
6766
6767 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6768 hddLog(LOG1, FL("Request Id: %u"), request_id);
6769 if (request_id == 0)
6770 {
6771 hddLog(LOGE, FL("request_id cannot be zero"));
6772 return -EINVAL;
6773 }
6774
6775 if (!tb[PARAM_PERIOD])
6776 {
6777 hddLog(LOGE, FL("attr period failed"));
6778 goto fail;
6779 }
6780 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
6781 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
6782 if (add_req->usPtrnIntervalMs == 0)
6783 {
6784 hddLog(LOGE, FL("Invalid interval zero, return failure"));
6785 goto fail;
6786 }
6787
6788 if (!tb[PARAM_SRC_MAC_ADDR])
6789 {
6790 hddLog(LOGE, FL("attr source mac address failed"));
6791 goto fail;
6792 }
6793 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
6794 VOS_MAC_ADDR_SIZE);
6795 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
6796 MAC_ADDR_ARRAY(add_req->macAddress));
6797
6798 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
6799 VOS_MAC_ADDR_SIZE))
6800 {
6801 hddLog(LOGE,
6802 FL("input src mac address and connected ap bssid are different"));
6803 goto fail;
6804 }
6805
6806 if (!tb[PARAM_DST_MAC_ADDR])
6807 {
6808 hddLog(LOGE, FL("attr dst mac address failed"));
6809 goto fail;
6810 }
6811 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
6812 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
6813 MAC_ADDR_ARRAY(dst_addr.bytes));
6814
6815 if (!tb[PARAM_IP_PACKET])
6816 {
6817 hddLog(LOGE, FL("attr ip packet failed"));
6818 goto fail;
6819 }
6820 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
6821 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
6822
6823 if (add_req->ucPtrnSize < 0 ||
6824 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
6825 HDD_ETH_HEADER_LEN))
6826 {
6827 hddLog(LOGE, FL("Invalid IP packet len: %d"),
6828 add_req->ucPtrnSize);
6829 goto fail;
6830 }
6831
6832 len = 0;
6833 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
6834 len += VOS_MAC_ADDR_SIZE;
6835 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
6836 VOS_MAC_ADDR_SIZE);
6837 len += VOS_MAC_ADDR_SIZE;
6838 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
6839 len += 2;
6840
6841 /*
6842 * This is the IP packet, add 14 bytes Ethernet (802.3) header
6843 * ------------------------------------------------------------
6844 * | 14 bytes Ethernet (802.3) header | IP header and payload |
6845 * ------------------------------------------------------------
6846 */
6847 vos_mem_copy(&add_req->ucPattern[len],
6848 nla_data(tb[PARAM_IP_PACKET]),
6849 add_req->ucPtrnSize);
6850 add_req->ucPtrnSize += len;
6851
6852 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6853 add_req->ucPattern, add_req->ucPtrnSize);
6854
6855 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6856 if (ret)
6857 {
6858 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6859 goto fail;
6860 }
6861 add_req->ucPtrnId = pattern_id;
6862 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
6863
6864 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
6865 if (!HAL_STATUS_SUCCESS(status))
6866 {
6867 hddLog(LOGE,
6868 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
6869 goto fail;
6870 }
6871
6872 EXIT();
6873 vos_mem_free(add_req);
6874 return 0;
6875
6876fail:
6877 vos_mem_free(add_req);
6878 return -EINVAL;
6879}
6880
6881/**
6882 * wlan_hdd_del_tx_ptrn() - delete tx pattern
6883 * @adapter: adapter pointer
6884 * @hdd_ctx: hdd context
6885 * @tb: nl attributes
6886 *
6887 * This function reads the NL attributes and forms a DelTxPtrn message
6888 * posts it to SME.
6889 *
6890 */
6891static int
6892wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6893 struct nlattr **tb)
6894{
6895 struct sSirDelPeriodicTxPtrn *del_req;
6896 eHalStatus status;
6897 uint32_t request_id, ret;
6898 uint8_t pattern_id = 0;
6899
6900 /* Parse and fetch request Id */
6901 if (!tb[PARAM_REQUEST_ID])
6902 {
6903 hddLog(LOGE, FL("attr request id failed"));
6904 return -EINVAL;
6905 }
6906 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6907 if (request_id == 0)
6908 {
6909 hddLog(LOGE, FL("request_id cannot be zero"));
6910 return -EINVAL;
6911 }
6912
6913 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6914 if (ret)
6915 {
6916 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6917 return -EINVAL;
6918 }
6919
6920 del_req = vos_mem_malloc(sizeof(*del_req));
6921 if (!del_req)
6922 {
6923 hddLog(LOGE, FL("memory allocation failed"));
6924 return -ENOMEM;
6925 }
6926
6927 vos_mem_set(del_req, sizeof(*del_req), 0);
6928 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
6929 VOS_MAC_ADDR_SIZE);
6930 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
6931 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
6932 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
6933 request_id, pattern_id, del_req->ucPatternIdBitmap);
6934
6935 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
6936 if (!HAL_STATUS_SUCCESS(status))
6937 {
6938 hddLog(LOGE,
6939 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
6940 goto fail;
6941 }
6942
6943 EXIT();
6944 vos_mem_free(del_req);
6945 return 0;
6946
6947fail:
6948 vos_mem_free(del_req);
6949 return -EINVAL;
6950}
6951
6952
6953/**
6954 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
6955 * @wiphy: Pointer to wireless phy
6956 * @wdev: Pointer to wireless device
6957 * @data: Pointer to data
6958 * @data_len: Data length
6959 *
6960 * Return: 0 on success, negative errno on failure
6961 */
6962static int
6963__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
6964 struct wireless_dev *wdev,
6965 const void *data,
6966 int data_len)
6967{
6968 struct net_device *dev = wdev->netdev;
6969 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6970 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6971 struct nlattr *tb[PARAM_MAX + 1];
6972 uint8_t control;
6973 int ret;
6974 static const struct nla_policy policy[PARAM_MAX + 1] =
6975 {
6976 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6977 [PARAM_CONTROL] = { .type = NLA_U32 },
6978 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
6979 .len = VOS_MAC_ADDR_SIZE },
6980 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
6981 .len = VOS_MAC_ADDR_SIZE },
6982 [PARAM_PERIOD] = { .type = NLA_U32 },
6983 };
6984
6985 ENTER();
6986
6987 ret = wlan_hdd_validate_context(hdd_ctx);
6988 if (0 != ret)
6989 {
6990 hddLog(LOGE, FL("HDD context is not valid"));
6991 return ret;
6992 }
6993
6994 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
6995 {
6996 hddLog(LOGE,
6997 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
6998 return -ENOTSUPP;
6999 }
7000
7001 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7002 {
7003 hddLog(LOGE, FL("Invalid ATTR"));
7004 return -EINVAL;
7005 }
7006
7007 if (!tb[PARAM_CONTROL])
7008 {
7009 hddLog(LOGE, FL("attr control failed"));
7010 return -EINVAL;
7011 }
7012 control = nla_get_u32(tb[PARAM_CONTROL]);
7013 hddLog(LOG1, FL("Control: %d"), control);
7014
7015 if (control == WLAN_START_OFFLOADED_PACKETS)
7016 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7017 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7018 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7019 else
7020 {
7021 hddLog(LOGE, FL("Invalid control: %d"), control);
7022 return -EINVAL;
7023 }
7024}
7025
7026/*
7027 * done with short names for the global vendor params
7028 * used by __wlan_hdd_cfg80211_offloaded_packets()
7029 */
7030#undef PARAM_MAX
7031#undef PARAM_REQUEST_ID
7032#undef PARAM_CONTROL
7033#undef PARAM_IP_PACKET
7034#undef PARAM_SRC_MAC_ADDR
7035#undef PARAM_DST_MAC_ADDR
7036#undef PARAM_PERIOD
7037
7038/**
7039 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7040 * @wiphy: wiphy structure pointer
7041 * @wdev: Wireless device structure pointer
7042 * @data: Pointer to the data received
7043 * @data_len: Length of @data
7044 *
7045 * Return: 0 on success; errno on failure
7046 */
7047static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7048 struct wireless_dev *wdev,
7049 const void *data,
7050 int data_len)
7051{
7052 int ret = 0;
7053
7054 vos_ssr_protect(__func__);
7055 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7056 wdev, data, data_len);
7057 vos_ssr_unprotect(__func__);
7058
7059 return ret;
7060}
7061#endif
7062
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307063static const struct
7064nla_policy
7065qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
7066 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
7067};
7068
7069/**
7070 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7071 * get link properties like nss, rate flags and operating frequency for
7072 * the connection with the given peer.
7073 * @wiphy: WIPHY structure pointer
7074 * @wdev: Wireless device structure pointer
7075 * @data: Pointer to the data received
7076 * @data_len: Length of the data received
7077 *
7078 * This function return the above link properties on success.
7079 *
7080 * Return: 0 on success and errno on failure
7081 */
7082static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7083 struct wireless_dev *wdev,
7084 const void *data,
7085 int data_len)
7086{
7087 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7088 struct net_device *dev = wdev->netdev;
7089 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7090 hdd_station_ctx_t *hdd_sta_ctx;
7091 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7092 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7093 uint32_t sta_id;
7094 struct sk_buff *reply_skb;
7095 uint32_t rate_flags = 0;
7096 uint8_t nss;
7097 uint8_t final_rate_flags = 0;
7098 uint32_t freq;
7099 v_CONTEXT_t pVosContext = NULL;
7100 ptSapContext pSapCtx = NULL;
7101
7102 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7103 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7104 return -EINVAL;
7105 }
7106
7107 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7108 qca_wlan_vendor_attr_policy)) {
7109 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7110 return -EINVAL;
7111 }
7112
7113 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7114 hddLog(VOS_TRACE_LEVEL_ERROR,
7115 FL("Attribute peerMac not provided for mode=%d"),
7116 adapter->device_mode);
7117 return -EINVAL;
7118 }
7119
7120 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7121 sizeof(peer_mac));
7122 hddLog(VOS_TRACE_LEVEL_INFO,
7123 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7124 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7125
7126 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7127 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7128 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7129 if ((hdd_sta_ctx->conn_info.connState !=
7130 eConnectionState_Associated) ||
7131 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7132 VOS_MAC_ADDRESS_LEN)) {
7133 hddLog(VOS_TRACE_LEVEL_ERROR,
7134 FL("Not Associated to mac "MAC_ADDRESS_STR),
7135 MAC_ADDR_ARRAY(peer_mac));
7136 return -EINVAL;
7137 }
7138
7139 nss = 1; //pronto supports only one spatial stream
7140 freq = vos_chan_to_freq(
7141 hdd_sta_ctx->conn_info.operationChannel);
7142 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7143
7144 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7145 adapter->device_mode == WLAN_HDD_SOFTAP) {
7146
7147 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7148 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7149 if(pSapCtx == NULL){
7150 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7151 FL("psapCtx is NULL"));
7152 return -ENOENT;
7153 }
7154
7155
7156 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7157 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7158 !vos_is_macaddr_broadcast(
7159 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7160 vos_mem_compare(
7161 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7162 peer_mac, VOS_MAC_ADDRESS_LEN))
7163 break;
7164 }
7165
7166 if (WLAN_MAX_STA_COUNT == sta_id) {
7167 hddLog(VOS_TRACE_LEVEL_ERROR,
7168 FL("No active peer with mac="MAC_ADDRESS_STR),
7169 MAC_ADDR_ARRAY(peer_mac));
7170 return -EINVAL;
7171 }
7172
7173 nss = 1; //pronto supports only one spatial stream
7174 freq = vos_chan_to_freq(
7175 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7176 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7177 } else {
7178 hddLog(VOS_TRACE_LEVEL_ERROR,
7179 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7180 MAC_ADDR_ARRAY(peer_mac));
7181 return -EINVAL;
7182 }
7183
7184 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7185 if (rate_flags & eHAL_TX_RATE_VHT80) {
7186 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7187 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7188 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7189 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7190 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7191 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7192 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7193 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7194 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7195 if (rate_flags & eHAL_TX_RATE_HT40)
7196 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7197 }
7198
7199 if (rate_flags & eHAL_TX_RATE_SGI) {
7200 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7201 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7202 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7203 }
7204 }
7205
7206 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7207 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7208
7209 if (NULL == reply_skb) {
7210 hddLog(VOS_TRACE_LEVEL_ERROR,
7211 FL("getLinkProperties: skb alloc failed"));
7212 return -EINVAL;
7213 }
7214
7215 if (nla_put_u8(reply_skb,
7216 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7217 nss) ||
7218 nla_put_u8(reply_skb,
7219 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7220 final_rate_flags) ||
7221 nla_put_u32(reply_skb,
7222 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7223 freq)) {
7224 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7225 kfree_skb(reply_skb);
7226 return -EINVAL;
7227 }
7228
7229 return cfg80211_vendor_cmd_reply(reply_skb);
7230}
7231
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307232#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7233#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7234#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7235#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
7236
7237/**
7238 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7239 * vendor command
7240 *
7241 * @wiphy: wiphy device pointer
7242 * @wdev: wireless device pointer
7243 * @data: Vendor command data buffer
7244 * @data_len: Buffer length
7245 *
7246 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7247 *
7248 * Return: EOK or other error codes.
7249 */
7250
7251static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7252 struct wireless_dev *wdev,
7253 const void *data,
7254 int data_len)
7255{
7256 struct net_device *dev = wdev->netdev;
7257 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7258 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7259 hdd_station_ctx_t *pHddStaCtx;
7260 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7261 tpSetWifiConfigParams pReq;
7262 eHalStatus status;
7263 int ret_val;
7264 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7265 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7266 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
7267 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7268 };
7269
7270 ENTER();
7271
7272 if (VOS_FTM_MODE == hdd_get_conparam()) {
7273 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7274 return -EINVAL;
7275 }
7276
7277 ret_val = wlan_hdd_validate_context(pHddCtx);
7278 if (ret_val) {
7279 return ret_val;
7280 }
7281
7282 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7283
7284 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7285 hddLog(LOGE, FL("Not in Connected state!"));
7286 return -ENOTSUPP;
7287 }
7288
7289 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7290 hddLog(LOGE, FL("Invalid ATTR"));
7291 return -EINVAL;
7292 }
7293
7294 /* check the Wifi Capability */
7295 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7296 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7297 {
7298 hddLog(VOS_TRACE_LEVEL_ERROR,
7299 FL("WIFICONFIG not supported by Firmware"));
7300 return -EINVAL;
7301 }
7302
7303 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
7304
7305 if (!pReq) {
7306 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7307 "%s: Not able to allocate memory for tSetWifiConfigParams",
7308 __func__);
7309 return eHAL_STATUS_E_MALLOC_FAILED;
7310 }
7311
7312 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7313
7314 pReq->sessionId = pAdapter->sessionId;
7315 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7316
7317 if (tb[PARAM_MODULATED_DTIM]) {
7318 pReq->paramValue = nla_get_u32(
7319 tb[PARAM_MODULATED_DTIM]);
7320 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7321 pReq->paramValue);
7322 pHddCtx->cfg_ini->fMaxLIModulatedDTIM = pReq->paramValue;
7323 hdd_set_pwrparams(pHddCtx);
7324 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7325 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7326
7327 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7328 iw_full_power_cbfn, pAdapter,
7329 eSME_FULL_PWR_NEEDED_BY_HDD);
7330 }
7331 else
7332 {
7333 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7334 }
7335 }
7336
7337 if (tb[PARAM_STATS_AVG_FACTOR]) {
7338 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7339 pReq->paramValue = nla_get_u16(
7340 tb[PARAM_STATS_AVG_FACTOR]);
7341 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7342 pReq->paramType, pReq->paramValue);
7343 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7344
7345 if (eHAL_STATUS_SUCCESS != status)
7346 {
7347 vos_mem_free(pReq);
7348 pReq = NULL;
7349 ret_val = -EPERM;
7350 return ret_val;
7351 }
7352 }
7353
7354
7355 if (tb[PARAM_GUARD_TIME]) {
7356 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7357 pReq->paramValue = nla_get_u32(
7358 tb[PARAM_GUARD_TIME]);
7359 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7360 pReq->paramType, pReq->paramValue);
7361 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7362
7363 if (eHAL_STATUS_SUCCESS != status)
7364 {
7365 vos_mem_free(pReq);
7366 pReq = NULL;
7367 ret_val = -EPERM;
7368 return ret_val;
7369 }
7370
7371 }
7372
7373 EXIT();
7374 return ret_val;
7375}
7376
7377/**
7378 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7379 * vendor command
7380 *
7381 * @wiphy: wiphy device pointer
7382 * @wdev: wireless device pointer
7383 * @data: Vendor command data buffer
7384 * @data_len: Buffer length
7385 *
7386 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7387 *
7388 * Return: EOK or other error codes.
7389 */
7390static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7391 struct wireless_dev *wdev,
7392 const void *data,
7393 int data_len)
7394{
7395 int ret;
7396
7397 vos_ssr_protect(__func__);
7398 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
7399 data, data_len);
7400 vos_ssr_unprotect(__func__);
7401
7402 return ret;
7403}
Sunil Duttc69bccb2014-05-26 21:30:20 +05307404const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
7405{
Mukul Sharma2a271632014-10-13 14:59:01 +05307406 {
7407 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7408 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
7409 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7410 WIPHY_VENDOR_CMD_NEED_NETDEV |
7411 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307412 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05307413 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05307414
7415 {
7416 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7417 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
7418 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7419 WIPHY_VENDOR_CMD_NEED_NETDEV |
7420 WIPHY_VENDOR_CMD_NEED_RUNNING,
7421 .doit = wlan_hdd_cfg80211_nan_request
7422 },
7423
Sunil Duttc69bccb2014-05-26 21:30:20 +05307424#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7425 {
7426 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7427 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
7428 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7429 WIPHY_VENDOR_CMD_NEED_NETDEV |
7430 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307431 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05307432 },
7433
7434 {
7435 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7436 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
7437 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7438 WIPHY_VENDOR_CMD_NEED_NETDEV |
7439 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307440 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05307441 },
7442
7443 {
7444 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7445 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
7446 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7447 WIPHY_VENDOR_CMD_NEED_NETDEV |
7448 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307449 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05307450 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307451#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307452#ifdef WLAN_FEATURE_EXTSCAN
7453 {
7454 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7455 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
7456 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7457 WIPHY_VENDOR_CMD_NEED_NETDEV |
7458 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307459 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05307460 },
7461 {
7462 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7463 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
7464 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7465 WIPHY_VENDOR_CMD_NEED_NETDEV |
7466 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307467 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05307468 },
7469 {
7470 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7471 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
7472 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7473 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307474 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05307475 },
7476 {
7477 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7478 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
7479 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7480 WIPHY_VENDOR_CMD_NEED_NETDEV |
7481 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307482 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05307483 },
7484 {
7485 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7486 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
7487 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7488 WIPHY_VENDOR_CMD_NEED_NETDEV |
7489 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307490 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05307491 },
7492 {
7493 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7494 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
7495 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7496 WIPHY_VENDOR_CMD_NEED_NETDEV |
7497 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307498 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307499 },
7500 {
7501 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7502 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
7503 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7504 WIPHY_VENDOR_CMD_NEED_NETDEV |
7505 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307506 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307507 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307508 {
7509 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7510 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST,
7511 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7512 WIPHY_VENDOR_CMD_NEED_NETDEV |
7513 WIPHY_VENDOR_CMD_NEED_RUNNING,
7514 .doit = wlan_hdd_cfg80211_extscan_set_ssid_hotlist
7515 },
7516 {
7517 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7518 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST,
7519 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7520 WIPHY_VENDOR_CMD_NEED_NETDEV |
7521 WIPHY_VENDOR_CMD_NEED_RUNNING,
7522 .doit = wlan_hdd_cfg80211_extscan_reset_ssid_hotlist
7523 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307524#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307525/*EXT TDLS*/
7526 {
7527 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7528 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
7529 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7530 WIPHY_VENDOR_CMD_NEED_NETDEV |
7531 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307532 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05307533 },
7534 {
7535 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7536 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
7537 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7538 WIPHY_VENDOR_CMD_NEED_NETDEV |
7539 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307540 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05307541 },
7542 {
7543 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7544 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
7545 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7546 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307547 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05307548 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05307549 {
7550 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7551 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
7552 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7553 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307554 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05307555 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05307556 {
7557 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7558 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
7559 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7560 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307561 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05307562 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307563 {
7564 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7565 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
7566 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7567 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307568 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307569 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307570 {
7571 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7572 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
7573 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7574 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307575 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307576 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307577 {
7578 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05307579 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
7580 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7581 WIPHY_VENDOR_CMD_NEED_NETDEV |
7582 WIPHY_VENDOR_CMD_NEED_RUNNING,
7583 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
7584 },
7585 {
7586 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307587 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
7588 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7589 WIPHY_VENDOR_CMD_NEED_NETDEV |
7590 WIPHY_VENDOR_CMD_NEED_RUNNING,
7591 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05307592 },
7593 {
7594 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7595 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
7596 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7597 WIPHY_VENDOR_CMD_NEED_NETDEV,
7598 .doit = wlan_hdd_cfg80211_wifi_logger_start
7599 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05307600 {
7601 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7602 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
7603 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7604 WIPHY_VENDOR_CMD_NEED_NETDEV|
7605 WIPHY_VENDOR_CMD_NEED_RUNNING,
7606 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05307607 },
7608 {
7609 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7610 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
7611 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7612 WIPHY_VENDOR_CMD_NEED_NETDEV |
7613 WIPHY_VENDOR_CMD_NEED_RUNNING,
7614 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307615 },
7616 {
7617 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7618 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
7619 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7620 WIPHY_VENDOR_CMD_NEED_NETDEV |
7621 WIPHY_VENDOR_CMD_NEED_RUNNING,
7622 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307623 },
7624#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7625 {
7626 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7627 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
7628 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7629 WIPHY_VENDOR_CMD_NEED_NETDEV |
7630 WIPHY_VENDOR_CMD_NEED_RUNNING,
7631 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307632 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307633#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307634 {
7635 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7636 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
7637 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7638 WIPHY_VENDOR_CMD_NEED_NETDEV |
7639 WIPHY_VENDOR_CMD_NEED_RUNNING,
7640 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307641 },
7642 {
7643 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7644 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
7645 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7646 WIPHY_VENDOR_CMD_NEED_NETDEV |
7647 WIPHY_VENDOR_CMD_NEED_RUNNING,
7648 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307649 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05307650};
7651
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007652/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05307653static const
7654struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007655{
7656#ifdef FEATURE_WLAN_CH_AVOID
7657 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05307658 .vendor_id = QCA_NL80211_VENDOR_ID,
7659 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007660 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307661#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
7662#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7663 {
7664 /* Index = 1*/
7665 .vendor_id = QCA_NL80211_VENDOR_ID,
7666 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
7667 },
7668 {
7669 /* Index = 2*/
7670 .vendor_id = QCA_NL80211_VENDOR_ID,
7671 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
7672 },
7673 {
7674 /* Index = 3*/
7675 .vendor_id = QCA_NL80211_VENDOR_ID,
7676 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
7677 },
7678 {
7679 /* Index = 4*/
7680 .vendor_id = QCA_NL80211_VENDOR_ID,
7681 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
7682 },
7683 {
7684 /* Index = 5*/
7685 .vendor_id = QCA_NL80211_VENDOR_ID,
7686 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
7687 },
7688 {
7689 /* Index = 6*/
7690 .vendor_id = QCA_NL80211_VENDOR_ID,
7691 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
7692 },
7693#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307694#ifdef WLAN_FEATURE_EXTSCAN
7695 {
7696 .vendor_id = QCA_NL80211_VENDOR_ID,
7697 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
7698 },
7699 {
7700 .vendor_id = QCA_NL80211_VENDOR_ID,
7701 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
7702 },
7703 {
7704 .vendor_id = QCA_NL80211_VENDOR_ID,
7705 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
7706 },
7707 {
7708 .vendor_id = QCA_NL80211_VENDOR_ID,
7709 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
7710 },
7711 {
7712 .vendor_id = QCA_NL80211_VENDOR_ID,
7713 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
7714 },
7715 {
7716 .vendor_id = QCA_NL80211_VENDOR_ID,
7717 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
7718 },
7719 {
7720 .vendor_id = QCA_NL80211_VENDOR_ID,
7721 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
7722 },
7723 {
7724 .vendor_id = QCA_NL80211_VENDOR_ID,
7725 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
7726 },
7727 {
7728 .vendor_id = QCA_NL80211_VENDOR_ID,
7729 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
7730 },
7731 {
7732 .vendor_id = QCA_NL80211_VENDOR_ID,
7733 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
7734 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307735 {
7736 .vendor_id = QCA_NL80211_VENDOR_ID,
7737 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST
7738 },
7739 {
7740 .vendor_id = QCA_NL80211_VENDOR_ID,
7741 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST
7742 },
7743 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX] = {
7744 .vendor_id = QCA_NL80211_VENDOR_ID,
7745 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND
7746 },
7747 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX] = {
7748 .vendor_id = QCA_NL80211_VENDOR_ID,
7749 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST
7750 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307751#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307752/*EXT TDLS*/
7753 {
7754 .vendor_id = QCA_NL80211_VENDOR_ID,
7755 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
7756 },
c_manjeecfd1efb2015-09-25 19:32:34 +05307757 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
7758 .vendor_id = QCA_NL80211_VENDOR_ID,
7759 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
7760 },
7761
Srinivas Dasari030bad32015-02-18 23:23:54 +05307762
7763 {
7764 .vendor_id = QCA_NL80211_VENDOR_ID,
7765 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
7766 },
7767
Sushant Kaushik084f6592015-09-10 13:11:56 +05307768 {
7769 .vendor_id = QCA_NL80211_VENDOR_ID,
7770 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307771 },
7772 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
7773 .vendor_id = QCA_NL80211_VENDOR_ID,
7774 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
7775 },
Sushant Kaushik084f6592015-09-10 13:11:56 +05307776
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007777};
7778
Jeff Johnson295189b2012-06-20 16:38:30 -07007779/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307780 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307781 * This function is called by hdd_wlan_startup()
7782 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307783 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07007784 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307785struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07007786{
7787 struct wiphy *wiphy;
7788 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307789 /*
7790 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07007791 */
7792 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
7793
7794 if (!wiphy)
7795 {
7796 /* Print error and jump into err label and free the memory */
7797 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
7798 return NULL;
7799 }
7800
Sunil Duttc69bccb2014-05-26 21:30:20 +05307801
Jeff Johnson295189b2012-06-20 16:38:30 -07007802 return wiphy;
7803}
7804
7805/*
7806 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307807 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07007808 * private ioctl to change the band value
7809 */
7810int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
7811{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307812 int i, j;
7813 eNVChannelEnabledType channelEnabledState;
7814
Jeff Johnsone7245742012-09-05 17:12:55 -07007815 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307816
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307817 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007818 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307819
7820 if (NULL == wiphy->bands[i])
7821 {
7822 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
7823 __func__, i);
7824 continue;
7825 }
7826
7827 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
7828 {
7829 struct ieee80211_supported_band *band = wiphy->bands[i];
7830
7831 channelEnabledState = vos_nv_getChannelEnabledState(
7832 band->channels[j].hw_value);
7833
7834 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
7835 {
Abhishek Singh678227a2014-11-04 10:52:38 +05307836 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307837 continue;
7838 }
7839 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
7840 {
7841 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7842 continue;
7843 }
7844
7845 if (NV_CHANNEL_DISABLE == channelEnabledState ||
7846 NV_CHANNEL_INVALID == channelEnabledState)
7847 {
7848 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7849 }
7850 else if (NV_CHANNEL_DFS == channelEnabledState)
7851 {
7852 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
7853 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
7854 }
7855 else
7856 {
7857 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
7858 |IEEE80211_CHAN_RADAR);
7859 }
7860 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007861 }
7862 return 0;
7863}
7864/*
7865 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307866 * This function is called by hdd_wlan_startup()
7867 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07007868 * This function is used to initialize and register wiphy structure.
7869 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307870int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007871 struct wiphy *wiphy,
7872 hdd_config_t *pCfg
7873 )
7874{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307875 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05307876 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7877
Jeff Johnsone7245742012-09-05 17:12:55 -07007878 ENTER();
7879
Jeff Johnson295189b2012-06-20 16:38:30 -07007880 /* Now bind the underlying wlan device with wiphy */
7881 set_wiphy_dev(wiphy, dev);
7882
7883 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07007884
Kiet Lam6c583332013-10-14 05:37:09 +05307885#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07007886 /* the flag for the other case would be initialzed in
7887 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07007888 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05307889#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007890
Amar Singhalfddc28c2013-09-05 13:03:40 -07007891 /* This will disable updating of NL channels from passive to
7892 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307893#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7894 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
7895#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07007896 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307897#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07007898
Amar Singhala49cbc52013-10-08 18:37:44 -07007899
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007900#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07007901 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
7902 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
7903 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07007904 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307905#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7906 wiphy->regulatory_flags = REGULATORY_COUNTRY_IE_IGNORE;
7907#else
7908 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
7909#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007910#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007911
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007912#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007913 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08007914#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007915 || pCfg->isFastRoamIniFeatureEnabled
7916#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007917#ifdef FEATURE_WLAN_ESE
7918 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007919#endif
7920 )
7921 {
7922 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
7923 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08007924#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007925#ifdef FEATURE_WLAN_TDLS
7926 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
7927 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
7928#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307929#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05307930 if (pCfg->configPNOScanSupport)
7931 {
7932 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
7933 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
7934 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
7935 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
7936 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307937#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007938
Abhishek Singh10d85972015-04-17 10:27:23 +05307939#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7940 wiphy->features |= NL80211_FEATURE_HT_IBSS;
7941#endif
7942
Amar Singhalfddc28c2013-09-05 13:03:40 -07007943#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07007944 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
7945 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07007946 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07007947 driver need to determine what to do with both
7948 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07007949
7950 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07007951#else
7952 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07007953#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007954
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307955 wiphy->max_scan_ssids = MAX_SCAN_SSID;
7956
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05307957 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07007958
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307959 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
7960
Jeff Johnson295189b2012-06-20 16:38:30 -07007961 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05307962 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
7963 | BIT(NL80211_IFTYPE_ADHOC)
7964 | BIT(NL80211_IFTYPE_P2P_CLIENT)
7965 | BIT(NL80211_IFTYPE_P2P_GO)
7966 | BIT(NL80211_IFTYPE_AP);
7967
7968 if (VOS_MONITOR_MODE == hdd_get_conparam())
7969 {
7970 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
7971 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007972
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307973 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007974 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307975#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7976 if( pCfg->enableMCC )
7977 {
7978 /* Currently, supports up to two channels */
7979 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007980
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307981 if( !pCfg->allowMCCGODiffBI )
7982 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007983
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307984 }
7985 wiphy->iface_combinations = &wlan_hdd_iface_combination;
7986 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007987#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307988 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007989
Jeff Johnson295189b2012-06-20 16:38:30 -07007990 /* Before registering we need to update the ht capabilitied based
7991 * on ini values*/
7992 if( !pCfg->ShortGI20MhzEnable )
7993 {
7994 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
7995 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
7996 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
7997 }
7998
7999 if( !pCfg->ShortGI40MhzEnable )
8000 {
8001 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
8002 }
8003
8004 if( !pCfg->nChannelBondingMode5GHz )
8005 {
8006 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
8007 }
8008
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308009 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308010 if (true == hdd_is_5g_supported(pHddCtx))
8011 {
8012 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
8013 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308014
8015 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
8016 {
8017
8018 if (NULL == wiphy->bands[i])
8019 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05308020 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308021 __func__, i);
8022 continue;
8023 }
8024
8025 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8026 {
8027 struct ieee80211_supported_band *band = wiphy->bands[i];
8028
8029 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
8030 {
8031 // Enable social channels for P2P
8032 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
8033 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8034 else
8035 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8036 continue;
8037 }
8038 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
8039 {
8040 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8041 continue;
8042 }
8043 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008044 }
8045 /*Initialise the supported cipher suite details*/
8046 wiphy->cipher_suites = hdd_cipher_suites;
8047 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
8048
8049 /*signal strength in mBm (100*dBm) */
8050 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
8051
8052#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05308053 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07008054#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008055
Sunil Duttc69bccb2014-05-26 21:30:20 +05308056 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
8057 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008058 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
8059 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
8060
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308061 EXIT();
8062 return 0;
8063}
8064
8065/* In this function we are registering wiphy. */
8066int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
8067{
8068 ENTER();
8069 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008070 if (0 > wiphy_register(wiphy))
8071 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308072 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07008073 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8074 return -EIO;
8075 }
8076
8077 EXIT();
8078 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308079}
Jeff Johnson295189b2012-06-20 16:38:30 -07008080
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308081/* In this function we are updating channel list when,
8082 regulatory domain is FCC and country code is US.
8083 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
8084 As per FCC smart phone is not a indoor device.
8085 GO should not opeate on indoor channels */
8086void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
8087{
8088 int j;
8089 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8090 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
8091 //Default counrtycode from NV at the time of wiphy initialization.
8092 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
8093 &defaultCountryCode[0]))
8094 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008095 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308096 }
8097 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
8098 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308099 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
8100 {
8101 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
8102 return;
8103 }
8104 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
8105 {
8106 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
8107 // Mark UNII -1 band channel as passive
8108 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
8109 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
8110 }
8111 }
8112}
8113
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308114/* This function registers for all frame which supplicant is interested in */
8115void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008116{
Jeff Johnson295189b2012-06-20 16:38:30 -07008117 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8118 /* Register for all P2P action, public action etc frames */
8119 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
8120
Jeff Johnsone7245742012-09-05 17:12:55 -07008121 ENTER();
8122
Jeff Johnson295189b2012-06-20 16:38:30 -07008123 /* Right now we are registering these frame when driver is getting
8124 initialized. Once we will move to 2.6.37 kernel, in which we have
8125 frame register ops, we will move this code as a part of that */
8126 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308127 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07008128 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8129
8130 /* GAS Initial Response */
8131 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8132 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308133
Jeff Johnson295189b2012-06-20 16:38:30 -07008134 /* GAS Comeback Request */
8135 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8136 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8137
8138 /* GAS Comeback Response */
8139 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8140 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8141
8142 /* P2P Public Action */
8143 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308144 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008145 P2P_PUBLIC_ACTION_FRAME_SIZE );
8146
8147 /* P2P Action */
8148 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8149 (v_U8_t*)P2P_ACTION_FRAME,
8150 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07008151
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05308152 /* WNM BSS Transition Request frame */
8153 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8154 (v_U8_t*)WNM_BSS_ACTION_FRAME,
8155 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008156
8157 /* WNM-Notification */
8158 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8159 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8160 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008161}
8162
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308163void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008164{
Jeff Johnson295189b2012-06-20 16:38:30 -07008165 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8166 /* Register for all P2P action, public action etc frames */
8167 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
8168
Jeff Johnsone7245742012-09-05 17:12:55 -07008169 ENTER();
8170
Jeff Johnson295189b2012-06-20 16:38:30 -07008171 /* Right now we are registering these frame when driver is getting
8172 initialized. Once we will move to 2.6.37 kernel, in which we have
8173 frame register ops, we will move this code as a part of that */
8174 /* GAS Initial Request */
8175
8176 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8177 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8178
8179 /* GAS Initial Response */
8180 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8181 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308182
Jeff Johnson295189b2012-06-20 16:38:30 -07008183 /* GAS Comeback Request */
8184 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8185 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8186
8187 /* GAS Comeback Response */
8188 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8189 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8190
8191 /* P2P Public Action */
8192 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308193 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008194 P2P_PUBLIC_ACTION_FRAME_SIZE );
8195
8196 /* P2P Action */
8197 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8198 (v_U8_t*)P2P_ACTION_FRAME,
8199 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008200 /* WNM-Notification */
8201 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8202 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8203 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008204}
8205
8206#ifdef FEATURE_WLAN_WAPI
8207void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05308208 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07008209{
8210 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8211 tCsrRoamSetKey setKey;
8212 v_BOOL_t isConnected = TRUE;
8213 int status = 0;
8214 v_U32_t roamId= 0xFF;
8215 tANI_U8 *pKeyPtr = NULL;
8216 int n = 0;
8217
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308218 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
8219 __func__, hdd_device_modetoString(pAdapter->device_mode),
8220 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008221
Gopichand Nakkalae7480202013-02-11 15:24:22 +05308222 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008223 setKey.keyId = key_index; // Store Key ID
8224 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
8225 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
8226 setKey.paeRole = 0 ; // the PAE role
8227 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8228 {
8229 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
8230 }
8231 else
8232 {
8233 isConnected = hdd_connIsConnected(pHddStaCtx);
8234 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
8235 }
8236 setKey.keyLength = key_Len;
8237 pKeyPtr = setKey.Key;
8238 memcpy( pKeyPtr, key, key_Len);
8239
Arif Hussain6d2a3322013-11-17 19:50:10 -08008240 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07008241 __func__, key_Len);
8242 for (n = 0 ; n < key_Len; n++)
8243 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
8244 __func__,n,setKey.Key[n]);
8245
8246 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8247 if ( isConnected )
8248 {
8249 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8250 pAdapter->sessionId, &setKey, &roamId );
8251 }
8252 if ( status != 0 )
8253 {
8254 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8255 "[%4d] sme_RoamSetKey returned ERROR status= %d",
8256 __LINE__, status );
8257 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8258 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308259 /* Need to clear any trace of key value in the memory.
8260 * Thus zero out the memory even though it is local
8261 * variable.
8262 */
8263 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008264}
8265#endif /* FEATURE_WLAN_WAPI*/
8266
8267#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308268int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008269 beacon_data_t **ppBeacon,
8270 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008271#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308272int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008273 beacon_data_t **ppBeacon,
8274 struct cfg80211_beacon_data *params,
8275 int dtim_period)
8276#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308277{
Jeff Johnson295189b2012-06-20 16:38:30 -07008278 int size;
8279 beacon_data_t *beacon = NULL;
8280 beacon_data_t *old = NULL;
8281 int head_len,tail_len;
8282
Jeff Johnsone7245742012-09-05 17:12:55 -07008283 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008284 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308285 {
8286 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8287 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008288 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308289 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008290
8291 old = pAdapter->sessionCtx.ap.beacon;
8292
8293 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308294 {
8295 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8296 FL("session(%d) old and new heads points to NULL"),
8297 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008298 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308299 }
8300
8301 if (params->tail && !params->tail_len)
8302 {
8303 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8304 FL("tail_len is zero but tail is not NULL"));
8305 return -EINVAL;
8306 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008307
Jeff Johnson295189b2012-06-20 16:38:30 -07008308#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
8309 /* Kernel 3.0 is not updating dtim_period for set beacon */
8310 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308311 {
8312 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8313 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008314 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308315 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008316#endif
8317
8318 if(params->head)
8319 head_len = params->head_len;
8320 else
8321 head_len = old->head_len;
8322
8323 if(params->tail || !old)
8324 tail_len = params->tail_len;
8325 else
8326 tail_len = old->tail_len;
8327
8328 size = sizeof(beacon_data_t) + head_len + tail_len;
8329
8330 beacon = kzalloc(size, GFP_KERNEL);
8331
8332 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308333 {
8334 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8335 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008336 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308337 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008338
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008339#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008340 if(params->dtim_period || !old )
8341 beacon->dtim_period = params->dtim_period;
8342 else
8343 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008344#else
8345 if(dtim_period || !old )
8346 beacon->dtim_period = dtim_period;
8347 else
8348 beacon->dtim_period = old->dtim_period;
8349#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308350
Jeff Johnson295189b2012-06-20 16:38:30 -07008351 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
8352 beacon->tail = beacon->head + head_len;
8353 beacon->head_len = head_len;
8354 beacon->tail_len = tail_len;
8355
8356 if(params->head) {
8357 memcpy (beacon->head,params->head,beacon->head_len);
8358 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308359 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07008360 if(old)
8361 memcpy (beacon->head,old->head,beacon->head_len);
8362 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308363
Jeff Johnson295189b2012-06-20 16:38:30 -07008364 if(params->tail) {
8365 memcpy (beacon->tail,params->tail,beacon->tail_len);
8366 }
8367 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308368 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07008369 memcpy (beacon->tail,old->tail,beacon->tail_len);
8370 }
8371
8372 *ppBeacon = beacon;
8373
8374 kfree(old);
8375
8376 return 0;
8377
8378}
Jeff Johnson295189b2012-06-20 16:38:30 -07008379
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308380v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
8381#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
8382 const v_U8_t *pIes,
8383#else
8384 v_U8_t *pIes,
8385#endif
8386 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008387{
8388 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308389 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07008390 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308391
Jeff Johnson295189b2012-06-20 16:38:30 -07008392 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308393 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008394 elem_id = ptr[0];
8395 elem_len = ptr[1];
8396 left -= 2;
8397 if(elem_len > left)
8398 {
8399 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07008400 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07008401 eid,elem_len,left);
8402 return NULL;
8403 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308404 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008405 {
8406 return ptr;
8407 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308408
Jeff Johnson295189b2012-06-20 16:38:30 -07008409 left -= elem_len;
8410 ptr += (elem_len + 2);
8411 }
8412 return NULL;
8413}
8414
Jeff Johnson295189b2012-06-20 16:38:30 -07008415/* Check if rate is 11g rate or not */
8416static int wlan_hdd_rate_is_11g(u8 rate)
8417{
Sanjay Devnani28322e22013-06-21 16:13:40 -07008418 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008419 u8 i;
8420 for (i = 0; i < 8; i++)
8421 {
8422 if(rate == gRateArray[i])
8423 return TRUE;
8424 }
8425 return FALSE;
8426}
8427
8428/* Check for 11g rate and set proper 11g only mode */
8429static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
8430 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
8431{
8432 u8 i, num_rates = pIe[0];
8433
8434 pIe += 1;
8435 for ( i = 0; i < num_rates; i++)
8436 {
8437 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
8438 {
8439 /* If rate set have 11g rate than change the mode to 11G */
8440 *pSapHw_mode = eSAP_DOT11_MODE_11g;
8441 if (pIe[i] & BASIC_RATE_MASK)
8442 {
8443 /* If we have 11g rate as basic rate, it means mode
8444 is 11g only mode.
8445 */
8446 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
8447 *pCheckRatesfor11g = FALSE;
8448 }
8449 }
8450 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
8451 {
8452 *require_ht = TRUE;
8453 }
8454 }
8455 return;
8456}
8457
8458static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
8459{
8460 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
8461 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8462 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
8463 u8 checkRatesfor11g = TRUE;
8464 u8 require_ht = FALSE;
8465 u8 *pIe=NULL;
8466
8467 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
8468
8469 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
8470 pBeacon->head_len, WLAN_EID_SUPP_RATES);
8471 if (pIe != NULL)
8472 {
8473 pIe += 1;
8474 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8475 &pConfig->SapHw_mode);
8476 }
8477
8478 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8479 WLAN_EID_EXT_SUPP_RATES);
8480 if (pIe != NULL)
8481 {
8482
8483 pIe += 1;
8484 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8485 &pConfig->SapHw_mode);
8486 }
8487
8488 if( pConfig->channel > 14 )
8489 {
8490 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
8491 }
8492
8493 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8494 WLAN_EID_HT_CAPABILITY);
8495
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308496 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07008497 {
8498 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
8499 if(require_ht)
8500 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
8501 }
8502}
8503
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308504static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
8505 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
8506{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008507 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308508 v_U8_t *pIe = NULL;
8509 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8510
8511 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
8512 pBeacon->tail, pBeacon->tail_len);
8513
8514 if (pIe)
8515 {
8516 ielen = pIe[1] + 2;
8517 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8518 {
8519 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
8520 }
8521 else
8522 {
8523 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
8524 return -EINVAL;
8525 }
8526 *total_ielen += ielen;
8527 }
8528 return 0;
8529}
8530
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008531static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
8532 v_U8_t *genie, v_U8_t *total_ielen)
8533{
8534 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8535 int left = pBeacon->tail_len;
8536 v_U8_t *ptr = pBeacon->tail;
8537 v_U8_t elem_id, elem_len;
8538 v_U16_t ielen = 0;
8539
8540 if ( NULL == ptr || 0 == left )
8541 return;
8542
8543 while (left >= 2)
8544 {
8545 elem_id = ptr[0];
8546 elem_len = ptr[1];
8547 left -= 2;
8548 if (elem_len > left)
8549 {
8550 hddLog( VOS_TRACE_LEVEL_ERROR,
8551 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
8552 elem_id, elem_len, left);
8553 return;
8554 }
8555 if (IE_EID_VENDOR == elem_id)
8556 {
8557 /* skipping the VSIE's which we don't want to include or
8558 * it will be included by existing code
8559 */
8560 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
8561#ifdef WLAN_FEATURE_WFD
8562 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
8563#endif
8564 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8565 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8566 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
8567 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8568 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
8569 {
8570 ielen = ptr[1] + 2;
8571 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8572 {
8573 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
8574 *total_ielen += ielen;
8575 }
8576 else
8577 {
8578 hddLog( VOS_TRACE_LEVEL_ERROR,
8579 "IE Length is too big "
8580 "IEs eid=%d elem_len=%d total_ie_lent=%d",
8581 elem_id, elem_len, *total_ielen);
8582 }
8583 }
8584 }
8585
8586 left -= elem_len;
8587 ptr += (elem_len + 2);
8588 }
8589 return;
8590}
8591
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008592#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008593static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
8594 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008595#else
8596static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
8597 struct cfg80211_beacon_data *params)
8598#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008599{
8600 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308601 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008602 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07008603 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008604
8605 genie = vos_mem_malloc(MAX_GENIE_LEN);
8606
8607 if(genie == NULL) {
8608
8609 return -ENOMEM;
8610 }
8611
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308612 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8613 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008614 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308615 hddLog(LOGE,
8616 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308617 ret = -EINVAL;
8618 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008619 }
8620
8621#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308622 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8623 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
8624 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308625 hddLog(LOGE,
8626 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308627 ret = -EINVAL;
8628 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008629 }
8630#endif
8631
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308632 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8633 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008634 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308635 hddLog(LOGE,
8636 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308637 ret = -EINVAL;
8638 goto done;
8639 }
8640
8641 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
8642 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008643 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07008644 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008645
8646 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8647 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
8648 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
8649 {
8650 hddLog(LOGE,
8651 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008652 ret = -EINVAL;
8653 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008654 }
8655
8656 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8657 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
8658 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8659 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8660 ==eHAL_STATUS_FAILURE)
8661 {
8662 hddLog(LOGE,
8663 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008664 ret = -EINVAL;
8665 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008666 }
8667
8668 // Added for ProResp IE
8669 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
8670 {
8671 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
8672 u8 probe_rsp_ie_len[3] = {0};
8673 u8 counter = 0;
8674 /* Check Probe Resp Length if it is greater then 255 then Store
8675 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
8676 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
8677 Store More then 255 bytes into One Variable.
8678 */
8679 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
8680 {
8681 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
8682 {
8683 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
8684 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
8685 }
8686 else
8687 {
8688 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
8689 rem_probe_resp_ie_len = 0;
8690 }
8691 }
8692
8693 rem_probe_resp_ie_len = 0;
8694
8695 if (probe_rsp_ie_len[0] > 0)
8696 {
8697 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8698 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
8699 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8700 probe_rsp_ie_len[0], NULL,
8701 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8702 {
8703 hddLog(LOGE,
8704 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008705 ret = -EINVAL;
8706 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008707 }
8708 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
8709 }
8710
8711 if (probe_rsp_ie_len[1] > 0)
8712 {
8713 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8714 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
8715 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8716 probe_rsp_ie_len[1], NULL,
8717 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8718 {
8719 hddLog(LOGE,
8720 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008721 ret = -EINVAL;
8722 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008723 }
8724 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
8725 }
8726
8727 if (probe_rsp_ie_len[2] > 0)
8728 {
8729 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8730 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
8731 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8732 probe_rsp_ie_len[2], NULL,
8733 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8734 {
8735 hddLog(LOGE,
8736 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008737 ret = -EINVAL;
8738 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008739 }
8740 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
8741 }
8742
8743 if (probe_rsp_ie_len[1] == 0 )
8744 {
8745 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8746 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
8747 eANI_BOOLEAN_FALSE) )
8748 {
8749 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008750 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008751 }
8752 }
8753
8754 if (probe_rsp_ie_len[2] == 0 )
8755 {
8756 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8757 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
8758 eANI_BOOLEAN_FALSE) )
8759 {
8760 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008761 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008762 }
8763 }
8764
8765 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8766 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
8767 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8768 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8769 == eHAL_STATUS_FAILURE)
8770 {
8771 hddLog(LOGE,
8772 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008773 ret = -EINVAL;
8774 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008775 }
8776 }
8777 else
8778 {
8779 // Reset WNI_CFG_PROBE_RSP Flags
8780 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
8781
8782 hddLog(VOS_TRACE_LEVEL_INFO,
8783 "%s: No Probe Response IE received in set beacon",
8784 __func__);
8785 }
8786
8787 // Added for AssocResp IE
8788 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
8789 {
8790 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8791 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
8792 params->assocresp_ies_len, NULL,
8793 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8794 {
8795 hddLog(LOGE,
8796 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008797 ret = -EINVAL;
8798 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008799 }
8800
8801 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8802 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
8803 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8804 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8805 == eHAL_STATUS_FAILURE)
8806 {
8807 hddLog(LOGE,
8808 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008809 ret = -EINVAL;
8810 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008811 }
8812 }
8813 else
8814 {
8815 hddLog(VOS_TRACE_LEVEL_INFO,
8816 "%s: No Assoc Response IE received in set beacon",
8817 __func__);
8818
8819 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8820 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
8821 eANI_BOOLEAN_FALSE) )
8822 {
8823 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008824 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008825 }
8826 }
8827
Jeff Johnsone7245742012-09-05 17:12:55 -07008828done:
Jeff Johnson295189b2012-06-20 16:38:30 -07008829 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308830 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008831}
Jeff Johnson295189b2012-06-20 16:38:30 -07008832
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308833/*
Jeff Johnson295189b2012-06-20 16:38:30 -07008834 * FUNCTION: wlan_hdd_validate_operation_channel
8835 * called by wlan_hdd_cfg80211_start_bss() and
8836 * wlan_hdd_cfg80211_set_channel()
8837 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308838 * channel list.
8839 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07008840VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008841{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308842
Jeff Johnson295189b2012-06-20 16:38:30 -07008843 v_U32_t num_ch = 0;
8844 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
8845 u32 indx = 0;
8846 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308847 v_U8_t fValidChannel = FALSE, count = 0;
8848 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308849
Jeff Johnson295189b2012-06-20 16:38:30 -07008850 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8851
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308852 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008853 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308854 /* Validate the channel */
8855 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008856 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308857 if ( channel == rfChannels[count].channelNum )
8858 {
8859 fValidChannel = TRUE;
8860 break;
8861 }
8862 }
8863 if (fValidChannel != TRUE)
8864 {
8865 hddLog(VOS_TRACE_LEVEL_ERROR,
8866 "%s: Invalid Channel [%d]", __func__, channel);
8867 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008868 }
8869 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308870 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008871 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308872 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
8873 valid_ch, &num_ch))
8874 {
8875 hddLog(VOS_TRACE_LEVEL_ERROR,
8876 "%s: failed to get valid channel list", __func__);
8877 return VOS_STATUS_E_FAILURE;
8878 }
8879 for (indx = 0; indx < num_ch; indx++)
8880 {
8881 if (channel == valid_ch[indx])
8882 {
8883 break;
8884 }
8885 }
8886
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05308887 if (indx >= num_ch)
8888 {
8889 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
8890 {
8891 eCsrBand band;
8892 unsigned int freq;
8893
8894 sme_GetFreqBand(hHal, &band);
8895
8896 if (eCSR_BAND_5G == band)
8897 {
8898#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
8899 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
8900 {
8901 freq = ieee80211_channel_to_frequency(channel,
8902 IEEE80211_BAND_2GHZ);
8903 }
8904 else
8905 {
8906 freq = ieee80211_channel_to_frequency(channel,
8907 IEEE80211_BAND_5GHZ);
8908 }
8909#else
8910 freq = ieee80211_channel_to_frequency(channel);
8911#endif
8912 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
8913 return VOS_STATUS_SUCCESS;
8914 }
8915 }
8916
8917 hddLog(VOS_TRACE_LEVEL_ERROR,
8918 "%s: Invalid Channel [%d]", __func__, channel);
8919 return VOS_STATUS_E_FAILURE;
8920 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008921 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05308922
Jeff Johnson295189b2012-06-20 16:38:30 -07008923 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308924
Jeff Johnson295189b2012-06-20 16:38:30 -07008925}
8926
Viral Modi3a32cc52013-02-08 11:14:52 -08008927/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308928 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08008929 * This function is used to set the channel number
8930 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308931static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08008932 struct ieee80211_channel *chan,
8933 enum nl80211_channel_type channel_type
8934 )
8935{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308936 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08008937 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07008938 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08008939 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308940 hdd_context_t *pHddCtx;
8941 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08008942
8943 ENTER();
8944
8945 if( NULL == dev )
8946 {
8947 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008948 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08008949 return -ENODEV;
8950 }
8951 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308952
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308953 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8954 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
8955 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08008956 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308957 "%s: device_mode = %s (%d) freq = %d", __func__,
8958 hdd_device_modetoString(pAdapter->device_mode),
8959 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308960
8961 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8962 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308963 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08008964 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308965 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08008966 }
8967
8968 /*
8969 * Do freq to chan conversion
8970 * TODO: for 11a
8971 */
8972
8973 channel = ieee80211_frequency_to_channel(freq);
8974
8975 /* Check freq range */
8976 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
8977 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
8978 {
8979 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008980 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08008981 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
8982 WNI_CFG_CURRENT_CHANNEL_STAMAX);
8983 return -EINVAL;
8984 }
8985
8986 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8987
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05308988 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
8989 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08008990 {
8991 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
8992 {
8993 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008994 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08008995 return -EINVAL;
8996 }
8997 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
8998 "%s: set channel to [%d] for device mode =%d",
8999 __func__, channel,pAdapter->device_mode);
9000 }
9001 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08009002 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08009003 )
9004 {
9005 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9006 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
9007 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9008
9009 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
9010 {
9011 /* Link is up then return cant set channel*/
9012 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009013 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009014 return -EINVAL;
9015 }
9016
9017 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
9018 pHddStaCtx->conn_info.operationChannel = channel;
9019 pRoamProfile->ChannelInfo.ChannelList =
9020 &pHddStaCtx->conn_info.operationChannel;
9021 }
9022 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08009023 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08009024 )
9025 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309026 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9027 {
9028 if(VOS_STATUS_SUCCESS !=
9029 wlan_hdd_validate_operation_channel(pAdapter,channel))
9030 {
9031 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009032 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309033 return -EINVAL;
9034 }
9035 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9036 }
9037 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08009038 {
9039 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
9040
9041 /* If auto channel selection is configured as enable/ 1 then ignore
9042 channel set by supplicant
9043 */
9044 if ( cfg_param->apAutoChannelSelection )
9045 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309046 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
9047 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08009048 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309049 "%s: set channel to auto channel (0) for device mode =%s (%d)",
9050 __func__, hdd_device_modetoString(pAdapter->device_mode),
9051 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08009052 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309053 else
9054 {
9055 if(VOS_STATUS_SUCCESS !=
9056 wlan_hdd_validate_operation_channel(pAdapter,channel))
9057 {
9058 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009059 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309060 return -EINVAL;
9061 }
9062 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9063 }
Viral Modi3a32cc52013-02-08 11:14:52 -08009064 }
9065 }
9066 else
9067 {
9068 hddLog(VOS_TRACE_LEVEL_FATAL,
9069 "%s: Invalid device mode failed to set valid channel", __func__);
9070 return -EINVAL;
9071 }
9072 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309073 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009074}
9075
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309076static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
9077 struct net_device *dev,
9078 struct ieee80211_channel *chan,
9079 enum nl80211_channel_type channel_type
9080 )
9081{
9082 int ret;
9083
9084 vos_ssr_protect(__func__);
9085 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
9086 vos_ssr_unprotect(__func__);
9087
9088 return ret;
9089}
9090
Jeff Johnson295189b2012-06-20 16:38:30 -07009091#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9092static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9093 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009094#else
9095static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9096 struct cfg80211_beacon_data *params,
9097 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309098 enum nl80211_hidden_ssid hidden_ssid,
9099 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009100#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009101{
9102 tsap_Config_t *pConfig;
9103 beacon_data_t *pBeacon = NULL;
9104 struct ieee80211_mgmt *pMgmt_frame;
9105 v_U8_t *pIe=NULL;
9106 v_U16_t capab_info;
9107 eCsrAuthType RSNAuthType;
9108 eCsrEncryptionType RSNEncryptType;
9109 eCsrEncryptionType mcRSNEncryptType;
9110 int status = VOS_STATUS_SUCCESS;
9111 tpWLAN_SAPEventCB pSapEventCallback;
9112 hdd_hostapd_state_t *pHostapdState;
9113 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
9114 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309115 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009116 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309117 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07009118 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08009119 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05309120 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07009121 v_BOOL_t MFPCapable = VOS_FALSE;
9122 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309123 v_BOOL_t sapEnable11AC =
9124 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07009125 ENTER();
9126
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309127 iniConfig = pHddCtx->cfg_ini;
9128
Jeff Johnson295189b2012-06-20 16:38:30 -07009129 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
9130
9131 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9132
9133 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9134
9135 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9136
9137 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
9138
9139 //channel is already set in the set_channel Call back
9140 //pConfig->channel = pCommitConfig->channel;
9141
9142 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309143 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07009144 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
9145
9146 pConfig->dtim_period = pBeacon->dtim_period;
9147
Arif Hussain6d2a3322013-11-17 19:50:10 -08009148 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07009149 pConfig->dtim_period);
9150
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08009151 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07009152 {
9153 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009154 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05309155 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
9156 {
9157 tANI_BOOLEAN restartNeeded;
9158 pConfig->ieee80211d = 1;
9159 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
9160 sme_setRegInfo(hHal, pConfig->countryCode);
9161 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
9162 }
9163 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009164 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07009165 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07009166 pConfig->ieee80211d = 1;
9167 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
9168 sme_setRegInfo(hHal, pConfig->countryCode);
9169 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07009170 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009171 else
9172 {
9173 pConfig->ieee80211d = 0;
9174 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309175 /*
9176 * If auto channel is configured i.e. channel is 0,
9177 * so skip channel validation.
9178 */
9179 if( AUTO_CHANNEL_SELECT != pConfig->channel )
9180 {
9181 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
9182 {
9183 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009184 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309185 return -EINVAL;
9186 }
9187 }
9188 else
9189 {
9190 if(1 != pHddCtx->is_dynamic_channel_range_set)
9191 {
9192 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
9193 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
9194 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
9195 }
9196 pHddCtx->is_dynamic_channel_range_set = 0;
9197 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009198 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009199 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009200 {
9201 pConfig->ieee80211d = 0;
9202 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309203
9204#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9205 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9206 pConfig->authType = eSAP_OPEN_SYSTEM;
9207 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9208 pConfig->authType = eSAP_SHARED_KEY;
9209 else
9210 pConfig->authType = eSAP_AUTO_SWITCH;
9211#else
9212 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9213 pConfig->authType = eSAP_OPEN_SYSTEM;
9214 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9215 pConfig->authType = eSAP_SHARED_KEY;
9216 else
9217 pConfig->authType = eSAP_AUTO_SWITCH;
9218#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009219
9220 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309221
9222 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07009223 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
9224
9225 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
9226
9227 /*Set wps station to configured*/
9228 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
9229
9230 if(pIe)
9231 {
9232 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
9233 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009234 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07009235 return -EINVAL;
9236 }
9237 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
9238 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009239 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07009240 /* Check 15 bit of WPS IE as it contain information for wps state
9241 * WPS state
9242 */
9243 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
9244 {
9245 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
9246 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
9247 {
9248 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
9249 }
9250 }
9251 }
9252 else
9253 {
9254 pConfig->wps_state = SAP_WPS_DISABLED;
9255 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309256 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07009257
c_hpothufe599e92014-06-16 11:38:55 +05309258 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9259 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9260 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
9261 eCSR_ENCRYPT_TYPE_NONE;
9262
Jeff Johnson295189b2012-06-20 16:38:30 -07009263 pConfig->RSNWPAReqIELength = 0;
9264 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309265 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009266 WLAN_EID_RSN);
9267 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309268 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009269 pConfig->RSNWPAReqIELength = pIe[1] + 2;
9270 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
9271 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309272 /* The actual processing may eventually be more extensive than
9273 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07009274 * by the app.
9275 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309276 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009277 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9278 &RSNEncryptType,
9279 &mcRSNEncryptType,
9280 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009281 &MFPCapable,
9282 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07009283 pConfig->pRSNWPAReqIE[1]+2,
9284 pConfig->pRSNWPAReqIE );
9285
9286 if( VOS_STATUS_SUCCESS == status )
9287 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309288 /* Now copy over all the security attributes you have
9289 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009290 * */
9291 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9292 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9293 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9294 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309295 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009296 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009297 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9298 }
9299 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309300
Jeff Johnson295189b2012-06-20 16:38:30 -07009301 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9302 pBeacon->tail, pBeacon->tail_len);
9303
9304 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
9305 {
9306 if (pConfig->pRSNWPAReqIE)
9307 {
9308 /*Mixed mode WPA/WPA2*/
9309 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
9310 pConfig->RSNWPAReqIELength += pIe[1] + 2;
9311 }
9312 else
9313 {
9314 pConfig->RSNWPAReqIELength = pIe[1] + 2;
9315 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
9316 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309317 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009318 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9319 &RSNEncryptType,
9320 &mcRSNEncryptType,
9321 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009322 &MFPCapable,
9323 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07009324 pConfig->pRSNWPAReqIE[1]+2,
9325 pConfig->pRSNWPAReqIE );
9326
9327 if( VOS_STATUS_SUCCESS == status )
9328 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309329 /* Now copy over all the security attributes you have
9330 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009331 * */
9332 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9333 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9334 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9335 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309336 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009337 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009338 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9339 }
9340 }
9341 }
9342
Jeff Johnson4416a782013-03-25 14:17:50 -07009343 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
9344 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
9345 return -EINVAL;
9346 }
9347
Jeff Johnson295189b2012-06-20 16:38:30 -07009348 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
9349
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009350#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009351 if (params->ssid != NULL)
9352 {
9353 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
9354 pConfig->SSIDinfo.ssid.length = params->ssid_len;
9355 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9356 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9357 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009358#else
9359 if (ssid != NULL)
9360 {
9361 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
9362 pConfig->SSIDinfo.ssid.length = ssid_len;
9363 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9364 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9365 }
9366#endif
9367
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309368 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07009369 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309370
Jeff Johnson295189b2012-06-20 16:38:30 -07009371 /* default value */
9372 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
9373 pConfig->num_accept_mac = 0;
9374 pConfig->num_deny_mac = 0;
9375
9376 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9377 pBeacon->tail, pBeacon->tail_len);
9378
9379 /* pIe for black list is following form:
9380 type : 1 byte
9381 length : 1 byte
9382 OUI : 4 bytes
9383 acl type : 1 byte
9384 no of mac addr in black list: 1 byte
9385 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309386 */
9387 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009388 {
9389 pConfig->SapMacaddr_acl = pIe[6];
9390 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009391 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009392 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309393 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
9394 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009395 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9396 for (i = 0; i < pConfig->num_deny_mac; i++)
9397 {
9398 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9399 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309400 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009401 }
9402 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9403 pBeacon->tail, pBeacon->tail_len);
9404
9405 /* pIe for white list is following form:
9406 type : 1 byte
9407 length : 1 byte
9408 OUI : 4 bytes
9409 acl type : 1 byte
9410 no of mac addr in white list: 1 byte
9411 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309412 */
9413 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009414 {
9415 pConfig->SapMacaddr_acl = pIe[6];
9416 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009417 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009418 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309419 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
9420 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009421 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9422 for (i = 0; i < pConfig->num_accept_mac; i++)
9423 {
9424 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9425 acl_entry++;
9426 }
9427 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309428
Jeff Johnson295189b2012-06-20 16:38:30 -07009429 wlan_hdd_set_sapHwmode(pHostapdAdapter);
9430
Jeff Johnsone7245742012-09-05 17:12:55 -07009431#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009432 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309433 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
9434 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05309435 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
9436 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009437 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
9438 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309439 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
9440 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07009441 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309442 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07009443 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309444 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009445
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309446 /* If ACS disable and selected channel <= 14
9447 * OR
9448 * ACS enabled and ACS operating band is choosen as 2.4
9449 * AND
9450 * VHT in 2.4G Disabled
9451 * THEN
9452 * Fallback to 11N mode
9453 */
9454 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
9455 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05309456 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309457 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009458 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309459 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
9460 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009461 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
9462 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009463 }
9464#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309465
Jeff Johnson295189b2012-06-20 16:38:30 -07009466 // ht_capab is not what the name conveys,this is used for protection bitmap
9467 pConfig->ht_capab =
9468 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
9469
9470 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
9471 {
9472 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
9473 return -EINVAL;
9474 }
9475
9476 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309477 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07009478 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
9479 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309480 pConfig->obssProtEnabled =
9481 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07009482
Chet Lanctot8cecea22014-02-11 19:09:36 -08009483#ifdef WLAN_FEATURE_11W
9484 pConfig->mfpCapable = MFPCapable;
9485 pConfig->mfpRequired = MFPRequired;
9486 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
9487 pConfig->mfpCapable, pConfig->mfpRequired);
9488#endif
9489
Arif Hussain6d2a3322013-11-17 19:50:10 -08009490 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07009491 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08009492 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
9493 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
9494 (int)pConfig->channel);
9495 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
9496 pConfig->SapHw_mode, pConfig->privacy,
9497 pConfig->authType);
9498 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
9499 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
9500 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
9501 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07009502
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309503 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009504 {
9505 //Bss already started. just return.
9506 //TODO Probably it should update some beacon params.
9507 hddLog( LOGE, "Bss Already started...Ignore the request");
9508 EXIT();
9509 return 0;
9510 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309511
Agarwal Ashish51325b52014-06-16 16:50:49 +05309512 if (vos_max_concurrent_connections_reached()) {
9513 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9514 return -EINVAL;
9515 }
9516
Jeff Johnson295189b2012-06-20 16:38:30 -07009517 pConfig->persona = pHostapdAdapter->device_mode;
9518
Peng Xu2446a892014-09-05 17:21:18 +05309519 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
9520 if ( NULL != psmeConfig)
9521 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309522 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05309523 sme_GetConfigParam(hHal, psmeConfig);
9524 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309525#ifdef WLAN_FEATURE_AP_HT40_24G
9526 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
9527 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
9528 && pHddCtx->cfg_ini->apHT40_24GEnabled)
9529 {
9530 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
9531 sme_UpdateConfig (hHal, psmeConfig);
9532 }
9533#endif
Peng Xu2446a892014-09-05 17:21:18 +05309534 vos_mem_free(psmeConfig);
9535 }
Peng Xuafc34e32014-09-25 13:23:55 +05309536 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05309537
Jeff Johnson295189b2012-06-20 16:38:30 -07009538 pSapEventCallback = hdd_hostapd_SAPEventCB;
9539 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
9540 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
9541 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009542 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009543 return -EINVAL;
9544 }
9545
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309546 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07009547 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
9548
9549 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309550
Jeff Johnson295189b2012-06-20 16:38:30 -07009551 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309552 {
9553 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009554 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07009555 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009556 VOS_ASSERT(0);
9557 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309558
Jeff Johnson295189b2012-06-20 16:38:30 -07009559 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05309560 /* Initialize WMM configuation */
9561 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309562 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009563
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009564#ifdef WLAN_FEATURE_P2P_DEBUG
9565 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
9566 {
9567 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
9568 {
9569 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9570 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009571 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009572 }
9573 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
9574 {
9575 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9576 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009577 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009578 }
9579 }
9580#endif
9581
Jeff Johnson295189b2012-06-20 16:38:30 -07009582 pHostapdState->bCommit = TRUE;
9583 EXIT();
9584
9585 return 0;
9586}
9587
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009588#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309589static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309590 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07009591 struct beacon_parameters *params)
9592{
9593 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309594 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309595 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009596
9597 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309598
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309599 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9600 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
9601 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309602 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
9603 hdd_device_modetoString(pAdapter->device_mode),
9604 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009605
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309606 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9607 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309608 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009609 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309610 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009611 }
9612
Agarwal Ashish51325b52014-06-16 16:50:49 +05309613 if (vos_max_concurrent_connections_reached()) {
9614 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9615 return -EINVAL;
9616 }
9617
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309618 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009619 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009620 )
9621 {
9622 beacon_data_t *old,*new;
9623
9624 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309625
Jeff Johnson295189b2012-06-20 16:38:30 -07009626 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309627 {
9628 hddLog(VOS_TRACE_LEVEL_WARN,
9629 FL("already beacon info added to session(%d)"),
9630 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009631 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309632 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009633
9634 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
9635
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309636 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07009637 {
9638 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009639 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009640 return -EINVAL;
9641 }
9642
9643 pAdapter->sessionCtx.ap.beacon = new;
9644
9645 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
9646 }
9647
9648 EXIT();
9649 return status;
9650}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309651
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309652static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
9653 struct net_device *dev,
9654 struct beacon_parameters *params)
9655{
9656 int ret;
9657
9658 vos_ssr_protect(__func__);
9659 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
9660 vos_ssr_unprotect(__func__);
9661
9662 return ret;
9663}
9664
9665static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009666 struct net_device *dev,
9667 struct beacon_parameters *params)
9668{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309669 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309670 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9671 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309672 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009673
9674 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309675
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309676 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9677 TRACE_CODE_HDD_CFG80211_SET_BEACON,
9678 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
9679 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9680 __func__, hdd_device_modetoString(pAdapter->device_mode),
9681 pAdapter->device_mode);
9682
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309683 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9684 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309685 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009686 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309687 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009688 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309689
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309690 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009691 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309692 )
Jeff Johnson295189b2012-06-20 16:38:30 -07009693 {
9694 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309695
Jeff Johnson295189b2012-06-20 16:38:30 -07009696 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309697
Jeff Johnson295189b2012-06-20 16:38:30 -07009698 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309699 {
9700 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9701 FL("session(%d) old and new heads points to NULL"),
9702 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009703 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309704 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009705
9706 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
9707
9708 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309709 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009710 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009711 return -EINVAL;
9712 }
9713
9714 pAdapter->sessionCtx.ap.beacon = new;
9715
9716 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
9717 }
9718
9719 EXIT();
9720 return status;
9721}
9722
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309723static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
9724 struct net_device *dev,
9725 struct beacon_parameters *params)
9726{
9727 int ret;
9728
9729 vos_ssr_protect(__func__);
9730 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
9731 vos_ssr_unprotect(__func__);
9732
9733 return ret;
9734}
9735
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009736#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9737
9738#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309739static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009740 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009741#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309742static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009743 struct net_device *dev)
9744#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009745{
9746 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07009747 hdd_context_t *pHddCtx = NULL;
9748 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309749 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309750 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009751
9752 ENTER();
9753
9754 if (NULL == pAdapter)
9755 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309756 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009757 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009758 return -ENODEV;
9759 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009760
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309761 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9762 TRACE_CODE_HDD_CFG80211_STOP_AP,
9763 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309764 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9765 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309766 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009767 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309768 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07009769 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009770
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009771 pScanInfo = &pHddCtx->scan_info;
9772
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309773 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9774 __func__, hdd_device_modetoString(pAdapter->device_mode),
9775 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009776
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309777 ret = wlan_hdd_scan_abort(pAdapter);
9778
Girish Gowli4bf7a632014-06-12 13:42:11 +05309779 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07009780 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309781 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9782 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309783
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309784 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07009785 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309786 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9787 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08009788
Jeff Johnsone7245742012-09-05 17:12:55 -07009789 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309790 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07009791 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309792 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009793 }
9794
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05309795 /* Delete all associated STAs before stopping AP/P2P GO */
9796 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05309797 hdd_hostapd_stop(dev);
9798
Jeff Johnson295189b2012-06-20 16:38:30 -07009799 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009800 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009801 )
9802 {
9803 beacon_data_t *old;
9804
9805 old = pAdapter->sessionCtx.ap.beacon;
9806
9807 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309808 {
9809 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9810 FL("session(%d) beacon data points to NULL"),
9811 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009812 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309813 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009814
Jeff Johnson295189b2012-06-20 16:38:30 -07009815 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009816
9817 mutex_lock(&pHddCtx->sap_lock);
9818 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9819 {
Jeff Johnson4416a782013-03-25 14:17:50 -07009820 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009821 {
9822 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9823
9824 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
9825
9826 if (!VOS_IS_STATUS_SUCCESS(status))
9827 {
9828 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009829 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009830 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309831 }
9832 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009833 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309834 /* BSS stopped, clear the active sessions for this device mode */
9835 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009836 }
9837 mutex_unlock(&pHddCtx->sap_lock);
9838
9839 if(status != VOS_STATUS_SUCCESS)
9840 {
9841 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009842 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009843 return -EINVAL;
9844 }
9845
Jeff Johnson4416a782013-03-25 14:17:50 -07009846 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07009847 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
9848 ==eHAL_STATUS_FAILURE)
9849 {
9850 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009851 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009852 }
9853
Jeff Johnson4416a782013-03-25 14:17:50 -07009854 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07009855 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9856 eANI_BOOLEAN_FALSE) )
9857 {
9858 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009859 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009860 }
9861
9862 // Reset WNI_CFG_PROBE_RSP Flags
9863 wlan_hdd_reset_prob_rspies(pAdapter);
9864
9865 pAdapter->sessionCtx.ap.beacon = NULL;
9866 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009867#ifdef WLAN_FEATURE_P2P_DEBUG
9868 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
9869 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
9870 {
9871 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
9872 "GO got removed");
9873 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
9874 }
9875#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009876 }
9877 EXIT();
9878 return status;
9879}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009880
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309881#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9882static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
9883 struct net_device *dev)
9884{
9885 int ret;
9886
9887 vos_ssr_protect(__func__);
9888 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
9889 vos_ssr_unprotect(__func__);
9890
9891 return ret;
9892}
9893#else
9894static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
9895 struct net_device *dev)
9896{
9897 int ret;
9898
9899 vos_ssr_protect(__func__);
9900 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
9901 vos_ssr_unprotect(__func__);
9902
9903 return ret;
9904}
9905#endif
9906
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009907#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
9908
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309909static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309910 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009911 struct cfg80211_ap_settings *params)
9912{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309913 hdd_adapter_t *pAdapter;
9914 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309915 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009916
9917 ENTER();
9918
Girish Gowlib143d7a2015-02-18 19:39:55 +05309919 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07009920 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309921 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05309922 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309923 return -ENODEV;
9924 }
9925
9926 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9927 if (NULL == pAdapter)
9928 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309929 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309930 "%s: HDD adapter is Null", __func__);
9931 return -ENODEV;
9932 }
9933
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309934 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9935 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
9936 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309937 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
9938 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309939 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309940 "%s: HDD adapter magic is invalid", __func__);
9941 return -ENODEV;
9942 }
9943
9944 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309945 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309946 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309947 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309948 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309949 }
9950
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309951 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
9952 __func__, hdd_device_modetoString(pAdapter->device_mode),
9953 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309954
9955 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009956 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009957 )
9958 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309959 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009960
9961 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309962
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009963 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309964 {
9965 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9966 FL("already beacon info added to session(%d)"),
9967 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009968 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309969 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009970
Girish Gowlib143d7a2015-02-18 19:39:55 +05309971#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9972 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
9973 &new,
9974 &params->beacon);
9975#else
9976 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
9977 &new,
9978 &params->beacon,
9979 params->dtim_period);
9980#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009981
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309982 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009983 {
9984 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309985 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009986 return -EINVAL;
9987 }
9988 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08009989#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07009990 wlan_hdd_cfg80211_set_channel(wiphy, dev,
9991#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
9992 params->channel, params->channel_type);
9993#else
9994 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
9995#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08009996#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009997 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309998 params->ssid_len, params->hidden_ssid,
9999 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010000 }
10001
10002 EXIT();
10003 return status;
10004}
10005
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010006static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
10007 struct net_device *dev,
10008 struct cfg80211_ap_settings *params)
10009{
10010 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010011
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010012 vos_ssr_protect(__func__);
10013 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
10014 vos_ssr_unprotect(__func__);
10015
10016 return ret;
10017}
10018
10019static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010020 struct net_device *dev,
10021 struct cfg80211_beacon_data *params)
10022{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010023 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010024 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010025 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010026
10027 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010028
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010029 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10030 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
10031 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010032 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010033 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010034
10035 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10036 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010037 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010038 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010039 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010040 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010041
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010042 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010043 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010044 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010045 {
10046 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010047
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010048 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010049
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010050 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010051 {
10052 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10053 FL("session(%d) beacon data points to NULL"),
10054 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010055 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010056 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010057
10058 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
10059
10060 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010061 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010062 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010063 return -EINVAL;
10064 }
10065
10066 pAdapter->sessionCtx.ap.beacon = new;
10067
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010068 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
10069 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010070 }
10071
10072 EXIT();
10073 return status;
10074}
10075
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010076static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
10077 struct net_device *dev,
10078 struct cfg80211_beacon_data *params)
10079{
10080 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010081
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010082 vos_ssr_protect(__func__);
10083 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
10084 vos_ssr_unprotect(__func__);
10085
10086 return ret;
10087}
10088
10089#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010090
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010091static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010092 struct net_device *dev,
10093 struct bss_parameters *params)
10094{
10095 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010096 hdd_context_t *pHddCtx;
10097 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010098
10099 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010100
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010101 if (NULL == pAdapter)
10102 {
10103 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10104 "%s: HDD adapter is Null", __func__);
10105 return -ENODEV;
10106 }
10107 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010108 ret = wlan_hdd_validate_context(pHddCtx);
10109 if (0 != ret)
10110 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010111 return ret;
10112 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010113 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10114 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
10115 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010116 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10117 __func__, hdd_device_modetoString(pAdapter->device_mode),
10118 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010119
10120 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010121 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010122 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010123 {
10124 /* ap_isolate == -1 means that in change bss, upper layer doesn't
10125 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010126 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070010127 {
10128 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010129 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010130 }
10131
10132 EXIT();
10133 return 0;
10134}
10135
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010136static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
10137 struct net_device *dev,
10138 struct bss_parameters *params)
10139{
10140 int ret;
10141
10142 vos_ssr_protect(__func__);
10143 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
10144 vos_ssr_unprotect(__func__);
10145
10146 return ret;
10147}
Kiet Lam10841362013-11-01 11:36:50 +053010148/* FUNCTION: wlan_hdd_change_country_code_cd
10149* to wait for contry code completion
10150*/
10151void* wlan_hdd_change_country_code_cb(void *pAdapter)
10152{
10153 hdd_adapter_t *call_back_pAdapter = pAdapter;
10154 complete(&call_back_pAdapter->change_country_code);
10155 return NULL;
10156}
10157
Jeff Johnson295189b2012-06-20 16:38:30 -070010158/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010159 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070010160 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
10161 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010162int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010163 struct net_device *ndev,
10164 enum nl80211_iftype type,
10165 u32 *flags,
10166 struct vif_params *params
10167 )
10168{
10169 struct wireless_dev *wdev;
10170 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010171 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070010172 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010173 tCsrRoamProfile *pRoamProfile = NULL;
10174 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010175 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010176 eMib_dot11DesiredBssType connectedBssType;
10177 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010178 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010179
10180 ENTER();
10181
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010182 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010183 {
10184 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10185 "%s: Adapter context is null", __func__);
10186 return VOS_STATUS_E_FAILURE;
10187 }
10188
10189 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10190 if (!pHddCtx)
10191 {
10192 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10193 "%s: HDD context is null", __func__);
10194 return VOS_STATUS_E_FAILURE;
10195 }
10196
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010197 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10198 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
10199 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010200 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010201 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010202 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010203 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010204 }
10205
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010206 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10207 __func__, hdd_device_modetoString(pAdapter->device_mode),
10208 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010209
Agarwal Ashish51325b52014-06-16 16:50:49 +053010210 if (vos_max_concurrent_connections_reached()) {
10211 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10212 return -EINVAL;
10213 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010214 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070010215 wdev = ndev->ieee80211_ptr;
10216
10217#ifdef WLAN_BTAMP_FEATURE
10218 if((NL80211_IFTYPE_P2P_CLIENT == type)||
10219 (NL80211_IFTYPE_ADHOC == type)||
10220 (NL80211_IFTYPE_AP == type)||
10221 (NL80211_IFTYPE_P2P_GO == type))
10222 {
10223 pHddCtx->isAmpAllowed = VOS_FALSE;
10224 // stop AMP traffic
10225 status = WLANBAP_StopAmp();
10226 if(VOS_STATUS_SUCCESS != status )
10227 {
10228 pHddCtx->isAmpAllowed = VOS_TRUE;
10229 hddLog(VOS_TRACE_LEVEL_FATAL,
10230 "%s: Failed to stop AMP", __func__);
10231 return -EINVAL;
10232 }
10233 }
10234#endif //WLAN_BTAMP_FEATURE
10235 /* Reset the current device mode bit mask*/
10236 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
10237
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053010238 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
10239 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
10240 (type == NL80211_IFTYPE_P2P_GO)))
10241 {
10242 /* Notify Mode change in case of concurrency.
10243 * Below function invokes TDLS teardown Functionality Since TDLS is
10244 * not Supported in case of concurrency i.e Once P2P session
10245 * is detected disable offchannel and teardown TDLS links
10246 */
10247 hddLog(LOG1,
10248 FL("Device mode = %d Interface type = %d"),
10249 pAdapter->device_mode, type);
10250 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
10251 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053010252
Jeff Johnson295189b2012-06-20 16:38:30 -070010253 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070010254 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070010255 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010256 )
10257 {
10258 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010259 if (!pWextState)
10260 {
10261 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10262 "%s: pWextState is null", __func__);
10263 return VOS_STATUS_E_FAILURE;
10264 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010265 pRoamProfile = &pWextState->roamProfile;
10266 LastBSSType = pRoamProfile->BSSType;
10267
10268 switch (type)
10269 {
10270 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010271 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010272 hddLog(VOS_TRACE_LEVEL_INFO,
10273 "%s: setting interface Type to INFRASTRUCTURE", __func__);
10274 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010275#ifdef WLAN_FEATURE_11AC
10276 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
10277 {
10278 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
10279 }
10280#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010281 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070010282 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010283 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010284 //Check for sub-string p2p to confirm its a p2p interface
10285 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010286 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053010287#ifdef FEATURE_WLAN_TDLS
10288 mutex_lock(&pHddCtx->tdls_lock);
10289 wlan_hdd_tdls_exit(pAdapter, TRUE);
10290 mutex_unlock(&pHddCtx->tdls_lock);
10291#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010292 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10293 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10294 }
10295 else
10296 {
10297 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010298 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010299 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010300 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053010301
Jeff Johnson295189b2012-06-20 16:38:30 -070010302 case NL80211_IFTYPE_ADHOC:
10303 hddLog(VOS_TRACE_LEVEL_INFO,
10304 "%s: setting interface Type to ADHOC", __func__);
10305 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
10306 pRoamProfile->phyMode =
10307 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070010308 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010309 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053010310 hdd_set_ibss_ops( pAdapter );
10311 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053010312
10313 status = hdd_sta_id_hash_attach(pAdapter);
10314 if (VOS_STATUS_SUCCESS != status) {
10315 hddLog(VOS_TRACE_LEVEL_ERROR,
10316 FL("Failed to initialize hash for IBSS"));
10317 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010318 break;
10319
10320 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010321 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010322 {
10323 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10324 "%s: setting interface Type to %s", __func__,
10325 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
10326
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010327 //Cancel any remain on channel for GO mode
10328 if (NL80211_IFTYPE_P2P_GO == type)
10329 {
10330 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
10331 }
Mohit Khanna0f232092012-09-11 14:46:08 -070010332 if (NL80211_IFTYPE_AP == type)
10333 {
10334 /* As Loading WLAN Driver one interface being created for p2p device
10335 * address. This will take one HW STA and the max number of clients
10336 * that can connect to softAP will be reduced by one. so while changing
10337 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
10338 * interface as it is not required in SoftAP mode.
10339 */
10340
10341 // Get P2P Adapter
10342 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
10343
10344 if (pP2pAdapter)
10345 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010346 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053010347 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070010348 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
10349 }
10350 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053010351 //Disable IMPS & BMPS for SAP/GO
10352 if(VOS_STATUS_E_FAILURE ==
10353 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
10354 {
10355 //Fail to Exit BMPS
10356 VOS_ASSERT(0);
10357 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053010358
10359 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
10360
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010361#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070010362
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010363 /* A Mutex Lock is introduced while changing the mode to
10364 * protect the concurrent access for the Adapters by TDLS
10365 * module.
10366 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010367 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010368#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010369 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053010370 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010371 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070010372 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10373 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010374#ifdef FEATURE_WLAN_TDLS
10375 mutex_unlock(&pHddCtx->tdls_lock);
10376#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010377 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
10378 (pConfig->apRandomBssidEnabled))
10379 {
10380 /* To meet Android requirements create a randomized
10381 MAC address of the form 02:1A:11:Fx:xx:xx */
10382 get_random_bytes(&ndev->dev_addr[3], 3);
10383 ndev->dev_addr[0] = 0x02;
10384 ndev->dev_addr[1] = 0x1A;
10385 ndev->dev_addr[2] = 0x11;
10386 ndev->dev_addr[3] |= 0xF0;
10387 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
10388 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080010389 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
10390 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010391 }
10392
Jeff Johnson295189b2012-06-20 16:38:30 -070010393 hdd_set_ap_ops( pAdapter->dev );
10394
Kiet Lam10841362013-11-01 11:36:50 +053010395 /* This is for only SAP mode where users can
10396 * control country through ini.
10397 * P2P GO follows station country code
10398 * acquired during the STA scanning. */
10399 if((NL80211_IFTYPE_AP == type) &&
10400 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
10401 {
10402 int status = 0;
10403 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
10404 "%s: setting country code from INI ", __func__);
10405 init_completion(&pAdapter->change_country_code);
10406 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
10407 (void *)(tSmeChangeCountryCallback)
10408 wlan_hdd_change_country_code_cb,
10409 pConfig->apCntryCode, pAdapter,
10410 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053010411 eSIR_FALSE,
10412 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053010413 if (eHAL_STATUS_SUCCESS == status)
10414 {
10415 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010416 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053010417 &pAdapter->change_country_code,
10418 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010419 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053010420 {
10421 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010422 FL("SME Timed out while setting country code %ld"),
10423 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080010424
10425 if (pHddCtx->isLogpInProgress)
10426 {
10427 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10428 "%s: LOGP in Progress. Ignore!!!", __func__);
10429 return -EAGAIN;
10430 }
Kiet Lam10841362013-11-01 11:36:50 +053010431 }
10432 }
10433 else
10434 {
10435 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010436 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053010437 return -EINVAL;
10438 }
10439 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010440 status = hdd_init_ap_mode(pAdapter);
10441 if(status != VOS_STATUS_SUCCESS)
10442 {
10443 hddLog(VOS_TRACE_LEVEL_FATAL,
10444 "%s: Error initializing the ap mode", __func__);
10445 return -EINVAL;
10446 }
10447 hdd_set_conparam(1);
10448
Nirav Shah7e3c8132015-06-22 23:51:42 +053010449 status = hdd_sta_id_hash_attach(pAdapter);
10450 if (VOS_STATUS_SUCCESS != status)
10451 {
10452 hddLog(VOS_TRACE_LEVEL_ERROR,
10453 FL("Failed to initialize hash for AP"));
10454 return -EINVAL;
10455 }
10456
Jeff Johnson295189b2012-06-20 16:38:30 -070010457 /*interface type changed update in wiphy structure*/
10458 if(wdev)
10459 {
10460 wdev->iftype = type;
10461 pHddCtx->change_iface = type;
10462 }
10463 else
10464 {
10465 hddLog(VOS_TRACE_LEVEL_ERROR,
10466 "%s: ERROR !!!! Wireless dev is NULL", __func__);
10467 return -EINVAL;
10468 }
10469 goto done;
10470 }
10471
10472 default:
10473 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10474 __func__);
10475 return -EOPNOTSUPP;
10476 }
10477 }
10478 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010479 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010480 )
10481 {
10482 switch(type)
10483 {
10484 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010485 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010486 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053010487
10488 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010489#ifdef FEATURE_WLAN_TDLS
10490
10491 /* A Mutex Lock is introduced while changing the mode to
10492 * protect the concurrent access for the Adapters by TDLS
10493 * module.
10494 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010495 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010496#endif
c_hpothu002231a2015-02-05 14:58:51 +053010497 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010498 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010499 //Check for sub-string p2p to confirm its a p2p interface
10500 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010501 {
10502 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10503 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10504 }
10505 else
10506 {
10507 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010508 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010509 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010510 hdd_set_conparam(0);
10511 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010512 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
10513 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010514#ifdef FEATURE_WLAN_TDLS
10515 mutex_unlock(&pHddCtx->tdls_lock);
10516#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053010517 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070010518 if( VOS_STATUS_SUCCESS != status )
10519 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070010520 /* In case of JB, for P2P-GO, only change interface will be called,
10521 * This is the right place to enable back bmps_imps()
10522 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010523 if (pHddCtx->hdd_wlan_suspended)
10524 {
10525 hdd_set_pwrparams(pHddCtx);
10526 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010527 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010528 goto done;
10529 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010530 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010531 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010532 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10533 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010534 goto done;
10535 default:
10536 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10537 __func__);
10538 return -EOPNOTSUPP;
10539
10540 }
10541
10542 }
10543 else
10544 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010545 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
10546 __func__, hdd_device_modetoString(pAdapter->device_mode),
10547 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010548 return -EOPNOTSUPP;
10549 }
10550
10551
10552 if(pRoamProfile)
10553 {
10554 if ( LastBSSType != pRoamProfile->BSSType )
10555 {
10556 /*interface type changed update in wiphy structure*/
10557 wdev->iftype = type;
10558
10559 /*the BSS mode changed, We need to issue disconnect
10560 if connected or in IBSS disconnect state*/
10561 if ( hdd_connGetConnectedBssType(
10562 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
10563 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
10564 {
10565 /*need to issue a disconnect to CSR.*/
10566 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10567 if( eHAL_STATUS_SUCCESS ==
10568 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10569 pAdapter->sessionId,
10570 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
10571 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010572 ret = wait_for_completion_interruptible_timeout(
10573 &pAdapter->disconnect_comp_var,
10574 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10575 if (ret <= 0)
10576 {
10577 hddLog(VOS_TRACE_LEVEL_ERROR,
10578 FL("wait on disconnect_comp_var failed %ld"), ret);
10579 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010580 }
10581 }
10582 }
10583 }
10584
10585done:
10586 /*set bitmask based on updated value*/
10587 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070010588
10589 /* Only STA mode support TM now
10590 * all other mode, TM feature should be disabled */
10591 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
10592 (~VOS_STA & pHddCtx->concurrency_mode) )
10593 {
10594 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
10595 }
10596
Jeff Johnson295189b2012-06-20 16:38:30 -070010597#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010598 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053010599 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070010600 {
10601 //we are ok to do AMP
10602 pHddCtx->isAmpAllowed = VOS_TRUE;
10603 }
10604#endif //WLAN_BTAMP_FEATURE
10605 EXIT();
10606 return 0;
10607}
10608
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010609/*
10610 * FUNCTION: wlan_hdd_cfg80211_change_iface
10611 * wrapper function to protect the actual implementation from SSR.
10612 */
10613int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
10614 struct net_device *ndev,
10615 enum nl80211_iftype type,
10616 u32 *flags,
10617 struct vif_params *params
10618 )
10619{
10620 int ret;
10621
10622 vos_ssr_protect(__func__);
10623 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
10624 vos_ssr_unprotect(__func__);
10625
10626 return ret;
10627}
10628
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010629#ifdef FEATURE_WLAN_TDLS
10630static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010631 struct net_device *dev,
10632#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10633 const u8 *mac,
10634#else
10635 u8 *mac,
10636#endif
10637 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010638{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010639 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010640 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010641 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010642 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010643 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010644 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010645
10646 ENTER();
10647
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010648 if (!dev) {
10649 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
10650 return -EINVAL;
10651 }
10652
10653 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
10654 if (!pAdapter) {
10655 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
10656 return -EINVAL;
10657 }
10658
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010659 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010660 {
10661 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10662 "Invalid arguments");
10663 return -EINVAL;
10664 }
Hoonki Lee27511902013-03-14 18:19:06 -070010665
10666 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
10667 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
10668 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010669 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070010670 "%s: TDLS mode is disabled OR not enabled in FW."
10671 MAC_ADDRESS_STR " Request declined.",
10672 __func__, MAC_ADDR_ARRAY(mac));
10673 return -ENOTSUPP;
10674 }
10675
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010676 if (pHddCtx->isLogpInProgress)
10677 {
10678 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10679 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053010680 wlan_hdd_tdls_set_link_status(pAdapter,
10681 mac,
10682 eTDLS_LINK_IDLE,
10683 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010684 return -EBUSY;
10685 }
10686
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053010687 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053010688 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010689
10690 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010691 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010692 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
10693 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053010694 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010695 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010696 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010697
10698 /* in add station, we accept existing valid staId if there is */
10699 if ((0 == update) &&
10700 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
10701 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010702 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010703 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010704 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010705 " link_status %d. staId %d. add station ignored.",
10706 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010707 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010708 return 0;
10709 }
10710 /* in change station, we accept only when staId is valid */
10711 if ((1 == update) &&
10712 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
10713 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
10714 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010715 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010716 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010717 "%s: " MAC_ADDRESS_STR
10718 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010719 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
10720 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
10721 mutex_unlock(&pHddCtx->tdls_lock);
10722 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010723 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010724 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010725
10726 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053010727 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010728 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010729 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10730 "%s: " MAC_ADDRESS_STR
10731 " TDLS setup is ongoing. Request declined.",
10732 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070010733 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010734 }
10735
10736 /* first to check if we reached to maximum supported TDLS peer.
10737 TODO: for now, return -EPERM looks working fine,
10738 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010739 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
10740 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010741 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010742 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10743 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010744 " TDLS Max peer already connected. Request declined."
10745 " Num of peers (%d), Max allowed (%d).",
10746 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
10747 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070010748 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010749 }
10750 else
10751 {
10752 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010753 mutex_lock(&pHddCtx->tdls_lock);
10754 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010755 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010756 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010757 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010758 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10759 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
10760 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010761 return -EPERM;
10762 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010763 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010764 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010765 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053010766 wlan_hdd_tdls_set_link_status(pAdapter,
10767 mac,
10768 eTDLS_LINK_CONNECTING,
10769 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010770
Jeff Johnsond75fe012013-04-06 10:53:06 -070010771 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010772 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010773 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010774 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010775 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070010776 if(StaParams->htcap_present)
10777 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010778 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010779 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010780 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010781 "ht_capa->extended_capabilities: %0x",
10782 StaParams->HTCap.extendedHtCapInfo);
10783 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010784 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010785 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010786 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070010787 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070010788 if(StaParams->vhtcap_present)
10789 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010790 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010791 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
10792 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
10793 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
10794 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010795 {
10796 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010797 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010798 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010799 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010800 "[%d]: %x ", i, StaParams->supported_rates[i]);
10801 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070010802 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010803 else if ((1 == update) && (NULL == StaParams))
10804 {
10805 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10806 "%s : update is true, but staParams is NULL. Error!", __func__);
10807 return -EPERM;
10808 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010809
10810 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
10811
10812 if (!update)
10813 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010814 /*Before adding sta make sure that device exited from BMPS*/
10815 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
10816 {
10817 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10818 "%s: Adding tdls peer sta. Disable BMPS", __func__);
10819 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
10820 if (status != VOS_STATUS_SUCCESS) {
10821 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
10822 }
10823 }
10824
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010825 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010826 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010827 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010828 hddLog(VOS_TRACE_LEVEL_ERROR,
10829 FL("Failed to add TDLS peer STA. Enable Bmps"));
10830 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010831 return -EPERM;
10832 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010833 }
10834 else
10835 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010836 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010837 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010838 if (ret != eHAL_STATUS_SUCCESS) {
10839 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
10840 return -EPERM;
10841 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010842 }
10843
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010844 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010845 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
10846
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010847 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010848 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010849 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010850 "%s: timeout waiting for tdls add station indication %ld",
10851 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010852 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010853 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010854
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010855 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
10856 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010857 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010858 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010859 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010860 }
10861
10862 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070010863
10864error:
Atul Mittal115287b2014-07-08 13:26:33 +053010865 wlan_hdd_tdls_set_link_status(pAdapter,
10866 mac,
10867 eTDLS_LINK_IDLE,
10868 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070010869 return -EPERM;
10870
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010871}
10872#endif
10873
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010874static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010875 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010876#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10877 const u8 *mac,
10878#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010879 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010880#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010881 struct station_parameters *params)
10882{
10883 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010884 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010885 hdd_context_t *pHddCtx;
10886 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010887 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010888 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070010889#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010890 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010891 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053010892 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070010893#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010894
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010895 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010896
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010897 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053010898 if ((NULL == pAdapter))
10899 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010900 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053010901 "invalid adapter ");
10902 return -EINVAL;
10903 }
10904
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010905 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10906 TRACE_CODE_HDD_CHANGE_STATION,
10907 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053010908 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053010909
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010910 ret = wlan_hdd_validate_context(pHddCtx);
10911 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053010912 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010913 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010914 }
10915
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010916 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10917
10918 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010919 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010920 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10921 "invalid HDD station context");
10922 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010923 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010924 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
10925
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010926 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10927 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070010928 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010929 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070010930 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010931 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070010932 WLANTL_STA_AUTHENTICATED);
10933
Gopichand Nakkala29149562013-05-10 21:43:41 +053010934 if (status != VOS_STATUS_SUCCESS)
10935 {
10936 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10937 "%s: Not able to change TL state to AUTHENTICATED", __func__);
10938 return -EINVAL;
10939 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010940 }
10941 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070010942 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
10943 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053010944#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010945 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
10946 StaParams.capability = params->capability;
10947 StaParams.uapsd_queues = params->uapsd_queues;
10948 StaParams.max_sp = params->max_sp;
10949
Naresh Jayaram3180aa42014-02-12 21:47:26 +053010950 /* Convert (first channel , number of channels) tuple to
10951 * the total list of channels. This goes with the assumption
10952 * that if the first channel is < 14, then the next channels
10953 * are an incremental of 1 else an incremental of 4 till the number
10954 * of channels.
10955 */
10956 if (0 != params->supported_channels_len) {
10957 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
10958 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
10959 {
10960 int wifi_chan_index;
10961 StaParams.supported_channels[j] = params->supported_channels[i];
10962 wifi_chan_index =
10963 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
10964 no_of_channels = params->supported_channels[i+1];
10965 for(k=1; k <= no_of_channels; k++)
10966 {
10967 StaParams.supported_channels[j+1] =
10968 StaParams.supported_channels[j] + wifi_chan_index;
10969 j+=1;
10970 }
10971 }
10972 StaParams.supported_channels_len = j;
10973 }
10974 vos_mem_copy(StaParams.supported_oper_classes,
10975 params->supported_oper_classes,
10976 params->supported_oper_classes_len);
10977 StaParams.supported_oper_classes_len =
10978 params->supported_oper_classes_len;
10979
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010980 if (0 != params->ext_capab_len)
10981 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
10982 sizeof(StaParams.extn_capability));
10983
10984 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070010985 {
10986 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010987 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070010988 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010989
10990 StaParams.supported_rates_len = params->supported_rates_len;
10991
10992 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
10993 * The supported_rates array , for all the structures propogating till Add Sta
10994 * to the firmware has to be modified , if the supplicant (ieee80211) is
10995 * modified to send more rates.
10996 */
10997
10998 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
10999 */
11000 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
11001 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
11002
11003 if (0 != StaParams.supported_rates_len) {
11004 int i = 0;
11005 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
11006 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011007 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011008 "Supported Rates with Length %d", StaParams.supported_rates_len);
11009 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011010 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011011 "[%d]: %0x", i, StaParams.supported_rates[i]);
11012 }
11013
11014 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011015 {
11016 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011017 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011018 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011019
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011020 if (0 != params->ext_capab_len ) {
11021 /*Define A Macro : TODO Sunil*/
11022 if ((1<<4) & StaParams.extn_capability[3]) {
11023 isBufSta = 1;
11024 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011025 /* TDLS Channel Switching Support */
11026 if ((1<<6) & StaParams.extn_capability[3]) {
11027 isOffChannelSupported = 1;
11028 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011029 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011030 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
11031 &StaParams, isBufSta,
11032 isOffChannelSupported);
11033
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053011034 if (VOS_STATUS_SUCCESS != status) {
11035 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11036 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
11037 return -EINVAL;
11038 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011039 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
11040
11041 if (VOS_STATUS_SUCCESS != status) {
11042 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11043 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
11044 return -EINVAL;
11045 }
11046 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011047#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053011048 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011049 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011050 return status;
11051}
11052
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011053#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
11054static int wlan_hdd_change_station(struct wiphy *wiphy,
11055 struct net_device *dev,
11056 const u8 *mac,
11057 struct station_parameters *params)
11058#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011059static int wlan_hdd_change_station(struct wiphy *wiphy,
11060 struct net_device *dev,
11061 u8 *mac,
11062 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011063#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011064{
11065 int ret;
11066
11067 vos_ssr_protect(__func__);
11068 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
11069 vos_ssr_unprotect(__func__);
11070
11071 return ret;
11072}
11073
Jeff Johnson295189b2012-06-20 16:38:30 -070011074/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011075 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011076 * This function is used to initialize the key information
11077 */
11078#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011079static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011080 struct net_device *ndev,
11081 u8 key_index, bool pairwise,
11082 const u8 *mac_addr,
11083 struct key_params *params
11084 )
11085#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011086static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011087 struct net_device *ndev,
11088 u8 key_index, const u8 *mac_addr,
11089 struct key_params *params
11090 )
11091#endif
11092{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011093 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011094 tCsrRoamSetKey setKey;
11095 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011096 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011097 v_U32_t roamId= 0xFF;
11098 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011099 hdd_hostapd_state_t *pHostapdState;
11100 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011101 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011102 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011103
11104 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011105
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011106 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11107 TRACE_CODE_HDD_CFG80211_ADD_KEY,
11108 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011109 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11110 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011111 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011112 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011113 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011114 }
11115
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011116 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11117 __func__, hdd_device_modetoString(pAdapter->device_mode),
11118 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011119
11120 if (CSR_MAX_NUM_KEY <= key_index)
11121 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011122 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011123 key_index);
11124
11125 return -EINVAL;
11126 }
11127
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011128 if (CSR_MAX_KEY_LEN < params->key_len)
11129 {
11130 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
11131 params->key_len);
11132
11133 return -EINVAL;
11134 }
11135
11136 hddLog(VOS_TRACE_LEVEL_INFO,
11137 "%s: called with key index = %d & key length %d",
11138 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070011139
11140 /*extract key idx, key len and key*/
11141 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11142 setKey.keyId = key_index;
11143 setKey.keyLength = params->key_len;
11144 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
11145
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011146 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011147 {
11148 case WLAN_CIPHER_SUITE_WEP40:
11149 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
11150 break;
11151
11152 case WLAN_CIPHER_SUITE_WEP104:
11153 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
11154 break;
11155
11156 case WLAN_CIPHER_SUITE_TKIP:
11157 {
11158 u8 *pKey = &setKey.Key[0];
11159 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
11160
11161 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
11162
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011163 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070011164
11165 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011166 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011167 |--------------|----------|----------|
11168 <---16bytes---><--8bytes--><--8bytes-->
11169
11170 */
11171 /*Sme expects the 32 bytes key to be in the below order
11172
11173 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011174 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011175 |--------------|----------|----------|
11176 <---16bytes---><--8bytes--><--8bytes-->
11177 */
11178 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011179 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070011180
11181 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011182 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011183
11184 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011185 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011186
11187
11188 break;
11189 }
11190
11191 case WLAN_CIPHER_SUITE_CCMP:
11192 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
11193 break;
11194
11195#ifdef FEATURE_WLAN_WAPI
11196 case WLAN_CIPHER_SUITE_SMS4:
11197 {
11198 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11199 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
11200 params->key, params->key_len);
11201 return 0;
11202 }
11203#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011204
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011205#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011206 case WLAN_CIPHER_SUITE_KRK:
11207 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
11208 break;
11209#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011210
11211#ifdef WLAN_FEATURE_11W
11212 case WLAN_CIPHER_SUITE_AES_CMAC:
11213 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070011214 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070011215#endif
11216
Jeff Johnson295189b2012-06-20 16:38:30 -070011217 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011218 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011219 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011220 status = -EOPNOTSUPP;
11221 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011222 }
11223
11224 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
11225 __func__, setKey.encType);
11226
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011227 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070011228#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11229 (!pairwise)
11230#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011231 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070011232#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011233 )
11234 {
11235 /* set group key*/
11236 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11237 "%s- %d: setting Broadcast key",
11238 __func__, __LINE__);
11239 setKey.keyDirection = eSIR_RX_ONLY;
11240 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11241 }
11242 else
11243 {
11244 /* set pairwise key*/
11245 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11246 "%s- %d: setting pairwise key",
11247 __func__, __LINE__);
11248 setKey.keyDirection = eSIR_TX_RX;
11249 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11250 }
11251 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
11252 {
11253 setKey.keyDirection = eSIR_TX_RX;
11254 /*Set the group key*/
11255 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11256 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070011257
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011258 if ( 0 != status )
11259 {
11260 hddLog(VOS_TRACE_LEVEL_ERROR,
11261 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011262 status = -EINVAL;
11263 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011264 }
11265 /*Save the keys here and call sme_RoamSetKey for setting
11266 the PTK after peer joins the IBSS network*/
11267 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
11268 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011269 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011270 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053011271 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
11272 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
11273 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011274 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011275 if( pHostapdState->bssState == BSS_START )
11276 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011277 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11278 vos_status = wlan_hdd_check_ula_done(pAdapter);
11279
11280 if ( vos_status != VOS_STATUS_SUCCESS )
11281 {
11282 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11283 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11284 __LINE__, vos_status );
11285
11286 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
11287
11288 status = -EINVAL;
11289 goto end;
11290 }
11291
Jeff Johnson295189b2012-06-20 16:38:30 -070011292 status = WLANSAP_SetKeySta( pVosContext, &setKey);
11293
11294 if ( status != eHAL_STATUS_SUCCESS )
11295 {
11296 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11297 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11298 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011299 status = -EINVAL;
11300 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011301 }
11302 }
11303
11304 /* Saving WEP keys */
11305 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
11306 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
11307 {
11308 //Save the wep key in ap context. Issue setkey after the BSS is started.
11309 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11310 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
11311 }
11312 else
11313 {
11314 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011315 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011316 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
11317 }
11318 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011319 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
11320 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011321 {
11322 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11323 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11324
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011325#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11326 if (!pairwise)
11327#else
11328 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
11329#endif
11330 {
11331 /* set group key*/
11332 if (pHddStaCtx->roam_info.deferKeyComplete)
11333 {
11334 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11335 "%s- %d: Perform Set key Complete",
11336 __func__, __LINE__);
11337 hdd_PerformRoamSetKeyComplete(pAdapter);
11338 }
11339 }
11340
Jeff Johnson295189b2012-06-20 16:38:30 -070011341 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
11342
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080011343 pWextState->roamProfile.Keys.defaultIndex = key_index;
11344
11345
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011346 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011347 params->key, params->key_len);
11348
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011349
Jeff Johnson295189b2012-06-20 16:38:30 -070011350 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11351
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011352 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011353 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011354 __func__, setKey.peerMac[0], setKey.peerMac[1],
11355 setKey.peerMac[2], setKey.peerMac[3],
11356 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011357 setKey.keyDirection);
11358
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011359 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053011360
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011361 if ( vos_status != VOS_STATUS_SUCCESS )
11362 {
11363 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011364 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11365 __LINE__, vos_status );
11366
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011367 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011368
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011369 status = -EINVAL;
11370 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011371
11372 }
11373
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011374#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011375 /* The supplicant may attempt to set the PTK once pre-authentication
11376 is done. Save the key in the UMAC and include it in the ADD BSS
11377 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011378 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011379 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011380 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011381 hddLog(VOS_TRACE_LEVEL_INFO_MED,
11382 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011383 status = 0;
11384 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011385 }
11386 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
11387 {
11388 hddLog(VOS_TRACE_LEVEL_ERROR,
11389 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011390 status = -EINVAL;
11391 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011392 }
11393#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070011394
11395 /* issue set key request to SME*/
11396 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11397 pAdapter->sessionId, &setKey, &roamId );
11398
11399 if ( 0 != status )
11400 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011401 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011402 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
11403 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011404 status = -EINVAL;
11405 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011406 }
11407
11408
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011409 /* in case of IBSS as there was no information available about WEP keys during
11410 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070011411 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011412 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
11413 !( ( IW_AUTH_KEY_MGMT_802_1X
11414 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070011415 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
11416 )
11417 &&
11418 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
11419 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
11420 )
11421 )
11422 {
11423 setKey.keyDirection = eSIR_RX_ONLY;
11424 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11425
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011426 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011427 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011428 __func__, setKey.peerMac[0], setKey.peerMac[1],
11429 setKey.peerMac[2], setKey.peerMac[3],
11430 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011431 setKey.keyDirection);
11432
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011433 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011434 pAdapter->sessionId, &setKey, &roamId );
11435
11436 if ( 0 != status )
11437 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011438 hddLog(VOS_TRACE_LEVEL_ERROR,
11439 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011440 __func__, status);
11441 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011442 status = -EINVAL;
11443 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011444 }
11445 }
11446 }
11447
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011448end:
11449 /* Need to clear any trace of key value in the memory.
11450 * Thus zero out the memory even though it is local
11451 * variable.
11452 */
11453 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011454 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011455 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011456}
11457
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011458#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11459static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11460 struct net_device *ndev,
11461 u8 key_index, bool pairwise,
11462 const u8 *mac_addr,
11463 struct key_params *params
11464 )
11465#else
11466static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11467 struct net_device *ndev,
11468 u8 key_index, const u8 *mac_addr,
11469 struct key_params *params
11470 )
11471#endif
11472{
11473 int ret;
11474 vos_ssr_protect(__func__);
11475#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11476 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
11477 mac_addr, params);
11478#else
11479 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
11480 params);
11481#endif
11482 vos_ssr_unprotect(__func__);
11483
11484 return ret;
11485}
11486
Jeff Johnson295189b2012-06-20 16:38:30 -070011487/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011488 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011489 * This function is used to get the key information
11490 */
11491#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011492static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011493 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011494 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011495 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011496 const u8 *mac_addr, void *cookie,
11497 void (*callback)(void *cookie, struct key_params*)
11498 )
11499#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011500static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011501 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011502 struct net_device *ndev,
11503 u8 key_index, const u8 *mac_addr, void *cookie,
11504 void (*callback)(void *cookie, struct key_params*)
11505 )
11506#endif
11507{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011508 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011509 hdd_wext_state_t *pWextState = NULL;
11510 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011511 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011512 hdd_context_t *pHddCtx;
11513 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011514
11515 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011516
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011517 if (NULL == pAdapter)
11518 {
11519 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11520 "%s: HDD adapter is Null", __func__);
11521 return -ENODEV;
11522 }
11523
11524 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11525 ret = wlan_hdd_validate_context(pHddCtx);
11526 if (0 != ret)
11527 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011528 return ret;
11529 }
11530
11531 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11532 pRoamProfile = &(pWextState->roamProfile);
11533
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011534 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11535 __func__, hdd_device_modetoString(pAdapter->device_mode),
11536 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011537
Jeff Johnson295189b2012-06-20 16:38:30 -070011538 memset(&params, 0, sizeof(params));
11539
11540 if (CSR_MAX_NUM_KEY <= key_index)
11541 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011542 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070011543 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011544 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011545
11546 switch(pRoamProfile->EncryptionType.encryptionType[0])
11547 {
11548 case eCSR_ENCRYPT_TYPE_NONE:
11549 params.cipher = IW_AUTH_CIPHER_NONE;
11550 break;
11551
11552 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
11553 case eCSR_ENCRYPT_TYPE_WEP40:
11554 params.cipher = WLAN_CIPHER_SUITE_WEP40;
11555 break;
11556
11557 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
11558 case eCSR_ENCRYPT_TYPE_WEP104:
11559 params.cipher = WLAN_CIPHER_SUITE_WEP104;
11560 break;
11561
11562 case eCSR_ENCRYPT_TYPE_TKIP:
11563 params.cipher = WLAN_CIPHER_SUITE_TKIP;
11564 break;
11565
11566 case eCSR_ENCRYPT_TYPE_AES:
11567 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
11568 break;
11569
11570 default:
11571 params.cipher = IW_AUTH_CIPHER_NONE;
11572 break;
11573 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011574
c_hpothuaaf19692014-05-17 17:01:48 +053011575 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11576 TRACE_CODE_HDD_CFG80211_GET_KEY,
11577 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011578
Jeff Johnson295189b2012-06-20 16:38:30 -070011579 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
11580 params.seq_len = 0;
11581 params.seq = NULL;
11582 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
11583 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011584 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011585 return 0;
11586}
11587
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011588#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11589static int wlan_hdd_cfg80211_get_key(
11590 struct wiphy *wiphy,
11591 struct net_device *ndev,
11592 u8 key_index, bool pairwise,
11593 const u8 *mac_addr, void *cookie,
11594 void (*callback)(void *cookie, struct key_params*)
11595 )
11596#else
11597static int wlan_hdd_cfg80211_get_key(
11598 struct wiphy *wiphy,
11599 struct net_device *ndev,
11600 u8 key_index, const u8 *mac_addr, void *cookie,
11601 void (*callback)(void *cookie, struct key_params*)
11602 )
11603#endif
11604{
11605 int ret;
11606
11607 vos_ssr_protect(__func__);
11608#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11609 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
11610 mac_addr, cookie, callback);
11611#else
11612 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
11613 callback);
11614#endif
11615 vos_ssr_unprotect(__func__);
11616
11617 return ret;
11618}
11619
Jeff Johnson295189b2012-06-20 16:38:30 -070011620/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011621 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011622 * This function is used to delete the key information
11623 */
11624#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011625static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011626 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011627 u8 key_index,
11628 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011629 const u8 *mac_addr
11630 )
11631#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011632static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011633 struct net_device *ndev,
11634 u8 key_index,
11635 const u8 *mac_addr
11636 )
11637#endif
11638{
11639 int status = 0;
11640
11641 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011642 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070011643 //it is observed that this is invalidating peer
11644 //key index whenever re-key is done. This is affecting data link.
11645 //It should be ok to ignore del_key.
11646#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011647 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
11648 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011649 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
11650 tCsrRoamSetKey setKey;
11651 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011652
Jeff Johnson295189b2012-06-20 16:38:30 -070011653 ENTER();
11654
11655 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
11656 __func__,pAdapter->device_mode);
11657
11658 if (CSR_MAX_NUM_KEY <= key_index)
11659 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011660 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011661 key_index);
11662
11663 return -EINVAL;
11664 }
11665
11666 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11667 setKey.keyId = key_index;
11668
11669 if (mac_addr)
11670 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11671 else
11672 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
11673
11674 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
11675
11676 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011677 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011678 )
11679 {
11680
11681 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070011682 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11683 if( pHostapdState->bssState == BSS_START)
11684 {
11685 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011686
Jeff Johnson295189b2012-06-20 16:38:30 -070011687 if ( status != eHAL_STATUS_SUCCESS )
11688 {
11689 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11690 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11691 __LINE__, status );
11692 }
11693 }
11694 }
11695 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011696 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070011697 )
11698 {
11699 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11700
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011701 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11702
11703 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011704 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011705 __func__, setKey.peerMac[0], setKey.peerMac[1],
11706 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070011707 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011708 if(pAdapter->sessionCtx.station.conn_info.connState ==
11709 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070011710 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011711 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011712 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011713
Jeff Johnson295189b2012-06-20 16:38:30 -070011714 if ( 0 != status )
11715 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011716 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011717 "%s: sme_RoamSetKey failure, returned %d",
11718 __func__, status);
11719 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
11720 return -EINVAL;
11721 }
11722 }
11723 }
11724#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070011725 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011726 return status;
11727}
11728
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011729#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11730static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
11731 struct net_device *ndev,
11732 u8 key_index,
11733 bool pairwise,
11734 const u8 *mac_addr
11735 )
11736#else
11737static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
11738 struct net_device *ndev,
11739 u8 key_index,
11740 const u8 *mac_addr
11741 )
11742#endif
11743{
11744 int ret;
11745
11746 vos_ssr_protect(__func__);
11747#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11748 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
11749 mac_addr);
11750#else
11751 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
11752#endif
11753 vos_ssr_unprotect(__func__);
11754
11755 return ret;
11756}
11757
Jeff Johnson295189b2012-06-20 16:38:30 -070011758/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011759 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011760 * This function is used to set the default tx key index
11761 */
11762#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011763static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011764 struct net_device *ndev,
11765 u8 key_index,
11766 bool unicast, bool multicast)
11767#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011768static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011769 struct net_device *ndev,
11770 u8 key_index)
11771#endif
11772{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011773 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011774 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011775 hdd_wext_state_t *pWextState;
11776 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011777 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011778
11779 ENTER();
11780
Gopichand Nakkala29149562013-05-10 21:43:41 +053011781 if ((NULL == pAdapter))
11782 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011783 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053011784 "invalid adapter");
11785 return -EINVAL;
11786 }
11787
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011788 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11789 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
11790 pAdapter->sessionId, key_index));
11791
Gopichand Nakkala29149562013-05-10 21:43:41 +053011792 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11793 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11794
11795 if ((NULL == pWextState) || (NULL == pHddStaCtx))
11796 {
11797 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11798 "invalid Wext state or HDD context");
11799 return -EINVAL;
11800 }
11801
Arif Hussain6d2a3322013-11-17 19:50:10 -080011802 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011803 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011804
Jeff Johnson295189b2012-06-20 16:38:30 -070011805 if (CSR_MAX_NUM_KEY <= key_index)
11806 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011807 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011808 key_index);
11809
11810 return -EINVAL;
11811 }
11812
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011813 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11814 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011815 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011816 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011817 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011818 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011819
Jeff Johnson295189b2012-06-20 16:38:30 -070011820 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070011821 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011822 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011823 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053011824 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080011825 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011826 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080011827 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070011828 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011829 {
11830 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070011831 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011832
Jeff Johnson295189b2012-06-20 16:38:30 -070011833 tCsrRoamSetKey setKey;
11834 v_U32_t roamId= 0xFF;
11835 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011836
11837 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011838 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011839
Jeff Johnson295189b2012-06-20 16:38:30 -070011840 Keys->defaultIndex = (u8)key_index;
11841 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11842 setKey.keyId = key_index;
11843 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011844
11845 vos_mem_copy(&setKey.Key[0],
11846 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011847 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011848
Gopichand Nakkala29149562013-05-10 21:43:41 +053011849 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011850
11851 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070011852 &pHddStaCtx->conn_info.bssId[0],
11853 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011854
Gopichand Nakkala29149562013-05-10 21:43:41 +053011855 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
11856 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
11857 eCSR_ENCRYPT_TYPE_WEP104)
11858 {
11859 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
11860 even though ap is configured for WEP-40 encryption. In this canse the key length
11861 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
11862 type(104) and switching encryption type to 40*/
11863 pWextState->roamProfile.EncryptionType.encryptionType[0] =
11864 eCSR_ENCRYPT_TYPE_WEP40;
11865 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
11866 eCSR_ENCRYPT_TYPE_WEP40;
11867 }
11868
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011869 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070011870 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011871
Jeff Johnson295189b2012-06-20 16:38:30 -070011872 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011873 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011874 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011875
Jeff Johnson295189b2012-06-20 16:38:30 -070011876 if ( 0 != status )
11877 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011878 hddLog(VOS_TRACE_LEVEL_ERROR,
11879 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011880 status);
11881 return -EINVAL;
11882 }
11883 }
11884 }
11885
11886 /* In SoftAp mode setting key direction for default mode */
11887 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
11888 {
11889 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
11890 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
11891 (eCSR_ENCRYPT_TYPE_AES !=
11892 pWextState->roamProfile.EncryptionType.encryptionType[0])
11893 )
11894 {
11895 /* Saving key direction for default key index to TX default */
11896 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11897 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
11898 }
11899 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011900 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011901 return status;
11902}
11903
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011904#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11905static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
11906 struct net_device *ndev,
11907 u8 key_index,
11908 bool unicast, bool multicast)
11909#else
11910static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
11911 struct net_device *ndev,
11912 u8 key_index)
11913#endif
11914{
11915 int ret;
11916 vos_ssr_protect(__func__);
11917#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11918 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
11919 multicast);
11920#else
11921 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
11922#endif
11923 vos_ssr_unprotect(__func__);
11924
11925 return ret;
11926}
11927
Jeff Johnson295189b2012-06-20 16:38:30 -070011928/*
11929 * FUNCTION: wlan_hdd_cfg80211_inform_bss
11930 * This function is used to inform the BSS details to nl80211 interface.
11931 */
11932static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
11933 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
11934{
11935 struct net_device *dev = pAdapter->dev;
11936 struct wireless_dev *wdev = dev->ieee80211_ptr;
11937 struct wiphy *wiphy = wdev->wiphy;
11938 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
11939 int chan_no;
11940 int ie_length;
11941 const char *ie;
11942 unsigned int freq;
11943 struct ieee80211_channel *chan;
11944 int rssi = 0;
11945 struct cfg80211_bss *bss = NULL;
11946
Jeff Johnson295189b2012-06-20 16:38:30 -070011947 if( NULL == pBssDesc )
11948 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011949 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011950 return bss;
11951 }
11952
11953 chan_no = pBssDesc->channelId;
11954 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
11955 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
11956
11957 if( NULL == ie )
11958 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011959 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011960 return bss;
11961 }
11962
11963#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
11964 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
11965 {
11966 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
11967 }
11968 else
11969 {
11970 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
11971 }
11972#else
11973 freq = ieee80211_channel_to_frequency(chan_no);
11974#endif
11975
11976 chan = __ieee80211_get_channel(wiphy, freq);
11977
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053011978 if (!chan) {
11979 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
11980 return NULL;
11981 }
11982
Abhishek Singhaee43942014-06-16 18:55:47 +053011983 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070011984
Anand N Sunkad9f80b742015-07-30 20:05:51 +053011985 return cfg80211_inform_bss(wiphy, chan,
11986#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11987 CFG80211_BSS_FTYPE_UNKNOWN,
11988#endif
11989 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011990 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070011991 pBssDesc->capabilityInfo,
11992 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053011993 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070011994}
11995
11996
11997
11998/*
11999 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
12000 * This function is used to inform the BSS details to nl80211 interface.
12001 */
12002struct cfg80211_bss*
12003wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
12004 tSirBssDescription *bss_desc
12005 )
12006{
12007 /*
12008 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
12009 already exists in bss data base of cfg80211 for that particular BSS ID.
12010 Using cfg80211_inform_bss_frame to update the bss entry instead of
12011 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
12012 now there is no possibility to get the mgmt(probe response) frame from PE,
12013 converting bss_desc to ieee80211_mgmt(probe response) and passing to
12014 cfg80211_inform_bss_frame.
12015 */
12016 struct net_device *dev = pAdapter->dev;
12017 struct wireless_dev *wdev = dev->ieee80211_ptr;
12018 struct wiphy *wiphy = wdev->wiphy;
12019 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012020#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12021 qcom_ie_age *qie_age = NULL;
12022 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
12023#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012024 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012025#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012026 const char *ie =
12027 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
12028 unsigned int freq;
12029 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012030 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012031 struct cfg80211_bss *bss_status = NULL;
12032 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
12033 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070012034 hdd_context_t *pHddCtx;
12035 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070012036#ifdef WLAN_OPEN_SOURCE
12037 struct timespec ts;
12038#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012039
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012040
Wilson Yangf80a0542013-10-07 13:02:37 -070012041 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12042 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070012043 if (0 != status)
12044 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012045 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012046 }
12047
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012048 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070012049 if (!mgmt)
12050 {
12051 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12052 "%s: memory allocation failed ", __func__);
12053 return NULL;
12054 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012055
Jeff Johnson295189b2012-06-20 16:38:30 -070012056 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012057
12058#ifdef WLAN_OPEN_SOURCE
12059 /* Android does not want the timestamp from the frame.
12060 Instead it wants a monotonic increasing value */
12061 get_monotonic_boottime(&ts);
12062 mgmt->u.probe_resp.timestamp =
12063 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
12064#else
12065 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070012066 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
12067 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070012068
12069#endif
12070
Jeff Johnson295189b2012-06-20 16:38:30 -070012071 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
12072 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012073
12074#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12075 /* GPS Requirement: need age ie per entry. Using vendor specific. */
12076 /* Assuming this is the last IE, copy at the end */
12077 ie_length -=sizeof(qcom_ie_age);
12078 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
12079 qie_age->element_id = QCOM_VENDOR_IE_ID;
12080 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
12081 qie_age->oui_1 = QCOM_OUI1;
12082 qie_age->oui_2 = QCOM_OUI2;
12083 qie_age->oui_3 = QCOM_OUI3;
12084 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
12085 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
12086#endif
12087
Jeff Johnson295189b2012-06-20 16:38:30 -070012088 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053012089 if (bss_desc->fProbeRsp)
12090 {
12091 mgmt->frame_control |=
12092 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
12093 }
12094 else
12095 {
12096 mgmt->frame_control |=
12097 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
12098 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012099
12100#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012101 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012102 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
12103 {
12104 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12105 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012106 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012107 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
12108
12109 {
12110 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12111 }
12112 else
12113 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012114 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
12115 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070012116 kfree(mgmt);
12117 return NULL;
12118 }
12119#else
12120 freq = ieee80211_channel_to_frequency(chan_no);
12121#endif
12122 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012123 /*when the band is changed on the fly using the GUI, three things are done
12124 * 1. scan abort 2.flush scan results from cache 3.update the band with the new band user specified(refer to the hdd_setBand_helper function)
12125 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
12126 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
12127 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
12128 * and discards the channels correponding to previous band and calls back with zero bss results.
12129 * but if the time between band update and scan done callback is very small then band change will not reflect in SME and SME reports to HDD
12130 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
12131 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
12132 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
12133 * So drop the bss and continue to next bss.
12134 */
12135 if(chan == NULL)
12136 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012137 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -070012138 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012139 return NULL;
12140 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053012141 /*To keep the rssi icon of the connected AP in the scan window
12142 *and the rssi icon of the wireless networks in sync
12143 * */
12144 if (( eConnectionState_Associated ==
12145 pAdapter->sessionCtx.station.conn_info.connState ) &&
12146 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
12147 pAdapter->sessionCtx.station.conn_info.bssId,
12148 WNI_CFG_BSSID_LEN)) &&
12149 (pHddCtx->hdd_wlan_suspended == FALSE))
12150 {
12151 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
12152 rssi = (pAdapter->rssi * 100);
12153 }
12154 else
12155 {
12156 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
12157 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012158
Nirav Shah20ac06f2013-12-12 18:14:06 +053012159 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053012160 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
12161 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053012162
Jeff Johnson295189b2012-06-20 16:38:30 -070012163 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
12164 frame_len, rssi, GFP_KERNEL);
12165 kfree(mgmt);
12166 return bss_status;
12167}
12168
12169/*
12170 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
12171 * This function is used to update the BSS data base of CFG8011
12172 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012173struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012174 tCsrRoamInfo *pRoamInfo
12175 )
12176{
12177 tCsrRoamConnectedProfile roamProfile;
12178 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12179 struct cfg80211_bss *bss = NULL;
12180
12181 ENTER();
12182
12183 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
12184 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
12185
12186 if (NULL != roamProfile.pBssDesc)
12187 {
Girish Gowlif4b68022014-08-28 23:18:57 +053012188 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12189 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070012190
12191 if (NULL == bss)
12192 {
12193 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
12194 __func__);
12195 }
12196
12197 sme_RoamFreeConnectProfile(hHal, &roamProfile);
12198 }
12199 else
12200 {
12201 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
12202 __func__);
12203 }
12204 return bss;
12205}
12206
12207/*
12208 * FUNCTION: wlan_hdd_cfg80211_update_bss
12209 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012210static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
12211 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070012212 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012213{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012214 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012215 tCsrScanResultInfo *pScanResult;
12216 eHalStatus status = 0;
12217 tScanResultHandle pResult;
12218 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012219 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012220 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070012221 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012222
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012223 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12224 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
12225 NO_SESSION, pAdapter->sessionId));
12226
Wilson Yangf80a0542013-10-07 13:02:37 -070012227 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12228
12229 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -070012230 {
Wilson Yangf80a0542013-10-07 13:02:37 -070012231 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12232 "%s:LOGP in Progress. Ignore!!!",__func__);
12233 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -070012234 }
12235
Wilson Yangf80a0542013-10-07 13:02:37 -070012236
12237 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +053012238 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -070012239 {
12240 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12241 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
12242 return VOS_STATUS_E_PERM;
12243 }
12244
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012245 if (pAdapter->request != NULL)
12246 {
12247 if ((pAdapter->request->n_ssids == 1)
12248 && (pAdapter->request->ssids != NULL)
12249 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
12250 is_p2p_scan = true;
12251 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012252 /*
12253 * start getting scan results and populate cgf80211 BSS database
12254 */
12255 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
12256
12257 /* no scan results */
12258 if (NULL == pResult)
12259 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012260 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
12261 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053012262 wlan_hdd_get_frame_logs(pAdapter,
12263 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070012264 return status;
12265 }
12266
12267 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
12268
12269 while (pScanResult)
12270 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012271 /*
12272 * cfg80211_inform_bss() is not updating ie field of bss entry, if
12273 * entry already exists in bss data base of cfg80211 for that
12274 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
12275 * bss entry instead of cfg80211_inform_bss, But this call expects
12276 * mgmt packet as input. As of now there is no possibility to get
12277 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070012278 * ieee80211_mgmt(probe response) and passing to c
12279 * fg80211_inform_bss_frame.
12280 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012281 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
12282 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
12283 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012284 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12285 continue; //Skip the non p2p bss entries
12286 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012287 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12288 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012289
Jeff Johnson295189b2012-06-20 16:38:30 -070012290
12291 if (NULL == bss_status)
12292 {
12293 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012294 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012295 }
12296 else
12297 {
Yue Maf49ba872013-08-19 12:04:25 -070012298 cfg80211_put_bss(
12299#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
12300 wiphy,
12301#endif
12302 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070012303 }
12304
12305 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12306 }
12307
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012308 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012309 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012310 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012311}
12312
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012313void
12314hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
12315{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012316 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080012317 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012318} /****** end hddPrintMacAddr() ******/
12319
12320void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012321hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012322{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012323 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012324 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012325 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
12326 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
12327 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012328} /****** end hddPrintPmkId() ******/
12329
12330//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
12331//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
12332
12333//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
12334//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
12335
12336#define dump_bssid(bssid) \
12337 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012338 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
12339 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012340 }
12341
12342#define dump_pmkid(pMac, pmkid) \
12343 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012344 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
12345 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012346 }
12347
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070012348#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012349/*
12350 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
12351 * This function is used to notify the supplicant of a new PMKSA candidate.
12352 */
12353int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012354 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012355 int index, bool preauth )
12356{
Jeff Johnsone7245742012-09-05 17:12:55 -070012357#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012358 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012359 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012360
12361 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070012362 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012363
12364 if( NULL == pRoamInfo )
12365 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012366 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012367 return -EINVAL;
12368 }
12369
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012370 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
12371 {
12372 dump_bssid(pRoamInfo->bssid);
12373 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012374 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012375 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012376#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012377 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012378}
12379#endif //FEATURE_WLAN_LFR
12380
Yue Maef608272013-04-08 23:09:17 -070012381#ifdef FEATURE_WLAN_LFR_METRICS
12382/*
12383 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
12384 * 802.11r/LFR metrics reporting function to report preauth initiation
12385 *
12386 */
12387#define MAX_LFR_METRICS_EVENT_LENGTH 100
12388VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
12389 tCsrRoamInfo *pRoamInfo)
12390{
12391 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12392 union iwreq_data wrqu;
12393
12394 ENTER();
12395
12396 if (NULL == pAdapter)
12397 {
12398 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12399 return VOS_STATUS_E_FAILURE;
12400 }
12401
12402 /* create the event */
12403 memset(&wrqu, 0, sizeof(wrqu));
12404 memset(metrics_notification, 0, sizeof(metrics_notification));
12405
12406 wrqu.data.pointer = metrics_notification;
12407 wrqu.data.length = scnprintf(metrics_notification,
12408 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
12409 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12410
12411 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12412
12413 EXIT();
12414
12415 return VOS_STATUS_SUCCESS;
12416}
12417
12418/*
12419 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
12420 * 802.11r/LFR metrics reporting function to report preauth completion
12421 * or failure
12422 */
12423VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
12424 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
12425{
12426 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12427 union iwreq_data wrqu;
12428
12429 ENTER();
12430
12431 if (NULL == pAdapter)
12432 {
12433 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12434 return VOS_STATUS_E_FAILURE;
12435 }
12436
12437 /* create the event */
12438 memset(&wrqu, 0, sizeof(wrqu));
12439 memset(metrics_notification, 0, sizeof(metrics_notification));
12440
12441 scnprintf(metrics_notification, sizeof(metrics_notification),
12442 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
12443 MAC_ADDR_ARRAY(pRoamInfo->bssid));
12444
12445 if (1 == preauth_status)
12446 strncat(metrics_notification, " TRUE", 5);
12447 else
12448 strncat(metrics_notification, " FALSE", 6);
12449
12450 wrqu.data.pointer = metrics_notification;
12451 wrqu.data.length = strlen(metrics_notification);
12452
12453 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12454
12455 EXIT();
12456
12457 return VOS_STATUS_SUCCESS;
12458}
12459
12460/*
12461 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
12462 * 802.11r/LFR metrics reporting function to report handover initiation
12463 *
12464 */
12465VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
12466 tCsrRoamInfo *pRoamInfo)
12467{
12468 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12469 union iwreq_data wrqu;
12470
12471 ENTER();
12472
12473 if (NULL == pAdapter)
12474 {
12475 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12476 return VOS_STATUS_E_FAILURE;
12477 }
12478
12479 /* create the event */
12480 memset(&wrqu, 0, sizeof(wrqu));
12481 memset(metrics_notification, 0, sizeof(metrics_notification));
12482
12483 wrqu.data.pointer = metrics_notification;
12484 wrqu.data.length = scnprintf(metrics_notification,
12485 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
12486 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12487
12488 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12489
12490 EXIT();
12491
12492 return VOS_STATUS_SUCCESS;
12493}
12494#endif
12495
Jeff Johnson295189b2012-06-20 16:38:30 -070012496/*
12497 * FUNCTION: hdd_cfg80211_scan_done_callback
12498 * scanning callback function, called after finishing scan
12499 *
12500 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012501static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070012502 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
12503{
12504 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012505 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070012506 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012507 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012508 struct cfg80211_scan_request *req = NULL;
12509 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012510 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012511 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012512 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012513 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012514
12515 ENTER();
12516
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012517 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053012518 if (NULL == pHddCtx) {
12519 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012520 goto allow_suspend;
12521 }
12522
12523 pScanInfo = &pHddCtx->scan_info;
12524
Jeff Johnson295189b2012-06-20 16:38:30 -070012525 hddLog(VOS_TRACE_LEVEL_INFO,
12526 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080012527 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012528 __func__, halHandle, pContext, (int) scanId, (int) status);
12529
Kiet Lamac06e2c2013-10-23 16:25:07 +053012530 pScanInfo->mScanPendingCounter = 0;
12531
Jeff Johnson295189b2012-06-20 16:38:30 -070012532 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012533 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070012534 &pScanInfo->scan_req_completion_event,
12535 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012536 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070012537 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012538 hddLog(VOS_TRACE_LEVEL_ERROR,
12539 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070012540 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012541 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012542 }
12543
Yue Maef608272013-04-08 23:09:17 -070012544 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012545 {
12546 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012547 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012548 }
12549
12550 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012551 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070012552 {
12553 hddLog(VOS_TRACE_LEVEL_INFO,
12554 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080012555 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070012556 (int) scanId);
12557 }
12558
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012559 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012560 pAdapter);
12561
12562 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012563 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012564
12565
12566 /* If any client wait scan result through WEXT
12567 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012568 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070012569 {
12570 /* The other scan request waiting for current scan finish
12571 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012572 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012573 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012574 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070012575 }
12576 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012577 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012578 {
12579 struct net_device *dev = pAdapter->dev;
12580 union iwreq_data wrqu;
12581 int we_event;
12582 char *msg;
12583
12584 memset(&wrqu, '\0', sizeof(wrqu));
12585 we_event = SIOCGIWSCAN;
12586 msg = NULL;
12587 wireless_send_event(dev, we_event, &wrqu, msg);
12588 }
12589 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012590 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012591
12592 /* Get the Scan Req */
12593 req = pAdapter->request;
12594
12595 if (!req)
12596 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012597 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070012598 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -070012599 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012600 }
12601
Jeff Johnson295189b2012-06-20 16:38:30 -070012602 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070012603 /* Scan is no longer pending */
12604 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012605
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012606 /* last_scan_timestamp is used to decide if new scan
12607 * is needed or not on station interface. If last station
12608 * scan time and new station scan time is less then
12609 * last_scan_timestamp ; driver will return cached scan.
12610 */
12611 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
12612 {
12613 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
12614
12615 if ( req->n_channels )
12616 {
12617 for (i = 0; i < req->n_channels ; i++ )
12618 {
12619 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
12620 }
12621 /* store no of channel scanned */
12622 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
12623 }
12624
12625 }
12626
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070012627 /*
12628 * cfg80211_scan_done informing NL80211 about completion
12629 * of scanning
12630 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012631 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
12632 {
12633 aborted = true;
12634 }
12635 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080012636 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070012637
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053012638 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
12639 ) && (pHddCtx->spoofMacAddr.isEnabled
12640 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053012641 /* Generate new random mac addr for next scan */
12642 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
12643 hdd_processSpoofMacAddrRequest(pHddCtx);
12644 }
12645
Jeff Johnsone7245742012-09-05 17:12:55 -070012646allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070012647 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012648 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012649
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012650 /* Acquire wakelock to handle the case where APP's tries to suspend
12651 * immediatly after the driver gets connect request(i.e after scan)
12652 * from supplicant, this result in app's is suspending and not able
12653 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012654 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012655
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070012656#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053012657 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070012658#endif
12659
Jeff Johnson295189b2012-06-20 16:38:30 -070012660 EXIT();
12661 return 0;
12662}
12663
12664/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053012665 * FUNCTION: hdd_isConnectionInProgress
12666 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012667 *
12668 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012669v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012670{
12671 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12672 hdd_station_ctx_t *pHddStaCtx = NULL;
12673 hdd_adapter_t *pAdapter = NULL;
12674 VOS_STATUS status = 0;
12675 v_U8_t staId = 0;
12676 v_U8_t *staMac = NULL;
12677
c_hpothu9b781ba2013-12-30 20:57:45 +053012678 if (TRUE == pHddCtx->btCoexModeSet)
12679 {
12680 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053012681 FL("BTCoex Mode operation in progress"));
12682 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053012683 }
12684
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012685 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
12686
12687 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
12688 {
12689 pAdapter = pAdapterNode->pAdapter;
12690
12691 if( pAdapter )
12692 {
12693 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012694 "%s: Adapter with device mode %s (%d) exists",
12695 __func__, hdd_device_modetoString(pAdapter->device_mode),
12696 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012697 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053012698 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
12699 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
12700 (eConnectionState_Connecting ==
12701 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
12702 {
12703 hddLog(VOS_TRACE_LEVEL_ERROR,
12704 "%s: %p(%d) Connection is in progress", __func__,
12705 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
12706 return VOS_TRUE;
12707 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012708 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053012709 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012710 {
12711 hddLog(VOS_TRACE_LEVEL_ERROR,
12712 "%s: %p(%d) Reassociation is in progress", __func__,
12713 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
12714 return VOS_TRUE;
12715 }
12716 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012717 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
12718 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012719 {
12720 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12721 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012722 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012723 {
12724 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
12725 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080012726 "%s: client " MAC_ADDRESS_STR
12727 " is in the middle of WPS/EAPOL exchange.", __func__,
12728 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053012729 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012730 }
12731 }
12732 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
12733 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
12734 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012735 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12736 ptSapContext pSapCtx = NULL;
12737 pSapCtx = VOS_GET_SAP_CB(pVosContext);
12738 if(pSapCtx == NULL){
12739 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12740 FL("psapCtx is NULL"));
12741 return VOS_FALSE;
12742 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012743 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
12744 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012745 if ((pSapCtx->aStaInfo[staId].isUsed) &&
12746 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012747 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012748 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012749
12750 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080012751 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
12752 "middle of WPS/EAPOL exchange.", __func__,
12753 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053012754 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012755 }
12756 }
12757 }
12758 }
12759 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12760 pAdapterNode = pNext;
12761 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053012762 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012763}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012764
12765/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012766 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070012767 * this scan respond to scan trigger and update cfg80211 scan database
12768 * later, scan dump command can be used to recieve scan results
12769 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012770int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080012771#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
12772 struct net_device *dev,
12773#endif
12774 struct cfg80211_scan_request *request)
12775{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012776 hdd_adapter_t *pAdapter = NULL;
12777 hdd_context_t *pHddCtx = NULL;
12778 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012779 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012780 tCsrScanRequest scanRequest;
12781 tANI_U8 *channelList = NULL, i;
12782 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012783 int status;
12784 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012785 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012786 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053012787 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053012788 bool is_p2p_scan = false;
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053012789 v_S7_t rssi=0;
12790 hdd_station_ctx_t *pHddStaCtx=NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012791
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012792#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
12793 struct net_device *dev = NULL;
12794 if (NULL == request)
12795 {
12796 hddLog(VOS_TRACE_LEVEL_ERROR,
12797 "%s: scan req param null", __func__);
12798 return -EINVAL;
12799 }
12800 dev = request->wdev->netdev;
12801#endif
12802
12803 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
12804 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
12805 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12806
Jeff Johnson295189b2012-06-20 16:38:30 -070012807 ENTER();
12808
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012809 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12810 __func__, hdd_device_modetoString(pAdapter->device_mode),
12811 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012812
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012813 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012814 if (0 != status)
12815 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012816 return status;
12817 }
12818
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012819 if (NULL == pwextBuf)
12820 {
12821 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
12822 __func__);
12823 return -EIO;
12824 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012825 cfg_param = pHddCtx->cfg_ini;
12826 pScanInfo = &pHddCtx->scan_info;
12827
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053012828 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12829 if ( (pHddStaCtx != NULL) && (TRUE == hdd_connIsConnected(pHddStaCtx)))
12830 {
12831 wlan_hdd_get_roam_rssi(pAdapter, &rssi);
12832 hddLog(VOS_TRACE_LEVEL_INFO, FL("rssi: %d"), rssi);
12833 }
12834
Jeff Johnson295189b2012-06-20 16:38:30 -070012835#ifdef WLAN_BTAMP_FEATURE
12836 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012837 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070012838 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080012839 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012840 "%s: No scanning when AMP is on", __func__);
12841 return -EOPNOTSUPP;
12842 }
12843#endif
12844 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012845 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012846 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012847 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012848 "%s: Not scanning on device_mode = %s (%d)",
12849 __func__, hdd_device_modetoString(pAdapter->device_mode),
12850 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012851 return -EOPNOTSUPP;
12852 }
12853
12854 if (TRUE == pScanInfo->mScanPending)
12855 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053012856 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
12857 {
12858 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
12859 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012860 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070012861 }
12862
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053012863 // Don't allow scan if PNO scan is going on.
12864 if (pHddCtx->isPnoEnable)
12865 {
12866 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12867 FL("pno scan in progress"));
12868 return -EBUSY;
12869 }
12870
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012871 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070012872 //Channel and action frame is pending
12873 //Otherwise Cancel Remain On Channel and allow Scan
12874 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012875 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070012876 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053012877 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070012878 return -EBUSY;
12879 }
12880
Jeff Johnson295189b2012-06-20 16:38:30 -070012881 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
12882 {
12883 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080012884 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012885 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012886 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012887 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
12888 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012889 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012890 "%s: MAX TM Level Scan not allowed", __func__);
12891 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012892 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070012893 }
12894 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
12895
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012896 /* Check if scan is allowed at this point of time.
12897 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012898 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012899 {
12900 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
12901 return -EBUSY;
12902 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012903
Jeff Johnson295189b2012-06-20 16:38:30 -070012904 vos_mem_zero( &scanRequest, sizeof(scanRequest));
12905
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012906 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
12907 * Becasue of this, driver is assuming that this is not wildcard scan and so
12908 * is not aging out the scan results.
12909 */
12910 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070012911 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012912 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012913 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012914
12915 if ((request->ssids) && (0 < request->n_ssids))
12916 {
12917 tCsrSSIDInfo *SsidInfo;
12918 int j;
12919 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
12920 /* Allocate num_ssid tCsrSSIDInfo structure */
12921 SsidInfo = scanRequest.SSIDs.SSIDList =
12922 ( tCsrSSIDInfo *)vos_mem_malloc(
12923 request->n_ssids*sizeof(tCsrSSIDInfo));
12924
12925 if(NULL == scanRequest.SSIDs.SSIDList)
12926 {
12927 hddLog(VOS_TRACE_LEVEL_ERROR,
12928 "%s: memory alloc failed SSIDInfo buffer", __func__);
12929 return -ENOMEM;
12930 }
12931
12932 /* copy all the ssid's and their length */
12933 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
12934 {
12935 /* get the ssid length */
12936 SsidInfo->SSID.length = request->ssids[j].ssid_len;
12937 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
12938 SsidInfo->SSID.length);
12939 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
12940 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
12941 j, SsidInfo->SSID.ssId);
12942 }
12943 /* set the scan type to active */
12944 scanRequest.scanType = eSIR_ACTIVE_SCAN;
12945 }
12946 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070012947 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012948 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12949 TRACE_CODE_HDD_CFG80211_SCAN,
12950 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070012951 /* set the scan type to active */
12952 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070012953 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012954 else
12955 {
12956 /*Set the scan type to default type, in this case it is ACTIVE*/
12957 scanRequest.scanType = pScanInfo->scan_mode;
12958 }
12959 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
12960 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070012961
12962 /* set BSSType to default type */
12963 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
12964
12965 /*TODO: scan the requested channels only*/
12966
12967 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012968 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070012969 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012970 hddLog(VOS_TRACE_LEVEL_WARN,
12971 "No of Scan Channels exceeded limit: %d", request->n_channels);
12972 request->n_channels = MAX_CHANNEL;
12973 }
12974
12975 hddLog(VOS_TRACE_LEVEL_INFO,
12976 "No of Scan Channels: %d", request->n_channels);
12977
12978
12979 if( request->n_channels )
12980 {
12981 char chList [(request->n_channels*5)+1];
12982 int len;
12983 channelList = vos_mem_malloc( request->n_channels );
12984 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053012985 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012986 hddLog(VOS_TRACE_LEVEL_ERROR,
12987 "%s: memory alloc failed channelList", __func__);
12988 status = -ENOMEM;
12989 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053012990 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012991
12992 for( i = 0, len = 0; i < request->n_channels ; i++ )
12993 {
12994 channelList[i] = request->channels[i]->hw_value;
12995 len += snprintf(chList+len, 5, "%d ", channelList[i]);
12996 }
12997
Nirav Shah20ac06f2013-12-12 18:14:06 +053012998 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012999 "Channel-List: %s ", chList);
13000 }
c_hpothu53512302014-04-15 18:49:53 +053013001
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013002 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
13003 scanRequest.ChannelInfo.ChannelList = channelList;
13004
13005 /* set requestType to full scan */
13006 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
13007
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013008 /* if there is back to back scan happening in driver with in
13009 * nDeferScanTimeInterval interval driver should defer new scan request
13010 * and should provide last cached scan results instead of new channel list.
13011 * This rule is not applicable if scan is p2p scan.
13012 * This condition will work only in case when last request no of channels
13013 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053013014 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053013015 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013016 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013017
Sushant Kaushik86592172015-04-27 16:35:03 +053013018 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
13019 /* if wps ie is NULL , then only defer scan */
13020 if ( pWpsIe == NULL &&
13021 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053013022 {
13023 if ( pScanInfo->last_scan_timestamp !=0 &&
13024 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
13025 {
13026 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
13027 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
13028 vos_mem_compare(pScanInfo->last_scan_channelList,
13029 channelList, pScanInfo->last_scan_numChannels))
13030 {
13031 hddLog(VOS_TRACE_LEVEL_WARN,
13032 " New and old station scan time differ is less then %u",
13033 pHddCtx->cfg_ini->nDeferScanTimeInterval);
13034
13035 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013036 pAdapter);
13037
Agarwal Ashish57e84372014-12-05 18:26:53 +053013038 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013039 "Return old cached scan as all channels and no of channels are same");
13040
Agarwal Ashish57e84372014-12-05 18:26:53 +053013041 if (0 > ret)
13042 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013043
Agarwal Ashish57e84372014-12-05 18:26:53 +053013044 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013045
13046 status = eHAL_STATUS_SUCCESS;
13047 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053013048 }
13049 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013050 }
13051
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013052 /* Flush the scan results(only p2p beacons) for STA scan and P2P
13053 * search (Flush on both full scan and social scan but not on single
13054 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
13055 */
13056
13057 /* Supplicant does single channel scan after 8-way handshake
13058 * and in that case driver shoudnt flush scan results. If
13059 * driver flushes the scan results here and unfortunately if
13060 * the AP doesnt respond to our probe req then association
13061 * fails which is not desired
13062 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013063 if ((request->n_ssids == 1)
13064 && (request->ssids != NULL)
13065 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
13066 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013067
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013068 if( is_p2p_scan ||
13069 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013070 {
13071 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
13072 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
13073 pAdapter->sessionId );
13074 }
13075
13076 if( request->ie_len )
13077 {
13078 /* save this for future association (join requires this) */
13079 /*TODO: Array needs to be converted to dynamic allocation,
13080 * as multiple ie.s can be sent in cfg80211_scan_request structure
13081 * CR 597966
13082 */
13083 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
13084 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
13085 pScanInfo->scanAddIE.length = request->ie_len;
13086
13087 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13088 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13089 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013090 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013091 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070013092 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013093 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
13094 memcpy( pwextBuf->roamProfile.addIEScan,
13095 request->ie, request->ie_len);
13096 }
13097 else
13098 {
13099 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
13100 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013101 }
13102
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013103 }
13104 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
13105 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
13106
13107 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
13108 request->ie_len);
13109 if (pP2pIe != NULL)
13110 {
13111#ifdef WLAN_FEATURE_P2P_DEBUG
13112 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
13113 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
13114 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053013115 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013116 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
13117 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13118 "Go nego completed to Connection is started");
13119 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13120 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053013121 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013122 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
13123 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013124 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013125 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
13126 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13127 "Disconnected state to Connection is started");
13128 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13129 "for 4way Handshake");
13130 }
13131#endif
13132
13133 /* no_cck will be set during p2p find to disable 11b rates */
13134 if(TRUE == request->no_cck)
13135 {
13136 hddLog(VOS_TRACE_LEVEL_INFO,
13137 "%s: This is a P2P Search", __func__);
13138 scanRequest.p2pSearch = 1;
13139
13140 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053013141 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013142 /* set requestType to P2P Discovery */
13143 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
13144 }
13145
13146 /*
13147 Skip Dfs Channel in case of P2P Search
13148 if it is set in ini file
13149 */
13150 if(cfg_param->skipDfsChnlInP2pSearch)
13151 {
13152 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013153 }
13154 else
13155 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013156 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013157 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013158
Agarwal Ashish4f616132013-12-30 23:32:50 +053013159 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013160 }
13161 }
13162
13163 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
13164
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013165#ifdef FEATURE_WLAN_TDLS
13166 /* if tdls disagree scan right now, return immediately.
13167 tdls will schedule the scan when scan is allowed. (return SUCCESS)
13168 or will reject the scan if any TDLS is in progress. (return -EBUSY)
13169 */
13170 status = wlan_hdd_tdls_scan_callback (pAdapter,
13171 wiphy,
13172#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13173 dev,
13174#endif
13175 request);
13176 if(status <= 0)
13177 {
13178 if(!status)
13179 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
13180 "scan rejected %d", __func__, status);
13181 else
13182 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
13183 __func__, status);
13184
13185 return status;
13186 }
13187#endif
13188
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070013189 /* acquire the wakelock to avoid the apps suspend during the scan. To
13190 * address the following issues.
13191 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
13192 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
13193 * for long time, this result in apps running at full power for long time.
13194 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
13195 * be stuck in full power because of resume BMPS
13196 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013197 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013198
Nirav Shah20ac06f2013-12-12 18:14:06 +053013199 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
13200 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013201 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
13202 scanRequest.requestType, scanRequest.scanType,
13203 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053013204 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
13205
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053013206 if (pHddCtx->spoofMacAddr.isEnabled &&
13207 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053013208 {
13209 hddLog(VOS_TRACE_LEVEL_INFO,
13210 "%s: MAC Spoofing enabled for current scan", __func__);
13211 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
13212 * to fill TxBds for probe request during current scan
13213 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013214 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053013215 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013216
13217 if(status != VOS_STATUS_SUCCESS)
13218 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013219 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013220 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053013221#ifdef FEATURE_WLAN_TDLS
13222 wlan_hdd_tdls_scan_done_callback(pAdapter);
13223#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013224 goto free_mem;
13225 }
Siddharth Bhal76972212014-10-15 16:22:51 +053013226 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053013227 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070013228 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013229 pAdapter->sessionId, &scanRequest, &scanId,
13230 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070013231
Jeff Johnson295189b2012-06-20 16:38:30 -070013232 if (eHAL_STATUS_SUCCESS != status)
13233 {
13234 hddLog(VOS_TRACE_LEVEL_ERROR,
13235 "%s: sme_ScanRequest returned error %d", __func__, status);
13236 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013237 if(eHAL_STATUS_RESOURCES == status)
13238 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013239 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
13240 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013241 status = -EBUSY;
13242 } else {
13243 status = -EIO;
13244 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013245 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013246
13247#ifdef FEATURE_WLAN_TDLS
13248 wlan_hdd_tdls_scan_done_callback(pAdapter);
13249#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013250 goto free_mem;
13251 }
13252
13253 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053013254 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070013255 pAdapter->request = request;
13256 pScanInfo->scanId = scanId;
13257
13258 complete(&pScanInfo->scan_req_completion_event);
13259
13260free_mem:
13261 if( scanRequest.SSIDs.SSIDList )
13262 {
13263 vos_mem_free(scanRequest.SSIDs.SSIDList);
13264 }
13265
13266 if( channelList )
13267 vos_mem_free( channelList );
13268
13269 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013270 return status;
13271}
13272
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013273int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
13274#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13275 struct net_device *dev,
13276#endif
13277 struct cfg80211_scan_request *request)
13278{
13279 int ret;
13280
13281 vos_ssr_protect(__func__);
13282 ret = __wlan_hdd_cfg80211_scan(wiphy,
13283#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13284 dev,
13285#endif
13286 request);
13287 vos_ssr_unprotect(__func__);
13288
13289 return ret;
13290}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013291
13292void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
13293{
13294 v_U8_t iniDot11Mode =
13295 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
13296 eHddDot11Mode hddDot11Mode = iniDot11Mode;
13297
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013298 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
13299 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013300 switch ( iniDot11Mode )
13301 {
13302 case eHDD_DOT11_MODE_AUTO:
13303 case eHDD_DOT11_MODE_11ac:
13304 case eHDD_DOT11_MODE_11ac_ONLY:
13305#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053013306 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
13307 sme_IsFeatureSupportedByFW(DOT11AC) )
13308 hddDot11Mode = eHDD_DOT11_MODE_11ac;
13309 else
13310 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013311#else
13312 hddDot11Mode = eHDD_DOT11_MODE_11n;
13313#endif
13314 break;
13315 case eHDD_DOT11_MODE_11n:
13316 case eHDD_DOT11_MODE_11n_ONLY:
13317 hddDot11Mode = eHDD_DOT11_MODE_11n;
13318 break;
13319 default:
13320 hddDot11Mode = iniDot11Mode;
13321 break;
13322 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013323#ifdef WLAN_FEATURE_AP_HT40_24G
13324 if (operationChannel > SIR_11B_CHANNEL_END)
13325#endif
13326 {
13327 /* This call decides required channel bonding mode */
13328 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013329 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
13330 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013331 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013332}
13333
Jeff Johnson295189b2012-06-20 16:38:30 -070013334/*
13335 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013336 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070013337 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013338int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013339 const u8 *ssid, size_t ssid_len, const u8 *bssid,
13340 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070013341{
13342 int status = 0;
13343 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080013344 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013345 v_U32_t roamId;
13346 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070013347 eCsrAuthType RSNAuthType;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013348 const u8 *pValidBssid = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013349
13350 ENTER();
13351
13352 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080013353 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13354
13355 status = wlan_hdd_validate_context(pHddCtx);
13356 if (status)
13357 {
Yue Mae36e3552014-03-05 17:06:20 -080013358 return status;
13359 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013360
Jeff Johnson295189b2012-06-20 16:38:30 -070013361 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
13362 {
13363 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
13364 return -EINVAL;
13365 }
13366
13367 pRoamProfile = &pWextState->roamProfile;
13368
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013369 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070013370 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013371 hdd_station_ctx_t *pHddStaCtx;
13372 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013373
Siddharth Bhalda0d1622015-04-24 15:47:49 +053013374 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
13375
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013376 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070013377 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
13378 {
13379 /*QoS not enabled in cfg file*/
13380 pRoamProfile->uapsd_mask = 0;
13381 }
13382 else
13383 {
13384 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013385 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070013386 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
13387 }
13388
13389 pRoamProfile->SSIDs.numOfSSIDs = 1;
13390 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
13391 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013392 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070013393 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
13394 ssid, ssid_len);
13395
13396 if (bssid)
13397 {
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013398 pValidBssid = bssid;
13399 }
13400 else if (bssid_hint)
13401 {
13402 pValidBssid = bssid_hint;
13403 }
13404 if (pValidBssid)
13405 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013406 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013407 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013408 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013409 /* Save BSSID in seperate variable as well, as RoamProfile
13410 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070013411 case of join failure we should send valid BSSID to supplicant
13412 */
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013413 vos_mem_copy((void *)(pWextState->req_bssId), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013414 WNI_CFG_BSSID_LEN);
13415 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070013416 else
13417 {
13418 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
13419 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013420
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013421 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
13422 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070013423 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
13424 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013425 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013426 /*set gen ie*/
13427 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
13428 /*set auth*/
13429 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
13430 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013431#ifdef FEATURE_WLAN_WAPI
13432 if (pAdapter->wapi_info.nWapiMode)
13433 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013434 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013435 switch (pAdapter->wapi_info.wapiAuthMode)
13436 {
13437 case WAPI_AUTH_MODE_PSK:
13438 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013439 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013440 pAdapter->wapi_info.wapiAuthMode);
13441 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
13442 break;
13443 }
13444 case WAPI_AUTH_MODE_CERT:
13445 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013446 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013447 pAdapter->wapi_info.wapiAuthMode);
13448 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
13449 break;
13450 }
13451 } // End of switch
13452 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
13453 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
13454 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013455 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013456 pRoamProfile->AuthType.numEntries = 1;
13457 pRoamProfile->EncryptionType.numEntries = 1;
13458 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13459 pRoamProfile->mcEncryptionType.numEntries = 1;
13460 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13461 }
13462 }
13463#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013464#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013465 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013466 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13467 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
13468 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013469 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
13470 sizeof (tSirGtkOffloadParams));
13471 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013472 }
13473#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013474 pRoamProfile->csrPersona = pAdapter->device_mode;
13475
Jeff Johnson32d95a32012-09-10 13:15:23 -070013476 if( operatingChannel )
13477 {
13478 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
13479 pRoamProfile->ChannelInfo.numOfChannels = 1;
13480 }
Chet Lanctot186b5732013-03-18 10:26:30 -070013481 else
13482 {
13483 pRoamProfile->ChannelInfo.ChannelList = NULL;
13484 pRoamProfile->ChannelInfo.numOfChannels = 0;
13485 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013486 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
13487 {
13488 hdd_select_cbmode(pAdapter,operatingChannel);
13489 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013490
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013491 /*
13492 * Change conn_state to connecting before sme_RoamConnect(),
13493 * because sme_RoamConnect() has a direct path to call
13494 * hdd_smeRoamCallback(), which will change the conn_state
13495 * If direct path, conn_state will be accordingly changed
13496 * to NotConnected or Associated by either
13497 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
13498 * in sme_RoamCallback()
13499 * if sme_RomConnect is to be queued,
13500 * Connecting state will remain until it is completed.
13501 * If connection state is not changed,
13502 * connection state will remain in eConnectionState_NotConnected state.
13503 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
13504 * if conn state is eConnectionState_NotConnected.
13505 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
13506 * informed of connect result indication which is an issue.
13507 */
13508
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013509 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13510 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053013511 {
13512 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013513 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013514 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
13515 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053013516 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013517 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013518 pAdapter->sessionId, pRoamProfile, &roamId);
13519
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013520 if ((eHAL_STATUS_SUCCESS != status) &&
13521 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13522 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013523
13524 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013525 hddLog(VOS_TRACE_LEVEL_ERROR,
13526 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
13527 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013528 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013529 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013530 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013531 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013532
13533 pRoamProfile->ChannelInfo.ChannelList = NULL;
13534 pRoamProfile->ChannelInfo.numOfChannels = 0;
13535
Jeff Johnson295189b2012-06-20 16:38:30 -070013536 }
13537 else
13538 {
13539 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
13540 return -EINVAL;
13541 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013542 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013543 return status;
13544}
13545
13546/*
13547 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
13548 * This function is used to set the authentication type (OPEN/SHARED).
13549 *
13550 */
13551static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
13552 enum nl80211_auth_type auth_type)
13553{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013554 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013555 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13556
13557 ENTER();
13558
13559 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013560 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070013561 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013562 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013563 hddLog(VOS_TRACE_LEVEL_INFO,
13564 "%s: set authentication type to AUTOSWITCH", __func__);
13565 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
13566 break;
13567
13568 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013569#ifdef WLAN_FEATURE_VOWIFI_11R
13570 case NL80211_AUTHTYPE_FT:
13571#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013572 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013573 "%s: set authentication type to OPEN", __func__);
13574 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
13575 break;
13576
13577 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013578 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013579 "%s: set authentication type to SHARED", __func__);
13580 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
13581 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013582#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013583 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013584 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013585 "%s: set authentication type to CCKM WPA", __func__);
13586 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
13587 break;
13588#endif
13589
13590
13591 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013592 hddLog(VOS_TRACE_LEVEL_ERROR,
13593 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013594 auth_type);
13595 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
13596 return -EINVAL;
13597 }
13598
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013599 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070013600 pHddStaCtx->conn_info.authType;
13601 return 0;
13602}
13603
13604/*
13605 * FUNCTION: wlan_hdd_set_akm_suite
13606 * This function is used to set the key mgmt type(PSK/8021x).
13607 *
13608 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013609static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013610 u32 key_mgmt
13611 )
13612{
13613 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13614 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053013615 /* Should be in ieee802_11_defs.h */
13616#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
13617#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070013618 /*set key mgmt type*/
13619 switch(key_mgmt)
13620 {
13621 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053013622 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013623#ifdef WLAN_FEATURE_VOWIFI_11R
13624 case WLAN_AKM_SUITE_FT_PSK:
13625#endif
13626 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070013627 __func__);
13628 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
13629 break;
13630
13631 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053013632 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013633#ifdef WLAN_FEATURE_VOWIFI_11R
13634 case WLAN_AKM_SUITE_FT_8021X:
13635#endif
13636 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070013637 __func__);
13638 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
13639 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013640#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013641#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
13642#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
13643 case WLAN_AKM_SUITE_CCKM:
13644 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
13645 __func__);
13646 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
13647 break;
13648#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070013649#ifndef WLAN_AKM_SUITE_OSEN
13650#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
13651 case WLAN_AKM_SUITE_OSEN:
13652 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
13653 __func__);
13654 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
13655 break;
13656#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013657
13658 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013659 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013660 __func__, key_mgmt);
13661 return -EINVAL;
13662
13663 }
13664 return 0;
13665}
13666
13667/*
13668 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013669 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070013670 * (NONE/WEP40/WEP104/TKIP/CCMP).
13671 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013672static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
13673 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070013674 bool ucast
13675 )
13676{
13677 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013678 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013679 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13680
13681 ENTER();
13682
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013683 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013684 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053013685 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070013686 __func__, cipher);
13687 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13688 }
13689 else
13690 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013691
Jeff Johnson295189b2012-06-20 16:38:30 -070013692 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013693 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013694 {
13695 case IW_AUTH_CIPHER_NONE:
13696 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13697 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013698
Jeff Johnson295189b2012-06-20 16:38:30 -070013699 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013700 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070013701 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013702
Jeff Johnson295189b2012-06-20 16:38:30 -070013703 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013704 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070013705 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013706
Jeff Johnson295189b2012-06-20 16:38:30 -070013707 case WLAN_CIPHER_SUITE_TKIP:
13708 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
13709 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013710
Jeff Johnson295189b2012-06-20 16:38:30 -070013711 case WLAN_CIPHER_SUITE_CCMP:
13712 encryptionType = eCSR_ENCRYPT_TYPE_AES;
13713 break;
13714#ifdef FEATURE_WLAN_WAPI
13715 case WLAN_CIPHER_SUITE_SMS4:
13716 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
13717 break;
13718#endif
13719
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013720#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013721 case WLAN_CIPHER_SUITE_KRK:
13722 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
13723 break;
13724#endif
13725 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013726 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013727 __func__, cipher);
13728 return -EOPNOTSUPP;
13729 }
13730 }
13731
13732 if (ucast)
13733 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013734 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013735 __func__, encryptionType);
13736 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
13737 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013738 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070013739 encryptionType;
13740 }
13741 else
13742 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013743 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013744 __func__, encryptionType);
13745 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
13746 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
13747 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
13748 }
13749
13750 return 0;
13751}
13752
13753
13754/*
13755 * FUNCTION: wlan_hdd_cfg80211_set_ie
13756 * This function is used to parse WPA/RSN IE's.
13757 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013758int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013759#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13760 const u8 *ie,
13761#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013762 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013763#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013764 size_t ie_len
13765 )
13766{
13767 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013768#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13769 const u8 *genie = ie;
13770#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013771 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013772#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013773 v_U16_t remLen = ie_len;
13774#ifdef FEATURE_WLAN_WAPI
13775 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
13776 u16 *tmp;
13777 v_U16_t akmsuiteCount;
13778 int *akmlist;
13779#endif
13780 ENTER();
13781
13782 /* clear previous assocAddIE */
13783 pWextState->assocAddIE.length = 0;
13784 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070013785 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013786
13787 while (remLen >= 2)
13788 {
13789 v_U16_t eLen = 0;
13790 v_U8_t elementId;
13791 elementId = *genie++;
13792 eLen = *genie++;
13793 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013794
Arif Hussain6d2a3322013-11-17 19:50:10 -080013795 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070013796 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013797
13798 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070013799 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013800 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013801 if (4 > eLen) /* should have at least OUI which is 4 bytes so extra 2 bytes not needed */
Jeff Johnson295189b2012-06-20 16:38:30 -070013802 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013803 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013804 "%s: Invalid WPA IE", __func__);
13805 return -EINVAL;
13806 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013807 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070013808 {
13809 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013810 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070013811 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013812
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013813 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013814 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013815 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
13816 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070013817 VOS_ASSERT(0);
13818 return -ENOMEM;
13819 }
13820 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
13821 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13822 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013823
Jeff Johnson295189b2012-06-20 16:38:30 -070013824 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
13825 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13826 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13827 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013828 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
13829 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013830 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
13831 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
13832 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
13833 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
13834 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
13835 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013836 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053013837 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070013838 {
13839 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013840 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070013841 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013842
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013843 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013844 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013845 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13846 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070013847 VOS_ASSERT(0);
13848 return -ENOMEM;
13849 }
13850 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
13851 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13852 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013853
Jeff Johnson295189b2012-06-20 16:38:30 -070013854 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13855 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13856 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013857#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013858 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
13859 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013860 /*Consider WFD IE, only for P2P Client */
13861 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
13862 {
13863 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013864 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070013865 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013866
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013867 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013868 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013869 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13870 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070013871 VOS_ASSERT(0);
13872 return -ENOMEM;
13873 }
13874 // WFD IE is saved to Additional IE ; it should be accumulated to handle
13875 // WPS IE + P2P IE + WFD IE
13876 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13877 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013878
Jeff Johnson295189b2012-06-20 16:38:30 -070013879 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13880 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13881 }
13882#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013883 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013884 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013885 HS20_OUI_TYPE_SIZE)) )
13886 {
13887 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013888 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013889 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013890
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013891 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013892 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013893 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13894 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013895 VOS_ASSERT(0);
13896 return -ENOMEM;
13897 }
13898 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13899 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013900
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013901 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13902 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13903 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070013904 /* Appending OSEN Information Element in Assiciation Request */
13905 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
13906 OSEN_OUI_TYPE_SIZE)) )
13907 {
13908 v_U16_t curAddIELen = pWextState->assocAddIE.length;
13909 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
13910 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013911
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013912 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070013913 {
13914 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13915 "Need bigger buffer space");
13916 VOS_ASSERT(0);
13917 return -ENOMEM;
13918 }
13919 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13920 pWextState->assocAddIE.length += eLen + 2;
13921
13922 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
13923 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13924 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13925 }
13926
Abhishek Singh4322e622015-06-10 15:42:54 +053013927 /* Update only for WPA IE */
13928 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
13929 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070013930
13931 /* populating as ADDIE in beacon frames */
13932 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013933 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070013934 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
13935 {
13936 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
13937 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
13938 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
13939 {
13940 hddLog(LOGE,
13941 "Coldn't pass "
13942 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
13943 }
13944 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
13945 else
13946 hddLog(LOGE,
13947 "Could not pass on "
13948 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
13949
13950 /* IBSS mode doesn't contain params->proberesp_ies still
13951 beaconIE's need to be populated in probe response frames */
13952 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
13953 {
13954 u16 rem_probe_resp_ie_len = eLen + 2;
13955 u8 probe_rsp_ie_len[3] = {0};
13956 u8 counter = 0;
13957
13958 /* Check Probe Resp Length if it is greater then 255 then
13959 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
13960 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
13961 not able Store More then 255 bytes into One Variable */
13962
13963 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
13964 {
13965 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
13966 {
13967 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
13968 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
13969 }
13970 else
13971 {
13972 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
13973 rem_probe_resp_ie_len = 0;
13974 }
13975 }
13976
13977 rem_probe_resp_ie_len = 0;
13978
13979 if (probe_rsp_ie_len[0] > 0)
13980 {
13981 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
13982 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
13983 (tANI_U8*)(genie - 2),
13984 probe_rsp_ie_len[0], NULL,
13985 eANI_BOOLEAN_FALSE)
13986 == eHAL_STATUS_FAILURE)
13987 {
13988 hddLog(LOGE,
13989 "Could not pass"
13990 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
13991 }
13992 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
13993 }
13994
13995 if (probe_rsp_ie_len[1] > 0)
13996 {
13997 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
13998 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
13999 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14000 probe_rsp_ie_len[1], NULL,
14001 eANI_BOOLEAN_FALSE)
14002 == eHAL_STATUS_FAILURE)
14003 {
14004 hddLog(LOGE,
14005 "Could not pass"
14006 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
14007 }
14008 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
14009 }
14010
14011 if (probe_rsp_ie_len[2] > 0)
14012 {
14013 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14014 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
14015 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14016 probe_rsp_ie_len[2], NULL,
14017 eANI_BOOLEAN_FALSE)
14018 == eHAL_STATUS_FAILURE)
14019 {
14020 hddLog(LOGE,
14021 "Could not pass"
14022 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
14023 }
14024 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
14025 }
14026
14027 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14028 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
14029 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14030 {
14031 hddLog(LOGE,
14032 "Could not pass"
14033 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
14034 }
14035 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014036 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014037 break;
14038 case DOT11F_EID_RSN:
14039 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
14040 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
14041 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
14042 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
14043 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
14044 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053014045
14046 /* Appending Extended Capabilities with Interworking bit set
14047 * in Assoc Req.
14048 *
14049 * In assoc req this EXT Cap will only be taken into account if
14050 * interworkingService bit is set to 1. Currently
14051 * driver is only interested in interworkingService capability
14052 * from supplicant. If in future any other EXT Cap info is
14053 * required from supplicat, it needs to be handled while
14054 * sending Assoc Req in LIM.
14055 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014056 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014057 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014058 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014059 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014060 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014061
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014062 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014063 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014064 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14065 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014066 VOS_ASSERT(0);
14067 return -ENOMEM;
14068 }
14069 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14070 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014071
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014072 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14073 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14074 break;
14075 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014076#ifdef FEATURE_WLAN_WAPI
14077 case WLAN_EID_WAPI:
14078 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070014079 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070014080 pAdapter->wapi_info.nWapiMode);
14081 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014082 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070014083 akmsuiteCount = WPA_GET_LE16(tmp);
14084 tmp = tmp + 1;
14085 akmlist = (int *)(tmp);
14086 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
14087 {
14088 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
14089 }
14090 else
14091 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014092 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070014093 VOS_ASSERT(0);
14094 return -EINVAL;
14095 }
14096
14097 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
14098 {
14099 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014100 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014101 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014102 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014103 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014104 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014105 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014106 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014107 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
14108 }
14109 break;
14110#endif
14111 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014112 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014113 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014114 /* when Unknown IE is received we should break and continue
14115 * to the next IE in the buffer instead we were returning
14116 * so changing this to break */
14117 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070014118 }
14119 genie += eLen;
14120 remLen -= eLen;
14121 }
14122 EXIT();
14123 return 0;
14124}
14125
14126/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014127 * FUNCTION: hdd_isWPAIEPresent
14128 * Parse the received IE to find the WPA IE
14129 *
14130 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014131static bool hdd_isWPAIEPresent(
14132#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
14133 const u8 *ie,
14134#else
14135 u8 *ie,
14136#endif
14137 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014138{
14139 v_U8_t eLen = 0;
14140 v_U16_t remLen = ie_len;
14141 v_U8_t elementId = 0;
14142
14143 while (remLen >= 2)
14144 {
14145 elementId = *ie++;
14146 eLen = *ie++;
14147 remLen -= 2;
14148 if (eLen > remLen)
14149 {
14150 hddLog(VOS_TRACE_LEVEL_ERROR,
14151 "%s: IE length is wrong %d", __func__, eLen);
14152 return FALSE;
14153 }
14154 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
14155 {
14156 /* OUI - 0x00 0X50 0XF2
14157 WPA Information Element - 0x01
14158 WPA version - 0x01*/
14159 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
14160 return TRUE;
14161 }
14162 ie += eLen;
14163 remLen -= eLen;
14164 }
14165 return FALSE;
14166}
14167
14168/*
Jeff Johnson295189b2012-06-20 16:38:30 -070014169 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014170 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070014171 * parameters during connect operation.
14172 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014173int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014174 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014175 )
Jeff Johnson295189b2012-06-20 16:38:30 -070014176{
14177 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014178 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014179 ENTER();
14180
14181 /*set wpa version*/
14182 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
14183
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014184 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014185 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053014186 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014187 {
14188 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
14189 }
14190 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
14191 {
14192 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
14193 }
14194 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014195
14196 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014197 pWextState->wpaVersion);
14198
14199 /*set authentication type*/
14200 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
14201
14202 if (0 > status)
14203 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014204 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014205 "%s: failed to set authentication type ", __func__);
14206 return status;
14207 }
14208
14209 /*set key mgmt type*/
14210 if (req->crypto.n_akm_suites)
14211 {
14212 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
14213 if (0 > status)
14214 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014215 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070014216 __func__);
14217 return status;
14218 }
14219 }
14220
14221 /*set pairwise cipher type*/
14222 if (req->crypto.n_ciphers_pairwise)
14223 {
14224 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
14225 req->crypto.ciphers_pairwise[0], true);
14226 if (0 > status)
14227 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014228 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014229 "%s: failed to set unicast cipher type", __func__);
14230 return status;
14231 }
14232 }
14233 else
14234 {
14235 /*Reset previous cipher suite to none*/
14236 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
14237 if (0 > status)
14238 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014239 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014240 "%s: failed to set unicast cipher type", __func__);
14241 return status;
14242 }
14243 }
14244
14245 /*set group cipher type*/
14246 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
14247 false);
14248
14249 if (0 > status)
14250 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014251 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070014252 __func__);
14253 return status;
14254 }
14255
Chet Lanctot186b5732013-03-18 10:26:30 -070014256#ifdef WLAN_FEATURE_11W
14257 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
14258#endif
14259
Jeff Johnson295189b2012-06-20 16:38:30 -070014260 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
14261 if (req->ie_len)
14262 {
14263 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
14264 if ( 0 > status)
14265 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014266 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070014267 __func__);
14268 return status;
14269 }
14270 }
14271
14272 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014273 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014274 {
14275 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
14276 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
14277 )
14278 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014279 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070014280 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
14281 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014282 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070014283 __func__);
14284 return -EOPNOTSUPP;
14285 }
14286 else
14287 {
14288 u8 key_len = req->key_len;
14289 u8 key_idx = req->key_idx;
14290
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014291 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014292 && (CSR_MAX_NUM_KEY > key_idx)
14293 )
14294 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014295 hddLog(VOS_TRACE_LEVEL_INFO,
14296 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014297 __func__, key_idx, key_len);
14298 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014299 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070014300 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014301 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014302 (u8)key_len;
14303 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
14304 }
14305 }
14306 }
14307 }
14308
14309 return status;
14310}
14311
14312/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014313 * FUNCTION: wlan_hdd_try_disconnect
14314 * This function is used to disconnect from previous
14315 * connection
14316 */
14317static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
14318{
14319 long ret = 0;
14320 hdd_station_ctx_t *pHddStaCtx;
14321 eMib_dot11DesiredBssType connectedBssType;
14322
14323 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14324
14325 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
14326
14327 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
14328 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
14329 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
14330 {
Abhishek Singhf7962582015-10-23 10:54:06 +053014331 hdd_connSetConnectionState(pHddStaCtx,
14332 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014333 /* Issue disconnect to CSR */
14334 INIT_COMPLETION(pAdapter->disconnect_comp_var);
14335 if( eHAL_STATUS_SUCCESS ==
14336 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
14337 pAdapter->sessionId,
14338 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
14339 {
14340 ret = wait_for_completion_interruptible_timeout(
14341 &pAdapter->disconnect_comp_var,
14342 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
14343 if (0 >= ret)
14344 {
14345 hddLog(LOGE, FL("Failed to receive disconnect event"));
14346 return -EALREADY;
14347 }
14348 }
14349 }
14350 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
14351 {
14352 ret = wait_for_completion_interruptible_timeout(
14353 &pAdapter->disconnect_comp_var,
14354 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
14355 if (0 >= ret)
14356 {
14357 hddLog(LOGE, FL("Failed to receive disconnect event"));
14358 return -EALREADY;
14359 }
14360 }
14361
14362 return 0;
14363}
14364
14365/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053014366 * FUNCTION: __wlan_hdd_cfg80211_connect
14367 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070014368 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014369static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014370 struct net_device *ndev,
14371 struct cfg80211_connect_params *req
14372 )
14373{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014374 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014375 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070014376 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053014377 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014378
14379 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014380
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014381 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14382 TRACE_CODE_HDD_CFG80211_CONNECT,
14383 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014384 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014385 "%s: device_mode = %s (%d)", __func__,
14386 hdd_device_modetoString(pAdapter->device_mode),
14387 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014388
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014389 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014390 if (!pHddCtx)
14391 {
14392 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14393 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053014394 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014395 }
14396
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014397 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014398 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014399 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014400 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014401 }
14402
Agarwal Ashish51325b52014-06-16 16:50:49 +053014403 if (vos_max_concurrent_connections_reached()) {
14404 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14405 return -ECONNREFUSED;
14406 }
14407
Jeff Johnson295189b2012-06-20 16:38:30 -070014408#ifdef WLAN_BTAMP_FEATURE
14409 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014410 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070014411 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014412 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014413 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080014414 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070014415 }
14416#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014417
14418 //If Device Mode is Station Concurrent Sessions Exit BMps
14419 //P2P Mode will be taken care in Open/close adapter
14420 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053014421 (vos_concurrent_open_sessions_running())) {
14422 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
14423 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014424 }
14425
14426 /*Try disconnecting if already in connected state*/
14427 status = wlan_hdd_try_disconnect(pAdapter);
14428 if ( 0 > status)
14429 {
14430 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
14431 " connection"));
14432 return -EALREADY;
14433 }
14434
Jeff Johnson295189b2012-06-20 16:38:30 -070014435 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014436 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070014437
14438 if ( 0 > status)
14439 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014440 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070014441 __func__);
14442 return status;
14443 }
Mohit Khanna765234a2012-09-11 15:08:35 -070014444 if ( req->channel )
14445 {
14446 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
14447 req->ssid_len, req->bssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053014448 req->bssid_hint,
Mohit Khanna765234a2012-09-11 15:08:35 -070014449 req->channel->hw_value);
14450 }
14451 else
14452 {
14453 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053014454 req->ssid_len, req->bssid,
14455 req->bssid_hint, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070014456 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014457
Sushant Kaushikd7083982015-03-18 14:33:24 +053014458 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014459 {
14460 //ReEnable BMPS if disabled
14461 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
14462 (NULL != pHddCtx))
14463 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053014464 if (pHddCtx->hdd_wlan_suspended)
14465 {
14466 hdd_set_pwrparams(pHddCtx);
14467 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014468 //ReEnable Bmps and Imps back
14469 hdd_enable_bmps_imps(pHddCtx);
14470 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053014471 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070014472 return status;
14473 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014474 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014475 EXIT();
14476 return status;
14477}
14478
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014479static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
14480 struct net_device *ndev,
14481 struct cfg80211_connect_params *req)
14482{
14483 int ret;
14484 vos_ssr_protect(__func__);
14485 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
14486 vos_ssr_unprotect(__func__);
14487
14488 return ret;
14489}
Jeff Johnson295189b2012-06-20 16:38:30 -070014490
14491/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014492 * FUNCTION: wlan_hdd_disconnect
14493 * This function is used to issue a disconnect request to SME
14494 */
14495int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
14496{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014497 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014498 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014499 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014500 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014501
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014502 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014503
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014504 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014505 if (0 != status)
14506 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014507 return status;
14508 }
Abhishek Singh07e4a892015-11-23 11:29:57 +053014509 /* Indicate sme of disconnect so that in progress connection or preauth
14510 * can be aborted
14511 */
14512 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
Sushant Kaushikb4834d22015-07-15 15:29:05 +053014513 pAdapter->sessionId);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014514 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014515
Agarwal Ashish47d18112014-08-04 19:55:07 +053014516 /* Need to apply spin lock before decreasing active sessions
14517 * as there can be chance for double decrement if context switch
14518 * Calls hdd_DisConnectHandler.
14519 */
14520
14521 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014522 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
14523 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014524 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
14525 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053014526 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
14527 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014528
Abhishek Singhf4669da2014-05-26 15:07:49 +053014529 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053014530 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
14531
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014532 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014533
Mihir Shete182a0b22014-08-18 16:08:48 +053014534 /*
14535 * stop tx queues before deleting STA/BSS context from the firmware.
14536 * tx has to be disabled because the firmware can get busy dropping
14537 * the tx frames after BSS/STA has been deleted and will not send
14538 * back a response resulting in WDI timeout
14539 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053014540 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053014541 netif_tx_disable(pAdapter->dev);
14542 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014543
Mihir Shete182a0b22014-08-18 16:08:48 +053014544 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014545 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
14546 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014547 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
14548 {
14549 hddLog(VOS_TRACE_LEVEL_INFO,
14550 FL("status = %d, already disconnected"),
14551 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014552
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014553 }
14554 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014555 {
14556 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014557 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014558 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014559 result = -EINVAL;
14560 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014561 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014562 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014563 &pAdapter->disconnect_comp_var,
14564 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014565 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014566 {
14567 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014568 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014569 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014570 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014571 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014572 {
14573 hddLog(VOS_TRACE_LEVEL_ERROR,
14574 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014575 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014576 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014577disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014578 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14579 FL("Set HDD connState to eConnectionState_NotConnected"));
14580 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
14581
Abhishek Singh087de602015-10-21 17:18:55 +053014582#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)
14583 /* Sending disconnect event to userspace for kernel version < 3.11
14584 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
14585 */
14586 hddLog(LOG1, FL("Send disconnected event to userspace"));
14587 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
14588 NULL, 0, GFP_KERNEL);
14589#endif
14590
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014591 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014592 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014593}
14594
14595
14596/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014597 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070014598 * This function is used to issue a disconnect request to SME
14599 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014600static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014601 struct net_device *dev,
14602 u16 reason
14603 )
14604{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014605 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014606 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014607 tCsrRoamProfile *pRoamProfile;
14608 hdd_station_ctx_t *pHddStaCtx;
14609 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014610#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014611 tANI_U8 staIdx;
14612#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014613
Jeff Johnson295189b2012-06-20 16:38:30 -070014614 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014615
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014616 if (!pAdapter) {
14617 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
14618 return -EINVAL;
14619 }
14620
14621 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14622 if (!pHddStaCtx) {
14623 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
14624 return -EINVAL;
14625 }
14626
14627 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14628 status = wlan_hdd_validate_context(pHddCtx);
14629 if (0 != status)
14630 {
14631 return status;
14632 }
14633
14634 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
14635
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014636 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14637 TRACE_CODE_HDD_CFG80211_DISCONNECT,
14638 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014639 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
14640 __func__, hdd_device_modetoString(pAdapter->device_mode),
14641 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014642
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014643 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
14644 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070014645
Jeff Johnson295189b2012-06-20 16:38:30 -070014646 if (NULL != pRoamProfile)
14647 {
14648 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053014649 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
14650 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070014651 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014652 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070014653 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014654 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014655 switch(reason)
14656 {
14657 case WLAN_REASON_MIC_FAILURE:
14658 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
14659 break;
14660
14661 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
14662 case WLAN_REASON_DISASSOC_AP_BUSY:
14663 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
14664 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
14665 break;
14666
14667 case WLAN_REASON_PREV_AUTH_NOT_VALID:
14668 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053014669 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070014670 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
14671 break;
14672
Jeff Johnson295189b2012-06-20 16:38:30 -070014673 default:
14674 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
14675 break;
14676 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014677 pScanInfo = &pHddCtx->scan_info;
14678 if (pScanInfo->mScanPending)
14679 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053014680 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014681 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053014682 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053014683 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014684 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053014685 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014686#ifdef FEATURE_WLAN_TDLS
14687 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014688 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014689 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014690 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
14691 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014692 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014693 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014694 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014695 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014696 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014697 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014698 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014699 status = sme_DeleteTdlsPeerSta(
14700 WLAN_HDD_GET_HAL_CTX(pAdapter),
14701 pAdapter->sessionId,
14702 mac);
14703 if (status != eHAL_STATUS_SUCCESS) {
14704 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
14705 return -EPERM;
14706 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014707 }
14708 }
14709#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014710 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014711 status = wlan_hdd_disconnect(pAdapter, reasonCode);
14712 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070014713 {
14714 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014715 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014716 __func__, (int)status );
14717 return -EINVAL;
14718 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014719 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053014720 else
14721 {
14722 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
14723 "called while in %d state", __func__,
14724 pHddStaCtx->conn_info.connState);
14725 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014726 }
14727 else
14728 {
14729 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
14730 }
14731
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014732 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014733 return status;
14734}
14735
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014736static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
14737 struct net_device *dev,
14738 u16 reason
14739 )
14740{
14741 int ret;
14742 vos_ssr_protect(__func__);
14743 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
14744 vos_ssr_unprotect(__func__);
14745
14746 return ret;
14747}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014748
Jeff Johnson295189b2012-06-20 16:38:30 -070014749/*
14750 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014751 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070014752 * settings in IBSS mode.
14753 */
14754static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014755 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014756 struct cfg80211_ibss_params *params
14757 )
14758{
14759 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014760 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014761 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14762 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014763
Jeff Johnson295189b2012-06-20 16:38:30 -070014764 ENTER();
14765
14766 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070014767 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070014768
14769 if (params->ie_len && ( NULL != params->ie) )
14770 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014771 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
14772 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070014773 {
14774 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
14775 encryptionType = eCSR_ENCRYPT_TYPE_AES;
14776 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014777 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070014778 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070014779 tDot11fIEWPA dot11WPAIE;
14780 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014781 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070014782
Wilson Yang00256342013-10-10 23:13:38 -070014783 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014784 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
14785 params->ie_len, DOT11F_EID_WPA);
14786 if ( NULL != ie )
14787 {
14788 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
14789 // Unpack the WPA IE
14790 //Skip past the EID byte and length byte - and four byte WiFi OUI
14791 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
14792 &ie[2+4],
14793 ie[1] - 4,
14794 &dot11WPAIE);
14795 /*Extract the multicast cipher, the encType for unicast
14796 cipher for wpa-none is none*/
14797 encryptionType =
14798 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
14799 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014800 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014801
Jeff Johnson295189b2012-06-20 16:38:30 -070014802 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
14803
14804 if (0 > status)
14805 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014806 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070014807 __func__);
14808 return status;
14809 }
14810 }
14811
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014812 pWextState->roamProfile.AuthType.authType[0] =
14813 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070014814 eCSR_AUTH_TYPE_OPEN_SYSTEM;
14815
14816 if (params->privacy)
14817 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014818 /* Security enabled IBSS, At this time there is no information available
14819 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070014820 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014821 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070014822 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014823 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070014824 *enable privacy bit in beacons */
14825
14826 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
14827 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070014828 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
14829 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070014830 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
14831 pWextState->roamProfile.EncryptionType.numEntries = 1;
14832 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070014833 return status;
14834}
14835
14836/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014837 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014838 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070014839 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014840static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014841 struct net_device *dev,
14842 struct cfg80211_ibss_params *params
14843 )
14844{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014845 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070014846 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14847 tCsrRoamProfile *pRoamProfile;
14848 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014849 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14850 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014851 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070014852
14853 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014854
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014855 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14856 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
14857 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014858 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014859 "%s: device_mode = %s (%d)", __func__,
14860 hdd_device_modetoString(pAdapter->device_mode),
14861 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014862
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014863 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014864 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014865 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014866 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014867 }
14868
14869 if (NULL == pWextState)
14870 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014871 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070014872 __func__);
14873 return -EIO;
14874 }
14875
Agarwal Ashish51325b52014-06-16 16:50:49 +053014876 if (vos_max_concurrent_connections_reached()) {
14877 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14878 return -ECONNREFUSED;
14879 }
14880
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014881 /*Try disconnecting if already in connected state*/
14882 status = wlan_hdd_try_disconnect(pAdapter);
14883 if ( 0 > status)
14884 {
14885 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
14886 " IBSS connection"));
14887 return -EALREADY;
14888 }
14889
Jeff Johnson295189b2012-06-20 16:38:30 -070014890 pRoamProfile = &pWextState->roamProfile;
14891
14892 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
14893 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014894 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014895 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014896 return -EINVAL;
14897 }
14898
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070014899 /* BSSID is provided by upper layers hence no need to AUTO generate */
14900 if (NULL != params->bssid) {
14901 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
14902 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
14903 hddLog (VOS_TRACE_LEVEL_ERROR,
14904 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
14905 return -EIO;
14906 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014907 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070014908 }
krunal sonie9002db2013-11-25 14:24:17 -080014909 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
14910 {
14911 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
14912 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
14913 {
14914 hddLog (VOS_TRACE_LEVEL_ERROR,
14915 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
14916 return -EIO;
14917 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014918
14919 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080014920 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014921 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080014922 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070014923
Jeff Johnson295189b2012-06-20 16:38:30 -070014924 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070014925 if (NULL !=
14926#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
14927 params->chandef.chan)
14928#else
14929 params->channel)
14930#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014931 {
14932 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014933 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
14934 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
14935 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14936 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014937
14938 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014939 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070014940 ieee80211_frequency_to_channel(
14941#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
14942 params->chandef.chan->center_freq);
14943#else
14944 params->channel->center_freq);
14945#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014946
14947 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
14948 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070014949 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014950 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
14951 __func__);
14952 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070014953 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014954
14955 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070014956 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014957 if (channelNum == validChan[indx])
14958 {
14959 break;
14960 }
14961 }
14962 if (indx >= numChans)
14963 {
14964 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014965 __func__, channelNum);
14966 return -EINVAL;
14967 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014968 /* Set the Operational Channel */
14969 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
14970 channelNum);
14971 pRoamProfile->ChannelInfo.numOfChannels = 1;
14972 pHddStaCtx->conn_info.operationChannel = channelNum;
14973 pRoamProfile->ChannelInfo.ChannelList =
14974 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070014975 }
14976
14977 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014978 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070014979 if (status < 0)
14980 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014981 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070014982 __func__);
14983 return status;
14984 }
14985
14986 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014987 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053014988 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014989 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070014990
14991 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014992 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014993
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014994 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014995 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014996}
14997
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014998static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
14999 struct net_device *dev,
15000 struct cfg80211_ibss_params *params
15001 )
15002{
15003 int ret = 0;
15004
15005 vos_ssr_protect(__func__);
15006 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
15007 vos_ssr_unprotect(__func__);
15008
15009 return ret;
15010}
15011
Jeff Johnson295189b2012-06-20 16:38:30 -070015012/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015013 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015014 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070015015 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015016static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015017 struct net_device *dev
15018 )
15019{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015020 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015021 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15022 tCsrRoamProfile *pRoamProfile;
15023 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015024 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015025
15026 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015027
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015028 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15029 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
15030 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015031 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015032 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015033 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015034 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015035 }
15036
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015037 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
15038 hdd_device_modetoString(pAdapter->device_mode),
15039 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015040 if (NULL == pWextState)
15041 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015042 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070015043 __func__);
15044 return -EIO;
15045 }
15046
15047 pRoamProfile = &pWextState->roamProfile;
15048
15049 /* Issue disconnect only if interface type is set to IBSS */
15050 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
15051 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015052 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070015053 __func__);
15054 return -EINVAL;
15055 }
15056
15057 /* Issue Disconnect request */
15058 INIT_COMPLETION(pAdapter->disconnect_comp_var);
15059 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
15060 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
15061
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015062 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015063 return 0;
15064}
15065
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015066static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
15067 struct net_device *dev
15068 )
15069{
15070 int ret = 0;
15071
15072 vos_ssr_protect(__func__);
15073 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
15074 vos_ssr_unprotect(__func__);
15075
15076 return ret;
15077}
15078
Jeff Johnson295189b2012-06-20 16:38:30 -070015079/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015080 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070015081 * This function is used to set the phy parameters
15082 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
15083 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015084static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015085 u32 changed)
15086{
15087 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15088 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015089 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015090
15091 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015092
15093 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015094 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
15095 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015096
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015097 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015098 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015099 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015100 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015101 }
15102
Jeff Johnson295189b2012-06-20 16:38:30 -070015103 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
15104 {
15105 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
15106 WNI_CFG_RTS_THRESHOLD_STAMAX :
15107 wiphy->rts_threshold;
15108
15109 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015110 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070015111 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015112 hddLog(VOS_TRACE_LEVEL_ERROR,
15113 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015114 __func__, rts_threshold);
15115 return -EINVAL;
15116 }
15117
15118 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
15119 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015120 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015121 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015122 hddLog(VOS_TRACE_LEVEL_ERROR,
15123 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015124 __func__, rts_threshold);
15125 return -EIO;
15126 }
15127
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015128 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015129 rts_threshold);
15130 }
15131
15132 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
15133 {
15134 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
15135 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
15136 wiphy->frag_threshold;
15137
15138 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015139 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015140 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015141 hddLog(VOS_TRACE_LEVEL_ERROR,
15142 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015143 frag_threshold);
15144 return -EINVAL;
15145 }
15146
15147 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
15148 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015149 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015150 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015151 hddLog(VOS_TRACE_LEVEL_ERROR,
15152 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015153 __func__, frag_threshold);
15154 return -EIO;
15155 }
15156
15157 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
15158 frag_threshold);
15159 }
15160
15161 if ((changed & WIPHY_PARAM_RETRY_SHORT)
15162 || (changed & WIPHY_PARAM_RETRY_LONG))
15163 {
15164 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
15165 wiphy->retry_short :
15166 wiphy->retry_long;
15167
15168 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
15169 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
15170 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015171 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015172 __func__, retry_value);
15173 return -EINVAL;
15174 }
15175
15176 if (changed & WIPHY_PARAM_RETRY_SHORT)
15177 {
15178 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
15179 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015180 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015181 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015182 hddLog(VOS_TRACE_LEVEL_ERROR,
15183 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015184 __func__, retry_value);
15185 return -EIO;
15186 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015187 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015188 __func__, retry_value);
15189 }
15190 else if (changed & WIPHY_PARAM_RETRY_SHORT)
15191 {
15192 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
15193 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015194 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015195 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015196 hddLog(VOS_TRACE_LEVEL_ERROR,
15197 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015198 __func__, retry_value);
15199 return -EIO;
15200 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015201 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015202 __func__, retry_value);
15203 }
15204 }
15205
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015206 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015207 return 0;
15208}
15209
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015210static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
15211 u32 changed)
15212{
15213 int ret;
15214
15215 vos_ssr_protect(__func__);
15216 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
15217 vos_ssr_unprotect(__func__);
15218
15219 return ret;
15220}
15221
Jeff Johnson295189b2012-06-20 16:38:30 -070015222/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015223 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015224 * This function is used to set the txpower
15225 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015226static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015227#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15228 struct wireless_dev *wdev,
15229#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015230#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015231 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015232#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015233 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015234#endif
15235 int dbm)
15236{
15237 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015238 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015239 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
15240 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015241 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015242
15243 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015244
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015245 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15246 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
15247 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015248 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015249 if (0 != status)
15250 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015251 return status;
15252 }
15253
15254 hHal = pHddCtx->hHal;
15255
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015256 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
15257 dbm, ccmCfgSetCallback,
15258 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015259 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015260 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015261 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
15262 return -EIO;
15263 }
15264
15265 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
15266 dbm);
15267
15268 switch(type)
15269 {
15270 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
15271 /* Fall through */
15272 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
15273 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
15274 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015275 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
15276 __func__);
15277 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070015278 }
15279 break;
15280 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015281 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070015282 __func__);
15283 return -EOPNOTSUPP;
15284 break;
15285 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015286 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
15287 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070015288 return -EIO;
15289 }
15290
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015291 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015292 return 0;
15293}
15294
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015295static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
15296#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15297 struct wireless_dev *wdev,
15298#endif
15299#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15300 enum tx_power_setting type,
15301#else
15302 enum nl80211_tx_power_setting type,
15303#endif
15304 int dbm)
15305{
15306 int ret;
15307 vos_ssr_protect(__func__);
15308 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
15309#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15310 wdev,
15311#endif
15312#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15313 type,
15314#else
15315 type,
15316#endif
15317 dbm);
15318 vos_ssr_unprotect(__func__);
15319
15320 return ret;
15321}
15322
Jeff Johnson295189b2012-06-20 16:38:30 -070015323/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015324 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015325 * This function is used to read the txpower
15326 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015327static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015328#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15329 struct wireless_dev *wdev,
15330#endif
15331 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070015332{
15333
15334 hdd_adapter_t *pAdapter;
15335 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015336 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015337
Jeff Johnsone7245742012-09-05 17:12:55 -070015338 ENTER();
15339
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015340 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015341 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015342 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015343 *dbm = 0;
15344 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015345 }
15346
Jeff Johnson295189b2012-06-20 16:38:30 -070015347 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
15348 if (NULL == pAdapter)
15349 {
15350 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
15351 return -ENOENT;
15352 }
15353
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015354 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15355 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
15356 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070015357 wlan_hdd_get_classAstats(pAdapter);
15358 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
15359
Jeff Johnsone7245742012-09-05 17:12:55 -070015360 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015361 return 0;
15362}
15363
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015364static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
15365#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15366 struct wireless_dev *wdev,
15367#endif
15368 int *dbm)
15369{
15370 int ret;
15371
15372 vos_ssr_protect(__func__);
15373 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
15374#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15375 wdev,
15376#endif
15377 dbm);
15378 vos_ssr_unprotect(__func__);
15379
15380 return ret;
15381}
15382
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015383static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015384#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15385 const u8* mac,
15386#else
15387 u8* mac,
15388#endif
15389 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070015390{
15391 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15392 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15393 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053015394 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070015395
15396 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
15397 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070015398
15399 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
15400 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
15401 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
15402 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
15403 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
15404 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
15405 tANI_U16 maxRate = 0;
15406 tANI_U16 myRate;
15407 tANI_U16 currentRate = 0;
15408 tANI_U8 maxSpeedMCS = 0;
15409 tANI_U8 maxMCSIdx = 0;
15410 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053015411 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070015412 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015413 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015414
Leo Chang6f8870f2013-03-26 18:11:36 -070015415#ifdef WLAN_FEATURE_11AC
15416 tANI_U32 vht_mcs_map;
15417 eDataRate11ACMaxMcs vhtMaxMcs;
15418#endif /* WLAN_FEATURE_11AC */
15419
Jeff Johnsone7245742012-09-05 17:12:55 -070015420 ENTER();
15421
Jeff Johnson295189b2012-06-20 16:38:30 -070015422 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
15423 (0 == ssidlen))
15424 {
15425 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
15426 " Invalid ssidlen, %d", __func__, ssidlen);
15427 /*To keep GUI happy*/
15428 return 0;
15429 }
15430
Mukul Sharma811205f2014-07-09 21:07:30 +053015431 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
15432 {
15433 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15434 "%s: Roaming in progress, so unable to proceed this request", __func__);
15435 return 0;
15436 }
15437
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015438 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015439 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015440 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015441 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015442 }
15443
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053015444 wlan_hdd_get_station_stats(pAdapter);
15445 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070015446
Kiet Lam3b17fc82013-09-27 05:24:08 +053015447 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
15448 sinfo->filled |= STATION_INFO_SIGNAL;
15449
c_hpothu09f19542014-05-30 21:53:31 +053015450 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053015451 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
15452 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053015453 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053015454 {
15455 rate_flags = pAdapter->maxRateFlags;
15456 }
c_hpothu44ff4e02014-05-08 00:13:57 +053015457
Jeff Johnson295189b2012-06-20 16:38:30 -070015458 //convert to the UI units of 100kbps
15459 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
15460
15461#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070015462 pr_info("RSSI %d, RLMS %u, rate %d, rssi high %d, rssi mid %d, rssi low %d, rate_flags 0x%x, MCS %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -070015463 sinfo->signal,
15464 pCfg->reportMaxLinkSpeed,
15465 myRate,
15466 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015467 (int) pCfg->linkSpeedRssiMid,
15468 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070015469 (int) rate_flags,
15470 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070015471#endif //LINKSPEED_DEBUG_ENABLED
15472
15473 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
15474 {
15475 // we do not want to necessarily report the current speed
15476 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
15477 {
15478 // report the max possible speed
15479 rssidx = 0;
15480 }
15481 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
15482 {
15483 // report the max possible speed with RSSI scaling
15484 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
15485 {
15486 // report the max possible speed
15487 rssidx = 0;
15488 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015489 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070015490 {
15491 // report middle speed
15492 rssidx = 1;
15493 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015494 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
15495 {
15496 // report middle speed
15497 rssidx = 2;
15498 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015499 else
15500 {
15501 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015502 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070015503 }
15504 }
15505 else
15506 {
15507 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
15508 hddLog(VOS_TRACE_LEVEL_ERROR,
15509 "%s: Invalid value for reportMaxLinkSpeed: %u",
15510 __func__, pCfg->reportMaxLinkSpeed);
15511 rssidx = 0;
15512 }
15513
15514 maxRate = 0;
15515
15516 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015517 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
15518 OperationalRates, &ORLeng))
15519 {
15520 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15521 /*To keep GUI happy*/
15522 return 0;
15523 }
15524
Jeff Johnson295189b2012-06-20 16:38:30 -070015525 for (i = 0; i < ORLeng; i++)
15526 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015527 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015528 {
15529 /* Validate Rate Set */
15530 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
15531 {
15532 currentRate = supported_data_rate[j].supported_rate[rssidx];
15533 break;
15534 }
15535 }
15536 /* Update MAX rate */
15537 maxRate = (currentRate > maxRate)?currentRate:maxRate;
15538 }
15539
15540 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015541 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
15542 ExtendedRates, &ERLeng))
15543 {
15544 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15545 /*To keep GUI happy*/
15546 return 0;
15547 }
15548
Jeff Johnson295189b2012-06-20 16:38:30 -070015549 for (i = 0; i < ERLeng; i++)
15550 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015551 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015552 {
15553 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
15554 {
15555 currentRate = supported_data_rate[j].supported_rate[rssidx];
15556 break;
15557 }
15558 }
15559 /* Update MAX rate */
15560 maxRate = (currentRate > maxRate)?currentRate:maxRate;
15561 }
c_hpothu79aab322014-07-14 21:11:01 +053015562
Kiet Lamb69f8dc2013-11-15 15:34:27 +053015563 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053015564 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053015565 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053015566 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070015567 {
c_hpothu79aab322014-07-14 21:11:01 +053015568 if (rate_flags & eHAL_TX_RATE_VHT80)
15569 mode = 2;
15570 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
15571 mode = 1;
15572 else
15573 mode = 0;
15574
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015575 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
15576 MCSRates, &MCSLeng))
15577 {
15578 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15579 /*To keep GUI happy*/
15580 return 0;
15581 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015582 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070015583#ifdef WLAN_FEATURE_11AC
15584 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015585 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070015586 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015587 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015588 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070015589 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070015590 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015591 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070015592 }
Leo Chang6f8870f2013-03-26 18:11:36 -070015593 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070015594 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015595 maxMCSIdx = 7;
15596 }
15597 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
15598 {
15599 maxMCSIdx = 8;
15600 }
15601 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
15602 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015603 //VHT20 is supporting 0~8
15604 if (rate_flags & eHAL_TX_RATE_VHT20)
15605 maxMCSIdx = 8;
15606 else
15607 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070015608 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015609
c_hpothu79aab322014-07-14 21:11:01 +053015610 if (0 != rssidx)/*check for scaled */
15611 {
15612 //get middle rate MCS index if rssi=1/2
15613 for (i=0; i <= maxMCSIdx; i++)
15614 {
15615 if (sinfo->signal <= rssiMcsTbl[mode][i])
15616 {
15617 maxMCSIdx = i;
15618 break;
15619 }
15620 }
15621 }
15622
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015623 if (rate_flags & eHAL_TX_RATE_VHT80)
15624 {
15625 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
15626 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
15627 }
15628 else if (rate_flags & eHAL_TX_RATE_VHT40)
15629 {
15630 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
15631 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
15632 }
15633 else if (rate_flags & eHAL_TX_RATE_VHT20)
15634 {
15635 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
15636 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
15637 }
15638
Leo Chang6f8870f2013-03-26 18:11:36 -070015639 maxSpeedMCS = 1;
15640 if (currentRate > maxRate)
15641 {
15642 maxRate = currentRate;
15643 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015644
Leo Chang6f8870f2013-03-26 18:11:36 -070015645 }
15646 else
15647#endif /* WLAN_FEATURE_11AC */
15648 {
15649 if (rate_flags & eHAL_TX_RATE_HT40)
15650 {
15651 rateFlag |= 1;
15652 }
15653 if (rate_flags & eHAL_TX_RATE_SGI)
15654 {
15655 rateFlag |= 2;
15656 }
15657
Girish Gowli01abcee2014-07-31 20:18:55 +053015658 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053015659 if (rssidx == 1 || rssidx == 2)
15660 {
15661 //get middle rate MCS index if rssi=1/2
15662 for (i=0; i <= 7; i++)
15663 {
15664 if (sinfo->signal <= rssiMcsTbl[mode][i])
15665 {
15666 temp = i+1;
15667 break;
15668 }
15669 }
15670 }
c_hpothu79aab322014-07-14 21:11:01 +053015671
15672 for (i = 0; i < MCSLeng; i++)
15673 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015674 for (j = 0; j < temp; j++)
15675 {
15676 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
15677 {
15678 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053015679 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070015680 break;
15681 }
15682 }
15683 if ((j < temp) && (currentRate > maxRate))
15684 {
15685 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070015686 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015687 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053015688 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070015689 }
15690 }
15691
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015692 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
15693 {
15694 maxRate = myRate;
15695 maxSpeedMCS = 1;
15696 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
15697 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015698 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053015699 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070015700 {
15701 maxRate = myRate;
15702 if (rate_flags & eHAL_TX_RATE_LEGACY)
15703 {
15704 maxSpeedMCS = 0;
15705 }
15706 else
15707 {
15708 maxSpeedMCS = 1;
15709 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
15710 }
15711 }
15712
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015713 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070015714 {
15715 sinfo->txrate.legacy = maxRate;
15716#ifdef LINKSPEED_DEBUG_ENABLED
15717 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
15718#endif //LINKSPEED_DEBUG_ENABLED
15719 }
15720 else
15721 {
15722 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070015723#ifdef WLAN_FEATURE_11AC
15724 sinfo->txrate.nss = 1;
15725 if (rate_flags & eHAL_TX_RATE_VHT80)
15726 {
15727 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015728 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070015729 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015730 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070015731 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015732 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
15733 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
15734 }
15735 else if (rate_flags & eHAL_TX_RATE_VHT20)
15736 {
15737 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
15738 }
15739#endif /* WLAN_FEATURE_11AC */
15740 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
15741 {
15742 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
15743 if (rate_flags & eHAL_TX_RATE_HT40)
15744 {
15745 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
15746 }
Leo Chang6f8870f2013-03-26 18:11:36 -070015747 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015748 if (rate_flags & eHAL_TX_RATE_SGI)
15749 {
15750 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
15751 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015752
Jeff Johnson295189b2012-06-20 16:38:30 -070015753#ifdef LINKSPEED_DEBUG_ENABLED
15754 pr_info("Reporting MCS rate %d flags %x\n",
15755 sinfo->txrate.mcs,
15756 sinfo->txrate.flags );
15757#endif //LINKSPEED_DEBUG_ENABLED
15758 }
15759 }
15760 else
15761 {
15762 // report current rate instead of max rate
15763
15764 if (rate_flags & eHAL_TX_RATE_LEGACY)
15765 {
15766 //provide to the UI in units of 100kbps
15767 sinfo->txrate.legacy = myRate;
15768#ifdef LINKSPEED_DEBUG_ENABLED
15769 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
15770#endif //LINKSPEED_DEBUG_ENABLED
15771 }
15772 else
15773 {
15774 //must be MCS
15775 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070015776#ifdef WLAN_FEATURE_11AC
15777 sinfo->txrate.nss = 1;
15778 if (rate_flags & eHAL_TX_RATE_VHT80)
15779 {
15780 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
15781 }
15782 else
15783#endif /* WLAN_FEATURE_11AC */
15784 {
15785 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
15786 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015787 if (rate_flags & eHAL_TX_RATE_SGI)
15788 {
15789 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
15790 }
15791 if (rate_flags & eHAL_TX_RATE_HT40)
15792 {
15793 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
15794 }
Leo Chang6f8870f2013-03-26 18:11:36 -070015795#ifdef WLAN_FEATURE_11AC
15796 else if (rate_flags & eHAL_TX_RATE_VHT80)
15797 {
15798 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
15799 }
15800#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070015801#ifdef LINKSPEED_DEBUG_ENABLED
15802 pr_info("Reporting actual MCS rate %d flags %x\n",
15803 sinfo->txrate.mcs,
15804 sinfo->txrate.flags );
15805#endif //LINKSPEED_DEBUG_ENABLED
15806 }
15807 }
15808 sinfo->filled |= STATION_INFO_TX_BITRATE;
15809
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070015810 sinfo->tx_packets =
15811 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
15812 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
15813 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
15814 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
15815
15816 sinfo->tx_retries =
15817 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
15818 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
15819 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
15820 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
15821
15822 sinfo->tx_failed =
15823 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
15824 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
15825 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
15826 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
15827
15828 sinfo->filled |=
15829 STATION_INFO_TX_PACKETS |
15830 STATION_INFO_TX_RETRIES |
15831 STATION_INFO_TX_FAILED;
15832
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015833 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15834 TRACE_CODE_HDD_CFG80211_GET_STA,
15835 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070015836 EXIT();
15837 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070015838}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015839#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
15840static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
15841 const u8* mac, struct station_info *sinfo)
15842#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015843static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
15844 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015845#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015846{
15847 int ret;
15848
15849 vos_ssr_protect(__func__);
15850 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
15851 vos_ssr_unprotect(__func__);
15852
15853 return ret;
15854}
15855
15856static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070015857 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070015858{
15859 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015860 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015861 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015862 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015863
Jeff Johnsone7245742012-09-05 17:12:55 -070015864 ENTER();
15865
Jeff Johnson295189b2012-06-20 16:38:30 -070015866 if (NULL == pAdapter)
15867 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015868 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015869 return -ENODEV;
15870 }
15871
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015872 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15873 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
15874 pAdapter->sessionId, timeout));
15875
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015876 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015877 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015878 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015879 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015880 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015881 }
15882
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015883 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
15884 (TRUE == pHddCtx->hdd_wlan_suspended) &&
15885 (pHddCtx->cfg_ini->fhostArpOffload) &&
15886 (eConnectionState_Associated ==
15887 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
15888 {
Amar Singhald53568e2013-09-26 11:03:45 -070015889
15890 hddLog(VOS_TRACE_LEVEL_INFO,
15891 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053015892 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015893 if (!VOS_IS_STATUS_SUCCESS(vos_status))
15894 {
15895 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015896 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015897 __func__, vos_status);
15898 }
15899 }
15900
Jeff Johnson295189b2012-06-20 16:38:30 -070015901 /**The get power cmd from the supplicant gets updated by the nl only
15902 *on successful execution of the function call
15903 *we are oppositely mapped w.r.t mode in the driver
15904 **/
15905 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
15906
15907 if (VOS_STATUS_E_FAILURE == vos_status)
15908 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015909 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15910 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015911 return -EINVAL;
15912 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015913 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015914 return 0;
15915}
15916
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015917static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
15918 struct net_device *dev, bool mode, int timeout)
15919{
15920 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070015921
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015922 vos_ssr_protect(__func__);
15923 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
15924 vos_ssr_unprotect(__func__);
15925
15926 return ret;
15927}
Sushant Kaushik084f6592015-09-10 13:11:56 +053015928
Jeff Johnson295189b2012-06-20 16:38:30 -070015929#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015930static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
15931 struct net_device *netdev,
15932 u8 key_index)
15933{
15934 ENTER();
15935 return 0;
15936}
15937
Jeff Johnson295189b2012-06-20 16:38:30 -070015938static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015939 struct net_device *netdev,
15940 u8 key_index)
15941{
15942 int ret;
15943 vos_ssr_protect(__func__);
15944 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
15945 vos_ssr_unprotect(__func__);
15946 return ret;
15947}
15948#endif //LINUX_VERSION_CODE
15949
15950#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
15951static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
15952 struct net_device *dev,
15953 struct ieee80211_txq_params *params)
15954{
15955 ENTER();
15956 return 0;
15957}
15958#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
15959static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
15960 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070015961{
Jeff Johnsone7245742012-09-05 17:12:55 -070015962 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070015963 return 0;
15964}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015965#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070015966
15967#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
15968static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015969 struct net_device *dev,
15970 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070015971{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015972 int ret;
15973
15974 vos_ssr_protect(__func__);
15975 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
15976 vos_ssr_unprotect(__func__);
15977 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070015978}
15979#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
15980static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
15981 struct ieee80211_txq_params *params)
15982{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015983 int ret;
15984
15985 vos_ssr_protect(__func__);
15986 ret = __wlan_hdd_set_txq_params(wiphy, params);
15987 vos_ssr_unprotect(__func__);
15988 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070015989}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015990#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015991
Naresh Jayaram69e3f282014-10-14 12:29:12 +053015992static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015993 struct net_device *dev,
15994 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070015995{
15996 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015997 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015998 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015999 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016000 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016001 v_CONTEXT_t pVosContext = NULL;
16002 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016003
Jeff Johnsone7245742012-09-05 17:12:55 -070016004 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016005
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016006 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070016007 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016008 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016009 return -EINVAL;
16010 }
16011
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016012 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16013 TRACE_CODE_HDD_CFG80211_DEL_STA,
16014 pAdapter->sessionId, pAdapter->device_mode));
16015
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016016 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16017 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016018 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016019 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016020 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016021 }
16022
Jeff Johnson295189b2012-06-20 16:38:30 -070016023 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016024 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016025 )
16026 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016027 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
16028 pSapCtx = VOS_GET_SAP_CB(pVosContext);
16029 if(pSapCtx == NULL){
16030 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16031 FL("psapCtx is NULL"));
16032 return -ENOENT;
16033 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016034 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070016035 {
16036 v_U16_t i;
16037 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
16038 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016039 if ((pSapCtx->aStaInfo[i].isUsed) &&
16040 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070016041 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016042 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016043 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016044 ETHER_ADDR_LEN);
16045
Jeff Johnson295189b2012-06-20 16:38:30 -070016046 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016047 "%s: Delete STA with MAC::"
16048 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016049 __func__,
16050 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
16051 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070016052 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016053 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016054 }
16055 }
16056 }
16057 else
16058 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016059
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016060 vos_status = hdd_softap_GetStaId(pAdapter,
16061 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016062 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16063 {
16064 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016065 "%s: Skip this DEL STA as this is not used::"
16066 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016067 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016068 return -ENOENT;
16069 }
16070
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016071 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016072 {
16073 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016074 "%s: Skip this DEL STA as deauth is in progress::"
16075 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016076 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016077 return -ENOENT;
16078 }
16079
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016080 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016081
Jeff Johnson295189b2012-06-20 16:38:30 -070016082 hddLog(VOS_TRACE_LEVEL_INFO,
16083 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016084 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016085 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016086 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016087
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016088 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016089 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16090 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016091 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016092 hddLog(VOS_TRACE_LEVEL_INFO,
16093 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016094 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016095 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016096 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016097 return -ENOENT;
16098 }
16099
Jeff Johnson295189b2012-06-20 16:38:30 -070016100 }
16101 }
16102
16103 EXIT();
16104
16105 return 0;
16106}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016107
16108#ifdef CFG80211_DEL_STA_V2
16109static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16110 struct net_device *dev,
16111 struct station_del_parameters *param)
16112#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016113#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16114static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16115 struct net_device *dev, const u8 *mac)
16116#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016117static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16118 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016119#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016120#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016121{
16122 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016123 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070016124
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016125 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016126
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016127#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016128 if (NULL == param) {
16129 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016130 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016131 return -EINVAL;
16132 }
16133
16134 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
16135 param->subtype, &delStaParams);
16136
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016137#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053016138 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016139 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016140#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016141 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
16142
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016143 vos_ssr_unprotect(__func__);
16144
16145 return ret;
16146}
16147
16148static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016149 struct net_device *dev,
16150#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16151 const u8 *mac,
16152#else
16153 u8 *mac,
16154#endif
16155 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016156{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016157 hdd_adapter_t *pAdapter;
16158 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016159 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016160#ifdef FEATURE_WLAN_TDLS
16161 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016162
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016163 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016164
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016165 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16166 if (NULL == pAdapter)
16167 {
16168 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16169 "%s: Adapter is NULL",__func__);
16170 return -EINVAL;
16171 }
16172 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16173 status = wlan_hdd_validate_context(pHddCtx);
16174 if (0 != status)
16175 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016176 return status;
16177 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016178
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016179 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16180 TRACE_CODE_HDD_CFG80211_ADD_STA,
16181 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016182 mask = params->sta_flags_mask;
16183
16184 set = params->sta_flags_set;
16185
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016186 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016187 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
16188 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016189
16190 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
16191 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080016192 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016193 }
16194 }
16195#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016196 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016197 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016198}
16199
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016200#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16201static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16202 struct net_device *dev, const u8 *mac,
16203 struct station_parameters *params)
16204#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016205static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16206 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016207#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016208{
16209 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016210
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016211 vos_ssr_protect(__func__);
16212 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
16213 vos_ssr_unprotect(__func__);
16214
16215 return ret;
16216}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016217#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070016218
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016219static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070016220 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016221{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016222 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16223 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016224 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016225 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016226 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016227 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070016228
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016229 ENTER();
16230
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016231 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016232 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016233 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016234 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016235 return -EINVAL;
16236 }
16237
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016238 if (!pmksa) {
16239 hddLog(LOGE, FL("pmksa is NULL"));
16240 return -EINVAL;
16241 }
16242
16243 if (!pmksa->bssid || !pmksa->pmkid) {
16244 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
16245 pmksa->bssid, pmksa->pmkid);
16246 return -EINVAL;
16247 }
16248
16249 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
16250 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16251
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016252 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16253 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016254 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016255 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016256 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016257 }
16258
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016259 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016260 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16261
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016262 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
16263 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016264
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016265 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016266 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016267 &pmk_id, 1, FALSE);
16268
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016269 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16270 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
16271 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016272
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016273 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016274 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016275}
16276
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016277static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
16278 struct cfg80211_pmksa *pmksa)
16279{
16280 int ret;
16281
16282 vos_ssr_protect(__func__);
16283 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
16284 vos_ssr_unprotect(__func__);
16285
16286 return ret;
16287}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016288
Wilson Yang6507c4e2013-10-01 20:11:19 -070016289
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016290static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070016291 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016292{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016293 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16294 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016295 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016296 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016297
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016298 ENTER();
16299
Wilson Yang6507c4e2013-10-01 20:11:19 -070016300 /* Validate pAdapter */
16301 if (NULL == pAdapter)
16302 {
16303 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
16304 return -EINVAL;
16305 }
16306
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016307 if (!pmksa) {
16308 hddLog(LOGE, FL("pmksa is NULL"));
16309 return -EINVAL;
16310 }
16311
16312 if (!pmksa->bssid) {
16313 hddLog(LOGE, FL("pmksa->bssid is NULL"));
16314 return -EINVAL;
16315 }
16316
Kiet Lam98c46a12014-10-31 15:34:57 -070016317 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
16318 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16319
Wilson Yang6507c4e2013-10-01 20:11:19 -070016320 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16321 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070016322 if (0 != status)
16323 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070016324 return status;
16325 }
16326
16327 /*Retrieve halHandle*/
16328 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16329
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016330 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16331 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
16332 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016333 /* Delete the PMKID CSR cache */
16334 if (eHAL_STATUS_SUCCESS !=
16335 sme_RoamDelPMKIDfromCache(halHandle,
16336 pAdapter->sessionId, pmksa->bssid, FALSE)) {
16337 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
16338 MAC_ADDR_ARRAY(pmksa->bssid));
16339 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016340 }
16341
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016342 EXIT();
16343 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016344}
16345
Wilson Yang6507c4e2013-10-01 20:11:19 -070016346
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016347static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
16348 struct cfg80211_pmksa *pmksa)
16349{
16350 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016351
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016352 vos_ssr_protect(__func__);
16353 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
16354 vos_ssr_unprotect(__func__);
16355
16356 return ret;
16357
16358}
16359
16360static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016361{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016362 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16363 tHalHandle halHandle;
16364 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016365 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016366
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016367 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070016368
16369 /* Validate pAdapter */
16370 if (NULL == pAdapter)
16371 {
16372 hddLog(VOS_TRACE_LEVEL_ERROR,
16373 "%s: Invalid Adapter" ,__func__);
16374 return -EINVAL;
16375 }
16376
16377 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16378 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070016379 if (0 != status)
16380 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070016381 return status;
16382 }
16383
16384 /*Retrieve halHandle*/
16385 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16386
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016387 /* Flush the PMKID cache in CSR */
16388 if (eHAL_STATUS_SUCCESS !=
16389 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
16390 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
16391 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016392 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016393 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080016394 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016395}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016396
16397static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
16398{
16399 int ret;
16400
16401 vos_ssr_protect(__func__);
16402 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
16403 vos_ssr_unprotect(__func__);
16404
16405 return ret;
16406}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016407#endif
16408
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016409#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016410static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
16411 struct net_device *dev,
16412 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016413{
16414 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16415 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016416 hdd_context_t *pHddCtx;
16417 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016418
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016419 ENTER();
16420
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016421 if (NULL == pAdapter)
16422 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016423 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016424 return -ENODEV;
16425 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016426 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16427 ret = wlan_hdd_validate_context(pHddCtx);
16428 if (0 != ret)
16429 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016430 return ret;
16431 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016432 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016433 if (NULL == pHddStaCtx)
16434 {
16435 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
16436 return -EINVAL;
16437 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016438
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016439 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16440 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
16441 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016442 // Added for debug on reception of Re-assoc Req.
16443 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
16444 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016445 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016446 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080016447 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016448 }
16449
16450#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080016451 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016452 ftie->ie_len);
16453#endif
16454
16455 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016456 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
16457 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016458 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016459
16460 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016461 return 0;
16462}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016463
16464static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
16465 struct net_device *dev,
16466 struct cfg80211_update_ft_ies_params *ftie)
16467{
16468 int ret;
16469
16470 vos_ssr_protect(__func__);
16471 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
16472 vos_ssr_unprotect(__func__);
16473
16474 return ret;
16475}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016476#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016477
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016478#ifdef FEATURE_WLAN_SCAN_PNO
16479
16480void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
16481 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
16482{
16483 int ret;
16484 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
16485 hdd_context_t *pHddCtx;
16486
Nirav Shah80830bf2013-12-31 16:35:12 +053016487 ENTER();
16488
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016489 if (NULL == pAdapter)
16490 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053016491 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016492 "%s: HDD adapter is Null", __func__);
16493 return ;
16494 }
16495
16496 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16497 if (NULL == pHddCtx)
16498 {
16499 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16500 "%s: HDD context is Null!!!", __func__);
16501 return ;
16502 }
16503
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016504 spin_lock(&pHddCtx->schedScan_lock);
16505 if (TRUE == pHddCtx->isWiphySuspended)
16506 {
16507 pHddCtx->isSchedScanUpdatePending = TRUE;
16508 spin_unlock(&pHddCtx->schedScan_lock);
16509 hddLog(VOS_TRACE_LEVEL_INFO,
16510 "%s: Update cfg80211 scan database after it resume", __func__);
16511 return ;
16512 }
16513 spin_unlock(&pHddCtx->schedScan_lock);
16514
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016515 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
16516
16517 if (0 > ret)
16518 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053016519 else
16520 {
16521 /* Acquire wakelock to handle the case where APP's tries to suspend
16522 * immediatly after the driver gets connect request(i.e after pno)
16523 * from supplicant, this result in app's is suspending and not able
16524 * to process the connect request to AP */
16525 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
16526 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016527 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016528 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16529 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016530}
16531
16532/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016533 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016534 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016535 */
16536static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
16537{
16538 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
16539 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016540 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016541 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16542 int status = 0;
16543 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
16544
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016545 /* The current firmware design does not allow PNO during any
16546 * active sessions. Hence, determine the active sessions
16547 * and return a failure.
16548 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016549 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
16550 {
16551 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016552 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016553
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016554 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
16555 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
16556 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
16557 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
16558 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053016559 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016560 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016561 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016562 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016563 }
16564 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
16565 pAdapterNode = pNext;
16566 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016567 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016568}
16569
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016570void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
16571{
16572 hdd_adapter_t *pAdapter = callbackContext;
16573 hdd_context_t *pHddCtx;
16574
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016575 ENTER();
16576
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016577 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
16578 {
16579 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16580 FL("Invalid adapter or adapter has invalid magic"));
16581 return;
16582 }
16583
16584 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16585 if (0 != wlan_hdd_validate_context(pHddCtx))
16586 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016587 return;
16588 }
16589
c_hpothub53c45d2014-08-18 16:53:14 +053016590 if (VOS_STATUS_SUCCESS != status)
16591 {
16592 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016593 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053016594 pHddCtx->isPnoEnable = FALSE;
16595 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016596
16597 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
16598 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016599 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016600}
16601
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016602/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016603 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
16604 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016605 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016606static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016607 struct net_device *dev, struct cfg80211_sched_scan_request *request)
16608{
16609 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016610 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016611 hdd_context_t *pHddCtx;
16612 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016613 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053016614 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
16615 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016616 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
16617 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016618 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016619 hdd_config_t *pConfig = NULL;
16620 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016621
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016622 ENTER();
16623
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016624 if (NULL == pAdapter)
16625 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016626 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016627 "%s: HDD adapter is Null", __func__);
16628 return -ENODEV;
16629 }
16630
16631 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016632 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016633
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016634 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016635 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016636 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016637 }
16638
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016639 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016640 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16641 if (NULL == hHal)
16642 {
16643 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16644 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016645 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016646 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016647 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16648 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
16649 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053016650 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053016651 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053016652 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053016653 {
16654 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16655 "%s: aborting the existing scan is unsuccessfull", __func__);
16656 return -EBUSY;
16657 }
16658
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016659 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016660 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016662 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016663 return -EBUSY;
16664 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016665
c_hpothu37f21312014-04-09 21:49:54 +053016666 if (TRUE == pHddCtx->isPnoEnable)
16667 {
16668 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
16669 FL("already PNO is enabled"));
16670 return -EBUSY;
16671 }
c_hpothu225aa7c2014-10-22 17:45:13 +053016672
16673 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
16674 {
16675 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16676 "%s: abort ROC failed ", __func__);
16677 return -EBUSY;
16678 }
16679
c_hpothu37f21312014-04-09 21:49:54 +053016680 pHddCtx->isPnoEnable = TRUE;
16681
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016682 pnoRequest.enable = 1; /*Enable PNO */
16683 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016684
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016685 if (( !pnoRequest.ucNetworksCount ) ||
16686 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016687 {
16688 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053016689 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016690 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053016691 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016692 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016693 goto error;
16694 }
16695
16696 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
16697 {
16698 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053016699 "%s: Incorrect number of channels %d",
16700 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016701 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016702 goto error;
16703 }
16704
16705 /* Framework provides one set of channels(all)
16706 * common for all saved profile */
16707 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
16708 channels_allowed, &num_channels_allowed))
16709 {
16710 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16711 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016712 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016713 goto error;
16714 }
16715 /* Checking each channel against allowed channel list */
16716 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053016717 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016718 {
Nirav Shah80830bf2013-12-31 16:35:12 +053016719 char chList [(request->n_channels*5)+1];
16720 int len;
16721 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016722 {
Nirav Shah80830bf2013-12-31 16:35:12 +053016723 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016724 {
Nirav Shah80830bf2013-12-31 16:35:12 +053016725 if (request->channels[i]->hw_value == channels_allowed[indx])
16726 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016727 if ((!pConfig->enableDFSPnoChnlScan) &&
16728 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
16729 {
16730 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16731 "%s : Dropping DFS channel : %d",
16732 __func__,channels_allowed[indx]);
16733 num_ignore_dfs_ch++;
16734 break;
16735 }
16736
Nirav Shah80830bf2013-12-31 16:35:12 +053016737 valid_ch[num_ch++] = request->channels[i]->hw_value;
16738 len += snprintf(chList+len, 5, "%d ",
16739 request->channels[i]->hw_value);
16740 break ;
16741 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016742 }
16743 }
Nirav Shah80830bf2013-12-31 16:35:12 +053016744 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016745
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016746 /*If all channels are DFS and dropped, then ignore the PNO request*/
16747 if (num_ignore_dfs_ch == request->n_channels)
16748 {
16749 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16750 "%s : All requested channels are DFS channels", __func__);
16751 ret = -EINVAL;
16752 goto error;
16753 }
16754 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016755
16756 pnoRequest.aNetworks =
16757 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
16758 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016759 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016760 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
16761 FL("failed to allocate memory aNetworks %u"),
16762 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
16763 goto error;
16764 }
16765 vos_mem_zero(pnoRequest.aNetworks,
16766 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
16767
16768 /* Filling per profile params */
16769 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
16770 {
16771 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016772 request->match_sets[i].ssid.ssid_len;
16773
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016774 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
16775 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016776 {
16777 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053016778 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016779 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016780 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016781 goto error;
16782 }
16783
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016784 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016785 request->match_sets[i].ssid.ssid,
16786 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053016787 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16788 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016789 i, pnoRequest.aNetworks[i].ssId.ssId);
16790 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
16791 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
16792 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016793
16794 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016795 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
16796 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016797
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016798 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016799 }
16800
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016801 for (i = 0; i < request->n_ssids; i++)
16802 {
16803 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016804 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016805 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016806 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016807 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016808 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016809 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016810 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016811 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016812 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016813 break;
16814 }
16815 j++;
16816 }
16817 }
16818 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16819 "Number of hidden networks being Configured = %d",
16820 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053016821 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080016822 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016823
16824 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
16825 if (pnoRequest.p24GProbeTemplate == NULL)
16826 {
16827 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
16828 FL("failed to allocate memory p24GProbeTemplate %u"),
16829 SIR_PNO_MAX_PB_REQ_SIZE);
16830 goto error;
16831 }
16832
16833 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
16834 if (pnoRequest.p5GProbeTemplate == NULL)
16835 {
16836 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
16837 FL("failed to allocate memory p5GProbeTemplate %u"),
16838 SIR_PNO_MAX_PB_REQ_SIZE);
16839 goto error;
16840 }
16841
16842 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
16843 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
16844
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053016845 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
16846 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053016847 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016848 pnoRequest.us24GProbeTemplateLen = request->ie_len;
16849 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
16850 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053016851
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016852 pnoRequest.us5GProbeTemplateLen = request->ie_len;
16853 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
16854 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053016855 }
16856
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016857 /* Driver gets only one time interval which is hardcoded in
16858 * supplicant for 10000ms. Taking power consumption into account 6 timers
16859 * will be used, Timervalue is increased exponentially i.e 10,20,40,
16860 * 80,160,320 secs. And number of scan cycle for each timer
16861 * is configurable through INI param gPNOScanTimerRepeatValue.
16862 * If it is set to 0 only one timer will be used and PNO scan cycle
16863 * will be repeated after each interval specified by supplicant
16864 * till PNO is disabled.
16865 */
16866 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016867 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016868 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016869 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016870 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
16871
16872 tempInterval = (request->interval)/1000;
16873 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16874 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
16875 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016876 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016877 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016878 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016879 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016880 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016881 tempInterval *= 2;
16882 }
16883 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016884 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016885
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016886 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016887
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016888 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016889 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
16890 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016891 pAdapter->pno_req_status = 0;
16892
Nirav Shah80830bf2013-12-31 16:35:12 +053016893 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16894 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016895 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
16896 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053016897
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016898 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016899 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016900 hdd_cfg80211_sched_scan_done_callback, pAdapter);
16901 if (eHAL_STATUS_SUCCESS != status)
16902 {
16903 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053016904 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016905 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016906 goto error;
16907 }
16908
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016909 ret = wait_for_completion_timeout(
16910 &pAdapter->pno_comp_var,
16911 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
16912 if (0 >= ret)
16913 {
16914 // Did not receive the response for PNO enable in time.
16915 // Assuming the PNO enable was success.
16916 // Returning error from here, because we timeout, results
16917 // in side effect of Wifi (Wifi Setting) not to work.
16918 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16919 FL("Timed out waiting for PNO to be Enabled"));
16920 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016921 }
16922
16923 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053016924 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016925
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016926error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016927 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16928 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053016929 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016930 if (pnoRequest.aNetworks)
16931 vos_mem_free(pnoRequest.aNetworks);
16932 if (pnoRequest.p24GProbeTemplate)
16933 vos_mem_free(pnoRequest.p24GProbeTemplate);
16934 if (pnoRequest.p5GProbeTemplate)
16935 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016936
16937 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016938 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016939}
16940
16941/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016942 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
16943 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016944 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016945static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
16946 struct net_device *dev, struct cfg80211_sched_scan_request *request)
16947{
16948 int ret;
16949
16950 vos_ssr_protect(__func__);
16951 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
16952 vos_ssr_unprotect(__func__);
16953
16954 return ret;
16955}
16956
16957/*
16958 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
16959 * Function to disable PNO
16960 */
16961static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016962 struct net_device *dev)
16963{
16964 eHalStatus status = eHAL_STATUS_FAILURE;
16965 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16966 hdd_context_t *pHddCtx;
16967 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016968 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016969 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016970
16971 ENTER();
16972
16973 if (NULL == pAdapter)
16974 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016975 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016976 "%s: HDD adapter is Null", __func__);
16977 return -ENODEV;
16978 }
16979
16980 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016981
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016982 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016983 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016984 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016985 "%s: HDD context is Null", __func__);
16986 return -ENODEV;
16987 }
16988
16989 /* The return 0 is intentional when isLogpInProgress and
16990 * isLoadUnloadInProgress. We did observe a crash due to a return of
16991 * failure in sched_scan_stop , especially for a case where the unload
16992 * of the happens at the same time. The function __cfg80211_stop_sched_scan
16993 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
16994 * success. If it returns a failure , then its next invocation due to the
16995 * clean up of the second interface will have the dev pointer corresponding
16996 * to the first one leading to a crash.
16997 */
16998 if (pHddCtx->isLogpInProgress)
16999 {
17000 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17001 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053017002 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017003 return ret;
17004 }
17005
Mihir Shete18156292014-03-11 15:38:30 +053017006 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017007 {
17008 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17009 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17010 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017011 }
17012
17013 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17014 if (NULL == hHal)
17015 {
17016 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17017 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017018 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017019 }
17020
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017021 pnoRequest.enable = 0; /* Disable PNO */
17022 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017023
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017024 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17025 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
17026 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017027
17028 INIT_COMPLETION(pAdapter->pno_comp_var);
17029 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
17030 pnoRequest.callbackContext = pAdapter;
17031 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017032 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017033 pAdapter->sessionId,
17034 NULL, pAdapter);
17035 if (eHAL_STATUS_SUCCESS != status)
17036 {
17037 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17038 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017039 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017040 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017041 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017042 ret = wait_for_completion_timeout(
17043 &pAdapter->pno_comp_var,
17044 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
17045 if (0 >= ret)
17046 {
17047 // Did not receive the response for PNO disable in time.
17048 // Assuming the PNO disable was success.
17049 // Returning error from here, because we timeout, results
17050 // in side effect of Wifi (Wifi Setting) not to work.
17051 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17052 FL("Timed out waiting for PNO to be disabled"));
17053 ret = 0;
17054 }
17055
17056 ret = pAdapter->pno_req_status;
17057 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017058
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017059error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017060 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017061 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017062
17063 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017064 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017065}
17066
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017067/*
17068 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
17069 * NL interface to disable PNO
17070 */
17071static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
17072 struct net_device *dev)
17073{
17074 int ret;
17075
17076 vos_ssr_protect(__func__);
17077 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
17078 vos_ssr_unprotect(__func__);
17079
17080 return ret;
17081}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017082#endif /*FEATURE_WLAN_SCAN_PNO*/
17083
17084
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017085#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017086#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017087static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17088 struct net_device *dev,
17089 u8 *peer, u8 action_code,
17090 u8 dialog_token,
17091 u16 status_code, u32 peer_capability,
17092 const u8 *buf, size_t len)
17093#else /* TDLS_MGMT_VERSION2 */
17094#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17095static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17096 struct net_device *dev,
17097 const u8 *peer, u8 action_code,
17098 u8 dialog_token, u16 status_code,
17099 u32 peer_capability, bool initiator,
17100 const u8 *buf, size_t len)
17101#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17102static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17103 struct net_device *dev,
17104 const u8 *peer, u8 action_code,
17105 u8 dialog_token, u16 status_code,
17106 u32 peer_capability, const u8 *buf,
17107 size_t len)
17108#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17109static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17110 struct net_device *dev,
17111 u8 *peer, u8 action_code,
17112 u8 dialog_token,
17113 u16 status_code, u32 peer_capability,
17114 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017115#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017116static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17117 struct net_device *dev,
17118 u8 *peer, u8 action_code,
17119 u8 dialog_token,
17120 u16 status_code, const u8 *buf,
17121 size_t len)
17122#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017123#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017124{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017125 hdd_adapter_t *pAdapter;
17126 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017127 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070017128 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080017129 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070017130 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017131 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017132 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017133#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017134 u32 peer_capability = 0;
17135#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017136 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017137 hdd_station_ctx_t *pHddStaCtx = NULL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017138
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017139 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17140 if (NULL == pAdapter)
17141 {
17142 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17143 "%s: Adapter is NULL",__func__);
17144 return -EINVAL;
17145 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017146 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17147 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
17148 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017149
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017150 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017151 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017152 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017153 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017154 "Invalid arguments");
17155 return -EINVAL;
17156 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017157
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017158 if (pHddCtx->isLogpInProgress)
17159 {
17160 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17161 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053017162 wlan_hdd_tdls_set_link_status(pAdapter,
17163 peer,
17164 eTDLS_LINK_IDLE,
17165 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017166 return -EBUSY;
17167 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017168
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017169 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
17170 {
17171 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17172 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17173 return -EAGAIN;
17174 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017175
Hoonki Lee27511902013-03-14 18:19:06 -070017176 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017177 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017178 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017179 "%s: TDLS mode is disabled OR not enabled in FW."
17180 MAC_ADDRESS_STR " action %d declined.",
17181 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017182 return -ENOTSUPP;
17183 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017184
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017185 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17186
17187 if( NULL == pHddStaCtx )
17188 {
17189 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17190 "%s: HDD station context NULL ",__func__);
17191 return -EINVAL;
17192 }
17193
17194 /* STA should be connected and authenticated
17195 * before sending any TDLS frames
17196 */
17197 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
17198 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
17199 {
17200 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17201 "STA is not connected or unauthenticated. "
17202 "connState %u, uIsAuthenticated %u",
17203 pHddStaCtx->conn_info.connState,
17204 pHddStaCtx->conn_info.uIsAuthenticated);
17205 return -EAGAIN;
17206 }
17207
Hoonki Lee27511902013-03-14 18:19:06 -070017208 /* other than teardown frame, other mgmt frames are not sent if disabled */
17209 if (SIR_MAC_TDLS_TEARDOWN != action_code)
17210 {
17211 /* if tdls_mode is disabled to respond to peer's request */
17212 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
17213 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017214 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017215 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017216 " TDLS mode is disabled. action %d declined.",
17217 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070017218
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017219 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070017220 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053017221
17222 if (vos_max_concurrent_connections_reached())
17223 {
17224 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17225 return -EINVAL;
17226 }
Hoonki Lee27511902013-03-14 18:19:06 -070017227 }
17228
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017229 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
17230 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053017231 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017232 {
17233 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017234 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017235 " TDLS setup is ongoing. action %d declined.",
17236 __func__, MAC_ADDR_ARRAY(peer), action_code);
17237 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017238 }
17239 }
17240
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017241 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
17242 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080017243 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017244 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
17245 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017246 {
17247 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
17248 we return error code at 'add_station()'. Hence we have this
17249 check again in addtion to add_station().
17250 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017251 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017252 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017253 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17254 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017255 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
17256 __func__, MAC_ADDR_ARRAY(peer), action_code,
17257 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053017258 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080017259 }
17260 else
17261 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017262 /* maximum reached. tweak to send error code to peer and return
17263 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080017264 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017265 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17266 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017267 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
17268 __func__, MAC_ADDR_ARRAY(peer), status_code,
17269 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070017270 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017271 /* fall through to send setup resp with failure status
17272 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080017273 }
17274 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017275 else
17276 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017277 mutex_lock(&pHddCtx->tdls_lock);
17278 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070017279 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017280 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017281 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017282 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017283 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
17284 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017285 return -EPERM;
17286 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017287 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017288 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017289 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017290
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017291 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017292 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017293 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
17294 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017295
Hoonki Leea34dd892013-02-05 22:56:02 -080017296 /*Except teardown responder will not be used so just make 0*/
17297 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017298 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080017299 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017300
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017301 mutex_lock(&pHddCtx->tdls_lock);
17302 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017303
17304 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
17305 responder = pTdlsPeer->is_responder;
17306 else
Hoonki Leea34dd892013-02-05 22:56:02 -080017307 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017308 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017309 "%s: " MAC_ADDRESS_STR " peer doesn't exist or not connected %d dialog_token %d status %d, len = %zu",
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017310 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
17311 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017312 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017313 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080017314 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017315 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017316 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017317
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017318 /* Discard TDLS setup if peer is removed by user app */
17319 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
17320 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
17321 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
17322 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
17323
17324 mutex_lock(&pHddCtx->tdls_lock);
17325 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
17326 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
17327 mutex_unlock(&pHddCtx->tdls_lock);
17328 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
17329 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
17330 MAC_ADDR_ARRAY(peer), action_code);
17331 return -EINVAL;
17332 }
17333 mutex_unlock(&pHddCtx->tdls_lock);
17334 }
17335
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017336 /* For explicit trigger of DIS_REQ come out of BMPS for
17337 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070017338 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017339 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
17340 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070017341 {
17342 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
17343 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017344 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017345 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017346 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
17347 if (status != VOS_STATUS_SUCCESS) {
17348 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
17349 }
Hoonki Lee14621352013-04-16 17:51:19 -070017350 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017351 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017352 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017353 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
17354 }
17355 }
Hoonki Lee14621352013-04-16 17:51:19 -070017356 }
17357
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017358 /* make sure doesn't call send_mgmt() while it is pending */
17359 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
17360 {
17361 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017362 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017363 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017364 ret = -EBUSY;
17365 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017366 }
17367
17368 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017369 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
17370
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017371 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
17372 pAdapter->sessionId, peer, action_code, dialog_token,
17373 status_code, peer_capability, (tANI_U8 *)buf, len,
17374 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017375
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017376 if (VOS_STATUS_SUCCESS != status)
17377 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017378 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17379 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017380 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017381 ret = -EINVAL;
17382 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017383 }
17384
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017385 if ((SIR_MAC_TDLS_DIS_REQ == action_code) ||
17386 (SIR_MAC_TDLS_DIS_RSP == action_code))
17387 {
17388 /* for DIS_REQ/DIS_RSP, supplicant don't consider the return status.
17389 * So we no need to wait for tdls_mgmt_comp for sending ack status.
17390 */
17391 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17392 "%s: tx done for frm %u", __func__, action_code);
17393 return 0;
17394 }
17395
17396 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17397 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
17398 WAIT_TIME_TDLS_MGMT);
17399
Hoonki Leed37cbb32013-04-20 00:31:14 -070017400 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
17401 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
17402
17403 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017404 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070017405 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070017406 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070017407 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017408 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080017409
17410 if (pHddCtx->isLogpInProgress)
17411 {
17412 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17413 "%s: LOGP in Progress. Ignore!!!", __func__);
17414 return -EAGAIN;
17415 }
Abhishek Singh837adf22015-10-01 17:37:37 +053017416 if (rc <= 0)
17417 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
17418 WLAN_LOG_INDICATOR_HOST_DRIVER,
17419 WLAN_LOG_REASON_HDD_TIME_OUT,
17420 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080017421
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017422 ret = -EINVAL;
17423 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017424 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017425 else
17426 {
17427 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17428 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
17429 __func__, rc, pAdapter->mgmtTxCompletionStatus);
17430 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017431
Gopichand Nakkala05922802013-03-14 12:23:19 -070017432 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070017433 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017434 ret = max_sta_failed;
17435 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070017436 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017437
Hoonki Leea34dd892013-02-05 22:56:02 -080017438 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
17439 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017440 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017441 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
17442 }
Hoonki Leea34dd892013-02-05 22:56:02 -080017443 }
17444 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
17445 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017446 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017447 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
17448 }
Hoonki Leea34dd892013-02-05 22:56:02 -080017449 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017450
17451 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017452
17453tx_failed:
17454 /* add_station will be called before sending TDLS_SETUP_REQ and
17455 * TDLS_SETUP_RSP and as part of add_station driver will enable
17456 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
17457 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
17458 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
17459 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
17460 */
17461
17462 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
17463 (SIR_MAC_TDLS_SETUP_RSP == action_code))
17464 wlan_hdd_tdls_check_bmps(pAdapter);
17465 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017466}
17467
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017468#if TDLS_MGMT_VERSION2
17469static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
17470 u8 *peer, u8 action_code, u8 dialog_token,
17471 u16 status_code, u32 peer_capability,
17472 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017473#else /* TDLS_MGMT_VERSION2 */
17474#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
17475static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17476 struct net_device *dev,
17477 const u8 *peer, u8 action_code,
17478 u8 dialog_token, u16 status_code,
17479 u32 peer_capability, bool initiator,
17480 const u8 *buf, size_t len)
17481#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17482static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17483 struct net_device *dev,
17484 const u8 *peer, u8 action_code,
17485 u8 dialog_token, u16 status_code,
17486 u32 peer_capability, const u8 *buf,
17487 size_t len)
17488#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
17489static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17490 struct net_device *dev,
17491 u8 *peer, u8 action_code,
17492 u8 dialog_token,
17493 u16 status_code, u32 peer_capability,
17494 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017495#else
17496static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
17497 u8 *peer, u8 action_code, u8 dialog_token,
17498 u16 status_code, const u8 *buf, size_t len)
17499#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017500#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017501{
17502 int ret;
17503
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017504 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017505#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017506 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17507 dialog_token, status_code,
17508 peer_capability, buf, len);
17509#else /* TDLS_MGMT_VERSION2 */
17510#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17511 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17512 dialog_token, status_code,
17513 peer_capability, initiator,
17514 buf, len);
17515#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17516 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17517 dialog_token, status_code,
17518 peer_capability, buf, len);
17519#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17520 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17521 dialog_token, status_code,
17522 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017523#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017524 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17525 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017526#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017527#endif
17528 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017529
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017530 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017531}
Atul Mittal115287b2014-07-08 13:26:33 +053017532
17533int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017534#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17535 const u8 *peer,
17536#else
Atul Mittal115287b2014-07-08 13:26:33 +053017537 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017538#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017539 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053017540 cfg80211_exttdls_callback callback)
17541{
17542
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017543 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053017544 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017545 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053017546 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17547 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
17548 __func__, MAC_ADDR_ARRAY(peer));
17549
17550 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
17551 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
17552
17553 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017554 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
17555 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
17556 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053017557 return -ENOTSUPP;
17558 }
17559
17560 /* To cater the requirement of establishing the TDLS link
17561 * irrespective of the data traffic , get an entry of TDLS peer.
17562 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053017563 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017564 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
17565 if (pTdlsPeer == NULL) {
17566 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17567 "%s: peer " MAC_ADDRESS_STR " not existing",
17568 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053017569 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017570 return -EINVAL;
17571 }
17572
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053017573 /* check FW TDLS Off Channel capability */
17574 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053017575 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053017576 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017577 {
17578 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
17579 pTdlsPeer->peerParams.global_operating_class =
17580 tdls_peer_params->global_operating_class;
17581 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
17582 pTdlsPeer->peerParams.min_bandwidth_kbps =
17583 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017584 /* check configured channel is valid, non dfs and
17585 * not current operating channel */
17586 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
17587 tdls_peer_params->channel)) &&
17588 (pHddStaCtx) &&
17589 (tdls_peer_params->channel !=
17590 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017591 {
17592 pTdlsPeer->isOffChannelConfigured = TRUE;
17593 }
17594 else
17595 {
17596 pTdlsPeer->isOffChannelConfigured = FALSE;
17597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17598 "%s: Configured Tdls Off Channel is not valid", __func__);
17599
17600 }
17601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017602 "%s: tdls_off_channel %d isOffChannelConfigured %d "
17603 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017604 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017605 pTdlsPeer->isOffChannelConfigured,
17606 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017607 }
17608 else
17609 {
17610 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053017611 "%s: TDLS off channel FW capability %d, "
17612 "host capab %d or Invalid TDLS Peer Params", __func__,
17613 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
17614 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017615 }
17616
Atul Mittal115287b2014-07-08 13:26:33 +053017617 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
17618
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017619 mutex_unlock(&pHddCtx->tdls_lock);
17620
Atul Mittal115287b2014-07-08 13:26:33 +053017621 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17622 " %s TDLS Add Force Peer Failed",
17623 __func__);
17624 return -EINVAL;
17625 }
17626 /*EXT TDLS*/
17627
17628 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017629 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17631 " %s TDLS set callback Failed",
17632 __func__);
17633 return -EINVAL;
17634 }
17635
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017636 mutex_unlock(&pHddCtx->tdls_lock);
17637
Atul Mittal115287b2014-07-08 13:26:33 +053017638 return(0);
17639
17640}
17641
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017642int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
17643#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17644 const u8 *peer
17645#else
17646 u8 *peer
17647#endif
17648)
Atul Mittal115287b2014-07-08 13:26:33 +053017649{
17650
17651 hddTdlsPeer_t *pTdlsPeer;
17652 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17653 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17654 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
17655 __func__, MAC_ADDR_ARRAY(peer));
17656
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017657 if (0 != wlan_hdd_validate_context(pHddCtx)) {
17658 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
17659 return -EINVAL;
17660 }
17661
Atul Mittal115287b2014-07-08 13:26:33 +053017662 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
17663 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
17664
17665 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017666 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
17667 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
17668 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053017669 return -ENOTSUPP;
17670 }
17671
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017672 mutex_lock(&pHddCtx->tdls_lock);
17673 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053017674
17675 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017676 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017677 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017678 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053017679 __func__, MAC_ADDR_ARRAY(peer));
17680 return -EINVAL;
17681 }
17682 else {
17683 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
17684 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017685 /* if channel switch is configured, reset
17686 the channel for this peer */
17687 if (TRUE == pTdlsPeer->isOffChannelConfigured)
17688 {
17689 pTdlsPeer->peerParams.channel = 0;
17690 pTdlsPeer->isOffChannelConfigured = FALSE;
17691 }
Atul Mittal115287b2014-07-08 13:26:33 +053017692 }
17693
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017694 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017695 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017696 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053017697 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017698 }
Atul Mittal115287b2014-07-08 13:26:33 +053017699
17700 /*EXT TDLS*/
17701
17702 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017703 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017704 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17705 " %s TDLS set callback Failed",
17706 __func__);
17707 return -EINVAL;
17708 }
Atul Mittal115287b2014-07-08 13:26:33 +053017709
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017710 mutex_unlock(&pHddCtx->tdls_lock);
17711
17712 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053017713}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017714static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017715#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17716 const u8 *peer,
17717#else
17718 u8 *peer,
17719#endif
17720 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017721{
17722 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17723 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017724 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017725 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017726
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017727 ENTER();
17728
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017729 if (!pAdapter) {
17730 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
17731 return -EINVAL;
17732 }
17733
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017734 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17735 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
17736 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017737 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017738 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017739 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070017740 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017741 return -EINVAL;
17742 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080017743
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017744 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017745 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017746 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017747 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017748 }
17749
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017750
17751 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080017752 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017753 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080017754 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017755 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
17756 "Cannot process TDLS commands",
17757 pHddCtx->cfg_ini->fEnableTDLSSupport,
17758 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017759 return -ENOTSUPP;
17760 }
17761
17762 switch (oper) {
17763 case NL80211_TDLS_ENABLE_LINK:
17764 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017765 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017766 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053017767 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053017768 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017769 tANI_U16 numCurrTdlsPeers = 0;
17770 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017771 tANI_U8 suppChannelLen = 0;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017772
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017773 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17774 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
17775 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017776
Sunil Dutt41de4e22013-11-14 18:09:02 +053017777 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053017778 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053017779 if ( NULL == pTdlsPeer ) {
17780 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
17781 " (oper %d) not exsting. ignored",
17782 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
17783 return -EINVAL;
17784 }
17785
17786 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17787 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
17788 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
17789 "NL80211_TDLS_ENABLE_LINK");
17790
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070017791 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
17792 {
17793 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
17794 MAC_ADDRESS_STR " failed",
17795 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
17796 return -EINVAL;
17797 }
17798
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053017799 /* before starting tdls connection, set tdls
17800 * off channel established status to default value */
17801 pTdlsPeer->isOffChannelEstablished = FALSE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017802 /* TDLS Off Channel, Disable tdls channel switch,
17803 when there are more than one tdls link */
17804 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053017805 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017806 {
17807 /* get connected peer and send disable tdls off chan */
17808 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017809 if ((connPeer) &&
17810 (connPeer->isOffChannelSupported == TRUE) &&
17811 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017812 {
17813 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17814 "%s: More then one peer connected, Disable "
17815 "TDLS channel switch", __func__);
17816
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053017817 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017818
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017819 ret = sme_SendTdlsChanSwitchReq(
17820 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017821 pAdapter->sessionId,
17822 connPeer->peerMac,
17823 connPeer->peerParams.channel,
17824 TDLS_OFF_CHANNEL_BW_OFFSET,
17825 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017826 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017827 hddLog(VOS_TRACE_LEVEL_ERROR,
17828 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017829 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017830 }
17831 else
17832 {
17833 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17834 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017835 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017836 "isOffChannelConfigured %d",
17837 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017838 (connPeer ? (connPeer->isOffChannelSupported)
17839 : -1),
17840 (connPeer ? (connPeer->isOffChannelConfigured)
17841 : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017842 }
17843 }
17844
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017845 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017846 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053017847 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053017848
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053017849 if (0 != wlan_hdd_tdls_get_link_establish_params(
17850 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017851 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053017852 return -EINVAL;
17853 }
17854 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053017855
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017856 ret = sme_SendTdlsLinkEstablishParams(
17857 WLAN_HDD_GET_HAL_CTX(pAdapter),
17858 pAdapter->sessionId, peer,
17859 &tdlsLinkEstablishParams);
17860 if (ret != VOS_STATUS_SUCCESS) {
17861 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
17862 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053017863 /* Send TDLS peer UAPSD capabilities to the firmware and
17864 * register with the TL on after the response for this operation
17865 * is received .
17866 */
17867 ret = wait_for_completion_interruptible_timeout(
17868 &pAdapter->tdls_link_establish_req_comp,
17869 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
17870 if (ret <= 0)
17871 {
17872 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017873 FL("Link Establish Request Failed Status %ld"),
17874 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053017875 return -EINVAL;
17876 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053017877 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017878
Atul Mittal115287b2014-07-08 13:26:33 +053017879 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
17880 eTDLS_LINK_CONNECTED,
17881 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053017882 staDesc.ucSTAId = pTdlsPeer->staId;
17883 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017884 ret = WLANTL_UpdateTdlsSTAClient(
17885 pHddCtx->pvosContext,
17886 &staDesc);
17887 if (ret != VOS_STATUS_SUCCESS) {
17888 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
17889 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053017890
Gopichand Nakkala471708b2013-06-04 20:03:01 +053017891 /* Mark TDLS client Authenticated .*/
17892 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
17893 pTdlsPeer->staId,
17894 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070017895 if (VOS_STATUS_SUCCESS == status)
17896 {
Hoonki Lee14621352013-04-16 17:51:19 -070017897 if (pTdlsPeer->is_responder == 0)
17898 {
17899 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053017900 tdlsConnInfo_t *tdlsInfo;
17901
17902 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
17903
17904 /* Initialize initiator wait callback */
17905 vos_timer_init(
17906 &pTdlsPeer->initiatorWaitTimeoutTimer,
17907 VOS_TIMER_TYPE_SW,
17908 wlan_hdd_tdls_initiator_wait_cb,
17909 tdlsInfo);
Hoonki Lee14621352013-04-16 17:51:19 -070017910
17911 wlan_hdd_tdls_timer_restart(pAdapter,
17912 &pTdlsPeer->initiatorWaitTimeoutTimer,
17913 WAIT_TIME_TDLS_INITIATOR);
17914 /* suspend initiator TX until it receives direct packet from the
17915 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017916 ret = WLANTL_SuspendDataTx(
17917 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
17918 &staId, NULL);
17919 if (ret != VOS_STATUS_SUCCESS) {
17920 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
17921 }
Hoonki Lee14621352013-04-16 17:51:19 -070017922 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017923
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017924 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017925 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017926 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017927 suppChannelLen =
17928 tdlsLinkEstablishParams.supportedChannelsLen;
17929
17930 if ((suppChannelLen > 0) &&
17931 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
17932 {
17933 tANI_U8 suppPeerChannel = 0;
17934 int i = 0;
17935 for (i = 0U; i < suppChannelLen; i++)
17936 {
17937 suppPeerChannel =
17938 tdlsLinkEstablishParams.supportedChannels[i];
17939
17940 pTdlsPeer->isOffChannelSupported = FALSE;
17941 if (suppPeerChannel ==
17942 pTdlsPeer->peerParams.channel)
17943 {
17944 pTdlsPeer->isOffChannelSupported = TRUE;
17945 break;
17946 }
17947 }
17948 }
17949 else
17950 {
17951 pTdlsPeer->isOffChannelSupported = FALSE;
17952 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017953 }
17954 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17955 "%s: TDLS channel switch request for channel "
17956 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017957 "%d isOffChannelSupported %d", __func__,
17958 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017959 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017960 suppChannelLen,
17961 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017962
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017963 /* TDLS Off Channel, Enable tdls channel switch,
17964 when their is only one tdls link and it supports */
17965 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
17966 if ((numCurrTdlsPeers == 1) &&
17967 (TRUE == pTdlsPeer->isOffChannelSupported) &&
17968 (TRUE == pTdlsPeer->isOffChannelConfigured))
17969 {
17970 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17971 "%s: Send TDLS channel switch request for channel %d",
17972 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053017973
17974 pTdlsPeer->isOffChannelEstablished = TRUE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017975 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
17976 pAdapter->sessionId,
17977 pTdlsPeer->peerMac,
17978 pTdlsPeer->peerParams.channel,
17979 TDLS_OFF_CHANNEL_BW_OFFSET,
17980 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017981 if (ret != VOS_STATUS_SUCCESS) {
17982 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
17983 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017984 }
17985 else
17986 {
17987 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17988 "%s: TDLS channel switch request not sent"
17989 " numCurrTdlsPeers %d "
17990 "isOffChannelSupported %d "
17991 "isOffChannelConfigured %d",
17992 __func__, numCurrTdlsPeers,
17993 pTdlsPeer->isOffChannelSupported,
17994 pTdlsPeer->isOffChannelConfigured);
17995 }
17996
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070017997 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017998 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053017999
18000 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018001 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
18002 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018003 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018004 int ac;
18005 uint8 ucAc[4] = { WLANTL_AC_VO,
18006 WLANTL_AC_VI,
18007 WLANTL_AC_BK,
18008 WLANTL_AC_BE };
18009 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
18010 for(ac=0; ac < 4; ac++)
18011 {
18012 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
18013 pTdlsPeer->staId, ucAc[ac],
18014 tlTid[ac], tlTid[ac], 0, 0,
18015 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018016 if (status != VOS_STATUS_SUCCESS) {
18017 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
18018 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018019 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018020 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018021 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018022 }
18023 break;
18024 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080018025 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018026 tANI_U16 numCurrTdlsPeers = 0;
18027 hddTdlsPeer_t *connPeer = NULL;
18028
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018029 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18030 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
18031 __func__, MAC_ADDR_ARRAY(peer));
18032
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018033 mutex_lock(&pHddCtx->tdls_lock);
18034 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018035
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018036
Sunil Dutt41de4e22013-11-14 18:09:02 +053018037 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018038 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018039 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18040 " (oper %d) not exsting. ignored",
18041 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18042 return -EINVAL;
18043 }
18044
18045 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18046 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
18047 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
18048 "NL80211_TDLS_DISABLE_LINK");
18049
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018050 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080018051 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018052 long status;
18053
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053018054 /* set tdls off channel status to false for this peer */
18055 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053018056 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
18057 eTDLS_LINK_TEARING,
18058 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
18059 eTDLS_LINK_UNSPECIFIED:
18060 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018061 mutex_unlock(&pHddCtx->tdls_lock);
18062
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018063 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
18064
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018065 status = sme_DeleteTdlsPeerSta(
18066 WLAN_HDD_GET_HAL_CTX(pAdapter),
18067 pAdapter->sessionId, peer );
18068 if (status != VOS_STATUS_SUCCESS) {
18069 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
18070 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018071
18072 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
18073 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018074
18075 mutex_lock(&pHddCtx->tdls_lock);
18076 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18077 if ( NULL == pTdlsPeer ) {
18078 mutex_unlock(&pHddCtx->tdls_lock);
18079 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18080 " peer was freed in other context",
18081 __func__, MAC_ADDR_ARRAY(peer));
18082 return -EINVAL;
18083 }
18084
Atul Mittal271a7652014-09-12 13:18:22 +053018085 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053018086 eTDLS_LINK_IDLE,
18087 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018088 mutex_unlock(&pHddCtx->tdls_lock);
18089
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018090 if (status <= 0)
18091 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018092 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18093 "%s: Del station failed status %ld",
18094 __func__, status);
18095 return -EPERM;
18096 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018097
18098 /* TDLS Off Channel, Enable tdls channel switch,
18099 when their is only one tdls link and it supports */
18100 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18101 if (numCurrTdlsPeers == 1)
18102 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018103 tSirMacAddr peerMac;
18104 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018105
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018106 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018107 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018108
18109 if (connPeer == NULL) {
18110 mutex_unlock(&pHddCtx->tdls_lock);
18111 hddLog(VOS_TRACE_LEVEL_ERROR,
18112 "%s connPeer is NULL", __func__);
18113 return -EINVAL;
18114 }
18115
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018116 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
18117 channel = connPeer->peerParams.channel;
18118
18119 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18120 "%s: TDLS channel switch "
18121 "isOffChannelSupported %d "
18122 "isOffChannelConfigured %d "
18123 "isOffChannelEstablished %d",
18124 __func__,
18125 (connPeer ? connPeer->isOffChannelSupported : -1),
18126 (connPeer ? connPeer->isOffChannelConfigured : -1),
18127 (connPeer ? connPeer->isOffChannelEstablished : -1));
18128
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018129 if ((connPeer) &&
18130 (connPeer->isOffChannelSupported == TRUE) &&
18131 (connPeer->isOffChannelConfigured == TRUE))
18132 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018133 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018134 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018135 status = sme_SendTdlsChanSwitchReq(
18136 WLAN_HDD_GET_HAL_CTX(pAdapter),
18137 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018138 peerMac,
18139 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018140 TDLS_OFF_CHANNEL_BW_OFFSET,
18141 TDLS_CHANNEL_SWITCH_ENABLE);
18142 if (status != VOS_STATUS_SUCCESS) {
18143 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
18144 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018145 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018146 else
18147 mutex_unlock(&pHddCtx->tdls_lock);
18148 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018149 else
18150 {
18151 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18152 "%s: TDLS channel switch request not sent "
18153 "numCurrTdlsPeers %d ",
18154 __func__, numCurrTdlsPeers);
18155 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018156 }
18157 else
18158 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018159 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018160 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18161 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080018162 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018163 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018164 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018165 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053018166 {
Atul Mittal115287b2014-07-08 13:26:33 +053018167 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018168
Atul Mittal115287b2014-07-08 13:26:33 +053018169 if (0 != status)
18170 {
18171 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018172 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053018173 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053018174 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053018175 break;
18176 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018177 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053018178 {
Atul Mittal115287b2014-07-08 13:26:33 +053018179 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
18180 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018181 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053018182 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018183
Atul Mittal115287b2014-07-08 13:26:33 +053018184 if (0 != status)
18185 {
18186 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018187 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053018188 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053018189 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053018190 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053018191 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018192 case NL80211_TDLS_DISCOVERY_REQ:
18193 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018194 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018195 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018196 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018197 return -ENOTSUPP;
18198 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018199 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18200 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018201 return -ENOTSUPP;
18202 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018203
18204 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018205 return 0;
18206}
Chilam NG571c65a2013-01-19 12:27:36 +053018207
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018208static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018209#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18210 const u8 *peer,
18211#else
18212 u8 *peer,
18213#endif
18214 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018215{
18216 int ret;
18217
18218 vos_ssr_protect(__func__);
18219 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
18220 vos_ssr_unprotect(__func__);
18221
18222 return ret;
18223}
18224
Chilam NG571c65a2013-01-19 12:27:36 +053018225int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
18226 struct net_device *dev, u8 *peer)
18227{
Arif Hussaina7c8e412013-11-20 11:06:42 -080018228 hddLog(VOS_TRACE_LEVEL_INFO,
18229 "tdls send discover req: "MAC_ADDRESS_STR,
18230 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053018231
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018232#if TDLS_MGMT_VERSION2
18233 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18234 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18235#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018236#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
18237 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18238 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
18239#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18240 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18241 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18242#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
18243 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18244 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18245#else
Chilam NG571c65a2013-01-19 12:27:36 +053018246 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18247 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018248#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018249#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053018250}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018251#endif
18252
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018253#ifdef WLAN_FEATURE_GTK_OFFLOAD
18254/*
18255 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
18256 * Callback rountine called upon receiving response for
18257 * get offload info
18258 */
18259void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
18260 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
18261{
18262
18263 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018264 tANI_U8 tempReplayCounter[8];
18265 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018266
18267 ENTER();
18268
18269 if (NULL == pAdapter)
18270 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053018271 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018272 "%s: HDD adapter is Null", __func__);
18273 return ;
18274 }
18275
18276 if (NULL == pGtkOffloadGetInfoRsp)
18277 {
18278 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18279 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
18280 return ;
18281 }
18282
18283 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
18284 {
18285 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18286 "%s: wlan Failed to get replay counter value",
18287 __func__);
18288 return ;
18289 }
18290
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018291 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18292 /* Update replay counter */
18293 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
18294 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
18295
18296 {
18297 /* changing from little to big endian since supplicant
18298 * works on big endian format
18299 */
18300 int i;
18301 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
18302
18303 for (i = 0; i < 8; i++)
18304 {
18305 tempReplayCounter[7-i] = (tANI_U8)p[i];
18306 }
18307 }
18308
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018309 /* Update replay counter to NL */
18310 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018311 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018312}
18313
18314/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018315 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018316 * This function is used to offload GTK rekeying job to the firmware.
18317 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018318int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018319 struct cfg80211_gtk_rekey_data *data)
18320{
18321 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18322 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
18323 hdd_station_ctx_t *pHddStaCtx;
18324 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018325 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018326 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018327 eHalStatus status = eHAL_STATUS_FAILURE;
18328
18329 ENTER();
18330
18331 if (NULL == pAdapter)
18332 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018333 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018334 "%s: HDD adapter is Null", __func__);
18335 return -ENODEV;
18336 }
18337
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018338 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18339 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
18340 pAdapter->sessionId, pAdapter->device_mode));
18341
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018342 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018343 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018344 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018345 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018346 }
18347
18348 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18349 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18350 if (NULL == hHal)
18351 {
18352 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18353 "%s: HAL context is Null!!!", __func__);
18354 return -EAGAIN;
18355 }
18356
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018357 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
18358 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
18359 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
18360 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018361 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018362 {
18363 /* changing from big to little endian since driver
18364 * works on little endian format
18365 */
18366 tANI_U8 *p =
18367 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
18368 int i;
18369
18370 for (i = 0; i < 8; i++)
18371 {
18372 p[7-i] = data->replay_ctr[i];
18373 }
18374 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018375
18376 if (TRUE == pHddCtx->hdd_wlan_suspended)
18377 {
18378 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018379 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
18380 sizeof (tSirGtkOffloadParams));
18381 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018382 pAdapter->sessionId);
18383
18384 if (eHAL_STATUS_SUCCESS != status)
18385 {
18386 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18387 "%s: sme_SetGTKOffload failed, returned %d",
18388 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053018389
18390 /* Need to clear any trace of key value in the memory.
18391 * Thus zero out the memory even though it is local
18392 * variable.
18393 */
18394 vos_mem_zero(&hddGtkOffloadReqParams,
18395 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018396 return status;
18397 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018398 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18399 "%s: sme_SetGTKOffload successfull", __func__);
18400 }
18401 else
18402 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018403 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18404 "%s: wlan not suspended GTKOffload request is stored",
18405 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018406 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018407
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053018408 /* Need to clear any trace of key value in the memory.
18409 * Thus zero out the memory even though it is local
18410 * variable.
18411 */
18412 vos_mem_zero(&hddGtkOffloadReqParams,
18413 sizeof(hddGtkOffloadReqParams));
18414
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018415 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018416 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018417}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018418
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018419int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
18420 struct cfg80211_gtk_rekey_data *data)
18421{
18422 int ret;
18423
18424 vos_ssr_protect(__func__);
18425 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
18426 vos_ssr_unprotect(__func__);
18427
18428 return ret;
18429}
18430#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018431/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018432 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018433 * This function is used to set access control policy
18434 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018435static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
18436 struct net_device *dev,
18437 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018438{
18439 int i;
18440 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18441 hdd_hostapd_state_t *pHostapdState;
18442 tsap_Config_t *pConfig;
18443 v_CONTEXT_t pVosContext = NULL;
18444 hdd_context_t *pHddCtx;
18445 int status;
18446
18447 ENTER();
18448
18449 if (NULL == pAdapter)
18450 {
18451 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18452 "%s: HDD adapter is Null", __func__);
18453 return -ENODEV;
18454 }
18455
18456 if (NULL == params)
18457 {
18458 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18459 "%s: params is Null", __func__);
18460 return -EINVAL;
18461 }
18462
18463 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18464 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018465 if (0 != status)
18466 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018467 return status;
18468 }
18469
18470 pVosContext = pHddCtx->pvosContext;
18471 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
18472
18473 if (NULL == pHostapdState)
18474 {
18475 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18476 "%s: pHostapdState is Null", __func__);
18477 return -EINVAL;
18478 }
18479
18480 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
18481 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018482 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18483 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
18484 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018485
18486 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
18487 {
18488 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
18489
18490 /* default value */
18491 pConfig->num_accept_mac = 0;
18492 pConfig->num_deny_mac = 0;
18493
18494 /**
18495 * access control policy
18496 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
18497 * listed in hostapd.deny file.
18498 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
18499 * listed in hostapd.accept file.
18500 */
18501 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
18502 {
18503 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
18504 }
18505 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
18506 {
18507 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
18508 }
18509 else
18510 {
18511 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18512 "%s:Acl Policy : %d is not supported",
18513 __func__, params->acl_policy);
18514 return -ENOTSUPP;
18515 }
18516
18517 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
18518 {
18519 pConfig->num_accept_mac = params->n_acl_entries;
18520 for (i = 0; i < params->n_acl_entries; i++)
18521 {
18522 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18523 "** Add ACL MAC entry %i in WhiletList :"
18524 MAC_ADDRESS_STR, i,
18525 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
18526
18527 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
18528 sizeof(qcmacaddr));
18529 }
18530 }
18531 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
18532 {
18533 pConfig->num_deny_mac = params->n_acl_entries;
18534 for (i = 0; i < params->n_acl_entries; i++)
18535 {
18536 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18537 "** Add ACL MAC entry %i in BlackList :"
18538 MAC_ADDRESS_STR, i,
18539 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
18540
18541 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
18542 sizeof(qcmacaddr));
18543 }
18544 }
18545
18546 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
18547 {
18548 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18549 "%s: SAP Set Mac Acl fail", __func__);
18550 return -EINVAL;
18551 }
18552 }
18553 else
18554 {
18555 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053018556 "%s: Invalid device_mode = %s (%d)",
18557 __func__, hdd_device_modetoString(pAdapter->device_mode),
18558 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018559 return -EINVAL;
18560 }
18561
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018562 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018563 return 0;
18564}
18565
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018566static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
18567 struct net_device *dev,
18568 const struct cfg80211_acl_data *params)
18569{
18570 int ret;
18571 vos_ssr_protect(__func__);
18572 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
18573 vos_ssr_unprotect(__func__);
18574
18575 return ret;
18576}
18577
Leo Chang9056f462013-08-01 19:21:11 -070018578#ifdef WLAN_NL80211_TESTMODE
18579#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070018580void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070018581(
18582 void *pAdapter,
18583 void *indCont
18584)
18585{
Leo Changd9df8aa2013-09-26 13:32:26 -070018586 tSirLPHBInd *lphbInd;
18587 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053018588 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070018589
18590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070018591 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070018592
c_hpothu73f35e62014-04-18 13:40:08 +053018593 if (pAdapter == NULL)
18594 {
18595 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18596 "%s: pAdapter is NULL\n",__func__);
18597 return;
18598 }
18599
Leo Chang9056f462013-08-01 19:21:11 -070018600 if (NULL == indCont)
18601 {
18602 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070018603 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070018604 return;
18605 }
18606
c_hpothu73f35e62014-04-18 13:40:08 +053018607 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070018608 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070018609 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053018610 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070018611 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070018612 GFP_ATOMIC);
18613 if (!skb)
18614 {
18615 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18616 "LPHB timeout, NL buffer alloc fail");
18617 return;
18618 }
18619
Leo Changac3ba772013-10-07 09:47:04 -070018620 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070018621 {
18622 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18623 "WLAN_HDD_TM_ATTR_CMD put fail");
18624 goto nla_put_failure;
18625 }
Leo Changac3ba772013-10-07 09:47:04 -070018626 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070018627 {
18628 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18629 "WLAN_HDD_TM_ATTR_TYPE put fail");
18630 goto nla_put_failure;
18631 }
Leo Changac3ba772013-10-07 09:47:04 -070018632 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070018633 sizeof(tSirLPHBInd), lphbInd))
18634 {
18635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18636 "WLAN_HDD_TM_ATTR_DATA put fail");
18637 goto nla_put_failure;
18638 }
Leo Chang9056f462013-08-01 19:21:11 -070018639 cfg80211_testmode_event(skb, GFP_ATOMIC);
18640 return;
18641
18642nla_put_failure:
18643 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18644 "NLA Put fail");
18645 kfree_skb(skb);
18646
18647 return;
18648}
18649#endif /* FEATURE_WLAN_LPHB */
18650
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018651static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070018652{
18653 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
18654 int err = 0;
18655#ifdef FEATURE_WLAN_LPHB
18656 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070018657 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018658
18659 ENTER();
18660
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018661 err = wlan_hdd_validate_context(pHddCtx);
18662 if (0 != err)
18663 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018664 return err;
18665 }
Leo Chang9056f462013-08-01 19:21:11 -070018666#endif /* FEATURE_WLAN_LPHB */
18667
18668 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
18669 if (err)
18670 {
18671 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18672 "%s Testmode INV ATTR", __func__);
18673 return err;
18674 }
18675
18676 if (!tb[WLAN_HDD_TM_ATTR_CMD])
18677 {
18678 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18679 "%s Testmode INV CMD", __func__);
18680 return -EINVAL;
18681 }
18682
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018683 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18684 TRACE_CODE_HDD_CFG80211_TESTMODE,
18685 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070018686 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
18687 {
18688#ifdef FEATURE_WLAN_LPHB
18689 /* Low Power Heartbeat configuration request */
18690 case WLAN_HDD_TM_CMD_WLAN_HB:
18691 {
18692 int buf_len;
18693 void *buf;
18694 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080018695 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070018696
18697 if (!tb[WLAN_HDD_TM_ATTR_DATA])
18698 {
18699 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18700 "%s Testmode INV DATA", __func__);
18701 return -EINVAL;
18702 }
18703
18704 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
18705 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080018706
18707 hb_params_temp =(tSirLPHBReq *)buf;
18708 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
18709 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
18710 return -EINVAL;
18711
Leo Chang9056f462013-08-01 19:21:11 -070018712 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
18713 if (NULL == hb_params)
18714 {
18715 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18716 "%s Request Buffer Alloc Fail", __func__);
18717 return -EINVAL;
18718 }
18719
18720 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070018721 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
18722 hb_params,
18723 wlan_hdd_cfg80211_lphb_ind_handler);
18724 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070018725 {
Leo Changd9df8aa2013-09-26 13:32:26 -070018726 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18727 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070018728 vos_mem_free(hb_params);
18729 }
Leo Chang9056f462013-08-01 19:21:11 -070018730 return 0;
18731 }
18732#endif /* FEATURE_WLAN_LPHB */
18733 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018734 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18735 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070018736 return -EOPNOTSUPP;
18737 }
18738
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018739 EXIT();
18740 return err;
Leo Chang9056f462013-08-01 19:21:11 -070018741}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018742
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053018743static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
18744#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
18745 struct wireless_dev *wdev,
18746#endif
18747 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018748{
18749 int ret;
18750
18751 vos_ssr_protect(__func__);
18752 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
18753 vos_ssr_unprotect(__func__);
18754
18755 return ret;
18756}
Leo Chang9056f462013-08-01 19:21:11 -070018757#endif /* CONFIG_NL80211_TESTMODE */
18758
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018759static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018760 struct net_device *dev,
18761 int idx, struct survey_info *survey)
18762{
18763 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18764 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053018765 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018766 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053018767 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018768 v_S7_t snr,rssi;
18769 int status, i, j, filled = 0;
18770
18771 ENTER();
18772
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018773 if (NULL == pAdapter)
18774 {
18775 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18776 "%s: HDD adapter is Null", __func__);
18777 return -ENODEV;
18778 }
18779
18780 if (NULL == wiphy)
18781 {
18782 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18783 "%s: wiphy is Null", __func__);
18784 return -ENODEV;
18785 }
18786
18787 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18788 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018789 if (0 != status)
18790 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018791 return status;
18792 }
18793
Mihir Sheted9072e02013-08-21 17:02:29 +053018794 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18795
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018796 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053018797 0 != pAdapter->survey_idx ||
18798 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018799 {
18800 /* The survey dump ops when implemented completely is expected to
18801 * return a survey of all channels and the ops is called by the
18802 * kernel with incremental values of the argument 'idx' till it
18803 * returns -ENONET. But we can only support the survey for the
18804 * operating channel for now. survey_idx is used to track
18805 * that the ops is called only once and then return -ENONET for
18806 * the next iteration
18807 */
18808 pAdapter->survey_idx = 0;
18809 return -ENONET;
18810 }
18811
Mukul Sharma9d5233b2015-06-11 20:28:20 +053018812 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
18813 {
18814 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18815 "%s: Roaming in progress, hence return ", __func__);
18816 return -ENONET;
18817 }
18818
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018819 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18820
18821 wlan_hdd_get_snr(pAdapter, &snr);
18822 wlan_hdd_get_rssi(pAdapter, &rssi);
18823
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018824 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18825 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
18826 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018827 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
18828 hdd_wlan_get_freq(channel, &freq);
18829
18830
18831 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
18832 {
18833 if (NULL == wiphy->bands[i])
18834 {
18835 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
18836 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
18837 continue;
18838 }
18839
18840 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
18841 {
18842 struct ieee80211_supported_band *band = wiphy->bands[i];
18843
18844 if (band->channels[j].center_freq == (v_U16_t)freq)
18845 {
18846 survey->channel = &band->channels[j];
18847 /* The Rx BDs contain SNR values in dB for the received frames
18848 * while the supplicant expects noise. So we calculate and
18849 * return the value of noise (dBm)
18850 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
18851 */
18852 survey->noise = rssi - snr;
18853 survey->filled = SURVEY_INFO_NOISE_DBM;
18854 filled = 1;
18855 }
18856 }
18857 }
18858
18859 if (filled)
18860 pAdapter->survey_idx = 1;
18861 else
18862 {
18863 pAdapter->survey_idx = 0;
18864 return -ENONET;
18865 }
18866
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018867 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018868 return 0;
18869}
18870
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018871static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
18872 struct net_device *dev,
18873 int idx, struct survey_info *survey)
18874{
18875 int ret;
18876
18877 vos_ssr_protect(__func__);
18878 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
18879 vos_ssr_unprotect(__func__);
18880
18881 return ret;
18882}
18883
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018884/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018885 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018886 * this is called when cfg80211 driver resume
18887 * driver updates latest sched_scan scan result(if any) to cfg80211 database
18888 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018889int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018890{
18891 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
18892 hdd_adapter_t *pAdapter;
18893 hdd_adapter_list_node_t *pAdapterNode, *pNext;
18894 VOS_STATUS status = VOS_STATUS_SUCCESS;
18895
18896 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018897
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018898 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018899 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018900 return 0;
18901 }
18902
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018903 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
18904 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018905 spin_lock(&pHddCtx->schedScan_lock);
18906 pHddCtx->isWiphySuspended = FALSE;
18907 if (TRUE != pHddCtx->isSchedScanUpdatePending)
18908 {
18909 spin_unlock(&pHddCtx->schedScan_lock);
18910 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18911 "%s: Return resume is not due to PNO indication", __func__);
18912 return 0;
18913 }
18914 // Reset flag to avoid updatating cfg80211 data old results again
18915 pHddCtx->isSchedScanUpdatePending = FALSE;
18916 spin_unlock(&pHddCtx->schedScan_lock);
18917
18918 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
18919
18920 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
18921 {
18922 pAdapter = pAdapterNode->pAdapter;
18923 if ( (NULL != pAdapter) &&
18924 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
18925 {
18926 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053018927 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018928 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
18929 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053018930 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018931 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053018932 {
18933 /* Acquire wakelock to handle the case where APP's tries to
18934 * suspend immediately after updating the scan results. Whis
18935 * results in app's is in suspended state and not able to
18936 * process the connect request to AP
18937 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053018938 hdd_prevent_suspend_timeout(2000,
18939 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018940 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053018941 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018942
18943 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18944 "%s : cfg80211 scan result database updated", __func__);
18945
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018946 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018947 return 0;
18948
18949 }
18950 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
18951 pAdapterNode = pNext;
18952 }
18953
18954 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18955 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018956 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018957 return 0;
18958}
18959
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018960int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
18961{
18962 int ret;
18963
18964 vos_ssr_protect(__func__);
18965 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
18966 vos_ssr_unprotect(__func__);
18967
18968 return ret;
18969}
18970
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018971/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018972 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018973 * this is called when cfg80211 driver suspends
18974 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018975int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018976 struct cfg80211_wowlan *wow)
18977{
18978 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018979 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018980
18981 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018982
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018983 ret = wlan_hdd_validate_context(pHddCtx);
18984 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018985 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018986 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018987 }
18988
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018989
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018990 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18991 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
18992 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018993 pHddCtx->isWiphySuspended = TRUE;
18994
18995 EXIT();
18996
18997 return 0;
18998}
18999
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019000int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
19001 struct cfg80211_wowlan *wow)
19002{
19003 int ret;
19004
19005 vos_ssr_protect(__func__);
19006 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
19007 vos_ssr_unprotect(__func__);
19008
19009 return ret;
19010}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019011
19012#ifdef FEATURE_OEM_DATA_SUPPORT
19013static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
19014 void *pMsg)
19015{
19016 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
19017
19018 ENTER();
19019
19020 if (wlan_hdd_validate_context(pHddCtx)) {
19021 return;
19022 }
19023 if (!pMsg)
19024 {
19025 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
19026 return;
19027 }
19028
19029 send_oem_data_rsp_msg(sizeof(tOemDataRspNew), pMsg);
19030
19031 EXIT();
19032 return;
19033
19034}
19035
19036void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
19037 void *pMsg)
19038{
19039 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
19040
19041 ENTER();
19042
19043 if (wlan_hdd_validate_context(pHddCtx)) {
19044 return;
19045 }
19046
19047 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
19048
19049 switch(evType) {
19050 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
19051 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg);
19052 break;
19053 default:
19054 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
19055 break;
19056 }
19057 EXIT();
19058}
19059#endif
19060
Jeff Johnson295189b2012-06-20 16:38:30 -070019061/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019062static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070019063{
19064 .add_virtual_intf = wlan_hdd_add_virtual_intf,
19065 .del_virtual_intf = wlan_hdd_del_virtual_intf,
19066 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
19067 .change_station = wlan_hdd_change_station,
19068#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
19069 .add_beacon = wlan_hdd_cfg80211_add_beacon,
19070 .del_beacon = wlan_hdd_cfg80211_del_beacon,
19071 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019072#else
19073 .start_ap = wlan_hdd_cfg80211_start_ap,
19074 .change_beacon = wlan_hdd_cfg80211_change_beacon,
19075 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070019076#endif
19077 .change_bss = wlan_hdd_cfg80211_change_bss,
19078 .add_key = wlan_hdd_cfg80211_add_key,
19079 .get_key = wlan_hdd_cfg80211_get_key,
19080 .del_key = wlan_hdd_cfg80211_del_key,
19081 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080019082#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070019083 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080019084#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019085 .scan = wlan_hdd_cfg80211_scan,
19086 .connect = wlan_hdd_cfg80211_connect,
19087 .disconnect = wlan_hdd_cfg80211_disconnect,
19088 .join_ibss = wlan_hdd_cfg80211_join_ibss,
19089 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
19090 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
19091 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
19092 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070019093 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
19094 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053019095 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070019096#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
19097 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
19098 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
19099 .set_txq_params = wlan_hdd_set_txq_params,
19100#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019101 .get_station = wlan_hdd_cfg80211_get_station,
19102 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
19103 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019104 .add_station = wlan_hdd_cfg80211_add_station,
19105#ifdef FEATURE_WLAN_LFR
19106 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
19107 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
19108 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
19109#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019110#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
19111 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
19112#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019113#ifdef FEATURE_WLAN_TDLS
19114 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
19115 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
19116#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019117#ifdef WLAN_FEATURE_GTK_OFFLOAD
19118 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
19119#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019120#ifdef FEATURE_WLAN_SCAN_PNO
19121 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
19122 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
19123#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019124 .resume = wlan_hdd_cfg80211_resume_wlan,
19125 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019126 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070019127#ifdef WLAN_NL80211_TESTMODE
19128 .testmode_cmd = wlan_hdd_cfg80211_testmode,
19129#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019130 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070019131};
19132